diff --git a/services/presence/buddy.py b/services/presence/buddy.py index 35191e6c..8b2eec4a 100644 --- a/services/presence/buddy.py +++ b/services/presence/buddy.py @@ -255,7 +255,8 @@ class GenericOwner(Buddy): 'key-hash' : (str, None, None, None, gobject.PARAM_READABLE | gobject.PARAM_CONSTRUCT) } - def __init__(self, bus_name, object_id, **kwargs): + def __init__(self, ps, bus_name, object_id, **kwargs): + self._ps = ps self._server = 'olpc.collabora.co.uk' self._key_hash = None self._registered = False @@ -294,7 +295,7 @@ class ShellOwner(GenericOwner): _SHELL_OWNER_INTERFACE = "org.laptop.Shell.Owner" _SHELL_PATH = "/org/laptop/Shell" - def __init__(self, bus_name, object_id, test=False): + def __init__(self, ps, bus_name, object_id, test=False): server = profile.get_server() key_hash = profile.get_private_key_hash() registered = profile.get_server_registered() @@ -307,7 +308,7 @@ class ShellOwner(GenericOwner): icon = f.read() f.close() - GenericOwner.__init__(self, bus_name, object_id, key=key, nick=nick, + GenericOwner.__init__(self, ps, bus_name, object_id, key=key, nick=nick, color=color, icon=icon, server=server, key_hash=key_hash, registered=registered) @@ -371,9 +372,12 @@ class TestOwner(GenericOwner): __gtype_name__ = "TestOwner" - def __init__(self, bus_name, object_id, test_num): + def __init__(self, ps, bus_name, object_id, test_num): 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) @@ -392,11 +396,46 @@ class TestOwner(GenericOwner): color = xocolor.XoColor().to_string() icon = _get_random_image() - GenericOwner.__init__(self, bus_name, object_id, key=pubkey, nick=nick, + logging.debug("pubkey is %s" % pubkey) + GenericOwner.__init__(self, ps, bus_name, object_id, key=pubkey, nick=nick, color=color, icon=icon, registered=registered, key_hash=privkey_hash) + self._ps.connect('connection-status', self._ps_connection_status_cb) + + def _share_reply_cb(self, actid, object_path): + activity = self._ps.internal_get_activity(actid) + if not activity or not object_path: + logging.debug("Couldn't find activity %s even though it was shared." % actid) + return + logging.debug("Shared activity %s (%s)." % (actid, activity.props.name)) + self._test_activities.append(activity) + + def _share_error_cb(self, actid, err): + logging.debug("Error sharing activity %s: %s" % (actid, str(err))) + + def _ps_connection_status_cb(self, ps, connected): + if not connected: + return + + if not len(self._test_activities): + # Share some activities + actid = util.unique_id("Activity 1") + callbacks = (lambda *args: self._share_reply_cb(actid, *args), + lambda *args: self._share_error_cb(actid, *args)) + atype = "org.laptop.WebActivity" + properties = {"foo": "bar"} + self._ps._share_activity(actid, atype, "Wembley Stadium", properties, callbacks) + + actid2 = util.unique_id("Activity 2") + callbacks = (lambda *args: self._share_reply_cb(actid2, *args), + lambda *args: self._share_error_cb(actid2, *args)) + atype = "org.laptop.WebActivity" + properties = {"baz": "bar"} + self._ps._share_activity(actid2, atype, "Maine Road", properties, callbacks) + # Change a random property ever 10 seconds - gobject.timeout_add(10000, self._update_something) + if self._change_timeout == 0: + self._change_timeout = gobject.timeout_add(10000, self._update_something) def set_registered(self, value): if value: @@ -443,12 +482,14 @@ class TestOwner(GenericOwner): props = {'nick': _get_random_name()} self.set_properties(props) elif it == 3: - bork = random.randint(25, 65) - it = "" - for i in range(0, bork): - it += chr(random.randint(40, 127)) - from sugar import util - props = {'current-activity': util.unique_id(it)} + actid = "" + idx = random.randint(0, len(self._test_activities)) + # if idx == len(self._test_activites), it means no current + # activity + if idx < len(self._test_activities): + activity = self._test_activities[idx] + actid = activity.props.id + props = {'current-activity': actid} self.set_properties(props) return True diff --git a/services/presence/presenceservice.py b/services/presence/presenceservice.py index d71a3d24..1312fec0 100644 --- a/services/presence/presenceservice.py +++ b/services/presence/presenceservice.py @@ -40,24 +40,36 @@ class NotFoundError(dbus.DBusException): dbus.DBusException.__init__(self) self._dbus_error_name = _PRESENCE_INTERFACE + '.NotFound' +class DBusGObjectMetaclass(dbus.service.InterfaceType, gobject.GObjectMeta): pass +class DBusGObject(dbus.service.Object, gobject.GObject): __metaclass__ = DBusGObjectMetaclass + +class PresenceService(DBusGObject): + __gtype_name__ = "PresenceService" + + __gsignals__ = { + 'connection-status': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, + ([gobject.TYPE_BOOLEAN])) + } -class PresenceService(dbus.service.Object): def __init__(self, test=0): self._next_object_id = 0 + self._connected = False self._buddies = {} # key -> Buddy self._handles_buddies = {} # tp client -> (handle -> Buddy) self._activities = {} # activity id -> Activity + gobject.GObject.__init__(self) + bus = dbus.SessionBus() self._bus_name = dbus.service.BusName(_PRESENCE_SERVICE, bus=bus) # Create the Owner object objid = self._get_next_object_id() if test > 0: - self._owner = TestOwner(self._bus_name, objid, test) + self._owner = TestOwner(self, self._bus_name, objid, test) else: - self._owner = ShellOwner(self._bus_name, objid) + self._owner = ShellOwner(self, self._bus_name, objid) self._buddies[self._owner.props.key] = self._owner self._registry = ManagerRegistry() @@ -92,8 +104,15 @@ class PresenceService(dbus.service.Object): async_err_cb(exc) def _server_status_cb(self, plugin, status, reason): + # FIXME: figure out connection status when we have a salut plugin too + old_status = self._connected if status == CONNECTION_STATUS_CONNECTED: - pass + self._connected = True + else: + self._connected = False + + if self._connected != old_status: + self.emit('connection-status', self._connected) def _contact_online(self, tp, handle, props): new_buddy = False @@ -260,11 +279,10 @@ class PresenceService(dbus.service.Object): @dbus.service.method(_PRESENCE_INTERFACE, in_signature="s", out_signature="o") def GetActivityById(self, actid): - if self._activities.has_key(actid): - act = self._activities[actid] - if act.props.valid: - return act.object_path() - raise NotFoundError("The activity was not found.") + act = self.internal_get_activity(actid) + if not act or not act.props.valid: + raise NotFoundError("The activity was not found.") + return act.object_path() @dbus.service.method(_PRESENCE_INTERFACE, out_signature="ao") def GetBuddies(self): @@ -333,6 +351,11 @@ class PresenceService(dbus.service.Object): if activity: activity.set_properties(props) + def internal_get_activity(self, actid): + if not self._activities.has_key(actid): + return None + return self._activities[actid] + def main(test=False): loop = gobject.MainLoop()