示例#1
0
from htmlr.environment import Environment

e = Environment('.')

t = e.get_template('sample')
print(t.display())
示例#2
0
class Svana():

    def __init__(self, route,
                 sender_id=None,
                 host='localhost',
                 port=8000,
                 db='config.sqlite',
                 default_methods=None,
                 debug=False,
                 template_path=None,
                 template_environment=None):
        self.url_map = Map(converters={'default': UnquoteConverter})
        self.url_adapter = self.url_map.bind('{0}:{1}'.format(host, port))
        self.default_methods = default_methods or ['GET']
        self.endpoint_lookup = {}
        self.sender_id = sender_id or uuid4().hex
        if isinstance(route, (str, unicode)):
            route = self.get_pub_sub(route, db)
        self.pub, self.sub = route
        self.debug = debug
        self.host = host
        self.port = port
        if template_path:
            if template_environment is None:
                self.templates = Environment(template_path)
            else:
                self.templates = template_environment(template_path)
        else:
            self.templates = None

    def render_template(self, name, *datalist, **datadict):
        if self.templates:
            t = self.templates.get_template(name)
            datalist = list(datalist)
            while True:
                try:
                    r = t.render(*datalist, **datadict)
                except KeyError as exc:
                    print(exc)
                    print(exc.message)
                    datadict[exc.message] = ''
                    print(datadict)
                except IndexError as exc:
                    print(exc)
                    datalist.append('')
                    print(datalist)
                else:
                    break

            return HTMLResponse(r)
        else:
            raise NotFound

    def get_pub_sub(self, route, db=None):
        if db is None:
            db = 'config.sqlite'
        store = model.begin(db)
        routes = store.find(model.Route, model.Route.path == unicode(route))
        if routes.count() == 1:
            target = routes.one().target
            try:
                return target.send_spec, target.recv_spec
            except AttributeError:
                raise Exception('route.target is not a mongrel2 handler: {0}'
                                .format(target))
        else:
            raise Exception('route is not unique: {0}'.format(', '.join()))

    def route(self, url, methods=None, wrapper=None):
        def hitch(obj):
            if isinstance(obj, types.FunctionType):
                route_methods = methods or self.default_methods
                endpoint = wrapper(obj) if wrapper else obj
                self.endpoint_lookup[obj] = endpoint
                self.url_map.add(Rule(url, endpoint=endpoint, methods=route_methods))
            else:
                for prop in list(obj.__dict__.keys()):
                    method = getattr(obj, prop)
                    if hasattr(method, '__call__'):
                        def instantiator(req, prop=prop, *args, **kwds):
                            instance = obj()
                            return getattr(instance, prop)(req, *args, **kwds)
                        endpoint = wrapper(instantiator) if wrapper else instantiator
                        self.url_map.add(Rule(url, endpoint=endpoint, methods=[prop]))
                        self.endpoint_lookup[method] = endpoint
            return obj
        return hitch

    def route_json(self, url, methods=None):
        def json_wrapper(fn):
            def go(req, *args, **kwds):
                req.json = json.loads(req.body) if req.body else None
                res = fn(req, *args, **kwds)
                return JSONResponse(json.dumps(res, ensure_ascii=False))
            return go
        return self.route(url, methods, json_wrapper)

    def url_for(self, endpoint, method=None, external=False,
                append_unknown=True, anchor=None, **values):
        if endpoint not in self.url_map._rules_by_endpoint:
            # check for method
            if endpoint in self.endpoint_lookup:
                endpoint = self.endpoint_lookup[endpoint]
            # check for unbound method
            elif hasattr(endpoint, 'im_class'):
                endpoint = endpoint.im_class.__dict__[endpoint.__name__]
        print('building for {0} values {1}'.format(endpoint, values))
        rv = self.url_adapter.build(endpoint, values,
                                    method=method,
                                    force_external=external,
                                    append_unknown=append_unknown)
        if anchor is not None:
            rv += '#' + url_quote(anchor)
        return rv
        
    def dispatch(self, req):
        path = req.path
        method = req.headers.get('METHOD', 'HEAD')
        for key, value in req.headers.items():
            print(key, value)
        print('dispatching {0} {1} ... '.format(path, method))
        if req.body:
            print(req.body)
        endpoint, arguments = self.url_adapter.match(path, method)
        print('found endpoint {0}'.format(endpoint))
        result = endpoint(req, **arguments)
        if not isinstance(result, BaseResponse):
            result = BaseResponse(result)
        return result

    def run(self):
        # setup debugging if needed
        conn = SvanaConnection(self.sender_id, self.pub, self.sub, self.host, self.port)
        if self.debug:
            def app(environ, start_response):
                try:
                    result = self.dispatch(environ['svana.req'])
                except HTTPException as exc:
                    result = exc
                return result(environ, start_response)
            app = DebuggedApplication(app, evalex=True, lodgeit_url=None)
            while True:
                print('waiting for request')
                req = conn.recv()
                if req.is_disconnect():
                    continue
                print('received {0}{1} {2}'.format(req.path,
                                                   req.headers.get('QUERY', None),
                                                   req.headers.get('METHOD', None)))
                try:
                    print('start WSGI')
                    conn.reply_wsgi(req, app)
                    print('end WSGI')
                except HTTPException as e:
                    print('failing debug mode')
                    print('{req.sender} {req.path} {req.conn_id} - {error}\n'.format(req=req, error=e))
                    conn.reply_wsgi(req, e)
        else:
            while True:
                req = conn.recv()
                if req.is_disconnect():
                    continue
                try:
                    res = self.dispatch(req)
                    conn.reply_http(req, res)
                except HTTPException as e:
                    conn.reply_wsgi(req, e)
                except Exception as e:
                    print(e)
                    conn.reply_wsgi(req, InternalServerError())