Patch en pièce jointe pour la notification Darcs

Cette modification permet d'envoyer le patch en pièce jointe (inline) au lieu de le mettre directement dans le corps du message

darcs-hash:20071214223740-ffbb2-96d9400a9935026956c93c1b35933d9a49b12d85.gz
This commit is contained in:
Nicolas Dandrimont 2007-12-14 23:37:40 +01:00
parent 6458f06ce2
commit 8b3d4f05e6

View file

@ -5,6 +5,7 @@
# ---------------------
#
# Copyright (C) 2007 Jeremie Dimino <jeremie@dimino.org>
# Copyright (C) 2007 Nicolas Dandrimont <Nicolas.Dandrimont@crans.org>
#
# This file is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@ -30,13 +31,17 @@ import commands, os, sys, email
try:
from lxml import etree
except:
sys.stderr.write("darcs_send_changes recquiert le paquet python-lxml.\n")
sys.stderr.write("darcs_send_changes requiert le paquet python-lxml.\n")
sys.stderr.flush()
sys.exit(1)
sys.path.append("/usr/scripts/gestion")
from affich_tools import cprint, encoding
from unicode2ascii import unicode2ascii
from email.MIMEMultipart import MIMEMultipart
from email.MIMEText import MIMEText
from email.Utils import formatdate
from email import Encoders
def to_utf8(str):
""" Decode un str ou un unicode vers un str en UTF-8. """
@ -84,60 +89,64 @@ def get_patches_properties(from_hash):
props.append(get_patch_properties(change.attrib['hash']))
return props
DEFAULT_TEMPLATE = """From: %(author)s
To: %(recipient)s
Subject: Darcs record (%(shortrepo)s): %(name)s
Mail-Followup-To: %(recipient)s
Mail-Reply-To: %(author)s
X-CVSinfo: CRANS
X-DarcsInfo: CRANS-%(shortrepo)s
%(changes)s
%(diff)s
"""
CONF_PATH = "_darcs/third-party/darcs-send-changes"
TEMPLATE_FILE = CONF_PATH + "/email-template"
LAST_SEEN_FILE = CONF_PATH + "/last-seen"
def send_changes(smtp, recipient, patch_props, template=DEFAULT_TEMPLATE):
""" Formatte et envoie un mail avec les modifications sur le dernier
def send_changes(smtp, recipient, patch_props):
""" Formate et envoie un mail avec les modifications sur le dernier
patch appliqué au dépot.
recipient est une liste des destinataires du mail.
template est une chaîne de format python qui
peut contenir les variables suivantes:
Les différents templates sont des chaînes de format python qui peuvent
contenir les variables suivantes:
* author, date, hash, name, comment
* repo: le dépot (hote + chemin)
* shortrepo: basename(chemin du dépot)
* changes: la sortie de darcs changes --summary
* diff: la sortie de darcs diff --unified a partir du premier diff
* recipient: les destinataires du mail
si template est None, DEFAULT_TEMPLATE est utilisé.
"""
patch_props["recipient"] = ", ".join(recipient)
from_template = "%(author)s"
subject_template = "Darcs record (%(shortrepo)s): %(name)s"
message_template = "%(changes)s"
diff_template = "%(diff)s"
# On met toutes valeurs en string, en UTF-8
for key, val in patch_props.items():
patch_props[key] = to_utf8(val)
template = to_utf8(template or DEFAULT_TEMPLATE)
mail = email.message_from_string(template % patch_props)
mail = MIMEMultipart()
# On met le titre en ascii sinon c'est atroce pour le filtrage
# automatique
subject = mail['Subject']
subject = subject_template % patch_props
if subject:
subject = unicode2ascii(subject.decode("UTF-8"))
mail.replace_header('Subject', subject)
mail['Subject'] = subject_template % patch_props
mail['From'] = from_template % patch_props
mail['To'] = ", ".join(recipient)
mail['Date'] = formatdate(localtime=True)
mail['Mail-Followup-To'] = ", ".join(recipient)
mail['Mail-Reply-To'] = from_template % patch_props
mail['X-CVSinfo'] = "CRANS"
mail['X-DarcsInfo'] = "CRANS-%(shortrepo)s" % patch_props
texte = MIMEText(message_template % patch_props, "UTF-8")
texte.set_charset("UTF-8")
mail.attach(texte)
patch = MIMEText(diff_template % patch_props, "UTF-8")
patch.set_type('text/x-patch')
patch.set_charset("UTF-8")
patch.add_header('Content-Disposition', 'inline', filename='%(hash)s.diff' % patch_props)
mail.attach(patch)
if not mail['Content-Transfer-Encoding']:
mail['Content-Transfer-Encoding'] = '8bit'
charset = mail.get_charset()
if not charset:
charset = "UTF-8"
mail.set_charset("UTF-8")
rawmail = mail.as_string()
if charset != "UTF-8":
rawmail = rawmail.decode("UTF-8").encode(charset)
mail.set_charset("UTF-8")
for to in recipient:
smtp.sendmail(patch_props['author'], to, rawmail)
smtp.sendmail(patch_props['author'], to, mail.as_string())
def __usage(err=None):
if err: cprint("%s\n" % err)
@ -153,10 +162,9 @@ Les options disponibles sont:
-h, --help affiche cette aide
-s, --smtp <serveur> spécifie le serveur smtp à utiliser
-r, --repo <chemin> spécifie l'emplacement du dépôt
-t, --template <fichier> fichier a utiliser comme template
-f, --from <hash> hash du premier patch de la série a envoyer
Si aucun destinataires n'est donné, roots@crans.org est utilisé.
Si aucun destinataire n'est donné, roots@crans.org est utilisé.
""" % { 'name': os.path.basename(sys.argv[0]) })
sys.exit(0)
@ -165,11 +173,10 @@ if __name__ == "__main__":
smtp = 'localhost'
repo = None
template = None
from_hash = None
try:
options, arg = getopt.getopt(sys.argv[1:], 'hs:r:t:f:', [ 'help', 'smtp=', 'repo=', 'template=', 'from='])
options, arg = getopt.getopt(sys.argv[1:], 'hs:r:f:', [ 'help', 'smtp=', 'repo=', 'from='])
except getopt.error, msg:
__usage(unicode(msg))
for opt, val in options:
@ -179,8 +186,6 @@ if __name__ == "__main__":
smtp = val
elif opt in [ '-r', '--repo' ]:
repo = val
elif opt in [ '-t', '--template' ]:
template = val
elif opt in [ '-f', '--from' ]:
from_hash = val
else:
@ -197,12 +202,7 @@ if __name__ == "__main__":
if not os.path.exists('_darcs') and os.getcwd() == '/':
cprint("Pas de dépôt darcs trouvé")
sys.exit(1)
if not template and os.path.exists(TEMPLATE_FILE):
template = TEMPLATE_FILE
if template:
f = open(template)
template = f.read()
f.close()
if not from_hash:
if os.path.exists(LAST_SEEN_FILE):
f = open(LAST_SEEN_FILE)
@ -216,7 +216,7 @@ if __name__ == "__main__":
sys.exit(0)
for patch in patches:
cprint("Envoi du patch %s a %s." % (patch['hash'], ", ".join(recipient)))
send_changes(smtplib.SMTP(smtp), recipient, patch, template)
send_changes(smtplib.SMTP(smtp), recipient, patch)
if not os.path.exists(CONF_PATH):
p = ""
for comp in CONF_PATH.split('/'):