Example #1
0
def env(a, import_models=False, c=None, f=None, dir="", extra_request={}):
    """
    Return web2py execution environment for application (a), controller (c),
    function (f).
    If import_models is True the exec all application models into the
    environment.

    extra_request allows you to pass along any extra
    variables to the request object before your models
    get executed. This was mainly done to support
    web2py_utils.test_runner, however you can use it
    with any wrapper scripts that need access to the
    web2py environment.
    """

    request = Request({})
    response = Response()
    session = Session()
    request.application = a

    # Populate the dummy environment with sensible defaults.

    if not dir:
        request.folder = os.path.join("applications", a)
    else:
        request.folder = dir
    request.controller = c or "default"
    request.function = f or "index"
    response.view = "%s/%s.html" % (request.controller, request.function)
    request.env.http_host = "127.0.0.1:8000"
    request.env.remote_addr = "127.0.0.1"
    request.env.web2py_runtime_gae = global_settings.web2py_runtime_gae

    for k, v in extra_request.items():
        request[k] = v

    path_info = "/%s/%s/%s" % (a, c, f)
    if request.args:
        path_info = "%s/%s" % (path_info, "/".join(request.args))
    if request.vars:
        vars = ["%s=%s" % (k, v) if v else "%s" % k for (k, v) in request.vars.iteritems()]
        path_info = "%s?%s" % (path_info, "&".join(vars))
    request.env.path_info = path_info

    # Monkey patch so credentials checks pass.

    def check_credentials(request, other_application="admin"):
        return True

    fileutils.check_credentials = check_credentials

    environment = build_environment(request, response, session)

    if import_models:
        try:
            run_models_in(environment)
        except RestrictedError, e:
            sys.stderr.write(e.traceback + "\n")
            sys.exit(1)
Example #2
0
 def test_include_meta(self):
     response = Response()
     response.meta['web2py'] = 'web2py'
     response.include_meta()
     self.assertEqual(response.body.getvalue(), '\n<meta name="web2py" content="web2py" />\n')
     response = Response()
     response.meta['meta_dict'] = {'tag_name':'tag_value'}
     response.include_meta()
     self.assertEqual(response.body.getvalue(), '\n<meta tag_name="tag_value" />\n')
 def setUp(self):
     self.request = Request(env={})
     self.request.application = 'a'
     self.request.controller = 'c'
     self.request.function = 'f'
     self.request.folder = 'applications/admin'
     self.response = Response()
     self.session = Session()
     T = translator('', 'en')
     self.session.connect(self.request, self.response)
     from gluon.globals import current
     self.current = current
     self.current.request = self.request
     self.current.response = self.response
     self.current.session = self.session
     self.current.T = T
     self.db = DAL(DEFAULT_URI, check_reserved=['all'])
     self.auth = AuthAPI(self.db)
     self.auth.define_tables(username=True, signature=False)
     # Create a user
     self.auth.table_user().validate_and_insert(first_name='Bart',
                                                last_name='Simpson',
                                                username='******',
                                                email='*****@*****.**',
                                                password='******',
                                                registration_key='',
                                                registration_id='')
     self.db.commit()
Example #4
0
    def setUp(self):
        request = Request(env={})
        request.application = 'a'
        request.controller = 'c'
        request.function = 'f'
        request.folder = 'applications/admin'
        response = Response()
        session = Session()
        T = translator('', 'en')
        session.connect(request, response)
        from gluon.globals import current
        current.request = request
        current.response = response
        current.session = session
        current.T = T
        self.db = DAL(DEFAULT_URI, check_reserved=['all'])
        self.auth = Auth(self.db)
        self.auth.define_tables(username=True, signature=False)
        self.db.define_table('t0', Field('tt'), self.auth.signature)
        self.auth.enable_record_versioning(self.db)
        # Create a user
        self.db.auth_user.insert(first_name='Bart',
                                 last_name='Simpson',
                                 username='******',
                                 email='*****@*****.**',
                                 password='******',
                                 registration_key=None,
                                 registration_id=None)

        self.db.commit()
Example #5
0
def initVars():
	global current, request, response, session, cache, T
	current.request = request = Request()
	current.response = response = Response()
	current.session = session = Session()
	current.cache = cache = Cache(request)
	current.T = T = m__T__
Example #6
0
 def build_web2py_environment(self):
     "build a namespace suitable for editor autocompletion and calltips"
     # warning: this can alter current global variable, use with care!
     try:
         from gluon.globals import Request, Response, Session
         from gluon.compileapp import build_environment, DAL
         request = Request()
         response = Response()
         session = Session()
         # fake request values
         request.folder = ""
         request.application = "welcome"
         request.controller = "default"
         request.function = "index"
         ns = build_environment(
             request,
             response,
             session,
         )
         # fake common model objects
         db = ns['db'] = DAL("sqlite:memory")
         from gluon.tools import Auth, Crud, Service
         ns['auth'] = Auth(db)
         ns['crud'] = Crud(db)
         ns['service'] = Service()
     except Exception, e:
         print e
         ns = {}
Example #7
0
def exec_environment(
        pyfile='',
        request=Request(),
        response=Response(),
        session=Session(),
):
    """
    Environment builder and module loader.

    Builds a web2py environment and optionally executes a Python
    file into the environment.
    A Storage dictionary containing the resulting environment is returned.
    The working directory must be web2py root -- this is the web2py default.

    """

    from gluon.compileapp import read_pyc

    if request.folder is None:
        mo = re.match(r'(|.*/)applications/(?P<appname>[^/]+)', pyfile)
        if mo:
            appname = mo.group('appname')
            request.folder = os.path.join('applications', appname)
        else:
            request.folder = ''
    env = build_environment(request, response, session)
    if pyfile:
        pycfile = pyfile + 'c'
        if os.path.isfile(pycfile):
            exec read_pyc(pycfile) in env
        else:
            execfile(pyfile, env)
    return Storage(env)
Example #8
0
 def test_include_meta(self):
     response = Response()
     response.meta[u'web2py'] = 'web2py'
     response.include_meta()
     self.assertEqual(response.body.getvalue(), '\n<meta name="web2py" content="web2py" />\n')
     response = Response()
     response.meta[u'meta_dict'] = {u'tag_name':'tag_value'}
     response.include_meta()
     self.assertEqual(response.body.getvalue(), '\n<meta tag_name="tag_value" />\n')
Example #9
0
def env(
    a,
    import_models=False,
    c=None,
    f=None,
    dir='',
    ):
    """
    Return web2py execution environment for application (a), controller (c),
    function (f).
    If import_models is True the exec all application models into the
    evironment.
    """

    request = Request()
    response = Response()
    session = Session()
    request.application = a

    # Populate the dummy environment with sensible defaults.

    if not dir:
        request.folder = os.path.join('applications', a)
    else:
        request.folder = dir
    request.controller = c or 'default'
    request.function = f or 'index'
    response.view = '%s/%s.html' % (request.controller,
                                    request.function)
    request.env.path_info = '/%s/%s/%s' % (a, c, f)
    request.env.http_host = '127.0.0.1:8000'
    request.env.remote_addr = '127.0.0.1'

    # Monkey patch so credentials checks pass.

    def check_credentials(request, other_application='admin'):
        return True

    gluon.fileutils.check_credentials = check_credentials

    environment = build_environment(request, response, session)

    if import_models:
        run_models_in(environment)
    return environment
Example #10
0
def env(
    a,
    import_models=False,
    c=None,
    f=None,
    dir='',
):
    """
    Return web2py execution environment for application (a), controller (c),
    function (f).
    If import_models is True the exec all application models into the
    evironment.
    """

    request = Request()
    response = Response()
    session = Session()
    request.application = a

    # Populate the dummy environment with sensible defaults.

    if not dir:
        request.folder = os.path.join('applications', a)
    else:
        request.folder = dir
    request.controller = c or 'default'
    request.function = f or 'index'
    response.view = '%s/%s.html' % (request.controller, request.function)
    request.env.path_info = '/%s/%s/%s' % (a, c, f)
    request.env.http_host = '127.0.0.1:8000'
    request.env.remote_addr = '127.0.0.1'

    # Monkey patch so credentials checks pass.

    def check_credentials(request, other_application='admin'):
        return True

    gluon.fileutils.check_credentials = check_credentials

    environment = build_environment(request, response, session)

    if import_models:
        run_models_in(environment)
    return environment
Example #11
0
    def testRun(self):
        # setup
        request = Request(env={})
        request.application = 'a'
        request.controller = 'c'
        request.function = 'f'
        request.folder = 'applications/admin'
        response = Response()
        session = Session()
        T = translator('', 'en')
        session.connect(request, response)
        from gluon.globals import current
        current.request = request
        current.response = response
        current.session = session
        current.T = T
        db = DAL(DEFAULT_URI, check_reserved=['all'])
        auth = Auth(db)
        auth.define_tables(username=True, signature=False)
        self.assertTrue('auth_user' in db)
        self.assertTrue('auth_group' in db)
        self.assertTrue('auth_membership' in db)
        self.assertTrue('auth_permission' in db)
        self.assertTrue('auth_event' in db)
        db.define_table('t0', Field('tt'), auth.signature)
        auth.enable_record_versioning(db)
        self.assertTrue('t0_archive' in db)
        for f in [
                'login', 'register', 'retrieve_password', 'retrieve_username'
        ]:
            html_form = getattr(auth, f)().xml()
            self.assertTrue('name="_formkey"' in html_form)

        for f in [
                'logout', 'verify_email', 'reset_password', 'change_password',
                'profile', 'groups'
        ]:
            self.assertRaisesRegexp(HTTP, "303*", getattr(auth, f))

        self.assertRaisesRegexp(HTTP, "401*", auth.impersonate)

        try:
            for t in [
                    't0_archive', 't0', 'auth_cas', 'auth_event',
                    'auth_membership', 'auth_permission', 'auth_group',
                    'auth_user'
            ]:
                db[t].drop()
        except SyntaxError as e:
            # GAE doesn't support drop
            pass
        return
