From: Vincent Le Gallic Date: Thu, 12 Mar 2015 02:33:35 +0000 (+0100) Subject: [mails/rmdups] Scripts pour supprimer les doublons mail X-Git-Url: http://gitweb.pimeys.fr/?a=commitdiff_plain;h=24d1d3727de0f841e0678787acabd99bd062a097;p=scripts-20-100.git [mails/rmdups] Scripts pour supprimer les doublons mail --- diff --git a/mails/rmdups.py b/mails/rmdups.py new file mode 100755 index 0000000..fa75d69 --- /dev/null +++ b/mails/rmdups.py @@ -0,0 +1,76 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +""" Pour supprimer des mails présents en double dans un dossier Imap. + Supprimme toujours les doublons les plus lourds. + + Des "doublons" sont des mails qui ont le même Message-Id. """ + +from __future__ import print_function + +import sys +import os +import re +import collections +import argparse +import pprint + +def get_files(dir): + """Donne les fichiers dans le dossier.""" + l = [os.path.join(dir, f) for f in os.listdir(dir)] + return [f for f in l if os.path.isfile(f)] + +def message_id(file): + """Récupère le message-id du mail""" + l = re.findall("^Message-I(?:D|d): <(.*)>", open(file, "r").read(), flags=re.MULTILINE) + if l: + return l[0] + +def finddups(dir, verbose=False): + """Trouve les doublons dans ``dir``""" + todelete = [] + l = get_files(dir) + d = collections.defaultdict(lambda : []) + for f in l: + d[message_id(f)].append(f) + # On affiche les fichiers pour lesquels on n'a pas réussi à trouver de Message-ID + if d[None]: + print("Attention : Fichiers sans Message-ID :", file=sys.stderr) + for f in d[None]: + print(f, file=sys.stderr) + # On ne les considère pas comme des doublons + del d[None] + d = {id : files for (id, files) in d.iteritems() if len(files) > 1} + if verbose: + print("Doublons trouvés :") + pprint.pprint(d) + return d + +def run(dir, verbose=False, dry=False): + """Do the job sur ``dir``""" + dups = finddups(dir, verbose) + if not dups: + print("Aucun doublon trouvé") + return + if dry: + print("**dry-run**, rien ne sera supprimé") + for (_, files) in dups.iteritems(): + sizes = [os.path.getsize(f) for f in files] + msize = min(sizes) + keep = files[sizes.index(msize)] + removes = [f for f in files if f != keep] + if verbose or dry: + for f in removes: + print("Suppression de %s (doublon de %s)" % (f, keep)) + if not dry: + for f in removes: + os.remove(f) + +parser = argparse.ArgumentParser(description="Suppression de mails identiques.") +parser.add_argument("-v", "--verbose", help="Afficher ce qui est supprimé", action="store_true") +parser.add_argument("-n", "--dry-run", help="Faire semblant", action="store_true") +parser.add_argument("dir", help="Le dossier où chercher les doublons", type=str) + +if __name__ == "__main__": + args = parser.parse_args() + d = run(args.dir, verbose=args.verbose, dry=args.dry_run)