From d79853ceb733c20aeb3b153e00bcb96dddabe7f7 Mon Sep 17 00:00:00 2001 From: mdipierro Date: Tue, 28 Aug 2012 20:30:32 -0500 Subject: [PATCH] lots of simplifications --- VERSION | 2 +- gluon/compileapp.py | 73 +++++++++--------- gluon/dal.py | 1 + gluon/globals.py | 5 +- gluon/main.py | 181 ++++++++++++++++++++++---------------------- 5 files changed, 133 insertions(+), 129 deletions(-) diff --git a/VERSION b/VERSION index 4447b72d..7a27f3d6 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -Version 2.00.1 (2012-08-28 19:11:39) rc4 +Version 2.00.1 (2012-08-28 20:30:26) rc4 diff --git a/gluon/compileapp.py b/gluon/compileapp.py index f0044834..e9e8d8a8 100644 --- a/gluon/compileapp.py +++ b/gluon/compileapp.py @@ -50,6 +50,8 @@ is_pypy = settings.global_settings.is_pypy is_gae = settings.global_settings.web2py_runtime_gae is_jython = settings.global_settings.is_jython +pjoin = os.path.join + TEST_CODE = \ r""" def _TEST(): @@ -319,7 +321,7 @@ def local_import_aux(name, reload_force=False, app='welcome'): """ OLD IMPLEMENTATION: items = name.replace('/','.').split('.') - filename, modulepath = items[-1], os.path.join(apath,'modules',*items[:-1]) + filename, modulepath = items[-1], pjoin(apath,'modules',*items[:-1]) imp.acquire_lock() try: file=None @@ -387,7 +389,7 @@ def build_environment(request, response, session, store_current=True): environment['local_import'] = \ lambda name, reload=False, app=request.application:\ local_import_aux(name,reload,app) - BaseAdapter.set_folder(os.path.join(request.folder, 'databases')) + BaseAdapter.set_folder(pjoin(request.folder, 'databases')) response._view_environment = copy.copy(environment) return environment @@ -417,11 +419,11 @@ def compile_views(folder): Compiles all the views in the application specified by `folder` """ - path = os.path.join(folder, 'views') + path = pjoin(folder, 'views') for file in listdir(path, '^[\w/\-]+(\.\w+)+$'): data = parse_template(file, path) filename = ('views/%s.py' % file).replace('/', '_').replace('\\', '_') - filename = os.path.join(folder, 'compiled', filename) + filename = pjoin(folder, 'compiled', filename) write_file(filename, data) save_pyc(filename) os.unlink(filename) @@ -432,10 +434,10 @@ def compile_models(folder): Compiles all the models in the application specified by `folder` """ - path = os.path.join(folder, 'models') + path = pjoin(folder, 'models') for file in listdir(path, '.+\.py$'): - data = read_file(os.path.join(path, file)) - filename = os.path.join(folder, 'compiled','models',file) + data = read_file(pjoin(path, file)) + filename = pjoin(folder, 'compiled','models',file) mktree(filename) write_file(filename, data) save_pyc(filename) @@ -447,15 +449,15 @@ def compile_controllers(folder): Compiles all the controllers in the application specified by `folder` """ - path = os.path.join(folder, 'controllers') + path = pjoin(folder, 'controllers') for file in listdir(path, '.+\.py$'): - ### why is this here? save_pyc(os.path.join(path, file)) - data = read_file(os.path.join(path,file)) + ### why is this here? save_pyc(pjoin(path, file)) + data = read_file(pjoin(path,file)) exposed = regex_expose.findall(data) for function in exposed: command = data + "\nresponse._vars=response._caller(%s)\n" % \ function - filename = os.path.join(folder, 'compiled', ('controllers/' + filename = pjoin(folder, 'compiled', ('controllers/' + file[:-3]).replace('/', '_') + '_' + function + '.py') write_file(filename, command) @@ -472,18 +474,18 @@ def run_models_in(environment): folder = environment['request'].folder c = environment['request'].controller f = environment['request'].function - cpath = os.path.join(folder, 'compiled') + cpath = pjoin(folder, 'compiled') if os.path.exists(cpath): for model in listdir(cpath, '^models_\w+\.pyc$', 0): restricted(read_pyc(model), environment, layer=model) - path = os.path.join(cpath, 'models') + path = pjoin(cpath, 'models') models = listdir(path, '^\w+\.pyc$',0,sort=False) compiled=True else: - path = os.path.join(folder, 'models') + path = pjoin(folder, 'models') models = listdir(path, '^\w+\.py$',0,sort=False) compiled=False - paths = (path, os.path.join(path,c), os.path.join(path,c,f)) + paths = (path, pjoin(path,c), pjoin(path,c,f)) for model in models: if not os.path.split(model)[0] in paths and c!='appadmin': continue @@ -507,11 +509,11 @@ def run_controller_in(controller, function, environment): # if compiled should run compiled! folder = environment['request'].folder - path = os.path.join(folder, 'compiled') + path = pjoin(folder, 'compiled') badc = 'invalid controller (%s/%s)' % (controller, function) badf = 'invalid function (%s/%s)' % (controller, function) if os.path.exists(path): - filename = os.path.join(path, 'controllers_%s_%s.pyc' + filename = pjoin(path, 'controllers_%s_%s.pyc' % (controller, function)) if not os.path.exists(filename): raise HTTP(404, @@ -526,7 +528,7 @@ def run_controller_in(controller, function, environment): [add_path_first(path) for path in paths] # TESTING END - filename = os.path.join(folder, 'controllers/%s.py' + filename = pjoin(folder, 'controllers/%s.py' % controller) if not os.path.exists(filename): raise HTTP(404, @@ -537,7 +539,7 @@ def run_controller_in(controller, function, environment): code += TEST_CODE restricted(code, environment, layer=filename) else: - filename = os.path.join(folder, 'controllers/%s.py' + filename = pjoin(folder, 'controllers/%s.py' % controller) if not os.path.exists(filename): raise HTTP(404, @@ -575,19 +577,20 @@ def run_view_in(environment): request = environment['request'] response = environment['response'] + view = response.view folder = request.folder - path = os.path.join(folder, 'compiled') - badv = 'invalid view (%s)' % response.view + path = pjoin(folder, 'compiled') + badv = 'invalid view (%s)' % view patterns = response.generic_patterns or [] regex = re.compile('|'.join(map(fnmatch.translate, patterns))) short_action = '%(controller)s/%(function)s.%(extension)s' % request allow_generic = patterns and regex.search(short_action) - if not isinstance(response.view, str): - ccode = parse_template(response.view, os.path.join(folder, 'views'), + if not isinstance(view, str): + ccode = parse_template(view, pjoin(folder, 'views'), context=environment) restricted(ccode, environment, 'file stream') elif os.path.exists(path): - x = response.view.replace('/', '_') + x = view.replace('/', '_') files = ['views_%s.pyc' % x] if allow_generic: files.append('views_generic.%s.pyc' % request.extension) @@ -598,7 +601,7 @@ def run_view_in(environment): files.append('views_generic.pyc') # end backward compatibility code for f in files: - filename = os.path.join(path,f) + filename = pjoin(path,f) if os.path.exists(filename): code = read_pyc(filename) restricted(code, environment, layer=filename) @@ -607,10 +610,10 @@ def run_view_in(environment): rewrite.thread.routes.error_message % badv, web2py_error=badv) else: - filename = os.path.join(folder, 'views', response.view) + filename = pjoin(folder, 'views', view) if not os.path.exists(filename) and allow_generic: - response.view = 'generic.' + request.extension - filename = os.path.join(folder, 'views', response.view) + view = 'generic.' + request.extension + filename = pjoin(folder, 'views', view) if not os.path.exists(filename): raise HTTP(404, rewrite.thread.routes.error_message % badv, @@ -618,12 +621,12 @@ def run_view_in(environment): layer = filename if is_gae: ccode = getcfs(layer, filename, - lambda: compile2(parse_template(response.view, - os.path.join(folder, 'views'), + lambda: compile2(parse_template(view, + pjoin(folder, 'views'), context=environment),layer)) else: - ccode = parse_template(response.view, - os.path.join(folder, 'views'), + ccode = parse_template(view, + pjoin(folder, 'views'), context=environment) restricted(ccode, environment, layer) @@ -632,8 +635,8 @@ def remove_compiled_application(folder): Deletes the folder `compiled` containing the compiled application. """ try: - shutil.rmtree(os.path.join(folder, 'compiled')) - path = os.path.join(folder, 'controllers') + shutil.rmtree(pjoin(folder, 'compiled')) + path = pjoin(folder, 'controllers') for file in listdir(path,'.*\.pyc$',drop=False): os.unlink(file) except OSError: @@ -645,7 +648,7 @@ def compile_application(folder): Compiles all models, views, controller for the application in `folder`. """ remove_compiled_application(folder) - os.mkdir(os.path.join(folder, 'compiled')) + os.mkdir(pjoin(folder, 'compiled')) compile_models(folder) compile_controllers(folder) compile_views(folder) diff --git a/gluon/dal.py b/gluon/dal.py index e7885b4c..38ba95b6 100644 --- a/gluon/dal.py +++ b/gluon/dal.py @@ -8458,6 +8458,7 @@ class Field(Expression): return (filename, stream) def retrieve_file_properties(self, name, path=None): + self_uploadfield = self.uploadfield if self.custom_retrieve_file_properties: return self.custom_retrieve_file_properties(name, path) try: diff --git a/gluon/globals.py b/gluon/globals.py index 7054b310..5e94b726 100644 --- a/gluon/globals.py +++ b/gluon/globals.py @@ -367,12 +367,13 @@ class Response(Storage): (filename, stream) = field.retrieve(name) except IOError: raise HTTP(404) + headers = self.headers headers['Content-Type'] = contenttype(name) if attachment: headers['Content-Disposition'] = \ 'attachment; filename=%s' % filename - return self.stream(stream, chunk_size = chunk_size, - request=request) + return self.stream(stream, chunk_size=chunk_size, request=request) + def json(self, data, default=None): return json(data, default = default or custom_json) diff --git a/gluon/main.py b/gluon/main.py index 8976c1b6..be0edaf1 100644 --- a/gluon/main.py +++ b/gluon/main.py @@ -21,7 +21,6 @@ import re import copy import sys import time -import thread import datetime import signal import socket @@ -29,6 +28,7 @@ import tempfile import random import string import urllib2 +from thread import allocate_lock from fileutils import abspath, write_file, parse_version from settings import global_settings @@ -69,8 +69,11 @@ import logging.config import gluon.messageboxhandler logging.gluon = gluon +exists = os.path.exists +pjoin = os.path.join + logpath = abspath("logging.conf") -if os.path.exists(logpath): +if exists(logpath): logging.config.fileConfig(abspath("logging.conf")) else: logging.basicConfig() @@ -89,8 +92,8 @@ from validators import CRYPT from cache import Cache from html import URL as Url, xmlescape from utils import is_valid_ip_address +from rewrite import load, url_in, thread as rwthread, try_rewrite_on_error import newcron -import rewrite __all__ = ['wsgibase', 'save_password', 'appfactory', 'HttpServer'] @@ -103,7 +106,7 @@ requests = 0 # gc timer regex_client = re.compile('[\w\-:]+(\.[\w\-]+)*\.?') # ## to account for IPV6 try: - version_info = open(os.path.join(global_settings.gluon_parent, 'VERSION'), 'r') + version_info = open(pjoin(global_settings.gluon_parent, 'VERSION'), 'r') raw_version_string = version_info.read().strip() version_info.close() global_settings.web2py_version = parse_version(raw_version_string) @@ -118,7 +121,7 @@ except: if not global_settings.web2py_runtime_gae: logger.warn('unable to import Rocket') -rewrite.load() +load() def get_client(env): """ @@ -129,11 +132,16 @@ def get_client(env): """ g = regex_client.search(env.get('http_x_forwarded_for', '')) if g: - return g.group() - g = regex_client.search(env.get('remote_addr', '')) - if g: - return g.group() - return '127.0.0.1' + client = g.group() + else: + g = regex_client.search(env.get('remote_addr', '')) + if g: + client = g.group() + else: + client = '127.0.0.1' + if not is_valid_ip_address(client): + raise HTTP(400,"Bad Request (request.client=%s)" % client) + return client def copystream_progress(request, chunk_size= 10**5): """ @@ -253,8 +261,8 @@ def middleware_aux(request, response, *middleware_apps): for item in middleware_apps: app=item(app) def caller(app): - return app(request.wsgi.environ, - request.wsgi.start_response) + wsgi = request.wsgi + return app(wsgi.environ, wsgi.start_response) return lambda caller=caller, app=app: caller(app) return middleware @@ -280,14 +288,14 @@ def parse_get_post_vars(request, environ): # parse POST variables on POST, PUT, BOTH only in post_vars try: - request.body = copystream_progress(request) ### stores request body + request.body = body = copystream_progress(request) except IOError: raise HTTP(400,"Bad Request - HTTP body is incomplete") - if (request.body and request.env.request_method in ('POST', 'PUT', 'BOTH')): - dpost = cgi.FieldStorage(fp=request.body,environ=environ,keep_blank_values=1) + if (body and request.env.request_method in ('POST', 'PUT', 'BOTH')): + dpost = cgi.FieldStorage(fp=body,environ=environ,keep_blank_values=1) # The same detection used by FieldStorage to detect multipart POSTs is_multipart = dpost.type[:10] == 'multipart/' - request.body.seek(0) + body.seek(0) isle25 = sys.version_info[1] <= 5 def listify(a): @@ -358,9 +366,10 @@ def wsgibase(environ, responder): request = Request() response = Response() session = Session() - request.env.web2py_path = global_settings.applications_parent - request.env.web2py_version = web2py_version - request.env.update(global_settings) + env = request.env + env.web2py_path = global_settings.applications_parent + env.web2py_version = web2py_version + env.update(global_settings) static_file = False try: try: @@ -374,8 +383,8 @@ def wsgibase(environ, responder): # serve file if static # ################################################## - if not environ.get('PATH_INFO',None) and \ - environ.get('REQUEST_URI',None): + eget = environ.get + if not eget('PATH_INFO',None) and eget('REQUEST_URI',None): # for fcgi, get path_info and # query_string from request_uri items = environ['REQUEST_URI'].split('?') @@ -384,13 +393,13 @@ def wsgibase(environ, responder): environ['QUERY_STRING'] = items[1] else: environ['QUERY_STRING'] = '' - if not environ.get('HTTP_HOST',None): - environ['HTTP_HOST'] = '%s:%s' % ( - environ.get('SERVER_NAME'), - environ.get('SERVER_PORT')) + if not eget('HTTP_HOST',None): + environ['HTTP_HOST'] = \ + eget('SERVER_NAME')+':'+eget('SERVER_PORT') + + + (static_file, environ) = url_in(request, environ) - (static_file, environ) = \ - rewrite.url_in(request, environ) if static_file: if environ.get('QUERY_STRING','').startswith( 'attachment'): @@ -401,10 +410,11 @@ def wsgibase(environ, responder): # ################################################## # fill in request items # ################################################## - - http_host = request.env.http_host.split(':',1)[0] - - local_hosts = [http_host,'::1','127.0.0.1','::ffff:127.0.0.1'] + app = request.application ## must go after url_in! + + http_host = env.http_host.split(':',1)[0] + local_hosts = [http_host,'::1','127.0.0.1', + '::ffff:127.0.0.1'] if not global_settings.web2py_runtime_gae: local_hosts.append(socket.gethostname()) try: @@ -412,47 +422,39 @@ def wsgibase(environ, responder): socket.gethostbyname(http_host)) except socket.gaierror: pass - request.client = get_client(request.env) - if not is_valid_ip_address(request.client): - raise HTTP(400,"Bad Request (request.client=%s)" %\ - request.client) - request.folder = abspath( - 'applications',request.application) + os.sep - x_req_with = str(request.env.http_x_requested_with).lower() - request.ajax = x_req_with == 'xmlhttprequest' - request.cid = request.env.http_web2py_component_element - request.is_local = request.env.remote_addr in local_hosts - request.is_https = request.env.wsgi_url_scheme \ - in ['https', 'HTTPS'] or request.env.https == 'on' - - # ################################################## - # compute a request.uuid to be used for tickets and toolbar - # ################################################## - - response.uuid = request.compute_uuid() + client = get_client(env) + x_req_with = str(env.http_x_requested_with).lower() + + request.update(dict( + client = client, + folder = abspath('applications',app) + os.sep, + ajax = x_req_with == 'xmlhttprequest', + cid = env.http_web2py_component_element, + is_local = env.remote_addr in local_hosts, + is_https = env.wsgi_url_scheme \ + in ['https', 'HTTPS'] or env.https=='on')) + request.uuid = request.compute_uuid() # requires client # ################################################## # access the requested application # ################################################## - if not os.path.exists(request.folder): - if request.application == \ - rewrite.thread.routes.default_application \ - and request.application != 'welcome': - request.application = 'welcome' - redirect(Url(r=request)) - elif rewrite.thread.routes.error_handler: - _handler = rewrite.thread.routes.error_handler + if not exists(request.folder): + if app == rwthread.routes.default_application \ + and app != 'welcome': + redirect(Url(app,'default','index')) + elif rwthread.routes.error_handler: + _handler = rwthread.routes.error_handler redirect(Url(_handler['application'], _handler['controller'], _handler['function'], - args=request.application)) + args=app)) else: - raise HTTP(404, rewrite.thread.routes.error_message \ + raise HTTP(404, rwthread.routes.error_message \ % 'invalid request', web2py_error='invalid application') elif not request.is_local and \ - os.path.exists(os.path.join(request.folder,'DISABLED')): + exists(pjoin(request.folder,'DISABLED')): raise HTTP(503, "

