From 9034dc8f3b926ff8e3e9773966c38ad3b8506340 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Thu, 15 Jun 2006 17:05:44 -0400 Subject: [PATCH] More fixes for sharing activities --- sugar/browser/BrowserActivity.py | 51 ++++++++++++++++++++----------- sugar/presence/PresenceService.py | 23 ++++++++------ sugar/presence/Service.py | 30 ++++++++++++------ 3 files changed, 68 insertions(+), 36 deletions(-) diff --git a/sugar/browser/BrowserActivity.py b/sugar/browser/BrowserActivity.py index aa06dfb7..7171100e 100644 --- a/sugar/browser/BrowserActivity.py +++ b/sugar/browser/BrowserActivity.py @@ -8,8 +8,12 @@ import urllib from sugar.shell import activity from sugar.browser import NotificationBar from sugar.browser import NavigationToolbar +from sugar.presence.PresenceService import PresenceService + _BROWSER_ACTIVITY_TYPE = "_web_browser_olpc._udp" +_SERVICE_URI_TAG = "URI" +_SERVICE_TITLE_TAG = "Title" class BrowserActivity(activity.Activity): SOLO = 1 @@ -20,6 +24,11 @@ class BrowserActivity(activity.Activity): activity.Activity.__init__(self) self.uri = uri self._mode = BrowserActivity.SOLO + self._pservice = PresenceService.get_instance() + self._pservice.start() + self._pservice.track_service_type(_BROWSER_ACTIVITY_TYPE) + self._share_service = None + self._model = None def _update_shared_location(self): address = self.embed.get_address() @@ -46,10 +55,11 @@ class BrowserActivity(activity.Activity): self._notif_bar.show() def _setup_shared(self, uri): - self._model = self._group.get_store().get_model(uri) - if self._model: - self.set_mode(BrowserActivity.FOLLOWING) - self._model.add_listener(self.__shared_location_changed_cb) + if False: + self._model = self._group.get_store().get_model(uri) + if self._model: + self.set_mode(BrowserActivity.FOLLOWING) + self._model.add_listener(self.__shared_location_changed_cb) def on_connected_to_shell(self): self.set_ellipsize_tab(True) @@ -90,20 +100,27 @@ class BrowserActivity(activity.Activity): return self.embed def share(self): - url = self.embed.get_address() - self._model = self._group.get_store().create_model(url) - self._model.set_value('owner', self._group.get_owner().get_nick_name()) - self._update_shared_location() - self.set_mode(BrowserActivity.LEADING) - - bus = dbus.SessionBus() - proxy_obj = bus.get_object('com.redhat.Sugar.Chat', '/com/redhat/Sugar/Chat') - chat_shell = dbus.Interface(proxy_obj, 'com.redhat.Sugar.ChatShell') - escaped_title = urllib.quote(self.embed.get_title()) - escaped_url = urllib.quote(url) - chat_shell.send_text_message('' + escaped_title + '') + escaped_url = urllib.quote(self.embed.get_address()) + + # Publish ourselves on the network + properties = {_SERVICE_URI_TAG: escaped_url, _SERVICE_TITLE_TAG: escaped_title} + self._share_service = self._pservice.share_activity(self, + stype=_BROWSER_ACTIVITY_TYPE, properties=properties) + + if False: + # Create our activity-specific browser sharing service + self._model = self._group.get_store().create_model(url) + self._model.set_value('owner', self._pservice.get_owner().get_nick_name()) + self._update_shared_location() + self.set_mode(BrowserActivity.LEADING) + + bus = dbus.SessionBus() + proxy_obj = bus.get_object('com.redhat.Sugar.Chat', '/com/redhat/Sugar/Chat') + chat_shell = dbus.Interface(proxy_obj, 'com.redhat.Sugar.ChatShell') + + chat_shell.send_text_message('' + escaped_title + '') def __title_cb(self, embed): self.set_tab_text(embed.get_title()) diff --git a/sugar/presence/PresenceService.py b/sugar/presence/PresenceService.py index 8a9d0d05..860e63aa 100644 --- a/sugar/presence/PresenceService.py +++ b/sugar/presence/PresenceService.py @@ -4,6 +4,7 @@ import Buddy import Service import os import string +import random from sugar import util def _get_local_ip_address(ifname): @@ -164,8 +165,6 @@ class PresenceService(gobject.GObject): if domain and adv.domain() != domain: continue adv_list.append(adv) - if not len(adv_list): - return None return adv_list def _is_special_service_type(self, stype): @@ -191,6 +190,7 @@ class PresenceService(gobject.GObject): if service.get_address() in self._local_addrs.values(): buddy = Buddy.Owner(service) self._owner = buddy + print "Set owner to %s" % name else: buddy = Buddy.Buddy(service) self._buddies[name] = buddy @@ -200,7 +200,7 @@ class PresenceService(gobject.GObject): def _handle_new_service_for_activity(self, service, buddy): # If the serivce is a group service, merge it into our groups list - uid = service.get_activity_uid() + (uid, ignore) = service.get_activity_uid() if not uid: uid = "*" if not self._activity_services.has_key(uid): @@ -208,7 +208,7 @@ class PresenceService(gobject.GObject): self._activity_services[uid].append((buddy, service)) def _handle_remove_service_for_activity(self, service, buddy): - uid = service.get_activity_uid() + (uid, ignore) = service.get_activity_uid() if not uid: uid = "*" if self._activity_services.has_key(uid): @@ -238,7 +238,8 @@ class PresenceService(gobject.GObject): # Merge the service into our buddy and group lists, if needed buddy = self._handle_new_service_for_buddy(service) - if buddy and service.get_activity_uid(): + (uid, ignore) = service.get_activity_uid() + if buddy and uid: self._handle_new_service_for_activity(service, buddy) return False @@ -376,8 +377,11 @@ class PresenceService(gobject.GObject): a certain mDNS service types.""" if not self._started: raise RuntimeError("presence service must be started first.") - if not type(stype) == type(""): + print "about to track type %s" % stype + if type(stype) != type("") and type(stype) != type(u""): raise ValueError("service type must be a string.") + if type(stype) == type(u""): + stype = stype.encode() if self._is_special_service_type(stype): return if stype in self._allowed_service_types: @@ -423,7 +427,7 @@ class PresenceService(gobject.GObject): """Convenience function to share an activity with other buddies.""" uid = activity.get_id() owner_nick = self._owner.get_nick_name() - real_stype = "_%s_%s" % (uid, stype) + real_stype = Service.compose_service_type(stype, uid) if address and type(address) != type(""): raise ValueError("address must be a valid string.") if not address: @@ -449,7 +453,7 @@ class PresenceService(gobject.GObject): raise RuntimeError("presence service must be started first.") rs_name = service.get_name() - rs_stype = service.get_network_type() + rs_stype = service.get_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.") @@ -472,7 +476,8 @@ class PresenceService(gobject.GObject): # should un-register it an re-register with the correct info if str(exc) == "Local name collision": pass - self.track_service_type(service.get_network_type()) + (uid, activity_stype) = service.get_activity_uid() + self.track_service_type(activity_stype) return group def get_buddy_by_nick_name(self, nick_name): diff --git a/sugar/presence/Service.py b/sugar/presence/Service.py index 4ad23aa1..4e1d72f6 100644 --- a/sugar/presence/Service.py +++ b/sugar/presence/Service.py @@ -41,6 +41,9 @@ def _txt_to_dict(txt): prop_dict[key] = value return prop_dict +def compose_service_type(stype, activity_uid): + return "_%s_%s" % (activity_uid, stype) + def _decompose_service_type(stype): """Break a service type into the UID and real service type, if we can.""" if len(stype) < util.ACTIVITY_UID_LEN + 5: @@ -54,7 +57,7 @@ def _decompose_service_type(stype): uid = stype[start:end] if not util.validate_activity_uid(uid): return (None, stype) - return (uid, stype[end:]) + return (uid, stype[end+1:]) def is_multicast_address(address): """Simple numerical check for whether an IP4 address @@ -89,13 +92,19 @@ class Service(object): if len(domain) and domain != "local" and domain != u"local": raise ValueError("must use the 'local' domain (for now).") + if type(stype) == type(u""): + stype = stype.encode() (uid, real_stype) = _decompose_service_type(stype) - if uid and not util.validate_activity_uid(activity_uid): - raise ValueError("activity_uid not a valid activity UID.") - + if uid and not util.validate_activity_uid(uid): + raise ValueError("service type activity uid not a valid activity UID.") + + if type(name) == type(u""): + name = name.encode() self._name = name self._stype = stype - self._real_stype = real_stype + self._activity_stype = real_stype + if type(domain) == type(u""): + domain = domain.encode() self._domain = domain self._address = None self.set_address(address) @@ -147,15 +156,14 @@ class Service(object): self._properties = _txt_to_dict(properties) elif type(properties) == type({}): self._properties = properties + for key, value in self._properties.items(): + if type(self._properties[key]) == type(u""): + self._properties[key] = self._properties[key].encode() def get_type(self): """Return the service's service type.""" return self._stype - def get_network_type(self): - """Return the full service type, including activity UID.""" - return self._real_stype - def get_port(self): return self._port @@ -173,6 +181,8 @@ class Service(object): raise ValueError("must specify a valid address.") if not len(address): raise ValueError("must specify a valid address.") + if address and type(address) == type(u""): + address = address.encode() self._address = address def get_domain(self): @@ -181,7 +191,7 @@ class Service(object): def get_activity_uid(self): """Return the activity UID this service is associated with, if any.""" - return self._activity_uid + return (self._activity_uid, self._activity_stype) #################################################################