Example #12
0
def setup_clean_session():
    request = Request(env={})
    request.application = 'a'
    request.controller = 'c'
    request.function = 'f'
    request.folder = 'applications/admin'
    response = Response()
    session = Session()
    session.connect(request, response)
    from gluon.globals import current
    current.request = request
    current.response = response
    current.session = session
    return current
Example #13
0
 def setUp(self):
     request = Request(env={})
     request.application = 'a'
     request.controller = 'c'
     request.function = 'f'
     request.folder = 'applications/admin'
     response = Response()
     session = Session()
     session.connect(request, response)
     from gluon.globals import current
     current.request = request
     current.response = response
     current.session = session
     self.current = current
     rconn = RConn(host='localhost')
     self.db = RedisSession(redis_conn=rconn, session_expiry=False)
     self.tname = 'testtablename'
     return current
Example #14
0
def exec_environment(
    pyfile='',
    request=None,
    response=None,
    session=None,
):
    """
    .. function:: gluon.shell.exec_environment([pyfile=''[, request=Request()
        [, response=Response[, session=Session()]]]])

        Environment builder and module loader.


        Builds a web2py environment and optionally executes a Python
        file into the environment.
        A Storage dictionary containing the resulting environment is returned.
        The working directory must be web2py root -- this is the web2py default.

    """

    if request is None:
        request = Request({})
    if response is None:
        response = Response()
    if session is None:
        session = Session()

    if request.folder is None:
        mo = re.match(r'(|.*/)applications/(?P<appname>[^/]+)', pyfile)
        if mo:
            appname = mo.group('appname')
            request.folder = os.path.join('applications', appname)
        else:
            request.folder = ''
    env = build_environment(request, response, session, store_current=False)
    if pyfile:
        pycfile = pyfile + 'c'
        if os.path.isfile(pycfile):
            exec read_pyc(pycfile) in env
        else:
            execfile(pyfile, env)
    return Storage(env)
 def setUp(self):
     from gluon.globals import Request, Response, Session, current
     from gluon.html import A, DIV, FORM, MENU, TABLE, TR, INPUT, URL, XML
     from gluon.html import ASSIGNJS
     from gluon.validators import IS_NOT_EMPTY
     from gluon.compileapp import LOAD
     from gluon.http import HTTP, redirect
     from gluon.tools import Auth
     from gluon.sql import SQLDB
     from gluon.sqlhtml import SQLTABLE, SQLFORM
     self.original_check_credentials = fileutils.check_credentials
     fileutils.check_credentials = fake_check_credentials
     request = Request(env={})
     request.application = 'welcome'
     request.controller = 'appadmin'
     request.function = self._testMethodName.split('_')[1]
     request.folder = 'applications/welcome'
     request.env.http_host = '127.0.0.1:8000'
     request.env.remote_addr = '127.0.0.1'
     response = Response()
     session = Session()
     T = translator('', 'en')
     session.connect(request, response)
     current.request = request
     current.response = response
     current.session = session
     current.T = T
     db = DAL(DEFAULT_URI, check_reserved=['all'])
     auth = Auth(db)
     auth.define_tables(username=True, signature=False)
     db.define_table('t0', Field('tt'), auth.signature)
     # Create a user
     db.auth_user.insert(first_name='Bart',
                         last_name='Simpson',
                         username='******',
                         email='*****@*****.**',
                         password='******',
                         registration_key=None,
                         registration_id=None)
     self.env = locals()
Example #16
0
def exec_environment(
    pyfile='',
    request=None,
    response=None,
    session=None,
):
    """Environment builder and module loader.

    Builds a web2py environment and optionally executes a Python file into
    the environment.

    A Storage dictionary containing the resulting environment is returned.
    The working directory must be web2py root -- this is the web2py default.

    """

    if request is None:
        request = Request({})
    if response is None:
        response = Response()
    if session is None:
        session = Session()

    if request.folder is None:
        mo = re.match(REGEX_APP_PATH, pyfile)
        if mo:
            a = mo.group('a')
            request.folder = os.path.abspath(os.path.join('applications', a))
        else:
            request.folder = ''
    env = build_environment(request, response, session, store_current=False)
    if pyfile:
        pycfile = pyfile + 'c'
        if os.path.isfile(pycfile):
            exec(read_pyc(pycfile), env)
        else:
            execfile(pyfile, env)
    return Storage(env)
web2py_path = os.path.abspath(os.path.join(os.getcwd(), '..', '..', '..'))
sys.path.append(web2py_path)

# setup the application controllers path
sys.path.append(os.path.abspath(os.path.join(os.getcwd(), '..',
                                             'controllers')))

# setup a very basic environment
from gluon import current
from gluon.globals import Request, Session, Response
from gluon.storage import Storage

current.T = lambda t: t
current.request = Request(dict())
current.session = Session()
current.response = Response()

# you will need to update this with your application name
current.request.application = 'web2py_unit_test'

# create our test database
from app import Application
application = Application(
    config=Storage(db=Storage(uri='sqlite://test_storage.db',
                              migrate=True,
                              migrate_enabled=True,
                              folder='databases'),
                   mail=Storage(server='logging', sender='*****@*****.**'),
                   upload_folder=os.path.join(os.getcwd(), 'uploads')))

from test_controllers import default_test, admin_test
Example #18
0
def wsgibase(environ, responder):
    """
    this is the gluon wsgi application. the first function called when a page
    is requested (static or dynamic). it can be called by paste.httpserver
    or by apache mod_wsgi.

      - fills request with info
      - the environment variables, replacing '.' with '_'
      - adds web2py path and version info
      - compensates for fcgi missing path_info and query_string
      - validates the path in url

    The url path must be either:

    1. for static pages:

      - /<application>/static/<file>

    2. for dynamic pages:

      - /<application>[/<controller>[/<function>[/<sub>]]][.<extension>]
      - (sub may go several levels deep, currently 3 levels are supported:
         sub1/sub2/sub3)

    The naming conventions are:

      - application, controller, function and extension may only contain
        [a-zA-Z0-9_]
      - file and sub may also contain '-', '=', '.' and '/'
    """
    eget = environ.get
    current.__dict__.clear()
    request = Request(environ)
    response = Response()
    session = Session()
    env = request.env
    #env.web2py_path = global_settings.applications_parent
    env.web2py_version = web2py_version
    #env.update(global_settings)
    static_file = False
    try:
        try:
            try:
                # ##################################################
                # handle fcgi missing path_info and query_string
                # select rewrite parameters
                # rewrite incoming URL
                # parse rewritten header variables
                # parse rewritten URL
                # serve file if static
                # ##################################################

                fixup_missing_path_info(environ)
                (static_file, version, environ) = url_in(request, environ)
                response.status = env.web2py_status_code or response.status

                if static_file:
                    if eget('QUERY_STRING', '').startswith('attachment'):
                        response.headers['Content-Disposition'] \
                            = 'attachment'
                    if version:
                        response.headers['Cache-Control'] = 'max-age=315360000'
                        response.headers[
                            'Expires'] = 'Thu, 31 Dec 2037 23:59:59 GMT'
                    response.stream(static_file, request=request)


                # ##################################################
                # fill in request items
                # ##################################################
                app = request.application  # must go after url_in!

                if not global_settings.local_hosts:
                    local_hosts = set(['127.0.0.1', '::ffff:127.0.0.1', '::1'])
                    if not global_settings.web2py_runtime_gae:
                        try:
                            fqdn = socket.getfqdn()
                            local_hosts.add(socket.gethostname())
                            local_hosts.add(fqdn)
                            local_hosts.update([
                                addrinfo[4][0] for addrinfo
                                in getipaddrinfo(fqdn)])
                            if env.server_name:
                                local_hosts.add(env.server_name)
                                local_hosts.update([
                                        addrinfo[4][0] for addrinfo
                                        in getipaddrinfo(env.server_name)])
                        except (socket.gaierror, TypeError):
                            pass
                    global_settings.local_hosts = list(local_hosts)
                else:
                    local_hosts = global_settings.local_hosts
                client = get_client(env)
                x_req_with = str(env.http_x_requested_with).lower()

                request.update(
                    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_SCHEMES or \
                        request.env.http_x_forwarded_proto in HTTPS_SCHEMES \
                        or env.https == 'on'
                    )
                request.compute_uuid()  # requires client
                request.url = environ['PATH_INFO']

                # ##################################################
                # access the requested application
                # ##################################################

                disabled = pjoin(request.folder, 'DISABLED')
                if not exists(request.folder):
                    if app == rwthread.routes.default_application \
                            and app != 'welcome':
                        redirect(URL('welcome', 'default', 'index'))
                    elif rwthread.routes.error_handler:
                        _handler = rwthread.routes.error_handler
                        redirect(URL(_handler['application'],
                                     _handler['controller'],
                                     _handler['function'],
                                     args=app))
                    else:
                        raise HTTP(404, rwthread.routes.error_message
                                   % 'invalid request',
                                   web2py_error='invalid application')
                elif not request.is_local and exists(disabled):
                    raise HTTP(503, "<html><body><h1>Temporarily down for maintenance</h1></body></html>")

                # ##################################################
                # build missing folders
                # ##################################################

                create_missing_app_folders(request)

                # ##################################################
                # get the GET and POST data
                # ##################################################

                #parse_get_post_vars(request, environ)

                # ##################################################
                # expose wsgi hooks for convenience
                # ##################################################

                request.wsgi = LazyWSGI(environ, request, response)

                # ##################################################
                # load cookies
                # ##################################################

                if env.http_cookie:
                    try:
                        request.cookies.load(env.http_cookie)
                    except Cookie.CookieError, e:
                        pass  # invalid cookies

                # ##################################################
                # try load session or create new session file
                # ##################################################

                if not env.web2py_disable_session:
                    session.connect(request, response)

                # ##################################################
                # run controller
                # ##################################################

                if global_settings.debugging and app != "admin":
                    import gluon.debug
                    # activate the debugger
                    gluon.debug.dbg.do_debug(mainpyfile=request.folder)

                serve_controller(request, response, session)

            except HTTP, http_response:

                if static_file:
                    return http_response.to(responder, env=env)

                if request.body:
                    request.body.close()

                if hasattr(current,'request'):

                    # ##################################################
                    # on success, try store session in database
                    # ##################################################
                    session._try_store_in_db(request, response)

                    # ##################################################
                    # on success, commit database
                    # ##################################################

                    if response.do_not_commit is True:
                        BaseAdapter.close_all_instances(None)
                    elif response.custom_commit:
                        BaseAdapter.close_all_instances(response.custom_commit)
                    else:
                        BaseAdapter.close_all_instances('commit')

                    # ##################################################
                    # if session not in db try store session on filesystem
                    # this must be done after trying to commit database!
                    # ##################################################

                    session._try_store_in_cookie_or_file(request, response)

                    # Set header so client can distinguish component requests.
                    if request.cid:
                        http_response.headers.setdefault(
                            'web2py-component-content', 'replace')

                    if request.ajax:
                        if response.flash:
                            http_response.headers['web2py-component-flash'] = \
                                urllib2.quote(xmlescape(response.flash)\
                                                  .replace('\n',''))
                        if response.js:
                            http_response.headers['web2py-component-command'] = \
                                urllib2.quote(response.js.replace('\n',''))

                    # ##################################################
                    # store cookies in headers
                    # ##################################################

                    session._fixup_before_save()
                    http_response.cookies2headers(response.cookies)

                ticket = None

            except RestrictedError, e:

                if request.body:
                    request.body.close()

                # ##################################################
                # on application error, rollback database
                # ##################################################

                # log tickets before rollback if not in DB
                if not request.tickets_db:
                    ticket = e.log(request) or 'unknown'
                # rollback
                if response._custom_rollback:
                    response._custom_rollback()
                else:
                    BaseAdapter.close_all_instances('rollback')
                # if tickets in db, reconnect and store it in db
                if request.tickets_db:
                    ticket = e.log(request) or 'unknown'

                http_response = \
                    HTTP(500, rwthread.routes.error_message_ticket %
                         dict(ticket=ticket),
                         web2py_error='ticket %s' % ticket)
