On 06/03/2013 03:16 PM, Pavel Sanda wrote:
Pavel Sanda wrote:
(new mails are encapsulated in base64 encoding that's why coloring works).
Actually no, I seem to be fooled by my own scripts ;)
Why do you use base64 encoding?
Can't we continue with plain text version of the mails?
I didn't know that had changed.
The script is a modification of one I found on the web. If you want to
have a look, I've attached it. I'm not sure why it would be base64.
rh
#!/usr/bin/python
from __future__ import with_statement
import re
import smtplib
import subprocess
import sys
import time
import traceback
from collections import defaultdict
from email.mime.text import MIMEText
from StringIO import StringIO
MAILINGLIST = 'hooks.mailinglist'
SMTP_PREFIX = 'hooks.smtp-prefix'
SMTP_SENDER = 'hooks.smtp-sender'
POST_RECEIVE_LOGFILE = 'hooks.post-receive-logfile'
SMTP_REPLY_TO = 'hooks.smtp-reply-to'
class Mailer(object):
def __init__(self, sender, reply_to, recipients):
self.sender = sender
self.reply_to = reply_to
self.recipients = recipients
def send(self, sname, semail, subject, message):
if not self.recipients:
return
mime_text = MIMEText(message, _charset='utf-8')
mime_text['From'] = "%s <%s>" % (sname, semail)
mime_text['Reply-To'] = self.reply_to
mime_text['To'] = ', '.join(self.recipients)
mime_text['Subject'] = subject
server = smtplib.SMTP()
server.connect()
server.ehlo()
server.sendmail(semail, self.recipients,
mime_text.as_string())
server.rset()
server.quit()
def git_config_get(name):
p = subprocess.Popen(['git', 'config', '--get', name],
stdout=subprocess.PIPE)
# Cut off the last \n character.
return p.stdout.read()[:-1]
def git_show(hash):
p = subprocess.Popen(['git', 'show', hash], stdout = subprocess.PIPE)
return p.stdout.read()
def git_rev_parse(hash, short=False):
args = ['git', 'rev-parse']
if short:
args.append('--short')
args.append(hash)
p = subprocess.Popen(args, stdout=subprocess.PIPE)
# Cut off the last \n character.
return p.stdout.read()[:-1]
def get_commit_info(hash):
p = subprocess.Popen(['git', 'show', '--pretty=format:%s%n%h%n%ae%n%an', '-s', hash],
stdout = subprocess.PIPE)
s = StringIO(p.stdout.read())
def undefined():
return 'undefined'
info = defaultdict(undefined)
for k in ['message', 'hash', 'email', 'name']:
info[k] = s.readline().strip()
return info
def process_commits(commits, mailer, prefix):
for ref_name in commits.keys():
use_index = len(commits[ref_name]) > 1
for i, commit in enumerate(commits[ref_name]):
info = get_commit_info(commit)
rname = ref_name
t = "refs/heads/"
if rname.startswith(t):
rname = rname[len(t):]
subject = "[%s/%s] %s" % (prefix, rname, info['message'])
message = git_show(commit)
mailer.send(info['name'], info['email'], subject, message)
def get_commits(old_rev, new_rev):
p = subprocess.Popen(['git', 'log', '--pretty=format:%H', '--reverse',
'%s..%s' % (old_rev, new_rev)],
stdout=subprocess.PIPE)
return p.stdout.read().split('\n')
def parse_post_receive_line(l):
return l.split()
def post_receive(mailer, subject_prefix):
lines = sys.stdin.readlines()
commits = {}
for line in lines:
old_rev, new_rev, ref_name = parse_post_receive_line(line)
commits[ref_name] = get_commits(old_rev, new_rev)
process_commits(commits, mailer, subject_prefix)
def get_config_variables():
def optional(variable):
config[variable] = git_config_get(variable)
def required(variable, type_=str):
v = git_config_get(variable)
if not v:
raise RuntimeError('This script needs %s to work.' % variable)
config[variable] = type_(v)
def recipients(variable):
v = git_config_get(variable)
config[variable] = [r for r in re.split(' *, *| +', v) if r]
config = {}
optional(SMTP_PREFIX)
required(SMTP_REPLY_TO)
required(SMTP_SENDER)
recipients(MAILINGLIST)
return config
def main():
log_file_path = git_config_get(POST_RECEIVE_LOGFILE)
with open(log_file_path, 'a') as log_file:
try:
config = get_config_variables()
mailer = Mailer(config[SMTP_SENDER], config[SMTP_REPLY_TO], config[MAILINGLIST])
post_receive(mailer, config[SMTP_PREFIX])
except:
log_file.write('%s\n' % time.strftime('%Y-%m-%d %X'))
traceback.print_exc(file=log_file)
if __name__ == '__main__':
main()