Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/tutorius/TProbe.py
diff options
context:
space:
mode:
Diffstat (limited to 'tutorius/TProbe.py')
-rw-r--r--tutorius/TProbe.py162
1 files changed, 83 insertions, 79 deletions
diff --git a/tutorius/TProbe.py b/tutorius/TProbe.py
index 1521eab..7021f80 100644
--- a/tutorius/TProbe.py
+++ b/tutorius/TProbe.py
@@ -1,10 +1,25 @@
+# Copyright (C) 2009, Tutorius.org
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 1 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
import logging
LOGGER = logging.getLogger("sugar.tutorius.TProbe")
import os
import gobject
-import dbus
import dbus.service
import cPickle as pickle
@@ -12,7 +27,6 @@ import cPickle as pickle
from . import addon
from . import properties
from .services import ObjectStore
-from .properties import TPropContainer
from .dbustools import remote_call, save_args
import copy
@@ -78,8 +92,6 @@ class TProbe(dbus.service.Object):
LOGGER.debug("TProbe :: registering '%s' with unique_id '%s'", self._activity_name, activity.get_id())
self._service_proxy.register_probe(self._activity_name, self._unique_id)
-
-
def start(self):
"""
@@ -184,32 +196,12 @@ class TProbe(dbus.service.Object):
in_signature='s', out_signature='s')
def create_event(self, addon_name):
# avoid recursive imports
- from .creator import WidgetSelector, SignalInputDialog, TextInputDialog
-
event = addon.create(addon_name)
addonname = type(event).__name__
meta = addon.get_addon_meta(addonname)
for propname in meta['mandatory_props']:
prop = getattr(type(event), propname)
- if isinstance(prop, properties.TUAMProperty):
- selector = WidgetSelector(self._activity)
- setattr(event, propname, selector.select())
- elif isinstance(prop, properties.TEventType):
- try:
- dlg = SignalInputDialog(self._activity,
- text="Mandatory property",
- field=propname,
- addr=event.object_id)
- setattr(event, propname, dlg.pop())
- except AttributeError:
- pass
- elif isinstance(prop, properties.TStringProperty):
- dlg = TextInputDialog(self._activity,
- text="Mandatory property",
- field=propname)
- setattr(event, propname, dlg.pop())
- else:
- raise NotImplementedError()
+ prop.widget_class.run_dialog(self._activity, event, propname)
return pickle.dumps(event)
@@ -322,7 +314,6 @@ class ProbeProxy:
self._subscribedEvents = {}
self._registeredCallbacks = {}
-
self._object.connect_to_signal("eventOccured", self._handle_signal, dbus_interface="org.tutorius.ProbeInterface")
def _handle_signal(self, pickled_event):
@@ -344,58 +335,57 @@ class ProbeProxy:
except:
return False
- def __update_action(self, action, address):
+ def __update_action(self, action, callback, address):
LOGGER.debug("ProbeProxy :: Updating action %s with address %s", str(action), str(address))
- self._actions[action] = str(address)
+ self._actions[address] = action
+ callback(address)
- def __clear_action(self, action):
- self._actions.pop(action, None)
+ def __clear_action(self, address):
+ self._actions.pop(address, None)
- def install(self, action, block=False, is_editing=False):
+ def install(self, action, action_installed_cb, error_cb, is_editing=False):
"""
Install an action on the TProbe's activity
@param action Action to install
- @param block Force a synchroneous dbus call if True
+ @param action_installed_cb The callback function to call once the action is installed
+ @param error_cb The callback function to call when an error happens
@param is_editing whether this action comes from the editor
@return None
"""
- return remote_call(self._probe.install,
- (pickle.dumps(action), is_editing),
- save_args(self.__update_action, action),
- block=block)
+ self._probe.install(pickle.dumps(action), is_editing,
+ reply_handler=save_args(self.__update_action, action, action_installed_cb),
+ error_handler=save_args(error_cb, action))
- def update(self, action, newaction, block=False, is_editing=False):
+ def update(self, action_address, newaction, is_editing=False):
"""
Update an already installed action's properties and run it again
- @param action Action to update
+ @param action_address The address of the action to update. This is
+ provided by the install callback method.
@param newaction Action to update it with
@param block Force a synchroneous dbus call if True
@param is_editing whether this action comes from the editor
@return None
"""
#TODO review how to make this work well
- if not action in self._actions.keys():
+ if not action_address in self._actions.keys():
raise RuntimeWarning("Action not installed")
#TODO Check error handling
- return remote_call(self._probe.update,
- (self._actions[action],
- pickle.dumps(newaction._props),
- is_editing),
- block=block)
+ return self._probe.update(action_address, pickle.dumps(newaction._props), is_editing,
+ reply_handler=ignore,
+ error_handler=logError)
- def uninstall(self, action, block=False, is_editing=False):
+ def uninstall(self, action_address, is_editing):
"""
Uninstall an installed action
- @param action Action to uninstall
- @param block Force a synchroneous dbus call if True
+ @param action_address The address of the action to uninstall. This address was given
+ on action installation
@param is_editing whether this action comes from the editor
"""
- if action in self._actions.keys():
- remote_call(self._probe.uninstall,
- (self._actions.pop(action), is_editing),
- block=block)
+ if action_address in self._actions:
+ self._actions.pop(action_address, None)
+ self._probe.uninstall(action_address, is_editing, reply_handler=ignore, error_handler=logError)
- def __update_event(self, event, callback, address):
+ def __update_event(self, event, callback, event_subscribed_cb, address):
LOGGER.debug("ProbeProxy :: Registered event %s with address %s", str(hash(event)), str(address))
# Since multiple callbacks could be associated to the same
# event signature, we will store multiple callbacks
@@ -411,7 +401,7 @@ class ProbeProxy:
# TODO elavoie 2009-07-25 decide on a proper exception
# taxonomy
if self._registeredCallbacks[event].has_key(address):
- # Oups, how come we have two similar addresses?
+ # Oops, how come we have two similar addresses?
# send the bad news!
raise Exception("Probe subscribe exception, the following address already exists: " + str(address))
@@ -424,6 +414,7 @@ class ProbeProxy:
# our dictionary (python pass arguments by reference)
self._subscribedEvents[address] = copy.copy(event)
+ event_subscribed_cb(address)
return address
def __clear_event(self, address):
@@ -453,24 +444,26 @@ class ProbeProxy:
"""
return pickle.loads(str(self._probe.create_event(addon_name)))
- def subscribe(self, event, callback, block=True):
+ def subscribe(self, event, notification_cb, event_subscribed_cb, error_cb):
+
"""
Register an event listener
@param event Event to listen for
- @param callback callable that will be called when the event occurs
- @param block Force a synchroneous dbus call if True (Not allowed yet)
+ @param notification_cb callable that will be called when the event occurs
+ @param event_installed_cb callable that will be called once the event is subscribed to
+ @param error_cb callable that will be called if the subscription fails
@return address identifier used for unsubscribing
"""
LOGGER.debug("ProbeProxy :: Registering event %s", str(hash(event)))
- if not block:
- raise RuntimeError("This function does not allow non-blocking mode yet")
+ #if not block:
+ # raise RuntimeError("This function does not allow non-blocking mode yet")
# TODO elavoie 2009-07-25 When we will allow for patterns both
# for event types and sources, we will need to revise the lookup
# mecanism for which callback function to call
- return remote_call(self._probe.subscribe, (pickle.dumps(event),),
- save_args(self.__update_event, event, callback),
- block=block)
+ self._probe.subscribe(pickle.dumps(event),
+ reply_handler=save_args(self.__update_event, event, notification_cb, event_subscribed_cb),
+ error_handler=save_args(error_cb, event))
def unsubscribe(self, address, block=True):
"""
@@ -481,9 +474,10 @@ class ProbeProxy:
"""
LOGGER.debug("ProbeProxy :: Unregister adress %s issued", str(address))
if address in self._subscribedEvents.keys():
- remote_call(self._probe.unsubscribe, (address,),
- return_cb=save_args(self.__clear_event, address),
- block=block)
+ self.__clear_event(address)
+ self._probe.unsubscribe(address,
+ reply_handler=save_args(self.__clear_event, address),
+ error_handler=logError)
else:
LOGGER.debug("ProbeProxy :: unsubscribe address %s failed : not registered", address)
@@ -493,10 +487,10 @@ class ProbeProxy:
subscribed events should be removed.
"""
for action_addr in self._actions.keys():
- self.uninstall(action_addr, block)
+ self.uninstall(action_addr)
for address in self._subscribedEvents.keys():
- self.unsubscribe(address, block)
+ self.unsubscribe(address)
class ProbeManager(object):
@@ -536,43 +530,48 @@ class ProbeManager(object):
currentActivity = property(fget=getCurrentActivity, fset=setCurrentActivity)
- def install(self, action, block=False, is_editing=False):
+ def install(self, action, action_installed_cb, error_cb, is_editing=False):
"""
Install an action on the current activity
@param action Action to install
+ @param action_installed_cb The callback to call once the action is installed
+ @param error_cb The callback that will be called if there is an error during installation
@param block Force a synchroneous dbus call if True
@param is_editing whether this action comes from the editor
@return None
"""
if self.currentActivity:
- return self._first_proxy(self.currentActivity).install(action, block, is_editing)
+ return self._first_proxy(self.currentActivity).install(
+ action=action,
+ is_editing=is_editing,
+ action_installed_cb=action_installed_cb,
+ error_cb=error_cb)
else:
raise RuntimeWarning("No activity attached")
- def update(self, action, newaction, block=False, is_editing=False):
+ def update(self, action_address, newaction, is_editing=False):
"""
Update an already installed action's properties and run it again
- @param action Action to update
+ @param action_address Action to update
@param newaction Action to update it with
@param block Force a synchroneous dbus call if True
@param is_editing whether this action comes from the editor
@return None
"""
if self.currentActivity:
- return self._first_proxy(self.currentActivity).update(action, newaction, block, is_editing)
+ return self._first_proxy(self.currentActivity).update(action_address, newaction, is_editing)
else:
raise RuntimeWarning("No activity attached")
- def uninstall(self, action, block=False, is_editing=False):
+ def uninstall(self, action_address, is_editing=False):
"""
Uninstall an installed action
- @param action Action to uninstall
+ @param action_address Action to uninstall
@param block Force a synchroneous dbus call if True
@param is_editing whether this action comes from the editor
"""
if self.currentActivity:
- # return self._probes[self.currentActivity].uninstall(action, block, is_editing)
- return self._first_proxy(self.currentActivity).uninstall(action, block, is_editing)
+ return self._first_proxy(self.currentActivity).uninstall(action_address, is_editing)
else:
raise RuntimeWarning("No activity attached")
@@ -585,19 +584,24 @@ class ProbeManager(object):
@returns: an eventfilter instance
"""
if self.currentActivity:
- return self._first_proxy(self.currentActivity).uninstall(action, block)
+ return self._first_proxy(self.currentActivity).create_event(addon_name)
else:
raise RuntimeWarning("No activity attached")
- def subscribe(self, event, callback):
+ def subscribe(self, event, notification_cb, event_subscribed_cb, error_cb):
"""
Register an event listener
@param event Event to listen for
- @param callback callable that will be called when the event occurs
+ @param notification_cb callable that will be called when the event occurs
+ @param subscribe_cb callable that will be called once the action has been
+ installed
+ @param error_cb callable that will be called if an error happens during
+ installation
@return address identifier used for unsubscribing
"""
if self.currentActivity:
- return self._first_proxy(self.currentActivity).subscribe(event, callback)
+ return self._first_proxy(self.currentActivity).subscribe(event, notification_cb,\
+ event_subscribed_cb, error_cb)
else:
raise RuntimeWarning("No activity attached")