diff options
author | Agustin Zubiaga <aguz@sugarlabs.org> | 2012-09-05 16:35:05 (GMT) |
---|---|---|
committer | Agustin Zubiaga <aguz@sugarlabs.org> | 2012-09-05 16:35:05 (GMT) |
commit | e32b2d78d1c5fa87cf339378fb4858fd79f53fe0 (patch) | |
tree | c5ff2a797d06e2e98dc85299207c71e4b7b9d72f | |
parent | 8439198a08fbd8b6d7dad2fb95b020b37de5fd27 (diff) |
Starting collaboration
-rw-r--r-- | activity.py | 145 |
1 files changed, 145 insertions, 0 deletions
diff --git a/activity.py b/activity.py index 772aec5..491e33e 100644 --- a/activity.py +++ b/activity.py @@ -17,6 +17,12 @@ from gi.repository import Gtk +import logging +import telepathy +from dbus.service import signal +from dbus.gobject_service import ExportedGObject +from sugar3.presence import presenceservice +from sugar3.presence.tubeconn import TubeConnection from sugar3.activity import activity from sugar3.activity.widgets import StopButton from sugar3.activity.widgets import ActivityToolbarButton @@ -28,6 +34,10 @@ from gettext import gettext as _ import game +SERVICE = 'org.sugarlabs.TicTacToe' +IFACE = SERVICE +PATH = '/org/augarlabs/TicTacToe' + class Activity(activity.Activity): def __init__(self, handle): @@ -99,6 +109,141 @@ class Activity(activity.Activity): stopbtn = StopButton(self) toolbarbox.toolbar.insert(stopbtn, -1) + self._setup_presence_service() + self.set_toolbar_box(toolbarbox) self.show_all() + def _setup_presence_service(self): + """Setup the Presence Service.""" + self.pservice = presenceservice.get_instance() + self.initiating = None # sharing (True) or joining (False) + + owner = self.pservice.get_owner() + self.owner = owner + self._share = "" + self.connect('shared', self._shared_cb) + self.connect('joined', self._joined_cb) + + def _shared_cb(self, activity): + """Either set up initial share...""" + self._new_tube_common(True) + + def _joined_cb(self, activity): + """...or join an exisiting share.""" + self._new_tube_common(False) + + def _new_tube_common(self, sharer): + """Joining and sharing are mostly the same...""" + if self.shared_activity is None: + logging.debug("Error: Failed to share or join activity ... \ + _shared_activity is null in _shared_cb()") + return + + self.initiating = sharer + self.waiting_for_hand = not sharer + + self.conn = self.shared_activity.telepathy_conn + self.tubes_chan = self.shared_activity.telepathy_tubes_chan + self.text_chan = self.shared_activity.telepathy_text_chan + + self.tubes_chan[telepathy.CHANNEL_TYPE_TUBES].connect_to_signal( + 'NewTube', self._new_tube_cb) + + if sharer: + logging.debug('This is my activity: making a tube...') + id = self.tubes_chan[telepathy.CHANNEL_TYPE_TUBES].OfferDBusTube( + SERVICE, {}) + else: + logging.debug('I am joining an activity: waiting for a tube...') + self.tubes_chan[telepathy.CHANNEL_TYPE_TUBES].ListTubes( + reply_handler=self._list_tubes_reply_cb, + error_handler=self._list_tubes_error_cb) + + def _list_tubes_reply_cb(self, tubes): + """Reply to a list request.""" + for tube_info in tubes: + self._new_tube_cb(*tube_info) + + def _list_tubes_error_cb(self, e): + """Log errors.""" + logging.debug('Error: ListTubes() failed: %s' % (e)) + + def _new_tube_cb(self, id, initiator, type, service, params, state): + """Create a new tube.""" + logging.debug('New tube: ID=%d initator=%d type=%d service=%s \ +params=%r state=%d' % (id, initiator, type, service, params, state)) + + if (type == telepathy.TUBE_TYPE_DBUS and service == SERVICE): + if state == telepathy.TUBE_STATE_LOCAL_PENDING: + self.tubes_chan[ \ + telepathy.CHANNEL_TYPE_TUBES].AcceptDBusTube(id) + + tube_conn = TubeConnection(self.conn, + self.tubes_chan[telepathy.CHANNEL_TYPE_TUBES], id, \ + group_iface=self.text_chan[telepathy.CHANNEL_INTERFACE_GROUP]) + + self.chattube = ChatTube(tube_conn, self.initiating, \ + self.event_received_cb) + + def _setup_dispatch_table(self): + """Associate tokens with commands.""" + self._processing_methods = { + 'x': [self._receive_cross, 'get a cross'], + 'o': [self._receive_circle, 'get a circle'], + } + + def event_received_cb(self, event_message): + """Data from a tube has arrived.""" + if len(event_message) == 0: + return + try: + command, payload = event_message.split('|', 2) + except ValueError: + logging.debug('Could not split event message %s' % (event_message)) + return + self._processing_methods[command][0](payload) + + def send_new_cross(self, square): + self.send_event('x|%s' % square) + + def send_new_circle(self, square): + self.send_event('o|%s' % square) + + def _receive_new_cross(self, square): + square = int(square) + logging.debug('Receive a new cross %s' % square) + + def _receive_new_circle(self, square): + square = int(square) + logging.debug('Receive a new circle %s' % square) + + def send_event(self, entry): + """ Send event through the tube. """ + if hasattr(self, 'chattube') and self.chattube is not None: + self.chattube.SendText(entry) + + +class ChatTube(ExportedGObject): + """ Class for setting up tube for sharing """ + + def __init__(self, tube, is_initiator, stack_received_cb): + super(ChatTube, self).__init__(tube, PATH) + self.tube = tube + self.is_initiator = is_initiator + self.stack_received_cb = stack_received_cb + self.stack = '' + + self.tube.add_signal_receiver(self.send_stack_cb, 'SendText', IFACE, + path=PATH, sender_keyword='sender') + + def send_stack_cb(self, text, sender=None): + if sender == self.tube.get_unique_name(): + return + self.stack = text + self.stack_received_cb(text) + + @signal(dbus_interface=IFACE, signature='s') + def SendText(self, text): + self.stack = text + |