Script pour envoyer le dernier commit dans darcs par mail.
darcs-hash:20071208223243-af139-7ce74d950e424a60ee130344a952245f0a823d27.gz
This commit is contained in:
parent
60a9ec9315
commit
aa0141a047
1 changed files with 172 additions and 0 deletions
172
gestion/darcs_send_changes.py
Executable file
172
gestion/darcs_send_changes.py
Executable file
|
@ -0,0 +1,172 @@
|
|||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# darcs_send_changes.py
|
||||
# ---------------------
|
||||
#
|
||||
# Copyright (C) 2007 Jeremie Dimino <jeremie@dimino.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
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This file is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA.
|
||||
|
||||
|
||||
"""
|
||||
Envoie un mail détaillant le dernier patch appliqué à un dépot.
|
||||
"""
|
||||
|
||||
import commands, os, sys, email, re, cStringIO
|
||||
|
||||
try:
|
||||
from lxml import etree
|
||||
except:
|
||||
sys.stderr.write("darcs_send_changes recquiert le paquet python-lxml.\n")
|
||||
sys.stderr.flush()
|
||||
sys.exit(1)
|
||||
|
||||
sys.path.append("/usr/scripts/gestion")
|
||||
from affich_tools import cprint
|
||||
from unicode2ascii import unicode2ascii
|
||||
|
||||
def darcs(args):
|
||||
""" Invoque darcs et renvoie sa sortie. """
|
||||
return commands.getoutput("darcs " + args)
|
||||
|
||||
def get_patch_properties():
|
||||
""" Récupère les informations a propos du dernier patch. """
|
||||
prop = etree.XML(darcs("changes --last 1 --xml-output"))[0]
|
||||
diff = darcs("diff --last 1 --unified")
|
||||
diff = diff[diff.find('\ndiff ')+1:]
|
||||
cwd = os.getcwd()
|
||||
return { 'author': prop.attrib['author'],
|
||||
'repo': "%s:%s" % (commands.getoutput('hostname -s'), cwd),
|
||||
'shortrepo': os.path.basename(cwd),
|
||||
'date': prop.attrib['local_date'],
|
||||
'hash': prop.attrib['hash'],
|
||||
'name': prop.findtext('name'),
|
||||
'comment': prop.findtext('comment'),
|
||||
'diff': diff,
|
||||
'changes': darcs('changes --last 1 --summary') }
|
||||
|
||||
DEFAULT_TEMPLATE = """From: %(author)s
|
||||
To: %(recipient)s
|
||||
Subject: Darcs record (%(shortrepo)s): %(name)s
|
||||
|
||||
%(changes)s
|
||||
|
||||
%(diff)s
|
||||
"""
|
||||
TEMPLATE_FILE = "_darcs/third-party/darcs-send-changes/email-template"
|
||||
|
||||
__darcs_escaped_re = re.compile('\\[_\\\\[0-9a-f][0-9a-f]_\\]')
|
||||
def darcs_unescape(str):
|
||||
""" Converti les séquences d'échappement de darcs en charactère unicode. """
|
||||
start = 0
|
||||
newstr = cStringIO.StringIO()
|
||||
s = __darcs_escaped_re.search(str, start)
|
||||
while s:
|
||||
newstr.write(str[start:s.start()])
|
||||
newstr.write(chr(int(str[s.start()+3:s.start()+5], 16)))
|
||||
start = s.end()
|
||||
s = __darcs_escaped_re.search(str, start)
|
||||
newstr.write(str[start:])
|
||||
return newstr.getvalue()
|
||||
|
||||
def send_changes(smtp, recipient, patch_props, template=DEFAULT_TEMPLATE):
|
||||
""" Formatte 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:
|
||||
* 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)
|
||||
rawmail = darcs_unescape((template or DEFAULT_TEMPLATE) % patch_props)
|
||||
mail = email.message_from_string(rawmail)
|
||||
if not mail['Content-Transfer-Encoding']:
|
||||
mail['Content-Transfer-Encoding'] = 'quoted-printable'
|
||||
if not mail.get_charset():
|
||||
mail.set_charset("UTF-8")
|
||||
# On met le titre en ascii sinon c'est atroce pour le filtrage
|
||||
# automatique
|
||||
subject = unicode2ascii(mail['Subject'].decode("UTF-8"))
|
||||
mail.replace_header('Subject', subject)
|
||||
rawmail = mail.as_string()
|
||||
for to in recipient:
|
||||
smtp.sendmail(patch_props['author'], to, rawmail)
|
||||
|
||||
def __usage(err=None):
|
||||
if err: cprint("%s\n" % err)
|
||||
cprint("""Usage: %(name)s [OPTIONS] destinataires
|
||||
pour en savoir plus faites « %(name)s --help »
|
||||
""" % { 'name': os.path.basename(sys.argv[0]) })
|
||||
sys.exit(2)
|
||||
|
||||
def __help():
|
||||
cprint("""Usage: %(name)s [options] destinataires
|
||||
|
||||
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
|
||||
|
||||
Si aucun destinataires n'est donné, roots@crans.org est utilisé.
|
||||
""" % { 'name': os.path.basename(sys.argv[0]) })
|
||||
sys.exit(0)
|
||||
|
||||
if __name__ == "__main__":
|
||||
import smtplib, getopt
|
||||
|
||||
smtp = 'localhost'
|
||||
repo = None
|
||||
template = None
|
||||
|
||||
try:
|
||||
options, arg = getopt.getopt(sys.argv[1:], 'hs:r:t:', [ 'help', 'smtp=', 'repo=', 'template='])
|
||||
except getopt.error, msg:
|
||||
__usage(unicode(msg))
|
||||
for opt, val in options:
|
||||
if opt in [ '-h', '--help' ]:
|
||||
__help()
|
||||
elif opt in [ '-s', '--smtp' ]:
|
||||
smtp = val
|
||||
elif opt in [ '-r', '--repo' ]:
|
||||
repo = val
|
||||
elif opt in [ '-t', '--template' ]:
|
||||
template = val
|
||||
else:
|
||||
__usage("option inconnue « %s »'" % opt)
|
||||
recipient = arg
|
||||
if len(recipient) == 0:
|
||||
recipient = [ 'roots@crans.org' ]
|
||||
|
||||
if repo:
|
||||
os.chdir(repo)
|
||||
if not template and os.path.exists(TEMPLATE_FILE):
|
||||
template = TEMPLATE_FILE
|
||||
if template:
|
||||
f = open(template)
|
||||
template = f.read()
|
||||
f.close()
|
||||
|
||||
cprint("Envoie du patch a " + ", ".join(recipient))
|
||||
send_changes(smtplib.SMTP(smtp), recipient, get_patch_properties(), template)
|
Loading…
Add table
Add a link
Reference in a new issue