def origin_annotation_load(request, action, user): # Find last accepted review which means it was reviewed and annotated. review = review_find_last(request, user, ['accepted']) if not review: return False try: annotation = yaml.safe_load(review.comment) except yaml.scanner.ScannerError as e: # OBS used to prefix subsequent review lines with two spaces. At some # point it was changed to no longer indent, but still need to be able # to load older annotations. comment_stripped = re.sub(r'^ ', '', review.comment, flags=re.MULTILINE) annotation = yaml.safe_load(comment_stripped) if not annotation or type( annotation) is not dict or 'origin' not in annotation: # Only returned structured data (ie. dict) with a minimum of the origin # key available, otherwise None. return None if len(request.actions) > 1: action_key = request_action_key(action) if action_key not in annotation: return False return annotation[action_key] return annotation
def add_review(self, req, by_group=None, by_user=None, by_project=None, by_package=None, msg=None, allow_duplicate=False): query = {'cmd': 'addreview'} if by_group: query['by_group'] = by_group elif by_user: query['by_user'] = by_user elif by_project: query['by_project'] = by_project if by_package: query['by_package'] = by_package else: raise osc.oscerr.WrongArgs("missing by_*") for r in req.reviews: if (r.by_group == by_group and r.by_project == by_project and r.by_package == by_package and r.by_user == by_user and # Only duplicate when allow_duplicate and state != new. (not allow_duplicate or r.state == 'new')): del query['cmd'] self.logger.debug( 'skipped adding duplicate review for {}'.format('/'.join( query.values()))) return u = osc.core.makeurl(self.apiurl, ['request', req.reqid], query) if self.dryrun: self.logger.info('POST %s' % u) return if self.multiple_actions: key = request_action_key(self.action) msg = yaml.dump({key: msg}, default_flow_style=False) try: r = osc.core.http_POST(u, data=msg) except HTTPError as e: if e.code != 403: raise e del query['cmd'] self.logger.info('unable to add review {} with message: {}'.format( query, msg)) return code = ET.parse(r).getroot().attrib['code'] if code != 'ok': raise Exception('non-ok return code: {}'.format(code))
def check_one_request(self, req): """ check all actions in one request. calls helper functions for each action type return None if nothing to do, True to accept, False to reject """ if len(req.actions) > 1: if self.only_one_action: self.review_messages[ 'declined'] = 'Only one action per request supported' return False # Will cause added reviews and overall review message to include # each actions message prefixed by an action key. self.multiple_actions = True review_messages_multi = {} else: self.multiple_actions = False # Copy original values to revert changes made to them. self.review_messages = self.DEFAULT_REVIEW_MESSAGES.copy() if self.comment_handler is not False: self.comment_handler_add() overall = True for a in req.actions: if self.multiple_actions: self.review_messages = self.DEFAULT_REVIEW_MESSAGES.copy() # Store in-case sub-classes need direct access to original values. self.action = a key = request_action_key(a) with sentry_sdk.configure_scope() as scope: scope.set_extra('action.key', key) override = self.request_override_check() if override is not None: ret = override else: func = getattr(self, self.action_method(a)) ret = func(req, a) # In the case of multiple actions take the "lowest" result where the # order from lowest to highest is: False, None, True. if overall is not False: if ((overall is True and ret is not True) or (overall is None and ret is False)): overall = ret if self.multiple_actions and ret is not None: message_key = self.review_message_key(ret) review_messages_multi[key] = self.review_messages[message_key] message_key = self.review_message_key(overall) if self.multiple_actions: message_combined = yaml.dump(review_messages_multi, default_flow_style=False) self.review_messages[message_key] = message_combined elif type(self.review_messages[message_key]) is dict: self.review_messages[message_key] = yaml.dump( self.review_messages[message_key], default_flow_style=False) return overall