]> gitweb.pimeys.fr Git - scripts-20-100.git/commitdiff
[mails/rmdups] Scripts pour supprimer les doublons mail
authorVincent Le Gallic <legallic@crans.org>
Thu, 12 Mar 2015 02:33:35 +0000 (03:33 +0100)
committerVincent Le Gallic <legallic@crans.org>
Thu, 12 Mar 2015 02:33:35 +0000 (03:33 +0100)
mails/rmdups.py [new file with mode: 0755]

diff --git a/mails/rmdups.py b/mails/rmdups.py
new file mode 100755 (executable)
index 0000000..fa75d69
--- /dev/null
@@ -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)