(Steve Dougherty)
2013-06-24: Update identity search to reflect LCWoT changes. Update identity search to reflect LCWoT changes. It is no longer an error for more than MaxIdentites to match. There is a field containing the number of matched identities. It also became clear that nicknames require a wildcard to match as with startswith(), whereas the ID uses startswith() already.
diff --git a/infocalypse/wot.py b/infocalypse/wot.py --- a/infocalypse/wot.py +++ b/infocalypse/wot.py @@ -254,12 +254,18 @@ def resolve_identity(ui, truster, identi # TODO: LCWoT allows limiting by context, but how to make sure otherwise? # TODO: Should this manually ensure an identity has a vcs context # otherwise? + + # LCWoT can have * to allow a wildcard match, but a wildcard alone is not + # allowed. See Lucine Term Modifiers documentation. The nickname uses + # this syntax but the ID is inherently startswith(). params = {'Message': 'GetIdentitiesByPartialNickname', 'Truster': truster, - 'PartialNickname': nickname_prefix, + 'PartialNickname': + nickname_prefix + '*' if nickname_prefix else '', 'PartialID': key_prefix, - 'MaxIdentities': 1, # Match must be unambiguous. + 'MaxIdentities': 2, 'Context': 'vcs'} + response = \ node.fcpPluginMessage(async=False, plugin_name="plugins.WebOfTrust.WebOfTrust", @@ -270,25 +276,21 @@ def resolve_identity(ui, truster, identi ui.warn('Unexpected reply. Got {0}\n'.format(response)) return elif response['Replies.Message'] == 'Identities': - # TODO: What if no identities matched? - return read_identity(response, 0) - elif response['Replies.Message'] == 'Error': - # The difficulty here is that the message type is Error for both an - # unrecognized message type and ambiguous search terms. - # TODO: This seems likely to break - the Description seems intended - # for human readers and will probably change. - if response['Replies.Description'].startswith('Number of matched'): - # Supported version of LCWoT - terms ambiguous. - ui.warn("'{0}@{1}' is ambiguous.".format(nickname_prefix, - key_prefix)) + matches = response['Replies.IdentitiesMatched'] + if matches == 0: + ui.warn("No identities match '{0}'\n".format(identity)) return - elif response['Replies.Description'].startswith('Unknown message') or \ - response['Replies.Description'].startswith('Could not match'): - # Not supported; check for exact identity. - ui.warn('Searching by partial nickname/key not supported.') + elif matches == 1: + return read_identity(response, 0) + else: + ui.warn("'{0}' is ambiguous.\n".format(identity)) + return - # Attempt to search failed - check for exact key. Here key_prefix must be - # a complete key for the lookup to succeed. + # Partial matching not supported, or unknown truster. The only difference + # in the errors is human-readable, so just try the exact match. + assert response['Replies.Message'] == 'Error' + + # key_prefix must be a complete key for the lookup to succeed. params = {'Message': 'GetIdentity', 'Truster': truster, 'Identity': key_prefix} @@ -297,6 +299,11 @@ def resolve_identity(ui, truster, identi plugin_name="plugins.WebOfTrust.WebOfTrust", plugin_params=params)[0] + if response['Replies.Message'] == 'Error': + # Searching by exact public key hash, not matching. + ui.warn("No such identity '{0}'.\n".format(identity)) + return + # There should be only one result. # Depends on https://bugs.freenetproject.org/view.php?id=5729 return read_identity(response, 0)