1 """
2 This file is part of web2py Web Framework (Copyrighted, 2007)
3 Developed by Massimo Di Pierro <mdipierro@cs.depaul.edu>
4 License: GPL v2
5 """
6
7 import sys; sys.path.append('../gluon')
8 from template import parse_template
9 from restricted import restricted
10 from fileutils import listdir
11 from myregex import regex_expose
12 from http import HTTP
13 from html import CODE
14 import os, py_compile, marshal, imp, types, doctest
15
16 error_message='<html><body><h1>Invalid request</h1>%s</body></html>'
17
18 TEST_CODE=r"""
19 def _TEST():
20 import doctest, sys, cStringIO, types, cgi, gluon.fileutils
21 if not gluon.fileutils.check_credentials(request):
22 raise HTTP(400,web2py_error='invalid credentials')
23 stdout=sys.stdout
24 html='<h2>Testing controller "%s.py" ... done.</h2><br/>\n' % request.controller
25 for key in [key for key in globals() if not key in __symbols__+['_TEST']]:
26 if type(eval(key))==types.FunctionType:
27 if doctest.DocTestFinder().find(eval(key)):
28 sys.stdout=cStringIO.StringIO()
29 name='%s/controllers/%s.py in %s.__doc__' % (request.folder, request.controller, key)
30 doctest.run_docstring_examples(eval(key),globals(),False,name=name)
31 report=sys.stdout.getvalue().strip()
32 if report: pf='failed'
33 else: pf='passed'
34 html+='<h3 class="%s">Function %s [%s]</h3>'%(pf,key,pf)
35 if report: html+=CODE(report,language='web2py',link='/examples/global/vars/').xml()
36 html+='<br/>\n'
37 else:
38 html+='<h3 class="nodoctests">Function %s [no doctests]</h3><br/>'%(key)
39 response._vars=html
40 sys.stdout=stdout
41 _TEST()
42 """
43
45 py_compile.compile(filename)
46
48 data=open(filename,'rb').read()
49 if data[:4]!=imp.get_magic():
50 raise SystemError, "compiled code is incompatible"
51 return marshal.loads(data[8:])
52
54 """
55 compiles all the views in the applicaiton specified by the
56 current folder
57 """
58 path=os.path.join(folder,'views/')
59 for file in listdir(path,'.+\.html$'):
60 data=parse_template(file,path)
61 filename=os.path.join(folder,'compiled/',('views/'+file[:-5]+'.py').replace('/','_').replace('\\','_'))
62 open(filename,'w').write(data)
63 save_pyc(filename)
64 os.unlink(filename)
65
67 """
68 compiles all the models in the applicaiton specified by the
69 current folder
70 """
71 path=os.path.join(folder,'models/')
72 for file in listdir(path,'.+\.py$'):
73 data=open(os.path.join(path,file),'r').read()
74 filename=os.path.join(folder,'compiled/',('models/'+file).replace('/','_'))
75 open(filename,'w').write(data)
76 save_pyc(filename)
77 os.unlink(filename)
78
80 """
81 compiles all the controllers in the applicaiton specified by the
82 current folder
83 """
84 path=os.path.join(folder,'controllers/')
85 for file in listdir(path,'.+\.py$'):
86 data=open(path+file,'r').read()
87 exposed=regex_expose.findall(data)
88 for function in exposed:
89 command=data+'\n\nresponse._vars=%s()' % function
90 filename=os.path.join(folder,'compiled/',('controllers/'+file[:-3]).replace('/','_')+'_'+function+'.py')
91 open(filename,'w').write(command)
92 save_pyc(filename)
93 os.unlink(filename)
94
96 """
97 runs all models (in the app specified by the current folder)
98 in the environment. it tries precompiled models first.
99 """
100 folder=environment['request'].folder
101 path=os.path.join(folder,'compiled/')
102 if os.access(path,os.R_OK):
103 for model in listdir(path,'^models_.+\.pyc$',0):
104 restricted(read_pyc(model),environment,layer=model)
105 else:
106 models=listdir(os.path.join(folder,'models/'),'^\w+\.py$',0)
107 for model in models:
108 restricted(open(model,'r').read(),environment,layer=model)
109
111 """
112 runs the controller.function() (for the app specified by
113 the current folder) in the environment.
114 it tries precompiled controller_function.pyc first.
115 """
116
117 folder=environment['request'].folder
118 path=os.path.join(folder,'compiled/')
119 if os.access(path,os.R_OK):
120 filename=os.path.join(path,'controllers_%s_%s.pyc' %(controller,function))
121 if not os.access(filename,os.R_OK):
122 raise HTTP(400,error_message % 'invalid function',
123 web2py_error='invalid function')
124 restricted(read_pyc(filename),environment,layer=filename)
125 elif function=='_TEST':
126 filename=os.path.join(folder,'controllers/%s.py' % controller)
127 if not os.access(filename,os.R_OK):
128 raise HTTP(400,error_message % 'invalid controller',
129 web2py_error='invalid controller')
130 environment['__symbols__']=environment.keys()
131 code=open(filename,'r').read()
132 code+=TEST_CODE
133 restricted(code,environment,layer=filename)
134 else:
135 filename=os.path.join(folder,'controllers/%s.py' % controller)
136 if not os.access(filename,os.R_OK):
137 raise HTTP(400,error_message % 'invalid controller',
138 web2py_error='invalid controller')
139 code=open(filename,'r').read()
140 exposed=regex_expose.findall(code)
141 if not function in exposed:
142 raise HTTP(400,error_message % 'invalid function',
143 web2py_error='invalid function')
144 code+='\n\nresponse._vars=%s()' % function
145 restricted(code,environment,layer=filename)
146 response=environment['response']
147 if type(response._vars)==types.StringType:
148 response.body=response._vars
149 elif type(response._vars)==types.GeneratorType:
150 response.body=response._vars
151 elif type(response._vars)!=types.DictType:
152 response.body=str(response._vars)
153
155 """
156 exectutes the view in resposne.view or generic.html.
157 it tries the precompiled views_controller_funciton.pyc first.
158 """
159 folder=environment['request'].folder
160 response=environment['response']
161 path=os.path.join(folder,'compiled/')
162 if os.access(path,os.R_OK):
163 filename=os.path.join(path,'views_%s.pyc' % response.view[:-5].replace('/','_'))
164 if not os.access(filename,os.R_OK):
165 filename=os.path.join(folder,'compiled/','views_generic.pyc')
166 if not os.access(filename,os.R_OK):
167 raise HTTP(400,error_message % 'invalid view',
168 web2py_error='invalid view')
169 code=read_pyc(filename)
170
171 restricted(code,environment,layer=filename)
172 else:
173 filename=os.path.join(folder,'views/',response.view)
174 if not os.access(filename,os.R_OK):
175 response.view='generic.html'
176 filename=os.path.join(folder,'views/',response.view)
177 if not os.access(filename,os.R_OK):
178 raise HTTP(400,error_message % 'invalid view',
179 web2py_error='invalid view')
180 code=parse_template(response.view,os.path.join(folder,'views/'))
181
182 restricted(code,environment,layer=filename)
183
185 try:
186 path=os.path.join(folder,'compiled/')
187 for file in listdir(path): os.unlink(os.path.join(path,file))
188 os.rmdir(path)
189 except OSError: pass
190
197
199 """
200 Example:
201 >>> import traceback, types
202 >>> environment={'x':1}
203 >>> open('a.py','w').write('print 1/x')
204 >>> save_pyc('a.py')
205 >>> os.unlink('a.py')
206 >>> if type(read_pyc('a.pyc'))==types.CodeType: print 'code'
207 code
208 >>> exec read_pyc('a.pyc') in environment
209 1
210 """
211 return
212
213 if __name__=='__main__':
214 import doctest
215 doctest.testmod()
216