merge with upstream
This commit is contained in:
commit
9a957c907a
59 files changed
+4594
-7709
No files matched your search
+55
-51
@@ -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
@@ -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 = []
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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):
|
||||
|
||||
Reference in new issue
Block a user