diff options
Diffstat (limited to 'shell/model')
-rw-r--r-- | shell/model/BuddyModel.py | 238 | ||||
-rw-r--r-- | shell/model/Friends.py | 116 | ||||
-rw-r--r-- | shell/model/Invites.py | 52 | ||||
-rw-r--r-- | shell/model/MeshModel.py | 264 | ||||
-rw-r--r-- | shell/model/Owner.py | 174 | ||||
-rw-r--r-- | shell/model/ShellModel.py | 58 |
6 files changed, 451 insertions, 451 deletions
diff --git a/shell/model/BuddyModel.py b/shell/model/BuddyModel.py index 651e911..8e175e7 100644 --- a/shell/model/BuddyModel.py +++ b/shell/model/BuddyModel.py @@ -21,122 +21,122 @@ import gobject _NOT_PRESENT_COLOR = "#888888,#BBBBBB" class BuddyModel(gobject.GObject): - __gsignals__ = { - 'appeared': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, ([])), - 'disappeared': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, ([])), - 'color-changed': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, - ([gobject.TYPE_PYOBJECT])), - 'icon-changed': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, - ([])), - 'current-activity-changed': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, - ([gobject.TYPE_PYOBJECT])) - } - - def __init__(self, name=None, buddy=None): - if name and buddy: - raise RuntimeError("Must specify only _one_ of name or buddy.") - - gobject.GObject.__init__(self) - - self._ba_handler = None - self._pc_handler = None - self._dis_handler = None - self._bic_handler = None - self._cac_handler = None - - self._pservice = PresenceService.get_instance() - - self._buddy = None - - # If given just a name, try to get the buddy from the PS first - if not buddy: - self._name = name - # FIXME: use public key, not name - buddy = self._pservice.get_buddy_by_name(self._name) - - # If successful, copy properties from the PS buddy object - if buddy: - self.__update_buddy(buddy) - else: - # Otherwise, connect to the PS's buddy-appeared signal and - # wait for the buddy to appear - self._ba_handler = self._pservice.connect('buddy-appeared', - self.__buddy_appeared_cb) - self._name = name - # Set color to 'inactive'/'disconnected' - self.__set_color_from_string(_NOT_PRESENT_COLOR) - - def __set_color_from_string(self, color_string): - self._color = IconColor(color_string) - - def get_name(self): - return self._name - - def get_color(self): - return self._color - - def get_buddy(self): - return self._buddy - - def is_present(self): - if self._buddy: - return True - return False - - def get_current_activity(self): - if self._buddy: - return self._buddy.get_current_activity() - return None - - def __update_buddy(self, buddy): - if not buddy: - raise ValueError("Buddy cannot be None.") - - self._buddy = buddy - self._name = self._buddy.get_name() - self.__set_color_from_string(self._buddy.get_color()) - - self._pc_handler = self._buddy.connect('property-changed', self.__buddy_property_changed_cb) - self._dis_handler = self._buddy.connect('disappeared', self.__buddy_disappeared_cb) - self._bic_handler = self._buddy.connect('icon-changed', self.__buddy_icon_changed_cb) - self._cac_handler = self._buddy.connect('current-activity-changed', self.__buddy_current_activity_changed_cb) - - def __buddy_appeared_cb(self, pservice, buddy): - # FIXME: use public key rather than buddy name - if self._buddy or buddy.get_name() != self._name: - return - - if self._ba_handler: - # Once we have the buddy, we no longer need to - # monitor buddy-appeared events - self._pservice.disconnect(self._ba_handler) - self._ba_handler = None - - self.__update_buddy(buddy) - self.emit('appeared') - - def __buddy_property_changed_cb(self, buddy, keys): - if not self._buddy: - return - if 'color' in keys: - self.__set_color_from_string(self._buddy.get_color()) - self.emit('color-changed', self.get_color()) - - def __buddy_disappeared_cb(self, buddy): - if buddy != self._buddy: - return - self._buddy.disconnect(self._pc_handler) - self._buddy.disconnect(self._dis_handler) - self._buddy.disconnect(self._bic_handler) - self._buddy.disconnect(self._cac_handler) - self.__set_color_from_string(_NOT_PRESENT_COLOR) - self.emit('disappeared') - self._buddy = None - - def __buddy_icon_changed_cb(self, buddy): - self.emit('icon-changed') - - def __buddy_current_activity_changed_cb(self, buddy, activity=None): - if not self._buddy: - return - self.emit('current-activity-changed', activity) + __gsignals__ = { + 'appeared': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, ([])), + 'disappeared': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, ([])), + 'color-changed': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, + ([gobject.TYPE_PYOBJECT])), + 'icon-changed': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, + ([])), + 'current-activity-changed': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, + ([gobject.TYPE_PYOBJECT])) + } + + def __init__(self, name=None, buddy=None): + if name and buddy: + raise RuntimeError("Must specify only _one_ of name or buddy.") + + gobject.GObject.__init__(self) + + self._ba_handler = None + self._pc_handler = None + self._dis_handler = None + self._bic_handler = None + self._cac_handler = None + + self._pservice = PresenceService.get_instance() + + self._buddy = None + + # If given just a name, try to get the buddy from the PS first + if not buddy: + self._name = name + # FIXME: use public key, not name + buddy = self._pservice.get_buddy_by_name(self._name) + + # If successful, copy properties from the PS buddy object + if buddy: + self.__update_buddy(buddy) + else: + # Otherwise, connect to the PS's buddy-appeared signal and + # wait for the buddy to appear + self._ba_handler = self._pservice.connect('buddy-appeared', + self.__buddy_appeared_cb) + self._name = name + # Set color to 'inactive'/'disconnected' + self.__set_color_from_string(_NOT_PRESENT_COLOR) + + def __set_color_from_string(self, color_string): + self._color = IconColor(color_string) + + def get_name(self): + return self._name + + def get_color(self): + return self._color + + def get_buddy(self): + return self._buddy + + def is_present(self): + if self._buddy: + return True + return False + + def get_current_activity(self): + if self._buddy: + return self._buddy.get_current_activity() + return None + + def __update_buddy(self, buddy): + if not buddy: + raise ValueError("Buddy cannot be None.") + + self._buddy = buddy + self._name = self._buddy.get_name() + self.__set_color_from_string(self._buddy.get_color()) + + self._pc_handler = self._buddy.connect('property-changed', self.__buddy_property_changed_cb) + self._dis_handler = self._buddy.connect('disappeared', self.__buddy_disappeared_cb) + self._bic_handler = self._buddy.connect('icon-changed', self.__buddy_icon_changed_cb) + self._cac_handler = self._buddy.connect('current-activity-changed', self.__buddy_current_activity_changed_cb) + + def __buddy_appeared_cb(self, pservice, buddy): + # FIXME: use public key rather than buddy name + if self._buddy or buddy.get_name() != self._name: + return + + if self._ba_handler: + # Once we have the buddy, we no longer need to + # monitor buddy-appeared events + self._pservice.disconnect(self._ba_handler) + self._ba_handler = None + + self.__update_buddy(buddy) + self.emit('appeared') + + def __buddy_property_changed_cb(self, buddy, keys): + if not self._buddy: + return + if 'color' in keys: + self.__set_color_from_string(self._buddy.get_color()) + self.emit('color-changed', self.get_color()) + + def __buddy_disappeared_cb(self, buddy): + if buddy != self._buddy: + return + self._buddy.disconnect(self._pc_handler) + self._buddy.disconnect(self._dis_handler) + self._buddy.disconnect(self._bic_handler) + self._buddy.disconnect(self._cac_handler) + self.__set_color_from_string(_NOT_PRESENT_COLOR) + self.emit('disappeared') + self._buddy = None + + def __buddy_icon_changed_cb(self, buddy): + self.emit('icon-changed') + + def __buddy_current_activity_changed_cb(self, buddy, activity=None): + if not self._buddy: + return + self.emit('current-activity-changed', activity) diff --git a/shell/model/Friends.py b/shell/model/Friends.py index ab1935b..36c443f 100644 --- a/shell/model/Friends.py +++ b/shell/model/Friends.py @@ -24,61 +24,61 @@ from sugar import env import logging class Friends(gobject.GObject): - __gsignals__ = { - 'friend-added': (gobject.SIGNAL_RUN_FIRST, - gobject.TYPE_NONE, ([object])), - 'friend-removed': (gobject.SIGNAL_RUN_FIRST, - gobject.TYPE_NONE, ([str])), - } - - def __init__(self): - gobject.GObject.__init__(self) - - self._friends = {} - self._path = os.path.join(env.get_profile_path(), 'friends') - - self.load() - - def has_buddy(self, buddy): - return self._friends.has_key(buddy.get_name()) - - def add_friend(self, buddy_info): - self._friends[buddy_info.get_name()] = buddy_info - self.emit('friend-added', buddy_info) - - def make_friend(self, buddy): - if not self.has_buddy(buddy): - self.add_friend(BuddyModel(buddy=buddy)) - self.save() - - def remove(self, buddy_info): - del self._friends[buddy_info.get_name()] - self.save() - self.emit('friend-removed', buddy_info.get_name()) - - def __iter__(self): - return self._friends.values().__iter__() - - def load(self): - cp = ConfigParser() - - try: - success = cp.read([self._path]) - if success: - for name in cp.sections(): - buddy = BuddyModel(name) - self.add_friend(buddy) - except Exception, exc: - logging.error("Error parsing friends file: %s" % exc) - - def save(self): - cp = ConfigParser() - - for friend in self: - section = friend.get_name() - cp.add_section(section) - cp.set(section, 'color', friend.get_color().to_string()) - - fileobject = open(self._path, 'w') - cp.write(fileobject) - fileobject.close() + __gsignals__ = { + 'friend-added': (gobject.SIGNAL_RUN_FIRST, + gobject.TYPE_NONE, ([object])), + 'friend-removed': (gobject.SIGNAL_RUN_FIRST, + gobject.TYPE_NONE, ([str])), + } + + def __init__(self): + gobject.GObject.__init__(self) + + self._friends = {} + self._path = os.path.join(env.get_profile_path(), 'friends') + + self.load() + + def has_buddy(self, buddy): + return self._friends.has_key(buddy.get_name()) + + def add_friend(self, buddy_info): + self._friends[buddy_info.get_name()] = buddy_info + self.emit('friend-added', buddy_info) + + def make_friend(self, buddy): + if not self.has_buddy(buddy): + self.add_friend(BuddyModel(buddy=buddy)) + self.save() + + def remove(self, buddy_info): + del self._friends[buddy_info.get_name()] + self.save() + self.emit('friend-removed', buddy_info.get_name()) + + def __iter__(self): + return self._friends.values().__iter__() + + def load(self): + cp = ConfigParser() + + try: + success = cp.read([self._path]) + if success: + for name in cp.sections(): + buddy = BuddyModel(name) + self.add_friend(buddy) + except Exception, exc: + logging.error("Error parsing friends file: %s" % exc) + + def save(self): + cp = ConfigParser() + + for friend in self: + section = friend.get_name() + cp.add_section(section) + cp.set(section, 'color', friend.get_color().to_string()) + + fileobject = open(self._path, 'w') + cp.write(fileobject) + fileobject.close() diff --git a/shell/model/Invites.py b/shell/model/Invites.py index bc947a9..7bc0af0 100644 --- a/shell/model/Invites.py +++ b/shell/model/Invites.py @@ -17,38 +17,38 @@ import gobject class Invite: - def __init__(self, issuer, bundle_id, activity_id): - self._issuer = issuer - self._activity_id = activity_id - self._bundle_id = bundle_id + def __init__(self, issuer, bundle_id, activity_id): + self._issuer = issuer + self._activity_id = activity_id + self._bundle_id = bundle_id - def get_activity_id(self): - return self._activity_id + def get_activity_id(self): + return self._activity_id - def get_bundle_id(self): - return self._bundle_id + def get_bundle_id(self): + return self._bundle_id class Invites(gobject.GObject): - __gsignals__ = { - 'invite-added': (gobject.SIGNAL_RUN_FIRST, - gobject.TYPE_NONE, ([object])), - 'invite-removed': (gobject.SIGNAL_RUN_FIRST, - gobject.TYPE_NONE, ([object])), - } + __gsignals__ = { + 'invite-added': (gobject.SIGNAL_RUN_FIRST, + gobject.TYPE_NONE, ([object])), + 'invite-removed': (gobject.SIGNAL_RUN_FIRST, + gobject.TYPE_NONE, ([object])), + } - def __init__(self): - gobject.GObject.__init__(self) + def __init__(self): + gobject.GObject.__init__(self) - self._list = [] + self._list = [] - def add_invite(self, issuer, bundle_id, activity_id): - invite = Invite(issuer, bundle_id, activity_id) - self._list.append(invite) - self.emit('invite-added', invite) + def add_invite(self, issuer, bundle_id, activity_id): + invite = Invite(issuer, bundle_id, activity_id) + self._list.append(invite) + self.emit('invite-added', invite) - def remove_invite(self, invite): - self._list.remove(invite) - self.emit('invite-removed', invite) + def remove_invite(self, invite): + self._list.remove(invite) + self.emit('invite-removed', invite) - def __iter__(self): - return self._list.__iter__() + def __iter__(self): + return self._list.__iter__() diff --git a/shell/model/MeshModel.py b/shell/model/MeshModel.py index 0ecf2b8..5ab36e9 100644 --- a/shell/model/MeshModel.py +++ b/shell/model/MeshModel.py @@ -21,137 +21,137 @@ from sugar.presence import PresenceService from model.BuddyModel import BuddyModel class ActivityModel: - def __init__(self, activity, bundle, service): - self._service = service - self._activity = activity - - def get_id(self): - return self._activity.get_id() - - def get_icon_name(self): - return bundle.get_icon() - - def get_color(self): - return IconColor(self._activity.get_color()) - - def get_service(self): - return self._service + def __init__(self, activity, bundle, service): + self._service = service + self._activity = activity + + def get_id(self): + return self._activity.get_id() + + def get_icon_name(self): + return bundle.get_icon() + + def get_color(self): + return IconColor(self._activity.get_color()) + + def get_service(self): + return self._service class MeshModel(gobject.GObject): - __gsignals__ = { - 'activity-added': (gobject.SIGNAL_RUN_FIRST, - gobject.TYPE_NONE, ([gobject.TYPE_PYOBJECT])), - 'activity-removed': (gobject.SIGNAL_RUN_FIRST, - gobject.TYPE_NONE, ([gobject.TYPE_PYOBJECT])), - 'buddy-added': (gobject.SIGNAL_RUN_FIRST, - gobject.TYPE_NONE, ([gobject.TYPE_PYOBJECT])), - 'buddy-moved': (gobject.SIGNAL_RUN_FIRST, - gobject.TYPE_NONE, ([gobject.TYPE_PYOBJECT, - gobject.TYPE_PYOBJECT])), - 'buddy-removed': (gobject.SIGNAL_RUN_FIRST, - gobject.TYPE_NONE, ([gobject.TYPE_PYOBJECT])) - } - - def __init__(self, bundle_registry): - gobject.GObject.__init__(self) - - self._activities = {} - self._buddies = {} - self._bundle_registry = bundle_registry - - self._pservice = PresenceService.get_instance() - self._pservice.connect("service-appeared", - self._service_appeared_cb) - self._pservice.connect('activity-disappeared', - self._activity_disappeared_cb) - self._pservice.connect("buddy-appeared", - self._buddy_appeared_cb) - self._pservice.connect("buddy-disappeared", - self._buddy_disappeared_cb) - - # Add any buddies the PS knows about already - for buddy in self._pservice.get_buddies(): - self._buddy_appeared_cb(self._pservice, buddy) - - for service in self._pservice.get_services(): - self._check_service(service) - - def get_activities(self): - return self._activities.values() - - def get_buddies(self): - return self._buddies.values() - - def _buddy_activity_changed_cb(self, buddy, cur_activity): - if not self._buddies.has_key(buddy.get_name()): - return - buddy_model = self._buddies[buddy.get_name()] - if cur_activity == None: - self.emit('buddy-moved', buddy_model, None) - else: - self._notify_buddy_change(buddy_model, cur_activity) - - def _notify_buddy_change(self, buddy_model, cur_activity): - if self._activities.has_key(cur_activity.get_id()): - activity_model = self._activities[cur_activity.get_id()] - self.emit('buddy-moved', buddy_model, activity_model) - - def _buddy_appeared_cb(self, pservice, buddy): - model = BuddyModel(buddy=buddy) - if self._buddies.has_key(model.get_name()): - del model - return - - model.connect('current-activity-changed', - self._buddy_activity_changed_cb) - self._buddies[model.get_name()] = model - self.emit('buddy-added', model) - - cur_activity = buddy.get_current_activity() - if cur_activity: - self._notify_buddy_change(model, cur_activity) - - def _buddy_disappeared_cb(self, pservice, buddy): - if not self._buddies.has_key(buddy.get_name()): - return - self.emit('buddy-removed', buddy) - del self._buddies[buddy.get_name()] - - def _service_appeared_cb(self, pservice, service): - self._check_service(service) - - def _check_service(self, service): - if self._bundle_registry.get_bundle(service.get_type()) != None: - activity_id = service.get_activity_id() - if not self.has_activity(activity_id): - activity = self._pservice.get_activity(activity_id) - if activity != None: - self.add_activity(activity, service) - - def has_activity(self, activity_id): - return self._activities.has_key(activity_id) - - def get_activity(self, activity_id): - if self.has_activity(activity_id): - return self._activities[activity_id] - else: - return None - - def add_activity(self, activity, service): - bundle = self._bundle_registry.get_bundle(service.get_type()) - model = ActivityModel(activity, bundle, service) - self._activities[model.get_id()] = model - self.emit('activity-added', model) - - for buddy in self._pservice.get_buddies(): - cur_activity = buddy.get_current_activity() - name = buddy.get_name() - if cur_activity == activity and self._buddies.has_key(name): - buddy_model = self._buddies[name] - self.emit('buddy-moved', buddy_model, model) - - def _activity_disappeared_cb(self, pservice, activity): - if self._activities.has_key(activity.get_id()): - activity_model = self._activities[activity.get_id()] - self.emit('activity-removed', activity_model) - del self._activities[activity.get_id()] + __gsignals__ = { + 'activity-added': (gobject.SIGNAL_RUN_FIRST, + gobject.TYPE_NONE, ([gobject.TYPE_PYOBJECT])), + 'activity-removed': (gobject.SIGNAL_RUN_FIRST, + gobject.TYPE_NONE, ([gobject.TYPE_PYOBJECT])), + 'buddy-added': (gobject.SIGNAL_RUN_FIRST, + gobject.TYPE_NONE, ([gobject.TYPE_PYOBJECT])), + 'buddy-moved': (gobject.SIGNAL_RUN_FIRST, + gobject.TYPE_NONE, ([gobject.TYPE_PYOBJECT, + gobject.TYPE_PYOBJECT])), + 'buddy-removed': (gobject.SIGNAL_RUN_FIRST, + gobject.TYPE_NONE, ([gobject.TYPE_PYOBJECT])) + } + + def __init__(self, bundle_registry): + gobject.GObject.__init__(self) + + self._activities = {} + self._buddies = {} + self._bundle_registry = bundle_registry + + self._pservice = PresenceService.get_instance() + self._pservice.connect("service-appeared", + self._service_appeared_cb) + self._pservice.connect('activity-disappeared', + self._activity_disappeared_cb) + self._pservice.connect("buddy-appeared", + self._buddy_appeared_cb) + self._pservice.connect("buddy-disappeared", + self._buddy_disappeared_cb) + + # Add any buddies the PS knows about already + for buddy in self._pservice.get_buddies(): + self._buddy_appeared_cb(self._pservice, buddy) + + for service in self._pservice.get_services(): + self._check_service(service) + + def get_activities(self): + return self._activities.values() + + def get_buddies(self): + return self._buddies.values() + + def _buddy_activity_changed_cb(self, buddy, cur_activity): + if not self._buddies.has_key(buddy.get_name()): + return + buddy_model = self._buddies[buddy.get_name()] + if cur_activity == None: + self.emit('buddy-moved', buddy_model, None) + else: + self._notify_buddy_change(buddy_model, cur_activity) + + def _notify_buddy_change(self, buddy_model, cur_activity): + if self._activities.has_key(cur_activity.get_id()): + activity_model = self._activities[cur_activity.get_id()] + self.emit('buddy-moved', buddy_model, activity_model) + + def _buddy_appeared_cb(self, pservice, buddy): + model = BuddyModel(buddy=buddy) + if self._buddies.has_key(model.get_name()): + del model + return + + model.connect('current-activity-changed', + self._buddy_activity_changed_cb) + self._buddies[model.get_name()] = model + self.emit('buddy-added', model) + + cur_activity = buddy.get_current_activity() + if cur_activity: + self._notify_buddy_change(model, cur_activity) + + def _buddy_disappeared_cb(self, pservice, buddy): + if not self._buddies.has_key(buddy.get_name()): + return + self.emit('buddy-removed', buddy) + del self._buddies[buddy.get_name()] + + def _service_appeared_cb(self, pservice, service): + self._check_service(service) + + def _check_service(self, service): + if self._bundle_registry.get_bundle(service.get_type()) != None: + activity_id = service.get_activity_id() + if not self.has_activity(activity_id): + activity = self._pservice.get_activity(activity_id) + if activity != None: + self.add_activity(activity, service) + + def has_activity(self, activity_id): + return self._activities.has_key(activity_id) + + def get_activity(self, activity_id): + if self.has_activity(activity_id): + return self._activities[activity_id] + else: + return None + + def add_activity(self, activity, service): + bundle = self._bundle_registry.get_bundle(service.get_type()) + model = ActivityModel(activity, bundle, service) + self._activities[model.get_id()] = model + self.emit('activity-added', model) + + for buddy in self._pservice.get_buddies(): + cur_activity = buddy.get_current_activity() + name = buddy.get_name() + if cur_activity == activity and self._buddies.has_key(name): + buddy_model = self._buddies[name] + self.emit('buddy-moved', buddy_model, model) + + def _activity_disappeared_cb(self, pservice, activity): + if self._activities.has_key(activity.get_id()): + activity_model = self._activities[activity.get_id()] + self.emit('activity-removed', activity_model) + del self._activities[activity.get_id()] diff --git a/shell/model/Owner.py b/shell/model/Owner.py index 7d83ab2..49386a9 100644 --- a/shell/model/Owner.py +++ b/shell/model/Owner.py @@ -31,90 +31,90 @@ from model.Invites import Invites PRESENCE_SERVICE_TYPE = "_presence_olpc._tcp" class ShellOwner(object): - """Class representing the owner of this machine/instance. This class - runs in the shell and serves up the buddy icon and other stuff. It's the - server portion of the Owner, paired with the client portion in Buddy.py.""" - def __init__(self): - self._nick = profile.get_nick_name() - user_dir = env.get_profile_path() - - self._icon = None - self._icon_hash = "" - for fname in os.listdir(user_dir): - if not fname.startswith("buddy-icon."): - continue - fd = open(os.path.join(user_dir, fname), "r") - self._icon = fd.read() - if self._icon: - # Get the icon's hash - import md5, binascii - digest = md5.new(self._icon).digest() - self._icon_hash = util.printable_hash(digest) - fd.close() - break - - self._pservice = PresenceService.get_instance() - - self._invites = Invites() - - self._last_activity_update = time.time() - self._pending_activity_update_timer = None - self._pending_activity_update = None - - def get_invites(self): - return self._invites - - def get_name(self): - return self._nick - - def announce(self): - # Create and announce our presence - color = profile.get_color() - props = {'color': color.to_string(), 'icon-hash': self._icon_hash} - self._service = self._pservice.register_service(self._nick, - PRESENCE_SERVICE_TYPE, properties=props) - logging.debug("Owner '%s' using port %d" % (self._nick, self._service.get_port())) - self._icon_stream = Stream.Stream.new_from_service(self._service) - self._icon_stream.register_reader_handler(self._handle_buddy_icon_request, "get_buddy_icon") - self._icon_stream.register_reader_handler(self._handle_invite, "invite") - - def _handle_buddy_icon_request(self): - """XMLRPC method, return the owner's icon encoded with base64.""" - if self._icon: - return base64.b64encode(self._icon) - return "" - - def _handle_invite(self, issuer, bundle_id, activity_id): - """XMLRPC method, called when the owner is invited to an activity.""" - self._invites.add_invite(issuer, bundle_id, activity_id) - return '' - - def __update_advertised_current_activity_cb(self): - self._last_activity_update = time.time() - self._pending_activity_update_timer = None - if self._pending_activity_update: - logging.debug("*** Updating current activity to %s" % self._pending_activity_update) - self._service.set_published_value('curact', dbus.String(self._pending_activity_update)) - return False - - def set_current_activity(self, activity_id): - """Update our presence service with the latest activity, but no - more frequently than every 30 seconds""" - self._pending_activity_update = activity_id - # If there's no pending update, we must not have updated it in the - # last 30 seconds (except for the initial update, hence we also check - # for the last update) - if not self._pending_activity_update_timer or time.time() - self._last_activity_update > 30: - self.__update_advertised_current_activity_cb() - return - - # If we have a pending update already, we have nothing left to do - if self._pending_activity_update_timer: - return - - # Otherwise, we start a timer to update the activity at the next - # interval, which should be 30 seconds from the last update, or if that - # is in the past already, then now - next = 30 - max(30, time.time() - self._last_activity_update) - self._pending_activity_update_timer = gobject.timeout_add(next * 1000, - self.__update_advertised_current_activity_cb) + """Class representing the owner of this machine/instance. This class + runs in the shell and serves up the buddy icon and other stuff. It's the + server portion of the Owner, paired with the client portion in Buddy.py.""" + def __init__(self): + self._nick = profile.get_nick_name() + user_dir = env.get_profile_path() + + self._icon = None + self._icon_hash = "" + for fname in os.listdir(user_dir): + if not fname.startswith("buddy-icon."): + continue + fd = open(os.path.join(user_dir, fname), "r") + self._icon = fd.read() + if self._icon: + # Get the icon's hash + import md5, binascii + digest = md5.new(self._icon).digest() + self._icon_hash = util.printable_hash(digest) + fd.close() + break + + self._pservice = PresenceService.get_instance() + + self._invites = Invites() + + self._last_activity_update = time.time() + self._pending_activity_update_timer = None + self._pending_activity_update = None + + def get_invites(self): + return self._invites + + def get_name(self): + return self._nick + + def announce(self): + # Create and announce our presence + color = profile.get_color() + props = {'color': color.to_string(), 'icon-hash': self._icon_hash} + self._service = self._pservice.register_service(self._nick, + PRESENCE_SERVICE_TYPE, properties=props) + logging.debug("Owner '%s' using port %d" % (self._nick, self._service.get_port())) + self._icon_stream = Stream.Stream.new_from_service(self._service) + self._icon_stream.register_reader_handler(self._handle_buddy_icon_request, "get_buddy_icon") + self._icon_stream.register_reader_handler(self._handle_invite, "invite") + + def _handle_buddy_icon_request(self): + """XMLRPC method, return the owner's icon encoded with base64.""" + if self._icon: + return base64.b64encode(self._icon) + return "" + + def _handle_invite(self, issuer, bundle_id, activity_id): + """XMLRPC method, called when the owner is invited to an activity.""" + self._invites.add_invite(issuer, bundle_id, activity_id) + return '' + + def __update_advertised_current_activity_cb(self): + self._last_activity_update = time.time() + self._pending_activity_update_timer = None + if self._pending_activity_update: + logging.debug("*** Updating current activity to %s" % self._pending_activity_update) + self._service.set_published_value('curact', dbus.String(self._pending_activity_update)) + return False + + def set_current_activity(self, activity_id): + """Update our presence service with the latest activity, but no + more frequently than every 30 seconds""" + self._pending_activity_update = activity_id + # If there's no pending update, we must not have updated it in the + # last 30 seconds (except for the initial update, hence we also check + # for the last update) + if not self._pending_activity_update_timer or time.time() - self._last_activity_update > 30: + self.__update_advertised_current_activity_cb() + return + + # If we have a pending update already, we have nothing left to do + if self._pending_activity_update_timer: + return + + # Otherwise, we start a timer to update the activity at the next + # interval, which should be 30 seconds from the last update, or if that + # is in the past already, then now + next = 30 - max(30, time.time() - self._last_activity_update) + self._pending_activity_update_timer = gobject.timeout_add(next * 1000, + self.__update_advertised_current_activity_cb) diff --git a/shell/model/ShellModel.py b/shell/model/ShellModel.py index d2d6e9d..95ed344 100644 --- a/shell/model/ShellModel.py +++ b/shell/model/ShellModel.py @@ -24,45 +24,45 @@ from model.Owner import ShellOwner from sugar import env class ShellModel: - def __init__(self): - self._current_activity = None + def __init__(self): + self._current_activity = None - self._bundle_registry = BundleRegistry() + self._bundle_registry = BundleRegistry() - PresenceService.start() - self._pservice = PresenceService.get_instance() + PresenceService.start() + self._pservice = PresenceService.get_instance() - self._owner = ShellOwner() - self._owner.announce() + self._owner = ShellOwner() + self._owner.announce() - self._friends = Friends() - self._mesh = MeshModel(self._bundle_registry) + self._friends = Friends() + self._mesh = MeshModel(self._bundle_registry) - path = os.path.expanduser('~/Activities') - self._bundle_registry.add_search_path(path) + path = os.path.expanduser('~/Activities') + self._bundle_registry.add_search_path(path) - for path in env.get_data_dirs(): - bundles_path = os.path.join(path, 'activities') - self._bundle_registry.add_search_path(bundles_path) + for path in env.get_data_dirs(): + bundles_path = os.path.join(path, 'activities') + self._bundle_registry.add_search_path(bundles_path) - def get_bundle_registry(self): - return self._bundle_registry + def get_bundle_registry(self): + return self._bundle_registry - def get_mesh(self): - return self._mesh + def get_mesh(self): + return self._mesh - def get_friends(self): - return self._friends + def get_friends(self): + return self._friends - def get_invites(self): - return self._owner.get_invites() + def get_invites(self): + return self._owner.get_invites() - def get_owner(self): - return self._owner + def get_owner(self): + return self._owner - def set_current_activity(self, activity_id): - self._current_activity = activity_id - self._owner.set_current_activity(activity_id) + def set_current_activity(self, activity_id): + self._current_activity = activity_id + self._owner.set_current_activity(activity_id) - def get_current_activity(self): - return self._current_activity + def get_current_activity(self): + return self._current_activity |