removed unwanted whitespaces

This commit is contained in:
mdipierro
2012-08-16 11:56:07 -05:00
parent f78f27982b
commit a608df5a29
90 changed files with 253 additions and 162 deletions
+1 -1
View File
@@ -1 +1 @@
Version 2.00.0 (2012-08-16 11:06:01) dev
Version 2.00.0 (2012-08-16 11:56:03) dev
+2
View File
@@ -4,3 +4,5 @@
+3 -2
View File
@@ -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__':
+1
View File
@@ -5,3 +5,4 @@ def webapp_add_wsgi_middleware(app):
+1
View File
@@ -64,3 +64,4 @@ wsgiref.handlers.CGIHandler().run(gluon.main.wsgibase)
+1
View File
@@ -54,3 +54,4 @@ fcgi.WSGIServer(application, bindAddress='/tmp/fcgi.sock').run()
+1
View File
@@ -102,3 +102,4 @@ if __name__ == '__main__':
+4 -2
View File
@@ -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:
+1
View File
@@ -464,3 +464,4 @@ def create_missing_app_folders(request):
+3 -2
View File
@@ -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
+1
View File
@@ -55,3 +55,4 @@ def getcfs(key, filename, filter=None):
+2 -1
View File
@@ -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__':
+1
View File
@@ -722,3 +722,4 @@ def contenttype(filename, default='text/plain'):
+1
View File
@@ -262,3 +262,4 @@ if __name__=='__main__':
+1
View File
@@ -242,3 +242,4 @@ if __name__=='__main__':
+1
View File
@@ -4,3 +4,4 @@
+1
View File
@@ -500,3 +500,4 @@ aes_Rcon = array('B',
'c697356ad4b37dfaefc5913972e4d3bd'
'61c29f254a943366cc831d3a74e8cb'.decode('hex')
)
+5 -4
View File
@@ -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()
+1
View File
@@ -193,3 +193,4 @@ if __name__ == "__main__":
+1
View File
@@ -3909,3 +3909,4 @@ def parse(url_file_stream_or_string, etag=None, modified=None, agent=None, refer
+1
View File
@@ -54,3 +54,4 @@ class MemcacheClient(Client):
+1
View File
@@ -89,3 +89,4 @@ def autoretry_datastore_timeouts(attempts=5.0, interval=0.1, exponent=2.0):
+1
View File
@@ -66,3 +66,4 @@ def pdf_from_html(html):
+1
View File
@@ -18,3 +18,4 @@ def button(merchant_id="123456789012345",
+1
View File
@@ -8,3 +8,4 @@ from gluon.dal import DAL, Field, Table, Query, Set, Expression, Row, Rows, driv
+1
View File
@@ -57,3 +57,4 @@ def THUMB(image, nx=120, ny=120, gae=False, name='thumb'):
return thumb
else:
return image
+1
View File
@@ -910,3 +910,4 @@ if __name__ == '__main__':
+1
View File
@@ -126,3 +126,4 @@ if __name__ == "__main__":
+1
View File
@@ -128,3 +128,4 @@ def test():
if __name__ == '__main__':
test()
+1
View File
@@ -170,3 +170,4 @@ if __name__ == '__main__':
+1
View File
@@ -963,3 +963,4 @@ if __name__ == '__main__':
qdb.main(**kwargs)
+1
View File
@@ -166,3 +166,4 @@ class RedisClient(object):
+1
View File
@@ -591,3 +591,4 @@ if __name__ == '__main__':
+1
View File
@@ -269,3 +269,4 @@ if __name__=='__main__':
+1
View File
@@ -150,3 +150,4 @@ if __name__ == "__main__":
print client.add(1, 2)
+1
View File
@@ -115,3 +115,4 @@ def sms_email(number,provider):
+25 -24
View File
@@ -27,7 +27,7 @@ class Node:
self.onchange = onchange
self.size = 4
self.locked = False
def xml(self):
return """<input name="%s" id="%s" value="%s" size="%s"
onkeyup="ajax('%s/keyup',['%s'], ':eval');"
@@ -44,7 +44,7 @@ class Node:
class Sheet:
"""
Basic class for creating web spreadsheets
New features:
-dal spreadsheets:
@@ -105,32 +105,32 @@ class Sheet:
more details)
client JavaScript objects:
-var w2p_spreadsheet_data
Stores cell updates by key and
Used for updated cells control
-var w2p_spreadsheet_update_button
Stores the id of the update command
Used for event binding (update click)
var w2p_spreadsheet_update_result
object attributes:
modified - n updated records
errors - n errors
message - a message for feedback and errors
Stores the ajax db update call returned stats
and the db_callback string js
Used after calling w2p_spreadsheet_update_db()
-function w2p_spreadsheet_update_cell(a)
Used for responding to normal cell events
(encapsulates old behavior)
-function w2p_spreadsheet_update_db_callback(result)
Called after a background db update
-function w2p_spreadsheet_update_db()
Called for updating the database with
client data
@@ -182,7 +182,7 @@ class Sheet:
Second method: Sending data updates with .ajax()
-spreadsheet page's view:
{{
=INPUT(_type="button", _value="update data",
_id="w2p_spreadsheet_update_data")
@@ -223,9 +223,9 @@ class Sheet:
# -Delete checkbox columns for each table and default
# -Deletable=True option for showing/hiding delete checkboxes
# -process() method support for db I/O
"""
regex = re.compile('(?<!\w)[a-zA-Z_]\w*')
pregex = re.compile('\d+')
re_strings = re.compile(r'(?P<name>'
@@ -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
+1
View File
@@ -65,3 +65,4 @@ if __name__=='__main__':
+1
View File
@@ -246,3 +246,4 @@ class TaskBarIcon:
+1
View File
@@ -94,3 +94,4 @@ if __name__=='__main__':
# You can turn off ordering of results
print(t.getReportText(orderByCost=False))
+1
View File
@@ -519,3 +519,4 @@ class mobilize(object):
+1
View File
@@ -328,3 +328,4 @@ class _Web2pyDateTrackerImporter(_Web2pyImporter, _DateTrackerImporter):
+44 -43
View File
@@ -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:
{<tablename>: str <server mailbox name>}
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 = field<value
@@ -7324,7 +7324,7 @@ class Table(dict):
archive_name = archive_name % dict(tablename=self._tablename)
if archive_name in archive_db.tables():
return # do not try define the archive if already exists
fieldnames = self.fields()
fieldnames = self.fields()
field_type = self if archive_db is self._db else 'bigint'
archive_table = archive_db.define_table(
archive_name,
@@ -7607,18 +7607,18 @@ class Table(dict):
*args, **kwargs
):
"""
Import records from csv file.
Column headers must have same names as table fields.
Import records from csv file.
Column headers must have same names as table fields.
Field 'id' is ignored.
If column names read 'table.file' the 'table.' prefix is ignored.
'unique' argument is a field which must be unique
'unique' argument is a field which must be unique
(typically a uuid field)
'restore' argument is default False;
if set True will remove old values in table first.
'id_map' ff set to None will not map ids.
The import will keep the id numbers in the restored table.
The import will keep the id numbers in the restored table.
This assumes that there is an field of type id that
is integer and in incrementing order.
is integer and in incrementing order.
Will keep the id numbers in restored table.
"""
@@ -7703,7 +7703,7 @@ class Table(dict):
curr_id = self.insert(**dict(items))
if first:
first = False
# First curr_id is bigger than csv_id,
# First curr_id is bigger than csv_id,
# then we are not restoring but
# extending db table with csv db table
if curr_id>csv_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__':
+1
View File
@@ -191,3 +191,4 @@ import gluon.main
gluon.main.global_settings.debugging = True
+1
View File
@@ -77,3 +77,4 @@ def decoder(buffer):
+1
View File
@@ -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)
+10 -9
View File
@@ -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):
+1
View File
@@ -347,3 +347,4 @@ if __name__ == '__main__':
+5 -4
View File
@@ -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__':
+2 -1
View File
@@ -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):
+1
View File
@@ -112,3 +112,4 @@ for module in base_modules + contributed_modules:
+1
View File
@@ -938,3 +938,4 @@ if __name__ == '__main__':
import doctest
doctest.testmod()
+2 -1
View File
@@ -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):
+1
View File
@@ -13,3 +13,4 @@ class MessageBoxHandler(logging.Handler):
if tkMessageBox:
msg = self.format(record)
tkMessageBox.showinfo('info1', msg)
+1
View File
@@ -31,3 +31,4 @@ regex_extend = re.compile(\
+1
View File
@@ -342,3 +342,4 @@ def crondance(applications_parent, ctype='soft', startup=False, apps=None):
+1
View File
@@ -150,3 +150,4 @@ if __name__=='__main__':
f.close()
+1
View File
@@ -1716,3 +1716,4 @@ ADAPTERS['all'] = reduce(lambda a,b:a.union(b),(x for x in ADAPTERS.values()))
+1
View File
@@ -306,3 +306,4 @@ def snapshot(info=None, context=5, code=None, environment=None):
+1
View File
@@ -1316,3 +1316,4 @@ def get_effective_router(appname):
+1
View File
@@ -2084,3 +2084,4 @@ if __name__=='__main__':
+1
View File
@@ -227,3 +227,4 @@ def sanitize(text, permitted_tags=[
+2 -1
View File
@@ -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()
+1
View File
@@ -116,3 +116,4 @@ def rss(feed):
+1
View File
@@ -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
+4 -3
View File
@@ -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__':
+1
View File
@@ -8,3 +8,4 @@ from dal import DAL, Field, Table, Query, Set, Expression, Row, Rows, drivers, B
+8 -7
View File
@@ -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):
+2 -1
View File
@@ -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<n or -n<=i<0:
value = self[i]
@@ -244,3 +244,4 @@ if __name__ == '__main__':
+1
View File
@@ -111,3 +111,4 @@ def stream_file_or_304_or_206(
+1
View File
@@ -947,3 +947,4 @@ if __name__ == '__main__':
+33 -32
View File
@@ -676,8 +676,8 @@ class Recaptcha(DIV):
Usage:
form = FORM(Recaptcha(public_key='...',private_key='...'))
or
or
form = SQLFORM(...)
form.append(Recaptcha(public_key='...',private_key='...'))
@@ -1152,7 +1152,7 @@ class Auth(object):
# for "remember me" option
response = current.response
if auth and auth.remember:
if auth and auth.remember:
# when user wants to be logged in for longer
response.cookies[response.session_id_name]["expires"] = \
auth.expiration
@@ -1223,12 +1223,12 @@ class Auth(object):
if URL() == action:
next = ''
else:
next = '?_next=' + urllib.quote(URL(args=request.args,
next = '?_next=' + urllib.quote(URL(args=request.args,
vars=request.get_vars))
href = lambda function: '%s/%s%s' % (action, function,
next if referrer_actions is DEFAULT or function in referrer_actions else '')
if self.user_id:
if user_identifier is DEFAULT:
user_identifier = '%(first_name)s'
@@ -1279,7 +1279,7 @@ class Auth(object):
else:
return True
def enable_record_versioning(self,
def enable_record_versioning(self,
tables,
archive_db = None,
archive_names='%(tablename)s_archive',
@@ -1295,13 +1295,13 @@ class Auth(object):
tables can be the db (all table) or a list of tables.
only tables with modified_by and modified_on fiels (as created
by auth.signature) will have versioning. Old record versions will be
by auth.signature) will have versioning. Old record versions will be
in table 'mything_archive' automatically defined.
when you enable enable_record_versioning, records are never
deleted but marked with is_active=False.
enable_record_versioning enables a common_filter for
enable_record_versioning enables a common_filter for
every table that filters out records with is_active = False
Important: If you use auth.enable_record_versioning,
@@ -1311,7 +1311,7 @@ class Auth(object):
"""
tables = [table for table in tables]
for table in tables:
for table in tables:
if 'modified_on' in table.fields():
table._enable_record_versioning(
archive_db = archive_db,
@@ -1355,7 +1355,7 @@ class Auth(object):
label=T('Modified By')))
def define_tables(self, username=False, signature=None,
def define_tables(self, username=False, signature=None,
migrate=True, fake_migrate=False):
"""
to be called unless tables are defined manually
@@ -2021,7 +2021,7 @@ class Auth(object):
cas_user = cas.get_user()
if cas_user:
next = cas.logout_url(next)
current.session.auth = None
current.session.flash = self.messages.logged_out
redirect(next)
@@ -2061,7 +2061,7 @@ class Auth(object):
username = 'username'
else:
username = 'email'
# Ensure the username field is unique.
unique_validator = IS_NOT_IN_DB(self.db, table_user[username])
if not table_user[username].requires:
@@ -2076,7 +2076,7 @@ class Auth(object):
elif not isinstance(table_user[username].requires, IS_NOT_IN_DB):
table_user[username].requires = [table_user[username].requires,
unique_validator]
passfield = self.settings.password_field
formstyle = self.settings.formstyle
form = SQLFORM(table_user,
@@ -2639,7 +2639,7 @@ class Auth(object):
redirect(next)
return form
def is_impersonating(self):
def is_impersonating(self):
return current.session.auth and \
'impersonator' in current.session.auth
@@ -2851,8 +2851,8 @@ class Auth(object):
else:
user = self.user
return self.settings.create_user_groups % user
def has_membership(self, group_id=None, user_id=None, role=None):
"""
checks if user is member of group_id or role
@@ -2935,7 +2935,7 @@ class Auth(object):
self.has_permission(
name,table_name,record_id,user_id=None,
group_id=self.settings.everybody_group_id): return True
if not user_id and not group_id and self.user:
user_id = self.user.id
if user_id:
@@ -4453,7 +4453,7 @@ class Wiki(object):
everybody = 'everybody'
rows_page = 25
regex_redirect = re.compile('redirect\s+(\w+\://\S+)\s*')
def markmin_render(self,page):
def markmin_render(self,page):
return MARKMIN(page.body,url=True,environment=self.env,
autolinks=lambda link: expand_one(link,{})).xml()
def __init__(self,auth,env=None,automenu=True,render='markmin',
@@ -4501,7 +4501,7 @@ class Wiki(object):
if tag: db.wiki_tag.insert(name=tag,wiki_page=id)
def update_tags_update(dbset,page,db=db):
page = dbset.select().first()
db(db.wiki_tag.wiki_page==page.id).delete()
db(db.wiki_tag.wiki_page==page.id).delete()
for tag in page.tags or []:
tag = tag.strip().lower()
if tag: db.wiki_tag.insert(name=tag,wiki_page=page.id)
@@ -4515,7 +4515,7 @@ class Wiki(object):
return True
elif self.auth.user:
groups = self.auth.user_groups.values()
if ('wiki_editor' in groups or
if ('wiki_editor' in groups or
set(groups).intersection(set(page.can_read+page.can_edit)) or
page.created_by==self.auth.user.id): return True
return False
@@ -4525,7 +4525,7 @@ class Wiki(object):
return ('wiki_editor' in groups or
(page is None and 'wiki_author' in groups) or
not page is None and (
set(groups).intersection(set(page.can_edit)) or
set(groups).intersection(set(page.can_edit)) or
page.created_by==self.auth.user.id))
def can_manage(self):
if not self.auth.user: redirect(self.auth.settings.login_url)
@@ -4564,7 +4564,7 @@ class Wiki(object):
)
elif zero=='_cloud':
return self.cloud()
def first_paragraph(self,page):
if not self.can_read(page):
@@ -4582,13 +4582,13 @@ class Wiki(object):
redirect(URL(args=('_create',slug)))
if not self.can_read(page): return self.not_authorized(page)
if current.request.extension == 'html':
if not page:
if not page:
url = URL(args=('_edit',slug))
return dict(content=A('Create page "%s"' % slug,_href=url,_class="btn"))
else:
match = self.regex_redirect.match(page.body)
if match: redirect(match.group(1))
return dict(content=XML(page.html))
return dict(content=XML(page.html))
elif current.request.extension == 'load':
return page.html if page else ''
else:
@@ -4607,7 +4607,7 @@ class Wiki(object):
redirect(self.auth.settings.login_url)
elif not self.auth.has_membership(role):
if not act: return False
raise HTTP(401, "Not Authorized")
raise HTTP(401, "Not Authorized")
return True
def edit(self,slug):
auth = self.auth
@@ -4729,7 +4729,7 @@ class Wiki(object):
if mode in (1,2):
submenu.append((current.T('Edit Page Media'),None,
URL(controller,function,args=('_editmedia',slug))))
submenu.append((current.T('Create New Page'),None,
URL(controller,function,args=('_create'))))
# if self.can_manage():
@@ -4740,7 +4740,7 @@ class Wiki(object):
URL(controller,function,args=('_search'))))
return menu
def search(self,tags=None,query=None,cloud=True,preview=True,
limitby=(0,100),orderby=None):
limitby=(0,100),orderby=None):
if not self.can_search(): return self.not_authorized()
request = current.request
content = CAT()
@@ -4766,7 +4766,7 @@ class Wiki(object):
pages = db(query).select(
*fields,**dict(orderby=orderby or ~count,
groupby=db.wiki_page.id,
limitby=limitby))
limitby=limitby))
if request.extension in ('html','load'):
if not pages:
content.append(DIV(T("No results",_class='w2p_wiki_form')))
@@ -4784,7 +4784,7 @@ class Wiki(object):
cloud=False
content = [p.as_dict() for p in pages]
elif cloud:
content.append(self.cloud()['content'])
content.append(self.cloud()['content'])
if request.extension=='load':
return content
return dict(content=content)
@@ -4806,10 +4806,11 @@ class Wiki(object):
vars=dict(tags=item.wiki_tag.name)))
for item in ids]
return dict(content=DIV(_class='w2p_cloud',*items))
if __name__ == '__main__':
import doctest
doctest.testmod()
+1
View File
@@ -653,3 +653,4 @@ if __name__ == '__main__':
doctests()
+5 -4
View File
@@ -47,7 +47,7 @@ def simple_hash(text, key='', salt = '', digest_alg = 'md5'):
elif digest_alg.startswith('pbkdf2'): # latest and coolest!
iterations, keylen, alg = digest_alg[7:-1].split(',')
return pbkdf2_hex(text, salt, int(iterations),
int(keylen),get_digest(alg))
int(keylen),get_digest(alg))
elif key: # use hmac
digest_alg = get_digest(digest_alg)
h = hmac.new(key+salt,text,digest_alg)
@@ -154,7 +154,7 @@ def is_valid_ip_address(address):
True
>>> 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):
+20 -19
View File
@@ -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:
<algorithm>$<salt>$<hash>
<algorithm>$<salt>$<hash>
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__':
+1
View File
@@ -1183,3 +1183,4 @@ end tell
+2 -1
View File
@@ -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__':
+1
View File
@@ -24,3 +24,4 @@ def handler(request, response, methods):
+1
View File
@@ -36,3 +36,4 @@ if __name__=='__main__':
+1
View File
@@ -225,3 +225,4 @@ def handler(req):
+1
View File
@@ -34,3 +34,4 @@ nocron = None
+1
View File
@@ -212,3 +212,4 @@ if __name__ == '__main__':
+1
View File
@@ -173,3 +173,4 @@ if __name__ == '__main__':
+1
View File
@@ -74,3 +74,4 @@ if SOFTCRON:
SCGIServer(application, port=4000).enable_sighandler().run()
+1
View File
@@ -80,3 +80,4 @@ if __name__ == '__main__':
+1
View File
@@ -55,3 +55,4 @@ setup(app=['web2py.py'],
+1
View File
@@ -185,3 +185,4 @@ print "Enjoy web2py " +web2py_version_line
+1
View File
@@ -167,3 +167,4 @@ print "Enjoy web2py " +web2py_version_line
+1
View File
@@ -26,3 +26,4 @@ if __name__ == '__main__':
+1
View File
@@ -45,3 +45,4 @@ if SOFTCRON: