Also check .meta subfolder for metadata
[pyTivo.git] / Cheetah / ImportHooks.py
blob9d50119bd24bc2f2bf809c7e3e408fe7b0cde1f9
1 #!/usr/bin/env python
2 # $Id: ImportHooks.py,v 1.25 2006/06/20 19:23:27 tavis_rudd Exp $
4 """Provides some import hooks to allow Cheetah's .tmpl files to be imported
5 directly like Python .py modules.
7 To use these:
8 import Cheetah.ImportHooks
9 Cheetah.ImportHooks.install()
11 Meta-Data
12 ================================================================================
13 Author: Tavis Rudd <tavis@damnsimple.com>
14 License: This software is released for unlimited distribution under the
15 terms of the MIT license. See the LICENSE file.
16 Version: $Revision: 1.25 $
17 Start Date: 2001/03/30
18 Last Revision Date: $Date: 2006/06/20 19:23:27 $
19 """
20 __author__ = "Tavis Rudd <tavis@damnsimple.com>"
21 __revision__ = "$Revision: 1.25 $"[11:-2]
23 import sys
24 import os.path
25 import types
26 import __builtin__
27 import new
28 import imp
29 from threading import Lock
30 import string
31 import traceback
32 from Cheetah import ImportManager
33 from Cheetah.ImportManager import DirOwner
34 from Cheetah.Compiler import Compiler
35 from Cheetah.convertTmplPathToModuleName import convertTmplPathToModuleName
37 _installed = False
39 ##################################################
40 ## HELPER FUNCS
42 _cacheDir = []
43 def setCacheDir(cacheDir):
44 global _cacheDir
45 _cacheDir.append(cacheDir)
47 ##################################################
48 ## CLASSES
50 class CheetahDirOwner(DirOwner):
51 _lock = Lock()
52 _acquireLock = _lock.acquire
53 _releaseLock = _lock.release
55 templateFileExtensions = ('.tmpl',)
57 def getmod(self, name):
58 try:
59 self._acquireLock()
60 mod = DirOwner.getmod(self, name)
61 if mod:
62 return mod
64 for ext in self.templateFileExtensions:
65 tmplPath = os.path.join(self.path, name + ext)
66 if os.path.exists(tmplPath):
67 try:
68 return self._compile(name, tmplPath)
69 except:
70 # @@TR: log the error
71 exc_txt = traceback.format_exc()
72 exc_txt =' '+(' \n'.join(exc_txt.splitlines()))
73 raise ImportError(
74 'Error while compiling Cheetah module'
75 ' %(name)s, original traceback follows:\n%(exc_txt)s'%locals())
77 return None
79 finally:
80 self._releaseLock()
82 def _compile(self, name, tmplPath):
83 ## @@ consider adding an ImportError raiser here
84 code = str(Compiler(file=tmplPath, moduleName=name,
85 mainClassName=name))
86 if _cacheDir:
87 __file__ = os.path.join(_cacheDir[0],
88 convertTmplPathToModuleName(tmplPath)) + '.py'
89 try:
90 open(__file__, 'w').write(code)
91 except OSError:
92 ## @@ TR: need to add some error code here
93 traceback.print_exc(file=sys.stderr)
94 __file__ = tmplPath
95 else:
96 __file__ = tmplPath
97 co = compile(code+'\n', __file__, 'exec')
99 mod = imp.new_module(name)
100 mod.__file__ = co.co_filename
101 if _cacheDir:
102 mod.__orig_file__ = tmplPath # @@TR: this is used in the WebKit
103 # filemonitoring code
104 mod.__co__ = co
105 return mod
108 ##################################################
109 ## FUNCTIONS
111 def install(templateFileExtensions=('.tmpl',)):
112 """Install the Cheetah Import Hooks"""
114 global _installed
115 if not _installed:
116 CheetahDirOwner.templateFileExtensions = templateFileExtensions
117 import __builtin__
118 if type(__builtin__.__import__) == types.BuiltinFunctionType:
119 global __oldimport__
120 __oldimport__ = __builtin__.__import__
121 ImportManager._globalOwnerTypes.insert(0, CheetahDirOwner)
122 #ImportManager._globalOwnerTypes.append(CheetahDirOwner)
123 global _manager
124 _manager=ImportManager.ImportManager()
125 _manager.setThreaded()
126 _manager.install()
128 def uninstall():
129 """Uninstall the Cheetah Import Hooks"""
130 global _installed
131 if not _installed:
132 import __builtin__
133 if type(__builtin__.__import__) == types.MethodType:
134 __builtin__.__import__ = __oldimport__
135 global _manager
136 del _manager
138 if __name__ == '__main__':
139 install()