Example #19
0
def env(app, dir='', nomodel=False):
    import gluon.html as html
    import gluon.validators as validators
    from gluon.http import HTTP, redirect
    from gluon.languages import translator
    from gluon.cache import Cache
    from gluon.globals import Request, Response, Session
    from gluon.sqlhtml import SQLFORM, SQLTABLE
    from gluon.dal import BaseAdapter, SQLDB, SQLField, DAL, Field
    from gluon.compileapp import local_import_aux, LoadFactory

    request = Request()
    response = Response()
    session = Session()

    if not dir:
        request.folder = os.path.join('applications', app)
    else:
        request.folder = dir

    environment = {}
    #    for key in html.__all__: environment[key]=eval('html.%s' % key)
    #    for key in validators.__all__: environment[key]=eval('validators.%s' % key)
    for key in html.__all__:
        environment[key] = getattr(html, key)
    for key in validators.__all__:
        environment[key] = getattr(validators, key)
    global __builtins__
    environment['__builtins__'] = __builtins__
    environment['T'] = translator(request)
    #    environment['HTTP']=HTTP
    #    environment['redirect']=redirect
    #    environment['request']=request
    #    environment['response']=response
    #    environment['session']=session
    #    environment['cache']=Cache(request)
    #    environment['SQLDB']=SQLDB
    #    SQLDB._set_thread_folder(os.path.join(request.folder,'databases'))
    #    environment['SQLField']=SQLField
    #    environment['SQLFORM']=SQLFORM
    #    environment['SQLTABLE']=SQLTABLE
    #
    #    if not nomodel:
    #        model_path = os.path.join(request.folder,'models', '*.py')
    #        from glob import glob
    #        for f in glob(model_path):
    #            fname, ext = os.path.splitext(f)
    #            execfile(f, environment)
    ##            print 'Imported "%s" model file' % fname

    environment['HTTP'] = HTTP
    environment['redirect'] = redirect
    environment['request'] = request
    environment['response'] = response
    environment['session'] = session
    environment['DAL'] = DAL
    environment['Field'] = Field
    environment['SQLDB'] = SQLDB  # for backward compatibility
    environment['SQLField'] = SQLField  # for backward compatibility
    environment['SQLFORM'] = SQLFORM
    environment['SQLTABLE'] = SQLTABLE
    environment['LOAD'] = LoadFactory(environment)
    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'))
    response._view_environment = copy.copy(environment)

    return environment
Example #20
0
def env(
    a,
    import_models=False,
    c=None,
    f=None,
    dir='',
    extra_request={},
):
    """
    Returns web2py execution environment for application (a), controller (c),
    function (f).
    If import_models is True the exec all application models into the
    environment.

    extra_request allows you to pass along any extra variables to the request
    object before your models get executed. This was mainly done to support
    web2py_utils.test_runner, however you can use it with any wrapper scripts
    that need access to the web2py environment.
    """

    request = Request({})
    response = Response()
    session = Session()
    request.application = a

    # Populate the dummy environment with sensible defaults.

    if not dir:
        request.folder = os.path.join('applications', a)
    else:
        request.folder = dir
    request.controller = c or 'default'
    request.function = f or 'index'
    response.view = '%s/%s.html' % (request.controller,
                                    request.function)
    if global_settings.cmd_options:
        ip = global_settings.cmd_options.ip
        port = global_settings.cmd_options.port
        request.is_shell = global_settings.cmd_options.shell is not None
        request.is_scheduler = global_settings.cmd_options.scheduler is not None
    else:
        ip, port = '127.0.0.1', '8000'
    request.env.http_host = '%s:%s' % (ip, port)
    request.env.remote_addr = '127.0.0.1'
    request.env.web2py_runtime_gae = global_settings.web2py_runtime_gae

    for k, v in extra_request.items():
        request[k] = v

    path_info = '/%s/%s/%s' % (a, c, f)
    if request.args:
        path_info = '%s/%s' % (path_info, '/'.join(request.args))
    if request.vars:
        vars = ['%s=%s' % (k, v) if v else '%s' % k
                for (k, v) in request.vars.iteritems()]
        path_info = '%s?%s' % (path_info, '&'.join(vars))
    request.env.path_info = path_info

    # Monkey patch so credentials checks pass.

    def check_credentials(request, other_application='admin'):
        return True

    fileutils.check_credentials = check_credentials

    environment = build_environment(request, response, session)

    if import_models:
        try:
            run_models_in(environment)
        except RestrictedError, e:
            sys.stderr.write(e.traceback + '\n')
            sys.exit(1)
Example #21
0
    def __call__(self, c=None, f='index', args=None, vars=None,
                 extension=None, target=None, ajax=False, ajax_trap=False,
                 url=None, user_signature=False, content='loading...', **attr):
        if args is None:
            args = []
        vars = Storage(vars or {})
        target = target or 'c' + str(random.random())[2:]
        attr['_id'] = target
        request = current.request
        if '.' in f:
            f, extension = f.rsplit('.', 1)
        if url or ajax:
            url = url or html.URL(request.application, c, f, r=request,
                                  args=args, vars=vars, extension=extension,
                                  user_signature=user_signature)
            script = html.SCRIPT('$.web2py.component("%s","%s")' % (url, target),
                                 _type="text/javascript")
            return html.TAG[''](script, html.DIV(content, **attr))
        else:
            if not isinstance(args, (list, tuple)):
                args = [args]
            c = c or request.controller

            other_request = Storage(request)
            other_request['env'] = Storage(request.env)
            other_request.controller = c
            other_request.function = f
            other_request.extension = extension or request.extension
            other_request.args = List(args)
            other_request.vars = vars
            other_request.get_vars = vars
            other_request.post_vars = Storage()
            other_response = Response()
            other_request.env.path_info = '/' + \
                '/'.join([request.application, c, f] +
                         [str(a) for a in other_request.args])
            other_request.env.query_string = \
                vars and html.URL(vars=vars).split('?')[1] or ''
            other_request.env.http_web2py_component_location = \
                request.env.path_info
            other_request.cid = target
            other_request.env.http_web2py_component_element = target
            other_response.view = '%s/%s.%s' % (c, f, other_request.extension)
            other_environment = copy.copy(self.environment)
            other_response._view_environment = other_environment
            other_response.generic_patterns = \
                copy.copy(current.response.generic_patterns)
            other_environment['request'] = other_request
            other_environment['response'] = other_response

            ## some magic here because current are thread-locals

            original_request, current.request = current.request, other_request
            original_response, current.response = current.response, other_response
            page = run_controller_in(c, f, other_environment)
            if isinstance(page, dict):
                other_response._vars = page
                other_response._view_environment.update(page)
                page = run_view_in(other_response._view_environment)

            current.request, current.response = original_request, original_response
            js = None
            if ajax_trap:
                link = html.URL(request.application, c, f, r=request,
                                args=args, vars=vars, extension=extension,
                                user_signature=user_signature)
                js = "$.web2py.trap_form('%s','%s');" % (link, target)
            script = js and html.SCRIPT(js, _type="text/javascript") or ''
            return html.TAG[''](html.DIV(html.XML(page), **attr), script)
