DirectoryParser() to parse config directories
authorKonstantin Stepanov <kstep@p-nut.info>
Tue, 21 Dec 2010 18:51:47 +0000 (20:51 +0200)
committerKonstantin Stepanov <kstep@p-nut.info>
Tue, 21 Dec 2010 18:51:47 +0000 (20:51 +0200)
dbuscron/parser.py

index 6937e14..f31d3ee 100644 (file)
@@ -1,20 +1,22 @@
 # encoding: utf-8
 from __future__ import with_statement
+import os
 import re
 from dbuscron.bus import DbusBus
 
 def unescape_():
     h = '[0-9A-Fa-f]'
     r = re.compile(r'\\x('+h+r'{2})|\\u('+h+'{4})')
+
     def unescape(value):
-        if not (value and \
-            (r'\x' in value or r'\u' in value)):
+        if not (value and
+                (r'\x' in value or r'\u' in value)):
             return value
 
-        return r.sub(\
-            lambda m: chr(int(m.group(1), 16)) \
-                if m.group(1) is not None else \
-                    unichr(int(m.group(2), 16))\
+        return r.sub(
+            lambda m: chr(int(m.group(1), 16))
+                if m.group(1) is not None else
+                    unichr(int(m.group(2), 16))
                         .encode('utf-8'),\
             value)
     return unescape
@@ -47,7 +49,7 @@ class CrontabParser(object):
     __envvar_sep = re.compile(r'\s*=\s*')
     __fields_chk = {
             'bus_'         : None,
-            'type_'        : ('signal','method_call','method_return','error'),
+            'type_'        : ('signal', 'method_call', 'method_return', 'error'),
             'sender_'      : None,
             'interface_'   : re.compile(r'^[a-zA-Z][a-zA-Z0-9_.]+$'),
             'path_'        : re.compile(r'^/[a-zA-Z0-9_/]+$'),
@@ -75,10 +77,10 @@ class CrontabParser(object):
     def environ(self):
         return self.__environ
 
-    def __iter__(self):
+    def _iterate_file(self, filename):
         # bus type sender interface path member destination args command
         lineno = 0
-        with open(self.__filename) as f:
+        with open(filename) as f:
             for line in f:
                 lineno += 1
                 line = line.strip()
@@ -95,14 +97,14 @@ class CrontabParser(object):
 
                     raise CrontabParserError('Unexpected number of records', lineno)
 
-                rule = [('s','S'), self.__fields_chk['type_'], (None,), (None,), (None,), (None,), (None,), (None,)]
+                rule = [('s', 'S'), self.__fields_chk['type_'], (None,), (None,), (None,), (None,), (None,), (None,)]
 
                 for p in range(0, 8):
                     if parts[p] != '*':
                         rule[p] = parts[p].split(',')
 
                 command = parts[8]
+
                 for r in product(*rule):
                     r = list(r)
                     if r[0] == 'S':
@@ -129,11 +131,44 @@ class CrontabParser(object):
 
                     yield ruled, command
 
+    def __iter__(self):
+        return self._iterate_file(self.__filename)
+
+class DirectoryParser(CrontabParser):
+
+    def __init__(self, dirname, recursive=False):
+        self.__dirname = dirname
+        self.__recursive = recursive
+        super(DirectoryParser, self).__init__(None)
+
+    def _dirwalker_plain(self):
+        for i in os.listdir(self.__dirname):
+            if os.path.isfile(i):
+                yield i
+
+    def _dirwalker_recursive(self):
+        for r, d, f in os.walk(self.__dirname):
+            for i in f:
+                yield i
+
+    def __iter__(self):
+
+        if self.__recursive:
+            dirwalker = self._dirwalker_recursive
+        else:
+            dirwalker = self._dirwalker_plain
+
+        for fname in dirwalker():
+            fullname = os.path.join(self.__dirname, fname)
+            self.__filename = fullname
+            for item in self._iterate_file(fullname):
+                yield item
+
 def OptionsParser(args=None, help=u'', **opts):
 
     from optparse import OptionParser
     import dbuscron
-    parser = OptionParser(usage=help, version="%prog "+dbuscron.__version__)
+    parser = OptionParser(usage=help, version="%prog " + dbuscron.__version__)
     for opt, desc in opts.iteritems():
         names = desc.pop('names')
         desc['dest'] = opt