def __init__(self): super(P1NoActivity, self).__init__() self.escalation = Escalation( self.people, data=utils.get_config(self.name(), "escalation"), skiplist=utils.get_config("workflow", "supervisor_skiplist", []), )
def __init__(self): super(P1NoAssignee, self).__init__() self.escalation = Escalation( self.people, data=utils.get_config(self.name(), 'escalation'), blacklist=utils.get_config('workflow', 'supervisor_blacklist', []), )
def __init__(self): super(P1NoActivity, self).__init__() self.escalation = Escalation( self.people, data=utils.get_config(self.name(), 'escalation'), blacklist=utils.get_config('workflow', 'supervisor_blacklist', []), )
def __init__(self): super(P2NoActivity, self).__init__() self.nmonths = utils.get_config(self.name(), 'months_lookup', 3) self.escalation = Escalation( self.people, data=utils.get_config(self.name(), 'escalation'), blacklist=utils.get_config('workflow', 'supervisor_blacklist', []), )
def __init__(self): super(P2NoActivity, self).__init__() self.nmonths = utils.get_config(self.name(), 'months_lookup', 3) self.escalation = Escalation( self.people, data=utils.get_config(self.name(), 'escalation'), skiplist=utils.get_config('workflow', 'supervisor_skiplist', []), )
def __init__(self): super(AssigneeNoLogin, self).__init__() self.nmonths = utils.get_config(self.name(), "number_of_months", 12) self.last_activity_months = utils.get_config(self.name(), "last_activity_months", 3) self.autofix_assignee = {} self.default_assignees = utils.get_default_assignees() self.people = people.People.get_instance()
def __init__(self): super(P1NoAssignee, self).__init__() self.escalation = Escalation( self.people, data=utils.get_config(self.name(), "escalation"), skiplist=utils.get_config("workflow", "supervisor_skiplist", []), ) self.round_robin = RoundRobin.get_instance() self.components_skiplist = utils.get_config("workflow", "components_skiplist")
def __init__(self, typ): super(NoPriority, self).__init__() assert typ in {'first', 'second'} self.typ = typ self.lookup_first = utils.get_config(self.name(), 'first-step', 2) self.lookup_second = utils.get_config(self.name(), 'second-step', 4) self.escalation = Escalation( self.people, data=utils.get_config(self.name(), 'escalation-{}'.format(typ)), blacklist=utils.get_config('workflow', 'supervisor_blacklist', []), ) self.round_robin = RoundRobin(people=self.people)
def __init__(self, typ): super(NoSeverity, self).__init__() assert typ in {"first", "second"} self.typ = typ self.lookup_first = utils.get_config(self.name(), "first-step", 2) self.lookup_second = utils.get_config(self.name(), "second-step", 4) self.escalation = Escalation( self.people, data=utils.get_config(self.name(), "escalation-{}".format(typ)), skiplist=utils.get_config("workflow", "supervisor_skiplist", []), ) self.round_robin = RoundRobin.get_instance() self.components_skiplist = utils.get_config("workflow", "components_skiplist")
def __init__(self): super(NiFromManager, self).__init__() self.nweeks = utils.get_config(self.name(), "number_of_weeks", 1) self.vip = self.get_people().get_rm_or_directors() self.white_list = utils.get_config(self.name(), "white-list", []) self.black_list = utils.get_config(self.name(), "black-list", []) self.init_versions() self.status_flags = ( utils.get_flag(self.versions["central"], "status", "central"), utils.get_flag(self.versions["beta"], "status", "beta"), utils.get_flag(self.versions["release"], "status", "release"), utils.get_flag(self.versions["esr_previous"], "status", "esr"), utils.get_flag(self.versions["esr"], "status", "esr"), )
def get_receivers(self): receivers = self.get_config('receivers') if isinstance(receivers, six.string_types): receivers = utils.get_config('common', 'receiver_list', default={})[ receivers ] return receivers
def feed(self, rr=None): self.data = {} filenames = {} if rr is None: rr = {} for team, path in utils.get_config( 'round-robin', 'teams', default={} ).items(): with open('./auto_nag/scripts/configs/{}'.format(path), 'r') as In: rr[team] = json.load(In) filenames[team] = path # rr is dictionary: # - doc -> documentation # - components -> dictionary: Product::Component -> strategy name # - strategies: dictionary: {calendar: url} # Get all the strategies for each team for team, data in rr.items(): calendars = self.get_calendar(team, data) self.all_calendars += list(calendars.values()) # finally self.data is a dictionary: # - Product::Component -> dictionary {fallback: who to nag when we've nobody # calendar} for pc, strategy in data['components'].items(): self.data[pc] = calendars[strategy]
def get_bz_params(self, date): start_date, end_date = self.get_dates(date) reporters = self.get_config('reporter_exception', default=[]) reporters = ','.join(reporters) regexp = r'http[s]?://hg\.mozilla\.org/(releases/)?mozilla-[^/]+/rev/[0-9a-f]+' bot = utils.get_config('common', 'bot_bz_mail')[0] params = { 'resolution': 'FIXED', 'bug_status': ['RESOLVED', 'VERIFIED'], 'keywords': 'meta', 'keywords_type': 'nowords', 'f1': 'longdesc', 'o1': 'regexp', 'v1': regexp, 'f2': 'resolution', 'o2': 'changedafter', 'v2': start_date, 'f3': 'resolution', 'o3': 'changedbefore', 'v3': end_date, 'n4': 1, 'f4': 'assigned_to', 'o4': 'changedby', 'v4': bot, } if reporters: params.update({'f5': 'reporter', 'o5': 'nowordssubstr', 'v5': reporters}) utils.get_empty_assignees(params) return params
def get_bz_params(self, date): start_date, end_date = self.get_dates(date) reporters = self.get_config("reporter_exception", default=[]) reporters = ",".join(reporters) regexp = r"http[s]?://hg\.mozilla\.org/(releases/)?mozilla-[^/]+/rev/[0-9a-f]+" bot = utils.get_config("common", "bot_bz_mail")[0] params = { "resolution": "FIXED", "bug_status": ["RESOLVED", "VERIFIED"], "keywords": "meta", "keywords_type": "nowords", "f1": "longdesc", "o1": "regexp", "v1": regexp, "f2": "resolution", "o2": "changedafter", "v2": start_date, "f3": "resolution", "o3": "changedbefore", "v3": end_date, "n4": 1, "f4": "assigned_to", "o4": "changedby", "v4": bot, } if reporters: params.update({"f5": "reporter", "o5": "nowordssubstr", "v5": reporters}) utils.get_empty_assignees(params) return params
def _get(data, name): res = [] data = utils.get_config(name, "ndays") if data is None else data["ndays"] for r, n in data.items(): res.append((Range.from_string(r), n)) return sorted(res)
def get_who_to_nag(self, date): fallbacks = {} date = lmdutils.get_date_ymd(date) days = utils.get_config('round-robin', 'days_to_nag', 7) next_date = date + relativedelta(days=days) for cal in self.all_calendars: persons = cal.get_persons(next_date) if persons and all(p is not None for _, p in persons): continue name = cal.get_team_name() fb = cal.get_fallback_mozmail() if fb not in fallbacks: fallbacks[fb] = {} if name not in fallbacks[fb]: fallbacks[fb][name] = {'nobody': False, 'persons': []} info = fallbacks[fb][name] if not persons: info['nobody'] = True else: people_names = [n for n, p in persons if p is None] if people_names: info['persons'] += people_names return fallbacks
def gather(self): env = Environment(loader=FileSystemLoader("templates")) common = env.get_template("common.html") login_info = utils.get_login_info() From = Nag.get_from() Default_Cc = set(utils.get_config("auto_nag", "cc", [])) all_mails = {} for nagger in self.naggers: mails = nagger.prepare_mails() for m in mails: manager = m["manager"] if manager not in all_mails: all_mails[manager] = {"to": m["to"], "body": m["body"]} else: all_mails[manager]["to"] |= m["to"] all_mails[manager]["body"] += "\n" + m["body"] for manager, m in all_mails.items(): Cc = Default_Cc.copy() Cc.add(manager) body = common.render(message=m["body"], has_table=True) mail.send( From, list(sorted(m["to"])), self.title(), body, Cc=list(sorted(Cc)), html=True, login=login_info, dryrun=self.is_dryrun, ) time.sleep(1)
def get_receivers(self): receivers = self.get_config("receivers") if isinstance(receivers, six.string_types): receivers = utils.get_config("common", "receiver_list", default={})[ receivers ] return receivers
def __init__(self): super(BzCleaner, self).__init__() self.has_autofix = False self.no_manager = set() self.auto_needinfo = {} self.has_flags = False self.test_mode = utils.get_config('common', 'test', False)
def get_who_to_nag(self, date): fallbacks = {} date = lmdutils.get_date_ymd(date) days = utils.get_config("round-robin", "days_to_nag", 7) next_date = date + relativedelta(days=days) for cal in self.all_calendars: persons = cal.get_persons(next_date) if persons and all(p is not None for _, p in persons): continue name = cal.get_team_name() fb = cal.get_fallback_mozmail() if fb not in fallbacks: fallbacks[fb] = {} if name not in fallbacks[fb]: fallbacks[fb][name] = {"nobody": False, "persons": []} info = fallbacks[fb][name] if not persons: info["nobody"] = True else: people_names = [n for n, p in persons if p is None] if people_names: info["persons"] += people_names return fallbacks
def feed(self, teams, rr=None): self.data = {} filenames = {} if rr is None: rr = {} for team, path in utils.get_config( "round-robin", "teams", default={} ).items(): if teams is not None and team not in teams: continue with open("./auto_nag/scripts/configs/{}".format(path), "r") as In: rr[team] = json.load(In) filenames[team] = path # rr is dictionary: # - doc -> documentation # - components -> dictionary: Product::Component -> strategy name # - strategies: dictionary: {calendar: url} # Get all the strategies for each team for team, data in rr.items(): calendars = self.get_calendar(team, data) self.all_calendars += list(calendars.values()) # finally self.data is a dictionary: # - Product::Component -> dictionary {fallback: who to nag when we've nobody # calendar} for pc, strategy in data["components"].items(): self.data[pc] = calendars[strategy]
def get_dates(self, date): """Get the dates for the bugzilla query (changedafter and changedbefore fields)""" date = lmdutils.get_date_ymd(date) lookup = utils.get_config(self.name(), 'days_lookup', 7) start_date = date - relativedelta(days=lookup) end_date = date + relativedelta(days=1) return start_date, end_date
def __init__(self): super(BzCleaner, self).__init__() self._set_tool_name() self.has_autofix = False self.no_manager = set() self.auto_needinfo = {} self.has_flags = False self.cache = Cache(self.name(), self.max_days_in_cache()) self.test_mode = utils.get_config('common', 'test', False)
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')) if not self.add(owner, buginfo, priority=priority): self.add_no_manager(buginfo['id']) return bug
def __init__(self): super().__init__() self.init_versions() self.status_esr = utils.get_flag(self.versions["esr_previous"], "status", "esr") self.status_esr_next = utils.get_flag(self.versions["esr"], "status", "esr") self.status_changes = {} self.component_exception = set( utils.get_config(self.name(), "component_exception"))
def __init__(self): super(BzCleaner, self).__init__() self._set_tool_name() self.has_autofix = False self.no_manager = set() self.auto_needinfo = {} self.has_flags = False self.cache = Cache(self.name(), self.max_days_in_cache()) self.test_mode = utils.get_config("common", "test", False) self.versions = None logger.info("Run tool {}".format(self.get_tool_path()))
def autofix(self, bugs): """Autofix the bugs according to what is returned by get_autofix_change""" ni_changes = self.set_needinfo() change = self.get_autofix_change() if not ni_changes and not change: return bugs self.has_autofix = True new_changes = {} if not self.has_individual_autofix(change): bugids = self.get_list_bugs(bugs) for bugid in bugids: new_changes[bugid] = utils.merge_bz_changes( change, ni_changes.get(bugid, {}) ) else: change = {str(k): v for k, v in change.items()} bugids = set(change.keys()) | set(ni_changes.keys()) for bugid in bugids: mrg = utils.merge_bz_changes( change.get(bugid, {}), ni_changes.get(bugid, {}) ) if mrg: new_changes[bugid] = mrg if self.dryrun or self.test_mode: for bugid, ch in new_changes.items(): logger.info( "The bugs: {}\n will be autofixed with:\n{}".format(bugid, ch) ) else: extra = self.get_db_extra() max_retries = utils.get_config("common", "bugzilla_max_retries", 3) for bugid, ch in new_changes.items(): added = False for _ in range(max_retries): failures = Bugzilla([str(bugid)]).put(ch) if failures: time.sleep(1) else: added = True db.BugChange.add(self.name(), bugid, extra=extra.get(bugid, "")) break if not added: self.failure_callback(bugid) logger.error( "{}: Cannot put data for bug {} (change => {}).".format( self.name(), bugid, ch ) ) return bugs
def get_bz_params(self, date): self.components = utils.get_config('workflow', 'components') params = { 'component': utils.get_components(self.components), 'resolution': '---', 'f1': 'priority', 'o1': 'equals', 'v1': 'P2', } utils.get_empty_assignees(params) return params
def _get_steps(priority, people, data): res = [] data = (utils.get_config('escalation', priority) if data is None else data.get(priority, {})) for r, sd in data.items(): res.append( Step( Range.from_string(r), Supervisor(sd['supervisor'], people), {DAYS[d] for d in sd['days']}, )) return sorted(res)
def get_bz_params(self, date): self.components = utils.get_config("workflow", "components") params = { "component": utils.get_components(self.components), "resolution": "---", "f1": "priority", "o1": "equals", "v1": "P2", } utils.get_empty_assignees(params) return params
def set_people_to_nag(self, bug, buginfo): priority = 'default' if not self.filter_bug(priority): return None # check if the product::component is in the list if not utils.check_product_component(self.components, bug): return None owner = bug['triage_owner'] self.add_triage_owner(owner, utils.get_config('workflow', 'components')) if not self.add(owner, buginfo, priority=priority): self.add_no_manager(buginfo['id']) return bug
def set_people_to_nag(self, bug, buginfo): priority = "default" if not self.filter_bug(priority): return None # check if the product::component is in the list if not utils.check_product_component(self.components, bug): return None owner = bug["triage_owner"] self.add_triage_owner(owner, utils.get_config("workflow", "components")) if not self.add(owner, buginfo, priority=priority): self.add_no_manager(buginfo["id"]) return bug
def _get_steps(priority, people, data): res = [] data = (utils.get_config("escalation", priority) if data is None else data.get(priority, {})) week = utils.get_weekdays() for r, sd in data.items(): res.append( Step( Range.from_string(r), Supervisor(sd["supervisor"], people), {week[d] for d in sd["days"]}, )) return sorted(res)
def _get_steps(priority, people, data): res = [] data = ( utils.get_config('escalation', priority) if data is None else data.get(priority, {}) ) for r, sd in data.items(): res.append( Step( Range.from_string(r), Supervisor(sd['supervisor'], people), {DAYS[d] for d in sd['days']}, ) ) return sorted(res)
def get_bz_params(self, date): date = lmdutils.get_date_ymd(date) start_date = date - relativedelta(months=self.nmonths) days = (date - start_date).days self.components = utils.get_config('workflow', 'components') params = { 'component': utils.get_components(self.components), 'bug_type': 'defect', 'resolution': '---', 'f1': 'priority', 'o1': 'anywordssubstr', 'v1': ','.join(['P3', 'P4', 'P5']), 'f2': 'days_elapsed', 'o2': 'greaterthaneq', 'v2': days, } return params
def get_bz_params(self, date): date = lmdutils.get_date_ymd(date) start_date = date - relativedelta(months=self.nmonths) days = (date - start_date).days self.components = utils.get_config("workflow", "components") params = { "component": utils.get_components(self.components), "bug_type": "defect", "resolution": "---", "f1": "priority", "o1": "anywordssubstr", "v1": ",".join(["P3", "P4", "P5"]), "f2": "days_elapsed", "o2": "greaterthaneq", "v2": days, } return params
def get_bz_params(self, date): date = lmdutils.get_date_ymd(date) start_date = date - relativedelta(months=self.nmonths) days = (date - start_date).days fields = ['triage_owner'] comps = utils.get_config('workflow', 'components') params = { 'include_fields': fields, 'component': comps, 'resolution': '---', 'f1': 'priority', 'o1': 'equals', 'v1': 'P2', 'f2': 'days_elapsed', 'o2': 'greaterthaneq', 'v2': days, } return params
def get_bz_params(self, date): date = lmdutils.get_date_ymd(date) start_date = date - relativedelta(months=self.nmonths) days = (date - start_date).days fields = ['triage_owner'] self.components = utils.get_config('workflow', 'components') params = { 'include_fields': fields, 'bug_type': 'defect', 'component': utils.get_components(self.components), 'resolution': '---', 'f1': 'priority', 'o1': 'equals', 'v1': 'P2', 'f2': 'days_elapsed', 'o2': 'greaterthaneq', 'v2': days, } return params
def get_bz_params(self, date): date = lmdutils.get_date_ymd(date) start_date = date - relativedelta(months=self.nmonths) days = (date - start_date).days fields = ["triage_owner"] self.components = utils.get_config("workflow", "components") params = { "include_fields": fields, "bug_type": "defect", "component": utils.get_components(self.components), "resolution": "---", "f1": "priority", "o1": "equals", "v1": "P2", "f2": "days_elapsed", "o2": "greaterthaneq", "v2": days, } return params
def get_bz_params(self, date): self.ndays = NoActivityDays(self.name()).get( (utils.get_next_release_date() - self.nag_date).days ) fields = ['triage_owner', 'flags'] self.components = utils.get_config('workflow', 'components') params = { 'component': utils.get_components(self.components), 'bug_type': 'defect', 'include_fields': fields, 'resolution': '---', 'f1': 'priority', 'o1': 'equals', 'v1': 'P1', 'f2': 'days_elapsed', 'o2': 'greaterthaneq', 'v2': self.ndays, } utils.get_empty_assignees(params) return params
def __init__(self): super(P3P4P5, self).__init__() self.nmonths = utils.get_config(self.name(), 'months_lookup', 6)
def __init__(self): super(LeaveOpenNoActivity, self).__init__() self.people = People() self.nmonths = utils.get_config(self.name(), 'months_lookup') self.max_ni = utils.get_config(self.name(), 'max_ni') self.blacklist = set(utils.get_config(self.name(), 'blacklist', []))
def __init__(self): super(MetaDefect, self).__init__() self.nmonths = utils.get_config(self.name(), 'months_lookup')
def __init__(self): super(AssigneeNoLogin, self).__init__() self.nmonths = utils.get_config(self.name(), 'number_of_months', 12) self.autofix_assignee = {} self.default_assignees = utils.get_default_assignees() self.people = people.People()
def get_cc(): return set(utils.get_config('auto_nag', 'cc', []))
def __init__(self): super(NiFromManager, self).__init__() self.nweeks = utils.get_config(self.name(), 'number_of_weeks', 1) self.vip = self.get_people().get_rm_or_directors() self.white_list = utils.get_config(self.name(), 'white-list', []) self.black_list = utils.get_config(self.name(), 'black-list', [])
def __init__(self): super(NoCrashes, self).__init__() self.nweeks = utils.get_config(self.name(), 'number_of_weeks', 12) self.summaries = {}
def __init__(self): super(ReporterWithNI, self).__init__() self.nweeks = utils.get_config(self.name(), 'number_of_weeks', 12)
cc_only=options.cc_only) if options.email_password is None or options.mozilla_mail is None: print("Please supply a username/password (-m, -p) for sending email") sys.exit(1) if not options.dryrun: print("SENDING EMAIL") mail.sendMail(options.mozilla_mail, toaddrs, msg, login={'ldap_username': options.mozilla_mail, 'ldap_password': options.email_password}, dryrun=options.dryrun) else: # Get yr nag on! for email, info in managers.items(): inp = '' if 'nagging' in info: if email in utils.get_config('auto_nag', 'no_mail_for_manager', default=[]): email = None toaddrs, msg = generateEmailOutput( subject=options.email_subject, manager_email=email, queries=info['nagging'], people=people, template=options.template, show_comment=options.show_comment, cc_only=options.cc_only) while True and not options.no_verification: print("\nRelMan Nag is ready to send the following email:\n<------ MESSAGE BELOW -------->") print(msg) print("<------- END MESSAGE -------->\nWould you like to send now?") inp = raw_input('\n Please select y/Y to send, v/V to edit, or n/N to skip and continue to next email: ')
def _get(data, name): res = [] data = utils.get_config(name, 'ndays') if data is None else data['ndays'] for r, n in data.items(): res.append((Range.from_string(r), n)) return sorted(res)
import json from libmozdata import utils as lmdutils import os import six from sqlalchemy.ext.declarative import declarative_base from sqlalchemy import create_engine from sqlalchemy.orm import relationship, sessionmaker from sqlalchemy.orm.exc import NoResultFound from sqlalchemy import Column, ForeignKey, Integer, String from auto_nag import logger, utils from auto_nag.history import History Base = declarative_base() lock_path = utils.get_config('common', 'lock') db_url = utils.get_config('common', 'database') engine = create_engine(db_url) DBSession = sessionmaker(bind=engine) Base.metadata.bind = engine session = DBSession() def init(): hist = History().get() logger.info('Put history in db: start...') BugChange.import_from_dict(hist) logger.info('Put history in db: end.') def check(table_name):
def get_path(self): cache_path = utils.get_config('common', 'cache') if not os.path.exists(cache_path): os.mkdir(cache_path) return '{}/{}.json'.format(cache_path, self.name)
def __init__(self): super(NotLanded, self).__init__() self.nweeks = utils.get_config(self.name(), 'number_of_weeks', 2) self.nyears = utils.get_config(self.name(), 'number_of_years', 2) self.phab_token = utils.get_login_info()['phab_api_key'] self.extra_ni = {}
def __init__(self): super(NewbieWithNI, self).__init__() self.people = People() self.ndays = utils.get_config(self.name(), 'number_of_days', 14) self.ncomments = utils.get_config(self.name(), 'number_of_comments', 2) self.autofix_reporters = {}
def get_config(self, entry, default=None): return utils.get_config('unlanded', entry, default=default)
def get_config(self, entry, default=None): return utils.get_config(self.name(), entry, default=default)
def get_from(): return utils.get_config('auto_nag', 'from', '*****@*****.**')