summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJason A. Donenfeld <Jason@zx2c4.com>2013-09-05 17:40:58 +0200
committerJason A. Donenfeld <Jason@zx2c4.com>2013-09-05 17:40:58 +0200
commited8ee4383288e5781fc16ca7c4b48b21114a8a53 (patch)
tree2c7bb48b692469849573b39ce74cd0d93c87aada
parentRemember to fsync in case of power failure. (diff)
downloadgmail-notmuch-ed8ee4383288e5781fc16ca7c4b48b21114a8a53.tar.xz
gmail-notmuch-ed8ee4383288e5781fc16ca7c4b48b21114a8a53.zip
Support importing from gmvault.
-rwxr-xr-xgmvault-notmuch.py103
1 files changed, 103 insertions, 0 deletions
diff --git a/gmvault-notmuch.py b/gmvault-notmuch.py
new file mode 100755
index 0000000..36d7ba3
--- /dev/null
+++ b/gmvault-notmuch.py
@@ -0,0 +1,103 @@
+#!/usr/bin/env python
+
+# (C) Copyright 2013 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
+
+# This program 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.
+
+import os.path
+import os
+import json
+import notmuch
+
+def main():
+ try:
+ database = notmuch.Database(None, False, notmuch.Database.MODE.READ_WRITE)
+ except notmuch.NotmuchError as e:
+ print(str(e))
+ return
+ if database.needs_upgrade():
+ database.upgrade()
+ destination = database.get_path()
+
+ for root, dirs, files in os.walk(destination):
+ for name in files:
+ filename = os.path.join(root, name)
+ base, ext = os.path.splitext(filename)
+ if ext != ".eml":
+ continue
+ metafile = base + ".meta"
+ if not os.path.exists(metafile):
+ print("Strange: %s has no metafile" % filename)
+ continue
+ metafile = open(metafile, "r")
+ metadata = json.load(metafile)
+ metafile.close()
+
+ process_message(database, filename, metadata)
+
+ database.close()
+
+def process_message(database, filename, metadata):
+ print("[*] Processing %s" % filename)
+ labels = filter_labels(metadata["labels"] + metadata["flags"])
+ database.begin_atomic()
+ message, status = database.add_message(filename, False)
+ if status == notmuch.STATUS.SUCCESS:
+ print(" [+] New message.")
+ elif status == notmuch.STATUS.DUPLICATE_MESSAGE_ID:
+ print(" [ ] Old message.")
+ tag_message(message, labels)
+ database.end_atomic()
+
+
+def tag_message(message, labels):
+ if set(labels) == set(message.get_tags()):
+ print(" [ ] No new tags.")
+ return
+ print(" [+] Adding tags.")
+ message.freeze()
+ message.remove_all_tags(False)
+ for tag in labels:
+ message.add_tag(tag, False)
+ message.thaw()
+
+def filter_labels(labels):
+ translation = { "\\Inbox": "inbox",
+ "\\Drafts": "draft",
+ "\\Sent": "sent",
+ "\\Spam": "spam",
+ "\\Starred": "flagged",
+ "\\Trash": "deleted",
+ "\\Answered": "replied",
+ "\\Flagged": "flagged",
+ "\\Draft": "draft",
+ "\\Deleted": "deleted",
+ "\\Seen": "!read!",
+ "\\Important": None, # I realize this is controversial, but I hate the priority inbox.
+ "\\Muted": None, # I also don't intend to use the muted idea going forward.
+ "Junk": "spam",
+ "NonJunk": None }
+ ret = set()
+ for label in labels:
+ if label in translation:
+ if translation[label] is None:
+ continue
+ ret.add(translation[label])
+ else:
+ ret.add(label)
+ if "!read!" in ret:
+ ret.remove("!read!")
+ else:
+ ret.add("unread")
+ if "" in ret:
+ ret.remove("")
+ return ret
+
+if __name__ == '__main__':
+ try:
+ main()
+ except KeyboardInterrupt:
+ sys.exit(1)