(Steve Dougherty)
2013-06-18: Remove redundant full-key local identity matching. Remove redundant full-key local identity matching. Partial key matching works for full key matching too.
diff --git a/infocalypse/__init__.py b/infocalypse/__init__.py
--- a/infocalypse/__init__.py
+++ b/infocalypse/__init__.py
@@ -353,7 +353,7 @@ from wikicmds import execute_wiki, execu
from arccmds import execute_arc_create, execute_arc_pull, execute_arc_push, \
execute_arc_reinsert
-from config import read_freesite_cfg
+from config import read_freesite_cfg, Config
from validate import is_hex_string, is_fms_id
def set_target_version(ui_, repo, opts, params, msg_fmt):
@@ -555,6 +555,13 @@ def infocalypse_pull(ui_, repo, **opts):
# Hmmmm... can't really implement rev.
execute_pull(ui_, repo, params, stored_cfg)
+
+def infocalypse_pull_request(ui, repo, **opts):
+ if not opts['wot']:
+ ui.warning("Who do you want to send the pull request to? Set --wot.")
+ return
+
+
def infocalypse_push(ui_, repo, **opts):
""" Push to an Infocalypse repository in Freenet. """
params, stored_cfg = get_config_info(ui_, opts)
@@ -798,6 +805,20 @@ def infocalypse_setupwot(ui_, **opts):
wot.execute_setup_wot(ui_, opts)
+# TODO: Should Freemail setup also be part of fn-setup?
+# TODO: Should there be per-Identity config? Then each one would have a list
+# of repos and optionally a Freemail password.
+# Nah, FMS config is global.
+def infocalypse_setupfreemail(ui, **opts):
+ if 'truster' in opts:
+ identity = opts['truster']
+ else:
+ cfg = Config().from_ui(ui)
+ identity = cfg.defaults['TRUSTER']
+ import wot
+ # TODO: Should this be part of the normal fn-setup?
+ wot.execute_setup_freemail(ui, identity)
+
#----------------------------------------------------------"
def do_archive_create(ui_, opts, params, stored_cfg):
""" fn-archive --create."""
@@ -920,6 +941,11 @@ cmdtable = {
+ AGGRESSIVE_OPT,
"[options]"),
+ "fn-pull-request": (infocalypse_pull_request,
+ WOT_OPTS +
+ FCP_OPTS,
+ "--wot id@key/repo"),
+
"fn-push": (infocalypse_push,
[('', 'uri', '', 'insert URI to push to'),
# Buggy. Not well thought out.
@@ -1025,6 +1051,12 @@ cmdtable = {
WOT_OPTS,
"[options]"),
+ "fn-setupfreemail": (infocalypse_setupfreemail,
+ [('', 'password', '', 'Freemail password')]
+ + WOT_OPTS
+ + FCP_OPTS,
+ "[--truster nick@key] --password <password>"),
+
"fn-archive": (infocalypse_archive,
[('', 'uri', '', 'Request URI for --pull, Insert URI ' +
'for --create, --push'),
diff --git a/infocalypse/wot.py b/infocalypse/wot.py
--- a/infocalypse/wot.py
+++ b/infocalypse/wot.py
@@ -2,6 +2,32 @@ import fcp
from config import Config
import xml.etree.ElementTree as ET
from defusedxml.ElementTree import fromstring
+import smtplib
+from base64 import b32encode
+from fcp.node import base64decode
+
+
+def send_pull_request(ui, from_identity, to_identity):
+ local_identity = resolve_local_identity(ui, from_identity)
+ target_identity = resolve_identity(ui, from_identity, to_identity)
+
+ if local_identity is None or target_identity is None:
+ # Error.
+ return
+
+ from_address = to_freemail_address(local_identity)
+ to_address = to_freemail_address(to_identity)
+
+ if from_address is None or to_address is None:
+ ui.warn("At least one of {0} and {2} is not using Freemail."
+ .format(from_identity['Nickname'], to_identity['Nickname']))
+ return
+
+ # TODO: Use FCP host; default port.
+ smtp = smtplib.SMTP()
+ # TODO: Where to configure Freemail password?
+ smtp.login(from_address, )
+ smtp.sendmail()
def update_repo_listing(ui, for_identity):
@@ -86,6 +112,12 @@ def execute_setup_wot(ui_, opts):
Config.to_file(cfg)
+def execute_setup_freemail(ui, identity, password):
+
+ # TODO: get truster from config; check password.
+ pass
+
+
def resolve_local_identity(ui, identity):
"""
Mercurial ui for error messages.
@@ -109,19 +141,6 @@ def resolve_local_identity(ui, identity)
ui.warn("Unexpected reply. Got {0}\n.".format(response))
return
- prefix = 'Replies.Identity'
- id_num = -1
- # Go by full key instead.
- if nickname_prefix is None:
- for item in response.iteritems():
- if item[1] == key_prefix:
- # Assuming identities will always be unique.
- id_num = item[0][len(prefix):]
- return read_local_identity(response, id_num)
-
- ui.warn("No identity found with key '{0}'.\n".format(key_prefix))
- return
-
# Find nicknames starting with the supplied nickname prefix.
prefix = 'Replies.Nickname'
# Key: nickname, value (id_num, public key hash).
@@ -288,3 +307,22 @@ def parse_name(identity):
key_prefix = split[1]
return nickname_prefix, key_prefix
+
+
+def to_freemail_address(identity):
+ """
+ Return a Freemail address to contact the given identity if it has a
+ Freemail context. Return None if it does not have a Freemail context.
+ """
+
+ # Freemail addresses encode the public key hash with base32 instead of
+ # base64 as WoT does. This is to be case insensitive because email
+ # addresses are not case sensitive, so some clients may mangle case.
+ # See https://github.com/zidel/Freemail/blob/v0.2.2.1/docs/spec/spec.tex#L32
+
+ for item in identity.iteritem():
+ if item[1] == 'Freemail' and item[0].startswith('Context'):
+ return identity['Nickname'] + '@' + b32encode(base64decode(
+ identity['Identity'])) + 'freemail'
+
+ return None