-
Notifications
You must be signed in to change notification settings - Fork 0
/
pop3bot.py
115 lines (86 loc) · 3.13 KB
/
pop3bot.py
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
import poplib
import email.parser
import config
import logging
import gerrit_rest
# monkey patch max line length for poplib
# as gmail sometimes sends > 2048 char lines
poplib._MAXLINE = 1024 * 1024
logger = logging.getLogger('pop3bot')
def mkmailbox(debug=0):
username = config.username
password = config.password
mailbox = poplib.POP3_SSL(config.pophost, '995')
mailbox.set_debuglevel(debug)
mailbox.user(username)
mailbox.pass_(password)
return mailbox
def mail_generator(mailbox):
""" RETRieves the contents of mails, yields those
and DELEtes them before the next mail is RETRieved """
nmails, octets = mailbox.stat()
for i in range(1, nmails+1):
# use TOP rather than REPR to stop gmail from hiding/deleting emails
# without explicit DELE
yield "\n".join(
[x.decode('utf-8', 'replace') for x in mailbox.top(i, 1000)[1]]
)
mailbox.dele(i)
def message_generator(mailbox):
p = email.parser.Parser()
for mail in mail_generator(mailbox):
mail = p.parsestr(mail)
payload = mail.get_payload(decode=True)
if not payload:
logger.debug("email from %s does not have payload" % mail['From'])
continue
yield mail, payload.decode('utf-8', 'replace')
def get_gerrit_data_from_contents(contents):
for line in contents.split('\n'):
if ': ' in line:
key, value = line.split(': ', 1)
if key.startswith('Gerrit-') or key in ['Bug', 'Task', 'Closes']:
yield key, value.rstrip()
def gerritmail_generator(mailbox):
for message, contents in message_generator(mailbox):
if 'gerrit@wikimedia.org' not in message.get('From', ''):
logger.debug(
'Skipping message from %s' % message.get('From', '???')
)
continue
gerrit_data = dict(
(k, v) for (k, v) in message.items()
if k.startswith('X-Gerrit')
)
gerrit_data.update(dict(get_gerrit_data_from_contents(contents)))
if gerrit_data:
yield gerrit_data
g = gerrit_rest.GerritREST('https://gerrit.wikimedia.org/r')
def get_changeset(changeid, o=['CURRENT_REVISION', 'CURRENT_FILES']):
matchingchanges = g.changes(changeid, n=1, o=o)
if matchingchanges:
return matchingchanges[0]
else:
return None
if __name__ == "__main__":
mailbox = mkmailbox(0)
nmails, octets = mailbox.stat()
print("%i e-mails to process (%i kB)" % (nmails, octets/1024))
for m in gerritmail_generator(mailbox):
print(repr(m))
break
"""
if __name__ == "__main__":
mailbox = mkmailbox(0)
nmails, octets = mailbox.stat()
from add_reviewer import ReviewerFactory, add_reviewers
RF = ReviewerFactory()
print("%i e-mails to process (%i kB)" % (nmails, octets/1024))
try:
for j,changeset in enumerate(new_changeset_generator(mailbox)):
reviewers = get_reviewers_for_changeset(changeset)
add_reviewers(changeset['current_revision'], reviewers)
finally:
# flush succesfully processed emails
mailbox.quit()
"""