def decode_progress(self, bencoded_data: bytes) -> list: """Decodes string of bencoded progress output to list of updates Duplicates logic decoding logic from `SubProcessWidget.readStdout` and `SubProcessWidget.setProgress` which would be good to factor out. bdecode requires bencoded bytes and bencoded_data should BE bytes but doesn't appear to be. """ updates = [] for line in bencoded_data.split("\n"): if line.startswith(SUB_PROGRESS): # bdecode needs bytes, but we need to snip off the leading SUB_PROGRESS first n, transport_activity, task_info = bencode.bdecode( line[len(SUB_PROGRESS):].encode('utf-8')) if n == 1000000 and not task_info: task_message = "Finished!" else: # task_info will be a list of byte-strings, so join and then decode task_message = b" / ".join(task_info).decode("utf-8") # transport_activity will be bytes too... updates.append( (n, transport_activity.decode('utf-8'), task_message)) # Now we'll return a list of lines like: (0, '', 'Finding revisions / 0/2') return updates
def test_bittorrent_b_encode_unicode(self): # Encoding should ALWAYS give bytes and expects bytes BUT our routines convert self.assertEqual(b"l7:versione", bittorrent_b_encode_unicode(["version"])) # self.assertEqual(b"l3:add3:\u1234e", bittorrent_b_encode_unicode(["add", "\u1234"])) result = bittorrent_b_encode_unicode(["add", "\u1234"]) self.assertEqual(b'l3:add3:\xe1\x88\xb4e', result) # Now check the '\u1234' comes back when it's a string... u = bencode.bdecode(result) self.assertIsInstance(u, list) self.assertEqual("\u1234", u[1].decode('utf-8'))
def get_revision_paths(self, revnum): """See LogCache.get_revision_paths.""" self.mutter("get-revision-paths %d", revnum) ret = {} try: db = bencode.bdecode(self.db[b"paths/%d" % revnum]) except KeyError: raise KeyError("missing revision paths for %d" % revnum) for key, v in db.iteritems(): try: (action, cp, cr, kind) = v except ValueError: (action, cp, cr) = v kind = NODE_UNKNOWN if cp == b"" and cr == -1: cp = None else: cp = cp.decode('utf-8') ret[key.decode('utf-8')] = (action, cp, cr, kind) return ret
class HgMappingv1(foreign.VcsMapping): """Class that maps between Bazaar and Mercurial semantics.""" experimental = False revid_prefix = "hg-v1" def __init__(self): super(HgMappingv1, self).__init__(foreign_hg) def __str__(self): return self.revid_prefix @classmethod def revision_id_foreign_to_bzr(cls, revision_id): """See VcsMapping.revision_id_foreign_to_bzr.""" if revision_id == mercurial.node.nullid: return _mod_revision.NULL_REVISION if len(revision_id) == 20: hexhgrevid = hex(revision_id) elif len(revision_id) == 40: hexhgrevid = revision_id else: raise AssertionError("Invalid hg id %r" % revision_id) return "%s:%s" % (cls.revid_prefix, hexhgrevid) @classmethod def revision_id_bzr_to_foreign(cls, revision_id): """See VcsMapping.revision_id_foreign_to_bzr.""" if revision_id == _mod_revision.NULL_REVISION: return mercurial.node.nullid, cls() if not revision_id.startswith("%s:" % cls.revid_prefix): raise errors.InvalidRevisionId(revision_id, cls) return bin(revision_id[len(cls.revid_prefix) + 1:]), cls() @classmethod def generate_file_id(self, path): """Create a synthetic file_id for an hg file.""" if isinstance(path, text_type): path = path.encode("utf-8") if path == "": return "TREE_ROOT" return "hg:" + escape_path(path) @classmethod def parse_file_id(self, fileid): """Parse a file id.""" assert isinstance(fileid, str) if fileid == b'TREE_ROOT': return "" if not fileid.startswith(b"hg:"): raise ValueError('invalid file id %r' % fileid) return unescape_path(fileid[len("hg:"):]) def export_revision(self, rev, lossy=True, fileids={}): user = rev.committer time = rev.timestamp timezone = -rev.timezone extra = {} manifest = None for name, value in rev.properties.iteritems(): if name == 'manifest': manifest = mercurial.node.bin(value) elif name.startswith("hg:extra:"): extra[name[len("hg:extra:"):]] = base64.b64decode(value) elif name == 'rebase-of': try: hgid, mapping = self.revision_id_bzr_to_foreign(value) except errors.InvalidRevisionId: extra["bzr-revprop-" + name] = value.encode("utf-8") else: assert len(hgid) == 20 extra['rebase_source'] = mercurial.node.hex(hgid) elif name == 'converted-from': if value.count('\n') <= 1: continue extra['convert_revision'] = generate_convert_revision( value.splitlines()[-2]) else: assert not ":" in name extra["bzr-revprop-" + name] = value.encode("utf-8") if not lossy and not rev.revision_id.startswith(self.revid_prefix + ":"): extra["bzr-mapping"] = str(self) extra["bzr-revision-id"] = rev.revision_id if len(rev.parent_ids) > 2: extra["bzr-extra-parents"] = " ".join(rev.parent_ids[2:]) if fileids: extra["bzr-fileids"] = bencode.bencode(sorted(fileids.items())) desc = rev.message return (manifest, user, (time, timezone), desc, extra) def import_revision(self, revid, parent_ids, hgrevid, manifest, user, (time, timezone), desc, extra): result = foreign.ForeignRevision(hgrevid, self, revid) result.parent_ids = parent_ids if type(desc) != unicode: raise AssertionError result.message = desc result.inventory_sha1 = "" result.timezone = -timezone result.timestamp = time if type(user) != unicode: raise AssertionError result.committer = user result.properties = {'manifest': mercurial.node.hex(manifest)} fileids = {} for name, value in extra.iteritems(): if name.startswith("bzr-revprop-"): result.properties[name[len("bzr-revprop-")]] = value.decode( "utf-8") elif name == "bzr-extra-parents": result.parent_ids += tuple(value.split(" ")) elif name == "bzr-revision-id": result.revision_id = value elif name == "bzr-fileids": fileids = dict(bencode.bdecode(value)) elif name == "convert_revision": result.properties['converted-from'] = convert_converted_from( value) elif name == "rebase_source": result.properties[ 'rebase-of'] = self.revision_id_foreign_to_bzr(value) elif name.startswith("bzr-"): trace.mutter("unknown bzr extra %s: %r", name, value) else: result.properties["hg:extra:" + name] = base64.b64encode(value) if len(hgrevid) == 40: hghexrevid = hgrevid else: hghexrevid = mercurial.node.hex(hgrevid) result.properties['converted-from'] = \ result.properties.get('converted-from', '') + \ "hg %s\n" % hghexrevid return result, fileids
def get_revprops(self, revnum): """See LogCache.get_revprops.""" self.mutter("get-revision-properties %d", revnum) ret = bencode.bdecode(self.db["revprops/%d" % revnum]) return (ret[0], bool(ret[1]))