-# Joe Presbrey <presbrey@mit.edu>
-
+import qwobl
import os, sys, types, time
import threading
from pyinotify import WatchManager, Notifier, EventsCodes
from Cheetah.Template import Template as _Template
-
-__all__ = ['Templates']
+import logging
class Template(object):
- def __init__(self, name, ns={}, path=['templates']):
- self._name, self._ns, self._path = name, ns, path+[name]
- assert self._template()
+ def __init__(self, name='templates', ns={}, path=[]):
+ self._name, self._ns, self._path = name, ns, len(path) and path+[name] or [name]
+ if len(self._path) > 1:
+ assert self._template()
def _template(self):
return sys.modules['.'.join(self._path)]
return getattr(self._template(),
self._name)(namespaces=namespaces).respond()
-class Templates(object):
- _base = ''
+class Loader(object):
_mask = EventsCodes.ALL_FLAGS['IN_CREATE'] \
| EventsCodes.ALL_FLAGS['IN_MODIFY'] \
| EventsCodes.ALL_FLAGS['IN_DELETE'] \
_files = {}
_modules = {}
- def __init__(self, template_path, global_namespace={}):
- self._base = os.path.abspath(template_path)
+ def __init__(self, global_namespace={}):
self._event_init()
- self._assert_module('templates', [template_path])
+ self._assert_module('templates')
self._globals = global_namespace
- self.load()
self._thread = threading.Thread(target=self.loop)
self._thread.setDaemon(True)
self._thread.start()
self._modules[name].__path__ = path
sys.modules[name] = self._modules[name]
- def _get_template_path(self, template_file):
- r = template_file.startswith(self._base) \
- and template_file[len(self._base)+1:].split(os.path.sep) or []
+ def _get_template_path(self, path_name, template_file):
+ r = template_file.startswith(path_name) \
+ and template_file[len(path_name)+1:].split(os.path.sep) or []
if r[-1].endswith('.tmpl'):
r[-1] = r[-1][:-5]
return tuple(r)
compilerSettings={'useStackFrames':False})
return template
- def add(self, template_file):
- template_path = self._get_template_path(template_file)
+ def add(self, path_name, template_file):
+ template_path = self._get_template_path(path_name, template_file)
template_name = '.'.join(['templates']+list(template_path))
template_pkg = '.'.join(['templates']+list(template_path[:-1]))
template_py = os.path.join(os.path.dirname(template_file), '%s.py' % template_path[-1])
f_code = file(template_py, 'w')
f_code.write(code)
f_code.close()
- if self._loaded and \
- template_name in sys.modules:
+ if template_name in sys.modules:
reload(sys.modules[template_name])
def remove(self, template_file):
#print 'removing', template_file
pass
- def _walk_load(self, args, dname, fnames):
- for fname in fnames:
- if fname.endswith('.tmpl'):
- template_file = os.path.join(dname, fname)
- self.add(template_file)
-
- def load(self):
- if not self._loaded:
- os.path.walk(self._base, self._walk_load, None)
- for path, filename in self._files.items():
- __import__('.'.join(['templates']+list(path)))
- self._loaded = True
-
- def _event_handler(self, event):
- if event.name.endswith('.tmpl') and not event.name.startswith('.'):
- if event.maskname == 'IN_DELETE':
- self.remove(event.pathname)
- else:
- time.sleep(0.5)
- self.add(event.pathname)
-
+ def _walk_path(self, path_name):
+ def _walk_load(args, dname, fnames):
+ for fname in fnames:
+ if fname.endswith('.tmpl'):
+ template_file = os.path.join(dname, fname)
+ self.add(path_name, template_file)
+ return _walk_load
+
+ def load(self, path_name):
+ os.path.walk(path_name, self._walk_path(path_name), None)
+ for path, filename in self._files.items():
+ logging.debug('TEMPLATE LOAD [%s] %s', path, filename)
+ __import__('.'.join(['templates']+list(path)))
+ self._event_add_watch(path_name)
+
+ def _path_event_handler(self, path_name):
+ def _event_handler(event):
+ logging.debug('TEMPLATE EVENT: %s', repr(event.__dict__.items()))
+ if event.name.endswith('.tmpl') and not event.name.startswith('.'):
+ if event.maskname == 'IN_DELETE':
+ self.remove(event.pathname)
+ else:
+ time.sleep(0.5)
+ self.add(path_name, event.pathname)
+ return _event_handler
def _event_init(self):
self._watch_manager = WatchManager()
- self._watch_manager.add_watch(self._base,
- self._mask,
- self._event_handler,
- rec=True,
- auto_add=True)
self._notifier = Notifier(self._watch_manager)
+ def _event_add_watch(self, path_name):
+ r = self._watch_manager.add_watch(path_name,
+ self._mask,
+ self._path_event_handler(path_name),
+ rec=True,
+ auto_add=True)
+
def loop(self):
- self.load()
while True:
try:
self._notifier.process_events()
except KeyboardInterrupt:
self._notifier.stop()
break
-
- def __getattr__(self, key):
- return Template(key, self._globals)
+
+_loader = Loader()
+load = _loader.load
+templates = Template()
+
+__all__ = ['load', 'templates']
if __name__ == '__main__':
- t = Templates('/home/joe/templates')
+ t = Loader('/home/joe/templates')