Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAgustin Zubiaga <aguz@sugarlabs.org>2012-09-05 16:35:05 (GMT)
committer Agustin Zubiaga <aguz@sugarlabs.org>2012-09-05 16:35:05 (GMT)
commite32b2d78d1c5fa87cf339378fb4858fd79f53fe0 (patch)
treec5ff2a797d06e2e98dc85299207c71e4b7b9d72f
parent8439198a08fbd8b6d7dad2fb95b020b37de5fd27 (diff)
Starting collaboration
-rw-r--r--activity.py145
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
+