From aba40b2fd99044fa0696ba3e0b8c968f6b814a43 Mon Sep 17 00:00:00 2001 From: Marco Pesenti Gritti Date: Fri, 12 May 2006 18:09:13 -0400 Subject: [PATCH] Initial model and totems code --- sugar/browser/browser.py | 52 +++++++++++++++++++-------- sugar/chat/chat.py | 6 ++-- sugar/p2p/Group.py | 5 +++ sugar/p2p/Model.py | 76 ++++++++++++++++++++++++++++++++++++++++ 4 files changed, 121 insertions(+), 18 deletions(-) create mode 100644 sugar/p2p/Model.py diff --git a/sugar/browser/browser.py b/sugar/browser/browser.py index 633fa044..3de0c90d 100755 --- a/sugar/browser/browser.py +++ b/sugar/browser/browser.py @@ -11,6 +11,7 @@ import gtk import geckoembed from sugar.shell import activity +from sugar.p2p.Group import LocalGroup import sugar.env class AddressToolbar(gtk.Toolbar): @@ -88,11 +89,12 @@ class AddressEntry(gtk.HBox): self.set_folded(True) class NavigationToolbar(gtk.Toolbar): - def __init__(self, embed): + def __init__(self, browser): gtk.Toolbar.__init__(self) - self.embed = embed + self._browser = browser + self._embed = self._browser.get_embed() - self.set_style(gtk.TOOLBAR_ICONS) + self.set_style(gtk.TOOLBAR_BOTH_HORIZ) self.back = gtk.ToolButton(gtk.STOCK_GO_BACK) self.back.connect("clicked", self.__go_back_cb) @@ -113,7 +115,9 @@ class NavigationToolbar(gtk.Toolbar): self.insert(separator, -1) separator.show() - share = gtk.ToolButton("Share") + share = gtk.ToolButton(None, "Share") + share.set_icon_name('stock_shared-by-me') + share.set_is_important(True) share.connect("clicked", self.__share_cb) self.insert(share, -1) share.show() @@ -128,34 +132,40 @@ class NavigationToolbar(gtk.Toolbar): self._update_sensitivity() - self.embed.connect("location", self.__location_changed) + self._embed.connect("location", self.__location_changed) def _update_sensitivity(self): - self.back.set_sensitive(self.embed.can_go_back()) - self.forward.set_sensitive(self.embed.can_go_forward()) + self.back.set_sensitive(self._embed.can_go_back()) + self.forward.set_sensitive(self._embed.can_go_forward()) def __go_back_cb(self, button): - self.embed.go_back() + self._embed.go_back() def __go_forward_cb(self, button): - self.embed.go_forward() + self._embed.go_forward() def __reload_cb(self, button): - self.embed.reload() + self._embed.reload() def __share_cb(self, button): - pass + self._browser.share() def __location_changed(self, embed): self._update_sensitivity() def __open_address_cb(self, address): - self.embed.load_address(address) + self._embed.load_address(address) class BrowserActivity(activity.Activity): - def __init__(self, uri): + def __init__(self, group, uri): activity.Activity.__init__(self) self.uri = uri + self._group = group + + def _setup_shared(self, uri): + self._model = self._group.get_store().get_model(uri) + if self._model: + print self._model.get_value('current_address') def activity_on_connected_to_shell(self): self.activity_set_ellipsize_tab(True) @@ -173,7 +183,7 @@ class BrowserActivity(activity.Activity): self.embed.show() self.embed.load_address(self.uri) - nav_toolbar = NavigationToolbar(self.embed) + nav_toolbar = NavigationToolbar(self) vbox.pack_start(nav_toolbar, False) nav_toolbar.show() @@ -186,6 +196,17 @@ class BrowserActivity(activity.Activity): def get_embed(self): return self.embed + def share(self): + address = self.embed.get_address() + self._model = self._group.get_store().create_model(address) + self._model.set_value('current_address', address) + + 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_message('' + + self.embed.get_title() + '') + def __title_cb(self, embed): self.activity_set_tab_text(embed.get_title()) @@ -249,6 +270,7 @@ class BrowserShell(dbus.service.Object): dbus.service.Object.__init__(self, bus_name, object_path) self.__browsers = [] + self._group = LocalGroup() def open_web_activity(self): web_activity = WebActivity() @@ -267,7 +289,7 @@ class BrowserShell(dbus.service.Object): @dbus.service.method('com.redhat.Sugar.BrowserShell') def open_browser(self, uri): - browser = BrowserActivity(uri) + browser = BrowserActivity(self._group, uri) self.__browsers.append(browser) browser.activity_connect_to_shell() diff --git a/sugar/chat/chat.py b/sugar/chat/chat.py index 2bc72305..8be22314 100755 --- a/sugar/chat/chat.py +++ b/sugar/chat/chat.py @@ -387,12 +387,12 @@ class ChatShell(dbus.service.Object): dbus.service.Object.__init__(self, bus_name, object_path) def open_group_chat(self): - group_chat = GroupChat() - group_chat.activity_connect_to_shell() + self._group_chat = GroupChat() + self._group_chat.activity_connect_to_shell() @dbus.service.method('com.redhat.Sugar.ChatShell') def send_message(self, message): - pass + self._group_chat.send_message(message) def main(): ChatShell.get_instance().open_group_chat() diff --git a/sugar/p2p/Group.py b/sugar/p2p/Group.py index dedbc1ed..fda5f2f7 100644 --- a/sugar/p2p/Group.py +++ b/sugar/p2p/Group.py @@ -3,6 +3,7 @@ import avahi import presence from Buddy import * from Service import * +import Model SERVICE_ADDED = "service_added" SERVICE_REMOVED = "service_removed" @@ -14,6 +15,10 @@ class Group: def __init__(self): self._service_listeners = [] self._presence_listeners = [] + self._store = Model.Store(self) + + def get_store(self): + return self._store def join(self, buddy): pass diff --git a/sugar/p2p/Model.py b/sugar/p2p/Model.py new file mode 100644 index 00000000..f4bda478 --- /dev/null +++ b/sugar/p2p/Model.py @@ -0,0 +1,76 @@ +MODEL_SERVICE_TYPE = "_olpc_model._tcp" +MODEL_SERVICE_PORT = 6300 + +class RemoteModel: + def __init__(self, service): + self._service = service + + addr = "http://%s:%d" % (service.get_address(), service.get_port()) + self._client = xmlrpclib.ServerProxy(addr) + + def get_value(self, key): + self._client.get_value(key) + + def set_value(self, key, value): + self._client.set_value(key, value) + +class ModelRequestHandler(object): + def __init__(self, model): + self._model = model + + def get_value(self, key): + return self._model.get_value(key) + + def set_value(self, key, value): + return self._model.set_value(key, value) + +class LocalModel: + def __init__(self, model_id): + self._model_id = model_id + self._values = {} + + def get_value(self, key): + return self._values[key] + + def set_value(self, key, value): + self._values[key] = value + + def _setup_service(self): + service = Service(self._model_id, MODEL_SERVICE_TYPE, + '', MODEL_SERVICE_PORT) + self._setup_server(service) + + # FIXME this is duplicated with StreamReader + def _setup_server(self, service): + started = False + tries = 10 + port = service.get_port() + while not started and tries > 0: + try: + p2p_server = network.GlibXMLRPCServer(("", port)) + p2p_server.register_instance(StreamReaderRequestHandler(self)) + started = True + except: + port = port + 1 + tries = tries - 1 + service.set_port(port) + +class Store: + def __init__(self, group): + self._group = group + self._local_models = {} + + def create_model(self, model_id): + model = LocalModel(model_id) + self._local_models[model_id] = model + return model + + def get_model(self, model_id): + 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) + if service: + return RemoteModel(service) + else: + return None