From dd582c61e9eeae4fc5abaf24e863fa17de65f894 Mon Sep 17 00:00:00 2001 From: niphlod Date: Mon, 12 Aug 2013 23:59:03 +0200 Subject: [PATCH 1/4] added enhancement 1626, marker shown in grid also for default orderby --- gluon/sqlhtml.py | 29 +++++++++++++++++++---------- 1 file changed, 19 insertions(+), 10 deletions(-) diff --git a/gluon/sqlhtml.py b/gluon/sqlhtml.py index 7c9d0afa..faccbabb 100644 --- a/gluon/sqlhtml.py +++ b/gluon/sqlhtml.py @@ -13,12 +13,7 @@ Holds: - form_factory: provides a SQLFORM for an non-db backed table """ -try: - from urlparse import parse_qs as psq -except ImportError: - from cgi import parse_qs as psq import os -import copy from http import HTTP from html import XmlComponent from html import XML, SPAN, TAG, A, DIV, CAT, UL, LI, TEXTAREA, BR, IMG, SCRIPT @@ -2193,18 +2188,32 @@ class SQLFORM(FORM): headcols = [] if selectable: headcols.append(TH(_class=ui.get('default'))) + + ordermatch, marker = orderby, '' + if orderby: + #if orderby is a single column, remember to put the marker + if isinstance(orderby, Expression): + if orderby.first and not orderby.second: + ordermatch, marker = orderby.first, '~' + ordermatch = marker + str(ordermatch) for field in columns: if not field.readable: continue key = str(field) header = headers.get(str(field), field.label or key) if sortable and not isinstance(field, Field.Virtual): - if key == order: - key, marker = '~' + order, sorter_icons[0] - elif key == order[1:]: - marker = sorter_icons[1] + marker = '' + if order: + if key == order: + key, marker = '~' + order, sorter_icons[0] + elif key == order[1:]: + marker = sorter_icons[1] else: - marker = '' + print 'a', key, ordermatch + if key == ordermatch: + key, marker = '~' + order, sorter_icons[0] + elif key == ordermatch[1:]: + marker = sorter_icons[1] header = A(header, marker, _href=url(vars=dict( keywords=request.vars.keywords or '', order=key)), _class=trap_class()) From e132ccbd51b0045fe303d382bd2a6446c5ce741a Mon Sep 17 00:00:00 2001 From: Michele Comitini Date: Mon, 12 Aug 2013 12:44:11 +0200 Subject: [PATCH 2/4] removed wrong exception that masked other errors --- gluon/tools.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/gluon/tools.py b/gluon/tools.py index 22338607..cdbf6686 100644 --- a/gluon/tools.py +++ b/gluon/tools.py @@ -4584,8 +4584,6 @@ class Service(object): data = json_parser.loads(request.body.read()) except ValueError: # decoding error in json lib return return_error(None, -32700) - except json_parser.JSONDecodeError: # decoding error in simplejson lib - return return_error(None, -32700) # Batch handling if isinstance(data, list) and not batch_element: From f8bd8c274c850f8730405118dfe7c7a7fb78e656 Mon Sep 17 00:00:00 2001 From: Michele Comitini Date: Tue, 13 Aug 2013 09:16:46 +0200 Subject: [PATCH 3/4] first() backed by limitby to avoid memory and cpu cycles wasting --- gluon/tools.py | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/gluon/tools.py b/gluon/tools.py index 22338607..dc81cd2c 100644 --- a/gluon/tools.py +++ b/gluon/tools.py @@ -1899,8 +1899,8 @@ class Auth(object): logins user as specified by username (or email) and password """ settings = self._get_login_settings() - user = self.db(settings.table_user[settings.userfield] == \ - username).select().first() + user = settings.table_user(**{settings.userfield: \ + username}) if user and user.get(settings.passfield, False): password = settings.table_user[ settings.passfield].validate(password)[0] @@ -2168,8 +2168,7 @@ class Auth(object): accepted_form = True # check for username in db - user = self.db(table_user[username] - == form.vars[username]).select().first() + user = table_user(**{username: form.vars[username]}) if user: # user in db, check if registration pending or disabled temp_user = user @@ -2440,9 +2439,7 @@ class Auth(object): if not self.settings.registration_requires_verification: table_user[form.vars.id] = dict(registration_key='') session.flash = self.messages.registration_successful - user = self.db( - table_user[username] == form.vars[username] - ).select().first() + user = table_user(**{username: form.vars[username]}) self.login_user(user) session.flash = self.messages.logged_in self.log_event(log, form.vars) @@ -2882,7 +2879,7 @@ class Auth(object): onvalidation=onvalidation, hideerror=self.settings.hideerror): - if not form.vars['old_password'] == s.select().first()[passfield]: + if not form.vars['old_password'] == s.select(limitby=(0,1), orderby_on_limitby=False).first()[passfield]: form.errors['old_password'] = self.messages.invalid_password else: d = {passfield: str(form.vars.new_password)} @@ -3320,7 +3317,7 @@ class Auth(object): if group_id == 0: group_id = self.user_group() record = self.db(permission.group_id == group_id)(permission.name == name)(permission.table_name == str(table_name))( - permission.record_id == long(record_id)).select().first() + permission.record_id == long(record_id)).select(limitby=(0,1), orderby_on_limitby=False).first() if record: id = record.id else: @@ -5206,7 +5203,7 @@ class Wiki(object): db.wiki_tag.insert(name=tag, wiki_page=id) def update_tags_update(dbset, page, db=db): - page = dbset.select().first() + page = dbset.select(limitby=(0,1)).first() db(db.wiki_tag.wiki_page == page.id).delete() for tag in page.tags or []: tag = tag.strip().lower() From 17dcd836ddfb9dc2ba9e38737d8f7c263d6e0ff5 Mon Sep 17 00:00:00 2001 From: niphlod Date: Tue, 13 Aug 2013 23:44:59 +0200 Subject: [PATCH 4/4] fixed issue with request.body. Needs refactoring --- gluon/globals.py | 29 +++++++++++++++++------------ 1 file changed, 17 insertions(+), 12 deletions(-) diff --git a/gluon/globals.py b/gluon/globals.py index 9f214837..9798cb1a 100644 --- a/gluon/globals.py +++ b/gluon/globals.py @@ -83,21 +83,21 @@ def copystream_progress(request, chunk_size=10 ** 5): X-Progress-ID:length and X-Progress-ID:uploaded """ env = request.env - if not env.content_length: + if not env.get('CONTENT_LENGTH', None): return cStringIO.StringIO() - source = env.wsgi_input + source = env['wsgi.input'] try: - size = int(env.content_length) + size = int(env['CONTENT_LENGTH']) except ValueError: raise HTTP(400, "Invalid Content-Length header") try: # Android requires this dest = tempfile.NamedTemporaryFile() except NotImplementedError: # and GAE this dest = tempfile.TemporaryFile() - if not 'X-Progress-ID' in request.vars: + if not 'X-Progress-ID' in request.get_vars: copystream(source, dest, size, chunk_size) return dest - cache_key = 'X-Progress-ID:' + request.vars['X-Progress-ID'] + cache_key = 'X-Progress-ID:' + request.get_vars['X-Progress-ID'] cache_ram = CacheInRam(request) # same as cache.ram because meta_storage cache_ram(cache_key + ':length', lambda: size, 0) cache_ram(cache_key + ':uploaded', lambda: 0, 0) @@ -150,6 +150,7 @@ class Request(Storage): self._get_vars = None self._post_vars = None self._vars = None + self._body = None self.folder = None self.application = None self.function = None @@ -162,6 +163,7 @@ class Request(Storage): self.is_local = False self.global_settings = settings.global_settings + def parse_get_vars(self): query_string = self.env.get('QUERY_STRING','') dget = cgi.parse_qs(query_string, keep_blank_values=1) @@ -173,11 +175,7 @@ class Request(Storage): def parse_post_vars(self): env = self.env post_vars = self._post_vars = Storage() - try: - self.body = body = copystream_progress(self) - except IOError: - raise HTTP(400, "Bad Request - HTTP body is incomplete") - + body = self.body #if content-type is application/json, we must read the body is_json = env.get('content_type', '')[:16] == 'application/json' @@ -230,6 +228,15 @@ class Request(Storage): if len(pvalue): post_vars[key] = (len(pvalue) > 1 and pvalue) or pvalue[0] + @property + def body(self): + if self._body is None: + try: + self._body = copystream_progress(self) + except IOError: + raise HTTP(400, "Bad Request - HTTP body is incomplete") + return self._body + def parse_all_vars(self): self._vars = copy.copy(self.get_vars) for key,value in self.post_vars.iteritems(): @@ -297,8 +304,6 @@ class Request(Storage): current.session.forget() redirect(URL(scheme='https', args=self.args, vars=self.vars)) - - def restful(self): def wrapper(action, self=self): def f(_action=action, _self=self, *a, **b):