From e752cda5e6f09d3230b7d8cd10bd5b7d18f0e34b Mon Sep 17 00:00:00 2001 From: Marco Pesenti Gritti Date: Mon, 15 May 2006 14:07:16 -0400 Subject: [PATCH] Implement model changes notification and hook --- sugar/browser/browser.py | 17 ++++++++++++++--- sugar/p2p/NotificationListener.py | 27 +++++++++++++++++++++++++++ sugar/p2p/Notifier.py | 11 +++++++++++ sugar/p2p/model/LocalModel.py | 20 ++++++++++++-------- sugar/p2p/model/RemoteModel.py | 15 ++++++++++++--- sugar/p2p/model/Store.py | 2 +- 6 files changed, 77 insertions(+), 15 deletions(-) create mode 100644 sugar/p2p/NotificationListener.py create mode 100644 sugar/p2p/Notifier.py diff --git a/sugar/browser/browser.py b/sugar/browser/browser.py index 32a0ca1c..02af2e52 100755 --- a/sugar/browser/browser.py +++ b/sugar/browser/browser.py @@ -166,9 +166,9 @@ class BrowserActivity(activity.Activity): self._setup_shared(uri) def _setup_shared(self, uri): - self._model = self._group.get_store().get_model(uri) - if self._model: - print self._model.get_value('current_address') + self._model = self._group.get_store().get_model(uri) + self._load_shared_address() + self._model.add_listener(self.__shared_address_changed_cb) def activity_on_connected_to_shell(self): self.activity_set_ellipsize_tab(True) @@ -203,6 +203,7 @@ class BrowserActivity(activity.Activity): address = self.embed.get_address() self._model = self._group.get_store().create_model(address) self._model.set_value('current_address', address) + self._model.add_listener(self.__shared_address_changed_cb) bus = dbus.SessionBus() proxy_obj = bus.get_object('com.redhat.Sugar.Chat', '/com/redhat/Sugar/Chat') @@ -212,6 +213,16 @@ class BrowserActivity(activity.Activity): def __title_cb(self, embed): self.activity_set_tab_text(embed.get_title()) + # Temporary hack, we need an UI + self._model.set_value('current_address', self.embed.get_address()) + + def _load_shared_address(self): + address = self._model.get_value("current_address") + if (address != self.embed.get_address()): + self.embed.load_address(address) + + def __shared_address_changed_cb(self, model, key): + self._load_shared_address() def activity_on_close_from_user(self): self.activity_shutdown() diff --git a/sugar/p2p/NotificationListener.py b/sugar/p2p/NotificationListener.py new file mode 100644 index 00000000..e490f390 --- /dev/null +++ b/sugar/p2p/NotificationListener.py @@ -0,0 +1,27 @@ +from Service import Service +import network + +class NotificationListener: + TYPE = "_olpc_model_notification._udp" + ADDRESS = "224.0.0.222" + PORT = 6300 + + def __init__(self, group, name): + server = network.GroupServer(NotificationListener.TYPE, + NotificationListener.PORT, + self._recv_multicast) + server.start() + + service = Service(name, NotificationListener.TYPE, + NotificationListener.ADDRESS, + NotificationListener.PORT, True) + service.register(group) + + self._listeners = {} + + def add_listener(self, listener): + self._listeners.add(listener) + + def _recv_multicast(self, msg): + for listener in self._listeners: + listener(msg) diff --git a/sugar/p2p/Notifier.py b/sugar/p2p/Notifier.py new file mode 100644 index 00000000..017183c9 --- /dev/null +++ b/sugar/p2p/Notifier.py @@ -0,0 +1,11 @@ +import network + +class Notifier: + def __init__(self, group, name): + service = group.get_service(name) + address = service.get_address() + port = service.get_port() + self._client = network.GroupClient(address, port) + + def notify(self, msg): + self._client.send_msg(msg) diff --git a/sugar/p2p/model/LocalModel.py b/sugar/p2p/model/LocalModel.py index b268a5dc..f8192cc3 100644 --- a/sugar/p2p/model/LocalModel.py +++ b/sugar/p2p/model/LocalModel.py @@ -1,10 +1,8 @@ import socket -import xmlrpclib from sugar.p2p.Service import Service - -MODEL_SERVICE_TYPE = "_olpc_model._tcp" -MODEL_SERVICE_PORT = 6300 +from sugar.p2p.model.AbstractModel import AbstractModel +import network class ModelRequestHandler(object): def __init__(self, model): @@ -16,26 +14,32 @@ class ModelRequestHandler(object): def set_value(self, key, value): return self._model.set_value(key, value) -class LocalModel: +class LocalModel(AbstractModel): + SERVICE_TYPE = "_olpc_model._tcp" + SERVICE_PORT = 6300 + def __init__(self, group, model_id): + AbstractModel.__init__(self) self._group = group self._model_id = model_id self._values = {} self._setup_service() + self._setup_notification() def get_value(self, key): return self._values[key] def set_value(self, key, value): self._values[key] = value + self._notify_model_change(key) def _setup_service(self): - service = Service(self._model_id, MODEL_SERVICE_TYPE, - '', MODEL_SERVICE_PORT) + service = Service(self._model_id, LocalModel.SERVICE_TYPE, '', + LocalModel.SERVICE_PORT) self._setup_server(service) service.register(self._group) - + # FIXME this is duplicated with StreamReader def _setup_server(self, service): started = False diff --git a/sugar/p2p/model/RemoteModel.py b/sugar/p2p/model/RemoteModel.py index 4492fe9b..b966b435 100644 --- a/sugar/p2p/model/RemoteModel.py +++ b/sugar/p2p/model/RemoteModel.py @@ -1,17 +1,26 @@ import xmlrpclib -from sugar.p2p.Service import Service -import network +from sugar.p2p.NotificationListener import NotificationListener +from sugar.p2p.model.AbstractModel import AbstractModel -class RemoteModel: +class RemoteModel(AbstractModel): def __init__(self, service): + AbstractModel.__init__(self) + self._service = service addr = "http://%s:%d" % (service.get_address(), service.get_port()) self._client = xmlrpclib.ServerProxy(addr) + + self._setup_notification_listener() def get_value(self, key): return self._client.get_value(key) def set_value(self, key, value): self._client.set_value(key, value) + + def _setup_notification_listener(self): + name = self._service.get_name() + self._notification = NotificationListener(self._group, name) + self._notification.add_listener(self._notify_model_change) diff --git a/sugar/p2p/model/Store.py b/sugar/p2p/model/Store.py index ae86dc1b..d39783f4 100644 --- a/sugar/p2p/model/Store.py +++ b/sugar/p2p/model/Store.py @@ -15,7 +15,7 @@ class Store: if self._local_models.has_key(model_id): return self._local_models(model_id) else: - service = self._group.get_service(model_id, MODEL_SERVICE_TYPE) + service = self._group.get_service(model_id, LocalModel.SERVICE_TYPE) if service: return RemoteModel(service) else: