1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31 import os
32 import sys
33 from threading import Lock
34 from exec_code import exec_code
35 import policies
36 import warn
37
38 import types
40 BooleanType = types.IntType
41 __builtins__['True'] = 1
42 __builtins__['False'] = 0
43
44 try:
45 BooleanType = types.BooleanType
46 True
47 except:
48 warn.warn("An old version of python or jython was detected")
49 _set_booleans()
50
51
52
53
54
55
56
58 """ The pool of objects interface. This class is a basic
59 pool implemented with a dictionary. To create a different
60 pool of objects is necessary to create a class that implement
61 every method in this interface.
62 """
64 """ Init the ServerObjectPool object with a """
65 if objects is None:
66 objects = {}
67 self.objects = objects
68
69 - def setobj(self, name, obj, authobj = None):
70 """ Register an object |obj| with the ID |name| """
71 self.objects[name] = (obj,authobj)
72
74 """ Get an object and its authorization data, it must raise a
75 KeyError exception if |name| is not present in the pool """
76 return self.objects[name]
77
79 """ Remove an object with name |name|"""
80 del self.objects[name]
81
82 - def setsend(self, newid, ret, auth = None):
83 """ Register an object (to send by reference)"""
84 self.setobj(newid, ret, auth)
85 return newid
86
88
90 - def read(self, name):
91 raise KeyError("This method must be overloaded")
92
95
99
100 - def read(self, filename):
101 f = file(filename)
102 d = f.read()
103 f.close()
104 return d
105
107 return os.stat(filename).st_mtime
108
110 - def __init__(self, zipfile, originseparator='/'):
111 self.zipfile = zipfile
112 self.originseparator = originseparator
113
114 - def read(self, filename):
115 filename = filename.replace(os.path.sep, self.originseparator)
116 return self.zipfile.read(filename)
117
119 filename = filename.replace(os.path.sep, self.originseparator)
120 self.zipfile.getinfo(filename)
121 return 0
122
124 """ Register python modules and executes functions in modules.
125 The registration of objects must not be used, instead a list of module's path is given.
126 The registrarion is supported to serve setsend calls. The getobj method reads modules
127 from path. The module is loaded the first time that is requested, next requests uses
128 a cached version of the module. If the module changes in the disk, is reloaded
129 (if checkupdates=True, True by default). Every
130 time that the module is readed it can execute global statments
131
132 """
133 - def __init__(self, path, checkupdates=True, codeloader=None):
134 """ Init the ServerObjectPool object with a """
135 self.path = path
136 self.objects = {}
137 self.cache = {}
138 self.lock = Lock()
139 self.gvars = {}
140 if codeloader is None:
141 codeloader = FileSystemCodeLoader()
142 self.codeloader = codeloader
143 self.checkupdates = checkupdates
144
145 - def setobj(self, name, obj, authobj = None):
146 """ Register an object |obj| with the ID |name| """
147 self.lock.acquire()
148 self.objects[name] = (obj,authobj)
149 self.lock.release()
150
151 - def _import_(self, name, _globals, _locals, fromlist):
152 """
153 Replace function of __import__ to support
154 import modules from the code pool
155 """
156 try:
157 return self.getobj(name)[0]
158
159 except KeyError,e:
160 return __import__(name,_globals,_locals,fromlist)
161
163 """ Reload an SPyRO module or a python module """
164 try:
165 import sys
166 sys.modules[mod.__name__] = self.getobj(mod.__name__)[0]
167 except KeyError:
168 reload(mod)
169
171 """ Get an object and its authorization data, it must raise a
172 KeyError exception if |name| is not present in the pool """
173 if name[0] != '!':
174 try:
175 obj, authobj = self.objects[name]
176 if not obj or self.checkupdates:
177 self.loadmodule(name, authobj)
178 except (KeyError, IndexError), err:
179 authobj = None
180 self.loadmodule(name, authobj)
181 return self.objects[name]
182
184 """ Loads a python's module in the object path (self.path)
185 The authority object is set to the |_spyro_authentication| global
186 variable in the module.
187 If it is not present the |authobj| argument is used instead.
188
189 """
190 if name.startswith('.') or os.path.sep in name:
191 return
192 for p in self.path:
193 filename = os.path.join(p, name + '.py')
194 codeloader = self.codeloader
195 try:
196 mtime = codeloader.getmtime(filename)
197 except:
198 continue
199 try:
200 _filename, _mtime = self.cache[name]
201 if _filename == filename and _mtime == mtime: return
202 except KeyError:
203 pass
204 lvars = ItemCodePool()
205 lvars.__dict__['__builtins__'] = {}
206 lvars.__dict__.update(__builtins__)
207 lvars.__dict__['__builtins__']['__import__'] = self._import_
208 lvars.__dict__['__name__'] = name
209
210
211
212
213 self.setobj(name, lvars, authobj)
214 exec_code(filename, self.gvars, lvars, codeloader.read(filename))
215 self.cache[name] = (filename, mtime)
216 try:
217 auth = lvars._spyro_authentication
218 except AttributeError:
219 if authobj == None:
220 auth = lvars._spyro_authentication = policies.PublicAllowCall()
221 else:
222 auth = authobj
223
224 self.setobj(name, lvars, auth)
225 return lvars
226
228 """ Remove an object with name |name|"""
229 del self.objects[name]
230 try:
231 del self.cache[name]
232 except:
233 pass
234
235 - def setsend(self, newid, ret, auth = None):
236 """ Register an object (to send by reference)"""
237 self.setobj(newid, ret, auth)
238 return newid
239
240
242 """
243 Register python modules as SPyRO objects. The modules must exists in a given path
244 and will be appended to system path (sys.path) if the path is not in the sys.path.
245
246 If the source code changes, the module will be reloaded.
247 The packages can exists in a zip files too, or any other supported python package
248 container, just giving the |statfunction| like os.stat function
249
250 """
251 - def __init__(self, path, checkupdates=True, statfunction=os.stat):
265
267 """ Get an object and its authorization data, it must raise a
268 KeyError exception if |name| is not present in the pool """
269 try:
270 res = ServerObjectPool.getobj(self, name)
271 if res[0] is None:
272 raise KeyError("Fake")
273 else:
274 return res
275 except KeyError, e:
276 try:
277 __import__(name)
278 except ImportError:
279 warn.warn("==================== Import error in ModulePool.getobj %s"%repr(name))
280 raise e
281 except SyntaxError:
282 warn.warn("==================== Syntax error importing a module ModulePool.getobj %s"%repr(name))
283 raise
284 m = sys.modules[name]
285 abspath = os.path.abspath(m.__file__)
286 if self.checkupdates:
287 if abspath[-1] == 'c':
288 abspath = abspath[:-1]
289 try:
290 try:
291 mtime = self.cache[name]
292 newmtime = self.statfunction(abspath).st_mtime
293 if mtime != newmtime:
294 self.cache[name] = newmtime
295 reload(m)
296 except KeyError:
297 self.cache[name] = self.statfunction(abspath).st_mtime
298 except (OSError, IOError),e:
299 raise e
300 for p in self.path:
301 if abspath.startswith(p):
302 try:
303 auth = m._spyro_authentication
304 except AttributeError:
305 auth = m._spyro_authentication = policies.PublicAllowCall()
306 return (m, auth)
307 raise e
308