Merge github.com:web2py/web2py
This commit is contained in:
@@ -1,6 +1,11 @@
|
||||
## 2.00.0
|
||||
|
||||
- request.args(0,default=0, cast=int, url_onerror=URL(...)), thanks Anthony
|
||||
- redirect(...,type='auto') will be handled properly in ajax responses
|
||||
- experimental MongoDB support in DAL
|
||||
- FORM.confirm('Confirm?',{'Back':URL(...)})
|
||||
- @auth.requires_login(otherwise=URL(...))
|
||||
- request.args(0,default=0, cast=int, otherwise=URL(...)), thanks Anthony
|
||||
- better memcache support
|
||||
- generic.ics
|
||||
- generic.map
|
||||
- geodal and spatialite, thanks Denes and Fran
|
||||
@@ -11,6 +16,23 @@
|
||||
- form.add_button(value,link)
|
||||
- db.table.insert(uploadfield=open(....))
|
||||
- DAL BIGINT support and DAL(...,bigint_id=True)
|
||||
- IS_IN_DB distinct
|
||||
- more secure SQLFORM.grid and SQLFORM.smartgrid
|
||||
- more export options in SQLFORM.grid and SQLFORM.smartgrid
|
||||
- more secure admin against CSRF
|
||||
- improved spreadsheet, thanks Alan
|
||||
- routes in can redirect outside with routes_in=[('/path','303->http://..')]
|
||||
- auth supports salt and compatible with third party data, thanks Dave Stoll
|
||||
- CRYPT now defaults to pbkdf2(1000,20,sha1)
|
||||
- experimental GIT integration
|
||||
- experimental OpenShift deployment
|
||||
- new makrmin with supports for nested lists, <i>, <em>, autolinks
|
||||
- new interantionalization engine
|
||||
- multi-language pluralization engine
|
||||
- db.table.field.count(True)
|
||||
- auth.wiki()
|
||||
- new syntax BR()*5
|
||||
- gluon.cache.lazy_cache decorator
|
||||
- auth.settings.everybody_group_id
|
||||
- ace text web editor in admin
|
||||
- -E -b -L options for scheduler
|
||||
@@ -18,7 +40,6 @@
|
||||
- ldap certificate support
|
||||
- pg8000 postgresql driver support
|
||||
- portable html.py
|
||||
- <i> to <em> in markmin
|
||||
- new admin pages: manage_students, bulk_regsiter, and progress reports
|
||||
- @cache('%(name)s%(args)s%(vars)s',5) and cache.autokey
|
||||
- added tox.ini, thanks Marc
|
||||
@@ -36,6 +57,12 @@
|
||||
- SQLFORM.grid(groupby=...')
|
||||
- db.table.field.filter_in, filter_out
|
||||
- allowed storage of uploads on any PyFileSystem (including amazon)
|
||||
- new scheduler can now handle 10k tasks with 20 concurrent workers and no known issues (thanks to niphlod, ykessler, dhx, toomim)
|
||||
- shceduler: tasks can be found in the environment (no need to define the tasks parameter)
|
||||
- scheduler: max_empty_runs kills the workers automatically if no new tasks are found in queue (nice for "spikes" of processing power), discard_results to completely discard the results (if you don't need the output of the task), utc_time enables datetime calculations with UTC time, task_name is no longer required (filled automatically with function_name if found empty), uuid makes easy to coordinate scheduler_task maintenance (filled automatically if not provided), stop_time has no default (previously was today+1), retry_failed to requeue automatically failed tasks, sync_output refreshes automatically the output (nice to report percentages)
|
||||
- scheduler tasks can be DISABLED (put to sleep and do nothing if not sending the heartbeat every 30 seconds), TERMINATE (complete the current task and then die), KILL (kill ASAP), EXPIRED (if stop_time passed)
|
||||
- web2py.py -K myapp -X starts the myapp scheduler alongside the webserver
|
||||
|
||||
|
||||
## 1.99.5-1.99.7
|
||||
- admin in Russian (Bulat), Japanese (Omi) and Slovenian (Robert Valentak)
|
||||
|
||||
@@ -43,11 +43,11 @@ src:
|
||||
rm -f applications/admin/uploads/*
|
||||
rm -f applications/welcome/uploads/*
|
||||
rm -f applications/examples/uploads/*
|
||||
### make admin layout and appadmin the default
|
||||
cp applications/admin/views/appadmin.html applications/welcome/views
|
||||
cp applications/admin/views/appadmin.html applications/examples/views
|
||||
cp applications/admin/controllers/appadmin.py applications/welcome/controllers
|
||||
cp applications/admin/controllers/appadmin.py applications/examples/controllers
|
||||
### make welcome layout and appadmin the default
|
||||
cp applications/welcome/views/appadmin.html applications/admin/views
|
||||
cp applications/welcome/views/appadmin.html applications/examples/views
|
||||
cp applications/welcome/controllers/appadmin.py applications/admin/controllers
|
||||
cp applications/welcome/controllers/appadmin.py applications/examples/controllers
|
||||
### build web2py_src.zip
|
||||
echo '' > NEWINSTALL
|
||||
mv web2py_src.zip web2py_src_old.zip | echo 'no old'
|
||||
|
||||
@@ -1 +1 @@
|
||||
Version 2.00.0 (2012-07-27 09:32:24) dev
|
||||
Version 2.00.0 (2012-08-18 16:21:48) dev
|
||||
|
||||
@@ -4,3 +4,5 @@
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
+4
-2
@@ -128,13 +128,14 @@ class Servers:
|
||||
from gunicorn.app.base import Application
|
||||
config = {'bind': "%s:%d" % address}
|
||||
config.update(options)
|
||||
sys.argv = ['anyserver.py']
|
||||
class GunicornApplication(Application):
|
||||
def init(self, parser, opts, args):
|
||||
def init(self, parser, opts, args):
|
||||
return config
|
||||
def load(self):
|
||||
return app
|
||||
g = GunicornApplication()
|
||||
g.run()
|
||||
g.run()
|
||||
|
||||
@staticmethod
|
||||
def eventlet(app,address, **options):
|
||||
@@ -307,3 +308,4 @@ if __name__=='__main__':
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -5,3 +5,4 @@ def webapp_add_wsgi_middleware(app):
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -199,17 +199,8 @@ def select():
|
||||
_class='delete', _type='checkbox', value=False), ''),
|
||||
TR('', '', INPUT(_type='submit', _value=T('submit')))),
|
||||
_action=URL(r=request,args=request.args))
|
||||
if request.vars.csvfile != None:
|
||||
try:
|
||||
import_csv(db[request.vars.table],
|
||||
request.vars.csvfile.file)
|
||||
response.flash = T('data uploaded')
|
||||
except Exception, e:
|
||||
response.flash = DIV(T('unable to parse csv file'),PRE(str(e)))
|
||||
if form.accepts(request.vars, formname=None):
|
||||
# regex = re.compile(request.args[0] + '\.(?P<table>\w+)\.id\>0')
|
||||
regex = re.compile(request.args[0] + '\.(?P<table>\w+)\..+')
|
||||
|
||||
match = regex.match(form.vars.query.strip())
|
||||
if match:
|
||||
table = match.group('table')
|
||||
@@ -230,6 +221,23 @@ def select():
|
||||
except Exception, e:
|
||||
(rows, nrows) = ([], 0)
|
||||
response.flash = DIV(T('Invalid Query'),PRE(str(e)))
|
||||
# begin handle upload csv
|
||||
if table:
|
||||
formcsv = FORM(str(T('or import from csv file'))+" ",
|
||||
INPUT(_type='file',_name='csvfile'),
|
||||
INPUT(_type='hidden',_value=table,_name='table'),
|
||||
INPUT(_type='submit',_value=T('import')))
|
||||
else:
|
||||
formcsv = None
|
||||
if formcsv and formcsv.process().accepted and request.vars.csvfile:
|
||||
try:
|
||||
import_csv(db[request.vars.table],
|
||||
request.vars.csvfile.file)
|
||||
response.flash = T('data uploaded')
|
||||
except Exception, e:
|
||||
response.flash = DIV(T('unable to parse csv file'),PRE(str(e)))
|
||||
# end handle upload csv
|
||||
|
||||
return dict(
|
||||
form=form,
|
||||
table=table,
|
||||
@@ -238,6 +246,7 @@ def select():
|
||||
nrows=nrows,
|
||||
rows=rows,
|
||||
query=request.vars.query,
|
||||
formcsv = formcsv,
|
||||
)
|
||||
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@ if EXPERIMENTAL_STUFF:
|
||||
import re
|
||||
from gluon.admin import *
|
||||
from gluon.fileutils import abspath, read_file, write_file
|
||||
from gluon.utils import web2py_uuid
|
||||
from glob import glob
|
||||
import shutil
|
||||
import platform
|
||||
@@ -40,6 +41,9 @@ if FILTER_APPS and request.args(0) and not request.args(0) in FILTER_APPS:
|
||||
session.flash = T('disabled in demo mode')
|
||||
redirect(URL('site'))
|
||||
|
||||
|
||||
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('#')])
|
||||
|
||||
@@ -167,6 +171,7 @@ def change_password():
|
||||
redirect(URL('site'))
|
||||
return dict(form=form)
|
||||
|
||||
|
||||
def site():
|
||||
""" Site handler """
|
||||
|
||||
@@ -175,12 +180,32 @@ def site():
|
||||
# Shortcut to make the elif statements more legible
|
||||
file_or_appurl = 'file' in request.vars or 'appurl' in request.vars
|
||||
|
||||
class IS_VALID_APPNAME(object):
|
||||
def __call__(self,value):
|
||||
if not re.compile('\w+').match(value):
|
||||
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)
|
||||
|
||||
is_appname = IS_VALID_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),
|
||||
Field('url'),
|
||||
Field('overwrite','boolean'),
|
||||
table_name='appupdate')
|
||||
form_create.process()
|
||||
form_update.process()
|
||||
|
||||
if DEMO_MODE:
|
||||
pass
|
||||
|
||||
elif request.vars.filename and not 'file' in request.vars:
|
||||
elif form_create.accepted:
|
||||
# create a new application
|
||||
appname = cleanpath(request.vars.filename).replace('.', '_')
|
||||
appname = cleanpath(form_create.vars.name)
|
||||
if app_create(appname, request):
|
||||
if MULTI_USER_MODE:
|
||||
db.app.insert(name=appname,owner=auth.user.id)
|
||||
@@ -189,49 +214,44 @@ def site():
|
||||
redirect(URL('design',args=appname))
|
||||
else:
|
||||
session.flash = \
|
||||
T('unable to create application "%s" (it may exist already)', request.vars.filename)
|
||||
T('unable to create application "%s" (it may exist already)',
|
||||
form_create.vars.name)
|
||||
redirect(URL(r=request))
|
||||
|
||||
elif file_or_appurl and not request.vars.filename:
|
||||
# can't do anything without an app name
|
||||
msg = 'you must specify a name for the uploaded application'
|
||||
response.flash = T(msg)
|
||||
|
||||
elif (request.vars.appurl or '').endswith('.git') and request.vars.filename:
|
||||
if not have_git:
|
||||
session.flash = GIT_MISSING
|
||||
elif request.vars.filename:
|
||||
target = os.path.join(apath(r=request),request.vars.filename)
|
||||
if os.path.exists(target):
|
||||
session.flash = 'Application by that name already exists.'
|
||||
else:
|
||||
try:
|
||||
new_repo = Repo.clone_from(request.vars.appurl,target)
|
||||
session.flash = T('new application "%s" imported',request.vars.filename)
|
||||
except GitCommandError, err:
|
||||
session.flash = T('Invalid git repository specified.')
|
||||
else:
|
||||
session.flash = 'Application Name required for git import.'
|
||||
redirect(URL(r=request))
|
||||
|
||||
elif file_or_appurl and request.vars.filename:
|
||||
# fetch an application via URL or file upload
|
||||
f = None
|
||||
if request.vars.appurl:
|
||||
elif form_update.accepted:
|
||||
if (form_update.vars.url or '').endswith('.git'):
|
||||
if not have_git:
|
||||
session.flash = GIT_MISSING
|
||||
target = os.path.join(apath(r=request),form_update.vars.name)
|
||||
try:
|
||||
f = urllib.urlopen(request.vars.appurl)
|
||||
except Exception, e:
|
||||
session.flash = DIV(T('Unable to download app because:'),PRE(str(e)))
|
||||
redirect(URL(r=request))
|
||||
fname = request.vars.appurl
|
||||
elif request.vars.file:
|
||||
f = request.vars.file.file
|
||||
fname = request.vars.file.filename
|
||||
new_repo = Repo.clone_from(form_update.vars.url,target)
|
||||
session.flash = T('new application "%s" imported',
|
||||
form_update.vars.name)
|
||||
except GitCommandError, err:
|
||||
session.flash = T('Invalid git repository specified.')
|
||||
redirect(URL(r=request))
|
||||
|
||||
elif form_update.vars.url:
|
||||
# fetch an application via URL or file upload
|
||||
try:
|
||||
f = urllib.urlopen(form_update.vars.url)
|
||||
if f.code == 404:
|
||||
raise Exception("404 file not found")
|
||||
except Exception, e:
|
||||
session.flash = \
|
||||
DIV(T('Unable to download app because:'),PRE(str(e)))
|
||||
redirect(URL(r=request))
|
||||
fname = form_update.vars.url
|
||||
|
||||
elif form_update.accepted and form_update.vars.file:
|
||||
fname = request.vars.file.filename
|
||||
f = request.vars.file.file
|
||||
|
||||
if f:
|
||||
appname = cleanpath(request.vars.filename).replace('.', '_')
|
||||
installed = app_install(appname, f, request, fname,
|
||||
overwrite=request.vars.overwrite_check)
|
||||
appname = cleanpath(form_update.vars.name)
|
||||
installed = app_install(appname, f,
|
||||
request, fname,
|
||||
overwrite=form_update.vars.overwrite)
|
||||
if f and installed:
|
||||
msg = 'application %(appname)s installed with md5sum: %(digest)s'
|
||||
if MULTI_USER_MODE:
|
||||
@@ -239,14 +259,12 @@ def site():
|
||||
log_progress(appname)
|
||||
session.flash = T(msg, dict(appname=appname,
|
||||
digest=md5_hash(installed)))
|
||||
elif f and request.vars.overwrite_check:
|
||||
elif f and form_update.vars.overwrite:
|
||||
msg = 'unable to install application "%(appname)s"'
|
||||
session.flash = T(msg, dict(appname=request.vars.filename))
|
||||
|
||||
session.flash = T(msg, dict(appname=form_update.vars.name))
|
||||
else:
|
||||
msg = 'unable to install application "%(appname)s"'
|
||||
session.flash = T(msg, dict(appname=request.vars.filename))
|
||||
|
||||
session.flash = T(msg, dict(appname=form_update.vars.name))
|
||||
redirect(URL(r=request))
|
||||
|
||||
regex = re.compile('^\w+$')
|
||||
@@ -261,7 +279,8 @@ def site():
|
||||
|
||||
apps = sorted(apps,lambda a,b:cmp(a.upper(),b.upper()))
|
||||
|
||||
return dict(app=None, apps=apps, myversion=myversion)
|
||||
return dict(app=None, apps=apps, myversion=myversion,
|
||||
form_create=form_create, form_update=form_update)
|
||||
|
||||
|
||||
def report_progress(app):
|
||||
@@ -317,20 +336,24 @@ def pack_plugin():
|
||||
redirect(URL('plugin',args=request.args))
|
||||
|
||||
def upgrade_web2py():
|
||||
if 'upgrade' in request.vars:
|
||||
dialog = FORM.confim(T('Upgrade'),
|
||||
{T('Cancel'):URL('site')})
|
||||
if dialog.accepted:
|
||||
(success, error) = upgrade(request)
|
||||
if success:
|
||||
session.flash = T('web2py upgraded; please restart it')
|
||||
else:
|
||||
session.flash = T('unable to upgrade because "%s"', error)
|
||||
redirect(URL('site'))
|
||||
elif 'noupgrade' in request.vars:
|
||||
redirect(URL('site'))
|
||||
return dict()
|
||||
return dict(dialog=dialog)
|
||||
|
||||
def uninstall():
|
||||
app = get_app()
|
||||
if 'delete' in request.vars:
|
||||
|
||||
dialog = FORM.confim(T('Uninstall'),
|
||||
{T('Cancel'):URL('site')})
|
||||
|
||||
if dialog.accepted:
|
||||
if MULTI_USER_MODE:
|
||||
if is_manager() and db(db.app.name==app).delete():
|
||||
pass
|
||||
@@ -344,9 +367,7 @@ def uninstall():
|
||||
else:
|
||||
session.flash = T('unable to uninstall "%s"', app)
|
||||
redirect(URL('site'))
|
||||
elif 'nodelete' in request.vars:
|
||||
redirect(URL('site'))
|
||||
return dict(app=app)
|
||||
return dict(app=app, dialog=dialog)
|
||||
|
||||
|
||||
def cleanup():
|
||||
@@ -412,7 +433,7 @@ def delete():
|
||||
if isinstance(sender, list): # ## fix a problem with Vista
|
||||
sender = sender[0]
|
||||
|
||||
dialog = FORM.dialog(T('Delete'),
|
||||
dialog = FORM.confim(T('Delete'),
|
||||
{T('Cancel'):URL(sender, anchor=request.vars.id)})
|
||||
|
||||
if dialog.accepted:
|
||||
@@ -846,6 +867,9 @@ def design():
|
||||
msg = T('ATTENTION: you cannot edit the running application!')
|
||||
response.flash = msg
|
||||
|
||||
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 plugin_install(app, request.vars.pluginfile.file,
|
||||
@@ -978,9 +1002,12 @@ def delete_plugin():
|
||||
app=request.args(0)
|
||||
plugin = request.args(1)
|
||||
plugin_name='plugin_'+plugin
|
||||
if 'nodelete' in request.vars:
|
||||
redirect(URL('design', args=app, anchor=request.vars.id))
|
||||
elif 'delete' in request.vars:
|
||||
|
||||
dialog = FORM.confim(
|
||||
T('Delete'),
|
||||
{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)
|
||||
@@ -997,7 +1024,7 @@ 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(plugin=plugin)
|
||||
return dict(dialog=dialog,plugin=plugin)
|
||||
|
||||
def plugin():
|
||||
""" Application design handler """
|
||||
@@ -1094,6 +1121,8 @@ def plugin():
|
||||
|
||||
def create_file():
|
||||
""" Create files handler """
|
||||
if request.vars and not request.vars.token==session.token:
|
||||
redirect(URL('logout'))
|
||||
try:
|
||||
anchor='#'+request.vars.id if request.vars.id else ''
|
||||
if request.vars.app:
|
||||
@@ -1241,6 +1270,8 @@ def create_file():
|
||||
|
||||
def upload_file():
|
||||
""" File uploading handler """
|
||||
if request.vars and not request.vars.token==session.token:
|
||||
redirect(URL('logout'))
|
||||
try:
|
||||
filename = None
|
||||
app = get_app(name=request.vars.location.split('/')[0])
|
||||
@@ -1586,7 +1617,6 @@ def reload_routes():
|
||||
gluon.rewrite.load()
|
||||
redirect(URL('site'))
|
||||
|
||||
|
||||
def manage_students():
|
||||
if not (MULTI_USER_MODE and is_manager()):
|
||||
session.flash = T('Not Authorized')
|
||||
@@ -1621,7 +1651,9 @@ def git_pull():
|
||||
if not have_git:
|
||||
session.flash = GIT_MISSING
|
||||
redirect(URL('site'))
|
||||
if 'pull' in request.vars:
|
||||
dialog = FORM.confim(T('Pull'),
|
||||
{T('Cancel'):URL('site')})
|
||||
if dialog.accepted:
|
||||
try:
|
||||
repo = Repo(os.path.join(apath(r=request),app))
|
||||
origin = repo.remotes.origin
|
||||
@@ -1649,7 +1681,7 @@ def git_pull():
|
||||
redirect(URL('site'))
|
||||
elif 'cancel' in request.vars:
|
||||
redirect(URL('site'))
|
||||
return dict(app=app)
|
||||
return dict(app=app,dialog=dialog)
|
||||
|
||||
|
||||
def git_push():
|
||||
@@ -1666,8 +1698,7 @@ def git_push():
|
||||
try:
|
||||
repo = Repo(os.path.join(apath(r=request),app))
|
||||
index = repo.index
|
||||
os.chdir(os.path.join(apath(r=request),app))
|
||||
index.add('*')
|
||||
index.add([apath(r=request)+app+'/*'])
|
||||
new_commit = index.commit(form.vars.changelog)
|
||||
origin = repo.remotes.origin
|
||||
origin.push()
|
||||
@@ -1680,6 +1711,5 @@ def git_push():
|
||||
logging.error("Unexpected error:", sys.exc_info()[0])
|
||||
session.flash = T("Push failed, git exited abnormally. See logs for details.")
|
||||
redirect(URL('site'))
|
||||
os.chdir(apath(r=request))
|
||||
return dict(app=app,form=form)
|
||||
|
||||
|
||||
@@ -139,7 +139,7 @@ def step2():
|
||||
if not name in session.app['pages']:
|
||||
session.app['pages'].append(name)
|
||||
session.app['page_'+name] = \
|
||||
'## Manage %s\n{{=form}}' % (table)
|
||||
'## Manage %s\n\n{{=form}}' % (table)
|
||||
if session.app['tables']:
|
||||
redirect(URL('step3',args=0))
|
||||
else:
|
||||
@@ -248,8 +248,11 @@ def sort_tables(tables):
|
||||
def append(table,trail=[]):
|
||||
if table in trail:
|
||||
raise RuntimeError
|
||||
for t in d[table]: append(t,trail=trail+[table])
|
||||
if not table in tables: tables.append(table)
|
||||
for t in d[table]:
|
||||
# if not t==table: (problem, no dropdown for self references)
|
||||
append(t,trail=trail+[table])
|
||||
if not table in tables:
|
||||
tables.append(table)
|
||||
for table in d: append(table)
|
||||
return tables
|
||||
|
||||
@@ -351,7 +354,7 @@ def make_table(table,fields):
|
||||
s+="""
|
||||
db.auth_user.first_name.requires = IS_NOT_EMPTY(error_message=auth.messages.is_empty)
|
||||
db.auth_user.last_name.requires = IS_NOT_EMPTY(error_message=auth.messages.is_empty)
|
||||
db.auth_user.password.requires = CRYPT(key=auth.settings.hmac_key)
|
||||
db.auth_user.password.requires = CRYPT(key=auth.settings.hmac_key, min_length=4)
|
||||
db.auth_user.username.requires = IS_NOT_IN_DB(db, db.auth_user.username)
|
||||
db.auth_user.email.requires = (IS_EMAIL(error_message=auth.messages.invalid_email),
|
||||
IS_NOT_IN_DB(db, db.auth_user.email))
|
||||
|
||||
+189
-177
@@ -3,198 +3,28 @@
|
||||
'!langcode!': 'de',
|
||||
'!langname!': 'Deutsch',
|
||||
'"update" is an optional expression like "field1=\'newvalue\'". You cannot update or delete the results of a JOIN': '"Update" ist ein optionaler Ausdruck wie "Feld1 = \'newvalue". JOIN Ergebnisse können nicht aktualisiert oder gelöscht werden',
|
||||
'%Y-%m-%d': '%Y-%m-%d',
|
||||
'%Y-%m-%d %H:%M:%S': '%Y-%m-%d %H:%M:%S',
|
||||
'%s %%{row} deleted': '%s Zeilen gelöscht',
|
||||
'%s %%{row} updated': '%s Zeilen aktualisiert',
|
||||
'%Y-%m-%d': '%Y-%m-%d',
|
||||
'%Y-%m-%d %H:%M:%S': '%Y-%m-%d %H:%M:%S',
|
||||
'(requires internet access)': '(requires internet access)',
|
||||
'(something like "it-it")': '(so etwas wie "it-it")',
|
||||
'@markmin\x01Searching: **%s** %%{file}': 'Searching: **%s** files',
|
||||
'A new version of web2py is available': 'Eine neue Version von web2py ist verfügbar',
|
||||
'A new version of web2py is available: %s': 'Eine neue Version von web2py ist verfügbar: %s',
|
||||
'A new version of web2py is available: Version 1.85.3 (2010-09-18 07:07:46)\n': 'Eine neue Version von web2py ist verfügbar: Version 1.85.3 (2010-09-18 07:07:46)\n',
|
||||
'ATTENTION: Login requires a secure (HTTPS) connection or running on localhost.': 'ACHTUNG: Die Einwahl benötigt eine sichere (HTTPS) Verbindung. Es sei denn sie läuft Lokal(localhost).',
|
||||
'ATTENTION: TESTING IS NOT THREAD SAFE SO DO NOT PERFORM MULTIPLE TESTS CONCURRENTLY.': 'ACHTUNG: Testen ist nicht threadsicher. Führen sie also nicht mehrere Tests gleichzeitig aus.',
|
||||
'ATTENTION: This is an experimental feature and it needs more testing.': 'ACHTUNG: Dies ist eine experimentelle Funktion und benötigt noch weitere Tests.',
|
||||
'ATTENTION: you cannot edit the running application!': 'ACHTUNG: Eine laufende Anwendung kann nicht editiert werden!',
|
||||
'Abort': 'Abbrechen',
|
||||
'About': 'Über',
|
||||
'About application': 'Über die Anwendung',
|
||||
'Additional code for your application': 'Additional code for your application',
|
||||
'Admin is disabled because insecure channel': 'Appadmin ist deaktiviert, wegen der Benutzung eines unsicheren Kanals',
|
||||
'Admin is disabled because unsecure channel': 'Appadmin ist deaktiviert, wegen der Benutzung eines unsicheren Kanals',
|
||||
'Admin language': 'Admin language',
|
||||
'Administrator Password:': 'Administrator Passwort:',
|
||||
'Application name:': 'Application name:',
|
||||
'Are you sure you want to delete file "%s"?': 'Sind Sie sich sicher, dass Sie diese Datei löschen wollen "%s"?',
|
||||
'Are you sure you want to uninstall application "%s"': 'Sind Sie sich sicher, dass Sie diese Anwendung deinstallieren wollen "%s"',
|
||||
'Are you sure you want to uninstall application "%s"?': 'Sind Sie sich sicher, dass Sie diese Anwendung deinstallieren wollen "%s"?',
|
||||
'Are you sure you want to upgrade web2py now?': 'Sind Sie sich sicher, dass Sie web2py jetzt upgraden möchten?',
|
||||
'Authentication': 'Authentifizierung',
|
||||
'Available databases and tables': 'Verfügbare Datenbanken und Tabellen',
|
||||
'Cannot be empty': 'Darf nicht leer sein',
|
||||
'Cannot compile: there are errors in your app. Debug it, correct errors and try again.': 'Nicht Kompilierbar:Es sind Fehler in der Anwendung. Beseitigen Sie die Fehler und versuchen Sie es erneut.',
|
||||
'Change Password': 'Passwort ändern',
|
||||
'Change admin password': 'Administrator-Passwort ändern',
|
||||
'Check for upgrades': 'check for upgrades',
|
||||
'Check to delete': 'Markiere zum löschen',
|
||||
'Checking for upgrades...': 'Auf Updates überprüfen...',
|
||||
'Clean': 'löschen',
|
||||
'Client IP': 'Client IP',
|
||||
'Compile': 'kompilieren',
|
||||
'Controller': 'Controller',
|
||||
'Controllers': 'Controller',
|
||||
'Copyright': 'Urheberrecht',
|
||||
'Create': 'erstellen',
|
||||
'Create new simple application': 'Erzeuge neue Anwendung',
|
||||
'Current request': 'Aktuelle Anfrage (request)',
|
||||
'Current response': 'Aktuelle Antwort (response)',
|
||||
'Current session': 'Aktuelle Sitzung (session)',
|
||||
'DB Model': 'DB Modell',
|
||||
'DESIGN': 'design',
|
||||
'Database': 'Datenbank',
|
||||
'Date and Time': 'Datum und Uhrzeit',
|
||||
'Delete': 'Löschen',
|
||||
'Delete:': 'Löschen:',
|
||||
'Deploy': 'deploy',
|
||||
'Deploy on Google App Engine': 'Auf Google App Engine installieren',
|
||||
'Description': 'Beschreibung',
|
||||
'Design for': 'Design für',
|
||||
'E-mail': 'E-mail',
|
||||
'EDIT': 'BEARBEITEN',
|
||||
'Edit': 'bearbeiten',
|
||||
'Edit Profile': 'Bearbeite Profil',
|
||||
'Edit This App': 'Bearbeite diese Anwendung',
|
||||
'Edit application': 'Bearbeite Anwendung',
|
||||
'Edit current record': 'Bearbeite aktuellen Datensatz',
|
||||
'Editing Language file': 'Sprachdatei bearbeiten',
|
||||
'Editing file': 'Bearbeite Datei',
|
||||
'Editing file "%s"': 'Bearbeite Datei "%s"',
|
||||
'Enterprise Web Framework': 'Enterprise Web Framework',
|
||||
'Error logs for "%(app)s"': 'Fehlerprotokoll für "%(app)s"',
|
||||
'Errors': 'Fehler',
|
||||
'Exception instance attributes': 'Atribute der Ausnahmeinstanz',
|
||||
'Expand Abbreviation': 'Kürzel erweitern',
|
||||
'First name': 'Vorname',
|
||||
'Functions with no doctests will result in [passed] tests.': 'Funktionen ohne doctests erzeugen [passed] in Tests',
|
||||
'Go to Matching Pair': 'gehe zum übereinstimmenden Paar',
|
||||
'Group ID': 'Gruppen ID',
|
||||
'Hello World': 'Hallo Welt',
|
||||
'Help': 'Hilfe',
|
||||
'If the report above contains a ticket number it indicates a failure in executing the controller, before any attempt to execute the doctests. This is usually due to an indentation error or an error outside function code.\nA green title indicates that all tests (if defined) passed. In this case test results are not shown.': 'Falls der obere Test eine Fehler-Ticketnummer enthält deutet das auf einen Fehler in der Ausführung des Controllers hin, noch bevor der Doctest ausgeführt werden konnte. Gewöhnlich führen fehlerhafte Einrückungen oder fehlerhafter Code ausserhalb der Funktion zu solchen Fehlern. Ein grüner Titel deutet darauf hin, dass alle Test(wenn sie vorhanden sind) erfolgreich durchlaufen wurden. In diesem Fall werden die Testresultate nicht angezeigt.',
|
||||
'If you answer "yes", be patient, it may take a while to download': '',
|
||||
'If you answer yes, be patient, it may take a while to download': 'If you answer yes, be patient, it may take a while to download',
|
||||
'Import/Export': 'Importieren/Exportieren',
|
||||
'Index': 'Index',
|
||||
'Install': 'installieren',
|
||||
'Installed applications': 'Installierte Anwendungen',
|
||||
'Internal State': 'interner Status',
|
||||
'Invalid Query': 'Ungültige Abfrage',
|
||||
'Invalid action': 'Ungültige Aktion',
|
||||
'Invalid email': 'Ungültige Email',
|
||||
'Key bindings': 'Tastenbelegungen',
|
||||
'Key bindings for ZenConding Plugin': 'Tastenbelegungen für das ZenConding Plugin',
|
||||
'Language files (static strings) updated': 'Sprachdatei (statisch Strings) aktualisiert',
|
||||
'Languages': 'Sprachen',
|
||||
'Last name': 'Nachname',
|
||||
'Last saved on:': 'Zuletzt gespeichert am:',
|
||||
'Layout': 'Layout',
|
||||
'License for': 'Lizenz für',
|
||||
'Login': 'Anmelden',
|
||||
'Login to the Administrative Interface': 'An das Administrations-Interface anmelden',
|
||||
'Logout': 'abmelden',
|
||||
'Lost Password': 'Passwort vergessen',
|
||||
'Main Menu': 'Menú principal',
|
||||
'Match Pair': 'Paare finden',
|
||||
'Menu Model': 'Menü Modell',
|
||||
'Merge Lines': 'Zeilen zusammenfügen',
|
||||
'Models': 'Modelle',
|
||||
'Modules': 'Module',
|
||||
'NO': 'NEIN',
|
||||
'Name': 'Name',
|
||||
'New Record': 'Neuer Datensatz',
|
||||
'New application wizard': 'New application wizard',
|
||||
'New simple application': 'New simple application',
|
||||
'Next Edit Point': 'nächster Bearbeitungsschritt',
|
||||
'No databases in this application': 'Keine Datenbank in dieser Anwendung',
|
||||
'Origin': 'Herkunft',
|
||||
'Original/Translation': 'Original/Übersetzung',
|
||||
'Overwrite installed app': 'installierte Anwendungen überschreiben',
|
||||
'Pack all': 'verpacke alles',
|
||||
'Pack compiled': 'Verpacke kompiliert',
|
||||
'Password': 'Passwort',
|
||||
'Peeking at file': 'Dateiansicht',
|
||||
'Plugin "%s" in application': 'Plugin "%s" in Anwendung',
|
||||
'Plugins': 'Plugins',
|
||||
'Powered by': 'Unterstützt von',
|
||||
'Previous Edit Point': 'vorheriger Bearbeitungsschritt',
|
||||
'Query:': 'Abfrage:',
|
||||
'Record ID': 'Datensatz ID',
|
||||
'Register': 'registrieren',
|
||||
'Registration key': 'Registrierungsschlüssel',
|
||||
'Remove compiled': 'kompilat gelöscht',
|
||||
'Reset Password key': 'Passwortschlüssel zurücksetzen',
|
||||
'Resolve Conflict file': 'bereinige Konflikt-Datei',
|
||||
'Role': 'Rolle',
|
||||
'Rows in table': 'Zeilen in Tabelle',
|
||||
'Rows selected': 'Zeilen ausgewählt',
|
||||
'Save via Ajax': 'via Ajax sichern',
|
||||
'Saved file hash:': 'Gespeicherter Datei-Hash:',
|
||||
'Site': 'Seite',
|
||||
'Start wizard': 'start wizard',
|
||||
'Static files': 'statische Dateien',
|
||||
'Stylesheet': 'Stylesheet',
|
||||
'Sure you want to delete this object?': 'Wollen Sie das Objekt wirklich löschen?',
|
||||
'TM': 'TM',
|
||||
'Table name': 'Tabellen Name',
|
||||
'Testing application': 'Teste die Anwendung',
|
||||
'Testing controller': 'teste Controller',
|
||||
'The "query" is a condition like "db.table1.field1==\'value\'". Something like "db.table1.field1==db.table2.field2" results in a SQL JOIN.': 'Die "query" ist eine Bedingung wie "db.table1.field1 == \'Wert\'". Etwas wie "db.table1.field1 db.table2.field2 ==" führt zu einem SQL JOIN.',
|
||||
'The application logic, each URL path is mapped in one exposed function in the controller': 'The application logic, each URL path is mapped in one exposed function in the controller',
|
||||
'The data representation, define database tables and sets': 'The data representation, define database tables and sets',
|
||||
'The output of the file is a dictionary that was rendered by the view': 'The output of the file is a dictionary that was rendered by the view',
|
||||
'The presentations layer, views are also known as templates': 'The presentations layer, views are also known as templates',
|
||||
'There are no controllers': 'Keine Controller vorhanden',
|
||||
'There are no models': 'Keine Modelle vorhanden',
|
||||
'There are no modules': 'Keine Module vorhanden',
|
||||
'There are no plugins': 'There are no plugins',
|
||||
'There are no static files': 'Keine statischen Dateien vorhanden',
|
||||
'There are no translators, only default language is supported': 'Keine Übersetzungen vorhanden, nur die voreingestellte Sprache wird unterstützt',
|
||||
'There are no views': 'Keine Views vorhanden',
|
||||
'These files are served without processing, your images go here': 'These files are served without processing, your images go here',
|
||||
'This is a copy of the scaffolding application': 'Dies ist eine Kopie einer Grundgerüst-Anwendung',
|
||||
'This is the %(filename)s template': 'Dies ist das Template %(filename)s',
|
||||
'Ticket': 'Ticket',
|
||||
'Timestamp': 'Timestamp',
|
||||
'To create a plugin, name a file/folder plugin_[name]': 'Um ein Plugin zu erstellen benennen Sie eine(n) Datei/Ordner plugin_[Name]',
|
||||
'Translation strings for the application': 'Translation strings for the application',
|
||||
'Unable to check for upgrades': 'überprüfen von Upgrades nicht möglich',
|
||||
'Unable to download': 'herunterladen nicht möglich',
|
||||
'Unable to download app': 'herunterladen der Anwendung nicht möglich',
|
||||
'Uninstall': 'deinstallieren',
|
||||
'Update:': 'Aktualisiere:',
|
||||
'Upload & install packed application': 'Verpackte Anwendung hochladen und installieren',
|
||||
'Upload a package:': 'Upload a package:',
|
||||
'Upload existing application': 'lade existierende Anwendung hoch',
|
||||
'Use (...)&(...) for AND, (...)|(...) for OR, and ~(...) for NOT to build more complex queries.': 'Benutze (...)&(...) für AND, (...)|(...) für OR, und ~(...) für NOT, um komplexe Abfragen zu erstellen.',
|
||||
'Use an url:': 'Use an url:',
|
||||
'User ID': 'Benutzer ID',
|
||||
'Version': 'Version',
|
||||
'View': 'View',
|
||||
'Views': 'Views',
|
||||
'Welcome %s': 'Willkommen %s',
|
||||
'Welcome to web2py': 'Willkommen zu web2py',
|
||||
'Which called the function': 'Which called the function',
|
||||
'Wrap with Abbreviation': 'mit Kürzel einhüllen',
|
||||
'YES': 'JA',
|
||||
'You are successfully running web2py': 'web2by wird erfolgreich ausgeführt',
|
||||
'You can modify this application and adapt it to your needs': 'Sie können diese Anwendung verändern und Ihren Bedürfnissen anpassen',
|
||||
'You visited the url': 'Sie besuchten die URL',
|
||||
'additional code for your application': 'zusätzlicher Code für Ihre Anwendung',
|
||||
'admin disabled because no admin password': ' admin ist deaktiviert, weil kein Admin-Passwort gesetzt ist',
|
||||
'admin disabled because not supported on google apps engine': 'admin ist deaktiviert, es existiert dafür keine Unterstützung auf der google apps engine',
|
||||
'admin disabled because unable to access password file': 'admin ist deaktiviert, weil kein Zugriff auf die Passwortdatei besteht',
|
||||
'Admin is disabled because insecure channel': 'Appadmin ist deaktiviert, wegen der Benutzung eines unsicheren Kanals',
|
||||
'Admin is disabled because unsecure channel': 'Appadmin ist deaktiviert, wegen der Benutzung eines unsicheren Kanals',
|
||||
'Admin language': 'Admin language',
|
||||
'administrative interface': 'administrative interface',
|
||||
'Administrator Password:': 'Administrator Passwort:',
|
||||
'and rename it (required):': 'und benenne sie um (erforderlich):',
|
||||
'and rename it:': ' und benenne sie um:',
|
||||
'appadmin': 'appadmin',
|
||||
@@ -202,49 +32,108 @@
|
||||
'application "%s" uninstalled': 'Anwendung "%s" deinstalliert',
|
||||
'application compiled': 'Anwendung kompiliert',
|
||||
'application is compiled and cannot be designed': 'Die Anwendung ist kompiliert kann deswegen nicht mehr geändert werden',
|
||||
'Application name:': 'Application name:',
|
||||
'Are you sure you want to delete file "%s"?': 'Sind Sie sich sicher, dass Sie diese Datei löschen wollen "%s"?',
|
||||
'Are you sure you want to delete this object?': 'Are you sure you want to delete this object?',
|
||||
'Are you sure you want to uninstall application "%s"': 'Sind Sie sich sicher, dass Sie diese Anwendung deinstallieren wollen "%s"',
|
||||
'Are you sure you want to uninstall application "%s"?': 'Sind Sie sich sicher, dass Sie diese Anwendung deinstallieren wollen "%s"?',
|
||||
'Are you sure you want to upgrade web2py now?': 'Sind Sie sich sicher, dass Sie web2py jetzt upgraden möchten?',
|
||||
'arguments': 'arguments',
|
||||
'ATTENTION: Login requires a secure (HTTPS) connection or running on localhost.': 'ACHTUNG: Die Einwahl benötigt eine sichere (HTTPS) Verbindung. Es sei denn sie läuft Lokal(localhost).',
|
||||
'ATTENTION: TESTING IS NOT THREAD SAFE SO DO NOT PERFORM MULTIPLE TESTS CONCURRENTLY.': 'ACHTUNG: Testen ist nicht threadsicher. Führen sie also nicht mehrere Tests gleichzeitig aus.',
|
||||
'ATTENTION: This is an experimental feature and it needs more testing.': 'ACHTUNG: Dies ist eine experimentelle Funktion und benötigt noch weitere Tests.',
|
||||
'ATTENTION: you cannot edit the running application!': 'ACHTUNG: Eine laufende Anwendung kann nicht editiert werden!',
|
||||
'Authentication': 'Authentifizierung',
|
||||
'Available databases and tables': 'Verfügbare Datenbanken und Tabellen',
|
||||
'back': 'zurück',
|
||||
'beautify': 'beautify',
|
||||
'cache': 'Cache',
|
||||
'cache, errors and sessions cleaned': 'Zwischenspeicher (cache), Fehler und Sitzungen (sessions) gelöscht',
|
||||
'call': 'call',
|
||||
'can be a git repo': 'can be a git repo',
|
||||
'Cannot be empty': 'Darf nicht leer sein',
|
||||
'Cannot compile: there are errors in your app. Debug it, correct errors and try again.': 'Nicht Kompilierbar:Es sind Fehler in der Anwendung. Beseitigen Sie die Fehler und versuchen Sie es erneut.',
|
||||
'cannot create file': 'Kann Datei nicht erstellen',
|
||||
'cannot upload file "%(filename)s"': 'Kann Datei nicht Hochladen "%(filename)s"',
|
||||
'Change admin password': 'Administrator-Passwort ändern',
|
||||
'Change Password': 'Passwort ändern',
|
||||
'change password': 'Passwort ändern',
|
||||
'check all': 'alles auswählen',
|
||||
'Check for upgrades': 'check for upgrades',
|
||||
'Check to delete': 'Markiere zum löschen',
|
||||
'Checking for upgrades...': 'Auf Updates überprüfen...',
|
||||
'Clean': 'löschen',
|
||||
'click here for online examples': 'hier klicken für online Beispiele',
|
||||
'click here for the administrative interface': 'hier klicken für die Administrationsoberfläche ',
|
||||
'click to check for upgrades': 'hier klicken um nach Upgrades zu suchen',
|
||||
'Client IP': 'Client IP',
|
||||
'code': 'code',
|
||||
'collapse/expand all': 'collapse/expand all',
|
||||
'Compile': 'kompilieren',
|
||||
'compiled application removed': 'kompilierte Anwendung gelöscht',
|
||||
'Controller': 'Controller',
|
||||
'Controllers': 'Controller',
|
||||
'controllers': 'Controllers',
|
||||
'Copyright': 'Urheberrecht',
|
||||
'Create': 'erstellen',
|
||||
'create file with filename:': 'erzeuge Datei mit Dateinamen:',
|
||||
'create new application:': 'erzeuge neue Anwendung:',
|
||||
'Create new simple application': 'Erzeuge neue Anwendung',
|
||||
'created by': 'created by',
|
||||
'crontab': 'crontab',
|
||||
'Current request': 'Aktuelle Anfrage (request)',
|
||||
'Current response': 'Aktuelle Antwort (response)',
|
||||
'Current session': 'Aktuelle Sitzung (session)',
|
||||
'currently running': 'currently running',
|
||||
'currently saved or': 'des derzeit gespeicherten oder',
|
||||
'customize me!': 'pass mich an!',
|
||||
'data uploaded': 'Daten hochgeladen',
|
||||
'Database': 'Datenbank',
|
||||
'database': 'Datenbank',
|
||||
'database %s select': 'Datenbank %s ausgewählt',
|
||||
'database administration': 'Datenbankadministration',
|
||||
'Date and Time': 'Datum und Uhrzeit',
|
||||
'db': 'db',
|
||||
'DB Model': 'DB Modell',
|
||||
'Debug': 'Debug',
|
||||
'defines tables': 'definiere Tabellen',
|
||||
'Delete': 'Löschen',
|
||||
'delete': 'löschen',
|
||||
'delete all checked': 'lösche alle markierten',
|
||||
'delete plugin': 'Plugin löschen',
|
||||
'Delete:': 'Löschen:',
|
||||
'Deploy': 'deploy',
|
||||
'Deploy on Google App Engine': 'Auf Google App Engine installieren',
|
||||
'Deploy to OpenShift': 'Deploy to OpenShift',
|
||||
'Description': 'Beschreibung',
|
||||
'design': 'design',
|
||||
'DESIGN': 'design',
|
||||
'Design for': 'Design für',
|
||||
'direction: ltr': 'direction: ltr',
|
||||
'Disable': 'Disable',
|
||||
'documentation': 'Dokumentation',
|
||||
'done!': 'fertig!',
|
||||
'download layouts': 'download layouts',
|
||||
'download plugins': 'download plugins',
|
||||
'E-mail': 'E-mail',
|
||||
'EDIT': 'BEARBEITEN',
|
||||
'Edit': 'bearbeiten',
|
||||
'Edit application': 'Bearbeite Anwendung',
|
||||
'edit controller': 'Bearbeite Controller',
|
||||
'Edit current record': 'Bearbeite aktuellen Datensatz',
|
||||
'Edit Profile': 'Bearbeite Profil',
|
||||
'edit profile': 'bearbeite Profil',
|
||||
'Edit This App': 'Bearbeite diese Anwendung',
|
||||
'edit views:': 'Views bearbeiten:',
|
||||
'Editing file': 'Bearbeite Datei',
|
||||
'Editing file "%s"': 'Bearbeite Datei "%s"',
|
||||
'Editing Language file': 'Sprachdatei bearbeiten',
|
||||
'Enterprise Web Framework': 'Enterprise Web Framework',
|
||||
'Error logs for "%(app)s"': 'Fehlerprotokoll für "%(app)s"',
|
||||
'Errors': 'Fehler',
|
||||
'escape': 'escape',
|
||||
'Exception instance attributes': 'Atribute der Ausnahmeinstanz',
|
||||
'Expand Abbreviation': 'Kürzel erweitern',
|
||||
'export as csv file': 'Exportieren als CSV-Datei',
|
||||
'exposes': 'stellt zur Verfügung',
|
||||
'extends': 'erweitert',
|
||||
@@ -259,81 +148,204 @@
|
||||
'file saved on %(time)s': 'Datei gespeichert am %(time)s',
|
||||
'file saved on %s': 'Datei gespeichert auf %s',
|
||||
'filter': 'filter',
|
||||
'First name': 'Vorname',
|
||||
'Functions with no doctests will result in [passed] tests.': 'Funktionen ohne doctests erzeugen [passed] in Tests',
|
||||
'Get from URL:': 'Get from URL:',
|
||||
'Git Pull': 'Git Pull',
|
||||
'Git Push': 'Git Push',
|
||||
'Go to Matching Pair': 'gehe zum übereinstimmenden Paar',
|
||||
'Group ID': 'Gruppen ID',
|
||||
'Hello World': 'Hallo Welt',
|
||||
'Help': 'Hilfe',
|
||||
'htmledit': 'htmledit',
|
||||
'If the report above contains a ticket number it indicates a failure in executing the controller, before any attempt to execute the doctests. This is usually due to an indentation error or an error outside function code.\nA green title indicates that all tests (if defined) passed. In this case test results are not shown.': 'Falls der obere Test eine Fehler-Ticketnummer enthält deutet das auf einen Fehler in der Ausführung des Controllers hin, noch bevor der Doctest ausgeführt werden konnte. Gewöhnlich führen fehlerhafte Einrückungen oder fehlerhafter Code ausserhalb der Funktion zu solchen Fehlern. Ein grüner Titel deutet darauf hin, dass alle Test(wenn sie vorhanden sind) erfolgreich durchlaufen wurden. In diesem Fall werden die Testresultate nicht angezeigt.',
|
||||
'If you answer "yes", be patient, it may take a while to download': '',
|
||||
'If you answer yes, be patient, it may take a while to download': 'If you answer yes, be patient, it may take a while to download',
|
||||
'Import/Export': 'Importieren/Exportieren',
|
||||
'includes': 'Einfügen',
|
||||
'Index': 'Index',
|
||||
'index': 'index',
|
||||
'insert new': 'neu einfügen',
|
||||
'insert new %s': 'neu einfügen %s',
|
||||
'Install': 'installieren',
|
||||
'Installed applications': 'Installierte Anwendungen',
|
||||
'internal error': 'interner Fehler',
|
||||
'Internal State': 'interner Status',
|
||||
'Invalid action': 'Ungültige Aktion',
|
||||
'Invalid email': 'Ungültige Email',
|
||||
'invalid password': 'Ungültiges Passwort',
|
||||
'Invalid Query': 'Ungültige Abfrage',
|
||||
'invalid request': 'ungültige Anfrage',
|
||||
'invalid ticket': 'ungültiges Ticket',
|
||||
'Key bindings': 'Tastenbelegungen',
|
||||
'Key bindings for ZenConding Plugin': 'Tastenbelegungen für das ZenConding Plugin',
|
||||
'language file "%(filename)s" created/updated': 'Sprachdatei "%(filename)s" erstellt/aktualisiert',
|
||||
'Language files (static strings) updated': 'Sprachdatei (statisch Strings) aktualisiert',
|
||||
'languages': 'Sprachen',
|
||||
'Languages': 'Sprachen',
|
||||
'languages updated': 'Sprachen aktualisiert',
|
||||
'Last name': 'Nachname',
|
||||
'Last saved on:': 'Zuletzt gespeichert am:',
|
||||
'Layout': 'Layout',
|
||||
'License for': 'Lizenz für',
|
||||
'loading...': 'lade...',
|
||||
'located in the file': 'located in Datei',
|
||||
'Login': 'Anmelden',
|
||||
'login': 'anmelden',
|
||||
'Login to the Administrative Interface': 'An das Administrations-Interface anmelden',
|
||||
'Logout': 'abmelden',
|
||||
'Lost Password': 'Passwort vergessen',
|
||||
'lost password?': 'Passwort vergessen?',
|
||||
'Main Menu': 'Menú principal',
|
||||
'Match Pair': 'Paare finden',
|
||||
'Menu Model': 'Menü Modell',
|
||||
'merge': 'verbinden',
|
||||
'Merge Lines': 'Zeilen zusammenfügen',
|
||||
'Models': 'Modelle',
|
||||
'models': 'Modelle',
|
||||
'Modules': 'Module',
|
||||
'modules': 'Module',
|
||||
'Name': 'Name',
|
||||
'new application "%s" created': 'neue Anwendung "%s" erzeugt',
|
||||
'New application wizard': 'New application wizard',
|
||||
'New Record': 'Neuer Datensatz',
|
||||
'new record inserted': 'neuer Datensatz eingefügt',
|
||||
'New simple application': 'New simple application',
|
||||
'next 100 rows': 'nächsten 100 Zeilen',
|
||||
'Next Edit Point': 'nächster Bearbeitungsschritt',
|
||||
'NO': 'NEIN',
|
||||
'No databases in this application': 'Keine Datenbank in dieser Anwendung',
|
||||
'or import from csv file': 'oder importieren von cvs Datei',
|
||||
'or provide app url:': 'oder geben Sie eine Anwendungs-URL an:',
|
||||
'or provide application url:': 'oder geben Sie eine Anwendungs-URL an:',
|
||||
'Origin': 'Herkunft',
|
||||
'Original/Translation': 'Original/Übersetzung',
|
||||
'Overwrite installed app': 'installierte Anwendungen überschreiben',
|
||||
'Pack all': 'verpacke alles',
|
||||
'Pack compiled': 'Verpacke kompiliert',
|
||||
'pack plugin': 'Plugin verpacken',
|
||||
'Password': 'Passwort',
|
||||
'Peeking at file': 'Dateiansicht',
|
||||
'please wait!': 'bitte warten!',
|
||||
'Plugin "%s" in application': 'Plugin "%s" in Anwendung',
|
||||
'plugins': 'plugins',
|
||||
'Plugins': 'Plugins',
|
||||
'Powered by': 'Unterstützt von',
|
||||
'previous 100 rows': 'vorherige 100 zeilen',
|
||||
'Previous Edit Point': 'vorheriger Bearbeitungsschritt',
|
||||
'Query:': 'Abfrage:',
|
||||
'record': 'Datensatz',
|
||||
'record does not exist': 'Datensatz existiert nicht',
|
||||
'record id': 'Datensatz id',
|
||||
'Record ID': 'Datensatz ID',
|
||||
'register': 'Registrierung',
|
||||
'Register': 'registrieren',
|
||||
'Registration key': 'Registrierungsschlüssel',
|
||||
'Reload routes': 'Reload routes',
|
||||
'Remove compiled': 'kompilat gelöscht',
|
||||
'Reset Password key': 'Passwortschlüssel zurücksetzen',
|
||||
'Resolve Conflict file': 'bereinige Konflikt-Datei',
|
||||
'restore': 'wiederherstellen',
|
||||
'revert': 'zurückkehren',
|
||||
'Role': 'Rolle',
|
||||
'Rows in table': 'Zeilen in Tabelle',
|
||||
'Rows selected': 'Zeilen ausgewählt',
|
||||
'Running on %s': 'Running on %s',
|
||||
'save': 'sichern',
|
||||
'Save via Ajax': 'via Ajax sichern',
|
||||
'Saved file hash:': 'Gespeicherter Datei-Hash:',
|
||||
'selected': 'ausgewählt(e)',
|
||||
'session expired': 'Sitzung Abgelaufen',
|
||||
'shell': 'shell',
|
||||
'Site': 'Seite',
|
||||
'some files could not be removed': 'einige Dateien konnten nicht gelöscht werden',
|
||||
'Start wizard': 'start wizard',
|
||||
'state': 'Status',
|
||||
'static': 'statische Dateien',
|
||||
'Static files': 'statische Dateien',
|
||||
'Stylesheet': 'Stylesheet',
|
||||
'Submit': 'Submit',
|
||||
'submit': 'Absenden',
|
||||
'Sure you want to delete this object?': 'Wollen Sie das Objekt wirklich löschen?',
|
||||
'table': 'Tabelle',
|
||||
'Table name': 'Tabellen Name',
|
||||
'test': 'Test',
|
||||
'test_def': 'test_def',
|
||||
'test_for': 'test_for',
|
||||
'test_if': 'test_if',
|
||||
'test_try': 'test_try',
|
||||
'Testing application': 'Teste die Anwendung',
|
||||
'Testing controller': 'teste Controller',
|
||||
'The "query" is a condition like "db.table1.field1==\'value\'". Something like "db.table1.field1==db.table2.field2" results in a SQL JOIN.': 'Die "query" ist eine Bedingung wie "db.table1.field1 == \'Wert\'". Etwas wie "db.table1.field1 db.table2.field2 ==" führt zu einem SQL JOIN.',
|
||||
'the application logic, each URL path is mapped in one exposed function in the controller': 'Die Logik der Anwendung, jeder URL-Pfad wird auf eine Funktion abgebildet die der Controller zur Verfügung stellt',
|
||||
'The application logic, each URL path is mapped in one exposed function in the controller': 'The application logic, each URL path is mapped in one exposed function in the controller',
|
||||
'the data representation, define database tables and sets': 'Die Datenrepräsentation definiert Mengen von Tabellen und Datenbanken ',
|
||||
'The data representation, define database tables and sets': 'The data representation, define database tables and sets',
|
||||
'The output of the file is a dictionary that was rendered by the view': 'The output of the file is a dictionary that was rendered by the view',
|
||||
'The presentations layer, views are also known as templates': 'The presentations layer, views are also known as templates',
|
||||
'the presentations layer, views are also known as templates': 'Die Präsentationsschicht, Views sind auch bekannt als Vorlagen/Templates',
|
||||
'There are no controllers': 'Keine Controller vorhanden',
|
||||
'There are no models': 'Keine Modelle vorhanden',
|
||||
'There are no modules': 'Keine Module vorhanden',
|
||||
'There are no plugins': 'There are no plugins',
|
||||
'There are no static files': 'Keine statischen Dateien vorhanden',
|
||||
'There are no translators, only default language is supported': 'Keine Übersetzungen vorhanden, nur die voreingestellte Sprache wird unterstützt',
|
||||
'There are no views': 'Keine Views vorhanden',
|
||||
'These files are served without processing, your images go here': 'These files are served without processing, your images go here',
|
||||
'these files are served without processing, your images go here': 'Diese Dateien werden ohne Verarbeitung ausgeliefert. Beispielsweise Bilder kommen hier hin.',
|
||||
'This is a copy of the scaffolding application': 'Dies ist eine Kopie einer Grundgerüst-Anwendung',
|
||||
'This is the %(filename)s template': 'Dies ist das Template %(filename)s',
|
||||
'Ticket': 'Ticket',
|
||||
'Timestamp': 'Timestamp',
|
||||
'TM': 'TM',
|
||||
'to previous version.': 'zu einer früheren Version.',
|
||||
'To create a plugin, name a file/folder plugin_[name]': 'Um ein Plugin zu erstellen benennen Sie eine(n) Datei/Ordner plugin_[Name]',
|
||||
'translation strings for the application': 'Übersetzungs-Strings für die Anwendung',
|
||||
'Translation strings for the application': 'Translation strings for the application',
|
||||
'try': 'versuche',
|
||||
'try something like': 'versuche so etwas wie',
|
||||
'Unable to check for upgrades': 'überprüfen von Upgrades nicht möglich',
|
||||
'unable to create application "%s"': 'erzeugen von Anwendung "%s" nicht möglich',
|
||||
'unable to delete file "%(filename)s"': 'löschen von Datein "%(filename)s" nicht möglich',
|
||||
'Unable to download': 'herunterladen nicht möglich',
|
||||
'Unable to download app': 'herunterladen der Anwendung nicht möglich',
|
||||
'unable to parse csv file': 'analysieren der cvs Datei nicht möglich',
|
||||
'unable to uninstall "%s"': 'deinstallieren von "%s" nicht möglich',
|
||||
'uncheck all': 'alles demarkieren',
|
||||
'Uninstall': 'deinstallieren',
|
||||
'update': 'aktualisieren',
|
||||
'update all languages': 'aktualisiere alle Sprachen',
|
||||
'Update:': 'Aktualisiere:',
|
||||
'upgrade web2py now': 'jetzt web2py upgraden',
|
||||
'upload': 'upload',
|
||||
'Upload & install packed application': 'Verpackte Anwendung hochladen und installieren',
|
||||
'Upload a package:': 'Upload a package:',
|
||||
'Upload and install packed application': 'Upload and install packed application',
|
||||
'upload application:': 'lade Anwendung hoch:',
|
||||
'Upload existing application': 'lade existierende Anwendung hoch',
|
||||
'upload file:': 'lade Datei hoch:',
|
||||
'upload plugin file:': 'Plugin-Datei hochladen:',
|
||||
'Use (...)&(...) for AND, (...)|(...) for OR, and ~(...) for NOT to build more complex queries.': 'Benutze (...)&(...) für AND, (...)|(...) für OR, und ~(...) für NOT, um komplexe Abfragen zu erstellen.',
|
||||
'Use an url:': 'Use an url:',
|
||||
'user': 'user',
|
||||
'User ID': 'Benutzer ID',
|
||||
'variables': 'variables',
|
||||
'Version': 'Version',
|
||||
'Version %s.%s.%s (%s) %s': 'Version %s.%s.%s (%s) %s',
|
||||
'versioning': 'Versionierung',
|
||||
'View': 'View',
|
||||
'view': 'View',
|
||||
'Views': 'Views',
|
||||
'views': 'Views',
|
||||
'web2py Recent Tweets': 'neuste Tweets von web2py',
|
||||
'web2py is up to date': 'web2py ist auf dem neuesten Stand',
|
||||
'web2py Recent Tweets': 'neuste Tweets von web2py',
|
||||
'Welcome %s': 'Willkommen %s',
|
||||
'Welcome to web2py': 'Willkommen zu web2py',
|
||||
'Which called the function': 'Which called the function',
|
||||
'Wrap with Abbreviation': 'mit Kürzel einhüllen',
|
||||
'xml': 'xml',
|
||||
'YES': 'JA',
|
||||
'You are successfully running web2py': 'web2by wird erfolgreich ausgeführt',
|
||||
'You can modify this application and adapt it to your needs': 'Sie können diese Anwendung verändern und Ihren Bedürfnissen anpassen',
|
||||
'You visited the url': 'Sie besuchten die URL',
|
||||
}
|
||||
|
||||
@@ -11,7 +11,6 @@
|
||||
'(something like "it-it")': '(למשל "it-it")',
|
||||
'@markmin\x01Searching: **%s** %%{file}': 'Searching: **%s** files',
|
||||
'A new version of web2py is available: %s': 'גירסא חדשה של web2py זמינה: %s',
|
||||
'A new version of web2py is available: Version 1.85.3 (2010-09-18 07:07:46)\n': 'A new version of web2py is available: Version 1.85.3 (2010-09-18 07:07:46)\r\n',
|
||||
'ATTENTION: Login requires a secure (HTTPS) connection or running on localhost.': 'לתשומת ליבך: ניתן להתחבר רק בערוץ מאובטח (HTTPS) או מlocalhost',
|
||||
'ATTENTION: TESTING IS NOT THREAD SAFE SO DO NOT PERFORM MULTIPLE TESTS CONCURRENTLY.': 'לתשומת ליבך: אין לערוך מספר בדיקות במקביל, שכן הן עשויות להפריע זו לזו',
|
||||
'ATTENTION: you cannot edit the running application!': 'לתשומת ליבך: לא ניתן לערוך אפליקציה בזמן הרצתה',
|
||||
|
||||
@@ -12,7 +12,6 @@
|
||||
'@markmin\x01Searching: **%s** %%{file}': 'Найдено: **%s** %%{файл}',
|
||||
'A new version of web2py is available': 'Доступна новая версия web2py',
|
||||
'A new version of web2py is available: %s': 'Доступна новая версия web2py: %s',
|
||||
'A new version of web2py is available: Version 1.85.3 (2010-09-18 07:07:46)\n': 'Доступна новая версия web2py: Версия 1.85.3 (2010-09-18 07:07:46)\n',
|
||||
'Abort': 'Отмена',
|
||||
'About': 'О',
|
||||
'About application': 'О приложении',
|
||||
|
||||
@@ -12,7 +12,6 @@
|
||||
'@markmin\x01Searching: **%s** %%{file}': 'Iskanje: **%s** datoteke',
|
||||
'A new version of web2py is available': 'Nova različica web2py je na voljo',
|
||||
'A new version of web2py is available: %s': 'Nova različica web2py je na voljo: %s',
|
||||
'A new version of web2py is available: Version 1.85.3 (2010-09-18 07:07:46)\n': 'Nova različica web2py je na voljo: Različica 1.85.3 (2010-09-18 07:07:46)\n',
|
||||
'ATTENTION: Login requires a secure (HTTPS) connection or running on localhost.': 'POZOR: Prijava zahteva varno povezavo (HTTPS) ali lokalni (localhost) dostop.',
|
||||
'ATTENTION: TESTING IS NOT THREAD SAFE SO DO NOT PERFORM MULTIPLE TESTS CONCURRENTLY.': 'POZOR: Testiranje ni večopravilno, zato ne poganjajte več testov hkrati.',
|
||||
'ATTENTION: This is an experimental feature and it needs more testing.': 'POZOR: To je preizkusni fazi in potrebuje več testiranja.',
|
||||
|
||||
@@ -65,6 +65,7 @@
|
||||
'cache': 'кеш',
|
||||
'Cache Keys': 'Ключі кешу',
|
||||
'cache, errors and sessions cleaned': 'кеш, список зареєстрованих помилок та сесії очищенні',
|
||||
'can be a git repo': 'може бути git-репозитарієм',
|
||||
'Cancel': 'Відмінити',
|
||||
'Cannot be empty': 'Не може бути порожнім',
|
||||
'Cannot compile: there are errors in your app:': 'Не вдається скомпілювати: є помилки у вашому додатку:',
|
||||
@@ -85,6 +86,7 @@
|
||||
'Code listing': 'Лістинг',
|
||||
'collapse/expand all': 'згорнути/розгорнути все',
|
||||
'Command': 'Команда',
|
||||
'Commit': 'Комміт',
|
||||
'Compile': 'Компілювати',
|
||||
'compiled application removed': 'скомпільований додаток вилучено',
|
||||
'Condition': 'Умова',
|
||||
@@ -187,6 +189,8 @@
|
||||
'GAE Password': 'Пароль GAE',
|
||||
'Generate': 'Генерувати',
|
||||
'Get from URL:': 'Отримати з URL:',
|
||||
'Git Pull': 'Git Pull',
|
||||
'Git Push': 'Git Push',
|
||||
'Globals##debug': 'Глобальні змінні',
|
||||
'Go to Matching Pair': 'Перейти до відповідної пари',
|
||||
'go!': 'почали!',
|
||||
@@ -200,7 +204,7 @@
|
||||
'honored only if the expression evaluates to true': 'точка зупинки активується тільки за істинності умови',
|
||||
'If start the downgrade, be patient, it may take a while to rollback': 'Запустивши повернення на попередню версію, будьте терплячими, це може зайняти трохи часу',
|
||||
'If start the upgrade, be patient, it may take a while to download': 'Запустивши оновлення, будьте терплячими, потрібен час для завантаження необхідних даних',
|
||||
'If the report above contains a ticket number it indicates a failure in executing the controller, before any attempt to execute the doctests. This is usually due to an indentation error or an error outside function code.\nA green title indicates that all tests (if defined) passed. In this case test results are not shown.': 'Якщо в наданому вище звіті присутня позначка про помилку (ticket number), то це вказує на збій у виконанні контролера ще до початку запуску док-тестів. Це, зазвичай, сигналізує про помилку вирівнювання тексту програми (indention error) або помилку за межами функції (error outside function code).\r\nЗелений заголовок сигналізує, що всі тести (з наявних) пройшли успішно. В цьому випадку результат тестів показано не буде.',
|
||||
'If the report above contains a ticket number it indicates a failure in executing the controller, before any attempt to execute the doctests. This is usually due to an indentation error or an error outside function code.\nA green title indicates that all tests (if defined) passed. In this case test results are not shown.': 'Якщо в наданому вище звіті присутня позначка про помилку (ticket number), то це вказує на збій у виконанні контролера ще до початку запуску док-тестів. Це, зазвичай, сигналізує про помилку вирівнювання тексту програми (indention error) або помилку за межами функції (error outside function code). Зелений заголовок сигналізує, що всі тести (з наявних) пройшли успішно. В цьому випадку результат тестів показано не буде.',
|
||||
'Import/Export': 'Імпорт/Експорт',
|
||||
'In development, use the default Rocket webserver that is currently supported by this debugger.': 'Під час розробки , використовуйте вбудований веб-сервер Rocket, він найкраще налаштований на спільну роботу з інтерактивним ладначем.',
|
||||
'includes': 'включає',
|
||||
@@ -306,7 +310,11 @@
|
||||
'Powered by': 'Працює на',
|
||||
'previous 100 rows': 'попередні 100 рядків',
|
||||
'Previous Edit Point': 'Попереднє місце редагування',
|
||||
'Private files': 'Приватні файли',
|
||||
'private files': 'приватні файли',
|
||||
'Project Progress': 'Поступ проекту',
|
||||
'Pull': 'Втягнути',
|
||||
'Push': 'Проштовхнути',
|
||||
'Query:': 'Запит:',
|
||||
'RAM Cache Keys': 'Ключ ОЗП-кешу (RAM Cache)',
|
||||
'Ram Cleared': "Кеш в пам'яті очищено",
|
||||
@@ -383,6 +391,7 @@
|
||||
'There are no translators': 'Перекладів нема',
|
||||
'There are no translators, only default language is supported': 'Перекладів нема, підтримується тільки мова оригіналу',
|
||||
'There are no views': 'Відображень нема',
|
||||
'These files are not served, they are only available from within your app': 'Ці файли ніяк не обробляються, вони доступні тільки в межах вашого додатку',
|
||||
'These files are served without processing, your images go here': 'Ці файли обслуговуються "як є", без обробки, ваші графічні файли та інші супутні файли даних можуть знаходитись тут',
|
||||
"This debugger may not work properly if you don't have a threaded webserver or you're using multiple daemon processes.": 'Цей ладнач може працювати некоректно, якщо ви використовуєте веб-сервер без підтримки потоків або використовуєте декілька сервісних процесів.',
|
||||
'This is an experimental feature and it needs more testing. If you decide to downgrade you do it at your own risk': 'Це експериментальна властивість, яка вимагає подальшого тестування. Якщо ви вирішили повернутись на попередню версію, ви це робити на ваш власний розсуд.',
|
||||
@@ -391,6 +400,8 @@
|
||||
"This page can commit your changes to an openshift app repo and push them to your cloud instance. This assumes that you've already created the application instance using the web2py skeleton and have that repo somewhere on a filesystem that this web2py instance can access. This functionality requires GitPython installed and on the python path of the runtime that web2py is operating in.": 'На цій сторінці можна закомітити ваші зміни в репозитарій додатків openshift та проштовхнути їх у ваш примірник в хмарі. Це передбачає, що ви вже створили примірник додатку, використовуючи базовий додаток web2py, як скелет, і маєте репозитарій десь на вашій файловій системі, причому екземпляр web2py має до нього доступ. Ця властивість вимагає наявності встановленого модулю GitPython так, щоб web2py міг його викликати.',
|
||||
'This page can upload your application to the Google App Engine computing cloud. Mind that you must first create indexes locally and this is done by installing the Google appserver and running the app locally with it once, or there will be errors when selecting records. Attention: deployment may take long time, depending on the network speed. Attention: it will overwrite your app.yaml. DO NOT SUBMIT TWICE.': 'На цій сторінці ви можете завантажити свій додаток в сервіс хмарних обчислень Google App Engine. Майте на увазі, що спочатку необхідно локально створити індекси, і це можна зробити встановивши сервер додатків Google appserver та запустивши в ньому додаток один раз, інакше при виборі записів виникатимуть помилки. Увага: розгортання може зайняти тривалий час, в залежності від швидкості мережі. Увага: це призведе до перезапису app.yaml. НЕ ПУБЛІКУЙТЕ ДВІЧІ.',
|
||||
'this page to see if a breakpoint was hit and debug interaction is required.': 'цю сторінку, щоб побачити, чи була досягнута точка зупинки і процес ладнання розпочато.',
|
||||
'This will pull changes from the remote repo for application "%s"?': '"Втягнути" (pull) зміни з віддаленого репозитарію для додатку "%s"?',
|
||||
'This will push changes to the remote repo for application "%s".': 'Проштовхнути (push) зміни у віддалений репозитарій для додатку "%s"?',
|
||||
'ticket': 'позначка',
|
||||
'Ticket': 'Позначка (Ticket)',
|
||||
'Ticket ID': 'Ід.позначки (Ticket ID)',
|
||||
|
||||
@@ -33,6 +33,6 @@ def helpicon():
|
||||
return IMG(_src=URL('static', 'images/help.png'), _alt='help')
|
||||
|
||||
def searchbox(elementid):
|
||||
return TAG[''](LABEL(IMG(_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))
|
||||
|
||||
|
||||
|
||||
@@ -1,190 +1,181 @@
|
||||
/** these MUST stay **/
|
||||
body { margin: 0; padding:0; border: 0; }
|
||||
a { text-decoration:none; white-space: nowrap;}
|
||||
a:hover {text-decoration: underline}
|
||||
a.button {text-decoration: none}
|
||||
h1,h2,h3,h4,h5,h6 {margin: 0.5em 0 0.25em 0; display: block; font-family: Helvetica;}
|
||||
h1 { font-size: 4.00em;}
|
||||
h2 { font-size: 3.00em;}
|
||||
h3 { font-size: 2.00em;}
|
||||
h4 { font-size: 1.50em;}
|
||||
h5 { font-size: 1.25em;}
|
||||
h6 { font-size: 1.12em;}
|
||||
right { float:right; text-align: right; }
|
||||
left { float:left; text-align: left; }
|
||||
center { width:100; text-align: center; vertical-align:middle;}
|
||||
th, label { font-weight: bold; white-space: nowrap; }
|
||||
td, th { text-align: left; padding: 2px 5px 2px 5px; }
|
||||
th { vertical-align: middle; border-right: 1px solid white;}
|
||||
td { vertical-align: top; }
|
||||
form table tr td label { text-align: left; }
|
||||
p, table, ol, ul { padding: 0.5em 0 0.5em 0 }
|
||||
p {text-align: justify }
|
||||
ol, ul { padding-left: 30px }
|
||||
li { margin-bottom: 0.5em; }
|
||||
span, input, select, textarea, button, label, a { display: inline }
|
||||
img { border: 0; }
|
||||
blockquote, blockquote p, p blockquote { font-style: italic; margin: 0.5em 30px 0.5em 30px; font-size: 0.9em}
|
||||
i, em { font-style: italic; }
|
||||
strong { font-weight: bold; }
|
||||
small { font-size: 0.8em; }
|
||||
textarea { width: 100%; }
|
||||
code { font-family: Courier;}
|
||||
video { width:400px; }
|
||||
audio { width:200px; }
|
||||
input[type=text], input[type=password], select { width: 300px; margin-right: 5px }
|
||||
ul { list-style-type: none; margin: 0px; padding: 0px; }
|
||||
a {text-decoration:none; white-space:nowrap}
|
||||
a:hover {text-decoration:underline}
|
||||
a.button {text-decoration:none}
|
||||
h1,h2,h3,h4,h5,h6 {margin:0.5em 0 0.25em 0; display:block;
|
||||
font-family:Helvetica}
|
||||
h1 {font-size:4.00em}
|
||||
h2 {font-size:3.00em}
|
||||
h3 {font-size:2.00em}
|
||||
h4 {font-size:1.50em}
|
||||
h5 {font-size:1.25em}
|
||||
h6 {font-size:1.12em}
|
||||
th,label {font-weight:bold; white-space:nowrap}
|
||||
td,th {text-align:left; padding:2px 5px 2px 5px}
|
||||
th {vertical-align:middle; border-right:1px solid white}
|
||||
td {vertical-align:top}
|
||||
form table tr td label {text-align:left}
|
||||
p,table,ol,ul {padding:0; margin: 0.5em 0}
|
||||
p {text-align:justify}
|
||||
ol, ul {list-style-position:inside}
|
||||
li {margin-bottom:0.5em}
|
||||
span,input,select,textarea,button,label,a {display:inline}
|
||||
img {border:0}
|
||||
blockquote,blockquote p,p blockquote {
|
||||
font-style:italic; margin:0.5em 30px 0.5em 30px; font-size:0.9em}
|
||||
i,em {font-style:italic}
|
||||
strong {font-weight:bold}
|
||||
small {font-size:0.8em}
|
||||
code {font-family:Courier}
|
||||
textarea {width:100%}
|
||||
video {width:400px}
|
||||
audio {width:200px}
|
||||
input[type=text],input[type=password],select{width:300px; margin-right:5px}
|
||||
.hidden {display:none;visibility:visible}
|
||||
.right {float:right; text-align:right}
|
||||
.left {float:left; text-align:left}
|
||||
.center {width:100; text-align:center; vertical-align:middle}
|
||||
/** end **/
|
||||
|
||||
/* Sticky footer begin */
|
||||
html, body {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.wrapper {
|
||||
min-height: 100%;
|
||||
height: auto !important;
|
||||
height: 100%;
|
||||
margin: 0 auto -8em; /* set last value to footer height plus footer vertical padding */
|
||||
min-height:100%;
|
||||
height:auto !important;
|
||||
height:100%;
|
||||
margin:0 auto -8em; /* set last value to footer height plus footer vertical padding */
|
||||
}
|
||||
|
||||
.main {
|
||||
padding: 20px 0 50px 0;
|
||||
padding:20px 0 50px 0;
|
||||
}
|
||||
|
||||
.footer, .push {
|
||||
height: 6em;
|
||||
padding: 1em 0;
|
||||
clear: both;
|
||||
.footer,.push {
|
||||
height:6em;
|
||||
padding:1em 0;
|
||||
clear:both;
|
||||
}
|
||||
|
||||
.footer-content {position: relative; bottom: -4em; width: 100%;}
|
||||
.footer-content {position:relative; bottom:-4em; width:100%}
|
||||
|
||||
.auth_navbar {
|
||||
white-space: nowrap;
|
||||
white-space:nowrap;
|
||||
}
|
||||
|
||||
/* Sticky footer end */
|
||||
|
||||
.footer {
|
||||
border-top: 1px #DEDEDE solid;
|
||||
border-top:1px #DEDEDE solid;
|
||||
}
|
||||
.header {
|
||||
// background: <fill here for header image>;
|
||||
// background:<fill here for header image>;
|
||||
}
|
||||
|
||||
|
||||
fieldset { padding: 16px; border-top: 1px #DEDEDE solid;}
|
||||
fieldset legend {text-transform:uppercase; font-weight: bold; padding: 4px 16px 4px 16px; background: #f1f1f1;}
|
||||
fieldset {padding:16px; border-top:1px #DEDEDE solid}
|
||||
fieldset legend {text-transform:uppercase; font-weight:bold; padding:4px 16px 4px 16px; background:#f1f1f1}
|
||||
|
||||
/* fix ie problem with menu */
|
||||
.ie-lte7 .topbar .container {z-index: 2; }
|
||||
.ie-lte7 .topbar .container {z-index:2}
|
||||
|
||||
td.w2p_fw {padding-bottom: 1px;}
|
||||
td.w2p_fl, td.w2p_fw, td.w2p_fc { vertical-align:top; }
|
||||
td.w2p_fl { text-align:right; }
|
||||
td.w2p_fl, td.w2p_fw {padding-right: 7px;}
|
||||
td.w2p_fl, td.w2p_fc { padding-top: 4px; }
|
||||
td.w2p_fw {padding-bottom:1px}
|
||||
td.w2p_fl,td.w2p_fw,td.w2p_fc {vertical-align:top}
|
||||
td.w2p_fl {text-align:right}
|
||||
td.w2p_fl, td.w2p_fw {padding-right:7px}
|
||||
td.w2p_fl,td.w2p_fc {padding-top:4px}
|
||||
|
||||
/* tr#submit_record__row {border-top: 1px solid #E5E5E5;} */
|
||||
#submit_record__row td {padding-top: .5em;}
|
||||
/* tr#submit_record__row {border-top:1px solid #E5E5E5} */
|
||||
#submit_record__row td {padding-top:.5em}
|
||||
|
||||
/* Fix */
|
||||
#auth_user_remember__row label {display: inline;}
|
||||
#web2py_user_form td { vertical-align:top; }
|
||||
#auth_user_remember__row label {display:inline}
|
||||
#web2py_user_form td {vertical-align:top}
|
||||
|
||||
/*********** web2py specific ***********/
|
||||
div.flash {
|
||||
font-weight: bold;
|
||||
display: none;
|
||||
position: fixed;
|
||||
padding: 10px;
|
||||
top: 48px;
|
||||
right: 50px;
|
||||
min-width: 280px;
|
||||
opacity: 0.85;
|
||||
margin: 0px 0px 10px 10px;
|
||||
color: #fff;
|
||||
vertical-align: middle;
|
||||
cursor: pointer;
|
||||
background: #000;
|
||||
border: 2px solid #fff;
|
||||
border-radius: 5px;
|
||||
-moz-border-radius: 5px;
|
||||
-webkit-border-radius: 5px;
|
||||
z-index: 2;
|
||||
font-weight:bold;
|
||||
display:none;
|
||||
position:fixed;
|
||||
padding:10px;
|
||||
top:48px;
|
||||
right:50px;
|
||||
min-width:280px;
|
||||
opacity:0.85;
|
||||
margin:0px 0px 10px 10px;
|
||||
color:#fff;
|
||||
vertical-align:middle;
|
||||
cursor:pointer;
|
||||
background:#000;
|
||||
border:2px solid #fff;
|
||||
border-radius:5px;
|
||||
-moz-border-radius:5px;
|
||||
-webkit-border-radius:5px;
|
||||
z-index:2000;
|
||||
}
|
||||
div.flash {z-index:2000;}
|
||||
|
||||
div.error_wrapper { display: block; }
|
||||
div.error_wrapper {display:block}
|
||||
div.error {
|
||||
background-color: red;
|
||||
color: white;
|
||||
padding: 3px;
|
||||
display: inline-block;
|
||||
background-color:red;
|
||||
color:white;
|
||||
padding:3px;
|
||||
display:inline-block;
|
||||
}
|
||||
|
||||
.topbar {
|
||||
padding: 10px 0;
|
||||
padding:10px 0;
|
||||
width:100%;
|
||||
color: #959595;
|
||||
vertical-align: middle;
|
||||
padding: auto;
|
||||
background-image: -khtml-gradient(linear, left top, left bottom, from(#333333), to(#222222));
|
||||
background-image: -moz-linear-gradient(top, #333333, #222222);
|
||||
background-image: -ms-linear-gradient(top, #333333, #222222);
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #333333), color-stop(100%, #222222));
|
||||
background-image: -webkit-linear-gradient(top, #333333, #222222);
|
||||
background-image: -o-linear-gradient(top, #333333, #222222);
|
||||
background-image: linear-gradient(top, #333333, #222222);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#333333', endColorstr='#222222', GradientType=0);
|
||||
-webkit-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.25), inset 0 -1px 0 rgba(0, 0, 0, 0.1);
|
||||
-moz-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.25), inset 0 -1px 0 rgba(0, 0, 0, 0.1);
|
||||
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.25), inset 0 -1px 0 rgba(0, 0, 0, 0.1);
|
||||
color:#959595;
|
||||
vertical-align:middle;
|
||||
padding:auto;
|
||||
background-image:-khtml-gradient(linear,left top,left bottom,from(#333333),to(#222222));
|
||||
background-image:-moz-linear-gradient(top,#333333,#222222);
|
||||
background-image:-ms-linear-gradient(top,#333333,#222222);
|
||||
background-image:-webkit-gradient(linear,left top,left bottom,color-stop(0%,#333333),color-stop(100%,#222222));
|
||||
background-image:-webkit-linear-gradient(top,#333333,#222222);
|
||||
background-image:-o-linear-gradient(top,#333333,#222222);
|
||||
background-image:linear-gradient(top,#333333,#222222);
|
||||
filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#333333',endColorstr='#222222',GradientType=0);
|
||||
-webkit-box-shadow:0 1px 3px rgba(0,0,0,0.25),inset 0 -1px 0 rgba(0,0,0,0.1);
|
||||
-moz-box-shadow:0 1px 3px rgba(0,0,0,0.25),inset 0 -1px 0 rgba(0,0,0,0.1);
|
||||
box-shadow:0 1px 3px rgba(0,0,0,0.25),inset 0 -1px 0 rgba(0,0,0,0.1);
|
||||
}
|
||||
|
||||
.topbar a {
|
||||
color: #e1e1e1;
|
||||
color:#e1e1e1;
|
||||
}
|
||||
|
||||
#navbar {float: right; padding: 5px; /* same as superfish */}
|
||||
|
||||
.right {
|
||||
width:100%;
|
||||
text-align: right;
|
||||
float: right;
|
||||
}
|
||||
#navbar {float:right; padding:5px; /* same as superfish */}
|
||||
|
||||
.statusbar {
|
||||
background-color: #F5F5F5;
|
||||
margin-top: 1em;
|
||||
margin-bottom: 1em;
|
||||
padding: .5em 1em;
|
||||
border: 1px solid #ddd;
|
||||
border-radius: 5px;
|
||||
-moz-border-radius: 5px;
|
||||
-webkit-border-radius: 5px;
|
||||
background-color:#F5F5F5;
|
||||
margin-top:1em;
|
||||
margin-bottom:1em;
|
||||
padding:.5em 1em;
|
||||
border:1px solid #ddd;
|
||||
border-radius:5px;
|
||||
-moz-border-radius:5px;
|
||||
-webkit-border-radius:5px;
|
||||
}
|
||||
|
||||
.breadcrumbs { float: left; }
|
||||
.breadcrumbs {float:left}
|
||||
|
||||
.copyright {float: left;}
|
||||
#poweredBy {float: right;}
|
||||
.copyright {float:left}
|
||||
#poweredBy {float:right}
|
||||
|
||||
/* #MEDIA QUERIES SECTION */
|
||||
|
||||
/* All Mobile Sizes (devices and browser) */
|
||||
@media only screen and (max-width: 767px) {
|
||||
@media only screen and (max-width:767px) {
|
||||
/* removed because of bootswatch
|
||||
.topbar {text-align: center;}
|
||||
#navbar, #menu {float: none;}
|
||||
#navbar {font-size: 1.2em; padding: .6em 0 1.2em;}
|
||||
#menu {padding: 0 0 1.5em;}
|
||||
#menu select {font-size: 1.2em; margin: 0; padding: 0;}
|
||||
.topbar {text-align:center}
|
||||
#navbar,#menu {float:none}
|
||||
#navbar {font-size:1.2em; padding:.6em 0 1.2em}
|
||||
#menu {padding:0 0 1.5em}
|
||||
#menu select {font-size:1.2em; margin:0; padding:0}
|
||||
|
||||
div.flash {top: 110px; right: 10px;}
|
||||
div.flash {top:110px; right:10px}
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
*Grid
|
||||
@@ -193,43 +184,47 @@ div.error {
|
||||
* will look better with the declarations below
|
||||
* if needed to remove base.css consider keeping these following lines in some css file.
|
||||
*/
|
||||
// .web2py_table { border: 1px solid #ccc; }
|
||||
.web2py_paginator { }
|
||||
.web2py_grid {width: 100% }
|
||||
.web2py_grid table { width: 100% }
|
||||
// .web2py_table {border:1px solid #ccc}
|
||||
.web2py_paginator {}
|
||||
.web2py_grid {width:100%}
|
||||
.web2py_grid table {width:100%}
|
||||
.web2py_grid tbody td {
|
||||
padding: 2px 5px 2px 5px;
|
||||
vertical-align: middle;
|
||||
padding:2px 5px 2px 5px;
|
||||
vertical-align:middle;
|
||||
}
|
||||
|
||||
.web2py_grid thead th, .web2py_grid tfoot td {
|
||||
.web2py_grid thead th,.web2py_grid tfoot td {
|
||||
background-color:#EAEAEA;
|
||||
padding: 10px 5px 10px 5px;
|
||||
padding:10px 5px 10px 5px;
|
||||
}
|
||||
|
||||
.web2py_grid tr.odd {background-color: #F9F9F9;}
|
||||
.web2py_grid tr:hover {background-color: #F5F5F5; }
|
||||
.web2py_grid tr.odd {background-color:#F9F9F9}
|
||||
.web2py_grid tr:hover {background-color:#F5F5F5}
|
||||
|
||||
/*
|
||||
.web2py_breadcrumbs a {
|
||||
line-height: 20px; margin-right: 5px; display: inline-block;
|
||||
padding: 3px 5px 3px 5px;
|
||||
font-family: 'lucida grande', tahoma, verdana, arial, sans-serif;
|
||||
color: #3C3C3D;
|
||||
text-shadow: 1px 1px 0 #FFFFFF;
|
||||
white-space: nowrap; overflow: visible; cursor: pointer;
|
||||
line-height:20px; margin-right:5px; display:inline-block;
|
||||
padding:3px 5px 3px 5px;
|
||||
font-family:'lucida grande',tahoma,verdana,arial,sans-serif;
|
||||
color:#3C3C3D;
|
||||
text-shadow:1px 1px 0 #FFFFFF;
|
||||
white-space:nowrap; overflow:visible; cursor:pointer;
|
||||
background:#ECECEC;
|
||||
border: 1px solid #CACACA;
|
||||
-webkit-border-radius: 2px; -moz-border-radius: 2px;
|
||||
-webkit-background-clip: padding-box; border-radius: 2px;
|
||||
outline: none; position: relative; zoom: 1; *display: inline;
|
||||
border:1px solid #CACACA;
|
||||
-webkit-border-radius:2px; -moz-border-radius:2px;
|
||||
-webkit-background-clip:padding-box; border-radius:2px;
|
||||
outline:none; position:relative; zoom:1; *display:inline;
|
||||
}
|
||||
*/
|
||||
|
||||
.web2py_console form {
|
||||
width:100%;
|
||||
display:inline;
|
||||
}
|
||||
|
||||
.web2py_console form select {
|
||||
margin:0;
|
||||
}
|
||||
|
||||
.web2py_search_actions{
|
||||
float:left;
|
||||
@@ -238,14 +233,14 @@ div.error {
|
||||
|
||||
.web2py_grid .row_buttons {
|
||||
min-height:25px;
|
||||
vertical-align: middle;
|
||||
vertical-align:middle;
|
||||
}
|
||||
.web2py_grid .row_buttons a {
|
||||
margin: 3px;
|
||||
margin:3px;
|
||||
}
|
||||
|
||||
.web2py_search_actions {
|
||||
width: 100%;
|
||||
width:100%;
|
||||
}
|
||||
|
||||
.web2py_grid .row_buttons a,
|
||||
@@ -254,13 +249,13 @@ div.error {
|
||||
.web2py_console input[type=submit],
|
||||
.web2py_console input[type=button],
|
||||
.web2py_console button {
|
||||
line-height: 20px;
|
||||
margin-right: 5px; display: inline-block;
|
||||
padding: 3px 5px 3px 5px;
|
||||
line-height:20px;
|
||||
margin-right:5px; display:inline-block;
|
||||
padding:3px 5px 3px 5px;
|
||||
}
|
||||
|
||||
.web2py_counter {
|
||||
margin-top: 5px;
|
||||
margin-top:5px;
|
||||
margin-right:5px;
|
||||
width:35%;
|
||||
float:right;
|
||||
@@ -268,37 +263,37 @@ div.error {
|
||||
}
|
||||
|
||||
/*Fix firefox problem*/
|
||||
.web2py_table {clear: both; display: block;}
|
||||
.web2py_table {clear:both; display:block}
|
||||
|
||||
.web2py_paginator {
|
||||
padding: 5px;
|
||||
padding:5px;
|
||||
text-align:right;
|
||||
background-color: #f2f2f2;
|
||||
background-color:#f2f2f2;
|
||||
|
||||
}
|
||||
.web2py_paginator ul {
|
||||
list-style-type: none;
|
||||
margin: 0px;
|
||||
padding: 0px;
|
||||
list-style-type:none;
|
||||
margin:0px;
|
||||
padding:0px;
|
||||
}
|
||||
|
||||
.web2py_paginator ul li {
|
||||
display: inline;
|
||||
display:inline;
|
||||
}
|
||||
|
||||
.web2py_paginator .current {
|
||||
font-weight: bold;
|
||||
font-weight:bold;
|
||||
}
|
||||
|
||||
#w2p_query_panel {}
|
||||
|
||||
.web2py_breadcrumbs ul {
|
||||
list-style: none;
|
||||
margin-bottom: 18px;
|
||||
list-style:none;
|
||||
margin-bottom:18px;
|
||||
}
|
||||
|
||||
.web2py_breadcrumbs ul li {
|
||||
display: inline-block;
|
||||
display:inline-block;
|
||||
}
|
||||
|
||||
.ie9 #query_panel {padding-bottom:2px;}
|
||||
.ie9 #query_panel {padding-bottom:2px}
|
||||
|
||||
@@ -72,7 +72,7 @@ function doClickSave() {
|
||||
|
||||
// show flash message (if any)
|
||||
var flash=xhr.getResponseHeader('web2py-component-flash');
|
||||
if (flash) jQuery('.flash').html(flash).slideDown();
|
||||
if (flash) jQuery('.flash').html(decodeURIComponent(flash)).slideDown();
|
||||
else jQuery('.flash').hide();
|
||||
|
||||
// reenable disabled submit button
|
||||
@@ -149,8 +149,8 @@ function doToggleBreakpoint(filename, url) {
|
||||
success: function(json,text,xhr){
|
||||
|
||||
// show flash message (if any)
|
||||
var flash=decodeURIComponent(xhr.getResponseHeader('web2py-component-flash'));
|
||||
if (flash) jQuery('.flash').html(flash).slideDown();
|
||||
var flash=xhr.getResponseHeader('web2py-component-flash');
|
||||
if (flash) jQuery('.flash').html(decodeURIComponent(flash)).slideDown();
|
||||
else jQuery('.flash').hide();
|
||||
try {
|
||||
if (json.error) {
|
||||
|
||||
+2
-5
@@ -45,11 +45,8 @@ if(jQuery) (function($){
|
||||
html += '<div class="multiSelectOptions" style="position: absolute; z-index: 99999; display: none;">';
|
||||
if( o.selectAll ) html += '<label class="selectAll"><input type="checkbox" class="selectAll" />' + o.selectAllText + '</label>';
|
||||
$(select).find('OPTION').each( function() {
|
||||
if( $(this).val() != '' ) {
|
||||
html += '<label><input type="checkbox" name="' + $(select).attr('name') + '" value="' + $(this).val() + '"';
|
||||
if( $(this).attr('selected') ) html += ' checked="checked"';
|
||||
html += ' />' + $(this).html() + '</label>';
|
||||
}
|
||||
if( $(this).val() != '' )
|
||||
html += '<label for="'+$(select).attr('name')+'">'+$(this).html() + '</label><input type="checkbox" name="' + $(select).attr('name') + '" value="' + $(this).val() + '"'+($(this).attr('selected')?' checked="checked"':'')+' />';
|
||||
});
|
||||
html += '</div>';
|
||||
$(select).after(html);
|
||||
|
||||
@@ -44,6 +44,12 @@ function web2py_event_handlers() {
|
||||
doc.on('keyup', 'input.double, input.decimal', function(){this.value=this.value.reverse().replace(/[^0-9\-\.,]|[\-](?=.)|[\.,](?=[0-9]*[\.,])/g,'').reverse();});
|
||||
var confirm_message = (typeof w2p_ajax_confirm_message != 'undefined') ? w2p_ajax_confirm_message : "Are you sure you want to delete this object?";
|
||||
doc.on('click', "input[type='checkbox'].delete", function(){if(this.checked) if(!confirm(confirm_message)) this.checked=false;});
|
||||
doc.ajaxSuccess(function(e, xhr) {
|
||||
var redirect=xhr.getResponseHeader('web2py-redirect-location');
|
||||
if (redirect != null) {
|
||||
window.location = redirect;
|
||||
};
|
||||
});
|
||||
};
|
||||
|
||||
jQuery(function() {
|
||||
@@ -98,8 +104,8 @@ function web2py_ajax_page(method, action, data, target) {
|
||||
eval(decodeURIComponent(command));
|
||||
if(flash)
|
||||
jQuery('.flash').html(decodeURIComponent(flash)).slideDown();
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function web2py_component(action, target, timeout, times){
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
{{pass}}
|
||||
{{pass}}
|
||||
<h3>
|
||||
{{=A("%s.%s" % (db,table),_href=URL('select',args=[db],vars=dict(query=qry)))}}
|
||||
{{=A("%s.%s" % (db,table),_href=URL('select',args=[db],vars=dict(query=qry)))}}
|
||||
</h3>
|
||||
[ {{=A(str(T('insert new'))+' '+table,_href=URL('insert',args=[db,table]))}} ]
|
||||
<br /><br />
|
||||
@@ -50,7 +50,7 @@
|
||||
{{=T('Use (...)&(...) for AND, (...)|(...) for OR, and ~(...) for NOT to build more complex queries.')}}<br/>
|
||||
{{=T('"update" is an optional expression like "field1=\'newvalue\'". You cannot update or delete the results of a JOIN')}}</p>
|
||||
<br/><br/>
|
||||
<h4>{{=nrows}} {{=T("selected")}}</h4>
|
||||
<h4>{{=T("%s selected", nrows)}}</h4>
|
||||
{{if start>0:}}[ {{=A(T('previous 100 rows'),_href=URL('select',args=request.args[0],vars=dict(start=start-100)))}} ]{{pass}}
|
||||
{{if stop<nrows:}}[ {{=A(T('next 100 rows'),_href=URL('select',args=request.args[0],vars=dict(start=start+100)))}} ]{{pass}}
|
||||
{{if rows:}}
|
||||
@@ -62,10 +62,7 @@
|
||||
{{pass}}
|
||||
<br/><br/><h3>{{=T("Import/Export")}}</h3><br/>
|
||||
[ <a href="{{=URL('csv',args=request.args[0],vars=dict(query=query))}}">{{=T("export as csv file")}}</a> ]
|
||||
{{if table:}}
|
||||
{{=FORM(str(T('or import from csv file'))+" ",INPUT(_type='file',_name='csvfile'),INPUT(_type='hidden',_value=table,_name='table'),INPUT(_type='submit',_value=T('import')))}}
|
||||
{{pass}}
|
||||
|
||||
{{=formcsv or ''}}
|
||||
|
||||
{{elif request.function=='insert':}}
|
||||
<h2>{{=T("database")}} {{=A(request.args[0],_href=URL('index'))}}
|
||||
@@ -108,40 +105,34 @@
|
||||
|
||||
|
||||
{{elif request.function == 'ccache':}}
|
||||
<h2>Cache</h2>
|
||||
<h2>{{T("Cache")}}</h2>
|
||||
<div class="list">
|
||||
|
||||
<div class="list-header">
|
||||
<h3>Statistics</h3>
|
||||
<h3>{{T("Statistics")}}</h3>
|
||||
</div>
|
||||
|
||||
<div class="content">
|
||||
<h4>Overview</h4>
|
||||
<p>Number of entries: <strong>{{=total['entries']}}</strong>
|
||||
{{if total['entries'] > 0:}}
|
||||
</p>
|
||||
<h4>{{=T("Overview")}}</h4>
|
||||
<p>{{=T.M("Number of entries: **%s**", total['entries'])}}</p>
|
||||
{{if total['entries'] > 0:}}
|
||||
<p>{{=T.M("Hit Ratio: **%(ratio)s%%** (**%(hits)s** %%{hit(hits)} and **%(misses)s** %%{miss(misses})",
|
||||
dict(ratio=total['ratio'], hits=total['hits'], misses=total['misses']))}}
|
||||
</p>
|
||||
<p>
|
||||
Hit Ratio:
|
||||
<strong>{{=total['ratio']}}%</strong>
|
||||
(<strong>{{=total['hits']}}</strong> hits
|
||||
and <strong>{{=total['misses']}}</strong> misses)
|
||||
</p>
|
||||
<p>
|
||||
Size of cache:
|
||||
{{=T("Size of cache:")}}
|
||||
{{if object_stats:}}
|
||||
<strong>{{=total['objects']}}</strong> items,
|
||||
<strong>{{=total['bytes']}}</strong> bytes
|
||||
{{if total['bytes'] > 524287:}}
|
||||
(<strong>{{="%.0d" % (total['bytes'] / 1048576)}} MB</strong>)
|
||||
{{pass}}
|
||||
{{else:}} <strong>not available</strong> (requires the Python <a href="http://pypi.python.org/pypi/guppy/" target="_blank">guppy</a> library)
|
||||
{{=T.M("**%(items)s** %%{item(items)}, **%(bytes)s** %%{byte(bytes)}", dict(items=total['objects'], bytes=total['bytes']))}}
|
||||
{{if total['bytes'] > 524287:}}
|
||||
{{=T.M("(**%.0d MB**)", total['bytes'] / 1048576)}}
|
||||
{{pass}}
|
||||
{{else:}}
|
||||
{{=T.M("**not available** (requires the Python [[guppy http://pypi.python.org/pypi/guppy/ popup]] library)")}}
|
||||
{{pass}}
|
||||
</p>
|
||||
<p>
|
||||
Cache contains items up to
|
||||
<strong>{{="%02d" % total['oldest'][0]}}</strong> hours
|
||||
<strong>{{="%02d" % total['oldest'][1]}}</strong> minutes
|
||||
<strong>{{="%02d" % total['oldest'][2]}}</strong> seconds old.
|
||||
{{=T.M("Cache contains items up to **%(hours)02d** %%{hour(hours)} **%(min)02d** %%{minute(min)} **%(sec)02d** %%{second(sec)} old.",
|
||||
dict(hours=total['oldest'][0], min=total['oldest'][1], sec=total['oldest'][2]))}}
|
||||
</p>
|
||||
{{=BUTTON(T('Cache Keys'), _onclick='jQuery("#all_keys").toggle();')}}
|
||||
<div class="hidden" id="all_keys">
|
||||
@@ -150,31 +141,26 @@
|
||||
<br />
|
||||
{{pass}}
|
||||
|
||||
<h4>RAM</h4>
|
||||
<p>Number of entries: <strong>{{=ram['entries']}}</strong>
|
||||
{{if ram['entries'] > 0:}}</p>
|
||||
<p>
|
||||
Hit Ratio:
|
||||
<strong>{{=ram['ratio']}}%</strong>
|
||||
(<strong>{{=ram['hits']}}</strong> hits
|
||||
and <strong>{{=ram['misses']}}</strong> misses)
|
||||
<h4>{{=T("RAM")}}</h4>
|
||||
<p>{{=T.M("Number of entries: **%s**", ram['entries'])}}</p>
|
||||
{{if ram['entries'] > 0:}}
|
||||
<p>{{=T.M("Hit Ratio: **%(ratio)s%%** (**%(hits)s** %{hit(hits)} and **%(misses)s** %%{miss(misses)})",
|
||||
dict( ratio=ram['ratio'], hits=ram['hits'], misses=ram['misses']))}}
|
||||
</p>
|
||||
<p>
|
||||
Size of cache:
|
||||
{{=T("Size of cache:")}}
|
||||
{{if object_stats:}}
|
||||
<strong>{{=ram['objects']}}</strong> items,
|
||||
<strong>{{=ram['bytes']}}</strong> bytes
|
||||
{{if ram['bytes'] > 524287:}}
|
||||
(<strong>{{=ram['bytes'] / 1048576}} MB</strong>)
|
||||
{{pass}}
|
||||
{{else:}} <strong>not available</strong> (requires the Python <a href="http://pypi.python.org/pypi/guppy/" target="_blank">guppy</a> library)
|
||||
{{=T.M("**%(items)s** items, **%(bytes)s** %%{byte(bytes)}", dict(items=ram['objects'], bytes=ram['bytes']))}}
|
||||
{{if ram['bytes'] > 524287:}}
|
||||
{{=T.M("(**%.0d MB**)", ram['bytes'] / 10485576)}}
|
||||
{{pass}}
|
||||
{{else:}}
|
||||
{{=T.M("``**not available**``:red (requires the Python [[guppy http://pypi.python.org/pypi/guppy/ popup]] library)")}}
|
||||
{{pass}}
|
||||
</p>
|
||||
<p>
|
||||
RAM contains items up to
|
||||
<strong>{{="%02d" % ram['oldest'][0]}}</strong> hours
|
||||
<strong>{{="%02d" % ram['oldest'][1]}}</strong> minutes
|
||||
<strong>{{="%02d" % ram['oldest'][2]}}</strong> seconds old.
|
||||
{{=T.M("RAM contains items up to **%(hours)02d** %%{hour(hours)} **%(min)02d** %%{minute(min)} **%(sec)02d** %%{second(sec)} old.",
|
||||
dict(hours=ram['oldest'][0], min=ram['oldest'][1], sec=ram['oldest'][2]))}}
|
||||
</p>
|
||||
{{=BUTTON(T('RAM Cache Keys'), _onclick='jQuery("#ram_keys").toggle();')}}
|
||||
<div class="hidden" id="ram_keys">
|
||||
@@ -183,43 +169,38 @@
|
||||
<br />
|
||||
{{pass}}
|
||||
|
||||
<h4>DISK</h4>
|
||||
<p>Number of entries: <strong>{{=disk['entries']}}</strong>
|
||||
{{if disk['entries'] > 0:}}
|
||||
</p>
|
||||
<p>
|
||||
Hit Ratio:
|
||||
<strong>{{=disk['ratio']}}%</strong>
|
||||
(<strong>{{=disk['hits']}}</strong> hits
|
||||
and <strong>{{=disk['misses']}}</strong> misses)
|
||||
</p>
|
||||
<p>
|
||||
Size of cache:
|
||||
<h4>{{=T("DISK")}}</h4>
|
||||
<p>{{=T.M("Number of entries: **%s**", disk['entries'])}}</p>
|
||||
{{if disk['entries'] > 0:}}
|
||||
<p>
|
||||
{{=T.M("Hit Ratio: **%(ratio)s%%** (**%(hits)s** %%{hit(hits)} and **%(misses)s** %%{miss(misses)})",
|
||||
dict(ratio=disk['ratio'], hits=disk['hits'], misses=disk['misses']))}}
|
||||
</p>
|
||||
<p>
|
||||
{{=T("Size of cache:")}}
|
||||
{{if object_stats:}}
|
||||
<strong>{{=disk['objects']}}</strong> items,
|
||||
<strong>{{=disk['bytes']}}</strong> bytes
|
||||
{{if disk['bytes'] > 524287:}}
|
||||
(<strong>{{=disk['bytes'] / 1048576}} MB</strong>)
|
||||
{{=T.M("**%(items)s** %%{item(items)}, **%(bytes)s** %%{byte(bytes)}", dict( items=disk['objects'], bytes=disk['bytes']))}}
|
||||
{{if disk['bytes'] > 524287:}}
|
||||
{{=T.M("(**%.0d MB**)", disk['bytes'] / 1048576)}}
|
||||
{{pass}}
|
||||
{{else:}}
|
||||
{{=T.M("``**not available**``:red (requires the Python [[guppy http://pypi.python.org/pypi/guppy/ popup]] library)")}}
|
||||
{{pass}}
|
||||
{{else:}} <strong>not available</strong> (requires the Python <a href="http://pypi.python.org/pypi/guppy/" target="_blank">guppy</a> library)
|
||||
{{pass}}
|
||||
</p>
|
||||
<p>
|
||||
DISK contains items up to
|
||||
<strong>{{="%02d" % disk['oldest'][0]}}</strong> hours
|
||||
<strong>{{="%02d" % disk['oldest'][1]}}</strong> minutes
|
||||
<strong>{{="%02d" % disk['oldest'][2]}}</strong> seconds old.
|
||||
</p>
|
||||
{{=BUTTON(T('Disk Cache Keys'), _onclick='jQuery("#disk_keys").toggle();')}}
|
||||
<div class="hidden" id="disk_keys">
|
||||
</p>
|
||||
<p>
|
||||
{{=T.M("DISK contains items up to **%(hours)02d** %%{hour(hours)} **%(min)02d** %%{minute(min)} **%(sec)02d** %%{second(sec)} old.",
|
||||
dict(hours=disk['oldest'][0], min=disk['oldest'][1], sec=disk['oldest'][2]))}}
|
||||
</p>
|
||||
{{=BUTTON(T('Disk Cache Keys'), _onclick='jQuery("#disk_keys").toggle();')}}
|
||||
<div class="hidden" id="disk_keys">
|
||||
{{=disk['keys']}}
|
||||
</div>
|
||||
<br />
|
||||
</div>
|
||||
<br />
|
||||
{{pass}}
|
||||
</div>
|
||||
|
||||
<div class="list-header">
|
||||
<h3>Manage Cache</h3>
|
||||
<h3>{{=T("Manage Cache")}}</h3>
|
||||
</div>
|
||||
|
||||
<div class="content">
|
||||
|
||||
@@ -62,6 +62,7 @@
|
||||
}
|
||||
|
||||
</style-->
|
||||
<script src="{{=URL('static', 'js/autoscroll.js')}}"></script>
|
||||
|
||||
<div id="wrapper">
|
||||
<textarea id="output" readonly="readonly">{{=T('web2py Debugger')}} {{=request.env.web2py_version}}{{=data}}</textarea>
|
||||
@@ -69,6 +70,7 @@
|
||||
<form id="form" action="{{=URL(r=request,f='callback',args=app)}}" method="get">
|
||||
<div id="shellwrapper">
|
||||
<div id="caret">>>></div>
|
||||
<div id="autoscroll" style="cursor:pointer;float:right;">autoscroll</div>
|
||||
<div class="tooltip">
|
||||
<textarea class="prompt" name="statement" id="statement"></textarea>
|
||||
<span>{{=T('Type PDB debugger command in here and hit Return (Enter) to execute it.')}}</span>
|
||||
|
||||
@@ -102,7 +102,7 @@ $(document).bind("mobileinit", function(){
|
||||
</div>
|
||||
<div data-role="footer" data-fullscreen="true" data-position="fixed" style="padding: 5px; text-align: center">
|
||||
{{block footer}}
|
||||
powered by web2py - @2011
|
||||
powered by web2py - @{{=request.now.year}}
|
||||
{{end}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
|
||||
{{block sectionclass}}delete{{end}}
|
||||
|
||||
<div class="center">
|
||||
<h2>{{=T('Are you sure you want to delete file "%s"?', filename)}}</h2>
|
||||
<p>{{=dialog}}</p>
|
||||
<div class="center">
|
||||
{{=dialog}}
|
||||
</div>
|
||||
|
||||
|
||||
@@ -2,9 +2,8 @@
|
||||
|
||||
{{block sectionclass}}delete_plugin{{end}}
|
||||
|
||||
<div class="center">
|
||||
<h2>{{=T('Are you sure you want to delete plugin "%s"?', plugin)}}</h2>
|
||||
<p>{{=FORM(INPUT(_type='submit',_name='nodelete',_value=T('NO')))}}</p>
|
||||
<p>{{=FORM(INPUT(_type='submit',_name='delete',_value=T('YES')))}}</p>
|
||||
<div class="center">
|
||||
{{=dialog}}
|
||||
</div>
|
||||
|
||||
|
||||
@@ -19,6 +19,7 @@ def file_upload_form(location, anchor=None):
|
||||
INPUT(_type="file",_name="file")," ",T("and rename it:")," ",
|
||||
INPUT(_type="text",_name="filename",requires=IS_NOT_EMPTY),
|
||||
INPUT(_type="hidden",_name="location",_value=location),
|
||||
INPUT(_type="hidden",_name="token",_value=session.token),
|
||||
INPUT(_type="hidden",_name="sender",_value=URL('design',args=app, anchor=anchor)),
|
||||
INPUT(_type="submit",_value=T("upload")),_action=URL('upload_file'))
|
||||
return form
|
||||
@@ -27,6 +28,7 @@ def file_create_form(location, anchor=None):
|
||||
INPUT(_type="text",_name="filename",requires=IS_NOT_EMPTY),
|
||||
INPUT(_type="hidden",_name="location",_value=location),
|
||||
INPUT(_type="hidden",_name="sender",_value=URL('design',args=app)),
|
||||
INPUT(_type="hidden",_name="token",_value=session.token),
|
||||
INPUT(_type="hidden",_name="id",_value=anchor),
|
||||
INPUT(_type="submit",_value=T("Create")),_action=URL('create_file'))
|
||||
return form
|
||||
@@ -34,6 +36,7 @@ def upload_plugin_form(app, anchor=None):
|
||||
form=FORM(T("upload plugin file:")," ",
|
||||
INPUT(_type="file",_name="pluginfile"),
|
||||
INPUT(_type="hidden",_name="id",_value=anchor),
|
||||
INPUT(_type="hidden",_name="token",_value=session.token),
|
||||
INPUT(_type="submit",_value=T("upload")))
|
||||
return form
|
||||
def deletefile(arglist, vars={}):
|
||||
@@ -204,7 +207,7 @@ for c in controllers: controller_functions+=[c[:-3]+'/%s.html'%x for x in functi
|
||||
{{if p[0] == 0:}}
|
||||
<b>{{=T("rules are not defined")}}</b>,
|
||||
<span class="controls comptools">
|
||||
{{=button(URL('create_file', vars=dict(filename=p[2], location='gluon/contrib/rules/', sender=URL('design', args=app), id=id, app=app)), T('Create rules'))}}
|
||||
{{=button(URL('create_file', vars=dict(filename=p[2], location='gluon/contrib/rules/', sender=URL('design', args=app), id=id, app=app, token=session.token)), T('Create rules'))}}
|
||||
</span>
|
||||
{{else:}}
|
||||
{{if p[0] == 1:}}
|
||||
@@ -357,7 +360,7 @@ for c in controllers: controller_functions+=[c[:-3]+'/%s.html'%x for x in functi
|
||||
{{=editfile('private',file, dict(id="private"))}} {{=deletefile([app,'private',file], dict(id="private",id2="private"))}}
|
||||
</span>
|
||||
<span class="file">
|
||||
{{=filename}}
|
||||
{{=peekfile('private',file, dict(id="private"))}}
|
||||
</span>
|
||||
</li>{{
|
||||
pass
|
||||
@@ -399,10 +402,8 @@ for c in controllers: controller_functions+=[c[:-3]+'/%s.html'%x for x in functi
|
||||
|
||||
|
||||
<script>
|
||||
jQuery(document).ready(function(){
|
||||
jQuery('#search').keyup(function(e){
|
||||
var code = (e.keyCode ? e.keyCode : e.which);
|
||||
if(code==13 && jQuery('#search').val()){
|
||||
function filter_files() {
|
||||
if(jQuery('#search').val()){
|
||||
jQuery.getJSON('{{=URL('search',args=request.args)}}?keywords='+escape(jQuery('#search').val()),null,function(data, textStatus, xhr){
|
||||
jQuery('.component_contents li, .formfield, .comptools').hide();
|
||||
files=data['files'];
|
||||
@@ -411,11 +412,17 @@ jQuery(document).ready(function(){
|
||||
jQuery('li#'+files[i].replace(/\//g,'__').replace('.','__')).slideDown();
|
||||
jQuery('.flash').html(message).slideDown();
|
||||
});
|
||||
} else if(code==13) {
|
||||
} else {
|
||||
jQuery('.component_contents li, .formfield, .comptools').slideDown();
|
||||
jQuery('.flash').html('').hide();
|
||||
}
|
||||
}
|
||||
jQuery(document).ready(function(){
|
||||
jQuery('#search').keyup(function(e){
|
||||
var code = (e.keyCode ? e.keyCode : e.which);
|
||||
if(code==13) filter_files();
|
||||
});
|
||||
jQuery('#search_start').click(function(e){ filter_files(); });
|
||||
});
|
||||
</script>
|
||||
|
||||
|
||||
@@ -1,14 +0,0 @@
|
||||
{{extend 'layout.html'}}
|
||||
|
||||
{{block sectionclass}}upgrade{{end}}
|
||||
|
||||
<h2>{{=T('web2py downgrade')}}</h2>
|
||||
|
||||
<p class="center"><strong class="att">{{=T('ATTENTION:')}}</strong> {{=T('This is an experimental feature and it needs more testing. If you decide to downgrade you do it at your own risk')}}<br />
|
||||
{{=T('If start the downgrade, be patient, it may take a while to rollback')}}</p>
|
||||
|
||||
<div class="center">
|
||||
{{=FORM(INPUT(_type='submit',_name='nodowngrade',_value=T('Cancel')), _class='inline')}}
|
||||
{{=FORM(INPUT(_type='submit',_name='downgrade',_value=T('Downgrade')), _class='inline')}}
|
||||
</div>
|
||||
|
||||
@@ -1,9 +1,5 @@
|
||||
{{extend 'layout.html'}}
|
||||
|
||||
<center>
|
||||
<div class="center">
|
||||
<h2>{{=T('This will pull changes from the remote repo for application "%s"?', app)}}</h2>
|
||||
<table><tr>
|
||||
<td>{{=FORM(INPUT(_type='submit',_name='cancel',_value=T('Cancel')))}}</td>
|
||||
<td>{{=FORM(INPUT(_type='submit',_name='pull',_value=T('Pull')))}}</td>
|
||||
</tr></table>
|
||||
</center>
|
||||
{{=dialog}}
|
||||
|
||||
@@ -16,6 +16,7 @@ def file_upload_form(location):
|
||||
INPUT(_type="file",_name="file")," ",T("and rename it:")," ",
|
||||
INPUT(_type="text",_name="filename",requires=IS_NOT_EMPTY),
|
||||
INPUT(_type="hidden",_name="location",_value=location),
|
||||
INPUT(_type="hidden",_name="token",_value=session.token),
|
||||
INPUT(_type="hidden",_name="sender",_value=URL('design/'+app)),
|
||||
INPUT(_type="submit",_value=T("submit")),_action=URL('upload_file'))
|
||||
return form
|
||||
@@ -23,14 +24,10 @@ def file_create_form(location):
|
||||
form=FORM(T("create file with filename:")," ",
|
||||
INPUT(_type="text",_name="filename",requires=IS_NOT_EMPTY),
|
||||
INPUT(_type="hidden",_name="location",_value=location),
|
||||
INPUT(_type="hidden",_name="token",_value=session.token),
|
||||
INPUT(_type="hidden",_name="sender",_value=URL('design/'+app)),
|
||||
INPUT(_type="submit",_value=T("submit")),_action=URL('create_file'))
|
||||
return form
|
||||
def upload_plugin_form(app):
|
||||
form=FORM(T("upload plugin file:")," ",
|
||||
INPUT(_type="file",_name="pluginfile"),
|
||||
INPUT(_type="submit",_value=T("submit")))
|
||||
return form
|
||||
def deletefile(arglist):
|
||||
return A(TAG[''](IMG(_src=URL('static', 'images/delete_icon.png')), SPAN(T('Delete this file (you will be asked to confirm deletion)'))), _class='icon delete tooltip', _href=URL('delete',args=arglist,vars=dict(sender=request.function+'/'+app)))
|
||||
}}
|
||||
|
||||
@@ -70,12 +70,12 @@
|
||||
{{else:}}
|
||||
<p id="check_version">
|
||||
{{=button("javascript:ajax('"+URL('check_version')+"',[],'check_version')", T('Check for upgrades'))}}
|
||||
{{pass}}
|
||||
{{=button(URL('default','reload_routes'), T('Reload routes'))}}
|
||||
</p>
|
||||
<div class="formfield">
|
||||
{{pass}}
|
||||
<p>
|
||||
{{=T("Running on %s", request.env.server_software)}}
|
||||
</div>
|
||||
<p>{{=button(URL('default','reload_routes'), T('Reload routes'))}}</p>
|
||||
</p>
|
||||
</div>
|
||||
{{pass}}
|
||||
<!-- APP WIZARD -->
|
||||
@@ -87,64 +87,42 @@
|
||||
<!-- SCAFFOLD APP -->
|
||||
<div class="box">
|
||||
<h3>{{=T("New simple application")}}</h3>
|
||||
<form action="" enctype="multipart/form-data" method="post">
|
||||
<div class="formfield">
|
||||
{{=LABEL(T("Application name:"), _for="scaffold_filename")}}
|
||||
<input name="filename" type="text" id="scaffold_filename" />
|
||||
<button type="submit" class="button">{{=T('Create')}}</button>
|
||||
</div>
|
||||
<div class="hidden"></div>
|
||||
</form>
|
||||
{{=form_create.custom.begin}}
|
||||
<table><tr><td>
|
||||
{{=LABEL(T("Application name:"))}}
|
||||
</td><td>
|
||||
{{=form_create.custom.widget.name}}
|
||||
</td><td>
|
||||
<button type="submit">{{=T('Create')}}</button>
|
||||
</td></tr></table>
|
||||
{{=form_create.custom.end}}
|
||||
</div>
|
||||
<!-- UPLOAD PACKAGE -->
|
||||
<div class="box">
|
||||
<h3>{{=T("Upload and install packed application")}}</h3>
|
||||
<form action="" enctype="multipart/form-data" method="post">
|
||||
<div class="formfield">
|
||||
<table>
|
||||
<tr>
|
||||
<td>
|
||||
{{=LABEL(T("Application name:"), _form='upload_filename')}}
|
||||
</td>
|
||||
<td>
|
||||
<input id="appname" name="filename" type="text" id="upload_filename" />
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
{{=LABEL(T("Upload a package:"), _for='upload_file')}}
|
||||
</td>
|
||||
<td>
|
||||
<input id="file" name="file" type="file" id="upload_file" />
|
||||
<b>OR</b>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
{{=LABEL(T("Get from URL:"), _for='upload_url')}}
|
||||
</td>
|
||||
<td>
|
||||
<input id="appurl" name="appurl" type="text" id="upload_url"/><br/>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
{{=form_update.custom.begin}}
|
||||
<table><tr><td>
|
||||
{{=LABEL(T("Application name:"))}}
|
||||
</td><td>
|
||||
{{=form_update.custom.widget.name}}
|
||||
</td></tr><tr><td>
|
||||
{{=LABEL(T("Upload a package:"))}}
|
||||
</td><td>
|
||||
{{=form_update.custom.widget.file}}
|
||||
</td></tr><tr><td>
|
||||
{{=LABEL('Or ',T("Get from URL:"))}}
|
||||
</td><td>
|
||||
{{=form_update.custom.widget.url}}
|
||||
</td></tr><tr><td>
|
||||
({{=T('can be a git repo')}})
|
||||
</td>
|
||||
<td>
|
||||
<input type="checkbox" name="overwrite_check" id="upload_overwrite" />
|
||||
{{=LABEL(T("Overwrite installed app"), _for='upload_overwrite')}}
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td></td>
|
||||
<td>
|
||||
<button type="submit">{{=T('Install')}}</button>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
</form>
|
||||
</td><td>
|
||||
{{=form_update.custom.widget.overwrite}}
|
||||
{{=LABEL(T("Overwrite installed app"))}}
|
||||
</td></tr><tr><td>
|
||||
</td><td>
|
||||
<button type="submit">{{=T('Install')}}</button>
|
||||
</td></tr></table>
|
||||
{{=form_update.custom.end}}
|
||||
</div>
|
||||
<!-- DEPLOY ON GAE -->
|
||||
<div class="box">
|
||||
|
||||
@@ -1,10 +1,7 @@
|
||||
{{extend 'layout.html'}}
|
||||
|
||||
<center>
|
||||
<h2>{{=T('Are you sure you want to uninstall application "%s"?', app)}}</h2>
|
||||
<table><tr>
|
||||
<td>{{=FORM(INPUT(_type='submit',_name='nodelete',_value=T('Abort')))}}</td>
|
||||
<td>{{=FORM(INPUT(_type='submit',_name='delete',_value=T('Uninstall')))}}</td>
|
||||
</tr></table>
|
||||
</center>
|
||||
<div class="center">
|
||||
{{=dialog}}
|
||||
</div>
|
||||
|
||||
|
||||
@@ -8,7 +8,6 @@
|
||||
{{=T('If start the upgrade, be patient, it may take a while to download')}}</p>
|
||||
|
||||
<div class="center">
|
||||
{{=FORM(INPUT(_type='submit',_name='noupgrade',_value=T('Cancel')), _class='inline')}}
|
||||
{{=FORM(INPUT(_type='submit',_name='upgrade',_value=T('Upgrade')), _class='inline')}}
|
||||
{{=dialog}}
|
||||
</div>
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<div id="footer" class="fixed">
|
||||
{{=T('Powered by')}} {{=A('web2py', _href='http://www.web2py.com')}}™ {{=T('created by')}} Massimo Di Pierro ©2007-2012 -
|
||||
{{=T('Powered by')}} {{=A('web2py', _href='http://www.web2py.com')}}™ {{=T('created by')}} Massimo Di Pierro ©2007-{{=request.now.year}} -
|
||||
{{if hasattr(T,'get_possible_languages_info'):}}
|
||||
<span>
|
||||
{{=T('Admin language')}}
|
||||
|
||||
@@ -103,7 +103,7 @@ $(document).bind("mobileinit", function(){
|
||||
</div>
|
||||
<div data-role="footer" data-fullscreen="true" data-position="fixed" style="padding: 5px; text-align: center">
|
||||
{{block footer}}
|
||||
powered by web2py - @2011
|
||||
powered by web2py - @{{=request.now.year}}
|
||||
{{end}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -73,7 +73,7 @@
|
||||
<textarea class="prompt" name="statement" id="statement"></textarea>
|
||||
<span>Type some Python code in here and hit Return (Enter) to execute it.</span>
|
||||
</div>
|
||||
<div id="autoscroll" style="float:right;">autoscroll</div>
|
||||
<div id="autoscroll" style="cursor:pointer;float:right;">autoscroll</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
@@ -199,17 +199,8 @@ def select():
|
||||
_class='delete', _type='checkbox', value=False), ''),
|
||||
TR('', '', INPUT(_type='submit', _value=T('submit')))),
|
||||
_action=URL(r=request,args=request.args))
|
||||
if request.vars.csvfile != None:
|
||||
try:
|
||||
import_csv(db[request.vars.table],
|
||||
request.vars.csvfile.file)
|
||||
response.flash = T('data uploaded')
|
||||
except Exception, e:
|
||||
response.flash = DIV(T('unable to parse csv file'),PRE(str(e)))
|
||||
if form.accepts(request.vars, formname=None):
|
||||
# regex = re.compile(request.args[0] + '\.(?P<table>\w+)\.id\>0')
|
||||
regex = re.compile(request.args[0] + '\.(?P<table>\w+)\..+')
|
||||
|
||||
match = regex.match(form.vars.query.strip())
|
||||
if match:
|
||||
table = match.group('table')
|
||||
@@ -230,6 +221,23 @@ def select():
|
||||
except Exception, e:
|
||||
(rows, nrows) = ([], 0)
|
||||
response.flash = DIV(T('Invalid Query'),PRE(str(e)))
|
||||
# begin handle upload csv
|
||||
if table:
|
||||
formcsv = FORM(str(T('or import from csv file'))+" ",
|
||||
INPUT(_type='file',_name='csvfile'),
|
||||
INPUT(_type='hidden',_value=table,_name='table'),
|
||||
INPUT(_type='submit',_value=T('import')))
|
||||
else:
|
||||
formcsv = None
|
||||
if formcsv and formcsv.process().accepted and request.vars.csvfile:
|
||||
try:
|
||||
import_csv(db[request.vars.table],
|
||||
request.vars.csvfile.file)
|
||||
response.flash = T('data uploaded')
|
||||
except Exception, e:
|
||||
response.flash = DIV(T('unable to parse csv file'),PRE(str(e)))
|
||||
# end handle upload csv
|
||||
|
||||
return dict(
|
||||
form=form,
|
||||
table=table,
|
||||
@@ -238,6 +246,7 @@ def select():
|
||||
nrows=nrows,
|
||||
rows=rows,
|
||||
query=request.vars.query,
|
||||
formcsv = formcsv,
|
||||
)
|
||||
|
||||
|
||||
|
||||
@@ -49,14 +49,3 @@ def cache_controller_and_view():
|
||||
return response.render(d)
|
||||
|
||||
|
||||
def cache_db_select():
|
||||
"""cache the database select in ram for 5 seconds"""
|
||||
|
||||
db.users.insert(name='somebody', email='gluon@mdp.cti.depaul.edu')
|
||||
records = db().select(db.users.ALL, cache=(cache.ram, 5))
|
||||
if len(records) > 20:
|
||||
db(dba.users.id > 0).delete()
|
||||
return dict(records=records)
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,90 +0,0 @@
|
||||
from gluon.fileutils import read_file
|
||||
|
||||
response.menu = [['Register Person', False, URL('register_person')],
|
||||
['Register Dog', False, URL('register_dog')],
|
||||
['Register Product', False, URL('register_product')],
|
||||
['Buy product', False, URL('buy')]]
|
||||
|
||||
|
||||
def register_person():
|
||||
""" simple person registration form with validation and database.insert()
|
||||
also lists all records currently in the table"""
|
||||
|
||||
# create an insert form from the table
|
||||
form = SQLFORM(db.person)
|
||||
|
||||
# if form correct perform the insert
|
||||
if form.process().accepted:
|
||||
response.flash = 'new record inserted'
|
||||
|
||||
# and get a list of all persons
|
||||
records = SQLTABLE(db().select(db.person.ALL),headers='fieldname:capitalize')
|
||||
|
||||
return dict(form=form, records=records)
|
||||
|
||||
|
||||
def register_dog():
|
||||
""" simple person registration form with validation and database.insert()
|
||||
also lists all records currently in the table"""
|
||||
|
||||
form = SQLFORM(db.dog)
|
||||
if form.process().accepted:
|
||||
response.flash = 'new record inserted'
|
||||
download = URL('download') # to see the picture
|
||||
records = SQLTABLE(db().select(db.dog.ALL), upload=download,
|
||||
headers='fieldname:capitalize')
|
||||
return dict(form=form, records=records)
|
||||
|
||||
|
||||
def register_product():
|
||||
""" simple person registration form with validation and database.insert()
|
||||
also lists all records currently in the table"""
|
||||
|
||||
form = SQLFORM(db.product)
|
||||
if form.process().accepted:
|
||||
response.flash = 'new record inserted'
|
||||
records = SQLTABLE(db().select(db.product.ALL),
|
||||
headers='fieldname:capitalize')
|
||||
return dict(form=form, records=records)
|
||||
|
||||
|
||||
def buy():
|
||||
""" uses a form to query who is buying what. validates form and
|
||||
updates existing record or inserts new record in purchases """
|
||||
|
||||
form = SQLFORM.factory(
|
||||
Field('buyer_id',requires=IS_IN_DB(db,db.person.id,'%(name)s')),
|
||||
Field('product_id',requires=IS_IN_DB(db,db.product.id,'%(name)s')),
|
||||
Field('quantity','integer',requires=IS_INT_IN_RANGE(1,100)))
|
||||
if form.process().accepted:
|
||||
# get previous purchese
|
||||
purchase = db((db.purchase.buyer_id == form.vars.buyer_id)&
|
||||
(db.purchase.product_id==form.vars.product_id)).select().first()
|
||||
|
||||
if purchase:
|
||||
# if list contains a record, update that record
|
||||
purchase.update_record(
|
||||
quantity = purchase.quantity+form.vars.quantity)
|
||||
else:
|
||||
# self insert a new record in table
|
||||
db.purchase.insert(buyer_id=form.vars.buyer_id,
|
||||
product_id=form.vars.product_id,
|
||||
quantity=form.vars.quantity)
|
||||
response.flash = 'product purchased!'
|
||||
elif form.errors:
|
||||
response.flash = 'invalid values in form!'
|
||||
|
||||
# now get a list of all purchases
|
||||
records = SQLTABLE(db(purchased).select(),headers='fieldname:capitalize')
|
||||
return dict(form=form, records=records)
|
||||
|
||||
|
||||
def delete_purchased():
|
||||
""" delete all records in purchases """
|
||||
db(db.purchase.id > 0).delete()
|
||||
redirect(URL('buy'))
|
||||
|
||||
def download():
|
||||
""" used to download uploaded files """
|
||||
return response.download(request,db)
|
||||
|
||||
@@ -1,69 +0,0 @@
|
||||
#########################################################################
|
||||
## This scaffolding model makes your app work on Google App Engine too
|
||||
#########################################################################
|
||||
|
||||
if request.controller.endswith('_examples'): response.generic_patterns.append('*')
|
||||
|
||||
from gluon.settings import settings
|
||||
|
||||
# if running on Google App Engine
|
||||
if settings.web2py_runtime_gae:
|
||||
from gluon.contrib.gql import *
|
||||
# connect to Google BigTable
|
||||
db = DAL('gae')
|
||||
# and store sessions there
|
||||
session.connect(request, response, db=db)
|
||||
else:
|
||||
# if not, use SQLite or other DB
|
||||
db = DAL('sqlite://storage.sqlite')
|
||||
|
||||
db.define_table(
|
||||
'users',
|
||||
Field('name'),
|
||||
Field('email')
|
||||
)
|
||||
|
||||
# ONE (users) TO MANY (dogs)
|
||||
|
||||
db.define_table(
|
||||
'dogs',
|
||||
Field('owner_id', db.users),
|
||||
Field('name'),
|
||||
Field('type'),
|
||||
Field('vaccinated', 'boolean', default=False),
|
||||
Field('picture', 'upload', default=''),
|
||||
)
|
||||
|
||||
db.define_table(
|
||||
'products',
|
||||
Field('name'),
|
||||
Field('description', 'text')
|
||||
)
|
||||
|
||||
# MANY (users) TO MANY (purchases)
|
||||
|
||||
db.define_table(
|
||||
'purchases',
|
||||
Field('buyer_id', db.users),
|
||||
Field('product_id', db.products),
|
||||
Field('quantity', 'integer')
|
||||
)
|
||||
|
||||
# if running on Google App Engine
|
||||
if settings.web2py_runtime_gae:
|
||||
# quick hack to skip the join
|
||||
purchased = None
|
||||
else:
|
||||
# use a joined view
|
||||
purchased = (db.users.id == db.purchases.buyer_id) & (db.products.id
|
||||
== db.purchases.product_id)
|
||||
|
||||
db.users.name.requires = IS_NOT_EMPTY()
|
||||
db.users.email.requires = [IS_EMAIL(), IS_NOT_IN_DB(db, 'users.email')]
|
||||
db.dogs.owner_id.requires = IS_IN_DB(db, 'users.id', 'users.name')
|
||||
db.dogs.name.requires = IS_NOT_EMPTY()
|
||||
db.dogs.type.requires = IS_IN_SET(['small', 'medium', 'large'])
|
||||
db.purchases.buyer_id.requires = IS_IN_DB(db, 'users.id', 'users.name')
|
||||
db.purchases.product_id.requires = IS_IN_DB(db, 'products.id',
|
||||
'products.name')
|
||||
db.purchases.quantity.requires = IS_INT_IN_RANGE(0, 10)
|
||||
@@ -1,72 +0,0 @@
|
||||
#########################################################################
|
||||
## This scaffolding model makes your app work on Google App Engine too
|
||||
#########################################################################
|
||||
|
||||
if request.controller.endswith('_examples'): response.generic_patterns.append('*')
|
||||
|
||||
from gluon.settings import settings
|
||||
|
||||
# if running on Google App Engine
|
||||
if settings.web2py_runtime_gae:
|
||||
from gluon.contrib.gql import *
|
||||
# connect to Google BigTable
|
||||
db = DAL('gae')
|
||||
# and store sessions there
|
||||
session.connect(request, response, db=db)
|
||||
else:
|
||||
# if not, use SQLite or other DB
|
||||
db = DAL('sqlite://storage.sqlite')
|
||||
|
||||
db.define_table(
|
||||
'person',
|
||||
Field('name'),
|
||||
Field('email'),
|
||||
format = '%(name)s',
|
||||
singular = 'Person',
|
||||
plural = 'Persons',
|
||||
)
|
||||
|
||||
# ONE (person) TO MANY (dogs)
|
||||
|
||||
db.define_table(
|
||||
'dog',
|
||||
Field('owner_id', db.person),
|
||||
Field('name'),
|
||||
Field('type'),
|
||||
Field('vaccinated', 'boolean', default=False),
|
||||
Field('picture', 'upload', default=''),
|
||||
format = '%(name)s',
|
||||
singular = 'Dog',
|
||||
plural = 'Dogs',
|
||||
)
|
||||
|
||||
db.define_table(
|
||||
'product',
|
||||
Field('name'),
|
||||
Field('description', 'text'),
|
||||
format = '%(name)s',
|
||||
singular = 'Product',
|
||||
plural = 'Products',
|
||||
)
|
||||
|
||||
# MANY (persons) TO MANY (purchases)
|
||||
|
||||
db.define_table(
|
||||
'purchase',
|
||||
Field('buyer_id', db.person),
|
||||
Field('product_id', db.product),
|
||||
Field('quantity', 'integer'),
|
||||
format = '%(quantity)s %(product_id)s -> %(buyer_id)s',
|
||||
singular = 'Purchase',
|
||||
plural = 'Purchases',
|
||||
)
|
||||
|
||||
purchased = \
|
||||
(db.person.id==db.purchase.buyer_id)&\
|
||||
(db.product.id==db.purchase.product_id)
|
||||
|
||||
db.person.name.requires = IS_NOT_EMPTY()
|
||||
db.person.email.requires = [IS_EMAIL(), IS_NOT_IN_DB(db, 'person.email')]
|
||||
db.dog.name.requires = IS_NOT_EMPTY()
|
||||
db.dog.type.requires = IS_IN_SET(('small', 'medium', 'large'))
|
||||
db.purchase.quantity.requires = IS_INT_IN_RANGE(0, 10)
|
||||
@@ -1,12 +0,0 @@
|
||||
import random
|
||||
quotes = [
|
||||
("web2py was the life saver today for me, my blog post: Standalone Usage of web2py's", "caglartoklu", "http://twitter.com/#!/caglartoklu/status/84292131707031553"),
|
||||
("Get Things Done - Faster, Better and More Easily with web2py",
|
||||
"Bruno Rocha", "http://twitter.com/#!/rochacbruno/status/73583156044890112"),
|
||||
("Please use www.web2py.com when using MVC , no PHP/SQL stuff please...its 2011 not 1999", "rabblesoft", "http://twitter.com/#!/rabblesoft/status/79189028431343616"),
|
||||
('web2py rules! as a sysadmin I like the no installation and no configuration approach a lot)', "kjogut", "http://twitter.com/#!/jkogut/status/61414554273447936"),
|
||||
("web2py it is. Compatible with everything under the sun and great interfaces to googleappengine", "comamitc","http://twitter.com/#!/comamitc/status/51744719071477760"),
|
||||
("If you are still learning python, web2py is best tool by far", "pbreit", "http://twitter.com/#!/pbreit/status/48260905775017984")
|
||||
]
|
||||
random.shuffle(quotes)
|
||||
|
||||
@@ -1,190 +1,181 @@
|
||||
/** these MUST stay **/
|
||||
body { margin: 0; padding:0; border: 0; }
|
||||
a { text-decoration:none; white-space: nowrap;}
|
||||
a:hover {text-decoration: underline}
|
||||
a.button {text-decoration: none}
|
||||
h1,h2,h3,h4,h5,h6 {margin: 0.5em 0 0.25em 0; display: block; font-family: Helvetica;}
|
||||
h1 { font-size: 4.00em;}
|
||||
h2 { font-size: 3.00em;}
|
||||
h3 { font-size: 2.00em;}
|
||||
h4 { font-size: 1.50em;}
|
||||
h5 { font-size: 1.25em;}
|
||||
h6 { font-size: 1.12em;}
|
||||
right { float:right; text-align: right; }
|
||||
left { float:left; text-align: left; }
|
||||
center { width:100; text-align: center; vertical-align:middle;}
|
||||
th, label { font-weight: bold; white-space: nowrap; }
|
||||
td, th { text-align: left; padding: 2px 5px 2px 5px; }
|
||||
th { vertical-align: middle; border-right: 1px solid white;}
|
||||
td { vertical-align: top; }
|
||||
form table tr td label { text-align: left; }
|
||||
p, table, ol, ul { padding: 0.5em 0 0.5em 0 }
|
||||
p {text-align: justify }
|
||||
ol, ul { padding-left: 30px }
|
||||
li { margin-bottom: 0.5em; }
|
||||
span, input, select, textarea, button, label, a { display: inline }
|
||||
img { border: 0; }
|
||||
blockquote, blockquote p, p blockquote { font-style: italic; margin: 0.5em 30px 0.5em 30px; font-size: 0.9em}
|
||||
i, em { font-style: italic; }
|
||||
strong { font-weight: bold; }
|
||||
small { font-size: 0.8em; }
|
||||
textarea { width: 100%; }
|
||||
code { font-family: Courier;}
|
||||
video { width:400px; }
|
||||
audio { width:200px; }
|
||||
input[type=text], input[type=password], select { width: 300px; margin-right: 5px }
|
||||
ul { list-style-type: none; margin: 0px; padding: 0px; }
|
||||
a {text-decoration:none; white-space:nowrap}
|
||||
a:hover {text-decoration:underline}
|
||||
a.button {text-decoration:none}
|
||||
h1,h2,h3,h4,h5,h6 {margin:0.5em 0 0.25em 0; display:block;
|
||||
font-family:Helvetica}
|
||||
h1 {font-size:4.00em}
|
||||
h2 {font-size:3.00em}
|
||||
h3 {font-size:2.00em}
|
||||
h4 {font-size:1.50em}
|
||||
h5 {font-size:1.25em}
|
||||
h6 {font-size:1.12em}
|
||||
th,label {font-weight:bold; white-space:nowrap}
|
||||
td,th {text-align:left; padding:2px 5px 2px 5px}
|
||||
th {vertical-align:middle; border-right:1px solid white}
|
||||
td {vertical-align:top}
|
||||
form table tr td label {text-align:left}
|
||||
p,table,ol,ul {padding:0; margin: 0.5em 0}
|
||||
p {text-align:justify}
|
||||
ol, ul {list-style-position:inside}
|
||||
li {margin-bottom:0.5em}
|
||||
span,input,select,textarea,button,label,a {display:inline}
|
||||
img {border:0}
|
||||
blockquote,blockquote p,p blockquote {
|
||||
font-style:italic; margin:0.5em 30px 0.5em 30px; font-size:0.9em}
|
||||
i,em {font-style:italic}
|
||||
strong {font-weight:bold}
|
||||
small {font-size:0.8em}
|
||||
code {font-family:Courier}
|
||||
textarea {width:100%}
|
||||
video {width:400px}
|
||||
audio {width:200px}
|
||||
input[type=text],input[type=password],select{width:300px; margin-right:5px}
|
||||
.hidden {display:none;visibility:visible}
|
||||
.right {float:right; text-align:right}
|
||||
.left {float:left; text-align:left}
|
||||
.center {width:100; text-align:center; vertical-align:middle}
|
||||
/** end **/
|
||||
|
||||
/* Sticky footer begin */
|
||||
html, body {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.wrapper {
|
||||
min-height: 100%;
|
||||
height: auto !important;
|
||||
height: 100%;
|
||||
margin: 0 auto -8em; /* set last value to footer height plus footer vertical padding */
|
||||
min-height:100%;
|
||||
height:auto !important;
|
||||
height:100%;
|
||||
margin:0 auto -8em; /* set last value to footer height plus footer vertical padding */
|
||||
}
|
||||
|
||||
.main {
|
||||
padding: 20px 0 50px 0;
|
||||
padding:20px 0 50px 0;
|
||||
}
|
||||
|
||||
.footer, .push {
|
||||
height: 6em;
|
||||
padding: 1em 0;
|
||||
clear: both;
|
||||
.footer,.push {
|
||||
height:6em;
|
||||
padding:1em 0;
|
||||
clear:both;
|
||||
}
|
||||
|
||||
.footer-content {position: relative; bottom: -4em; width: 100%;}
|
||||
.footer-content {position:relative; bottom:-4em; width:100%}
|
||||
|
||||
.auth_navbar {
|
||||
white-space: nowrap;
|
||||
white-space:nowrap;
|
||||
}
|
||||
|
||||
/* Sticky footer end */
|
||||
|
||||
.footer {
|
||||
border-top: 1px #DEDEDE solid;
|
||||
border-top:1px #DEDEDE solid;
|
||||
}
|
||||
.header {
|
||||
// background: <fill here for header image>;
|
||||
// background:<fill here for header image>;
|
||||
}
|
||||
|
||||
|
||||
fieldset { padding: 16px; border-top: 1px #DEDEDE solid;}
|
||||
fieldset legend {text-transform:uppercase; font-weight: bold; padding: 4px 16px 4px 16px; background: #f1f1f1;}
|
||||
fieldset {padding:16px; border-top:1px #DEDEDE solid}
|
||||
fieldset legend {text-transform:uppercase; font-weight:bold; padding:4px 16px 4px 16px; background:#f1f1f1}
|
||||
|
||||
/* fix ie problem with menu */
|
||||
.ie-lte7 .topbar .container {z-index: 2; }
|
||||
.ie-lte7 .topbar .container {z-index:2}
|
||||
|
||||
td.w2p_fw {padding-bottom: 1px;}
|
||||
td.w2p_fl, td.w2p_fw, td.w2p_fc { vertical-align:top; }
|
||||
td.w2p_fl { text-align:right; }
|
||||
td.w2p_fl, td.w2p_fw {padding-right: 7px;}
|
||||
td.w2p_fl, td.w2p_fc { padding-top: 4px; }
|
||||
td.w2p_fw {padding-bottom:1px}
|
||||
td.w2p_fl,td.w2p_fw,td.w2p_fc {vertical-align:top}
|
||||
td.w2p_fl {text-align:right}
|
||||
td.w2p_fl, td.w2p_fw {padding-right:7px}
|
||||
td.w2p_fl,td.w2p_fc {padding-top:4px}
|
||||
|
||||
/* tr#submit_record__row {border-top: 1px solid #E5E5E5;} */
|
||||
#submit_record__row td {padding-top: .5em;}
|
||||
/* tr#submit_record__row {border-top:1px solid #E5E5E5} */
|
||||
#submit_record__row td {padding-top:.5em}
|
||||
|
||||
/* Fix */
|
||||
#auth_user_remember__row label {display: inline;}
|
||||
#web2py_user_form td { vertical-align:top; }
|
||||
#auth_user_remember__row label {display:inline}
|
||||
#web2py_user_form td {vertical-align:top}
|
||||
|
||||
/*********** web2py specific ***********/
|
||||
div.flash {
|
||||
font-weight: bold;
|
||||
display: none;
|
||||
position: fixed;
|
||||
padding: 10px;
|
||||
top: 48px;
|
||||
right: 50px;
|
||||
min-width: 280px;
|
||||
opacity: 0.85;
|
||||
margin: 0px 0px 10px 10px;
|
||||
color: #fff;
|
||||
vertical-align: middle;
|
||||
cursor: pointer;
|
||||
background: #000;
|
||||
border: 2px solid #fff;
|
||||
border-radius: 5px;
|
||||
-moz-border-radius: 5px;
|
||||
-webkit-border-radius: 5px;
|
||||
z-index: 2;
|
||||
font-weight:bold;
|
||||
display:none;
|
||||
position:fixed;
|
||||
padding:10px;
|
||||
top:48px;
|
||||
right:50px;
|
||||
min-width:280px;
|
||||
opacity:0.85;
|
||||
margin:0px 0px 10px 10px;
|
||||
color:#fff;
|
||||
vertical-align:middle;
|
||||
cursor:pointer;
|
||||
background:#000;
|
||||
border:2px solid #fff;
|
||||
border-radius:5px;
|
||||
-moz-border-radius:5px;
|
||||
-webkit-border-radius:5px;
|
||||
z-index:2000;
|
||||
}
|
||||
div.flash {z-index:2000;}
|
||||
|
||||
div.error_wrapper { display: block; }
|
||||
div.error_wrapper {display:block}
|
||||
div.error {
|
||||
background-color: red;
|
||||
color: white;
|
||||
padding: 3px;
|
||||
display: inline-block;
|
||||
background-color:red;
|
||||
color:white;
|
||||
padding:3px;
|
||||
display:inline-block;
|
||||
}
|
||||
|
||||
.topbar {
|
||||
padding: 10px 0;
|
||||
padding:10px 0;
|
||||
width:100%;
|
||||
color: #959595;
|
||||
vertical-align: middle;
|
||||
padding: auto;
|
||||
background-image: -khtml-gradient(linear, left top, left bottom, from(#333333), to(#222222));
|
||||
background-image: -moz-linear-gradient(top, #333333, #222222);
|
||||
background-image: -ms-linear-gradient(top, #333333, #222222);
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #333333), color-stop(100%, #222222));
|
||||
background-image: -webkit-linear-gradient(top, #333333, #222222);
|
||||
background-image: -o-linear-gradient(top, #333333, #222222);
|
||||
background-image: linear-gradient(top, #333333, #222222);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#333333', endColorstr='#222222', GradientType=0);
|
||||
-webkit-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.25), inset 0 -1px 0 rgba(0, 0, 0, 0.1);
|
||||
-moz-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.25), inset 0 -1px 0 rgba(0, 0, 0, 0.1);
|
||||
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.25), inset 0 -1px 0 rgba(0, 0, 0, 0.1);
|
||||
color:#959595;
|
||||
vertical-align:middle;
|
||||
padding:auto;
|
||||
background-image:-khtml-gradient(linear,left top,left bottom,from(#333333),to(#222222));
|
||||
background-image:-moz-linear-gradient(top,#333333,#222222);
|
||||
background-image:-ms-linear-gradient(top,#333333,#222222);
|
||||
background-image:-webkit-gradient(linear,left top,left bottom,color-stop(0%,#333333),color-stop(100%,#222222));
|
||||
background-image:-webkit-linear-gradient(top,#333333,#222222);
|
||||
background-image:-o-linear-gradient(top,#333333,#222222);
|
||||
background-image:linear-gradient(top,#333333,#222222);
|
||||
filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#333333',endColorstr='#222222',GradientType=0);
|
||||
-webkit-box-shadow:0 1px 3px rgba(0,0,0,0.25),inset 0 -1px 0 rgba(0,0,0,0.1);
|
||||
-moz-box-shadow:0 1px 3px rgba(0,0,0,0.25),inset 0 -1px 0 rgba(0,0,0,0.1);
|
||||
box-shadow:0 1px 3px rgba(0,0,0,0.25),inset 0 -1px 0 rgba(0,0,0,0.1);
|
||||
}
|
||||
|
||||
.topbar a {
|
||||
color: #e1e1e1;
|
||||
color:#e1e1e1;
|
||||
}
|
||||
|
||||
#navbar {float: right; padding: 5px; /* same as superfish */}
|
||||
|
||||
.right {
|
||||
width:100%;
|
||||
text-align: right;
|
||||
float: right;
|
||||
}
|
||||
#navbar {float:right; padding:5px; /* same as superfish */}
|
||||
|
||||
.statusbar {
|
||||
background-color: #F5F5F5;
|
||||
margin-top: 1em;
|
||||
margin-bottom: 1em;
|
||||
padding: .5em 1em;
|
||||
border: 1px solid #ddd;
|
||||
border-radius: 5px;
|
||||
-moz-border-radius: 5px;
|
||||
-webkit-border-radius: 5px;
|
||||
background-color:#F5F5F5;
|
||||
margin-top:1em;
|
||||
margin-bottom:1em;
|
||||
padding:.5em 1em;
|
||||
border:1px solid #ddd;
|
||||
border-radius:5px;
|
||||
-moz-border-radius:5px;
|
||||
-webkit-border-radius:5px;
|
||||
}
|
||||
|
||||
.breadcrumbs { float: left; }
|
||||
.breadcrumbs {float:left}
|
||||
|
||||
.copyright {float: left;}
|
||||
#poweredBy {float: right;}
|
||||
.copyright {float:left}
|
||||
#poweredBy {float:right}
|
||||
|
||||
/* #MEDIA QUERIES SECTION */
|
||||
|
||||
/* All Mobile Sizes (devices and browser) */
|
||||
@media only screen and (max-width: 767px) {
|
||||
@media only screen and (max-width:767px) {
|
||||
/* removed because of bootswatch
|
||||
.topbar {text-align: center;}
|
||||
#navbar, #menu {float: none;}
|
||||
#navbar {font-size: 1.2em; padding: .6em 0 1.2em;}
|
||||
#menu {padding: 0 0 1.5em;}
|
||||
#menu select {font-size: 1.2em; margin: 0; padding: 0;}
|
||||
.topbar {text-align:center}
|
||||
#navbar,#menu {float:none}
|
||||
#navbar {font-size:1.2em; padding:.6em 0 1.2em}
|
||||
#menu {padding:0 0 1.5em}
|
||||
#menu select {font-size:1.2em; margin:0; padding:0}
|
||||
|
||||
div.flash {top: 110px; right: 10px;}
|
||||
div.flash {top:110px; right:10px}
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
*Grid
|
||||
@@ -193,43 +184,47 @@ div.error {
|
||||
* will look better with the declarations below
|
||||
* if needed to remove base.css consider keeping these following lines in some css file.
|
||||
*/
|
||||
// .web2py_table { border: 1px solid #ccc; }
|
||||
.web2py_paginator { }
|
||||
.web2py_grid {width: 100% }
|
||||
.web2py_grid table { width: 100% }
|
||||
// .web2py_table {border:1px solid #ccc}
|
||||
.web2py_paginator {}
|
||||
.web2py_grid {width:100%}
|
||||
.web2py_grid table {width:100%}
|
||||
.web2py_grid tbody td {
|
||||
padding: 2px 5px 2px 5px;
|
||||
vertical-align: middle;
|
||||
padding:2px 5px 2px 5px;
|
||||
vertical-align:middle;
|
||||
}
|
||||
|
||||
.web2py_grid thead th, .web2py_grid tfoot td {
|
||||
.web2py_grid thead th,.web2py_grid tfoot td {
|
||||
background-color:#EAEAEA;
|
||||
padding: 10px 5px 10px 5px;
|
||||
padding:10px 5px 10px 5px;
|
||||
}
|
||||
|
||||
.web2py_grid tr.odd {background-color: #F9F9F9;}
|
||||
.web2py_grid tr:hover {background-color: #F5F5F5; }
|
||||
.web2py_grid tr.odd {background-color:#F9F9F9}
|
||||
.web2py_grid tr:hover {background-color:#F5F5F5}
|
||||
|
||||
/*
|
||||
.web2py_breadcrumbs a {
|
||||
line-height: 20px; margin-right: 5px; display: inline-block;
|
||||
padding: 3px 5px 3px 5px;
|
||||
font-family: 'lucida grande', tahoma, verdana, arial, sans-serif;
|
||||
color: #3C3C3D;
|
||||
text-shadow: 1px 1px 0 #FFFFFF;
|
||||
white-space: nowrap; overflow: visible; cursor: pointer;
|
||||
line-height:20px; margin-right:5px; display:inline-block;
|
||||
padding:3px 5px 3px 5px;
|
||||
font-family:'lucida grande',tahoma,verdana,arial,sans-serif;
|
||||
color:#3C3C3D;
|
||||
text-shadow:1px 1px 0 #FFFFFF;
|
||||
white-space:nowrap; overflow:visible; cursor:pointer;
|
||||
background:#ECECEC;
|
||||
border: 1px solid #CACACA;
|
||||
-webkit-border-radius: 2px; -moz-border-radius: 2px;
|
||||
-webkit-background-clip: padding-box; border-radius: 2px;
|
||||
outline: none; position: relative; zoom: 1; *display: inline;
|
||||
border:1px solid #CACACA;
|
||||
-webkit-border-radius:2px; -moz-border-radius:2px;
|
||||
-webkit-background-clip:padding-box; border-radius:2px;
|
||||
outline:none; position:relative; zoom:1; *display:inline;
|
||||
}
|
||||
*/
|
||||
|
||||
.web2py_console form {
|
||||
width:100%;
|
||||
display:inline;
|
||||
}
|
||||
|
||||
.web2py_console form select {
|
||||
margin:0;
|
||||
}
|
||||
|
||||
.web2py_search_actions{
|
||||
float:left;
|
||||
@@ -238,14 +233,14 @@ div.error {
|
||||
|
||||
.web2py_grid .row_buttons {
|
||||
min-height:25px;
|
||||
vertical-align: middle;
|
||||
vertical-align:middle;
|
||||
}
|
||||
.web2py_grid .row_buttons a {
|
||||
margin: 3px;
|
||||
margin:3px;
|
||||
}
|
||||
|
||||
.web2py_search_actions {
|
||||
width: 100%;
|
||||
width:100%;
|
||||
}
|
||||
|
||||
.web2py_grid .row_buttons a,
|
||||
@@ -254,13 +249,13 @@ div.error {
|
||||
.web2py_console input[type=submit],
|
||||
.web2py_console input[type=button],
|
||||
.web2py_console button {
|
||||
line-height: 20px;
|
||||
margin-right: 5px; display: inline-block;
|
||||
padding: 3px 5px 3px 5px;
|
||||
line-height:20px;
|
||||
margin-right:5px; display:inline-block;
|
||||
padding:3px 5px 3px 5px;
|
||||
}
|
||||
|
||||
.web2py_counter {
|
||||
margin-top: 5px;
|
||||
margin-top:5px;
|
||||
margin-right:5px;
|
||||
width:35%;
|
||||
float:right;
|
||||
@@ -268,37 +263,37 @@ div.error {
|
||||
}
|
||||
|
||||
/*Fix firefox problem*/
|
||||
.web2py_table {clear: both; display: block;}
|
||||
.web2py_table {clear:both; display:block}
|
||||
|
||||
.web2py_paginator {
|
||||
padding: 5px;
|
||||
padding:5px;
|
||||
text-align:right;
|
||||
background-color: #f2f2f2;
|
||||
background-color:#f2f2f2;
|
||||
|
||||
}
|
||||
.web2py_paginator ul {
|
||||
list-style-type: none;
|
||||
margin: 0px;
|
||||
padding: 0px;
|
||||
list-style-type:none;
|
||||
margin:0px;
|
||||
padding:0px;
|
||||
}
|
||||
|
||||
.web2py_paginator ul li {
|
||||
display: inline;
|
||||
display:inline;
|
||||
}
|
||||
|
||||
.web2py_paginator .current {
|
||||
font-weight: bold;
|
||||
font-weight:bold;
|
||||
}
|
||||
|
||||
#w2p_query_panel {}
|
||||
|
||||
.web2py_breadcrumbs ul {
|
||||
list-style: none;
|
||||
margin-bottom: 18px;
|
||||
list-style:none;
|
||||
margin-bottom:18px;
|
||||
}
|
||||
|
||||
.web2py_breadcrumbs ul li {
|
||||
display: inline-block;
|
||||
display:inline-block;
|
||||
}
|
||||
|
||||
.ie9 #query_panel {padding-bottom:2px;}
|
||||
.ie9 #query_panel {padding-bottom:2px}
|
||||
|
||||
@@ -44,6 +44,12 @@ function web2py_event_handlers() {
|
||||
doc.on('keyup', 'input.double, input.decimal', function(){this.value=this.value.reverse().replace(/[^0-9\-\.,]|[\-](?=.)|[\.,](?=[0-9]*[\.,])/g,'').reverse();});
|
||||
var confirm_message = (typeof w2p_ajax_confirm_message != 'undefined') ? w2p_ajax_confirm_message : "Are you sure you want to delete this object?";
|
||||
doc.on('click', "input[type='checkbox'].delete", function(){if(this.checked) if(!confirm(confirm_message)) this.checked=false;});
|
||||
doc.ajaxSuccess(function(e, xhr) {
|
||||
var redirect=xhr.getResponseHeader('web2py-redirect-location');
|
||||
if (redirect != null) {
|
||||
window.location = redirect;
|
||||
};
|
||||
});
|
||||
};
|
||||
|
||||
jQuery(function() {
|
||||
@@ -98,8 +104,8 @@ function web2py_ajax_page(method, action, data, target) {
|
||||
eval(decodeURIComponent(command));
|
||||
if(flash)
|
||||
jQuery('.flash').html(decodeURIComponent(flash)).slideDown();
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function web2py_component(action, target, timeout, times){
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
{{pass}}
|
||||
{{pass}}
|
||||
<h3>
|
||||
{{=A("%s.%s" % (db,table),_href=URL('select',args=[db],vars=dict(query=qry)))}}
|
||||
{{=A("%s.%s" % (db,table),_href=URL('select',args=[db],vars=dict(query=qry)))}}
|
||||
</h3>
|
||||
[ {{=A(str(T('insert new'))+' '+table,_href=URL('insert',args=[db,table]))}} ]
|
||||
<br /><br />
|
||||
@@ -50,7 +50,7 @@
|
||||
{{=T('Use (...)&(...) for AND, (...)|(...) for OR, and ~(...) for NOT to build more complex queries.')}}<br/>
|
||||
{{=T('"update" is an optional expression like "field1=\'newvalue\'". You cannot update or delete the results of a JOIN')}}</p>
|
||||
<br/><br/>
|
||||
<h4>{{=nrows}} {{=T("selected")}}</h4>
|
||||
<h4>{{=T("%s selected", nrows)}}</h4>
|
||||
{{if start>0:}}[ {{=A(T('previous 100 rows'),_href=URL('select',args=request.args[0],vars=dict(start=start-100)))}} ]{{pass}}
|
||||
{{if stop<nrows:}}[ {{=A(T('next 100 rows'),_href=URL('select',args=request.args[0],vars=dict(start=start+100)))}} ]{{pass}}
|
||||
{{if rows:}}
|
||||
@@ -62,10 +62,7 @@
|
||||
{{pass}}
|
||||
<br/><br/><h3>{{=T("Import/Export")}}</h3><br/>
|
||||
[ <a href="{{=URL('csv',args=request.args[0],vars=dict(query=query))}}">{{=T("export as csv file")}}</a> ]
|
||||
{{if table:}}
|
||||
{{=FORM(str(T('or import from csv file'))+" ",INPUT(_type='file',_name='csvfile'),INPUT(_type='hidden',_value=table,_name='table'),INPUT(_type='submit',_value=T('import')))}}
|
||||
{{pass}}
|
||||
|
||||
{{=formcsv or ''}}
|
||||
|
||||
{{elif request.function=='insert':}}
|
||||
<h2>{{=T("database")}} {{=A(request.args[0],_href=URL('index'))}}
|
||||
@@ -108,40 +105,34 @@
|
||||
|
||||
|
||||
{{elif request.function == 'ccache':}}
|
||||
<h2>Cache</h2>
|
||||
<h2>{{T("Cache")}}</h2>
|
||||
<div class="list">
|
||||
|
||||
<div class="list-header">
|
||||
<h3>Statistics</h3>
|
||||
<h3>{{T("Statistics")}}</h3>
|
||||
</div>
|
||||
|
||||
<div class="content">
|
||||
<h4>Overview</h4>
|
||||
<p>Number of entries: <strong>{{=total['entries']}}</strong>
|
||||
{{if total['entries'] > 0:}}
|
||||
</p>
|
||||
<h4>{{=T("Overview")}}</h4>
|
||||
<p>{{=T.M("Number of entries: **%s**", total['entries'])}}</p>
|
||||
{{if total['entries'] > 0:}}
|
||||
<p>{{=T.M("Hit Ratio: **%(ratio)s%%** (**%(hits)s** %%{hit(hits)} and **%(misses)s** %%{miss(misses})",
|
||||
dict(ratio=total['ratio'], hits=total['hits'], misses=total['misses']))}}
|
||||
</p>
|
||||
<p>
|
||||
Hit Ratio:
|
||||
<strong>{{=total['ratio']}}%</strong>
|
||||
(<strong>{{=total['hits']}}</strong> hits
|
||||
and <strong>{{=total['misses']}}</strong> misses)
|
||||
</p>
|
||||
<p>
|
||||
Size of cache:
|
||||
{{=T("Size of cache:")}}
|
||||
{{if object_stats:}}
|
||||
<strong>{{=total['objects']}}</strong> items,
|
||||
<strong>{{=total['bytes']}}</strong> bytes
|
||||
{{if total['bytes'] > 524287:}}
|
||||
(<strong>{{="%.0d" % (total['bytes'] / 1048576)}} MB</strong>)
|
||||
{{pass}}
|
||||
{{else:}} <strong>not available</strong> (requires the Python <a href="http://pypi.python.org/pypi/guppy/" target="_blank">guppy</a> library)
|
||||
{{=T.M("**%(items)s** %%{item(items)}, **%(bytes)s** %%{byte(bytes)}", dict(items=total['objects'], bytes=total['bytes']))}}
|
||||
{{if total['bytes'] > 524287:}}
|
||||
{{=T.M("(**%.0d MB**)", total['bytes'] / 1048576)}}
|
||||
{{pass}}
|
||||
{{else:}}
|
||||
{{=T.M("**not available** (requires the Python [[guppy http://pypi.python.org/pypi/guppy/ popup]] library)")}}
|
||||
{{pass}}
|
||||
</p>
|
||||
<p>
|
||||
Cache contains items up to
|
||||
<strong>{{="%02d" % total['oldest'][0]}}</strong> hours
|
||||
<strong>{{="%02d" % total['oldest'][1]}}</strong> minutes
|
||||
<strong>{{="%02d" % total['oldest'][2]}}</strong> seconds old.
|
||||
{{=T.M("Cache contains items up to **%(hours)02d** %%{hour(hours)} **%(min)02d** %%{minute(min)} **%(sec)02d** %%{second(sec)} old.",
|
||||
dict(hours=total['oldest'][0], min=total['oldest'][1], sec=total['oldest'][2]))}}
|
||||
</p>
|
||||
{{=BUTTON(T('Cache Keys'), _onclick='jQuery("#all_keys").toggle();')}}
|
||||
<div class="hidden" id="all_keys">
|
||||
@@ -150,31 +141,26 @@
|
||||
<br />
|
||||
{{pass}}
|
||||
|
||||
<h4>RAM</h4>
|
||||
<p>Number of entries: <strong>{{=ram['entries']}}</strong>
|
||||
{{if ram['entries'] > 0:}}</p>
|
||||
<p>
|
||||
Hit Ratio:
|
||||
<strong>{{=ram['ratio']}}%</strong>
|
||||
(<strong>{{=ram['hits']}}</strong> hits
|
||||
and <strong>{{=ram['misses']}}</strong> misses)
|
||||
<h4>{{=T("RAM")}}</h4>
|
||||
<p>{{=T.M("Number of entries: **%s**", ram['entries'])}}</p>
|
||||
{{if ram['entries'] > 0:}}
|
||||
<p>{{=T.M("Hit Ratio: **%(ratio)s%%** (**%(hits)s** %{hit(hits)} and **%(misses)s** %%{miss(misses)})",
|
||||
dict( ratio=ram['ratio'], hits=ram['hits'], misses=ram['misses']))}}
|
||||
</p>
|
||||
<p>
|
||||
Size of cache:
|
||||
{{=T("Size of cache:")}}
|
||||
{{if object_stats:}}
|
||||
<strong>{{=ram['objects']}}</strong> items,
|
||||
<strong>{{=ram['bytes']}}</strong> bytes
|
||||
{{if ram['bytes'] > 524287:}}
|
||||
(<strong>{{=ram['bytes'] / 1048576}} MB</strong>)
|
||||
{{pass}}
|
||||
{{else:}} <strong>not available</strong> (requires the Python <a href="http://pypi.python.org/pypi/guppy/" target="_blank">guppy</a> library)
|
||||
{{=T.M("**%(items)s** items, **%(bytes)s** %%{byte(bytes)}", dict(items=ram['objects'], bytes=ram['bytes']))}}
|
||||
{{if ram['bytes'] > 524287:}}
|
||||
{{=T.M("(**%.0d MB**)", ram['bytes'] / 10485576)}}
|
||||
{{pass}}
|
||||
{{else:}}
|
||||
{{=T.M("``**not available**``:red (requires the Python [[guppy http://pypi.python.org/pypi/guppy/ popup]] library)")}}
|
||||
{{pass}}
|
||||
</p>
|
||||
<p>
|
||||
RAM contains items up to
|
||||
<strong>{{="%02d" % ram['oldest'][0]}}</strong> hours
|
||||
<strong>{{="%02d" % ram['oldest'][1]}}</strong> minutes
|
||||
<strong>{{="%02d" % ram['oldest'][2]}}</strong> seconds old.
|
||||
{{=T.M("RAM contains items up to **%(hours)02d** %%{hour(hours)} **%(min)02d** %%{minute(min)} **%(sec)02d** %%{second(sec)} old.",
|
||||
dict(hours=ram['oldest'][0], min=ram['oldest'][1], sec=ram['oldest'][2]))}}
|
||||
</p>
|
||||
{{=BUTTON(T('RAM Cache Keys'), _onclick='jQuery("#ram_keys").toggle();')}}
|
||||
<div class="hidden" id="ram_keys">
|
||||
@@ -183,43 +169,38 @@
|
||||
<br />
|
||||
{{pass}}
|
||||
|
||||
<h4>DISK</h4>
|
||||
<p>Number of entries: <strong>{{=disk['entries']}}</strong>
|
||||
{{if disk['entries'] > 0:}}
|
||||
</p>
|
||||
<p>
|
||||
Hit Ratio:
|
||||
<strong>{{=disk['ratio']}}%</strong>
|
||||
(<strong>{{=disk['hits']}}</strong> hits
|
||||
and <strong>{{=disk['misses']}}</strong> misses)
|
||||
</p>
|
||||
<p>
|
||||
Size of cache:
|
||||
<h4>{{=T("DISK")}}</h4>
|
||||
<p>{{=T.M("Number of entries: **%s**", disk['entries'])}}</p>
|
||||
{{if disk['entries'] > 0:}}
|
||||
<p>
|
||||
{{=T.M("Hit Ratio: **%(ratio)s%%** (**%(hits)s** %%{hit(hits)} and **%(misses)s** %%{miss(misses)})",
|
||||
dict(ratio=disk['ratio'], hits=disk['hits'], misses=disk['misses']))}}
|
||||
</p>
|
||||
<p>
|
||||
{{=T("Size of cache:")}}
|
||||
{{if object_stats:}}
|
||||
<strong>{{=disk['objects']}}</strong> items,
|
||||
<strong>{{=disk['bytes']}}</strong> bytes
|
||||
{{if disk['bytes'] > 524287:}}
|
||||
(<strong>{{=disk['bytes'] / 1048576}} MB</strong>)
|
||||
{{=T.M("**%(items)s** %%{item(items)}, **%(bytes)s** %%{byte(bytes)}", dict( items=disk['objects'], bytes=disk['bytes']))}}
|
||||
{{if disk['bytes'] > 524287:}}
|
||||
{{=T.M("(**%.0d MB**)", disk['bytes'] / 1048576)}}
|
||||
{{pass}}
|
||||
{{else:}}
|
||||
{{=T.M("``**not available**``:red (requires the Python [[guppy http://pypi.python.org/pypi/guppy/ popup]] library)")}}
|
||||
{{pass}}
|
||||
{{else:}} <strong>not available</strong> (requires the Python <a href="http://pypi.python.org/pypi/guppy/" target="_blank">guppy</a> library)
|
||||
{{pass}}
|
||||
</p>
|
||||
<p>
|
||||
DISK contains items up to
|
||||
<strong>{{="%02d" % disk['oldest'][0]}}</strong> hours
|
||||
<strong>{{="%02d" % disk['oldest'][1]}}</strong> minutes
|
||||
<strong>{{="%02d" % disk['oldest'][2]}}</strong> seconds old.
|
||||
</p>
|
||||
{{=BUTTON(T('Disk Cache Keys'), _onclick='jQuery("#disk_keys").toggle();')}}
|
||||
<div class="hidden" id="disk_keys">
|
||||
</p>
|
||||
<p>
|
||||
{{=T.M("DISK contains items up to **%(hours)02d** %%{hour(hours)} **%(min)02d** %%{minute(min)} **%(sec)02d** %%{second(sec)} old.",
|
||||
dict(hours=disk['oldest'][0], min=disk['oldest'][1], sec=disk['oldest'][2]))}}
|
||||
</p>
|
||||
{{=BUTTON(T('Disk Cache Keys'), _onclick='jQuery("#disk_keys").toggle();')}}
|
||||
<div class="hidden" id="disk_keys">
|
||||
{{=disk['keys']}}
|
||||
</div>
|
||||
<br />
|
||||
</div>
|
||||
<br />
|
||||
{{pass}}
|
||||
</div>
|
||||
|
||||
<div class="list-header">
|
||||
<h3>Manage Cache</h3>
|
||||
<h3>{{=T("Manage Cache")}}</h3>
|
||||
</div>
|
||||
|
||||
<div class="content">
|
||||
|
||||
@@ -90,7 +90,7 @@
|
||||
<a href="{{=URL('static', 'artwork.tar.gz')}}" >Download WEB2PY artwork pack in editable .png format</a>
|
||||
</p>
|
||||
<p>
|
||||
Logo, Stickers and Layout developed by <a target="_blank" href="http://twitter.com/josev2010">José V. Sousa</a> and <a target="_blank" href="http://twitter.com/rochacbruno">Bruno Rocha</a> (at <a target="_blank" href="http://www.blouweb.com">Blouweb</a>) All rights reserved by <a target="_blank" href="http://mycti.cti.depaul.edu/people/facultyInfo_mycti.asp?id=343">Massimo Di Pierro</a> © 2010
|
||||
Logo, Stickers and Layout developed by <a target="_blank" href="http://twitter.com/josev2010">José V. Sousa</a> and <a target="_blank" href="http://twitter.com/rochacbruno">Bruno Rocha</a> (at <a target="_blank" href="http://www.blouweb.com">Blouweb</a>) All rights reserved by <a target="_blank" href="http://mycti.cti.depaul.edu/people/facultyInfo_mycti.asp?id=343">Massimo Di Pierro</a> © {{=request.now.year}}
|
||||
</p>
|
||||
<p>
|
||||
Favicon and HTML5 compatibility by <a target="_blank" href="">Martin Mulone</a>
|
||||
|
||||
@@ -354,7 +354,7 @@ def form():
|
||||
|
||||
<p>You can find more examples of the web2py Database Abstraction Layer <a href="http://www.web2py.com/book/default/chapter/06">here</a></p>
|
||||
|
||||
<p>Let's create a simple model with users, dogs, products and purchases (the database of an animal store). Users can have many dogs (ONE TO MANY), can buy many products and every product can have many buyers (MANY TO MANY).</p>
|
||||
<p>Let's create a simple model with users, products (sold by users) and purchases (the database of an animal store). Each user can sell many products (ONE TO MANY). A user can buy many products and each product can have many buyers (MANY TO MANY).</p>
|
||||
|
||||
<h3>Example {{=c}}{{c+=1}}</h3><b>in model: db.py</b>
|
||||
{{=CODE("""
|
||||
@@ -364,21 +364,14 @@ db.define_table(
|
||||
Field('email'),
|
||||
format = '%(name)s')
|
||||
|
||||
# ONE (person) TO MANY (dogs)
|
||||
|
||||
db.define_table(
|
||||
'dog',
|
||||
Field('owner_id', db.person),
|
||||
Field('name'),
|
||||
Field('type'),
|
||||
Field('vaccinated', 'boolean', default=False),
|
||||
Field('picture', 'upload', default=''),
|
||||
format = '%(name)s')
|
||||
# ONE (person) TO MANY (products)
|
||||
|
||||
db.define_table(
|
||||
'product',
|
||||
Field('seller_id',db_person),
|
||||
Field('name'),
|
||||
Field('description', 'text'),
|
||||
Field('picture', 'upload', default=''),
|
||||
format = '%(name)s')
|
||||
|
||||
# MANY (persons) TO MANY (purchases)
|
||||
@@ -396,8 +389,7 @@ purchased = \
|
||||
|
||||
db.person.name.requires = IS_NOT_EMPTY()
|
||||
db.person.email.requires = [IS_EMAIL(), IS_NOT_IN_DB(db, 'person.email')]
|
||||
db.dog.name.requires = IS_NOT_EMPTY()
|
||||
db.dog.type.requires = IS_IN_SET(('small', 'medium', 'large'))
|
||||
db.product.name.requires = IS_NOT_EMPTY()
|
||||
db.purchase.quantity.requires = IS_INT_IN_RANGE(0, 10)
|
||||
""".strip(),language='web2py',link=URL('global','vars'),_class='boxCode')}}
|
||||
<p>
|
||||
@@ -407,20 +399,18 @@ db.purchase.quantity.requires = IS_INT_IN_RANGE(0, 10)
|
||||
<br/><br/>
|
||||
define_tables creates the table and attempts a migration if table has changed or if database name has changed since last time. If you know you already have the table in the database and you do not want to attempt a migration add one last argument to define_table <tt>migrate=False</tt>.</p>
|
||||
|
||||
|
||||
<h3>Example {{=c}}{{c+=1}}</h3><b>In controller: database_examples.py </b>
|
||||
{{=CODE("""
|
||||
response.menu = [['Register Person', False, URL('register_person')],
|
||||
['Register Dog', False, URL('register_dog')],
|
||||
['Register Product', False, URL('register_product')],
|
||||
['Buy product', False, URL('buy')]]
|
||||
|
||||
def register_person():
|
||||
# create an insert form from the table
|
||||
form = SQLFORM(db.person)
|
||||
form = SQLFORM(db.person).process()
|
||||
|
||||
# if form correct perform the insert
|
||||
if form.process().accepted:
|
||||
if form.accepted:
|
||||
response.flash = 'new record inserted'
|
||||
|
||||
# and get a list of all persons
|
||||
@@ -432,39 +422,21 @@ def register_person():
|
||||
<p>This is a simple user registration form. SQLFORM takes a table and returns the corresponding entry form with validators, etc. SQLFORM.accepts is similar to FORM.accepts but, if form is validated, the corresponding insert is also performed. SQLFORM can also do update and edit if a record is passed as its second argument.
|
||||
SQLTABLE instead turns a set of records (result of a select) into an HTML table with links as specified by its optional parameters.
|
||||
The response.menu on top is just a variable used by the layout to make the navigation menu for all functions in this controller.<br/>
|
||||
Try it here: <a href="/{{=request.application}}/database_examples/register_person">register_person</a></p>
|
||||
|
||||
<h3>Example {{=c}}{{c+=1}}</h3><b>In controller: database_examples.py </b>
|
||||
{{=CODE("""
|
||||
|
||||
|
||||
def register_dog():
|
||||
form = SQLFORM(db.dog)
|
||||
if form.process().accepted:
|
||||
response.flash = 'new record inserted'
|
||||
download = URL('download') # to see the picture
|
||||
records = SQLTABLE(db().select(db.dog.ALL), upload=download,
|
||||
headers='fieldname:capitalize')
|
||||
return dict(form=form, records=records)
|
||||
|
||||
""".strip(),language='web2py',link=URL('global','vars'),_class='boxCode')}}<b>and view: database_examples/register_dog.html</b>
|
||||
{{=CODE(open(os.path.join(request.folder,'views/database_examples/register_dog.html'),'r').read(),language='html',link=URL('global','vars'),_class='boxCode')}}
|
||||
<p>Here is a dog registration form. Notice that the "image" (type "upload") field is rendered into a <INPUT type="file"> html tag. SQLFORM.accepts(...) handles the upload of the file into the uploads/ folder.
|
||||
<br/>Try it here: <a href="/{{=request.application}}/database_examples/register_dog">register_dog</a></p>
|
||||
|
||||
<h3>Example {{=c}}{{c+=1}}</h3><b>In controller: database_examples.py </b>
|
||||
{{=CODE("""
|
||||
def register_product():
|
||||
form = SQLFORM(db.product)
|
||||
if form.process().accepted:
|
||||
form = SQLFORM(db.product).process()
|
||||
if form.accepted:
|
||||
response.flash = 'new record inserted'
|
||||
records = SQLTABLE(db().select(db.product.ALL),headers='fieldname:capitalize')
|
||||
records = SQLTABLE(db().select(db.product.ALL),
|
||||
upload = URL('download'), # allows pics preview
|
||||
headers='fieldname:capitalize')
|
||||
return dict(form=form, records=records)
|
||||
|
||||
""".strip(),language='web2py',link=URL('global','vars'),_class='boxCode')}}<b>and view: database_examples/register_product.html</b>
|
||||
{{=CODE(open(os.path.join(request.folder,'views/database_examples/register_product.html'),'r').read(),language='html',link=URL('global','vars'),_class='boxCode')}}
|
||||
<p>Nothing new here.
|
||||
<br/>Try it here: <a href="/{{=request.application}}/database_examples/register_product">register_product</a></p>
|
||||
|
||||
<h3>Example {{=c}}{{c+=1}}</h3><b>In controller: database_examples.py </b>
|
||||
{{=CODE("""
|
||||
@@ -473,8 +445,8 @@ def buy():
|
||||
form = SQLFORM.factory(
|
||||
Field('buyer_id',requires=IS_IN_DB(db,db.person.id,'%(name)s')),
|
||||
Field('product_id',requires=IS_IN_DB(db,db.product.id,'%(name)s')),
|
||||
Field('quantity','integer',requires=IS_INT_IN_RANGE(1,100)))
|
||||
if form.process().accepted:
|
||||
Field('quantity','integer',requires=IS_INT_IN_RANGE(1,100))).process()
|
||||
if form.accepted:
|
||||
# get previous purchese for same product
|
||||
purchase = db((db.purchase.buyer_id == form.vars.buyer_id)&
|
||||
(db.purchase.product_id==form.vars.product_id)).select().first()
|
||||
@@ -498,22 +470,25 @@ def buy():
|
||||
""".strip(),language='web2py',link=URL('global','vars'),_class='boxCode')}}<b>and view: database_examples/buy.html</b>
|
||||
{{=CODE(open(os.path.join(request.folder,'views/database_examples/buy.html'),'r').read(),language='html',link=URL('global','vars'),_class='boxCode')}}
|
||||
<p>Here is a rather sophisticated buy form. It checks that the buyer and the product are in the database and updates the corresponding record or inserts a new purchase. It also does a JOIN to list all purchases.
|
||||
<br/>Try it here: <a href="/{{=request.application}}/database_examples/buy">buy</a></p>
|
||||
|
||||
<h3>Example {{=c}}{{c+=1}}</h3><b>In controller: database_examples.py</b>
|
||||
{{=CODE("""
|
||||
def delete_purchased():
|
||||
db(db.purchase.id > 0).delete()
|
||||
redirect(URL('buy'))
|
||||
""".strip(),language='web2py',link=URL('global','vars'),_class='boxCode')}}Try it here: <a href="/{{=request.application}}/database_examples/delete_purchased">delete_purchased</a>
|
||||
|
||||
<h3>Example {{=c}}{{c+=1}}</h3><b>In controller: database_examples.py</b>
|
||||
{{=CODE("""
|
||||
def download():
|
||||
return response.download(request,db)
|
||||
""".strip(),language='web2py',link=URL('global','vars'),_class='boxCode')}}
|
||||
<p>This controller allows users to download the uploaded pictures of the dogs.
|
||||
Remember the upload=URL(...'download'...) statement in the register_dog function. Notice that in the URL path /application/controller/function/a/b/etc a, b, etc are passed to the controller as request.args[0], request.args[1], etc. Since the URL is validated request.args[] always contain valid filenames and no '~' or '..' etc. This is useful to allow visitors to link uploaded files.</p>
|
||||
<p>This controller allows users to download the uploaded pictures of products.
|
||||
Remember the upload=URL('download') statement in the register_product function. Notice that in the URL path /application/controller/function/a/b/etc a, b, etc are passed to the controller as request.args[0], request.args[1], etc. Since the URL is validated request.args[] always contain valid filenames and no '~' or '..' etc. This is useful to allow visitors to link uploaded files.</p>
|
||||
|
||||
<h3>Example {{=c}}{{c+=1}}</h3><b>Using a Smartgrid</b>
|
||||
<p>All of the above database examples can be condensed in one simple command using the SQLFORM.smartgrid:</p>
|
||||
{{=CODE("""
|
||||
def manage_transactions():
|
||||
grid = SQLFORM.smartgrid(db.person,linked_tables=['product','purchase'],
|
||||
user_signature=False)
|
||||
return dict(grid=grid)
|
||||
""".strip(),language='web2py',link=URL('global','vars'),_class='boxCode')}}
|
||||
|
||||
The SQLFORM.smartgrid allows to create/read/delete persons as well as records in the linked tables (product and purchase). It also allows searching with pagination. It can be highly customized. The user_signature=False disables grid access control features which are beyond this simple example.
|
||||
|
||||
<h2 id="cache_examples">Cache Examples</h2>
|
||||
|
||||
@@ -593,7 +568,6 @@ def cache_db_select():
|
||||
return dict(records=records)
|
||||
""".strip(),language='web2py',link=URL('global','vars'),_class='boxCode')}}
|
||||
<p>The results of a select are complex unpickleable objects that cannot be cached using the previous method, but the select command takes an argument <tt>cache=(cache_model,time_expire)</tt> and will cache the result of the query accordingly. Notice that the key is not necessary since key is generated based on the database name and the select string.
|
||||
<br/>Try it here: <a href="/{{=request.application}}/cache_examples/cache_db_select">cache_db_select</a></p>
|
||||
|
||||
<h2 id="ajax_examples">Ajax Examples</h2>
|
||||
|
||||
|
||||
@@ -1,5 +1,18 @@
|
||||
{{right_sidebar_enabled=True}}
|
||||
{{extend 'layout.html'}}
|
||||
{{
|
||||
import random
|
||||
quotes = [
|
||||
("web2py was the life saver today for me, my blog post: Standalone Usage of web2py's", "caglartoklu", "http://twitter.com/#!/caglartoklu/status/84292131707031553"),
|
||||
("Get Things Done - Faster, Better and More Easily with web2py",
|
||||
"Bruno Rocha", "http://twitter.com/#!/rochacbruno/status/73583156044890112"),
|
||||
("Please use www.web2py.com when using MVC , no PHP/SQL stuff please...its 2011 not 1999", "rabblesoft", "http://twitter.com/#!/rabblesoft/status/79189028431343616"),
|
||||
('web2py rules! as a sysadmin I like the no installation and no configuration approach a lot)', "kjogut", "http://twitter.com/#!/jkogut/status/61414554273447936"),
|
||||
("web2py it is. Compatible with everything under the sun and great interfaces to googleappengine", "comamitc","http://twitter.com/#!/comamitc/status/51744719071477760"),
|
||||
("If you are still learning python, web2py is best tool by far", "pbreit", "http://twitter.com/#!/pbreit/status/48260905775017984")
|
||||
]
|
||||
random.shuffle(quotes)
|
||||
}}
|
||||
|
||||
<table width="100%">
|
||||
<tr>
|
||||
|
||||
@@ -122,7 +122,7 @@
|
||||
<div class="sixteen columns">
|
||||
{{block footer}} <!-- this is default footer -->
|
||||
<div class="footer-content" >
|
||||
{{=T('Copyright')}} © 2011
|
||||
{{=T('Copyright')}} © {{=request.now.year}}
|
||||
- User communities in <a href="https://groups.google.com/forum/?fromgroups#!forum/web2py" target="_blank">English<a>, <a href="https://groups.google.com/forum/?fromgroups#!forum/web2py-fr" target="_blank">French</a>, <a href="https://groups.google.com/forum/?fromgroups#!forum/web2py-japan" target="_blank">Japanese</a>, <a href="https://groups.google.com/forum/?fromgroups#!forum/web2py-users-brazil" target="_blank">Portuguese</a>, and <a href="https://groups.google.com/forum/?fromgroups#!forum/web2py-usuarios" target="_blank">Spanish</a>.
|
||||
<div style="float: right;">
|
||||
<a href="http://www.web2py.com/" style="float: left; padding-right: 6px;">
|
||||
|
||||
@@ -199,17 +199,8 @@ def select():
|
||||
_class='delete', _type='checkbox', value=False), ''),
|
||||
TR('', '', INPUT(_type='submit', _value=T('submit')))),
|
||||
_action=URL(r=request,args=request.args))
|
||||
if request.vars.csvfile != None:
|
||||
try:
|
||||
import_csv(db[request.vars.table],
|
||||
request.vars.csvfile.file)
|
||||
response.flash = T('data uploaded')
|
||||
except Exception, e:
|
||||
response.flash = DIV(T('unable to parse csv file'),PRE(str(e)))
|
||||
if form.accepts(request.vars, formname=None):
|
||||
# regex = re.compile(request.args[0] + '\.(?P<table>\w+)\.id\>0')
|
||||
regex = re.compile(request.args[0] + '\.(?P<table>\w+)\..+')
|
||||
|
||||
match = regex.match(form.vars.query.strip())
|
||||
if match:
|
||||
table = match.group('table')
|
||||
@@ -230,6 +221,23 @@ def select():
|
||||
except Exception, e:
|
||||
(rows, nrows) = ([], 0)
|
||||
response.flash = DIV(T('Invalid Query'),PRE(str(e)))
|
||||
# begin handle upload csv
|
||||
if table:
|
||||
formcsv = FORM(str(T('or import from csv file'))+" ",
|
||||
INPUT(_type='file',_name='csvfile'),
|
||||
INPUT(_type='hidden',_value=table,_name='table'),
|
||||
INPUT(_type='submit',_value=T('import')))
|
||||
else:
|
||||
formcsv = None
|
||||
if formcsv and formcsv.process().accepted and request.vars.csvfile:
|
||||
try:
|
||||
import_csv(db[request.vars.table],
|
||||
request.vars.csvfile.file)
|
||||
response.flash = T('data uploaded')
|
||||
except Exception, e:
|
||||
response.flash = DIV(T('unable to parse csv file'),PRE(str(e)))
|
||||
# end handle upload csv
|
||||
|
||||
return dict(
|
||||
form=form,
|
||||
table=table,
|
||||
@@ -238,6 +246,7 @@ def select():
|
||||
nrows=nrows,
|
||||
rows=rows,
|
||||
query=request.vars.query,
|
||||
formcsv = formcsv,
|
||||
)
|
||||
|
||||
|
||||
|
||||
@@ -6,4 +6,11 @@
|
||||
'изменена': ['изменены','изменено'],
|
||||
'строка': ['строки','строк'],
|
||||
'удалена': ['удалены','удалено'],
|
||||
'день': ['дня', 'дней'],
|
||||
'месяц': ['месяца','месяцев'],
|
||||
'неделю': ['недели','недель'],
|
||||
'год': ['года','лет'],
|
||||
'час': ['часа','часов'],
|
||||
'минуту': ['минуты','минут'],
|
||||
'секунду': ['секунды','секунд'],
|
||||
}
|
||||
|
||||
@@ -10,4 +10,8 @@
|
||||
'секунду': ['секунди','секунд'],
|
||||
'схибнення': ['схибнення','схибнень'],
|
||||
'хвилину': ['хвилини','хвилин'],
|
||||
'день': ['дні', 'днів'],
|
||||
'місяць': ['місяці','місяців'],
|
||||
'тиждень': ['тижні','тижнів'],
|
||||
'рік': ['роки','років'],
|
||||
}
|
||||
|
||||
@@ -3,11 +3,25 @@
|
||||
'!langcode!': 'ru',
|
||||
'!langname!': 'Русский',
|
||||
'"update" is an optional expression like "field1=\'newvalue\'". You cannot update or delete the results of a JOIN': '"Изменить" - необязательное выражение вида "field1=\'новое значение\'". Результаты операции JOIN нельзя изменить или удалить.',
|
||||
'%d days ago': '%d %%{день} тому',
|
||||
'%d hours ago': '%d %%{час} тому',
|
||||
'%d minutes ago': '%d %%{минуту} тому',
|
||||
'%d months ago': '%d %%{месяц} тому',
|
||||
'%d seconds ago': '%d %%{секунду} тому',
|
||||
'%d weeks ago': '%d %%{неделю} тому',
|
||||
'%d years ago': '%d %%{год} тому',
|
||||
'%s %%{row} deleted': '%%{!удалена[0]} %s %%{строка[0]}',
|
||||
'%s %%{row} updated': '%%{!изменена[0]} %s %%{строка[0]}',
|
||||
'%s selected': '%%{!выбрана[0]} %s %%{запись[0]}',
|
||||
'%Y-%m-%d': '%Y-%m-%d',
|
||||
'%Y-%m-%d %H:%M:%S': '%Y-%m-%d %H:%M:%S',
|
||||
'1 day ago': '1 день тому',
|
||||
'1 hour ago': '1 час тому',
|
||||
'1 minute ago': '1 минуту тому',
|
||||
'1 month ago': '1 месяц тому',
|
||||
'1 second ago': '1 секунду тому',
|
||||
'1 week ago': '1 неделю тому',
|
||||
'1 year ago': '1 год тому',
|
||||
'About': 'About',
|
||||
'Access Control': 'Access Control',
|
||||
'Administrative Interface': 'Administrative Interface',
|
||||
@@ -31,8 +45,8 @@
|
||||
'Current session': 'Текущая сессия',
|
||||
'customize me!': 'настройте внешний вид!',
|
||||
'data uploaded': 'данные загружены',
|
||||
'Database': 'Database',
|
||||
'database': 'база данных',
|
||||
'Database': 'Database',
|
||||
'database %s select': 'выбор базы данных %s',
|
||||
'db': 'БД',
|
||||
'DB Model': 'DB Model',
|
||||
@@ -93,6 +107,7 @@
|
||||
'new record inserted': 'новая запись добавлена',
|
||||
'next 100 rows': 'следующие 100 строк',
|
||||
'No databases in this application': 'В приложении нет баз данных',
|
||||
'now': 'сейчас',
|
||||
'Object or table name': 'Object or table name',
|
||||
'Old password': 'Старый пароль',
|
||||
'Online examples': 'примеры он-лайн',
|
||||
|
||||
@@ -3,11 +3,25 @@
|
||||
'!langcode!': 'uk',
|
||||
'!langname!': 'Українська',
|
||||
'"update" is an optional expression like "field1=\'newvalue\'". You cannot update or delete the results of a JOIN': '"Оновити" це додатковий вираз, такий, як "field1=\'нове_значення\'". Ви не можете змінювати або вилучати дані об\'єднаних таблиць.',
|
||||
'%d days ago': '%d %%{день} тому',
|
||||
'%d hours ago': '%d %%{годину} тому',
|
||||
'%d minutes ago': '%d %%{хвилину} тому',
|
||||
'%d months ago': '%d %%{місяць} тому',
|
||||
'%d secods ago': '%d %%{секунду} тому',
|
||||
'%d weeks ago': '%d %%{тиждень} тому',
|
||||
'%d years ago': '%d %%{рік} тому',
|
||||
'%s %%{row} deleted': 'Вилучено %s %%{рядок}',
|
||||
'%s %%{row} updated': 'Змінено %s %%{рядок}',
|
||||
'%s selected': 'Вибрано %s %%{запис}',
|
||||
'%Y-%m-%d': '%Y/%m/%d',
|
||||
'%Y-%m-%d %H:%M:%S': '%Y/%m/%d %H:%M:%S',
|
||||
'1 day ago': '1 день тому',
|
||||
'1 hour ago': '1 годину тому',
|
||||
'1 minute ago': '1 хвилину тому',
|
||||
'1 month ago': '1 місяць тому',
|
||||
'1 second ago': '1 секунду тому',
|
||||
'1 week ago': '1 тиждень тому',
|
||||
'1 year ago': '1 рік тому',
|
||||
'@markmin\x01(**%.0d MB**)': '(**``%.0d``:red МБ**)',
|
||||
'@markmin\x01**%(items)s** %%{item(items)}, **%(bytes)s** %%{byte(bytes)}': '**%(items)s** %%{елемент(items)}, **%(bytes)s** %%{байт(bytes)}',
|
||||
'@markmin\x01``**not available**``:red (requires the Python [[guppy http://pypi.python.org/pypi/guppy/ popup]] library)': '**нема в наявності** (потребує Пітонівської бібліотеки [[guppy {посилання відкриється у новому вікні} http://pypi.python.org/pypi/guppy/ popup]])',
|
||||
@@ -115,6 +129,7 @@
|
||||
'new record inserted': 'новий рядок додано',
|
||||
'next 100 rows': 'наступні 100 рядків',
|
||||
'No databases in this application': 'Даний додаток не використовує базу даних',
|
||||
'now': 'зараз',
|
||||
'Object or table name': "Об'єкт або назва таблиці",
|
||||
'Old password': 'Старий пароль',
|
||||
'Online examples': 'Зразковий демо-сайт',
|
||||
|
||||
@@ -13,7 +13,6 @@ response.meta.author = 'Your Name <you@example.com>'
|
||||
response.meta.description = 'a cool new app'
|
||||
response.meta.keywords = 'web2py, python, framework'
|
||||
response.meta.generator = 'Web2py Web Framework'
|
||||
response.meta.copyright = 'Copyright 2011'
|
||||
|
||||
## your http://google.com/analytics id
|
||||
response.google_analytics_id = None
|
||||
@@ -36,7 +35,7 @@ def _():
|
||||
ctr = request.controller
|
||||
# useful links to internal and external resources
|
||||
response.menu+=[
|
||||
(SPAN('web2py',_style='color:yellow'),False, None, [
|
||||
(SPAN('web2py',_style='color:yellow'),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,
|
||||
|
||||
@@ -1,112 +1,130 @@
|
||||
#navbar{padding-top:9px;}
|
||||
body {
|
||||
padding-top: 60px;
|
||||
}
|
||||
|
||||
#navbar .auth_navbar, #navbar .auth_navbar a {color:inherit;}
|
||||
|
||||
@media only screen and (max-width: 479px) {
|
||||
div.flash {
|
||||
right: 5px;
|
||||
}
|
||||
/* bootstrap dropdown */
|
||||
|
||||
.dropdown-menu ul {
|
||||
left: 100%;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
visibility: hidden;
|
||||
margin-top: -1px;
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 767px) {
|
||||
.dropdown-menu li:hover ul {
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
.mastheader h1 {
|
||||
margin-bottom: 9px;
|
||||
font-size: 81px;
|
||||
font-weight: bold;
|
||||
letter-spacing: -1px;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
.mastheader h1 {
|
||||
font-size: 54px;
|
||||
}
|
||||
|
||||
.mastheader small {
|
||||
font-size: 20px;
|
||||
font-weight: 300;
|
||||
}
|
||||
|
||||
.navbar .dropdown-menu ul:before {
|
||||
border-bottom: 7px solid transparent;
|
||||
border-left: none;
|
||||
border-right: 7px solid rgba(0, 0, 0, 0.2);
|
||||
border-top: 7px solid transparent;
|
||||
left: -7px;
|
||||
top: 5px;
|
||||
}
|
||||
|
||||
.navbar .dropdown-menu ul:after {
|
||||
border-top: 6px solid transparent;
|
||||
border-left: none;
|
||||
border-right: 6px solid #fff;
|
||||
border-bottom: 6px solid transparent;
|
||||
left: 10px;
|
||||
top: 6px;
|
||||
left: -6px;
|
||||
}
|
||||
|
||||
.dropdown-menu span{
|
||||
display:inline-block;
|
||||
}
|
||||
|
||||
.chevron-right {
|
||||
border-left: 4px solid #000;
|
||||
border-right: 4px solid transparent;
|
||||
border-bottom: 4px solid transparent;
|
||||
border-top: 4px solid transparent;
|
||||
content: "";
|
||||
display: inline-block;
|
||||
height: 0;
|
||||
opacity: 0.7;
|
||||
vertical-align: top;
|
||||
width: 0;
|
||||
margin-right:-13px;
|
||||
margin-top: 7px;
|
||||
float:right;
|
||||
}
|
||||
|
||||
.open > .dropdown-menu ul { /* fix menu issue when BS2.0.4 is applied */
|
||||
display: block;
|
||||
}
|
||||
|
||||
.ie-lte7 #navbar .auth_navbar, #navbar .auth_navbar a {color:expression(this.parentNode.currentStyle['color']); /* ie7 doesn't support inherit */}
|
||||
|
||||
#navbar .auth_navbar a:hover {color:white;text-decoration:none;} /* this overwrite bootswatch */
|
||||
|
||||
body {
|
||||
height:auto; /*to avoid vertical scroll bar*/
|
||||
}
|
||||
|
||||
h1,h2,h3,h4,h5,h6 {font-family: inherit;}
|
||||
|
||||
li {margin-bottom: 0;} /*bootswatch*/
|
||||
|
||||
.auth_navbar, .navbar .btn-group { padding:0; }
|
||||
|
||||
[class^="icon-"],[class*=" icon-"]{background-image:url("../images/glyphicons-halflings.png")} /* right folder for bootstrap black images/icons */
|
||||
.icon-white{background-image:url("../images/glyphicons-halflings-white.png");} /* right folder for bootstrap white images/icons */
|
||||
|
||||
@media only screen and (max-width: 979px) {
|
||||
body {
|
||||
padding-top: 0px;
|
||||
}
|
||||
|
||||
.navbar-inner{position:relative;}
|
||||
#navbar{bottom:-10px;left:4px;}
|
||||
|
||||
div.flash {
|
||||
right: 5px;
|
||||
}
|
||||
|
||||
.dropdown-menu ul {
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@media only screen and (min-width: 768px) {
|
||||
body {
|
||||
height:auto; /*to avoid vertical scroll bar*/
|
||||
}
|
||||
|
||||
h1,h2,h3,h4,h5,h6 {font-family: inherit;}
|
||||
|
||||
li {margin-bottom: 0;} /*bootswatch*/
|
||||
|
||||
.auth_navbar, .navbar .btn-group{padding:0;}
|
||||
|
||||
.mastheader h1 {
|
||||
margin-bottom: 9px;
|
||||
font-size: 81px;
|
||||
font-weight: bold;
|
||||
letter-spacing: -1px;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
.mastheader h1 {
|
||||
font-size: 54px;
|
||||
}
|
||||
|
||||
.mastheader small {
|
||||
font-size: 20px;
|
||||
font-weight: 300;
|
||||
}
|
||||
|
||||
/* bootstrap dropdown */
|
||||
|
||||
.dropdown-menu ul {
|
||||
left: 100%;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
visibility: hidden;
|
||||
margin-top: -1px;
|
||||
}
|
||||
|
||||
.dropdown-menu li:hover ul {
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
.navbar .dropdown-menu ul:before {
|
||||
border-bottom: 7px solid transparent;
|
||||
border-left: none;
|
||||
border-right: 7px solid rgba(0, 0, 0, 0.2);
|
||||
border-top: 7px solid transparent;
|
||||
left: -7px;
|
||||
top: 5px;
|
||||
}
|
||||
|
||||
.navbar .dropdown-menu ul:after {
|
||||
border-top: 6px solid transparent;
|
||||
border-left: none;
|
||||
border-right: 6px solid #fff;
|
||||
border-bottom: 6px solid transparent;
|
||||
left: 10px;
|
||||
top: 6px;
|
||||
left: -6px;
|
||||
}
|
||||
|
||||
.dropdown-menu span{
|
||||
display:inline-block;
|
||||
}
|
||||
|
||||
.chevron-right {
|
||||
border-left: 4px solid #000;
|
||||
border-right: 4px solid transparent;
|
||||
border-bottom: 4px solid transparent;
|
||||
border-top: 4px solid transparent;
|
||||
content: "";
|
||||
display: inline-block;
|
||||
height: 0;
|
||||
opacity: 0.7;
|
||||
vertical-align: top;
|
||||
width: 0;
|
||||
margin-right:-13px;
|
||||
margin-top: 7px;
|
||||
float:right;
|
||||
}
|
||||
|
||||
.open > .dropdown-menu ul { /* fix menu issue when BS2.0.4 is applied */
|
||||
display: block;
|
||||
}
|
||||
|
||||
.ie-lte7 #navbar .auth_navbar, #navbar .auth_navbar a {color:expression(this.parentNode.currentStyle['color']); /* ie7 doesn't support inherit */}
|
||||
|
||||
#navbar .auth_navbar a:hover {color:white;text-decoration:none;} /* this overwrite bootswatch */
|
||||
|
||||
[class^="icon-"],[class*=" icon-"]{background-image:url("../images/glyphicons-halflings.png")} /* right folder for bootstrap black images/icons */
|
||||
.icon-white{background-image:url("../images/glyphicons-halflings-white.png");} /* right folder for bootstrap white images/icons */
|
||||
}
|
||||
|
||||
@media only screen and (min-width: 980px) {
|
||||
body {
|
||||
padding-top: 60px;
|
||||
}
|
||||
@media only screen and (max-width: 479px) {
|
||||
body {
|
||||
padding-left: 10px;
|
||||
padding-right: 10px;
|
||||
}
|
||||
|
||||
.navbar-fixed-top, .navbar-fixed-bottom {
|
||||
margin-left: -10px;
|
||||
margin-right: -10px;
|
||||
}
|
||||
|
||||
input[type="text"], input[type="password"], select {
|
||||
width: 95%;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,187 +1,181 @@
|
||||
/** these MUST stay **/
|
||||
a { text-decoration:none; white-space: nowrap;}
|
||||
a:hover {text-decoration: underline}
|
||||
a.button {text-decoration: none}
|
||||
h1,h2,h3,h4,h5,h6 {margin: 0.5em 0 0.25em 0; display: block; font-family: Helvetica;}
|
||||
h1 { font-size: 4.00em;}
|
||||
h2 { font-size: 3.00em;}
|
||||
h3 { font-size: 2.00em;}
|
||||
h4 { font-size: 1.50em;}
|
||||
h5 { font-size: 1.25em;}
|
||||
h6 { font-size: 1.12em;}
|
||||
right { float:right; text-align: right; }
|
||||
left { float:left; text-align: left; }
|
||||
center { width:100; text-align: center; vertical-align:middle;}
|
||||
th, label { font-weight: bold; white-space: nowrap; }
|
||||
td, th { text-align: left; padding: 2px 5px 2px 5px; }
|
||||
th { vertical-align: middle; border-right: 1px solid white;}
|
||||
td { vertical-align: top; }
|
||||
form table tr td label { text-align: left; }
|
||||
p, table, ol, ul { padding: 0.5em 0 0.5em 0 }
|
||||
p {text-align: justify }
|
||||
ol, ul { padding-left: 30px }
|
||||
li { margin-bottom: 0.5em; }
|
||||
span, input, select, textarea, button, label, a { display: inline }
|
||||
img { border: 0; }
|
||||
blockquote, blockquote p, p blockquote { font-style: italic; margin: 0.5em 30px 0.5em 30px; font-size: 0.9em}
|
||||
i, em { font-style: italic; }
|
||||
strong { font-weight: bold; }
|
||||
small { font-size: 0.8em; }
|
||||
textarea { width: 100%; }
|
||||
code { font-family: Courier;}
|
||||
video { width:400px; }
|
||||
audio { width:200px; }
|
||||
input[type=text], input[type=password], select { width: 300px; margin-right: 5px }
|
||||
ul { list-style-type: none; margin: 0px; padding: 0px; }
|
||||
a {text-decoration:none; white-space:nowrap}
|
||||
a:hover {text-decoration:underline}
|
||||
a.button {text-decoration:none}
|
||||
h1,h2,h3,h4,h5,h6 {margin:0.5em 0 0.25em 0; display:block;
|
||||
font-family:Helvetica}
|
||||
h1 {font-size:4.00em}
|
||||
h2 {font-size:3.00em}
|
||||
h3 {font-size:2.00em}
|
||||
h4 {font-size:1.50em}
|
||||
h5 {font-size:1.25em}
|
||||
h6 {font-size:1.12em}
|
||||
th,label {font-weight:bold; white-space:nowrap}
|
||||
td,th {text-align:left; padding:2px 5px 2px 5px}
|
||||
th {vertical-align:middle; border-right:1px solid white}
|
||||
td {vertical-align:top}
|
||||
form table tr td label {text-align:left}
|
||||
p,table,ol,ul {padding:0; margin: 0.5em 0}
|
||||
p {text-align:justify}
|
||||
ol, ul {list-style-position:inside}
|
||||
li {margin-bottom:0.5em}
|
||||
span,input,select,textarea,button,label,a {display:inline}
|
||||
img {border:0}
|
||||
blockquote,blockquote p,p blockquote {
|
||||
font-style:italic; margin:0.5em 30px 0.5em 30px; font-size:0.9em}
|
||||
i,em {font-style:italic}
|
||||
strong {font-weight:bold}
|
||||
small {font-size:0.8em}
|
||||
code {font-family:Courier}
|
||||
textarea {width:100%}
|
||||
video {width:400px}
|
||||
audio {width:200px}
|
||||
input[type=text],input[type=password],select{width:300px; margin-right:5px}
|
||||
.hidden {display:none;visibility:visible}
|
||||
.right {float:right; text-align:right}
|
||||
.left {float:left; text-align:left}
|
||||
.center {width:100; text-align:center; vertical-align:middle}
|
||||
/** end **/
|
||||
|
||||
/* Sticky footer begin */
|
||||
|
||||
.wrapper {
|
||||
min-height: 100%;
|
||||
height: auto !important;
|
||||
height: 100%;
|
||||
margin: 0 auto -8em; /* set last value to footer height plus footer vertical padding */
|
||||
min-height:100%;
|
||||
height:auto !important;
|
||||
height:100%;
|
||||
margin:0 auto -8em; /* set last value to footer height plus footer vertical padding */
|
||||
}
|
||||
|
||||
.main {
|
||||
padding: 20px 0 50px 0;
|
||||
padding:20px 0 50px 0;
|
||||
}
|
||||
|
||||
.footer, .push {
|
||||
height: 6em;
|
||||
padding: 1em 0;
|
||||
clear: both;
|
||||
.footer,.push {
|
||||
height:6em;
|
||||
padding:1em 0;
|
||||
clear:both;
|
||||
}
|
||||
|
||||
.footer-content {position: relative; bottom: -4em; width: 100%;}
|
||||
.footer-content {position:relative; bottom:-4em; width:100%}
|
||||
|
||||
.auth_navbar {
|
||||
white-space: nowrap;
|
||||
white-space:nowrap;
|
||||
}
|
||||
|
||||
/* Sticky footer end */
|
||||
|
||||
.footer {
|
||||
border-top: 1px #DEDEDE solid;
|
||||
border-top:1px #DEDEDE solid;
|
||||
}
|
||||
.header {
|
||||
// background: <fill here for header image>;
|
||||
// background:<fill here for header image>;
|
||||
}
|
||||
|
||||
|
||||
fieldset { padding: 16px; border-top: 1px #DEDEDE solid;}
|
||||
fieldset legend {text-transform:uppercase; font-weight: bold; padding: 4px 16px 4px 16px; background: #f1f1f1;}
|
||||
fieldset {padding:16px; border-top:1px #DEDEDE solid}
|
||||
fieldset legend {text-transform:uppercase; font-weight:bold; padding:4px 16px 4px 16px; background:#f1f1f1}
|
||||
|
||||
/* fix ie problem with menu */
|
||||
.ie-lte7 .topbar .container {z-index: 2; }
|
||||
.ie-lte7 .topbar .container {z-index:2}
|
||||
|
||||
td.w2p_fw {padding-bottom: 1px;}
|
||||
td.w2p_fl, td.w2p_fw, td.w2p_fc { vertical-align:top; }
|
||||
td.w2p_fl { text-align:right; }
|
||||
td.w2p_fl, td.w2p_fw {padding-right: 7px;}
|
||||
td.w2p_fl, td.w2p_fc { padding-top: 4px; }
|
||||
td.w2p_fw {padding-bottom:1px}
|
||||
td.w2p_fl,td.w2p_fw,td.w2p_fc {vertical-align:top}
|
||||
td.w2p_fl {text-align:right}
|
||||
td.w2p_fl, td.w2p_fw {padding-right:7px}
|
||||
td.w2p_fl,td.w2p_fc {padding-top:4px}
|
||||
|
||||
/* tr#submit_record__row {border-top: 1px solid #E5E5E5;} */
|
||||
#submit_record__row td {padding-top: .5em;}
|
||||
/* tr#submit_record__row {border-top:1px solid #E5E5E5} */
|
||||
#submit_record__row td {padding-top:.5em}
|
||||
|
||||
/* Fix */
|
||||
#auth_user_remember__row label {display: inline;}
|
||||
#web2py_user_form td { vertical-align:top; }
|
||||
#auth_user_remember__row label {display:inline}
|
||||
#web2py_user_form td {vertical-align:top}
|
||||
|
||||
/*********** web2py specific ***********/
|
||||
div.flash {
|
||||
font-weight: bold;
|
||||
display: none;
|
||||
position: fixed;
|
||||
padding: 10px;
|
||||
top: 48px;
|
||||
right: 50px;
|
||||
min-width: 280px;
|
||||
opacity: 0.85;
|
||||
margin: 0px 0px 10px 10px;
|
||||
color: #fff;
|
||||
vertical-align: middle;
|
||||
cursor: pointer;
|
||||
background: #000;
|
||||
border: 2px solid #fff;
|
||||
border-radius: 5px;
|
||||
-moz-border-radius: 5px;
|
||||
-webkit-border-radius: 5px;
|
||||
z-index: 2;
|
||||
font-weight:bold;
|
||||
display:none;
|
||||
position:fixed;
|
||||
padding:10px;
|
||||
top:48px;
|
||||
right:50px;
|
||||
min-width:280px;
|
||||
opacity:0.85;
|
||||
margin:0px 0px 10px 10px;
|
||||
color:#fff;
|
||||
vertical-align:middle;
|
||||
cursor:pointer;
|
||||
background:#000;
|
||||
border:2px solid #fff;
|
||||
border-radius:5px;
|
||||
-moz-border-radius:5px;
|
||||
-webkit-border-radius:5px;
|
||||
z-index:2000;
|
||||
}
|
||||
div.flash {z-index:2000;}
|
||||
|
||||
div.error_wrapper { display: block; }
|
||||
div.error_wrapper {display:block}
|
||||
div.error {
|
||||
background-color: red;
|
||||
color: white;
|
||||
padding: 3px;
|
||||
display: inline-block;
|
||||
background-color:red;
|
||||
color:white;
|
||||
padding:3px;
|
||||
display:inline-block;
|
||||
}
|
||||
|
||||
.topbar {
|
||||
padding: 10px 0;
|
||||
padding:10px 0;
|
||||
width:100%;
|
||||
color: #959595;
|
||||
vertical-align: middle;
|
||||
padding: auto;
|
||||
background-image: -khtml-gradient(linear, left top, left bottom, from(#333333), to(#222222));
|
||||
background-image: -moz-linear-gradient(top, #333333, #222222);
|
||||
background-image: -ms-linear-gradient(top, #333333, #222222);
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #333333), color-stop(100%, #222222));
|
||||
background-image: -webkit-linear-gradient(top, #333333, #222222);
|
||||
background-image: -o-linear-gradient(top, #333333, #222222);
|
||||
background-image: linear-gradient(top, #333333, #222222);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#333333', endColorstr='#222222', GradientType=0);
|
||||
-webkit-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.25), inset 0 -1px 0 rgba(0, 0, 0, 0.1);
|
||||
-moz-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.25), inset 0 -1px 0 rgba(0, 0, 0, 0.1);
|
||||
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.25), inset 0 -1px 0 rgba(0, 0, 0, 0.1);
|
||||
color:#959595;
|
||||
vertical-align:middle;
|
||||
padding:auto;
|
||||
background-image:-khtml-gradient(linear,left top,left bottom,from(#333333),to(#222222));
|
||||
background-image:-moz-linear-gradient(top,#333333,#222222);
|
||||
background-image:-ms-linear-gradient(top,#333333,#222222);
|
||||
background-image:-webkit-gradient(linear,left top,left bottom,color-stop(0%,#333333),color-stop(100%,#222222));
|
||||
background-image:-webkit-linear-gradient(top,#333333,#222222);
|
||||
background-image:-o-linear-gradient(top,#333333,#222222);
|
||||
background-image:linear-gradient(top,#333333,#222222);
|
||||
filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#333333',endColorstr='#222222',GradientType=0);
|
||||
-webkit-box-shadow:0 1px 3px rgba(0,0,0,0.25),inset 0 -1px 0 rgba(0,0,0,0.1);
|
||||
-moz-box-shadow:0 1px 3px rgba(0,0,0,0.25),inset 0 -1px 0 rgba(0,0,0,0.1);
|
||||
box-shadow:0 1px 3px rgba(0,0,0,0.25),inset 0 -1px 0 rgba(0,0,0,0.1);
|
||||
}
|
||||
|
||||
.topbar a {
|
||||
color: #e1e1e1;
|
||||
color:#e1e1e1;
|
||||
}
|
||||
|
||||
#navbar {float: right; padding: 5px; /* same as superfish */}
|
||||
|
||||
.right {
|
||||
width:100%;
|
||||
text-align: right;
|
||||
float: right;
|
||||
}
|
||||
#navbar {float:right; padding:5px; /* same as superfish */}
|
||||
|
||||
.statusbar {
|
||||
background-color: #F5F5F5;
|
||||
margin-top: 1em;
|
||||
margin-bottom: 1em;
|
||||
padding: .5em 1em;
|
||||
border: 1px solid #ddd;
|
||||
border-radius: 5px;
|
||||
-moz-border-radius: 5px;
|
||||
-webkit-border-radius: 5px;
|
||||
background-color:#F5F5F5;
|
||||
margin-top:1em;
|
||||
margin-bottom:1em;
|
||||
padding:.5em 1em;
|
||||
border:1px solid #ddd;
|
||||
border-radius:5px;
|
||||
-moz-border-radius:5px;
|
||||
-webkit-border-radius:5px;
|
||||
}
|
||||
|
||||
.breadcrumbs { float: left; }
|
||||
.breadcrumbs {float:left}
|
||||
|
||||
.copyright {float: left;}
|
||||
#poweredBy {float: right;}
|
||||
.copyright {float:left}
|
||||
#poweredBy {float:right}
|
||||
|
||||
/* #MEDIA QUERIES SECTION */
|
||||
|
||||
/* All Mobile Sizes (devices and browser) */
|
||||
@media only screen and (max-width: 767px) {
|
||||
@media only screen and (max-width:767px) {
|
||||
/* removed because of bootswatch
|
||||
.topbar {text-align: center;}
|
||||
#navbar, #menu {float: none;}
|
||||
#navbar {font-size: 1.2em; padding: .6em 0 1.2em;}
|
||||
#menu {padding: 0 0 1.5em;}
|
||||
#menu select {font-size: 1.2em; margin: 0; padding: 0;}
|
||||
.topbar {text-align:center}
|
||||
#navbar,#menu {float:none}
|
||||
#navbar {font-size:1.2em; padding:.6em 0 1.2em}
|
||||
#menu {padding:0 0 1.5em}
|
||||
#menu select {font-size:1.2em; margin:0; padding:0}
|
||||
|
||||
div.flash {top: 110px; right: 10px;}
|
||||
div.flash {top:110px; right:10px}
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
*Grid
|
||||
@@ -190,46 +184,46 @@ div.error {
|
||||
* will look better with the declarations below
|
||||
* if needed to remove base.css consider keeping these following lines in some css file.
|
||||
*/
|
||||
// .web2py_table { border: 1px solid #ccc; }
|
||||
.web2py_paginator { }
|
||||
.web2py_grid {width: 100% }
|
||||
.web2py_grid table { width: 100% }
|
||||
// .web2py_table {border:1px solid #ccc}
|
||||
.web2py_paginator {}
|
||||
.web2py_grid {width:100%}
|
||||
.web2py_grid table {width:100%}
|
||||
.web2py_grid tbody td {
|
||||
padding: 2px 5px 2px 5px;
|
||||
vertical-align: middle;
|
||||
padding:2px 5px 2px 5px;
|
||||
vertical-align:middle;
|
||||
}
|
||||
|
||||
.web2py_grid thead th, .web2py_grid tfoot td {
|
||||
.web2py_grid thead th,.web2py_grid tfoot td {
|
||||
background-color:#EAEAEA;
|
||||
padding: 10px 5px 10px 5px;
|
||||
padding:10px 5px 10px 5px;
|
||||
}
|
||||
|
||||
.web2py_grid tr.odd {background-color: #F9F9F9;}
|
||||
.web2py_grid tr:hover {background-color: #F5F5F5; }
|
||||
.web2py_grid tr.odd {background-color:#F9F9F9}
|
||||
.web2py_grid tr:hover {background-color:#F5F5F5}
|
||||
|
||||
/*
|
||||
.web2py_breadcrumbs a {
|
||||
line-height: 20px; margin-right: 5px; display: inline-block;
|
||||
padding: 3px 5px 3px 5px;
|
||||
font-family: 'lucida grande', tahoma, verdana, arial, sans-serif;
|
||||
color: #3C3C3D;
|
||||
text-shadow: 1px 1px 0 #FFFFFF;
|
||||
white-space: nowrap; overflow: visible; cursor: pointer;
|
||||
line-height:20px; margin-right:5px; display:inline-block;
|
||||
padding:3px 5px 3px 5px;
|
||||
font-family:'lucida grande',tahoma,verdana,arial,sans-serif;
|
||||
color:#3C3C3D;
|
||||
text-shadow:1px 1px 0 #FFFFFF;
|
||||
white-space:nowrap; overflow:visible; cursor:pointer;
|
||||
background:#ECECEC;
|
||||
border: 1px solid #CACACA;
|
||||
-webkit-border-radius: 2px; -moz-border-radius: 2px;
|
||||
-webkit-background-clip: padding-box; border-radius: 2px;
|
||||
outline: none; position: relative; zoom: 1; *display: inline;
|
||||
border:1px solid #CACACA;
|
||||
-webkit-border-radius:2px; -moz-border-radius:2px;
|
||||
-webkit-background-clip:padding-box; border-radius:2px;
|
||||
outline:none; position:relative; zoom:1; *display:inline;
|
||||
}
|
||||
*/
|
||||
|
||||
.web2py_console form {
|
||||
width:100%;
|
||||
display: inline;
|
||||
display:inline;
|
||||
}
|
||||
|
||||
.web2py_console form select {
|
||||
margin: 0;
|
||||
margin:0;
|
||||
}
|
||||
|
||||
.web2py_search_actions{
|
||||
@@ -239,14 +233,14 @@ div.error {
|
||||
|
||||
.web2py_grid .row_buttons {
|
||||
min-height:25px;
|
||||
vertical-align: middle;
|
||||
vertical-align:middle;
|
||||
}
|
||||
.web2py_grid .row_buttons a {
|
||||
margin: 3px;
|
||||
margin:3px;
|
||||
}
|
||||
|
||||
.web2py_search_actions {
|
||||
width: 100%;
|
||||
width:100%;
|
||||
}
|
||||
|
||||
.web2py_grid .row_buttons a,
|
||||
@@ -255,13 +249,13 @@ div.error {
|
||||
.web2py_console input[type=submit],
|
||||
.web2py_console input[type=button],
|
||||
.web2py_console button {
|
||||
line-height: 20px;
|
||||
margin-right: 5px; display: inline-block;
|
||||
padding: 3px 5px 3px 5px;
|
||||
line-height:20px;
|
||||
margin-right:5px; display:inline-block;
|
||||
padding:3px 5px 3px 5px;
|
||||
}
|
||||
|
||||
.web2py_counter {
|
||||
margin-top: 5px;
|
||||
margin-top:5px;
|
||||
margin-right:5px;
|
||||
width:35%;
|
||||
float:right;
|
||||
@@ -269,37 +263,37 @@ div.error {
|
||||
}
|
||||
|
||||
/*Fix firefox problem*/
|
||||
.web2py_table {clear: both; display: block;}
|
||||
.web2py_table {clear:both; display:block}
|
||||
|
||||
.web2py_paginator {
|
||||
padding: 5px;
|
||||
padding:5px;
|
||||
text-align:right;
|
||||
background-color: #f2f2f2;
|
||||
background-color:#f2f2f2;
|
||||
|
||||
}
|
||||
.web2py_paginator ul {
|
||||
list-style-type: none;
|
||||
margin: 0px;
|
||||
padding: 0px;
|
||||
list-style-type:none;
|
||||
margin:0px;
|
||||
padding:0px;
|
||||
}
|
||||
|
||||
.web2py_paginator ul li {
|
||||
display: inline;
|
||||
display:inline;
|
||||
}
|
||||
|
||||
.web2py_paginator .current {
|
||||
font-weight: bold;
|
||||
font-weight:bold;
|
||||
}
|
||||
|
||||
#w2p_query_panel {}
|
||||
|
||||
.web2py_breadcrumbs ul {
|
||||
list-style: none;
|
||||
margin-bottom: 18px;
|
||||
list-style:none;
|
||||
margin-bottom:18px;
|
||||
}
|
||||
|
||||
.web2py_breadcrumbs ul li {
|
||||
display: inline-block;
|
||||
display:inline-block;
|
||||
}
|
||||
|
||||
.ie9 #query_panel {padding-bottom:2px;}
|
||||
.ie9 #query_panel {padding-bottom:2px}
|
||||
|
||||
|
Before Width: | Height: | Size: 198 B After Width: | Height: | Size: 198 B |
|
Before Width: | Height: | Size: 323 B After Width: | Height: | Size: 323 B |
@@ -44,6 +44,12 @@ function web2py_event_handlers() {
|
||||
doc.on('keyup', 'input.double, input.decimal', function(){this.value=this.value.reverse().replace(/[^0-9\-\.,]|[\-](?=.)|[\.,](?=[0-9]*[\.,])/g,'').reverse();});
|
||||
var confirm_message = (typeof w2p_ajax_confirm_message != 'undefined') ? w2p_ajax_confirm_message : "Are you sure you want to delete this object?";
|
||||
doc.on('click', "input[type='checkbox'].delete", function(){if(this.checked) if(!confirm(confirm_message)) this.checked=false;});
|
||||
doc.ajaxSuccess(function(e, xhr) {
|
||||
var redirect=xhr.getResponseHeader('web2py-redirect-location');
|
||||
if (redirect != null) {
|
||||
window.location = redirect;
|
||||
};
|
||||
});
|
||||
};
|
||||
|
||||
jQuery(function() {
|
||||
@@ -98,8 +104,8 @@ function web2py_ajax_page(method, action, data, target) {
|
||||
eval(decodeURIComponent(command));
|
||||
if(flash)
|
||||
jQuery('.flash').html(decodeURIComponent(flash)).slideDown();
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function web2py_component(action, target, timeout, times){
|
||||
|
||||
@@ -1,2 +0,0 @@
|
||||
User-agent: *
|
||||
Disallow: /welcome/default/user
|
||||
@@ -29,7 +29,7 @@
|
||||
{{pass}}
|
||||
{{pass}}
|
||||
<h3>
|
||||
{{=A("%s.%s" % (db,table),_href=URL('select',args=[db],vars=dict(query=qry)))}}
|
||||
{{=A("%s.%s" % (db,table),_href=URL('select',args=[db],vars=dict(query=qry)))}}
|
||||
</h3>
|
||||
[ {{=A(str(T('insert new'))+' '+table,_href=URL('insert',args=[db,table]))}} ]
|
||||
<br /><br />
|
||||
@@ -50,7 +50,7 @@
|
||||
{{=T('Use (...)&(...) for AND, (...)|(...) for OR, and ~(...) for NOT to build more complex queries.')}}<br/>
|
||||
{{=T('"update" is an optional expression like "field1=\'newvalue\'". You cannot update or delete the results of a JOIN')}}</p>
|
||||
<br/><br/>
|
||||
<h4>{{=nrows}} {{=T("selected")}}</h4>
|
||||
<h4>{{=T("%s selected", nrows)}}</h4>
|
||||
{{if start>0:}}[ {{=A(T('previous 100 rows'),_href=URL('select',args=request.args[0],vars=dict(start=start-100)))}} ]{{pass}}
|
||||
{{if stop<nrows:}}[ {{=A(T('next 100 rows'),_href=URL('select',args=request.args[0],vars=dict(start=start+100)))}} ]{{pass}}
|
||||
{{if rows:}}
|
||||
@@ -62,10 +62,7 @@
|
||||
{{pass}}
|
||||
<br/><br/><h3>{{=T("Import/Export")}}</h3><br/>
|
||||
[ <a href="{{=URL('csv',args=request.args[0],vars=dict(query=query))}}">{{=T("export as csv file")}}</a> ]
|
||||
{{if table:}}
|
||||
{{=FORM(str(T('or import from csv file'))+" ",INPUT(_type='file',_name='csvfile'),INPUT(_type='hidden',_value=table,_name='table'),INPUT(_type='submit',_value=T('import')))}}
|
||||
{{pass}}
|
||||
|
||||
{{=formcsv or ''}}
|
||||
|
||||
{{elif request.function=='insert':}}
|
||||
<h2>{{=T("database")}} {{=A(request.args[0],_href=URL('index'))}}
|
||||
@@ -108,40 +105,34 @@
|
||||
|
||||
|
||||
{{elif request.function == 'ccache':}}
|
||||
<h2>Cache</h2>
|
||||
<h2>{{T("Cache")}}</h2>
|
||||
<div class="list">
|
||||
|
||||
<div class="list-header">
|
||||
<h3>Statistics</h3>
|
||||
<h3>{{T("Statistics")}}</h3>
|
||||
</div>
|
||||
|
||||
<div class="content">
|
||||
<h4>Overview</h4>
|
||||
<p>Number of entries: <strong>{{=total['entries']}}</strong>
|
||||
{{if total['entries'] > 0:}}
|
||||
</p>
|
||||
<h4>{{=T("Overview")}}</h4>
|
||||
<p>{{=T.M("Number of entries: **%s**", total['entries'])}}</p>
|
||||
{{if total['entries'] > 0:}}
|
||||
<p>{{=T.M("Hit Ratio: **%(ratio)s%%** (**%(hits)s** %%{hit(hits)} and **%(misses)s** %%{miss(misses})",
|
||||
dict(ratio=total['ratio'], hits=total['hits'], misses=total['misses']))}}
|
||||
</p>
|
||||
<p>
|
||||
Hit Ratio:
|
||||
<strong>{{=total['ratio']}}%</strong>
|
||||
(<strong>{{=total['hits']}}</strong> hits
|
||||
and <strong>{{=total['misses']}}</strong> misses)
|
||||
</p>
|
||||
<p>
|
||||
Size of cache:
|
||||
{{=T("Size of cache:")}}
|
||||
{{if object_stats:}}
|
||||
<strong>{{=total['objects']}}</strong> items,
|
||||
<strong>{{=total['bytes']}}</strong> bytes
|
||||
{{if total['bytes'] > 524287:}}
|
||||
(<strong>{{="%.0d" % (total['bytes'] / 1048576)}} MB</strong>)
|
||||
{{pass}}
|
||||
{{else:}} <strong>not available</strong> (requires the Python <a href="http://pypi.python.org/pypi/guppy/" target="_blank">guppy</a> library)
|
||||
{{=T.M("**%(items)s** %%{item(items)}, **%(bytes)s** %%{byte(bytes)}", dict(items=total['objects'], bytes=total['bytes']))}}
|
||||
{{if total['bytes'] > 524287:}}
|
||||
{{=T.M("(**%.0d MB**)", total['bytes'] / 1048576)}}
|
||||
{{pass}}
|
||||
{{else:}}
|
||||
{{=T.M("**not available** (requires the Python [[guppy http://pypi.python.org/pypi/guppy/ popup]] library)")}}
|
||||
{{pass}}
|
||||
</p>
|
||||
<p>
|
||||
Cache contains items up to
|
||||
<strong>{{="%02d" % total['oldest'][0]}}</strong> hours
|
||||
<strong>{{="%02d" % total['oldest'][1]}}</strong> minutes
|
||||
<strong>{{="%02d" % total['oldest'][2]}}</strong> seconds old.
|
||||
{{=T.M("Cache contains items up to **%(hours)02d** %%{hour(hours)} **%(min)02d** %%{minute(min)} **%(sec)02d** %%{second(sec)} old.",
|
||||
dict(hours=total['oldest'][0], min=total['oldest'][1], sec=total['oldest'][2]))}}
|
||||
</p>
|
||||
{{=BUTTON(T('Cache Keys'), _onclick='jQuery("#all_keys").toggle();')}}
|
||||
<div class="hidden" id="all_keys">
|
||||
@@ -150,31 +141,26 @@
|
||||
<br />
|
||||
{{pass}}
|
||||
|
||||
<h4>RAM</h4>
|
||||
<p>Number of entries: <strong>{{=ram['entries']}}</strong>
|
||||
{{if ram['entries'] > 0:}}</p>
|
||||
<p>
|
||||
Hit Ratio:
|
||||
<strong>{{=ram['ratio']}}%</strong>
|
||||
(<strong>{{=ram['hits']}}</strong> hits
|
||||
and <strong>{{=ram['misses']}}</strong> misses)
|
||||
<h4>{{=T("RAM")}}</h4>
|
||||
<p>{{=T.M("Number of entries: **%s**", ram['entries'])}}</p>
|
||||
{{if ram['entries'] > 0:}}
|
||||
<p>{{=T.M("Hit Ratio: **%(ratio)s%%** (**%(hits)s** %{hit(hits)} and **%(misses)s** %%{miss(misses)})",
|
||||
dict( ratio=ram['ratio'], hits=ram['hits'], misses=ram['misses']))}}
|
||||
</p>
|
||||
<p>
|
||||
Size of cache:
|
||||
{{=T("Size of cache:")}}
|
||||
{{if object_stats:}}
|
||||
<strong>{{=ram['objects']}}</strong> items,
|
||||
<strong>{{=ram['bytes']}}</strong> bytes
|
||||
{{if ram['bytes'] > 524287:}}
|
||||
(<strong>{{=ram['bytes'] / 1048576}} MB</strong>)
|
||||
{{pass}}
|
||||
{{else:}} <strong>not available</strong> (requires the Python <a href="http://pypi.python.org/pypi/guppy/" target="_blank">guppy</a> library)
|
||||
{{=T.M("**%(items)s** items, **%(bytes)s** %%{byte(bytes)}", dict(items=ram['objects'], bytes=ram['bytes']))}}
|
||||
{{if ram['bytes'] > 524287:}}
|
||||
{{=T.M("(**%.0d MB**)", ram['bytes'] / 10485576)}}
|
||||
{{pass}}
|
||||
{{else:}}
|
||||
{{=T.M("``**not available**``:red (requires the Python [[guppy http://pypi.python.org/pypi/guppy/ popup]] library)")}}
|
||||
{{pass}}
|
||||
</p>
|
||||
<p>
|
||||
RAM contains items up to
|
||||
<strong>{{="%02d" % ram['oldest'][0]}}</strong> hours
|
||||
<strong>{{="%02d" % ram['oldest'][1]}}</strong> minutes
|
||||
<strong>{{="%02d" % ram['oldest'][2]}}</strong> seconds old.
|
||||
{{=T.M("RAM contains items up to **%(hours)02d** %%{hour(hours)} **%(min)02d** %%{minute(min)} **%(sec)02d** %%{second(sec)} old.",
|
||||
dict(hours=ram['oldest'][0], min=ram['oldest'][1], sec=ram['oldest'][2]))}}
|
||||
</p>
|
||||
{{=BUTTON(T('RAM Cache Keys'), _onclick='jQuery("#ram_keys").toggle();')}}
|
||||
<div class="hidden" id="ram_keys">
|
||||
@@ -183,43 +169,38 @@
|
||||
<br />
|
||||
{{pass}}
|
||||
|
||||
<h4>DISK</h4>
|
||||
<p>Number of entries: <strong>{{=disk['entries']}}</strong>
|
||||
{{if disk['entries'] > 0:}}
|
||||
</p>
|
||||
<p>
|
||||
Hit Ratio:
|
||||
<strong>{{=disk['ratio']}}%</strong>
|
||||
(<strong>{{=disk['hits']}}</strong> hits
|
||||
and <strong>{{=disk['misses']}}</strong> misses)
|
||||
</p>
|
||||
<p>
|
||||
Size of cache:
|
||||
<h4>{{=T("DISK")}}</h4>
|
||||
<p>{{=T.M("Number of entries: **%s**", disk['entries'])}}</p>
|
||||
{{if disk['entries'] > 0:}}
|
||||
<p>
|
||||
{{=T.M("Hit Ratio: **%(ratio)s%%** (**%(hits)s** %%{hit(hits)} and **%(misses)s** %%{miss(misses)})",
|
||||
dict(ratio=disk['ratio'], hits=disk['hits'], misses=disk['misses']))}}
|
||||
</p>
|
||||
<p>
|
||||
{{=T("Size of cache:")}}
|
||||
{{if object_stats:}}
|
||||
<strong>{{=disk['objects']}}</strong> items,
|
||||
<strong>{{=disk['bytes']}}</strong> bytes
|
||||
{{if disk['bytes'] > 524287:}}
|
||||
(<strong>{{=disk['bytes'] / 1048576}} MB</strong>)
|
||||
{{=T.M("**%(items)s** %%{item(items)}, **%(bytes)s** %%{byte(bytes)}", dict( items=disk['objects'], bytes=disk['bytes']))}}
|
||||
{{if disk['bytes'] > 524287:}}
|
||||
{{=T.M("(**%.0d MB**)", disk['bytes'] / 1048576)}}
|
||||
{{pass}}
|
||||
{{else:}}
|
||||
{{=T.M("``**not available**``:red (requires the Python [[guppy http://pypi.python.org/pypi/guppy/ popup]] library)")}}
|
||||
{{pass}}
|
||||
{{else:}} <strong>not available</strong> (requires the Python <a href="http://pypi.python.org/pypi/guppy/" target="_blank">guppy</a> library)
|
||||
{{pass}}
|
||||
</p>
|
||||
<p>
|
||||
DISK contains items up to
|
||||
<strong>{{="%02d" % disk['oldest'][0]}}</strong> hours
|
||||
<strong>{{="%02d" % disk['oldest'][1]}}</strong> minutes
|
||||
<strong>{{="%02d" % disk['oldest'][2]}}</strong> seconds old.
|
||||
</p>
|
||||
{{=BUTTON(T('Disk Cache Keys'), _onclick='jQuery("#disk_keys").toggle();')}}
|
||||
<div class="hidden" id="disk_keys">
|
||||
</p>
|
||||
<p>
|
||||
{{=T.M("DISK contains items up to **%(hours)02d** %%{hour(hours)} **%(min)02d** %%{minute(min)} **%(sec)02d** %%{second(sec)} old.",
|
||||
dict(hours=disk['oldest'][0], min=disk['oldest'][1], sec=disk['oldest'][2]))}}
|
||||
</p>
|
||||
{{=BUTTON(T('Disk Cache Keys'), _onclick='jQuery("#disk_keys").toggle();')}}
|
||||
<div class="hidden" id="disk_keys">
|
||||
{{=disk['keys']}}
|
||||
</div>
|
||||
<br />
|
||||
</div>
|
||||
<br />
|
||||
{{pass}}
|
||||
</div>
|
||||
|
||||
<div class="list-header">
|
||||
<h3>Manage Cache</h3>
|
||||
<h3>{{=T("Manage Cache")}}</h3>
|
||||
</div>
|
||||
|
||||
<div class="content">
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
{{if 'message' in globals():}}
|
||||
<h3>{{=message}}</h3>
|
||||
|
||||
<h4/>{{=T('How did you get here?')}}</h4>
|
||||
<h4>{{=T('How did you get here?')}}</h4>
|
||||
<ol>
|
||||
<li>{{=T('You are successfully running web2py')}}</li>
|
||||
<li>{{=XML(T('You visited the url %s', A(request.env.path_info,_href=request.env.path_info)))}}</li>
|
||||
@@ -16,7 +16,6 @@
|
||||
A('web2py/applications/%(application)s/views/%(controller)s/index.html'%request,
|
||||
_href=URL('admin','default','peek',args=(request.application,'views',request.controller,'index.html')))))}}</li>
|
||||
<li>{{=T('You can modify this application and adapt it to your needs')}}</li>
|
||||
</ul>
|
||||
</ol>
|
||||
{{else:}}
|
||||
{{=BEAUTIFY(response._vars)}}
|
||||
|
||||
@@ -31,9 +31,8 @@
|
||||
user-scalable = yes allows the user to zoom in -->
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
|
||||
<!-- Place favicon.ico and apple-touch-icon.png in the root of your domain and delete these references -->
|
||||
<link rel="shortcut icon" href="{{=URL('static','favicon.ico')}}" type="image/x-icon">
|
||||
<link rel="apple-touch-icon" href="{{=URL('static','favicon.png')}}">
|
||||
<link rel="shortcut icon" href="{{=URL('static','images/favicon.ico')}}" type="image/x-icon">
|
||||
<link rel="apple-touch-icon" href="{{=URL('static','images/favicon.png')}}">
|
||||
|
||||
<!-- All JavaScript at the bottom, except for Modernizr which enables
|
||||
HTML5 elements & feature detects -->
|
||||
@@ -46,6 +45,10 @@
|
||||
response.files.append(URL('static','css/web2py.css'))
|
||||
response.files.append(URL('static','css/bootswatch.css'))
|
||||
}}
|
||||
<!-- Makes bootswatch working on IE 7/8 -->
|
||||
<!--[if (lt IE 9)]>
|
||||
<link rel="stylesheet" href="{{=URL('static','css/bootswatch_ie.css')}}">
|
||||
<![endif]-->
|
||||
|
||||
{{include 'web2py_ajax.html'}}
|
||||
|
||||
@@ -61,18 +64,6 @@
|
||||
<link rel="stylesheet" href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.16/themes/base/jquery-ui.css" type="text/css" media="all" />
|
||||
<script src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.16/jquery-ui.min.js" type="text/javascript"></script>
|
||||
uncomment to load jquery-ui //-->
|
||||
<script>
|
||||
jQuery(function(){
|
||||
jQuery('.nav>li>a').each(function(){
|
||||
if(jQuery(this).parent().find('ul').length)
|
||||
jQuery(this).attr({'class':'dropdown-toggle','data-toggle':'dropdown'}).append('<b class="caret"></b>');
|
||||
});
|
||||
jQuery('.nav li li').each(function(){
|
||||
if(jQuery(this).find('ul').length)
|
||||
jQuery(this).children('a').contents().before('<i class="chevron-right"></i>');
|
||||
});
|
||||
});
|
||||
</script>
|
||||
<noscript><link href="{{=URL('static', 'css/bootswatch_nojs.css')}}" rel="stylesheet" type="text/css" /></noscript>
|
||||
{{block head}}{{end}}
|
||||
</head>
|
||||
@@ -82,13 +73,14 @@
|
||||
<div class="navbar navbar-fixed-top">
|
||||
<div class="navbar-inner">
|
||||
<div class="container">
|
||||
<!-- the next tag is necessary for bootstrap menus, do not remove -->
|
||||
<a class="btn btn-navbar" data-toggle="collapse" data-target=".nav-collapse">
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
</a>
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
</a>
|
||||
<a class="brand" href="#">web2py™ </a>
|
||||
<div id="navbar">{{='auth' in globals() and auth.navbar(separators=(' ',' | ','')) or ''}}</div>
|
||||
<div id="navbar">{{='auth' in globals() and auth.navbar() or ''}}</div>
|
||||
<div class="nav-collapse">
|
||||
{{is_mobile=request.user_agent().is_mobile}}
|
||||
{{if response.menu:}}
|
||||
@@ -99,9 +91,9 @@
|
||||
</div>
|
||||
</div><!--/top navbar -->
|
||||
|
||||
<div class="flash">{{=response.flash or ''}}</div>
|
||||
|
||||
<div class="container">
|
||||
<div class="flash">{{=response.flash or ''}}</div>
|
||||
|
||||
<!-- Masthead ================================================== -->
|
||||
<header class="mastheader" id="header">
|
||||
<div class="page-header">
|
||||
@@ -144,7 +136,7 @@
|
||||
<footer class="footer">
|
||||
{{block footer}} <!-- this is default footer -->
|
||||
<div class="footer-content">
|
||||
<div class="copyright pull-left">{{=T('Copyright')}} © 2011</div>
|
||||
<div class="copyright pull-left">{{=T('Copyright')}} © {{=request.now.year}}</div>
|
||||
<div id="poweredBy" class="pull-right">
|
||||
{{=T('Powered by')}}
|
||||
<a href="http://www.web2py.com/">web2py</a>
|
||||
@@ -155,10 +147,31 @@
|
||||
|
||||
</div> <!-- /container -->
|
||||
|
||||
<!-- Le javascript ================================================== -->
|
||||
<!-- Placed at the end of the document so the pages load faster -->
|
||||
<script src="{{=URL('static','js/bootstrap.min.js')}}"></script>
|
||||
|
||||
<!-- The javascript =============================================
|
||||
(Placed at the end of the document so the pages load faster) -->
|
||||
<script>
|
||||
// this code improves bootstrap menus and adds dropdown support
|
||||
jQuery(function(){
|
||||
jQuery('.nav>li>a').each(function(){
|
||||
if(jQuery(this).parent().find('ul').length)
|
||||
jQuery(this).attr({'class':'dropdown-toggle','data-toggle':'dropdown'}).append('<b class="caret"></b>');
|
||||
});
|
||||
jQuery('.nav li li').each(function(){
|
||||
if(jQuery(this).find('ul').length)
|
||||
jQuery(this).children('a').contents().before('<i class="chevron-right"></i>');
|
||||
});
|
||||
|
||||
if(jQuery(document).width()>=980) {
|
||||
jQuery('ul.nav li.dropdown').hover(function() {
|
||||
jQuery(this).find('.dropdown-menu').stop(true, true).delay(200).fadeIn();
|
||||
}, function() {
|
||||
jQuery(this).find('.dropdown-menu').stop(true, true).delay(200).fadeOut();
|
||||
});
|
||||
}
|
||||
jQuery('ul.nav li.dropdown a').click(function(){window.location=jQuery(this).attr('href');});
|
||||
});
|
||||
</script>
|
||||
<script src="{{=URL('static','js/bootstrap.min.js')}}"></script>
|
||||
<!--[if lt IE 7 ]>
|
||||
<script src="{{=URL('static','js/dd_belatedpng.js')}}"></script>
|
||||
<script> DD_belatedPNG.fix('img, .png_bg'); //fix any <img> or .png_bg background-images </script>
|
||||
|
||||
@@ -64,3 +64,4 @@ wsgiref.handlers.CGIHandler().run(gluon.main.wsgibase)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -54,3 +54,4 @@ fcgi.WSGIServer(application, bindAddress='/tmp/fcgi.sock').run()
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -102,3 +102,4 @@ if __name__ == '__main__':
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
+4
-2
@@ -26,14 +26,14 @@ if 0:
|
||||
from cache import Cache
|
||||
from languages import translator
|
||||
from tools import Auth, Crud, Mail, Service, PluginManager
|
||||
|
||||
|
||||
# API objects
|
||||
request = Request()
|
||||
response = Response()
|
||||
session = Session()
|
||||
cache = Cache(request)
|
||||
T = translator(request)
|
||||
|
||||
|
||||
# Objects commonly defined in application model files
|
||||
# (names are conventions only -- not part of API)
|
||||
db = DAL()
|
||||
@@ -50,3 +50,5 @@ if 0:
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -464,3 +464,4 @@ def create_missing_app_folders(request):
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
+10
-7
@@ -175,6 +175,7 @@ class CacheInRam(CacheAbstract):
|
||||
"""
|
||||
|
||||
dt = time_expire
|
||||
now = time.time()
|
||||
|
||||
self.locker.acquire()
|
||||
item = self.storage.get(key, None)
|
||||
@@ -187,14 +188,14 @@ class CacheInRam(CacheAbstract):
|
||||
|
||||
if f is None:
|
||||
return None
|
||||
if item and (dt is None or item[0] > time.time() - dt):
|
||||
if item and (dt is None or item[0] > now - dt):
|
||||
return item[1]
|
||||
elif item and (item[0] < time.time() - dt) and destroyer:
|
||||
elif item and (item[0] < now - dt) and destroyer:
|
||||
destroyer(item[1])
|
||||
value = f()
|
||||
|
||||
self.locker.acquire()
|
||||
self.storage[key] = (time.time(), value)
|
||||
self.storage[key] = (now, value)
|
||||
self.storage[CacheAbstract.cache_stats_name]['misses'] += 1
|
||||
self.locker.release()
|
||||
return value
|
||||
@@ -345,15 +346,16 @@ class CacheOnDisk(CacheAbstract):
|
||||
if storage:
|
||||
storage.close()
|
||||
|
||||
now = time.time()
|
||||
if f is None:
|
||||
return None
|
||||
if item and (dt is None or item[0] > time.time() - dt):
|
||||
if item and (dt is None or item[0] > now - dt):
|
||||
return item[1]
|
||||
value = f()
|
||||
|
||||
storage = self._open_shelf_with_lock()
|
||||
try:
|
||||
storage[key] = (time.time(), value)
|
||||
storage[key] = (now, value)
|
||||
|
||||
storage[CacheAbstract.cache_stats_name] = {
|
||||
'hit_total': storage[CacheAbstract.cache_stats_name]['hit_total'],
|
||||
@@ -396,9 +398,9 @@ class CacheAction(object):
|
||||
.replace('%(args)s',str(a)).replace('%(vars)s',str(b))
|
||||
cache_model = self.cache_model
|
||||
if not cache_model or isinstance(cache_model,str):
|
||||
cache_model = getattr(self.cache,cache_model or 'ram')
|
||||
cache_model = getattr(self.cache,cache_model or 'ram')
|
||||
return cache_model(key2,
|
||||
lambda a=a,b=b:self.func(*a,**b),
|
||||
lambda a=a,b=b:self.func(*a,**b),
|
||||
self.time_expire)
|
||||
|
||||
|
||||
@@ -495,3 +497,4 @@ def lazy_cache(key=None,time_expire=None,cache_model='ram'):
|
||||
return g
|
||||
return decorator
|
||||
|
||||
|
||||
|
||||
@@ -55,3 +55,4 @@ def getcfs(key, filename, filter=None):
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
+2
-1
@@ -358,7 +358,7 @@ def build_environment(request, response, session, store_current=True):
|
||||
"""
|
||||
Build the environment dictionary into which web2py files are executed.
|
||||
"""
|
||||
|
||||
|
||||
environment = {}
|
||||
for key in html.__all__:
|
||||
environment[key] = getattr(html, key)
|
||||
@@ -690,3 +690,4 @@ if __name__ == '__main__':
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -722,3 +722,4 @@ def contenttype(filename, default='text/plain'):
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -262,3 +262,4 @@ if __name__=='__main__':
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -242,3 +242,4 @@ if __name__=='__main__':
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -4,3 +4,4 @@
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -500,3 +500,4 @@ aes_Rcon = array('B',
|
||||
'c697356ad4b37dfaefc5913972e4d3bd'
|
||||
'61c29f254a943366cc831d3a74e8cb'.decode('hex')
|
||||
)
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ Released under the web2py license (LGPL)
|
||||
|
||||
What does it do?
|
||||
|
||||
if html is a variable containing HTML text and urls in the text, when you call
|
||||
if html is a variable containing HTML text and urls in the text, when you call
|
||||
|
||||
html = expend_html(html)
|
||||
|
||||
@@ -44,9 +44,13 @@ viddler.com
|
||||
|
||||
import re, cgi, sys
|
||||
from simplejson import loads
|
||||
from BeautifulSoup import BeautifulSoup, Comment
|
||||
import urllib
|
||||
import uuid
|
||||
try:
|
||||
from BeautifulSoup import BeautifulSoup, Comment
|
||||
have_soup = True
|
||||
except ImportError:
|
||||
have_soup = False
|
||||
|
||||
regex_link = re.compile('https?://\S+')
|
||||
|
||||
@@ -59,7 +63,7 @@ EMBED_MAPS = [
|
||||
'http://www.hulu.com/api/oembed.json'),
|
||||
(re.compile('http://vimeo.com/\S*'),
|
||||
'http://vimeo.com/api/oembed.json'),
|
||||
(re.compile('http://www.slideshare.net/[^\/]+/\S*'),
|
||||
(re.compile('http://www.slideshare.net/[^\/]+/\S*'),
|
||||
'http://www.slideshare.net/api/oembed/2'),
|
||||
(re.compile('http://qik.com/\S*'),
|
||||
'http://qik.com/api/oembed.json'),
|
||||
@@ -124,8 +128,8 @@ EXTENSION_MAPS = {
|
||||
|
||||
def oembed(url):
|
||||
for k,v in EMBED_MAPS:
|
||||
if k.match(url):
|
||||
oembed = v+'?format=json&url='+cgi.escape(url)
|
||||
if k.match(url):
|
||||
oembed = v+'?format=json&url='+cgi.escape(url)
|
||||
try:
|
||||
return loads(urllib.urlopen(oembed).read())
|
||||
except:
|
||||
@@ -145,12 +149,13 @@ def expand_one(url,cdict):
|
||||
r = oembed(url)
|
||||
# if oembed service
|
||||
if 'html' in r:
|
||||
if r['html'].startswith('<object'):
|
||||
return '<embed style="max-width:100%%">%s</embed>' % r['html']
|
||||
html = r['html'].encode('utf8')
|
||||
if html.startswith('<object'):
|
||||
return '<embed style="max-width:100%%">%s</embed>' % html
|
||||
else:
|
||||
return r['html']
|
||||
return html
|
||||
elif 'url' in r:
|
||||
url = r['url']
|
||||
url = r['url'].encode('utf8')
|
||||
# embed images, video, audio files
|
||||
ext = extension(url)
|
||||
if ext in EXTENSION_MAPS:
|
||||
@@ -159,6 +164,8 @@ def expand_one(url,cdict):
|
||||
return '<a href="%(u)s">%(u)s</a>' % dict(u=url)
|
||||
|
||||
def expand_html(html,cdict=None):
|
||||
if not have_soup:
|
||||
raise RuntimeError, "Missing BeautifulSoup"
|
||||
soup = BeautifulSoup(html)
|
||||
comments = soup.findAll(text=lambda text:isinstance(text, Comment))
|
||||
[comment.extract() for comment in comments]
|
||||
@@ -189,3 +196,4 @@ if __name__=="__main__":
|
||||
print expand_html(open(sys.argv[1]).read())
|
||||
else:
|
||||
print test()
|
||||
|
||||
|
||||
@@ -193,3 +193,4 @@ if __name__ == "__main__":
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -3909,3 +3909,4 @@ def parse(url_file_stream_or_string, etag=None, modified=None, agent=None, refer
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -54,3 +54,4 @@ class MemcacheClient(Client):
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -89,3 +89,4 @@ def autoretry_datastore_timeouts(attempts=5.0, interval=0.1, exponent=2.0):
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -66,3 +66,4 @@ def pdf_from_html(html):
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -18,3 +18,4 @@ def button(merchant_id="123456789012345",
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -8,3 +8,4 @@ from gluon.dal import DAL, Field, Table, Query, Set, Expression, Row, Rows, driv
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -57,3 +57,4 @@ def THUMB(image, nx=120, ny=120, gae=False, name='thumb'):
|
||||
return thumb
|
||||
else:
|
||||
return image
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
"""
|
||||
BrowserID Authentication for web2py
|
||||
developed by Madhukar R Pai (Copyright © 2011)
|
||||
developed by Madhukar R Pai (Copyright 2012)
|
||||
Email <madspai@gmail.com>
|
||||
License : LGPL
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
"""
|
||||
Dropbox Authentication for web2py
|
||||
Developed by Massimo Di Pierro (2011)
|
||||
Developed by Massimo Di Pierro (2012)
|
||||
Same License as Web2py License
|
||||
"""
|
||||
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -1,4 +1,4 @@
|
||||
#!/usr/bin/env python
|
||||
#!/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
# created by Massimo Di Pierro
|
||||
# recreated by Vladyslav Kozlovskyy
|
||||
@@ -71,15 +71,22 @@ a list with tables in it:
|
||||
-----------:blockquoteclass[blockquoteid]
|
||||
|
||||
This this a new paragraph
|
||||
with a table. Table has header and footer:
|
||||
with a table. Table has header, footer, sections, odd and even rows:
|
||||
-------------------------------
|
||||
**Title 1**|**Title 2**|**Title 3**
|
||||
==============================
|
||||
data 1 | data 2 | 2.00
|
||||
data 4 |data5(long)| 23.00
|
||||
|data 8 | 33.50
|
||||
data 3 |data4(long)| 23.00
|
||||
|data 5 | 33.50
|
||||
==============================
|
||||
Total: | 3 items | 58.50
|
||||
New section|New data | 5.00
|
||||
data 1 |data2(long)|100.45
|
||||
|data 3 | 12.50
|
||||
data 4 | data 5 | .33
|
||||
data 6 |data7(long)| 8.01
|
||||
|data 8 | 514
|
||||
==============================
|
||||
Total: | 9 items |698,79
|
||||
------------------------------:tableclass1[tableid2]
|
||||
|
||||
## Multilevel
|
||||
@@ -503,8 +510,8 @@ META = '\x06'
|
||||
LINK = '\x07'
|
||||
DISABLED_META = '\x08'
|
||||
LATEX = '<img src="http://chart.apis.google.com/chart?cht=tx&chl=%s" />'
|
||||
regex_URL=re.compile(r'@\{(?P<f>\w+)/(?P<args>.+?)\}')
|
||||
regex_env=re.compile(r'@\{(?P<a>\w+?)\}')
|
||||
regex_URL=re.compile(r'@\{(?P<f>\w+)/(?P<args>.*?)\}')
|
||||
regex_env=re.compile(r'@\{(?P<a>[\w\-\.]+?)(\:(?P<b>.*?))?\}')
|
||||
regex_expand_meta = re.compile('('+META+'|'+DISABLED_META+')')
|
||||
regex_dd=re.compile(r'\$\$(?P<latex>.*?)\$\$')
|
||||
regex_code = re.compile('('+META+'|'+DISABLED_META+r')|(``(?P<t>.+?)``(?::(?P<c>[a-zA-Z][_a-zA-Z\-\d]*)(?:\[(?P<p>[^\]]*)\])?)?)',re.S)
|
||||
@@ -512,17 +519,11 @@ regex_strong=re.compile(r'\*\*(?P<t>[^\s*]+( +[^\s*]+)*)\*\*')
|
||||
regex_del=re.compile(r'~~(?P<t>[^\s*]+( +[^\s*]+)*)~~')
|
||||
regex_em=re.compile(r"''(?P<t>[^\s']+(?: +[^\s']+)*)''")
|
||||
regex_num=re.compile(r"^\s*[+-]?((\d+(\.\d*)?)|\.\d+)([eE][+-]?[0-9]+)?\s*$")
|
||||
regex_list=re.compile('^(?:(#{1,6}|\.+|\++|\-+)(\.)?\s+)?(.*)$')
|
||||
regex_list=re.compile('^(?:(#{1,6}|\.+ |\++ |\++\. |\-+ |\-+\. )\s*)?(.*)$')
|
||||
regex_bq_headline=re.compile('^(?:(\.+|\++|\-+)(\.)?\s+)?(-{3}-*)$')
|
||||
regex_tq=re.compile('^(-{3}-*)(?::(?P<c>[a-zA-Z][_a-zA-Z\-\d]*)(?:\[(?P<p>[a-zA-Z][_a-zA-Z\-\d]*)\])?)?$')
|
||||
regex_qr = re.compile(r'(?<!["\w>/=])qr:(?P<k>\w+://[\w\d\-+?&%/:.]+)',re.M)
|
||||
regex_embed = re.compile(r'(?<!["\w>/=])embed:(?P<k>\w+://[\w\d\-+_=?%&/:.]+)', re.M)
|
||||
regex_iframe = re.compile(r'(?<!["\w>/=])iframe:(?P<k>\w+://[\w\d\-+=?%&/:.]+)', re.M)
|
||||
regex_auto_image = re.compile(r'(?<!["\w>/=])(?P<k>\w+://[\w\d\-+_=%&/:.]+\.(jpeg|JPEG|jpg|JPG|gif|GIF|png|PNG)(\?[\w\d/\-+_=%&:.]+)?)',re.M)
|
||||
regex_auto_video = re.compile(r'(?<!["\w>/=])(?P<k>\w+://[\w\d\-+_=%&/:.]+\.(mp4|MP4|mpeg|MPEG|mov|MOV|ogv|OGV)(\?[\w\d/\-+_=%&:.]+)?)',re.M)
|
||||
regex_auto_audio = re.compile(r'(?<!["\w>/=])(?P<k>\w+://[\w\d\-+_=%&/:.]+\.(mp3|MP3|wav|WAV|ogg|OGG)(\?[\w\d/\-+_=%&:.]+)?)',re.M)
|
||||
regex_proto = re.compile(r'(?<!["\w>/=])(?P<p>\w+):(?P<k>\w+://[\w\d\-+=?%&/:.]+)', re.M)
|
||||
regex_auto = re.compile(r'(?<!["\w>/=])(?P<k>\w+://[\w\d\-+_=?%&/:.]+)',re.M)
|
||||
|
||||
regex_link=re.compile(r'('+LINK+r')|\[\[(?P<s>.+?)\]\]')
|
||||
regex_link_level2=re.compile(r'^(?P<t>\S.*?)?(?:\s+\[(?P<a>.+?)\])?(?:\s+(?P<k>\S+))?(?:\s+(?P<p>popup))?\s*$')
|
||||
regex_media_level2=re.compile(r'^(?P<t>\S.*?)?(?:\s+\[(?P<a>.+?)\])?(?:\s+(?P<k>\S+))?\s+(?P<p>img|IMG|left|right|center|video|audio)(?:\s+(?P<w>\d+px))?\s*$')
|
||||
@@ -533,10 +534,52 @@ ttab_in = maketrans("'`:*~\\[]{}@$+-.#", '\x0b\x0c\x0e\x0f\x10\x11\x12\x13\x14\
|
||||
ttab_out = maketrans('\x0b\x0c\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b',"'`:*~\\[]{}@$+-.#")
|
||||
|
||||
def markmin_escape(text):
|
||||
""" insert \\ before markmin control characters: '`:*~[]{}@$ """
|
||||
return regex_markmin_escape.sub(lambda m: '\\'+m.group(0).replace('\\','\\\\'), text)
|
||||
""" insert \\ before markmin control characters: '`:*~[]{}@$ """
|
||||
return regex_markmin_escape.sub(
|
||||
lambda m: '\\'+m.group(0).replace('\\','\\\\'), text)
|
||||
|
||||
def render(text,extra={},allowed={},sep='p',URL=None,environment=None,latex='google',auto=True,class_prefix='',id_prefix='markmin_'):
|
||||
def autolinks_simple(url):
|
||||
"""
|
||||
it automatically converts the url to link,
|
||||
image, video or audio tag
|
||||
"""
|
||||
u_url=url.lower()
|
||||
if u_url.endswith(('.jpg','.jpeg','.gif','.png')):
|
||||
return '<img src="%s" controls />' % url
|
||||
elif u_url.endswith(('.mp4','.mpeg','.mov','.ogv')):
|
||||
return '<video src="%s" controls></video>' % url
|
||||
elif u_url.endswith(('.mp3','.wav','.ogg')):
|
||||
return '<audio src="%s" controls></audio>' % url
|
||||
return '<a href="%s">%s</a>' % (url,url)
|
||||
|
||||
def protolinks_simple(proto, url):
|
||||
"""
|
||||
it converts url to html-string using appropriate proto-prefix:
|
||||
Uses for construction "proto:url", e.g.:
|
||||
"iframe:http://www.example.com/path" will call protolinks()
|
||||
with parameters:
|
||||
proto="iframe"
|
||||
url="http://www.example.com/path"
|
||||
"""
|
||||
if proto in ('iframe','embed'): #== 'iframe':
|
||||
return '<iframe src="%s" frameborder="0" allowfullscreen></iframe>'%url
|
||||
#elif proto == 'embed': # NOTE: embed is a synonym to iframe now
|
||||
# return '<a href="%s" class="%sembed">%s></a>'%(url,class_prefix,url)
|
||||
elif proto == 'qr':
|
||||
return '<img width="80px" src="http://qrcode.kaywa.com/img.php?s=8&d=%s" alt="qr code" />'%url
|
||||
return proto+':'+url
|
||||
|
||||
def render(text,
|
||||
extra={},
|
||||
allowed={},
|
||||
sep='p',
|
||||
URL=None,
|
||||
environment=None,
|
||||
latex='google',
|
||||
autolinks='default',
|
||||
protolinks='default',
|
||||
class_prefix='',
|
||||
id_prefix='markmin_'):
|
||||
"""
|
||||
Arguments:
|
||||
- text is the text to be processed
|
||||
@@ -546,8 +589,18 @@ def render(text,extra={},allowed={},sep='p',URL=None,environment=None,latex='goo
|
||||
allowed = dict(code=('python','cpp','java'))
|
||||
- sep can be 'p' to separate text in <p>...</p>
|
||||
or can be 'br' to separate text using <br />
|
||||
- auto is a True/False value (default is True) -
|
||||
enables auto links processing for iframe,embed,qr,url,image,video,audio
|
||||
- URL -
|
||||
- environment is a dictionary of environment variables (can be accessed with @{variable}
|
||||
- latex -
|
||||
- autolinks is a function to convert auto urls to html-code (default is autolinks(url) )
|
||||
- protolinks is a function to convert proto-urls (e.g."proto:url") to html-code
|
||||
(default is protolinks(proto,url))
|
||||
- class_prefix is a prefix for ALL classes in markmin text. E.g. if class_prefix='my_'
|
||||
then for ``test``:cls class will be changed to "my_cls" (default value is '')
|
||||
- id_prefix is prefix for ALL ids in markmin text (default value is 'markmin_'). E.g.:
|
||||
-- [[id]] will be converted to <a name="markmin_id"></a>
|
||||
-- [[link #id]] will be converted to <a href="#markmin_id">link</a>
|
||||
-- ``test``:cls[id] will be converted to <code class="cls" id="markmin_id">test</code>
|
||||
|
||||
>>> render('this is\\n# a section\\n\\nparagraph')
|
||||
'<p>this is</p><h1>a section</h1><p>paragraph</p>'
|
||||
@@ -583,7 +636,7 @@ def render(text,extra={},allowed={},sep='p',URL=None,environment=None,latex='goo
|
||||
'<ol><li>this</li><li>is</li><li>a list</li></ol><p>and this</p><ol><li>is</li><li>another</li></ol>'
|
||||
|
||||
>>> render("----\\na | b\\nc | d\\n----\\n")
|
||||
'<table><tbody><tr><td>a</td><td>b</td></tr><tr><td>c</td><td>d</td></tr></tbody></table>'
|
||||
'<table><tbody><tr class="first"><td>a</td><td>b</td></tr><tr class="even"><td>c</td><td>d</td></tr></tbody></table>'
|
||||
|
||||
>>> render("----\\nhello world\\n----\\n")
|
||||
'<blockquote>hello world</blockquote>'
|
||||
@@ -630,6 +683,15 @@ def render(text,extra={},allowed={},sep='p',URL=None,environment=None,latex='goo
|
||||
>>> render("auto-image: (http://example.com/image.jpeg)")
|
||||
'<p>auto-image: (<img src="http://example.com/image.jpeg" controls />)</p>'
|
||||
|
||||
>>> render("qr: (qr:http://example.com/image.jpeg)")
|
||||
'<p>qr: (<img width="80px" src="http://qrcode.kaywa.com/img.php?s=8&d=http://example.com/image.jpeg" alt="qr code" />)</p>'
|
||||
|
||||
>>> render("embed: (embed:http://example.com/page)")
|
||||
'<p>embed: (<iframe src="http://example.com/page" frameborder="0" allowfullscreen></iframe>)</p>'
|
||||
|
||||
>>> render("iframe: (iframe:http://example.com/page)")
|
||||
'<p>iframe: (<iframe src="http://example.com/page" frameborder="0" allowfullscreen></iframe>)</p>'
|
||||
|
||||
>>> render("title1: [[test message [simple \[test\] title] http://example.com ]] test")
|
||||
'<p>title1: <a href="http://example.com" title="simple [test] title">test message</a> test</p>'
|
||||
|
||||
@@ -723,26 +785,23 @@ def render(text,extra={},allowed={},sep='p',URL=None,environment=None,latex='goo
|
||||
>>> render("this is ``a green text``:color[green:]")
|
||||
'<p>this is <span style="color: green;">a green text</span></p>'
|
||||
|
||||
>>> render("**@{probe}**", environment=dict(probe="this is a test"))
|
||||
'<p><strong>this is a test</strong></p>'
|
||||
>>> render("**@{probe:1}**", environment=dict(probe=lambda t:"test %s" % t))
|
||||
'<p><strong>test 1</strong></p>'
|
||||
|
||||
>>> render('[[id1 [span **messag** in ''markmin''] ]] ... [[**link** to id [link\\\'s title] #mark1]]')
|
||||
'<p><a name="markmin_id1">span <strong>messag</strong> in markmin</a> ... <a href="#markmin_mark1" title="link\\\'s title"><strong>link</strong> to id</a></p>'
|
||||
|
||||
"""
|
||||
if autolinks=="default": autolinks = autolinks_simple
|
||||
if protolinks=="default": protolinks = protolinks_simple
|
||||
text = str(text or '')
|
||||
text = regex_backslash.sub(lambda m: m.group(1).translate(ttab_in), text)
|
||||
|
||||
if environment:
|
||||
def u2(match, environment=environment):
|
||||
return str(environment.get(match.group('a'), match.group(0)))
|
||||
text = regex_env.sub(u2, text)
|
||||
|
||||
if URL is not None:
|
||||
# this is experimental @{function/args}
|
||||
# turns into a digitally signed URL
|
||||
def u1(match,URL=URL):
|
||||
f,args = match.group('f','args')
|
||||
f,args = match.group('f','args')
|
||||
return URL(f,args=args.split('/'), scheme=True, host=True)
|
||||
text = regex_URL.sub(u1,text)
|
||||
|
||||
@@ -780,14 +839,11 @@ def render(text,extra={},allowed={},sep='p',URL=None,environment=None,latex='goo
|
||||
text = regex_link.sub(mark_link, text)
|
||||
text = escape(text)
|
||||
|
||||
if auto:
|
||||
text = regex_iframe.sub('<iframe src="\g<k>" frameborder="0" allowfullscreen></iframe>',text)
|
||||
text = regex_embed.sub('<a href="\g<k>" class="embed">\g<k></a>',text)
|
||||
text = regex_qr.sub('<img width="80px" src="http://qrcode.kaywa.com/img.php?s=8&d=\g<k>" alt="qr code" />',text)
|
||||
text = regex_auto_image.sub('<img src="\g<k>" controls />', text)
|
||||
text = regex_auto_video.sub('<video src="\g<k>" controls></video>', text)
|
||||
text = regex_auto_audio.sub('<audio src="\g<k>" controls></audio>', text)
|
||||
text = regex_auto.sub('<a href="\g<k>">\g<k></a>', text)
|
||||
if protolinks:
|
||||
text = regex_proto.sub(lambda m: protolinks(*m.group('p','k')), text)
|
||||
|
||||
if autolinks:
|
||||
text = regex_auto.sub(lambda m: autolinks(m.group('k')), text)
|
||||
|
||||
#############################################################
|
||||
# normalize spaces
|
||||
@@ -904,6 +960,7 @@ def render(text,extra={},allowed={},sep='p',URL=None,environment=None,latex='goo
|
||||
tout=[]
|
||||
thead=[]
|
||||
tbody=[]
|
||||
rownum=0
|
||||
t_id = ''
|
||||
t_cls = ''
|
||||
|
||||
@@ -914,9 +971,10 @@ def render(text,extra={},allowed={},sep='p',URL=None,environment=None,latex='goo
|
||||
if s.count('=')==len(s) and len(s)>3: # header or footer
|
||||
if not thead: # if thead list is empty:
|
||||
thead = tout
|
||||
else: # if tbody list is empty:
|
||||
else:
|
||||
tbody.extend(tout)
|
||||
tout = []
|
||||
rownum=0
|
||||
lineno+=1
|
||||
continue
|
||||
|
||||
@@ -926,12 +984,17 @@ def render(text,extra={},allowed={},sep='p',URL=None,environment=None,latex='goo
|
||||
t_id = m.group('p') or ''
|
||||
break
|
||||
|
||||
tout.append('<tr>'+''.join(['<td%s>%s</td>'% \
|
||||
(' class="num"'
|
||||
if regex_num.match(f)
|
||||
else '',
|
||||
f.strip()
|
||||
) for f in s.split('|')])+'</tr>')
|
||||
if rownum % 2:
|
||||
tr = '<tr class="even">'
|
||||
else:
|
||||
tr = '<tr class="first">' if rownum == 0 else '<tr>'
|
||||
tout.append(tr+''.join(['<td%s>%s</td>'% \
|
||||
(' class="num"'
|
||||
if regex_num.match(f)
|
||||
else '',
|
||||
f.strip()
|
||||
) for f in s.split('|')])+'</tr>')
|
||||
rownum+=1
|
||||
lineno+=1
|
||||
|
||||
t_cls = ' class="%s%s"'%(class_prefix, t_cls) if t_cls and t_cls != 'id' else ''
|
||||
@@ -990,7 +1053,8 @@ def render(text,extra={},allowed={},sep='p',URL=None,environment=None,latex='goo
|
||||
URL,
|
||||
environment,
|
||||
latex,
|
||||
auto,
|
||||
autolinks,
|
||||
protolinks,
|
||||
class_prefix,
|
||||
id_prefix)
|
||||
)
|
||||
@@ -1031,9 +1095,13 @@ def render(text,extra={},allowed={},sep='p',URL=None,environment=None,latex='goo
|
||||
c0=s[:1]
|
||||
if c0: # for non empty strings
|
||||
if c0 in "#+-.": # first character is one of: # + - .
|
||||
(t,p,s) = regex_list.findall(s)[0] # t - tag ("###", "+++", "---", "...")
|
||||
# p - paragraph point ('.')->for "++." or "--."
|
||||
# s - other part of string
|
||||
match = regex_list.search(s)
|
||||
(t,p,s) = match.group(1), None, match.group(2)
|
||||
t = (t or '').strip()
|
||||
if t.endswith('.'): t, p = t[:-1], '.'
|
||||
# t - tag ("###", "+++", "---", "...")
|
||||
# p - paragraph point ('.')->for "++." or "--."
|
||||
# s - other part of string
|
||||
if t:
|
||||
# headers and lists:
|
||||
if c0 == '#': # headers
|
||||
@@ -1107,7 +1175,7 @@ def render(text,extra={},allowed={},sep='p',URL=None,environment=None,latex='goo
|
||||
style = ' style="float:%s"' % p
|
||||
if p in ('video','audio'):
|
||||
t = render(t, {}, {}, 'br', URL, environment, latex,
|
||||
auto, class_prefix, id_prefix)
|
||||
autolinks, protolinks, class_prefix, id_prefix)
|
||||
return '<%(p)s controls="controls"%(title)s%(width)s><source src="%(k)s" />%(t)s</%(p)s>' \
|
||||
% dict(p=p, title=title, width=width, k=k, t=t)
|
||||
alt = ' alt="%s"'%escape(t).replace(META, DISABLED_META) if t else ''
|
||||
@@ -1127,14 +1195,14 @@ def render(text,extra={},allowed={},sep='p',URL=None,environment=None,latex='goo
|
||||
k = escape(k)
|
||||
title = ' title="%s"' % a.replace(META, DISABLED_META) if a else ''
|
||||
target = ' target="_blank"' if p == 'popup' else ''
|
||||
t = render(t, {}, {}, 'br', URL, environment, latex, auto,
|
||||
class_prefix, id_prefix) if t else k
|
||||
t = render(t, {}, {}, 'br', URL, environment, latex, autolinks,
|
||||
protolinks, class_prefix, id_prefix) if t else k
|
||||
return '<a href="%(k)s"%(title)s%(target)s>%(t)s</a>' \
|
||||
% dict(k=k, title=title, target=target, t=t)
|
||||
return '<a name="%s">%s</a>' % (escape(id_prefix+t),
|
||||
render(a, {},{},'br', URL,
|
||||
environment, latex, auto,
|
||||
class_prefix, id_prefix))
|
||||
environment, latex, autolinks,
|
||||
protolinks, class_prefix, id_prefix))
|
||||
|
||||
parts = text.split(LINK)
|
||||
text = parts[0]
|
||||
@@ -1172,13 +1240,13 @@ def render(text,extra={},allowed={},sep='p',URL=None,environment=None,latex='goo
|
||||
return LATEX % code.replace('"','\"').replace('\n',' ')
|
||||
elif b in html_colors:
|
||||
return '<span style="color: %s">%s</span>' \
|
||||
% (b, render(code,{},{},'br',URL,environment,latex,auto))
|
||||
% (b, render(code,{},{},'br',URL,environment,latex,autolinks, protolinks))
|
||||
elif b in ('c', 'color') and p:
|
||||
c=p.split(':')
|
||||
fg='color: %s;' % c[0] if c[0] else ''
|
||||
bg='background-color: %s;' % c[1] if len(c)>1 and c[1] else ''
|
||||
return '<span style="%s%s">%s</span>' \
|
||||
% (fg, bg, render(code,{},{},'br', URL, environment, latex, auto))
|
||||
% (fg, bg, render(code,{},{},'br', URL, environment, latex, autolinks, protolinks))
|
||||
cls = ' class="%s%s"'%(class_prefix,b) if b and b != 'id' else ''
|
||||
id = ' id="%s%s"'%(id_prefix,escape(p)) if p else ''
|
||||
beg=(code[:1]=='\n')
|
||||
@@ -1186,12 +1254,27 @@ def render(text,extra={},allowed={},sep='p',URL=None,environment=None,latex='goo
|
||||
if beg and end:
|
||||
return '<pre><code%s%s>%s</code></pre>' % (cls, id, escape(code[1:-1]))
|
||||
return '<code%s%s>%s</code>' % (cls, id, escape(code[beg:end]))
|
||||
|
||||
text = regex_expand_meta.sub(expand_meta, text)
|
||||
text = text.translate(ttab_out)
|
||||
|
||||
if environment:
|
||||
def u2(match, environment=environment):
|
||||
f = environment.get(match.group('a'), match.group(0))
|
||||
if callable(f):
|
||||
try:
|
||||
f = f(match.group('b'))
|
||||
except Exception, e:
|
||||
f = 'ERROR: %s' % e
|
||||
return str(f)
|
||||
text = regex_env.sub(u2, text)
|
||||
|
||||
return text
|
||||
|
||||
def markmin2html(text, extra={}, allowed={}, sep='p', auto=True):
|
||||
return render(text, extra, allowed, sep, auto=auto)
|
||||
def markmin2html(text, extra={}, allowed={}, sep='p',
|
||||
autolinks='default',protolinks='default'):
|
||||
return render(text, extra, allowed, sep,
|
||||
autolinks=autolinks, protolinks=protolinks)
|
||||
|
||||
if __name__ == '__main__':
|
||||
import sys
|
||||
@@ -1214,15 +1297,18 @@ if __name__ == '__main__':
|
||||
if sys.argv[1:2] == ['-h']:
|
||||
style=dedent("""
|
||||
<style>
|
||||
blockquote { background-color: lime; }
|
||||
thead { color: white; background-color: gray; text-align: center; }
|
||||
tfoot { color: white; background-color: gray; }
|
||||
.tableclass1 { background-color: yellow; }
|
||||
blockquote { background-color: #FFFAAE; padding: 7px; }
|
||||
table { border-collapse: collapse; }
|
||||
thead td { border-bottom: 1px solid; }
|
||||
tfoot td { border-top: 1px solid; }
|
||||
.tableclass1 { background-color: lime; }
|
||||
.tableclass1 thead { color: yellow; background-color: green; }
|
||||
.tableclass1 tfoot { color: yellow; background-color: green; }
|
||||
.tableclass1 .even td { background-color: #80FF7F; }
|
||||
.tableclass1 .first td {border-top: 1px solid; }
|
||||
|
||||
td.num { text-align: right; }
|
||||
pre { background-color: #E0E0E0; }
|
||||
pre { background-color: #E0E0E0; padding: 5px; }
|
||||
</style>""")[1:]
|
||||
|
||||
print html % dict(title="Markmin markup language", style=style, body=markmin2html(__doc__))
|
||||
@@ -1236,9 +1322,29 @@ if __name__ == '__main__':
|
||||
elif len(sys.argv) > 1:
|
||||
fargv = open(sys.argv[1],'r')
|
||||
try:
|
||||
print html % dict(title=sys.argv[1], style='', body=markmin2html(fargv.read()))
|
||||
markmin_text=fargv.read()
|
||||
|
||||
# embed css file from second parameter into html file
|
||||
if len(sys.argv) > 2:
|
||||
if sys.argv[2].startswith('@'):
|
||||
markmin_style = '<link rel="stylesheet" href="'+sys.argv[2][1:]+'"/>'
|
||||
else:
|
||||
fargv2 = open(sys.argv[2],'r')
|
||||
try:
|
||||
markmin_style = "<style>\n" + fargv2.read() + "</style>"
|
||||
finally:
|
||||
fargv2.close()
|
||||
else:
|
||||
markmin_style = ""
|
||||
|
||||
print html % dict(title=sys.argv[1], style=markmin_style, body=markmin2html(markmin_text))
|
||||
finally:
|
||||
fargv.close()
|
||||
else:
|
||||
doctest.testmod()
|
||||
|
||||
else:
|
||||
print "Usage: "+sys.argv[0]+" -h | -t | file.markmin [file.css|@path_to/css]"
|
||||
print "where: -h - print __doc__"
|
||||
print " -t - timeit __doc__ (for testing purpuse only)"
|
||||
print " file.markmin [file.css] - process file.markmin + built in file.css (optional)"
|
||||
print " file.markmin [@path_to/css] - process file.markmin + link path_to/css (optional)"
|
||||
doctest.testmod()
|
||||
|
||||
@@ -139,7 +139,7 @@ def render(text,
|
||||
text = regex_noindent.sub('\n\\\\noindent \g<t>',text)
|
||||
|
||||
### fix paths in images
|
||||
regex=re.compile('\\\\_[\w_]*\.(eps|png|jpg|gif)')
|
||||
regex=re.compile('\\\\_\w*\.(eps|png|jpg|gif)')
|
||||
while True:
|
||||
match=regex.search(text)
|
||||
if not match: break
|
||||
|
||||
@@ -10,21 +10,19 @@ cache.memcache = MemcacheClient(request,[127.0.0.1:11211],debug=true)
|
||||
|
||||
import cPickle as pickle
|
||||
import thread
|
||||
from gluon import current
|
||||
|
||||
locker = thread.allocate_lock()
|
||||
DEFAULT_TIME_EXPIRE = 300 # seconds (must be the same as cache.ram)
|
||||
|
||||
def MemcacheClient(*a, **b):
|
||||
locker.acquire()
|
||||
try:
|
||||
if not hasattr(MemcacheClient, '__mc_instance'):
|
||||
MemcacheClient.__mc_instance = _MemcacheClient(*a, **b)
|
||||
finally:
|
||||
locker.release()
|
||||
return MemcacheClient.__mc_instance
|
||||
if not hasattr(current,'__mc_instance'):
|
||||
current.__memcache_client = MemcacheClientObj(*a, **b)
|
||||
return current.__memecache_client
|
||||
|
||||
class _MemcacheClient(Client):
|
||||
class MemcacheClientObj(Client):
|
||||
|
||||
meta_storage = {}
|
||||
max_time_expire = 24*3600
|
||||
|
||||
def __init__(self, request, servers, debug=0, pickleProtocol=0,
|
||||
pickler=pickle.Pickler, unpickler=pickle.Unpickler,
|
||||
@@ -45,33 +43,50 @@ class _MemcacheClient(Client):
|
||||
else:
|
||||
self.storage = self.meta_storage[app]
|
||||
|
||||
|
||||
def __call__(self, key, f, time_expire=300):
|
||||
def __call__(self, key, f,
|
||||
time_expire=DEFAULT_TIME_EXPIRE):
|
||||
if time_expire == None:
|
||||
time_expire = 10**10
|
||||
time_expire = self.max_time_expire
|
||||
# this must be commented because get and set are redefined
|
||||
# key = self.__keyFormat__(key)
|
||||
now = time.time()
|
||||
value = None
|
||||
obj = self.get(key)
|
||||
if obj:
|
||||
value = obj
|
||||
elif f is None:
|
||||
if obj: self.delete(key)
|
||||
if f is None: # force deletion of value
|
||||
self.delete(key)
|
||||
return None
|
||||
elif time_expire==0: # value forced expired
|
||||
item = None # value to be computed
|
||||
else:
|
||||
item = self.get(key)
|
||||
if item:
|
||||
if not isinstance(item,(list,tuple)):
|
||||
value = item
|
||||
elif (item[0] < now - dt): # value expired
|
||||
item = None # value to be computed
|
||||
else:
|
||||
value = item[1]
|
||||
if not item:
|
||||
value = f()
|
||||
self.set(key, value, time_expire)
|
||||
self.set(key, (now,value), self.max_time_expire)
|
||||
return value
|
||||
|
||||
def increment(self, key, value=1, time_expire=300):
|
||||
def increment(self, key, value=1, time_expire=DEFAULT_TIME_EXPIRE):
|
||||
""" time_expire is ignored """
|
||||
newKey = self.__keyFormat__(key)
|
||||
obj = Client.get(self, newKey)
|
||||
if obj:
|
||||
return Client.incr(self, newKey, value)
|
||||
if isinstance(obj,(int,double,long)):
|
||||
return Client.incr(self, newKey, value)
|
||||
else:
|
||||
value += obj[1]
|
||||
Client.set(self,newKey,(time.time(),value),
|
||||
self.max_time_expire)
|
||||
return value
|
||||
else:
|
||||
Client.set(self, newKey, value, time_expire)
|
||||
Client.set(self, newKey, value, self.max_time_expire)
|
||||
return value
|
||||
|
||||
def set(self, key, value, time_expire=300):
|
||||
def set(self, key, value, time_expire=DEFAULT_TIME_EXPIRE):
|
||||
newKey = self.__keyFormat__(key)
|
||||
return Client.set(self, newKey, value, time_expire)
|
||||
|
||||
|
||||
@@ -910,3 +910,4 @@ if __name__ == '__main__':
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -126,3 +126,4 @@ if __name__ == "__main__":
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -128,3 +128,4 @@ def test():
|
||||
|
||||
if __name__ == '__main__':
|
||||
test()
|
||||
|
||||
|
||||
@@ -140,7 +140,7 @@ def populate(table, n, default=True, compute=False):
|
||||
ids[tablename] = [x.id for x in table._db(table._db[field.type[15:]].id>0).select()]
|
||||
n = len(ids[tablename])
|
||||
if n:
|
||||
record[fieldname] = [item[0] for item in random.sample(ids[tablename], random.randint(0,n-1)/2)]
|
||||
record[fieldname] = [item for item in random.sample(ids[tablename], random.randint(0,n-1)/2)]
|
||||
else:
|
||||
record[fieldname] = 0
|
||||
elif field.type=='list:string' and hasattr(field.requires,'options'):
|
||||
@@ -170,3 +170,4 @@ if __name__ == '__main__':
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -963,3 +963,4 @@ if __name__ == '__main__':
|
||||
qdb.main(**kwargs)
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -166,3 +166,4 @@ class RedisClient(object):
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -591,3 +591,4 @@ if __name__ == '__main__':
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -269,3 +269,4 @@ if __name__=='__main__':
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -150,3 +150,4 @@ if __name__ == "__main__":
|
||||
print client.add(1, 2)
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -115,3 +115,4 @@ def sms_email(number,provider):
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user