diff options
author | Jason A. Donenfeld <Jason@zx2c4.com> | 2013-09-05 17:40:58 +0200 |
---|---|---|
committer | Jason A. Donenfeld <Jason@zx2c4.com> | 2013-09-05 17:40:58 +0200 |
commit | ed8ee4383288e5781fc16ca7c4b48b21114a8a53 (patch) | |
tree | 2c7bb48b692469849573b39ce74cd0d93c87aada | |
parent | Remember to fsync in case of power failure. (diff) | |
download | gmail-notmuch-ed8ee4383288e5781fc16ca7c4b48b21114a8a53.tar.xz gmail-notmuch-ed8ee4383288e5781fc16ca7c4b48b21114a8a53.zip |
Support importing from gmvault.
-rwxr-xr-x | gmvault-notmuch.py | 103 |
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) |