(Steve Dougherty)
2013-08-30: Update repo list when creating with clone. Update repo list when creating with clone. Layer separation difficulties mean the local identity is resolved twice. This adds some USK functionality that didn't end up being used, yet still seems likely to be relevant. "USK@" is no longer considered part of the key.
diff --git a/.bugs/bugs b/.bugs/bugs --- a/.bugs/bugs +++ b/.bugs/bugs @@ -1,5 +1,5 @@ minimize dependencies | owner:Arne Babenhauserheide <bab@draketo.de>, open:True, id:0fc25f7b84f3e1fb89e9134a28eeabbe76bf054f, time:1372231529.45 -Problems using clone to create repositories.~ | owner:Steve Dougherty <steve@asksteved.com>, open:True, id:210c0e45adba5d500c6c5c00d750bfe43824cd3a, time:1375737210.02 +Problems using clone to create repositories.~ | owner:Steve Dougherty <steve@asksteved.com>, open:False, id:210c0e45adba5d500c6c5c00d750bfe43824cd3a, time:1375737210.02 Update USK hgrc paths | owner:Steve Dougherty <steve@asksteved.com>, open:True, id:2a4a5dfd11551f488701997054d6547ac586165a, time:1377872619.04 Add command to reinsert repo list. | owner:, open:False, id:2dcc27c850209062080906368530b4b9202271d0, time:1373407233.84 pull fails, because config.get_wot_identity requests self.defaults['DEFAULT_TRUSTER'] which is not in defaults. | owner:Arne Babenhauserheide <bab@draketo.de>, open:False, id:31beb672d404944a4655a546b21c95c7baa91002, time:1371735138.39 diff --git a/infocalypse/__init__.py b/infocalypse/__init__.py --- a/infocalypse/__init__.py +++ b/infocalypse/__init__.py @@ -345,6 +345,8 @@ from mercurial.i18n import _ import freenetrepo +from keys import strip_protocol + _freenetschemes = ('freenet', ) for _scheme in _freenetschemes: hg.schemes[_scheme] = freenetrepo @@ -592,10 +594,7 @@ def freenetpathtouri(ui, path, operation # TODO: Is this the only URL encoding that may happen? Why not use a more # semantically meaningful function? path = path.replace("%7E", "~").replace("%2C", ",") - if path.startswith("freenet://"): - path = path[len("freenet://"):] - elif path.startswith("freenet:"): - path = path[len("freenet:"):] + path = strip_protocol(path) # Guess whether it's WoT. This won't work if someone has chosen their WoT # nick to be "USK", but this is a corner case. Using --wot will still work. @@ -784,7 +783,15 @@ def freenetclone(orig, *args, **opts): #pushuri = pushuri[:namepartpos] + namepart opts["uri"] = pushuri repo = hg.repository(ui, ui.expandpath(source)) - infocalypse_create(ui, repo, **opts) + # TODO: A local identity is looked up for the push URI, + # but not returned, yet it is required to update configuration. + # Expecting dest to be something like freenet://name@key/reponame + local_identifier = strip_protocol(dest).split('/')[0] + + from wot_id import Local_WoT_ID + local_identity = Local_WoT_ID(local_identifier) + + infocalypse_create(ui, repo, local_identity, **opts) with repo.opener("hgrc", "a", text=True) as f: f.write("""[paths] diff --git a/infocalypse/commands.py b/infocalypse/commands.py --- a/infocalypse/commands.py +++ b/infocalypse/commands.py @@ -18,7 +18,7 @@ from validate import is_hex_string, is_f import os -from keys import parse_repo_path +from keys import parse_repo_path, USK def set_target_version(ui_, repo, opts, params, msg_fmt): @@ -47,12 +47,14 @@ def infocalypse_update_repo_list(ui, **o wot.update_repo_listing(ui, Local_WoT_ID(opts['wot'])) -def infocalypse_create(ui_, repo, **opts): - """ Create a new Infocalypse repository in Freenet. """ +def infocalypse_create(ui_, repo, local_identity=None, **opts): + """ Create a new Infocalypse repository in Freenet. + :type local_identity: WoT_ID + :param local_identity: If specified the new repository is associated with + that identity. + """ params, stored_cfg = get_config_info(ui_, opts) - insert_uri = '' - local_id = None if opts['uri'] and opts['wot']: ui_.warn("Please specify only one of --uri or --wot.\n") return @@ -68,18 +70,23 @@ def infocalypse_create(ui_, repo, **opts from wot_id import Local_WoT_ID - local_id = Local_WoT_ID(nick_prefix) + local_identity = Local_WoT_ID(nick_prefix) - insert_uri = local_id.insert_uri.clone() + insert_uri = local_identity.insert_uri.clone() insert_uri.name = repo_name insert_uri.edition = repo_edition # Before passing along into execute_create(). insert_uri = str(insert_uri) + else: + ui_.warn("Please set the insert key with either --uri or --wot.\n") + return + # This is a WoT repository. + if local_identity: # Add "vcs" context. No-op if the identity already has it. msg_params = {'Message': 'AddContext', - 'Identity': local_id.identity_id, + 'Identity': local_identity.identity_id, 'Context': 'vcs'} import fcp @@ -91,28 +98,22 @@ def infocalypse_create(ui_, repo, **opts if vcs_response['header'] != 'FCPPluginReply' or\ 'Replies.Message' not in vcs_response or\ vcs_response['Replies.Message'] != 'ContextAdded': - ui_.warn("Failed to add context. Got {0}\n.".format(vcs_response)) - return - - else: - ui_.warn("Please set the insert key with either --uri or --wot.\n") - return + raise util.Abort("Failed to add context. Got {0}\n.".format( + vcs_response)) set_target_version(ui_, repo, opts, params, "Only inserting to version(s): %s\n") params['INSERT_URI'] = insert_uri inserted_to = execute_create(ui_, repo, params, stored_cfg) - if inserted_to and opts['wot']: + if inserted_to and local_identity: # TODO: Would it be friendlier to include the nickname as well? # creation returns a list of request URIs; use the first. - stored_cfg.set_wot_identity(inserted_to[0], local_id) + stored_cfg.set_wot_identity(inserted_to[0], local_identity) Config.to_file(stored_cfg) - # TODO: Imports don't go out of scope, right? The variables - # from the import are only visible in the function, so yes. import wot - wot.update_repo_listing(ui_, local_id) + wot.update_repo_listing(ui_, local_identity) def infocalypse_copy(ui_, repo, **opts): diff --git a/infocalypse/keys.py b/infocalypse/keys.py --- a/infocalypse/keys.py +++ b/infocalypse/keys.py @@ -8,23 +8,17 @@ class USK: # Expecting USK@key/name/edition assert len(components) == 3 - self.key = components[0] + self.key = components[0].split('@')[1] self.name = components[1] self.edition = int(components[2]) # TODO: Is stripping "freenet://" appropriate? - if self.key.startswith('freenet:'): - self.key = self.key[len('freenet:'):] - elif self.key.startswith('freenet://'): - self.key = self.key[len('freenet://'):] + self.key = strip_protocol(self.key) def get_repo_name(self): """ Return name with the redundancy level, if any, removed. - # TODO: tests. Use in detecting duplicate names. (Also - # determining repo names from URI.) - >>> USK('USK@.../name/5').get_repo_name() 'name' >>> USK('USK@.../name.R1/5').get_repo_name() @@ -40,11 +34,20 @@ class USK: return self.name[:-3] return self.name + def get_public_key_hash(self): + """ + Return the public key hash component of the key. + + >>> USK('USK@wHllqvhRlGLZZrXwqgsFFGbv2V9S33lq~-MTIN2FvOw,mN0trI6Yx1W6ecyERrVxANHQmA3vJwk88UEHW3qCsRA,AQACAAE/vcs/22').get_public_key_hash() + 'wHllqvhRlGLZZrXwqgsFFGbv2V9S33lq~-MTIN2FvOw' + """ + return self.key.split(',')[0] + def clone(self): return USK(str(self)) def __str__(self): - return '%s/%s/%s' % (self.key, self.name, self.edition) + return 'USK@%s/%s/%s' % (self.key, self.name, self.edition) def __repr__(self): return "USK('%s')" % str(self) @@ -95,3 +98,17 @@ def parse_repo_path(path, assume_redunda parts[1] += '.R1' return '/'.join(parts) + + +def strip_protocol(uri): + """ + Return the uri without "freenet:" or "freenet://" at the start, if present. + + >>> strip_protocol('freenet:USK@.../test/0') + 'USK@.../test/0' + """ + if uri.startswith('freenet:'): + return uri[len('freenet:'):] + elif uri.startswith('freenet://'): + return uri[len('freenet://'):] + return uri