diff --git a/gestion/darcs_send_changes.py b/gestion/darcs_send_changes.py index a13b56f6..5e945742 100755 --- a/gestion/darcs_send_changes.py +++ b/gestion/darcs_send_changes.py @@ -58,10 +58,9 @@ def darcs(args): """ Invoque darcs et renvoie sa sortie. """ return to_utf8(commands.getoutput("env DARCS_DONT_ESCAPE_8BIT=1 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] - hash = prop.attrib['hash'] +def get_patch_properties(hash): + """ Récupère les informations a propos d'un certain patch. """ + prop = etree.XML(darcs("changes --match='hash %s' --xml-output" % hash))[0] diff = darcs("diff --match='hash %s' --unified" % hash) diff = diff[diff.find('\ndiff ')+1:] cwd = os.getcwd() @@ -75,6 +74,16 @@ def get_patch_properties(): 'diff': diff, 'changes': darcs("changes --match='hash %s' --summary" % hash) } +def get_patches_properties(from_hash): + """ Construit la liste des informations sur les patches à partir du patch from_hash. """ + changelog = etree.XML(darcs("changes --from-match='hash %s' --reverse --xml-output" % from_hash)) + props = [] + for change in changelog[1:]: + # Ca peut parraitre inutile de refaire un darcs changes, mais c'est pour palier aux problemes + # d'encodages + 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 @@ -83,7 +92,9 @@ Subject: Darcs record (%(shortrepo)s): %(name)s %(diff)s """ -TEMPLATE_FILE = "_darcs/third-party/darcs-send-changes/email-template" +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 @@ -140,6 +151,7 @@ Les options disponibles sont: -s, --smtp spécifie le serveur smtp à utiliser -r, --repo spécifie l'emplacement du dépôt -t, --template fichier a utiliser comme template + -f, --from hash du premier patch de la série a envoyer Si aucun destinataires n'est donné, roots@crans.org est utilisé. """ % { 'name': os.path.basename(sys.argv[0]) }) @@ -151,9 +163,10 @@ if __name__ == "__main__": smtp = 'localhost' repo = None template = None + from_hash = None try: - options, arg = getopt.getopt(sys.argv[1:], 'hs:r:t:', [ 'help', 'smtp=', 'repo=', 'template=']) + options, arg = getopt.getopt(sys.argv[1:], 'hs:r:t:f:', [ 'help', 'smtp=', 'repo=', 'template=', 'from=']) except getopt.error, msg: __usage(unicode(msg)) for opt, val in options: @@ -165,6 +178,8 @@ if __name__ == "__main__": repo = val elif opt in [ '-t', '--template' ]: template = val + elif opt in [ '-f', '--from' ]: + from_hash = val else: __usage("option inconnue « %s »'" % opt) recipient = arg @@ -179,6 +194,27 @@ if __name__ == "__main__": f = open(template) template = f.read() f.close() + if not from_hash: + if os.path.exists(LAST_SEEN_FILE): + f = open(LAST_SEEN_FILE) + from_hash = f.read().strip() + f.close() + else: + from_hash = "" + + patches = get_patches_properties(from_hash) + if len(patches) == 0: + sys.exit(0) + for patch in patches: + cprint("Envoie du patch %s a %s." % (patch['hash'], ", ".join(recipient))) + send_changes(smtplib.SMTP(smtp), recipient, patch, template) + if not os.path.exists(CONF_PATH): + p = "" + for comp in CONF_PATH.split('/'): + p = "%s/%s" % (p, comp) + if not os.path.exits(p): + os.mkdir(p) + f = open(LAST_SEEN_FILE, "w") + f.write(patches[-1]['hash']) + f.close() - cprint("Envoie du patch a " + ", ".join(recipient)) - send_changes(smtplib.SMTP(smtp), recipient, get_patch_properties(), template)