def get_view_env(self): #prepare local env local_env = {} #process before view call dispatch.call(self, 'prepare_view_env', local_env) local_env['application'] = __global__.application local_env['request'] = local.request local_env['response'] = local.response local_env['settings'] = __global__.settings env = Storage(self.env.to_dict()) env.update(local_env) return env
def _prepare_env(self): env = Storage({}) env['url_for'] = url_for env['redirect'] = redirect env['Redirect'] = Redirect env['error'] = error env['application'] = self env['settings'] = settings env['json'] = json env['jsonp'] = jsonp return env
def wrap_result(self, handler, result, request, response, env): # #process ajax invoke, return a json response # if request.is_xhr and isinstance(result, dict): # result = json(result) if isinstance(result, dict): result = Storage(result) if hasattr(response, 'template'): tmpfile = response.template else: args = handler.func_dict.get('__template__') if not args: args = { 'function': request.function, 'view_class': request.view_class, 'appname': request.appname } if isinstance(args, dict): #TEMPLATE_TEMPLATE should be two elements tuple or list, the first one will be used for view_class is not empty #and the second one will be used for common functions if request.view_class: tmpfile = settings.GLOBAL.TEMPLATE_TEMPLATE[ 0] % args + settings.GLOBAL.TEMPLATE_SUFFIX else: tmpfile = settings.GLOBAL.TEMPLATE_TEMPLATE[ 1] % args + settings.GLOBAL.TEMPLATE_SUFFIX else: tmpfile = args response.template = tmpfile content_type = response.content_type #if debug mode, then display a default_template if self.debug: d = ['default.html', self.default_template] else: d = None response.write( self.template(tmpfile, result, env, default_template=d)) elif isinstance(result, string_types): response.write(result) elif isinstance(result, (Response, BaseResponse)): response = result #add generator support 2014-1-8 elif isinstance(result, types.GeneratorType): return Response(result, direct_passthrough=True, content_type='text/html;charset=utf-8') else: response = Response(str(result), content_type='text/html') return response
def get_env(self, env=None): e = Storage(self.env.copy()) if env: e.update(env) return e
def _open(self, environ, pre_call=None, post_call=None, middlewares=None): if middlewares is None: middlewares = self.middlewares process_request_classes = self.process_request_classes process_response_classes = self.process_response_classes process_exception_classes = self.process_exception_classes else: m = self._sort_middlewares(middlewares) process_request_classes, process_response_classes, process_exception_classes = self._get_middlewares_classes( m) self.lock.acquire() try: local.request = req = Request(environ) local.response = res = Response(content_type='text/html') #add local cached local.local_cache = {} #add in web flag local.in_web = True finally: self.lock.release() url_adapter = get_url_adapter('default') try: rule, values = url_adapter.match(return_rule=True) mod, handler_cls, handler = self.prepare_request(req, rule) #process static if rule.endpoint in static_views: response = self.call_view(mod, handler_cls, handler, req, res, kwargs=values) else: response = None _clses = {} _inss = {} for cls in process_request_classes: ins = cls(self, settings) _inss[cls] = ins response = ins.process_request(req) if response is not None: break if response is None: try: if pre_call: response = pre_call(req) if response is None: try: response = self.call_view(mod, handler_cls, handler, req, res, kwargs=values) except RedirectException as e: response = e.get_response() if post_call: response = post_call(req, response) except Exception as e: for cls in process_exception_classes: ins = _inss.get(cls) if not ins: ins = cls(self, settings) response = ins.process_exception(req, e) if response: break raise for cls in process_response_classes: ins = _inss.get(cls) if not ins: ins = cls(self, settings) response = ins.process_response(req, response) if not isinstance(response, (OriginalResponse, Response)): raise Exception( "Middleware %s should return an Response object, but %r found" % (ins.__class__.__name__, response)) #process post_response call, you can set some async process in here #but the sync may fail, so you should think about the checking mechanism if hasattr(response, 'post_response') and response.post_response: response.post_response() if hasattr(res, 'post_response') and res.post_response: res.post_response() #endif except HTTPError as e: response = self.render(e.errorpage, Storage(e.errors)) except NotFound as e: response = self.not_found(e) except HTTPException as e: response = e except Exception as e: if not self.settings.get_var('GLOBAL/DEBUG'): response = self.internal_error(e) else: # log.exception(e) raise finally: local.local_cache = {} local.in_web = False return response
def parse_multiple_query(self, param): tables = [] condition = true() order_by = [] group_by = [] limit = __default_limit__ total = None page = 0 columns = [] for k, v in param.items(): if isinstance(v, dict): # Schema c = self.parse_param(k, v) tables.append(c.table) columns.extend(c.columns) condition = c.condition & condition if c.relation is not None: condition = c.relation & condition else: if k.startswith('@'): if k == '@limit': limit = v elif k == '@page': page = v elif k == '@order_by': if isinstance(v, (str, unicode)): orders = v.split(',') else: orders = v for c in orders: if '.' in c: v = c.split('.') if len(v) == 3: schema_name, col_name, dir = v else: schema_name, col_name = v dir = 'asc' else: col_name = c dir = 'asc' S = get_schema(schema_name) col = S.get_column(col_name) if dir == 'desc': order_by.append(col.desc()) else: order_by.append(col) elif k == '@group_by': if isinstance(v, (str, unicode)): groups = v.split(',') else: groups = v for c in groups: if '.' in c: schema_name, col_name = c.split('.') S = get_schema(schema_name) col = S.get_column(col_name) group_by.append(col) elif k == '@total': total = v config = Storage({}) config.tables = tables config.condition = condition config.columns = columns config.order_by = order_by config.group_by = group_by config.page = page config.limit = limit config.total = total return config
def parse_param(self, name, param): """ Parse schema parameter, it'll return { condition columns limit order_by group_by total page table name #schema name } :param name: schema name :param param: schema query parameter :return: dict """ S = get_schema(name) # prepare condition condition = true() fields = [] columns = [] columns_param = {} limit = __default_limit__ order_by = [] group_by = [] total = None page = 0 table = S.__table__ relation = None for k, v in param.items(): if k.startswith('@'): if k == '@columns': fields = v[:] elif k == '@limit': limit = v elif k == '@page': page = v elif k == '@order_by': if isinstance(v, (str, unicode)): orders = v.split(',') else: orders = v for c in orders: if '.' in c: col_name, dir = c.split('.') else: col_name = c dir = 'asc' col = S.get_column(col_name) if dir == 'desc': order_by.append(col.desc()) else: order_by.append(col) elif k == '@group_by': if isinstance(v, (str, unicode)): groups = v.split(',') else: groups = v for c in groups: col = S.get_column(c) group_by.append(col) elif k == '@total': total = v elif k == '@relation': relation_key = name, v relation = get_relation_condition(relation_key) elif k.startswith('$'): # condition c = self.parse_condition(S, k[1:], v) if c is not None: condition = c & condition elif isinstance(v, dict): # guest schema # todo nested schema # if there is not one row, it'll using left join otherwise using standalone # query nested_alias, nested_name, nested_need_list = self.parse_entry(k) nested_config = self.parse_param(nested_name, value) if nested_need_list: # insert resolve function pass else: relation = name, nested_config.name outerjoin_condition = get_relation_condition(relation) if outerjoin_condition is None: raise RelationError("Relation between {!r} can not be found".format(relation)) table.outerjoin(nested_config.table, outerjoin_condition) condition = nested_config.condition & condition columns.extend(nested_config.columns) else: # columns if k not in fields: fields.append(k) columns.extend([S.get_column(x) for x in fields or S._fields_list]) # used for select config = Storage({}) config.table = table config.condition = condition config.columns = columns config.columns_param = columns_param config.total = total config.limit = limit config.page = page config.order_by = order_by config.group_by = group_by config.name = name config.schema = S config.relation = relation return config