merge with upstream

This commit is contained in:
Michele Comitini committed 2013-01-24 02:10:16 +01:00
commit 9a957c907a
59 files changed
+4594 -7709

No files matched your search

+55 -51
View File
@@ -224,6 +224,13 @@ try:
have_serializers = True
except ImportError:
have_serializers = False
try:
import json as simplejson
except ImportError:
try:
import gluon.contrib.simplejson as simplejson
except ImportError:
simplejson = None
try:
import validators
@@ -605,6 +612,7 @@ class ConnectionPool(object):
###################################################################################
class BaseAdapter(ConnectionPool):
native_json = False
driver = None
driver_name = None
drivers = () # list of drivers from which to pick
@@ -1444,7 +1452,7 @@ class BaseAdapter(ConnectionPool):
tablename,fieldname = item.split('.')
append(db[tablename][fieldname])
else:
append(Expression(db,lambda:item))
append(Expression(db,lambda item=item:item))
else:
append(item)
# ## if no fields specified take them all from the requested tables
@@ -1782,16 +1790,14 @@ class BaseAdapter(ConnectionPool):
obj = obj.isoformat()[:10]
else:
obj = str(obj)
elif (fieldtype == 'json'):
if not isinstance(obj, basestring):
elif fieldtype == 'json':
if not self.native_json:
if have_serializers:
obj = serializers.json(obj)
else:
try:
import json as simplejson
except ImportError:
import gluon.contrib.simplejson as simplejson
elif simplejson:
obj = simplejson.dumps(items)
else:
raise RuntimeError("missing simplejson")
if not isinstance(obj,bytes):
obj = bytes(obj)
try:
@@ -1924,17 +1930,17 @@ class BaseAdapter(ConnectionPool):
return float(value)
def parse_json(self, value, field_type):
if isinstance(value, basestring):
if not self.native_json:
if not isinstance(value, basestring):
raise RuntimeError('json data not a string')
if isinstance(value, unicode):
value = value.encode('utf-8')
if have_serializers:
value = serializers.loads_json(value)
else:
try:
import json as simplejson
except ImportError:
import gluon.contrib.simplejson as simplejson
elif simplejson:
value = simplejson.loads(value)
else:
raise RuntimeError("missing simplejson")
return value
def build_parsemap(self):
@@ -4250,16 +4256,13 @@ class NoSQLAdapter(BaseAdapter):
elif fieldtype == 'blob':
pass
elif fieldtype == 'json':
if isinstance(obj, basestring):
obj = self.to_unicode(obj)
if have_serializers:
obj = serializers.loads_json(obj)
else:
try:
import json as simplejson
except ImportError:
import gluon.contrib.simplejson as simplejson
obj = simplejson.loads(obj)
obj = self.to_unicode(obj)
if have_serializers:
obj = serializers.loads_json(obj)
elif simplejson:
obj = simplejson.loads(obj)
else:
raise RuntimeError("missing simplejson")
elif is_string and field_is_type('list:string'):
return map(self.to_unicode,obj)
elif is_list:
@@ -4959,6 +4962,7 @@ def cleanup(text):
return text
class MongoDBAdapter(NoSQLAdapter):
native_json = True
drivers = ('pymongo',)
uploads_in_blob = True
@@ -6792,12 +6796,10 @@ class Row(object):
return serializers.json(item,
default=default or
serializers.custom_json)
else:
try:
import json as simplejson
except ImportError:
import gluon.contrib.simplejson as simplejson
elif simplejson:
return simplejson.dumps(item)
else:
raise RuntimeError("missing simplejson")
else:
return item
@@ -7209,24 +7211,26 @@ class DAL(object):
EXAMPLE:
db.define_table('person',Field('name'),Field('info'))
db.define_table('pet',Field('owner',db.person),Field('name'),Field('info'))
db.define_table('pet',Field('ownedby',db.person),Field('name'),Field('info'))
@request.restful()
def index():
def GET(*args,**vars):
patterns = [
"/friends[person]",
"/{friend.name.startswith}",
"/{friend.name}/:field",
"/{friend.name}/pets[pet.owner]",
"/{friend.name}/pet[pet.owner]/{pet.name}",
"/{friend.name}/pet[pet.owner]/{pet.name}/:field"
"/{person.name}/:field",
"/{person.name}/pets[pet.ownedby]",
"/{person.name}/pets[pet.ownedby]/{pet.name}",
"/{person.name}/pets[pet.ownedby]/{pet.name}/:field",
("/dogs[pet]", db.pet.info=='dog'),
("/dogs[pet]/{pet.name.startswith}", db.pet.info=='dog'),
]
parser = db.parse_as_rest(patterns,args,vars)
if parser.status == 200:
return dict(content=parser.response)
else:
raise HTTP(parser.status,parser.error)
def POST(table_name,**vars):
if table_name == 'person':
return db.person.validate_and_insert(**vars)
@@ -7403,7 +7407,7 @@ def index():
dbset = db(queries[table])
dbset=dbset(db[table])
elif tag==':field' and table:
# # print 're3:'+tag
# print 're3:'+tag
field = args[i]
if not field in db[table]: break
# hand-built patterns should respect .readable=False as well
@@ -7411,16 +7415,18 @@ def index():
return Row({'status':418,'pattern':pattern,
'error':'I\'m a teapot','response':None})
try:
item = dbset.select(db[table][field],limitby=(0,1)).first()
distinct = vars.get('distinct', False) == 'True'
offset = int(vars.get('offset',None) or 0)
limits = (offset,int(vars.get('limit',None) or 1000)+offset)
except ValueError:
return Row({'status':400,'pattern':pattern,
'error':'invalid path','response':None})
if not item:
return Row({'status':404,'pattern':pattern,
'error':'record not found','response':None})
else:
return Row({'status':200,'response':item[field],
return Row({'status':400,'error':'invalid limits','response':None})
items = dbset.select(db[table][field], distinct=distinct, limitby=limits)
if items:
return Row({'status':200,'response':items,
'pattern':pattern})
else:
return Row({'status':404,'pattern':pattern,
'error':'no record found','response':None})
elif tag != args[i]:
break
otable = table
@@ -7437,9 +7443,9 @@ def index():
offset = int(vars.get('offset',None) or 0)
limits = (offset,int(vars.get('limit',None) or 1000)+offset)
except ValueError:
Row({'status':400,'error':'invalid limits','response':None})
return Row({'status':400,'error':'invalid limits','response':None})
if count > limits[1]-limits[0]:
Row({'status':400,'error':'too many records','response':None})
return Row({'status':400,'error':'too many records','response':None})
try:
response = dbset.select(limitby=limits,orderby=orderby,*fields)
except ValueError:
@@ -9729,12 +9735,10 @@ class Rows(object):
return serializers.json(items,
default=default or
serializers.custom_json)
else:
try:
import json as simplejson
except ImportError:
import gluon.contrib.simplejson as simplejson
elif simplejson:
return simplejson.dumps(items)
else:
raise RuntimeError("missing simplejson")
# for consistent naming yet backwards compatible
as_csv = __str__
+1 -1
View File
@@ -2245,7 +2245,7 @@ class BEAUTIFY(DIV):
if c.value:
components.append(c.value)
if hasattr(c, 'xml') and callable(c.xml):
c = str(c)
components.append(c)
continue
elif hasattr(c, 'keys') and callable(c.keys):
rows = []
+23 -4
View File
@@ -1,9 +1,10 @@
import logging
import os
try:
import tkMessageBox
import Tkinter
except:
tkMessageBox = None
Tkinter = None
class MessageBoxHandler(logging.Handler):
@@ -11,6 +12,24 @@ class MessageBoxHandler(logging.Handler):
logging.Handler.__init__(self)
def emit(self, record):
if tkMessageBox:
if Tkinter:
msg = self.format(record)
tkMessageBox.showinfo('info1', msg)
root = Tkinter.Tk()
root.wm_title("web2py logger message")
text = Tkinter.Text()
text["height"] = 12
text.insert(0.1, msg)
text.pack()
button = Tkinter.Button(root, text="OK", command=root.destroy)
button.pack()
root.mainloop()
class NotifySendHandler(logging.Handler):
def __init__(self):
logging.Handler.__init__(self)
def emit(self, record):
if Tkinter:
msg = self.format(record)
os.system("notify-send '%s'" % msg)
+1 -1
View File
@@ -864,7 +864,7 @@ class MapUrlIn(object):
if not self.host:
(self.host, self.port) = ('localhost', '80')
if ':' in self.host:
(self.host, self.port) = self.host.split(':')
(self.host, self.port) = self.host.rsplit(':',1) # for ipv6 support
if not self.port:
self.port = '443' if self.scheme == 'https' else '80'
+6 -1
View File
@@ -2017,7 +2017,12 @@ class SQLFORM(FORM):
expcolumns = columns
if export_type.endswith('with_hidden_cols'):
expcolumns = [f for f in fields if f._tablename in tablenames]
expcolumns = []
for table in tables:
for field in table:
if field.readable and field._tablename in tablenames:
expcolumns.append(field)
if export_type in exportManager and exportManager[export_type]:
if request.vars.keywords:
try:
+2 -1
View File
@@ -5235,7 +5235,8 @@ class Wiki(object):
if self.templates:
fields.append(
Field("from_template", "reference wiki_page",
requires=IS_EMPTY_OR(IS_IN_DB(db(self.templates),
requires=IS_EMPTY_OR(IS_IN_DB(db(self.templates),
db.wiki_page._id,
'%(slug)s')),
comment=current.T(
"Choose Template or empty for new Page")))
+9 -4
View File
@@ -328,12 +328,17 @@ class IS_JSON(Validator):
self.error_message = error_message
def __call__(self, value):
if value is None:
return None
try:
simplejson.loads(value)
return (value, None)
return (simplejson.loads(value), None)
except JSONErrors:
pass
return (value, translate(self.error_message))
return (value, translate(self.error_message))
def formatter(self,value):
if value is None:
return None
return simplejson.dumps(value)
class IS_IN_SET(Validator):