diff --git a/applications/admin/controllers/default.py b/applications/admin/controllers/default.py index b24f347a..547d6c94 100644 --- a/applications/admin/controllers/default.py +++ b/applications/admin/controllers/default.py @@ -1,4 +1,4 @@ -# coding: utf8 +# -*- coding: utf-8 -*- EXPERIMENTAL_STUFF = True MAXNFILES = 1000 @@ -1292,7 +1292,7 @@ def create_file(): langinfo = read_possible_languages(apath(app, r=request))[lang] text = dedent(""" #!/usr/bin/env python - # -*- coding: utf8 -*- + # -*- coding: utf-8 -*- # Plural-Forms for %(lang)s (%(langname)s) nplurals=2 # for example, English language has 2 forms: @@ -1333,7 +1333,7 @@ def create_file(): if len(filename) == 3: raise SyntaxError - text = '# coding: utf8\n' + text = '# -*- coding: utf-8 -*-\n' elif path[-13:] == '/controllers/': # Handle python controllers @@ -1343,7 +1343,7 @@ def create_file(): if len(filename) == 3: raise SyntaxError - text = '# coding: utf8\n# %s\ndef index(): return dict(message="hello from %s")' + text = '# -*- coding: utf-8 -*-\n# %s\ndef index(): return dict(message="hello from %s")' text = text % (T('try something like'), filename) elif path[-7:] == '/views/': @@ -1383,7 +1383,7 @@ def create_file(): text = dedent(""" #!/usr/bin/env python - # coding: utf8 + # -*- coding: utf-8 -*- from gluon import *\n""")[1:] elif (path[-8:] == '/static/') or (path[-9:] == '/private/'): diff --git a/applications/admin/languages/af.py b/applications/admin/languages/af.py index 5d164923..d1a83621 100644 --- a/applications/admin/languages/af.py +++ b/applications/admin/languages/af.py @@ -1,4 +1,4 @@ -# coding: utf8 +# -*- coding: utf-8 -*- { '!langcode!': 'af', '!langname!': 'Afrikaanse', diff --git a/applications/admin/languages/bg.py b/applications/admin/languages/bg.py index 46e90655..c8d02f87 100644 --- a/applications/admin/languages/bg.py +++ b/applications/admin/languages/bg.py @@ -1,4 +1,4 @@ -# coding: utf8 +# -*- coding: utf-8 -*- { '!langcode!': 'bg', '!langname!': 'Български', diff --git a/applications/admin/languages/cs.py b/applications/admin/languages/cs.py index f5dd2f6c..9c8c7b63 100644 --- a/applications/admin/languages/cs.py +++ b/applications/admin/languages/cs.py @@ -1,4 +1,4 @@ -# coding: utf8 +# -*- coding: utf-8 -*- { '!langcode!': 'cs-cz', '!langname!': 'čeština', diff --git a/applications/admin/languages/de.py b/applications/admin/languages/de.py index 0e58e35a..654aa43c 100644 --- a/applications/admin/languages/de.py +++ b/applications/admin/languages/de.py @@ -1,4 +1,4 @@ -# coding: utf8 +# -*- coding: utf-8 -*- { '!langcode!': 'de', '!langname!': 'Deutsch', diff --git a/applications/admin/languages/default.py b/applications/admin/languages/default.py index 1369b2fd..779145a8 100644 --- a/applications/admin/languages/default.py +++ b/applications/admin/languages/default.py @@ -1,4 +1,4 @@ -# coding: utf8 +# -*- coding: utf-8 -*- { '!langcode!': 'en-us', '!langname!': 'English (US)', diff --git a/applications/admin/languages/fr.py b/applications/admin/languages/fr.py index b89c4139..66326765 100644 --- a/applications/admin/languages/fr.py +++ b/applications/admin/languages/fr.py @@ -1,4 +1,4 @@ -# coding: utf8 +# -*- coding: utf-8 -*- { '!langcode!': 'fr', '!langname!': 'Français', diff --git a/applications/admin/languages/he.py b/applications/admin/languages/he.py index c209c3ec..79da3921 100644 --- a/applications/admin/languages/he.py +++ b/applications/admin/languages/he.py @@ -1,4 +1,4 @@ -# coding: utf8 +# -*- coding: utf-8 -*- { '!langcode!': 'he-il', '!langname!': 'עברית', diff --git a/applications/admin/languages/ja.py b/applications/admin/languages/ja.py index 633c4261..04bc9cf3 100644 --- a/applications/admin/languages/ja.py +++ b/applications/admin/languages/ja.py @@ -1,4 +1,4 @@ -# coding: utf8 +# -*- coding: utf-8 -*- { '!langcode!': 'ja-jp', '!langname!': '日本語', diff --git a/applications/admin/languages/nl.py b/applications/admin/languages/nl.py index ec586cf1..1a9c09be 100755 --- a/applications/admin/languages/nl.py +++ b/applications/admin/languages/nl.py @@ -1,4 +1,4 @@ -# coding: utf8 +# -*- coding: utf-8 -*- { '!langcode!': 'nl', '!langname!': 'Nederlands', diff --git a/applications/admin/languages/pl.py b/applications/admin/languages/pl.py index a4933694..67dfa16a 100644 --- a/applications/admin/languages/pl.py +++ b/applications/admin/languages/pl.py @@ -1,4 +1,4 @@ -# coding: utf8 +# -*- coding: utf-8 -*- { '!langcode!': 'pl', '!langname!': 'Polska', diff --git a/applications/admin/languages/ro.py b/applications/admin/languages/ro.py index 65ca658e..aec84f9f 100644 --- a/applications/admin/languages/ro.py +++ b/applications/admin/languages/ro.py @@ -1,4 +1,4 @@ -# coding: utf8 +# -*- coding: utf-8 -*- { '!=': '!=', '!langcode!': 'ro', diff --git a/applications/admin/languages/ru.py b/applications/admin/languages/ru.py index 7a91ccfc..04ad7ede 100644 --- a/applications/admin/languages/ru.py +++ b/applications/admin/languages/ru.py @@ -1,4 +1,4 @@ -# coding: utf8 +# -*- coding: utf-8 -*- { '!langcode!': 'ru', '!langname!': 'Русский', diff --git a/applications/admin/languages/sl.py b/applications/admin/languages/sl.py index 701a8170..e4a1c1c6 100755 --- a/applications/admin/languages/sl.py +++ b/applications/admin/languages/sl.py @@ -1,4 +1,4 @@ -# coding: utf8 +# -*- coding: utf-8 -*- { '!langcode!': 'sl', '!langname!': 'Slovenski', diff --git a/applications/admin/languages/sr-cr.py b/applications/admin/languages/sr-cr.py index a0acdbd9..04ff676c 100644 --- a/applications/admin/languages/sr-cr.py +++ b/applications/admin/languages/sr-cr.py @@ -1,4 +1,4 @@ -# coding: utf8 +# -*- coding: utf-8 -*- { '!langcode!': 'sr-cr', '!langname!': 'Српски (Ћирилица)', diff --git a/applications/admin/languages/sr-lt.py b/applications/admin/languages/sr-lt.py index 7ab1bda6..64f8eb7f 100644 --- a/applications/admin/languages/sr-lt.py +++ b/applications/admin/languages/sr-lt.py @@ -1,4 +1,4 @@ -# coding: utf8 +# -*- coding: utf-8 -*- { '!langcode!': 'sr-lt', '!langname!': 'Srpski (Latinica)', diff --git a/applications/admin/languages/uk.py b/applications/admin/languages/uk.py index 558ee92e..ca54e12c 100644 --- a/applications/admin/languages/uk.py +++ b/applications/admin/languages/uk.py @@ -1,4 +1,4 @@ -# coding: utf8 +# -*- coding: utf-8 -*- { '!langcode!': 'uk', '!langname!': 'Українська', diff --git a/applications/admin/languages/zh-tw.py b/applications/admin/languages/zh-tw.py index d04b2c48..79cb4183 100644 --- a/applications/admin/languages/zh-tw.py +++ b/applications/admin/languages/zh-tw.py @@ -1,4 +1,4 @@ -# coding: utf8 +# -*- coding: utf-8 -*- { '!langcode!': 'zh-tw', '!langname!': '台灣中文', diff --git a/applications/admin/languages/zh.py b/applications/admin/languages/zh.py index 4633a17a..d62b0804 100644 --- a/applications/admin/languages/zh.py +++ b/applications/admin/languages/zh.py @@ -1,4 +1,4 @@ -# coding: utf8 +# -*- coding: utf-8 -*- { '!langcode!': 'zh-cn', '!langname!': '中文', diff --git a/applications/examples/controllers/soap_examples.py b/applications/examples/controllers/soap_examples.py index e9ab84a3..7840105e 100644 --- a/applications/examples/controllers/soap_examples.py +++ b/applications/examples/controllers/soap_examples.py @@ -1,4 +1,4 @@ -# coding: utf8 +# -*- coding: utf-8 -*- # SOAP webservices (server and client) example and basic test # (using pysimplesoap contrib included in web2py) diff --git a/applications/welcome/languages/cs.py b/applications/welcome/languages/cs.py index f5dd2f6c..9c8c7b63 100644 --- a/applications/welcome/languages/cs.py +++ b/applications/welcome/languages/cs.py @@ -1,4 +1,4 @@ -# coding: utf8 +# -*- coding: utf-8 -*- { '!langcode!': 'cs-cz', '!langname!': 'čeština', diff --git a/applications/welcome/languages/default.py b/applications/welcome/languages/default.py index 5e6e8125..6524a902 100644 --- a/applications/welcome/languages/default.py +++ b/applications/welcome/languages/default.py @@ -1,4 +1,4 @@ -# coding: utf8 +# -*- coding: utf-8 -*- { '!langcode!': 'en-us', '!langname!': 'English (US)', diff --git a/applications/welcome/languages/fr-ca.py b/applications/welcome/languages/fr-ca.py index 7693d5b4..55dfb9ed 100644 --- a/applications/welcome/languages/fr-ca.py +++ b/applications/welcome/languages/fr-ca.py @@ -1,4 +1,4 @@ -# coding: utf8 +# -*- coding: utf-8 -*- { '!langcode!': 'fr-ca', '!langname!': 'Français (Canadien)', diff --git a/applications/welcome/languages/fr.py b/applications/welcome/languages/fr.py index c3922ad3..048ac1b1 100644 --- a/applications/welcome/languages/fr.py +++ b/applications/welcome/languages/fr.py @@ -1,4 +1,4 @@ -# coding: utf8 +# -*- coding: utf-8 -*- { '!langcode!': 'fr', '!langname!': 'Français', diff --git a/applications/welcome/languages/hi.py b/applications/welcome/languages/hi.py index 46a47e86..63a7acdc 100644 --- a/applications/welcome/languages/hi.py +++ b/applications/welcome/languages/hi.py @@ -1,4 +1,4 @@ -# coding: utf8 +# -*- coding: utf-8 -*- { '!langcode!': 'hi-in', '!langname!': 'हिन्दी', diff --git a/applications/welcome/languages/hu.py b/applications/welcome/languages/hu.py index bc32c8dd..615ee394 100644 --- a/applications/welcome/languages/hu.py +++ b/applications/welcome/languages/hu.py @@ -1,4 +1,4 @@ -# coding: utf8 +# -*- coding: utf-8 -*- { '!langcode!': 'hu', '!langname!': 'Magyar', diff --git a/applications/welcome/languages/id.py b/applications/welcome/languages/id.py index 0bb837dc..2273ae5a 100755 --- a/applications/welcome/languages/id.py +++ b/applications/welcome/languages/id.py @@ -1,4 +1,4 @@ -# coding: utf8 +# -*- coding: utf-8 -*- { '!langcode!': 'id', '!langname!': 'Indonesian', diff --git a/applications/welcome/languages/it.py b/applications/welcome/languages/it.py index 77a706be..b44bf2e8 100644 --- a/applications/welcome/languages/it.py +++ b/applications/welcome/languages/it.py @@ -1,4 +1,4 @@ -# coding: utf8 +# -*- coding: utf-8 -*- { '!=': '!=', '!langcode!': 'it', diff --git a/applications/welcome/languages/my.py b/applications/welcome/languages/my.py index d5b85f95..8e634d4d 100755 --- a/applications/welcome/languages/my.py +++ b/applications/welcome/languages/my.py @@ -1,4 +1,4 @@ -# coding: utf8 +# -*- coding: utf-8 -*- { '!langcode!': 'my', '!langname!': 'Malay', diff --git a/applications/welcome/languages/nl.py b/applications/welcome/languages/nl.py index 39892e52..4b942d52 100644 --- a/applications/welcome/languages/nl.py +++ b/applications/welcome/languages/nl.py @@ -1,4 +1,4 @@ -# coding: utf8 +# -*- coding: utf-8 -*- { '!langcode!': 'nl', '!langname!': 'Nederlands', diff --git a/applications/welcome/languages/pl.py b/applications/welcome/languages/pl.py index aa1e5701..fa0f3c96 100644 --- a/applications/welcome/languages/pl.py +++ b/applications/welcome/languages/pl.py @@ -1,4 +1,4 @@ -# coding: utf8 +# -*- coding: utf-8 -*- { '!langcode!': 'pl', '!langname!': 'Polska', diff --git a/applications/welcome/languages/pt.py b/applications/welcome/languages/pt.py index 8d36be6f..c34aee8a 100644 --- a/applications/welcome/languages/pt.py +++ b/applications/welcome/languages/pt.py @@ -1,4 +1,4 @@ -# coding: utf8 +# -*- coding: utf-8 -*- { '!langcode!': 'pt', '!langname!': 'Português', diff --git a/applications/welcome/languages/ro.py b/applications/welcome/languages/ro.py index 0f830e3d..63c9741b 100644 --- a/applications/welcome/languages/ro.py +++ b/applications/welcome/languages/ro.py @@ -1,4 +1,4 @@ -# coding: utf8 +# -*- coding: utf-8 -*- { '!=': '!=', '!langcode!': 'ro', diff --git a/applications/welcome/languages/ru.py b/applications/welcome/languages/ru.py index 85644ea2..0487a715 100644 --- a/applications/welcome/languages/ru.py +++ b/applications/welcome/languages/ru.py @@ -1,4 +1,4 @@ -# coding: utf8 +# -*- coding: utf-8 -*- { '!langcode!': 'ru', '!langname!': 'Русский', diff --git a/applications/welcome/languages/sk.py b/applications/welcome/languages/sk.py index 88f8343f..e90ccf81 100644 --- a/applications/welcome/languages/sk.py +++ b/applications/welcome/languages/sk.py @@ -1,4 +1,4 @@ -# coding: utf8 +# -*- coding: utf-8 -*- { '!langcode!': 'sk', '!langname!': 'Slovenský', diff --git a/applications/welcome/languages/uk.py b/applications/welcome/languages/uk.py index 17bfde51..3a5f791f 100644 --- a/applications/welcome/languages/uk.py +++ b/applications/welcome/languages/uk.py @@ -1,4 +1,4 @@ -# coding: utf8 +# -*- coding: utf-8 -*- { '!langcode!': 'uk', '!langname!': 'Українська', diff --git a/applications/welcome/languages/zh-cn.py b/applications/welcome/languages/zh-cn.py index 61009f6e..d92a8c53 100644 --- a/applications/welcome/languages/zh-cn.py +++ b/applications/welcome/languages/zh-cn.py @@ -1,4 +1,4 @@ -# coding: utf8 +# -*- coding: utf-8 -*- { '!langcode!': 'zh-cn', '!langname!': '中文', diff --git a/applications/welcome/languages/zh-tw.py b/applications/welcome/languages/zh-tw.py index 5b109604..fa805aa4 100644 --- a/applications/welcome/languages/zh-tw.py +++ b/applications/welcome/languages/zh-tw.py @@ -1,4 +1,4 @@ -# coding: utf8 +# -*- coding: utf-8 -*- { '!langcode!': 'zh-cn', '!langname!': '中文', diff --git a/applications/welcome/languages/zh.py b/applications/welcome/languages/zh.py index 263918ce..d4790627 100644 --- a/applications/welcome/languages/zh.py +++ b/applications/welcome/languages/zh.py @@ -1,4 +1,4 @@ -# coding: utf8 +# -*- coding: utf-8 -*- { '!langcode!': 'zh-tw', '!langname!': '中文', diff --git a/gluon/contrib/websocket_messaging.py b/gluon/contrib/websocket_messaging.py index c7f5d03f..7755e650 100644 --- a/gluon/contrib/websocket_messaging.py +++ b/gluon/contrib/websocket_messaging.py @@ -1,4 +1,4 @@ -# -*- coding: utf8 -*- +# -*- coding: utf-8 -*- #!/usr/bin/env python """ diff --git a/gluon/custom_import.py b/gluon/custom_import.py index b56ba65a..2f627609 100644 --- a/gluon/custom_import.py +++ b/gluon/custom_import.py @@ -97,7 +97,7 @@ def custom_importer(name, globals=None, locals=None, fromlist=None, level=-1): except ImportError, e3: raise ImportError, e1, import_tb # there an import error in the module except Exception, e2: - raise e2 # there is an error in the module + raise # there is an error in the module finally: if import_tb: import_tb = None diff --git a/gluon/dal.py b/gluon/dal.py index 2677b723..537a7d76 100644 --- a/gluon/dal.py +++ b/gluon/dal.py @@ -2840,6 +2840,8 @@ class PostgreSQLAdapter(BaseAdapter): self._after_connection = after_connection self.srid = srid self.find_or_make_work_folder() + self._last_insert = None # for INSERT ... RETURNING ID + ruri = uri.split('://', 1)[1] m = self.REGEX_URI.match(ruri) if not m: @@ -2884,10 +2886,29 @@ class PostgreSQLAdapter(BaseAdapter): self.execute("SET standard_conforming_strings=on;") self.try_json() - def lastrowid(self, table=None): - self.execute("select lastval()") - return int(self.cursor.fetchone()[0]) + def _insert(self, table, fields): + table_rname = table.sqlsafe + if fields: + keys = ','.join(f.sqlsafe_name for f, v in fields) + values = ','.join(self.expand(v, f.type) for f, v in fields) + if table._id: + self._last_insert = (table._id, 1) + return 'INSERT INTO %s(%s) VALUES (%s) RETURNING %s;' % ( + table_rname, keys, values, table._id.name) + else: + self._last_insert = None + return 'INSERT INTO %s(%s) VALUES (%s);' % (table_rname, keys, values) + else: + self._last_insert + return self._insert_empty(table) + def lastrowid(self, table=None): + if self._last_insert: + return int(self.cursor.fetchone()[0]) + else: + self.execute("select lastval()") + return int(self.cursor.fetchone()[0]) + def try_json(self): # check JSON data type support # (to be added to after_connection) diff --git a/gluon/http.py b/gluon/http.py index ce557572..ee25c006 100644 --- a/gluon/http.py +++ b/gluon/http.py @@ -150,7 +150,7 @@ class HTTP(Exception): return self.message -def redirect(location='', how=303, client_side=False): +def redirect(location='', how=303, client_side=False, headers=None): """Raises a redirect (303) Args: @@ -159,16 +159,20 @@ def redirect(location='', how=303, client_side=False): client_side: if set to True, it triggers a reload of the entire page when the fragment has been loaded as a component """ + headers = headers or {} if location: from gluon import current loc = location.replace('\r', '%0D').replace('\n', '%0A') if client_side and current.request.ajax: - raise HTTP(200, **{'web2py-redirect-location': loc}) + headers['web2py-redirect-location'] = loc + raise HTTP(200, **headers) else: + headers['Location'] = loc raise HTTP(how, 'You are being redirected here' % loc, - Location=loc) + **headers) else: from gluon import current if client_side and current.request.ajax: - raise HTTP(200, **{'web2py-component-command': 'window.location.reload(true)'}) + headers['web2py-component-command'] = 'window.location.reload(true)' + raise HTTP(200, **headers) diff --git a/gluon/main.py b/gluon/main.py index 6c821e30..e6e33059 100644 --- a/gluon/main.py +++ b/gluon/main.py @@ -359,6 +359,7 @@ def wsgibase(environ, responder): local_hosts = global_settings.local_hosts client = get_client(env) x_req_with = str(env.http_x_requested_with).lower() + cmd_opts = request.global_settings.cmd_options request.update( client = client, @@ -366,6 +367,8 @@ def wsgibase(environ, responder): ajax = x_req_with == 'xmlhttprequest', cid = env.http_web2py_component_element, is_local = env.remote_addr in local_hosts, + is_shell = cmd_opts and cmd_opts.shell, + is_sheduler = cmd_opts and cmd_opts.scheduler, is_https = env.wsgi_url_scheme in HTTPS_SCHEMES or \ request.env.http_x_forwarded_proto in HTTPS_SCHEMES \ or env.https == 'on' diff --git a/gluon/sqlhtml.py b/gluon/sqlhtml.py index cb85158d..60b822ea 100644 --- a/gluon/sqlhtml.py +++ b/gluon/sqlhtml.py @@ -2442,7 +2442,7 @@ class SQLFORM(FORM): message = T('at least %(nrows)s records found') % dict(nrows=nrows) else: message = T('%(nrows)s records found') % dict(nrows=nrows) - console.append(DIV(message or T('None'), _class='web2py_counter')) + console.append(DIV(message or '', _class='web2py_counter')) paginator = UL() if paginate and dbset._db._adapter.dbengine == 'google:datastore': @@ -2672,7 +2672,7 @@ class SQLFORM(FORM): @staticmethod def smartgrid(table, constraints=None, linked_tables=None, - links=None, links_in_grid=True, + links=None, links_in_grid=True, max_linked_inline=0, args=None, user_signature=True, divider='>', breadcrumbs_class='', **kwargs): @@ -2814,6 +2814,8 @@ class SQLFORM(FORM): linked_tables = linked_tables.get(table._tablename, []) if linked_tables: for item in linked_tables: + opts = [OPTION(T('References')+':', _value='')] + linked = [] tb = None if isinstance(item, Table) and item._tablename in check: tablename = item._tablename @@ -2835,11 +2837,22 @@ class SQLFORM(FORM): t = T(tb._plural) if not multiple_links else \ T(tb._plural + '(' + fieldname + ')') args0 = tablename + '.' + fieldname - links.append( + opts.append(OPTION(t,_value=args0)) + linked.append( lambda row, t=t, nargs=nargs, args0=args0: A(SPAN(t), cid=request.cid, _href=url( args=[args0, row[id_field_name]]))) + if 0 < max_linked_inline < len(opts)-1: + links.append( + lambda row: + SELECT(opts, cid=request.cid, _rowid=row[id_field_name], + _onchange="javascript:document.location='"+url()+ + "/'+this.value+'/'+this.attributes['rowid'].value" + ) + ) + else: links += linked + grid = SQLFORM.grid(query, args=request.args[:nargs], links=links, links_in_grid=links_in_grid, user_signature=user_signature, **kwargs) diff --git a/gluon/tools.py b/gluon/tools.py index 4eecfcdd..0fef93e3 100644 --- a/gluon/tools.py +++ b/gluon/tools.py @@ -2177,15 +2177,14 @@ class Auth(object): elif not fields.get(settings.userfield): raise ValueError("register_bare: " + "userfield not provided or invalid") - fields[settings.passfield - ] = settings.table_user[settings.passfield].validate( - fields[settings.passfield])[0] - user = self.get_or_create_user(fields, login=False, - get=False, - update_fields=self.settings.update_fields) + fields[settings.passfield] = \ + settings.table_user[settings.passfield].validate( + fields[settings.passfield])[0] + user = self.get_or_create_user( + fields, login=False, get=False, + update_fields=self.settings.update_fields) if not user: - # get or create did not create a user (it ignores - # duplicate records) + # get or create did not create a user (it ignores duplicate records) return False return user @@ -3223,8 +3222,7 @@ class Auth(object): passfield = self.settings.password_field form = SQLFORM.factory( Field('old_password', 'password', - label=self.messages.old_password, - requires=table_user[passfield].requires), + label=self.messages.old_password), Field('new_password', 'password', label=self.messages.new_password, requires=table_user[passfield].requires), @@ -3243,7 +3241,8 @@ class Auth(object): onvalidation=onvalidation, hideerror=self.settings.hideerror): - if not form.vars['old_password'] == s.select(limitby=(0,1), orderby_on_limitby=False).first()[passfield]: + current_user = s.select(limitby=(0,1), orderby_on_limitby=False).first() + if not form.vars['old_password'] == current_user[passfield]: form.errors['old_password'] = self.messages.invalid_password else: d = {passfield: str(form.vars.new_password)} @@ -5380,8 +5379,11 @@ class Expose(object): base = base or os.path.join(current.request.folder, 'static') basename = basename or current.request.function self.basename = basename - self.args = current.request.raw_args and \ - [arg for arg in current.request.raw_args.split('/') if arg] or [] + + if current.request.raw_args: + self.args = [arg for arg in current.request.raw_args.split('/') if arg] + else: + self.args = [arg for arg in current.request.args if args] filename = os.path.join(base, *self.args) if not os.path.exists(filename): raise HTTP(404, "FILE NOT FOUND")