infocalypse
 
(Steve Dougherty)
2013-06-25: Add freenet://WoT path resolution.

Add freenet://WoT path resolution.

diff --git a/infocalypse/__init__.py b/infocalypse/__init__.py
--- a/infocalypse/__init__.py
+++ b/infocalypse/__init__.py
@@ -552,13 +552,29 @@ extensions.wrapfunction(discovery, 'find
 
 # wrap the commands
 
-def freenetpathtouri(path):
+
+def freenetpathtouri(ui, path, pull=True):
+    # 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://"):
-        return path[len("freenet://"):]
-    if path.startswith("freenet:"):
-        return path[len("freenet:"):]
-    return path
+        path = path[len("freenet://"):]
+    elif path.startswith("freenet:"):
+        path = path[len("freenet:"):]
+
+    # 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.
+    if not path.startswith("USK"):
+        import wot
+        if pull:
+            cfg = Config()
+            cfg.from_ui(ui)
+            truster = cfg.defaults['DEFAULT_TRUSTER']
+            return wot.resolve_pull_uri(ui, path, truster)
+        else:
+            return wot.resolve_push_uri(ui, path)
+    else:
+        return path
 
 def freenetpull(orig, *args, **opts):
     def parsepushargs(ui, repo, path=None):
@@ -578,7 +594,7 @@ def freenetpull(orig, *args, **opts):
     # only act differently, if the target is an infocalypse repo.
     if not isfreenetpath(path):
         return orig(*args, **opts)
-    uri = freenetpathtouri(path)
+    uri = freenetpathtouri(ui, path)
     opts["uri"] = uri
     opts["aggressive"] = True # always search for the latest revision.
     return infocalypse_pull(ui, repo, **opts)
@@ -615,7 +631,7 @@ def freenetpush(orig, *args, **opts):
     # only act differently, if the target is an infocalypse repo.
     if not isfreenetpath(path):
         return orig(*args, **opts)
-    uri = freenetpathtouri(path)
+    uri = freenetpathtouri(ui, path, pull=False)
     # if the uri is the short form (USK@/name/#), generate the key and preprocess the uri.
     if uri.startswith("USK@/"):
         ui.status("creating a new key for the repo. For a new repo with an existing key, use clone.\n")
diff --git a/infocalypse/commands.py b/infocalypse/commands.py
--- a/infocalypse/commands.py
+++ b/infocalypse/commands.py
@@ -189,22 +189,10 @@ def infocalypse_pull(ui_, repo, **opts):
             truster = stored_cfg.get_wot_identity(
                 stored_cfg.get_dir_insert_uri(repo.root))
 
-        # Expecting <id stuff>/reponame
-        wot_id, repo_name = opts['wot'].split('/', 1)
+        request_uri = wot.resolve_pull_uri(ui_, opts['wot'], truster)
 
-        # TODO: How to handle redundancy? Does Infocalypse automatically try
-        # an R0 if an R1 fails?
-
-        repositories = wot.read_repo_listing(ui_, truster, wot_id)
-
-        if repositories is None:
+        if request_uri is None:
             return
-
-        if repo_name not in repositories:
-            ui_.warn("Could not find repository named \"{0}\".\n".format(repo_name))
-            return
-
-        request_uri = repositories[repo_name]
     else:
         request_uri = opts['uri']
 
diff --git a/infocalypse/wot.py b/infocalypse/wot.py
--- a/infocalypse/wot.py
+++ b/infocalypse/wot.py
@@ -100,6 +100,58 @@ def read_repo_listing(ui, truster, ident
 
     return repositories
 
+
+def resolve_pull_uri(ui, path, truster):
+        """
+        Return a pull URI for the given path.
+        Print an error message and return None on failure.
+        TODO: Is it appropriate to outline possible errors?
+        Possible failures are being unable to fetch a repo list for the given
+        identity, which may be a fetch failure or being unable to find the
+        identity, and not finding the requested repo in the list.
+
+        :param ui: For feedback.
+        :param path: path describing a repo: nick@key/reponame
+        :param truster: identity whose trust list to use.
+        :return:
+        """
+        # Expecting <id stuff>/reponame
+        wot_id, repo_name = path.split('/', 1)
+
+        # TODO: How to handle redundancy? Does Infocalypse automatically try
+        # an R0 if an R1 fails?
+
+        repositories = read_repo_listing(ui, truster, wot_id)
+
+        if repositories is None:
+            return
+
+        if repo_name not in repositories:
+            ui.warn("Could not find repository named \"{0}\".\n"
+                    .format(repo_name))
+            return
+
+        return repositories[repo_name]
+
+
+def resolve_push_uri(ui, path):
+    """
+    Return a push URI for the given path.
+    Print an error message and return None on failure.
+
+    :param ui: For feedback.
+    :param path: path describing a repo: nick@key/reponame,
+    where the identity is a local one. (Such that the insert URI is known.)
+    """
+    # Expecting <id stuff>/reponame
+    # TODO: Duplcate with resolve_pull
+    wot_id, repo_name = path.split('/', 1)
+
+    local_id = resolve_local_identity(ui, )
+
+    # Get edition by checking one's own repo list.
+    repositories = read_repo_listing(ui, )
+
 # Support for querying WoT for own identities and identities meeting various
 # criteria.
 # TODO: "cmds" suffix to module name to fit fms, arc, inf?