def GetBuddyByPublicKey(self, key): buddy = self._buddies_by_pubkey.get(key) if buddy is not None: if buddy.props.valid: return buddy.object_path() keyid = pubkey_to_keyid(key) buddy = self._buddies.get('keyid/' + keyid) if buddy is not None: if buddy.props.valid: return buddy.object_path() raise NotFoundError("The buddy was not found.")
def __init__(self, ps, bus): """Initialize the ShellOwner instance ps -- presenceservice.PresenceService object bus -- a connection to the D-Bus session bus Retrieves initial property values from the profile module. Loads the buddy icon from file as well. XXX note: no error handling on that calls GenericOwner.__init__ """ client = gconf.client_get_default() profile = get_profile() key_hash = profile.privkey_hash key = profile.pubkey color = client.get_string("/desktop/sugar/user/color") tags = client.get_string("/desktop/sugar/user/tags") nick = client.get_string("/desktop/sugar/user/nick") if not isinstance(nick, unicode): nick = unicode(nick, 'utf-8') GenericOwner.__init__(self, ps, bus, 'keyid/' + psutils.pubkey_to_keyid(key), key=key, nick=nick, color=color, icon=None, key_hash=key_hash, tags=tags) # Ask to get notifications on Owner object property changes in the # shell. If it's not currently running, no problem - we'll get the # signals when it does run for (signal, cb) in (('IconChanged', self._icon_changed_cb), ('ColorChanged', self._color_changed_cb), ('NickChanged', self._nick_changed_cb), ('TagsChanged', self._tags_changed_cb), ('CurrentActivityChanged', self._cur_activity_changed_cb)): self._bus.add_signal_receiver(cb, signal_name=signal, dbus_interface=self._SHELL_OWNER_INTERFACE, bus_name=self._SHELL_SERVICE, path=self._SHELL_PATH) # we already know our own nick, color, key self._awaiting = None
def sync_friends(self, keys): if self._friends_channel is None or self._subscribe_channel is None: # not ready yet return client = gconf.client_get_default() server = client.get_string("/desktop/sugar/collaboration/jabber_server") friends_handles = set() friends = set() for key in keys: identity = psutils.pubkey_to_keyid(key) # this assumes that all our friends are on the same server as us jid = '%s@%s' % (identity, server) friends.add(jid) def error_syncing_friends(e): _logger.debug('error syncing friends: %r' % e) def friends_group_synced(): _logger.debug('friends group synced') def friends_subscribed(): _logger.debug('friends subscribed') def got_friends_handles(handles): friends_handles.update(handles) # subscribe friends self._subscribe_channel[CHANNEL_INTERFACE_GROUP].AddMembers( friends_handles, "New friend", reply_handler=friends_subscribed, error_handler=error_syncing_friends) # add friends to the "Friends" group self._friends_channel[CHANNEL_INTERFACE_GROUP].AddMembers( friends_handles, "New friend", reply_handler=friends_group_synced, error_handler=error_syncing_friends) self._conn[CONN_INTERFACE].RequestHandles( HANDLE_TYPE_CONTACT, friends, reply_handler=got_friends_handles, error_handler=error_syncing_friends)
def __init__(self, ps, bus, test_num, randomize): self._cp = ConfigParser() self._section = "Info" self._test_activities = [] self._test_cur_act = "" self._change_timeout = 0 self._cfg_file = os.path.join(env.get_profile_path(), 'test-buddy-%d' % test_num) (pubkey, privkey, registered) = self._load_config() if not pubkey or not len(pubkey) or not privkey or not len(privkey): (pubkey, privkey) = _get_new_keypair(test_num) if not pubkey or not privkey: raise RuntimeError("Couldn't get or create test buddy keypair") self._save_config(pubkey, privkey, registered) privkey_hash = util.printable_hash(util._sha_data(privkey)) nick = _get_random_name() from sugar.graphics import xocolor color = xocolor.XoColor().to_string() icon = _get_random_image() _logger.debug("pubkey is %s" % pubkey) GenericOwner.__init__(self, ps, bus, 'keyid/' + pubkey_to_keyid(pubkey), key=pubkey, nick=nick, color=color, icon=icon, registered=registered, key_hash=privkey_hash) # we already know our own nick, color, key self._awaiting = None # Only do the random stuff if randomize is true if randomize: self._ps.connect('connection-status', self._ps_connection_status_cb)
print "Running test_psutils..." from psutils import escape_identifier, pubkey_to_keyid assert pubkey_to_keyid('abc') == 'a9993e364706816aba3e25717850c26c9cd0d89d' assert escape_identifier('') == '_' assert escape_identifier('_') == '_5f' assert escape_identifier('1') == '_31' assert escape_identifier('a1') == 'a1' assert escape_identifier('1a') == '_31a' assert escape_identifier("0123abc_xyz\x01\xff") == '_30123abc_5fxyz_01_ff'
def __init__(self): self._next_object_id = 0 # all Buddy objects # identifier -> Buddy, GC'd when no more refs exist self._buddies = WeakValueDictionary() # the online buddies for whom we know the full public key # base64 public key -> Buddy self._buddies_by_pubkey = {} # The online buddies (those who're available via some CM) # TP plugin -> (handle -> Buddy) self._handles_buddies = {} # activity id -> Activity self._activities_by_id = {} #: Tp plugin -> (handle -> Activity) self._activities_by_handle = {} #: Connection -> list of SignalMatch self._conn_matches = {} self._session_bus = dbus.SessionBus() self._session_bus.add_signal_receiver(self._connection_disconnected_cb, signal_name="Disconnected", dbus_interface="org.freedesktop.DBus") # Create the Owner object self._owner = self._create_owner() key = self._owner.props.key keyid = pubkey_to_keyid(key) self._buddies['keyid/' + keyid] = self._owner self._buddies_by_pubkey[key] = self._owner self._registry = ManagerRegistry() self._registry.LoadManagers() # Set up the Telepathy plugins self._plugins = [] debug_flags = set(environ.get('PRESENCE_SERVICE_DEBUG', '').split(',')) _logger.debug('Debug flags: %r', debug_flags) if 'disable-gabble' in debug_flags: self._server_plugin = None else: server = self._owner.get_server() if server and len(server): self._server_plugin = ServerPlugin(self._registry, self._owner) self._plugins.append(self._server_plugin) else: self._server_plugin = None if 'disable-salut' in debug_flags: self._ll_plugin = None else: self._ll_plugin = LinkLocalPlugin(self._registry, self._owner) self._plugins.append(self._ll_plugin) self._connected_plugins = set() for tp in self._plugins: self._handles_buddies[tp] = {} self._activities_by_handle[tp] = {} tp.connect('status', self._tp_status_cb) tp.connect('contacts-online', self._contacts_online) tp.connect('contacts-offline', self._contacts_offline) tp.connect('activity-invitation', self._activity_invitation) tp.connect('private-invitation', self._private_invitation) tp.connect('want-to-connect', self._want_to_connect) connection = tp.get_connection() if connection is not None: status = connection.GetStatus() self._tp_status_cb(tp, status, CONNECTION_STATUS_REASON_NONE_SPECIFIED) self._contacts_online_queue = [] ExportedGObject.__init__(self, self._session_bus, _PRESENCE_PATH) # for activation to work in a race-free way, we should really # export the bus name only after we export our initial object; # so this comes after the parent __init__ self._bus_name = dbus.service.BusName(_PRESENCE_SERVICE, bus=self._session_bus)
def identify_contacts(self, tp_chan, handles, identifiers=None): """Work out the "best" unique identifier we can for the given handles, in the context of the given channel (which may be None), using only 'fast' connection manager API (that does not involve network round-trips). For the XMPP server case, we proceed as follows: * Find the owners of the given handles, if the channel has channel-specific handles * If the owner (globally-valid JID) is on a trusted server, return 'keyid/' plus the 'key fingerprint' (the user part of their JID, currently implemented as the SHA-1 of the Base64 blob in owner.key.pub) * If the owner (globally-valid JID) cannot be found or is on an untrusted server, return 'xmpp/' plus an escaped form of the JID The idea is that we identify buddies by key-ID (i.e. by key, assuming no collisions) if we can find it without making network round-trips, but if that's not possible we just use their JIDs. :Parameters: `tp_chan` : telepathy.client.Channel or None The channel in which the handles were found, or None if they are known to be channel-specific handles `handles` : iterable over (int or long) The contacts' handles in that channel :Returns: A dict mapping the provided handles to the best available unique identifier, which is a string that could be used as a suffix to an object path """ # we need to be able to index into handles, so force them to # be a sequence if not isinstance(handles, (tuple, list)): handles = tuple(handles) # we happen to know that Salut has no channel-specific handles if identifiers is None: identifiers = self._conn[CONN_INTERFACE].InspectHandles( HANDLE_TYPE_CONTACT, handles) ret = {} for handle, ident in izip(handles, identifiers): # special-case the Owner - we always know who we are if handle == self.self_handle: ret[handle] = self._owner.props.objid continue # we also happen to know that on Salut, getting properties # is immediate, and the key is (well, will be) trustworthy if CONN_INTERFACE_BUDDY_INFO in self._conn: props = self._conn[CONN_INTERFACE_BUDDY_INFO].GetProperties( handle, byte_arrays=True, utf8_strings=True) key = props.get('key') else: key = None if key is not None: khash = psutils.pubkey_to_keyid(key) ret[handle] = 'keyid/' + khash else: ret[handle] = 'salut/' + psutils.escape_identifier(ident) return ret