2 from __future__ import with_statement
4 from dbuscron.bus import DbusBus
8 r = re.compile(r'\\x('+h+r'{2})|\\u('+h+'{4})')
11 (r'\x' in value or r'\u' in value)):
15 lambda m: chr(int(m.group(1), 16)) \
16 if m.group(1) is not None else \
17 unichr(int(m.group(2), 16))\
21 unescape = unescape_()
25 head, tail = args[0], args[1:]
27 for t in product(*tail):
33 class CrontabParserError(SyntaxError):
34 def __init__(self, message, lineno, expected=None):
36 if isinstance(expected, (tuple, list)):
37 exp = ' (expected %s or %s)' % (', '.join(expected[:-1]), expected[-1])
41 msg = '%s%s at line %d' % (message, exp, lineno)
43 SyntaxError.__init__(self, msg)
45 class CrontabParser(object):
46 __fields_sep = re.compile(r'\s+')
47 __envvar_sep = re.compile(r'\s*=\s*')
50 'type_' : ('signal','method_call','method_return','error'),
52 'interface_' : re.compile(r'^[a-zA-Z][a-zA-Z0-9_.]+$'),
53 'path_' : re.compile(r'^/[a-zA-Z0-9_/]+$'),
54 'member_' : re.compile(r'^[a-zA-Z][a-zA-Z0-9_]+$'),
55 'destination_' : None,
69 def __init__(self, fname):
70 self.__bus = DbusBus()
71 self.__filename = fname
72 self.__environ = dict()
79 # bus type sender interface path member destination args command
81 with open(self.__filename) as f:
86 if not line or line.startswith('#'):
89 parts = self.__fields_sep.split(line, 8)
91 parts = self.__envvar_sep.split(line, 1)
93 self.__environ[parts[0]] = parts[1]
96 raise CrontabParserError('Unexpected number of records', lineno)
98 rule = [('s','S'), self.__fields_chk['type_'], (None,), (None,), (None,), (None,), (None,), (None,)]
100 for p in range(0, 8):
102 rule[p] = parts[p].split(',')
106 for r in product(*rule):
109 r[0] = self.__bus.system
111 r[0] = self.__bus.session
113 raise CrontabParserError('Unexpected bus value', lineno, expected=('S', 's', '*'))
116 r[7] = map(unescape, r[7].split(';'))
119 for i, f in enumerate(self.__fields):
120 if r[i] is not None and self.__fields_chk[f]:
121 if isinstance(self.__fields_chk[f], tuple):
122 if r[i] not in self.__fields_chk[f]:
123 raise CrontabParserError('Unexpected %s value' % (f.strip('_')), lineno,
124 expected=self.__fields_chk[f])
126 if not self.__fields_chk[f].match(r[i]):
127 raise CrontabParserError('Incorrect %s value' % (f.strip('_')), lineno)
132 def OptionsParser(args=None, help=u'', **opts):
134 from optparse import OptionParser
136 parser = OptionParser(usage=help, version="%prog "+dbuscron.__version__)
137 for opt, desc in opts.iteritems():
138 names = desc.pop('names')
140 parser.add_option(*names, **desc)
142 return parser.parse_args(args)[0]