Package gluon :: Module compileapp
[hide private]
[frames] | no frames]

Source Code for Module gluon.compileapp

  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   
44 -def save_pyc(filename):
45 py_compile.compile(filename)
46
47 -def read_pyc(filename):
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
53 -def compile_views(folder):
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
66 -def compile_models(folder):
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
79 -def compile_controllers(folder):
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
95 -def run_models_in(environment):
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
110 -def run_controller_in(controller,function,environment):
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 # if compiled should run compiled! 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
154 -def run_view_in(environment):
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 #response.body=restricted(code,environment,layer=filename) 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 #response.body=restricted(code,environment,layer=filename) 182 restricted(code,environment,layer=filename)
183
184 -def remove_compiled_application(folder):
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
191 -def compile_application(folder):
192 remove_compiled_application(folder) 193 os.mkdir(os.path.join(folder,'compiled/')) 194 compile_models(folder) 195 compile_controllers(folder) 196 compile_views(folder)
197
198 -def test():
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