diff --git a/VERSION b/VERSION
index f34c30cf..4e40b239 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-Version 2.1.1 (2012-10-19 12:59:55) dev
+Version 2.1.1 (2012-10-19 14:13:30) dev
diff --git a/applications/admin/controllers/appadmin.py b/applications/admin/controllers/appadmin.py
index 6802c419..f62af94c 100644
--- a/applications/admin/controllers/appadmin.py
+++ b/applications/admin/controllers/appadmin.py
@@ -23,7 +23,7 @@ remote_addr = request.env.remote_addr
try:
hosts = (http_host, socket.gethostname(),
socket.gethostbyname(http_host),
- '::1','127.0.0.1','::ffff:127.0.0.1')
+ '::1', '127.0.0.1', '::ffff:127.0.0.1')
except:
hosts = (http_host, )
@@ -32,10 +32,10 @@ if request.env.http_x_forwarded_for or request.is_https:
elif (remote_addr not in hosts) and (remote_addr != "127.0.0.1"):
raise HTTP(200, T('appadmin is disabled because insecure channel'))
-if (request.application=='admin' and not session.authorized) or \
- (request.application!='admin' and not gluon.fileutils.check_credentials(request)):
+if (request.application == 'admin' and not session.authorized) or \
+ (request.application != 'admin' and not gluon.fileutils.check_credentials(request)):
redirect(URL('admin', 'default', 'index',
- vars=dict(send=URL(args=request.args,vars=request.vars))))
+ vars=dict(send=URL(args=request.args, vars=request.vars))))
ignore_rw = True
response.view = 'appadmin.html'
@@ -95,24 +95,23 @@ def get_query(request):
return None
-def query_by_table_type(tablename,db,request=request):
- keyed = hasattr(db[tablename],'_primarykey')
+def query_by_table_type(tablename, db, request=request):
+ keyed = hasattr(db[tablename], '_primarykey')
if keyed:
firstkey = db[tablename][db[tablename]._primarykey[0]]
cond = '>0'
if firstkey.type in ['string', 'text']:
cond = '!=""'
- qry = '%s.%s.%s%s' % (request.args[0], request.args[1], firstkey.name, cond)
+ qry = '%s.%s.%s%s' % (
+ request.args[0], request.args[1], firstkey.name, cond)
else:
qry = '%s.%s.id>0' % tuple(request.args[:2])
return qry
-
# ##########################################################
# ## list all databases and tables
# ###########################################################
-
def index():
return dict(databases=databases)
@@ -127,7 +126,7 @@ def insert():
form = SQLFORM(db[table], ignore_rw=ignore_rw)
if form.accepts(request.vars, session):
response.flash = T('new record inserted')
- return dict(form=form,table=db[table])
+ return dict(form=form, table=db[table])
# ##########################################################
@@ -138,7 +137,8 @@ def insert():
def download():
import os
db = get_database(request)
- return response.download(request,db)
+ return response.download(request, db)
+
def csv():
import gluon.contenttype
@@ -149,26 +149,27 @@ def csv():
if not query:
return None
response.headers['Content-disposition'] = 'attachment; filename=%s_%s.csv'\
- % tuple(request.vars.query.split('.')[:2])
- return str(db(query,ignore_common_filters=True).select())
+ % tuple(request.vars.query.split('.')[:2])
+ return str(db(query, ignore_common_filters=True).select())
def import_csv(table, file):
table.import_from_csv_file(file)
+
def select():
import re
db = get_database(request)
dbname = request.args[0]
regex = re.compile('(?P
\w+)\.(?P\w+)=(?P\d+)')
- if len(request.args)>1 and hasattr(db[request.args[1]],'_primarykey'):
+ if len(request.args) > 1 and hasattr(db[request.args[1]], '_primarykey'):
regex = re.compile('(?P\w+)\.(?P\w+)=(?P.+)')
if request.vars.query:
match = regex.match(request.vars.query)
if match:
request.vars.query = '%s.%s.%s==%s' % (request.args[0],
- match.group('table'), match.group('field'),
- match.group('value'))
+ match.group('table'), match.group('field'),
+ match.group('value'))
else:
request.vars.query = session.last_query
query = get_query(request)
@@ -192,14 +193,15 @@ def select():
session.last_query = request.vars.query
form = FORM(TABLE(TR(T('Query:'), '', INPUT(_style='width:400px',
_name='query', _value=request.vars.query or '',
- requires=IS_NOT_EMPTY(error_message=T("Cannot be empty")))), TR(T('Update:'),
+ requires=IS_NOT_EMPTY(
+ error_message=T("Cannot be empty")))), TR(T('Update:'),
INPUT(_name='update_check', _type='checkbox',
value=False), INPUT(_style='width:400px',
_name='update_fields', _value=request.vars.update_fields
- or '')), TR(T('Delete:'), INPUT(_name='delete_check',
+ or '')), TR(T('Delete:'), INPUT(_name='delete_check',
_class='delete', _type='checkbox', value=False), ''),
TR('', '', INPUT(_type='submit', _value=T('submit')))),
- _action=URL(r=request,args=request.args))
+ _action=URL(r=request, args=request.args))
tb = None
if form.accepts(request.vars, formname=None):
@@ -211,28 +213,30 @@ def select():
nrows = db(query).count()
if form.vars.update_check and form.vars.update_fields:
db(query).update(**eval_in_global_env('dict(%s)'
- % form.vars.update_fields))
+ % form.vars.update_fields))
response.flash = T('%s %%{row} updated', nrows)
elif form.vars.delete_check:
db(query).delete()
response.flash = T('%s %%{row} deleted', nrows)
nrows = db(query).count()
if orderby:
- rows = db(query,ignore_common_filters=True).select(limitby=(start, stop), orderby=eval_in_global_env(orderby))
+ rows = db(query, ignore_common_filters=True).select(limitby=(
+ start, stop), orderby=eval_in_global_env(orderby))
else:
- rows = db(query,ignore_common_filters=True).select(limitby=(start, stop))
+ rows = db(query, ignore_common_filters=True).select(
+ limitby=(start, stop))
except Exception, e:
import traceback
tb = traceback.format_exc()
(rows, nrows) = ([], 0)
- response.flash = DIV(T('Invalid Query'),PRE(str(e)))
+ response.flash = DIV(T('Invalid Query'), PRE(str(e)))
# begin handle upload csv
csv_table = table or request.vars.table
if csv_table:
- formcsv = FORM(str(T('or import from csv file'))+" ",
- INPUT(_type='file',_name='csvfile'),
- INPUT(_type='hidden',_value=csv_table,_name='table'),
- INPUT(_type='submit',_value=T('import')))
+ formcsv = FORM(str(T('or import from csv file')) + " ",
+ INPUT(_type='file', _name='csvfile'),
+ INPUT(_type='hidden', _value=csv_table, _name='table'),
+ INPUT(_type='submit', _value=T('import')))
else:
formcsv = None
if formcsv and formcsv.process().accepted:
@@ -241,7 +245,7 @@ def select():
request.vars.csvfile.file)
response.flash = T('data uploaded')
except Exception, e:
- response.flash = DIV(T('unable to parse csv file'),PRE(str(e)))
+ response.flash = DIV(T('unable to parse csv file'), PRE(str(e)))
# end handle upload csv
return dict(
@@ -252,9 +256,9 @@ def select():
nrows=nrows,
rows=rows,
query=request.vars.query,
- formcsv = formcsv,
- tb = tb,
- )
+ formcsv=formcsv,
+ tb=tb,
+ )
# ##########################################################
@@ -264,14 +268,16 @@ def select():
def update():
(db, table) = get_table(request)
- keyed = hasattr(db[table],'_primarykey')
+ keyed = hasattr(db[table], '_primarykey')
record = None
if keyed:
key = [f for f in request.vars if f in db[table]._primarykey]
if key:
- record = db(db[table][key[0]] == request.vars[key[0]], ignore_common_filters=True).select().first()
+ record = db(db[table][key[0]] == request.vars[key[
+ 0]], ignore_common_filters=True).select().first()
else:
- record = db(db[table].id == request.args(2),ignore_common_filters=True).select().first()
+ record = db(db[table].id == request.args(
+ 2), ignore_common_filters=True).select().first()
if not record:
qry = query_by_table_type(table, db)
@@ -281,20 +287,21 @@ def update():
if keyed:
for k in db[table]._primarykey:
- db[table][k].writable=False
+ db[table][k].writable = False
- form = SQLFORM(db[table], record, deletable=True, delete_label=T('Check to delete'),
- ignore_rw=ignore_rw and not keyed,
- linkto=URL('select',
+ form = SQLFORM(
+ db[table], record, deletable=True, delete_label=T('Check to delete'),
+ ignore_rw=ignore_rw and not keyed,
+ linkto=URL('select',
args=request.args[:1]), upload=URL(r=request,
- f='download', args=request.args[:1]))
+ f='download', args=request.args[:1]))
if form.accepts(request.vars, session):
session.flash = T('done!')
qry = query_by_table_type(table, db)
redirect(URL('select', args=request.args[:1],
vars=dict(query=qry)))
- return dict(form=form,table=db[table])
+ return dict(form=form, table=db[table])
# ##########################################################
@@ -305,11 +312,15 @@ def update():
def state():
return dict()
+
def ccache():
form = FORM(
- P(TAG.BUTTON(T("Clear CACHE?"), _type="submit", _name="yes", _value="yes")),
- P(TAG.BUTTON(T("Clear RAM"), _type="submit", _name="ram", _value="ram")),
- P(TAG.BUTTON(T("Clear DISK"), _type="submit", _name="disk", _value="disk")),
+ P(TAG.BUTTON(
+ T("Clear CACHE?"), _type="submit", _name="yes", _value="yes")),
+ P(TAG.BUTTON(
+ T("Clear RAM"), _type="submit", _name="ram", _value="ram")),
+ P(TAG.BUTTON(
+ T("Clear DISK"), _type="submit", _name="disk", _value="disk")),
)
if form.accepts(request.vars, session):
@@ -333,11 +344,16 @@ def ccache():
redirect(URL(r=request))
try:
- from guppy import hpy; hp=hpy()
+ from guppy import hpy
+ hp = hpy()
except ImportError:
hp = False
- import shelve, os, copy, time, math
+ import shelve
+ import os
+ import copy
+ import time
+ import math
from gluon import portalocker
ram = {
@@ -382,9 +398,10 @@ def ccache():
ram['keys'].append((key, GetInHMS(time.time() - value[0])))
locker = open(os.path.join(request.folder,
- 'cache/cache.lock'), 'a')
+ 'cache/cache.lock'), 'a')
portalocker.lock(locker, portalocker.LOCK_EX)
- disk_storage = shelve.open(os.path.join(request.folder, 'cache/cache.shelve'))
+ disk_storage = shelve.open(
+ os.path.join(request.folder, 'cache/cache.shelve'))
try:
for key, value in disk_storage.items():
if isinstance(value, dict):
@@ -415,7 +432,8 @@ def ccache():
total['misses'] = ram['misses'] + disk['misses']
total['keys'] = ram['keys'] + disk['keys']
try:
- total['ratio'] = total['hits'] * 100 / (total['hits'] + total['misses'])
+ total['ratio'] = total['hits'] * 100 / (total['hits'] +
+ total['misses'])
except (KeyError, ZeroDivisionError):
total['ratio'] = 0
diff --git a/applications/admin/controllers/debug.py b/applications/admin/controllers/debug.py
index f7c73d31..0b289420 100644
--- a/applications/admin/controllers/debug.py
+++ b/applications/admin/controllers/debug.py
@@ -5,35 +5,39 @@ import gluon.contrib.shell
import gluon.dal
import gluon.html
import gluon.validators
-import code, thread
+import code
+import thread
from gluon.debug import communicate, web_debugger, qdb_debugger
import pydoc
if DEMO_MODE or MULTI_USER_MODE:
session.flash = T('disabled in demo mode')
- redirect(URL('default','site'))
+ redirect(URL('default', 'site'))
+
+FE = 10 ** 9
-FE=10**9
def index():
app = request.args(0) or 'admin'
reset()
# read buffer
data = communicate()
- return dict(app=app,data=data)
+ return dict(app=app, data=data)
+
def callback():
app = request.args[0]
command = request.vars.statement
- session['debug_commands:'+app].append(command)
+ session['debug_commands:' + app].append(command)
output = communicate(command)
- k = len(session['debug_commands:'+app]) - 1
+ k = len(session['debug_commands:' + app]) - 1
return '[%i] %s%s\n' % (k + 1, command, output)
+
def reset():
app = request.args(0) or 'admin'
- session['debug_commands:'+app] = []
+ session['debug_commands:' + app] = []
return 'done'
@@ -50,9 +54,9 @@ def interact():
filename = web_debugger.filename
lineno = web_debugger.lineno
if filename:
- lines = dict([(i+1, l) for (i, l) in enumerate(
- [l.strip("\n").strip("\r") for l
- in open(filename).readlines()])])
+ lines = dict([(i + 1, l) for (i, l) in enumerate(
+ [l.strip("\n").strip("\r") for l
+ in open(filename).readlines()])])
filename = os.path.basename(filename)
else:
lines = {}
@@ -64,8 +68,8 @@ def interact():
f_globals = {}
for name, value in env['globals'].items():
if name not in gluon.html.__all__ and \
- name not in gluon.validators.__all__ and \
- name not in gluon.dal.__all__:
+ name not in gluon.validators.__all__ and \
+ name not in gluon.dal.__all__:
f_globals[name] = pydoc.text.repr(value)
else:
f_locals = {}
@@ -81,37 +85,43 @@ def interact():
f_globals=f_globals, f_locals=f_locals,
exception=web_debugger.exception_info)
+
def step():
web_debugger.do_step()
redirect(URL("interact"))
+
def next():
web_debugger.do_next()
redirect(URL("interact"))
+
def cont():
web_debugger.do_continue()
redirect(URL("interact"))
+
def ret():
web_debugger.do_return()
redirect(URL("interact"))
+
def stop():
web_debugger.do_quit()
redirect(URL("interact"))
+
def execute():
app = request.args[0]
command = request.vars.statement
- session['debug_commands:'+app].append(command)
+ session['debug_commands:' + app].append(command)
try:
output = web_debugger.do_exec(command)
if output is None:
output = ""
except Exception, e:
- output = T("Exception %s") % str(e)
- k = len(session['debug_commands:'+app]) - 1
+ output = T("Exception %s") % str(e)
+ k = len(session['debug_commands:' + app]) - 1
return '[%i] %s%s\n' % (k + 1, command, output)
@@ -122,8 +132,8 @@ def breakpoints():
files = listdir(apath('', r=request), '.*\.py$')
files = [filename for filename in files
if filename and 'languages' not in filename
- and not filename.startswith("admin")
- and not filename.startswith("examples")]
+ and not filename.startswith("admin")
+ and not filename.startswith("examples")]
form = SQLFORM.factory(
Field('filename', requires=IS_IN_SET(files), label=T("Filename")),
@@ -133,17 +143,17 @@ def breakpoints():
comment=T("deleted after first hit")),
Field('condition', 'string', label=T("Condition"),
comment=T("honored only if the expression evaluates to true")),
- )
+ )
if form.accepts(request.vars, session):
filename = os.path.join(request.env['applications_parent'],
'applications', form.vars.filename)
err = qdb_debugger.do_set_breakpoint(filename,
- form.vars.lineno,
- form.vars.temporary,
- form.vars.condition)
+ form.vars.lineno,
+ form.vars.temporary,
+ form.vars.condition)
response.flash = T("Set Breakpoint on %s at line %s: %s") % (
- filename, form.vars.lineno, err or T('successful'))
+ filename, form.vars.lineno, err or T('successful'))
for item in request.vars:
if item[:7] == 'delete_':
@@ -153,7 +163,7 @@ def breakpoints():
'path': bp[1], 'lineno': bp[2],
'temporary': bp[3], 'enabled': bp[4], 'hits': bp[5],
'condition': bp[6]}
- for bp in qdb_debugger.do_list_breakpoint()]
+ for bp in qdb_debugger.do_list_breakpoint()]
return dict(breakpoints=breakpoints, form=form)
@@ -185,13 +195,13 @@ def toggle_breakpoint():
if filename == bp_filename and lineno == bp_lineno:
err = qdb_debugger.do_clear_breakpoint(filename, lineno)
response.flash = T("Removed Breakpoint on %s at line %s", (
- filename, lineno))
+ filename, lineno))
ok = False
break
else:
err = qdb_debugger.do_set_breakpoint(filename, lineno)
response.flash = T("Set Breakpoint on %s at line %s: %s") % (
- filename, lineno, err or T('successful'))
+ filename, lineno, err or T('successful'))
ok = True
else:
response.flash = T("Unable to determine the line number!")
diff --git a/applications/admin/controllers/default.py b/applications/admin/controllers/default.py
index 0ecae821..97293161 100644
--- a/applications/admin/controllers/default.py
+++ b/applications/admin/controllers/default.py
@@ -4,7 +4,7 @@ EXPERIMENTAL_STUFF = True
if EXPERIMENTAL_STUFF:
if is_mobile:
- response.view = response.view.replace('default/','default.mobile/')
+ response.view = response.view.replace('default/', 'default.mobile/')
response.menu = []
import re
@@ -25,12 +25,12 @@ from gluon.languages import (read_possible_languages, read_dict, write_dict,
read_plural_dict, write_plural_dict)
-if DEMO_MODE and request.function in ['change_password','pack','pack_plugin','upgrade_web2py','uninstall','cleanup','compile_app','remove_compiled_app','delete','delete_plugin','create_file','upload_file','update_languages','reload_routes','git_push','git_pull']:
+if DEMO_MODE and request.function in ['change_password', 'pack', 'pack_plugin', 'upgrade_web2py', 'uninstall', 'cleanup', 'compile_app', 'remove_compiled_app', 'delete', 'delete_plugin', 'create_file', 'upload_file', 'update_languages', 'reload_routes', 'git_push', 'git_pull']:
session.flash = T('disabled in demo mode')
redirect(URL('site'))
-if not is_manager() and request.function in ['change_password','upgrade_web2py']:
+if not is_manager() and request.function in ['change_password', 'upgrade_web2py']:
session.flash = T('disabled in multi user mode')
redirect(URL('site'))
@@ -39,25 +39,32 @@ if FILTER_APPS and request.args(0) and not request.args(0) in FILTER_APPS:
redirect(URL('site'))
-if not session.token: session.token = web2py_uuid()
+if not session.token:
+ session.token = web2py_uuid()
+
def count_lines(data):
return len([line for line in data.split('\n') if line.strip() and not line.startswith('#')])
-def log_progress(app,mode='EDIT',filename=None,progress=0):
+
+def log_progress(app, mode='EDIT', filename=None, progress=0):
progress_file = os.path.join(apath(app, r=request), 'progress.log')
now = str(request.now)[:19]
if not os.path.exists(progress_file):
- safe_open(progress_file,'w').write('[%s] START\n' % now)
+ safe_open(progress_file, 'w').write('[%s] START\n' % now)
if filename:
- safe_open(progress_file,'a').write('[%s] %s %s: %s\n' % (now,mode,filename,progress))
+ safe_open(progress_file, 'a').write(
+ '[%s] %s %s: %s\n' % (now, mode, filename, progress))
-def safe_open(a,b):
+
+def safe_open(a, b):
if DEMO_MODE and ('w' in b or 'a' in b):
class tmp:
- def write(self,data): pass
+ def write(self, data):
+ pass
return tmp()
- return open(a,b)
+ return open(a, b)
+
def safe_read(a, b='r'):
safe_file = safe_open(a, b)
@@ -66,6 +73,7 @@ def safe_read(a, b='r'):
finally:
safe_file.close()
+
def safe_write(a, value, b='w'):
safe_file = safe_open(a, b)
try:
@@ -73,14 +81,16 @@ def safe_write(a, value, b='w'):
finally:
safe_file.close()
+
def get_app(name=None):
app = name or request.args(0)
- if app and (not MULTI_USER_MODE or is_manager() or \
- db(db.app.name==app)(db.app.owner==auth.user.id).count()):
+ if app and (not MULTI_USER_MODE or is_manager() or
+ db(db.app.name == app)(db.app.owner == auth.user.id).count()):
return app
session.flash = T('App does not exist or your are not authorized')
redirect(URL('site'))
+
def index():
""" Index handler """
@@ -127,18 +137,19 @@ def check_version():
session._unlock(response)
new_version, version_number = check_new_version(request.env.web2py_version,
- WEB2PY_VERSION_URL)
+ WEB2PY_VERSION_URL)
if new_version == -1:
return A(T('Unable to check for upgrades'), _href=WEB2PY_URL)
elif new_version != True:
return A(T('web2py is up to date'), _href=WEB2PY_URL)
- elif platform.system().lower() in ('windows','win32','win64') and os.path.exists("web2py.exe"):
+ elif platform.system().lower() in ('windows', 'win32', 'win64') and os.path.exists("web2py.exe"):
return SPAN('You should upgrade to version %s.%s.%s' % version_number[:3])
else:
return sp_button(URL('upgrade_web2py'), T('upgrade now')) \
- + XML(' %s.%s.%s' \
- % version_number[:3])
+ + XML(' %s.%s.%s'
+ % version_number[:3])
+
def logout():
""" Logout handler """
@@ -151,11 +162,13 @@ def logout():
def change_password():
if session.pam_user:
- session.flash = T('PAM authenticated user, cannot change password here')
+ session.flash = T(
+ 'PAM authenticated user, cannot change password here')
redirect(URL('site'))
- form=SQLFORM.factory(Field('current_admin_password','password'),
- Field('new_admin_password','password',requires=IS_STRONG()),
- Field('new_admin_password_again','password'))
+ form = SQLFORM.factory(Field('current_admin_password', 'password'),
+ Field('new_admin_password',
+ 'password', requires=IS_STRONG()),
+ Field('new_admin_password_again', 'password'))
if form.accepts(request.vars):
if not verify_password(request.vars.current_admin_password):
form.errors.current_admin_password = T('invalid password')
@@ -163,7 +176,8 @@ def change_password():
form.errors.new_admin_password_again = T('no match')
else:
path = abspath('parameters_%s.py' % request.env.server_port)
- safe_write(path, 'password="%s"' % CRYPT()(request.vars.new_admin_password)[0])
+ safe_write(path, 'password="%s"' % CRYPT()(
+ request.vars.new_admin_password)[0])
session.flash = T('password changed')
redirect(URL('site'))
return dict(form=form)
@@ -178,21 +192,21 @@ def site():
file_or_appurl = 'file' in request.vars or 'appurl' in request.vars
class IS_VALID_APPNAME(object):
- def __call__(self,value):
+ def __call__(self, value):
if not re.compile('\w+').match(value):
- return (value,T('Invalid application name'))
+ return (value, T('Invalid application name'))
if not request.vars.overwrite and \
- os.path.exists(os.path.join(apath(r=request),value)):
- return (value,T('Application exists already'))
- return (value,None)
+ os.path.exists(os.path.join(apath(r=request), value)):
+ return (value, T('Application exists already'))
+ return (value, None)
is_appname = IS_VALID_APPNAME()
- form_create = SQLFORM.factory(Field('name',requires=is_appname),
+ form_create = SQLFORM.factory(Field('name', requires=is_appname),
table_name='appcreate')
- form_update = SQLFORM.factory(Field('name',requires=is_appname),
- Field('file','upload',uploadfield=False),
+ form_update = SQLFORM.factory(Field('name', requires=is_appname),
+ Field('file', 'upload', uploadfield=False),
Field('url'),
- Field('overwrite','boolean'),
+ Field('overwrite', 'boolean'),
table_name='appupdate')
form_create.process()
form_update.process()
@@ -203,13 +217,13 @@ def site():
elif form_create.accepted:
# create a new application
appname = cleanpath(form_create.vars.name)
- created, error = app_create(appname, request,info=True)
+ created, error = app_create(appname, request, info=True)
if created:
if MULTI_USER_MODE:
- db.app.insert(name=appname,owner=auth.user.id)
+ db.app.insert(name=appname, owner=auth.user.id)
log_progress(appname)
session.flash = T('new application "%s" created', appname)
- redirect(URL('design',args=appname))
+ redirect(URL('design', args=appname))
else:
session.flash = \
DIV(T('unable to create application "%s"' % appname),
@@ -221,9 +235,9 @@ def site():
if not have_git:
session.flash = GIT_MISSING
redirect(URL(r=request))
- target = os.path.join(apath(r=request),form_update.vars.name)
+ target = os.path.join(apath(r=request), form_update.vars.name)
try:
- new_repo = Repo.clone_from(form_update.vars.url,target)
+ new_repo = Repo.clone_from(form_update.vars.url, target)
session.flash = T('new application "%s" imported',
form_update.vars.name)
except GitCommandError, err:
@@ -238,7 +252,7 @@ def site():
raise Exception("404 file not found")
except Exception, e:
session.flash = \
- DIV(T('Unable to download app because:'),PRE(str(e)))
+ DIV(T('Unable to download app because:'), PRE(str(e)))
redirect(URL(r=request))
fname = form_update.vars.url
@@ -258,7 +272,7 @@ def site():
if f and installed:
msg = 'application %(appname)s installed with md5sum: %(digest)s'
if MULTI_USER_MODE:
- db.app.insert(name=appname,owner=auth.user.id)
+ db.app.insert(name=appname, owner=auth.user.id)
log_progress(appname)
session.flash = T(msg, dict(appname=appname,
digest=md5_hash(installed)))
@@ -275,12 +289,12 @@ def site():
if is_manager():
apps = [f for f in os.listdir(apath(r=request)) if regex.match(f)]
else:
- apps = [f.name for f in db(db.app.owner==auth.user_id).select()]
+ apps = [f.name for f in db(db.app.owner == auth.user_id).select()]
if FILTER_APPS:
apps = [f for f in apps if f in FILTER_APPS]
- apps = sorted(apps,lambda a,b:cmp(a.upper(),b.upper()))
+ apps = sorted(apps, lambda a, b: cmp(a.upper(), b.upper()))
return dict(app=None, apps=apps, myversion=myversion,
form_create=form_create, form_update=form_update)
@@ -292,13 +306,15 @@ def report_progress(app):
regex = re.compile('\[(.*?)\][^\:]+\:\s+(\-?\d+)')
if not os.path.exists(progress_file):
return []
- matches = regex.findall(open(progress_file,'r').read())
- events,counter = [],0
+ matches = regex.findall(open(progress_file, 'r').read())
+ events, counter = [], 0
for m in matches:
- if not m: continue
- days = -(request.now - datetime.datetime.strptime(m[0],'%Y-%m-%d %H:%M:%S')).days
+ if not m:
+ continue
+ days = -(request.now - datetime.datetime.strptime(m[0],
+ '%Y-%m-%d %H:%M:%S')).days
counter += int(m[1])
- events.append([days,counter])
+ events.append([days, counter])
return events
@@ -324,6 +340,7 @@ def pack():
session.flash = T('internal error: %s' % e)
redirect(URL('site'))
+
def pack_plugin():
app = get_app()
if len(request.args) == 2:
@@ -336,11 +353,12 @@ def pack_plugin():
return safe_read(filename, 'rb')
else:
session.flash = T('internal error')
- redirect(URL('plugin',args=request.args))
+ redirect(URL('plugin', args=request.args))
+
def upgrade_web2py():
dialog = FORM.confirm(T('Upgrade'),
- {T('Cancel'):URL('site')})
+ {T('Cancel'): URL('site')})
if dialog.accepted:
(success, error) = upgrade(request)
if success:
@@ -350,17 +368,18 @@ def upgrade_web2py():
redirect(URL('site'))
return dict(dialog=dialog)
+
def uninstall():
app = get_app()
dialog = FORM.confirm(T('Uninstall'),
- {T('Cancel'):URL('site')})
+ {T('Cancel'): URL('site')})
if dialog.accepted:
if MULTI_USER_MODE:
- if is_manager() and db(db.app.name==app).delete():
+ if is_manager() and db(db.app.name == app).delete():
pass
- elif db(db.app.name==app)(db.app.owner==auth.user.id).delete():
+ elif db(db.app.name == app)(db.app.owner == auth.user.id).delete():
pass
else:
session.flash = T('no permission to uninstall "%s"', app)
@@ -396,7 +415,7 @@ def compile_app():
session.flash = T('application compiled')
else:
session.flash = DIV(T('Cannot compile: there are errors in your app:'),
- CODE(c))
+ CODE(c))
redirect(URL('site'))
@@ -407,6 +426,7 @@ def remove_compiled_app():
session.flash = T('compiled application removed')
redirect(URL('site'))
+
def delete():
""" Object delete handler """
app = get_app()
@@ -421,9 +441,9 @@ def delete():
elif 'delete' in request.vars:
try:
full_path = apath(filename, r=request)
- lineno = count_lines(open(full_path,'r').read())
+ lineno = count_lines(open(full_path, 'r').read())
os.unlink(full_path)
- log_progress(app,'DELETE',filename,progress=-lineno)
+ log_progress(app, 'DELETE', filename, progress=-lineno)
session.flash = T('file "%(filename)s" deleted',
dict(filename=filename))
except Exception:
@@ -432,6 +452,7 @@ def delete():
redirect(URL(sender, anchor=request.vars.id2))
return dict(filename=filename, sender=sender)
+
def delete():
""" Object delete handler """
app = get_app()
@@ -442,33 +463,35 @@ def delete():
sender = sender[0]
dialog = FORM.confirm(T('Delete'),
- {T('Cancel'):URL(sender, anchor=request.vars.id)})
+ {T('Cancel'): URL(sender, anchor=request.vars.id)})
if dialog.accepted:
try:
full_path = apath(filename, r=request)
- lineno = count_lines(open(full_path,'r').read())
+ lineno = count_lines(open(full_path, 'r').read())
os.unlink(full_path)
- log_progress(app,'DELETE',filename,progress=-lineno)
+ log_progress(app, 'DELETE', filename, progress=-lineno)
session.flash = T('file "%(filename)s" deleted',
dict(filename=filename))
except Exception:
session.flash = T('unable to delete file "%(filename)s"',
dict(filename=filename))
redirect(URL(sender, anchor=request.vars.id2))
- return dict(dialog=dialog,filename=filename)
+ return dict(dialog=dialog, filename=filename)
+
def enable():
app = get_app()
- filename = os.path.join(apath(app, r=request),'DISABLED')
+ filename = os.path.join(apath(app, r=request), 'DISABLED')
if is_gae:
- return SPAN(T('Not supported'),_style='color:yellow')
+ return SPAN(T('Not supported'), _style='color:yellow')
elif os.path.exists(filename):
os.unlink(filename)
- return SPAN(T('Disable'),_style='color:green')
+ return SPAN(T('Disable'), _style='color:green')
else:
- safe_open(filename,'wb').write(time.ctime())
- return SPAN(T('Enable'),_style='color:red')
+ safe_open(filename, 'wb').write(time.ctime())
+ return SPAN(T('Enable'), _style='color:red')
+
def peek():
""" Visualize object code """
@@ -479,7 +502,7 @@ def peek():
else:
path = apath(filename, r=request)
try:
- data = safe_read(path).replace('\r','')
+ data = safe_read(path).replace('\r', '')
except IOError:
session.flash = T('file does not exist')
redirect(URL('site'))
@@ -491,6 +514,7 @@ def peek():
data=data,
extension=extension)
+
def test():
""" Execute controller tests """
app = get_app()
@@ -499,28 +523,34 @@ def test():
else:
file = '.*\.py'
- controllers = listdir(apath('%s/controllers/' % app, r=request), file + '$')
+ controllers = listdir(
+ apath('%s/controllers/' % app, r=request), file + '$')
return dict(app=app, controllers=controllers)
+
def keepalive():
return ''
+
def search():
- keywords=request.vars.keywords or ''
+ keywords = request.vars.keywords or ''
app = get_app()
- def match(filename,keywords):
- filename=os.path.join(apath(app, r=request),filename)
- if keywords in read_file(filename,'rb'):
+
+ def match(filename, keywords):
+ filename = os.path.join(apath(app, r=request), filename)
+ if keywords in read_file(filename, 'rb'):
return True
return False
path = apath(request.args[0], r=request)
- files1 = glob(os.path.join(path,'*/*.py'))
- files2 = glob(os.path.join(path,'*/*.html'))
- files3 = glob(os.path.join(path,'*/*/*.html'))
- files=[x[len(path)+1:].replace('\\','/') for x in files1+files2+files3 if match(x,keywords)]
+ files1 = glob(os.path.join(path, '*/*.py'))
+ files2 = glob(os.path.join(path, '*/*.html'))
+ files3 = glob(os.path.join(path, '*/*/*.html'))
+ files = [x[len(path) + 1:].replace(
+ '\\', '/') for x in files1 + files2 + files3 if match(x, keywords)]
return response.json(dict(files=files, message=T.M('Searching: **%s** %%{file}', len(files))))
+
def edit():
""" File edit handler """
# Load json only if it is ajax edited...
@@ -552,7 +582,7 @@ def edit():
except IOError:
session.flash = T('Invalid action')
if 'from_ajax' in request.vars:
- return response.json({'error': str(T('Invalid action'))})
+ return response.json({'error': str(T('Invalid action'))})
else:
redirect(URL('site'))
@@ -590,7 +620,8 @@ def edit():
data = request.vars.data.replace('\r\n', '\n').strip() + '\n'
safe_write(path, data)
lineno_new = count_lines(data)
- log_progress(app,'EDIT',filename,progress=lineno_new-lineno_old)
+ log_progress(
+ app, 'EDIT', filename, progress=lineno_new - lineno_old)
file_hash = md5_hash(data)
saved_on = time.ctime(os.stat(path)[stat.ST_MTIME])
response.flash = T('file saved on %s', saved_on)
@@ -602,35 +633,40 @@ def edit():
if filetype == 'python' and request.vars.data:
import _ast
try:
- code = request.vars.data.rstrip().replace('\r\n','\n')+'\n'
+ code = request.vars.data.rstrip().replace('\r\n', '\n') + '\n'
compile(code, path, "exec", _ast.PyCF_ONLY_AST)
except Exception, e:
- start = sum([len(line)+1 for l, line
- in enumerate(request.vars.data.split("\n"))
- if l < e.lineno-1])
+ start = sum([len(line) + 1 for l, line
+ in enumerate(request.vars.data.split("\n"))
+ if l < e.lineno - 1])
if e.text and e.offset:
- offset = e.offset - (len(e.text) - len(e.text.splitlines()[-1]))
+ offset = e.offset - (len(e.text) - len(
+ e.text.splitlines()[-1]))
else:
offset = 0
- highlight = {'start': start, 'end': start + offset + 1, 'lineno': e.lineno}
+ highlight = {'start': start, 'end': start +
+ offset + 1, 'lineno': e.lineno}
try:
ex_name = e.__class__.__name__
except:
ex_name = 'unknown exception!'
response.flash = DIV(T('failed to compile file because:'), BR(),
- B(ex_name), ' '+T('at line %s', e.lineno),
- offset and ' '+T('at char %s', offset) or '',
+ B(ex_name), ' ' + T('at line %s', e.lineno),
+ offset and ' ' +
+ T('at char %s', offset) or '',
PRE(str(e)))
if data_or_revert and request.args[1] == 'modules':
# Lets try to reload the modules
try:
mopath = '.'.join(request.args[2:])[:-3]
- exec 'import applications.%s.modules.%s' % (request.args[0], mopath)
+ exec 'import applications.%s.modules.%s' % (
+ request.args[0], mopath)
reload(sys.modules['applications.%s.modules.%s'
- % (request.args[0], mopath)])
+ % (request.args[0], mopath)])
except Exception, e:
- response.flash = DIV(T('failed to reload module because:'),PRE(str(e)))
+ response.flash = DIV(
+ T('failed to reload module because:'), PRE(str(e)))
edit_controller = None
editviewlinks = None
@@ -640,28 +676,28 @@ def edit():
request.args[2] + '.py')
if os.path.exists(apath(cfilename, r=request)):
edit_controller = URL('edit', args=[cfilename])
- view = request.args[3].replace('.html','')
- view_link = URL(request.args[0],request.args[2],view)
+ view = request.args[3].replace('.html', '')
+ view_link = URL(request.args[0], request.args[2], view)
elif filetype == 'python' and request.args[1] == 'controllers':
## it's a controller file.
## Create links to all of the associated view files.
app = get_app()
viewname = os.path.splitext(request.args[2])[0]
- viewpath = os.path.join(app,'views',viewname)
+ viewpath = os.path.join(app, 'views', viewname)
aviewpath = apath(viewpath, r=request)
viewlist = []
if os.path.exists(aviewpath):
if os.path.isdir(aviewpath):
- viewlist = glob(os.path.join(aviewpath,'*.html'))
- elif os.path.exists(aviewpath+'.html'):
- viewlist.append(aviewpath+'.html')
+ viewlist = glob(os.path.join(aviewpath, '*.html'))
+ elif os.path.exists(aviewpath + '.html'):
+ viewlist.append(aviewpath + '.html')
if len(viewlist):
editviewlinks = []
for v in viewlist:
vf = os.path.split(v)[-1]
- vargs = "/".join([viewpath.replace(os.sep,"/"),vf])
- editviewlinks.append(A(vf.split(".")[0],\
- _href=URL('edit',args=[vargs])))
+ vargs = "/".join([viewpath.replace(os.sep, "/"), vf])
+ editviewlinks.append(A(vf.split(".")[0],
+ _href=URL('edit', args=[vargs])))
if len(request.args) > 2 and request.args[1] == 'controllers':
controller = (request.args[2])[:-3]
@@ -670,7 +706,7 @@ def edit():
(controller, functions) = (None, None)
if 'from_ajax' in request.vars:
- return response.json({'file_hash': file_hash, 'saved_on': saved_on, 'functions':functions, 'controller': controller, 'application': request.args[0], 'highlight': highlight })
+ return response.json({'file_hash': file_hash, 'saved_on': saved_on, 'functions': functions, 'controller': controller, 'application': request.args[0], 'highlight': highlight})
else:
editarea_preferences = {}
@@ -680,8 +716,8 @@ def edit():
editarea_preferences['REPLACE_TAB_BY_SPACES'] = '4'
editarea_preferences['DISPLAY'] = 'onload'
for key in editarea_preferences:
- if globals().has_key(key):
- editarea_preferences[key]=globals()[key]
+ if key in globals():
+ editarea_preferences[key] = globals()[key]
return dict(app=request.args[0],
filename=filename,
filetype=filetype,
@@ -695,6 +731,7 @@ def edit():
editarea_preferences=editarea_preferences,
editviewlinks=editviewlinks)
+
def resolve():
"""
"""
@@ -739,19 +776,19 @@ def resolve():
return 'minus'
if request.vars:
- c = '\n'.join([item[2:].rstrip() for (i, item) in enumerate(d) if item[0] \
- == ' ' or 'line%i' % i in request.vars])
+ c = '\n'.join([item[2:].rstrip() for (i, item) in enumerate(d) if item[0]
+ == ' ' or 'line%i' % i in request.vars])
safe_write(path, c)
session.flash = 'files merged'
redirect(URL('edit', args=request.args))
else:
# Making the short circuit compatible with <= python2.4
- gen_data = lambda index,item: not item[:1] in ['+','-'] and "" \
- or INPUT(_type='checkbox',
- _name='line%i' % index,
- value=item[0] == '+')
+ gen_data = lambda index, item: not item[:1] in ['+', '-'] and "" \
+ or INPUT(_type='checkbox',
+ _name='line%i' % index,
+ value=item[0] == '+')
- diff = TABLE(*[TR(TD(gen_data(i,item)),
+ diff = TABLE(*[TR(TD(gen_data(i, item)),
TD(item[0]),
TD(leading(item[2:]),
TT(item[2:].rstrip())), _class=getclass(item))
@@ -767,10 +804,11 @@ def edit_language():
strings = read_dict(apath(filename, r=request))
if '__corrupted__' in strings:
- form = SPAN(strings['__corrupted__'],_class='error')
- return dict(filename=filename, form=form)
+ form = SPAN(strings['__corrupted__'], _class='error')
+ return dict(filename=filename, form=form)
- keys = sorted(strings.keys(),lambda x,y: cmp(unicode(x,'utf-8').lower(), unicode(y,'utf-8').lower()))
+ keys = sorted(strings.keys(), lambda x, y: cmp(
+ unicode(x, 'utf-8').lower(), unicode(y, 'utf-8').lower()))
rows = []
rows.append(H2(T('Original/Translation')))
@@ -779,16 +817,16 @@ def edit_language():
s = strings[key]
(prefix, sep, key) = key.partition('\x01')
if sep:
- prefix = SPAN(prefix+': ', _class='tm_ftag')
+ prefix = SPAN(prefix + ': ', _class='tm_ftag')
k = key
else:
(k, prefix) = (prefix, '')
- _class='untranslated' if k==s else 'translated'
+ _class = 'untranslated' if k == s else 'translated'
if len(s) <= 40:
elem = INPUT(_type='text', _name=name, value=s,
- _size=70,_class=_class)
+ _size=70, _class=_class)
else:
elem = TEXTAREA(_name=name, value=s, _cols=70,
_rows=5, _class=_class)
@@ -797,7 +835,7 @@ def edit_language():
k = (s != k) and k or B(k)
rows.append(P(prefix, k, BR(), elem, TAG.BUTTON(T('delete'),
- _onclick='return delkey("%s")' % name), _id=name))
+ _onclick='return delkey("%s")' % name), _id=name))
rows.append(INPUT(_type='submit', _value=T('update')))
form = FORM(*rows)
@@ -805,57 +843,66 @@ def edit_language():
strs = dict()
for key in keys:
name = md5_hash(key)
- if form.vars[name]==chr(127): continue
+ if form.vars[name] == chr(127):
+ continue
strs[key] = form.vars[name]
write_dict(apath(filename, r=request), strs)
session.flash = T('file saved on %(time)s', dict(time=time.ctime()))
- redirect(URL(r=request,args=request.args))
+ redirect(URL(r=request, args=request.args))
return dict(app=request.args[0], filename=filename, form=form)
+
def edit_plurals():
""" Edit plurals file """
app = get_app()
filename = '/'.join(request.args)
- plurals = read_plural_dict(apath(filename, r=request)) # plural forms dictionary
- nplurals = int(request.vars.nplurals)-1 # plural forms quantity
+ plurals = read_plural_dict(
+ apath(filename, r=request)) # plural forms dictionary
+ nplurals = int(request.vars.nplurals) - 1 # plural forms quantity
xnplurals = xrange(nplurals)
if '__corrupted__' in plurals:
- # show error message and exit
- form = SPAN(plurals['__corrupted__'],_class='error')
- return dict(filename=filename, form=form)
+ # show error message and exit
+ form = SPAN(plurals['__corrupted__'], _class='error')
+ return dict(filename=filename, form=form)
- keys = sorted(plurals.keys(),lambda x,y: cmp(unicode(x,'utf-8').lower(), unicode(y,'utf-8').lower()))
+ keys = sorted(plurals.keys(), lambda x, y: cmp(
+ unicode(x, 'utf-8').lower(), unicode(y, 'utf-8').lower()))
rows = []
- row=[T("Singular Form")]
- row.extend([T("Plural Form #%s", n+1) for n in xnplurals])
- table=TABLE(THEAD(TR(row)))
+ row = [T("Singular Form")]
+ row.extend([T("Plural Form #%s", n + 1) for n in xnplurals])
+ table = TABLE(THEAD(TR(row)))
for key in keys:
name = md5_hash(key)
forms = plurals[key]
if len(forms) < nplurals:
- forms.extend(None for i in xrange(nplurals-len(forms)))
+ forms.extend(None for i in xrange(nplurals - len(forms)))
row = [B(key)]
- row.extend([INPUT(_type='text', _name=name+'_'+str(n), value=forms[n], _size=20) for n in xnplurals])
- row.append(TD(TAG.BUTTON(T('delete'), _onclick='return delkey("%s")' % name)))
+ row.extend([INPUT(_type='text', _name=name + '_' + str(n),
+ value=forms[n], _size=20) for n in xnplurals])
+ row.append(TD(
+ TAG.BUTTON(T('delete'), _onclick='return delkey("%s")' % name)))
rows.append(TR(row, _id=name))
if rows:
table.append(TBODY(rows))
- rows=[table, INPUT(_type='submit', _value=T('update'))]
+ rows = [table, INPUT(_type='submit', _value=T('update'))]
form = FORM(*rows)
if form.accepts(request.vars, keepvalues=True):
new_plurals = dict()
for key in keys:
name = md5_hash(key)
- if form.vars[name+'_0']==chr(127): continue
- new_plurals[key] = [form.vars[name+'_'+str(n)] for n in xnplurals]
+ if form.vars[name + '_0'] == chr(127):
+ continue
+ new_plurals[key] = [form.vars[name + '_' + str(n)]
+ for n in xnplurals]
write_plural_dict(apath(filename, r=request), new_plurals)
session.flash = T('file saved on %(time)s', dict(time=time.ctime()))
- redirect(URL(r=request, args=request.args, vars=dict(nplurals=request.vars.nplurals)))
+ redirect(URL(r=request, args=request.args, vars=dict(
+ nplurals=request.vars.nplurals)))
return dict(app=request.args[0], filename=filename, form=form)
@@ -865,7 +912,7 @@ def about():
# ## check if file is not there
about = safe_read(apath('%s/ABOUT' % app, r=request))
license = safe_read(apath('%s/LICENSE' % app, r=request))
- return dict(app=app, about=MARKMIN(about), license=MARKMIN(license),progress=report_progress(app))
+ return dict(app=app, about=MARKMIN(about), license=MARKMIN(license), progress=report_progress(app))
def design():
@@ -876,24 +923,23 @@ def design():
msg = T('ATTENTION: you cannot edit the running application!')
response.flash = msg
- if request.vars and not request.vars.token==session.token:
+ if request.vars and not request.vars.token == session.token:
redirect(URL('logout'))
- if request.vars.pluginfile!=None and not isinstance(request.vars.pluginfile,str):
- filename=os.path.basename(request.vars.pluginfile.filename)
+ if request.vars.pluginfile is not None and not isinstance(request.vars.pluginfile, str):
+ filename = os.path.basename(request.vars.pluginfile.filename)
if plugin_install(app, request.vars.pluginfile.file,
request, filename):
session.flash = T('new plugin installed')
- redirect(URL('design',args=app))
+ redirect(URL('design', args=app))
else:
session.flash = \
T('unable to create application "%s"', request.vars.filename)
redirect(URL(r=request))
- elif isinstance(request.vars.pluginfile,str):
+ elif isinstance(request.vars.pluginfile, str):
session.flash = T('plugin not specified')
redirect(URL(r=request))
-
# If we have only pyc files it means that
# we cannot design
if os.path.exists(apath('%s/compiled' % app, r=request)):
@@ -903,7 +949,7 @@ def design():
# Get all models
models = listdir(apath('%s/models/' % app, r=request), '.*\.py$')
- models=[x.replace('\\','/') for x in models]
+ models = [x.replace('\\', '/') for x in models]
defines = {}
for m in models:
data = safe_read(apath('%s/models/%s' % (app, m), r=request))
@@ -911,8 +957,9 @@ def design():
defines[m].sort()
# Get all controllers
- controllers = sorted(listdir(apath('%s/controllers/' % app, r=request), '.*\.py$'))
- controllers = [x.replace('\\','/') for x in controllers]
+ controllers = sorted(
+ listdir(apath('%s/controllers/' % app, r=request), '.*\.py$'))
+ controllers = [x.replace('\\', '/') for x in controllers]
functions = {}
for c in controllers:
data = safe_read(apath('%s/controllers/%s' % (app, c), r=request))
@@ -920,8 +967,9 @@ def design():
functions[c] = items
# Get all views
- views = sorted(listdir(apath('%s/views/' % app, r=request), '[\w/\-]+(\.\w+)+$'))
- views = [x.replace('\\','/') for x in views if not x.endswith('.bak')]
+ views = sorted(
+ listdir(apath('%s/views/' % app, r=request), '[\w/\-]+(\.\w+)+$'))
+ views = [x.replace('\\', '/') for x in views if not x.endswith('.bak')]
extend = {}
include = {}
for c in views:
@@ -936,72 +984,76 @@ def design():
# Get all modules
modules = listdir(apath('%s/modules/' % app, r=request), '.*\.py$')
- modules = modules=[x.replace('\\','/') for x in modules]
+ modules = modules = [x.replace('\\', '/') for x in modules]
modules.sort()
# Get all private files
privates = listdir(apath('%s/private/' % app, r=request), '[^\.#].*')
- privates = [x.replace('\\','/') for x in privates]
+ privates = [x.replace('\\', '/') for x in privates]
privates.sort()
# Get all static files
statics = listdir(apath('%s/static/' % app, r=request), '[^\.#].*')
- statics = [x.replace('\\','/') for x in statics]
+ statics = [x.replace('\\', '/') for x in statics]
statics.sort()
# Get all languages
- languages=dict([(lang,info) for lang,info
- in read_possible_languages(
- apath(app, r=request)).iteritems()
- if info[2]!=0]) # info[2] is langfile_mtime:
+ languages = dict([(lang, info) for lang, info
+ in read_possible_languages(
+ apath(app, r=request)).iteritems()
+ if info[2] != 0]) # info[2] is langfile_mtime:
# get only existed files
#Get crontab
cronfolder = apath('%s/cron' % app, r=request)
- if not os.path.exists(cronfolder): os.mkdir(cronfolder)
+ if not os.path.exists(cronfolder):
+ os.mkdir(cronfolder)
crontab = apath('%s/cron/crontab' % app, r=request)
if not os.path.exists(crontab):
safe_write(crontab, '#crontab')
- plugins=[]
- def filter_plugins(items,plugins):
- plugins+=[item[7:].split('/')[0].split('.')[0] for item in items if item.startswith('plugin_')]
- plugins[:]=list(set(plugins))
+ plugins = []
+
+ def filter_plugins(items, plugins):
+ plugins += [item[7:].split('/')[0].split(
+ '.')[0] for item in items if item.startswith('plugin_')]
+ plugins[:] = list(set(plugins))
plugins.sort()
return [item for item in items if not item.startswith('plugin_')]
return dict(app=app,
- models=filter_plugins(models,plugins),
+ models=filter_plugins(models, plugins),
defines=defines,
- controllers=filter_plugins(controllers,plugins),
+ controllers=filter_plugins(controllers, plugins),
functions=functions,
- views=filter_plugins(views,plugins),
- modules=filter_plugins(modules,plugins),
+ views=filter_plugins(views, plugins),
+ modules=filter_plugins(modules, plugins),
extend=extend,
include=include,
- privates=filter_plugins(privates,plugins),
- statics=filter_plugins(statics,plugins),
+ privates=filter_plugins(privates, plugins),
+ statics=filter_plugins(statics, plugins),
languages=languages,
crontab=crontab,
plugins=plugins)
+
def delete_plugin():
""" Object delete handler """
- app=request.args(0)
+ app = request.args(0)
plugin = request.args(1)
- plugin_name='plugin_'+plugin
+ plugin_name = 'plugin_' + plugin
dialog = FORM.confirm(
T('Delete'),
- {T('Cancel'):URL('design', args=app)})
+ {T('Cancel'): URL('design', args=app)})
if dialog.accepted:
try:
- for folder in ['models','views','controllers','static','modules', 'private']:
- path=os.path.join(apath(app,r=request),folder)
+ for folder in ['models', 'views', 'controllers', 'static', 'modules', 'private']:
+ path = os.path.join(apath(app, r=request), folder)
for item in os.listdir(path):
- if item.rsplit('.',1)[0] == plugin_name:
- filename=os.path.join(path,item)
+ if item.rsplit('.', 1)[0] == plugin_name:
+ filename = os.path.join(path, item)
if os.path.isdir(filename):
shutil.rmtree(filename)
else:
@@ -1012,7 +1064,8 @@ def delete_plugin():
session.flash = T('unable to delete file plugin "%(plugin)s"',
dict(plugin=plugin))
redirect(URL('design', args=request.args(0), anchor=request.vars.id2))
- return dict(dialog=dialog,plugin=plugin)
+ return dict(dialog=dialog, plugin=plugin)
+
def plugin():
""" Application design handler """
@@ -1032,7 +1085,7 @@ def plugin():
# Get all models
models = listdir(apath('%s/models/' % app, r=request), '.*\.py$')
- models=[x.replace('\\','/') for x in models]
+ models = [x.replace('\\', '/') for x in models]
defines = {}
for m in models:
data = safe_read(apath('%s/models/%s' % (app, m), r=request))
@@ -1040,8 +1093,9 @@ def plugin():
defines[m].sort()
# Get all controllers
- controllers = sorted(listdir(apath('%s/controllers/' % app, r=request), '.*\.py$'))
- controllers = [x.replace('\\','/') for x in controllers]
+ controllers = sorted(
+ listdir(apath('%s/controllers/' % app, r=request), '.*\.py$'))
+ controllers = [x.replace('\\', '/') for x in controllers]
functions = {}
for c in controllers:
data = safe_read(apath('%s/controllers/%s' % (app, c), r=request))
@@ -1049,8 +1103,9 @@ def plugin():
functions[c] = items
# Get all views
- views = sorted(listdir(apath('%s/views/' % app, r=request), '[\w/\-]+\.\w+$'))
- views = [x.replace('\\','/') for x in views]
+ views = sorted(
+ listdir(apath('%s/views/' % app, r=request), '[\w/\-]+\.\w+$'))
+ views = [x.replace('\\', '/') for x in views]
extend = {}
include = {}
for c in views:
@@ -1064,23 +1119,23 @@ def plugin():
# Get all modules
modules = listdir(apath('%s/modules/' % app, r=request), '.*\.py$')
- modules = modules=[x.replace('\\','/') for x in modules]
+ modules = modules = [x.replace('\\', '/') for x in modules]
modules.sort()
# Get all private files
privates = listdir(apath('%s/private/' % app, r=request), '[^\.#].*')
- privates = [x.replace('\\','/') for x in privates]
+ privates = [x.replace('\\', '/') for x in privates]
privates.sort()
# Get all static files
statics = listdir(apath('%s/static/' % app, r=request), '[^\.#].*')
- statics = [x.replace('\\','/') for x in statics]
+ statics = [x.replace('\\', '/') for x in statics]
statics.sort()
# Get all languages
- languages = sorted([lang+'.py' for lang, info in
- T.get_possible_languages_info().iteritems()
- if info[2]!=0]) # info[2] is langfile_mtime:
+ languages = sorted([lang + '.py' for lang, info in
+ T.get_possible_languages_info().iteritems()
+ if info[2] != 0]) # info[2] is langfile_mtime:
# get only existed files
#Get crontab
@@ -1089,7 +1144,7 @@ def plugin():
safe_write(crontab, '#crontab')
def filter_plugins(items):
- regex=re.compile('^plugin_'+plugin+'(/.*|\..*)?$')
+ regex = re.compile('^plugin_' + plugin + '(/.*|\..*)?$')
return [item for item in items if item and regex.match(item)]
return dict(app=app,
@@ -1109,10 +1164,10 @@ def plugin():
def create_file():
""" Create files handler """
- if request.vars and not request.vars.token==session.token:
+ if request.vars and not request.vars.token == session.token:
redirect(URL('logout'))
try:
- anchor='#'+request.vars.id if request.vars.id else ''
+ anchor = '#' + request.vars.id if request.vars.id else ''
if request.vars.app:
app = get_app(request.vars.app)
path = abspath(request.vars.location)
@@ -1126,7 +1181,7 @@ def create_file():
raise SyntaxError
if not filename[-3:] == '.py':
filename += '.py'
- lang = re.match('^plural_rules-(.*)\.py$',filename).group(1)
+ lang = re.match('^plural_rules-(.*)\.py$', filename).group(1)
langinfo = read_possible_languages(apath(app, r=request))[lang]
text = dedent("""
#!/usr/bin/env python
@@ -1154,14 +1209,14 @@ def create_file():
raise SyntaxError
if not filename[-3:] == '.py':
filename += '.py'
- path=os.path.join(apath(app, r=request),'languages',filename)
+ path = os.path.join(apath(app, r=request), 'languages', filename)
if not os.path.exists(path):
safe_write(path, '')
# create language xx[-yy].py file:
findT(apath(app, r=request), filename[:-3])
session.flash = T('language file "%(filename)s" created/updated',
- dict(filename=filename))
- redirect(request.vars.sender+anchor)
+ dict(filename=filename))
+ redirect(request.vars.sender + anchor)
elif path[-8:] == '/models/':
# Handle python models
@@ -1188,21 +1243,22 @@ def create_file():
if request.vars.plugin and not filename.startswith('plugin_%s/' % request.vars.plugin):
filename = 'plugin_%s/%s' % (request.vars.plugin, filename)
# Handle template (html) views
- if filename.find('.')<0:
+ if filename.find('.') < 0:
filename += '.html'
extension = filename.split('.')[-1].lower()
if len(filename) == 5:
raise SyntaxError
- msg = T('This is the %(filename)s template', dict(filename=filename))
+ msg = T(
+ 'This is the %(filename)s template', dict(filename=filename))
if extension == 'html':
text = dedent("""
{{extend 'layout.html'}}
%s
{{=BEAUTIFY(response._vars)}}""" % msg)[1:]
else:
- generic = os.path.join(path,'generic.'+extension)
+ generic = os.path.join(path, 'generic.' + extension)
if os.path.exists(generic):
text = read_file(generic)
else:
@@ -1229,7 +1285,7 @@ def create_file():
text = ''
else:
- redirect(request.vars.sender+anchor)
+ redirect(request.vars.sender + anchor)
full_filename = os.path.join(path, filename)
dirpath = os.path.dirname(full_filename)
@@ -1241,24 +1297,26 @@ def create_file():
raise SyntaxError
safe_write(full_filename, text)
- log_progress(app,'CREATE',filename)
+ log_progress(app, 'CREATE', filename)
session.flash = T('file "%(filename)s" created',
dict(filename=full_filename[len(path):]))
- vars={}
- if request.vars.id: vars['id']=request.vars.id
- if request.vars.app: vars['app']=request.vars.app
+ vars = {}
+ if request.vars.id:
+ vars['id'] = request.vars.id
+ if request.vars.app:
+ vars['app'] = request.vars.app
redirect(URL('edit',
args=[os.path.join(request.vars.location, filename)], vars=vars))
except Exception, e:
- if not isinstance(e,HTTP):
+ if not isinstance(e, HTTP):
session.flash = T('cannot create file')
- redirect(request.vars.sender+anchor)
+ redirect(request.vars.sender + anchor)
def upload_file():
""" File uploading handler """
- if request.vars and not request.vars.token==session.token:
+ if request.vars and not request.vars.token == session.token:
redirect(URL('logout'))
try:
filename = None
@@ -1294,14 +1352,14 @@ def upload_file():
data = request.vars.file.file.read()
lineno = count_lines(data)
safe_write(filename, data, 'wb')
- log_progress(app,'UPLOAD',filename,lineno)
+ log_progress(app, 'UPLOAD', filename, lineno)
session.flash = T('file "%(filename)s" uploaded',
dict(filename=filename[len(path):]))
except Exception:
if filename:
- d = dict(filename = filename[len(path):])
+ d = dict(filename=filename[len(path):])
else:
- d = dict(filename = 'unkown')
+ d = dict(filename='unkown')
session.flash = T('cannot upload file "%(filename)s"', d)
redirect(request.vars.sender)
@@ -1319,7 +1377,8 @@ def errors():
method = request.args(1) or 'new'
db_ready = {}
db_ready['status'] = get_ticket_storage(app)
- db_ready['errmessage'] = T("No ticket_storage.txt found under /private folder")
+ db_ready['errmessage'] = T(
+ "No ticket_storage.txt found under /private folder")
db_ready['errlink'] = "http://web2py.com/books/default/chapter/29/13#Collecting-tickets"
if method == 'new':
@@ -1334,7 +1393,8 @@ def errors():
for fn in listdir(errors_path, '^[a-fA-F0-9.\-]+$'):
fullpath = os.path.join(errors_path, fn)
- if not os.path.isfile(fullpath): continue
+ if not os.path.isfile(fullpath):
+ continue
try:
fullpath_file = open(fullpath, 'r')
try:
@@ -1360,13 +1420,12 @@ def errors():
hash2error[hash] = dict(count=1, pickel=error,
causer=error_causer,
last_line=last_line,
- hash=hash,ticket=fn)
+ hash=hash, ticket=fn)
decorated = [(x['count'], x) for x in hash2error.values()]
decorated.sort(key=operator.itemgetter(0), reverse=True)
- return dict(errors = [x[1] for x in decorated], app=app, method=method, db_ready=db_ready)
-
+ return dict(errors=[x[1] for x in decorated], app=app, method=method, db_ready=db_ready)
elif method == 'dbnew':
errors_path = apath('%s/errors' % app, r=request)
@@ -1379,7 +1438,7 @@ def errors():
hash2error = dict()
- for fn in tk_db(tk_table.id>0).select():
+ for fn in tk_db(tk_table.id > 0).select():
try:
error = pickle.loads(fn.ticket_data)
except AttributeError:
@@ -1401,13 +1460,13 @@ def errors():
hash2error[hash] = dict(count=1, pickel=error,
causer=error_causer,
last_line=last_line,
- hash=hash,ticket=fn.ticket_id)
+ hash=hash, ticket=fn.ticket_id)
decorated = [(x['count'], x) for x in hash2error.values()]
decorated.sort(key=operator.itemgetter(0), reverse=True)
- return dict(errors = [x[1] for x in decorated], app=app, method=method)
+ return dict(errors=[x[1] for x in decorated], app=app, method=method)
elif method == 'dbold':
tk_db, tk_table = get_ticket_storage(app)
@@ -1415,9 +1474,10 @@ def errors():
if item[:7] == 'delete_':
tk_db(tk_table.ticket_id == item[7:]).delete()
tk_db.commit()
- tickets_ = tk_db(tk_table.id>0).select(tk_table.ticket_id, tk_table.created_datetime, orderby=~tk_table.created_datetime)
+ tickets_ = tk_db(tk_table.id > 0).select(tk_table.ticket_id, tk_table.created_datetime, orderby=~tk_table.created_datetime)
tickets = [row.ticket_id for row in tickets_]
- times = dict([(row.ticket_id, row.created_datetime) for row in tickets_])
+ times = dict(
+ [(row.ticket_id, row.created_datetime) for row in tickets_])
return dict(app=app, tickets=tickets, method=method, times=times)
@@ -1425,20 +1485,22 @@ def errors():
for item in request.vars:
if item[:7] == 'delete_':
os.unlink(apath('%s/errors/%s' % (app, item[7:]), r=request))
- func = lambda p: os.stat(apath('%s/errors/%s' % \
- (app, p), r=request)).st_mtime
- tickets = sorted(listdir(apath('%s/errors/' % app, r=request), '^\w.*'),
- key=func,
- reverse=True)
+ func = lambda p: os.stat(apath('%s/errors/%s' %
+ (app, p), r=request)).st_mtime
+ tickets = sorted(
+ listdir(apath('%s/errors/' % app, r=request), '^\w.*'),
+ key=func,
+ reverse=True)
return dict(app=app, tickets=tickets, method=method, db_ready=db_ready)
+
def get_ticket_storage(app):
private_folder = apath('%s/private' % app, r=request)
ticket_file = os.path.join(private_folder, 'ticket_storage.txt')
if os.path.exists(ticket_file):
db_string = open(ticket_file).read()
- db_string = db_string.strip().replace('\r','').replace('\n','')
+ db_string = db_string.strip().replace('\r', '').replace('\n', '')
else:
return False
tickets_table = 'web2py_ticket'
@@ -1447,12 +1509,13 @@ def get_ticket_storage(app):
ticketsdb = DAL(db_string, folder=db_path, auto_import=True)
if not ticketsdb.get(tablename):
table = ticketsdb.define_table(
- tablename,
- Field('ticket_id', length=100),
- Field('ticket_data', 'text'),
- Field('created_datetime', 'datetime'),
- )
- return ticketsdb , ticketsdb.get(tablename)
+ tablename,
+ Field('ticket_id', length=100),
+ Field('ticket_data', 'text'),
+ Field('created_datetime', 'datetime'),
+ )
+ return ticketsdb, ticketsdb.get(tablename)
+
def make_link(path):
""" Create a link from a path """
@@ -1465,7 +1528,7 @@ def make_link(path):
editable = {'controllers': '.py', 'models': '.py', 'views': '.html'}
for key in editable.keys():
- check_extension = folder.endswith("%s/%s" % (app,key))
+ check_extension = folder.endswith("%s/%s" % (app, key))
if ext.lower() == editable[key] and check_extension:
return A('"' + tryFile + '"',
_href=URL(r=request,
@@ -1536,6 +1599,7 @@ def ticket():
layer=e.layer,
myversion=myversion)
+
def ticketdb():
""" Ticket handler """
@@ -1559,17 +1623,19 @@ def ticketdb():
layer=e.layer,
myversion=myversion)
+
def error():
""" Generate a ticket (for testing) """
raise RuntimeError('admin ticket generator at your service')
+
def update_languages():
""" Update available languages """
app = get_app()
update_all_languages(apath(app, r=request))
session.flash = T('Language files (static strings) updated')
- redirect(URL('design',args=app,anchor='languages'))
+ redirect(URL('design', args=app, anchor='languages'))
def twitter():
@@ -1585,11 +1651,11 @@ def twitter():
for e in data:
d[e["id"]] = e
r = reversed(sorted(d))
- return dict(tweets = [d[k] for k in r])
+ return dict(tweets=[d[k] for k in r])
else:
return 'disabled'
except Exception, e:
- return DIV(T('Unable to download because:'),BR(),str(e))
+ return DIV(T('Unable to download because:'), BR(), str(e))
def user():
@@ -1600,12 +1666,14 @@ def user():
else:
return dict(form=T("Disabled"))
+
def reload_routes():
""" Reload routes.py """
import gluon.rewrite
gluon.rewrite.load()
redirect(URL('site'))
+
def manage_students():
if not (MULTI_USER_MODE and is_manager()):
session.flash = T('Not Authorized')
@@ -1614,18 +1682,19 @@ def manage_students():
grid = SQLFORM.grid(db.auth_user)
return locals()
+
def bulk_register():
if not (MULTI_USER_MODE and is_manager()):
session.flash = T('Not Authorized')
redirect(URL('site'))
- form = SQLFORM.factory(Field('emails','text'))
+ form = SQLFORM.factory(Field('emails', 'text'))
if form.process().accepted:
emails = [x.strip() for x in form.vars.emails.split('\n') if x.strip()]
n = 0
for email in emails:
if not db.auth_user(email=email):
- n += db.auth_user.insert(email = email) and 1 or 0
- session.flash = T('%s students registered',n)
+ n += db.auth_user.insert(email=email) and 1 or 0
+ session.flash = T('%s students registered', n)
redirect(URL('site'))
return locals()
@@ -1634,6 +1703,7 @@ def bulk_register():
# 2) should not prompt user at console
# 3) should give option to force commit and not reuqire manual merge
+
def git_pull():
""" Git Pull handler """
app = get_app()
@@ -1641,10 +1711,10 @@ def git_pull():
session.flash = GIT_MISSING
redirect(URL('site'))
dialog = FORM.confirm(T('Pull'),
- {T('Cancel'):URL('site')})
+ {T('Cancel'): URL('site')})
if dialog.accepted:
try:
- repo = Repo(os.path.join(apath(r=request),app))
+ repo = Repo(os.path.join(apath(r=request), app))
origin = repo.remotes.origin
origin.fetch()
origin.pull()
@@ -1660,14 +1730,16 @@ def git_pull():
session.flash = T("Pull is not possible because you have unmerged files. Fix them up in the work tree, and then try again.")
redirect(URL('site'))
except GitCommandError, status:
- session.flash = T("Pull failed, git exited abnormally. See logs for details.")
+ session.flash = T(
+ "Pull failed, git exited abnormally. See logs for details.")
redirect(URL('site'))
- except Exception,e:
- session.flash = T("Pull failed, git exited abnormally. See logs for details.")
+ except Exception, e:
+ session.flash = T(
+ "Pull failed, git exited abnormally. See logs for details.")
redirect(URL('site'))
elif 'cancel' in request.vars:
redirect(URL('site'))
- return dict(app=app,dialog=dialog)
+ return dict(app=app, dialog=dialog)
def git_push():
@@ -1676,24 +1748,26 @@ def git_push():
if not have_git:
session.flash = GIT_MISSING
redirect(URL('site'))
- form = SQLFORM.factory(Field('changelog',requires=IS_NOT_EMPTY()))
- form.element('input[type=submit]')['_value']=T('Push')
- form.add_button(T('Cancel'),URL('site'))
+ form = SQLFORM.factory(Field('changelog', requires=IS_NOT_EMPTY()))
+ form.element('input[type=submit]')['_value'] = T('Push')
+ form.add_button(T('Cancel'), URL('site'))
form.process()
if form.accepted:
try:
- repo = Repo(os.path.join(apath(r=request),app))
+ repo = Repo(os.path.join(apath(r=request), app))
index = repo.index
- index.add([apath(r=request)+app+'/*'])
+ index.add([apath(r=request) + app + '/*'])
new_commit = index.commit(form.vars.changelog)
origin = repo.remotes.origin
origin.push()
- session.flash = T("Git repo updated with latest application changes.")
+ session.flash = T(
+ "Git repo updated with latest application changes.")
redirect(URL('site'))
except UnmergedEntriesError:
session.flash = T("Push failed, there are unmerged entries in the cache. Resolve merge issues manually and try again.")
redirect(URL('site'))
except Exception, e:
- session.flash = T("Push failed, git exited abnormally. See logs for details.")
+ session.flash = T(
+ "Push failed, git exited abnormally. See logs for details.")
redirect(URL('site'))
- return dict(app=app,form=form)
+ return dict(app=app, form=form)
diff --git a/applications/admin/controllers/gae.py b/applications/admin/controllers/gae.py
index 2047a3e7..ddb13e0a 100644
--- a/applications/admin/controllers/gae.py
+++ b/applications/admin/controllers/gae.py
@@ -9,83 +9,92 @@ try:
import shutil
from gluon.fileutils import read_file, write_file
except:
- session.flash='sorry, only on Unix systems'
- redirect(URL(request.application,'default','site'))
+ session.flash = 'sorry, only on Unix systems'
+ redirect(URL(request.application, 'default', 'site'))
if MULTI_USER_MODE and not is_manager():
session.flash = 'Not Authorized'
- redirect(URL('default','site'))
+ redirect(URL('default', 'site'))
+
+forever = 10 ** 8
-forever=10**8
def kill():
- p = cache.ram('gae_upload',lambda:None,forever)
- if not p or p.poll()!=None:
+ p = cache.ram('gae_upload', lambda: None, forever)
+ if not p or p.poll() is not None:
return 'oops'
os.kill(p.pid, signal.SIGKILL)
- cache.ram('gae_upload',lambda:None,-1)
+ cache.ram('gae_upload', lambda: None, -1)
+
class EXISTS(object):
def __init__(self, error_message='file not found'):
self.error_message = error_message
+
def __call__(self, value):
if os.path.exists(value):
- return (value,None)
- return (value,self.error_message)
+ return (value, None)
+ return (value, self.error_message)
+
def deploy():
regex = re.compile('^\w+$')
- apps = sorted(file for file in os.listdir(apath(r=request)) if regex.match(file))
+ apps = sorted(
+ file for file in os.listdir(apath(r=request)) if regex.match(file))
form = SQLFORM.factory(
- Field('appcfg',default=GAE_APPCFG,label=T('Path to appcfg.py'),
+ Field('appcfg', default=GAE_APPCFG, label=T('Path to appcfg.py'),
requires=EXISTS(error_message=T('file not found'))),
- Field('google_application_id',requires=IS_MATCH('[\w\-]+'),label=T('Google Application Id')),
- Field('applications','list:string',
- requires=IS_IN_SET(apps,multiple=True),
+ Field('google_application_id', requires=IS_MATCH(
+ '[\w\-]+'), label=T('Google Application Id')),
+ Field('applications', 'list:string',
+ requires=IS_IN_SET(apps, multiple=True),
label=T('web2py apps to deploy')),
- Field('email',requires=IS_EMAIL(),label=T('GAE Email')),
- Field('password','password',requires=IS_NOT_EMPTY(),label=T('GAE Password')))
- cmd = output = errors= ""
- if form.accepts(request,session):
+ Field('email', requires=IS_EMAIL(), label=T('GAE Email')),
+ Field('password', 'password', requires=IS_NOT_EMPTY(), label=T('GAE Password')))
+ cmd = output = errors = ""
+ if form.accepts(request, session):
try:
kill()
except:
pass
- ignore_apps = [item for item in apps \
- if not item in form.vars.applications]
+ ignore_apps = [item for item in apps
+ if not item in form.vars.applications]
regex = re.compile('\(applications/\(.*')
yaml = apath('../app.yaml', r=request)
if not os.path.exists(yaml):
example = apath('../app.example.yaml', r=request)
- shutil.copyfile(example,yaml)
+ shutil.copyfile(example, yaml)
data = read_file(yaml)
- data = re.sub('application:.*','application: %s' % form.vars.google_application_id,data)
- data = regex.sub('(applications/(%s)/.*)|' % '|'.join(ignore_apps),data)
+ data = re.sub('application:.*', 'application: %s' %
+ form.vars.google_application_id, data)
+ data = regex.sub(
+ '(applications/(%s)/.*)|' % '|'.join(ignore_apps), data)
write_file(yaml, data)
path = request.env.applications_parent
cmd = '%s --email=%s --passin update %s' % \
(form.vars.appcfg, form.vars.email, path)
p = cache.ram('gae_upload',
- lambda s=subprocess,c=cmd:s.Popen(c, shell=True,
- stdin=s.PIPE,
- stdout=s.PIPE,
- stderr=s.PIPE, close_fds=True),-1)
- p.stdin.write(form.vars.password+'\n')
+ lambda s=subprocess, c=cmd: s.Popen(c, shell=True,
+ stdin=s.PIPE,
+ stdout=s.PIPE,
+ stderr=s.PIPE, close_fds=True), -1)
+ p.stdin.write(form.vars.password + '\n')
fcntl.fcntl(p.stdout.fileno(), fcntl.F_SETFL, os.O_NONBLOCK)
fcntl.fcntl(p.stderr.fileno(), fcntl.F_SETFL, os.O_NONBLOCK)
- return dict(form=form,command=cmd)
+ return dict(form=form, command=cmd)
+
def callback():
- p = cache.ram('gae_upload',lambda:None,forever)
- if not p or p.poll()!=None:
+ p = cache.ram('gae_upload', lambda: None, forever)
+ if not p or p.poll() is not None:
return ''
try:
output = p.stdout.read()
except:
- output=''
+ output = ''
try:
errors = p.stderr.read()
except:
- errors=''
- return (output+errors).replace('\n','
')
+ errors = ''
+ return (output + errors).replace('\n', '
')
diff --git a/applications/admin/controllers/mercurial.py b/applications/admin/controllers/mercurial.py
index 34e0516b..dd70a85e 100644
--- a/applications/admin/controllers/mercurial.py
+++ b/applications/admin/controllers/mercurial.py
@@ -2,10 +2,10 @@ from gluon.fileutils import read_file, write_file
if DEMO_MODE or MULTI_USER_MODE:
session.flash = T('disabled in demo mode')
- redirect(URL('default','site'))
+ redirect(URL('default', 'site'))
if not have_mercurial:
- session.flash=T("Sorry, could not find mercurial installed")
- redirect(URL('default','design',args=request.args(0)))
+ session.flash = T("Sorry, could not find mercurial installed")
+ redirect(URL('default', 'design', args=request.args(0)))
_hgignore_content = """\
syntax: glob
@@ -22,6 +22,7 @@ sessions/*
errors/*
"""
+
def hg_repo(path):
import os
uio = ui.ui()
@@ -37,13 +38,14 @@ def hg_repo(path):
write_file(hgignore, _hgignore_content)
return repo
+
def commit():
app = request.args(0)
path = apath(app, r=request)
repo = hg_repo(path)
- form = FORM('Comment:',INPUT(_name='comment',requires=IS_NOT_EMPTY()),
- INPUT(_type='submit',_value=T('Commit')))
- if form.accepts(request.vars,session):
+ form = FORM('Comment:', INPUT(_name='comment', requires=IS_NOT_EMPTY()),
+ INPUT(_type='submit', _value=T('Commit')))
+ if form.accepts(request.vars, session):
oldid = repo[repo.lookup('.')]
addremove(repo)
repo.commit(text=form.vars.comment)
@@ -51,32 +53,33 @@ def commit():
response.flash = 'no changes'
try:
files = TABLE(*[TR(file) for file in repo[repo.lookup('.')].files()])
- changes = TABLE(TR(TH('revision'),TH('description')))
+ changes = TABLE(TR(TH('revision'), TH('description')))
for change in repo.changelog:
- ctx=repo.changectx(change)
+ ctx = repo.changectx(change)
revision, description = ctx.rev(), ctx.description()
- changes.append(TR(A(revision,_href=URL('revision',
- args=(app,revision))),
+ changes.append(TR(A(revision, _href=URL('revision',
+ args=(app, revision))),
description))
except:
files = []
changes = []
- return dict(form=form,files=files,changes=changes,repo=repo)
+ return dict(form=form, files=files, changes=changes, repo=repo)
+
def revision():
app = request.args(0)
path = apath(app, r=request)
repo = hg_repo(path)
revision = request.args(1)
- ctx=repo.changectx(revision)
- form=FORM(INPUT(_type='submit',_value=T('Revert')))
+ ctx = repo.changectx(revision)
+ form = FORM(INPUT(_type='submit', _value=T('Revert')))
if form.accepts(request.vars):
hg.update(repo, revision)
session.flash = "reverted to revision %s" % ctx.rev()
- redirect(URL('default','design',args=app))
+ redirect(URL('default', 'design', args=app))
return dict(
files=ctx.files(),
rev=str(ctx.rev()),
desc=ctx.description(),
form=form
- )
+ )
diff --git a/applications/admin/controllers/openshift.py b/applications/admin/controllers/openshift.py
index df9e6d8b..e42b61fc 100644
--- a/applications/admin/controllers/openshift.py
+++ b/applications/admin/controllers/openshift.py
@@ -3,31 +3,34 @@ try:
from distutils import dir_util
except ImportError:
session.flash = T('requires distutils, but not installed')
- redirect(URL('default','site'))
+ redirect(URL('default', 'site'))
try:
from git import *
except ImportError:
session.flash = T('requires python-git, but not installed')
- redirect(URL('default','site'))
+ redirect(URL('default', 'site'))
+
def deploy():
apps = sorted(file for file in os.listdir(apath(r=request)))
form = SQLFORM.factory(
- Field('osrepo',default='/tmp',label=T('Path to local openshift repo root.'),
- requires=EXISTS(error_message=T('directory not found'))),
- Field('osname',default='web2py',label=T('WSGI reference name')),
- Field('applications','list:string',
- requires=IS_IN_SET(apps,multiple=True),
+ Field(
+ 'osrepo', default='/tmp', label=T('Path to local openshift repo root.'),
+ requires=EXISTS(error_message=T('directory not found'))),
+ Field('osname', default='web2py', label=T('WSGI reference name')),
+ Field('applications', 'list:string',
+ requires=IS_IN_SET(apps, multiple=True),
label=T('web2py apps to deploy')))
- cmd = output = errors= ""
- if form.accepts(request,session):
+ cmd = output = errors = ""
+ if form.accepts(request, session):
try:
kill()
except:
pass
- ignore_apps = [item for item in apps if not item in form.vars.applications]
+ ignore_apps = [
+ item for item in apps if not item in form.vars.applications]
regex = re.compile('\(applications/\(.*')
w2p_origin = os.getcwd()
osrepo = form.vars.osrepo
@@ -38,23 +41,25 @@ def deploy():
assert repo.bare == False
for i in form.vars.applications:
- appsrc = os.path.join(apath(r=request),i)
- appdest = os.path.join(osrepo,'wsgi',osname,'applications',i)
- dir_util.copy_tree(appsrc,appdest)
+ appsrc = os.path.join(apath(r=request), i)
+ appdest = os.path.join(osrepo, 'wsgi', osname, 'applications', i)
+ dir_util.copy_tree(appsrc, appdest)
#shutil.copytree(appsrc,appdest)
- index.add(['wsgi/'+osname+'/applications/'+i])
+ index.add(['wsgi/' + osname + '/applications/' + i])
new_commit = index.commit("Deploy from Web2py IDE")
origin = repo.remotes.origin
origin.push
origin.push()
#Git code ends here
- return dict(form=form,command=cmd)
+ return dict(form=form, command=cmd)
+
class EXISTS(object):
def __init__(self, error_message='file not found'):
self.error_message = error_message
+
def __call__(self, value):
if os.path.exists(value):
- return (value,None)
- return (value,self.error_message)
+ return (value, None)
+ return (value, self.error_message)
diff --git a/applications/admin/controllers/plugin_jqmobile.py b/applications/admin/controllers/plugin_jqmobile.py
index b9265a63..18fc67d7 100644
--- a/applications/admin/controllers/plugin_jqmobile.py
+++ b/applications/admin/controllers/plugin_jqmobile.py
@@ -1,8 +1,10 @@
-response.files=response.files[:3]
-response.menu=[]
+response.files = response.files[:3]
+response.menu = []
+
def index():
return locals()
+
def about():
return locals()
diff --git a/applications/admin/controllers/shell.py b/applications/admin/controllers/shell.py
index 561e06eb..1abc0f72 100644
--- a/applications/admin/controllers/shell.py
+++ b/applications/admin/controllers/shell.py
@@ -1,25 +1,29 @@
import sys
import cStringIO
import gluon.contrib.shell
-import code, thread
+import code
+import thread
from gluon.shell import env
if DEMO_MODE or MULTI_USER_MODE:
session.flash = T('disabled in demo mode')
- redirect(URL('default','site'))
+ redirect(URL('default', 'site'))
+
+FE = 10 ** 9
-FE=10**9
def index():
app = request.args(0) or 'admin'
reset()
return dict(app=app)
+
def callback():
app = request.args[0]
command = request.vars.statement
- escape = command[:1]!='!'
- history = session['history:'+app] = session.get('history:'+app,gluon.contrib.shell.History())
+ escape = command[:1] != '!'
+ history = session['history:' + app] = session.get(
+ 'history:' + app, gluon.contrib.shell.History())
if not escape:
command = command[1:]
if command == '%reset':
@@ -27,19 +31,20 @@ def callback():
return '*** reset ***'
elif command[0] == '%':
try:
- command=session['commands:'+app][int(command[1:])]
+ command = session['commands:' + app][int(command[1:])]
except ValueError:
return ''
- session['commands:'+app].append(command)
- environ=env(app,True)
- output = gluon.contrib.shell.run(history,command,environ)
- k = len(session['commands:'+app]) - 1
+ session['commands:' + app].append(command)
+ environ = env(app, True)
+ output = gluon.contrib.shell.run(history, command, environ)
+ k = len(session['commands:' + app]) - 1
#output = PRE(output)
#return TABLE(TR('In[%i]:'%k,PRE(command)),TR('Out[%i]:'%k,output))
return 'In [%i] : %s%s\n' % (k + 1, command, output)
+
def reset():
app = request.args(0) or 'admin'
- session['commands:'+app] = []
- session['history:'+app] = gluon.contrib.shell.History()
+ session['commands:' + app] = []
+ session['history:' + app] = gluon.contrib.shell.History()
return 'done'
diff --git a/applications/admin/controllers/toolbar.py b/applications/admin/controllers/toolbar.py
index 9e0294a3..83a25f83 100644
--- a/applications/admin/controllers/toolbar.py
+++ b/applications/admin/controllers/toolbar.py
@@ -2,10 +2,12 @@ import os
from gluon.settings import global_settings, read_file
#
+
def index():
app = request.args(0)
return dict(app=app)
+
def profiler():
"""
to use the profiler start web2py with -F profiler.log
@@ -19,11 +21,11 @@ def profiler():
else:
size = 0
if os.path.exists(filename):
- data = read_file('profiler.log','rb')
- if size=m: redirect(URL('step2'))
- table=session.app['tables'][n]
- form=SQLFORM.factory(Field('field_names','list:string',
- default=session.app.get('table_'+table,[])))
+ response.view = 'wizard/step.html'
+ n = int(request.args(0) or 0)
+ m = len(session.app['tables'])
+ if n >= m:
+ redirect(URL('step2'))
+ table = session.app['tables'][n]
+ form = SQLFORM.factory(Field('field_names', 'list:string',
+ default=session.app.get('table_' + table, [])))
if form.accepts(request.vars) and form.vars.field_names:
- fields=listify(form.vars.field_names)
- if table=='auth_user':
- for field in ['first_name','last_name','username','email','password']:
+ fields = listify(form.vars.field_names)
+ if table == 'auth_user':
+ for field in ['first_name', 'last_name', 'username', 'email', 'password']:
if not field in fields:
fields.append(field)
- session.app['table_'+table]=[t.strip().lower()
- for t in listify(form.vars.field_names)
- if t.strip()]
+ session.app['table_' + table] = [t.strip().lower()
+ for t in listify(form.vars.field_names)
+ if t.strip()]
try:
- tables=sort_tables(session.app['tables'])
+ tables = sort_tables(session.app['tables'])
except RuntimeError:
- response.flash=T('invalid circular reference')
+ response.flash = T('invalid circular reference')
else:
- if n=m: redirect(URL('step4'))
- page=session.app['pages'][n]
- markmin_url='http://web2py.com/examples/static/markmin.html'
- form=SQLFORM.factory(Field('content','text',
- default=session.app.get('page_'+page,[]),
- comment=A('use markmin',
- _href=markmin_url,_target='_blank')),
- formstyle='table2cols')
+ response.view = 'wizard/step.html'
+ n = int(request.args(0) or 0)
+ m = len(session.app['pages'])
+ if n >= m:
+ redirect(URL('step4'))
+ page = session.app['pages'][n]
+ markmin_url = 'http://web2py.com/examples/static/markmin.html'
+ form = SQLFORM.factory(Field('content', 'text',
+ default=session.app.get('page_' + page, []),
+ comment=A('use markmin',
+ _href=markmin_url, _target='_blank')),
+ formstyle='table2cols')
if form.accepts(request.vars):
- session.app['page_'+page]=form.vars.content
- if n' % settings\n"
- s+='response.meta.keywords = settings.keywords\n'
- s+='response.meta.description = settings.description\n'
- s+='response.menu = [\n'
+ s = ''
+ s += 'response.title = settings.title\n'
+ s += 'response.subtitle = settings.subtitle\n'
+ s += "response.meta.author = '%(author)s <%(author_email)s>' % settings\n"
+ s += 'response.meta.keywords = settings.keywords\n'
+ s += 'response.meta.description = settings.description\n'
+ s += 'response.menu = [\n'
for page in pages:
if not page.startswith('error'):
if page.endswith('_manage'):
@@ -403,65 +440,70 @@ def make_menu(pages):
else:
page_name = page
page_name = ' '.join(x.capitalize() for x in page_name.split('_'))
- s+="(T('%s'),URL('default','%s')==URL(),URL('default','%s'),[]),\n" \
- % (page_name,page,page)
- s+=']'
+ s += "(T('%s'),URL('default','%s')==URL(),URL('default','%s'),[]),\n" \
+ % (page_name, page, page)
+ s += ']'
return s
-def make_page(page,contents):
- if 'auth_user' in session.app['tables'] and not page in ('index','error'):
- s="@auth.requires_login()\ndef %s():\n" % page
+
+def make_page(page, contents):
+ if 'auth_user' in session.app['tables'] and not page in ('index', 'error'):
+ s = "@auth.requires_login()\ndef %s():\n" % page
else:
- s="def %s():\n" % page
- items = page.rsplit('_',1)
- if items[0] in session.app['tables'] and len(items)==2 and items[1]=='manage':
- s+=" form = SQLFORM.smartgrid(db.t_%s,onupdate=auth.archive)\n" % items[0]
- s+=" return locals()\n\n"
+ s = "def %s():\n" % page
+ items = page.rsplit('_', 1)
+ if items[0] in session.app['tables'] and len(items) == 2 and items[1] == 'manage':
+ s += " form = SQLFORM.smartgrid(db.t_%s,onupdate=auth.archive)\n" % items[0]
+ s += " return locals()\n\n"
else:
- s+=" return dict()\n\n"
+ s += " return dict()\n\n"
return s
-def make_view(page,contents):
- s="{{extend 'layout.html'}}\n\n"
- s+=str(MARKMIN(contents))
+
+def make_view(page, contents):
+ s = "{{extend 'layout.html'}}\n\n"
+ s += str(MARKMIN(contents))
return s
+
def populate(tables):
s = 'from gluon.contrib.populate import populate\n'
- s+= 'if db(db.auth_user).isempty():\n'
+ s += 'if db(db.auth_user).isempty():\n'
for table in sort_tables(tables):
- t=table=='auth_user' and 'auth_user' or 't_'+table
- s+=" populate(db.%s,10)\n" % t
+ t = table == 'auth_user' and 'auth_user' or 't_' + table
+ s += " populate(db.%s,10)\n" % t
return s
+
def create(options):
if DEMO_MODE:
session.flash = T('disabled in demo mode')
redirect(URL('step6'))
params = dict(session.app['params'])
app = session.app['name']
- if app_create(app,request,force=True,key=params['security_key']):
+ if app_create(app, request, force=True, key=params['security_key']):
if MULTI_USER_MODE:
- db.app.insert(name=app,owner=auth.user.id)
+ db.app.insert(name=app, owner=auth.user.id)
else:
session.flash = 'Failure to create application'
redirect(URL('step6'))
### save metadata in newapp/wizard.metadata
try:
- meta = os.path.join(request.folder,'..',app,'wizard.metadata')
- file=open(meta,'wb')
- pickle.dump(session.app,file)
+ meta = os.path.join(request.folder, '..', app, 'wizard.metadata')
+ file = open(meta, 'wb')
+ pickle.dump(session.app, file)
file.close()
except IOError:
session.flash = 'Failure to write wizard metadata'
redirect(URL('step6'))
### apply theme
- if options.apply_layout and params['layout_theme']!='Default':
+ if options.apply_layout and params['layout_theme'] != 'Default':
try:
fn = 'web2py.plugin.layout_%s.w2p' % params['layout_theme']
- theme = urllib.urlopen(LAYOUTS_APP+'/static/plugin_layouts/plugins/'+fn)
+ theme = urllib.urlopen(
+ LAYOUTS_APP + '/static/plugin_layouts/plugins/' + fn)
plugin_install(app, theme, request, fn)
except:
session.flash = T("unable to download layout")
@@ -469,55 +511,58 @@ def create(options):
### apply plugins
for plugin in params['plugins']:
try:
- plugin_name = 'web2py.plugin.'+plugin+'.w2p'
- stream = urllib.urlopen(PLUGINS_APP+'/static/'+plugin_name)
+ plugin_name = 'web2py.plugin.' + plugin + '.w2p'
+ stream = urllib.urlopen(PLUGINS_APP + '/static/' + plugin_name)
plugin_install(app, stream, request, plugin_name)
except Exception, e:
session.flash = T("unable to download plugin: %s" % plugin)
### write configuration file into newapp/models/0.py
- model = os.path.join(request.folder,'..',app,'models','0.py')
+ model = os.path.join(request.folder, '..', app, 'models', '0.py')
file = open(model, 'wb')
try:
file.write("from gluon.storage import Storage\n")
file.write("settings = Storage()\n\n")
file.write("settings.migrate = True\n")
- for key,value in session.app['params']:
- file.write("settings.%s = %s\n" % (key,repr(value)))
+ for key, value in session.app['params']:
+ file.write("settings.%s = %s\n" % (key, repr(value)))
finally:
file.close()
### write configuration file into newapp/models/menu.py
if options.generate_menu:
- model = os.path.join(request.folder,'..',app,'models','menu.py')
- file = open(model,'wb')
+ model = os.path.join(request.folder, '..', app, 'models', 'menu.py')
+ file = open(model, 'wb')
try:
file.write(make_menu(session.app['pages']))
finally:
file.close()
### customize the auth_user table
- model = os.path.join(request.folder,'..',app,'models','db.py')
+ model = os.path.join(request.folder, '..', app, 'models', 'db.py')
fix_db(model)
### create newapp/models/db_wizard.py
if options.generate_model:
- model = os.path.join(request.folder,'..',app,'models','db_wizard.py')
- file = open(model,'wb')
+ model = os.path.join(
+ request.folder, '..', app, 'models', 'db_wizard.py')
+ file = open(model, 'wb')
try:
file.write('### we prepend t_ to tablenames and f_ to fieldnames for disambiguity\n\n')
tables = sort_tables(session.app['tables'])
for table in tables:
- if table=='auth_user': continue
- file.write(make_table(table,session.app['table_'+table]))
+ if table == 'auth_user':
+ continue
+ file.write(make_table(table, session.app['table_' + table]))
finally:
file.close()
- model = os.path.join(request.folder,'..',app,
- 'models','db_wizard_populate.py')
- if os.path.exists(model): os.unlink(model)
+ model = os.path.join(request.folder, '..', app,
+ 'models', 'db_wizard_populate.py')
+ if os.path.exists(model):
+ os.unlink(model)
if options.populate_database and session.app['tables']:
- file = open(model,'wb')
+ file = open(model, 'wb')
try:
file.write(populate(session.app['tables']))
finally:
@@ -525,8 +570,9 @@ def create(options):
### create newapp/controllers/default.py
if options.generate_controller:
- controller = os.path.join(request.folder,'..',app,'controllers','default.py')
- file = open(controller,'wb')
+ controller = os.path.join(
+ request.folder, '..', app, 'controllers', 'default.py')
+ file = open(controller, 'wb')
try:
file.write("""# -*- coding: utf-8 -*-
### required - do no delete
@@ -536,21 +582,24 @@ def call(): return service()
### end requires
""")
for page in session.app['pages']:
- file.write(make_page(page,session.app.get('page_'+page,'')))
+ file.write(
+ make_page(page, session.app.get('page_' + page, '')))
finally:
file.close()
### create newapp/views/default/*.html
if options.generate_views:
for page in session.app['pages']:
- view = os.path.join(request.folder,'..',app,'views','default',page+'.html')
- file = open(view,'wb')
+ view = os.path.join(
+ request.folder, '..', app, 'views', 'default', page + '.html')
+ file = open(view, 'wb')
try:
- file.write(make_view(page,session.app.get('page_'+page,'')))
+ file.write(
+ make_view(page, session.app.get('page_' + page, '')))
finally:
file.close()
if options.erase_database:
- path = os.path.join(request.folder,'..',app,'databases','*')
+ path = os.path.join(request.folder, '..', app, 'databases', '*')
for file in glob.glob(path):
os.unlink(file)
diff --git a/applications/admin/models/0.py b/applications/admin/models/0.py
index ebf9c29b..be8fe37a 100644
--- a/applications/admin/models/0.py
+++ b/applications/admin/models/0.py
@@ -1,7 +1,7 @@
EXPIRATION = 60 * 60 # logout after 60 minutes of inactivity
CHECK_VERSION = True
WEB2PY_URL = 'http://web2py.com'
-WEB2PY_VERSION_URL = WEB2PY_URL+'/examples/default/version'
+WEB2PY_VERSION_URL = WEB2PY_URL + '/examples/default/version'
###########################################################################
# Preferences for EditArea
@@ -21,7 +21,7 @@ TEXT_EDITOR_THEME = (
"tomorrow_night_eighties", "twilight", "vibrant_ink")[0]
## Editor Keyboard bindings (only for ace and codemirror)
-TEXT_EDITOR_KEYBINDING = '' # 'emacs' or 'vi'
+TEXT_EDITOR_KEYBINDING = '' # 'emacs' or 'vi'
### edit_area only
# The default font size, measured in 'points'. The value must be an integer > 0
@@ -59,9 +59,9 @@ GAE_APPCFG = os.path.abspath(os.path.join('/usr/local/bin/appcfg.py'))
# To use web2py as a teaching tool, set MULTI_USER_MODE to True
MULTI_USER_MODE = False
-EMAIL_SERVER = 'localhost'
-EMAIL_SENDER = 'professor@example.com'
-EMAIL_LOGIN = None
+EMAIL_SERVER = 'localhost'
+EMAIL_SENDER = 'professor@example.com'
+EMAIL_LOGIN = None
# configurable twitterbox, set to None/False to suppress
TWITTER_HASH = "web2py"
diff --git a/applications/admin/models/access.py b/applications/admin/models/access.py
index f268366f..d504b035 100644
--- a/applications/admin/models/access.py
+++ b/applications/admin/models/access.py
@@ -1,4 +1,6 @@
-import base64, os, time
+import base64
+import os
+import time
from gluon import portalocker
from gluon.admin import apath
from gluon.fileutils import read_file
@@ -24,7 +26,8 @@ elif not request.is_local and not DEMO_MODE:
try:
_config = {}
port = int(request.env.server_port or 0)
- restricted(read_file(apath('../parameters_%i.py' % port, request)), _config)
+ restricted(
+ read_file(apath('../parameters_%i.py' % port, request)), _config)
if not 'password' in _config or not _config['password']:
raise HTTP(200, T('admin disabled because no admin password'))
@@ -38,7 +41,8 @@ except IOError:
raise HTTP(200,
T('admin disabled because not supported on google app engine'))
else:
- raise HTTP(200, T('admin disabled because unable to access password file'))
+ raise HTTP(
+ 200, T('admin disabled because unable to access password file'))
def verify_password(password):
@@ -50,7 +54,7 @@ def verify_password(password):
elif _config['password'].startswith('pam_user:'):
session.pam_user = _config['password'][9:].strip()
import gluon.contrib.pam
- return gluon.contrib.pam.authenticate(session.pam_user,password)
+ return gluon.contrib.pam.authenticate(session.pam_user, password)
else:
return _config['password'] == CRYPT()(password)[0]
@@ -63,6 +67,7 @@ deny_file = os.path.join(request.folder, 'private', 'hosts.deny')
allowed_number_of_attempts = 5
expiration_failed_logins = 3600
+
def read_hosts_deny():
import datetime
hosts = {}
@@ -75,7 +80,7 @@ def read_hosts_deny():
continue
fields = line.strip().split()
if len(fields) > 2:
- hosts[fields[0].strip()] = ( # ip
+ hosts[fields[0].strip()] = ( # ip
int(fields[1].strip()), # n attemps
int(fields[2].strip()) # last attempts
)
@@ -83,28 +88,30 @@ def read_hosts_deny():
f.close()
return hosts
+
def write_hosts_deny(denied_hosts):
f = open(deny_file, 'w')
portalocker.lock(f, portalocker.LOCK_EX)
for key, val in denied_hosts.items():
- if time.time()-val[1] < expiration_failed_logins:
+ if time.time() - val[1] < expiration_failed_logins:
line = '%s %s %s\n' % (key, val[0], val[1])
f.write(line)
portalocker.unlock(f)
f.close()
+
def login_record(success=True):
denied_hosts = read_hosts_deny()
- val = (0,0)
+ val = (0, 0)
if success and request.client in denied_hosts:
del denied_hosts[request.client]
elif not success and not request.is_local:
- val = denied_hosts.get(request.client,(0,0))
- if time.time()-val[1]= allowed_number_of_attempts:
- return val[0] # locked out
- time.sleep(2**val[0])
- val = (val[0]+1,int(time.time()))
+ return val[0] # locked out
+ time.sleep(2 ** val[0])
+ val = (val[0] + 1, int(time.time()))
denied_hosts[request.client] = val
write_hosts_deny(denied_hosts)
return val[0]
@@ -124,9 +131,9 @@ if session.authorized:
session.last_time = t0
-if request.vars.is_mobile in ('true','false','auto'):
+if request.vars.is_mobile in ('true', 'false', 'auto'):
session.is_mobile = request.vars.is_mobile or 'auto'
-if request.controller=='default' and request.function=='index':
+if request.controller == 'default' and request.function == 'index':
if not request.vars.is_mobile:
session.is_mobile = 'auto'
if not session.is_mobile:
@@ -141,14 +148,14 @@ else:
if request.controller == "webservices":
basic = request.env.http_authorization
if not basic or not basic[:6].lower() == 'basic ':
- raise HTTP(401,"Wrong credentials")
+ raise HTTP(401, "Wrong credentials")
(username, password) = base64.b64decode(basic[6:]).split(':')
if not verify_password(password) or MULTI_USER_MODE:
time.sleep(10)
- raise HTTP(403,"Not authorized")
+ raise HTTP(403, "Not authorized")
elif not session.authorized and not \
- (request.controller+'/'+request.function in
- ('default/index','default/user','plugin_jqmobile/index','plugin_jqmobile/about')):
+ (request.controller + '/' + request.function in
+ ('default/index', 'default/user', 'plugin_jqmobile/index', 'plugin_jqmobile/about')):
if request.env.query_string:
query_string = '?' + request.env.query_string
@@ -165,6 +172,6 @@ elif session.authorized and \
request.function == 'index':
redirect(URL(request.application, 'default', 'site'))
-if request.controller=='appadmin' and DEMO_MODE:
+if request.controller == 'appadmin' and DEMO_MODE:
session.flash = 'Appadmin disabled in demo mode'
- redirect(URL('default','sites'))
+ redirect(URL('default', 'sites'))
diff --git a/applications/admin/models/buttons.py b/applications/admin/models/buttons.py
index ec79c8db..a7bbbedc 100644
--- a/applications/admin/models/buttons.py
+++ b/applications/admin/models/buttons.py
@@ -2,35 +2,41 @@
import os
-def A_button(*a,**b):
+
+def A_button(*a, **b):
b['_data-role'] = 'button'
b['_data-inline'] = 'true'
- return A(*a,**b)
+ return A(*a, **b)
+
def button(href, label):
if is_mobile:
ret = A_button(SPAN(label), _href=href)
else:
- ret = A(SPAN(label),_class='button',_href=href)
+ ret = A(SPAN(label), _class='button', _href=href)
return ret
+
def button_enable(href, app):
- if os.path.exists(os.path.join(apath(app,r=request),'DISABLED')):
- label = SPAN(T('Enable'),_style='color:red')
+ if os.path.exists(os.path.join(apath(app, r=request), 'DISABLED')):
+ label = SPAN(T('Enable'), _style='color:red')
else:
- label = SPAN(T('Disable'),_style='color:green')
- id = 'enable_'+app
- return A(label,_class='button',_id=id,callback=href,target=id)
+ label = SPAN(T('Disable'), _style='color:green')
+ id = 'enable_' + app
+ return A(label, _class='button', _id=id, callback=href, target=id)
+
def sp_button(href, label):
if request.user_agent().is_mobile:
ret = A_button(SPAN(label), _href=href)
else:
- ret = A(SPAN(label),_class='button special',_href=href)
+ ret = A(SPAN(label), _class='button special', _href=href)
return ret
+
def helpicon():
return IMG(_src=URL('static', 'images/help.png'), _alt='help')
+
def searchbox(elementid):
- return TAG[''](LABEL(IMG(_id="search_start",_src=URL('static', 'images/search.png'), _alt=T('filter')), _class='icon', _for=elementid), ' ', INPUT(_id=elementid, _type='text', _size=12))
+ return TAG[''](LABEL(IMG(_id="search_start", _src=URL('static', 'images/search.png'), _alt=T('filter')), _class='icon', _for=elementid), ' ', INPUT(_id=elementid, _type='text', _size=12))
diff --git a/applications/admin/models/db.py b/applications/admin/models/db.py
index b5df1aae..d6871cb2 100644
--- a/applications/admin/models/db.py
+++ b/applications/admin/models/db.py
@@ -4,35 +4,39 @@
if MULTI_USER_MODE:
db = DAL('sqlite://storage.sqlite') # if not, use SQLite or other DB
from gluon.tools import *
- auth = Auth(globals(),db) # authentication/authorization
- crud = Crud(globals(),db) # for CRUD helpers using auth
- service = Service(globals()) # for json, xml, jsonrpc, xmlrpc, amfrpc
+ auth = Auth(
+ globals(), db) # authentication/authorization
+ crud = Crud(
+ globals(), db) # for CRUD helpers using auth
+ service = Service(
+ globals()) # for json, xml, jsonrpc, xmlrpc, amfrpc
plugins = PluginManager()
mail = auth.settings.mailer
mail.settings.server = EMAIL_SERVER
mail.settings.sender = EMAIL_SENDER
- mail.settings.login = EMAIL_LOGIN
+ mail.settings.login = EMAIL_LOGIN
auth.settings.extra_fields['auth_user'] = \
- [Field('is_manager','boolean',default=False,writable=False)]
+ [Field('is_manager', 'boolean', default=False, writable=False)]
auth.define_tables() # creates all needed tables
auth.settings.registration_requires_verification = False
auth.settings.registration_requires_approval = True
auth.settings.reset_password_requires_verification = True
- db.define_table('app',Field('name'),Field('owner',db.auth_user))
+ db.define_table('app', Field('name'), Field('owner', db.auth_user))
if not session.authorized and MULTI_USER_MODE:
- if auth.user and not request.function=='user':
+ if auth.user and not request.function == 'user':
session.authorized = True
- elif not request.function=='user':
- redirect(URL('default','user/login'))
+ elif not request.function == 'user':
+ redirect(URL('default', 'user/login'))
+
def is_manager():
if not MULTI_USER_MODE:
return True
- elif auth.user and (auth.user.id==1 or auth.user.is_manager):
+ elif auth.user and (auth.user.id == 1 or auth.user.is_manager):
return True
else:
return False
diff --git a/applications/admin/models/menu.py b/applications/admin/models/menu.py
index fa7d5fa6..7429def1 100644
--- a/applications/admin/models/menu.py
+++ b/applications/admin/models/menu.py
@@ -7,29 +7,30 @@ _c = request.controller
_f = request.function
response.title = '%s %s' % (_f, '/'.join(request.args))
response.subtitle = 'admin'
-response.menu = [(T('Site'), _f == 'site', URL(_a,'default','site'))]
+response.menu = [(T('Site'), _f == 'site', URL(_a, 'default', 'site'))]
if request.vars.app or request.args:
_t = request.vars.app or request.args[0]
response.menu.append((T('Edit'), _c == 'default' and _f == 'design',
- URL(_a,'default','design',args=_t)))
+ URL(_a, 'default', 'design', args=_t)))
response.menu.append((T('About'), _c == 'default' and _f == 'about',
- URL(_a,'default','about',args=_t,)))
+ URL(_a, 'default', 'about', args=_t,)))
response.menu.append((T('Errors'), _c == 'default' and _f == 'errors',
- URL(_a,'default','errors',args=_t)))
+ URL(_a, 'default', 'errors', args=_t)))
response.menu.append((T('Versioning'),
_c == 'mercurial' and _f == 'commit',
- URL(_a,'mercurial','commit',args=_t)))
+ URL(_a, 'mercurial', 'commit', args=_t)))
if not session.authorized:
response.menu = [(T('Login'), True, URL('site'))]
else:
response.menu.append((T('Logout'), False,
- URL(_a,'default',f='logout')))
+ URL(_a, 'default', f='logout')))
response.menu.append((T('Debug'), False,
- URL(_a, 'debug','interact')))
+ URL(_a, 'debug', 'interact')))
if os.path.exists('applications/examples'):
- response.menu.append((T('Help'), False, URL('examples','default','index')))
+ response.menu.append(
+ (T('Help'), False, URL('examples', 'default', 'index')))
else:
response.menu.append((T('Help'), False, 'http://web2py.com/examples'))
diff --git a/applications/admin/models/plugin_multiselect.py b/applications/admin/models/plugin_multiselect.py
index ec45feec..39fa2a1e 100644
--- a/applications/admin/models/plugin_multiselect.py
+++ b/applications/admin/models/plugin_multiselect.py
@@ -1,3 +1,4 @@
-response.files.append(URL('static','plugin_multiselect/jquery.multi-select.js'))
-response.files.append(URL('static','plugin_multiselect/multi-select.css'))
-response.files.append(URL('static','plugin_multiselect/start.js'))
+response.files.append(
+ URL('static', 'plugin_multiselect/jquery.multi-select.js'))
+response.files.append(URL('static', 'plugin_multiselect/multi-select.css'))
+response.files.append(URL('static', 'plugin_multiselect/start.js'))
diff --git a/applications/examples/controllers/appadmin.py b/applications/examples/controllers/appadmin.py
index 6802c419..f62af94c 100644
--- a/applications/examples/controllers/appadmin.py
+++ b/applications/examples/controllers/appadmin.py
@@ -23,7 +23,7 @@ remote_addr = request.env.remote_addr
try:
hosts = (http_host, socket.gethostname(),
socket.gethostbyname(http_host),
- '::1','127.0.0.1','::ffff:127.0.0.1')
+ '::1', '127.0.0.1', '::ffff:127.0.0.1')
except:
hosts = (http_host, )
@@ -32,10 +32,10 @@ if request.env.http_x_forwarded_for or request.is_https:
elif (remote_addr not in hosts) and (remote_addr != "127.0.0.1"):
raise HTTP(200, T('appadmin is disabled because insecure channel'))
-if (request.application=='admin' and not session.authorized) or \
- (request.application!='admin' and not gluon.fileutils.check_credentials(request)):
+if (request.application == 'admin' and not session.authorized) or \
+ (request.application != 'admin' and not gluon.fileutils.check_credentials(request)):
redirect(URL('admin', 'default', 'index',
- vars=dict(send=URL(args=request.args,vars=request.vars))))
+ vars=dict(send=URL(args=request.args, vars=request.vars))))
ignore_rw = True
response.view = 'appadmin.html'
@@ -95,24 +95,23 @@ def get_query(request):
return None
-def query_by_table_type(tablename,db,request=request):
- keyed = hasattr(db[tablename],'_primarykey')
+def query_by_table_type(tablename, db, request=request):
+ keyed = hasattr(db[tablename], '_primarykey')
if keyed:
firstkey = db[tablename][db[tablename]._primarykey[0]]
cond = '>0'
if firstkey.type in ['string', 'text']:
cond = '!=""'
- qry = '%s.%s.%s%s' % (request.args[0], request.args[1], firstkey.name, cond)
+ qry = '%s.%s.%s%s' % (
+ request.args[0], request.args[1], firstkey.name, cond)
else:
qry = '%s.%s.id>0' % tuple(request.args[:2])
return qry
-
# ##########################################################
# ## list all databases and tables
# ###########################################################
-
def index():
return dict(databases=databases)
@@ -127,7 +126,7 @@ def insert():
form = SQLFORM(db[table], ignore_rw=ignore_rw)
if form.accepts(request.vars, session):
response.flash = T('new record inserted')
- return dict(form=form,table=db[table])
+ return dict(form=form, table=db[table])
# ##########################################################
@@ -138,7 +137,8 @@ def insert():
def download():
import os
db = get_database(request)
- return response.download(request,db)
+ return response.download(request, db)
+
def csv():
import gluon.contenttype
@@ -149,26 +149,27 @@ def csv():
if not query:
return None
response.headers['Content-disposition'] = 'attachment; filename=%s_%s.csv'\
- % tuple(request.vars.query.split('.')[:2])
- return str(db(query,ignore_common_filters=True).select())
+ % tuple(request.vars.query.split('.')[:2])
+ return str(db(query, ignore_common_filters=True).select())
def import_csv(table, file):
table.import_from_csv_file(file)
+
def select():
import re
db = get_database(request)
dbname = request.args[0]
regex = re.compile('(?P\w+)\.(?P\w+)=(?P\d+)')
- if len(request.args)>1 and hasattr(db[request.args[1]],'_primarykey'):
+ if len(request.args) > 1 and hasattr(db[request.args[1]], '_primarykey'):
regex = re.compile('(?P\w+)\.(?P\w+)=(?P.+)')
if request.vars.query:
match = regex.match(request.vars.query)
if match:
request.vars.query = '%s.%s.%s==%s' % (request.args[0],
- match.group('table'), match.group('field'),
- match.group('value'))
+ match.group('table'), match.group('field'),
+ match.group('value'))
else:
request.vars.query = session.last_query
query = get_query(request)
@@ -192,14 +193,15 @@ def select():
session.last_query = request.vars.query
form = FORM(TABLE(TR(T('Query:'), '', INPUT(_style='width:400px',
_name='query', _value=request.vars.query or '',
- requires=IS_NOT_EMPTY(error_message=T("Cannot be empty")))), TR(T('Update:'),
+ requires=IS_NOT_EMPTY(
+ error_message=T("Cannot be empty")))), TR(T('Update:'),
INPUT(_name='update_check', _type='checkbox',
value=False), INPUT(_style='width:400px',
_name='update_fields', _value=request.vars.update_fields
- or '')), TR(T('Delete:'), INPUT(_name='delete_check',
+ or '')), TR(T('Delete:'), INPUT(_name='delete_check',
_class='delete', _type='checkbox', value=False), ''),
TR('', '', INPUT(_type='submit', _value=T('submit')))),
- _action=URL(r=request,args=request.args))
+ _action=URL(r=request, args=request.args))
tb = None
if form.accepts(request.vars, formname=None):
@@ -211,28 +213,30 @@ def select():
nrows = db(query).count()
if form.vars.update_check and form.vars.update_fields:
db(query).update(**eval_in_global_env('dict(%s)'
- % form.vars.update_fields))
+ % form.vars.update_fields))
response.flash = T('%s %%{row} updated', nrows)
elif form.vars.delete_check:
db(query).delete()
response.flash = T('%s %%{row} deleted', nrows)
nrows = db(query).count()
if orderby:
- rows = db(query,ignore_common_filters=True).select(limitby=(start, stop), orderby=eval_in_global_env(orderby))
+ rows = db(query, ignore_common_filters=True).select(limitby=(
+ start, stop), orderby=eval_in_global_env(orderby))
else:
- rows = db(query,ignore_common_filters=True).select(limitby=(start, stop))
+ rows = db(query, ignore_common_filters=True).select(
+ limitby=(start, stop))
except Exception, e:
import traceback
tb = traceback.format_exc()
(rows, nrows) = ([], 0)
- response.flash = DIV(T('Invalid Query'),PRE(str(e)))
+ response.flash = DIV(T('Invalid Query'), PRE(str(e)))
# begin handle upload csv
csv_table = table or request.vars.table
if csv_table:
- formcsv = FORM(str(T('or import from csv file'))+" ",
- INPUT(_type='file',_name='csvfile'),
- INPUT(_type='hidden',_value=csv_table,_name='table'),
- INPUT(_type='submit',_value=T('import')))
+ formcsv = FORM(str(T('or import from csv file')) + " ",
+ INPUT(_type='file', _name='csvfile'),
+ INPUT(_type='hidden', _value=csv_table, _name='table'),
+ INPUT(_type='submit', _value=T('import')))
else:
formcsv = None
if formcsv and formcsv.process().accepted:
@@ -241,7 +245,7 @@ def select():
request.vars.csvfile.file)
response.flash = T('data uploaded')
except Exception, e:
- response.flash = DIV(T('unable to parse csv file'),PRE(str(e)))
+ response.flash = DIV(T('unable to parse csv file'), PRE(str(e)))
# end handle upload csv
return dict(
@@ -252,9 +256,9 @@ def select():
nrows=nrows,
rows=rows,
query=request.vars.query,
- formcsv = formcsv,
- tb = tb,
- )
+ formcsv=formcsv,
+ tb=tb,
+ )
# ##########################################################
@@ -264,14 +268,16 @@ def select():
def update():
(db, table) = get_table(request)
- keyed = hasattr(db[table],'_primarykey')
+ keyed = hasattr(db[table], '_primarykey')
record = None
if keyed:
key = [f for f in request.vars if f in db[table]._primarykey]
if key:
- record = db(db[table][key[0]] == request.vars[key[0]], ignore_common_filters=True).select().first()
+ record = db(db[table][key[0]] == request.vars[key[
+ 0]], ignore_common_filters=True).select().first()
else:
- record = db(db[table].id == request.args(2),ignore_common_filters=True).select().first()
+ record = db(db[table].id == request.args(
+ 2), ignore_common_filters=True).select().first()
if not record:
qry = query_by_table_type(table, db)
@@ -281,20 +287,21 @@ def update():
if keyed:
for k in db[table]._primarykey:
- db[table][k].writable=False
+ db[table][k].writable = False
- form = SQLFORM(db[table], record, deletable=True, delete_label=T('Check to delete'),
- ignore_rw=ignore_rw and not keyed,
- linkto=URL('select',
+ form = SQLFORM(
+ db[table], record, deletable=True, delete_label=T('Check to delete'),
+ ignore_rw=ignore_rw and not keyed,
+ linkto=URL('select',
args=request.args[:1]), upload=URL(r=request,
- f='download', args=request.args[:1]))
+ f='download', args=request.args[:1]))
if form.accepts(request.vars, session):
session.flash = T('done!')
qry = query_by_table_type(table, db)
redirect(URL('select', args=request.args[:1],
vars=dict(query=qry)))
- return dict(form=form,table=db[table])
+ return dict(form=form, table=db[table])
# ##########################################################
@@ -305,11 +312,15 @@ def update():
def state():
return dict()
+
def ccache():
form = FORM(
- P(TAG.BUTTON(T("Clear CACHE?"), _type="submit", _name="yes", _value="yes")),
- P(TAG.BUTTON(T("Clear RAM"), _type="submit", _name="ram", _value="ram")),
- P(TAG.BUTTON(T("Clear DISK"), _type="submit", _name="disk", _value="disk")),
+ P(TAG.BUTTON(
+ T("Clear CACHE?"), _type="submit", _name="yes", _value="yes")),
+ P(TAG.BUTTON(
+ T("Clear RAM"), _type="submit", _name="ram", _value="ram")),
+ P(TAG.BUTTON(
+ T("Clear DISK"), _type="submit", _name="disk", _value="disk")),
)
if form.accepts(request.vars, session):
@@ -333,11 +344,16 @@ def ccache():
redirect(URL(r=request))
try:
- from guppy import hpy; hp=hpy()
+ from guppy import hpy
+ hp = hpy()
except ImportError:
hp = False
- import shelve, os, copy, time, math
+ import shelve
+ import os
+ import copy
+ import time
+ import math
from gluon import portalocker
ram = {
@@ -382,9 +398,10 @@ def ccache():
ram['keys'].append((key, GetInHMS(time.time() - value[0])))
locker = open(os.path.join(request.folder,
- 'cache/cache.lock'), 'a')
+ 'cache/cache.lock'), 'a')
portalocker.lock(locker, portalocker.LOCK_EX)
- disk_storage = shelve.open(os.path.join(request.folder, 'cache/cache.shelve'))
+ disk_storage = shelve.open(
+ os.path.join(request.folder, 'cache/cache.shelve'))
try:
for key, value in disk_storage.items():
if isinstance(value, dict):
@@ -415,7 +432,8 @@ def ccache():
total['misses'] = ram['misses'] + disk['misses']
total['keys'] = ram['keys'] + disk['keys']
try:
- total['ratio'] = total['hits'] * 100 / (total['hits'] + total['misses'])
+ total['ratio'] = total['hits'] * 100 / (total['hits'] +
+ total['misses'])
except (KeyError, ZeroDivisionError):
total['ratio'] = 0
diff --git a/applications/examples/controllers/cache_examples.py b/applications/examples/controllers/cache_examples.py
index c4a95494..857833d5 100644
--- a/applications/examples/controllers/cache_examples.py
+++ b/applications/examples/controllers/cache_examples.py
@@ -4,21 +4,21 @@ import time
def cache_in_ram():
"""cache the output of the lambda function in ram"""
- t = cache.ram('time', lambda : time.ctime(), time_expire=5)
+ t = cache.ram('time', lambda: time.ctime(), time_expire=5)
return dict(time=t, link=A('click to reload', _href=URL(r=request)))
def cache_on_disk():
"""cache the output of the lambda function on disk"""
- t = cache.disk('time', lambda : time.ctime(), time_expire=5)
+ t = cache.disk('time', lambda: time.ctime(), time_expire=5)
return dict(time=t, link=A('click to reload', _href=URL(r=request)))
def cache_in_ram_and_disk():
"""cache the output of the lambda function on disk and in ram"""
- t = cache.ram('time', lambda : cache.disk('time', lambda : \
+ t = cache.ram('time', lambda: cache.disk('time', lambda:
time.ctime(), time_expire=5), time_expire=5)
return dict(time=t, link=A('click to reload', _href=URL(r=request)))
diff --git a/applications/examples/controllers/default.py b/applications/examples/controllers/default.py
index 8e39b694..7063a6fd 100644
--- a/applications/examples/controllers/default.py
+++ b/applications/examples/controllers/default.py
@@ -9,65 +9,81 @@ response.description = T('web2py Web Framework')
session.forget()
cache_expire = not request.is_local and 300 or 0
+
@cache('index', time_expire=cache_expire)
def index():
return response.render()
+
@cache('what', time_expire=cache_expire)
def what():
- import urllib;
+ import urllib
try:
- images = XML(urllib.urlopen('http://web2py.com/poweredby/default/images').read())
+ images = XML(urllib.urlopen(
+ 'http://web2py.com/poweredby/default/images').read())
except:
images = []
return response.render(images=images)
+
@cache('download', time_expire=cache_expire)
def download():
return response.render()
+
@cache('who', time_expire=cache_expire)
def who():
return response.render()
+
@cache('support', time_expire=cache_expire)
def support():
return response.render()
+
@cache('documentation', time_expire=cache_expire)
def documentation():
return response.render()
+
@cache('usergroups', time_expire=cache_expire)
def usergroups():
return response.render()
+
def contact():
- redirect(URL('default','usergroups'))
+ redirect(URL('default', 'usergroups'))
+
@cache('videos', time_expire=cache_expire)
def videos():
return response.render()
+
def security():
redirect('http://www.web2py.com/book/default/chapter/01#security')
+
def api():
redirect('http://web2py.com/book/default/chapter/04#API')
+
@cache('license', time_expire=cache_expire)
def license():
import os
filename = os.path.join(request.env.gluon_parent, 'LICENSE')
return response.render(dict(license=MARKMIN(read_file(filename))))
+
def version():
return 'Version %s.%s.%s (%s) %s' % request.env.web2py_version
+
@cache('examples', time_expire=cache_expire)
def examples():
return response.render()
+
@cache('changelog', time_expire=cache_expire)
def changelog():
import os
diff --git a/applications/examples/controllers/form_examples.py b/applications/examples/controllers/form_examples.py
index 3847b043..944aa08f 100644
--- a/applications/examples/controllers/form_examples.py
+++ b/applications/examples/controllers/form_examples.py
@@ -12,7 +12,7 @@ def form():
TR('Profile', TEXTAREA(_name='profile',
value='write something here')),
TR('', INPUT(_type='submit', _value='SUBMIT')),
- ))
+ ))
if form.process().accepted:
response.flash = 'form accepted'
elif form.errors:
diff --git a/applications/examples/controllers/global.py b/applications/examples/controllers/global.py
index bcfab063..a186037c 100644
--- a/applications/examples/controllers/global.py
+++ b/applications/examples/controllers/global.py
@@ -16,14 +16,14 @@ def vars():
c,
d,
value,
- ) = (
+ ) = (
'Global variables',
globals(),
None,
None,
(),
None,
- )
+ )
(title, args) = ('globals()', '')
elif len(request.args) < 3:
args = '.'.join(request.args)
@@ -75,4 +75,4 @@ def vars():
d=d,
doc=doc,
attributes=attributes,
- )
+ )
diff --git a/applications/examples/controllers/layout_examples.py b/applications/examples/controllers/layout_examples.py
index dea28f11..b05ac9d7 100644
--- a/applications/examples/controllers/layout_examples.py
+++ b/applications/examples/controllers/layout_examples.py
@@ -1,6 +1,6 @@
def civilized():
response.menu = [['civilized', True, URL('civilized'
- )], ['slick', False, URL('slick')],
+ )], ['slick', False, URL('slick')],
['basic', False, URL('basic')]]
response.flash = 'you clicked on civilized'
return dict(message='you clicked on civilized')
@@ -8,7 +8,7 @@ def civilized():
def slick():
response.menu = [['civilized', False, URL('civilized'
- )], ['slick', True, URL('slick')],
+ )], ['slick', True, URL('slick')],
['basic', False, URL('basic')]]
response.flash = 'you clicked on slick'
return dict(message='you clicked on slick')
@@ -16,7 +16,7 @@ def slick():
def basic():
response.menu = [['civilized', False, URL('civilized'
- )], ['slick', False, URL('slick')],
+ )], ['slick', False, URL('slick')],
['basic', True, URL('basic')]]
response.flash = 'you clicked on basic'
return dict(message='you clicked on basic')
diff --git a/applications/examples/controllers/simple_examples.py b/applications/examples/controllers/simple_examples.py
index 3438d3e8..35840bbb 100644
--- a/applications/examples/controllers/simple_examples.py
+++ b/applications/examples/controllers/simple_examples.py
@@ -102,9 +102,8 @@ def rss_aggregator():
return rss2.dumps(rss)
-
def ajaxwiki():
- default="""
+ default = """
# section
## subsection
@@ -129,11 +128,12 @@ Quoted text
3 | 0 | 0
---------
"""
- form = FORM(TEXTAREA(_id='text',_name='text',value=default),
+ form = FORM(TEXTAREA(_id='text', _name='text', value=default),
INPUT(_type='button',
_value='markmin',
_onclick="ajax('ajaxwiki_onclick',['text'],'html')"))
return dict(form=form, html=DIV(_id='html'))
+
def ajaxwiki_onclick():
return MARKMIN(request.vars.text).xml()
diff --git a/applications/examples/controllers/spreadsheet.py b/applications/examples/controllers/spreadsheet.py
index 426b8714..f46df702 100644
--- a/applications/examples/controllers/spreadsheet.py
+++ b/applications/examples/controllers/spreadsheet.py
@@ -1,9 +1,11 @@
from gluon.contrib.spreadsheet import Sheet
+
def callback():
- return cache.ram('sheet1',lambda:None,None).process(request)
+ return cache.ram('sheet1', lambda: None, None).process(request)
+
def index():
- sheet = cache.ram('sheet1',lambda:Sheet(10,10,URL('callback')),0)
+ sheet = cache.ram('sheet1', lambda: Sheet(10, 10, URL('callback')), 0)
#sheet.cell('r0c3',value='=r0c0+r0c1+r0c2',readonly=True)
return dict(sheet=sheet)
diff --git a/applications/examples/models/feeds_reader.py b/applications/examples/models/feeds_reader.py
index 658d5381..865fa048 100644
--- a/applications/examples/models/feeds_reader.py
+++ b/applications/examples/models/feeds_reader.py
@@ -1,44 +1,44 @@
-def group_feed_reader(group,mode='div',counter='5'):
+def group_feed_reader(group, mode='div', counter='5'):
"""parse group feeds"""
url = "http://groups.google.com/group/%s/feed/rss_v2_0_topics.xml?num=%s" %\
- (group,counter)
+ (group, counter)
from gluon.contrib import feedparser
g = feedparser.parse(url)
if mode == 'div':
- html = XML(TAG.BLOCKQUOTE(UL(*[LI(A(entry['title']+' - ' +\
- entry['author'][entry['author'].rfind('('):],\
- _href=entry['link'],_target='_blank'))\
- for entry in g['entries'] ]),\
- _class="boxInfo",\
- _style="padding-bottom:5px;"))
+ html = XML(TAG.BLOCKQUOTE(UL(*[LI(A(entry['title'] + ' - ' +
+ entry['author'][
+ entry['author'].rfind('('):],
+ _href=entry['link'], _target='_blank'))
+ for entry in g['entries']]),
+ _class="boxInfo",
+ _style="padding-bottom:5px;"))
else:
- html = XML(UL(*[LI(A(entry['title']+' - ' +\
- entry['author'][entry['author'].rfind('('):],\
- _href=entry['link'],_target='_blank'))\
- for entry in g['entries'] ]))
+ html = XML(UL(*[LI(A(entry['title'] + ' - ' +
+ entry['author'][entry['author'].rfind('('):],
+ _href=entry['link'], _target='_blank'))
+ for entry in g['entries']]))
return html
-def code_feed_reader(project,mode='div'):
+def code_feed_reader(project, mode='div'):
"""parse code feeds"""
url = "http://code.google.com/feeds/p/%s/hgchanges/basic" % project
from gluon.contrib import feedparser
g = feedparser.parse(url)
if mode == 'div':
- html = XML(DIV(UL(*[LI(A(entry['title'],_href=entry['link'],\
- _target='_blank'))\
- for entry in g['entries'][0:5]]),\
- _class="boxInfo",\
+ html = XML(DIV(UL(*[LI(A(entry['title'], _href=entry['link'],
+ _target='_blank'))
+ for entry in g['entries'][0:5]]),
+ _class="boxInfo",
_style="padding-bottom:5px;"))
else:
- html = XML(UL(*[LI(A(entry['title'],_href=entry['link'],\
- _target='_blank'))\
- for entry in g['entries'][0:5]]))
-
+ html = XML(UL(*[LI(A(entry['title'], _href=entry['link'],
+ _target='_blank'))
+ for entry in g['entries'][0:5]]))
return html
diff --git a/applications/examples/models/markmin.py b/applications/examples/models/markmin.py
index 4815ac79..3376bac6 100644
--- a/applications/examples/models/markmin.py
+++ b/applications/examples/models/markmin.py
@@ -2,18 +2,19 @@ import gluon.template
markmin_dict = dict(
code_python=lambda code: str(CODE(code)),
- template=lambda \
- code:gluon.template.render(code,context=globals()),
- sup=lambda \
- code:'%s'%code,
- br=lambda n:'
'*int(n),
- groupdates=lambda group:group_feed_reader(group),
- )
+ template=lambda
+ code: gluon.template.render(code, context=globals()),
+ sup=lambda
+ code: '%s' % code,
+ br=lambda n: '
' * int(n),
+ groupdates=lambda group: group_feed_reader(group),
+)
-def get_content(b=None,\
- c=request.controller,\
- f=request.function,\
- l='en',\
+
+def get_content(b=None,
+ c=request.controller,
+ f=request.function,
+ l='en',
format='markmin'):
"""Gets and renders the file in
/private/content////.
@@ -21,17 +22,18 @@ def get_content(b=None,\
def openfile():
import os
- path = os.path.join(request.folder,'private','content',l,c,f,b+'.'+format)
+ path = os.path.join(
+ request.folder, 'private', 'content', l, c, f, b + '.' + format)
return open(path)
try:
openedfile = openfile()
except Exception, IOError:
- l='en'
+ l = 'en'
openedfile = openfile()
if format == 'markmin':
- html = MARKMIN(str(T(openedfile.read())),markmin_dict)
+ html = MARKMIN(str(T(openedfile.read())), markmin_dict)
else:
html = str(T(openedfile.read()))
openedfile.close()
diff --git a/applications/examples/models/menu.py b/applications/examples/models/menu.py
index 1a696daf..d81bfa36 100644
--- a/applications/examples/models/menu.py
+++ b/applications/examples/models/menu.py
@@ -1,28 +1,29 @@
# -*- coding: utf-8 -*-
response.menu = [
- (T('Home'),False,URL('default','index')),
- (T('About'),False,URL('default','what')),
- (T('Download'),False,URL('default','download')),
- (T('Docs & Resources'),False,URL('default','documentation')),
- (T('Support'),False,URL('default','support')),
- (T('Contributors'),False,URL('default','who'))]
+ (T('Home'), False, URL('default', 'index')),
+ (T('About'), False, URL('default', 'what')),
+ (T('Download'), False, URL('default', 'download')),
+ (T('Docs & Resources'), False, URL('default', 'documentation')),
+ (T('Support'), False, URL('default', 'support')),
+ (T('Contributors'), False, URL('default', 'who'))]
#########################################################################
## Changes the menu active item
#########################################################################
-def toggle_menuclass(cssclass='pressed',menuid='headermenu'):
+
+
+def toggle_menuclass(cssclass='pressed', menuid='headermenu'):
"""This function changes the menu class to put pressed appearance"""
positions = dict(
- index='',
- what='-108px -115px',
- download='-211px -115px',
- who='-315px -115px',
- support='-418px -115px',
- documentation='-520px -115px'
- )
-
+ index='',
+ what='-108px -115px',
+ download='-211px -115px',
+ who='-315px -115px',
+ support='-418px -115px',
+ documentation='-520px -115px'
+ )
if request.function in positions.keys():
jscript = """
@@ -34,10 +35,10 @@ def toggle_menuclass(cssclass='pressed',menuid='headermenu'):
});
""" % dict(cssclass=cssclass,
- menuid=menuid,
- function=request.function,
- cssposition=positions[request.function]
- )
+ menuid=menuid,
+ function=request.function,
+ cssposition=positions[request.function]
+ )
return XML(jscript)
else:
diff --git a/applications/welcome/controllers/appadmin.py b/applications/welcome/controllers/appadmin.py
index 6802c419..f62af94c 100644
--- a/applications/welcome/controllers/appadmin.py
+++ b/applications/welcome/controllers/appadmin.py
@@ -23,7 +23,7 @@ remote_addr = request.env.remote_addr
try:
hosts = (http_host, socket.gethostname(),
socket.gethostbyname(http_host),
- '::1','127.0.0.1','::ffff:127.0.0.1')
+ '::1', '127.0.0.1', '::ffff:127.0.0.1')
except:
hosts = (http_host, )
@@ -32,10 +32,10 @@ if request.env.http_x_forwarded_for or request.is_https:
elif (remote_addr not in hosts) and (remote_addr != "127.0.0.1"):
raise HTTP(200, T('appadmin is disabled because insecure channel'))
-if (request.application=='admin' and not session.authorized) or \
- (request.application!='admin' and not gluon.fileutils.check_credentials(request)):
+if (request.application == 'admin' and not session.authorized) or \
+ (request.application != 'admin' and not gluon.fileutils.check_credentials(request)):
redirect(URL('admin', 'default', 'index',
- vars=dict(send=URL(args=request.args,vars=request.vars))))
+ vars=dict(send=URL(args=request.args, vars=request.vars))))
ignore_rw = True
response.view = 'appadmin.html'
@@ -95,24 +95,23 @@ def get_query(request):
return None
-def query_by_table_type(tablename,db,request=request):
- keyed = hasattr(db[tablename],'_primarykey')
+def query_by_table_type(tablename, db, request=request):
+ keyed = hasattr(db[tablename], '_primarykey')
if keyed:
firstkey = db[tablename][db[tablename]._primarykey[0]]
cond = '>0'
if firstkey.type in ['string', 'text']:
cond = '!=""'
- qry = '%s.%s.%s%s' % (request.args[0], request.args[1], firstkey.name, cond)
+ qry = '%s.%s.%s%s' % (
+ request.args[0], request.args[1], firstkey.name, cond)
else:
qry = '%s.%s.id>0' % tuple(request.args[:2])
return qry
-
# ##########################################################
# ## list all databases and tables
# ###########################################################
-
def index():
return dict(databases=databases)
@@ -127,7 +126,7 @@ def insert():
form = SQLFORM(db[table], ignore_rw=ignore_rw)
if form.accepts(request.vars, session):
response.flash = T('new record inserted')
- return dict(form=form,table=db[table])
+ return dict(form=form, table=db[table])
# ##########################################################
@@ -138,7 +137,8 @@ def insert():
def download():
import os
db = get_database(request)
- return response.download(request,db)
+ return response.download(request, db)
+
def csv():
import gluon.contenttype
@@ -149,26 +149,27 @@ def csv():
if not query:
return None
response.headers['Content-disposition'] = 'attachment; filename=%s_%s.csv'\
- % tuple(request.vars.query.split('.')[:2])
- return str(db(query,ignore_common_filters=True).select())
+ % tuple(request.vars.query.split('.')[:2])
+ return str(db(query, ignore_common_filters=True).select())
def import_csv(table, file):
table.import_from_csv_file(file)
+
def select():
import re
db = get_database(request)
dbname = request.args[0]
regex = re.compile('(?P\w+)\.(?P\w+)=(?P\d+)')
- if len(request.args)>1 and hasattr(db[request.args[1]],'_primarykey'):
+ if len(request.args) > 1 and hasattr(db[request.args[1]], '_primarykey'):
regex = re.compile('(?P\w+)\.(?P\w+)=(?P.+)')
if request.vars.query:
match = regex.match(request.vars.query)
if match:
request.vars.query = '%s.%s.%s==%s' % (request.args[0],
- match.group('table'), match.group('field'),
- match.group('value'))
+ match.group('table'), match.group('field'),
+ match.group('value'))
else:
request.vars.query = session.last_query
query = get_query(request)
@@ -192,14 +193,15 @@ def select():
session.last_query = request.vars.query
form = FORM(TABLE(TR(T('Query:'), '', INPUT(_style='width:400px',
_name='query', _value=request.vars.query or '',
- requires=IS_NOT_EMPTY(error_message=T("Cannot be empty")))), TR(T('Update:'),
+ requires=IS_NOT_EMPTY(
+ error_message=T("Cannot be empty")))), TR(T('Update:'),
INPUT(_name='update_check', _type='checkbox',
value=False), INPUT(_style='width:400px',
_name='update_fields', _value=request.vars.update_fields
- or '')), TR(T('Delete:'), INPUT(_name='delete_check',
+ or '')), TR(T('Delete:'), INPUT(_name='delete_check',
_class='delete', _type='checkbox', value=False), ''),
TR('', '', INPUT(_type='submit', _value=T('submit')))),
- _action=URL(r=request,args=request.args))
+ _action=URL(r=request, args=request.args))
tb = None
if form.accepts(request.vars, formname=None):
@@ -211,28 +213,30 @@ def select():
nrows = db(query).count()
if form.vars.update_check and form.vars.update_fields:
db(query).update(**eval_in_global_env('dict(%s)'
- % form.vars.update_fields))
+ % form.vars.update_fields))
response.flash = T('%s %%{row} updated', nrows)
elif form.vars.delete_check:
db(query).delete()
response.flash = T('%s %%{row} deleted', nrows)
nrows = db(query).count()
if orderby:
- rows = db(query,ignore_common_filters=True).select(limitby=(start, stop), orderby=eval_in_global_env(orderby))
+ rows = db(query, ignore_common_filters=True).select(limitby=(
+ start, stop), orderby=eval_in_global_env(orderby))
else:
- rows = db(query,ignore_common_filters=True).select(limitby=(start, stop))
+ rows = db(query, ignore_common_filters=True).select(
+ limitby=(start, stop))
except Exception, e:
import traceback
tb = traceback.format_exc()
(rows, nrows) = ([], 0)
- response.flash = DIV(T('Invalid Query'),PRE(str(e)))
+ response.flash = DIV(T('Invalid Query'), PRE(str(e)))
# begin handle upload csv
csv_table = table or request.vars.table
if csv_table:
- formcsv = FORM(str(T('or import from csv file'))+" ",
- INPUT(_type='file',_name='csvfile'),
- INPUT(_type='hidden',_value=csv_table,_name='table'),
- INPUT(_type='submit',_value=T('import')))
+ formcsv = FORM(str(T('or import from csv file')) + " ",
+ INPUT(_type='file', _name='csvfile'),
+ INPUT(_type='hidden', _value=csv_table, _name='table'),
+ INPUT(_type='submit', _value=T('import')))
else:
formcsv = None
if formcsv and formcsv.process().accepted:
@@ -241,7 +245,7 @@ def select():
request.vars.csvfile.file)
response.flash = T('data uploaded')
except Exception, e:
- response.flash = DIV(T('unable to parse csv file'),PRE(str(e)))
+ response.flash = DIV(T('unable to parse csv file'), PRE(str(e)))
# end handle upload csv
return dict(
@@ -252,9 +256,9 @@ def select():
nrows=nrows,
rows=rows,
query=request.vars.query,
- formcsv = formcsv,
- tb = tb,
- )
+ formcsv=formcsv,
+ tb=tb,
+ )
# ##########################################################
@@ -264,14 +268,16 @@ def select():
def update():
(db, table) = get_table(request)
- keyed = hasattr(db[table],'_primarykey')
+ keyed = hasattr(db[table], '_primarykey')
record = None
if keyed:
key = [f for f in request.vars if f in db[table]._primarykey]
if key:
- record = db(db[table][key[0]] == request.vars[key[0]], ignore_common_filters=True).select().first()
+ record = db(db[table][key[0]] == request.vars[key[
+ 0]], ignore_common_filters=True).select().first()
else:
- record = db(db[table].id == request.args(2),ignore_common_filters=True).select().first()
+ record = db(db[table].id == request.args(
+ 2), ignore_common_filters=True).select().first()
if not record:
qry = query_by_table_type(table, db)
@@ -281,20 +287,21 @@ def update():
if keyed:
for k in db[table]._primarykey:
- db[table][k].writable=False
+ db[table][k].writable = False
- form = SQLFORM(db[table], record, deletable=True, delete_label=T('Check to delete'),
- ignore_rw=ignore_rw and not keyed,
- linkto=URL('select',
+ form = SQLFORM(
+ db[table], record, deletable=True, delete_label=T('Check to delete'),
+ ignore_rw=ignore_rw and not keyed,
+ linkto=URL('select',
args=request.args[:1]), upload=URL(r=request,
- f='download', args=request.args[:1]))
+ f='download', args=request.args[:1]))
if form.accepts(request.vars, session):
session.flash = T('done!')
qry = query_by_table_type(table, db)
redirect(URL('select', args=request.args[:1],
vars=dict(query=qry)))
- return dict(form=form,table=db[table])
+ return dict(form=form, table=db[table])
# ##########################################################
@@ -305,11 +312,15 @@ def update():
def state():
return dict()
+
def ccache():
form = FORM(
- P(TAG.BUTTON(T("Clear CACHE?"), _type="submit", _name="yes", _value="yes")),
- P(TAG.BUTTON(T("Clear RAM"), _type="submit", _name="ram", _value="ram")),
- P(TAG.BUTTON(T("Clear DISK"), _type="submit", _name="disk", _value="disk")),
+ P(TAG.BUTTON(
+ T("Clear CACHE?"), _type="submit", _name="yes", _value="yes")),
+ P(TAG.BUTTON(
+ T("Clear RAM"), _type="submit", _name="ram", _value="ram")),
+ P(TAG.BUTTON(
+ T("Clear DISK"), _type="submit", _name="disk", _value="disk")),
)
if form.accepts(request.vars, session):
@@ -333,11 +344,16 @@ def ccache():
redirect(URL(r=request))
try:
- from guppy import hpy; hp=hpy()
+ from guppy import hpy
+ hp = hpy()
except ImportError:
hp = False
- import shelve, os, copy, time, math
+ import shelve
+ import os
+ import copy
+ import time
+ import math
from gluon import portalocker
ram = {
@@ -382,9 +398,10 @@ def ccache():
ram['keys'].append((key, GetInHMS(time.time() - value[0])))
locker = open(os.path.join(request.folder,
- 'cache/cache.lock'), 'a')
+ 'cache/cache.lock'), 'a')
portalocker.lock(locker, portalocker.LOCK_EX)
- disk_storage = shelve.open(os.path.join(request.folder, 'cache/cache.shelve'))
+ disk_storage = shelve.open(
+ os.path.join(request.folder, 'cache/cache.shelve'))
try:
for key, value in disk_storage.items():
if isinstance(value, dict):
@@ -415,7 +432,8 @@ def ccache():
total['misses'] = ram['misses'] + disk['misses']
total['keys'] = ram['keys'] + disk['keys']
try:
- total['ratio'] = total['hits'] * 100 / (total['hits'] + total['misses'])
+ total['ratio'] = total['hits'] * 100 / (total['hits'] +
+ total['misses'])
except (KeyError, ZeroDivisionError):
total['ratio'] = 0
diff --git a/applications/welcome/controllers/default.py b/applications/welcome/controllers/default.py
index 4c4b563d..9ac34c21 100644
--- a/applications/welcome/controllers/default.py
+++ b/applications/welcome/controllers/default.py
@@ -9,6 +9,7 @@
## - call exposes all registered services (none by default)
#########################################################################
+
def index():
"""
example action using the internationalization operator T and flash
@@ -20,6 +21,7 @@ def index():
response.flash = T("Welcome to web2py!")
return dict(message=T('Hello World'))
+
def user():
"""
exposes:
@@ -42,7 +44,7 @@ def download():
allows downloading of uploaded files
http://..../[app]/default/download/[filename]
"""
- return response.download(request,db)
+ return response.download(request, db)
def call():
diff --git a/applications/welcome/models/db.py b/applications/welcome/models/db.py
index 26d28122..2cd6638e 100644
--- a/applications/welcome/models/db.py
+++ b/applications/welcome/models/db.py
@@ -16,7 +16,7 @@ else:
## connect to Google BigTable (optional 'google:datastore://namespace')
db = DAL('google:datastore')
## store sessions and tickets there
- session.connect(request, response, db = db)
+ session.connect(request, response, db=db)
## or store session in Memcache, Redis, etc.
## from gluon.contrib.memdb import MEMDB
## from google.appengine.api.memcache import Client
@@ -47,7 +47,7 @@ crud, service, plugins = Crud(db), Service(), PluginManager()
auth.define_tables(username=False, signature=False)
## configure email
-mail=auth.settings.mailer
+mail = auth.settings.mailer
mail.settings.server = 'logging' or 'smtp.gmail.com:587'
mail.settings.sender = 'you@gmail.com'
mail.settings.login = 'username:password'
@@ -60,7 +60,7 @@ auth.settings.reset_password_requires_verification = True
## if you need to use OpenID, Facebook, MySpace, Twitter, Linkedin, etc.
## register with janrain.com, write your domain:api_key in private/janrain.key
from gluon.contrib.login_methods.rpx_account import use_janrain
-use_janrain(auth,filename='private/janrain.key')
+use_janrain(auth, filename='private/janrain.key')
#########################################################################
## Define your tables below (or better in another model file) for example
diff --git a/applications/welcome/models/menu.py b/applications/welcome/models/menu.py
index 81010a99..ae2cdbf2 100644
--- a/applications/welcome/models/menu.py
+++ b/applications/welcome/models/menu.py
@@ -5,7 +5,8 @@
## Customize your APP title, subtitle and menus here
#########################################################################
-response.title = ' '.join(word.capitalize() for word in request.application.split('_'))
+response.title = ' '.join(
+ word.capitalize() for word in request.application.split('_'))
response.subtitle = T('customize me!')
## read more at http://dev.w3.org/html5/markup/meta.name.html
@@ -22,78 +23,113 @@ response.google_analytics_id = None
#########################################################################
response.menu = [
- (T('Home'), False, URL('default','index'), [])
- ]
+ (T('Home'), False, URL('default', 'index'), [])
+]
#########################################################################
## provide shortcuts for development. remove in production
#########################################################################
+
def _():
# shortcuts
app = request.application
ctr = request.controller
# useful links to internal and external resources
- response.menu+=[
- (SPAN('web2py',_class='highlighted'),False, 'http://web2py.com', [
- (T('My Sites'),False,URL('admin','default','site')),
- (T('This App'),False,URL('admin','default','design/%s' % app), [
- (T('Controller'),False,
- URL('admin','default','edit/%s/controllers/%s.py' % (app,ctr))),
- (T('View'),False,
- URL('admin','default','edit/%s/views/%s' % (app,response.view))),
- (T('Layout'),False,
- URL('admin','default','edit/%s/views/layout.html' % app)),
- (T('Stylesheet'),False,
- URL('admin','default','edit/%s/static/css/web2py.css' % app)),
- (T('DB Model'),False,
- URL('admin','default','edit/%s/models/db.py' % app)),
- (T('Menu Model'),False,
- URL('admin','default','edit/%s/models/menu.py' % app)),
- (T('Database'),False, URL(app,'appadmin','index')),
- (T('Errors'),False, URL('admin','default','errors/' + app)),
- (T('About'),False, URL('admin','default','about/' + app)),
+ response.menu += [
+ (SPAN('web2py', _class='highlighted'), False, 'http://web2py.com', [
+ (T('My Sites'), False, URL('admin', 'default', 'site')),
+ (T('This App'), False, URL('admin', 'default', 'design/%s' % app), [
+ (T('Controller'), False,
+ URL(
+ 'admin', 'default', 'edit/%s/controllers/%s.py' % (app, ctr))),
+ (T('View'), False,
+ URL(
+ 'admin', 'default', 'edit/%s/views/%s' % (app, response.view))),
+ (T('Layout'), False,
+ URL(
+ 'admin', 'default', 'edit/%s/views/layout.html' % app)),
+ (T('Stylesheet'), False,
+ URL(
+ 'admin', 'default', 'edit/%s/static/css/web2py.css' % app)),
+ (T('DB Model'), False,
+ URL(
+ 'admin', 'default', 'edit/%s/models/db.py' % app)),
+ (T('Menu Model'), False,
+ URL(
+ 'admin', 'default', 'edit/%s/models/menu.py' % app)),
+ (T('Database'), False, URL(app, 'appadmin', 'index')),
+ (T('Errors'), False, URL(
+ 'admin', 'default', 'errors/' + app)),
+ (T('About'), False, URL(
+ 'admin', 'default', 'about/' + app)),
+ ]),
+ ('web2py.com', False, 'http://www.web2py.com', [
+ (T('Download'), False,
+ 'http://www.web2py.com/examples/default/download'),
+ (T('Support'), False,
+ 'http://www.web2py.com/examples/default/support'),
+ (T('Demo'), False, 'http://web2py.com/demo_admin'),
+ (T('Quick Examples'), False,
+ 'http://web2py.com/examples/default/examples'),
+ (T('FAQ'), False, 'http://web2py.com/AlterEgo'),
+ (T('Videos'), False,
+ 'http://www.web2py.com/examples/default/videos/'),
+ (T('Free Applications'),
+ False, 'http://web2py.com/appliances'),
+ (T('Plugins'), False, 'http://web2py.com/plugins'),
+ (T('Layouts'), False, 'http://web2py.com/layouts'),
+ (T('Recipes'), False, 'http://web2pyslices.com/'),
+ (T('Semantic'), False, 'http://web2py.com/semantic'),
+ ]),
+ (T('Documentation'), False, 'http://www.web2py.com/book', [
+ (T('Preface'), False,
+ 'http://www.web2py.com/book/default/chapter/00'),
+ (T('Introduction'), False,
+ 'http://www.web2py.com/book/default/chapter/01'),
+ (T('Python'), False,
+ 'http://www.web2py.com/book/default/chapter/02'),
+ (T('Overview'), False,
+ 'http://www.web2py.com/book/default/chapter/03'),
+ (T('The Core'), False,
+ 'http://www.web2py.com/book/default/chapter/04'),
+ (T('The Views'), False,
+ 'http://www.web2py.com/book/default/chapter/05'),
+ (T('Database'), False,
+ 'http://www.web2py.com/book/default/chapter/06'),
+ (T('Forms and Validators'), False,
+ 'http://www.web2py.com/book/default/chapter/07'),
+ (T('Email and SMS'), False,
+ 'http://www.web2py.com/book/default/chapter/08'),
+ (T('Access Control'), False,
+ 'http://www.web2py.com/book/default/chapter/09'),
+ (T('Services'), False,
+ 'http://www.web2py.com/book/default/chapter/10'),
+ (T('Ajax Recipes'), False,
+ 'http://www.web2py.com/book/default/chapter/11'),
+ (T('Components and Plugins'), False,
+ 'http://www.web2py.com/book/default/chapter/12'),
+ (T('Deployment Recipes'), False,
+ 'http://www.web2py.com/book/default/chapter/13'),
+ (T('Other Recipes'), False,
+ 'http://www.web2py.com/book/default/chapter/14'),
+ (T('Buy this book'), False,
+ 'http://stores.lulu.com/web2py'),
+ ]),
+ (T('Community'), False, None, [
+ (T('Groups'), False,
+ 'http://www.web2py.com/examples/default/usergroups'),
+ (T('Twitter'), False, 'http://twitter.com/web2py'),
+ (T('Live Chat'), False,
+ 'http://webchat.freenode.net/?channels=web2py'),
]),
- ('web2py.com',False,'http://www.web2py.com', [
- (T('Download'),False,'http://www.web2py.com/examples/default/download'),
- (T('Support'),False,'http://www.web2py.com/examples/default/support'),
- (T('Demo'),False,'http://web2py.com/demo_admin'),
- (T('Quick Examples'),False,'http://web2py.com/examples/default/examples'),
- (T('FAQ'),False,'http://web2py.com/AlterEgo'),
- (T('Videos'),False,'http://www.web2py.com/examples/default/videos/'),
- (T('Free Applications'),False,'http://web2py.com/appliances'),
- (T('Plugins'),False,'http://web2py.com/plugins'),
- (T('Layouts'),False,'http://web2py.com/layouts'),
- (T('Recipes'),False,'http://web2pyslices.com/'),
- (T('Semantic'),False,'http://web2py.com/semantic'),
- ]),
- (T('Documentation'),False,'http://www.web2py.com/book', [
- (T('Preface'),False,'http://www.web2py.com/book/default/chapter/00'),
- (T('Introduction'),False,'http://www.web2py.com/book/default/chapter/01'),
- (T('Python'),False,'http://www.web2py.com/book/default/chapter/02'),
- (T('Overview'),False,'http://www.web2py.com/book/default/chapter/03'),
- (T('The Core'),False,'http://www.web2py.com/book/default/chapter/04'),
- (T('The Views'),False,'http://www.web2py.com/book/default/chapter/05'),
- (T('Database'),False,'http://www.web2py.com/book/default/chapter/06'),
- (T('Forms and Validators'),False,'http://www.web2py.com/book/default/chapter/07'),
- (T('Email and SMS'),False,'http://www.web2py.com/book/default/chapter/08'),
- (T('Access Control'),False,'http://www.web2py.com/book/default/chapter/09'),
- (T('Services'),False,'http://www.web2py.com/book/default/chapter/10'),
- (T('Ajax Recipes'),False,'http://www.web2py.com/book/default/chapter/11'),
- (T('Components and Plugins'),False,'http://www.web2py.com/book/default/chapter/12'),
- (T('Deployment Recipes'),False,'http://www.web2py.com/book/default/chapter/13'),
- (T('Other Recipes'),False,'http://www.web2py.com/book/default/chapter/14'),
- (T('Buy this book'),False,'http://stores.lulu.com/web2py'),
- ]),
- (T('Community'),False, None, [
- (T('Groups'),False,'http://www.web2py.com/examples/default/usergroups'),
- (T('Twitter'),False,'http://twitter.com/web2py'),
- (T('Live Chat'),False,'http://webchat.freenode.net/?channels=web2py'),
- ]),
- (T('Plugins'),False,None, [
- ('plugin_wiki',False,'http://web2py.com/examples/default/download'),
- (T('Other Plugins'),False,'http://web2py.com/plugins'),
- (T('Layout Plugins'),False,'http://web2py.com/layouts'),
+ (T('Plugins'), False, None, [
+ ('plugin_wiki', False,
+ 'http://web2py.com/examples/default/download'),
+ (T('Other Plugins'), False,
+ 'http://web2py.com/plugins'),
+ (T('Layout Plugins'),
+ False, 'http://web2py.com/layouts'),
])
]
)]