diff --git a/VERSION b/VERSION index 776fda80..b370822f 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -Version 2.00.0 (2012-08-16 11:06:01) dev +Version 2.00.0 (2012-08-16 11:56:03) dev diff --git a/__init__.py b/__init__.py index 6fb66a5e..12a6f48e 100644 --- a/__init__.py +++ b/__init__.py @@ -4,3 +4,5 @@ + + diff --git a/anyserver.py b/anyserver.py index ed4a8a94..3d6c929c 100644 --- a/anyserver.py +++ b/anyserver.py @@ -130,12 +130,12 @@ class Servers: 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): @@ -308,3 +308,4 @@ if __name__=='__main__': + diff --git a/appengine_config.py b/appengine_config.py index 323f7a2b..33916e4d 100644 --- a/appengine_config.py +++ b/appengine_config.py @@ -5,3 +5,4 @@ def webapp_add_wsgi_middleware(app): + diff --git a/cgihandler.py b/cgihandler.py index 86d45f12..16620054 100755 --- a/cgihandler.py +++ b/cgihandler.py @@ -64,3 +64,4 @@ wsgiref.handlers.CGIHandler().run(gluon.main.wsgibase) + diff --git a/fcgihandler.py b/fcgihandler.py index a9fed0e6..196e538f 100755 --- a/fcgihandler.py +++ b/fcgihandler.py @@ -54,3 +54,4 @@ fcgi.WSGIServer(application, bindAddress='/tmp/fcgi.sock').run() + diff --git a/gaehandler.py b/gaehandler.py index f02fa1b3..0d09987b 100755 --- a/gaehandler.py +++ b/gaehandler.py @@ -102,3 +102,4 @@ if __name__ == '__main__': + diff --git a/gluon/__init__.py b/gluon/__init__.py index b1dde0cb..2f48d365 100644 --- a/gluon/__init__.py +++ b/gluon/__init__.py @@ -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: + + diff --git a/gluon/admin.py b/gluon/admin.py index e053800c..ce7bdaab 100644 --- a/gluon/admin.py +++ b/gluon/admin.py @@ -464,3 +464,4 @@ def create_missing_app_folders(request): + diff --git a/gluon/cache.py b/gluon/cache.py index 21b85554..cbe2b215 100644 --- a/gluon/cache.py +++ b/gluon/cache.py @@ -398,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) @@ -497,3 +497,4 @@ def lazy_cache(key=None,time_expire=None,cache_model='ram'): return g return decorator + diff --git a/gluon/cfs.py b/gluon/cfs.py index a99f9c06..d643882b 100644 --- a/gluon/cfs.py +++ b/gluon/cfs.py @@ -55,3 +55,4 @@ def getcfs(key, filename, filter=None): + diff --git a/gluon/compileapp.py b/gluon/compileapp.py index 516e92a4..378e8441 100644 --- a/gluon/compileapp.py +++ b/gluon/compileapp.py @@ -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__': + diff --git a/gluon/contenttype.py b/gluon/contenttype.py index 40bbc5b6..6e4c78b6 100644 --- a/gluon/contenttype.py +++ b/gluon/contenttype.py @@ -722,3 +722,4 @@ def contenttype(filename, default='text/plain'): + diff --git a/gluon/contrib/AuthorizeNet.py b/gluon/contrib/AuthorizeNet.py index 0b432304..aa6bf785 100755 --- a/gluon/contrib/AuthorizeNet.py +++ b/gluon/contrib/AuthorizeNet.py @@ -262,3 +262,4 @@ if __name__=='__main__': + diff --git a/gluon/contrib/DowCommerce.py b/gluon/contrib/DowCommerce.py index 4443e075..090fd077 100644 --- a/gluon/contrib/DowCommerce.py +++ b/gluon/contrib/DowCommerce.py @@ -242,3 +242,4 @@ if __name__=='__main__': + diff --git a/gluon/contrib/__init__.py b/gluon/contrib/__init__.py index 6fb66a5e..9e5f5f8a 100644 --- a/gluon/contrib/__init__.py +++ b/gluon/contrib/__init__.py @@ -4,3 +4,4 @@ + diff --git a/gluon/contrib/aes.py b/gluon/contrib/aes.py index 24e40878..bb745310 100644 --- a/gluon/contrib/aes.py +++ b/gluon/contrib/aes.py @@ -500,3 +500,4 @@ aes_Rcon = array('B', 'c697356ad4b37dfaefc5913972e4d3bd' '61c29f254a943366cc831d3a74e8cb'.decode('hex') ) + diff --git a/gluon/contrib/autolinks.py b/gluon/contrib/autolinks.py index 023e4c36..7e81a0f2 100644 --- a/gluon/contrib/autolinks.py +++ b/gluon/contrib/autolinks.py @@ -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) @@ -63,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'), @@ -128,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: @@ -196,3 +196,4 @@ if __name__=="__main__": print expand_html(open(sys.argv[1]).read()) else: print test() + diff --git a/gluon/contrib/comet_messaging.py b/gluon/contrib/comet_messaging.py index 0dcd7962..d41afb51 100644 --- a/gluon/contrib/comet_messaging.py +++ b/gluon/contrib/comet_messaging.py @@ -193,3 +193,4 @@ if __name__ == "__main__": + diff --git a/gluon/contrib/feedparser.py b/gluon/contrib/feedparser.py index a389abb5..371323e9 100755 --- a/gluon/contrib/feedparser.py +++ b/gluon/contrib/feedparser.py @@ -3909,3 +3909,4 @@ def parse(url_file_stream_or_string, etag=None, modified=None, agent=None, refer + diff --git a/gluon/contrib/gae_memcache.py b/gluon/contrib/gae_memcache.py index 22e7ae0d..e03e74fe 100644 --- a/gluon/contrib/gae_memcache.py +++ b/gluon/contrib/gae_memcache.py @@ -54,3 +54,4 @@ class MemcacheClient(Client): + diff --git a/gluon/contrib/gae_retry.py b/gluon/contrib/gae_retry.py index 0218365d..a3f671f2 100644 --- a/gluon/contrib/gae_retry.py +++ b/gluon/contrib/gae_retry.py @@ -89,3 +89,4 @@ def autoretry_datastore_timeouts(attempts=5.0, interval=0.1, exponent=2.0): + diff --git a/gluon/contrib/generics.py b/gluon/contrib/generics.py index 296362f1..a5f89dd7 100644 --- a/gluon/contrib/generics.py +++ b/gluon/contrib/generics.py @@ -66,3 +66,4 @@ def pdf_from_html(html): + diff --git a/gluon/contrib/google_wallet.py b/gluon/contrib/google_wallet.py index 8d13abd8..84d39171 100644 --- a/gluon/contrib/google_wallet.py +++ b/gluon/contrib/google_wallet.py @@ -18,3 +18,4 @@ def button(merchant_id="123456789012345", + diff --git a/gluon/contrib/gql.py b/gluon/contrib/gql.py index 3ae4d6f7..94465a7d 100644 --- a/gluon/contrib/gql.py +++ b/gluon/contrib/gql.py @@ -8,3 +8,4 @@ from gluon.dal import DAL, Field, Table, Query, Set, Expression, Row, Rows, driv + diff --git a/gluon/contrib/imageutils.py b/gluon/contrib/imageutils.py index 96facc08..1c5041ff 100644 --- a/gluon/contrib/imageutils.py +++ b/gluon/contrib/imageutils.py @@ -57,3 +57,4 @@ def THUMB(image, nx=120, ny=120, gae=False, name='thumb'): return thumb else: return image + diff --git a/gluon/contrib/memdb.py b/gluon/contrib/memdb.py index 9570c7d9..ee25566d 100644 --- a/gluon/contrib/memdb.py +++ b/gluon/contrib/memdb.py @@ -910,3 +910,4 @@ if __name__ == '__main__': + diff --git a/gluon/contrib/pam.py b/gluon/contrib/pam.py index 37fb3781..57b9e5be 100644 --- a/gluon/contrib/pam.py +++ b/gluon/contrib/pam.py @@ -126,3 +126,4 @@ if __name__ == "__main__": + diff --git a/gluon/contrib/pbkdf2.py b/gluon/contrib/pbkdf2.py index b7a7dd42..c751b4be 100644 --- a/gluon/contrib/pbkdf2.py +++ b/gluon/contrib/pbkdf2.py @@ -128,3 +128,4 @@ def test(): if __name__ == '__main__': test() + diff --git a/gluon/contrib/populate.py b/gluon/contrib/populate.py index 813753c2..efd90670 100644 --- a/gluon/contrib/populate.py +++ b/gluon/contrib/populate.py @@ -170,3 +170,4 @@ if __name__ == '__main__': + diff --git a/gluon/contrib/qdb.py b/gluon/contrib/qdb.py index c33c1e4f..bb6ecc0e 100644 --- a/gluon/contrib/qdb.py +++ b/gluon/contrib/qdb.py @@ -963,3 +963,4 @@ if __name__ == '__main__': qdb.main(**kwargs) + diff --git a/gluon/contrib/redis_cache.py b/gluon/contrib/redis_cache.py index cb978216..3a1a47fa 100644 --- a/gluon/contrib/redis_cache.py +++ b/gluon/contrib/redis_cache.py @@ -166,3 +166,4 @@ class RedisClient(object): + diff --git a/gluon/contrib/rss2.py b/gluon/contrib/rss2.py index aa220ee6..8f1a601e 100644 --- a/gluon/contrib/rss2.py +++ b/gluon/contrib/rss2.py @@ -591,3 +591,4 @@ if __name__ == '__main__': + diff --git a/gluon/contrib/shell.py b/gluon/contrib/shell.py index 172fcc77..d40400b3 100755 --- a/gluon/contrib/shell.py +++ b/gluon/contrib/shell.py @@ -269,3 +269,4 @@ if __name__=='__main__': + diff --git a/gluon/contrib/simplejsonrpc.py b/gluon/contrib/simplejsonrpc.py index f2f82c4d..865bb1c4 100644 --- a/gluon/contrib/simplejsonrpc.py +++ b/gluon/contrib/simplejsonrpc.py @@ -150,3 +150,4 @@ if __name__ == "__main__": print client.add(1, 2) + diff --git a/gluon/contrib/sms_utils.py b/gluon/contrib/sms_utils.py index c6af3cd6..29a50226 100644 --- a/gluon/contrib/sms_utils.py +++ b/gluon/contrib/sms_utils.py @@ -115,3 +115,4 @@ def sms_email(number,provider): + diff --git a/gluon/contrib/spreadsheet.py b/gluon/contrib/spreadsheet.py index e91dc733..b343eb31 100644 --- a/gluon/contrib/spreadsheet.py +++ b/gluon/contrib/spreadsheet.py @@ -27,7 +27,7 @@ class Node: self.onchange = onchange self.size = 4 self.locked = False - + def xml(self): return """' @@ -315,7 +315,7 @@ class Sheet: changes[tablename][row_id][fieldname] = value return changes - + def process(self, request, db=None, db_callback=None): """ @@ -429,7 +429,7 @@ class Sheet: self.readonly = readonly self.update_button = update_button - + self.client = { "columns": {}, "colnames": {}, @@ -439,14 +439,14 @@ class Sheet: "modified": {}, "headers": headers } - + # if db and query: if self.data is not None: # retrieve row columns length self.rows = len(self.data) # retrieve rows length self.cols = len(self.data.colnames) - + # map row data to rncn values for x, colname in enumerate(self.data.colnames): self.client["columns"][colname] = x @@ -557,7 +557,7 @@ class Sheet: # one column example: # {"0": {"value":1.0, "readonly":False, "active":True, "onchange":None}} # value: common value for all cells - + attributes = self.get_attributes(kwarg) if attributes is not None: self.tr_attributes[str(row)] = attributes @@ -593,10 +593,10 @@ class Sheet: # arg: value pairs # one row example: # {"0": {"value":1.0, "readonly":False, "active":True, "onchange":None}} - # value: common value for all cells + # value: common value for all cells """ attributes = self.get_attributes(kwarg) - + if isinstance(cells, dict): for row, data in cells.iteritems(): key = "r%sc%s" % (row, col) @@ -610,7 +610,7 @@ class Sheet: onchange=onchange, **attributes) else: active, onchange, readonly, all_value = \ - self.get_cell_arguments(kwarg) + self.get_cell_arguments(kwarg) for row, cell_value in enumerate(cells): key = "r%sc%s" % (row, col) if value is None: @@ -626,7 +626,7 @@ class Sheet: Insert a n x n matrix or a set of cells # starts: upper left cell # ends: lower right cell - + # cells: a sequence of value sequences # or a dict with "rncn" keys # Example 1 cells: @@ -637,7 +637,7 @@ class Sheet: # value: common value for all cells """ attributes = self.get_attributes(kwarg) - + starts_r, starts_c = self.position(starts) ends_r, ends_c = None, None if ends is not None: @@ -832,7 +832,7 @@ class Sheet: jQuery(function(){ jQuery(".%(name)s input").change(w2p_spreadsheet_update_cell); }); - + if (w2p_spreadsheet_update_button != ""){ jQuery(function(){ jQuery("#" + w2p_spreadsheet_update_button).click(w2p_spreadsheet_update_db); @@ -855,7 +855,7 @@ class Sheet: sorted_headers = [TH(),] + \ [TH(header[1]) for header in sorted(unsorted_headers)] - table.insert(0, TR(*sorted_headers, + table.insert(0, TR(*sorted_headers, **{_class:"%s_fieldnames" % \ attributes["_class"]})) else: @@ -878,3 +878,4 @@ if __name__ == '__main__': s.cell('c', value="=cos(a)**2+b*b") print s['c'].computed_value + diff --git a/gluon/contrib/stripe.py b/gluon/contrib/stripe.py index 7f99dedb..fc1a12b9 100644 --- a/gluon/contrib/stripe.py +++ b/gluon/contrib/stripe.py @@ -65,3 +65,4 @@ if __name__=='__main__': + diff --git a/gluon/contrib/taskbar_widget.py b/gluon/contrib/taskbar_widget.py index a91c6f5d..8009c93f 100644 --- a/gluon/contrib/taskbar_widget.py +++ b/gluon/contrib/taskbar_widget.py @@ -246,3 +246,4 @@ class TaskBarIcon: + diff --git a/gluon/contrib/timecollect.py b/gluon/contrib/timecollect.py index 37320550..229ac2e5 100644 --- a/gluon/contrib/timecollect.py +++ b/gluon/contrib/timecollect.py @@ -94,3 +94,4 @@ if __name__=='__main__': # You can turn off ordering of results print(t.getReportText(orderByCost=False)) + diff --git a/gluon/contrib/user_agent_parser.py b/gluon/contrib/user_agent_parser.py index ca08a49d..c326e92c 100644 --- a/gluon/contrib/user_agent_parser.py +++ b/gluon/contrib/user_agent_parser.py @@ -519,3 +519,4 @@ class mobilize(object): + diff --git a/gluon/custom_import.py b/gluon/custom_import.py index e37708ef..f31d3630 100644 --- a/gluon/custom_import.py +++ b/gluon/custom_import.py @@ -328,3 +328,4 @@ class _Web2pyDateTrackerImporter(_Web2pyImporter, _DateTrackerImporter): + diff --git a/gluon/dal.py b/gluon/dal.py index 4914d22a..a0bf317c 100644 --- a/gluon/dal.py +++ b/gluon/dal.py @@ -91,7 +91,7 @@ Example of usage: >>> person.drop() Supported field types: -id string text boolean integer double decimal password upload +id string text boolean integer double decimal password upload blob time date datetime Supported DAL URI strings: @@ -507,7 +507,7 @@ class ConnectionPool(object): def pool_connection(self, f, cursor=True): """ - this function defines: self.connection and self.cursor + this function defines: self.connection and self.cursor (iff cursor is True) if self.pool_size>0 it will try pull the connection from the pool if the connection is not active (closed by db server) it will loop @@ -691,7 +691,7 @@ class BaseAdapter(ConnectionPool): # make a guess here for circular references id_fieldname = referenced in table._db \ and table._db[referenced]._id.name or 'id' - ftype = self.types[field.type[:9]] % dict( + ftype = self.types[field.type[:9]] % dict( index_name = field.name+'__idx', field_name = field.name, constraint_name = constraint_name, @@ -749,11 +749,11 @@ class BaseAdapter(ConnectionPool): sql=ftype) if isinstance(field.default,(str,int,float)): - # Caveat: sql_fields and sql_fields_aux + # Caveat: sql_fields and sql_fields_aux # differ for default values. # sql_fields is used to trigger migrations and sql_fields_aux # is used for create tables. - # The reason is that we do not want to trigger + # The reason is that we do not want to trigger # a migration simply because a default value changes. not_null = self.NOT_NULL(field.default, field.type) ftype = ftype.replace('NOT NULL', not_null) @@ -785,7 +785,7 @@ class BaseAdapter(ConnectionPool): if hasattr(table,'_primarykey'): query = "CREATE TABLE %s(\n %s,\n %s) %s" % \ - (tablename, fields, + (tablename, fields, self.PRIMARY_KEY(', '.join(table._primarykey)),other) else: query = "CREATE TABLE %s(\n %s\n)%s" % \ @@ -823,7 +823,7 @@ class BaseAdapter(ConnectionPool): if not fake_migrate: self.create_sequence_and_triggers(query,table) table._db.commit() - # Postgres geom fields are added now, + # Postgres geom fields are added now, # after the table has been created for query in postcreation_fields: self.execute(query) @@ -911,7 +911,7 @@ class BaseAdapter(ConnectionPool): schema = parms.split(',')[0] query = [ "SELECT DropGeometryColumn ('%(schema)s', '%(table)s', '%(field)s');" % dict(schema=schema, table=tablename, field=key,) ] elif not self.dbengine in ('firebird',): - query = ['ALTER TABLE %s DROP COLUMN %s;' + query = ['ALTER TABLE %s DROP COLUMN %s;' % (tablename, key)] else: query = ['ALTER TABLE %s DROP %s;' % (tablename, key)] @@ -1097,11 +1097,11 @@ class BaseAdapter(ConnectionPool): self.expand(second, 'string')) def STARTSWITH(self, first, second): - return '(%s LIKE %s)' % (self.expand(first), + return '(%s LIKE %s)' % (self.expand(first), self.expand(second+'%', 'string')) def ENDSWITH(self, first, second): - return '(%s LIKE %s)' % (self.expand(first), + return '(%s LIKE %s)' % (self.expand(first), self.expand('%'+second, 'string')) def CONTAINS(self, first, second): @@ -1114,13 +1114,13 @@ class BaseAdapter(ConnectionPool): def EQ(self, first, second=None): if second is None: return '(%s IS NULL)' % self.expand(first) - return '(%s = %s)' % (self.expand(first), + return '(%s = %s)' % (self.expand(first), self.expand(second, first.type)) def NE(self, first, second=None): if second is None: return '(%s IS NOT NULL)' % self.expand(first) - return '(%s <> %s)' % (self.expand(first), + return '(%s <> %s)' % (self.expand(first), self.expand(second, first.type)) def LT(self,first,second=None): @@ -1156,7 +1156,7 @@ class BaseAdapter(ConnectionPool): self.expand(second, first.type)) def MUL(self, first, second): - return '(%s * %s)' % (self.expand(first), + return '(%s * %s)' % (self.expand(first), self.expand(second, first.type)) def DIV(self, first, second): @@ -1179,7 +1179,7 @@ class BaseAdapter(ConnectionPool): def COMMA(self, first, second): return '%s, %s' % (self.expand(first), self.expand(second)) - def expand(self, expression, field_type=None): + def expand(self, expression, field_type=None): if isinstance(expression, Field): return '%s.%s' % (expression.tablename, expression.name) elif isinstance(expression, (Expression, Query)): @@ -1375,24 +1375,24 @@ class BaseAdapter(ConnectionPool): icommand = self.JOIN() if not isinstance(inner_join, (tuple, list)): inner_join = [inner_join] - ijoint = [t._tablename for t in inner_join + ijoint = [t._tablename for t in inner_join if not isinstance(t,Expression)] ijoinon = [t for t in inner_join if isinstance(t, Expression)] itables_to_merge={} #issue 490 [itables_to_merge.update( dict.fromkeys(self.tables(t))) for t in ijoinon] ijoinont = [t.first._tablename for t in ijoinon] - [itables_to_merge.pop(t) for t in ijoinont + [itables_to_merge.pop(t) for t in ijoinont if t in itables_to_merge] #issue 490 iimportant_tablenames = ijoint + ijoinont + itables_to_merge.keys() - iexcluded = [t for t in tablenames + iexcluded = [t for t in tablenames if not t in iimportant_tablenames] if left: join = attributes['left'] command = self.LEFT_JOIN() if not isinstance(join, (tuple, list)): join = [join] - joint = [t._tablename for t in join + joint = [t._tablename for t in join if not isinstance(t, Expression)] joinon = [t for t in join if isinstance(t, Expression)] #patch join+left patch (solves problem with ordering in left joins) @@ -1402,7 +1402,7 @@ class BaseAdapter(ConnectionPool): joinont = [t.first._tablename for t in joinon] [tables_to_merge.pop(t) for t in joinont if t in tables_to_merge] important_tablenames = joint + joinont + tables_to_merge.keys() - excluded = [t for t in tablenames + excluded = [t for t in tablenames if not t in important_tablenames ] def alias(t): return str(self.db[t]) @@ -1809,10 +1809,10 @@ class BaseAdapter(ConnectionPool): else: id = value colset.update_record = ( - lambda _ = (colset, table, id), **a: + lambda _ = (colset, table, id), **a: update_record(_, a)) colset.delete_record = ( - lambda t = table, i = id: + lambda t = table, i = id: t._db(t._id==i).delete()) for (referee_table, referee_name) in table._referenced_by: s = db[referee_table][referee_name] @@ -1826,9 +1826,9 @@ class BaseAdapter(ConnectionPool): for tablename in virtualtables: ### new style virtual fields table = db[tablename] - fields_virtual = [(f,v) for (f,v) in table.items() + fields_virtual = [(f,v) for (f,v) in table.items() if isinstance(v,FieldVirtual)] - fields_lazy = [(f,v) for (f,v) in table.items() + fields_lazy = [(f,v) for (f,v) in table.items() if isinstance(v,FieldLazy)] if fields_virtual or fields_lazy: for row in rowsobj.records: @@ -2101,7 +2101,7 @@ class JDBCSQLiteAdapter(SQLiteAdapter): def after_connection(self): # FIXME http://www.zentus.com/sqlitejdbc/custom_functions.html for UDFs - self.connection.create_function('web2py_extract', 2, + self.connection.create_function('web2py_extract', 2, SQLiteAdapter.web2py_extract) def execute(self, a): @@ -2257,7 +2257,7 @@ class PostgreSQLAdapter(BaseAdapter): def adapt(self,obj): #if self.driver == self.drivers.get('pg8000'): - # obj = str(obj).replace('%','%%') + # obj = str(obj).replace('%','%%') return psycopg2_adapt(obj).getquoted() def sequence_name(self,table): @@ -2519,7 +2519,7 @@ class NewPostgreSQLAdapter(PostgreSQLAdapter): if fieldtype.startswith('list:string'): obj = [str(item) for item in obj] else: - obj = [int(item) for item in obj] + obj = [int(item) for item in obj] return 'ARRAY[%s]' % ','.join(repr(item) for item in obj) return BaseAdapter.represent(self, obj, fieldtype) @@ -4100,7 +4100,7 @@ class GoogleDatastoreAdapter(NoSQLAdapter): def parse_id(self, value, field_type): return value - + def create_table(self,table,migrate=True,fake_migrate=False, polymodel=None): myfields = {} for k in table.fields: @@ -4300,7 +4300,7 @@ class GoogleDatastoreAdapter(NoSQLAdapter): if isinstance(attributes.get('reusecursor'), str): cursor = attributes.get('reusecursor') items = gae.Query(tableobj, projection=query_projection, cursor=cursor) - + for filter in filters: if attributes.get('projection') == True and \ filter.name in query_projection and \ @@ -4375,7 +4375,7 @@ class GoogleDatastoreAdapter(NoSQLAdapter): requests, and the filters must be identical. It is up to the user to follow google's limitations: https://developers.google.com/appengine/docs/python/datastore/queries#Query_Cursors """ - + (items, tablename, fields) = self.select_raw(query,fields,attributes) # self.db['_lastsql'] = self._select(query,fields,attributes) rows = [[(t==self.db[tablename]._id.name and item) or \ @@ -5266,7 +5266,7 @@ class IMAPAdapter(NoSQLAdapter): .define_tables() returns a dictionary mapping dal tablenames to the server mailbox names with the following structure: - + {: str } Here is a list of supported fields: @@ -5434,7 +5434,7 @@ class IMAPAdapter(NoSQLAdapter): self.imap4 = self.driver.IMAP4 connection = self.imap4(driver_args["host"], driver_args["port"]) data = connection.login(driver_args["user"], driver_args["password"]) - + # static mailbox list connection.mailbox_names = None @@ -5649,7 +5649,7 @@ class IMAPAdapter(NoSQLAdapter): Field("email", "string", writable=False, readable=False), Field("attachments", "list:string", writable=False, readable=False), ) - + return self.connection.mailbox_names def create_table(self, *args, **kwargs): @@ -5893,7 +5893,7 @@ class IMAPAdapter(NoSQLAdapter): self.connection.mailbox_names[tablename]) string_query = "(%s)" % query result, data = self.connection.search(None, string_query) - store_list = [item.strip() for item in data[0].split() + store_list = [item.strip() for item in data[0].split() if item.strip().isdigit()] # change marked flags for number in store_list: @@ -6346,7 +6346,7 @@ copy_reg.pickle(Row, Row_pickler, Row_unpickler) ################################################################################ -# Everything below should be independent of the specifics of the database +# Everything below should be independent of the specifics of the database # and should work for RDBMs and some NoSQL databases ################################################################################ @@ -6440,7 +6440,7 @@ def smart_query(fields,text): value = constants[item[1:]] else: value = item - if field.type in ('text','string'): + if field.type in ('text','string'): if op == '=': op = 'like' if op == '=': new_query = field==value elif op == '<': new_query = fieldcsv_id: @@ -8442,7 +8442,7 @@ class Set(object): def count(self,distinct=None): return self.db._adapter.count(self.query,distinct) - def select(self, *fields, **attributes): + def select(self, *fields, **attributes): if self.query is None:# and fields[0]._table._common_filter != None: return self(fields[0]._table).select(*fields,**attributes) adapter = self.db._adapter @@ -9120,3 +9120,4 @@ if __name__ == '__main__': + diff --git a/gluon/debug.py b/gluon/debug.py index 77a063dd..6cb29b7f 100644 --- a/gluon/debug.py +++ b/gluon/debug.py @@ -191,3 +191,4 @@ import gluon.main gluon.main.global_settings.debugging = True + diff --git a/gluon/decoder.py b/gluon/decoder.py index 3e0d85d6..713a2c75 100644 --- a/gluon/decoder.py +++ b/gluon/decoder.py @@ -77,3 +77,4 @@ def decoder(buffer): + diff --git a/gluon/fileutils.py b/gluon/fileutils.py index ba7fd932..b8878019 100644 --- a/gluon/fileutils.py +++ b/gluon/fileutils.py @@ -397,3 +397,4 @@ def abspath(*relpath, **base): return os.path.join(global_settings.gluon_parent, path) return os.path.join(global_settings.applications_parent, path) + diff --git a/gluon/globals.py b/gluon/globals.py index d7d68feb..ce729b0a 100644 --- a/gluon/globals.py +++ b/gluon/globals.py @@ -428,9 +428,9 @@ class Session(Storage): if not masterapp: masterapp = request.application response.session_id_name = 'session_id_%s' % masterapp.lower() - + # Load session data from cookie - + if cookie_key: response.session_cookie_key = cookie_key response.session_cookie_key2 = hashlib.md5(cookie_key).digest() @@ -523,25 +523,25 @@ class Session(Storage): migrate=table_migrate, ) try: - - # Get session data out of the database - - # Key comes from the cookie + + # Get session data out of the database + + # Key comes from the cookie key = request.cookies[response.session_id_name].value (record_id, unique_key) = key.split(':') if record_id == '0': raise Exception, 'record_id == 0' - # Select from database. + # Select from database. rows = db(table.id == record_id).select() - # Make sure the session data exists in the database + # Make sure the session data exists in the database if len(rows) == 0 or rows[0].unique_key != unique_key: raise Exception, 'No record' # rows[0].update_record(locked=True) - # Unpickle the data + # Unpickle the data session_data = cPickle.loads(rows[0].session_data) self.update(session_data) except Exception: @@ -668,3 +668,4 @@ class Session(Storage): + diff --git a/gluon/highlight.py b/gluon/highlight.py index 620db98a..93c810c4 100644 --- a/gluon/highlight.py +++ b/gluon/highlight.py @@ -347,3 +347,4 @@ if __name__ == '__main__': + diff --git a/gluon/html.py b/gluon/html.py index f935e0dd..c20bb5ee 100644 --- a/gluon/html.py +++ b/gluon/html.py @@ -2034,11 +2034,11 @@ class FORM(DIV): return self REDIRECT_JS = "window.location='%s';return false" - + def add_button(self,value,url,_class=None): self[0][-1][1].append(INPUT(_type="button",_value=value,_class=_class, _onclick=self.REDIRECT_JS % url)) - + @staticmethod @@ -2052,7 +2052,7 @@ class FORM(DIV): inputs += [INPUT(_type='hidden', _name=name, _value=value) - for name,value in hidden.items()] + for name,value in hidden.items()] form = FORM(INPUT(_type='submit',_value=text),*inputs) form.process() return form @@ -2385,7 +2385,7 @@ class MARKMIN(XmlComponent): autolinks='default', protolinks='default', class_prefix='', - id_prefix='markmin_'): + id_prefix='markmin_'): self.text = text self.extra = extra or {} self.allowed = allowed or {} @@ -2434,3 +2434,4 @@ if __name__ == '__main__': + diff --git a/gluon/http.py b/gluon/http.py index 0e366745..bf8f55ef 100644 --- a/gluon/http.py +++ b/gluon/http.py @@ -128,7 +128,7 @@ class HTTP(BaseException): def redirect(location, how=303, client_side=False): if location: - from gluon import current + from gluon import current loc = location.replace('\r', '%0D').replace('\n', '%0A') if client_side and current.request.ajax: raise HTTP(200, **{'web2py-redirect-location': loc}) @@ -141,3 +141,4 @@ def redirect(location, how=303, client_side=False): + diff --git a/gluon/import_all.py b/gluon/import_all.py index ecc5786b..01c4e8c6 100644 --- a/gluon/import_all.py +++ b/gluon/import_all.py @@ -112,3 +112,4 @@ for module in base_modules + contributed_modules: + diff --git a/gluon/languages.py b/gluon/languages.py index 542a22ec..24f41a49 100644 --- a/gluon/languages.py +++ b/gluon/languages.py @@ -938,3 +938,4 @@ if __name__ == '__main__': import doctest doctest.testmod() + diff --git a/gluon/main.py b/gluon/main.py index 0d697f26..f163e50f 100644 --- a/gluon/main.py +++ b/gluon/main.py @@ -562,7 +562,7 @@ def wsgibase(environ, responder): del response.cookies[response.session_id_name] elif session._secure: response.cookies[response.session_id_name]['secure'] = True - + http_response.cookies2headers(response.cookies) ticket=None @@ -851,3 +851,4 @@ class HttpServer(object): + diff --git a/gluon/messageboxhandler.py b/gluon/messageboxhandler.py index 33cd59b4..17184a57 100644 --- a/gluon/messageboxhandler.py +++ b/gluon/messageboxhandler.py @@ -13,3 +13,4 @@ class MessageBoxHandler(logging.Handler): if tkMessageBox: msg = self.format(record) tkMessageBox.showinfo('info1', msg) + diff --git a/gluon/myregex.py b/gluon/myregex.py index 32bd1d58..04b48b73 100644 --- a/gluon/myregex.py +++ b/gluon/myregex.py @@ -31,3 +31,4 @@ regex_extend = re.compile(\ + diff --git a/gluon/newcron.py b/gluon/newcron.py index 1b6fb689..ff917551 100644 --- a/gluon/newcron.py +++ b/gluon/newcron.py @@ -342,3 +342,4 @@ def crondance(applications_parent, ctype='soft', startup=False, apps=None): + diff --git a/gluon/portalocker.py b/gluon/portalocker.py index 1093a352..36c94547 100644 --- a/gluon/portalocker.py +++ b/gluon/portalocker.py @@ -150,3 +150,4 @@ if __name__=='__main__': f.close() + diff --git a/gluon/reserved_sql_keywords.py b/gluon/reserved_sql_keywords.py index 37715741..713ac48d 100644 --- a/gluon/reserved_sql_keywords.py +++ b/gluon/reserved_sql_keywords.py @@ -1716,3 +1716,4 @@ ADAPTERS['all'] = reduce(lambda a,b:a.union(b),(x for x in ADAPTERS.values())) + diff --git a/gluon/restricted.py b/gluon/restricted.py index aa36e33a..fee54841 100644 --- a/gluon/restricted.py +++ b/gluon/restricted.py @@ -306,3 +306,4 @@ def snapshot(info=None, context=5, code=None, environment=None): + diff --git a/gluon/rewrite.py b/gluon/rewrite.py index da5f92a3..835fd287 100644 --- a/gluon/rewrite.py +++ b/gluon/rewrite.py @@ -1316,3 +1316,4 @@ def get_effective_router(appname): + diff --git a/gluon/rocket.py b/gluon/rocket.py index 5747f357..a091d8d2 100644 --- a/gluon/rocket.py +++ b/gluon/rocket.py @@ -2084,3 +2084,4 @@ if __name__=='__main__': + diff --git a/gluon/sanitizer.py b/gluon/sanitizer.py index 31f3e6e3..5e88f6e4 100644 --- a/gluon/sanitizer.py +++ b/gluon/sanitizer.py @@ -227,3 +227,4 @@ def sanitize(text, permitted_tags=[ + diff --git a/gluon/scheduler.py b/gluon/scheduler.py index 29ff3948..8d986f8c 100644 --- a/gluon/scheduler.py +++ b/gluon/scheduler.py @@ -108,7 +108,7 @@ SECONDS = 1 HEARTBEAT = 3*SECONDS MAXHIBERNATION = 10 -CALLABLETYPES = (types.LambdaType, types.FunctionType, +CALLABLETYPES = (types.LambdaType, types.FunctionType, types.BuiltinFunctionType, types.MethodType, types.BuiltinMethodType) @@ -801,3 +801,4 @@ def main(): if __name__=='__main__': main() + diff --git a/gluon/serializers.py b/gluon/serializers.py index a725c032..8af80157 100644 --- a/gluon/serializers.py +++ b/gluon/serializers.py @@ -116,3 +116,4 @@ def rss(feed): + diff --git a/gluon/settings.py b/gluon/settings.py index e926fbe9..19617882 100644 --- a/gluon/settings.py +++ b/gluon/settings.py @@ -33,3 +33,4 @@ global_settings.is_jython = 'java' in sys.platform.lower() or \ hasattr(sys, 'JYTHON_JAR') or \ str(sys.copyright).find('Jython') > 0 + diff --git a/gluon/shell.py b/gluon/shell.py index c0899b97..50f6d9f3 100644 --- a/gluon/shell.py +++ b/gluon/shell.py @@ -61,7 +61,7 @@ def exec_environment( appname = mo.group('appname') request.folder = os.path.join('applications', appname) else: - request.folder = '' + request.folder = '' env = build_environment(request, response, session, store_current=False) if pyfile: pycfile = pyfile + 'c' @@ -123,7 +123,7 @@ def env( return True fileutils.check_credentials = check_credentials - + environment = build_environment(request, response, session) if import_models: @@ -178,7 +178,7 @@ def run( logging.warn('application does not exist and will not be created') return if c.lower() in ['y', 'yes']: - + os.mkdir(adir) w2p_unpack('welcome.w2p', adir) for subfolder in ['models','views','controllers', 'databases', @@ -430,3 +430,4 @@ if __name__ == '__main__': + diff --git a/gluon/sql.py b/gluon/sql.py index 42d9bc7c..c9304adb 100644 --- a/gluon/sql.py +++ b/gluon/sql.py @@ -8,3 +8,4 @@ from dal import DAL, Field, Table, Query, Set, Expression, Row, Rows, drivers, B + diff --git a/gluon/sqlhtml.py b/gluon/sqlhtml.py index b957b81a..e8014640 100644 --- a/gluon/sqlhtml.py +++ b/gluon/sqlhtml.py @@ -414,9 +414,9 @@ class CheckboxesWidget(OptionsWidget): if opts: - opts.append(INPUT(_class="hidden", requires=attr.get('requires', None), + opts.append(INPUT(_class="hidden", requires=attr.get('requires', None), _disabled="disabled", _name=field.name, - hideerror=False)) + hideerror=False)) return parent(*opts, **attr) @@ -1298,14 +1298,14 @@ class SQLFORM(FORM): f = os.path.join(current.request.folder, os.path.normpath(f)) source_file = open(f, 'rb') - original_filename = os.path.split(f)[1] + original_filename = os.path.split(f)[1] elif hasattr(f, 'file'): (source_file, original_filename) = (f.file, f.filename) elif isinstance(f, (str, unicode)): ### do not know why this happens, it should not - (source_file, original_filename) = \ - (cStringIO.StringIO(f), 'file.txt') - newfilename = field.store(source_file, original_filename, + (source_file, original_filename) = \ + (cStringIO.StringIO(f), 'file.txt') + newfilename = field.store(source_file, original_filename, field.uploadfolder) # this line was for backward compatibility but problematic # self.vars['%s_newfilename' % fieldname] = newfilename @@ -1890,7 +1890,7 @@ class SQLFORM(FORM): label = k options.append(OPTION(T(label),_value=k)) items = url2().split('?', 1) - myurl = items[0] + myurl = items[0] if len(items)>1: mysignature = psq(items[1]).get('_signature', [None])[-1] else: @@ -2637,3 +2637,4 @@ class ExporterHtml(ExportClass): + diff --git a/gluon/storage.py b/gluon/storage.py index b4b73c56..71d82863 100644 --- a/gluon/storage.py +++ b/gluon/storage.py @@ -25,7 +25,7 @@ class List(list): instead of IndexOutOfBounds """ - def __call__(self, i, default=None, cast=None, url_onerror=None): + def __call__(self, i, default=None, cast=None, url_onerror=None): n = len(self) if 0<=i>> is_valid_ip_address('2001:660::1') True - """ + """ # deal with special cases if address.lower() in ('127.0.0.1','localhost','::1','::ffff:127.0.0.1'): return True @@ -166,7 +166,7 @@ def is_valid_ip_address(address): addr = socket.inet_aton(address) return True except socket.error: # invalid address - return False + return False else: # try validate using Regex match = REGEX_IPv4.match(address) if match and all(0<=int(math.group(i))<256 for i in (1,2,3,4)): @@ -177,7 +177,7 @@ def is_valid_ip_address(address): addr = socket.inet_pton(socket.AF_INET6, address) return True except socket.error: # invalid address - return False + return False else: # do not know what to do? assume it is a valid address return True @@ -185,3 +185,4 @@ def is_valid_ip_address(address): + diff --git a/gluon/validators.py b/gluon/validators.py index f4ebfc0e..4d04f421 100644 --- a/gluon/validators.py +++ b/gluon/validators.py @@ -266,7 +266,7 @@ class IS_LENGTH(Validator): if value is None: length = 0 if self.minsize <= length <= self.maxsize: - return (value, None) + return (value, None) elif isinstance(value, cgi.FieldStorage): if value.file: value.file.seek(0, os.SEEK_END) @@ -460,7 +460,7 @@ class IS_IN_DB(Validator): orderby = self.orderby or reduce(lambda a,b:a|b,fields) groupby = self.groupby distinct = self.distinct - dd = dict(orderby=orderby, groupby=groupby, + dd = dict(orderby=orderby, groupby=groupby, distinct=distinct, cache=self.cache) records = self.dbset(table).select(*fields, **dd) else: @@ -2560,7 +2560,7 @@ class LazyCrypt(object): key = 'pbkdf2(1000,64,sha512):uuid' 1000 iterations and 64 chars length """ if self.crypted: - return self.crypted + return self.crypted if self.crypt.key: if ':' in self.crypt.key: digest_alg, key = self.crypt.key.split(':',1) @@ -2569,7 +2569,7 @@ class LazyCrypt(object): else: digest_alg, key = self.crypt.digest_alg, '' if self.crypt.salt: - if self.crypt.salt == True: + if self.crypt.salt == True: salt = str(web2py_uuid()).replace('-','')[-16:] else: salt = self.crypt.salt @@ -2579,13 +2579,13 @@ class LazyCrypt(object): self.crypted = '%s$%s$%s' % (digest_alg, salt, hashed) return self.crypted - def __eq__(self, stored_password): + def __eq__(self, stored_password): """ compares the current lazy crypted password with a stored password """ if self.crypt.key: if ':' in self.crypt.key: - key = self.crypt.key.split(':')[1] + key = self.crypt.key.split(':')[1] else: key = self.crypt.key else: @@ -2593,16 +2593,16 @@ class LazyCrypt(object): if stored_password.count('$')==2: (digest_alg, salt, hash) = stored_password.split('$') h = simple_hash(self.password, key, salt, digest_alg) - temp_pass = '%s$%s$%s' % (digest_alg, salt, h) + temp_pass = '%s$%s$%s' % (digest_alg, salt, h) else: # no salting # guess digest_alg digest_alg = DIGEST_ALG_BY_SIZE.get(len(stored_password),None) - if not digest_alg: + if not digest_alg: return False else: temp_pass = simple_hash(self.password, key, '', digest_alg) return temp_pass == stored_password - + class CRYPT(object): """ @@ -2624,23 +2624,23 @@ class CRYPT(object): Notice that an empty password is accepted but invalid. It will not allow login back. Stores junk as hashed password. - Specify an algorithm or by default we will use sha512. + Specify an algorithm or by default we will use sha512. - Typical available algorithms: - md5, sha1, sha224, sha256, sha384, sha512 + Typical available algorithms: + md5, sha1, sha224, sha256, sha384, sha512 If salt, it hashes a password with a salt. - If salt is True, this method will automatically generate one. + If salt is True, this method will automatically generate one. Either case it returns an encrypted password string in the following format: - $$ + $$ Important: hashed password is returned as a LazyCrypt object and computed only if needed. The LasyCrypt object also knows how to compare itself with an existing salted password Supports standard algorithms - >>> for alg in ('md5','sha1','sha256','sha384','sha512'): + >>> for alg in ('md5','sha1','sha256','sha384','sha512'): ... print str(CRYPT(digest_alg=alg,salt=True)('test')[0]) md5$...$... sha1$...$... @@ -2682,17 +2682,17 @@ class CRYPT(object): True """ - def __init__(self, - key=None, + def __init__(self, + key=None, digest_alg='pbkdf2(1000,20,sha512)', - min_length=0, + min_length=0, error_message='too short', salt=True): """ important, digest_alg='md5' is not the default hashing algorithm for web2py. This is only an example of usage of this function. The actual hash algorithm is determined from the key which is - generated by web2py in tools.py. This defaults to hmac+sha512. + generated by web2py in tools.py. This defaults to hmac+sha512. """ self.key = key self.digest_alg = digest_alg @@ -3151,3 +3151,4 @@ if __name__ == '__main__': + diff --git a/gluon/widget.py b/gluon/widget.py index fa0c22d9..a0bb9dfd 100644 --- a/gluon/widget.py +++ b/gluon/widget.py @@ -1183,3 +1183,4 @@ end tell + diff --git a/gluon/winservice.py b/gluon/winservice.py index 78c28d1a..aa762a15 100644 --- a/gluon/winservice.py +++ b/gluon/winservice.py @@ -90,7 +90,7 @@ class Web2pyService(Service): cls = _winreg.QueryValue(h, 'PythonClass') finally: _winreg.CloseKey(h) - dir = os.path.dirname(cls) + dir = os.path.dirname(cls) os.chdir(dir) from gluon.settings import global_settings global_settings.gluon_parent = dir @@ -171,3 +171,4 @@ if __name__ == '__main__': + diff --git a/gluon/xmlrpc.py b/gluon/xmlrpc.py index 72a85038..24fd8f9c 100644 --- a/gluon/xmlrpc.py +++ b/gluon/xmlrpc.py @@ -24,3 +24,4 @@ def handler(request, response, methods): + diff --git a/isapiwsgihandler.py b/isapiwsgihandler.py index 5c967282..9a5c891a 100644 --- a/isapiwsgihandler.py +++ b/isapiwsgihandler.py @@ -36,3 +36,4 @@ if __name__=='__main__': + diff --git a/modpythonhandler.py b/modpythonhandler.py index 4b397c9e..add46cd3 100755 --- a/modpythonhandler.py +++ b/modpythonhandler.py @@ -225,3 +225,4 @@ def handler(req): + diff --git a/options_std.py b/options_std.py index a7ba2536..7cac9fc2 100644 --- a/options_std.py +++ b/options_std.py @@ -34,3 +34,4 @@ nocron = None + diff --git a/router.example.py b/router.example.py index 067b0e3e..a98b5436 100644 --- a/router.example.py +++ b/router.example.py @@ -212,3 +212,4 @@ if __name__ == '__main__': + diff --git a/routes.example.py b/routes.example.py index 4a706255..c48bd282 100644 --- a/routes.example.py +++ b/routes.example.py @@ -173,3 +173,4 @@ if __name__ == '__main__': + diff --git a/scgihandler.py b/scgihandler.py index 93679ee6..dbadb1d4 100755 --- a/scgihandler.py +++ b/scgihandler.py @@ -74,3 +74,4 @@ if SOFTCRON: SCGIServer(application, port=4000).enable_sighandler().run() + diff --git a/setup.py b/setup.py index 05bd940b..25c4f173 100644 --- a/setup.py +++ b/setup.py @@ -80,3 +80,4 @@ if __name__ == '__main__': + diff --git a/setup_app.py b/setup_app.py index 36e525af..67e0da5b 100755 --- a/setup_app.py +++ b/setup_app.py @@ -55,3 +55,4 @@ setup(app=['web2py.py'], + diff --git a/setup_exe.py b/setup_exe.py index 965efe03..dda70ca0 100755 --- a/setup_exe.py +++ b/setup_exe.py @@ -185,3 +185,4 @@ print "Enjoy web2py " +web2py_version_line + diff --git a/setup_exe_2.6.py b/setup_exe_2.6.py index 87d8f7e9..fcb49525 100644 --- a/setup_exe_2.6.py +++ b/setup_exe_2.6.py @@ -167,3 +167,4 @@ print "Enjoy web2py " +web2py_version_line + diff --git a/web2py.py b/web2py.py index d6d41ec2..0dfe3f54 100755 --- a/web2py.py +++ b/web2py.py @@ -26,3 +26,4 @@ if __name__ == '__main__': + diff --git a/wsgihandler.py b/wsgihandler.py index cf27b211..590f2b46 100644 --- a/wsgihandler.py +++ b/wsgihandler.py @@ -45,3 +45,4 @@ if SOFTCRON: +