Example #22
0
def render(content=None,
           stream=None,
           filename=None,
           path=None,
           context=None,
           lexers=None,
           delimiters='{{ }}',
           writer='response.write',
           reader=None):
    """
    Generic render function

    Args:
        content: default content
        stream: file-like obj to read template from
        filename: where to find template
        path: base path for templates
        context: env
        lexers: custom lexers to use
        delimiters: opening and closing tags
        writer: where to inject the resulting stream

    Example::
        >>> render()
        'hello world'
        >>> render(content='abc')
        'abc'
        >>> render(content="abc'")
        "abc'"
        >>> render(content=''''a"'bc''')
        'a"'bc'
        >>> render(content='a\\nbc')
        'a\\nbc'
        >>> render(content='a"bcd"e')
        'a"bcd"e'
        >>> render(content="'''a\\nc'''")
        "'''a\\nc'''"
        >>> render(content="'''a\\'c'''")
        "'''a\'c'''"
        >>> render(content='{{for i in range(a):}}{{=i}}<br />{{pass}}', context=dict(a=5))
        '0<br />1<br />2<br />3<br />4<br />'
        >>> render(content='{%for i in range(a):%}{%=i%}<br />{%pass%}', context=dict(a=5),delimiters=('{%','%}'))
        '0<br />1<br />2<br />3<br />4<br />'
        >>> render(content="{{='''hello\\nworld'''}}")
        'hello\\nworld'
        >>> render(content='{{for i in range(3):\\n=i\\npass}}')
        '012'

    """

    # If we don't have anything to render, why bother?
    if content is None and stream is None and filename is None:
        raise SyntaxError("Must specify a stream or filename or content")

    # handle defaults
    if context is None:
        context = {}
    if lexers is None:
        lexers = {}
    if isinstance(delimiters, basestring):
        delimiters = delimiters.split(' ', 1)
    if not reader:
        reader = file_reader

    # allow optional alternative delimiters
    if hasattr(context.get('response', None), 'delimiters'):
        if context['response'].delimiters is not None:
            delimiters = context['response'].delimiters

    # here to avoid circular Imports
    try:
        from gluon.globals import Response
    except ImportError:
        # Working standalone. Build a mock Response object.
        Response = DummyResponse

        # Add it to the context so we can use it.
        if 'NOESCAPE' not in context:
            context['NOESCAPE'] = NOESCAPE

    if isinstance(content, unicodeT):
        content = content.encode('utf8')

    # save current response class
    if context and 'response' in context:
        old_response_body = context['response'].body
        context['response'].body = StringIO()
    else:
        old_response_body = None
        context['response'] = Response()

    if content is None:
        if stream is not None:
            content = stream.read()
        elif filename is not None:
            content = reader(filename)
        else:
            content = '(no template found)'

    # Execute the template.
    code = str(
        TemplateParser(text=content,
                       context=context,
                       path=path,
                       lexers=lexers,
                       delimiters=delimiters,
                       writer=writer,
                       reader=reader))

    try:
        exec(code, context)
    except Exception:
        # for i,line in enumerate(code.split('\n')): print i,line
        raise

    # Returned the rendered content.
    text = context['response'].body.getvalue()
    if old_response_body is not None:
        context['response'].body = old_response_body
    return text
Example #23
0
    def __call__(self,
                 c=None,
                 f='index',
                 args=None,
                 vars=None,
                 extension=None,
                 target=None,
                 ajax=False,
                 ajax_trap=False,
                 url=None,
                 user_signature=False,
                 content='loading...',
                 **attr):
        if args is None:
            args = []
        vars = Storage(vars or {})
        target = target or 'c' + str(random.random())[2:]
        attr['_id'] = target
        request = current.request
        if '.' in f:
            f, extension = f.rsplit('.', 1)
        if url or ajax:
            url = url or html.URL(request.application,
                                  c,
                                  f,
                                  r=request,
                                  args=args,
                                  vars=vars,
                                  extension=extension,
                                  user_signature=user_signature)
            script = html.SCRIPT('$.web2py.component("%s","%s")' %
                                 (url, target),
                                 _type="text/javascript")
            return html.TAG[''](script, html.DIV(content, **attr))
        else:
            if not isinstance(args, (list, tuple)):
                args = [args]
            c = c or request.controller

            other_request = Storage(request)
            other_request['env'] = Storage(request.env)
            other_request.controller = c
            other_request.function = f
            other_request.extension = extension or request.extension
            other_request.args = List(args)
            other_request.vars = vars
            other_request.get_vars = vars
            other_request.post_vars = Storage()
            other_response = Response()
            other_request.env.path_info = '/' + \
                '/'.join([request.application, c, f] +
                         [str(a) for a in other_request.args])
            other_request.env.query_string = \
                vars and html.URL(vars=vars).split('?')[1] or ''
            other_request.env.http_web2py_component_location = \
                request.env.path_info
            other_request.cid = target
            other_request.env.http_web2py_component_element = target
            other_response.view = '%s/%s.%s' % (c, f, other_request.extension)
            other_environment = copy.copy(self.environment)
            other_response._view_environment = other_environment
            other_response.generic_patterns = \
                copy.copy(current.response.generic_patterns)
            other_environment['request'] = other_request
            other_environment['response'] = other_response

            ## some magic here because current are thread-locals

            original_request, current.request = current.request, other_request
            original_response, current.response = current.response, other_response
            page = run_controller_in(c, f, other_environment)
            if isinstance(page, dict):
                other_response._vars = page
                other_response._view_environment.update(page)
                page = run_view_in(other_response._view_environment)

            current.request, current.response = original_request, original_response
            js = None
            if ajax_trap:
                link = html.URL(request.application,
                                c,
                                f,
                                r=request,
                                args=args,
                                vars=vars,
                                extension=extension,
                                user_signature=user_signature)
                js = "$.web2py.trap_form('%s','%s');" % (link, target)
            script = js and html.SCRIPT(js, _type="text/javascript") or ''
            return html.TAG[''](html.DIV(html.XML(page), **attr), script)
# Cecill licence, see LICENSE
# $Id: chimitheque_ide_autocomplete.py 194 2015-02-23 16:27:16Z tbellemb $
# -*- coding: utf-8 -*-
if False:
    #
    # never imported - just for IDE autocompletion
    #
    from gluon import DAL
    db = DAL()
    from gluon import settings
    from gluon.cache import Cache
    from gluon.dal import Field
    from gluon.globals import Request
    request = Request()
    from gluon.globals import Response
    response = Response()
    from gluon.globals import Session
    session = Session()
    from gluon.html import *
    from gluon.http import HTTP
    from gluon.http import redirect
    from gluon.languages import translator
    T = translator(request)
    from gluon.sqlhtml import SQLFORM
    from gluon.tools import Auth
    auth = Auth()
    from gluon.tools import Crud, Mail
    from gluon.validators import *
    import sys
    mail = Mail()
    cache = Cache()
Example #25
0
def LOAD(c=None, f='index', args=None, vars=None,
         extension=None, target=None, ajax=False, ajax_trap=False,
         url=None, user_signature=False, timeout=None, times=1,
         content='loading...', post_vars=Storage(), **attr):
    """  LOADs a component into the action's document

    Args:
        c(str): controller
        f(str): function
        args(tuple or list): arguments
        vars(dict): vars
        extension(str): extension
        target(str): id of the target
        ajax(bool): True to enable AJAX bahaviour
        ajax_trap(bool): True if `ajax` is set to `True`, traps
            both links and forms "inside" the target
        url(str): overrides `c`,`f`,`args` and `vars`
        user_signature(bool): adds hmac signature to all links
            with a key that is different for every user
        timeout(int): in milliseconds, specifies the time to wait before
            starting the request or the frequency if times is greater than
            1 or "infinity"
        times(integer or str): how many times the component will be requested
            "infinity" or "continuous" are accepted to reload indefinitely the
            component
    """
    from gluon.html import TAG, DIV, URL, SCRIPT, XML
    if args is None:
        args = []
    vars = Storage(vars or {})
    target = target or 'c' + str(random.random())[2:]
    attr['_id'] = target
    request = current.request
    if '.' in f:
        f, extension = f.rsplit('.', 1)
    if url or ajax:
        url = url or URL(request.application, c, f, r=request,
                         args=args, vars=vars, extension=extension,
                         user_signature=user_signature)
        # timing options
        if isinstance(times, basestring):
            if times.upper() in ("INFINITY", "CONTINUOUS"):
                times = "Infinity"
            else:
                raise TypeError("Unsupported times argument %s" % times)
        elif isinstance(times, int):
            if times <= 0:
                raise ValueError("Times argument must be greater than zero, 'Infinity' or None")
        else:
            raise TypeError("Unsupported times argument type %s" % type(times))
        if timeout is not None:
            if not isinstance(timeout, (int, long)):
                raise ValueError("Timeout argument must be an integer or None")
            elif timeout <= 0:
                raise ValueError(
                    "Timeout argument must be greater than zero or None")
            statement = "$.web2py.component('%s','%s', %s, %s);" \
                % (url, target, timeout, times)
            attr['_data-w2p_timeout'] = timeout
            attr['_data-w2p_times'] = times
        else:
            statement = "$.web2py.component('%s','%s');" % (url, target)
        attr['_data-w2p_remote'] = url
        if not target is None:
            return DIV(content, **attr)

    else:
        if not isinstance(args, (list, tuple)):
            args = [args]
        c = c or request.controller
        other_request = Storage(request)
        other_request['env'] = Storage(request.env)
        other_request.controller = c
        other_request.function = f
        other_request.extension = extension or request.extension
        other_request.args = List(args)
        other_request.vars = vars
        other_request.get_vars = vars
        other_request.post_vars = post_vars
        other_response = Response()
        other_request.env.path_info = '/' + \
            '/'.join([request.application, c, f] +
                     map(str, other_request.args))
        other_request.env.query_string = \
            vars and URL(vars=vars).split('?')[1] or ''
        other_request.env.http_web2py_component_location = \
            request.env.path_info
        other_request.cid = target
        other_request.env.http_web2py_component_element = target
        other_request.restful = types.MethodType(request.restful.__func__, other_request) # A bit nasty but needed to use LOAD on action decorates with @request.restful()
        other_response.view = '%s/%s.%s' % (c, f, other_request.extension)

        other_environment = copy.copy(current.globalenv)  # NASTY

        other_response._view_environment = other_environment
        other_response.generic_patterns = \
            copy.copy(current.response.generic_patterns)
        other_environment['request'] = other_request
        other_environment['response'] = other_response

        ## some magic here because current are thread-locals

        original_request, current.request = current.request, other_request
        original_response, current.response = current.response, other_response
        page = run_controller_in(c, f, other_environment)
        if isinstance(page, dict):
            other_response._vars = page
            other_response._view_environment.update(page)
            page = run_view_in(other_response._view_environment)

        current.request, current.response = original_request, original_response
        js = None
        if ajax_trap:
            link = URL(request.application, c, f, r=request,
                       args=args, vars=vars, extension=extension,
                       user_signature=user_signature)
            js = "$.web2py.trap_form('%s','%s');" % (link, target)
        script = js and SCRIPT(js, _type="text/javascript") or ''
        return TAG[''](DIV(XML(page), **attr), script)
