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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145 import sys, os
146 from string import split, join
147 from types import StringType
148 import re
149
150
151 from Acquisition import Implicit, Explicit, Acquired
152 from Persistence import Persistent
153 from AccessControl.Role import RoleManager
154 from AccessControl import ClassSecurityInfo
155 from OFS.SimpleItem import Item
156 from OFS import History
157 from Globals import MessageDialog, DevelopmentMode
158 from Products.PageTemplates.PageTemplateFile import PageTemplateFile
159 from App.Management import Navigation
160 from OFS.Cache import Cacheable
161
162
163 import orm
164 from orm.adapters.pgsql.datasource import zpsycopg_db_conn
165 import orm.debug
166
167 if DevelopmentMode:
168 orm.debug.debug.verbose = True
169 orm.debug.sqllog.verbose = True
170
174
176 """
177 This is a port of the cgiutils header class to the Zope adapter.
178 You might not want to use it from within Zope, only if you'd like
179 to use you modes module with both Zope and cgiutils.
180 """
182 self.response = response
183
185 self.response.setHeader(field, value)
186
188 self.response.setHeader(field, value)
189
190
192 extra = []
193 for param, value in parameters.items():
194 value = url_quote(value)
195 extra.append("%s=%s" % (param, value,) )
196
197 extra = join(extra, "&")
198 if extra != "": extra = "?" + extra
199
200 content = "0; url=%s%s" % (url, extra, )
201
202 self.set("refresh", content)
203
204
205 unwanted_request_keys = {
206 'AUTHENTICATION_PATH' : 0, 'BASE1' : 0, 'BASE2' : 0, 'BASE3' : 0,
207 'BASE4' : 0, 'GATEWAY_INTERFACE' : 0,
208 'HTTP_PRAGMA' : 0, 'PARENTS' : 0,
209 'PATH_INFO' : 0, 'PATH_TRANSLATED' : 0, 'PUBLISHED' : 0,
210 'RESPONSE' : 0, 'SCRIPT_NAME' : 0,
211 'SERVER_NAME' : 0, 'SERVER_PORT' : 0, 'SERVER_PROTOCOL' : 0,
212 'SERVER_SOFTWARE' : 0, 'SERVER_URL' : 0, 'SESSION' : 0,
213 'TraversalRequestNameStack' : 0, 'URL' : 0, 'URL1' : 0, 'URL2' : 0,
214 'URL3':0 }
215
216 charset_re=re.compile(r'text/[0-9a-z]+\s*;\s*charset=([-_0-9a-z]+' +
217 r')(?:(?:\s*;)|\Z)', re.IGNORECASE)
218
219 -def manage_addORMMode(self, id, module_name, mode_function_name,
220 db_connection_name, db_charset,
221 session_on=False,
222 path_variables_on=False, path_variables="",
223 REQUEST=None):
249
250 manage_addORMModeForm = PageTemplateFile("www/ORMMode.pt", globals())
251
252 -class ORMMode(Explicit, Item, Persistent, RoleManager, Navigation, Cacheable):
253 """
254 This object type allows you to call ORM 'mode' functions from within
255 your Zope application.
256 """
257
258 meta_type = "ORM Mode"
259 manage_main = PageTemplateFile("www/ORMMode.pt", globals())
260
261 manage_options = (
262 (
263 {"label": "Edit", "action": "manage_main"},
264 {"label": "Test", "action": "test"},
265 {"label": "Security", "action": "manage_access"}
266 ) + Item.manage_options + Cacheable.manage_options )
267
268
269 __ac_permissions__ = (
270 ('View management screens', ('manage_main',)),
271 ('Change External Methods', ('manage_edit',)),
272 ('Call ORM mode function', ('__call__','index_html')),
273 )
274
275 ZopeTime=Acquired
276 HelpSys=Acquired
277
278 security = ClassSecurityInfo()
279
280 - def __init__(self, id, module_name, mode_function_name,
281 db_connection_name, db_charset, session_on,
282 path_variables_on, path_variables,
283 REQUEST=None):
289
290 - def manage_edit(self, module_name, mode_function_name,
291 db_connection_name, db_charset, session_on=False,
292 path_variables_on=False, path_variables="",
293 REQUEST=None):
294 """
295 Modify the ORMMode object.
296 """
297
298 if getattr(self, "_module_name",
299 None) != module_name:
300 self._module_name = module_name
301 self._v_module = None
302 self.module()
303
304 if getattr(self, "_mode_function_name",
305 None) != mode_function_name:
306 self._mode_function_name = mode_function_name
307 self._v_mode_functions = {}
308 self.mode_function()
309
310 self._db_connection_name = db_connection_name
311 self._db_charset = db_charset
312
313 self._session_on = session_on
314
315 self._path_variables_on = path_variables_on
316 self._path_variables = split(path_variables, "/")
317
318 self.ZCacheable_invalidate()
319
320 if REQUEST is not None:
321 message="ORM Mode updated."
322 return self.manage_main(self, REQUEST, manage_tabs_message=message)
323
324
326 """
327 Call the mode function and do cache management.
328 """
329 result = self.ZCacheable_get(default=None)
330
331 if result is None:
332 data = self.om_exec(*args, **kw)
333 mime_type = self.REQUEST.RESPONSE.headers.get(
334 "content-type", "text/plain")
335 self.ZCacheable_set(data=(data, mime_type))
336 else:
337 data, mime_type = result
338 self.REQUEST.RESPONSE.setHeader("Content-Type", mime_type)
339
340 return data
341
342
344 formdata = kw
345
346
347
348
349
350
351
352
353
354
355
356 encoding = sys.getdefaultencoding()
357
358
359 if self.REQUEST.RESPONSE.headers.has_key('content-type'):
360 match = charset_re.match(
361 self.REQUEST.RESPONSE.headers['content-type'])
362 if match:
363 encoding = match.group(1)
364
365
366
367
368 for key in self.REQUEST.keys():
369 if unwanted_request_keys.has_key(key):
370 continue
371 else:
372 value = self.REQUEST[key]
373
374
375
376 if type(value) == StringType:
377 try:
378 value = unicode(value, encoding)
379 except UnicodeDecodeError:
380 pass
381
382 formdata[key] = value
383
384
385 ds = self._ds()
386
387
388 formdata["ds"] = ds
389 formdata["base_url"] = self.absolute_url()
390 formdata["request"] = self.REQUEST
391 formdata["response"] = self.REQUEST.RESPONSE
392 formdata["REQUEST"] = self.REQUEST
393 formdata["RESPONSE"] = self.REQUEST.RESPONSE
394 formdata["context"] = self.aq_parent
395 formdata["header"] = _header(self.REQUEST.RESPONSE)
396 formdata["form"] = formdata.copy()
397 formdata["formdata"] = formdata["form"]
398
399 if self.session_on():
400 formdata["session"] = self.REQUEST.SESSION
401
402
403
404
405
406 mode = formdata.get("mode", self.mode_function_name())
407
408 function = self.mode_function(mode)
409
410 ret = function(*args, **formdata)
411
412
413
414 if ds is not None:
415 ds.rollback()
416
417 return ret
418
420 """
421 Return True if this adapter provied the mode functions with a
422 session object
423 """
424 return self._session_on
425
427 """
428 Accessor.
429 """
430
431
432 return getattr(self, "_path_variables_on", False)
433
435 """
436 Accessor.
437 """
438
439
440 return join(getattr(self, "_path_variables", []), "/")
441
443 """
444 Accessor. Return the name of the Python module where the
445 mode function resides.
446 """
447 return self._module_name
448
450 """
451 Accessor. Return the name of the mode function.
452 """
453 return self._mode_function_name
454
456 """
457 Return the name of the databse connection used for this
458 mode.
459 """
460 return self._db_connection_name
461
463 """
464 Accessor.
465 """
466 return self._db_charset
467
469 """
470 Return an ORM datasource object or None if self._db_connection_name
471 is not set.
472 """
473 if self._db_connection_name:
474
475
476
477
478
479 ds = zpsycopg_db_conn(self.aq_parent,
480 self.db_connection_name(),
481 self.db_charset())
482 return ds
483 else:
484 return None
485
487 """
488 Return the module object of the modes module
489 """
490 module = getattr(self, "_v_module", None)
491 if module is None:
492 name = self.module_name()
493 try:
494 module = __import__(name, globals(), locals(),
495 split(name, ".")[1:])
496
497
498
499 if DevelopmentMode:
500 self._v_module_mtime = self._module_mtime(module)
501
502 except ImportError, e:
503 msg = "Error importing module %s: %s" % (name, str(e))
504 raise NoSuchModule(msg)
505
506 self._v_module = module
507 else:
508
509
510 if DevelopmentMode:
511
512
513
514 if self._v_module_mtime != self._module_mtime(self._v_module):
515 print >> sys.stderr, "reloading ", self._v_module
516 reload(self._v_module)
517 self._v_module_mtime = self._module_mtime(self._v_module)
518 self._v_mode_functions = {}
519
520
521
522
523
524
525
526
527 reload_function = getattr(self._v_module, "__reload__",
528 None)
529 if reload_function is not None:
530 reload_function()
531
532
533 return self._v_module
534
536 """
537 Return the mode_function function object
538 """
539 if name is None: name = self.mode_function_name()
540
541
542
543 if DevelopmentMode: self.module()
544
545 functions_dict = getattr(self, "_v_mode_functions", {})
546
547 if functions_dict.has_key(name):
548 return functions_dict[name]
549 else:
550 module = self.module()
551 if not module.__dict__.has_key(name):
552 msg = "No Such function %s:" % (name)
553 raise NoSuchFunction(msg)
554 else:
555 functions_dict[name] = module.__dict__[name]
556
557 self._v_mode_functions = functions_dict
558 return functions_dict[name]
559
560
562 """
563 Return the modification time of the module's source(!) file.
564 The time is returned as the number of seconds since the epoch.
565 """
566 module_file = module.__file__
567
568
569 parts = split(module_file, ".")
570 fname = join(parts[:-1], ".")
571 try:
572 py_file = fname + ".py"
573 py_mtime = os.stat(py_file).st_mtime
574 except OSError:
575 py_mtime = 0
576
577 try:
578 pyc_file = fname + ".pyc"
579 pyc_mtime = os.stat(pyc_file).st_mtime
580 except OSError:
581 pyc_mtime = 0
582
583 return max(py_mtime, pyc_mtime)
584
585
587 if self.path_variables_on():
588
589 if len(REQUEST.path) > 0 and \
590 hasattr(object, REQUEST.path[0]):
591 return
592 else:
593 path = REQUEST.path[:]
594
595
596
597
598
599 for variable in self._path_variables:
600 try:
601 value = path.pop()
602 try:
603 value = unicode(value)
604 except UnicodeDecodeError:
605 try:
606 value = unicode(value, "iso-8859-1")
607 except UnicodeDecodeError:
608 value = unicode(repr(value))
609
610 REQUEST.set(variable, value)
611 except IndexError:
612 pass
613
614
615 REQUEST['TraversalRequestNameStack'] = []
616
618 "Just call self"
619 return self(*args, **kw)
620
621 - def PUT(self, *args, **kw):
622 "Just call self"
623 return self(*args, **kw)
624