* Add component as first column

* Remove useless code

* Remove debug stuff

* Fix test_email_no_assignee
This commit is contained in:
calixteman 2019-02-12 11:48:32 +01:00 коммит произвёл Sylvestre Ledru
Родитель 8e42d0a421
Коммит 46816d6e47
64 изменённых файлов: 490 добавлений и 536 удалений

Просмотреть файл

@ -20,12 +20,9 @@ class BzCleaner(object):
def __init__(self):
super(BzCleaner, self).__init__()
self.has_autofix = False
self.last_comment = {}
self.prod_comp = {}
self.no_manager = set()
self.assignees = {}
self.needinfos = {}
self.auto_needinfo = {}
self.has_flags = False
self.test_mode = utils.get_config('common', 'test', False)
def description(self):
@ -74,27 +71,6 @@ class BzCleaner(object):
def add_no_manager(self, bugid):
self.no_manager.add(str(bugid))
def add_assignee(self, bugid, name):
if name == 'Nobody; OK to take it and work on it':
name = 'nobody'
self.assignees[str(bugid)] = name
def add_needinfo(self, bugid, name):
bugid = str(bugid)
if bugid in self.needinfos:
self.needinfos[bugid].add(name)
else:
self.needinfos[bugid] = set([name])
def add_product_component(self, bugid, prod, comp):
self.prod_comp[str(bugid)] = {'p': prod, 'c': comp}
def get_needinfo_for_template(self):
res = {}
for bugid, ni in self.needinfos.items():
res[bugid] = list(sorted(ni))
return res
def has_assignee(self):
return False
@ -113,6 +89,12 @@ class BzCleaner(object):
def ignore_meta(self):
return False
def columns(self):
"""The fields to get for the columns in email report"""
if self.ignore_bug_summary():
return ['id']
return ['id', 'summary']
def get_dates(self, date):
"""Get the dates for the bugzilla query (changedafter and changedbefore fields)"""
date = lmdutils.get_date_ymd(date)
@ -139,7 +121,7 @@ class BzCleaner(object):
def get_data(self):
"""Get the data structure to use in the bughandler"""
return []
return {}
def get_summary(self, bug):
return '...' if bug['groups'] else bug['summary']
@ -153,9 +135,9 @@ class BzCleaner(object):
def get_product_component(self):
return self.prod_comp
def handle_bug(self, bug):
def handle_bug(self, bug, data):
"""Implement this function to get all the bugs from the query"""
pass
return bug
def get_auto_ni_blacklist(self):
return set()
@ -180,36 +162,40 @@ class BzCleaner(object):
def bughandler(self, bug, data):
"""bug handler for the Bugzilla query"""
self.handle_bug(bug)
if self.handle_bug(bug, data) is None:
return
if isinstance(self, Nag):
bug = self.set_people_to_nag(bug)
if not bug:
return
bugid = str(bug['id'])
res = {'id': bugid}
auto_ni = self.get_mail_to_auto_ni(bug)
self.add_auto_ni(bug['id'], auto_ni)
self.add_auto_ni(bugid, auto_ni)
if self.ignore_bug_summary():
data.append(bug['id'])
else:
data.append((bug['id'], self.get_summary(bug)))
if not self.ignore_bug_summary():
res['summary'] = self.get_summary(bug)
if self.has_assignee():
real = bug['assigned_to_detail']['real_name']
bugid = str(bug['id'])
self.add_assignee(bugid, real)
if utils.is_no_assignee(bug['assigned_to']):
real = 'nobody'
res['assignee'] = real
if self.has_needinfo():
bugid = str(bug['id'])
s = set()
for flag in utils.get_needinfo(bug):
self.add_needinfo(bugid, flag['requestee'])
s.add(flag['requestee'])
res['needinfos'] = sorted(s)
if self.has_product_component():
prod = bug['product']
comp = bug['component']
bugid = str(bug['id'])
self.add_product_component(bugid, prod, comp)
for k in ['product', 'component']:
res[k] = bug[k]
if isinstance(self, Nag):
bug = self.set_people_to_nag(bug, res)
if not bug:
return
data[bugid] = res
def amend_bzparams(self, params, bug_ids):
"""Amend the Bugzilla params"""
@ -262,9 +248,11 @@ class BzCleaner(object):
if self.has_default_products():
params['product'] = utils.get_config('common', 'products')
self.has_flags = 'flags' in params.get('include_fields', [])
def get_bugs(self, date='today', bug_ids=[]):
"""Get the bugs"""
bugids = self.get_data()
bugs = self.get_data()
params = self.get_bz_params(date)
self.amend_bzparams(params, bug_ids)
self.query_url = utils.get_bz_search_url(params)
@ -275,66 +263,52 @@ class BzCleaner(object):
Bugzilla(
params,
bughandler=self.bughandler,
bugdata=bugids,
bugdata=bugs,
timeout=utils.get_config(self.name(), 'bz_query_timeout'),
).get_data().wait()
self.get_comments(bugids)
return (
sorted(
bugids, reverse=utils.get_config(self.name(), 'reverse_order', False)
)
if isinstance(bugids, list)
else bugids
)
self.get_comments(bugs)
def get_comment_data(self):
return None
return bugs # TODO: attention au reverse_order (config/tools.json)
def commenthandler(self, bug, bugid, data):
return
def _commenthandler(self, *args):
if len(args) == 2:
bug, bugid = args
data = None
else:
bug, bugid, data = args
def _commenthandler(self, bug, bugid, data):
comments = bug['comments']
bugid = str(bugid)
if self.has_last_comment_time():
if comments:
# get the timestamp of the last comment
today = pytz.utc.localize(datetime.utcnow())
dt = dateutil.parser.parse(comments[-1]['time'])
self.last_comment[bugid] = humanize.naturaldelta(today - dt)
data[bugid]['last_comment'] = humanize.naturaldelta(today - dt)
else:
self.last_comment[bugid] = ''
data[bugid]['last_comment'] = ''
if data is not None:
self.commenthandler(bug, bugid, data)
self.commenthandler(bug, bugid, data)
def get_comments(self, bugids):
def get_comments(self, bugs):
"""Get the bugs comments"""
data = self.get_comment_data()
if data is not None or self.has_last_comment_time():
bugids = self.get_list_bugs(bugids)
if self.has_last_comment_time():
bugids = self.get_list_bugs(bugs)
Bugzilla(
bugids=bugids, commenthandler=self._commenthandler, commentdata=data
bugids=bugids, commenthandler=self._commenthandler, commentdata=bugs
).get_data().wait()
return bugs
def has_last_comment_time(self):
return False
def get_last_comment_time(self):
return self.last_comment
def get_list_bugs(self, bugs):
if self.ignore_bug_summary():
return list(map(str, bugs))
return [str(x) for x, _ in bugs]
return [x['id'] for x in bugs.values()]
def set_needinfo(self, bugs, dryrun):
def has_bot_set_ni(self, bug):
if not self.has_flags:
raise Exception
return utils.has_bot_set_ni(bug)
def set_needinfo(self, dryrun):
if not self.auto_needinfo:
return
@ -377,7 +351,7 @@ class BzCleaner(object):
def autofix(self, bugs, dryrun):
"""Autofix the bugs according to what is returned by get_autofix_change"""
self.set_needinfo(bugs, dryrun)
self.set_needinfo(dryrun)
change = self.get_autofix_change()
if change:
@ -405,27 +379,27 @@ class BzCleaner(object):
return bugs
def organize(self, bugs):
return utils.organize(bugs, self.columns())
def get_email(self, bztoken, date, dryrun, bug_ids=[]):
"""Get title and body for the email"""
Bugzilla.TOKEN = bztoken
bugids = self.get_bugs(date=date, bug_ids=bug_ids)
bugids = self.autofix(bugids, dryrun)
if bugids:
bugs = self.get_bugs(date=date, bug_ids=bug_ids)
bugs = self.autofix(bugs, dryrun)
if bugs:
bugs = self.organize(bugs)
extra = self.get_extra_for_template()
env = Environment(loader=FileSystemLoader('templates'))
template = env.get_template(self.template())
message = template.render(
date=date,
bugids=bugids,
data=bugs,
extra=extra,
str=str,
enumerate=enumerate,
plural=utils.plural,
no_manager=self.no_manager,
last_comment=self.last_comment,
prod_comp=self.prod_comp,
assignees=self.assignees,
needinfos=self.get_needinfo_for_template(),
)
common = env.get_template('common.html')
body = common.render(
@ -461,13 +435,7 @@ class BzCleaner(object):
)
if isinstance(self, Nag):
self.send_mails(
title,
self.last_comment,
self.assignees,
self.prod_comp,
dryrun=dryrun,
)
self.send_mails(title, dryrun=dryrun)
else:
name = self.name().upper()
if date:

Просмотреть файл