Example #26
0
def env(app, dir='', nomodel=False):
    import gluon.html as html
    import gluon.validators as validators
    from gluon.http import HTTP, redirect
    from gluon.languages import translator
    from gluon.cache import Cache
    from gluon.globals import Request, Response, Session
    from gluon.sqlhtml import SQLFORM, SQLTABLE
    from gluon.dal import BaseAdapter, SQLDB, SQLField, DAL, Field
    from gluon.compileapp import local_import_aux, LoadFactory
    
    request=Request()
    response=Response()
    session=Session()
    
    if not dir:
        request.folder = os.path.join('applications', app)
    else:
        request.folder = dir
        
    environment={}
#    for key in html.__all__: environment[key]=eval('html.%s' % key)
#    for key in validators.__all__: environment[key]=eval('validators.%s' % key)
    for key in html.__all__:
        environment[key] = getattr(html, key)
    for key in validators.__all__:
        environment[key] = getattr(validators, key)
    global __builtins__
    environment['__builtins__'] = __builtins__
    environment['T']=translator(request)
#    environment['HTTP']=HTTP
#    environment['redirect']=redirect
#    environment['request']=request
#    environment['response']=response
#    environment['session']=session
#    environment['cache']=Cache(request)
#    environment['SQLDB']=SQLDB
#    SQLDB._set_thread_folder(os.path.join(request.folder,'databases'))
#    environment['SQLField']=SQLField
#    environment['SQLFORM']=SQLFORM
#    environment['SQLTABLE']=SQLTABLE
#    
#    if not nomodel:
#        model_path = os.path.join(request.folder,'models', '*.py')
#        from glob import glob
#        for f in glob(model_path):
#            fname, ext = os.path.splitext(f)
#            execfile(f, environment)
##            print 'Imported "%s" model file' % fname

    environment['HTTP'] = HTTP
    environment['redirect'] = redirect
    environment['request'] = request
    environment['response'] = response
    environment['session'] = session
    environment['DAL'] = DAL
    environment['Field'] = Field
    environment['SQLDB'] = SQLDB        # for backward compatibility
    environment['SQLField'] = SQLField  # for backward compatibility
    environment['SQLFORM'] = SQLFORM
    environment['SQLTABLE'] = SQLTABLE
    environment['LOAD'] = LoadFactory(environment)
    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'))
    response._view_environment = copy.copy(environment)
    
    return environment
Example #27
0
def LOAD(c=None,
         f='index',
         args=None,
         vars=None,
         extension=None,
         target=None,
         ajax=False,
         ajax_trap=False,
         url=None,
         user_signature=False,
         timeout=None,
         times=1,
         content='loading...',
         **attr):
    """  LOAD a component into the action's document

    Timing options:
    -times: An integer or string ("infinity"/"continuous")
    specifies how many times the component is requested
    -timeout (milliseconds): specifies the time to wait before
    starting the request or the frequency if times is greater than
    1 or "infinity".
    Timing options default to the normal behavior. The component
    is added on page loading without delay.
    """
    from html import TAG, DIV, URL, SCRIPT, XML
    if args is None:
        args = []
    vars = Storage(vars or {})
    target = target or 'c' + str(random.random())[2:]
    attr['_id'] = target
    request = current.request
    if '.' in f:
        f, extension = f.rsplit('.', 1)
    if url or ajax:
        url = url or URL(request.application,
                         c,
                         f,
                         r=request,
                         args=args,
                         vars=vars,
                         extension=extension,
                         user_signature=user_signature)
        # timing options
        if isinstance(times, basestring):
            if times.upper() in ("INFINITY", "CONTINUOUS"):
                times = "Infinity"
            else:
                raise TypeError("Unsupported times argument %s" % times)
        elif isinstance(times, int):
            if times <= 0:
                raise ValueError(
                    "Times argument must be greater than zero, 'Infinity' or None"
                )
        else:
            raise TypeError("Unsupported times argument type %s" % type(times))
        if timeout is not None:
            if not isinstance(timeout, (int, long)):
                raise ValueError("Timeout argument must be an integer or None")
            elif timeout <= 0:
                raise ValueError(
                    "Timeout argument must be greater than zero or None")
            statement = "$.web2py.component('%s','%s', %s, %s);" \
                % (url, target, timeout, times)
            attr['_data-w2p_timeout'] = timeout
            attr['_data-w2p_times'] = times
        else:
            statement = "$.web2py.component('%s','%s');" % (url, target)
        attr['_data-w2p_remote'] = url
        if not target is None:
            return DIV(content, **attr)

    else:
        if not isinstance(args, (list, tuple)):
            args = [args]
        c = c or request.controller
        other_request = Storage(request)
        other_request['env'] = Storage(request.env)
        other_request.controller = c
        other_request.function = f
        other_request.extension = extension or request.extension
        other_request.args = List(args)
        other_request.vars = vars
        other_request.get_vars = vars
        other_request.post_vars = Storage()
        other_response = Response()
        other_request.env.path_info = '/' + \
            '/'.join([request.application, c, f] +
                     map(str, other_request.args))
        other_request.env.query_string = \
            vars and URL(vars=vars).split('?')[1] or ''
        other_request.env.http_web2py_component_location = \
            request.env.path_info
        other_request.cid = target
        other_request.env.http_web2py_component_element = target
        other_response.view = '%s/%s.%s' % (c, f, other_request.extension)

        other_environment = copy.copy(current.globalenv)  # NASTY

        other_response._view_environment = other_environment
        other_response.generic_patterns = \
            copy.copy(current.response.generic_patterns)
        other_environment['request'] = other_request
        other_environment['response'] = other_response

        ## some magic here because current are thread-locals

        original_request, current.request = current.request, other_request
        original_response, current.response = current.response, other_response
        page = run_controller_in(c, f, other_environment)
        if isinstance(page, dict):
            other_response._vars = page
            other_response._view_environment.update(page)
            run_view_in(other_response._view_environment)
            page = other_response.body.getvalue()
        current.request, current.response = original_request, original_response
        js = None
        if ajax_trap:
            link = URL(request.application,
                       c,
                       f,
                       r=request,
                       args=args,
                       vars=vars,
                       extension=extension,
                       user_signature=user_signature)
            js = "$.web2py.trap_form('%s','%s');" % (link, target)
        script = js and SCRIPT(js, _type="text/javascript") or ''
        return TAG[''](DIV(XML(page), **attr), script)
Example #28
0
def env(
    a,
    import_models=False,
    c=None,
    f=None,
    dir='',
    extra_request={},
):
    """
    Returns web2py execution environment for application (a), controller (c),
    function (f).
    If import_models is True the exec all application models into the
    environment.

    extra_request allows you to pass along any extra variables to the request
    object before your models get executed. This was mainly done to support
    web2py_utils.test_runner, however you can use it with any wrapper scripts
    that need access to the web2py environment.
    """

    request = Request({})
    response = Response()
    session = Session()
    request.application = a

    # Populate the dummy environment with sensible defaults.

    if not dir:
        request.folder = os.path.join('applications', a)
    else:
        request.folder = dir
    request.controller = c or 'default'
    request.function = f or 'index'
    response.view = '%s/%s.html' % (request.controller, request.function)
    if global_settings.cmd_options:
        ip = global_settings.cmd_options.ip
        port = global_settings.cmd_options.port
        request.is_shell = global_settings.cmd_options.shell is not None
        request.is_scheduler = global_settings.cmd_options.scheduler is not None
    else:
        ip, port = '127.0.0.1', '8000'
    request.env.http_host = '%s:%s' % (ip, port)
    request.env.remote_addr = '127.0.0.1'
    request.env.web2py_runtime_gae = global_settings.web2py_runtime_gae

    for k, v in extra_request.items():
        request[k] = v

    path_info = '/%s/%s/%s' % (a, c, f)
    if request.args:
        path_info = '%s/%s' % (path_info, '/'.join(request.args))
    if request.vars:
        vars = [
            '%s=%s' % (k, v) if v else '%s' % k
            for (k, v) in request.vars.iteritems()
        ]
        path_info = '%s?%s' % (path_info, '&'.join(vars))
    request.env.path_info = path_info

    # Monkey patch so credentials checks pass.

    def check_credentials(request, other_application='admin'):
        return True

    fileutils.check_credentials = check_credentials

    environment = build_environment(request, response, session)

    if import_models:
        try:
            run_models_in(environment)
        except RestrictedError, e:
            sys.stderr.write(e.traceback + '\n')
            sys.exit(1)
