diff --git a/services/presence2/buddy.py b/services/presence2/buddy.py index 1b51ae8e..1f17210c 100644 --- a/services/presence2/buddy.py +++ b/services/presence2/buddy.py @@ -32,11 +32,13 @@ class Buddy(dbus.service.Object): """Represents another person on the network and keeps track of the activities and resources they make available for sharing.""" - def __init__(self, bus_name, object_id, handle=None): + def __init__(self, bus_name, object_id, key=None): if not bus_name: raise ValueError("DBus bus name must be valid") if not object_id or not isinstance(object_id, int): raise ValueError("object id must be a valid number") + if not key: + raise ValueError("key must be valid") self._bus_name = bus_name self._object_id = object_id @@ -45,13 +47,12 @@ class Buddy(dbus.service.Object): dbus.service.Object.__init__(self, self._bus_name, self._object_path) self._activities = {} # Activity ID -> Activity - self.handles = {} # tp client -> handle + self._key = key self._icon = None - self._name = None + self._nick = None self._color = None - self._key = None self._current_activity = None # dbus signals @@ -96,7 +97,7 @@ class Buddy(dbus.service.Object): in_signature="", out_signature="a{sv}") def GetProperties(self): props = {} - props['name'] = self.get_name() + props['nick'] = self.get_nick() props['owner'] = self.is_owner() props['key'] = self.get_key() color = self.get_color() @@ -135,8 +136,8 @@ class Buddy(dbus.service.Object): """Return the buddies icon, if any.""" return self._icon - def get_name(self): - return self._name + def get_nick(self): + return self._nick def get_color(self): return self._color @@ -155,15 +156,15 @@ class Buddy(dbus.service.Object): self._icon = icon self.IconChanged(icon) - def _set_name(self, name): - self._name = name + def _set_nick(self, nick): + self._nick = nick def _set_color(self, color): self._color = color def set_properties(self, properties): - if "name" in properties.keys(): - self._set_name(properties["name"]) + if "nick" in properties.keys(): + self._set_nick(properties["nick"]) if "color" in properties.keys(): self._set_color(properties["color"]) self.PropertyChanged(properties) @@ -181,12 +182,12 @@ class Owner(Buddy): """Class representing the owner of the machine. This is the client portion of the Owner, paired with the server portion in Owner.py.""" def __init__(self, ps, bus_name, object_id): - Buddy.__init__(self, bus_name, object_id) + key = profile.get_pubkey() + Buddy.__init__(self, bus_name, object_id, key=key) self._ps = ps self._name = profile.get_nick_name() self._color = profile.get_color().to_string() - self._key = profile.get_pubkey() # dbus methods @dbus.service.method(_OWNER_INTERFACE, diff --git a/services/presence2/presenceservice.py b/services/presence2/presenceservice.py index f3739e38..cb9ad4f0 100644 --- a/services/presence2/presenceservice.py +++ b/services/presence2/presenceservice.py @@ -82,13 +82,11 @@ class PresenceService(dbus.service.Object): new_buddy = False key = props['key'] buddy = self._buddies.get(key) - if not buddy: # we don't know yet this buddy objid = self._get_next_object_id() - buddy = Buddy(self._bus_name, objid, handle=handle) - buddy.set_key(key) - print "create buddy", key + buddy = Buddy(self._bus_name, objid, key=key) + print "New buddy %s" % key self._buddies[key] = buddy new_buddy = True @@ -101,6 +99,7 @@ class PresenceService(dbus.service.Object): if new_buddy: self.BuddyAppeared(buddy.object_path()) buddy.set_properties(props) + print "New buddy properties %s" % props def _contact_offline(self, tp, handle): buddy = self._handles[tp].pop(handle) @@ -108,13 +107,10 @@ class PresenceService(dbus.service.Object): # the handle of the buddy for this CM is not valid anymore buddy.handles.pop(tp) - if not buddy.handles: - # we remove the last handle of the buddy, so we don't see - # it anymore. - self._buddies.pop(key) - print "remove buddy" self.BuddyDisappeared(buddy.object_path()) + print "Buddy %s gone" % buddy.get_key() + self._buddies.pop(key) def _get_next_object_id(self): """Increment and return the object ID counter.""" @@ -123,15 +119,15 @@ class PresenceService(dbus.service.Object): def _avatar_updated(self, tp, handle, avatar): buddy = self._handles[tp].get(handle) - - if buddy: + if buddy and not buddy.is_owner(): + print "Buddy %s icon updated" % buddy.get_key() buddy.set_icon(avatar) def _properties_changed(self, tp, handle, prop): buddy = self._handles[tp].get(handle) - if buddy: buddy.set_properties(prop) + print "Buddy %s properties updated" % buddy.get_key() def _activities_changed(self, tp, handle, prop): pass diff --git a/services/presence2/server_plugin.py b/services/presence2/server_plugin.py index bf493e49..53afeb74 100644 --- a/services/presence2/server_plugin.py +++ b/services/presence2/server_plugin.py @@ -91,7 +91,7 @@ class ServerPlugin(gobject.GObject): self._icon_cache = BuddyIconCache() self._gabble_mgr = registry.GetManager('gabble') - self._online_contacts = set() # handles of online contacts + self._online_contacts = {} # handle -> jid self._account = self._get_account_info() self._conn = self._init_connection() @@ -140,7 +140,6 @@ class ServerPlugin(gobject.GObject): acct = self._account.copy() # Create a new connection - print acct name, path = self._gabble_mgr[CONN_MGR_INTERFACE].RequestConnection(_PROTOCOL, acct) conn = Connection(name, path) del acct @@ -150,7 +149,7 @@ class ServerPlugin(gobject.GObject): # hack conn._valid_interfaces.add(CONN_INTERFACE_PRESENCE) conn[CONN_INTERFACE_PRESENCE].connect_to_signal('PresenceUpdate', - self._presence_update_cb) + self._presence_update_cb) return conn @@ -185,30 +184,12 @@ class ServerPlugin(gobject.GObject): not_subscribed = list(set(publish_handles) - set(subscribe_handles)) self_handle = self._conn[CONN_INTERFACE].GetSelfHandle() - self._online_contacts.add(self_handle) + self._online_contacts[self_handle] = self._account['account'] for handle in not_subscribed: # request subscriptions from people subscribed to us if we're not subscribed to them subscribe[CHANNEL_INTERFACE_GROUP].AddMembers([self_handle], '') - # hack - self._conn._valid_interfaces.add(CONN_INTERFACE_ALIASING) - - self._conn[CONN_INTERFACE_ALIASING].connect_to_signal('AliasesChanged', self._alias_changed_cb) - #if CONN_INTERFACE_ALIASING in self._conn: - # aliases = self._conn[CONN_INTERFACE_ALIASING].RequestAliases(subscribe_handles) - #else: - # aliases = self._conn[CONN_INTERFACE].InspectHandles(CONNECTION_HANDLE_TYPE_CONTACT, subscribe_handles) - - #for handle, alias in zip(subscribe_handles, aliases): - # print alias - # self.buddies[handle].alias = alias - - # hack - self._conn._valid_interfaces.add(CONN_INTERFACE_AVATARS) - - self._conn[CONN_INTERFACE_AVATARS].connect_to_signal('AvatarUpdated', self._avatar_updated_cb) - # hack self._conn._valid_interfaces.add(CONN_INTERFACE_BUDDY_INFO) if CONN_INTERFACE_BUDDY_INFO not in self._conn.get_valid_interfaces(): @@ -216,11 +197,22 @@ class ServerPlugin(gobject.GObject): self.disconnect() return - self._set_self_buddy_info() - self._conn[CONN_INTERFACE_BUDDY_INFO].connect_to_signal('PropertiesChanged', self._properties_changed_cb) self._conn[CONN_INTERFACE_BUDDY_INFO].connect_to_signal('ActivitiesChanged', self._activities_changed_cb) + # hack + self._conn._valid_interfaces.add(CONN_INTERFACE_AVATARS) + self._conn[CONN_INTERFACE_AVATARS].connect_to_signal('AvatarUpdated', self._avatar_updated_cb) + + # hack + self._conn._valid_interfaces.add(CONN_INTERFACE_ALIASING) + self._conn[CONN_INTERFACE_ALIASING].connect_to_signal('AliasesChanged', self._alias_changed_cb) + + self._set_self_buddy_info() + + # Request presence for everyone on the channel + self._conn[CONN_INTERFACE_PRESENCE].GetPresence(subscribe_handles) + def _set_self_buddy_info(self): # Set our OLPC buddy properties props = {} @@ -276,56 +268,47 @@ class ServerPlugin(gobject.GObject): def disconnect(self): self._conn[CONN_INTERFACE].Disconnect() - def _contact_go_offline(self, handle): - jid = self._conn[CONN_INTERFACE].InspectHandles(CONNECTION_HANDLE_TYPE_CONTACT, [handle])[0] - print jid, "offline" - - self._online_contacts.remove(handle) + def _contact_offline(self, handle): self.emit("contact-offline", handle) + del self._online_contacts[handle] - def _contact_go_online(self, handle): - jid = self._conn[CONN_INTERFACE].InspectHandles(CONNECTION_HANDLE_TYPE_CONTACT, [handle])[0] - print jid, "online" - + def _contact_online(self, handle): try: props = self._conn[CONN_INTERFACE_BUDDY_INFO].GetProperties(handle) except dbus.DBusException, e: if str(e).startswith("org.freedesktop.DBus.Error.NoReply"): raise InvalidBuddyError("couldn't get properties") - - name = self._conn[CONN_INTERFACE_ALIASING].RequestAliases([handle])[0] - if not props.has_key('color'): raise InvalidBuddyError("no color") if not props.has_key('key'): raise InvalidBuddyError("no key") - if not name: - raise InvalidBuddyError("no name") - self._online_contacts.add(handle) + jid = self._conn[CONN_INTERFACE].InspectHandles(CONNECTION_HANDLE_TYPE_CONTACT, [handle])[0] + nick = self._conn[CONN_INTERFACE_ALIASING].RequestAliases([handle])[0] + if not nick: + raise InvalidBuddyError("no name") + props['nick'] = nick + + self._online_contacts[handle] = jid self.emit("contact-online", handle, props) def _presence_update_cb(self, presence): for handle in presence: timestamp, statuses = presence[handle] - - name = self._conn[CONN_INTERFACE].InspectHandles(CONNECTION_HANDLE_TYPE_CONTACT, [handle])[0] online = handle in self._online_contacts - for status, params in statuses.items(): + print "Handle %s now online=%s with status %s" % (handle, online, status) if not online and status in ["available", "away", "brb", "busy", "dnd", "xa"]: try: - self._contact_go_online(handle) + self._contact_online(handle) except InvalidBuddyError, e: print "Not adding %s because %s" % (handle, e) elif online and status in ["offline", "invisible"]: - self._contact_go_offline(handle) + self._contact_offline(handle) def _avatar_updated_cb(self, handle, new_avatar_token): - jid = self._conn[CONN_INTERFACE].InspectHandles(CONNECTION_HANDLE_TYPE_CONTACT, [handle])[0] - + jid = self._online_contacts[handle] icon = self._icon_cache.get_icon(jid, new_avatar_token) - if not icon: # cache miss avatar, mime_type = self._conn[CONN_INTERFACE_AVATARS].RequestAvatar(handle) @@ -335,11 +318,10 @@ class ServerPlugin(gobject.GObject): self.emit("avatar-updated", handle, icon) def _alias_changed_cb(self, aliases): - print "alias changed cb" for handle, alias in aliases: - name = self._conn[CONN_INTERFACE_ALIASING].RequestAliases([handle])[0] - print "new alias", handle, alias, name - prop = {'name': name} + nick = self._conn[CONN_INTERFACE_ALIASING].RequestAliases([handle])[0] + prop = {'nick': nick} + print "Buddy %s alias changed to %s" % (handle, nick) self._properties_changed_cb(handle, prop) def _properties_changed_cb(self, contact, properties):