def supplement(self, request): """ Provide additional information for grouping """ if request.get('ignored'): # Only supplement once. return history = request.find('history') if history is not None: age = request_age(request).total_seconds() request.set('aged', str(age >= self.request_age_threshold)) request_type = request.find('./action').get('type') target = request.find('./action/target') target_project = target.get('project') target_package = target.get('package') devel, _ = devel_project_fallback(self.api.apiurl, target_project, target_package) if not devel and request_type == 'submit': devel = request.find('./action/source').get('project') if devel: target.set('devel_project', devel) StrategySuper.supplement(request) ring = self.ring_get(target_package) if ring: target.set('ring', ring) request_id = int(request.get('id')) if request_id in self.requests_ignored: request.set('ignored', str(self.requests_ignored[request_id])) else: request.set('ignored', 'False') request.set('postponed', 'False')
def notify(args): apiurl = osc.conf.config['apiurl'] # devel_projects_get() only works for Factory as such # devel_project_fallback() must be used on a per package basis. packages = meta_get_packagelist(apiurl, args.project) maintainer_map = {} for package in packages: devel_project, devel_package = devel_project_fallback(apiurl, args.project, package) if devel_project and devel_package: devel_package_identifier = '/'.join([devel_project, devel_package]) userids = maintainers_get(apiurl, devel_project, devel_package) for userid in userids: maintainer_map.setdefault(userid, set()) maintainer_map[userid].add(devel_package_identifier) Config(args.project) # Ensure mail-* options are loaded for mail_send(). subject = 'Packages you maintain are present in {}'.format(args.project) for userid, package_identifiers in maintainer_map.items(): email = entity_email(apiurl, userid) message = 'The following packages you maintain are in {}:\n\n- {}'.format( args.project, '\n- '.join(sorted(package_identifiers))) mail_send(args.project, email, subject, message, dry=args.dry) print('notified {} of {} packages'.format(userid, len(package_identifiers)))
def devel_project_review_add(self, request, project, package, message='adding devel project review'): devel_project, devel_package = devel_project_fallback(self.apiurl, project, package) if not devel_project: self.logger.warning('no devel project found for {}/{}'.format(project, package)) return False self.add_review(request, by_project=devel_project, by_package=devel_package, msg=message) return True
def check_action_add_role(self, request, action): # Decline add_role request (assumed the bot acting on requests to Factory or similar). message = 'Roles to packages are granted in the devel project, not in %s.' % action.tgt_project if action.tgt_package is not None: project, package = devel_project_fallback(self.apiurl, action.tgt_project, action.tgt_package) message += ' Send this request to {}/{}.'.format(project, package) self.review_messages['declined'] = message return False
def notify(args): import smtplib apiurl = osc.conf.config['apiurl'] # devel_projects_get() only works for Factory as such # devel_project_fallback() must be used on a per package basis. packages = args.packages if not packages: packages = package_list_kind_filtered(apiurl, args.project) maintainer_map = {} for package in packages: devel_project, devel_package = devel_project_fallback( apiurl, args.project, package) if devel_project and devel_package: devel_package_identifier = '/'.join([devel_project, devel_package]) userids = maintainers_get(apiurl, devel_project, devel_package) for userid in userids: maintainer_map.setdefault(userid, set()) maintainer_map[userid].add(devel_package_identifier) subject = 'Packages you maintain are present in {}'.format(args.project) for userid, package_identifiers in maintainer_map.items(): email = entity_email(apiurl, userid) message = """This is a friendly reminder about your packages in {}. Please verify that the included packages are working as intended and have versions appropriate for a stable release. Changes may be submitted until April 26th [at the latest]. Keep in mind that some packages may be shared with SUSE Linux Enterprise. Concerns with those should be raised via Bugzilla. Please contact [email protected] if your package needs special attention by the release team. According to the information in OBS ("osc maintainer") you are in charge of the following packages: - {}""".format(args.project, '\n- '.join(sorted(package_identifiers))) log = 'notified {} of {} packages'.format(userid, len(package_identifiers)) try: mail_send(apiurl, args.project, email, subject, message, dry=args.dry) print(log) except smtplib.SMTPRecipientsRefused: print('[FAILED ADDRESS] {} ({})'.format(log, email)) except smtplib.SMTPException as e: print('[FAILED SMTP] {} ({})'.format(log, e))
def notify(args): import smtplib apiurl = osc.conf.config['apiurl'] # devel_projects_get() only works for Factory as such # devel_project_fallback() must be used on a per package basis. packages = args.packages if not packages: packages = package_list_without_links(apiurl, args.project) maintainer_map = {} for package in packages: devel_project, devel_package = devel_project_fallback(apiurl, args.project, package) if devel_project and devel_package: devel_package_identifier = '/'.join([devel_project, devel_package]) userids = maintainers_get(apiurl, devel_project, devel_package) for userid in userids: maintainer_map.setdefault(userid, set()) maintainer_map[userid].add(devel_package_identifier) subject = 'Packages you maintain are present in {}'.format(args.project) for userid, package_identifiers in maintainer_map.items(): email = entity_email(apiurl, userid) message = """This is a friendly reminder about your packages in {}. Please verify that the included packages are working as intended and have versions appropriate for a stable release. Changes may be submitted until April 26th [at the latest]. Keep in mind that some packages may be shared with SUSE Linux Enterprise. Concerns with those should be raised via Bugzilla. Please contact [email protected] if your package needs special attention by the release team. According to the information in OBS ("osc maintainer") you are in charge of the following packages: - {}""".format( args.project, '\n- '.join(sorted(package_identifiers))) log = 'notified {} of {} packages'.format(userid, len(package_identifiers)) try: mail_send(apiurl, args.project, email, subject, message, dry=args.dry) print(log) except smtplib.SMTPRecipientsRefused as e: print('[FAILED ADDRESS] {} ({})'.format(log, email)) except smtplib.SMTPException as e: print('[FAILED SMTP] {} ({})'.format(log, e))
def devel_project_review_add(self, request, project, package, message='adding devel project review'): devel_project, devel_package = devel_project_fallback(self.apiurl, project, package) if not devel_project: self.logger.warning('no devel project found for {}/{}'.format(project, package)) return False try: self.add_review(request, by_project=devel_project, by_package=devel_package, msg=message) except HTTPError as e: # could happen when the bot is not actually a reviewer and has no permissions if e.code != 403: raise e self.logger.error('failed to add devel project review for {}/{}'.format(devel_project, devel_package)) return False return True
def package_comments(self, project, repository): self.logger.info('{} package comments'.format(len( self.package_results))) for package, sections in self.package_results.items(): if str2bool( Config.get(self.apiurl, project).get( 'repo_checker-package-comment-devel', 'False')): bot_name_suffix = project comment_project, comment_package = devel_project_fallback( self.apiurl, project, package) if comment_project is None or comment_package is None: self.logger.warning( 'unable to find devel project for {}'.format(package)) continue message = 'The version of this package in [`{project}`](/package/show/{project}/{package}) ' \ 'has installation issues and may not be installable:'.format( project=project, package=package) else: bot_name_suffix = repository comment_project = project comment_package = package message = 'This package has installation issues and may not be installable from the `{}` ' \ 'repository:'.format(repository) # Sort sections by text to group binaries together. sections = sorted(sections, key=lambda s: s.text) message += '\n\n<pre>\n{}\n</pre>'.format('\n'.join( [section.text for section in sections]).strip()) # Generate a hash based on the binaries involved and the number of # sections. This eliminates version or release changes from causing # an update to the comment while still updating on relevant changes. binaries = set() for section in sections: binaries.update(section.binaries) info = ';'.join(['::'.join(sorted(binaries)), str(len(sections))]) reference = hashlib.sha1(info).hexdigest()[:7] # Post comment on package in order to notifiy maintainers. self.comment_write(state='seen', result=reference, bot_name_suffix=bot_name_suffix, project=comment_project, package=comment_package, message=message)
def supplement(self, request): """ Provide additional information for grouping """ if request.get('ignored'): # Only supplement once. return history = request.find('history') if history is not None: created = dateutil.parser.parse( request.find('history').get('when')) delta = datetime.utcnow() - created request.set( 'aged', str(delta.total_seconds() >= self.request_age_threshold)) request_type = request.find('./action').get('type') target = request.find('./action/target') target_project = target.get('project') target_package = target.get('package') devel, _ = devel_project_fallback(self.api.apiurl, target_project, target_package) if not devel and request_type == 'submit': devel = request.find('./action/source').get('project') if devel: target.set('devel_project', devel) StrategySuper.supplement(request) ring = self.ring_get(target_package) if ring: target.set('ring', ring) elif request_type == 'delete': # Delete requests should always be considered in a ring. target.set('ring', 'delete') request_id = int(request.get('id')) if request_id in self.requests_ignored: request.set('ignored', str(self.requests_ignored[request_id])) else: request.set('ignored', 'False') request.set('postponed', 'False')
def supplement(self, request): """ Provide additional information for grouping """ if request.get('ignored'): # Only supplement once. return history = request.find('history') if history is not None: age = request_age(request).total_seconds() request.set('aged', str(age >= self.request_age_threshold)) request_type = request.find('./action').get('type') target = request.find('./action/target') target_project = target.get('project') target_package = target.get('package') devel, _ = devel_project_fallback(self.api.apiurl, target_project, target_package) if not devel and request_type == 'submit': devel = request.find('./action/source').get('project') if devel: target.set('devel_project', devel) StrategySuper.supplement(request) if target_project == self.api.cnonfree: target.set('nonfree', 'nonfree') ring = self.ring_get(target_package) if ring: target.set('ring', ring) elif not self.api.conlyadi and request_type == 'delete': # Delete requests should always be considered in a ring. target.set('ring', 'delete') request_id = int(request.get('id')) if request_id in self.requests_ignored: request.set('ignored', str(self.requests_ignored[request_id])) else: request.set('ignored', 'False') request.set('postponed', 'False')
def package_comments(self, project, repository): self.logger.info('{} package comments'.format(len(self.package_results))) for package, sections in self.package_results.items(): if str2bool(Config.get(self.apiurl, project).get('repo_checker-package-comment-devel', 'False')): bot_name_suffix = project comment_project, comment_package = devel_project_fallback(self.apiurl, project, package) if comment_project is None or comment_package is None: self.logger.warning('unable to find devel project for {}'.format(package)) continue message = 'The version of this package in [`{project}`](/package/show/{project}/{package}) ' \ 'has installation issues and may not be installable:'.format( project=project, package=package) else: bot_name_suffix = repository comment_project = project comment_package = package message = 'This package has installation issues and may not be installable from the `{}` ' \ 'repository:'.format(repository) # Sort sections by text to group binaries together. sections = sorted(sections, key=lambda s: s.text) message += '\n\n<pre>\n{}\n</pre>'.format( '\n'.join([section.text for section in sections]).strip()) # Generate a hash based on the binaries involved and the number of # sections. This eliminates version or release changes from causing # an update to the comment while still updating on relevant changes. binaries = set() for section in sections: binaries.update(section.binaries) info = ';'.join(['::'.join(sorted(binaries)), str(len(sections))]) reference = hashlib.sha1(info).hexdigest()[:7] # Post comment on package in order to notifiy maintainers. self.comment_write(state='seen', result=reference, bot_name_suffix=bot_name_suffix, project=comment_project, package=comment_package, message=message)