[pkg-fso-commits] [SCM] framworkd debian packageing branch, master, updated. milestone2-110-g76700a0
Michael 'Mickey' Lauer
mickey at vanille-media.de
Tue Sep 2 10:34:57 UTC 2008
The following commit has been merged in the master branch:
commit d7bcf13dcdd0b57491c283d697f08c27b6bbc953
Author: Michael 'Mickey' Lauer <mickey at vanille-media.de>
Date: Wed Aug 27 00:34:40 2008 +0200
use introspection to implement org.freesmartphone.framework.ListObjectsByInterface(). Closes FSO #2
NOTE: need to cleanup all references to saving the interface in the controller
diff --git a/framework/introspection.py b/framework/introspection.py
index 0746cba..dca68c0 100644
--- a/framework/introspection.py
+++ b/framework/introspection.py
@@ -27,14 +27,14 @@ from xml.parsers.expat import ExpatError, ParserCreate
from dbus.exceptions import IntrospectionParserException
class _Parser(object):
- __slots__ = ('map',
- 'in_iface',
- 'in_method',
+ __slots__ = ('map',
+ 'in_iface',
+ 'in_method',
'in_signal',
'in_property',
'property_access',
'in_sig',
- 'out_sig',
+ 'out_sig',
'node_level',
'in_signal')
def __init__(self):
@@ -44,7 +44,7 @@ class _Parser(object):
self.in_signal = ''
self.in_property = ''
self.property_access = ''
- self.in_sig = []
+ self.in_sig = []
self.out_sig = []
self.node_level = 0
@@ -107,7 +107,7 @@ class _Parser(object):
self.map['interfaces'][self.in_iface]['methods'][self.in_method] = (self.in_sig, self.out_sig)
self.in_method = ''
- self.in_sig = []
+ self.in_sig = []
self.out_sig = []
elif (self.in_signal and name == 'signal'):
if not self.map['interfaces'].has_key(self.in_iface):
@@ -131,13 +131,13 @@ class _Parser(object):
self.map['interfaces'][self.in_iface]['properties'][self.in_property] = (self.in_sig, self.property_access)
self.in_property = ''
- self.in_sig = []
+ self.in_sig = []
self.out_sig = []
self.property_access = ''
def process_introspection_data(data):
- """Return a structure mapping all of the elements from the introspect data
+ """Return a structure mapping all of the elements from the introspect data
to python types TODO: document this structure
:Parameters:
@@ -148,3 +148,4 @@ def process_introspection_data(data):
return _Parser().parse(data)
except Exception, e:
raise IntrospectionParserException('%s: %s' % (e.__class__, e))
+
diff --git a/framework/objectquery.py b/framework/objectquery.py
index 4dfa679..313fc6c 100644
--- a/framework/objectquery.py
+++ b/framework/objectquery.py
@@ -12,11 +12,14 @@ GPLv2 or later
__version__ = "0.5.1"
+from .introspection import process_introspection_data
from .config import DBUS_INTERFACE_PREFIX
+from framework.patterns import tasklet
import dbus, dbus.service
import os, sys, logging, logging.handlers
+logger = logging # is this ok or do we need a formal logger for this module as well?
loggingmap = { \
"DEBUG": logging.DEBUG,
@@ -50,23 +53,56 @@ class Objects( dbus.service.Object ):
DBUS_INTERFACE_FRAMEWORK = DBUS_INTERFACE_PREFIX + ".Framework"
DBUS_INTERFACE_FRAMEWORK_OBJECTS = DBUS_INTERFACE_PREFIX + ".Objects"
+ InterfaceCache = {}
+
def __init__( self, bus, controller ):
self.interface = self.DBUS_INTERFACE_FRAMEWORK_OBJECTS
self.path = "/org/freesmartphone/Framework"
+ self.bus = bus
dbus.service.Object.__init__( self, bus, self.path )
self.controller = controller
+ def _getInterfaceForObject( self, object, interface ):
+ obj = self.bus.get_object( "org.freesmartphone.frameworkd", object )
+ return dbus.Interface( obj, interface )
+
#
# dbus methods
#
- @dbus.service.method( DBUS_INTERFACE_FRAMEWORK_OBJECTS, "s", "ao" )
- def ListObjectsByInterface( self, interface ):
- if interface == "*":
- return [x for x in self.controller.objects.values()]
- elif interface.endswith( '*' ):
- return [x for x in self.controller.objects.values() if x.interface.startswith( interface[:-1] )]
- else:
- return [x for x in self.controller.objects.values() if x.interface == interface]
+ @dbus.service.method( DBUS_INTERFACE_FRAMEWORK_OBJECTS, "s", "ao",
+ async_callbacks=( "dbus_ok", "dbus_error" ) )
+ def ListObjectsByInterface( self, interface, dbus_ok, dbus_error ):
+
+ def task( self=self, interface=interface, dbus_ok=dbus_ok, dbus_error=dbus_error ):
+ if interface == "*":
+ dbus_ok( self.controller.objects.keys() )
+ else:
+ objects = []
+
+ for object in self.controller.objects:
+ try:
+ interfaces = Objects.InterfaceCache[object]
+ except KeyError:
+ logger.debug( "introspecting object %s..." % object )
+ introspectionData = yield tasklet.WaitDBus( self._getInterfaceForObject( object, "org.freedesktop.DBus.Introspectable" ).Introspect )
+ interfaces = process_introspection_data( introspectionData )["interfaces"]
+ Objects.InterfaceCache[object] = interfaces
+
+ logger.debug( "interfaces for object are %s" % interfaces )
+ for iface in interfaces:
+ if interface.endswith( '*' ):
+ if iface.startswith( interface[:-1] ):
+ objects.append( object )
+ break
+ else:
+ if iface == interface:
+ objects.append( object )
+ break
+
+ logger.debug( "introspection fully done, result is %s" % objects )
+ dbus_ok( objects )
+
+ tasklet.Tasklet( task(), dbus_ok, dbus_error ).start()
@dbus.service.method( DBUS_INTERFACE_FRAMEWORK, "", "as" )
def ListDebugLoggers( self ):
diff --git a/tests/tasklet.py b/tests/tasklet.py
index 34cb074..c27a6f4 100644
--- a/tests/tasklet.py
+++ b/tests/tasklet.py
@@ -23,29 +23,29 @@ import gobject
class Tasklet(object):
""" This class can be used to write easy callback style functions using the 'yield'
python expression.
-
+
It is usefull in some cases where callback functions are the right thing to do,
but make the code too messy
The code is really tricky ! To understand it please refer to python PEP 0342 :
http://www.python.org/dev/peps/pep-0342/
-
+
See the examples below to understand how to use it.
-
-
-
+
+
+
NOTE : This version is a modification of the original version used in tichy
"""
def __init__(self, generator = None, *args, **kargs):
self.generator = generator or self.run(*args, **kargs)
# The tasklet we are waiting for...
self.waiting = None
-
+
def run(self):
yield
-
+
def start(self, callback = None, err_callback = None, *args, **kargs):
"""Start the tasklet, connected to a callback and an error callback
-
+
every next argument will be send to the callback function when called
"""
self.callback = callback or Tasklet.default_callback
@@ -58,17 +58,17 @@ class Tasklet(object):
pass
except Exception, inst:
self.err_callback(*sys.exc_info())
-
+
@staticmethod
def default_callback(value):
"""The default callback if None is specified"""
pass
-
- @staticmethod
+
+ @staticmethod
def default_err_callback(type, value, traceback):
"""The default error call back if None is specified"""
raise type, value, traceback
-
+
def throw(self, type, value, traceback):
"""Throw an exeption into the tasklet generator"""
try:
@@ -87,12 +87,12 @@ class Tasklet(object):
# Otherwise we send the result to the callback function
self.close() # This is very important, cause we need to make sure we free the memory of the callback !
self.callback(value, *self.args, **self.kargs)
-
+
def close(self):
self.generator.close()
if self.waiting:
self.waiting.close()
-
+
def send(self, value = None):
"""Resume and send a value into the tasklet generator
"""
@@ -114,7 +114,7 @@ class Tasklet(object):
# Otherwise we send the result to the callback function
self.close() # This is very important, cause we need to make sure we free the memory of the callback !
self.callback(value, *self.args, **self.kargs)
-
+
class WaitDBusSignal(Tasklet):
"""A special tasklet that wait for a DBUs event to be emited"""
def __init__(self, obj, event, time_out = None):
@@ -123,16 +123,16 @@ class WaitDBusSignal(Tasklet):
self.event = event
self.time_out = time_out
self.connection = None
-
+
def _callback(self, *args):
if not self.connection:
return # We have been closed already
self.connection.remove()
-
+
if len(args) == 1: # What is going on here is that if we have a single value, we return it directly,
args = args[0] # but if we have several value we pack them in a tuple for the callback
# because the callback only accpet a single argument
-
+
try:
self.callback(args)
except:
@@ -141,32 +141,32 @@ class WaitDBusSignal(Tasklet):
self.obj = self.callback = None
return False
-
+
def _err_callback(self):
e = Exception("TimeOut")
self.err_callback(type(e), e, sys.exc_info()[2])
-
- def start(self, callback, err_callback):
+
+ def start(self, callback, err_callback):
self.callback = callback
self.err_callback = err_callback
self.connection = self.obj.connect_to_signal(self.event, self._callback)
if self.time_out:
gobject.timeout_add(self.time_out * 1000, self._err_callback)
-
+
def close(self):
# Note : it is not working very well !!!! Why ? I don't know...
if self.connection:
self.connection.remove()
self.obj = self.callback = self.connection = None
-
+
class WaitFirst(Tasklet):
"""A special tasklet that wait for the first to return of a list of tasklet"""
def __init__(self, *tasklets):
super(WaitFirst, self).__init__()
self.done = None
self.tasklets = tasklets
-
+
def _callback(self, *args):
i = args[-1]
values = args[:-1]
@@ -178,21 +178,21 @@ class WaitFirst(Tasklet):
t.close()
self.callback = None
self.tasklets = None
-
+
def start(self, callback = None, err_callback = None):
self.callback = callback
-
+
# We connect all the tasklets
for (i,t) in enumerate(self.tasklets):
t.start(self._callback, err_callback, i)
-
+
class WaitDBus(Tasklet):
"""Special tasket that wait for a DBus call"""
def __init__(self, method, *args):
super(WaitDBus, self).__init__()
self.method = method
self.args = args
- def start(self, callback, err_callback):
+ def start(self, callback, err_callback):
self.callback = callback
self.err_callback = err_callback
kargs = {'reply_handler':self._callback, 'error_handler':self._err_callback}
@@ -202,13 +202,10 @@ class WaitDBus(Tasklet):
def _err_callback(self, e):
self.err_callback(type(e), e, sys.exc_info()[2])
-
+
if __name__ == '__main__':
# And here is a simple example application using our tasklet class
- import gobject
-
-
class WaitSomething(Tasklet):
""" This is a 'primitive' tasklet that will trigger our call back after a short time
"""
@@ -220,7 +217,7 @@ if __name__ == '__main__':
def close(self):
# We cancel the event
gobject.source_remove(self.event_id)
-
+
def example1():
"""Simple example that wait two times for an input event"""
loop = gobject.MainLoop()
@@ -235,8 +232,8 @@ if __name__ == '__main__':
Tasklet(task1(10)).start()
print 'I do other things'
loop.run()
-
-
+
+
def example2():
"""We can call a tasklet form an other tasklet"""
def task1():
@@ -249,7 +246,7 @@ if __name__ == '__main__':
print "task2 returns"
yield 2 * x # Return value
Tasklet(task1()).start()
-
+
def example3():
"""We can pass exception through tasklets"""
def task1():
@@ -270,9 +267,9 @@ if __name__ == '__main__':
def task4():
print 'task4'
yield 10
-
- Tasklet(task1()).start()
-
+
+ Tasklet(task1()).start()
+
def example4():
"""We can cancel execution of a task before it ends"""
loop = gobject.MainLoop()
@@ -286,7 +283,7 @@ if __name__ == '__main__':
# At this point, we decide to cancel the task
task.close()
print "task canceled"
-
+
def example5():
"""A task can choose to perform specific action if it is canceld"""
loop = gobject.MainLoop()
@@ -296,7 +293,7 @@ if __name__ == '__main__':
yield WaitSomething(1000)
except GeneratorExit:
print "Executed before the task is canceled"
- raise
+ raise
print "task stopped"
loop.quit()
task = Tasklet(task())
@@ -304,7 +301,7 @@ if __name__ == '__main__':
# At this point, we decide to cancel the task
task.close()
print "task canceled"
-
+
def example6():
loop = gobject.MainLoop()
def task1(x):
@@ -313,16 +310,16 @@ if __name__ == '__main__':
loop.quit()
Tasklet(task1(10)).start()
loop.run()
-
+
def test():
"""We can call a tasklet form an other tasklet"""
def task1():
return
import gc
-
+
gc.collect()
n = len(gc.get_objects())
-
+
for i in range(100):
t = Tasklet(task1())
t.start()
@@ -331,10 +328,22 @@ if __name__ == '__main__':
gc.collect()
print len(gc.get_objects()) - n
-#test()
- example1()
- example2()
- example3()
- example4()
- example5()
- example6()
+ def dbustest():
+
+ def task():
+ print "dbus test..."
+ bus = dbus.SystemBus()
+ obj = bus.get_object( "org.freesmartphone.odeviced", "/org/freesmartphone/Device/Info" )
+ interface = dbus.Interface( obj, "org.freesmartphone.Device.Info" )
+ result = yield WaitDBus( interface.GetCpuInfo )
+ print "result=", result
+
+ task = Tasklet( task() )
+ task.start()
+
+ print "testing now"
+ import dbus, dbus.mainloop.glib
+ gobject.idle_add( dbustest )
+ dbus.mainloop.glib.DBusGMainLoop( set_as_default=True )
+ mainloop = gobject.MainLoop()
+ mainloop.run()
diff --git a/tools/cli-framework b/tools/cli-framework
index 6ef0e37..665bec8 100755
--- a/tools/cli-framework
+++ b/tools/cli-framework
@@ -68,6 +68,13 @@ devidle = getInterface( \
"org.freesmartphone.Device.IdleNotifier" \
)
+devpow = getInterface( \
+ bus,
+ "org.freesmartphone.odeviced",
+ "/org/freesmartphone/Device",
+ "org.freesmartphone.Device.PowerManagement" \
+ )
+
# device
gsmdevice = getInterface( bus,
"org.freesmartphone.ogsmd",
--
framworkd debian packageing
More information about the pkg-fso-commits
mailing list