fixes #1310 and improves upon ideas shared on #1450

This commit is contained in:
niphlod
2016-09-22 00:01:22 +02:00
parent 075f493332
commit e5dcdb074f
2 changed files with 27 additions and 31 deletions
+13 -18
View File
@@ -594,7 +594,7 @@ def run_controller_in(controller, function, environment):
""" """
Runs the controller.function() (for the app specified by Runs the controller.function() (for the app specified by
the current folder). the current folder).
It tries pre-compiled controller_function.pyc first before compiling it. It tries pre-compiled controller.function.pyc first before compiling it.
""" """
# if compiled should run compiled! # if compiled should run compiled!
@@ -606,20 +606,15 @@ def run_controller_in(controller, function, environment):
filename = pjoin(path, 'controllers.%s.%s.pyc' filename = pjoin(path, 'controllers.%s.%s.pyc'
% (controller, function)) % (controller, function))
if not os.path.exists(filename): if not os.path.exists(filename):
### for backward compatibility raise HTTP(404,
filename = pjoin(path, 'controllers_%s_%s.pyc' rewrite.THREAD_LOCAL.routes.error_message % badf,
% (controller, function)) web2py_error=badf)
### end for backward compatibility
if not os.path.exists(filename):
raise HTTP(404,
rewrite.THREAD_LOCAL.routes.error_message % badf,
web2py_error=badf)
code = getcfs(filename, filename, lambda: read_pyc(filename)) code = getcfs(filename, filename, lambda: read_pyc(filename))
restricted(code, environment, layer=filename) restricted(code, environment, layer=filename)
elif function == '_TEST': elif function == '_TEST':
# TESTING: adjust the path to include site packages # TESTING: adjust the path to include site packages
from settings import global_settings from gluon.settings import global_settings
from admin import abspath, add_path_first from gluon.admin import abspath, add_path_first
paths = (global_settings.gluon_parent, abspath( paths = (global_settings.gluon_parent, abspath(
'site-packages', gluon=True), abspath('gluon', gluon=True), '') 'site-packages', gluon=True), abspath('gluon', gluon=True), '')
[add_path_first(path) for path in paths] [add_path_first(path) for path in paths]
@@ -642,7 +637,7 @@ def run_controller_in(controller, function, environment):
raise HTTP(404, raise HTTP(404,
rewrite.THREAD_LOCAL.routes.error_message % badc, rewrite.THREAD_LOCAL.routes.error_message % badc,
web2py_error=badc) web2py_error=badc)
code = read_file(filename) code = getcfs(filename, filename, lambda: read_file(filename))
exposed = find_exposed_functions(code) exposed = find_exposed_functions(code)
if not function in exposed: if not function in exposed:
raise HTTP(404, raise HTTP(404,
@@ -669,7 +664,7 @@ def run_view_in(environment):
Executes the view for the requested action. Executes the view for the requested action.
The view is the one specified in `response.view` or determined by the url The view is the one specified in `response.view` or determined by the url
or `view/generic.extension` or `view/generic.extension`
It tries the pre-compiled views_controller_function.pyc before compiling it. It tries the pre-compiled views.controller.function.pyc before compiling it.
""" """
request = current.request request = current.request
response = current.response response = current.response
@@ -691,18 +686,18 @@ def run_view_in(environment):
else: else:
filename = pjoin(folder, 'views', view) filename = pjoin(folder, 'views', view)
if os.path.exists(path): # compiled views if os.path.exists(path): # compiled views
x = view.replace('/', '_') x = view.replace('/', '.')
files = ['views_%s.pyc' % x] files = ['views.%s.pyc' % x]
is_compiled = os.path.exists(pjoin(path, files[0])) is_compiled = os.path.exists(pjoin(path, files[0]))
# Don't use a generic view if the non-compiled view exists. # Don't use a generic view if the non-compiled view exists.
if is_compiled or (not is_compiled and not os.path.exists(filename)): if is_compiled or (not is_compiled and not os.path.exists(filename)):
if allow_generic: if allow_generic:
files.append('views_generic.%s.pyc' % request.extension) files.append('views.generic.%s.pyc' % request.extension)
# for backward compatibility # for backward compatibility
if request.extension == 'html': if request.extension == 'html':
files.append('views_%s.pyc' % x[:-5]) files.append('views.%s.pyc' % x[:-5])
if allow_generic: if allow_generic:
files.append('views_generic.pyc') files.append('views.generic.pyc')
# end backward compatibility code # end backward compatibility code
for f in files: for f in files:
compiled = pjoin(path, f) compiled = pjoin(path, f)
+14 -13
View File
@@ -24,6 +24,9 @@ try:
# have web2py # have web2py
from gluon.restricted import RestrictedError from gluon.restricted import RestrictedError
from gluon.globals import current from gluon.globals import current
from gluon.cfs import getcfs
from gluon.fileutils import read_file
HAS_CFS = True
except ImportError: except ImportError:
# do not have web2py # do not have web2py
current = None current = None
@@ -426,7 +429,7 @@ class TemplateParser(object):
# Allow Views to include other views dynamically # Allow Views to include other views dynamically
context = self.context context = self.context
if current and not "response" in context: if current and "response" not in context:
context["response"] = getattr(current, 'response', None) context["response"] = getattr(current, 'response', None)
# Get the filename; filename looks like ``"template.html"``. # Get the filename; filename looks like ``"template.html"``.
@@ -779,12 +782,15 @@ def parse_template(filename,
# First, if we have a str try to open the file # First, if we have a str try to open the file
if isinstance(filename, str): if isinstance(filename, str):
try: fname = os.path.join(path, filename)
fp = open(os.path.join(path, filename), 'rb') if HAS_CFS:
text = fp.read() text = getcfs(fname, fname, lambda: read_file(fname))
fp.close() else:
except IOError: try:
raise RestrictedError(filename, '', 'Unable to find the file') with open(fname, 'rb') as fp:
text = fp.read()
except IOError:
raise RestrictedError(filename, '', 'Unable to find the file')
else: else:
text = filename.read() text = filename.read()
text = to_native(text) text = to_native(text)
@@ -890,7 +896,7 @@ def render(content="hello world",
Response = DummyResponse Response = DummyResponse
# Add it to the context so we can use it. # Add it to the context so we can use it.
if not 'NOESCAPE' in context: if 'NOESCAPE' not in context:
context['NOESCAPE'] = NOESCAPE context['NOESCAPE'] = NOESCAPE
if isinstance(content, unicodeT): if isinstance(content, unicodeT):
@@ -936,8 +942,3 @@ def render(content="hello world",
if old_response_body is not None: if old_response_body is not None:
context['response'].body = old_response_body context['response'].body = old_response_body
return text return text
if __name__ == '__main__':
import doctest
doctest.testmod()