fixes issue 1980

pyflaked the module, at least a bit. Sometimes I feel developers are in a contest
where less characters and lines win. Concise implementation wins over verbose one,
but less SLOC DON'T mean somewhat better code. Just reading through
this module makes my brain hurt a bit
This commit is contained in:
niphlod
2014-09-30 21:30:28 +02:00
parent 05689aa526
commit 1e35262e67
+99 -67
View File
@@ -14,13 +14,18 @@ Holds:
"""
import datetime
import urllib
import re
import cStringIO
import os
from gluon.http import HTTP
from gluon.html import XmlComponent
from gluon.html import XML, SPAN, TAG, A, DIV, CAT, UL, LI, TEXTAREA, BR, IMG, SCRIPT, P
from gluon.http import HTTP, redirect
from gluon.html import XmlComponent, truncate_string
from gluon.html import XML, SPAN, TAG, A, DIV, CAT, UL, LI, TEXTAREA, BR, IMG
from gluon.html import FORM, INPUT, LABEL, OPTION, SELECT, COL, COLGROUP
from gluon.html import TABLE, THEAD, TBODY, TR, TD, TH, STYLE, DEFAULT_PASSWORD_DISPLAY
from gluon.html import URL, truncate_string, FIELDSET
from gluon.html import TABLE, THEAD, TBODY, TR, TD, TH, STYLE, SCRIPT
from gluon.html import URL, FIELDSET, P, DEFAULT_PASSWORD_DISPLAY
from gluon.dal import DAL, Field
from gluon.dal.base import DEFAULT
from gluon.dal.objects import Table, Row, Expression
@@ -29,16 +34,12 @@ from gluon.dal.helpers.methods import smart_query, bar_encode, sqlhtml_validator
from gluon.dal.helpers.classes import Reference, SQLCustomType
from gluon.storage import Storage
from gluon.utils import md5_hash
from gluon.validators import IS_EMPTY_OR, IS_NOT_EMPTY, IS_LIST_OF, IS_DATE, \
IS_DATETIME, IS_INT_IN_RANGE, IS_FLOAT_IN_RANGE, IS_STRONG
from gluon.validators import IS_EMPTY_OR, IS_NOT_EMPTY, IS_LIST_OF, IS_DATE
from gluon.validators import IS_DATETIME, IS_INT_IN_RANGE, IS_FLOAT_IN_RANGE
from gluon.validators import IS_STRONG
import gluon.serializers as serializers
import datetime
import urllib
import re
import cStringIO
from gluon.globals import current
from gluon.http import redirect
try:
import gluon.settings as settings
@@ -49,7 +50,7 @@ widget_class = re.compile('^\w*')
def add_class(a, b):
return a+' '+b if a else b
return a + ' ' + b if a else b
def represent(field, value, record):
@@ -85,11 +86,11 @@ def show_if(cond):
if not cond:
return None
base = "%s_%s" % (cond.first.tablename, cond.first.name)
if ((cond.op.__name__ == 'EQ' and cond.second == True) or
(cond.op.__name__ == 'NE' and cond.second == False)):
if ((cond.op.__name__ == 'EQ' and cond.second is True) or
(cond.op.__name__ == 'NE' and cond.second is False)):
return base, ":checked"
if ((cond.op.__name__ == 'EQ' and cond.second == False) or
(cond.op.__name__ == 'NE' and cond.second == True)):
if ((cond.op.__name__ == 'EQ' and cond.second is False) or
(cond.op.__name__ == 'NE' and cond.second is True)):
return base, ":not(:checked)"
if cond.op.__name__ == 'EQ':
return base, "[value='%s']" % cond.second
@@ -305,7 +306,8 @@ class ListWidget(StringWidget):
_class = 'string'
requires = field.requires if isinstance(
field.requires, (IS_NOT_EMPTY, IS_LIST_OF)) else None
if isinstance(value, str): value = [value]
if isinstance(value, str):
value = [value]
nvalue = value or ['']
items = [LI(INPUT(_id=_id, _class=_class, _name=_name,
value=v, hideerror=k < len(nvalue) - 1,
@@ -351,7 +353,6 @@ class RadioWidget(OptionsWidget):
else:
value = str(value)
attr = cls._attributes(field, {}, **attributes)
attr['_class'] = add_class(attr.get('_class'), 'web2py_radiowidget')
@@ -626,7 +627,7 @@ class AutocompleteWidget(object):
self.help_fields = help_fields or []
self.help_string = help_string
if self.help_fields and not self.help_string:
self.help_string = ' '.join('%%(%s)s'%f.name
self.help_string = ' '.join('%%(%s)s' % f.name
for f in self.help_fields)
self.request = request
@@ -900,7 +901,7 @@ def formstyle_bootstrap3_inline_factory(col_label_size=3):
label['_for'] = None
label.insert(0, controls)
_controls = DIV(DIV(label, _help, _class="checkbox"),
_class="%s %s" % (offset_class, col_class))
_class="%s %s" % (offset_class, col_class))
label = ''
elif isinstance(controls, SELECT):
controls.add_class('form-control')
@@ -1132,7 +1133,7 @@ class SQLFORM(FORM):
if fieldname.find('.') >= 0:
continue
field = (self.table[fieldname] if fieldname in self.table.fields
field = (self.table[fieldname] if fieldname in self.table.fields
else self.extra_fields[fieldname])
comment = None
@@ -1184,7 +1185,7 @@ class SQLFORM(FORM):
cond = readonly or \
(not ignore_rw and not field.writable and field.readable)
if default is not None and not cond:
if default is not None and not cond:
default = field.formatter(default)
dspval = default
@@ -1192,10 +1193,6 @@ class SQLFORM(FORM):
if cond:
# ## if field.re field.requires = sqlhtml_validators(field) field.requires = sqlhtml_validators(field)present is available else
# ## ignore blob and preview uploaded images
# ## format everything else
if field.represent:
inp = represent(field, default, record)
elif field.type in ['blob']:
@@ -1272,7 +1269,7 @@ class SQLFORM(FORM):
(olname.replace('.', '__') + SQLFORM.ID_ROW_SUFFIX,
'', widget, col3.get(olname, '')))
self.custom.linkto[olname.replace('.', '__')] = widget
# </block>
# </block>
# when deletable, add delete? checkbox
self.custom.delete = self.custom.deletable = ''
@@ -1291,16 +1288,15 @@ class SQLFORM(FORM):
)
xfields.append(
(self.FIELDKEY_DELETE_RECORD + SQLFORM.ID_ROW_SUFFIX,
LABEL(
LABEL(
T(delete_label), sep,
_for=self.FIELDKEY_DELETE_RECORD,
_id=self.FIELDKEY_DELETE_RECORD + \
SQLFORM.ID_LABEL_SUFFIX),
_id=self.FIELDKEY_DELETE_RECORD +
SQLFORM.ID_LABEL_SUFFIX),
widget,
col3.get(self.FIELDKEY_DELETE_RECORD, '')))
self.custom.delete = self.custom.deletable = widget
# when writable, add submit button
self.custom.submit = ''
if not readonly:
@@ -1480,7 +1476,7 @@ class SQLFORM(FORM):
# that does not pass validation, yet it should be deleted
for fieldname in self.fields:
field = (self.table[fieldname]
field = (self.table[fieldname]
if fieldname in self.table.fields
else self.extra_fields[fieldname])
### this is a workaround! widgets should always have default not None!
@@ -1995,6 +1991,18 @@ class SQLFORM(FORM):
details = details and not groupby
rows = None
# see issue 1980. Basically we can have keywords in get_vars
# (i.e. when the search term is propagated through page=2&keywords=abc)
# but if there is keywords in post_vars (i.e. POSTing a search request)
# the one in get_vars should be replaced by the new one
keywords = ''
if 'keywords' in request.post_vars:
keywords = request.post_vars.keywords
elif 'keywords' in request.get_vars:
keywords = request.get_vars.keywords
print 'keyworkds are', keywords
def fetch_count(dbset):
##FIXME for google:datastore cache_count is ignored
## if it's not an integer
@@ -2051,7 +2059,7 @@ class SQLFORM(FORM):
'/'.join(str(a) for a in args) == '/'.join(request.args) or
URL.verify(request, user_signature=user_signature,
hash_vars=False) or
(request.args(len(args))=='view' and not logged)):
(request.args(len(args))=='view' and not logged)):
session.flash = T('not authorized')
redirect(referrer)
@@ -2096,8 +2104,8 @@ class SQLFORM(FORM):
else:
fields = []
columns = []
filter1 = lambda f:isinstance(f, Field)
filter2 = lambda f:isinstance(f, Field) and f.readable
filter1 = lambda f: isinstance(f, Field)
filter2 = lambda f: isinstance(f, Field) and f.readable
for table in tables:
fields += filter(filter1, table)
columns += filter(filter2, table)
@@ -2111,15 +2119,18 @@ class SQLFORM(FORM):
if groupby is None:
field_id = tables[0]._id
elif groupby and isinstance(groupby, Field):
field_id = groupby #take the field passed as groupby
#take the field passed as groupby
field_id = groupby
elif groupby and isinstance(groupby, Expression):
field_id = groupby.first #take the first groupby field
while not(isinstance(field_id, Field)): # Navigate to the first Field of the expression
#take the first groupby field
field_id = groupby.first
while not(isinstance(field_id, Field)):
# Navigate to the first Field of the expression
field_id = field_id.first
table = field_id.table
tablename = table._tablename
if not any(str(f) == str(field_id) for f in fields):
fields = [f for f in fields]+[field_id]
fields = [f for f in fields] + [field_id]
if upload == '<default>':
upload = lambda filename: url(args=['download', filename])
if request.args(-2) == 'download':
@@ -2283,8 +2294,10 @@ class SQLFORM(FORM):
expcolumns = [str(f) for f in columns]
selectable_columns = [str(f) for f in columns if not isinstance(f, Field.Virtual)]
if export_type.endswith('with_hidden_cols'):
#expcolumns = [] start with the visible columns, which includes visible virtual fields
selectable_columns = [] #like expcolumns but excluding virtual
# expcolumns = [] start with the visible columns, which
# includes visible virtual fields
selectable_columns = []
#like expcolumns but excluding virtual
for table in tables:
for field in table:
if field.readable and field.tablename in tablenames:
@@ -2292,19 +2305,21 @@ class SQLFORM(FORM):
expcolumns.append(str(field))
if not(isinstance(field, Field.Virtual)):
selectable_columns.append(str(field))
#look for virtual fields not displayed (and virtual method fields to be added here?)
#look for virtual fields not displayed (and virtual method
#fields to be added here?)
for (field_name, field) in table.iteritems():
if isinstance(field, Field.Virtual) and not str(field) in expcolumns:
expcolumns.append(str(field))
if export_type in exportManager and exportManager[export_type]:
if request.vars.keywords:
if keywords:
try:
#the query should be constructed using searchable fields but not virtual fields
#the query should be constructed using searchable
#fields but not virtual fields
sfields = reduce(lambda a, b: a + b,
[[f for f in t if f.readable and not isinstance(f, Field.Virtual)] for t in tables])
dbset = dbset(SQLFORM.build_query(
sfields, request.vars.get('keywords', '')))
sfields, keywords))
rows = dbset.select(left=left, orderby=orderby,
cacheable=True, *selectable_columns)
except Exception, e:
@@ -2316,7 +2331,8 @@ class SQLFORM(FORM):
value = exportManager[export_type]
clazz = value[0] if hasattr(value, '__getitem__') else value
rows.colnames = expcolumns # expcolumns is all cols to be exported including virtual fields
# expcolumns is all cols to be exported including virtual fields
rows.colnames = expcolumns
oExp = clazz(rows)
filename = '.'.join(('rows', oExp.file_ext))
response.headers['Content-Type'] = oExp.content_type
@@ -2330,8 +2346,7 @@ class SQLFORM(FORM):
elif not request.vars.records:
request.vars.records = []
session['_web2py_grid_referrer_' + formname] = \
url2(vars=request.get_vars)
session['_web2py_grid_referrer_' + formname] = url2(vars=request.get_vars)
console = DIV(_class='web2py_console %(header)s %(cornertop)s' % ui)
error = None
if create:
@@ -2357,7 +2372,7 @@ class SQLFORM(FORM):
sfields_id = '%s_query_panel' % prefix
skeywords_id = '%s_keywords' % prefix
search_widget = lambda sfield, url: CAT(FORM(
INPUT(_name='keywords', _value=request.vars.keywords,
INPUT(_name='keywords', _value=keywords,
_id=skeywords_id,_class='form-control',
_onfocus="jQuery('#%s').change();jQuery('#%s').slideDown();" % (spanel_id, sfields_id) if advanced_search else ''
),
@@ -2368,7 +2383,6 @@ class SQLFORM(FORM):
form = search_widget and search_widget(sfields, url()) or ''
console.append(add)
console.append(form)
keywords = request.vars.get('keywords', '')
try:
if callable(searchable):
subquery = searchable(sfields, keywords)
@@ -2428,7 +2442,7 @@ class SQLFORM(FORM):
elif key == ordermatch[1:]:
marker = sorter_icons[1]
header = A(header, marker, _href=url(vars=dict(
keywords=request.vars.keywords or '',
keywords=keywords,
order=key)), cid=request.cid)
headcols.append(TH(header, _class=ui.get('default')))
@@ -2466,17 +2480,22 @@ class SQLFORM(FORM):
if paginate and dbset._db._adapter.dbengine == 'google:datastore':
cursor = request.vars.cursor or True
limitby = (0, paginate)
try: page = int(request.vars.page or 1)-1
except ValueError: page = 0
elif paginate and paginate<nrows:
try: page = int(request.vars.page or 1)-1
except ValueError: page = 0
limitby = (paginate*page, paginate*(page+1))
try:
page = int(request.vars.page or 1) - 1
except ValueError:
page = 0
elif paginate and paginate < nrows:
try:
page = int(request.vars.page or 1) - 1
except ValueError:
page = 0
limitby = (paginate * page, paginate * (page + 1))
else:
limitby = None
try:
table_fields = [field for field in fields
if (field.tablename in tablenames and not(isinstance(field, Field.Virtual)))]
if (field.tablename in tablenames and
not(isinstance(field, Field.Virtual)))]
if dbset._db._adapter.dbengine == 'google:datastore':
rows = dbset.select(left=left, orderby=orderby,
groupby=groupby, limitby=limitby,
@@ -2514,8 +2533,15 @@ class SQLFORM(FORM):
paginator.append(LI('page %s' % (page+1)))
if next_cursor:
d = dict(page=page+2, cursor=next_cursor)
if order: d['order'] = order
if request.vars.keywords: d['keywords'] = request.vars.keywords
if order:
d['order'] = order
# see issue 1980, also at the top of the definition
# if keyworkds is in request.vars, we don't need to
# copy over the keywords parameter in the links for pagination
if 'keywords' in request.vars and not keywords:
d['keywords'] = ''
elif keywords:
d['keywords'] = keywords
paginator.append(LI(
A('next', _href=url(vars=d), cid=request.cid)))
elif paginate and paginate < nrows:
@@ -2531,8 +2557,13 @@ class SQLFORM(FORM):
d = dict(page=p + 1)
if order:
d['order'] = order
if request.vars.keywords:
d['keywords'] = request.vars.keywords
# see issue 1980, also at the top of the definition
# if keyworkds is in request.vars, we don't need to
# copy over the keywords parameter in the links for pagination
if 'keywords' in request.vars and not keywords:
d['keywords'] = ''
elif keywords:
d['keywords'] = keywords
return A(name, _href=url(vars=d), cid=request.cid)
NPAGES = 5 # window is 2*NPAGES
if page > NPAGES + 1:
@@ -2660,7 +2691,8 @@ class SQLFORM(FORM):
_style='width:100%;overflow-x:auto;-ms-overflow-x:scroll')
if selectable:
if not callable(selectable):
#now expect that selectable and related parameters are iterator (list, tuple, etc)
#now expect that selectable and related parameters are
#iterator (list, tuple, etc)
inputs = []
for i, submit_info in enumerate(selectable):
submit_text = submit_info[0]
@@ -2708,7 +2740,7 @@ class SQLFORM(FORM):
link = url2(vars=dict(
order=request.vars.order or '',
_export_type=k,
keywords=request.vars.keywords or ''))
keywords=keywords or ''))
export_links.append(A(T(label), _href=link, _title=title, _class='btn btn-default'))
export_menu = \
DIV(T('Export:'), _class="w2p_export_menu", *export_links)
@@ -2797,7 +2829,7 @@ class SQLFORM(FORM):
elif callable(table._format):
return table._format(row)
else:
return '#'+str(row.id)
return '#' + str(row.id)
try:
nargs = len(args) + 1
previous_tablename, previous_fieldname, previous_id = \
@@ -2876,7 +2908,7 @@ class SQLFORM(FORM):
opts = [OPTION(T('References')+':', _value='')]
linked = []
if linked_tables:
for item in linked_tables:
for item in linked_tables:
tb = None
if isinstance(item, Table) and item._tablename in check:
tablename = item._tablename