776d4741b2cf6a33d6848cb7e0d39fca9e8653b5
[dbuscron] / dbuscron / command.py
1
2 import os
3 from dbuscron.bus import get_dbus_message_type, dbus_to_str
4 from dbuscron.logger import Logger
5 log = Logger(__name__)
6
7 class Command(object):
8     def __init__(self, cmd):
9         self.__value = cmd
10         if self.is_shell_cmd:
11             self.__file = os.environ.get('SHELL', '/bin/sh')
12             self.__args = [self.__file, '-c', self.__value]
13         else:
14             self.__args = cmd.split(' ')
15             self.__file = self.__args[0]
16
17     def __call__(self, bus, message, environ):
18         args_list = message.get_args_list()
19         env = dict()
20         env.update(environ)
21         dbus_env = dict(
22                 (('DBUS_ARG%d' % i, dbus_to_str(a)) for i, a in enumerate(args_list)),
23                 DBUS_ARGN   = str(len(args_list)),
24                 DBUS_SENDER = str(message.get_sender()),
25                 DBUS_DEST   = str(message.get_destination()),
26                 DBUS_IFACE  = str(message.get_interface()),
27                 DBUS_PATH   = str(message.get_path()),
28                 DBUS_MEMBER = str(message.get_member()),
29                 DBUS_BUS    = bus.__class__.__name__.lower()[0:-3],
30                 DBUS_TYPE   = get_dbus_message_type(message)
31                 )
32         env.update(dbus_env)
33         result = os.spawnvpe(os.P_WAIT, self.__file, self.__args, env)
34         if result != 0:
35             log.warn('run', self.__file, self.__args, dbus_env, result)
36         return result
37
38     @property
39     def is_shell_cmd(self):
40         for c in '|><$&;{}':
41             if c in self.__value:
42                 return True
43         return False
44
45     def __str__(self):
46         return self.__value
47
48 class Commands(object):
49     __commands = {}
50     __environ = {}
51
52     def __iter__(self):
53         for m, c in self.__commands.iteritems():
54             yield m, c
55
56     def _get_environ(self):
57         return self.__environ
58
59     def _set_environ(self, value):
60         self.__environ = dict()
61         self.__environ.update(os.environ)
62         self.__environ.update(value)
63
64     environ = property(_get_environ, _set_environ)
65
66     def handler(self, bus, message):
67         for rule, command in self.__commands.iteritems():
68             if rule.match(bus, message):
69                 log.info('matched %s %s' % (rule, command))
70                 command(bus, message, self.__environ)
71                 return
72
73     def add(self, matcher, command):
74         self.__commands[matcher] = command
75