summaryrefslogtreecommitdiffstats
path: root/gmvault-notmuch.py
blob: 1a9cce456e1452d5b2c0853a513f28ae5b2fe34f (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
#!/usr/bin/env python2

# (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
import sys
from progressbar import *

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()

	print("Counting emails...")
	total = 0
	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):
				continue
			total += 1
	
	progress = create_progressbar("Scanning messages", total)
	progress.start()
	i = 0
	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):
				continue
			metafile = open(metafile, "r")
			metadata = json.load(metafile)
			metafile.close()
			process_message(database, filename, metadata)
			i += 1
			try:
				progress.update(i)
			except:
				pass #Files were added since we started counting
	progress.finish()

	database.close()

def process_message(database, filename, metadata):
	labels = filter_labels(metadata["labels"] + metadata["flags"])
	message = database.find_message_by_filename(filename)
	if message is not None:
		if set(labels) == set(message.get_tags()):
			return
		database.begin_atomic()
	else:
		database.begin_atomic()
		message, status = database.add_message(filename, False)
		
	tag_message(message, labels)
	database.end_atomic()

def tag_message(message, labels):
	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

def create_progressbar(text, total):
	return ProgressBar(maxval=total, widgets=[text + ": ", SimpleProgress(), Bar(), Percentage(), " ", ETA(), " ", FileTransferSpeed(unit="emails")])

if __name__ == '__main__':
	try:
		main()
	except KeyboardInterrupt:
		print("")
		sys.exit(1)