def pre_translation(self, query): """Translates the query for possible aliases""" old = query.copy() if "bug_id" in query: if type(query["bug_id"]) is not list: query["id"] = query["bug_id"].split(",") else: query["id"] = query["bug_id"] del query["bug_id"] if "component" in query: if type(query["component"]) is not list: query["component"] = query["component"].split(",") if "include_fields" not in query and "column_list" not in query: return if "include_fields" not in query: query["include_fields"] = [] if "column_list" in query: query["include_fields"] = query["column_list"] del query["column_list"] # We need to do this for users here for users that # don't call build_query self._convert_include_field_list(query["include_fields"]) if old != query: log.debug("RHBugzilla pretranslated query to: %s", query)
def pre_translation(self, query): '''Translates the query for possible aliases''' old = query.copy() if 'bug_id' in query: if type(query['bug_id']) is not list: query['id'] = query['bug_id'].split(',') else: query['id'] = query['bug_id'] del query['bug_id'] if 'component' in query: if type(query['component']) is not list: query['component'] = query['component'].split(',') if 'include_fields' not in query and 'column_list' not in query: return if 'include_fields' not in query: query['include_fields'] = [] if 'column_list' in query: query['include_fields'] = query['column_list'] del query['column_list'] include_fields = query['include_fields'] for newname, oldname in self.field_aliases: if oldname in include_fields: include_fields.remove(oldname) if newname not in include_fields: include_fields.append(newname) if old != query: log.debug("RHBugzilla pretranslated query to: %s", query)
def _dowhiteboard(self, text, which, action, comment, private): ''' Update the whiteboard given by 'which' for the given bug. ''' if which not in ["status", "qa", "devel", "internal"]: raise ValueError("Unknown whiteboard type '%s'" % which) if not which.endswith('_whiteboard'): which = which + '_whiteboard' if which == "status_whiteboard": which = "whiteboard" if action != 'overwrite': wb = getattr(self, which, '').strip() tags = wb.split() sep = " " for t in tags: if t.endswith(","): sep = ", " if action == 'prepend': text = text + sep + wb elif action == 'append': text = wb + sep + text else: raise ValueError("Unknown whiteboard action '%s'" % action) updateargs = {which: text} vals = self.bugzilla.build_update(comment=comment, comment_private=private, **updateargs) log.debug("_updatewhiteboard: update=%s", vals) self.bugzilla.update_bugs(self.bug_id, vals)
def __getattr__(self, name): refreshed = False while True: if name in self.__dict__: return self.__dict__[name] # Check field aliases for newname, oldname in self.bugzilla.field_aliases: if name == oldname and newname in self.__dict__: return self.__dict__[newname] # Doing dir(bugobj) does getattr __members__/__methods__, # don't refresh for those if name.startswith("__") and name.endswith("__"): break if refreshed: break if 'id' not in self.__dict__: # This is fatal, since we have no ID to pass to refresh() # Can happen if a messed up include_fields is passed to query raise AttributeError("No bug ID cached for bug object") log.debug("Bug %i missing attribute '%s' - doing refresh()", self.bug_id, name) self.refresh() refreshed = True raise AttributeError("Bug object has no attribute '%s'" % name)
def setassignee(self, assigned_to=None, reporter=None, qa_contact=None, comment=None): ''' Set any of the assigned_to or qa_contact fields to a new bugzilla account, with an optional comment, e.g. setassignee(assigned_to='*****@*****.**') setassignee(qa_contact='*****@*****.**', comment='wwoods QA ftw') You must set at least one of the two assignee fields, or this method will throw a ValueError. Returns [bug_id, mailresults]. ''' if reporter: raise ValueError("reporter can not be changed") if not (assigned_to or qa_contact): raise ValueError("You must set one of assigned_to " " or qa_contact") vals = self.bugzilla.build_update(assigned_to=assigned_to, qa_contact=qa_contact, comment=comment) log.debug("setassignee: update=%s", vals) return self.bugzilla.update_bugs(self.bug_id, vals)
def close(self, resolution, dupeid=None, fixedin=None, comment=None, isprivate=False, private_in_it=False, nomail=False): '''Close this bug. Valid values for resolution are in bz.querydefaults['resolution_list'] For bugzilla.redhat.com that's: ['NOTABUG', 'WONTFIX', 'DEFERRED', 'WORKSFORME', 'CURRENTRELEASE', 'RAWHIDE', 'ERRATA', 'DUPLICATE', 'UPSTREAM', 'NEXTRELEASE', 'CANTFIX', 'INSUFFICIENT_DATA'] If using DUPLICATE, you need to set dupeid to the ID of the other bug. If using WORKSFORME/CURRENTRELEASE/RAWHIDE/ERRATA/UPSTREAM/NEXTRELEASE you can (and should) set 'new_fixed_in' to a string representing the version that fixes the bug. You can optionally add a comment while closing the bug. Set 'isprivate' to True if you want that comment to be private. ''' ignore = private_in_it ignore = nomail vals = self.bugzilla.build_update(comment=comment, comment_private=isprivate, resolution=resolution, dupe_of=dupeid, fixed_in=fixedin, status="CLOSED") log.debug("close: update=%s", vals) return self.bugzilla.update_bugs(self.bug_id, vals)
def _update_dict(self, newdict): ''' Update internal dictionary, in a way that ensures no duplicate entries are stored WRT field aliases ''' if self.bugzilla: self.bugzilla.post_translation({}, newdict) # pylint: disable=protected-access aliases = self.bugzilla._get_bug_aliases() # pylint: enable=protected-access for newname, oldname in aliases: if oldname not in newdict: continue if newname not in newdict: newdict[newname] = newdict[oldname] elif newdict[newname] != newdict[oldname]: log.debug("Update dict contained differing alias values " "d[%s]=%s and d[%s]=%s , dropping the value " "d[%s]", newname, newdict[newname], oldname, newdict[oldname], oldname) del(newdict[oldname]) for key in newdict.keys(): if key not in self._bug_fields: self._bug_fields.append(key) self.__dict__.update(newdict) if 'id' not in self.__dict__ and 'bug_id' not in self.__dict__: raise TypeError("Bug object needs a bug_id")
def deletecc(self, cclist, comment=None): ''' Removes the given email addresses from the CC list for this bug. ''' vals = self.bugzilla.build_update(comment=comment, cc_remove=cclist) log.debug("deletecc: update=%s", vals) return self.bugzilla.update_bugs(self.bug_id, vals)
def addcc(self, cclist, comment=None): ''' Adds the given email addresses to the CC list for this bug. cclist: list of email addresses (strings) comment: optional comment to add to the bug ''' vals = self.bugzilla.build_update(comment=comment, cc_add=cclist) log.debug("addcc: update=%s", vals) return self.bugzilla.update_bugs(self.bug_id, vals)
def addcomment(self, comment, private=False, timestamp=None, worktime=None, bz_gid=None): ''' Add the given comment to this bug. Set private to True to mark this comment as private. ''' ignore = timestamp ignore = bz_gid ignore = worktime vals = self.bugzilla.build_update(comment=comment, comment_private=private) log.debug("addcomment: update=%s", vals) return self.bugzilla.update_bugs(self.bug_id, vals)
def setstatus(self, status, comment=None, private=False, private_in_it=False, nomail=False): ''' Update the status for this bug report. Commonly-used values are ASSIGNED, MODIFIED, and NEEDINFO. To change bugs to CLOSED, use .close() instead. ''' ignore = private_in_it ignore = nomail vals = self.bugzilla.build_update(status=status, comment=comment, comment_private=private) log.debug("setstatus: update=%s", vals) return self.bugzilla.update_bugs(self.bug_id, vals)
def __init__(self, bugzilla, bug_id=None, dict=None, autorefresh=True): # pylint: disable=redefined-builtin # API had pre-existing issue that we can't change ('dict' usage) self.bugzilla = bugzilla self._bug_fields = [] self.autorefresh = autorefresh if bug_id: if not dict: dict = {} dict["id"] = bug_id if dict: log.debug("Bug(%s)", sorted(dict.keys())) self._update_dict(dict) self.weburl = bugzilla.url.replace('xmlrpc.cgi', 'show_bug.cgi?id=%i' % self.bug_id)
def __init__(self, bugzilla, **kwargs): self.bugzilla = bugzilla if 'dict' in kwargs and kwargs['dict']: log.debug("Bug(%s)" % sorted(kwargs['dict'].keys())) self._update_dict(kwargs['dict']) if 'bug_id' in kwargs: log.debug("Bug(%i)" % kwargs['bug_id']) setattr(self, 'id', kwargs['bug_id']) # Back compat for a previously handled param if 'autorefresh' in kwargs: del (kwargs["autorefresh"]) if not hasattr(self, 'id'): raise TypeError("Bug object needs a bug_id") self.weburl = bugzilla.url.replace('xmlrpc.cgi', 'show_bug.cgi?id=%i' % self.bug_id)
def __init__(self, bugzilla, **kwargs): self.bugzilla = bugzilla if 'dict' in kwargs and kwargs['dict']: log.debug("Bug(%s)", sorted(kwargs['dict'].keys())) self._update_dict(kwargs['dict']) if 'bug_id' in kwargs: log.debug("Bug(%i)", kwargs['bug_id']) setattr(self, 'id', kwargs['bug_id']) # Back compat for a previously handled param if 'autorefresh' in kwargs: del(kwargs["autorefresh"]) if not hasattr(self, 'id'): raise TypeError("Bug object needs a bug_id") self.weburl = bugzilla.url.replace('xmlrpc.cgi', 'show_bug.cgi?id=%i' % self.bug_id)
def _update_dict(self, newdict): ''' Update internal dictionary, in a way that ensures no duplicate entries are stored WRT field aliases ''' self.bugzilla.post_translation({}, newdict) for newname, oldname in self.bugzilla.field_aliases: if not oldname in newdict: continue if newname not in newdict: newdict[newname] = newdict[oldname] elif newdict[newname] != newdict[oldname]: log.debug("Update dict contained differing alias values " "d[%s]=%s and d[%s]=%s , dropping the value " "d[%s]", newname, newdict[newname], oldname, newdict[oldname], oldname) del(newdict[oldname]) self.__dict__.update(newdict)
def _update_dict(self, newdict): ''' Update internal dictionary, in a way that ensures no duplicate entries are stored WRT field aliases ''' self.bugzilla.post_translation({}, newdict) for newname, oldname in self.bugzilla.field_aliases: if not oldname in newdict: continue if newname not in newdict: newdict[newname] = newdict[oldname] elif newdict[newname] != newdict[oldname]: log.debug( "Update dict contained differing alias values " "d[%s]=%s and d[%s]=%s , dropping the value " "d[%s]", newname, newdict[newname], oldname, newdict[oldname], oldname) del (newdict[oldname]) self.__dict__.update(newdict)