PresenceService fixes; request buddy presence when using existing connection
This commit is contained in:
parent
48e9887d92
commit
57b887df30
@ -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,
|
||||
|
@ -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
|
||||
|
@ -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):
|
||||
|
Loading…
Reference in New Issue
Block a user