diff --git a/shell/shell.py b/shell/shell.py index e4cc36a2..a86e6dc5 100755 --- a/shell/shell.py +++ b/shell/shell.py @@ -10,7 +10,8 @@ import gobject import sugar.util from sugar.chat.ChatWindow import ChatWindow -from sugar.chat.GroupChat import GroupChat +from sugar.chat.ActivityChat import ActivityChat +from sugar.chat.MeshChat import MeshChat from sugar.LogWriter import LogWriter from Owner import ShellOwner @@ -82,7 +83,7 @@ class ActivityHost(dbus.service.Object): notebook.set_current_page(index) def _create_chat(self): - self._group_chat = GroupChat(self) + self._group_chat = ActivityChat(self) def get_chat(self): return self._group_chat @@ -322,6 +323,8 @@ class ActivityContainer(dbus.service.Object): self._chat_wm.set_height(0.5, WindowManager.SCREEN_RELATIVE) self._chat_wm.set_position(WindowManager.TOP) self._chat_wm.manage() + + self._mesh_chat = MeshChat() def show(self): self.window.show() @@ -339,6 +342,8 @@ class ActivityContainer(dbus.service.Object): if activity: host_chat = activity.get_chat() self._chat_window.set_chat(host_chat) + else: + self._chat_window.set_chat(self._mesh_chat) # For some reason the substitution screw up window position self._chat_wm.update() diff --git a/sugar/chat/ActivityChat.py b/sugar/chat/ActivityChat.py new file mode 100644 index 00000000..6e3c71c6 --- /dev/null +++ b/sugar/chat/ActivityChat.py @@ -0,0 +1,26 @@ +import logging + +from sugar.chat.GroupChat import GroupChat + +class ActivityChat(GroupChat): + SERVICE_TYPE = "_olpc_activity_chat._udp" + SERVICE_PORT = 6200 + + def __init__(self, activity): + GroupChat.__init__(self) + self._activity = activity + self._pservice.connect('service-appeared', self._service_appeared_cb) + self._pservice.track_service_type(ActivityChat.SERVICE_TYPE) + service = self._pservice.get_activity_service(activity, ActivityChat.SERVICE_TYPE) + if service is not None: + self._service_appeared_cb(self._pservice, None, service) + + def _service_appeared_cb(self, pservice, buddy, service): + if service.get_activity_uid() == self._activity.get_id(): + if service.get_type() == ActivityChat.SERVICE_TYPE: + logging.debug('Group chat service appeared, setup the stream.') + self._setup_stream(service) + + def publish(self): + service = self._pservice.share_activity(self._activity, + stype = ActivityChat.SERVICE_TYPE, port = ActivityChat.SERVICE_PORT) diff --git a/sugar/chat/GroupChat.py b/sugar/chat/GroupChat.py index 8f32ace5..a269552b 100644 --- a/sugar/chat/GroupChat.py +++ b/sugar/chat/GroupChat.py @@ -2,34 +2,15 @@ import logging from sugar.chat.Chat import Chat from sugar.p2p.Stream import Stream -from sugar.presence.PresenceService import PresenceService +from sugar.presence.PresenceService import PresenceService +import sugar.env class GroupChat(Chat): - SERVICE_TYPE = "_olpc_group_chat._udp" - SERVICE_PORT = 6200 - - def __init__(self, activity): + def __init__(self): Chat.__init__(self) - self._chats = {} - self._activity = activity - self._pservice = PresenceService.get_instance() - self._pservice.start() - self._pservice.connect('service-appeared', self._service_appeared_cb) - self._pservice.track_service_type(GroupChat.SERVICE_TYPE) - service = self._pservice.get_activity_service(activity, GroupChat.SERVICE_TYPE) - if service is not None: - self._service_appeared_cb(self._pservice, None, service) - - def _service_appeared_cb(self, pservice, buddy, service): - if service.get_activity_uid() == self._activity.get_id(): - if service.get_type() == GroupChat.SERVICE_TYPE: - logging.debug('Group chat service appeared, setup the stream.') - self._setup_stream(service) - - def publish(self): - service = self._pservice.share_activity(self._activity, - stype = GroupChat.SERVICE_TYPE, port = GroupChat.SERVICE_PORT) + self._pservice.start() + self._group_stream = None def _setup_stream(self, service): self._group_stream = Stream.new_from_service(service) diff --git a/sugar/chat/MeshChat.py b/sugar/chat/MeshChat.py new file mode 100644 index 00000000..0edc4c1a --- /dev/null +++ b/sugar/chat/MeshChat.py @@ -0,0 +1,36 @@ +import logging +import random + +from sugar.chat.GroupChat import GroupChat +from sugar.presence.Service import Service +import sugar.env + +class MeshChat(GroupChat): + SERVICE_TYPE = "_olpc_mesh_chat._udp" + SERVICE_PORT = 6301 + + def __init__(self): + GroupChat.__init__(self) + + self._pservice.connect('service-appeared', self._service_appeared_cb) + self._pservice.track_service_type(MeshChat.SERVICE_TYPE) + + self._publish() + + service = self._pservice.get_service(MeshChat.SERVICE_TYPE) + if service is not None: + self._service_appeared_cb(self._pservice, None, service) + + def _service_appeared_cb(self, pservice, buddy, service): + if self._group_stream == None: + if service.get_type() == MeshChat.SERVICE_TYPE: + logging.debug('Mesh chat service appeared, setup the stream.') + self._setup_stream(service) + + def _publish(self): + # Use random currently unassigned multicast address + address = "232.%d.%d.%d" % (random.randint(0, 254), random.randint(1, 254), + random.randint(1, 254)) + service = Service(sugar.env.get_nick_name(), MeshChat.SERVICE_TYPE, + 'local', address, MeshChat.SERVICE_PORT) + self._pservice.register_service(service) diff --git a/sugar/presence/PresenceService.py b/sugar/presence/PresenceService.py index c42e52e9..276bd69c 100644 --- a/sugar/presence/PresenceService.py +++ b/sugar/presence/PresenceService.py @@ -123,6 +123,14 @@ class PresenceService(gobject.GObject): self._server = dbus.Interface(self._bus.get_object(avahi.DBUS_NAME, avahi.DBUS_PATH_SERVER), avahi.DBUS_INTERFACE_SERVER) + def get_service(self, full_stype): + """Find a particular service by full service type.""" + services = self._find_service_adv(stype = full_stype) + if len(services) > 0: + return services[0] + else: + return None + def get_activity_service(self, activity, short_stype): """Find a particular service by activity and service type.""" # Decompose service type if we can