From 8608f78e6b6e283ac0d866380e269d34b4c5510c Mon Sep 17 00:00:00 2001 From: Hardirc Date: Fri, 6 Mar 2015 20:57:01 -0500 Subject: [PATCH 1/6] Improve PEP8 gluon/fileutils.py --- gluon/fileutils.py | 32 +++++++++++++++++++------------- 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/gluon/fileutils.py b/gluon/fileutils.py index 6c26726a..1eda8553 100644 --- a/gluon/fileutils.py +++ b/gluon/fileutils.py @@ -65,9 +65,10 @@ def parse_semantic(version="Version 1.99.0-rc.1+timestamp.2011.09.19.08.23.26"): pre_release = m.group('pre') or '' build = m.group('build') or '' if build.startswith('timestamp'): - build = datetime.datetime.strptime(build.split('.',1)[1], '%Y.%m.%d.%H.%M.%S') + build = datetime.datetime.strptime(build.split('.', 1)[1], '%Y.%m.%d.%H.%M.%S') return (a, b, c, pre_release, build) + def parse_legacy(version="Version 1.99.0 (2011-09-19 08:23:26)"): """Parses "legacy" version string @@ -85,6 +86,7 @@ def parse_legacy(version="Version 1.99.0 (2011-09-19 08:23:26)"): build = datetime.datetime.strptime(m.group('datetime'), '%Y-%m-%d %H:%M:%S') return (a, b, c, pre_release, build) + def parse_version(version): """Attempts to parse SemVer, fallbacks on legacy """ @@ -93,6 +95,7 @@ def parse_version(version): version_tuple = parse_legacy(version) return version_tuple + def read_file(filename, mode='r'): """Returns content from filename, making sure to close the file explicitly on exit. @@ -130,14 +133,13 @@ def mktree(path): os.mkdir(head) -def listdir( - path, - expression='^.+$', - drop=True, - add_dirs=False, - sort=True, - maxnum = None, -): +def listdir(path, + expression='^.+$', + drop=True, + add_dirs=False, + sort=True, + maxnum=None, + ): """ Like `os.listdir()` but you can specify a regex pattern to filter files. If `add_dirs` is True, the returned items will have the full path. @@ -212,6 +214,7 @@ def tar(file, dir, expression='^.+$', filenames=None): finally: tar.close() + def untar(file, dir): """Untar file into dir """ @@ -242,6 +245,7 @@ def w2p_pack(filename, path, compiled=False, filenames=None): tarfp.close() os.unlink(tarname) + def create_welcome_w2p(): if not os.path.exists('welcome.w2p') or os.path.exists('NEWINSTALL'): try: @@ -254,7 +258,7 @@ def create_welcome_w2p(): def w2p_unpack(filename, path, delete_tar=True): - if filename=='welcome.w2p': + if filename == 'welcome.w2p': create_welcome_w2p() filename = abspath(filename) path = abspath(path) @@ -352,6 +356,7 @@ def get_session(request, other_application='admin'): osession = storage.Storage() return osession + def set_session(request, session, other_application='admin'): """Checks that user is authorized to access other_application""" if request.application == other_application: @@ -359,7 +364,8 @@ def set_session(request, session, other_application='admin'): session_id = request.cookies['session_id_' + other_application].value session_filename = os.path.join( up(request.folder), other_application, 'sessions', session_id) - storage.save_storage(session,session_filename) + storage.save_storage(session, session_filename) + def check_credentials(request, other_application='admin', expiration=60 * 60, gae_login=True): @@ -381,7 +387,7 @@ def check_credentials(request, other_application='admin', r = (s.authorized and s.last_time and s.last_time > dt) if r: s.last_time = t0 - set_session(request,s,other_application) + set_session(request, s, other_application) return r @@ -434,7 +440,7 @@ def make_fake_file_like_object(): from settings import global_settings # we need to import settings here because - # settings imports fileutils too + # settings imports fileutils too def abspath(*relpath, **base): From 362e6dbad27c8ba90fcaef8056f87d1ef276161a Mon Sep 17 00:00:00 2001 From: Hardirc Date: Fri, 6 Mar 2015 22:04:46 -0500 Subject: [PATCH 2/6] Improve PEP8 gluon/html.py --- gluon/html.py | 50 ++++++++++++++++++++++++-------------------------- 1 file changed, 24 insertions(+), 26 deletions(-) diff --git a/gluon/html.py b/gluon/html.py index 5f5f2a4e..7177a743 100644 --- a/gluon/html.py +++ b/gluon/html.py @@ -139,11 +139,11 @@ def xmlescape(data, quote=True): data = cgi.escape(data, quote).replace("'", "'") return data -def call_as_list(f,*a,**b): - if not isinstance(f, (list,tuple)): +def call_as_list(f, *a, **b): + if not isinstance(f, (list, tuple)): f = [f] for item in f: - item(*a,**b) + item(*a, **b) def truncate_string(text, length, dots='...'): text = text.decode('utf-8') @@ -583,7 +583,7 @@ class XML(XmlComponent): 'img/', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'table', 'tr', 'td', 'div', - 'strong','span', + 'strong', 'span', ], allowed_attributes={ 'a': ['href', 'title', 'target'], @@ -937,14 +937,14 @@ class DIV(XmlComponent): elif value is False or value is None: continue attr.append((name, value)) - data = self.attributes.get('data',{}) + data = self.attributes.get('data', {}) for key, value in data.iteritems(): name = 'data-' + key value = data[key] - attr.append((name,value)) + attr.append((name, value)) attr.sort() fa = '' - for name,value in attr: + for name, value in attr: fa += ' %s="%s"' % (name, xmlescape(value, True)) # get the xml for the inner components co = join([xmlescape(component) for component in @@ -1256,8 +1256,8 @@ def TAG_pickler(data): class __tag_div__(DIV): - def __init__(self,name,*a,**b): - DIV.__init__(self,*a,**b) + def __init__(self, name, *a, **b): + DIV.__init__(self, *a, **b) self.tag = name copy_reg.pickle(__tag_div__, TAG_pickler, TAG_unpickler) @@ -1282,7 +1282,7 @@ class __TAG__(XmlComponent): name = name[:-1] + '/' if isinstance(name, unicode): name = name.encode('utf-8') - return lambda *a,**b: __tag_div__(name,*a,**b) + return lambda *a, **b: __tag_div__(name, *a, **b) def __call__(self, html): return web2pyHTMLParser(decoder.decoder(html)).tree @@ -1840,7 +1840,7 @@ class INPUT(DIV): if self['_type'] != 'checkbox': self['old_value'] = self['value'] or self['_value'] or '' value = request_vars_get(name, '') - self['value'] = value if not hasattr(value,'file') else None + self['value'] = value if not hasattr(value, 'file') else None else: self['old_value'] = self['value'] or False value = request_vars_get(name) @@ -1852,7 +1852,7 @@ class INPUT(DIV): if requires: if not isinstance(requires, (list, tuple)): requires = [requires] - for k,validator in enumerate(requires): + for k, validator in enumerate(requires): try: (value, errors) = validator(value) except: @@ -1873,8 +1873,7 @@ class INPUT(DIV): t = self['_type'] = 'text' t = t.lower() value = self['value'] - - if self['_value'] is None or isinstance(self['_value'],cgi.FieldStorage): + if self['_value'] is None or isinstance(self['_value'], cgi.FieldStorage): _value = None else: _value = str(self['_value']) @@ -1903,7 +1902,6 @@ class INPUT(DIV): elif not isinstance(value, list): self['_value'] = value - def xml(self): name = self.attributes.get('_name', None) if name and hasattr(self, 'errors') \ @@ -2126,29 +2124,29 @@ class FORM(DIV): onfailure = onvalidation.get('onfailure', None) onchange = onvalidation.get('onchange', None) if [k for k in onvalidation if not k in ( - 'onsuccess','onfailure','onchange')]: + 'onsuccess', 'onfailure', 'onchange')]: raise RuntimeError('Invalid key in onvalidate dict') if onsuccess and status: - call_as_list(onsuccess,self) + call_as_list(onsuccess, self) if onfailure and request_vars and not status: - call_as_list(onfailure,self) + call_as_list(onfailure, self) status = len(self.errors) == 0 if changed: if onchange and self.record_changed and \ self.detect_record_change: - call_as_list(onchange,self) + call_as_list(onchange, self) elif status: call_as_list(onvalidation, self) if self.errors: status = False if not session is None: if hasattr(self, 'record_hash'): - formkey = self.record_hash+':'+web2py_uuid() + formkey = self.record_hash + ':' + web2py_uuid() else: formkey = web2py_uuid() self.formkey = formkey keyname = '_formkey[%s]' % formname - session[keyname] = list(session.get(keyname,[]))[-9:] + [formkey] + session[keyname] = list(session.get(keyname, []))[-9:] + [formkey] if status and not keepvalues: self._traverse(False, hideerror) self.accepted = status @@ -2523,7 +2521,7 @@ class MENU(DIV): else: ul = UL(_class=self['ul_class']) for item in data: - if isinstance(item,LI): + if isinstance(item, LI): ul.append(item) else: (name, active, link) = item[:3] @@ -2531,7 +2529,7 @@ class MENU(DIV): li = LI(link) elif 'no_link_url' in self.attributes and self['no_link_url'] == link: li = LI(DIV(name)) - elif isinstance(link,dict): + elif isinstance(link, dict): li = LI(A(name, **link)) elif link: li = LI(A(name, _href=link)) @@ -2563,8 +2561,8 @@ class MENU(DIV): for item in data: # Custom item aren't serialized as mobile if len(item) >= 3 and (not item[0]) or (isinstance(item[0], DIV) and not (item[2])): - # ex: ('', False,A('title',_href=URL(...),_title="title")) - # ex: (A('title',_href=URL(...),_title="title"), False, None) + # ex: ('', False, A('title', _href=URL(...), _title="title")) + # ex: (A('title', _href=URL(...), _title="title"), False, None) custom_items.append(item) elif len(item) <= 4 or item[4] == True: select.append(OPTION(CAT(prefix, item[0]), @@ -2574,7 +2572,7 @@ class MENU(DIV): item[3], select, prefix=CAT(prefix, item[0], '/')) select['_onchange'] = 'window.location=this.value' # avoid to wrap the select if no custom items are present - html = DIV(select, self.serialize(custom_items)) if len( custom_items) else select + html = DIV(select, self.serialize(custom_items)) if len(custom_items) else select return html def xml(self): From df6fc812e3cacf4ac65f6e2dd6e90c84979d0ab7 Mon Sep 17 00:00:00 2001 From: Hardirc Date: Fri, 6 Mar 2015 22:06:37 -0500 Subject: [PATCH 3/6] Improve PEP8 http.py --- gluon/http.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/gluon/http.py b/gluon/http.py index ee25c006..53f5bf5d 100644 --- a/gluon/http.py +++ b/gluon/http.py @@ -48,7 +48,7 @@ defined_status = { 417: 'EXPECTATION FAILED', 422: 'UNPROCESSABLE ENTITY', 429: 'TOO MANY REQUESTS', - 451: 'UNAVAILABLE FOR LEGAL REASONS', # http://www.451unavailable.org/ + 451: 'UNAVAILABLE FOR LEGAL REASONS', # http://www.451unavailable.org/ 500: 'INTERNAL SERVER ERROR', 501: 'NOT IMPLEMENTED', 502: 'BAD GATEWAY', @@ -60,6 +60,7 @@ defined_status = { regex_status = re.compile('^\d{3} [0-9A-Z ]+$') + class HTTP(Exception): """Raises an HTTP response From 05daa164ac54bbcad71e09cefa8d508c0b7c8dd4 Mon Sep 17 00:00:00 2001 From: BuhtigithuB Date: Sun, 15 Mar 2015 20:07:24 -0400 Subject: [PATCH 4/6] unittest test compare() --- gluon/tests/test_utils.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/gluon/tests/test_utils.py b/gluon/tests/test_utils.py index cb4e6872..f38fe2e8 100644 --- a/gluon/tests/test_utils.py +++ b/gluon/tests/test_utils.py @@ -19,6 +19,18 @@ class TestUtils(unittest.TestCase): data = md5_hash("web2py rocks") self.assertEqual(data, '79509f3246a2824dee64635303e99204') + + def test_compare(self): + """ Tests the compare funciton """ + + a, b = 'test123', 'test123' + compare_result_true = compare(a, b) + self.assertTrue(compare_result_true) + + a, b = 'test123', 'test456' + compare_result_false = compare(a, b) + self.assertFalse(compare_result_false) + class TestPack(unittest.TestCase): """ Tests the compileapp.py module """ From 901236765fb5cab2c2c8507b8fdf56fb947ac271 Mon Sep 17 00:00:00 2001 From: BuhtigithuB Date: Sun, 15 Mar 2015 20:21:52 -0400 Subject: [PATCH 5/6] forget to importe compare --- gluon/tests/test_utils.py | 1 + 1 file changed, 1 insertion(+) diff --git a/gluon/tests/test_utils.py b/gluon/tests/test_utils.py index f38fe2e8..ff40d28e 100644 --- a/gluon/tests/test_utils.py +++ b/gluon/tests/test_utils.py @@ -9,6 +9,7 @@ from fix_path import fix_sys_path fix_sys_path(__file__) from utils import md5_hash +from utils import compare class TestUtils(unittest.TestCase): From 0094a323d707aa96113f3e6a2198cd4b6360c00e Mon Sep 17 00:00:00 2001 From: BuhtigithuB Date: Sun, 15 Mar 2015 21:07:21 -0400 Subject: [PATCH 6/6] test_simple_hash() --- gluon/tests/test_utils.py | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/gluon/tests/test_utils.py b/gluon/tests/test_utils.py index ff40d28e..bccf6ce8 100644 --- a/gluon/tests/test_utils.py +++ b/gluon/tests/test_utils.py @@ -11,6 +11,10 @@ fix_sys_path(__file__) from utils import md5_hash from utils import compare +import hashlib +from hashlib import md5, sha1, sha224, sha256, sha384, sha512 +from utils import simple_hash, get_digest + class TestUtils(unittest.TestCase): """ Tests the utils.py module """ @@ -31,6 +35,36 @@ class TestUtils(unittest.TestCase): a, b = 'test123', 'test456' compare_result_false = compare(a, b) self.assertFalse(compare_result_false) + + def test_simple_hash(self): + """ Tests the simple_hash function """ + + # no key, no salt, md5 + data_md5 = simple_hash('web2py rocks!', key='', salt='', digest_alg='md5') + self.assertEqual(data_md5, '37d95defba6c8834cb8cae86ee888568') + + # no key, no salt, sha1 + data_sha1 = simple_hash('web2py rocks!', key='', salt='', digest_alg='sha1') + self.assertEqual(data_sha1, '00489a46753d8db260c71542611cdef80652c4b7') + + # no key, no salt, sha224 + data_sha224 = simple_hash('web2py rocks!', key='', salt='', digest_alg='sha224') + self.assertEqual(data_sha224, '84d7054271842c2c17983baa2b1447e0289d101140a8c002d49d60da') + + # no key, no salt, sha256 + data_sha256 = simple_hash('web2py rocks!', key='', salt='', digest_alg='sha256') + self.assertEqual(data_sha256, '0849f224d8deb267e4598702aaec1bd749e6caec90832469891012a4be24af08') + + # no key, no salt, sha384 + data_sha384 = simple_hash('web2py rocks!', key='', salt='', digest_alg='sha384') + self.assertEqual(data_sha384, + '3cffaf39371adbe84eb10f588d2718207d8e965e9172a27a278321b86977351376ae79f92e91d8c58cad86c491282d5f') + + # no key, no salt, sha512 + data_sha512 = simple_hash('web2py rocks!', key='', salt='', digest_alg='sha512') + self.assertEqual(data_sha512, 'fa3237f594743e1d7b6c800bb134b3255cf4a98ab8b01e2ec23256328c9f8059' + '64fdef25a038d6cc3fda1b2fb45d66461eeed5c4669e506ec8bdfee71348db7e') + class TestPack(unittest.TestCase):