From 4b26840333f773020093b0bac7fea28b43991951 Mon Sep 17 00:00:00 2001 From: Simon McVittie Date: Tue, 15 May 2007 14:58:15 +0100 Subject: [PATCH 1/8] sugar.presence.presenceservice, services/presence: Use named loggers. This causes events in the log to be annotated with the module that emitted the message. Before: DEBUG - root: Starting up... After: DEBUG - s-p-s.server_plugin: Starting up... I've used a log domain of "sugar.presence..." for the client library and e.g. "s-p-s.activity" for the service internals. --- services/presence/activity.py | 14 +++--- services/presence/buddy.py | 27 +++++----- services/presence/presenceservice.py | 33 ++++++------ services/presence/psutils.py | 11 ++-- services/presence/server_plugin.py | 64 ++++++++++++------------ services/presence/sugar-presence-service | 12 +++-- sugar/presence/presenceservice.py | 16 +++--- 7 files changed, 98 insertions(+), 79 deletions(-) diff --git a/services/presence/activity.py b/services/presence/activity.py index d295ce3c..ee91bc82 100644 --- a/services/presence/activity.py +++ b/services/presence/activity.py @@ -36,6 +36,8 @@ _PROP_LOCAL = "local" _PROP_JOINED = "joined" _PROP_CUSTOM_PROPS = "custom-props" +_logger = logging.getLogger('s-p-s.activity') + class Activity(ExportedGObject): """Represents a potentially shareable activity on the network. """ @@ -359,7 +361,7 @@ class Activity(ExportedGObject): Called by the _shared_cb and _joined_cb methods. """ if not text_channel: - logging.debug("Error sharing: text channel was None, shouldn't happen") + _logger.debug("Error sharing: text channel was None, shouldn't happen") raise RuntimeError("Plugin returned invalid text channel") self._text_channel = text_channel @@ -379,14 +381,14 @@ class Activity(ExportedGObject): self._tp.disconnect(sigid) if exc: - logging.debug("Share of activity %s failed: %s" % (self._id, exc)) + _logger.debug("Share of activity %s failed: %s" % (self._id, exc)) async_err_cb(exc) else: self._handle_share_join(tp, text_channel) self.send_properties() owner.add_activity(self) async_cb(dbus.ObjectPath(self._object_path)) - logging.debug("Share of activity %s succeeded." % self._id) + _logger.debug("Share of activity %s succeeded." % self._id) def _share(self, (async_cb, async_err_cb), owner): """XXX - not documented yet @@ -394,13 +396,13 @@ class Activity(ExportedGObject): XXX - This method is called externally by the PresenceService despite the fact that this is supposed to be an internal method! """ - logging.debug("Starting share of activity %s" % self._id) + _logger.debug("Starting share of activity %s" % self._id) if self._joined: async_err_cb(RuntimeError("Already shared activity %s" % self.props.id)) return sigid = self._tp.connect('activity-shared', self._shared_cb) self._tp.share_activity(self.props.id, (sigid, owner, async_cb, async_err_cb)) - logging.debug("done with share attempt %s" % self._id) + _logger.debug("done with share attempt %s" % self._id) def _joined_cb(self, tp, activity_id, text_channel, exc, userdata): """XXX - not documented yet @@ -506,7 +508,7 @@ class Activity(ExportedGObject): if type != self._type: # Type can never be changed after first set if self._type: - logging.debug("Activity type changed by network; this is illegal") + _logger.debug("Activity type changed by network; this is illegal") else: self._type = type changed = True diff --git a/services/presence/buddy.py b/services/presence/buddy.py index 200401bd..429f8249 100644 --- a/services/presence/buddy.py +++ b/services/presence/buddy.py @@ -49,6 +49,9 @@ _PROP_VALID = "valid" # Will go away soon _PROP_IP4_ADDRESS = "ip4-address" +_logger = logging.getLogger('s-p-s.buddy') + + class Buddy(ExportedGObject): """Person on the network (tracks properties and shared activites) @@ -130,7 +133,7 @@ class Buddy(ExportedGObject): _ALLOWED_INIT_PROPS = [_PROP_NICK, _PROP_KEY, _PROP_ICON, _PROP_CURACT, _PROP_COLOR, _PROP_IP4_ADDRESS] for (key, value) in kwargs.items(): if key not in _ALLOWED_INIT_PROPS: - logging.debug("Invalid init property '%s'; ignoring..." % key) + _logger.debug("Invalid init property '%s'; ignoring..." % key) del kwargs[key] # Set icon after superclass init, because it sends DBus and GObject @@ -625,7 +628,7 @@ class TestOwner(GenericOwner): color = xocolor.XoColor().to_string() icon = _get_random_image() - logging.debug("pubkey is %s" % pubkey) + _logger.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) @@ -636,13 +639,13 @@ class TestOwner(GenericOwner): 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) + _logger.debug("Couldn't find activity %s even though it was shared." % actid) return - logging.debug("Shared activity %s (%s)." % (actid, activity.props.name)) + _logger.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))) + _logger.debug("Error sharing activity %s: %s" % (actid, str(err))) def _ps_connection_status_cb(self, ps, connected): if not connected: @@ -735,7 +738,7 @@ def _hash_private_key(self): lines = f.readlines() f.close() except IOError, e: - logging.error("Error reading private key: %s" % e) + _logger.error("Error reading private key: %s" % e) return key = "" @@ -747,7 +750,7 @@ def _hash_private_key(self): continue key += l if not len(key): - logging.error("Error parsing public key.") + _logger.error("Error parsing public key.") # hash it key_hash = util._sha_data(key) @@ -759,7 +762,7 @@ def _extract_public_key(keyfile): lines = f.readlines() f.close() except IOError, e: - logging.error("Error reading public key: %s" % e) + _logger.error("Error reading public key: %s" % e) return None # Extract the public key @@ -772,7 +775,7 @@ def _extract_public_key(keyfile): key = l[len(magic):] break if not len(key): - logging.error("Error parsing public key.") + _logger.error("Error parsing public key.") return None return key @@ -784,7 +787,7 @@ def _extract_private_key(keyfile): lines = f.readlines() f.close() except IOError, e: - logging.error("Error reading private key: %s" % e) + _logger.error("Error reading private key: %s" % e) return None key = "" @@ -796,7 +799,7 @@ def _extract_private_key(keyfile): continue key += l if not len(key): - logging.error("Error parsing private key.") + _logger.error("Error parsing private key.") return None return key @@ -821,7 +824,7 @@ def _get_new_keypair(num): print "Done." pubkey = privkey = None if s != 0: - logging.error("Could not generate key pair: %d (%s)" % (s, o)) + _logger.error("Could not generate key pair: %d (%s)" % (s, o)) else: pubkey = _extract_public_key(pubkeyfile) privkey = _extract_private_key(privkeyfile) diff --git a/services/presence/presenceservice.py b/services/presence/presenceservice.py index 6b67357e..c554ce6e 100644 --- a/services/presence/presenceservice.py +++ b/services/presence/presenceservice.py @@ -40,6 +40,9 @@ _PRESENCE_INTERFACE = "org.laptop.Sugar.Presence" _PRESENCE_PATH = "/org/laptop/Sugar/Presence" +_logger = logging.getLogger('s-p-s.presenceservice') + + class NotFoundError(dbus.DBusException): def __init__(self, msg): dbus.DBusException.__init__(self, msg) @@ -101,7 +104,7 @@ class PresenceService(ExportedGObject): def _connection_disconnected_cb(self, foo=None): """Log event when D-Bus kicks us off the bus for some reason""" - logging.debug("Disconnected from session bus!!!") + _logger.debug("Disconnected from session bus!!!") def _server_status_cb(self, plugin, status, reason): # FIXME: figure out connection status when we have a salut plugin too @@ -135,10 +138,10 @@ class PresenceService(ExportedGObject): def _buddy_validity_changed_cb(self, buddy, valid): if valid: self.BuddyAppeared(buddy.object_path()) - logging.debug("New Buddy: %s (%s)" % (buddy.props.nick, buddy.props.color)) + _logger.debug("New Buddy: %s (%s)" % (buddy.props.nick, buddy.props.color)) else: self.BuddyDisappeared(buddy.object_path()) - logging.debug("Buddy left: %s (%s)" % (buddy.props.nick, buddy.props.color)) + _logger.debug("Buddy left: %s (%s)" % (buddy.props.nick, buddy.props.color)) def _contact_offline(self, tp, handle): if not self._handles_buddies[tp].has_key(handle): @@ -152,7 +155,7 @@ class PresenceService(ExportedGObject): if not buddy.handles: if buddy.props.valid: self.BuddyDisappeared(buddy.object_path()) - logging.debug("Buddy left: %s (%s)" % (buddy.props.nick, buddy.props.color)) + _logger.debug("Buddy left: %s (%s)" % (buddy.props.nick, buddy.props.color)) self._buddies.pop(key) def _get_next_object_id(self): @@ -163,21 +166,21 @@ class PresenceService(ExportedGObject): def _avatar_updated(self, tp, handle, avatar): buddy = self._handles_buddies[tp].get(handle) if buddy and not buddy.props.owner: - logging.debug("Buddy %s icon updated" % buddy.props.nick) + _logger.debug("Buddy %s icon updated" % buddy.props.nick) buddy.props.icon = avatar def _buddy_properties_changed(self, tp, handle, properties): buddy = self._handles_buddies[tp].get(handle) if buddy: buddy.set_properties(properties) - logging.debug("Buddy %s properties updated: %s" % (buddy.props.nick, properties.keys())) + _logger.debug("Buddy %s properties updated: %s" % (buddy.props.nick, properties.keys())) def _new_activity(self, activity_id, tp): try: objid = self._get_next_object_id() activity = Activity(self._bus_name, objid, tp, id=activity_id) except Exception, e: - logging.debug("Invalid activity: %s" % e) + _logger.debug("Invalid activity: %s" % e) return None activity.connect("validity-changed", self._activity_validity_changed_cb) @@ -185,7 +188,7 @@ class PresenceService(ExportedGObject): return activity def _remove_activity(self, activity): - logging.debug("remove activity %s" % activity.props.id) + _logger.debug("remove activity %s" % activity.props.id) self.ActivityDisappeared(activity.object_path()) del self._activities[activity.props.id] @@ -194,7 +197,7 @@ class PresenceService(ExportedGObject): acts = [] for act in activities: acts.append(str(act)) - logging.debug("Handle %s activities changed: %s" % (contact_handle, acts)) + _logger.debug("Handle %s activities changed: %s" % (contact_handle, acts)) buddies = self._handles_buddies[tp] buddy = buddies.get(contact_handle) @@ -202,7 +205,7 @@ class PresenceService(ExportedGObject): # We don't know this buddy # FIXME: What should we do here? # FIXME: Do we need to check if the buddy is valid or something? - logging.debug("contact_activities_changed: buddy unknown") + _logger.debug("contact_activities_changed: buddy unknown") return old_activities = set() @@ -213,7 +216,7 @@ class PresenceService(ExportedGObject): activities_joined = new_activities - old_activities for act in activities_joined: - logging.debug("Handle %s joined activity %s" % (contact_handle, act)) + _logger.debug("Handle %s joined activity %s" % (contact_handle, act)) activity = self._activities.get(act) if not activity: # new activity, can fail @@ -225,7 +228,7 @@ class PresenceService(ExportedGObject): activities_left = old_activities - new_activities for act in activities_left: - logging.debug("Handle %s left activity %s" % (contact_handle, act)) + _logger.debug("Handle %s left activity %s" % (contact_handle, act)) activity = self._activities.get(act) if not activity: continue @@ -341,10 +344,10 @@ class PresenceService(ExportedGObject): def _activity_validity_changed_cb(self, activity, valid): if valid: self.ActivityAppeared(activity.object_path()) - logging.debug("New Activity: %s (%s)" % (activity.props.name, activity.props.id)) + _logger.debug("New Activity: %s (%s)" % (activity.props.name, activity.props.id)) else: self.ActivityDisappeared(activity.object_path()) - logging.debug("Activity disappeared: %s (%s)" % (activity.props.name, activity.props.id)) + _logger.debug("Activity disappeared: %s (%s)" % (activity.props.name, activity.props.id)) def _activity_properties_changed(self, tp, act_id, props): activity = self._activities.get(act_id) @@ -364,7 +367,7 @@ def main(test_num=0, randomize=False): loop.run() except KeyboardInterrupt: ps.cleanup() - logging.debug('Ctrl+C pressed, exiting...') + _logger.debug('Ctrl+C pressed, exiting...') if __name__ == "__main__": main() diff --git a/services/presence/psutils.py b/services/presence/psutils.py index b24b1df0..73a5315f 100644 --- a/services/presence/psutils.py +++ b/services/presence/psutils.py @@ -18,6 +18,9 @@ import dbus, dbus.glib, gobject import logging +_logger = logging.getLogger('s-p-s.psutils') + + def bytes_to_string(bytes): """The function converts a D-BUS byte array provided by dbus to string format. @@ -92,7 +95,7 @@ class IP4AddressMonitor(gobject.GObject): return self._addr = new_addr - logging.debug("IP4 address now '%s'" % new_addr) + _logger.debug("IP4 address now '%s'" % new_addr) self.emit('address-changed', new_addr) def _connect_to_nm(self): @@ -102,7 +105,7 @@ class IP4AddressMonitor(gobject.GObject): proxy = sys_bus.get_object(NM_SERVICE, NM_PATH) self._nm_obj = dbus.Interface(proxy, NM_IFACE) except dbus.DBusException, err: - logging.debug("Error finding NetworkManager: %s" % err) + _logger.debug("Error finding NetworkManager: %s" % err) self._nm_present = False return @@ -141,7 +144,7 @@ class IP4AddressMonitor(gobject.GObject): self._update_address(props[6]) def _device_properties_error_cb(self, err): - logging.debug("Error querying device properties: %s" % err) + _logger.debug("Error querying device properties: %s" % err) def _query_device_properties(self, device): sys_bus = dbus.SystemBus() @@ -156,7 +159,7 @@ class IP4AddressMonitor(gobject.GObject): self._query_device_properties(op) def _get_devices_error_cb(self, err): - logging.debug("Error getting NetworkManager devices: %s" % err) + _logger.debug("Error getting NetworkManager devices: %s" % err) def _query_devices(self): """Query NM for a list of network devices""" diff --git a/services/presence/server_plugin.py b/services/presence/server_plugin.py index c7f62575..b3b9482a 100644 --- a/services/presence/server_plugin.py +++ b/services/presence/server_plugin.py @@ -42,6 +42,8 @@ CONN_INTERFACE_ACTIVITY_PROPERTIES = 'org.laptop.Telepathy.ActivityProperties' _PROTOCOL = "jabber" +_logger = logging.getLogger('s-p-s.server_plugin') + class InvalidBuddyError(Exception): """(Unused) exception to indicate an invalid buddy specifier""" @@ -144,14 +146,14 @@ class ServerPlugin(gobject.GObject): self._ip4am.connect('address-changed', self._ip4_address_changed_cb) def _ip4_address_changed_cb(self, ip4am, address): - logging.debug("::: IP4 address now %s" % address) + _logger.debug("::: IP4 address now %s" % address) if address: - logging.debug("::: valid IP4 address, conn_status %s" % self._conn_status) + _logger.debug("::: valid IP4 address, conn_status %s" % self._conn_status) if self._conn_status == CONNECTION_STATUS_DISCONNECTED: - logging.debug("::: will connect") + _logger.debug("::: will connect") self.start() else: - logging.debug("::: invalid IP4 address, will disconnect") + _logger.debug("::: invalid IP4 address, will disconnect") self.cleanup() def _owner_property_changed_cb(self, owner, properties): @@ -169,7 +171,7 @@ class ServerPlugin(gobject.GObject): depending on which properties are present in the set of properties. """ - logging.debug("Owner properties changed: %s" % properties) + _logger.debug("Owner properties changed: %s" % properties) if properties.has_key("current-activity"): self._set_self_current_activity() @@ -185,7 +187,7 @@ class ServerPlugin(gobject.GObject): def _owner_icon_changed_cb(self, owner, icon): """Owner has changed their icon, forward to network""" - logging.debug("Owner icon changed to size %d" % len(str(icon))) + _logger.debug("Owner icon changed to size %d" % len(str(icon))) self._set_self_avatar(icon) def _get_account_info(self): @@ -250,7 +252,7 @@ class ServerPlugin(gobject.GObject): def _connect_error_cb(self, exception): """Handle connection failure""" - logging.debug("Connect error: %s" % exception) + _logger.debug("Connect error: %s" % exception) def _init_connection(self): """Set up our connection @@ -336,7 +338,7 @@ class ServerPlugin(gobject.GObject): subscribe[CHANNEL_INTERFACE_GROUP].AddMembers(not_subscribed, '') if CONN_INTERFACE_BUDDY_INFO not in self._conn.get_valid_interfaces(): - logging.debug('OLPC information not available') + _logger.debug('OLPC information not available') return False self._conn[CONN_INTERFACE_BUDDY_INFO].connect_to_signal('PropertiesChanged', @@ -394,7 +396,7 @@ class ServerPlugin(gobject.GObject): types, minw, minh, maxw, maxh, maxsize = self._conn[CONN_INTERFACE_AVATARS].GetAvatarRequirements() if not "image/jpeg" in types: - logging.debug("server does not accept JPEG format avatars.") + _logger.debug("server does not accept JPEG format avatars.") return img_data = _get_buddy_icon_at_size(icon_data, min(maxw, 96), min(maxh, 96), maxsize) @@ -414,7 +416,7 @@ class ServerPlugin(gobject.GObject): if (activity_id, handles[0]) in self._joined_activities: e = RuntimeError("Already joined activity %s" % activity_id) - logging.debug(str(e)) + _logger.debug(str(e)) self.emit(signal, activity_id, None, e, userdata) return @@ -425,7 +427,7 @@ class ServerPlugin(gobject.GObject): def _join_error_cb(self, activity_id, signal, userdata, err): e = Exception("Error joining/sharing activity %s: %s" % (activity_id, err)) - logging.debug(str(e)) + _logger.debug(str(e)) self.emit(signal, activity_id, None, e, userdata) def _internal_join_activity(self, activity_id, signal, userdata): @@ -470,7 +472,7 @@ class ServerPlugin(gobject.GObject): def _log_error_cb(self, msg, err): """Log a message (error) at debug level with prefix msg""" - logging.debug("Error %s: %s" % (msg, err)) + _logger.debug("Error %s: %s" % (msg, err)) def _set_self_olpc_properties(self): """Set color and key on our Telepathy server identity""" @@ -519,7 +521,7 @@ class ServerPlugin(gobject.GObject): # dont advertise a current activity that's not shared cur_activity = "" - logging.debug("Setting current activity to '%s' (handle %s)" % (cur_activity, cur_activity_handle)) + _logger.debug("Setting current activity to '%s' (handle %s)" % (cur_activity, cur_activity_handle)) self._conn[CONN_INTERFACE_BUDDY_INFO].SetCurrentActivity(cur_activity, cur_activity_handle, reply_handler=self._ignore_success_cb, @@ -549,17 +551,17 @@ class ServerPlugin(gobject.GObject): if status == CONNECTION_STATUS_CONNECTING: self._conn_status = status - logging.debug("status: connecting...") + _logger.debug("status: connecting...") elif status == CONNECTION_STATUS_CONNECTED: if self._connected_cb(): - logging.debug("status: connected") + _logger.debug("status: connected") self._conn_status = status else: self.cleanup() - logging.debug("status: was connected, but an error occurred") + _logger.debug("status: was connected, but an error occurred") elif status == CONNECTION_STATUS_DISCONNECTED: self.cleanup() - logging.debug("status: disconnected (reason %r)" % reason) + _logger.debug("status: disconnected (reason %r)" % reason) if reason == CONNECTION_STATUS_REASON_AUTHENTICATION_FAILED: # FIXME: handle connection failure; retry later? pass @@ -580,7 +582,7 @@ class ServerPlugin(gobject.GObject): status -- CONNECTION_STATUS_* reason -- integer code describing the reason... """ - logging.debug("::: connection status changed to %s" % status) + _logger.debug("::: connection status changed to %s" % status) self._handle_connection_status_change(status, reason) def start(self): @@ -594,7 +596,7 @@ class ServerPlugin(gobject.GObject): otherwise initiate a connection and transfer control to _connect_reply_cb or _connect_error_cb """ - logging.debug("Starting up...") + _logger.debug("Starting up...") if self._reconnect_id > 0: gobject.source_remove(self._reconnect_id) @@ -602,10 +604,10 @@ class ServerPlugin(gobject.GObject): # Only init connection if we have a valid IP address if self._ip4am.props.address: - logging.debug("::: Have IP4 address %s, will connect" % self._ip4am.props.address) + _logger.debug("::: Have IP4 address %s, will connect" % self._ip4am.props.address) self._init_connection() else: - logging.debug("::: No IP4 address, postponing connection") + _logger.debug("::: No IP4 address, postponing connection") def cleanup(self): """If we still have a connection, disconnect it""" @@ -638,14 +640,14 @@ class ServerPlugin(gobject.GObject): def _contact_online_activities_error_cb(self, handle, err): """Handle contact's activity list being unavailable""" - logging.debug("Handle %s - Error getting activities: %s" % (handle, err)) + _logger.debug("Handle %s - Error getting activities: %s" % (handle, err)) # Don't drop the buddy if we can't get their activities, for now #self._contact_offline(handle) def _contact_online_aliases_cb(self, handle, props, aliases): """Handle contact's alias being received (do further queries)""" if not self._conn or not aliases or not len(aliases): - logging.debug("Handle %s - No aliases" % handle) + _logger.debug("Handle %s - No aliases" % handle) self._contact_offline(handle) return @@ -660,17 +662,17 @@ class ServerPlugin(gobject.GObject): def _contact_online_aliases_error_cb(self, handle, err): """Handle failure to retrieve given user's alias/information""" - logging.debug("Handle %s - Error getting nickname: %s" % (handle, err)) + _logger.debug("Handle %s - Error getting nickname: %s" % (handle, err)) self._contact_offline(handle) def _contact_online_properties_cb(self, handle, props): """Handle failure to retrieve given user's alias/information""" if not props.has_key('key'): - logging.debug("Handle %s - invalid key." % handle) + _logger.debug("Handle %s - invalid key." % handle) self._contact_offline(handle) return if not props.has_key('color'): - logging.debug("Handle %s - invalid color." % handle) + _logger.debug("Handle %s - invalid color." % handle) self._contact_offline(handle) return @@ -683,7 +685,7 @@ class ServerPlugin(gobject.GObject): def _contact_online_properties_error_cb(self, handle, err): """Handle error retrieving property-set for a user (handle)""" - logging.debug("Handle %s - Error getting properties: %s" % (handle, err)) + _logger.debug("Handle %s - Error getting properties: %s" % (handle, err)) self._contact_offline(handle) def _contact_online(self, handle): @@ -712,7 +714,7 @@ class ServerPlugin(gobject.GObject): jid = self._conn[CONN_INTERFACE].InspectHandles(CONNECTION_HANDLE_TYPE_CONTACT, [handle])[0] olstr = "ONLINE" if not online: olstr = "OFFLINE" - logging.debug("Handle %s (%s) was %s, status now '%s'." % (handle, jid, olstr, status)) + _logger.debug("Handle %s (%s) was %s, status now '%s'." % (handle, jid, olstr, status)) if not online and status in ["available", "away", "brb", "busy", "dnd", "xa"]: self._contact_online(handle) elif status in ["offline", "invisible"]: @@ -726,12 +728,12 @@ class ServerPlugin(gobject.GObject): return if not self._online_contacts.has_key(handle): - logging.debug("Handle %s unknown." % handle) + _logger.debug("Handle %s unknown." % handle) return jid = self._online_contacts[handle] if not jid: - logging.debug("Handle %s not valid yet..." % handle) + _logger.debug("Handle %s not valid yet..." % handle) return icon = self._icon_cache.get_icon(jid, new_avatar_token) @@ -787,7 +789,7 @@ class ServerPlugin(gobject.GObject): if not len(activity) or not util.validate_activity_id(activity): activity = None prop = {'current-activity': activity} - logging.debug("Handle %s: current activity now %s" % (handle, activity)) + _logger.debug("Handle %s: current activity now %s" % (handle, activity)) self._buddy_properties_changed_cb(handle, prop) def _new_channel_cb(self, object_path, channel_type, handle_type, handle, suppress_handler): diff --git a/services/presence/sugar-presence-service b/services/presence/sugar-presence-service index 1680fea5..6ab871ca 100755 --- a/services/presence/sugar-presence-service +++ b/services/presence/sugar-presence-service @@ -24,8 +24,12 @@ import os from sugar import logger from sugar import env + +_logger = logging.getLogger('s-p-s') + + def usage(): - logging.debug("Usage: sugar-presence-service [] [randomize]") + _logger.debug("Usage: sugar-presence-service [] [randomize]") sys.path.append(env.get_service_path('presence')) @@ -35,9 +39,9 @@ if len(sys.argv) in [2, 3]: try: test_num = int(sys.argv[1]) except ValueError: - logging.debug("Bad test user number.") + _logger.debug("Bad test user number.") if test_num < 1 or test_num > 10: - logging.debug("Bad test user number.") + _logger.debug("Bad test user number.") if len(sys.argv) == 3 and sys.argv[2] == "randomize": randomize = True @@ -54,6 +58,6 @@ else: import presenceservice -logging.info('Starting presence service...') +_logger.info('Starting presence service...') presenceservice.main(test_num, randomize) diff --git a/sugar/presence/presenceservice.py b/sugar/presence/presenceservice.py index 621a2894..1bc9a579 100644 --- a/sugar/presence/presenceservice.py +++ b/sugar/presence/presenceservice.py @@ -36,6 +36,8 @@ DBUS_SERVICE = "org.laptop.Sugar.Presence" DBUS_INTERFACE = "org.laptop.Sugar.Presence" DBUS_PATH = "/org/laptop/Sugar/Presence" +_logger = logging.getLogger('sugar.presence.presenceservice') + class PresenceService(gobject.GObject): """UI-side interface to the dbus presence service @@ -116,7 +118,7 @@ class PresenceService(gobject.GObject): DBUS_INTERFACE ) except dbus.exceptions.DBusException, err: - logging.error( + _logger.error( """Failure retrieving %r interface from the D-BUS service %r %r: %s""", DBUS_INTERFACE, DBUS_SERVICE, DBUS_PATH, err ) @@ -247,7 +249,7 @@ class PresenceService(gobject.GObject): try: resp = self._ps.GetActivities() except dbus.exceptions.DBusException, err: - logging.warn( + _logger.warn( """Unable to retrieve activity list from presence service: %s""" % err ) @@ -269,7 +271,7 @@ class PresenceService(gobject.GObject): try: act_op = self._ps.GetActivityById(activity_id) except dbus.exceptions.DBusException, err: - logging.warn( + _logger.warn( """Unable to retrieve activity handle for %r from presence service: %s""" % (activity_id, err) ) @@ -285,7 +287,7 @@ class PresenceService(gobject.GObject): try: resp = self._ps.GetBuddies() except dbus.exceptions.DBusException, err: - logging.warn( + _logger.warn( """Unable to retrieve buddy-list from presence service: %s""" % err ) @@ -308,7 +310,7 @@ class PresenceService(gobject.GObject): try: buddy_op = self._ps.GetBuddyByPublicKey(dbus.ByteArray(key)) except dbus.exceptions.DBusException, err: - logging.warn( + _logger.warn( """Unable to retrieve buddy handle for %r from presence service: %s""" % key, err ) @@ -320,7 +322,7 @@ class PresenceService(gobject.GObject): try: owner_op = self._ps.GetOwner() except dbus.exceptions.DBusException, err: - logging.warn( + _logger.warn( """Unable to retrieve local user/owner from presence service: %s""" % err ) @@ -335,7 +337,7 @@ class PresenceService(gobject.GObject): def _share_activity_error_cb(self, activity, err): """Notify with GObject event of unsuccessful sharing of activity""" - logging.debug("Error sharing activity %s: %s" % (activity.get_id(), err)) + _logger.debug("Error sharing activity %s: %s" % (activity.get_id(), err)) self.emit("activity-shared", False, None, err) def share_activity(self, activity, properties={}): From 5d77ff680a64fc22a84be65b21c420cd10ecd343 Mon Sep 17 00:00:00 2001 From: Simon McVittie Date: Tue, 15 May 2007 15:20:02 +0100 Subject: [PATCH 2/8] services/presence: Stop using deprecated keyword argument named_service --- services/presence/psutils.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/services/presence/psutils.py b/services/presence/psutils.py index 73a5315f..4d6ae3d5 100644 --- a/services/presence/psutils.py +++ b/services/presence/psutils.py @@ -118,13 +118,13 @@ class IP4AddressMonitor(gobject.GObject): match = sys_bus.add_signal_receiver(self._nm_device_no_longer_active_cb, signal_name="DeviceNoLongerActive", dbus_interface=NM_IFACE, - named_service=NM_SERVICE) + bus_name=NM_SERVICE) self._matches.append(match) match = sys_bus.add_signal_receiver(self._nm_state_change_cb, signal_name="StateChange", dbus_interface=NM_IFACE, - named_service=NM_SERVICE) + bus_name=NM_SERVICE) self._matches.append(match) state = self._nm_obj.state() From 35d190b55e49aabcf7d9727cf3d44147451f4434 Mon Sep 17 00:00:00 2001 From: Simon McVittie Date: Wed, 16 May 2007 11:39:16 +0100 Subject: [PATCH 3/8] services/presence/server_plugin.py: Handle presence more correctly. This avoids unnecessary attempts to look up the buddy properties of channel-specific handles (which doesn't work) by only looking up the buddy properties of people we're subscribed to. Also, this approves subscription requests that come in while we're online, rather than handling them when we next go from offline to online. --- services/presence/server_plugin.py | 53 +++++++++++++++++++++++++++--- 1 file changed, 49 insertions(+), 4 deletions(-) diff --git a/services/presence/server_plugin.py b/services/presence/server_plugin.py index b3b9482a..ac569ba0 100644 --- a/services/presence/server_plugin.py +++ b/services/presence/server_plugin.py @@ -320,11 +320,22 @@ class ServerPlugin(gobject.GObject): # the group of contacts who may receive your presence publish = self._request_list_channel('publish') - publish_handles, local_pending, remote_pending = publish[CHANNEL_INTERFACE_GROUP].GetAllMembers() + self._publish_channel = publish + publish[CHANNEL_INTERFACE_GROUP].connect_to_signal('MembersChanged', + self._publish_members_changed_cb) + publish_handles, local_pending, remote_pending = \ + publish[CHANNEL_INTERFACE_GROUP].GetAllMembers() # the group of contacts for whom you wish to receive presence subscribe = self._request_list_channel('subscribe') - subscribe_handles = subscribe[CHANNEL_INTERFACE_GROUP].GetMembers() + self._subscribe_channel = subscribe + subscribe[CHANNEL_INTERFACE_GROUP].connect_to_signal('MembersChanged', + self._subscribe_members_changed_cb) + subscribe_handles, subscribe_lp, subscribe_rp = \ + subscribe[CHANNEL_INTERFACE_GROUP].GetAllMembers() + self._subscribe_members = set(subscribe_handles) + self._subscribe_local_pending = set(subscribe_lp) + self._subscribe_remote_pending = set(subscribe_rp) if local_pending: # accept pending subscriptions @@ -364,8 +375,7 @@ class ServerPlugin(gobject.GObject): self._set_self_current_activity() self._set_self_avatar() - # Request presence for everyone on the channel - subscribe_handles = subscribe[CHANNEL_INTERFACE_GROUP].GetMembers() + # Request presence for everyone we're subscribed to self._conn[CONN_INTERFACE_PRESENCE].RequestPresence(subscribe_handles) return True @@ -690,6 +700,13 @@ class ServerPlugin(gobject.GObject): def _contact_online(self, handle): """Handle a contact coming online""" + if (handle not in self._subscribe_members and + handle not in self._subscribe_local_pending and + handle not in self._subscribe_remote_pending): + # it's probably a channel-specific handle - can't create a Buddy + # object + return + self._online_contacts[handle] = None if handle == self._conn[CONN_INTERFACE].GetSelfHandle(): jid = self._conn[CONN_INTERFACE].InspectHandles(CONNECTION_HANDLE_TYPE_CONTACT, [handle])[0] @@ -702,6 +719,34 @@ class ServerPlugin(gobject.GObject): reply_handler=lambda *args: self._contact_online_properties_cb(handle, *args), error_handler=lambda *args: self._contact_online_properties_error_cb(handle, *args)) + def _subscribe_members_changed_cb(self, added, removed, local_pending, + remote_pending, actor, reason): + for handle in added: + self._subscribe_members.add(handle) + for handle in local_pending: + self._subscribe_local_pending.add(handle) + for handle in remote_pending: + self._subscribe_remote_pending.add(handle) + for handle in removed: + self._subscribe_members.discard(handle) + self._subscribe_local_pending.discard(handle) + self._subscribe_remote_pending.discard(handle) + + def _publish_members_changed_cb(self, added, removed, local_pending, + remote_pending, actor, reason): + + if local_pending: + # accept all requested subscriptions + self._publish_channel[CHANNEL_INTERFACE_GROUP].AddMembers( + local_pending, '') + + # subscribe to people who've subscribed to us, if necessary + added = list(set(added) - self._subscribe_members + - self._subscribe_remote_pending) + if added: + self._subscribe_channel[CHANNEL_INTERFACE_GROUP].AddMembers( + added, '') + def _presence_update_cb(self, presence): """Send update for online/offline status of presence""" for handle in presence: From 3ac4cb5432c30bc2744c4139dad825d0a3671792 Mon Sep 17 00:00:00 2001 From: Tomeu Vizoso Date: Sat, 19 May 2007 10:01:07 +0200 Subject: [PATCH 4/8] Stop depending on NSPR. --- configure.ac | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/configure.ac b/configure.ac index 6f4f2a33..ecfb7b1c 100644 --- a/configure.ac +++ b/configure.ac @@ -57,22 +57,6 @@ AC_SUBST(MOZILLA_INCLUDE_DIR) AC_SUBST(XPIDL) AC_SUBST(MOZILLA_IDL_DIR) -PKG_CHECK_MODULES(NSPR, [nspr], - [have_nspr=true], - [ -PKG_CHECK_MODULES(NSPR, [mozilla-nspr], - [have_nspr=true], - [ -PKG_CHECK_MODULES(NSPR, [xulrunner-nspr], - [have_nspr=true], - have_nspr=false) - ]) - ]) - -if test "x$have_nspr" = xfalse; then - AC_MSG_ERROR([Could not find nspr]) -fi - else AC_MSG_ERROR([Must specify the xulrunner sdk dir (--with-libxul-sdk)]) From abec4df66ec2433249185ce8a046e33a60c20acb Mon Sep 17 00:00:00 2001 From: Tomeu Vizoso Date: Sat, 19 May 2007 11:19:56 +0200 Subject: [PATCH 5/8] Don't try to display an icon without file name. --- sugar/graphics/canvasicon.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sugar/graphics/canvasicon.py b/sugar/graphics/canvasicon.py index 14f83519..ec141d0c 100644 --- a/sugar/graphics/canvasicon.py +++ b/sugar/graphics/canvasicon.py @@ -123,7 +123,7 @@ class _IconCache: del self._icons[evict_key] def get_handle(self, name, fill_color, stroke_color): - if name == None: + if not name: return None if name[0:6] == "theme:": From 5d4b9b1dfa6a10e25062f439b1af30cdfa06e3d2 Mon Sep 17 00:00:00 2001 From: Tomeu Vizoso Date: Sat, 19 May 2007 20:06:36 +0200 Subject: [PATCH 6/8] Set the activity icon on new journal entries. --- sugar/activity/activity.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/sugar/activity/activity.py b/sugar/activity/activity.py index 421d7ba2..05d02a4c 100644 --- a/sugar/activity/activity.py +++ b/sugar/activity/activity.py @@ -28,6 +28,7 @@ import gtk, gobject from sugar.presence import presenceservice from sugar.activity.activityservice import ActivityService +from sugar.activity import bundleregistry from sugar.graphics.window import Window from sugar.graphics.toolbox import Toolbox from sugar.graphics.toolbutton import ToolButton @@ -206,7 +207,7 @@ class Activity(Window, gtk.Container): self.jobject['title'] = '%s %s' % (get_bundle_name(), 'Activity') self.jobject['activity'] = self.get_service_name() self.jobject['date'] = str(time.time()) - self.jobject['icon'] = '' + self.jobject['icon'] = self._get_icon() self.jobject['keep'] = '0' self.jobject['buddies'] = '' self.jobject['preview'] = '' @@ -329,6 +330,10 @@ class Activity(Window, gtk.Container): raise self.destroy() + def _get_icon(self): + registry = bundleregistry.get_registry() + return registry.get_bundle(self.get_service_name()).get_icon() + def get_bundle_name(): """Return the bundle name for the current process' bundle """ From 04fc7047c2a640f731090839137f26cacc16094c Mon Sep 17 00:00:00 2001 From: Tomeu Vizoso Date: Sun, 20 May 2007 12:36:55 +0200 Subject: [PATCH 7/8] Don't autolaunch downloaded docs, this will be done from the Web activity. --- shell/view/clipboardicon.py | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/shell/view/clipboardicon.py b/shell/view/clipboardicon.py index fb370fb9..fc609f6b 100644 --- a/shell/view/clipboardicon.py +++ b/shell/view/clipboardicon.py @@ -106,16 +106,6 @@ class ClipboardIcon(CanvasIcon): else: self.props.xo_color = XoColor("#000000,#FFFFFF") - if activity and percent == 100: - # FIXME: restrict based on file type rather than activity once - # we have a better type registry - # restrict auto-open to a specific set of activities - allowed = ["org.laptop.AbiWordActivity", - "org.laptop.sugar.Xbook", - "org.vpri.EtoysActivity"] - if activity in allowed: - self._open_file() - def _open_file(self): if self._percent < 100: return From 11c89d86c91d91de42a815f7715076494c33fa25 Mon Sep 17 00:00:00 2001 From: Tomeu Vizoso Date: Sun, 20 May 2007 12:38:08 +0200 Subject: [PATCH 8/8] Put dates to work correctly on the journal, create a new journal entry when resuming a past entry. --- sugar/activity/activity.py | 4 +++- sugar/datastore/datastore.py | 3 +++ sugar/datastore/dbus_helpers.py | 2 +- 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/sugar/activity/activity.py b/sugar/activity/activity.py index 05d02a4c..3dba4c71 100644 --- a/sugar/activity/activity.py +++ b/sugar/activity/activity.py @@ -201,12 +201,14 @@ class Activity(Window, gtk.Container): if handle.object_id: self.jobject = datastore.get(handle.object_id) + self.jobject.object_id = '' + del self.jobject['ctime'] + del self.jobject['mtime'] elif create_jobject: logging.debug('Creating a jobject.') self.jobject = datastore.create() self.jobject['title'] = '%s %s' % (get_bundle_name(), 'Activity') self.jobject['activity'] = self.get_service_name() - self.jobject['date'] = str(time.time()) self.jobject['icon'] = self._get_icon() self.jobject['keep'] = '0' self.jobject['buddies'] = '' diff --git a/sugar/datastore/datastore.py b/sugar/datastore/datastore.py index 99fd230d..9d656707 100644 --- a/sugar/datastore/datastore.py +++ b/sugar/datastore/datastore.py @@ -39,6 +39,9 @@ class DSObject(gobject.GObject): self.metadata[key] = value self.emit('updated') + def __delitem__(self, key): + del self.metadata[key] + def get_metadata(self): return self._metadata diff --git a/sugar/datastore/dbus_helpers.py b/sugar/datastore/dbus_helpers.py index 33aa9a6e..fa054915 100644 --- a/sugar/datastore/dbus_helpers.py +++ b/sugar/datastore/dbus_helpers.py @@ -40,7 +40,7 @@ def create(properties, filename): return object_id def update(uid, properties, filename, reply_handler=None, error_handler=None): - logging.debug('dbus_helpers.update') + logging.debug('dbus_helpers.update: %s, %s' % (uid, filename)) if reply_handler and error_handler: _data_store.update(uid, dbus.Dictionary(properties), filename, reply_handler=reply_handler,