dbus_client: add --list to list devices
authorHelmut Grohne <helmut@subdivi.de>
Fri, 28 Jun 2013 10:38:37 +0000 (12:38 +0200)
committerHelmut Grohne <helmut@subdivi.de>
Fri, 28 Jun 2013 10:38:37 +0000 (12:38 +0200)
dbus_client.py
onoff/dbusutils.py

index 0ee6b7a..a675eb7 100755 (executable)
@@ -8,6 +8,7 @@ released.
 
 import argparse
 import os
+import xml.parsers.expat
 
 from dbus.mainloop.glib import DBusGMainLoop
 from gi.repository import GObject
@@ -25,6 +26,21 @@ def wait_for_signal(proxy, signal):
     loop.run()
     return state[0]
 
+def parse_introspection(xmlstring):
+    parser = xml.parsers.expat.ParserCreate()
+    nodes = []
+    def start_element(name, attrs):
+        if name != "node":
+            return
+        try:
+            value = attrs["name"]
+        except KeyError:
+            return
+        nodes.append(value)
+    parser.StartElementHandler = start_element
+    parser.Parse(xmlstring)
+    return nodes
+
 def main():
     parser = argparse.ArgumentParser(parents=[onoff.dbusutils.dbus_options])
     parser.add_argument("--duration", type=int, default=10,
@@ -33,10 +49,17 @@ def main():
     parser.add_argument("command", nargs=argparse.REMAINDER,
                         help="a command to be executed with the device being" +
                              "activated for the duration of the execution")
+    parser.add_argument("--list", action="store_true",
+                        help="list available devices and exit")
     args = parser.parse_args()
     DBusGMainLoop(set_as_default=True)
-    proxy = onoff.dbusutils.get_dbus_proxy(args)
-    if args.command:
+    if args.list:
+        bus = onoff.dbusutils.get_dbus(args)
+        proxy = bus.get_object(args.busname, onoff.dbusutils.object_prefix)
+        for elem in parse_introspection(proxy.Introspect()):
+            print(elem)
+    elif args.command:
+        proxy = onoff.dbusutils.get_dbus_proxy(args)
         st, fd = proxy.activatefd()
         fd = fd.take()
         os.dup2(fd, 254)
@@ -47,6 +70,7 @@ def main():
             print("new state is %d" % st)
         os.execvp(args.command[0], args.command)
     else:
+        proxy = onoff.dbusutils.get_dbus_proxy(args)
         st = proxy.activatetime(args.duration)
         if st != ST_ACTIVE:
             print("state is %d waiting for signal" % st)
index 5654c95..9685377 100644 (file)
@@ -18,21 +18,31 @@ dbus_options.add_argument("--bus", default="session",
 dbus_options.add_argument("--busname", type=str, default=default_busname,
                           help="which busname (i.e. client) to use " +
                                "(default: %(default)s)")
-dbus_options.add_argument("--device", type=str, required=True,
+dbus_options.add_argument("--device", type=str,
                           help="which device to control")
 
-def get_dbus_proxy(namespace):
+def get_dbus(namespace):
     """
     @param namespace: a namespace returned from a dbus_options argument parser
-    @returns: a dbus object proxy
+    @rtype: dbus.Bus
+    @returns: the requested bus
     """
     if namespace.bus == "session":
-        bus = dbus.SessionBus()
+        return dbus.SessionBus()
     elif namespace.bus == "system":
-        bus = dbus.SystemBus()
+        return dbus.SystemBus()
     else:
         raise AssertionError("namespace.bus %r is neither session nor system",
                              namespace.bus)
+
+def get_dbus_proxy(namespace):
+    """
+    @param namespace: a namespace returned from a dbus_options argument parser
+    @returns: a dbus object proxy
+    """
+    bus = get_dbus(namespace)
+    if not namespace.device:
+        raise ValueError("no --device given")
     objname = "%s/%s" % (object_prefix, namespace.device)
     return bus.get_object(namespace.busname, objname)