Example #29
0
 def setUp(self):
     from gluon.globals import current
     current.response = Response()
Example #30
0
def render(content="hello world",
           stream=None,
           filename=None,
           path=None,
           context={},
           lexers={},
           delimiters=('{{', '}}'),
           writer='response.write'
           ):
    """
    Generic render function

    Args:
        content: default content
        stream: file-like obj to read template from
        filename: where to find template
        path: base path for templates
        context: env
        lexers: custom lexers to use
        delimiters: opening and closing tags
        writer: where to inject the resulting stream

    Example::
        >>> render()
        'hello world'
        >>> render(content='abc')
        'abc'
        >>> render(content="abc'")
        "abc'"
        >>> render(content=''''a"'bc''')
        'a"'bc'
        >>> render(content='a\\nbc')
        'a\\nbc'
        >>> render(content='a"bcd"e')
        'a"bcd"e'
        >>> render(content="'''a\\nc'''")
        "'''a\\nc'''"
        >>> render(content="'''a\\'c'''")
        "'''a\'c'''"
        >>> render(content='{{for i in range(a):}}{{=i}}<br />{{pass}}', context=dict(a=5))
        '0<br />1<br />2<br />3<br />4<br />'
        >>> render(content='{%for i in range(a):%}{%=i%}<br />{%pass%}', context=dict(a=5),delimiters=('{%','%}'))
        '0<br />1<br />2<br />3<br />4<br />'
        >>> render(content="{{='''hello\\nworld'''}}")
        'hello\\nworld'
        >>> render(content='{{for i in range(3):\\n=i\\npass}}')
        '012'

    """
    # here to avoid circular Imports
    try:
        from gluon.globals import Response
    except ImportError:
        # Working standalone. Build a mock Response object.
        Response = DummyResponse

        # Add it to the context so we can use it.
        if 'NOESCAPE' not in context:
            context['NOESCAPE'] = NOESCAPE

    if isinstance(content, unicodeT):
        content = content.encode('utf8')

    # save current response class
    if context and 'response' in context:
        old_response_body = context['response'].body
        context['response'].body = StringIO()
    else:
        old_response_body = None
        context['response'] = Response()

    # If we don't have anything to render, why bother?
    if not content and not stream and not filename:
        raise SyntaxError("Must specify a stream or filename or content")

    # Here for legacy purposes, probably can be reduced to
    # something more simple.
    close_stream = False
    if not stream:
        if filename:
            stream = open(filename, 'rb')
            close_stream = True
        elif content:
            stream = StringIO(to_native(content))

    # Execute the template.
    code = str(TemplateParser(stream.read(
    ), context=context, path=path, lexers=lexers, delimiters=delimiters, writer=writer))

    try:
        exec(code, context)
    except Exception:
        # for i,line in enumerate(code.split('\n')): print i,line
        raise

    if close_stream:
        stream.close()

    # Returned the rendered content.
    text = context['response'].body.getvalue()
    if old_response_body is not None:
        context['response'].body = old_response_body
    return text
Example #31
0
    def test_include_files(self):

        def return_includes(response, extensions=None):
            response.include_files(extensions)
            return response.body.getvalue()

        response = Response()
        response.files.append(URL('a', 'static', 'css/file.css'))
        content = return_includes(response)
        self.assertEqual(content, '<link href="/a/static/css/file.css" rel="stylesheet" type="text/css" />')

        response = Response()
        response.files.append(URL('a', 'static', 'css/file.js'))
        content = return_includes(response)
        self.assertEqual(content, '<script src="/a/static/css/file.js" type="text/javascript"></script>')

        response = Response()
        response.files.append(URL('a', 'static', 'css/file.coffee'))
        content = return_includes(response)
        self.assertEqual(content, '<script src="/a/static/css/file.coffee" type="text/coffee"></script>')

        response = Response()
        response.files.append(URL('a', 'static', 'css/file.ts'))
        content = return_includes(response)
        self.assertEqual(content, '<script src="/a/static/css/file.ts" type="text/typescript"></script>')

        response = Response()
        response.files.append(URL('a', 'static', 'css/file.less'))
        content = return_includes(response)
        self.assertEqual(content, '<link href="/a/static/css/file.less" rel="stylesheet/less" type="text/css" />')

        response = Response()
        response.files.append(('css:inline', 'background-color; white;'))
        content = return_includes(response)
        self.assertEqual(content, '<style type="text/css">\nbackground-color; white;\n</style>')

        response = Response()
        response.files.append(('js:inline', 'alert("hello")'))
        content = return_includes(response)
        self.assertEqual(content, '<script type="text/javascript">\nalert("hello")\n</script>')

        response = Response()
        response.files.append('https://code.jquery.com/jquery-1.11.3.min.js')
        content = return_includes(response)
        self.assertEqual(content, '<script src="https://code.jquery.com/jquery-1.11.3.min.js" type="text/javascript"></script>')

        response = Response()
        response.files.append('https://code.jquery.com/jquery-1.11.3.min.js?var=0')
        content = return_includes(response)
        self.assertEqual(content, '<script src="https://code.jquery.com/jquery-1.11.3.min.js?var=0" type="text/javascript"></script>')

        response = Response()
        response.files.append('https://code.jquery.com/jquery-1.11.3.min.js?var=0')
        response.files.append('https://code.jquery.com/jquery-1.11.3.min.js?var=0')
        response.files.append(URL('a', 'static', 'css/file.css'))
        response.files.append(URL('a', 'static', 'css/file.css'))
        content = return_includes(response)
        self.assertEqual(content,
                         '<script src="https://code.jquery.com/jquery-1.11.3.min.js?var=0" type="text/javascript"></script>' +
                         '<link href="/a/static/css/file.css" rel="stylesheet" type="text/css" />')

        response = Response()
        response.files.append(('js', 'http://maps.google.com/maps/api/js?sensor=false'))
        response.files.append('https://code.jquery.com/jquery-1.11.3.min.js?var=0')
        response.files.append(URL('a', 'static', 'css/file.css'))
        response.files.append(URL('a', 'static', 'css/file.ts'))
        content = return_includes(response)
        self.assertEqual(content,
                         '<script src="http://maps.google.com/maps/api/js?sensor=false" type="text/javascript"></script>' +
                         '<script src="https://code.jquery.com/jquery-1.11.3.min.js?var=0" type="text/javascript"></script>' +
                         '<link href="/a/static/css/file.css" rel="stylesheet" type="text/css" />' +
                         '<script src="/a/static/css/file.ts" type="text/typescript"></script>'
                         )

        response = Response()
        response.files.append(URL('a', 'static', 'css/file.js'))
        response.files.append(URL('a', 'static', 'css/file.css'))
        content = return_includes(response, extensions=['css'])
        self.assertEqual(content, '<link href="/a/static/css/file.css" rel="stylesheet" type="text/css" />')

        # regr test for #628
        response = Response()
        response.files.append('http://maps.google.com/maps/api/js?sensor=false')
        content = return_includes(response)
        self.assertEqual(content, '')

        # regr test for #628
        response = Response()
        response.files.append(('js', 'http://maps.google.com/maps/api/js?sensor=false'))
        content = return_includes(response)
        self.assertEqual(content, '<script src="http://maps.google.com/maps/api/js?sensor=false" type="text/javascript"></script>')

        response = Response()
        response.files.append(['js', 'http://maps.google.com/maps/api/js?sensor=false'])
        content = return_includes(response)
        self.assertEqual(content, '<script src="http://maps.google.com/maps/api/js?sensor=false" type="text/javascript"></script>')

        response = Response()
        response.files.append(('js1', 'http://maps.google.com/maps/api/js?sensor=false'))
        content = return_includes(response)
        self.assertEqual(content, '')
Example #32
0
def LOAD(c=None, f='index', args=None, vars=None,
         extension=None, target=None, ajax=False, ajax_trap=False,
         url=None, user_signature=False, timeout=None, times=1,
         content='loading...', **attr):
    """  LOAD a component into the action's document

    Timing options:
    -times: An integer or string ("infinity"/"continuous")
    specifies how many times the component is requested
    -timeout (milliseconds): specifies the time to wait before
    starting the request or the frequency if times is greater than
    1 or "infinity".
    Timing options default to the normal behavior. The component
    is added on page loading without delay.
    """
    from html import TAG, DIV, URL, SCRIPT, XML
    if args is None:
        args = []
    vars = Storage(vars or {})
    target = target or 'c' + str(random.random())[2:]
    attr['_id'] = target
    request = current.request
    if '.' in f:
        f, extension = f.rsplit('.', 1)
    if url or ajax:
        url = url or URL(request.application, c, f, r=request,
                         args=args, vars=vars, extension=extension,
                         user_signature=user_signature)
        # timing options
        if isinstance(times, basestring):
            if times.upper() in ("INFINITY", "CONTINUOUS"):
                times = "Infinity"
            else:
                raise TypeError("Unsupported times argument %s" % times)
        elif isinstance(times, int):
            if times <= 0:
                raise ValueError("Times argument must be greater than zero, 'Infinity' or None")
        else:
            raise TypeError("Unsupported times argument type %s" % type(times))
        if timeout is not None:
            if not isinstance(timeout, (int, long)):
                raise ValueError("Timeout argument must be an integer or None")
            elif timeout <= 0:
                raise ValueError(
                    "Timeout argument must be greater than zero or None")
            statement = "$.web2py.component('%s','%s', %s, %s);" \
                % (url, target, timeout, times)
            attr['_data-w2p_timeout'] = timeout
            attr['_data-w2p_times'] = times
        else:
            statement = "$.web2py.component('%s','%s');" % (url, target)
        attr['_data-w2p_remote'] = url
        if not target is None:
            return DIV(content, **attr)

    else:
        if not isinstance(args, (list, tuple)):
            args = [args]
        c = c or request.controller
        other_request = Storage(request)
        other_request['env'] = Storage(request.env)
        other_request.controller = c
        other_request.function = f
        other_request.extension = extension or request.extension
        other_request.args = List(args)
        other_request.vars = vars
        other_request.get_vars = vars
        other_request.post_vars = Storage()
        other_response = Response()
        other_request.env.path_info = '/' + \
            '/'.join([request.application, c, f] +
                     map(str, other_request.args))
        other_request.env.query_string = \
            vars and URL(vars=vars).split('?')[1] or ''
        other_request.env.http_web2py_component_location = \
            request.env.path_info
        other_request.cid = target
        other_request.env.http_web2py_component_element = target
        other_response.view = '%s/%s.%s' % (c, f, other_request.extension)

        other_environment = copy.copy(current.globalenv)  # NASTY

        other_response._view_environment = other_environment
        other_response.generic_patterns = \
            copy.copy(current.response.generic_patterns)
        other_environment['request'] = other_request
        other_environment['response'] = other_response

        ## some magic here because current are thread-locals

        original_request, current.request = current.request, other_request
        original_response, current.response = current.response, other_response
        page = run_controller_in(c, f, other_environment)
        if isinstance(page, dict):
            other_response._vars = page
            other_response._view_environment.update(page)
            run_view_in(other_response._view_environment)
            page = other_response.body.getvalue()
        current.request, current.response = original_request, original_response
        js = None
        if ajax_trap:
            link = URL(request.application, c, f, r=request,
                       args=args, vars=vars, extension=extension,
                       user_signature=user_signature)
            js = "$.web2py.trap_form('%s','%s');" % (link, target)
        script = js and SCRIPT(js, _type="text/javascript") or ''
        return TAG[''](DIV(XML(page), **attr), script)
