diff --git a/VERSION b/VERSION
index 680409b5..75146f1f 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-Version 2.16.1-stable+timestamp.2018.03.08.10.23.01
+Version 2.16.1-stable+timestamp.2018.05.01.21.42.57
diff --git a/applications/admin/controllers/appadmin.py b/applications/admin/controllers/appadmin.py
index 0188ade9..da050a5b 100644
--- a/applications/admin/controllers/appadmin.py
+++ b/applications/admin/controllers/appadmin.py
@@ -224,15 +224,15 @@ def select():
session.last_orderby = orderby
session.last_query = request.vars.query
form = FORM(TABLE(TR(T('Query:'), '', INPUT(_style='width:400px',
- _name='query', _value=request.vars.query or '',
+ _name='query', _value=request.vars.query or '', _class="form-control",
requires=IS_NOT_EMPTY(
error_message=T("Cannot be empty")))), TR(T('Update:'),
INPUT(_name='update_check', _type='checkbox',
value=False), INPUT(_style='width:400px',
_name='update_fields', _value=request.vars.update_fields
- or '')), TR(T('Delete:'), INPUT(_name='delete_check',
+ or '', _class="form-control")), TR(T('Delete:'), INPUT(_name='delete_check',
_class='delete', _type='checkbox', value=False), ''),
- TR('', '', INPUT(_type='submit', _value=T('submit')))),
+ TR('', '', INPUT(_type='submit', _value=T('submit'), _class="btn btn-primary"))),
_action=URL(r=request, args=request.args))
tb = None
@@ -274,7 +274,7 @@ def select():
formcsv = FORM(str(T('or import from csv file')) + " ",
INPUT(_type='file', _name='csvfile'),
INPUT(_type='hidden', _value=csv_table, _name='table'),
- INPUT(_type='submit', _value=T('import')))
+ INPUT(_type='submit', _value=T('import'), _class="btn btn-primary"))
else:
formcsv = None
if formcsv and formcsv.process().accepted:
@@ -392,7 +392,7 @@ def ccache():
cache.disk.clear()
session.flash += T("Disk Cleared")
redirect(URL(r=request))
-
+
try:
from pympler.asizeof import asizeof
except ImportError:
@@ -588,7 +588,7 @@ def manage():
auth.table_permission().group_id.label = T('Role')
auth.table_permission().name.label = T('Permission')
if table == auth.table_user():
- linked_tables=[auth.settings.table_membership_name]
+ linked_tables = [auth.settings.table_membership_name]
elif table == auth.table_group():
orderby = 'role' if not request.args(3) or '.group_id' not in request.args(3) else None
elif table == auth.table_permission():
@@ -604,13 +604,13 @@ def manage():
def hooks():
import functools
import inspect
- list_op=['_%s_%s' %(h,m) for h in ['before', 'after'] for m in ['insert','update','delete']]
- tables=[]
- with_build_it=False
+ list_op = ['_%s_%s' %(h,m) for h in ['before', 'after'] for m in ['insert','update','delete']]
+ tables = []
+ with_build_it = False
for db_str in sorted(databases):
db = databases[db_str]
for t in db.tables:
- method_hooks=[]
+ method_hooks = []
for op in list_op:
functions = []
for f in getattr(db[t], op):
@@ -630,16 +630,16 @@ def hooks():
except:
pass
if len(functions):
- method_hooks.append({'name':op, 'functions':functions})
+ method_hooks.append({'name': op, 'functions':functions})
if len(method_hooks):
- tables.append({'name':"%s.%s" % (db_str,t), 'slug': IS_SLUG()("%s.%s" % (db_str,t))[0], 'method_hooks':method_hooks})
+ tables.append({'name': "%s.%s" % (db_str, t), 'slug': IS_SLUG()("%s.%s" % (db_str,t))[0], 'method_hooks':method_hooks})
# Render
ul_main = UL(_class='nav nav-list')
for t in tables:
ul_main.append(A(t['name'], _onclick="collapse('a_%s')" % t['slug']))
ul_t = UL(_class='nav nav-list', _id="a_%s" % t['slug'], _style='display:none')
for op in t['method_hooks']:
- ul_t.append(LI (op['name']))
+ ul_t.append(LI(op['name']))
ul_t.append(UL([LI(A(f['funcname'], _class="editor_filelink", _href=f['url']if 'url' in f else None, **{'_data-lineno':f['lineno']-1})) for f in op['functions']]))
ul_main.append(ul_t)
return ul_main
@@ -652,10 +652,10 @@ def hooks():
def d3_graph_model():
""" See https://www.facebook.com/web2py/posts/145613995589010 from Bruno Rocha
and also the app_admin bg_graph_model function
-
+
Create a list of table dicts, called "nodes"
"""
-
+
nodes = []
links = []
@@ -665,20 +665,20 @@ def d3_graph_model():
fields = []
for field in db[tablename]:
f_type = field.type
- if not isinstance(f_type,str):
+ if not isinstance(f_type, str):
disp = ' '
elif f_type == 'string':
- disp = field.length
+ disp = field.length
elif f_type == 'id':
- disp = "PK"
+ disp = "PK"
elif f_type.startswith('reference') or \
f_type.startswith('list:reference'):
disp = "FK"
else:
disp = ' '
- fields.append(dict(name= field.name, type=field.type, disp = disp))
+ fields.append(dict(name=field.name, type=field.type, disp=disp))
- if isinstance(f_type,str) and (
+ if isinstance(f_type, str) and (
f_type.startswith('reference') or
f_type.startswith('list:reference')):
referenced_table = f_type.split()[1].split('.')[0]
diff --git a/applications/admin/views/appadmin.html b/applications/admin/views/appadmin.html
index 8a9d3400..2ce42621 100644
--- a/applications/admin/views/appadmin.html
+++ b/applications/admin/views/appadmin.html
@@ -9,16 +9,19 @@
});
//-->
+
+
+
{{if request.function=='index':}}
{{=T("Available Databases and Tables")}}
{{if not databases:}}{{=T("No databases in this application")}}{{pass}}
-
+
{{for db in sorted(databases):}}
{{for table in databases[db].tables:}}
{{qry='%s.%s.id>0'%(db,table)}}
@@ -37,10 +40,10 @@
{{pass}}
|
- {{=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)))}}
|
- {{=A(str(T('New Record')),_href=URL('insert',args=[db,table]),_class="btn btn-default")}}
+ {{=A(str(T('New Record')),_href=URL('insert',args=[db,table]),_class="btn btn-primary")}}
|
{{pass}}
@@ -61,28 +64,31 @@
{{pass}}
{{if table:}}
- {{=A(str(T('New Record')),_href=URL('insert',args=[request.args[0],table]),_class="btn btn-default")}}
+ {{=A(str(T('New Record')),_href=URL('insert',args=[request.args[0],table]),_class="btn btn-primary", _role="button")}}
+
{{=T("Rows in Table")}}
{{else:}}
{{=T("Rows selected")}}
{{pass}}
{{=form}}
- {{=T('The "query" is a condition like "db.table1.field1==\'value\'". Something like "db.table1.field1==db.table2.field2" results in a SQL JOIN.')}}
+
{{=T('The "query" is a condition like "db.table1.field1==\'value\'". Something like "db.table1.field1==db.table2.field2" results in a SQL JOIN.')}}
{{=T('Use (...)&(...) for AND, (...)|(...) for OR, and ~(...) for NOT to build more complex queries.')}}
{{=T('"update" is an optional expression like "field1=\'newvalue\'". You cannot update or delete the results of a JOIN')}}
{{=T("%s selected", nrows)}}
- {{if start>0:}}{{=A(T('previous %s rows') % step,_href=URL('select',args=request.args[0],vars=dict(start=start-step)),_class="btn btn-default")}}{{pass}}
- {{if stop0:}}{{=A(T('previous %s rows') % step,_href=URL('select',args=request.args[0],vars=dict(start=start-step)),_class="btn btn-primary")}}{{pass}}
+ {{if stop
{{linkto = lambda f, t, r: URL('update', args=[request.args[0], r, f]) if f else "#"}}
{{upload=URL('download',args=request.args[0])}}
- {{=SQLTABLE(rows,linkto,upload,orderby=True,_class='sortable')}}
+ {{=SQLTABLE(rows,linkto,upload,orderby=True,_class='table table-striped table-bordered sortable')}}
{{pass}}
-
{{=T("Import/Export")}}
- {{=T("export as csv file")}}
+
+
+ {{=T("Import/Export")}}
+ {{=T("export as csv file")}}
{{=formcsv or ''}}
{{elif request.function=='insert':}}
@@ -268,3 +274,6 @@
{{pass}}
{{pass}}
+
+
+
diff --git a/applications/examples/controllers/appadmin.py b/applications/examples/controllers/appadmin.py
index 0188ade9..da050a5b 100644
--- a/applications/examples/controllers/appadmin.py
+++ b/applications/examples/controllers/appadmin.py
@@ -224,15 +224,15 @@ def select():
session.last_orderby = orderby
session.last_query = request.vars.query
form = FORM(TABLE(TR(T('Query:'), '', INPUT(_style='width:400px',
- _name='query', _value=request.vars.query or '',
+ _name='query', _value=request.vars.query or '', _class="form-control",
requires=IS_NOT_EMPTY(
error_message=T("Cannot be empty")))), TR(T('Update:'),
INPUT(_name='update_check', _type='checkbox',
value=False), INPUT(_style='width:400px',
_name='update_fields', _value=request.vars.update_fields
- or '')), TR(T('Delete:'), INPUT(_name='delete_check',
+ or '', _class="form-control")), TR(T('Delete:'), INPUT(_name='delete_check',
_class='delete', _type='checkbox', value=False), ''),
- TR('', '', INPUT(_type='submit', _value=T('submit')))),
+ TR('', '', INPUT(_type='submit', _value=T('submit'), _class="btn btn-primary"))),
_action=URL(r=request, args=request.args))
tb = None
@@ -274,7 +274,7 @@ def select():
formcsv = FORM(str(T('or import from csv file')) + " ",
INPUT(_type='file', _name='csvfile'),
INPUT(_type='hidden', _value=csv_table, _name='table'),
- INPUT(_type='submit', _value=T('import')))
+ INPUT(_type='submit', _value=T('import'), _class="btn btn-primary"))
else:
formcsv = None
if formcsv and formcsv.process().accepted:
@@ -392,7 +392,7 @@ def ccache():
cache.disk.clear()
session.flash += T("Disk Cleared")
redirect(URL(r=request))
-
+
try:
from pympler.asizeof import asizeof
except ImportError:
@@ -588,7 +588,7 @@ def manage():
auth.table_permission().group_id.label = T('Role')
auth.table_permission().name.label = T('Permission')
if table == auth.table_user():
- linked_tables=[auth.settings.table_membership_name]
+ linked_tables = [auth.settings.table_membership_name]
elif table == auth.table_group():
orderby = 'role' if not request.args(3) or '.group_id' not in request.args(3) else None
elif table == auth.table_permission():
@@ -604,13 +604,13 @@ def manage():
def hooks():
import functools
import inspect
- list_op=['_%s_%s' %(h,m) for h in ['before', 'after'] for m in ['insert','update','delete']]
- tables=[]
- with_build_it=False
+ list_op = ['_%s_%s' %(h,m) for h in ['before', 'after'] for m in ['insert','update','delete']]
+ tables = []
+ with_build_it = False
for db_str in sorted(databases):
db = databases[db_str]
for t in db.tables:
- method_hooks=[]
+ method_hooks = []
for op in list_op:
functions = []
for f in getattr(db[t], op):
@@ -630,16 +630,16 @@ def hooks():
except:
pass
if len(functions):
- method_hooks.append({'name':op, 'functions':functions})
+ method_hooks.append({'name': op, 'functions':functions})
if len(method_hooks):
- tables.append({'name':"%s.%s" % (db_str,t), 'slug': IS_SLUG()("%s.%s" % (db_str,t))[0], 'method_hooks':method_hooks})
+ tables.append({'name': "%s.%s" % (db_str, t), 'slug': IS_SLUG()("%s.%s" % (db_str,t))[0], 'method_hooks':method_hooks})
# Render
ul_main = UL(_class='nav nav-list')
for t in tables:
ul_main.append(A(t['name'], _onclick="collapse('a_%s')" % t['slug']))
ul_t = UL(_class='nav nav-list', _id="a_%s" % t['slug'], _style='display:none')
for op in t['method_hooks']:
- ul_t.append(LI (op['name']))
+ ul_t.append(LI(op['name']))
ul_t.append(UL([LI(A(f['funcname'], _class="editor_filelink", _href=f['url']if 'url' in f else None, **{'_data-lineno':f['lineno']-1})) for f in op['functions']]))
ul_main.append(ul_t)
return ul_main
@@ -652,10 +652,10 @@ def hooks():
def d3_graph_model():
""" See https://www.facebook.com/web2py/posts/145613995589010 from Bruno Rocha
and also the app_admin bg_graph_model function
-
+
Create a list of table dicts, called "nodes"
"""
-
+
nodes = []
links = []
@@ -665,20 +665,20 @@ def d3_graph_model():
fields = []
for field in db[tablename]:
f_type = field.type
- if not isinstance(f_type,str):
+ if not isinstance(f_type, str):
disp = ' '
elif f_type == 'string':
- disp = field.length
+ disp = field.length
elif f_type == 'id':
- disp = "PK"
+ disp = "PK"
elif f_type.startswith('reference') or \
f_type.startswith('list:reference'):
disp = "FK"
else:
disp = ' '
- fields.append(dict(name= field.name, type=field.type, disp = disp))
+ fields.append(dict(name=field.name, type=field.type, disp=disp))
- if isinstance(f_type,str) and (
+ if isinstance(f_type, str) and (
f_type.startswith('reference') or
f_type.startswith('list:reference')):
referenced_table = f_type.split()[1].split('.')[0]
diff --git a/applications/examples/views/appadmin.html b/applications/examples/views/appadmin.html
index 8a9d3400..2ce42621 100644
--- a/applications/examples/views/appadmin.html
+++ b/applications/examples/views/appadmin.html
@@ -9,16 +9,19 @@
});
//-->
+
+
+
{{if request.function=='index':}}
{{=T("Available Databases and Tables")}}
{{if not databases:}}{{=T("No databases in this application")}}{{pass}}
-
+
{{for db in sorted(databases):}}
{{for table in databases[db].tables:}}
{{qry='%s.%s.id>0'%(db,table)}}
@@ -37,10 +40,10 @@
{{pass}}
|
- {{=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)))}}
|
- {{=A(str(T('New Record')),_href=URL('insert',args=[db,table]),_class="btn btn-default")}}
+ {{=A(str(T('New Record')),_href=URL('insert',args=[db,table]),_class="btn btn-primary")}}
|
{{pass}}
@@ -61,28 +64,31 @@
{{pass}}
{{if table:}}
- {{=A(str(T('New Record')),_href=URL('insert',args=[request.args[0],table]),_class="btn btn-default")}}
+ {{=A(str(T('New Record')),_href=URL('insert',args=[request.args[0],table]),_class="btn btn-primary", _role="button")}}
+
{{=T("Rows in Table")}}
{{else:}}
{{=T("Rows selected")}}
{{pass}}
{{=form}}
- {{=T('The "query" is a condition like "db.table1.field1==\'value\'". Something like "db.table1.field1==db.table2.field2" results in a SQL JOIN.')}}
+
{{=T('The "query" is a condition like "db.table1.field1==\'value\'". Something like "db.table1.field1==db.table2.field2" results in a SQL JOIN.')}}
{{=T('Use (...)&(...) for AND, (...)|(...) for OR, and ~(...) for NOT to build more complex queries.')}}
{{=T('"update" is an optional expression like "field1=\'newvalue\'". You cannot update or delete the results of a JOIN')}}
{{=T("%s selected", nrows)}}
- {{if start>0:}}{{=A(T('previous %s rows') % step,_href=URL('select',args=request.args[0],vars=dict(start=start-step)),_class="btn btn-default")}}{{pass}}
- {{if stop0:}}{{=A(T('previous %s rows') % step,_href=URL('select',args=request.args[0],vars=dict(start=start-step)),_class="btn btn-primary")}}{{pass}}
+ {{if stop
{{linkto = lambda f, t, r: URL('update', args=[request.args[0], r, f]) if f else "#"}}
{{upload=URL('download',args=request.args[0])}}
- {{=SQLTABLE(rows,linkto,upload,orderby=True,_class='sortable')}}
+ {{=SQLTABLE(rows,linkto,upload,orderby=True,_class='table table-striped table-bordered sortable')}}
{{pass}}
-
{{=T("Import/Export")}}
- {{=T("export as csv file")}}
+
+
+ {{=T("Import/Export")}}
+ {{=T("export as csv file")}}
{{=formcsv or ''}}
{{elif request.function=='insert':}}
@@ -268,3 +274,6 @@
{{pass}}
{{pass}}
+
+
+
diff --git a/scripts/drop-pgsql-tables.sh b/scripts/drop-pgsql-tables.sh
new file mode 100644
index 00000000..44e51972
--- /dev/null
+++ b/scripts/drop-pgsql-tables.sh
@@ -0,0 +1,14 @@
+# first, login with psql
+psql -U USERNAME -d databasename
+
+# set output for all queries
+\o FILENAME.sql
+
+# run this query
+select 'drop table ' || tablename || ' cascade;' from pg_tables;
+
+# logout from psql
+\q
+
+# run sql script from commandline
+psql -U USERNAME -d databasename -f FILENAME.sql
\ No newline at end of file