c48df51cac3813c5b898cc097a682c765d53a2b6
[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         log.info('run %s %s %s %s' % (self.__file, self.__args, dbus_env, result))
35         return result
36
37     @property
38     def is_shell_cmd(self):
39         for c in '|><$&;{}':
40             if c in self.__value:
41                 return True
42         return False
43
44     def __str__(self):
45         return self.__value
46
47 class Commands(object):
48     __commands = {}
49     __environ = {}
50
51     def _get_environ(self):
52         return self.__environ
53
54     def _set_environ(self, value):
55         self.__environ = dict()
56         self.__environ.update(os.environ)
57         self.__environ.update(value)
58
59     environ = property(_get_environ, _set_environ)
60
61     def handler(self, bus, message):
62         for rule, command in self.__commands.iteritems():
63             if rule.match(bus, message):
64                 log.info('matched %s %s' % (rule, command))
65                 command(bus, message, self.__environ)
66                 return
67
68     def add(self, matcher, command):
69         self.__commands[matcher] = command
70