Merge github.com:web2py/web2py
This commit is contained in:
+11
-9
@@ -6281,9 +6281,11 @@ class Row(dict):
|
||||
this is only used to store a Row
|
||||
"""
|
||||
|
||||
def __init__(self,*args,**kwargs):
|
||||
dict.__init__(self,*args,**kwargs)
|
||||
self.__dict__ = self
|
||||
def __getattr__(self, key):
|
||||
return self[key]
|
||||
|
||||
def __setattr__(self, key, value):
|
||||
self[key] = value
|
||||
|
||||
def __getitem__(self, key):
|
||||
key=str(key)
|
||||
@@ -6572,7 +6574,6 @@ class DAL(dict):
|
||||
:fake_migrate_all (defaults to False). If sets to True fake migrates ALL tables
|
||||
:attempts (defaults to 5). Number of times to attempt connecting
|
||||
"""
|
||||
self.__dict__ = self
|
||||
if not decode_credentials:
|
||||
credential_decoder = lambda cred: cred
|
||||
else:
|
||||
@@ -6983,8 +6984,7 @@ def index():
|
||||
yield self[tablename]
|
||||
|
||||
def __getitem__(self, key):
|
||||
key = str(key)
|
||||
return dict.__getitem__(self,key)
|
||||
return self.__getattr__(str(key))
|
||||
|
||||
def __getattr__(self, key):
|
||||
if not key is '_LAZY_TABLES' and key in self._LAZY_TABLES:
|
||||
@@ -6999,7 +6999,7 @@ def index():
|
||||
if key[:1]!='_' and key in self:
|
||||
raise SyntaxError, \
|
||||
'Object %s exists and cannot be redefined' % key
|
||||
dict.__setattr__(self,key,value)
|
||||
dict.__setitem__(self,key,value)
|
||||
|
||||
def __repr__(self):
|
||||
return '<DAL ' + dict.__repr__(self) + '>'
|
||||
@@ -7201,7 +7201,6 @@ class Table(dict):
|
||||
|
||||
:raises SyntaxError: when a supplied field is of incorrect type.
|
||||
"""
|
||||
self.__dict__ = self
|
||||
self._actual = False # set to True by define_table()
|
||||
self._tablename = tablename
|
||||
self._sequence_name = args.get('sequence_name',None) or \
|
||||
@@ -7463,6 +7462,9 @@ class Table(dict):
|
||||
'value must be a dictionary: %s' % value
|
||||
dict.__setitem__(self, str(key), value)
|
||||
|
||||
def __getattr__(self, key):
|
||||
return self[key]
|
||||
|
||||
def __delitem__(self, key):
|
||||
if isinstance(key, dict):
|
||||
query = self._build_query(key)
|
||||
@@ -7474,7 +7476,7 @@ class Table(dict):
|
||||
def __setattr__(self, key, value):
|
||||
if key[:1]!='_' and key in self:
|
||||
raise SyntaxError, 'Object exists and cannot be redefined: %s' % key
|
||||
dict.__setattr__(self,key,value)
|
||||
self[key] = value
|
||||
|
||||
def __iter__(self):
|
||||
for fieldname in self.fields:
|
||||
|
||||
+1
-1
@@ -318,7 +318,7 @@ def get_session(request, other_application='admin'):
|
||||
session_id = request.cookies['session_id_' + other_application].value
|
||||
osession = storage.load_storage(os.path.join(
|
||||
up(request.folder), other_application, 'sessions', session_id))
|
||||
except:
|
||||
except Exception, e:
|
||||
osession = storage.Storage()
|
||||
return osession
|
||||
|
||||
|
||||
+1
-1
@@ -2044,7 +2044,7 @@ class FORM(DIV):
|
||||
|
||||
|
||||
@staticmethod
|
||||
def confim(text='OK',buttons=None,hidden=None):
|
||||
def confirm(text='OK',buttons=None,hidden=None):
|
||||
if not buttons: buttons = {}
|
||||
if not hidden: hidden={}
|
||||
inputs = [INPUT(_type='button',
|
||||
|
||||
+5
-11
@@ -476,7 +476,7 @@ def load_routers(all_apps):
|
||||
def regex_uri(e, regexes, tag, default=None):
|
||||
"filter incoming URI against a list of regexes"
|
||||
path = e['PATH_INFO']
|
||||
host = e.get('HTTP_HOST', 'localhost').lower()
|
||||
host = e.get('http_host', e.get('SERVER_NAME','localhost')).lower()
|
||||
i = host.find(':')
|
||||
if i > 0:
|
||||
host = host[:i]
|
||||
@@ -823,21 +823,15 @@ class MapUrlIn(object):
|
||||
self.remote_addr = self.env.get('REMOTE_ADDR','localhost')
|
||||
self.scheme = self.env.get('wsgi.url_scheme', 'http').lower()
|
||||
self.method = self.env.get('REQUEST_METHOD', 'get').lower()
|
||||
self.host = self.env.get('HTTP_HOST')
|
||||
self.port = None
|
||||
(self.host, self.port) = (self.env.get('HTTP_HOST'), None)
|
||||
if not self.host:
|
||||
self.host = self.env.get('SERVER_NAME')
|
||||
self.port = self.env.get('SERVER_PORT')
|
||||
(self.host, self.port) = (self.env.get('SERVER_NAME'), self.env.get('SERVER_PORT'))
|
||||
if not self.host:
|
||||
self.host = 'localhost'
|
||||
self.port = '80'
|
||||
(self.host, self.port) = ('localhost', '80')
|
||||
if ':' in self.host:
|
||||
(self.host, self.port) = self.host.split(':')
|
||||
if not self.port:
|
||||
if self.scheme == 'https':
|
||||
self.port = '443'
|
||||
else:
|
||||
self.port = '80'
|
||||
self.port = '443' if self.scheme == 'https' else '80'
|
||||
|
||||
def map_prefix(self):
|
||||
"strip path prefix, if present in its entirety"
|
||||
|
||||
+57
-70
@@ -13,42 +13,11 @@ Provides:
|
||||
"""
|
||||
|
||||
import cPickle
|
||||
import portalocker
|
||||
|
||||
__all__ = ['List', 'Storage', 'Settings', 'Messages',
|
||||
'StorageList', 'load_storage', 'save_storage']
|
||||
|
||||
|
||||
class List(list):
|
||||
"""
|
||||
Like a regular python list but a[i] if i is out of bounds return None
|
||||
instead of IndexOutOfBounds
|
||||
"""
|
||||
|
||||
def __call__(self, i, default=None, cast=None, otherwise=None):
|
||||
"""
|
||||
request.args(0,default=0,cast=int,otherwise='http://error_url')
|
||||
request.args(0,default=0,cast=int,otherwise=lambda:...)
|
||||
"""
|
||||
n = len(self)
|
||||
if 0<=i<n or -n<=i<0:
|
||||
value = self[i]
|
||||
else:
|
||||
value = default
|
||||
if cast:
|
||||
try:
|
||||
value = cast(value)
|
||||
except (ValueError, TypeError):
|
||||
from http import HTTP, redirect
|
||||
if otherwise is None:
|
||||
raise HTTP(404)
|
||||
elif isinstance(otherwise,str):
|
||||
redirect(otherwise)
|
||||
elif callable(otherwise):
|
||||
return otherwise()
|
||||
else:
|
||||
raise RuntimeError, "invalid otherwise"
|
||||
return value
|
||||
|
||||
class Storage(dict):
|
||||
"""
|
||||
A Storage object is like a dictionary except `obj.foo` can be used
|
||||
@@ -66,31 +35,24 @@ class Storage(dict):
|
||||
2
|
||||
|
||||
>>> del o.a
|
||||
>>> print o.a
|
||||
|
||||
>>> print o.a
|
||||
None
|
||||
"""
|
||||
def __init__(self, *args, **kwargs):
|
||||
dict.__init__(self, *args, **kwargs)
|
||||
self.__dict__ = self
|
||||
def __getattr__(self,key):
|
||||
return getattr(self,key) if key in self else None
|
||||
def __getitem__(self,key):
|
||||
return dict.get(self,key,None)
|
||||
def copy(self):
|
||||
self.__dict__ = {}
|
||||
s = Storage(self)
|
||||
self.__dict__ = self
|
||||
return s
|
||||
def __getattr__(self, key):
|
||||
return dict.get(self, key, None)
|
||||
def __setattr__(self, key, value):
|
||||
self[key] = value
|
||||
def __delattr__(self, key):
|
||||
del self[key]
|
||||
def __getitem__(self, key):
|
||||
return dict.get(self, key, None)
|
||||
def __repr__(self):
|
||||
return '<Storage %s>' % dict.__repr__(self)
|
||||
return '<Storage %s>' + dict.__repr__(self)
|
||||
def __getstate__(self):
|
||||
return dict(self)
|
||||
def __setstate__(self, sdict):
|
||||
dict.__init__(self, sdict)
|
||||
self.__dict__ = self
|
||||
def update(self, *args, **kwargs):
|
||||
dict.__init__(self, *args, **kwargs)
|
||||
self.__dict__ = self
|
||||
def __setstate__(self,values):
|
||||
self.update(values)
|
||||
|
||||
def getlist(self,key):
|
||||
"""
|
||||
Return a Storage value as a list.
|
||||
@@ -111,9 +73,10 @@ class Storage(dict):
|
||||
>>> request.vars.getlist('z')
|
||||
[]
|
||||
"""
|
||||
value = getattr(self,key,[])
|
||||
value = self.get(key,[])
|
||||
return value if not value else \
|
||||
value if isinstance(value,(list,tuple)) else [value]
|
||||
|
||||
def getfirst(self,key,default=None):
|
||||
"""
|
||||
Return the first or only value when given a request.vars-style key.
|
||||
@@ -132,8 +95,9 @@ class Storage(dict):
|
||||
'abc'
|
||||
>>> request.vars.getfirst('z')
|
||||
"""
|
||||
values = self.getlist(default)
|
||||
values = self.getlist(key)
|
||||
return values[0] if values else default
|
||||
|
||||
def getlast(self,key,default=None):
|
||||
"""
|
||||
Returns the last or only single value when
|
||||
@@ -153,8 +117,8 @@ class Storage(dict):
|
||||
'def'
|
||||
>>> request.vars.getlast('z')
|
||||
"""
|
||||
values = self.getlist(default)
|
||||
return values[0] if values else default
|
||||
values = self.getlist(key)
|
||||
return values[-1] if values else default
|
||||
|
||||
PICKABLE = (str,int,long,float,bool,list,dict,tuple,set)
|
||||
|
||||
@@ -191,29 +155,52 @@ def save_storage(storage, filename):
|
||||
|
||||
class Settings(Storage):
|
||||
def __setattr__(self, key, value):
|
||||
if key != 'lock_keys' and self.lock_keys and not key in self:
|
||||
if key != 'lock_keys' and 'lock_keys' in self and not key in self:
|
||||
raise SyntaxError, 'setting key \'%s\' does not exist' % key
|
||||
if key != 'lock_values' and self.lock_values:
|
||||
if key != 'lock_values' and 'lock_values' in self:
|
||||
raise SyntaxError, 'setting value cannot be changed: %s' % key
|
||||
Storage.__setattr__(self,key,value)
|
||||
self[key] = value
|
||||
|
||||
class Messages(Storage):
|
||||
class Messages(Settings):
|
||||
def __init__(self, T):
|
||||
Storage.__init__(self,T=T)
|
||||
|
||||
def __setattr__(self, key, value):
|
||||
if key != 'lock_keys' and self.lock_keys and not key in self:
|
||||
raise SyntaxError, 'setting key \'%s\' does not exist' % key
|
||||
if key != 'lock_values' and self.lock_values:
|
||||
raise SyntaxError, 'setting value cannot be changed: %s' % key
|
||||
Storage.__setattr__(self,key,value)
|
||||
|
||||
def __getattr__(self, key):
|
||||
value = Storage.__getattr__(self,key)
|
||||
value = self[key]
|
||||
if isinstance(value, str):
|
||||
return str(self.T(value))
|
||||
return value
|
||||
|
||||
class List(list):
|
||||
"""
|
||||
Like a regular python list but a[i] if i is out of bounds return None
|
||||
instead of IndexOutOfBounds
|
||||
"""
|
||||
|
||||
def __call__(self, i, default=None, cast=None, otherwise=None):
|
||||
"""
|
||||
request.args(0,default=0,cast=int,otherwise='http://error_url')
|
||||
request.args(0,default=0,cast=int,otherwise=lambda:...)
|
||||
"""
|
||||
n = len(self)
|
||||
if 0<=i<n or -n<=i<0:
|
||||
value = self[i]
|
||||
else:
|
||||
value = default
|
||||
if cast:
|
||||
try:
|
||||
value = cast(value)
|
||||
except (ValueError, TypeError):
|
||||
from http import HTTP, redirect
|
||||
if otherwise is None:
|
||||
raise HTTP(404)
|
||||
elif isinstance(otherwise,str):
|
||||
redirect(otherwise)
|
||||
elif callable(otherwise):
|
||||
return otherwise()
|
||||
else:
|
||||
raise RuntimeError, "invalid otherwise"
|
||||
return value
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
import doctest
|
||||
|
||||
+27
-25
@@ -3138,7 +3138,8 @@ class Auth(object):
|
||||
return id
|
||||
def wiki(self,slug=None,env=None,manage_permissions=False,force_prefix=''):
|
||||
if not hasattr(self,'_wiki'):
|
||||
self._wiki = Wiki(self,manage_permissions=manage_permissions,
|
||||
self._wiki = Wiki(self,
|
||||
manage_permissions=manage_permissions,
|
||||
force_prefix=force_prefix,env=env)
|
||||
else:
|
||||
self._wiki.env.update(env or {})
|
||||
@@ -4466,13 +4467,12 @@ class Wiki(object):
|
||||
items = text.split('/')
|
||||
controller, function, args = items[0], items[1], items[2:]
|
||||
return LOAD(controller, function, args=args, ajax=True).xml()
|
||||
def __init__(self,auth,env=None,automenu=True,render='markmin',
|
||||
def __init__(self,auth,env=None,render='markmin',
|
||||
manage_permissions=False,force_prefix=''):
|
||||
self.env = env or {}
|
||||
self.env['component'] = Wiki.component
|
||||
if render == 'markmin': render=self.markmin_render
|
||||
self.auth = auth
|
||||
self.automenu = automenu
|
||||
if self.auth.user:
|
||||
self.force_prefix = force_prefix % self.auth.user
|
||||
else:
|
||||
@@ -4487,7 +4487,6 @@ class Wiki(object):
|
||||
readable=False,writable=False),
|
||||
Field('title',unique=True),
|
||||
Field('body','text',notnull=True),
|
||||
Field('menu'),
|
||||
Field('tags','list:string'),
|
||||
Field('can_read','list:string',writable=perms,readable=perms,
|
||||
default=[Wiki.everybody]),
|
||||
@@ -4553,9 +4552,8 @@ class Wiki(object):
|
||||
### END POLICY
|
||||
def __call__(self):
|
||||
request = current.request
|
||||
if self.automenu:
|
||||
current.response.menu = self.menu(request.controller,
|
||||
request.function)
|
||||
automenu = self.menu(request.controller,request.function)
|
||||
current.response.menu += automenu
|
||||
zero = request.args(0)
|
||||
if zero and zero.isdigit():
|
||||
return self.media(int(zero))
|
||||
@@ -4644,8 +4642,10 @@ class Wiki(object):
|
||||
db.wiki_page.can_edit.default = [auth.user_group_role()]
|
||||
db.wiki_page.title.default = title_guess
|
||||
db.wiki_page.slug.default = slug
|
||||
db.wiki_page.menu.default = slug
|
||||
db.wiki_page.body.default = '## %s\n\npage content' % title_guess
|
||||
if slug == 'wiki-menu':
|
||||
db.wiki_page.body.default = '- Menu Item > @////index\n- - Submenu > http://web2py.com'
|
||||
else:
|
||||
db.wiki_page.body.default = '## %s\n\npage content' % title_guess
|
||||
vars = current.request.post_vars
|
||||
if vars.body:
|
||||
vars.body=vars.body.replace('://%s' % self.host,'://HOSTNAME')
|
||||
@@ -4716,23 +4716,23 @@ class Wiki(object):
|
||||
def menu(self,controller='default',function='index'):
|
||||
db = self.auth.db
|
||||
request = current.request
|
||||
rows = db((db.wiki_page.menu!=None)|(db.wiki_page.menu!=''))\
|
||||
.select(db.wiki_page.menu,db.wiki_page.title,db.wiki_page.slug,
|
||||
orderby = db.wiki_page.menu)
|
||||
menu_page = db.wiki_page(slug='wiki-menu')
|
||||
menu = []
|
||||
tree = {'.':menu}
|
||||
regex = re.compile('\d\:')
|
||||
for row in rows:
|
||||
if row.menu:
|
||||
key = './'+regex.sub('',row.menu)
|
||||
base = key.rsplit('/',1)[0]
|
||||
subtree = tree[key] = []
|
||||
if base in tree:
|
||||
tree[base].append((current.T(row.title),
|
||||
request.args(0)==row.slug,
|
||||
URL(controller,function,args=row.slug),
|
||||
subtree))
|
||||
#if self.auth.user:
|
||||
if menu_page:
|
||||
tree = {'':menu}
|
||||
regex = re.compile('[\r\n\t]*(?P<base>(\s*\-\s*)+)(?P<title>\w.*?)\s+\>\s+(?P<link>\S+)')
|
||||
for match in regex.finditer(self.fix_hostname(menu_page.body)):
|
||||
base = match.group('base').replace(' ','')
|
||||
title = match.group('title')
|
||||
link = match.group('link')
|
||||
if link.startswith('@'):
|
||||
items = link[1:].split('/')
|
||||
if len(items)>3:
|
||||
link = URL(a=items[0] or None,c=items[1] or None,f=items[2] or None, args=items[3:])
|
||||
parent = tree.get(base[1:],tree[''])
|
||||
subtree = []
|
||||
tree[base] = subtree
|
||||
parent.append((current.T(title),False,link,subtree))
|
||||
if True:
|
||||
submenu = []
|
||||
menu.append((current.T('[Wiki]'),None,None,submenu))
|
||||
@@ -4763,6 +4763,8 @@ class Wiki(object):
|
||||
# if self.can_manage():
|
||||
submenu.append((current.T('Manage Pages'),None,
|
||||
URL(controller,function,args=('_pages'))))
|
||||
submenu.append((current.T('Edit Menu'),None,
|
||||
URL(controller,function,args=('_edit','wiki-menu'))))
|
||||
# if self.can_search():
|
||||
submenu.append((current.T('Search Pages'),None,
|
||||
URL(controller,function,args=('_search'))))
|
||||
|
||||
Reference in New Issue
Block a user