diff options
author | Dan Williams <dcbw@redhat.com> | 2006-06-19 13:49:57 (GMT) |
---|---|---|
committer | Dan Williams <dcbw@redhat.com> | 2006-06-19 13:49:57 (GMT) |
commit | c65ef6f9cd4afb3560f2551aa9d1ac316711c69b (patch) | |
tree | ab184f26b4238e0fa6732fe67f2cd270a881f6f1 /sugar | |
parent | d08ea50d15834cef7649e57fbe6278c60ff7bdc8 (diff) |
Make the presence service resolve all shared activity services by default; it's up to the activities to ignore services that aren't theirs. Also add 'joined-activity' and 'left-activity' signals on Buddy objects, mainly for the PresenceWindow's 'Who's here' bits
Diffstat (limited to 'sugar')
-rw-r--r-- | sugar/browser/BrowserShell.py | 4 | ||||
-rw-r--r-- | sugar/chat/GroupChat.py | 6 | ||||
-rw-r--r-- | sugar/presence/Buddy.py | 48 | ||||
-rw-r--r-- | sugar/presence/PresenceService.py | 67 | ||||
-rw-r--r-- | sugar/shell/StartPage.py | 4 |
5 files changed, 67 insertions, 62 deletions
diff --git a/sugar/browser/BrowserShell.py b/sugar/browser/BrowserShell.py index c59de2f..a968772 100644 --- a/sugar/browser/BrowserShell.py +++ b/sugar/browser/BrowserShell.py @@ -37,8 +37,8 @@ class BrowserShell(dbus.service.Object): @dbus.service.method('com.redhat.Sugar.BrowserShell') def open_browser(self, uri, serialized_service=None): service = None -# if serialized_service is not None: -# service = Service.deserialize(serialized_service) + if serialized_service is not None: + service = Service.deserialize(serialized_service) browser = BrowserActivity(uri) self.__browsers.append(browser) gobject.idle_add(self._start_browser_cb, browser, service) diff --git a/sugar/chat/GroupChat.py b/sugar/chat/GroupChat.py index 5ab0645..97b32dc 100644 --- a/sugar/chat/GroupChat.py +++ b/sugar/chat/GroupChat.py @@ -19,12 +19,8 @@ class GroupChat(Chat): self._pservice.connect('service-appeared', self._service_appeared_cb) self._pservice.track_service_type(GroupChat.SERVICE_TYPE) - # FIXME remove, when we join the activity this will happen automatically - # (Once we have a global presence service) - self._pservice.track_activity(activity.get_id()) - def _service_appeared_cb(self, pservice, buddy, service): - if service.get_type() == GroupChat.SERVICE_TYPE: + if service.get_full_type() == GroupChat.SERVICE_TYPE: logging.debug('Group chat service appeared, setup the stream.') self._setup_stream(service) diff --git a/sugar/presence/Buddy.py b/sugar/presence/Buddy.py index b55230b..5fd3c77 100644 --- a/sugar/presence/Buddy.py +++ b/sugar/presence/Buddy.py @@ -20,7 +20,11 @@ class Buddy(gobject.GObject): 'service-added': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, ([gobject.TYPE_PYOBJECT])), 'service-removed': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, - ([gobject.TYPE_PYOBJECT])) + ([gobject.TYPE_PYOBJECT])), + 'joined-activity': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, + ([gobject.TYPE_STRING])), + 'left-activity': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, + ([gobject.TYPE_STRING])) } def __init__(self, service): @@ -69,12 +73,27 @@ class Buddy(gobject.GObject): if service.get_publisher_address() != self._address: logging.error('Service publisher and buddy address doesnt match: %s %s' % (service.get_publisher_address(), self._address)) return False - if service.get_type() in self._services.keys(): + full_type = service.get_full_type() + if full_type in self._services.keys(): return False - self._services[service.get_full_type()] = service + self._services[full_type] = service if self._valid: self.emit("service-added", service) - if service.get_full_type() == PRESENCE_SERVICE_TYPE: + + # If this is the first service we've seen that's owned by + # a particular activity, send out the 'joined-activity' signal + (uid, short_stype) = Service._decompose_service_type(full_type) + if uid is not None: + found = False + for serv in self._services.values(): + if serv.get_activity_uid() == uid and serv.get_full_type() != full_type: + found = True + break + if not found: + print "Buddy (%s) joined activity %s." % (self._nick_name, service.get_activity_uid()) + self.emit("joined-activity", service) + + if full_type == PRESENCE_SERVICE_TYPE: # A buddy isn't valid until its official presence # service has been found and resolved self._valid = True @@ -89,11 +108,26 @@ class Buddy(gobject.GObject): return if service.get_name() != self._nick_name: return - if self._services.has_key(service.get_full_type()): + full_type = service.get_full_type() + if self._services.has_key(full_type): if self._valid: self.emit("service-removed", service) - del self._services[service.get_full_type()] - if service.get_full_type() == PRESENCE_SERVICE_TYPE: + del self._services[full_type] + + # If this is the lase service owned by a particular activity, + # and it's just been removed, send out the 'left-actvity' signal + (uid, short_stype) = Service._decompose_service_type(full_type) + if uid is not None: + found = False + for serv in self._services.values(): + if serv.get_activity_uid() == uid: + found = True + break + if not found: + print "Buddy (%s) left activity %s." % (self._nick_name, service.get_activity_uid()) + self.emit("left-activity", service) + + if full_type == PRESENCE_SERVICE_TYPE: self._valid = False def get_service_of_type(self, stype=None, activity=None): diff --git a/sugar/presence/PresenceService.py b/sugar/presence/PresenceService.py index 29bc3ec..bf5f77f 100644 --- a/sugar/presence/PresenceService.py +++ b/sugar/presence/PresenceService.py @@ -93,7 +93,7 @@ class PresenceService(gobject.GObject): return PresenceService.__instance get_instance = staticmethod(get_instance) - def __init__(self, debug=False): + def __init__(self, debug=True): gobject.GObject.__init__(self) self._debug = debug @@ -113,7 +113,6 @@ class PresenceService(gobject.GObject): # All the mdns service types we care about self._allowed_service_types = [] # Short service type - self._allowed_activities = [] # activity UID # Keep track of stuff we're already browsing with ZC self._service_type_browsers = {} @@ -163,7 +162,7 @@ class PresenceService(gobject.GObject): def _resolve_service_error_handler(self, err): logging.error("error resolving service: %s" % err) - def _find_service_adv(self, interface=None, protocol=None, name=None, stype=None, domain=None): + def _find_service_adv(self, interface=None, protocol=None, name=None, stype=None, domain=None, is_short_stype=False): """Search a list of service advertisements for ones matching certain criteria.""" adv_list = [] for adv in self._service_advs: @@ -173,8 +172,13 @@ class PresenceService(gobject.GObject): continue if name and adv.name() != name: continue - if stype and adv.stype() != stype: - continue + if is_short_stype: + (uid, dec_stype) = Service._decompose_service_type(adv.stype()) + if uid is None or stype != dec_stype: + continue + else: + if stype and adv.stype() != stype: + continue if domain and adv.domain() != domain: continue adv_list.append(adv) @@ -314,9 +318,8 @@ class PresenceService(gobject.GObject): # If we care about the service right now, resolve it resolve = False - if uid in self._allowed_activities: - if short_stype in self._allowed_service_types: - resolve = True + if uid is not None or short_stype in self._allowed_service_types: + resolve = True if self._is_special_service_type(short_stype): resolve = True if resolve and not adv in self._resolve_queue: @@ -416,25 +419,6 @@ class PresenceService(gobject.GObject): def _new_domain_cb_glue(self, interface, protocol, domain, flags=0): gobject.idle_add(self._new_domain_cb, interface, protocol, domain, flags) - def track_activity(self, activity_uid): - """INTERNAL ONLY; register an activity's UID to recognize service - events for that specific activity.""" - if not activity_uid or not util.validate_activity_uid(activity_uid): - raise ValueError("activity uid must be a valid activity uid string.") - if activity_uid in self._allowed_activities: - return - self._allowed_activities.append(activity_uid) - self._check_and_resolve_service_advs() - - def untrack_activity(self, activity_uid): - """INTERNAL ONLY; unregister an activity's UID to stop service - events for that specific activity.""" - if not activity_uid or not util.validate_activity_uid(activity_uid): - raise ValueError("activity uid must be a valid activity uid string.") - if activity_uid not in self._allowed_activities: - return - self._allowed_activities.remove(activity_uid) - def track_service_type(self, short_stype): """Requests that the Presence service look for and recognize a certain mDNS service types.""" @@ -456,22 +440,17 @@ class PresenceService(gobject.GObject): self._allowed_service_types.append(dec_stype) self._check_and_resolve_service_advs(dec_stype) - def _check_and_resolve_service_advs(self, specific_stype=None): + def _check_and_resolve_service_advs(self, short_stype): + """We should only get called with short service types (ie, not + service types that can be decomposed into a UID and a type).""" # Find unresolved services that match the service type # we're now interested in, and resolve them resolv_list = [] - # Find all services first by their activity - search_types = self._allowed_service_types - if specific_stype: - search_types = [specific_stype] - for uid in self._allowed_activities: - for short_stype in search_types: - full_stype = Service.compose_service_type(short_stype, uid) - adv_list = self._find_service_adv(stype=full_stype) - resolv_list = resolv_list + adv_list - # Then, find services by just the plain service type - if specific_stype is not None: - resolv_list = resolv_list + self._find_service_adv(stype=specific_stype) + + # Find services of this type belonging to specific activities + resolv_list = self._find_service_adv(stype=short_stype, is_short_stype=True) + # And also just plain ones of this type + resolv_list = resolv_list + self._find_service_adv(stype=short_stype) # Request resolution for them if they aren't in-process already for adv in resolv_list: @@ -505,6 +484,9 @@ class PresenceService(gobject.GObject): def share_activity(self, activity, stype, properties={}, address=None, port=None): """Convenience function to share an activity with other buddies.""" + if not self._started: + raise RuntimeError("presence service must be started first.") + uid = activity.get_id() logging.debug('Sharing activity uid %s, stype %s' % (uid, stype)) owner_nick = self._owner.get_nick_name() @@ -536,8 +518,6 @@ class PresenceService(gobject.GObject): rs_name = service.get_name() rs_stype = service.get_full_type() rs_port = service.get_port() - if type(rs_port) != type(1) and (rs_port <= 1024 or rs_port > 65536): - raise ValueError("invalid service port.") rs_props = service.get_properties() rs_domain = service.get_domain() rs_address = service.get_address() @@ -560,10 +540,7 @@ class PresenceService(gobject.GObject): # should un-register it an re-register with the correct info if str(exc) == "Local name collision": pass - uid = service.get_activity_uid() activity_stype = service.get_type() - if uid: - self.track_activity(uid) self.track_service_type(activity_stype) return group diff --git a/sugar/shell/StartPage.py b/sugar/shell/StartPage.py index fce83d1..518315e 100644 --- a/sugar/shell/StartPage.py +++ b/sugar/shell/StartPage.py @@ -236,15 +236,13 @@ class StartPage(gtk.HBox): self._search(None) def _on_local_activity_started_cb(self, helper, activity_container, activity_id): - self._pservice.track_activity(activity_id) print "new local activity %s" % activity_id def _on_local_activity_ended_cb(self, helper, activity_container, activity_id): - self._pservice.untrack_activity(activity_id) + print "local activity %s disappeared" % activity_id def _on_new_service_adv_cb(self, pservice, activity_id, short_stype): if activity_id: - self._pservice.track_activity(activity_id) self._pservice.track_service_type(short_stype) def _on_activity_announced_cb(self, pservice, service, buddy): |