Temporarily down for maintenance

") request.url = Url(r=request, args=request.args, @@ -501,22 +503,23 @@ def wsgibase(environ, responder): # ################################################## # set no-cache headers # ################################################## - - response.headers['Content-Type'] = \ + + headers = response.headers + headers['Content-Type'] = \ contenttype('.'+request.extension) - response.headers['Cache-Control'] = \ + headers['Cache-Control'] = \ 'no-store, no-cache, must-revalidate, post-check=0, pre-check=0' - response.headers['Expires'] = \ + headers['Expires'] = \ time.strftime('%a, %d %b %Y %H:%M:%S GMT', time.gmtime()) - response.headers['Pragma'] = 'no-cache' + headers['Pragma'] = 'no-cache' # ################################################## # run controller # ################################################## - if global_settings.debugging and request.application != "admin": + if global_settings.debugging and app != "admin": import gluon.debug - # activate the debugger and wait to reach application code + # activate the debugger gluon.debug.dbg.do_debug(mainpyfile=request.folder) serve_controller(request, response, session) @@ -558,22 +561,24 @@ def wsgibase(environ, responder): # ################################################## if request.cid: - if response.flash and not 'web2py-component-flash' \ - in http_response.headers: - http_response.headers['web2py-component-flash'] = \ + rheaders + if response.flash and \ + not 'web2py-component-flash' in rheaders: + rheaders['web2py-component-flash'] = \ urllib2.quote(xmlescape(response.flash)\ .replace('\n','')) - if response.js and not 'web2py-component-command' \ - in http_response.headers: - http_response.headers['web2py-component-command'] = \ + if response.js and \ + not 'web2py-component-command' in readers: + readers['web2py-component-command'] = \ response.js.replace('\n','') + rcookies = response.cookies if session._forget and \ response.session_id_name in response.cookies: - del response.cookies[response.session_id_name] + del rcookies[response.session_id_name] elif session._secure: - response.cookies[response.session_id_name]['secure'] = True + rcookies[response.session_id_name]['secure'] = True - http_response.cookies2headers(response.cookies) + http_response.cookies2headers(rcookies) ticket=None except RestrictedError, e: @@ -592,7 +597,7 @@ def wsgibase(environ, responder): BaseAdapter.close_all_instances('rollback') http_response = \ - HTTP(500, rewrite.thread.routes.error_message_ticket % \ + HTTP(500, rwthread.routes.error_message_ticket % \ dict(ticket=ticket), web2py_error='ticket %s' % ticket) @@ -615,7 +620,7 @@ def wsgibase(environ, responder): e = RestrictedError('Framework', '', '', locals()) ticket = e.log(request) or 'unrecoverable' http_response = \ - HTTP(500, rewrite.thread.routes.error_message_ticket \ + HTTP(500, rwthread.routes.error_message_ticket \ % dict(ticket=ticket), web2py_error='ticket %s' % ticket) @@ -625,7 +630,7 @@ def wsgibase(environ, responder): response.session_file.close() session._unlock(response) - http_response, new_environ = rewrite.try_rewrite_on_error( + http_response, new_environ = try_rewrite_on_error( http_response, request, environ, ticket) if not http_response: return wsgibase(new_environ,responder) @@ -650,7 +655,7 @@ def save_password(password, port): print '*********************************************************' elif password == '': # reuse the current password if any - if os.path.exists(password_file): + if exists(password_file): return else: password = '' @@ -681,9 +686,9 @@ def appfactory(wsgiapp=wsgibase, [, profilerfilename='profiler.log']]]) """ - if profilerfilename and os.path.exists(profilerfilename): + if profilerfilename and exists(profilerfilename): os.unlink(profilerfilename) - locker = thread.allocate_lock() + locker = allocate_lock() def app_with_logging(environ, responder): """ @@ -794,7 +799,7 @@ class HttpServer(object): os.chdir(path) [add_path_first(p) for p in (path, abspath('site-packages'), "")] custom_import_install(web2py_path) - if os.path.exists("logging.conf"): + if exists("logging.conf"): logging.config.fileConfig("logging.conf") save_password(password, port) @@ -809,9 +814,9 @@ class HttpServer(object): logger.info('SSL is off') elif not rocket.ssl: logger.warning('Python "ssl" module unavailable. SSL is OFF') - elif not os.path.exists(ssl_certificate): + elif not exists(ssl_certificate): logger.warning('unable to open SSL certificate. SSL is OFF') - elif not os.path.exists(ssl_private_key): + elif not exists(ssl_private_key): logger.warning('unable to open SSL private key. SSL is OFF') else: sock_list.extend([ssl_private_key, ssl_certificate]) @@ -857,9 +862,3 @@ class HttpServer(object): except: pass - - - - - -