Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/TurtleArt/tacollaboration.py
diff options
context:
space:
mode:
Diffstat (limited to 'TurtleArt/tacollaboration.py')
-rw-r--r--TurtleArt/tacollaboration.py282
1 files changed, 192 insertions, 90 deletions
diff --git a/TurtleArt/tacollaboration.py b/TurtleArt/tacollaboration.py
index 52164e0..d4b7529 100644
--- a/TurtleArt/tacollaboration.py
+++ b/TurtleArt/tacollaboration.py
@@ -1,9 +1,35 @@
+#Copyright (c) 2011, Walter Bender
+#Copyright (c) 2011 Collabora Ltd. <http://www.collabora.co.uk/>
+
+#Permission is hereby granted, free of charge, to any person obtaining a copy
+#of this software and associated documentation files (the "Software"), to deal
+#in the Software without restriction, including without limitation the rights
+#to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+#copies of the Software, and to permit persons to whom the Software is
+#furnished to do so, subject to the following conditions:
+
+#The above copyright notice and this permission notice shall be included in
+#all copies or substantial portions of the Software.
+
+#THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+#IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+#FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+#AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+#LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+#OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+#THE SOFTWARE.
from dbus.service import signal
from dbus.gobject_service import ExportedGObject
import logging
import telepathy
-from TurtleArt.tautils import data_to_string, data_from_string
+
+import gtk
+import base64
+
+from TurtleArt.tautils import data_to_string, data_from_string, get_path, \
+ base64_to_image
+from TurtleArt.taconstants import DEFAULT_TURTLE_COLORS
try:
from sugar import profile
@@ -19,17 +45,19 @@ IFACE = SERVICE
PATH = '/org/laptop/TurtleArtActivity'
_logger = logging.getLogger('turtleart-activity')
+
class Collaboration():
def __init__(self, tw, activity):
""" A simplistic sharing model: the sharer is the master """
self._tw = tw
self._tw.send_event = self.send_event
self._activity = activity
+ self._setup_dispatch_table()
def setup(self):
# TODO: hand off role of master is sharer leaves
self.pservice = presenceservice.get_instance()
- self.initiating = None # sharing (True) or joining (False)
+ self.initiating = None # sharing (True) or joining (False)
# Add my buddy object to the list
owner = self.pservice.get_owner()
@@ -40,6 +68,24 @@ class Collaboration():
self._activity.connect('shared', self._shared_cb)
self._activity.connect('joined', self._joined_cb)
+ def _setup_dispatch_table(self):
+ self._processing_methods = {
+ 't': self._turtle_request,
+ 'T': self._receive_turtle_dict,
+ 'f': self._move_forward,
+ 'a': self._move_in_arc,
+ 'r': self._rotate_turtle,
+ 'x': self._setxy,
+ 'W': self._draw_text,
+ 'c': self._set_pen_color,
+ 'g': self._set_pen_gray_level,
+ 's': self._set_pen_shade,
+ 'w': self._set_pen_width,
+ 'p': self._set_pen_state,
+ 'F': self._fill_polygon,
+ 'P': self._draw_pixbuf
+ }
+
def _shared_cb(self, activity):
self._shared_activity = self._activity._shared_activity
if self._shared_activity is None:
@@ -128,98 +174,25 @@ class Collaboration():
_logger.debug(event)
self.send_event(event)
- def event_received_cb(self, text):
+ def event_received_cb(self, event_message):
"""
Events are sent as a tuple, nick|cmd, where nick is a turle name
and cmd is a turtle event. Everyone gets the turtle dictionary from
the sharer and watches for 't' events, which indicate that a new
turtle has joined.
"""
- if len(text) == 0:
+ if len(event_message) == 0:
return
- # Save active Turtle
+
+ # Save active Turtle
save_active_turtle = self._tw.active_turtle
- e = text.split("|", 2)
- text = e[1]
- if e[0] == 't': # request for turtle dictionary
- if text > 0:
- [nick, colors] = data_from_string(text)
- if nick != self._tw.nick:
- # There may not be a turtle dictionary.
- if hasattr(self, "turtle_dictionary"):
- self.turtle_dictionary[nick] = colors
- else:
- self.turtle_dictionary = {nick: colors}
- # Add new turtle for the joiner.
- self._tw.canvas.set_turtle(nick, colors)
- # Sharer should send turtle dictionary.
- if self.initiating:
- text = data_to_string(self.turtle_dictionary)
- self.send_event("T|" + text)
- elif e[0] == 'T': # Receiving the turtle dictionary.
- if self.waiting_for_turtles:
- if len(text) > 0:
- self.turtle_dictionary = data_from_string(text)
- for nick in self.turtle_dictionary:
- if nick != self._tw.nick:
- colors = self.turtle_dictionary[nick]
- # add new turtle for the joiner
- self._tw.canvas.set_turtle(nick, colors)
- self.waiting_for_turtles = False
- elif e[0] == 'f': # move a turtle forward
- if len(text) > 0:
- [nick, x] = data_from_string(text)
- if nick != self._tw.nick:
- self._tw.canvas.set_turtle(nick)
- self._tw.canvas.forward(x, False)
- elif e[0] == 'a': # move a turtle in an arc
- if len(text) > 0:
- [nick, [a, r]] = data_from_string(text)
- if nick != self._tw.nick:
- self._tw.canvas.set_turtle(nick)
- self._tw.canvas.arc(a, r, False)
- elif e[0] == 'r': # rotate turtle
- if len(text) > 0:
- [nick, h] = data_from_string(text)
- if nick != self._tw.nick:
- self._tw.canvas.set_turtle(nick)
- self._tw.canvas.seth(h, False)
- elif e[0] == 'x': # set turtle xy position
- if len(text) > 0:
- [nick, [x, y]] = data_from_string(text)
- if nick != self._tw.nick:
- self._tw.canvas.set_turtle(nick)
- self._tw.canvas.setxy(x, y, False)
- elif e[0] == 'c': # set turtle pen color
- if len(text) > 0:
- [nick, x] = data_from_string(text)
- if nick != self._tw.nick:
- self._tw.canvas.set_turtle(nick)
- self._tw.canvas.setcolor(x, False)
- elif e[0] == 'g': # set turtle pen gray level
- if len(text) > 0:
- [nick, x] = data_from_string(text)
- if nick != self._tw.nick:
- self._tw.canvas.set_turtle(nick)
- self._tw.canvas.setgray(x, False)
- elif e[0] == 's': # set turtle pen shade
- if len(text) > 0:
- [nick, x] = data_from_string(text)
- if nick != self._tw.nick:
- self._tw.canvas.set_turtle(nick)
- self._tw.canvas.setshade(x, False)
- elif e[0] == 'w': # set turtle pen width
- if len(text) > 0:
- [nick, x] = data_from_string(text)
- if nick != self._tw.nick:
- self._tw.canvas.set_turtle(nick)
- self._tw.canvas.setpensize(x, False)
- elif e[0] == 'p': # set turtle pen state
- if len(text) > 0:
- [nick, x] = data_from_string(text)
- if nick != self._tw.nick:
- self._tw.canvas.set_turtle(nick)
- self._tw.canvas.setpen(x, False)
+
+ try:
+ command, payload = event_message.split("|", 2)
+ self._processing_methods[command](payload)
+ except ValueError:
+ _logger.debug("could not split event message")
+
# Restore active Turtle
self._tw.canvas.set_turtle(self._tw.turtles.get_turtle_key(
save_active_turtle))
@@ -229,27 +202,156 @@ class Collaboration():
if hasattr(self, 'chattube') and self.chattube is not None:
self.chattube.SendText(entry)
+ def _turtle_request(self, payload):
+ if payload > 0:
+ [nick, colors] = data_from_string(payload)
+ if nick != self._tw.nick:
+ # There may not be a turtle dictionary.
+ if hasattr(self, "turtle_dictionary"):
+ self.turtle_dictionary[nick] = colors
+ else:
+ self.turtle_dictionary = {nick: colors}
+ # Add new turtle for the joiner.
+ self._tw.canvas.set_turtle(nick, colors)
+ # Sharer should send turtle dictionary.
+ if self.initiating:
+ event_payload = data_to_string(self.turtle_dictionary)
+ self.send_event("T|" + event_payload)
+
+ def _receive_turtle_dict(self, payload):
+ if self.waiting_for_turtles:
+ if len(payload) > 0:
+ self.turtle_dictionary = data_from_string(payload)
+ for nick in self.turtle_dictionary:
+ if nick != self._tw.nick:
+ colors = self.turtle_dictionary[nick]
+ # add new turtle for the joiner
+ self._tw.canvas.set_turtle(nick, colors)
+ self.waiting_for_turtles = False
+
+ def _draw_pixbuf(self, payload):
+ if len(payload) > 0:
+ [nick, [a, b, x, y, w, h, width, height, data]] =\
+ data_from_string(payload)
+ if nick != self._tw.nick:
+ if self._tw.running_sugar:
+ tmp_path = get_path(self._tw.activity, 'instance')
+ else:
+ tmp_path = '/tmp'
+ file_name = base64_to_image(data, tmp_path)
+ pixbuf = gtk.gdk.pixbuf_new_from_file_at_size(file_name,
+ width, height)
+ x, y = self._tw.canvas.turtle_to_screen_coordinates(x, y)
+ self._tw.canvas.draw_pixbuf(pixbuf, a, b, x, y, w, h,
+ file_name, False)
+
+ def _move_forward(self, payload):
+ if len(payload) > 0:
+ [nick, x] = data_from_string(payload)
+ if nick != self._tw.nick:
+ self._tw.canvas.set_turtle(nick)
+ self._tw.canvas.forward(x, False)
+
+ def _move_in_arc(self, payload):
+ if len(payload) > 0:
+ [nick, [a, r]] = data_from_string(payload)
+ if nick != self._tw.nick:
+ self._tw.canvas.set_turtle(nick)
+ self._tw.canvas.arc(a, r, False)
+
+ def _rotate_turtle(self, payload):
+ if len(payload) > 0:
+ [nick, h] = data_from_string(payload)
+ if nick != self._tw.nick:
+ self._tw.canvas.set_turtle(nick)
+ self._tw.canvas.seth(h, False)
+
+ def _setxy(self, payload):
+ if len(payload) > 0:
+ [nick, [x, y]] = data_from_string(payload)
+ if nick != self._tw.nick:
+ self._tw.canvas.set_turtle(nick)
+ self._tw.canvas.setxy(x, y, False)
+
+ def _draw_text(self, payload):
+ if len(payload) > 0:
+ [nick, [label, x, y, size, w]] = data_from_string(payload)
+ if nick != self._tw.nick:
+ self._tw.canvas.draw_text(label, x, y, size, w, False)
+
+ def _set_pen_color(self, payload):
+ if len(payload) > 0:
+ [nick, x] = data_from_string(payload)
+ if nick != self._tw.nick:
+ self._tw.canvas.set_turtle(nick)
+ self._tw.canvas.setcolor(x, False)
+
+ def _set_pen_gray_level(self, payload):
+ if len(payload) > 0:
+ [nick, x] = data_from_string(payload)
+ if nick != self._tw.nick:
+ self._tw.canvas.set_turtle(nick)
+ self._tw.canvas.setgray(x, False)
+
+ def _set_pen_shade(self, payload):
+ if len(payload) > 0:
+ [nick, x] = data_from_string(payload)
+ if nick != self._tw.nick:
+ self._tw.canvas.set_turtle(nick)
+ self._tw.canvas.setshade(x, False)
+
+ def _set_pen_width(self, payload):
+ if len(payload) > 0:
+ [nick, x] = data_from_string(payload)
+ if nick != self._tw.nick:
+ self._tw.canvas.set_turtle(nick)
+ self._tw.canvas.setpensize(x, False)
+
+ def _set_pen_state(self, payload):
+ if len(payload) > 0:
+ [nick, x] = data_from_string(payload)
+ if nick != self._tw.nick:
+ self._tw.canvas.set_turtle(nick)
+ self._tw.canvas.setpen(x, False)
+
+ def _fill_polygon(self, payload):
+ # Check to make sure that the poly_point array is passed properly
+ if len(payload) > 0:
+ [nick, poly_points] = data_from_string(payload)
+ shared_poly_points = []
+ for i in range(len(poly_points)):
+ shared_poly_points.append((
+ self._tw.canvas.turtle_to_screen_coordinates(
+ poly_points[i][0], poly_points[i][1])))
+ self._tw.canvas.fill_polygon(shared_poly_points)
+
def _get_dictionary(self):
- d = { self._get_nick(): self._get_colors()}
+ d = {self._get_nick(): self._get_colors()}
return d
def _get_nick(self):
return self._tw.nick
def _get_colors(self):
- if profile:
- colors = profile.get_color().to_string()
+ colors = None
+ if self._tw.running_sugar:
+ if profile.get_color() is not None:
+ colors = profile.get_color().to_string()
else:
colors = self._activity.get_colors()
+ if colors is None:
+ colors = '%s,%s' % (DEFAULT_TURTLE_COLORS[0],
+ DEFAULT_TURTLE_COLORS[1])
return colors
+
class ChatTube(ExportedGObject):
def __init__(self, tube, is_initiator, stack_received_cb):
"""Class for setting up tube for sharing."""
super(ChatTube, self).__init__(tube, PATH)
self.tube = tube
- self.is_initiator = is_initiator # Are we sharing or joining activity?
+ self.is_initiator = is_initiator # Are we sharing or joining activity?
self.stack_received_cb = stack_received_cb
self.stack = ''