@ -45,7 +45,7 @@ class Nag(object):
def get_people(self):
return self.people
def set_people_to_nag(self, bug):
def set_people_to_nag(self, bug, buginfo):
return bug
def escalate(self, person, priority, **kwargs):
@ -79,6 +79,9 @@ class Nag(object):
def get_extra_for_nag_template(self):
return {}
def columns_nag(self):
return None
def _is_in_list(self, mail, _list):
for manager in _list:
if self.people.is_under(mail, manager):
@ -117,10 +120,13 @@ class Nag(object):
return url
def send_mails(self, title, last_comment, assignees, prod_comp, dryrun=False):
self.last_comment_nag = last_comment
self.assignees_nag = assignees
self.prod_comp_nag = prod_comp
def organize_nag(self, bugs):
columns = self.columns_nag()
if columns is None:
columns = self.columns()
return utils.organize(bugs, columns)
def send_mails(self, title, dryrun=False):
if not self.send_nag_mail:
return
@ -176,14 +182,15 @@ class Nag(object):
extra=extra,
plural=utils.plural,
enumerate=enumerate,
data=data,
assignees=self.assignees_nag,
last_comment=self.last_comment_nag,
prod_comp=self.prod_comp_nag,
query_url=query_url,
data=self.organize_nag(data),
nag=True,
query_url_nag=query_url,
)
m = {'manager': manager, 'to': set(info.keys()), 'body': body}
mails.append(m)
return mails
def reorganize_to_bag(self, data):
return data

Просмотреть файл

@ -31,10 +31,11 @@ class MetaSummaryMissing(BzCleaner):
def has_individual_autofix(self):
return True
def handle_bug(self, bug):
def handle_bug(self, bug, data):
bugid = str(bug['id'])
summary = bug['summary']
self.autofix_meta[bugid] = {'summary': '[meta] ' + summary}
return bug
def get_bz_params(self, date):
days_lookup = self.get_config('days_lookup', default=180)

Просмотреть файл

@ -36,12 +36,12 @@ class MissingBetaStatus(BzCleaner):
def ignore_bug_summary(self):
return False
def handle_bug(self, bug):
def handle_bug(self, bug, data):
bugid = str(bug['id'])
central = bug[self.status_central]
release = bug[self.status_release]
if central == release and release != "verified":
if central == release and release != 'verified':
self.autofix_status[bugid] = {self.status_beta: central}
else:
# if the two status are different, we don't know what to set
@ -49,6 +49,8 @@ class MissingBetaStatus(BzCleaner):
# per say if this is verified
self.autofix_status[bugid] = {self.status_beta: '?'}
return bug
def get_bz_params(self, date):
versions = get_current_versions()
self.status_central = utils.get_flag(versions['central'], 'status', 'central')

Просмотреть файл

@ -49,15 +49,20 @@ class NiFromManager(BzCleaner, Nag):
def has_needinfo(self):
return True
def columns(self):
return ['id', 'summary', 'needinfos', 'last_comment']
def columns_nag(self):
return ['id', 'summary', 'to', 'from', 'last_comment']
def get_priority(self, bug):
return 'normal'
def set_people_to_nag(self, bug):
def set_people_to_nag(self, bug, buginfo):
priority = self.get_priority(bug)
if not self.filter_bug(priority):
return None
bugid = str(bug['id'])
has_manager = False
accepted = False
for flag in bug['flags']:
@ -69,17 +74,13 @@ class NiFromManager(BzCleaner, Nag):
requestee = flag['requestee']
if self.is_under(requestee):
accepted = True
bug_data = {
'id': bugid,
'summary': self.get_summary(bug),
'to': requestee,
'from': self.get_people().get_moz_name(flag['setter']),
}
if self.add(requestee, bug_data):
buginfo['to'] = requestee
buginfo['from'] = self.get_people().get_moz_name(flag['setter'])
if self.add(requestee, buginfo):
has_manager = True
if accepted and not has_manager:
self.add_no_manager(bugid)
self.add_no_manager(buginfo['id'])
return bug if accepted else None

Просмотреть файл

