-
Notifications
You must be signed in to change notification settings - Fork 2
/
bznag.py
executable file
·210 lines (172 loc) · 7.88 KB
/
bznag.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
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
#!/usr/bin/env python
#
# Author: Mike Hoye
# Email: mhoye@mozilla.com
# License: MPL (current)
import smtplib
import json
import urllib2
import sys
import re
import logging, logging.handlers
import random
import pprint
from datetime import date, timedelta
from os import mkdir
from bugzilla.agents import BMOAgent
from bugzilla.utils import get_credentials
from email.mime.text import MIMEText
def main():
pp = pprint.PrettyPrinter(indent=4)
fmt = logging.Formatter(fmt='%(asctime)s - %(levelname)s - %(message)s',
datefmt="%Y-%m-%d %H:%M:%S %Z")
if "--quiet" not in sys.argv:
sh = logging.StreamHandler()
sh.setFormatter(fmt)
sh.setLevel(logging.DEBUG)
logging.root.addHandler(sh)
rfh = logging.handlers.RotatingFileHandler("/var/log/bznag.log",
backupCount=10)
rfh.setFormatter(fmt)
rfh.setLevel(logging.DEBUG)
logging.root.addHandler(rfh)
logging.root.setLevel(logging.DEBUG)
# cfg should be safe to load/handle
config = json.load(open("/etc/bznag.cfg"))
recipients = json.load(open("/var/local/bznag/bznag-participants.cfg"))
alerts = findbugs(config, recipients)
sendSLAMail(alerts, recipients, config)
# Debugging
#pp.pprint(alerts)
#pp.pprint(recipients)
#pp.pprint(config)
for derp in alerts.keys():
pp.pprint(alerts[derp]['stale'])
def findbugs(cfg,recs):
server = cfg["server"].encode("utf8")
owner = cfg["owner"].encode("utf8")
user = cfg["user"]
password = cfg["password"]
try:
bzagent = BMOAgent(user,password)
logging.info("Connected to " + str(server) )
except:
logging.info("Failed to connect to " + str(server))
exit(-1)
notif = dict() # key = intended recipient, value = list of bugs
for ppl in recs.keys():
buglist = list()
# For each person, get the bugs have aged untouched to their level.
# I'm making a design decision here to make this range window only
# 2 days long - bugs older than that are being actively ignored.
sla = recs[ppl]
print str(ppl) + " " + str(sla)
inc = 1
# If it's a Monday, scan the last three days. Otherwise only the last one.
# The cron job that kicks off this clownshow should only be running mon/fri.
if (date.today().weekday() == 0):
inc = 3
week_inc = inc + 5
date_to = str(date.isoformat(date.today() - timedelta(sla + 1) )).encode("utf8")
date_from = str(date.isoformat(date.today() - timedelta(sla + inc + 1) )).encode("utf8")
stale_time = str(date.isoformat(date.today() - timedelta(sla + week_inc + inc + 1) )).encode("utf8")
print str("Stale date:") + str(stale_time)
# Not proud of this next part. Store this properly in a file somewhere, you donkus.
untriaged_bugs = list()
untriaged_params= {
'firefox_untriaged': {
'changed_field':'[Bug creation]',
'changed_after':date_from,
'changed_before':date_to,
'product': 'Firefox',
'component':'Untriaged'},
'core_untriaged': {
'changed_field':'[Bug creation]',
'changed_after':date_from,
'changed_before':date_to,
'product': 'Toolkit',
'component':'Untriaged'},
'toolkit_untriaged': {
'changed_field':'[Bug creation]',
'changed_after':date_from,
'changed_before':date_to,
'product': 'Core',
'component':'Untriaged' }
}
bugs = set()
for options in untriaged_params.values():
for b in bzagent.get_bug_list(options):
if str(b.creation_time) == str(b.last_change_time):
bugs.add(b)
print "Untriaged:" + str(b.id) + " - " + str(b.creation_time) + " - " + str(b.last_change_time)
untriaged_bugs = list(bugs) #add and dedupe
stale_bugs = list()
stale_params = {
"firefox_stale_bug": {
"product": "Core",
"bug_status": "UNCONFIRMED,NEW,ASSIGNED",
"component":"Untriaged" },
"core_stale_bug": {
"bug_status": "UNCONFIRMED,NEW,ASSIGNED",
"product": "Core",
"component":"Untriaged" },
"toolkit_stale_bug": {
"product": "Core",
"bug_status": "UNCONFIRMED,NEW,ASSIGNED",
"component":"Untriaged" }
}
bugs = set()
# juuuust subtly different.
for options in stale_params.values():
for b in bzagent.get_bug_list(options):
if str(b.creation_time) == stale_time:
bugs.add(b)
print "Stale:" + str(b.id) + " - " + str(b.last_change_time)
stale_bugs = list(bugs) # (this is so sloppy)
notif[ppl] = { "untriaged": untriaged_bugs, "stale": stale_bugs }
return ( notif )
def sendSLAMail(mailout,sla,cfg):
msg = dict()
# Ok, let's email some bugs.
mailoutlog = ""
for recipient in mailout.keys():
if (mailout[recipient]['untriaged'] or mailout[recipient]['stale']):
mailoutlog = recipient.encode("utf8")
content = "This is a message from Mozilla's NagBot.\n\n"
if mailout[recipient]['untriaged']:
content += "You have asked receive notifications when Untriaged bugs have gone " + str(sla[recipient]) + " days without being acted upon.\n"
content += "The following bugs have met that criteria:\n\n"
for boog in mailout[recipient]['untriaged']:
mailoutlog += " " + str(boog.id).encode("utf-8")
content += '''Bug %s - http://bugzilla.mozilla.org/%s - %s\n''' \
% ( str(boog.id).encode("utf-8"), str(boog.id).encode("utf-8"), str(boog.summary).encode("utf-8") )
if mailout[recipient]['stale']:
content += "\nThe following bugs are still in an Untriaged component, and have not been acted on in " + str(sla[recipient] + 5 ) + " days.\n"
content += "These bugs are getting stale:\n\n"
for boog in mailout[recipient]['stale']:
mailoutlog += " " + str(boog.id).encode("utf-8")
content += '''Bug %s - http://bugzilla.mozilla.org/%s - %s\n''' \
% ( str(boog.id).encode("utf-8"), str(boog.id).encode("utf-8"), str(boog.summary).encode("utf-8") )
content += "\n\nPlease examine these bugs at your earliest convenience, and either move them\n" +\
"to the correct category or assign them to or needinfo a developer.\n\n" +\
"If you have any questions about this notification service, please contact Mike Hoye."
smtp = cfg["smtp_server"].encode("utf8")
sender = cfg["smtp_from"].encode("utf8")
server = smtplib.SMTP(smtp, 587)
#server.set_debuglevel(True)
#server.connect(smtp)
server.ehlo()
server.starttls()
server.login(cfg["smtp_user"], cfg["smtp_password"].encode("utf8"))
#server.login(sender, cfg["smtp_pass"].encode("utf8"))
msg = MIMEText(str(content).encode("utf8"))
msg["Subject"] = str("NagBot: Untriaged bugs as of %s" % (date.today()) ).encode("utf8")
msg["From"] = cfg["smtp_from"].encode("utf8")
msg["To"] = recipient.encode("utf8")
msg["BCC"] = str("mhoye@mozilla.com").encode("utf8")
server.sendmail(sender, recipient.encode("utf8") , msg.as_string())
server.quit()
logging.info(mailoutlog)
#print msg.as_string()
if __name__ == "__main__":
main()