+# encoding: utf-8
import os
-from dbuscron.bus import get_dbus_message_type
+from dbuscron.bus import get_dbus_message_type, dbus_to_str
+from dbuscron.logger import Logger
+log = Logger(__name__)
class Command(object):
def __init__(self, cmd):
else:
self.__args = cmd.split(' ')
self.__file = self.__args[0]
+ if len(self.__args) == 1 \
+ and self.__file.startswith('!'):
+ self.__file = self.__file.lstrip('!')
+ self.__auto_args = True
+ else:
+ self.__auto_args = False
def __call__(self, bus, message, environ):
- args_list = message.get_args_list()
+ args_list = map(dbus_to_str, message.get_args_list())
env = dict()
env.update(environ)
- env.update(dict(
- (('DBUS_ARG%d' % i, str(args_list[i])) for i in range(0, len(args_list))),
- DBUS_ARGN = str(len(args_list)),
- DBUS_SENDER = str(message.get_sender()),
- DBUS_DEST = str(message.get_destination()),
- DBUS_IFACE = str(message.get_interface()),
- DBUS_PATH = str(message.get_path()),
- DBUS_MEMBER = str(message.get_member()),
- DBUS_BUS = bus.__class__.__name__.lower()[0:-3],
- DBUS_TYPE = get_dbus_message_type(message)
- ))
- result = os.spawnvpe(os.P_WAIT, self.__file, self.__args, env)
+ try:
+ dbus_env = dict(
+ (('DBUS_ARG%d' % i, a) for i, a in enumerate(args_list)),
+ DBUS_ARGN = str(len(args_list)),
+ DBUS_SENDER = str(message.get_sender() or ''),
+ DBUS_DEST = str(message.get_destination() or ''),
+ DBUS_IFACE = str(message.get_interface() or ''),
+ DBUS_PATH = str(message.get_path() or ''),
+ DBUS_MEMBER = str(message.get_member() or ''),
+ DBUS_BUS = bus.__class__.__name__.lower()[0:-3],
+ DBUS_ERROR = str(message.get_error_name() or ''),
+ DBUS_TYPE = get_dbus_message_type(message)
+ )
+ env.update(dbus_env)
+ except Exception, e:
+ log.error('environ exception', e)
+ raise e
+
+ if self.__auto_args:
+ if dbus_env['DBUS_TYPE'] in ('signal', 'method_call'):
+ args_list[0:0] = [
+ dbus_env['DBUS_IFACE'],
+ dbus_env['DBUS_MEMBER']]
+ elif dbus_env['DBUS_TYPE'] == 'error':
+ args_list.insert(0, dbus_env['DBUS_ERROR'])
+
+ args_list[0:0] = [
+ self.__file,
+ dbus_env['DBUS_SENDER'],
+ dbus_env['DBUS_DEST']]
+ else:
+ args_list = self.__args
+
+ result = os.spawnvpe(os.P_WAIT, self.__file, args_list, env)
+ if result != 0:
+ log.warn('command returned non-zero status', self.__file, args_list, dbus_env, result)
return result
@property
__commands = {}
__environ = {}
+ def __iter__(self):
+ for m, c in self.__commands.iteritems():
+ yield m, c
+
def _get_environ(self):
return self.__environ
def handler(self, bus, message):
for rule, command in self.__commands.iteritems():
if rule.match(bus, message):
+ log('rule matched', rule, command)
command(bus, message, self.__environ)
return
def add(self, matcher, command):
self.__commands[matcher] = command
+ def clear(self):
+ self.__commands = {}
+