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 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'), ]) ] )]