Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/services
diff options
context:
space:
mode:
authorSimon McVittie <simon.mcvittie@collabora.co.uk>2007-05-30 16:40:31 (GMT)
committer Simon McVittie <simon.mcvittie@collabora.co.uk>2007-05-30 16:40:31 (GMT)
commitf90de752f66e7f3484e2b93d7530f00c0a9517fd (patch)
treeb8225a2e355b8f650c9c2bbbc1363acb7bda15a0 /services
parentfd4e514e21f6cc5009c45d166b1714ff9c9c4aac (diff)
services/presence/presenceservice: weakly reference Buddy objects in _buddies
This makes sure we re-use an existing Buddy object if it's still referenced somewhere, rather than trying to make another and fighting over the object path.
Diffstat (limited to 'services')
-rw-r--r--services/presence/presenceservice.py50
1 files changed, 32 insertions, 18 deletions
diff --git a/services/presence/presenceservice.py b/services/presence/presenceservice.py
index 6f28bf5..6c17082 100644
--- a/services/presence/presenceservice.py
+++ b/services/presence/presenceservice.py
@@ -15,23 +15,24 @@
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-import gobject
+import logging
+from weakref import WeakValueDictionary
+
import dbus
import dbus.service
+import gobject
from dbus.gobject_service import ExportedGObject
from dbus.mainloop.glib import DBusGMainLoop
-import logging
-
from telepathy.client import ManagerRegistry, Connection
from telepathy.interfaces import (CONN_MGR_INTERFACE, CONN_INTERFACE)
from telepathy.constants import (CONNECTION_STATUS_CONNECTING,
CONNECTION_STATUS_CONNECTED,
CONNECTION_STATUS_DISCONNECTED)
-from server_plugin import ServerPlugin
-from linklocal_plugin import LinkLocalPlugin
from sugar import util
+from server_plugin import ServerPlugin
+from linklocal_plugin import LinkLocalPlugin
from buddy import Buddy, ShellOwner
from activity import Activity
from psutils import pubkey_to_keyid
@@ -65,11 +66,20 @@ class PresenceService(ExportedGObject):
self._next_object_id = 0
self._connected = False
- self._buddies = {} # identifier -> Buddy
- self._buddies_by_pubkey = {} # base64 public key -> Buddy
- self._handles_buddies = {} # tp client -> (handle -> Buddy)
+ # 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 = {}
- self._activities = {} # activity id -> Activity
+ # The online buddies (those who're available via some CM)
+ # TP plugin -> (handle -> Buddy)
+ self._handles_buddies = {}
+
+ # activity id -> Activity
+ self._activities = {}
self._session_bus = dbus.SessionBus()
self._session_bus.add_signal_receiver(self._connection_disconnected_cb,
@@ -174,11 +184,7 @@ class PresenceService(ExportedGObject):
def _buddy_disappeared_cb(self, buddy):
if buddy.props.valid:
- self.BuddyDisappeared(buddy.object_path())
- _logger.debug('Buddy left: %s (%s)', buddy.props.nick,
- buddy.props.color)
- self._buddies_by_pubkey.pop(buddy.props.key, None)
- self._buddies.pop(buddy.props.objid, None)
+ self._buddy_validity_changed_cb(buddy, False)
def _contact_offline(self, tp, handle):
if not self._handles_buddies[tp].has_key(handle):
@@ -325,10 +331,18 @@ class PresenceService(ExportedGObject):
@dbus.service.method(_PRESENCE_INTERFACE, in_signature='',
out_signature="ao")
def GetBuddies(self):
- ret = []
- for buddy in self._buddies.values():
- if buddy.props.valid:
- ret.append(buddy.object_path())
+ # in the presence of an out_signature, dbus-python will convert
+ # this set into an Array automatically (because it's iterable),
+ # so it's easy to use for uniquification (we want to avoid returning
+ # buddies who're visible on both Salut and Gabble twice)
+
+ # always include myself even if I have no handles
+ ret = set((self._owner,))
+
+ for handles_buddies in self._handles_buddies.itervalues():
+ for buddy in handles_buddies.itervalues():
+ if buddy.props.valid:
+ ret.add(buddy.object_path())
return ret
@dbus.service.method(_PRESENCE_INTERFACE,