nulib/web: ajout de redirect() et set_profile(). améliorer la lisibilité des arguments
This commit is contained in:
parent
c58a6ccaf7
commit
1a3550ed9a
|
@ -46,14 +46,20 @@ def load(prefix=None, icons=True, charset="utf-8"):
|
||||||
################################################################################
|
################################################################################
|
||||||
# Menu
|
# Menu
|
||||||
|
|
||||||
|
NAVBAR_TYPE_MAP = {
|
||||||
|
'fixed': 'fixed-top',
|
||||||
|
'static': 'static-top',
|
||||||
|
}
|
||||||
|
|
||||||
class Menu(ui.Menu):
|
class Menu(ui.Menu):
|
||||||
"""Un menu"""
|
"""Un menu"""
|
||||||
|
|
||||||
def __init__(self, title, mitems=None, profiles=None,
|
def __init__(self, title, mitems=None, profiles=None,
|
||||||
id=None, p=None, c=None, t=None, **kw):
|
id=None, in_profiles=None, css=None, navbar_type=None, **kw):
|
||||||
super(Menu, self).__init__(title, mitems, profiles, id, p, c, **kw)
|
if navbar_type is None: navbar_type = kw.pop('t', None)
|
||||||
if t is None: t = 'static'
|
super(Menu, self).__init__(title, mitems, profiles, id, in_profiles, css, **kw)
|
||||||
self.navbar_type = t
|
if navbar_type is None: navbar_type = 'static'
|
||||||
|
self.navbar_type = navbar_type
|
||||||
|
|
||||||
def __mitem(self, mitem, sel_profile):
|
def __mitem(self, mitem, sel_profile):
|
||||||
# ne pas afficher un menu qui n'est pas dans le bon profil
|
# ne pas afficher un menu qui n'est pas dans le bon profil
|
||||||
|
@ -87,16 +93,20 @@ class Menu(ui.Menu):
|
||||||
lines.append(u"""</ul>""")
|
lines.append(u"""</ul>""")
|
||||||
return lines
|
return lines
|
||||||
|
|
||||||
def __call__(self, s=None, p=None, t=None):
|
def render(self, select=None, profile=None, navbar_type=None, **kw):
|
||||||
if t is None: t = self.navbar_type
|
if select is None: select = kw.pop('s', None)
|
||||||
if s is not None: self.select(s, p)
|
if profile is None: profile = kw.pop('p', None)
|
||||||
|
if navbar_type is None: navbar_type = kw.pop('t', None)
|
||||||
|
|
||||||
|
if navbar_type is None: navbar_type = self.navbar_type
|
||||||
|
if select is not None: self.select(select, profile)
|
||||||
selection = self.get_mitem()
|
selection = self.get_mitem()
|
||||||
lines = []
|
lines = []
|
||||||
if t == 'fixed' or t == 'fixed-top':
|
if navbar_type == 'fixed' or navbar_type == 'fixed-top':
|
||||||
lines.append(u"""<style type="text/css">body { margin-top: 50px; }</style>""")
|
lines.append(u"""<style type="text/css">body { margin-top: 50px; }</style>""")
|
||||||
css = u''
|
css = u''
|
||||||
css = ui.addclassif('navbar-fixed-top', t == 'fixed' or t == 'fixed-top', css)
|
css = ui.addclassif('navbar-fixed-top', navbar_type == 'fixed' or navbar_type == 'fixed-top', css)
|
||||||
css = ui.addclassif('navbar-static-top', t == 'static' or t == 'static-top', css)
|
css = ui.addclassif('navbar-static-top', navbar_type == 'static' or navbar_type == 'static-top', css)
|
||||||
if self.profiles is not None and self.sel_profile is not None:
|
if self.profiles is not None and self.sel_profile is not None:
|
||||||
css = ui.addclassif('%s-profile' % self.sel_profile, None, css)
|
css = ui.addclassif('%s-profile' % self.sel_profile, None, css)
|
||||||
css = ui.addclassif(self.css, None, css)
|
css = ui.addclassif(self.css, None, css)
|
||||||
|
@ -145,10 +155,9 @@ class Menu(ui.Menu):
|
||||||
</div>
|
</div>
|
||||||
</div>""")
|
</div>""")
|
||||||
return u"\n".join(lines)
|
return u"\n".join(lines)
|
||||||
|
def __unicode__(self): return self.render()
|
||||||
|
|
||||||
def __unicode__(self): return self()
|
def set_menu(menu, **params):
|
||||||
|
|
||||||
def set_menu(menu):
|
|
||||||
"""Décorateur qui permet d'initialiser une instance de menu dans la session
|
"""Décorateur qui permet d'initialiser une instance de menu dans la session
|
||||||
"""
|
"""
|
||||||
def decorator(method):
|
def decorator(method):
|
||||||
|
@ -159,16 +168,24 @@ def set_menu(menu):
|
||||||
return wrapper
|
return wrapper
|
||||||
return decorator
|
return decorator
|
||||||
|
|
||||||
def menu(id=None, p=None):
|
def menu(id=None, profile=None, **params):
|
||||||
"""Décorateur qui permet de mettre à jour la sélection et le profil dans le menu
|
"""Décorateur qui permet de mettre à jour la sélection et le profil dans
|
||||||
|
le menu
|
||||||
|
|
||||||
|
par défaut, prendre le profil courant dans la session. le profil courant
|
||||||
|
est initialisé par le décorateur @set_profile
|
||||||
"""
|
"""
|
||||||
|
if profile is None: profile = params.pop('p', None)
|
||||||
def decorator(method):
|
def decorator(method):
|
||||||
def wrapper(self, *args, **kw):
|
def wrapper(self, *args, **kw):
|
||||||
session = _ensure_session(self)
|
session = _ensure_session(self)
|
||||||
if 'menu' not in session:
|
if 'menu' not in session:
|
||||||
raise ValueError("menu is required")
|
raise ValueError("menu est requis")
|
||||||
|
sel_profile = profile
|
||||||
|
if sel_profile is None and 'profile' in session:
|
||||||
|
sel_profile = session.profile
|
||||||
if id is not None:
|
if id is not None:
|
||||||
session.menu.select(id, p)
|
session.menu.select(id, sel_profile)
|
||||||
return method(self, *args, **kw)
|
return method(self, *args, **kw)
|
||||||
return wrapper
|
return wrapper
|
||||||
return decorator
|
return decorator
|
||||||
|
@ -229,64 +246,74 @@ class Alert(object):
|
||||||
action = None
|
action = None
|
||||||
showtb = None
|
showtb = None
|
||||||
|
|
||||||
def __init__(self, msg=None, e=Undef, t="error", c=False, x=None, action=None, showtb=True):
|
def __init__(self, msg=None, exc_info=Undef, type="error", closeable=False, escape=None, action=None, showtb=True, **kw):
|
||||||
self(msg, e, t, c, x, action, showtb)
|
self(msg, exc_info, type, closeable, escape, action, showtb, **kw)
|
||||||
|
|
||||||
|
def __call__(self, msg=Undef, exc_info=Undef, type=Undef, closeable=Undef, escape=Undef, action=Undef, showtb=Undef, **kw):
|
||||||
|
if exc_info is Undef: exc_info = kw.pop('e', Undef)
|
||||||
|
if type is Undef: type = kw.pop('t', Undef)
|
||||||
|
if closeable is Undef: closeable = kw.pop('c', Undef)
|
||||||
|
if escape is Undef: escape = kw.pop('x', Undef)
|
||||||
|
|
||||||
def __call__(self, msg=Undef, e=Undef, t=Undef, c=Undef, x=Undef, action=Undef, showtb=Undef):
|
|
||||||
if msg is Undef:
|
if msg is Undef:
|
||||||
# si on ne spécifie pas de message, alors prendre la valeur actuelle
|
# si on ne spécifie pas de message, alors prendre la valeur actuelle
|
||||||
msg = self.msg
|
msg = self.msg
|
||||||
if e is Undef: e = self.exc_info
|
if exc_info is Undef: exc_info = self.exc_info
|
||||||
else:
|
else:
|
||||||
# si on spécifie un message, alors prendre aussi l'exception courante
|
# si on spécifie un message, alors prendre aussi l'exception courante
|
||||||
if e is Undef: e = sys.exc_info()
|
if exc_info is Undef: exc_info = sys.exc_info()
|
||||||
if e == (None, None, None): e = None
|
if exc_info == (None, None, None): exc_info = None
|
||||||
if t is Undef: t = self.type
|
if type is Undef: type = self.type
|
||||||
if c is Undef: c = self.closeable
|
if closeable is Undef: closeable = self.closeable
|
||||||
if x is Undef: x = self.escape
|
if escape is Undef: escape = self.escape
|
||||||
if action is Undef: action = self.action
|
if action is Undef: action = self.action
|
||||||
if showtb is Undef: showtb = self.showtb
|
if showtb is Undef: showtb = self.showtb
|
||||||
|
|
||||||
self.msg = msg
|
self.msg = msg
|
||||||
self.exc_info = e
|
self.exc_info = exc_info
|
||||||
self.type = ALERT_TYPE_MAP.get(t, t)
|
self.type = ALERT_TYPE_MAP.get(type, type)
|
||||||
self.closeable = c
|
self.closeable = closeable
|
||||||
self.escape = x
|
self.escape = escape
|
||||||
self.action = action
|
self.action = action
|
||||||
self.showtb = showtb
|
self.showtb = showtb
|
||||||
return self
|
return self
|
||||||
|
|
||||||
def render(self, msg=Undef, e=Undef, t=Undef, c=Undef, x=Undef, action=Undef, showtb=Undef):
|
def render(self, msg=Undef, exc_info=Undef, type=Undef, closeable=Undef, escape=Undef, action=Undef, showtb=Undef, **kw):
|
||||||
|
if exc_info is Undef: exc_info = kw.pop('e', Undef)
|
||||||
|
if type is Undef: type = kw.pop('t', Undef)
|
||||||
|
if closeable is Undef: closeable = kw.pop('c', Undef)
|
||||||
|
if escape is Undef: escape = kw.pop('x', Undef)
|
||||||
|
|
||||||
if msg is Undef:
|
if msg is Undef:
|
||||||
# si on ne spécifie pas de message, alors prendre la valeur initiale
|
# si on ne spécifie pas de message, alors prendre la valeur initiale
|
||||||
msg = self.msg
|
msg = self.msg
|
||||||
if e is Undef: e = self.exc_info
|
if exc_info is Undef: exc_info = self.exc_info
|
||||||
else:
|
else:
|
||||||
# si on spécifie un message, alors prendre aussi l'exception courante
|
# si on spécifie un message, alors prendre aussi l'exception courante
|
||||||
if e is Undef: e = sys.exc_info()
|
if exc_info is Undef: exc_info = sys.exc_info()
|
||||||
if t is Undef: t = self.type
|
if type is Undef: type = self.type
|
||||||
if c is Undef: c = self.closeable
|
if closeable is Undef: closeable = self.closeable
|
||||||
if x is Undef: x = self.escape
|
if escape is Undef: escape = self.escape
|
||||||
if action is Undef: action = self.action
|
if action is Undef: action = self.action
|
||||||
if showtb is Undef: showtb = self.showtb
|
if showtb is Undef: showtb = self.showtb
|
||||||
|
|
||||||
if callable(msg):
|
if callable(msg):
|
||||||
# si msg est callable, par défaut ne pas mettre le résultat en
|
# si msg est callable, par défaut ne pas mettre le résultat en
|
||||||
# échappement
|
# échappement
|
||||||
if x is None: x = False
|
if escape is None: escape = False
|
||||||
msg = msg()
|
msg = msg()
|
||||||
if x is None: x = True
|
if escape is None: escape = True
|
||||||
|
|
||||||
if msg is None and e is not None:
|
if msg is None and exc_info is not None:
|
||||||
msg = u"Une erreur inattendue s'est produite"
|
msg = u"Une erreur inattendue s'est produite"
|
||||||
if msg is None: return u""
|
if msg is None: return u""
|
||||||
if x: msg = web.websafe(msg)
|
if escape: msg = web.websafe(msg)
|
||||||
|
|
||||||
lines = []
|
lines = []
|
||||||
css = u"alert alert-%s" % t
|
css = u"alert alert-%s" % ALERT_TYPE_MAP.get(type, type)
|
||||||
css = ui.addclassif("alert-dismissible", c, css)
|
css = ui.addclassif("alert-dismissible", closeable, css)
|
||||||
lines.append(u"""<div class="%s" role="alert">""" % css)
|
lines.append(u"""<div class="%s" role="alert">""" % css)
|
||||||
if c:
|
if closeable:
|
||||||
lines.append(u"""<button type="button" class="close" data-dismiss="alert" aria-label="Close"><span aria-hidden="true">×</span></button>""")
|
lines.append(u"""<button type="button" class="close" data-dismiss="alert" aria-label="Close"><span aria-hidden="true">×</span></button>""")
|
||||||
lines.append(p(msg))
|
lines.append(p(msg))
|
||||||
if action is not None:
|
if action is not None:
|
||||||
|
@ -296,19 +323,19 @@ class Alert(object):
|
||||||
title = web.websafe(action.title or u"Cliquez ici pour continuer")
|
title = web.websafe(action.title or u"Cliquez ici pour continuer")
|
||||||
action = u"""<p><a href="%s" accesskey="r">%s</a></p>""" % (url, title)
|
action = u"""<p><a href="%s" accesskey="r">%s</a></p>""" % (url, title)
|
||||||
lines.append(p(action))
|
lines.append(p(action))
|
||||||
if e is not None:
|
if exc_info is not None:
|
||||||
lines.append(u"""<div class="small" style="margin-top: 3em; color: gray;">Pour information, le message d'erreur technique est """)
|
lines.append(u"""<div class="small" style="margin-top: 3em; color: gray;">Pour information, le message d'erreur technique est """)
|
||||||
lines.extend(traceback.format_exception_only(*e[:2]))
|
lines.extend(traceback.format_exception_only(*exc_info[:2]))
|
||||||
if showtb:
|
if showtb:
|
||||||
lines.append(u"<!--")
|
lines.append(u"<!--")
|
||||||
lines.append("".join(traceback.format_exception(*e)))
|
lines.append("".join(traceback.format_exception(*exc_info)))
|
||||||
lines.append(u"-->")
|
lines.append(u"-->")
|
||||||
lines.append(u"""</div>""")
|
lines.append(u"""</div>""")
|
||||||
lines.append(u"""</div>""")
|
lines.append(u"""</div>""")
|
||||||
return u"\n".join([u(line) for line in lines])
|
return u"\n".join([u(line) for line in lines])
|
||||||
def __unicode__(self): return self.render()
|
def __unicode__(self): return self.render()
|
||||||
|
|
||||||
def set_alert(template=None, action=Undef, delay=None):
|
def set_alert(template=None, action=Undef, delay=None, **params):
|
||||||
"""Décorateur qui permet de gérer automatiquement une instance de Alert dans la
|
"""Décorateur qui permet de gérer automatiquement une instance de Alert dans la
|
||||||
page.
|
page.
|
||||||
|
|
||||||
|
@ -357,10 +384,14 @@ def set_alert(template=None, action=Undef, delay=None):
|
||||||
lines.append(u"""\
|
lines.append(u"""\
|
||||||
<title>%(title)s</title>
|
<title>%(title)s</title>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>""" % locals())
|
||||||
|
if web.config.have_session:
|
||||||
|
session = web.config._session
|
||||||
|
if 'menu' in session: lines.append(session.menu.render())
|
||||||
|
lines.append(u"""\
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<h1>%(title)s</h1>""" % locals())
|
<h1>%(title)s</h1>""" % locals())
|
||||||
lines.append(alert())
|
lines.append(alert.render())
|
||||||
lines.append(u"""\
|
lines.append(u"""\
|
||||||
</div>
|
</div>
|
||||||
</body>
|
</body>
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
# -*- coding: utf-8 mode: python -*- vim:sw=4:sts=4:et:ai:si:sta:fenc=utf-8
|
# -*- coding: utf-8 mode: python -*- vim:sw=4:sts=4:et:ai:si:sta:fenc=utf-8
|
||||||
|
|
||||||
__all__ = (
|
__all__ = (
|
||||||
'nocache', 'auth', 'defaults',
|
'nocache', 'auth', 'defaults', 'redirect',
|
||||||
'reset_session', 'set_session', 'session', 'check_session',
|
'reset_session', 'set_session', 'session', 'check_session',
|
||||||
|
'set_profile',
|
||||||
'Page', 'Application',
|
'Page', 'Application',
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -45,7 +46,7 @@ class MetaPage(type):
|
||||||
_fix_PATH(cls, name)
|
_fix_PATH(cls, name)
|
||||||
HANDLER_CLASSES.append(cls)
|
HANDLER_CLASSES.append(cls)
|
||||||
|
|
||||||
def nocache(method):
|
def nocache(method, **params):
|
||||||
"""Décorateur pour s'assurer que le résultat de la méthode web n'est pas mis en cache
|
"""Décorateur pour s'assurer que le résultat de la méthode web n'est pas mis en cache
|
||||||
"""
|
"""
|
||||||
def wrapper(self, *args, **kw):
|
def wrapper(self, *args, **kw):
|
||||||
|
@ -55,7 +56,7 @@ def nocache(method):
|
||||||
return method(self, *args, **kw)
|
return method(self, *args, **kw)
|
||||||
return wrapper
|
return wrapper
|
||||||
|
|
||||||
def auth(authenticator=None, realm='nulib'):
|
def auth(authenticator=None, realm='nulib', **params):
|
||||||
"""Décorateur pour s'assurer que la méthode web est authentifiée.
|
"""Décorateur pour s'assurer que la méthode web est authentifiée.
|
||||||
|
|
||||||
La fonction authenticator avec la signature (username, password) permet
|
La fonction authenticator avec la signature (username, password) permet
|
||||||
|
@ -75,6 +76,22 @@ def auth(authenticator=None, realm='nulib'):
|
||||||
return wrapper
|
return wrapper
|
||||||
return decorator
|
return decorator
|
||||||
|
|
||||||
|
def redirect(desturl, **params):
|
||||||
|
"""rediriger vers l'url spécifiée si la méthode retourne None.
|
||||||
|
|
||||||
|
L'url est enregistrée dans l'objet avec le nom desturl au cas où on
|
||||||
|
voudrait s'en servir dans la page retournée.
|
||||||
|
"""
|
||||||
|
def decorator(method):
|
||||||
|
def wrapper(self, *args, **kw):
|
||||||
|
self.desturl = desturl
|
||||||
|
self.desturl_params = params
|
||||||
|
result = method(self, *args, **kw)
|
||||||
|
if result is not None: return result
|
||||||
|
else: return web.redirect(web.url(desturl, **params))
|
||||||
|
return wrapper
|
||||||
|
return decorator
|
||||||
|
|
||||||
def defaults(*required, **defaults):
|
def defaults(*required, **defaults):
|
||||||
"""Initialiser dans l'objet courant des variables à des valeurs par
|
"""Initialiser dans l'objet courant des variables à des valeurs par
|
||||||
défaut, ou en les prenant parmi les paramètres de la requête.
|
défaut, ou en les prenant parmi les paramètres de la requête.
|
||||||
|
@ -207,6 +224,22 @@ def check_session(_onerror=None, **validators):
|
||||||
return wrapper
|
return wrapper
|
||||||
return decorator
|
return decorator
|
||||||
|
|
||||||
|
def set_profile(profile=None, **params):
|
||||||
|
"""mettre à jour la valeur du profil courant
|
||||||
|
|
||||||
|
s'assurer que l'objet courant contient la variable session. si les sessions
|
||||||
|
n'ont pas été configurées au niveau de l'application, une exception est
|
||||||
|
levée
|
||||||
|
"""
|
||||||
|
if profile is None: profile = params.pop('p', None)
|
||||||
|
def decorator(method):
|
||||||
|
def wrapper(self, *args, **kw):
|
||||||
|
session = _ensure_session(self)
|
||||||
|
session.profile = profile
|
||||||
|
return method(self, *args, **kw)
|
||||||
|
return wrapper
|
||||||
|
return decorator
|
||||||
|
|
||||||
def _fix_PATH(cls, name):
|
def _fix_PATH(cls, name):
|
||||||
if cls.PATH is None:
|
if cls.PATH is None:
|
||||||
if cls.PREFIX is None:
|
if cls.PREFIX is None:
|
||||||
|
@ -491,6 +524,8 @@ class Application(object):
|
||||||
session = web.session.Session(self.webapp, store, initializer=initializer)
|
session = web.session.Session(self.webapp, store, initializer=initializer)
|
||||||
self.session = web.config._session = session
|
self.session = web.config._session = session
|
||||||
|
|
||||||
|
web.config.have_session = session is not None
|
||||||
|
|
||||||
tg = self.template_globals
|
tg = self.template_globals
|
||||||
# session et application comme variables globales du template
|
# session et application comme variables globales du template
|
||||||
tg.setdefault("S", session)
|
tg.setdefault("S", session)
|
||||||
|
@ -529,7 +564,7 @@ class Application(object):
|
||||||
if args is None: args = []
|
if args is None: args = []
|
||||||
options, args = get_args(map(_u, args),
|
options, args = get_args(map(_u, args),
|
||||||
'S:s:H:P:Dp:' + (self.OPTIONS or ''),
|
'S:s:H:P:Dp:' + (self.OPTIONS or ''),
|
||||||
['server-type=', 'server-socket=', 'host=', 'port=', 'debug', 'profile='] + list(self.LONG_OPTIONS or ()))
|
['server-type=', 'server-socket=', 'host=', 'port=', 'debug', 'no-debug', 'profile='] + list(self.LONG_OPTIONS or ()))
|
||||||
server_type = None
|
server_type = None
|
||||||
server_socket = None
|
server_socket = None
|
||||||
for option, value in options:
|
for option, value in options:
|
||||||
|
@ -542,6 +577,8 @@ class Application(object):
|
||||||
elif option in ('-D', '--debug'):
|
elif option in ('-D', '--debug'):
|
||||||
self.DEBUG = True
|
self.DEBUG = True
|
||||||
set_verbosity('--debug')
|
set_verbosity('--debug')
|
||||||
|
elif option in ('--no-debug',):
|
||||||
|
self.DEBUG = False
|
||||||
elif option in ('-p', '--profile'): self.PROFILE = value
|
elif option in ('-p', '--profile'): self.PROFILE = value
|
||||||
self.args = args
|
self.args = args
|
||||||
self.process_args(args)
|
self.process_args(args)
|
||||||
|
|
|
@ -82,11 +82,11 @@ class Action(odict):
|
||||||
url: cible de l'action ou du lien (avec querystring)
|
url: cible de l'action ou du lien (avec querystring)
|
||||||
title: titre du lien ou de l'élément de menu
|
title: titre du lien ou de l'élément de menu
|
||||||
id: identifiant dans un menu
|
id: identifiant dans un menu
|
||||||
p (in_profiles): profils dans lequel l'action est valide. le premier profil
|
in_profiles (p): profils dans lequel l'action est valide. le premier profil
|
||||||
est le profil par défaut
|
est le profil par défaut
|
||||||
c (css): classe css à appliquer au lien
|
css (c): classe css à appliquer au lien
|
||||||
ak (accesskey): accesskey à installer sur le lien
|
accesskey (ak): accesskey à installer sur le lien
|
||||||
q (query): paramètres de la requête, sous forme de dictionnaire ou de chaine
|
query (q): paramètres de la requête, sous forme de dictionnaire ou de chaine
|
||||||
method: type de requête, get ou post
|
method: type de requête, get ou post
|
||||||
PROFILE_url, PROFILE_query: valeurs spécifiques à certains profils, PROFILE
|
PROFILE_url, PROFILE_query: valeurs spécifiques à certains profils, PROFILE
|
||||||
étant une valeur de in_profiles
|
étant une valeur de in_profiles
|
||||||
|
@ -121,74 +121,79 @@ class Action(odict):
|
||||||
self[querykey] = query
|
self[querykey] = query
|
||||||
self[urlkey] = url
|
self[urlkey] = url
|
||||||
|
|
||||||
def __init__(self, url, title=None, id=None, p=None, c=None, ak=None, q=None, method=None, **kw):
|
def __init__(self, url, title=None, id=None, in_profiles=None, css=None, accesskey=None, query=None, method=None, **kw):
|
||||||
super(Action, self).__init__(**kw)
|
super(Action, self).__init__(**kw)
|
||||||
if isseq(url):
|
if isseq(url):
|
||||||
if url[1:2]: title = url[1]
|
if url[1:2]: title = url[1]
|
||||||
if url[2:3]: id = url[2]
|
if url[2:3]: id = url[2]
|
||||||
if url[3:4]: p = url[3]
|
if url[3:4]: in_profiles = url[3]
|
||||||
if url[4:5]: c = url[4]
|
if url[4:5]: css = url[4]
|
||||||
if url[5:6]: ak = url[5]
|
if url[5:6]: accesskey = url[5]
|
||||||
if url[6:7]: method = url[6]
|
if url[6:7]: method = url[6]
|
||||||
url = url[0] if url[0:1] else None
|
url = url[0] if url[0:1] else None
|
||||||
if url is None: raise ValueError("url is required")
|
if url is None: raise ValueError("url is required")
|
||||||
if title is None: title = url
|
if title is None: title = url
|
||||||
if p is None: p = kw.get('in_profiles', None)
|
if in_profiles is None: in_profiles = kw.pop('p', None)
|
||||||
if c is None: c = kw.get('css', None)
|
if css is None: css = kw.pop('c', None)
|
||||||
if ak is None: ak = kw.get('accesskey', None)
|
if accesskey is None: accesskey = kw.pop('ak', None)
|
||||||
if q is None: q = kw.get('query', None)
|
if query is None: query = kw.pop('q', None)
|
||||||
if method is None: method = 'get'
|
if method is None: method = 'get'
|
||||||
|
|
||||||
self.title = title
|
self.title = title
|
||||||
self.id = id
|
self.id = id
|
||||||
self.css = c
|
self.css = css
|
||||||
self.accesskey = ak
|
self.accesskey = accesskey
|
||||||
self.method = method
|
self.method = method
|
||||||
|
|
||||||
self.url = url
|
self.url = url
|
||||||
self.query = q
|
self.query = query
|
||||||
self.__update_url('url', 'query', 'baseurl')
|
self.__update_url('url', 'query', 'baseurl')
|
||||||
|
|
||||||
self.in_profiles = seqof(p, None)
|
self.in_profiles = seqof(in_profiles, None)
|
||||||
if self.in_profiles is None: return
|
if self.in_profiles is None: return
|
||||||
for p in self.in_profiles:
|
for profile in self.in_profiles:
|
||||||
self.__update_url(*['%s_%s' % (p, key) for key in ('url', 'query', 'baseurl')])
|
self.__update_url(*['%s_%s' % (profile, key) for key in ('url', 'query', 'baseurl')])
|
||||||
self.__update_url(*['to_%s_%s' % (p, key) for key in ('url', 'query', 'baseurl')])
|
self.__update_url(*['to_%s_%s' % (profile, key) for key in ('url', 'query', 'baseurl')])
|
||||||
|
|
||||||
def __get_key(self, key, p=None, to=False):
|
def __get_key(self, key, profile=None, to=False):
|
||||||
if p is not None:
|
if profile is not None:
|
||||||
pkey = '%s%s_%s' % ('to_' if to else '', p, key)
|
pkey = '%s%s_%s' % ('to_' if to else '', profile, key)
|
||||||
value = self.get(pkey, None)
|
value = self.get(pkey, None)
|
||||||
if value is not None: return value
|
if value is not None: return value
|
||||||
return self[key]
|
return self[key]
|
||||||
def get_baseurl(self, p=None, to=False):
|
def get_baseurl(self, profile=None, to=False, **kw):
|
||||||
"""obtenir l'url de base
|
"""obtenir l'url de base
|
||||||
"""
|
"""
|
||||||
return self.__get_key('baseurl', p, to)
|
if profile is None: profile = kw.pop('p', None)
|
||||||
def get_query(self, p=None, to=False):
|
return self.__get_key('baseurl', profile, to)
|
||||||
|
def get_query(self, profile=None, to=False, **kw):
|
||||||
"""obtenir les paramètres de la requête sous forme de dictionnaire
|
"""obtenir les paramètres de la requête sous forme de dictionnaire
|
||||||
"""
|
"""
|
||||||
return self.__get_key('query', p, to)
|
if profile is None: profile = kw.pop('p', None)
|
||||||
def get_url(self, p=None, to=False):
|
return self.__get_key('query', profile, to)
|
||||||
|
def get_url(self, profile=None, to=False, **kw):
|
||||||
"""obtenir l'url
|
"""obtenir l'url
|
||||||
"""
|
"""
|
||||||
return self.__get_key('url', p, to)
|
if profile is None: profile = kw.pop('p', None)
|
||||||
|
return self.__get_key('url', profile, to)
|
||||||
|
|
||||||
def get_qs(self, p=None, to=False, sep=None):
|
def get_qs(self, profile=None, to=False, sep=None, **kw):
|
||||||
"""obtenir les paramètres de la requête sous forme de query-string
|
"""obtenir les paramètres de la requête sous forme de query-string
|
||||||
sep vaut par défaut '?' mais peut valoir '&'
|
sep vaut par défaut '?' mais peut valoir '&'
|
||||||
"""
|
"""
|
||||||
query = self.get_query(p, to)
|
if profile is None: profile = kw.pop('p', None)
|
||||||
|
query = self.get_query(profile, to)
|
||||||
if sep is None: sep = '?'
|
if sep is None: sep = '?'
|
||||||
return '%s%s' % (sep, urllib.urlencode(query, True))
|
return '%s%s' % (sep, urllib.urlencode(query, True))
|
||||||
qs = property(get_qs)
|
qs = property(get_qs)
|
||||||
get_querystring = get_qs; querystring = property(get_qs)
|
get_querystring = get_qs; querystring = property(get_qs)
|
||||||
|
|
||||||
def get_inputs(self, p=None, to=False):
|
def get_inputs(self, profile=None, to=False, **kw):
|
||||||
"""obtenir les paramètres de la requête sous forme d'une liste de définitions
|
"""obtenir les paramètres de la requête sous forme d'une liste de définitions
|
||||||
d'éléments de formulaire de type hidden
|
d'éléments de formulaire de type hidden
|
||||||
"""
|
"""
|
||||||
query = self.get_query(p, to)
|
if profile is None: profile = kw.pop('p', None)
|
||||||
|
query = self.get_query(profile, to)
|
||||||
Hidden = web.form.Hidden
|
Hidden = web.form.Hidden
|
||||||
inputs = []
|
inputs = []
|
||||||
for name, value in query.items():
|
for name, value in query.items():
|
||||||
|
@ -212,7 +217,9 @@ class Menu(odict):
|
||||||
return nextid
|
return nextid
|
||||||
|
|
||||||
def __init__(self, title, mitems=None, profiles=None,
|
def __init__(self, title, mitems=None, profiles=None,
|
||||||
id=None, p=None, c=None, **kw):
|
id=None, in_profiles=None, css=None, **kw):
|
||||||
|
if in_profiles is None: in_profiles = kw.pop('p', None)
|
||||||
|
if css is None: css = kw.pop('c', None)
|
||||||
super(Menu, self).__init__(**kw)
|
super(Menu, self).__init__(**kw)
|
||||||
self.__dict__['nextid'] = 0
|
self.__dict__['nextid'] = 0
|
||||||
self.__dict__['idmap'] = {}
|
self.__dict__['idmap'] = {}
|
||||||
|
@ -225,7 +232,7 @@ class Menu(odict):
|
||||||
self.default_profile = profiles[0] if profiles is not None else None
|
self.default_profile = profiles[0] if profiles is not None else None
|
||||||
self.id = str(id)
|
self.id = str(id)
|
||||||
self.in_profiles = seqof(p, None)
|
self.in_profiles = seqof(p, None)
|
||||||
self.css = c
|
self.css = css
|
||||||
self.sel_id = None
|
self.sel_id = None
|
||||||
self.sel_profile = None
|
self.sel_profile = None
|
||||||
self.active = False
|
self.active = False
|
||||||
|
@ -244,7 +251,7 @@ class Menu(odict):
|
||||||
self.mitems.append(mitem)
|
self.mitems.append(mitem)
|
||||||
self.idmap[mitem.id] = mitem
|
self.idmap[mitem.id] = mitem
|
||||||
|
|
||||||
def reset_selection(self):
|
def reset_selection(self, **kw):
|
||||||
self.sel_id = None
|
self.sel_id = None
|
||||||
self.sel_profile = self.default_profile
|
self.sel_profile = self.default_profile
|
||||||
self.active = False
|
self.active = False
|
||||||
|
@ -254,7 +261,8 @@ class Menu(odict):
|
||||||
else:
|
else:
|
||||||
mitem.active = False
|
mitem.active = False
|
||||||
|
|
||||||
def select(self, id, p=None):
|
def select(self, id, profile=None, **kw):
|
||||||
|
if profile is None: profile = kw.pop('p', None)
|
||||||
# d'abord déselectionner tout le monde
|
# d'abord déselectionner tout le monde
|
||||||
self.reset_selection()
|
self.reset_selection()
|
||||||
# ensuite chercher le mitem à sélectionner
|
# ensuite chercher le mitem à sélectionner
|
||||||
|
@ -262,10 +270,10 @@ class Menu(odict):
|
||||||
mitem = self.idmap.get(id, None)
|
mitem = self.idmap.get(id, None)
|
||||||
if mitem is not None:
|
if mitem is not None:
|
||||||
self.sel_id = id
|
self.sel_id = id
|
||||||
if p is None and mitem.in_profiles:
|
if profile is None and mitem.in_profiles:
|
||||||
p = mitem.in_profiles[0]
|
profile = mitem.in_profiles[0]
|
||||||
if p is None: p = self.default_profile
|
if profile is None: profile = self.default_profile
|
||||||
self.sel_profile = p
|
self.sel_profile = profile
|
||||||
mitem.active = self.active = True
|
mitem.active = self.active = True
|
||||||
return True
|
return True
|
||||||
else:
|
else:
|
||||||
|
@ -278,7 +286,7 @@ class Menu(odict):
|
||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def get_mitem(self, id=None):
|
def get_mitem(self, id=None, **kw):
|
||||||
"""retourner l'élément de menu correspondant à la sélection courante
|
"""retourner l'élément de menu correspondant à la sélection courante
|
||||||
"""
|
"""
|
||||||
if id is None: id = self.sel_id
|
if id is None: id = self.sel_id
|
||||||
|
|
|
@ -2,11 +2,13 @@
|
||||||
|
|
||||||
__all__ = (
|
__all__ = (
|
||||||
'web', 'Page', 'bs',
|
'web', 'Page', 'bs',
|
||||||
'nocache', 'auth', 'defaults',
|
'nocache', 'auth', 'defaults', 'redirect',
|
||||||
'reset_session', 'set_session', 'session', 'check_session',
|
'reset_session', 'set_session', 'session', 'check_session',
|
||||||
|
'set_profile',
|
||||||
'config',
|
'config',
|
||||||
)
|
)
|
||||||
|
|
||||||
from nulib.web import web, Page, bs, nocache, auth, defaults
|
from nulib.web import web, Page, bs, nocache, auth, defaults, redirect
|
||||||
from nulib.web import reset_session, set_session, session, check_session
|
from nulib.web import reset_session, set_session, session, check_session
|
||||||
|
from nulib.web import set_profile
|
||||||
from nulib.web.config_loader import config
|
from nulib.web.config_loader import config
|
||||||
|
|
Loading…
Reference in New Issue