Example #33
0
def LOAD(c=None,
         f='index',
         args=None,
         vars=None,
         extension=None,
         target=None,
         ajax=False,
         ajax_trap=False,
         url=None,
         user_signature=False,
         timeout=None,
         times=1,
         content='loading...',
         post_vars=Storage(),
         **attr):
    """  LOADs a component into the action's document

    Args:
        c(str): controller
        f(str): function
        args(tuple or list): arguments
        vars(dict): vars
        extension(str): extension
        target(str): id of the target
        ajax(bool): True to enable AJAX behaviour
        ajax_trap(bool): True if `ajax` is set to `True`, traps
            both links and forms "inside" the target
        url(str): overrides `c`, `f`, `args` and `vars`
        user_signature(bool): adds hmac signature to all links
            with a key that is different for every user
        timeout(int): in milliseconds, specifies the time to wait before
            starting the request or the frequency if times is greater than
            1 or "infinity"
        times(integer or str): how many times the component will be requested
            "infinity" or "continuous" are accepted to reload indefinitely the
            component
    """
    if args is None:
        args = []
    vars = Storage(vars or {})
    target = target or 'c' + str(random.random())[2:]
    attr['_id'] = target
    request = current.request
    if '.' in f:
        f, extension = f.rsplit('.', 1)
    if url or ajax:
        url = url or html.URL(request.application,
                              c,
                              f,
                              r=request,
                              args=args,
                              vars=vars,
                              extension=extension,
                              user_signature=user_signature)
        # timing options
        if isinstance(times, basestring):
            if times.upper() in ("INFINITY", "CONTINUOUS"):
                times = "Infinity"
            else:
                # FIXME: should be a ValueError
                raise TypeError("Unsupported times argument %s" % times)
        elif isinstance(times, int):
            if times <= 0:
                raise ValueError(
                    "Times argument must be greater than zero, 'Infinity' or None"
                )
        else:
            # NOTE: why do not use ValueError only?
            raise TypeError("Unsupported times argument type %s" % type(times))
        if timeout is not None:
            if not isinstance(timeout, integer_types):
                raise ValueError("Timeout argument must be an integer or None")
            elif timeout <= 0:
                raise ValueError(
                    "Timeout argument must be greater than zero or None")
            statement = "$.web2py.component('%s','%s', %s, %s);" \
                % (url, target, timeout, times)
            attr['_data-w2p_timeout'] = timeout
            attr['_data-w2p_times'] = times
        else:
            statement = "$.web2py.component('%s','%s');" % (url, target)
        attr['_data-w2p_remote'] = url
        if target is not None:
            return html.DIV(content, **attr)

    else:
        if not isinstance(args, (list, tuple)):
            args = [args]
        c = c or request.controller
        other_request = Storage(request)
        other_request['env'] = Storage(request.env)
        other_request.controller = c
        other_request.function = f
        other_request.extension = extension or request.extension
        other_request.args = List(args)
        other_request.vars = vars
        other_request.get_vars = vars
        other_request.post_vars = post_vars
        other_response = Response()
        other_request.env.path_info = '/' + \
            '/'.join([request.application, c, f] +
                     [str(a) for a in other_request.args])
        other_request.env.query_string = \
            vars and html.URL(vars=vars).split('?')[1] or ''
        other_request.env.http_web2py_component_location = \
            request.env.path_info
        other_request.cid = target
        other_request.env.http_web2py_component_element = target
        other_request.restful = types.MethodType(request.restful.__func__,
                                                 other_request)
        # A bit nasty but needed to use LOAD on action decorates with @request.restful()
        other_response.view = '%s/%s.%s' % (c, f, other_request.extension)

        other_environment = copy.copy(current.globalenv)  # FIXME: NASTY

        other_response._view_environment = other_environment
        other_response.generic_patterns = \
            copy.copy(current.response.generic_patterns)
        other_environment['request'] = other_request
        other_environment['response'] = other_response

        ## some magic here because current are thread-locals

        original_request, current.request = current.request, other_request
        original_response, current.response = current.response, other_response
        page = run_controller_in(c, f, other_environment)
        if isinstance(page, dict):
            other_response._vars = page
            other_response._view_environment.update(page)
            page = run_view_in(other_response._view_environment)

        current.request, current.response = original_request, original_response
        js = None
        if ajax_trap:
            link = html.URL(request.application,
                            c,
                            f,
                            r=request,
                            args=args,
                            vars=vars,
                            extension=extension,
                            user_signature=user_signature)
            js = "$.web2py.trap_form('%s','%s');" % (link, target)
        script = js and html.SCRIPT(js, _type="text/javascript") or ''
        return html.TAG[''](html.DIV(html.XML(page), **attr), script)
Example #34
0
def render(content=None,
           stream=None,
           filename=None,
           path=None,
           context=None,
           lexers=None,
           delimiters='{{ }}',
           writer='response.write',
           reader=None
           ):
    """
    Generic render function

    Args:
        content: default content
        stream: file-like obj to read template from
        filename: where to find template
        path: base path for templates
        context: env
        lexers: custom lexers to use
        delimiters: opening and closing tags
        writer: where to inject the resulting stream

    Example::
        >>> render()
        'hello world'
        >>> render(content='abc')
        'abc'
        >>> render(content="abc'")
        "abc'"
        >>> render(content=''''a"'bc''')
        'a"'bc'
        >>> render(content='a\\nbc')
        'a\\nbc'
        >>> render(content='a"bcd"e')
        'a"bcd"e'
        >>> render(content="'''a\\nc'''")
        "'''a\\nc'''"
        >>> render(content="'''a\\'c'''")
        "'''a\'c'''"
        >>> render(content='{{for i in range(a):}}{{=i}}<br />{{pass}}', context=dict(a=5))
        '0<br />1<br />2<br />3<br />4<br />'
        >>> render(content='{%for i in range(a):%}{%=i%}<br />{%pass%}', context=dict(a=5),delimiters=('{%','%}'))
        '0<br />1<br />2<br />3<br />4<br />'
        >>> render(content="{{='''hello\\nworld'''}}")
        'hello\\nworld'
        >>> render(content='{{for i in range(3):\\n=i\\npass}}')
        '012'

    """

    # If we don't have anything to render, why bother?
    if content is None and stream is None and filename is None:
        raise SyntaxError("Must specify a stream or filename or content")

    # handle defaults
    if context is None:
        context = {}
    if lexers is None:
        lexers = {}
    if isinstance(delimiters, basestring):
        delimiters = delimiters.split(' ',1)
    if not reader:
        reader = file_reader

    # allow optional alternative delimiters
    if hasattr(context.get('response', None), 'delimiters'):
        if context['response'].delimiters is not None:
            delimiters = context['response'].delimiters

    # here to avoid circular Imports
    try:
        from gluon.globals import Response
    except ImportError:
        # Working standalone. Build a mock Response object.
        Response = DummyResponse

        # Add it to the context so we can use it.
        if 'NOESCAPE' not in context:
            context['NOESCAPE'] = NOESCAPE

    if isinstance(content, unicodeT):
        content = content.encode('utf8')

    # save current response class
    if context and 'response' in context:
        old_response_body = context['response'].body
        context['response'].body = StringIO()
    else:
        old_response_body = None
        context['response'] = Response()


    if content is None:
        if stream is not None:
            content = stream.read()
        elif filename is not None:
            content = reader(filename)
        else:
            content = '(no template found)'

    # Execute the template.
    code = str(TemplateParser(text=content,
                              context=context,
                              path=path,
                              lexers=lexers,
                              delimiters=delimiters,
                              writer=writer,
                              reader=reader))

    try:
        exec(code, context)
    except Exception:
        # for i,line in enumerate(code.split('\n')): print i,line
        raise

    # Returned the rendered content.
    text = context['response'].body.getvalue()
    if old_response_body is not None:
        context['response'].body = old_response_body
    return text
