2 from __future__ import with_statement
4 from dbuscron.bus import DbusBus
8 head, tail = args[0], args[1:]
10 for t in product(*tail):
16 class CrontabParserError(SyntaxError):
17 def __init__(self, message, lineno, expected=None):
19 if isinstance(expected, (tuple, list)):
20 exp = ' (expected %s or %s)' % (', '.join(expected[:-1]), expected[-1])
24 msg = '%s%s at line %d' % (message, exp, lineno)
26 SyntaxError.__init__(self, msg)
28 class CrontabParser(object):
29 __fields_sep = re.compile(r'\s+')
30 __envvar_sep = re.compile(r'\s*=\s*')
33 'type_' : ('signal','method_call','method_return','error'),
35 'interface_' : re.compile(r'^[a-zA-Z][a-zA-Z0-9_.]+$'),
36 'path_' : re.compile(r'^/[a-zA-Z0-9_/]+$'),
37 'member_' : re.compile(r'^[a-zA-Z][a-zA-Z0-9_]+$'),
38 'destination_' : None,
52 def __init__(self, fname):
53 self.__bus = DbusBus()
54 self.__filename = fname
55 self.__environ = dict()
62 # bus type sender interface path member destination args command
64 with open(self.__filename) as f:
69 if not line or line.startswith('#'):
72 parts = self.__fields_sep.split(line, 8)
74 parts = self.__envvar_sep.split(line, 1)
76 self.__environ[parts[0]] = parts[1]
79 raise CrontabParserError('Unexpected number of records', lineno)
81 rule = [('s','S'), self.__fields_chk['type_'], (None,), (None,), (None,), (None,), (None,), (None,)]
85 rule[p] = parts[p].split(',')
89 for r in product(*rule):
92 r[0] = self.__bus.system
94 r[0] = self.__bus.session
96 raise CrontabParserError('Unexpected bus value', lineno, expected=('S', 's', '*'))
99 r[7] = r[7].split(';')
102 for i, f in enumerate(self.__fields):
103 if self.__fields_chk[f]:
104 if isinstance(self.__fields_chk[f], tuple):
105 if r[i] not in self.__fields_chk[f]:
106 raise CrontabParserError('Unexpected %s value' % (f.strip('_')), lineno,
107 expected=self.__fields_chk[f])
109 if not self.__fields_chk[f].match(r[i]):
110 raise CrontabParserError('Incorrect %s value' % (f.strip('_')), lineno)
115 def OptionsParser(args=None, help=u'', **opts):
117 from optparse import OptionParser
119 parser = OptionParser(usage=help, version="%prog "+dbuscron.__version__)
120 for opt, desc in opts.iteritems():
121 names = desc.pop('names')
123 parser.add_option(*names, **desc)
125 return parser.parse_args(args)[0]