import re, simplejson
-from allmydata.util import keyutil, base32
+from allmydata.util import keyutil, base32, rrefutil
def make_index(ann, key_s):
"""Return something that can be used as an index (e.g. a tuple of
strings), such that two messages that refer to the same 'thing' will have
the same index. This is a tuple of (service-name, signing-key, None) for
- signed announcements, or (service-name, None, tubid) for unsigned
+ signed announcements, or (service-name, None, tubid_s) for unsigned
announcements."""
service_name = str(ann["service-name"])
if key_s:
return (service_name, key_s, None)
else:
- tubid = get_tubid_string_from_ann(ann)
- return (service_name, None, tubid)
+ tubid_s = get_tubid_string_from_ann(ann)
+ return (service_name, None, tubid_s)
def get_tubid_string_from_ann(ann):
return get_tubid_string(str(ann.get("anonymous-storage-FURL")
assert type(ver) is str
assert type(oldest) is str
ann = {"version": 0,
- "nickname": nickname.decode("utf-8"),
+ "nickname": nickname.decode("utf-8", "replace"),
"app-versions": {},
"my-version": ver,
"oldest-supported": oldest,
key_vs = claimed_key_vs
ann = simplejson.loads(msg.decode("utf-8"))
return (ann, key_vs)
+
+class SubscriberDescriptor:
+ """This describes a subscriber, for status display purposes. It contains
+ the following attributes:
+
+ .service_name: what they subscribed to (string)
+ .when: time when they subscribed (seconds since epoch)
+ .nickname: their self-provided nickname, or "?" (unicode)
+ .version: their self-provided version (string)
+ .app_versions: versions of each library they use (dict str->str)
+ .remote_address: the external address from which they connected (string)
+ .tubid: for subscribers connecting with Foolscap, their tubid (string)
+ """
+
+ def __init__(self, service_name, when,
+ nickname, version, app_versions,
+ remote_address, tubid):
+ self.service_name = service_name
+ self.when = when
+ self.nickname = nickname
+ self.version = version
+ self.app_versions = app_versions
+ self.remote_address = remote_address
+ self.tubid = tubid
+
+class AnnouncementDescriptor:
+ """This describes an announcement, for status display purposes. It
+ contains the following attributes, which will be empty ("" for
+ strings) if the client did not provide them:
+
+ .when: time the announcement was first received (seconds since epoch)
+ .index: the announcements 'index', a tuple of (string-or-None).
+ The server remembers one announcement per index.
+ .canary: a Referenceable on the announcer, so the server can learn
+ when they disconnect (for the status display)
+ .announcement: raw dictionary of announcement data
+ .service_name: which service they are announcing (string)
+ .version: 'my-version' portion of announcement (string)
+ .nickname: their self-provided nickname, or "" (unicode)
+ .serverid: the server identifier. This is a pubkey (for V2 clients),
+ or a tubid (for V1 clients).
+ .connection_hints: where they listen (list of strings) if the
+ announcement included a key for
+ 'anonymous-storage-FURL', else an empty list.
+ """
+
+ def __init__(self, when, index, canary, ann_d):
+ self.when = when
+ self.index = index
+ self.canary = canary
+ self.announcement = ann_d
+ self.service_name = ann_d["service-name"]
+ self.version = ann_d.get("my-version", "")
+ self.nickname = ann_d.get("nickname", u"")
+ (service_name, key_s, tubid_s) = index
+ self.serverid = key_s or tubid_s
+ furl = ann_d.get("anonymous-storage-FURL")
+ if furl:
+ self.connection_hints = rrefutil.connection_hints_for_furl(furl)
+ else:
+ self.connection_hints = []