@ -33,6 +33,9 @@ class NoAssignee(BzCleaner):
def subject(self):
return 'Bugs with no assignees'
def columns(self):
return ['id', 'email']
def get_bz_params(self, date):
start_date, end_date = self.get_dates(date)
reporters = self.get_config('reporter_exception', default=[])
@ -76,7 +79,7 @@ class NoAssignee(BzCleaner):
return False
def get_revisions(self, bugids):
def get_revisions(self, bugs):
"""Get the revisions from the hg.m.o urls in the bug comments"""
nightly_pats = Bugzilla.get_landing_patterns(channels=['nightly'])
@ -97,8 +100,9 @@ class NoAssignee(BzCleaner):
if self.is_patch(attachment):
data[bugid]['creators'].add(attachment['creator'])
bugids = list(bugs.keys())
revisions = {
str(bugid): {'revisions': [], 'creators': set(), 'commenters': {}}
bugid: {'revisions': [], 'creators': set(), 'commenters': {}}
for bugid in bugids
}
Bugzilla(
@ -251,16 +255,19 @@ class NoAssignee(BzCleaner):
print('Auto assign {}: {}'.format(bugid, email))
else:
Bugzilla([bugid]).put({'assigned_to': email})
return self.hgdata
return bugs
def get_bugs(self, date='today', bug_ids=[]):
bugids = super(NoAssignee, self).get_bugs(date=date, bug_ids=bug_ids)
bzdata = self.get_revisions(bugids)
bugs = super(NoAssignee, self).get_bugs(date=date, bug_ids=bug_ids)
bzdata = self.get_revisions(bugs)
user_info = self.get_user_info(bzdata)
bugids = self.filter_from_hg(bzdata, user_info)
_bugs = self.filter_from_hg(bzdata, user_info)
bugs = {}
for bugid, email in _bugs.items():
bugs[bugid] = {'id': bugid, 'email': email}
return bugids
return bugs
if __name__ == '__main__':

Просмотреть файл

@ -136,12 +136,13 @@ class NoCrashes(BzCleaner):
def get_bugs_without_crashes(self, data):
# data['ids'] contains bugid => set(...signatures...)
# data['signatures'] is a set of signatures with no crashes
res = []
res = {}
signatures = data['signatures']
for bugid, bug_sgns in data['ids'].items():
if bug_sgns < signatures:
# all the signatures in the bug have no crashes
res.append(bugid)
bugid = str(bugid)
res[bugid] = {'id': bugid}
return res
def get_autofix_change(self):
@ -163,9 +164,8 @@ class NoCrashes(BzCleaner):
print('An error occurred when getting data from Socorro. Execution ended.')
sys.exit(1)
bugids = self.get_bugs_without_crashes(data)
return sorted(bugids)
bugs = self.get_bugs_without_crashes(data)
return bugs
if __name__ == '__main__':

Просмотреть файл

@ -54,6 +54,9 @@ class Regression(BzCleaner):
def all_include_fields(self):
return True
def columns(self):
return ['id', 'summary']
def get_bz_params(self, date):
start_date, end_date = self.get_dates(date)
resolution_blacklist = self.get_config('resolution_blacklist', default=[])
@ -116,8 +119,7 @@ class Regression(BzCleaner):
bugs[int(bug['id'])]['history'] = bug['history']
Bugzilla(
bugids=[bug_id for bug_id in bugs.keys()],
historyhandler=history_handler,
bugids=[bug_id for bug_id in bugs.keys()], historyhandler=history_handler
).get_data().wait()
def remove_using_history(self, bugs):
@ -145,7 +147,14 @@ class Regression(BzCleaner):
Bugzilla(
bugids=[bug_id for bug_id in bugs.keys()],
attachmenthandler=attachment_handler,
attachment_include_fields=['id', 'is_obsolete', 'flags', 'is_patch', 'creator', 'content_type'],
attachment_include_fields=[
'id',
'is_obsolete',
'flags',
'is_patch',
'creator',
'content_type',
],
).get_data().wait()
def get_bugs(self, date='today', bug_ids=[]):
@ -180,7 +189,10 @@ class Regression(BzCleaner):
# Attach summaries to bugs.
reg_bugids = [(n, all_bug_data['summaries'][n]) for n in reg_bugids]
return sorted(reg_bugids, reverse=True)
bugs = {}
for n in reg_bugids:
bugid = str(n)
bugs[bugid] = {'id': bugid, 'summary': all_bug_data['summaries'][n]}
if __name__ == '__main__':

Просмотреть файл

@ -47,15 +47,12 @@ class ReporterWithNI(BzCleaner):
return params
def bughandler(self, bug, data):
def handle_bug(self, bug, data):
creator = bug['creator']
for flag in bug['flags']:
if flag.get('name', '') != 'needinfo':
continue
if 'requestee' not in flag:
continue
if flag['requestee'] == creator:
super(ReporterWithNI, self).bughandler(bug, data)
for flag in utils.get_needinfo(bug):
if flag.get('requestee', '') == creator:
return bug
return None
if __name__ == '__main__':

Просмотреть файл

@ -52,28 +52,29 @@ class TrackedNeedinfo(BzCleaner, Nag):
return {'channel': self.channel, 'version': self.version}
def get_extra_for_nag_template(self):
return {
'channel': self.channel,
'version': self.version,
'needinfos': self.get_needinfo_for_template(),
'assignees': self.assignees,
}
return self.get_extra_for_template()
def set_people_to_nag(self, bug):
def columns(self):
return ['id', 'summary', 'needinfos', 'assignee', 'last_comment']
def columns_nag(self):
return ['id', 'summary', 'to', 'assignee', 'last_comment']
def set_people_to_nag(self, bug, buginfo):
priority = self.get_priority(bug)
if not self.filter_bug(priority):
return None
bugid = str(bug['id'])
has_manager = False
for flag in utils.get_needinfo(bug):
requestee = flag['requestee']
bug_data = {'id': bugid, 'summary': self.get_summary(bug), 'to': requestee}
if self.add(requestee, bug_data, priority=priority):
has_manager = True
requestee = flag.get('requestee', '')
if requestee:
buginfo['to'] = requestee
if self.add(requestee, buginfo, priority=priority):
has_manager = True
if not has_manager:
self.add_no_manager(bugid)
self.add_no_manager(buginfo['id'])
return bug

Просмотреть файл

@ -51,6 +51,9 @@ class Tracking(BzCleaner, Nag):
def has_default_products(self):
return False
def has_assignee(self):
return True
def get_extra_for_template(self):
return {
'channel': self.channel,
@ -61,24 +64,24 @@ class Tracking(BzCleaner, Nag):
def get_extra_for_nag_template(self):
return self.get_extra_for_template()
def set_people_to_nag(self, bug):
def columns(self):
return ['id', 'summary', 'assignee', 'last_comment']
def columns_nag(self):
return ['id', 'summary', 'To', 'last_comment']
def set_people_to_nag(self, bug, buginfo):
priority = self.get_priority(bug)
if not self.filter_bug(priority):
return None
assignee = bug['assigned_to']
bugid = str(bug['id'])
real = bug['assigned_to_detail']['real_name']
bug_data = {
'id': bugid,
'summary': self.get_summary(bug),
'to': assignee,
'To': real,
}
buginfo['to'] = assignee
buginfo['To'] = real
self.add_assignee(bugid, real)
if not self.add(assignee, bug_data, priority=priority):
self.add_no_manager(bugid)
if not self.add(assignee, buginfo, priority=priority):
self.add_no_manager(buginfo['id'])
return bug
@ -89,7 +92,7 @@ class Tracking(BzCleaner, Nag):
tracking_value = (
'+,blocking' if self.channel != 'esr' else self.versions['beta'] + '+'
)
fields = ['assigned_to', self.tracking]
fields = [self.tracking]
params = {
'include_fields': fields,
'f1': self.tracking,

Просмотреть файл

@ -23,7 +23,7 @@ class Unlanded(BzCleaner, Nag):
return 'unlanded.html'
def nag_template(self):
return 'unlanded_nag.html'
return self.template()
def subject(self):
return self.description()
@ -37,18 +37,21 @@ class Unlanded(BzCleaner, Nag):
def has_default_products(self):
return False
def set_people_to_nag(self, bug):
def has_assignee(self):
return True
def columns(self):
return ['id', 'summary', 'assignee', 'last_comment']
def set_people_to_nag(self, bug, buginfo):
priority = self.get_priority(bug)
if not self.filter_bug(priority):
return None
assignee = bug['assigned_to']
bugid = str(bug['id'])
real = bug['assigned_to_detail']['real_name']
bug_data = {'id': bugid, 'summary': self.get_summary(bug), 'to': assignee}
self.add_assignee(bugid, real)
if not self.add(assignee, bug_data):
self.add_no_manager(bugid)
buginfo['to'] = assignee
if not self.add(assignee, buginfo):
self.add_no_manager(buginfo['id'])
return bug
def get_bz_params(self, date):
@ -59,7 +62,7 @@ class Unlanded(BzCleaner, Nag):
bug_ids = utils.get_report_bugs(self.channel)
status = utils.get_flag(version, 'status', self.channel)
self.tracking = utils.get_flag(version, 'tracking', self.channel)
fields = ['assigned_to', self.tracking]
fields = [self.tracking]
params = {
'include_fields': fields,
'bug_id': ','.join(bug_ids),

Просмотреть файл

@ -36,7 +36,7 @@ class NoPriority(BzCleaner, Nag):
return 'workflow_no_priority_comment.txt'
def nag_template(self):
return 'workflow_no_priority_nag.html'
return self.template()
def subject(self):
return 'Bugs without a priority set'
@ -61,19 +61,22 @@ class NoPriority(BzCleaner, Nag):
def ignore_meta(self):
return True
def columns(self):
return ['component', 'id', 'summary']
def get_mail_to_auto_ni(self, bug):
if self.typ == 'second':
return None
# Avoid to ni everyday...
if utils.has_bot_set_ni(bug):
if self.has_bot_set_ni(bug):
return None
mail = bug['triage_owner']
nick = bug['triage_owner_detail']['nick']
return {'mail': mail, 'nickname': nick}
def set_people_to_nag(self, bug):
def set_people_to_nag(self, bug, buginfo):
if self.typ == 'first':
return bug
@ -83,10 +86,8 @@ class NoPriority(BzCleaner, Nag):
owner = bug['triage_owner']
self.add_triage_owner(owner, utils.get_config('workflow', 'components'))
bugid = str(bug['id'])
bug_data = {'id': bugid, 'summary': self.get_summary(bug)}
if not self.add(owner, bug_data, priority=priority):
self.add_no_manager(bugid)
if not self.add(owner, buginfo, priority=priority):
self.add_no_manager(buginfo['id'])
return bug
def get_bz_params(self, date):

Просмотреть файл

@ -27,7 +27,7 @@ class P1NoActivity(BzCleaner, Nag):
return 'workflow_p1_no_activity.html'
def nag_template(self):
return 'workflow_p1_no_activity_nag.html'
return self.template()
def subject(self):
return 'P1 bugs and no activity for {} days'.format(self.ndays)
@ -53,17 +53,18 @@ class P1NoActivity(BzCleaner, Nag):
def has_product_component(self):
return True
def set_people_to_nag(self, bug):
def columns(self):
return ['component', 'id', 'summary', 'last_comment', 'assignee']
def set_people_to_nag(self, bug, buginfo):
priority = 'high'
if not self.filter_bug(priority):
return None
bugid = str(bug['id'])
owner = bug['triage_owner']
assignee = bug['assigned_to']
bug_data = {'id': bugid, 'summary': self.get_summary(bug)}
if not self.add(assignee, bug_data, priority=priority, triage_owner=owner):
self.add_no_manager(bugid)
if not self.add(assignee, buginfo, priority=priority, triage_owner=owner):
self.add_no_manager(buginfo['id'])
return bug

Просмотреть файл

@ -27,7 +27,7 @@ class P1NoAssignee(BzCleaner, Nag):
return 'workflow_p1_no_assignee.html'
def nag_template(self):
return 'workflow_p1_no_assignee_nag.html'
return self.template()
def needinfo_template(self):
return 'workflow_p1_no_assignee_comment.txt'
@ -56,26 +56,27 @@ class P1NoAssignee(BzCleaner, Nag):
def has_product_component(self):
return True
def columns(self):
return ['component', 'id', 'summary', 'last_comment']
def get_mail_to_auto_ni(self, bug):
# Avoid to ni everyday...
if utils.has_bot_set_ni(bug):
if self.has_bot_set_ni(bug):
return None
mail = bug['triage_owner']
nick = bug['triage_owner_detail']['nick']
return {'mail': mail, 'nickname': nick}
def set_people_to_nag(self, bug):
def set_people_to_nag(self, bug, buginfo):
priority = 'high'
if not self.filter_bug(priority):
return None
bugid = str(bug['id'])
owner = bug['triage_owner']
self.add_triage_owner(owner, utils.get_config('workflow', 'components'))
bug_data = {'id': bugid, 'summary': self.get_summary(bug)}
if not self.add(owner, bug_data, priority=priority):
self.add_no_manager(bugid)
if not self.add(owner, buginfo, priority=priority):
self.add_no_manager(buginfo['id'])
return bug

Просмотреть файл

@ -39,6 +39,9 @@ class P2MergeDay(BzCleaner):
def ignore_meta(self):
return True
def columns(self):
return ['component', 'id', 'summary']
def get_bz_params(self, date):
comps = utils.get_config('workflow', 'components')
params = {

Просмотреть файл

@ -30,7 +30,7 @@ class P2NoActivity(BzCleaner, Nag):
return 'workflow_p2_no_activity.html'
def nag_template(self):
return 'workflow_p2_no_activity_nag.html'
return self.template()
def subject(self):
return 'P2 bugs without activity for {} months'.format(self.nmonths)
@ -53,17 +53,18 @@ class P2NoActivity(BzCleaner, Nag):
def has_product_component(self):
return True
def set_people_to_nag(self, bug):
def columns(self):
return ['component', 'id', 'summary', 'last_comment']
def set_people_to_nag(self, bug, buginfo):
priority = 'default'
if not self.filter_bug(priority):
return None
owner = bug['triage_owner']
self.add_triage_owner(owner, utils.get_config('workflow', 'components'))
bugid = str(bug['id'])
bug_data = {'id': bugid, 'summary': self.get_summary(bug)}
if not self.add(owner, bug_data, priority=priority):
self.add_no_manager(bugid)
if not self.add(owner, buginfo, priority=priority):
self.add_no_manager(buginfo['id'])
return bug
def get_bz_params(self, date):

Просмотреть файл

@ -39,6 +39,9 @@ class P3P4P5(BzCleaner):
def has_product_component(self):
return True
def columns(self):
return ['component', 'id', 'summary']
def get_bz_params(self, date):
date = lmdutils.get_date_ymd(date)
start_date = date - relativedelta(months=self.nmonths)

Просмотреть файл

@ -8,8 +8,6 @@ from auto_nag.scripts.no_assignee import NoAssignee
class TestEmailNoAssignee(unittest.TestCase):
def test_nobody(self):
bugids = NoAssignee().get_bugs('2011-01-01', bug_ids=[229367, 400095])
assert bugids == {'229367': 'smontagu@smontagu.org'}
assert bugids == {'229367': {'id': '229367', 'email': 'smontagu@smontagu.org'}}

Просмотреть файл

@ -148,12 +148,8 @@ def get_bz_search_url(params):
def has_bot_set_ni(bug):
bot = get_config('common', 'bot_bz_mail')
for flag in bug.get('flags', []):
if (
flag.get('name', '') == 'needinfo'
and flag['status'] == '?'
and flag['setter'] in bot
):
for flag in get_needinfo(bug):
if flag['setter'] in bot:
return True
return False
@ -186,3 +182,28 @@ def get_triage_owners():
else:
_TRIAGE_OWNERS[owner].append(comp_name)
return _TRIAGE_OWNERS
def organize(bugs, columns):
if isinstance(bugs, dict):
# we suppose that the values are the bugdata dict
bugs = bugs.values()
def identity(x):
return x
def bugid_key(x):
return -int(x)
lambdas = {'id': bugid_key}
def mykey(p):
return tuple(lambdas.get(c, identity)(x) for x, c in zip(p, columns))
if len(columns) >= 2:
res = [tuple(info[c] for c in columns) for info in bugs]
else:
c = columns[0]
res = [info[c] for info in bugs]
return sorted(res, key=mykey)

Просмотреть файл

@ -1,4 +1,4 @@
<p>The following {{ plural('bug is', bugids, pword='bugs are') }} assigned but status is UNCONFIRMED:
<p>The following {{ plural('bug is', data, pword='bugs are') }} assigned but status is UNCONFIRMED:
<table border="1">
<thead>
<tr>
@ -6,7 +6,7 @@
</tr>
</thead>
<tbody>
{% for i, (bugid, summary) in enumerate(bugids) -%}
{% for i, (bugid, summary) in enumerate(data) -%}
<tr {% if i % 2 == 0 %}bgcolor="#E0E0E0"{% endif -%}>
<td>
<a href="https://bugzilla.mozilla.org/show_bug.cgi?id={{ bugid }}">{{ bugid }}</a>

Просмотреть файл

@ -1,6 +1,6 @@
<p>The following {{ plural('bug has', bugids, pword='bugs have') }} both regression and feature as keywords:
<p>The following {{ plural('bug has', data, pword='bugs have') }} both regression and feature as keywords:
<ul>
{% for bugid in bugids -%}
{% for bugid in data -%}
<li><a href="https://bugzilla.mozilla.org/{{ bugid }}">{{ bugid }}</a></li>
{% endfor -%}
</ul>

Просмотреть файл

@ -1,6 +1,6 @@
<p>The following {{ plural('bug has', bugids, pword='bugs have') }} has_regression_range=yes but the regression keyword hasn't been set:
<p>The following {{ plural('bug has', data, pword='bugs have') }} has_regression_range=yes but the regression keyword hasn't been set:
<ul>
{% for bugid in bugids -%}
{% for bugid in data -%}
<li><a href="https://bugzilla.mozilla.org/{{ bugid }}">{{ bugid }}</a></li>
{% endfor -%}
</ul>

Просмотреть файл

@ -1,6 +1,6 @@
<p>The following {{ plural('bug has', bugids, pword='bugs have') }} been closed although the leave-open keyword is there:
<p>The following {{ plural('bug has', data, pword='bugs have') }} been closed although the leave-open keyword is there:
<ul>
{% for bugid in bugids -%}
{% for bugid in data -%}
<li><a href="https://bugzilla.mozilla.org/{{ bugid }}">{{ bugid }}</a></li>
{% endfor -%}
</ul>

Просмотреть файл

@ -1,4 +1,4 @@
<p>The following {{ plural('bug has', bugids, pword='bugs have') }} leave-open keyword and no activity for the last {{ extra['nmonths'] }} {{ plural('month', bugids) }}:
<p>The following {{ plural('bug has', data, pword='bugs have') }} leave-open keyword and no activity for the last {{ extra['nmonths'] }} {{ plural('month', data) }}:
<table border="1">
<thead>
<tr>
@ -6,7 +6,7 @@
</tr>
</thead>
<tbody>
{% for i, (bugid, summary) in enumerate(bugids) -%}
{% for i, (bugid, summary) in enumerate(data) -%}
<tr {% if i % 2 == 0 %}bgcolor="#E0E0E0"{% endif -%}>
<td>
<a href="https://bugzilla.mozilla.org/show_bug.cgi?id={{ bugid }}">{{ bugid }}</a>

Просмотреть файл

@ -1,4 +1,4 @@
<p>The following {{ plural('bug has', bugids, pword='bugs have') }} meta keyword, not depending on bugs and no activity for the last {{ extra['nmonths'] }} {{ plural('month', bugids) }}:
<p>The following {{ plural('bug has', data, pword='bugs have') }} meta keyword, not depending on bugs and no activity for the last {{ extra['nmonths'] }} {{ plural('month', extra['nmonths']) }}:
<table border="1">
<thead>
<tr>
@ -6,7 +6,7 @@
</tr>
</thead>
<tbody>
{% for i, (bugid, summary) in enumerate(bugids) -%}
{% for i, (bugid, summary) in enumerate(data) -%}
<tr {% if i % 2 == 0 %}bgcolor="#E0E0E0"{% endif -%}>
<td>
<a href="https://bugzilla.mozilla.org/show_bug.cgi?id={{ bugid }}">{{ bugid }}</a>

Просмотреть файл

@ -1,4 +1,4 @@
<p>The following {{ plural('bug has', bugids, pword='bugs have') }} meta keyword but not [meta] in the title:
<p>The following {{ plural('bug has', data, pword='bugs have') }} meta keyword but not [meta] in the title:
<table border="1">
<thead>
<tr>
@ -6,7 +6,7 @@
</tr>
</thead>
<tbody>
{% for i, (bugid, summary) in enumerate(bugids) -%}
{% for i, (bugid, summary) in enumerate(data) -%}
<tr {% if i % 2 == 0 %}bgcolor="#E0E0E0"{% endif -%}>
<td>
<a href="https://bugzilla.mozilla.org/show_bug.cgi?id={{ bugid }}">{{ bugid }}</a>

Просмотреть файл

@ -1,6 +1,6 @@
<p>The following {{ plural('bug is', bugids, pword='bugs are') }} tracked but with a bad priority:
<p>The following {{ plural('bug is', data, pword='bugs are') }} tracked but with a bad priority:
<ul>
{% for bugid in bugids -%}
{% for bugid in data -%}
<li><a href="https://bugzilla.mozilla.org/{{ bugid }}">{{ bugid }}</a></li>
{% endfor -%}
</ul>

Просмотреть файл

@ -1,4 +1,4 @@
<p>The following {{ plural('bug has', bugids, pword='bugs have') }} a missing beta status:
<p>The following {{ plural('bug has', data, pword='bugs have') }} a missing beta status:
<table border="1">
<thead>
<tr>
@ -6,7 +6,7 @@
</tr>
</thead>
<tbody>
{% for i, (bugid, summary) in enumerate(bugids) -%}
{% for i, (bugid, summary) in enumerate(data) -%}
<tr {% if i % 2 == 0 %}bgcolor="#E0E0E0"{% endif -%}>
<td>
<a href="https://bugzilla.mozilla.org/show_bug.cgi?id={{ bugid }}">{{ bugid }}</a>

Просмотреть файл

@ -1,4 +1,4 @@
<p>The following {{ plural('bug has', bugids, pword='bugs have') }} a needinfo from a manager or a director and no activity for the last {{ extra['nweeks'] }} {{ plural('week', extra['nweeks']) }} (when the bug is red, then the needinfo is on a person with no manager):
<p>The following {{ plural('bug has', data, pword='bugs have') }} a needinfo from a manager or a director and no activity for the last {{ extra['nweeks'] }} {{ plural('week', extra['nweeks']) }} (when the bug is red, then the needinfo is on a person with no manager):
<table border="1">
<thead>
<tr>
@ -6,9 +6,9 @@
</tr>
</thead>
<tbody>
{% for i, (bugid, summary) in enumerate(bugids) -%}
{% for i, (bugid, summary, needinfos, last_comment) in enumerate(data) -%}
<tr {% if i % 2 == 0 %}bgcolor="#E0E0E0"{% endif -%}>
<td {% if str(bugid) in no_manager %}style="background:red;"{% endif %}>
<td {% if bugid in no_manager %}style="background:red;"{% endif %}>
<a href="https://bugzilla.mozilla.org/show_bug.cgi?id={{ bugid }}">{{ bugid }}</a>
</td>
<td>
@ -16,13 +16,13 @@
</td>
<td>
<ul>
{% for ni in needinfos[str(bugid)] -%}
{% for ni in needinfos -%}
<li><a href="mailto:{{ ni }}">{{ ni | e }}</a></li>
{% endfor -%}
</ul>
</td>
<td>
{{ last_comment[str(bugid)] }}
{{ last_comment }}
</td>
</tr>
{% endfor -%}

Просмотреть файл

@ -2,20 +2,23 @@
<table border="1">
<thead>
<tr>
<th>Bug</th><th>Summary</th><th>Needinfos</th>
<th>Bug</th><th>Summary</th><th>Needinfo</th><th>Last comment</th>
</tr>
</thead>
<tbody>
{% for i, info in enumerate(data) -%}
{% for i, (bugid, summary, to, from, last_comment) in enumerate(data) -%}
<tr {% if i % 2 == 0 %}bgcolor="#E0E0E0"{% endif -%}>
<td>
<a href="https://bugzilla.mozilla.org/show_bug.cgi?id={{ info['id'] }}">{{ info['id'] }}</a>
<a href="https://bugzilla.mozilla.org/show_bug.cgi?id={{ bugid }}">{{ bugid }}</a>
</td>
<td>
{{ info['summary'] | e }}
{{ summary | e }}
</td>
<td>
<a href="mailto:{{ info['to'] | e }}">{{ info['to'] | e }}</a> from {{ info['from'] | e }}</a>
<a href="mailto:{{ to | e }}">{{ to | e }}</a> from {{ from | e }}</a>
</td>
<td>
{{ last_comment }}
</td>
</tr>
{% endfor -%}

Просмотреть файл

@ -1,23 +1,21 @@
<!doctype html>
<html lang="en-us">
<head>
<meta charset="utf-8">
<title>[autonag] Bugs with no priority and no activity for {{ extra['nweeks'] }} weeks</title>
</head>
<body>
<p>Hi there,</p>
<p>The following bugs have no activity in last {{ extra['nweeks'] }} weeks and no priority flag:
<ul>
{% for bugid, summary in bugids -%}
<li><a href="https://bugzilla.mozilla.org/{{ bugid }}">{{ bugid }}</a>: {{ summary | e }}</li>
{% endfor -%}
</ul>
</p>
<p>Sincerely,<br>
Release Management Bot
</p>
<p>
See the source / report issues on the <a href="https://github.com/mozilla/relman-auto-nag/">GitHub repo</a>
</p>
</body>
</html>
<p>The following bugs have no activity in last {{ extra['nweeks'] }} weeks and no priority flag:
<table border="1">
<thead>
<tr>
<th>Bug</th><th>Summary</th>
</tr>
</thead>
<tbody>
{% for i, (bugid, summary) in enumerate(data) -%}
<tr {% if i % 2 == 0 %}bgcolor="#E0E0E0"{% endif -%}>
<td>
<a href="https://bugzilla.mozilla.org/show_bug.cgi?id={{ bugid }}">{{ bugid }}</a>
</td>
<td>
{{ summary | e }}
</td>
</tr>
{% endfor -%}
</tbody>
</table>
</p>

Просмотреть файл

@ -1,4 +1,4 @@
<p>The following {{ plural('bug has', bugids, pword='bugs have') }} been reopened although the nightly status flag is still wontfix or fixed:
<p>The following {{ plural('bug has', data, pword='bugs have') }} been reopened although the nightly status flag is still wontfix or fixed:
<table border="1">
<thead>
<tr>
@ -6,7 +6,7 @@
</tr>
</thead>
<tbody>
{% for i, (bugid, summary) in enumerate(bugids) -%}
{% for i, (bugid, summary) in enumerate(data) -%}
<tr {% if i % 2 == 0 %}bgcolor="#E0E0E0"{% endif -%}>
<td>
<a href="https://bugzilla.mozilla.org/show_bug.cgi?id={{ bugid }}">{{ bugid }}</a>

Просмотреть файл

@ -1,17 +1,21 @@
<p>The following bugs have no assignees and a patch which landed in m-c:
<ul>
{% for bugid, email in bugids.items() -%}
{% if not email -%}
<li><a href="https://bugzilla.mozilla.org/{{ bugid }}">{{ bugid }}</a></li>
{% endif -%}
{% endfor -%}
</ul>
and these one have been auto-fixed:
<ul>
{% for bugid, email in bugids.items() -%}
{% if email -%}
<li><a href="https://bugzilla.mozilla.org/{{ bugid }}">{{ bugid }}</a> assigned to {{ email }}</li>
{% endif -%}
{% endfor -%}
</ul>
<p>The following {{ plural('bug has', data, pword='bugs have') }} no assignees and a patch which landed in m-c:
<table border="1">
<thead>
<tr>
<th>Bug</th><th>Assignee email</th>
</tr>
</thead>
<tbody>
{% for i, (bugid, email) in enumerate(data) -%}
<tr {% if i % 2 == 0 %}bgcolor="#E0E0E0"{% endif -%}>
<td>
<a href="https://bugzilla.mozilla.org/show_bug.cgi?id={{ bugid }}">{{ bugid }}</a>
</td>
<td>
{{ email | e }}
</td>
</tr>
{% endfor -%}
</tbody>
</table>
</p>

Просмотреть файл

@ -1,7 +1,18 @@
<p>The following {{ plural('bug has', bugids, pword='bugs have') }} no crashes in last {{ extra['nweeks'] }} {{ plural('week', extra['nweeks']) }}:
<ul>
{% for bugid in bugids -%}
<li><a href="https://bugzilla.mozilla.org/{{ bugid }}">{{ bugid }}</a></li>
{% endfor -%}
</ul>
<p>The following {{ plural('bug has', data, pword='bugs have') }} no crashes in last {{ extra['nweeks'] }} {{ plural('week', extra['nweeks']) }}:
<table border="1">
<thead>
<tr>
<th>Bug</th>
</tr>
</thead>
<tbody>
{% for i, bugid in enumerate(data) -%}
<tr {% if i % 2 == 0 %}bgcolor="#E0E0E0"{% endif -%}>
<td>
<a href="https://bugzilla.mozilla.org/show_bug.cgi?id={{ bugid }}">{{ bugid }}</a>
</td>
</tr>
{% endfor -%}
</tbody>
</table>
</p>

Просмотреть файл

@ -1,4 +1,4 @@
<p>The following {{ plural('bug has', bugids, pword='bugs have') }} a p1 priority but no activity in last {{ extra['nweeks'] }} {{ plural('week', extra['nweeks']) }}:
<p>The following {{ plural('bug has', data, pword='bugs have') }} a p1 priority but no activity in last {{ extra['nweeks'] }} {{ plural('week', extra['nweeks']) }}:
<table border="1">
<thead>
<tr>
@ -6,7 +6,7 @@
</tr>
</thead>
<tbody>
{% for i, (bugid, summary) in enumerate(bugids) -%}
{% for i, (bugid, summary) in enumerate(data) -%}
<tr {% if i % 2 == 0 %}bgcolor="#E0E0E0"{% endif -%}>
<td>
<a href="https://bugzilla.mozilla.org/show_bug.cgi?id={{ bugid }}">{{ bugid }}</a>

Просмотреть файл

@ -1,4 +1,4 @@
<p>The following {{ plural('bug has', bugids, pword='bugs have') }} a p2 priority but no activity in last {{ extra['nyears'] }} {{ plural('year', extra['nyears']) }}:
<p>The following {{ plural('bug has', data, pword='bugs have') }} a p2 priority but no activity in last {{ extra['nyears'] }} {{ plural('year', extra['nyears']) }}:
<table border="1">
<thead>
<tr>
@ -6,7 +6,7 @@
</tr>
</thead>
<tbody>
{% for i, (bugid, summary) in enumerate(bugids) -%}
{% for i, (bugid, summary) in enumerate(data) -%}
<tr {% if i % 2 == 0 %}bgcolor="#E0E0E0"{% endif -%}>
<td>
<a href="https://bugzilla.mozilla.org/show_bug.cgi?id={{ bugid }}">{{ bugid }}</a>

Просмотреть файл

@ -1,4 +1,4 @@
<p>The following {{ plural('bug has', bugids, pword='bugs have') }} only one or two words in the summary:
<p>The following {{ plural('bug has', data, pword='bugs have') }} only one or two words in the summary:
<table border="1">
<thead>
<tr>
@ -6,7 +6,7 @@
</tr>
</thead>
<tbody>
{% for i, (bugid, summary) in enumerate(bugids) -%}
{% for i, (bugid, summary) in enumerate(data) -%}
<tr {% if i % 2 == 0 %}bgcolor="#E0E0E0"{% endif -%}>
<td>
<a href="https://bugzilla.mozilla.org/show_bug.cgi?id={{ bugid }}">{{ bugid }}</a>

Просмотреть файл

@ -1,4 +1,4 @@
<p>The following {{ plural('bug is', bugids, pword='bugs are') }} probably a regression and don't have regression keyword:
<p>The following {{ plural('bug is', data, pword='bugs are') }} probably a regression and {{ plural('doesn\'t', data, pword='don\'t') }} have regression keyword:
<table border="1">
<thead>
<tr>
@ -6,7 +6,7 @@
</tr>
</thead>
<tbody>
{% for i, (bugid, summary) in enumerate(bugids) -%}
{% for i, (bugid, summary) in enumerate(data) -%}
<tr {% if i % 2 == 0 %}bgcolor="#E0E0E0"{% endif -%}>
<td>
<a href="https://bugzilla.mozilla.org/show_bug.cgi?id={{ bugid }}">{{ bugid }}</a>

Просмотреть файл

@ -1,4 +1,4 @@
<p>The following {{ plural('bug has', bugids, pword='bugs have') }} a needinfo on the reporter and no activity in last {{ extra['nweeks'] }} {{ plural('week', extra['nweeks']) }}:
<p>The following {{ plural('bug has', data, pword='bugs have') }} a needinfo on the reporter and no activity in last {{ extra['nweeks'] }} {{ plural('week', extra['nweeks']) }}:
<table border="1">
<thead>
<tr>
@ -6,7 +6,7 @@
</tr>
</thead>
<tbody>
{% for i, (bugid, summary) in enumerate(bugids) -%}
{% for i, (bugid, summary) in enumerate(data) -%}
<tr {% if i % 2 == 0 %}bgcolor="#E0E0E0"{% endif -%}>
<td>
<a href="https://bugzilla.mozilla.org/show_bug.cgi?id={{ bugid }}">{{ bugid }}</a>

Просмотреть файл

@ -1,7 +1,18 @@
<p>The following bugs have been closed although the stalled keyword is there:
<ul>
{% for bugid in bugids -%}
<li><a href="https://bugzilla.mozilla.org/{{ bugid }}">{{ bugid }}</a></li>
{% endfor -%}
</ul>
<p>The following {{ plural('bug has', data, pword='bugs have') }} been closed although the stalled keyword is there:
<table border="1">
<thead>
<tr>
<th>Bug</th>
</tr>
</thead>
<tbody>
{% for i, bugid in enumerate(data) -%}
<tr {% if i % 2 == 0 %}bgcolor="#E0E0E0"{% endif -%}>
<td>
<a href="https://bugzilla.mozilla.org/show_bug.cgi?id={{ bugid }}">{{ bugid }}</a>
</td>
</tr>
{% endfor -%}
</tbody>
</table>
</p>

Просмотреть файл

@ -1,7 +0,0 @@
<p>The following bugs have been closed although the stalled keyword is there:
<ul>
{% for bugid in bugids -%}
<li><a href="https://bugzilla.mozilla.org/{{ bugid }}">{{ bugid }}</a></li>
{% endfor -%}
</ul>
</p>

Просмотреть файл

@ -1,4 +1,4 @@
<p>The following {{ plural('bug hasn\'t', bugids, pword='bugs haven\'t') }} the meta keyword but {{ plural('has', bugids, pword='have') }} [meta] in the title:
<p>The following {{ plural('bug hasn\'t', data, pword='bugs haven\'t') }} the meta keyword but {{ plural('has', data, pword='have') }} [meta] in the title:
<table border="1">
<thead>
<tr>
@ -6,7 +6,7 @@
</tr>
</thead>
<tbody>
{% for i, (bugid, summary) in enumerate(bugids) -%}
{% for i, (bugid, summary) in enumerate(data) -%}
<tr {% if i % 2 == 0 %}bgcolor="#E0E0E0"{% endif -%}>
<td>
<a href="https://bugzilla.mozilla.org/show_bug.cgi?id={{ bugid }}">{{ bugid }}</a>

Просмотреть файл

@ -1,7 +1,18 @@
<p>The following {{ plural('bug has', bugids, pword='bugs have') }} topcrash as keyword but the severity isn't high enough:
<ul>
{% for bugid in bugids -%}
<li><a href="https://bugzilla.mozilla.org/{{ bugid }}">{{ bugid }}</a></li>
{% endfor -%}
</ul>
<p>The following {{ plural('bug has', data, pword='bugs have') }} topcrash as keyword but the severity isn't high enough:
<table border="1">
<thead>
<tr>
<th>Bug</th>
</tr>
</thead>
<tbody>
{% for i, bugid in enumerate(data) -%}
<tr {% if i % 2 == 0 %}bgcolor="#E0E0E0"{% endif -%}>
<td>
<a href="https://bugzilla.mozilla.org/show_bug.cgi?id={{ bugid }}">{{ bugid }}</a>
</td>
</tr>
{% endfor -%}
</tbody>
</table>
</p>

Просмотреть файл

@ -1,7 +1,18 @@
<p>The following {{ plural('bug is', bugids, pword='bugs are') }} tracked in a release but the bug severity is small:
<ul>
{% for bugid in bugids -%}
<li><a href="https://bugzilla.mozilla.org/{{ bugid }}">{{ bugid }}</a></li>
{% endfor -%}
</ul>
<p>The following {{ plural('bug is', data, pword='bugs are') }} tracked in a release but the bug severity is small:
<table border="1">
<thead>
<tr>
<th>Bug</th>
</tr>
</thead>
<tbody>
{% for i, bugid in enumerate(data) -%}
<tr {% if i % 2 == 0 %}bgcolor="#E0E0E0"{% endif -%}>
<td>
<a href="https://bugzilla.mozilla.org/show_bug.cgi?id={{ bugid }}">{{ bugid }}</a>
</td>
</tr>
{% endfor -%}
</tbody>
</table>
</p>

Просмотреть файл

@ -1,4 +1,4 @@
<p>The following {{ plural('bug is', bugids, pword='bugs are') }} tracked or nominated for tracking with a needinfo? in {{ extra['channel'] }} {{ extra['version'] }} (when the bug is red, then the needinfo is on a person with no manager):
<p>The following {{ plural('bug is', data, pword='bugs are') }} tracked or nominated for tracking with a needinfo? in {{ extra['channel'] }} {{ extra['version'] }} (when the bug is red, then the needinfo is on a person with no manager):
<table border="1">
<thead>
<tr>
@ -6,9 +6,9 @@
</tr>
</thead>
<tbody>
{% for i, (bugid, summary) in enumerate(bugids) -%}
{% for i, (bugid, summary, needinfos, assignee, last_comment) in enumerate(data) -%}
<tr {% if i % 2 == 0 %}bgcolor="#E0E0E0"{% endif -%}>
<td {% if str(bugid) in no_manager %}style="background:red;"{% endif %}>
<td {% if bugid in no_manager %}style="background:red;"{% endif %}>
<a href="https://bugzilla.mozilla.org/show_bug.cgi?id={{ bugid }}">{{ bugid }}</a>
</td>
<td>
@ -16,16 +16,16 @@
</td>
<td>
<ul>
{% for ni in needinfos[str(bugid)] -%}
{% for ni in needinfos[bugid] -%}
<li><a href="mailto:{{ ni }}">{{ ni | e }}</a></li>
{% endfor -%}
</ul>
</td>
<td>
{{ assignees[str(bugid)] | e }}
{{ assignee | e }}
</td>
<td>
{{ last_comment[str(bugid)] }}
{{ last_comment }}
</td>
</tr>
{% endfor -%}

Просмотреть файл

@ -2,27 +2,26 @@
<table border="1">
<thead>
<tr>
<th>Bug</th><th>Summary</th><th>Needinfos</th><th>Assignee</th>
<th>Bug</th><th>Summary</th><th>Needinfo to</th><th>Assignee</th><th>Last comment</th>
</tr>
</thead>
<tbody>
{% for i, info in enumerate(data) -%}
{% for i, (bugid, summary, to, assignee, last_comment) in enumerate(data) -%}
<tr {% if i % 2 == 0 %}bgcolor="#E0E0E0"{% endif -%}>
<td>
<a href="https://bugzilla.mozilla.org/show_bug.cgi?id={{ info['id'] }}">{{ info['id'] }}</a>
<a href="https://bugzilla.mozilla.org/show_bug.cgi?id={{ bugid }}">{{ bugid }}</a>
</td>
<td>
{{ info['summary'] | e }}
{{ summary | e }}
</td>
<td>
<ul>
{% for ni in extra['needinfos'][info['id']] -%}
<li><a href="mailto:{{ ni }}">{{ ni | e }}</a></li>
{% endfor -%}
</ul>
{{ to | e }}
</td>
<td>
{{ extra['assignees'][info['id']] | e }}
{{ assignee | e }}
</td>
<td>
{{ last_comment }}
</td>
</tr>
{% endfor -%}

Просмотреть файл

@ -1,4 +1,4 @@
<p>The following {{ plural('bug is', bugids, pword='bugs are') }} tracked in {{ extra['channel'] }} {{ extra['version'] }}{% if extra['untouched'] %} and untouched this week{% endif %} (when the bug is red, then the assignee is a person with no manager):
<p>The following {{ plural('bug is', data, pword='bugs are') }} tracked in {{ extra['channel'] }} {{ extra['version'] }}{% if extra['untouched'] %} and untouched this week{% endif %} (when the bug is red, then the assignee is a person with no manager):
<table border="1">
<thead>
<tr>
@ -6,19 +6,19 @@
</tr>
</thead>
<tbody>
{% for i, (bugid, summary) in enumerate(bugids) -%}
{% for i, (bugid, summary, assignee, last_comment) in enumerate(data) -%}
<tr {% if i % 2 == 0 %}bgcolor="#E0E0E0"{% endif -%}>
<td {% if str(bugid) in no_manager %}style="background:red;"{% endif %}>
<td {% if bugid in no_manager %}style="background:red;"{% endif %}>
<a href="https://bugzilla.mozilla.org/show_bug.cgi?id={{ bugid }}">{{ bugid }}</a>
</td>
<td>
{{ summary | e }}
</td>
<td>
{{ assignees[str(bugid)] | e }}
{{ assignee | e }}
</td>
<td>
{{ last_comment[str(bugid)] }}
{{ last_comment }}
</td>
</tr>
{% endfor -%}

Просмотреть файл

@ -2,20 +2,23 @@
<table border="1">
<thead>
<tr>
<th>Bug</th><th>Summary</th><th>Assignee</th>
<th>Bug</th><th>Summary</th><th>Assignee</th><th>Last comment</th>
</tr>
</thead>
<tbody>
{% for i, info in enumerate(data) -%}
{% for i, (buigid, summary, To, last_comment) in enumerate(data) -%}
<tr {% if i % 2 == 0 %}bgcolor="#E0E0E0"{% endif -%}>
<td>
<a href="https://bugzilla.mozilla.org/show_bug.cgi?id={{ info['id'] }}">{{ info['id'] }}</a>
<a href="https://bugzilla.mozilla.org/show_bug.cgi?id={{ bugid }}">{{ bugid }}</a>
</td>
<td>
{{ info['summary'] | e }}
{{ summary | e }}
</td>
<td>
{{ info['To'] | e }}
{{ To | e }}
</td>
<td>
{{ last_comment }}
</td>
</tr>
{% endfor -%}

Просмотреть файл

@ -1,4 +1,4 @@
<p>The following {{ plural('bug doesn\'t', bugids, pword='bugs don\'t') }} affect the release but {{ plural('affects', bugids, pword='affect') }} beta or nightly without the regression keyword:
<p>The following {{ plural('bug doesn\'t', data, pword='bugs don\'t') }} affect the release but {{ plural('affects', data, pword='affect') }} beta or nightly without the regression keyword:
<table border="1">
<thead>
<tr>
@ -6,7 +6,7 @@
</tr>
</thead>
<tbody>
{% for i, (bugid, summary) in enumerate(bugids) -%}
{% for i, (bugid, summary) in enumerate(data) -%}
<tr {% if i % 2 == 0 %}bgcolor="#E0E0E0"{% endif -%}>
<td>
<a href="https://bugzilla.mozilla.org/show_bug.cgi?id={{ bugid }}">{{ bugid }}</a>

Просмотреть файл

@ -1,4 +1,4 @@
<p>The following {{ plural('bug has', bugids, pword='bugs have') }} an unlanded patch or some flags not up-to-date (when the bug is red, then the assignee is a person with no manager):
<p>The following {{ plural('bug has', data, pword='bugs have') }} an unlanded patch or some flags not up-to-date{% if not nag %} (when the bug is red, then the assignee is a person with no manager){% endif %}:
<table border="1">
<thead>
<tr>
@ -6,7 +6,7 @@
</tr>
</thead>
<tbody>
{% for i, (bugid, summary) in enumerate(bugids) -%}
{% for i, (bugid, summary, assignee, last_comment) in enumerate(data) -%}
<tr {% if i % 2 == 0 %}bgcolor="#E0E0E0"{% endif -%}>
<td {% if str(bugid) in no_manager %}style="background:red;"{% endif %}>
<a href="https://bugzilla.mozilla.org/show_bug.cgi?id={{ bugid }}">{{ bugid }}</a>
@ -15,10 +15,10 @@
{{ summary | e }}
</td>
<td>
{{ assignees[str(bugid)] | e }}
{{ assignee | e }}
</td>
<td>
{{ last_comment[str(bugid)] }}
{{ last_comment }}
</td>
</tr>
{% endfor -%}

Просмотреть файл

@ -1,24 +0,0 @@
<p>The following {{ plural('bug', data) }} {{ plural('has', data, pword='have') }} an unlanded patch or some flags not up-to-date:
<table border="1">
<thead>
<tr>
<th>Bug</th><th>Summary</th><th>Assignee</th>
</tr>
</thead>
<tbody>
{% for i, info in enumerate(data) -%}
<tr {% if i % 2 == 0 %}bgcolor="#E0E0E0"{% endif -%}>
<td>
<a href="https://bugzilla.mozilla.org/show_bug.cgi?id={{ info['id'] }}">{{ info['id'] }}</a>
</td>
<td>
{{ info['summary'] | e }}
</td>
<td>
{{ extra['assignees'][info['id']] | e }}
</td>
</tr>
{% endfor -%}
</tbody>
</table>
</p>

Просмотреть файл

@ -1,4 +1,4 @@
<p>The following {{ plural('bug is', bugids, pword='bugs are') }} in untriagged with an important severity:
<p>The following {{ plural('bug is', data, pword='bugs are') }} in untriagged with an important severity:
<table border="1">
<thead>
<tr>
@ -6,7 +6,7 @@
</tr>
</thead>
<tbody>
{% for i, (bugid, summary) in enumerate(bugids) -%}
{% for i, (bugid, summary) in enumerate(data) -%}
<tr {% if i % 2 == 0 %}bgcolor="#E0E0E0"{% endif -%}>
<td>
<a href="https://bugzilla.mozilla.org/show_bug.cgi?id={{ bugid }}">{{ bugid }}</a>

Просмотреть файл

@ -1,7 +1,18 @@
<p>The following {{ plural('bug has', bugids, pword='bugs have') }} Version set but not status_firefox:
<ul>
{% for bugid in bugids -%}
<li><a href="https://bugzilla.mozilla.org/{{ bugid }}">{{ bugid }}</a></li>
{% endfor -%}
</ul>
<p>The following {{ plural('bug has', data, pword='bugs have') }} Version set but not status_firefox:
<table border="1">
<thead>
<tr>
<th>Bug</th>
</tr>
</thead>
<tbody>
{% for i, bugid in enumerate(data) -%}
<tr {% if i % 2 == 0 %}bgcolor="#E0E0E0"{% endif -%}>
<td>
<a href="https://bugzilla.mozilla.org/show_bug.cgi?id={{ bugid }}">{{ bugid }}</a>
</td>
</tr>
{% endfor -%}
</tbody>
</table>
</p>

Просмотреть файл

@ -1,22 +1,22 @@
<p>The following {{ plural('bug has', bugids, pword='bugs have') }} no priority flag set for the last {{ extra['nweeks'] }} {{ plural('week', extra['nweeks']) }}:
<p>The following {{ plural('bug has', data, pword='bugs have') }} no priority flag set for the last {{ extra['nweeks'] }} {{ plural('week', extra['nweeks']) }}:
<table border="1">
<thead>
<tr>
<th>Bug</th><th>Summary</th><th>Component</th>
<th>Component</th><th>Bug</th><th>Summary</th>
</tr>
</thead>
<tbody>
{% for i, (bugid, summary) in enumerate(bugids) -%}
{% for i, (comp, bugid, summary) in enumerate(data) -%}
<tr {% if i % 2 == 0 %}bgcolor="#E0E0E0"{% endif -%}>
<td>
{{ comp | e }}
</td>
<td>
<a href="https://bugzilla.mozilla.org/show_bug.cgi?id={{ bugid }}">{{ bugid }}</a>
</td>
<td>
{{ summary | e }}
</td>
<td>
{{ prod_comp[str(bugid)]['c'] | e }}
</td>
</tr>
{% endfor -%}
</tbody>

Просмотреть файл

@ -1,24 +0,0 @@
<p>The following {{ plural('bug has', data, pword='bugs have') }} no priority flag set for {{ extra['nweeks'] }} {{ plural('week', extra['nweeks']) }}{% if query_url %} (see the search query on <a href="{{ query_url }}">Bugzilla</a>){% endif %}:
<table border="1">
<thead>
<tr>
<th>Bug</th><th>Summary</th><th>Component</th>
</tr>
</thead>
<tbody>
{% for i, info in enumerate(data) -%}
<tr {% if i % 2 == 0 %}bgcolor="#E0E0E0"{% endif -%}>
<td>
<a href="https://bugzilla.mozilla.org/show_bug.cgi?id={{ info['id'] }}">{{ info['id'] }}</a>
</td>
<td>
{{ info['summary'] | e }}
</td>
<td>
{{ prod_comp[info['id']]['c'] | e }}
</td>
</tr>
{% endfor -%}
</tbody>
</table>
</p>

Просмотреть файл

@ -1,13 +1,16 @@
<p>The following {{ plural('bug has', bugids, pword='bugs have') }} a priority P1 and no activity for the last {{ extra['ndays'] }} {{ plural('day', extra['ndays']) }}:
<p>The following {{ plural('bug has', data, pword='bugs have') }} a priority P1 and no activity for the last {{ extra['ndays'] }} {{ plural('day', extra['ndays']) }}:
<table border="1">
<thead>
<tr>
<th>Bug</th><th>Summary</th><th>Last comment</th><th>Assignee</th><th>Component</th>
<th>Component</th><th>Bug</th><th>Summary</th><th>Last comment</th><th>Assignee</th>
</tr>
</thead>
<tbody>
{% for i, (bugid, summary) in enumerate(bugids) -%}
{% for i, (comp, bugid, summary, last_comment, assignee) in enumerate(data) -%}
<tr {% if i % 2 == 0 %}bgcolor="#E0E0E0"{% endif -%}>
<td>
{{ comp | e }}
</td>
<td>
<a href="https://bugzilla.mozilla.org/show_bug.cgi?id={{ bugid }}">{{ bugid }}</a>
</td>
@ -15,13 +18,10 @@
{{ summary | e }}
</td>
<td>
{{ last_comment[str(bugid)] }}
{{ last_comment }}
</td>
<td>
{{ assignees[str(bugid)] | e }}
</td>
<td>
{{ prod_comp[str(bugid)]['c'] | e }}
{{ assignee | e }}
</td>
</tr>
{% endfor -%}

Просмотреть файл

@ -1,30 +0,0 @@
<p>The following {{ plural('bug has', data, pword='bugs have') }} a priority P1 and no activity for the last {{ extra['ndays'] }} {{ plural('day', extra['ndays']) }}:
<table border="1">
<thead>
<tr>
<th>Bug</th><th>Summary</th><th>Last comment</th><th>Assignee</th><th>Component</th>
</tr>
</thead>
<tbody>
{% for i, info in enumerate(data) -%}
<tr {% if i % 2 == 0 %}bgcolor="#E0E0E0"{% endif -%}>
<td>
<a href="https://bugzilla.mozilla.org/show_bug.cgi?id={{ info['id'] }}">{{ info['id'] }}</a>
</td>
<td>
{{ info['summary'] | e }}
</td>
<td>
{{ last_comment[info['id']] }}
</td>
<td>
{{ assignees[info['id']] | e }}
</td>
<td>
{{ prod_comp[info['id']]['c'] | e }}
</td>
</tr>
{% endfor -%}
</tbody>
</table>
</p>

Просмотреть файл

@ -1,13 +1,16 @@
<p>The following {{ plural('bug has', bugids, pword='bugs have') }} a priority P1, no assignee and no activity for the last {{ extra['ndays'] }} {{ plural('day', extra['ndays']) }}:
<p>The following {{ plural('bug has', data, pword='bugs have') }} a priority P1, no assignee and no activity for the last {{ extra['ndays'] }} {{ plural('day', extra['ndays']) }}{% if query_url_nag %} (see the search query on <a href="{{ query_url_nag }}">Bugzilla</a>){% endif %}:
<table border="1">
<thead>
<tr>
<th>Bug</th><th>Summary</th><th>Last comment</th><th>Component</th>
<th>Component</th><th>Bug</th><th>Summary</th><th>Last comment</th>
</tr>
</thead>
<tbody>
{% for i, (bugid, summary) in enumerate(bugids) -%}
{% for i, (comp, bugid, summary, last_comment) in enumerate(data) -%}
<tr {% if i % 2 == 0 %}bgcolor="#E0E0E0"{% endif -%}>
<td>
{{ comp | e }}
</td>
<td>
<a href="https://bugzilla.mozilla.org/show_bug.cgi?id={{ bugid }}">{{ bugid }}</a>
</td>
@ -15,10 +18,7 @@
{{ summary | e }}
</td>
<td>
{{ last_comment[str(bugid)] }}
</td>
<td>
{{ prod_comp[str(bugid)]['c'] | e }}
{{ last_comment }}
</td>
</tr>
{% endfor -%}

Просмотреть файл

@ -1,27 +0,0 @@
<p>The following {{ plural('bug has', data, pword='bugs have') }} a priority P1, no assignee and no activity for the last {{ extra['ndays'] }} {{ plural('day', extra['ndays']) }}{% if query_url %} (see the search query on <a href="{{ query_url }}">Bugzilla</a>){% endif %}:
<table border="1">
<thead>
<tr>
<th>Bug</th><th>Summary</th><th>Last comment</th><th>Component</th>
</tr>
</thead>
<tbody>
{% for i, info in enumerate(data) -%}
<tr {% if i % 2 == 0 %}bgcolor="#E0E0E0"{% endif -%}>
<td>
<a href="https://bugzilla.mozilla.org/show_bug.cgi?id={{ info['id'] }}">{{ info['id'] }}</a>
</td>
<td>
{{ info['summary'] | e }}
</td>
<td>
{{ last_comment[info['id']] }}
</td>
<td>
{{ prod_comp[info['id']]['c'] | e }}
</td>
</tr>
{% endfor -%}
</tbody>
</table>
</p>

Просмотреть файл

@ -2,21 +2,21 @@
<table border="1">
<thead>
<tr>
<th>Bug</th><th>Summary</th><th>Component</th>
<th>Component</th><th>Bug</th><th>Summary</th>
</tr>
</thead>
<tbody>
{% for i, (bugid, summary) in enumerate(bugids) -%}
{% for i, (component, bugid, summary) in enumerate(data) -%}
<tr {% if i % 2 == 0 %}bgcolor="#E0E0E0"{% endif -%}>
<td>
{{ comp | e }}
</td>
<td>
<a href="https://bugzilla.mozilla.org/show_bug.cgi?id={{ bugid }}">{{ bugid }}</a>
</td>
<td>
{{ summary | e }}
</td>
<td>
{{ prod_comp[str(bugid)]['c'] | e }}
</td>
</tr>
{% endfor -%}
</tbody>

Просмотреть файл

@ -1,13 +1,16 @@
<p>The following {{ plural('bug has', bugids, pword='bugs have') }} a priority P2 and no activity for the last {{ extra['nmonths'] }} {{ plural('month', extra[nmonths]) }}:
<p>The following {{ plural('bug has', data, pword='bugs have') }} a priority P2 and no activity for the last {{ extra['nmonths'] }} {{ plural('month', extra[nmonths]) }}{% if query_url_nag %} (see the search query on <a href="{{ query_url_nag }}">Bugzilla</a>){% endif %}:
<table border="1">
<thead>
<tr>
<th>Bug</th><th>Summary</th><th>Last comment</th><th>Component</th>
<th>Component</th><th>Bug</th><th>Summary</th><th>Last comment</th>
</tr>
</thead>
<tbody>
{% for i, (bugid, summary) in enumerate(bugids) -%}
{% for i, (comp, bugid, summary, last_comment) in enumerate(data) -%}
<tr {% if i % 2 == 0 %}bgcolor="#E0E0E0"{% endif -%}>
<td>
{{ comp | e }}
</td>
<td>
<a href="https://bugzilla.mozilla.org/show_bug.cgi?id={{ bugid }}">{{ bugid }}</a>
</td>
@ -15,10 +18,7 @@
{{ summary | e }}
</td>
<td>
{{ last_comment[str(bugid)] }}
</td>
<td>
{{ prod_comp[str(bugid)]['c'] | e }}
{{ last_comment }}
</td>
</tr>
{% endfor -%}

Просмотреть файл

@ -1,27 +0,0 @@
<p>The following {{ plural('bug has', data, pword='bugs have') }} a priority P2 and no activity for the last {{ extra['nmonths'] }} {{ plural('month', extra[nmonths]) }}{% if query_url %} (see the search query on <a href="{{ query_url }}">Bugzilla</a>){% endif %}:
<table border="1">
<thead>
<tr>
<th>Bug</th><th>Summary</th><th>Last comment</th><th>Component</th>
</tr>
</thead>
<tbody>
{% for i, info in enumerate(data) -%}
<tr {% if i % 2 == 0 %}bgcolor="#E0E0E0"{% endif -%}>
<td>
<a href="https://bugzilla.mozilla.org/show_bug.cgi?id={{ info['id'] }}">{{ info['id'] }}</a>
</td>
<td>
{{ info['summary'] | e }}
</td>
<td>
{{ last_comment[info['id']] }}
</td>
<td>
{{ prod_comp[info['id']]['c'] | e }}
</td>
</tr>
{% endfor -%}
</tbody>
</table>
</p>

Просмотреть файл

@ -1,22 +1,22 @@
<p>The following {{ plural('bug has', bugids, pword='bugs have') }} a priority P3, P4 or P5 without activity for {{ extra['nmonths'] }} {{ plural('month', extra['nmonths']) }}:
<p>The following {{ plural('bug has', data, pword='bugs have') }} a priority P3, P4 or P5 without activity for {{ extra['nmonths'] }} {{ plural('month', extra['nmonths']) }}:
<table border="1">
<thead>
<tr>
<th>Bug</th><th>Summary</th><th>Component</th>
<th>Component</th><th>Bug</th><th>Summary</th>
</tr>
</thead>
<tbody>
{% for i, (bugid, summary) in enumerate(bugids) -%}
{% for i, (comp, bugid, summary) in enumerate(data) -%}
<tr {% if i % 2 == 0 %}bgcolor="#E0E0E0"{% endif -%}>
<td>
{{ comp | e }}
</td>
<td>
<a href="https://bugzilla.mozilla.org/show_bug.cgi?id={{ bugid }}">{{ bugid }}</a>
</td>
<td>
{{ summary | e }}
</td>
<td>
{{ prod_comp[str(bugid)]['c'] | e }}
</td>
</tr>
{% endfor -%}
</tbody>