[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