From c5063ebc198745386aca309291db4676da0f75f8 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Tue, 24 Jul 2007 18:29:18 -0400 Subject: [PATCH 1/8] Turn off logging by default; re-enable on a per-module basis using environment variables --- sugar/logger.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/sugar/logger.py b/sugar/logger.py index 6d9ff3ab..c7f610e6 100644 --- a/sugar/logger.py +++ b/sugar/logger.py @@ -103,6 +103,11 @@ def _get_logs_dir(): return logs_dir def start(module_id): + # Only log if logging is set up for the activity + module_key = module_id.upper() + "_DEBUG" + if not os.environ.has_key(module_key): + return + log_writer = LogWriter(module_id) root_logger = logging.getLogger('') From ba08537dc71432334bc43bfcde04dcf32f47d7a3 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Tue, 24 Jul 2007 18:39:48 -0400 Subject: [PATCH 2/8] update NEWS file --- NEWS | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/NEWS b/NEWS index 15375277..7b805edc 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,7 @@ +* Turn off logging by default. Logs may be re-enabled on a per-module basis + by adding environment variables like SHELL_DEBUG and RECORD_DEBUG to + the sugar environment + Snapshot 9ac5d38e90 * #2361 Ensure secondary palette state doesn't go out of screen. (marco) From 5e30ed9f3b02ae71bb75b7b49675fff86b6d446e Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Wed, 25 Jul 2007 12:24:10 -0400 Subject: [PATCH 3/8] Turn logs on by default for the emulator --- sugar/logger.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/sugar/logger.py b/sugar/logger.py index c7f610e6..e8570441 100644 --- a/sugar/logger.py +++ b/sugar/logger.py @@ -105,7 +105,11 @@ def _get_logs_dir(): def start(module_id): # Only log if logging is set up for the activity module_key = module_id.upper() + "_DEBUG" - if not os.environ.has_key(module_key): + emulator = False + if os.environ.has_key("SUGAR_EMULATOR"): + if os.environ["SUGAR_EMULATOR"] == "yes": + emulator = True + if not os.environ.has_key(module_key) and not emulator: return log_writer = LogWriter(module_id) From df5ebb32e0ad1f887d2a8f7c372ea5475e28708c Mon Sep 17 00:00:00 2001 From: Simon McVittie Date: Wed, 25 Jul 2007 13:09:51 -0400 Subject: [PATCH 4/8] Show channels, handles, activity participants, buddy activities, errors --- services/console/interface/ps_watcher.py | 254 ++++++++++++++++++++--- 1 file changed, 229 insertions(+), 25 deletions(-) diff --git a/services/console/interface/ps_watcher.py b/services/console/interface/ps_watcher.py index b9138e16..d71a6c08 100644 --- a/services/console/interface/ps_watcher.py +++ b/services/console/interface/ps_watcher.py @@ -19,7 +19,7 @@ from hashlib import sha1 import dbus from gtk import VBox, Label, TreeView, Expander, ListStore, CellRendererText,\ - ScrolledWindow, CellRendererToggle + ScrolledWindow, CellRendererToggle, TextView, VPaned from gobject import timeout_add @@ -42,6 +42,9 @@ ACT_COL_ID = 3 ACT_COL_COLOR = 4 ACT_COL_TYPE = 5 ACT_COL_NAME = 6 +ACT_COL_CONN = 7 +ACT_COL_CHANNELS = 8 +ACT_COL_BUDDIES = 9 BUDDY_COL_PATH = 0 BUDDY_COL_WEIGHT = 1 BUDDY_COL_STRIKE = 2 @@ -51,6 +54,8 @@ BUDDY_COL_COLOR = 5 BUDDY_COL_IP4 = 6 BUDDY_COL_CUR_ACT = 7 BUDDY_COL_KEY_ID = 8 +BUDDY_COL_ACTIVITIES = 9 +BUDDY_COL_HANDLES = 10 class ActivityWatcher(object): @@ -70,6 +75,9 @@ class ActivityWatcher(object): self.color = '?' self.type = '?' self.name = '?' + self.conn = '?' + self.channels = None + self.buddies = None self.iter = self.ps_watcher.add_activity(self) @@ -85,12 +93,84 @@ class ActivityWatcher(object): self.iface.GetName(reply_handler=self._on_get_name_success, error_handler=self._on_get_name_failure) + self.iface.connect_to_signal('NewChannel', self._on_new_channel) + self.iface.GetChannels(reply_handler=self._on_get_channels_success, + error_handler=self._on_get_channels_failure) + + self.iface.connect_to_signal('BuddyJoined', self._on_buddy_joined) + self.iface.connect_to_signal('BuddyLeft', self._on_buddy_left) + self.iface.GetJoinedBuddies(reply_handler=self._on_get_buddies_success, + error_handler=self._on_get_buddies_failure) + + def _on_buddy_joined(self, buddy): + if self.buddies is None: + return + if buddy.startswith('/org/laptop/Sugar/Presence/Buddies/'): + buddy = '.../' + buddy[35:] + self.buddies.append(buddy) + self.ps_watcher.activities_list_store.set(self.iter, ACT_COL_BUDDIES, + ' '.join(self.buddies)) + + def _on_buddy_left(self, buddy): + if self.buddies is None: + return + if buddy.startswith('/org/laptop/Sugar/Presence/Buddies/'): + buddy = '.../' + buddy[35:] + try: + self.buddies.remove(buddy) + except ValueError: + pass + self.ps_watcher.activities_list_store.set(self.iter, ACT_COL_BUDDIES, + ' '.join(self.buddies)) + + def _on_get_buddies_success(self, buddies): + self.buddies = [] + for buddy in buddies: + self._on_buddy_joined(buddy) + + def _on_get_buddies_failure(self, e): + self.log('.GetJoinedBuddies(): %s', self.object_path, e) + self.ps_watcher.activities_list_store.set(self.iter, ACT_COL_BUDDIES, + '!') + + def _on_new_channel(self, channel): + if self.channels is None: + return + if channel.startswith(self.full_conn): + channel = '...' + channel[len(self.full_conn):] + self.channels.append(channel) + # FIXME: listen for Telepathy Closed signal! + self.ps_watcher.activities_list_store.set(self.iter, ACT_COL_CHANNELS, + ' '.join(self.channels)) + + def _on_get_channels_success(self, service, conn, channels): + self.full_conn = conn + if conn.startswith('/org/freedesktop/Telepathy/Connection/'): + self.conn = '.../' + conn[38:] + else: + self.conn = conn + self.ps_watcher.activities_list_store.set(self.iter, ACT_COL_CONN, + self.conn) + self.channels = [] + for channel in channels: + self._on_new_channel(channel) + self.ps_watcher.activities_list_store.set(self.iter, ACT_COL_CHANNELS, + ' '.join(self.channels)) + + def _on_get_channels_failure(self, e): + self.ps_watcher.log('.GetChannels(): %s', + self.object_path, e) + self.ps_watcher.activities_list_store.set(self.iter, ACT_COL_CONN, + '!') + self.ps_watcher.activities_list_store.set(self.iter, ACT_COL_CHANNELS, + '!') + def _on_get_id_success(self, ident): self.id = ident self.ps_watcher.activities_list_store.set(self.iter, ACT_COL_ID, ident) def _on_get_id_failure(self, e): - logger.warning('.GetId(): %s', self.object_path, e) + self.ps_watcher.log('.GetId(): %s', self.object_path, e) self.ps_watcher.activities_list_store.set(self.iter, ACT_COL_ID, '!') @@ -100,7 +180,8 @@ class ActivityWatcher(object): color) def _on_get_color_failure(self, e): - logger.warning('.GetColor(): %s', self.object_path, e) + self.ps_watcher.log('.GetColor(): %s', + self.object_path, e) self.ps_watcher.activities_list_store.set(self.iter, ACT_COL_COLOR, '!') @@ -110,7 +191,7 @@ class ActivityWatcher(object): type_) def _on_get_type_failure(self, e): - logger.warning('.GetType(): %s', self.object_path, e) + self.ps_watcher.log('.GetType(): %s', self.object_path, e) self.ps_watcher.activities_list_store.set(self.iter, ACT_COL_TYPE, '!') @@ -120,7 +201,7 @@ class ActivityWatcher(object): name) def _on_get_name_failure(self, e): - logger.warning('.GetName(): %s', self.object_path, e) + self.ps_watcher.log('.GetName(): %s', self.object_path, e) self.ps_watcher.activities_list_store.set(self.iter, ACT_COL_NAME, '!') @@ -160,6 +241,8 @@ class BuddyWatcher(object): self.ipv4 = '?' self.cur_act = '?' self.keyid = '?' + self.activities = None + self.handles = None self.iter = self.ps_watcher.add_buddy(self) @@ -167,6 +250,81 @@ class BuddyWatcher(object): error_handler=self._on_get_props_failure, byte_arrays=True) + self.iface.connect_to_signal('JoinedActivity', self._on_joined) + self.iface.connect_to_signal('LeftActivity', self._on_left) + self.iface.GetJoinedActivities(reply_handler=self._on_get_acts_success, + error_handler=self._on_get_acts_failure) + + self.iface.connect_to_signal('TelepathyHandleAdded', + self._on_handle_added) + self.iface.connect_to_signal('TelepathyHandleRemoved', + self._on_handle_removed) + self.iface.GetTelepathyHandles( + reply_handler=self._on_get_handles_success, + error_handler=self._on_get_handles_failure) + + def _on_handle_added(self, service, conn, handle): + if self.handles is None: + return + if conn.startswith('/org/freedesktop/Telepathy/Connection/'): + conn = '.../' + conn[38:] + self.handles.append('%u@%s' % (handle, conn)) + self.ps_watcher.buddies_list_store.set(self.iter, + BUDDY_COL_HANDLES, + ' '.join(self.handles)) + + def _on_handle_removed(self, service, conn, handle): + if self.handles is None: + return + if conn.startswith('/org/freedesktop/Telepathy/Connection/'): + conn = '.../' + conn[38:] + try: + self.handles.append('%u@%s' % (handle, conn)) + except ValueError: + pass + self.ps_watcher.buddies_list_store.set(self.iter, BUDDY_COL_HANDLES, + ' '.join(self.handles)) + + def _on_get_handles_success(self, handles): + self.handles = [] + for service, conn, handle in handles: + self._on_handle_added(service, conn, handle) + + def _on_get_handles_failure(self, e): + self.log('.GetTelepathyHandles(): %s', self.object_path, e) + self.ps_watcher.buddies_list_store.set(self.iter, BUDDY_COL_HANDLES, + '!') + + def _on_joined(self, act): + if self.activities is None: + return + if act.startswith('/org/laptop/Sugar/Presence/Activities/'): + act = '.../' + act[38:] + self.activities.append(act) + self.ps_watcher.buddies_list_store.set(self.iter, + BUDDY_COL_ACTIVITIES, + ' '.join(self.activities)) + + def _on_left(self, act): + if self.activities is None: + return + try: + self.activities.remove(act) + except ValueError: + pass + self.ps_watcher.buddies_list_store.set(self.iter, BUDDY_COL_ACTIVITIES, + ' '.join(self.activities)) + + def _on_get_acts_success(self, activities): + self.activities = [] + for act in activities: + self._on_joined(act) + + def _on_get_acts_failure(self, e): + self.log('.GetJoinedActivities(): %s', self.object_path, e) + self.ps_watcher.buddies_list_store.set(self.iter, BUDDY_COL_ACTIVITIES, + '!') + def _on_get_props_success(self, props): # ignore key for now self.nick = props.get('nick', '?') @@ -194,7 +352,8 @@ class BuddyWatcher(object): self.keyid) def _on_get_props_failure(self, e): - logger.warning('.GetProperties(): %s', self.object_path, e) + self.ps_watcher.log('.GetProperties(): %s', + self.object_path, e) self.ps_watcher.buddies_list_store.set(self.iter, BUDDY_COL_NICK, '!') self.ps_watcher.buddies_list_store.set(self.iter, BUDDY_COL_OWNER, False) @@ -205,7 +364,6 @@ class BuddyWatcher(object): self.ps_watcher.buddies_list_store.set(self.iter, BUDDY_COL_KEY_ID, '!') - def _finish_appearing(self): self.appearing = False self.ps_watcher.buddies_list_store.set(self.iter, BUDDY_COL_WEIGHT, @@ -225,7 +383,7 @@ class BuddyWatcher(object): class PresenceServiceWatcher(VBox): - def __init__(self, bus, unique_name): + def __init__(self, bus, unique_name, log): VBox.__init__(self) logger.debug('Starting up PresenceServiceWatcher...') @@ -233,6 +391,7 @@ class PresenceServiceWatcher(VBox): self.unique_name = unique_name self.proxy = bus.get_object(unique_name, PS_PATH) self.iface = dbus.Interface(self.proxy, PS_IFACE) + self.log = log logger.debug('Starting up PresenceServiceWatcher (2)...') @@ -260,6 +419,9 @@ class PresenceServiceWatcher(VBox): str, # color str, # type str, # name + str, # conn + str, # channels + str, # buddies ) self.pack_start(Label('Activities:'), False, False) @@ -290,6 +452,19 @@ class PresenceServiceWatcher(VBox): strikethrough=ACT_COL_STRIKE) c.set_resizable(True) c.set_sort_column_id(ACT_COL_NAME) + c = self.activities_list.insert_column_with_attributes(5, 'Connection', + CellRendererText(), text=ACT_COL_CONN, weight=ACT_COL_WEIGHT, + strikethrough=ACT_COL_STRIKE) + c.set_resizable(True) + c.set_sort_column_id(ACT_COL_CONN) + c = self.activities_list.insert_column_with_attributes(6, 'Channels', + CellRendererText(), text=ACT_COL_CHANNELS, weight=ACT_COL_WEIGHT, + strikethrough=ACT_COL_STRIKE) + c.set_resizable(True) + c = self.activities_list.insert_column_with_attributes(7, 'Buddies', + CellRendererText(), text=ACT_COL_BUDDIES, weight=ACT_COL_WEIGHT, + strikethrough=ACT_COL_STRIKE) + c.set_resizable(True) scroller = ScrolledWindow() scroller.add(self.activities_list) @@ -297,7 +472,7 @@ class PresenceServiceWatcher(VBox): # keep this in sync with the BUDDY_COL_ constants self.buddies_list_store = ListStore(str, int, bool, str, bool, - str, str, str, str) + str, str, str, str, str, str) self.pack_start(Label('Buddies:'), False, False) self.buddies_list = TreeView(self.buddies_list_store) @@ -333,6 +508,16 @@ class PresenceServiceWatcher(VBox): weight=BUDDY_COL_WEIGHT, strikethrough=BUDDY_COL_STRIKE) c.set_resizable(True) c.set_sort_column_id(BUDDY_COL_CUR_ACT) + c = self.buddies_list.insert_column_with_attributes(7, 'Activities', + CellRendererText(), text=BUDDY_COL_ACTIVITIES, + weight=BUDDY_COL_WEIGHT, strikethrough=BUDDY_COL_STRIKE) + c.set_resizable(True) + c.set_sort_column_id(BUDDY_COL_ACTIVITIES) + c = self.buddies_list.insert_column_with_attributes(8, 'Handles', + CellRendererText(), text=BUDDY_COL_HANDLES, + weight=BUDDY_COL_WEIGHT, strikethrough=BUDDY_COL_STRIKE) + c.set_resizable(True) + c.set_sort_column_id(BUDDY_COL_HANDLES) scroller = ScrolledWindow() scroller.add(self.buddies_list) @@ -350,14 +535,14 @@ class PresenceServiceWatcher(VBox): self.activities[path] = ActivityWatcher(self, path) def _on_get_activities_failure(self, e): - logger.warning('PS GetActivities() failed with %s', e) + self.log('PS GetActivities() failed with %s', e) def add_activity(self, act): path = act.object_path if path.startswith('/org/laptop/Sugar/Presence/Activities/'): path = '.../' + path[38:] return self.activities_list_store.append((path, 700, False, - act.id, act.color, act.type, act.name)) + act.id, act.color, act.type, act.name, act.conn, '?', '?')) def remove_activity(self, act): self.activities.pop(act.object_path, None) @@ -375,8 +560,8 @@ class PresenceServiceWatcher(VBox): logger.debug('PS emitted ActivityDisappeared("%s")', path) act = self.activities.get(path) if act is None: - logger.warning('Trying to remove activity "%s" which is already ' - 'absent', path) + self.log('Trying to remove activity "%s" which is already ' + 'absent', path) else: # we don't remove the activity straight away, just cross it out act.disappear() @@ -395,14 +580,15 @@ class PresenceServiceWatcher(VBox): self.buddies[path] = BuddyWatcher(self, path) def _on_get_buddies_failure(self, e): - logger.warning('PS GetBuddies() failed with %s', e) + self.log('PS GetBuddies() failed with %s', e) def add_buddy(self, b): path = b.object_path if path.startswith('/org/laptop/Sugar/Presence/Buddies/'): path = '.../' + path[35:] return self.buddies_list_store.append((path, 700, False, - b.nick, b.owner, b.color, b.ipv4, b.cur_act, b.keyid)) + b.nick, b.owner, b.color, b.ipv4, b.cur_act, b.keyid, + '?', '?')) def remove_buddy(self, b): self.buddies.pop(b.object_path, None) @@ -420,8 +606,8 @@ class PresenceServiceWatcher(VBox): logger.debug('PS emitted BuddyDisappeared("%s")', path) b = self.buddies.get(path) if b is None: - logger.warning('Trying to remove buddy "%s" which is already ' - 'absent', path) + self.log('Trying to remove buddy "%s" which is already ' + 'absent', path) else: # we don't remove the activity straight away, just cross it out b.disappear() @@ -435,30 +621,48 @@ class PresenceServiceNameWatcher(VBox): self.bus = bus self.label = Label('Looking for Presence Service...') - bus.watch_name_owner(PS_NAME, self.on_name_owner_change) + self.errors = ListStore(str) + + errors = TreeView(model=self.errors) + errors.insert_column_with_attributes(0, 'Errors', CellRendererText(), + text=0) + scroller = ScrolledWindow() + scroller.add(errors) + + self.paned = VPaned() + self.paned.pack1(scroller) self.pack_start(self.label, False, False) - self.ps_watcher = None + self.pack_end(self.paned) + + bus.watch_name_owner(PS_NAME, self.on_name_owner_change) + self.ps_watcher = Label('-') + self.paned.pack2(self.ps_watcher) self.show_all() + def log(self, format, *args): + self.errors.append((format % args,)) + def on_name_owner_change(self, owner): try: if owner: self.label.set_text('Presence Service running: unique name %s' % owner) if self.ps_watcher is not None: - self.remove(self.ps_watcher) - self.ps_watcher = PresenceServiceWatcher(self.bus, owner) - self.pack_start(self.ps_watcher) + self.paned.remove(self.ps_watcher) + self.ps_watcher = PresenceServiceWatcher(self.bus, owner, + self.log) + self.paned.pack2(self.ps_watcher) self.show_all() else: self.label.set_text('Presence Service not running') if self.ps_watcher is not None: - self.remove(self.ps_watcher) - self.ps_watcher = None + self.paned.remove(self.ps_watcher) + self.ps_watcher = Label('-') + self.paned.pack2(self.ps_watcher) except Exception, e: - logger.warning('%s', e) + self.log('%s', e) class Interface(object): From 9885b892a2d95321da016ae1a28c2e1c9628c414 Mon Sep 17 00:00:00 2001 From: Simon McVittie Date: Wed, 25 Jul 2007 13:26:28 -0400 Subject: [PATCH 5/8] Console ps_watcher: Log signals as well as errors. Correctly remove activity from buddy's list when buddy leaves. --- services/console/interface/ps_watcher.py | 83 +++++++++++++++--------- 1 file changed, 52 insertions(+), 31 deletions(-) diff --git a/services/console/interface/ps_watcher.py b/services/console/interface/ps_watcher.py index d71a6c08..2216f39f 100644 --- a/services/console/interface/ps_watcher.py +++ b/services/console/interface/ps_watcher.py @@ -24,8 +24,8 @@ from gobject import timeout_add logger = logging.getLogger('ps_watcher') -logging.basicConfig(filename='/tmp/ps_watcher.log') -logging.getLogger().setLevel(1) +#logging.basicConfig(filename='/tmp/ps_watcher.log') +#logging.getLogger().setLevel(1) PS_NAME = 'org.laptop.Sugar.Presence' @@ -107,6 +107,8 @@ class ActivityWatcher(object): return if buddy.startswith('/org/laptop/Sugar/Presence/Buddies/'): buddy = '.../' + buddy[35:] + self.ps_watcher.log('INFO: Activity %s emitted BuddyJoined("%s")', + self.object_path, buddy) self.buddies.append(buddy) self.ps_watcher.activities_list_store.set(self.iter, ACT_COL_BUDDIES, ' '.join(self.buddies)) @@ -116,6 +118,8 @@ class ActivityWatcher(object): return if buddy.startswith('/org/laptop/Sugar/Presence/Buddies/'): buddy = '.../' + buddy[35:] + self.ps_watcher.log('INFO: Activity %s emitted BuddyLeft("%s")', + self.object_path, buddy) try: self.buddies.remove(buddy) except ValueError: @@ -129,7 +133,8 @@ class ActivityWatcher(object): self._on_buddy_joined(buddy) def _on_get_buddies_failure(self, e): - self.log('.GetJoinedBuddies(): %s', self.object_path, e) + self.log('ERROR: .GetJoinedBuddies(): %s', + self.object_path, e) self.ps_watcher.activities_list_store.set(self.iter, ACT_COL_BUDDIES, '!') @@ -138,6 +143,8 @@ class ActivityWatcher(object): return if channel.startswith(self.full_conn): channel = '...' + channel[len(self.full_conn):] + self.ps_watcher.log('INFO: Activity %s emitted NewChannel("%s")', + self.object_path, channel) self.channels.append(channel) # FIXME: listen for Telepathy Closed signal! self.ps_watcher.activities_list_store.set(self.iter, ACT_COL_CHANNELS, @@ -158,7 +165,7 @@ class ActivityWatcher(object): ' '.join(self.channels)) def _on_get_channels_failure(self, e): - self.ps_watcher.log('.GetChannels(): %s', + self.ps_watcher.log('ERROR: .GetChannels(): %s', self.object_path, e) self.ps_watcher.activities_list_store.set(self.iter, ACT_COL_CONN, '!') @@ -170,7 +177,8 @@ class ActivityWatcher(object): self.ps_watcher.activities_list_store.set(self.iter, ACT_COL_ID, ident) def _on_get_id_failure(self, e): - self.ps_watcher.log('.GetId(): %s', self.object_path, e) + self.ps_watcher.log('ERROR: .GetId(): %s', + self.object_path, e) self.ps_watcher.activities_list_store.set(self.iter, ACT_COL_ID, '!') @@ -180,7 +188,7 @@ class ActivityWatcher(object): color) def _on_get_color_failure(self, e): - self.ps_watcher.log('.GetColor(): %s', + self.ps_watcher.log('ERROR: .GetColor(): %s', self.object_path, e) self.ps_watcher.activities_list_store.set(self.iter, ACT_COL_COLOR, '!') @@ -191,7 +199,8 @@ class ActivityWatcher(object): type_) def _on_get_type_failure(self, e): - self.ps_watcher.log('.GetType(): %s', self.object_path, e) + self.ps_watcher.log('ERROR: .GetType(): %s', + self.object_path, e) self.ps_watcher.activities_list_store.set(self.iter, ACT_COL_TYPE, '!') @@ -201,7 +210,8 @@ class ActivityWatcher(object): name) def _on_get_name_failure(self, e): - self.ps_watcher.log('.GetName(): %s', self.object_path, e) + self.ps_watcher.log('ERROR: .GetName(): %s', + self.object_path, e) self.ps_watcher.activities_list_store.set(self.iter, ACT_COL_NAME, '!') @@ -266,6 +276,9 @@ class BuddyWatcher(object): def _on_handle_added(self, service, conn, handle): if self.handles is None: return + self.ps_watcher.log('INFO: Buddy %s emitted HandleAdded("%s", ' + '"%s", %u)', self.object_path, service, conn, + handle) if conn.startswith('/org/freedesktop/Telepathy/Connection/'): conn = '.../' + conn[38:] self.handles.append('%u@%s' % (handle, conn)) @@ -278,8 +291,11 @@ class BuddyWatcher(object): return if conn.startswith('/org/freedesktop/Telepathy/Connection/'): conn = '.../' + conn[38:] + self.ps_watcher.log('INFO: Buddy %s emitted HandleRemoved("%s", ' + '"%s", %u)', self.object_path, service, conn, + handle) try: - self.handles.append('%u@%s' % (handle, conn)) + self.handles.remove('%u@%s' % (handle, conn)) except ValueError: pass self.ps_watcher.buddies_list_store.set(self.iter, BUDDY_COL_HANDLES, @@ -291,7 +307,8 @@ class BuddyWatcher(object): self._on_handle_added(service, conn, handle) def _on_get_handles_failure(self, e): - self.log('.GetTelepathyHandles(): %s', self.object_path, e) + self.log('ERROR: .GetTelepathyHandles(): %s', + self.object_path, e) self.ps_watcher.buddies_list_store.set(self.iter, BUDDY_COL_HANDLES, '!') @@ -300,6 +317,8 @@ class BuddyWatcher(object): return if act.startswith('/org/laptop/Sugar/Presence/Activities/'): act = '.../' + act[38:] + self.ps_watcher.log('INFO: Buddy %s emitted ActivityJoined("%s")', + self.object_path, act) self.activities.append(act) self.ps_watcher.buddies_list_store.set(self.iter, BUDDY_COL_ACTIVITIES, @@ -308,6 +327,10 @@ class BuddyWatcher(object): def _on_left(self, act): if self.activities is None: return + if act.startswith('/org/laptop/Sugar/Presence/Activities/'): + act = '.../' + act[38:] + self.ps_watcher.log('INFO: Buddy %s emitted ActivityLeft("%s")', + self.object_path, act) try: self.activities.remove(act) except ValueError: @@ -321,7 +344,8 @@ class BuddyWatcher(object): self._on_joined(act) def _on_get_acts_failure(self, e): - self.log('.GetJoinedActivities(): %s', self.object_path, e) + self.log('ERROR: .GetJoinedActivities(): %s', + self.object_path, e) self.ps_watcher.buddies_list_store.set(self.iter, BUDDY_COL_ACTIVITIES, '!') @@ -352,7 +376,7 @@ class BuddyWatcher(object): self.keyid) def _on_get_props_failure(self, e): - self.ps_watcher.log('.GetProperties(): %s', + self.ps_watcher.log('ERROR: .GetProperties(): %s', self.object_path, e) self.ps_watcher.buddies_list_store.set(self.iter, BUDDY_COL_NICK, '!') self.ps_watcher.buddies_list_store.set(self.iter, BUDDY_COL_OWNER, @@ -386,15 +410,12 @@ class PresenceServiceWatcher(VBox): def __init__(self, bus, unique_name, log): VBox.__init__(self) - logger.debug('Starting up PresenceServiceWatcher...') self.bus = bus self.unique_name = unique_name self.proxy = bus.get_object(unique_name, PS_PATH) self.iface = dbus.Interface(self.proxy, PS_IFACE) self.log = log - logger.debug('Starting up PresenceServiceWatcher (2)...') - self.activities = None self.iface.connect_to_signal('ActivityAppeared', self._on_activity_appeared) @@ -529,13 +550,13 @@ class PresenceServiceWatcher(VBox): self._on_private_invitation) def _on_get_activities_success(self, paths): - logger.debug('PS GetActivities() returned %r', paths) + self.log('INFO: PS GetActivities() returned %r', paths) self.activities = {} for path in paths: self.activities[path] = ActivityWatcher(self, path) def _on_get_activities_failure(self, e): - self.log('PS GetActivities() failed with %s', e) + self.log('ERROR: PS GetActivities() failed with %s', e) def add_activity(self, act): path = act.object_path @@ -551,36 +572,36 @@ class PresenceServiceWatcher(VBox): def _on_activity_appeared(self, path): if self.activities is None: return - logger.debug('PS emitted ActivityAppeared("%s")', path) + self.log('INFO: PS emitted ActivityAppeared("%s")', path) self.activities[path] = ActivityWatcher(self, path) def _on_activity_disappeared(self, path): if self.activities is None: return - logger.debug('PS emitted ActivityDisappeared("%s")', path) + self.log('INFO: PS emitted ActivityDisappeared("%s")', path) act = self.activities.get(path) if act is None: - self.log('Trying to remove activity "%s" which is already ' - 'absent', path) + self.log('WARNING: Trying to remove activity "%s" which is ' + 'already absent', path) else: # we don't remove the activity straight away, just cross it out act.disappear() def _on_activity_invitation(self, path): - logger.debug('PS emitted ActivityInvitation("%s")', path) + self.log('INFO: PS emitted ActivityInvitation("%s")', path) def _on_private_invitation(self, bus_name, conn, channel): - logger.debug('PS emitted PrivateInvitation("%s", "%s", "%s")', - bus_name, conn, channel) + self.log('INFO: PS emitted PrivateInvitation("%s", "%s", "%s")', + bus_name, conn, channel) def _on_get_buddies_success(self, paths): - logger.debug('PS GetBuddies() returned %r', paths) + self.log('INFO: PS GetBuddies() returned %r', paths) self.buddies = {} for path in paths: self.buddies[path] = BuddyWatcher(self, path) def _on_get_buddies_failure(self, e): - self.log('PS GetBuddies() failed with %s', e) + self.log('ERROR: PS GetBuddies() failed with %s', e) def add_buddy(self, b): path = b.object_path @@ -597,16 +618,16 @@ class PresenceServiceWatcher(VBox): def _on_buddy_appeared(self, path): if self.buddies is None: return - logger.debug('PS emitted BuddyAppeared("%s")', path) + self.log('INFO: PS emitted BuddyAppeared("%s")', path) self.buddies[path] = BuddyWatcher(self, path) def _on_buddy_disappeared(self, path): if self.buddies is None: return - logger.debug('PS emitted BuddyDisappeared("%s")', path) + self.log('INFO: PS emitted BuddyDisappeared("%s")', path) b = self.buddies.get(path) if b is None: - self.log('Trying to remove buddy "%s" which is already ' + self.log('ERROR: Trying to remove buddy "%s" which is already ' 'absent', path) else: # we don't remove the activity straight away, just cross it out @@ -624,7 +645,7 @@ class PresenceServiceNameWatcher(VBox): self.errors = ListStore(str) errors = TreeView(model=self.errors) - errors.insert_column_with_attributes(0, 'Errors', CellRendererText(), + errors.insert_column_with_attributes(0, 'Log', CellRendererText(), text=0) scroller = ScrolledWindow() scroller.add(errors) @@ -662,7 +683,7 @@ class PresenceServiceNameWatcher(VBox): self.ps_watcher = Label('-') self.paned.pack2(self.ps_watcher) except Exception, e: - self.log('%s', e) + self.log('ERROR: %s', e) class Interface(object): From d35166842a048eab7f4392999958c2f4677f4026 Mon Sep 17 00:00:00 2001 From: Simon McVittie Date: Wed, 25 Jul 2007 16:08:33 -0400 Subject: [PATCH 6/8] Console ps_watcher: avoid misleading user in info messages --- services/console/interface/ps_watcher.py | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/services/console/interface/ps_watcher.py b/services/console/interface/ps_watcher.py index 2216f39f..7592ea82 100644 --- a/services/console/interface/ps_watcher.py +++ b/services/console/interface/ps_watcher.py @@ -107,7 +107,8 @@ class ActivityWatcher(object): return if buddy.startswith('/org/laptop/Sugar/Presence/Buddies/'): buddy = '.../' + buddy[35:] - self.ps_watcher.log('INFO: Activity %s emitted BuddyJoined("%s")', + self.ps_watcher.log('INFO: Activity %s emitted BuddyJoined("%s") ' + 'or mentioned the buddy in GetJoinedBuddies', self.object_path, buddy) self.buddies.append(buddy) self.ps_watcher.activities_list_store.set(self.iter, ACT_COL_BUDDIES, @@ -143,7 +144,8 @@ class ActivityWatcher(object): return if channel.startswith(self.full_conn): channel = '...' + channel[len(self.full_conn):] - self.ps_watcher.log('INFO: Activity %s emitted NewChannel("%s")', + self.ps_watcher.log('INFO: Activity %s emitted NewChannel("%s") ' + 'or mentioned the channel in GetChannels()', self.object_path, channel) self.channels.append(channel) # FIXME: listen for Telepathy Closed signal! @@ -276,9 +278,10 @@ class BuddyWatcher(object): def _on_handle_added(self, service, conn, handle): if self.handles is None: return - self.ps_watcher.log('INFO: Buddy %s emitted HandleAdded("%s", ' - '"%s", %u)', self.object_path, service, conn, - handle) + self.ps_watcher.log('INFO: Buddy %s emitted Telepathy HandleAdded(' + '"%s", "%s", %u) or mentioned the handle in ' + 'GetTelepathyHandles()', + self.object_path, service, conn, handle) if conn.startswith('/org/freedesktop/Telepathy/Connection/'): conn = '.../' + conn[38:] self.handles.append('%u@%s' % (handle, conn)) @@ -317,7 +320,8 @@ class BuddyWatcher(object): return if act.startswith('/org/laptop/Sugar/Presence/Activities/'): act = '.../' + act[38:] - self.ps_watcher.log('INFO: Buddy %s emitted ActivityJoined("%s")', + self.ps_watcher.log('INFO: Buddy %s emitted ActivityJoined("%s") ' + 'or mentioned it in GetJoinedActivities()', self.object_path, act) self.activities.append(act) self.ps_watcher.buddies_list_store.set(self.iter, @@ -351,6 +355,7 @@ class BuddyWatcher(object): def _on_get_props_success(self, props): # ignore key for now + self.log('INFO: .GetProperties() -> %r', props) self.nick = props.get('nick', '?') self.owner = props.get('owner', False) self.color = props.get('color', '?') From ee68ed1fb9f3ab489f876ff43d261bc1909cf39d Mon Sep 17 00:00:00 2001 From: Simon McVittie Date: Wed, 25 Jul 2007 17:58:12 -0400 Subject: [PATCH 7/8] Handle PropertyChanged signal --- services/console/interface/ps_watcher.py | 95 ++++++++++++++++-------- 1 file changed, 64 insertions(+), 31 deletions(-) diff --git a/services/console/interface/ps_watcher.py b/services/console/interface/ps_watcher.py index 7592ea82..6ee7e572 100644 --- a/services/console/interface/ps_watcher.py +++ b/services/console/interface/ps_watcher.py @@ -258,12 +258,17 @@ class BuddyWatcher(object): self.iter = self.ps_watcher.add_buddy(self) + self.iface.connect_to_signal('PropertyChanged', self._on_props_changed, + byte_arrays=True) + self.ps_watcher.log('Calling .GetProperties()', object_path) self.iface.GetProperties(reply_handler=self._on_get_props_success, error_handler=self._on_get_props_failure, byte_arrays=True) self.iface.connect_to_signal('JoinedActivity', self._on_joined) self.iface.connect_to_signal('LeftActivity', self._on_left) + self.ps_watcher.log('Calling .GetJoinedActivities()', + object_path) self.iface.GetJoinedActivities(reply_handler=self._on_get_acts_success, error_handler=self._on_get_acts_failure) @@ -271,6 +276,8 @@ class BuddyWatcher(object): self._on_handle_added) self.iface.connect_to_signal('TelepathyHandleRemoved', self._on_handle_removed) + self.ps_watcher.log('Calling .GetTelepathyHandles()', + object_path) self.iface.GetTelepathyHandles( reply_handler=self._on_get_handles_success, error_handler=self._on_get_handles_failure) @@ -310,7 +317,7 @@ class BuddyWatcher(object): self._on_handle_added(service, conn, handle) def _on_get_handles_failure(self, e): - self.log('ERROR: .GetTelepathyHandles(): %s', + self.ps_watcher.log('ERROR: .GetTelepathyHandles(): %s', self.object_path, e) self.ps_watcher.buddies_list_store.set(self.iter, BUDDY_COL_HANDLES, '!') @@ -348,37 +355,62 @@ class BuddyWatcher(object): self._on_joined(act) def _on_get_acts_failure(self, e): - self.log('ERROR: .GetJoinedActivities(): %s', + self.ps_watcher.log('ERROR: .GetJoinedActivities(): %s', self.object_path, e) self.ps_watcher.buddies_list_store.set(self.iter, BUDDY_COL_ACTIVITIES, '!') + def _on_props_changed(self, props): + try: + logger.debug('PropertyChanged(%s, %s)', self, props) + self.ps_watcher.log('INFO: emitted PropertyChanged(%r)', + self.object_path, props) + self._props_changed(props) + except Exception, e: + self.ps_watcher.log('INTERNAL ERROR: %s', e) + def _on_get_props_success(self, props): - # ignore key for now - self.log('INFO: .GetProperties() -> %r', props) - self.nick = props.get('nick', '?') - self.owner = props.get('owner', False) - self.color = props.get('color', '?') - self.ipv4 = props.get('ip4-address', '?') - self.ipv4 = props.get('ip4-address', '?') - self.cur_act = props.get('current-activity', '?') - key = props.get('key', None) - if key is not None: - self.keyid = sha1(key).hexdigest()[:8] + '...' - else: - self.keyid = '?' - self.ps_watcher.buddies_list_store.set(self.iter, BUDDY_COL_NICK, - self.nick) - self.ps_watcher.buddies_list_store.set(self.iter, BUDDY_COL_OWNER, - self.owner) - self.ps_watcher.buddies_list_store.set(self.iter, BUDDY_COL_COLOR, - self.color) - self.ps_watcher.buddies_list_store.set(self.iter, BUDDY_COL_IP4, - self.ipv4) - self.ps_watcher.buddies_list_store.set(self.iter, BUDDY_COL_CUR_ACT, - self.cur_act) - self.ps_watcher.buddies_list_store.set(self.iter, BUDDY_COL_KEY_ID, - self.keyid) + try: + logger.debug('GetProperties(%s, %s)', self, props) + self.ps_watcher.log('INFO: .GetProperties() -> %r', + self.object_path, props) + self._props_changed(props) + except Exception, e: + self.ps_watcher.log('INTERNAL ERROR: %s', e) + + def _props_changed(self, props): + logger.debug('Begin _props_changed') + if 'nick' in props: + self.nick = props.get('nick', '?') + self.ps_watcher.buddies_list_store.set(self.iter, BUDDY_COL_NICK, + self.nick) + if 'owner' in props: + self.owner = bool(props.get('owner', False)) + self.ps_watcher.buddies_list_store.set(self.iter, BUDDY_COL_OWNER, + self.owner) + if 'color' in props: + self.color = props.get('color', '?') + self.ps_watcher.buddies_list_store.set(self.iter, BUDDY_COL_COLOR, + self.color) + if 'ip4-address' in props: + self.ipv4 = props.get('ip4-address', '?') + self.ps_watcher.buddies_list_store.set(self.iter, BUDDY_COL_IP4, + self.ipv4) + if 'current-activity' in props: + self.cur_act = props.get('current-activity', '?') + self.ps_watcher.buddies_list_store.set(self.iter, BUDDY_COL_CUR_ACT, + self.cur_act) + if 'key' in props: + key = props.get('key', None) + if key: + self.keyid = '%d bytes, sha1 %s' % (len(key), + sha1(key).hexdigest()) + else: + # could be '' (present, empty value) or None (absent). Either way: + self.keyid = '?' + self.ps_watcher.buddies_list_store.set(self.iter, BUDDY_COL_KEY_ID, + self.keyid) + logger.debug('End _props_changed') def _on_get_props_failure(self, e): self.ps_watcher.log('ERROR: .GetProperties(): %s', @@ -507,7 +539,7 @@ class PresenceServiceWatcher(VBox): weight=BUDDY_COL_WEIGHT, strikethrough=BUDDY_COL_STRIKE) c.set_resizable(True) c.set_sort_column_id(BUDDY_COL_PATH) - c = self.buddies_list.insert_column_with_attributes(1, 'Key ID', + c = self.buddies_list.insert_column_with_attributes(1, 'Pubkey', CellRendererText(), text=BUDDY_COL_KEY_ID, weight=BUDDY_COL_WEIGHT, strikethrough=BUDDY_COL_STRIKE) c.set_resizable(True) @@ -646,14 +678,15 @@ class PresenceServiceNameWatcher(VBox): self.bus = bus + logger.debug('Running...') self.label = Label('Looking for Presence Service...') self.errors = ListStore(str) - errors = TreeView(model=self.errors) - errors.insert_column_with_attributes(0, 'Log', CellRendererText(), + errors_tree = TreeView(model=self.errors) + errors_tree.insert_column_with_attributes(0, 'Log', CellRendererText(), text=0) scroller = ScrolledWindow() - scroller.add(errors) + scroller.add(errors_tree) self.paned = VPaned() self.paned.pack1(scroller) From 20d5eaf4bcae21985845cf132411a3f7dc66c0fb Mon Sep 17 00:00:00 2001 From: Tomeu Vizoso Date: Thu, 26 Jul 2007 09:20:38 +0200 Subject: [PATCH 8/8] Add timeout arg to sugar.datastore.Datastore. --- NEWS | 1 + sugar/datastore/datastore.py | 5 +++-- sugar/datastore/dbus_helpers.py | 5 +++-- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/NEWS b/NEWS index 72afe0ff..82b42983 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,4 @@ +* Add timeout arg to sugar.datastore.Datastore. (tomeu) * Turn off logging by default. Logs may be re-enabled on a per-module basis by adding environment variables like SHELL_DEBUG and RECORD_DEBUG to the sugar environment diff --git a/sugar/datastore/datastore.py b/sugar/datastore/datastore.py index ef1dd45a..256c12fa 100644 --- a/sugar/datastore/datastore.py +++ b/sugar/datastore/datastore.py @@ -172,7 +172,7 @@ def create(): metadata['mtime'] = metadata['ctime'] return DSObject(object_id=None, metadata=metadata, file_path=None) -def write(ds_object, update_mtime=True, reply_handler=None, error_handler=None): +def write(ds_object, update_mtime=True, reply_handler=None, error_handler=None, timeout=-1): logging.debug('datastore.write') properties = ds_object.metadata.get_dictionary().copy() @@ -185,7 +185,8 @@ def write(ds_object, update_mtime=True, reply_handler=None, error_handler=None): properties, ds_object.file_path, reply_handler=reply_handler, - error_handler=error_handler) + error_handler=error_handler, + timeout=timeout) else: ds_object.object_id = dbus_helpers.create(properties, ds_object.file_path) diff --git a/sugar/datastore/dbus_helpers.py b/sugar/datastore/dbus_helpers.py index 6680cc12..f0cfa3bf 100644 --- a/sugar/datastore/dbus_helpers.py +++ b/sugar/datastore/dbus_helpers.py @@ -37,12 +37,13 @@ def create(properties, filename): logging.debug('dbus_helpers.create: ' + object_id) return object_id -def update(uid, properties, filename, reply_handler=None, error_handler=None): +def update(uid, properties, filename, reply_handler=None, error_handler=None, timeout=-1): logging.debug('dbus_helpers.update: %s, %s, %s' % (uid, filename, properties)) if reply_handler and error_handler: _data_store.update(uid, dbus.Dictionary(properties), filename, reply_handler=reply_handler, - error_handler=error_handler) + error_handler=error_handler, + timeout=timeout) else: _data_store.update(uid, dbus.Dictionary(properties), filename)