# -*- coding: utf-8 mode: python -*- vim:sw=4:sts=4:et:ai:si:sta:fenc=utf-8 __all__ = ('defaults', 'Page', 'register', 'next_page', 'set_trace', ) import sys, pdb from os import path from Cookie import BaseCookie from google.appengine.ext.webapp import RequestHandler, template from django.utils.simplejson.encoder import JSONEncoder from ulib.base.base import isseq from ulib.base.uio import _u, _s def set_trace(): pdb.Pdb(stdin=sys.__stdin__, stdout=sys.__stdout__).set_trace(sys._getframe().f_back) _none = [] def defaults(**values): def decorator(method): def wrapper(*args, **kw): self = args[0:1] and args[0] or None if self is not None: defaults = self.defaults if defaults is None: defaults = {} defaults.update(values) self.defaults = defaults for name, default_value in defaults.items(): if isseq(default_value): value = self.request.get_all(name) if not value: value = _none else: value = self.request.get(name, _none) if value is not _none: setattr(self, name, value) return method(*args, **kw) return wrapper return decorator class Page(RequestHandler): URL = None json = JSONEncoder() defaults = None def __getattr__(self, name): defaults = self.defaults if defaults is not None: if defaults.has_key(name): return defaults[name] raise NameError(name) def set_cookie(self, key, value='', max_age=None, path='/', domain=None, secure=None, httponly=False, version=None, comment=None): cookies = BaseCookie() cookies[key] = value for var_name, var_value in [ ('max_age', max_age), ('path', path), ('domain', domain), ('secure', secure), ('HttpOnly', httponly), ('version', version), ('comment', comment), ]: if var_value is not None and var_value is not False: cookies[key][var_name.replace('_', '-')] = str(var_value) header_value = cookies[key].output(header='').lstrip() self.response.headers.add_header('Set-Cookie', header_value) def _render(self, template_name=None, **kw): module_name = self.__class__.__module__ module = sys.modules[module_name] if template_name is None: template_name = self.__class__.__name__ + '.html' defaults = self.defaults if defaults is None: values = {} else: values = defaults.copy() names = values.keys() for name in names: value = getattr(self, name, _none) if value is not _none: values[name] = value values.update(kw) pf = path.join(path.dirname(module.__file__), template_name) self.response.out.write(template.render(pf, values)) def handler(self, *args): self._render() def get(self, *args): self.handler(*args) def post(self, *args): self.handler(*args) def get_error_msg(self): u"""Obtenir le message d'erreur de la dernière exception, ainsi que la classe CSS associée. @return: msg, msgclass """ type, value = sys.exc_info()[:2] if type is None: return None, u"success" elif isinstance(value, Warning): return u"%s: %s" % (_u(type.__name__), _u(value)), u"notice" elif isinstance(value, Exception): return u"%s: %s" % (_u(type.__name__), _u(value)), u"error" HANDLERS = [] HANDLERS_BY_NAME = {} def register(handler_cls): if handler_cls is None: return None if handler_cls.URL is None: return None HANDLERS.append((handler_cls.URL, handler_cls)) HANDLERS_BY_NAME[handler_cls.__name__] = handler_cls return handler_cls def next_page(name, page): cls = HANDLERS_BY_NAME.get(name, None) if cls is None: raise ValueError("Page not found: %s" % name) next_page = cls() next_page.initialize(page.request, page.response) return next_page