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