1 from __future__ import with_statement
4 from fnmatch import fnmatch
6 from dbuscron.logger import Logger
9 def dbus_to_str(value):
13 elif isinstance(value, dbus.Byte):
14 result = str(int(value))
15 elif isinstance(value, dbus.ByteArray):
16 result = ','.join(str(ord(v)) for v in value)
17 elif isinstance(value, dbus.Array):
18 result = ','.join(dbus_to_str(v) for v in value)
19 elif isinstance(value, dbus.Dictionary):
20 result = ','.join('%s:%s' % (k, dbus_to_str(v)) for k, v in value.iteritems())
21 elif isinstance(value, dbus.String):
22 result = value.encode('utf-8')
27 log.error('convert exception', e)
30 def get_dbus_message_type(message):
31 result = message.__class__.__name__[0:-7]
32 for c in 'ABCDEFGHIJKLMNOPQRSTUVWXYZ':
33 result = result.replace(c, '_'+c.lower())
34 return result.strip('_')
36 class DbusBus(object):
41 def __new__(cls, *args, **kw):
43 cls.__bus = super(DbusBus, cls).__new__(cls)
46 def __init__(self, session_bus_address=None):
47 if session_bus_address:
48 self.set_session_bus_address(session_bus_address)
50 self.get_session_bus_address()
52 from dbus.mainloop.glib import DBusGMainLoop
53 DBusGMainLoop(set_as_default=True)
55 def set_session_bus_address(self, value):
56 os.environ['DBUS_SESSION_BUS_ADDRESS'] = str(value)
58 def get_session_bus_address(self):
60 return os.environ['DBUS_SESSION_BUS_ADDRESS']
62 with open('/tmp/session_bus_address.user', 'rb') as f:
63 session_bus_address = f.readline().strip().split('=', 1).pop().strip("'\"")
64 os.environ['DBUS_SESSION_BUS_ADDRESS'] = session_bus_address
65 log('session bus address aquired', session_bus_address)
66 return session_bus_address
68 session_bus_address = property(get_session_bus_address, set_session_bus_address)
72 if not self.__system_bus:
73 self.__system_bus = dbus.SystemBus()
74 return self.__system_bus
78 if not self.__session_bus:
79 self.__session_bus = dbus.SessionBus()
80 return self.__session_bus
82 def attach_handler(self, handler):
84 self.__system_bus.add_message_filter(handler)
85 if self.__session_bus:
86 self.__session_bus.add_message_filter(handler)
88 from gobject import MainLoop
92 class DbusRule(object):
93 def __init__(self, bus_=None, type_=None, sender_=None, interface_=None, path_=None, member_=None, destination_=None, args_=[]):
96 self._sender = sender_
97 self._interface = interface_
99 self._member = member_
100 self._destination = destination_
106 self._bus.add_match_string(rule)
108 def unregister(self):
111 self._bus.remove_match_string(rule)
118 for key in ['type', 'sender', 'interface', 'path', 'member', 'destination']:
119 value = getattr(self, '_'+key)
120 if value is not None:
121 rule.append("%s='%s'" % (key, value))
124 for i, arg in enumerate(self._args):
125 rule.append("arg%d%s='%s'" % (i, 'path' if arg.startswith('/') else '', arg))
127 return ','.join(rule)
129 def match(self, bus, message):
130 if self._bus not in (None, bus):
133 if self._type is not None:
134 type_ = get_dbus_message_type(message)
135 if self._type != type_:
138 if self._sender not in (None, message.get_sender()):
141 if self._interface not in (None, message.get_interface()):
144 if self._path not in (None, message.get_path()):
147 if self._member not in (None, message.get_member()):
150 if self._destination not in (None, message.get_destination()):
153 if self._args is not None:
154 args_ = message.get_args_list()
155 for i, arg in enumerate(args_):
156 if i >= len(self._args):
159 if self._args[i] not in (None, a):
160 if not fnmatch(a, self._args[i]):