]> andersk Git - sql.git/blame - lib/python/mitsql/interface/cheetah.py
local_is_backup
[sql.git] / lib / python / mitsql / interface / cheetah.py
CommitLineData
e4fd5e1b 1import qwobl
5cb62ba9
JP
2import os, sys, types, time
3import threading
4from pyinotify import WatchManager, Notifier, EventsCodes
5from Cheetah.Template import Template as _Template
e4fd5e1b 6import logging
5cb62ba9
JP
7
8class Template(object):
e4fd5e1b
JP
9 def __init__(self, name='templates', ns={}, path=[]):
10 self._name, self._ns, self._path = name, ns, len(path) and path+[name] or [name]
11 if len(self._path) > 1:
12 assert self._template()
5cb62ba9
JP
13
14 def _template(self):
15 return sys.modules['.'.join(self._path)]
16
17 def __getattr__(self, name):
18 return Template(name, self._ns, self._path)
19
20 def __call__(self, **kw):
21 namespaces = self._ns.copy()
22 namespaces.update(kw)
23 return getattr(self._template(),
24 self._name)(namespaces=namespaces).respond()
25
e4fd5e1b 26class Loader(object):
5cb62ba9
JP
27 _mask = EventsCodes.ALL_FLAGS['IN_CREATE'] \
28 | EventsCodes.ALL_FLAGS['IN_MODIFY'] \
29 | EventsCodes.ALL_FLAGS['IN_DELETE'] \
30 | EventsCodes.ALL_FLAGS['IN_ATTRIB']
31 _watch_manager = None
32 _notifier = None
33 _thread = None
34
35 _loaded = False
36 _files = {}
37 _modules = {}
38
e4fd5e1b 39 def __init__(self, global_namespace={}):
5cb62ba9 40 self._event_init()
e4fd5e1b 41 self._assert_module('templates')
5cb62ba9 42 self._globals = global_namespace
5cb62ba9
JP
43 self._thread = threading.Thread(target=self.loop)
44 self._thread.setDaemon(True)
45 self._thread.start()
46
47 def _tree_walk(self, tree, path, func):
48 path = list(path)
49 if len(path) > 1:
50 x = path.pop(0)
51 if not x in tree:
52 tree[x] = {}
53 return self._tree_walk(tree[x], path, func)
54 elif callable(func):
55 return func(tree, path[0])
56
57 def _tree_add(self, tree, path, value):
58 def _add(tree, key):
59 tree[key] = value
60 return value
61 print self._tree_walk(tree, path, _add)
62
63 def _assert_module(self, name, path=None):
64 if not name in self._modules:
65 self._modules[name] = types.ModuleType(name)
66 if path:
67 self._modules[name].__path__ = path
68 sys.modules[name] = self._modules[name]
69
e4fd5e1b
JP
70 def _get_template_path(self, path_name, template_file):
71 r = template_file.startswith(path_name) \
72 and template_file[len(path_name)+1:].split(os.path.sep) or []
5cb62ba9
JP
73 if r[-1].endswith('.tmpl'):
74 r[-1] = r[-1][:-5]
75 return tuple(r)
76
77 def _compile(self, template_path):
78 template = _Template.compile(file=self._files[template_path],
79 returnAClass=False,
80 moduleName='.'.join(['templates']+list(template_path)),
81 className=template_path[-1],
82 useCache=False,
83 compilerSettings={'useStackFrames':False})
84 return template
85
e4fd5e1b
JP
86 def add(self, path_name, template_file):
87 template_path = self._get_template_path(path_name, template_file)
5cb62ba9
JP
88 template_name = '.'.join(['templates']+list(template_path))
89 template_pkg = '.'.join(['templates']+list(template_path[:-1]))
90 template_py = os.path.join(os.path.dirname(template_file), '%s.py' % template_path[-1])
91 self._assert_module(template_pkg, [os.path.dirname(template_file)])
92 self._files[template_path] = template_file
93 code = self._compile(template_path)
94 f_code = file(template_py, 'w')
95 f_code.write(code)
96 f_code.close()
e4fd5e1b 97 if template_name in sys.modules:
5cb62ba9
JP
98 reload(sys.modules[template_name])
99
100 def remove(self, template_file):
101 #print 'removing', template_file
102 pass
103
e4fd5e1b
JP
104 def _walk_path(self, path_name):
105 def _walk_load(args, dname, fnames):
106 for fname in fnames:
107 if fname.endswith('.tmpl'):
108 template_file = os.path.join(dname, fname)
109 self.add(path_name, template_file)
110 return _walk_load
111
112 def load(self, path_name):
113 os.path.walk(path_name, self._walk_path(path_name), None)
114 for path, filename in self._files.items():
115 logging.debug('TEMPLATE LOAD [%s] %s', path, filename)
116 __import__('.'.join(['templates']+list(path)))
117 self._event_add_watch(path_name)
118
119 def _path_event_handler(self, path_name):
120 def _event_handler(event):
121 logging.debug('TEMPLATE EVENT: %s', repr(event.__dict__.items()))
122 if event.name.endswith('.tmpl') and not event.name.startswith('.'):
123 if event.maskname == 'IN_DELETE':
124 self.remove(event.pathname)
125 else:
126 time.sleep(0.5)
127 self.add(path_name, event.pathname)
128 return _event_handler
5cb62ba9
JP
129
130 def _event_init(self):
131 self._watch_manager = WatchManager()
5cb62ba9
JP
132 self._notifier = Notifier(self._watch_manager)
133
e4fd5e1b
JP
134 def _event_add_watch(self, path_name):
135 r = self._watch_manager.add_watch(path_name,
136 self._mask,
137 self._path_event_handler(path_name),
138 rec=True,
139 auto_add=True)
140
5cb62ba9 141 def loop(self):
5cb62ba9
JP
142 while True:
143 try:
144 self._notifier.process_events()
145 if self._notifier.check_events():
146 self._notifier.read_events()
147 except KeyboardInterrupt:
148 self._notifier.stop()
149 break
e4fd5e1b
JP
150
151_loader = Loader()
152load = _loader.load
153templates = Template()
154
155__all__ = ['load', 'templates']
5cb62ba9
JP
156
157if __name__ == '__main__':
e4fd5e1b 158 t = Loader('/home/joe/templates')
This page took 0.148948 seconds and 5 git commands to generate.