Example #35
0
def wsgibase(environ, responder):
    """
    The gluon wsgi application. The first function called when a page
    is requested (static or dynamic). It can be called by paste.httpserver
    or by apache mod_wsgi (or any WSGI-compatible server).

      - fills request with info
      - the environment variables, replacing '.' with '_'
      - adds web2py path and version info
      - compensates for fcgi missing path_info and query_string
      - validates the path in url

    The url path must be either:

    1. for static pages:

      - /<application>/static/<file>

    2. for dynamic pages:

      - /<application>[/<controller>[/<function>[/<sub>]]][.<extension>]

    The naming conventions are:

      - application, controller, function and extension may only contain
        `[a-zA-Z0-9_]`
      - file and sub may also contain '-', '=', '.' and '/'
    """
    eget = environ.get
    current.__dict__.clear()
    request = Request(environ)
    response = Response()
    session = Session()
    env = request.env
    #env.web2py_path = global_settings.applications_parent
    env.web2py_version = web2py_version
    #env.update(global_settings)
    static_file = False
    try:
        try:
            try:
                # ##################################################
                # handle fcgi missing path_info and query_string
                # select rewrite parameters
                # rewrite incoming URL
                # parse rewritten header variables
                # parse rewritten URL
                # serve file if static
                # ##################################################

                fixup_missing_path_info(environ)
                (static_file, version, environ) = url_in(request, environ)
                response.status = env.web2py_status_code or response.status

                if static_file:
                    if eget('QUERY_STRING', '').startswith('attachment'):
                        response.headers['Content-Disposition'] \
                            = 'attachment'
                    if version:
                        response.headers['Cache-Control'] = 'max-age=315360000'
                        response.headers[
                            'Expires'] = 'Thu, 31 Dec 2037 23:59:59 GMT'
                    response.stream(static_file, request=request)

                # ##################################################
                # fill in request items
                # ##################################################
                app = request.application  # must go after url_in!

                if not global_settings.local_hosts:
                    local_hosts = set(['127.0.0.1', '::ffff:127.0.0.1', '::1'])
                    if not global_settings.web2py_runtime_gae:
                        try:
                            fqdn = socket.getfqdn()
                            local_hosts.add(socket.gethostname())
                            local_hosts.add(fqdn)
                            local_hosts.update([
                                addrinfo[4][0]
                                for addrinfo in getipaddrinfo(fqdn)
                            ])
                            if env.server_name:
                                local_hosts.add(env.server_name)
                                local_hosts.update([
                                    addrinfo[4][0] for addrinfo in
                                    getipaddrinfo(env.server_name)
                                ])
                        except (socket.gaierror, TypeError):
                            pass
                    global_settings.local_hosts = list(local_hosts)
                else:
                    local_hosts = global_settings.local_hosts
                client = get_client(env)
                x_req_with = str(env.http_x_requested_with).lower()

                request.update(
                    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_SCHEMES or \
                        request.env.http_x_forwarded_proto in HTTPS_SCHEMES \
                        or env.https == 'on'
                    )
                request.compute_uuid()  # requires client
                request.url = environ['PATH_INFO']

                # ##################################################
                # access the requested application
                # ##################################################

                disabled = pjoin(request.folder, 'DISABLED')
                if not exists(request.folder):
                    if app == rwthread.routes.default_application \
                            and app != 'welcome':
                        redirect(URL('welcome', 'default', 'index'))
                    elif rwthread.routes.error_handler:
                        _handler = rwthread.routes.error_handler
                        redirect(
                            URL(_handler['application'],
                                _handler['controller'],
                                _handler['function'],
                                args=app))
                    else:
                        raise HTTP(404,
                                   rwthread.routes.error_message %
                                   'invalid request',
                                   web2py_error='invalid application')
                elif not request.is_local and exists(disabled):
                    raise HTTP(
                        503,
                        "<html><body><h1>Temporarily down for maintenance</h1></body></html>"
                    )

                # ##################################################
                # build missing folders
                # ##################################################

                create_missing_app_folders(request)

                # ##################################################
                # get the GET and POST data
                # ##################################################

                #parse_get_post_vars(request, environ)

                # ##################################################
                # expose wsgi hooks for convenience
                # ##################################################

                request.wsgi = LazyWSGI(environ, request, response)

                # ##################################################
                # load cookies
                # ##################################################

                if env.http_cookie:
                    try:
                        request.cookies.load(env.http_cookie)
                    except Cookie.CookieError, e:
                        pass  # invalid cookies

                # ##################################################
                # try load session or create new session file
                # ##################################################

                if not env.web2py_disable_session:
                    session.connect(request, response)

                # ##################################################
                # run controller
                # ##################################################

                if global_settings.debugging and app != "admin":
                    import gluon.debug
                    # activate the debugger
                    gluon.debug.dbg.do_debug(mainpyfile=request.folder)

                serve_controller(request, response, session)

            except HTTP, http_response:

                if static_file:
                    return http_response.to(responder, env=env)

                if request.body:
                    request.body.close()

                if hasattr(current, 'request'):

                    # ##################################################
                    # on success, try store session in database
                    # ##################################################
                    session._try_store_in_db(request, response)

                    # ##################################################
                    # on success, commit database
                    # ##################################################

                    if response.do_not_commit is True:
                        BaseAdapter.close_all_instances(None)
                    elif response.custom_commit:
                        BaseAdapter.close_all_instances(response.custom_commit)
                    else:
                        BaseAdapter.close_all_instances('commit')

                    # ##################################################
                    # if session not in db try store session on filesystem
                    # this must be done after trying to commit database!
                    # ##################################################

                    session._try_store_in_cookie_or_file(request, response)

                    # Set header so client can distinguish component requests.
                    if request.cid:
                        http_response.headers.setdefault(
                            'web2py-component-content', 'replace')

                    if request.ajax:
                        if response.flash:
                            http_response.headers['web2py-component-flash'] = \
                                urllib2.quote(xmlescape(response.flash)\
                                                  .replace('\n',''))
                        if response.js:
                            http_response.headers['web2py-component-command'] = \
                                urllib2.quote(response.js.replace('\n',''))

                    # ##################################################
                    # store cookies in headers
                    # ##################################################

                    session._fixup_before_save()
                    http_response.cookies2headers(response.cookies)

                ticket = None

            except RestrictedError, e:

                if request.body:
                    request.body.close()

                # ##################################################
                # on application error, rollback database
                # ##################################################

                # log tickets before rollback if not in DB
                if not request.tickets_db:
                    ticket = e.log(request) or 'unknown'
                # rollback
                if response._custom_rollback:
                    response._custom_rollback()
                else:
                    BaseAdapter.close_all_instances('rollback')
                # if tickets in db, reconnect and store it in db
                if request.tickets_db:
                    ticket = e.log(request) or 'unknown'

                http_response = \
                    HTTP(500, rwthread.routes.error_message_ticket %
                         dict(ticket=ticket),
                         web2py_error='ticket %s' % ticket)
Example #36
0
def render(content="hello world",
           stream=None,
           filename=None,
           path=None,
           context={},
           lexers={},
           delimiters=('{{', '}}'),
           writer='response.write'):
    """
    Generic render function

    Args:
        content: default content
        stream: file-like obj to read template from
        filename: where to find template
        path: base path for templates
        context: env
        lexers: custom lexers to use
        delimiters: opening and closing tags
        writer: where to inject the resulting stream

    Example::
        >>> render()
        'hello world'
        >>> render(content='abc')
        'abc'
        >>> render(content="abc'")
        "abc'"
        >>> render(content=''''a"'bc''')
        'a"'bc'
        >>> render(content='a\\nbc')
        'a\\nbc'
        >>> render(content='a"bcd"e')
        'a"bcd"e'
        >>> render(content="'''a\\nc'''")
        "'''a\\nc'''"
        >>> render(content="'''a\\'c'''")
        "'''a\'c'''"
        >>> render(content='{{for i in range(a):}}{{=i}}<br />{{pass}}', context=dict(a=5))
        '0<br />1<br />2<br />3<br />4<br />'
        >>> render(content='{%for i in range(a):%}{%=i%}<br />{%pass%}', context=dict(a=5),delimiters=('{%','%}'))
        '0<br />1<br />2<br />3<br />4<br />'
        >>> render(content="{{='''hello\\nworld'''}}")
        'hello\\nworld'
        >>> render(content='{{for i in range(3):\\n=i\\npass}}')
        '012'

    """
    # here to avoid circular Imports
    try:
        from gluon.globals import Response
    except ImportError:
        # Working standalone. Build a mock Response object.
        Response = DummyResponse

        # Add it to the context so we can use it.
        if not 'NOESCAPE' in context:
            context['NOESCAPE'] = NOESCAPE

    if isinstance(content, unicodeT):
        content = content.encode('utf8')

    # save current response class
    if context and 'response' in context:
        old_response_body = context['response'].body
        context['response'].body = StringIO()
    else:
        old_response_body = None
        context['response'] = Response()

    # If we don't have anything to render, why bother?
    if not content and not stream and not filename:
        raise SyntaxError("Must specify a stream or filename or content")

    # Here for legacy purposes, probably can be reduced to
    # something more simple.
    close_stream = False
    if not stream:
        if filename:
            stream = open(filename, 'rb')
            close_stream = True
        elif content:
            stream = StringIO(to_native(content))

    # Execute the template.
    code = str(
        TemplateParser(stream.read(),
                       context=context,
                       path=path,
                       lexers=lexers,
                       delimiters=delimiters,
                       writer=writer))

    try:
        exec(code, context)
    except Exception:
        # for i,line in enumerate(code.split('\n')): print i,line
        raise

    if close_stream:
        stream.close()

    # Returned the rendered content.
    text = context['response'].body.getvalue()
    if old_response_body is not None:
        context['response'].body = old_response_body
    return text