OptionsParser & Logger is importable from dbuscron
[dbuscron] / dbuscron / bus.py
1
2 import dbus
3
4 def dbus_to_str(value):
5     if isinstance(value, dbus.Byte):
6         return str(int(value))
7     elif isinstance(value, dbus.ByteArray):
8         return ','.join(str(ord(v)) for v in value)
9     elif isinstance(value, dbus.Array):
10         return ','.join(str(v) for v in value)
11     elif isinstance(value, dbus.Dictionary):
12         return ','.join('%s:%s' % (k, v) for k, v in value.iteritems())
13     else:
14         return str(value)
15
16 def get_dbus_message_type(message):
17     result = message.__class__.__name__[0:-7]
18     for c in 'ABCDEFGHIJKLMNOPQRSTUVWXYZ':
19         result = result.replace(c, '_'+c.lower())
20     return result.strip('_')
21
22 class DbusBus(object):
23     __bus = None
24     __system_bus = None
25     __session_bus = None
26
27     def __new__(cls):
28         if not cls.__bus:
29             cls.__bus = super(DbusBus, cls).__new__(cls)
30         return cls.__bus
31
32     def __init__(self):
33         from dbus.mainloop.glib import DBusGMainLoop
34         DBusGMainLoop(set_as_default=True)
35
36     @property
37     def system(self):
38         if not self.__system_bus:
39             self.__system_bus = dbus.SystemBus()
40         return self.__system_bus
41
42     @property
43     def session(self):
44         if not self.__session_bus:
45             self.__session_bus = dbus.SessionBus()
46         return self.__session_bus
47
48     def attach_handler(self, handler):
49         if self.__system_bus:
50             self.__system_bus.add_message_filter(handler)
51         if self.__session_bus:
52             self.__session_bus.add_message_filter(handler)
53     def listen(self):
54         from gobject import MainLoop
55         loop = MainLoop()
56         loop.run()
57
58 class DbusRule(object):
59     def __init__(self, bus_=None, type_=None, sender_=None, interface_=None, path_=None, member_=None, destination_=None, args_=[]):
60         self._bus         = bus_
61         self._type        = type_
62         self._sender      = sender_
63         self._interface   = interface_
64         self._path        = path_
65         self._member      = member_
66         self._destination = destination_
67         self._args        = args_
68
69     def register(self):
70         rule = str(self)
71         if rule:
72             self._bus.add_match_string(str(self))
73
74     def __str__(self):
75         rule = []
76         for key in ['type', 'sender', 'interface', 'path', 'member', 'destination']:
77             value = getattr(self, '_'+key)
78             if value is not None:
79                 rule.append("%s='%s'" % (key, value))
80
81         if self._args:
82             for i, arg in enumerate(self._args):
83                 rule.append("arg%d%s='%s'" % (i, 'path' if arg.startswith('/') else '', arg))
84
85         return ','.join(rule)
86
87     def match(self, bus, message):
88
89         if self._bus not in (None, bus):
90             return False
91
92         if self._type is not None:
93             type_ = get_dbus_message_type(message)
94             if self._type != type_:
95                 return False
96
97         if self._sender not in (None, message.get_sender()):
98             return False
99
100         if self._interface not in (None, message.get_interface()):
101             return False
102
103         if self._path not in (None, message.get_path()):
104             return False
105
106         if self._member not in (None, message.get_member()):
107             return False
108
109         if self._destination not in (None, message.get_destination()):
110             return False
111
112         if self._args is not None:
113             args_ = message.get_args_list()
114             for i, arg in enumerate(args_):
115                 if i >= len(self._args):
116                     break
117                 if self._args[i] not in (None, str(arg)):
118                     return False
119
120         return True
121