Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/services
diff options
context:
space:
mode:
authorDan Williams <dcbw@redhat.com>2007-03-08 17:51:10 (GMT)
committer Dan Williams <dcbw@redhat.com>2007-03-08 17:51:10 (GMT)
commitd46382921adc42d5845cdefd255cb3ca5961eaca (patch)
treea040bf5b3a407eb672b8caaee7293a9c0a797d76 /services
parentafcfdaa2393e0cba1ac22da9fa693e7cd164aff1 (diff)
Convert Activity objects to gobjects and ensure validity before using
Diffstat (limited to 'services')
-rw-r--r--services/presence2/activity.py155
-rw-r--r--services/presence2/buddy.py17
-rw-r--r--services/presence2/presenceservice.py56
3 files changed, 162 insertions, 66 deletions
diff --git a/services/presence2/activity.py b/services/presence2/activity.py
index b79d2b0..656bb18 100644
--- a/services/presence2/activity.py
+++ b/services/presence2/activity.py
@@ -15,33 +15,118 @@
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+import gobject
import dbus, dbus.service
+from sugar import util
from telepathy.interfaces import (CHANNEL_INTERFACE)
_ACTIVITY_PATH = "/org/laptop/Sugar/Presence/Activities/"
_ACTIVITY_INTERFACE = "org.laptop.Sugar.Presence.Activity"
-class Activity(dbus.service.Object):
- def __init__(self, bus_name, object_id, activity_id, tp):
- self._buddies = []
- self._color = None
- self._valid = False
- self._name = None
- self._activity_id = activity_id
- self._type None
+class DBusGObjectMetaclass(gobject.GObjectMeta, dbus.service.InterfaceType): pass
+class DBusGObject(dbus.service.Object, gobject.GObject): __metaclass__ = DBusGObjectMetaclass
+
+
+class Activity(DBusGObject):
+ __gtype_name__ = "Activity"
+
+ __gsignals__ = {
+ 'validity-changed': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
+ ([gobject.TYPE_BOOLEAN]))
+ }
+
+ __gproperties__ = {
+ 'id' : (str, None, None, None,
+ gobject.PARAM_READWRITE | gobject.PARAM_CONSTRUCT_ONLY),
+ 'name' : (str, None, None, None, gobject.PARAM_READWRITE),
+ 'color' : (str, None, None, None, gobject.PARAM_READWRITE),
+ 'type' : (str, None, None, None, gobject.PARAM_READWRITE),
+ 'valid' : (bool, None, None, False, gobject.PARAM_READABLE),
+ 'local' : (bool, None, None, False,
+ gobject.PARAM_READWRITE | gobject.PARAM_CONSTRUCT_ONLY),
+ 'joined' : (bool, None, None, False, gobject.PARAM_READABLE)
+ }
+
+ def __init__(self, bus_name, object_id, tp, **kwargs):
+ if not bus_name:
+ raise ValueError("DBus bus name must be valid")
+ if not object_id or not isinstance(object_id, int):
+ raise ValueError("object id must be a valid number")
+ if not tp:
+ raise ValueError("telepathy CM must be valid")
self._object_id = object_id
- self._object_path = "/org/laptop/Presence/Activities/%d" % self._object_id
-
+ self._object_path = _ACTIVITY_PATH + str(self._object_id)
+ dbus.service.Object.__init__(self, bus_name, self._object_path)
+
+ self._buddies = []
+ self._joined = False
+
# the telepathy client
self._tp = tp
self._activity_text_channel = None
- self._joined = False
-
- dbus.service.Object.__init__(self, bus_name, self._object_path)
-
+ self._valid = False
+ self._id = None
+ self._local = False
+ self._type = None
+
+ if not kwargs.get("id"):
+ raise ValueError("activity id is required")
+ if not util.validate_activity_id(kwargs['id']):
+ raise ValueError("Invalid activity id '%s'" % kwargs['id'])
+
+ gobject.GObject.__init__(self, **kwargs)
+ if self.props.local and not self.props.valid:
+ raise RuntimeError("local activities require color, type, and name")
+
+ def do_get_property(self, pspec):
+ if pspec.name == "id":
+ return self._id
+ elif pspec.name == "name":
+ return self._name
+ elif pspec.name == "color":
+ return self._color
+ elif pspec.name == "type":
+ return self._type
+ elif pspec.name == "valid":
+ return self._valid
+ elif pspec.name == "joined":
+ return self._joined
+ elif pspec.name == "local":
+ return self._local
+
+ def do_set_property(self, pspec, value):
+ if pspec.name == "id":
+ self._id = value
+ elif pspec.name == "name":
+ self._name = value
+ elif pspec.name == "color":
+ self._color = value
+ elif pspec.name == "type":
+ if self._type:
+ raise RuntimeError("activity type is already set")
+ self._type = value
+ elif pspec.name == "joined":
+ self._joined = value
+ elif pspec.name == "local":
+ self._local = value
+
+ self._update_validity()
+
+ def _update_validity(self):
+ try:
+ old_valid = self._valid
+ if self._color and self._name and self._id and self._type:
+ self._valid = True
+ else:
+ self._valid = False
+
+ if old_valid != self._valid:
+ self.emit("validity-changed", self._valid)
+ except AttributeError:
+ self._valid = False
# dbus signals
@dbus.service.signal(_ACTIVITY_INTERFACE,
@@ -63,17 +148,17 @@ class Activity(dbus.service.Object):
@dbus.service.method(_ACTIVITY_INTERFACE,
in_signature="", out_signature="s")
def GetId(self):
- return self.get_id()
+ return self.props.id
@dbus.service.method(_ACTIVITY_INTERFACE,
in_signature="", out_signature="s")
def GetColor(self):
- return self.get_color()
+ return self.props.color
@dbus.service.method(_ACTIVITY_INTERFACE,
in_signature="", out_signature="s")
def GetType(self):
- return self.get_type()
+ return self.props.type
@dbus.service.method(_ACTIVITY_INTERFACE,
in_signature="", out_signature="")
@@ -83,8 +168,10 @@ class Activity(dbus.service.Object):
@dbus.service.method(_ACTIVITY_INTERFACE,
in_signature="", out_signature="ao")
def GetJoinedBuddies(self):
+ ret = []
for buddy in self._buddies:
- ret.append(buddy.object_path())
+ if buddy.props.valid:
+ ret.append(buddy.object_path())
return ret
@dbus.service.method(_ACTIVITY_INTERFACE,
@@ -95,44 +182,34 @@ class Activity(dbus.service.Object):
@dbus.service.method(_ACTIVITY_INTERFACE,
in_signature="", out_signature="s")
def GetName(self):
- return self.get_name()
+ return self.props.name
# methods
def object_path(self):
return dbus.ObjectPath(self._object_path)
- def is_valid(self):
- """An activity is only valid when it's color is available."""
- return self._valid
-
- def get_id(self):
- return self._activity_id
-
- def get_color(self):
- return self._color
-
def get_joined_buddies(self):
- return self._buddies
-
- def get_name(self):
- return self._name
-
- def get_type(self):
- return self._type
+ ret = []
+ for buddy in self._buddies:
+ if buddy.props.valid:
+ ret.append(buddy)
+ return ret
def buddy_joined(self, buddy):
if buddy not in self._buddies:
self._buddies.append(buddy)
- self.BuddyJoined(buddy.object_path())
+ if self.props.valid:
+ self.BuddyJoined(buddy.object_path())
def buddy_left(self, buddy):
if buddy in self._buddies:
self._buddies.remove(buddy)
- self.BuddyLeft(buddy.object_path())
+ if self.props.valid:
+ self.BuddyLeft(buddy.object_path())
def join(self):
if not self._joined:
- self._activity_text_channel = self._tp.join_activity(self._activity_id)
+ self._activity_text_channel = self._tp.join_activity(self.props.id)
self._activity_text_channel[CHANNEL_INTERFACE].connect_to_signal('Closed', self._activity_text_channel_closed_cb)
self._joined = True
diff --git a/services/presence2/buddy.py b/services/presence2/buddy.py
index 458d124..756b308 100644
--- a/services/presence2/buddy.py
+++ b/services/presence2/buddy.py
@@ -73,9 +73,10 @@ class Buddy(DBusGObject):
self._key = None
self._icon = ''
+ if not kwargs.get("key"):
+ raise ValueError("key required")
+
gobject.GObject.__init__(self, **kwargs)
- if not self._key:
- raise RuntimeError("public key required")
def do_get_property(self, pspec):
if pspec.name == "key":
@@ -109,8 +110,6 @@ class Buddy(DBusGObject):
elif pspec.name == "current-activity":
self._current_activity = value
elif pspec.name == "key":
- if self._key:
- raise RuntimeError("key already set")
self._key = value
self._update_validity()
@@ -167,25 +166,25 @@ class Buddy(DBusGObject):
return dbus.ObjectPath(self._object_path)
def add_activity(self, activity):
- actid = activity.get_id()
+ actid = activity.props.id
if self._activities.has_key(actid):
return
self._activities[actid] = activity
- if activity.is_valid():
+ if activity.props.valid:
self.JoinedActivity(activity.object_path())
def remove_activity(self, activity):
- actid = activity.get_id()
+ actid = activity.props.id
if not self._activities.has_key(actid):
return
del self._activities[actid]
- if activity.is_valid():
+ if activity.props.valid:
self.LeftActivity(activity.object_path())
def get_joined_activities(self):
acts = []
for act in self._activities.values():
- if act.is_valid():
+ if act.props.valid:
acts.append(act)
return acts
diff --git a/services/presence2/presenceservice.py b/services/presence2/presenceservice.py
index 4ad780d..2018ec1 100644
--- a/services/presence2/presenceservice.py
+++ b/services/presence2/presenceservice.py
@@ -137,22 +137,35 @@ class PresenceService(dbus.service.Object):
#print "Buddy %s properties updated" % buddy.props.key
def _new_activity(self, activity_id, tp):
- objid = self._get_next_object_id()
- activity = Activity(self._bus_name, objid, activity_id, tp)
- # FIXME : don't do that shit !
- activity._valid = True
+ try:
+ objid = self._get_next_object_id()
+ activity = Activity(self._bus_name, objid, tp, id=activity_id)
+ except Exception, e:
+ print "Invalid activity: %s" % e
+ return None
+
+ activity.connect("validity-changed", self._activity_validity_changed_cb)
+
self._activities[activity_id] = activity
- print "new activity", activity_id
- self.ActivityAppeared(activity.object_path())
+ # FIXME
+ # Use values from the network
+ import random
+ names = ["Tommy", "Susie", "Jill", "Bryan", "Nathan", "Sophia", "Haley", "Jimmy"]
+ name = names[random.randint(0, len(names) - 1)]
+ activity.props.name = "Chat with %s" % name
+ activity.props.type = "org.laptop.Sugar.Chat"
+ from sugar.graphics import xocolor
+ color = xocolor.XoColor().to_string()
+ activity.props.color = color
return activity
def _remove_activity(self, activity):
- print "remove activity", activity.get_id()
+ print "remove activity", activity.props.id
self.ActivityDisappeared(activity.object_path())
- del self._activities[activity.get_id()]
+ del self._activities[activity.props.id]
def _contact_activities_changed(self, tp, contact_handle, activities):
print "------------activities changed-------------"
@@ -168,7 +181,7 @@ class PresenceService(dbus.service.Object):
old_activities = set()
for activity in buddy.get_joined_activities():
- old_activities.add(activity.get_id())
+ old_activities.add(activity.props.id)
new_activities = set(activities)
@@ -177,11 +190,12 @@ class PresenceService(dbus.service.Object):
print "buddy", contact_handle, "joined", act
activity = self._activities.get(act)
if not activity:
- # new activity
+ # new activity, can fail
activity = self._new_activity(act, tp)
- activity.buddy_joined(buddy)
- buddy.add_activity(activity)
+ if activity:
+ activity.buddy_joined(buddy)
+ buddy.add_activity(activity)
activities_left = old_activities - new_activities
for act in activities_left:
@@ -278,18 +292,24 @@ class PresenceService(dbus.service.Object):
def _share_activity(self, actid, atype, name, properties):
objid = self._get_next_object_id()
# FIXME check which tp client we should use to share the activity
- activity = Activity(self._bus_name, objid, actid, self._server_plugin)
- # FIXME : don't do that shit !
- activity._valid = True
+ color = self._owner.props.color
+ activity = Activity(self._bus_name, objid, self._server_plugin,
+ id=actid, type=atype, name=name, color=color, local=True)
+ activity.connect("validity-changed", self._activity_validity_changed_cb)
self._activities[actid] = activity
- # FIXME set the type, name, properties...
- print "new activity", actid
activity.join()
- self.ActivityAppeared(activity.object_path())
return activity
+ def _activity_validity_changed_cb(self, activity, valid):
+ if valid:
+ self.ActivityAppeared(activity.object_path())
+ print "New Activity: %s (%s)" % (activity.props.name, activity.props.id)
+ else:
+ self.ActivityDisappeared(activity.object_path())
+ print "Activity disappeared: %s (%s)" % (activity.props.name, activity.props.id)
+
def main():
loop = gobject.MainLoop()