def bug_from_uuid(bugdirs, uuid): error = None for bugdir in bugdirs.values(): try: bug = bugdir.bug_from_uuid(uuid) except libbe.bugdir.NoBugMatches as e: error = e else: return bug raise error
def main(): storage = libbe.storage.vcs.git.ExecGit(".") storage.connect() bugdir = libbe.bugdir.BugDir(storage, from_storage=True) uuids = bugdir.uuids() bugs = sorted([bugdir.bug_from_uuid(u) for u in uuids], key=lambda bug: bug.time) print("<bugs>") for bug in bugs: print(bug.xml(indent=2, show_comments=True).encode("utf-8")) print("</bugs>")
def bug_comment_from_user_id(bugdir, id): p = libbe.util.id.parse_user(bugdir, id) if not p['type'] in ['bug', 'comment']: raise libbe.command.UserError( '%s is a %s id, not a bug or comment id' % (id, p['type'])) if p['bugdir'] != bugdir.uuid: raise libbe.command.UserError("%s doesn't belong to this bugdir (%s)" % (id, bugdir.uuid)) bug = bugdir.bug_from_uuid(p['bug']) if 'comment' in p: comment = bug.comment_from_uuid(p['comment']) else: comment = bug.comment_root return (bug, comment)
def bug_comment_from_user_id(bugdir, id): p = libbe.util.id.parse_user(bugdir, id) if not p['type'] in ['bug', 'comment']: raise libbe.command.UserError( '%s is a %s id, not a bug or comment id' % (id, p['type'])) if p['bugdir'] != bugdir.uuid: raise libbe.command.UserError( "%s doesn't belong to this bugdir (%s)" % (id, bugdir.uuid)) bug = bugdir.bug_from_uuid(p['bug']) if 'comment' in p: comment = bug.comment_from_uuid(p['comment']) else: comment = bug.comment_root return (bug, comment)
def _merge_bugs(self, bugdirs, bugdir, bugs, params, accept_changes, accept_extra_strings, accept_comments=True): for new in bugs: try: old = bugdir.bug_from_uuid(new.alt_id) except KeyError: bugdir.append(new, update=True) yield new else: old.load_comments(load_full=True) old.merge( new, accept_changes=accept_changes, accept_extra_strings=accept_extra_strings, accept_comments=accept_comments, ) yield old
def _merge_bugs(self, bugdirs, bugdir, bugs, params, accept_changes, accept_extra_strings, accept_comments=True): for new in bugs: try: old = bugdir.bug_from_uuid(new.alt_id) except KeyError: bugdir.append(new, update=True) yield new else: old.load_comments(load_full=True) old.merge(new, accept_changes=accept_changes, accept_extra_strings=accept_extra_strings, accept_comments=accept_comments) yield old
def bugdir_bug_comment_from_user_id(bugdirs, id): p = libbe.util.id.parse_user(bugdirs, id) if not p['type'] in ['bugdir', 'bug', 'comment']: raise libbe.command.UserError( '{} is a {} id, not a bugdir, bug, or comment id'.format( id, p['type'])) if p['bugdir'] not in bugdirs: raise libbe.command.UserError( "{} doesn't belong to any bugdirs in {}".format( id, sorted(bugdirs.keys()))) bugdir = bugdirs[p['bugdir']] if p['bugdir'] != bugdir.uuid: raise libbe.command.UserError("%s doesn't belong to this bugdir (%s)" % (id, bugdir.uuid)) if 'bug' in p: bug = bugdir.bug_from_uuid(p['bug']) if 'comment' in p: comment = bug.comment_from_uuid(p['comment']) else: comment = bug.comment_root else: bug = comment = None return (bugdir, bug, comment)
def bugdir_bug_comment_from_user_id(bugdirs, id): p = libbe.util.id.parse_user(bugdirs, id) if not p['type'] in ['bugdir', 'bug', 'comment']: raise libbe.command.UserError( '{} is a {} id, not a bugdir, bug, or comment id'.format( id, p['type'])) if p['bugdir'] not in bugdirs: raise libbe.command.UserError( "{} doesn't belong to any bugdirs in {}".format( id, sorted(bugdirs.keys()))) bugdir = bugdirs[p['bugdir']] if p['bugdir'] != bugdir.uuid: raise libbe.command.UserError( "%s doesn't belong to this bugdir (%s)" % (id, bugdir.uuid)) if 'bug' in p: bug = bugdir.bug_from_uuid(p['bug']) if 'comment' in p: comment = bug.comment_from_uuid(p['comment']) else: comment = bug.comment_root else: bug = comment = None return (bugdir, bug, comment)
return e.matches common = e.common matches = e.matches root,residual = libbe.util.id.residual(common, fragment) p = libbe.util.id.parse_user(bugdirs, e.common) bug = None if matches == None: # fragment was complete, get a list of children uuids if p['type'] == 'bugdir': bugdir = bugdirs[p['bugdir']] matches = bugdir.uuids() common = bugdir.id.user() elif p['type'] == 'bug': if comments == False: return [fragment] bugdir = bugdirs[p['bugdir']] bug = bugdir.bug_from_uuid(p['bug']) matches = bug.uuids() common = bug.id.user() else: assert p['type'] == 'comment', p return [fragment] if p['type'] == 'bugdir': bugdir = bugdirs[p['bugdir']] child_fn = bugdir.bug_from_uuid elif p['type'] == 'bug': if comments == False: return[fragment] bugdir = bugdirs[p['bugdir']] if bug == None: bug = bugdir.bug_from_uuid(p['bug']) child_fn = bug.comment_from_uuid
return e.matches common = e.common matches = e.matches root, residual = libbe.util.id.residual(common, fragment) p = libbe.util.id.parse_user(bugdirs, e.common) bug = None if matches == None: # fragment was complete, get a list of children uuids if p['type'] == 'bugdir': bugdir = bugdirs[p['bugdir']] matches = bugdir.uuids() common = bugdir.id.user() elif p['type'] == 'bug': if comments == False: return [fragment] bugdir = bugdirs[p['bugdir']] bug = bugdir.bug_from_uuid(p['bug']) matches = bug.uuids() common = bug.id.user() else: assert p['type'] == 'comment', p return [fragment] if p['type'] == 'bugdir': bugdir = bugdirs[p['bugdir']] child_fn = bugdir.bug_from_uuid elif p['type'] == 'bug': if comments == False: return [fragment] bugdir = bugdirs[p['bugdir']] if bug == None: bug = bugdir.bug_from_uuid(p['bug']) child_fn = bug.comment_from_uuid
class Import_XML(libbe.command.Command): """Import comments and bugs from XML >>> import time >>> import StringIO >>> import libbe.bugdir >>> bd = libbe.bugdir.SimpleBugDir(memory=False) >>> io = libbe.command.StringInputOutput() >>> io.stdout = sys.stdout >>> ui = libbe.command.UserInterface(io=io) >>> ui.storage_callbacks.set_storage(bd.storage) >>> cmd = Import_XML(ui=ui) >>> ui.io.set_stdin('<be-xml><comment><uuid>c</uuid><body>This is a comment about a</body></comment></be-xml>') >>> ret = ui.run(cmd, {'comment-root':'/a'}, ['-']) >>> bd.flush_reload() >>> bug = bd.bug_from_uuid('a') >>> bug.load_comments(load_full=False) >>> comment = bug.comment_root[0] >>> print comment.body This is a comment about a <BLANKLINE> >>> comment.time <= int(time.time()) True >>> comment.in_reply_to is None True >>> ui.cleanup() >>> bd.cleanup() """ name = 'import-xml' def __init__(self, *args, **kwargs): libbe.command.Command.__init__(self, *args, **kwargs) self.options.extend([ libbe.command.Option( name='ignore-missing-references', short_name='i', help= "If any comment's <in-reply-to> refers to a non-existent comment, ignore it (instead of raising an exception)." ), libbe.command.Option( name='add-only', short_name='a', help= 'If any bug or comment listed in the XML file already exists in the bug repository, do not alter the repository version.' ), libbe.command.Option( name='preserve-uuids', short_name='p', help= 'Preserve UUIDs for trusted input (potential name collisions).' ), libbe.command.Option( name='comment-root', short_name='c', help= 'Supply a bug or comment ID as the root of any <comment> elements that are direct children of the <be-xml> element. If any such <comment> elements exist, you are required to set this option.', arg=libbe.command.Argument(name='comment-root', metavar='ID', completion_callback=libbe.command. util.complete_bug_comment_id)), ]) self.args.extend([ libbe.command.Argument(name='xml-file', metavar='XML-FILE'), ]) def _run(self, **params): bugdir = self._get_bugdir() writeable = bugdir.storage.writeable bugdir.storage.writeable = False if params['comment-root'] != None: croot_bug,croot_comment = \ libbe.command.util.bug_comment_from_user_id( bugdir, params['comment-root']) croot_bug.load_comments(load_full=True) if croot_comment.uuid == libbe.comment.INVALID_UUID: croot_comment = croot_bug.comment_root else: croot_comment = croot_bug.comment_from_uuid(croot_comment.uuid) new_croot_bug = libbe.bug.Bug(bugdir=bugdir, uuid=croot_bug.uuid) new_croot_bug.explicit_attrs = [] new_croot_bug.comment_root = copy.deepcopy(croot_bug.comment_root) if croot_comment.uuid == libbe.comment.INVALID_UUID: new_croot_comment = new_croot_bug.comment_root else: new_croot_comment = \ new_croot_bug.comment_from_uuid(croot_comment.uuid) for new in new_croot_bug.comments(): new.explicit_attrs = [] else: croot_bug, croot_comment = (None, None) if params['xml-file'] == '-': xml = self.stdin.read().encode(self.stdin.encoding) else: self._check_restricted_access(bugdir.storage, params['xml-file']) xml = libbe.util.encoding.get_file_contents(params['xml-file']) # parse the xml root_bugs = [] root_comments = [] version = {} be_xml = ElementTree.XML(xml) if be_xml.tag != 'be-xml': raise libbe.util.utility.InvalidXML( 'import-xml', be_xml, 'root element must be <be-xml>') for child in be_xml.getchildren(): if child.tag == 'bug': new = libbe.bug.Bug(bugdir=bugdir) new.from_xml(child, preserve_uuids=params['preserve-uuids']) root_bugs.append(new) elif child.tag == 'comment': new = libbe.comment.Comment(croot_bug) new.from_xml(child, preserve_uuids=params['preserve-uuids']) root_comments.append(new) elif child.tag == 'version': for gchild in child.getchildren(): if child.tag in ['tag', 'nick', 'revision', 'revision-id']: text = xml.sax.saxutils.unescape(child.text) text = text.decode('unicode_escape').strip() version[child.tag] = text else: print >> sys.stderr, 'ignoring unknown tag %s in %s' \ % (gchild.tag, child.tag) else: print >> sys.stderr, 'ignoring unknown tag %s in %s' \ % (child.tag, comment_list.tag) # merge the new root_comments if params['add-only'] == True: accept_changes = False accept_extra_strings = False else: accept_changes = True accept_extra_strings = True accept_comments = True if len(root_comments) > 0: if croot_bug == None: raise libbe.command.UserError( '--comment-root option is required for your root comments:\n%s' % '\n\n'.join([c.string() for c in root_comments])) try: # link new comments new_croot_bug.add_comments(root_comments, default_parent=new_croot_comment, ignore_missing_references= \ params['ignore-missing-references']) except libbe.comment.MissingReference, e: raise libbe.command.UserError(e) croot_bug.merge(new_croot_bug, accept_changes=accept_changes, accept_extra_strings=accept_extra_strings, accept_comments=accept_comments) # merge the new croot_bugs merged_bugs = [] old_bugs = [] for new in root_bugs: try: old = bugdir.bug_from_uuid(new.alt_id) except KeyError: old = None if old == None: bugdir.append(new) else: old.load_comments(load_full=True) old.merge(new, accept_changes=accept_changes, accept_extra_strings=accept_extra_strings, accept_comments=accept_comments) merged_bugs.append(new) old_bugs.append(old) # protect against programmer error causing data loss: if croot_bug != None: comms = [] for c in croot_comment.traverse(): comms.append(c.uuid) if c.alt_id != None: comms.append(c.alt_id) if croot_comment.uuid == libbe.comment.INVALID_UUID: root_text = croot_bug.id.user() else: root_text = croot_comment.id.user() for new in root_comments: assert new.uuid in comms or new.alt_id in comms, \ "comment %s (alt: %s) wasn't added to %s" \ % (new.uuid, new.alt_id, root_text) for new in root_bugs: if not new in merged_bugs: assert bugdir.has_bug(new.uuid), \ "bug %s wasn't added" % (new.uuid) # save new information bugdir.storage.writeable = writeable if croot_bug != None: croot_bug.save() for new in root_bugs: if not new in merged_bugs: new.save() for old in old_bugs: old.save()