def read_many(self): set_common_headers(self.request, "layers", NO_CACHE) features = [] for layer in self._get_layers_for_request(): for f in self._proto_read(layer).features: f.properties["__layer_id__"] = layer.id features.append(f) return FeatureCollection(features)
def enumerate_attribute_values(self) -> Dict[str, Any]: set_common_headers(self.request, "layers", Cache.PUBLIC) if self.layers_enum_config is None: raise HTTPInternalServerError("Missing configuration") layername = self.request.matchdict["layer_name"] fieldname = self.request.matchdict["field_name"] # TODO check if layer is public or not return cast(Dict[str, Any], self._enumerate_attribute_values(layername, fieldname))
def loginform403(self) -> Dict[str, Any]: if self.request.authenticated_userid: raise HTTPUnauthorized() set_common_headers(self.request, "login", Cache.NO) return { "lang": self.lang, "came_from": self.request.path, "two_fa": self.two_factor_auth }
def locale(request): response = HTTPFound( request.static_url( '{package}_geoportal:static-ngeo/build/{lang}.json'.format( package=request.registry.settings["package"], lang=request.locale_name), _query={ 'cache': get_cache_version(), })) set_common_headers(request, 'api', NO_CACHE, response=response) return response
def enumerate_attribute_values(self): set_common_headers(self.request, "layers", PUBLIC_CACHE) if self.layers_enum_config is None: # pragma: no cover raise HTTPInternalServerError("Missing configuration") layername = self.request.matchdict["layer_name"] fieldname = self.request.matchdict["field_name"] # TODO check if layer is public or not return self._enumerate_attribute_values( layername, fieldname )
def _do(method, headers, credentials=False, settings=SETTINGS): request = DummyRequest({}, method=method, headers=headers) if settings is not None: request.registry.settings = {"headers": {"foo": settings}} else: request.registry.settings = {"headers": {}} set_common_headers(request, "foo", Cache.PRIVATE_NO, credentials=credentials) return dict(request.response.headers)
def create(self): set_common_headers(self.request, "layers", NO_CACHE) if self.request.user is None: raise HTTPForbidden() self.request.response.cache_control.no_cache = True layer = self._get_layer_for_request() def check_geometry(_, feature, obj): del obj # unused geom = feature.geometry if geom and not isinstance(geom, geojson.geometry.Default): shape = asShape(geom) srid = self._get_geom_col_info(layer)[1] spatial_elt = from_shape(shape, srid=srid) allowed = models.DBSession.query(func.count( RestrictionArea.id)) allowed = allowed.join(RestrictionArea.roles) allowed = allowed.join(RestrictionArea.layers) allowed = allowed.filter(RestrictionArea.readwrite.is_(True)) allowed = allowed.filter( Role.id.in_([r.id for r in self.request.user.roles])) allowed = allowed.filter(Layer.id == layer.id) allowed = allowed.filter( or_(RestrictionArea.area.is_(None), RestrictionArea.area.ST_Contains(spatial_elt))) if allowed.scalar() == 0: raise HTTPForbidden() # check if geometry is valid if self._get_validation_setting(layer): self._validate_geometry(spatial_elt) protocol = self._get_protocol_for_layer(layer, before_create=check_geometry) try: features = protocol.create(self.request) for feature in features.features: self._log_last_update(layer, feature) return features except TopologicalError as e: self.request.response.status_int = 400 return {"error_type": "validation_error", "message": str(e)} except exc.IntegrityError as e: log.error(str(e)) self.request.response.status_int = 400 return { "error_type": "integrity_error", "message": str(e.orig.diag.message_primary) }
def get(self) -> HTTPFound: ref = self.request.matchdict["ref"] short_urls = DBSession.query(Shorturl).filter( Shorturl.ref == ref).all() if len(short_urls) != 1: raise HTTPNotFound(f"Ref '{ref!s}' not found") short_urls[0].nb_hits += 1 short_urls[0].last_hit = datetime.now() set_common_headers(self.request, "shortener", Cache.PUBLIC_NO) return HTTPFound(location=short_urls[0].url)
def oauth2loginform(self) -> Dict[str, Any]: set_common_headers(self.request, "login", Cache.PUBLIC) if self.request.user: self._oauth2_login(self.request.user) login_param = {"type": "oauth2"} login_param.update(self.request.params) return { "lang": self.lang, "login_params": login_param, "two_fa": self.two_factor_auth, }
def get(self): ref = self.request.matchdict["ref"] short_urls = DBSession.query(Shorturl).filter( Shorturl.ref == ref).all() if len(short_urls) != 1: raise HTTPNotFound("Ref '{0!s}' not found".format(ref)) short_urls[0].nb_hits += 1 short_urls[0].last_hit = datetime.now() set_common_headers(self.request, "shortener", NO_CACHE) return HTTPFound(location=short_urls[0].url)
def get(self): ref = self.request.matchdict["ref"] short_urls = DBSession.query(Shorturl).filter(Shorturl.ref == ref).all() if len(short_urls) != 1: raise HTTPNotFound("Ref '{0!s}' not found".format(ref)) short_urls[0].nb_hits += 1 short_urls[0].last_hit = datetime.now() set_common_headers( self.request, "shortener", NO_CACHE ) return HTTPFound(location=short_urls[0].url)
def update(self): set_common_headers(self.request, "layers", NO_CACHE) if self.request.user is None: raise HTTPForbidden() self.request.response.cache_control.no_cache = True feature_id = self.request.matchdict.get("feature_id") layer = self._get_layer_for_request() def check_geometry(r, feature, o): # we need both the "original" and "new" geometry to be # within the restriction area geom_attr, srid = self._get_geom_col_info(layer) geom_attr = getattr(o, geom_attr) geom = feature.geometry allowed = models.DBSession.query(func.count(RestrictionArea.id)) allowed = allowed.join(RestrictionArea.roles) allowed = allowed.join(RestrictionArea.layers) allowed = allowed.filter(RestrictionArea.readwrite.is_(True)) allowed = allowed.filter(Role.id == self.request.user.role.id) allowed = allowed.filter(Layer.id == layer.id) allowed = allowed.filter( or_(RestrictionArea.area.is_(None), RestrictionArea.area.ST_Contains(geom_attr))) spatial_elt = None if geom and not isinstance(geom, geojson.geometry.Default): shape = asShape(geom) spatial_elt = from_shape(shape, srid=srid) allowed = allowed.filter( or_(RestrictionArea.area.is_(None), RestrictionArea.area.ST_Contains(spatial_elt))) if allowed.scalar() == 0: raise HTTPForbidden() # check is geometry is valid if self._get_validation_setting(layer): self._validate_geometry(spatial_elt) protocol = self._get_protocol_for_layer(layer, before_update=check_geometry) try: feature = protocol.update(self.request, feature_id) self._log_last_update(layer, feature) return feature except TopologicalError as e: self.request.response.status_int = 400 return {"validation_error": str(e)}
def loginform403(self) -> Union[Dict[str, Any], pyramid.response.Response]: if self.request.authenticated_userid is not None: return HTTPForbidden() set_common_headers(self.request, "login", Cache.PRIVATE_NO) return { "lang": self.lang, "login_params": { "came_from": (f"{self.request.path}?{urllib.parse.urlencode(self.request.GET)}" ) }, "two_fa": self.two_factor_auth, }
def exportgpxkml(request): """ View used to export a GPX or KML document. """ fmt = request.params.get("format") if fmt is None: return HTTPBadRequest("format parameter is required") if fmt not in _CONTENT_TYPES: return HTTPBadRequest("format is not supported") name = request.params.get("name") if name is None: return HTTPBadRequest("name parameter is required") doc = request.params.get("doc") if doc is None: return HTTPBadRequest("doc parameter is required") charset = "utf-8" response = request.response response.body = doc.encode(charset) response.charset = charset response.content_disposition = ("attachment; filename={0!s}.{1!s}".format( name.replace(" ", "_"), fmt)) return set_common_headers(request, "exportgpxkml", NO_CACHE, content_type=_CONTENT_TYPES[fmt])
def exportgpxkml(request): """ View used to export a GPX or KML document. """ fmt = request.params.get("format") if fmt is None: return HTTPBadRequest("format parameter is required") if fmt not in _CONTENT_TYPES: return HTTPBadRequest("format is not supported") name = request.params.get("name") if name is None: return HTTPBadRequest("name parameter is required") doc = request.params.get("doc") if doc is None: return HTTPBadRequest("doc parameter is required") charset = "utf-8" response = request.response response.body = doc.encode(charset) response.charset = charset response.content_disposition = ("attachment; filename={0!s}.{1!s}".format(name.replace(" ", "_"), fmt)) return set_common_headers( request, "exportgpxkml", NO_CACHE, content_type=_CONTENT_TYPES[fmt] )
def exportcsv(request): csv = request.params.get("csv") if csv is None: return HTTPBadRequest("csv parameter is required") request.response.cache_control.no_cache = True csv_extension = request.params.get("csv_extension", DEFAULT_CSV_EXTENSION) csv_encoding = request.params.get("csv_encoding", DEFAULT_CSV_ENCODING) name = request.params.get("name", "export") response = request.response content = b"" if csv_encoding == DEFAULT_CSV_ENCODING: content += codecs.BOM_UTF8 content += csv.encode(csv_encoding) request.response.body = content response.charset = csv_encoding.encode(csv_encoding) response.content_disposition = "attachment; filename={0!s}.{1!s}".format( name.replace(" ", "_"), csv_extension ) return set_common_headers( request, "csvecho", NO_CACHE, content_type="text/csv" )
def csv(self): """answers to /profile.csv""" layers, points = self._compute_points() result = _("distance") + "," + ",".join(layers) + ",x,y" template = ",".join("%s" for l in layers) for point in points: # Handles cases when a layer is undefined, thus when not all raster # have the same geographical coverage for l in layers: if l not in point["values"]: point["values"][l] = -9999 r = template % tuple((str(point["values"][l]) for l in layers)) result += "\n{},{},{:.1f},{:.1f}".format(str(point["dist"]), r, point["x"], point["y"]) return set_common_headers(self.request, "profile", NO_CACHE, response=Response( result, headers={ "Content-Disposition": 'attachment; filename="profile.csv"', }), content_type="text/csv; charset=utf-8", vary=True)
def oauth2token(self) -> pyramid.response.Response: LOG.debug( "Call OAuth create_token_response with:\nurl: %s\nmethod: %s\nbody:\n%s", self.request.current_route_url(_query=self.request.GET), self.request.method, self.request.body, ) headers, body, status = oauth2.get_oauth_client( self.request.registry.settings).create_token_response( self.request.current_route_url(_query=self.request.GET), self.request.method, self.request.body, self.request.headers, {}, ) LOG.debug("OAuth create_token_response return status: %s", status) if hasattr(self.request, "tm"): self.request.tm.commit() # All requests to /token will return a json response, no redirection. if status != 200: if body: raise exception_response(status, detail=body) raise exception_response(status) return set_common_headers( self.request, "login", Cache.PRIVATE_NO, response=Response(body, headers=headers.items()), )
def _oauth2_login(self, user: static.User) -> pyramid.response.Response: self.request.user_ = user LOG.debug( "Call OAuth create_authorization_response with:\nurl: %s\nmethod: %s\nbody:\n%s", self.request.current_route_url(_query=self.request.GET), self.request.method, self.request.body, ) headers, body, status = oauth2.get_oauth_client( self.request.registry.settings).create_authorization_response( self.request.current_route_url(_query=self.request.GET), self.request.method, self.request.body, self.request.headers, ) if hasattr(self.request, "tm"): self.request.tm.commit() LOG.debug( "OAuth create_authorization_response return\nstatus: %s\nbody:\n%s", status, body) if status == 302: raise HTTPFound(location=headers["Location"]) if status != 200: if body: raise exception_response(status, details=body) raise exception_response(status) return set_common_headers( self.request, "login", Cache.PRIVATE_NO, response=Response(body, headers=headers.items()), )
def error_handler(http_exception, request): # pragma: no cover """ View callable for handling all the exceptions that are not already handled. """ LOG.warning("%s returned status code %s", request.url, http_exception.status_code) return caching.set_common_headers(request, "error", caching.NO_CACHE, http_exception)
def error_handler( http_exception: HTTPException, request: pyramid.request.Request) -> pyramid.response.Response: """View callable for handling all the exceptions that are not already handled.""" LOG.warning("%s returned status code %s", request.url, http_exception.status_code) return caching.set_common_headers(request, "error", caching.Cache.PRIVATE_NO, http_exception)
def metadata(self): set_common_headers(self.request, "layers", PRIVATE_CACHE) layer = self._get_layer_for_request() if not layer.public and self.request.user is None: raise HTTPForbidden() # exclude the columns used to record the last features update exclude = [] if layer.exclude_properties is None else layer.exclude_properties.split( ",") last_update_date = self._get_metadata(layer, "lastUpdateDateColumn") if last_update_date is not None: exclude.append(last_update_date) last_update_user = self._get_metadata(layer, "lastUpdateUserColumn") if last_update_user is not None: exclude.append(last_update_user) return get_class(layer.geo_table, exclude_properties=exclude)
def error_handler(http_exception, request): # pragma: no cover """ View callable for handling all the exceptions that are not already handled. """ log.warning("%s returned status code %s", request.url, http_exception.status_code) return caching.set_common_headers( request, "error", caching.NO_CACHE, http_exception, vary=True )
def raster(self): lon = float(self.request.params["lon"]) lat = float(self.request.params["lat"]) if "layers" in self.request.params: rasters = {} layers = self.request.params["layers"].split(",") for layer in layers: if layer in self.rasters: rasters[layer] = self.rasters[layer] else: raise HTTPNotFound("Layer {0!s} not found".format(layer)) else: rasters = self.rasters result = {} for ref in list(rasters.keys()): result[ref] = self._get_raster_value(rasters[ref], lon, lat) set_common_headers(self.request, "raster", NO_CACHE) return result
def loginresetpassword(self) -> Dict[str, Any]: set_common_headers(self.request, "login", Cache.NO) user, username, password, error = self._loginresetpassword() if error is not None: LOG.info(error) raise HTTPUnauthorized("See server logs for details") assert user is not None assert password is not None if user.deactivated: LOG.info("The user '%s' is deactivated", username) raise HTTPUnauthorized("See server logs for details") send_email_config(self.request.registry.settings, "reset_password", user.email, user=username, password=password) return {"success": True}
def raster(self) -> Dict[str, Any]: lon = self._get_required_finite_float_param("lon") lat = self._get_required_finite_float_param("lat") if "layers" in self.request.params: rasters = {} layers = self.request.params["layers"].split(",") for layer in layers: if layer in self.rasters: rasters[layer] = self.rasters[layer] else: raise HTTPNotFound(f"Layer {layer} not found") else: rasters = self.rasters result = {} for ref in list(rasters.keys()): result[ref] = self._get_raster_value(rasters[ref], ref, lon, lat) set_common_headers(self.request, "raster", Cache.PUBLIC_NO) return result
def canvas_view(request: pyramid.request.Request, interface_config: Dict[str, Any]) -> Dict[str, Any]: """Get view used as entry point of a canvas interface.""" js_files = _get_ngeo_resources( f"{interface_config.get('layout', interface_config['name'])}*.js") css_files = _get_ngeo_resources( f"{interface_config.get('layout', interface_config['name'])}*.css") css = "\n ".join([ f'<link href="{request.static_url(css)}" rel="stylesheet" crossorigin="anonymous">' for css in css_files ]) set_common_headers(request, "index", Cache.PUBLIC_NO, content_type="text/html") spinner = "" spinner_filenames = _get_ngeo_resources("spinner*.svg") if spinner_filenames: with open(spinner_filenames[0], encoding="utf-8") as spinner_file: spinner = spinner_file.read() return { "request": request, "header": f""" <meta name="dynamicUrl" content="{request.route_url("dynamic")}"> <meta name="interface" content="{interface_config['name']}"> {css}""", "footer": "\n ".join([ f'<script src="{request.static_url(js)}" crossorigin="anonymous"></script>' for js in js_files ]), "spinner": spinner, }
def _build_response(self, response, content, cache_control, service_name, headers=None, headers_update=None, content_type=None): if isinstance(content, str): content = content.encode("utf-8") if headers_update is None: headers_update = {} headers = response.headers if headers is None else headers # Hop-by-hop Headers are not supported by WSGI # See: # https://www.python.org/dev/peps/pep-3333/#other-http-features # chapter 13.5.1 at https://www.faqs.org/rfcs/rfc2616.html for header in [ "Connection", "Keep-Alive", "Proxy-Authenticate", "Proxy-Authorization", "te", "Trailers", "Transfer-Encoding", "Upgrade", ]: # pragma: no cover if header in headers: del headers[header] # Other problematic headers for header in [ "Content-Length", "Content-Location", "Content-Encoding", ]: # pragma: no cover if header in headers: del headers[header] headers.update(headers_update) response = Response(content, status=response.status_code, headers=headers) return set_common_headers( self.request, service_name, cache_control, response=response, content_type=content_type, )
def read_one(self): from c2cgeoportal_commons.models.main import ( # pylint: disable=import-outside-toplevel Layer, RestrictionArea, Role, ) set_common_headers(self.request, "layers", NO_CACHE) layer = self._get_layer_for_request() protocol = self._get_protocol_for_layer(layer) feature_id = self.request.matchdict.get("feature_id") feature = protocol.read(self.request, id=feature_id) if not isinstance(feature, Feature): return feature if layer.public: return feature if self.request.user is None: raise HTTPForbidden() geom = feature.geometry if not geom or isinstance( geom, geojson.geometry.Default): # pragma: no cover return feature shape = asShape(geom) srid = self._get_geom_col_info(layer)[1] spatial_elt = from_shape(shape, srid=srid) allowed = models.DBSession.query(func.count(RestrictionArea.id)) allowed = allowed.join(RestrictionArea.roles) allowed = allowed.join(RestrictionArea.layers) allowed = allowed.filter(Role.id.in_(get_roles_id(self.request))) allowed = allowed.filter(Layer.id == layer.id) allowed = allowed.filter( or_(RestrictionArea.area.is_(None), RestrictionArea.area.ST_Contains(spatial_elt))) if allowed.scalar() == 0: raise HTTPForbidden() return feature
def logout(self) -> pyramid.response.Response: headers = forget(self.request) if not self.request.user: LOG.info("Logout on non login user.") raise HTTPUnauthorized("See server logs for details") LOG.info("User '%s' (%s) logging out.", self.request.user.username, self.request.user.id) headers.append(("Content-Type", "text/json")) return set_common_headers(self.request, "login", Cache.PRIVATE_NO, response=Response("true", headers=headers))
def _build_response( self, response: pyramid.response.Response, content: str, cache_control: Cache, service_name: str, headers: Dict[str, str] = None, headers_update: Dict[str, str] = None, content_type: str = None, ) -> pyramid.response.Response: if headers_update is None: headers_update = {} headers = response.headers if headers is None else headers # Hop-by-hop Headers are not supported by WSGI # See: # https://www.python.org/dev/peps/pep-3333/#other-http-features # chapter 13.5.1 at https://www.faqs.org/rfcs/rfc2616.html for header in [ "Connection", "Keep-Alive", "Proxy-Authenticate", "Proxy-Authorization", "te", "Trailers", "Transfer-Encoding", "Upgrade", ]: if header in headers: del headers[header] # Other problematic headers for header in [ "Content-Length", "Content-Location", "Content-Encoding" ]: if header in headers: del headers[header] headers.update(headers_update) response = pyramid.response.Response(content, status=response.status_code, headers=headers) return set_common_headers(self.request, service_name, cache_control, response=response, content_type=content_type)
def get(self): """ Get created PDF. """ resp, content = self._proxy("{0!s}{1!s}.printout".format( self.config["print_url"], self.request.matchdict.get("file"))) headers = {} if "content-type" in resp: headers["content-type"] = resp["content-type"] if "content-disposition" in resp: headers["content-disposition"] = resp["content-disposition"] return set_common_headers( self.request, "print", NO_CACHE, response=Response(content, status=resp.status, headers=headers), )
def echo_csv(self): name = self.request.params.get("name") if name is None: return HTTPBadRequest("name parameter is required") csv = self.request.params.get("csv") if csv is None: return HTTPBadRequest("csv parameter is required") charset = "utf-8" response = self.request.response response.body = csv.encode(charset) response.charset = charset response.content_disposition = ("attachment; filename=%s.csv" % (name.replace(" ", "_"))) return set_common_headers( self.request, "exportcsv", NO_CACHE, content_type="application/csv" )
def echo(request): """ Echo an uploaded file back to the client as an text/html document so it can be handled by Ext. The response is JSON-wrapped and base64-encoded to ensure that there are no special HTML characters or charset problems and so that braindead ext does not barf on it. See: http://docs.sencha.com/ext-js/3-4/#!/api/Ext.form.BasicForm-cfg-fileUpload """ try: file_ = request.POST["file"] except KeyError: return HTTPBadRequest() response = Response() response.app_iter = json_base64_encode(file_.filename, file_.file) return set_common_headers( request, "echo", NO_CACHE, response=response, content_type="text/html" )
def csv(self): """answers to /profile.csv""" layers, points = self._compute_points() result = _("distance") + "," + ",".join(layers) + ",x,y" template = ",".join("%s" for l in layers) for point in points: # Handles cases when a layer is undefined, thus when not all raster # have the same geographical coverage for l in layers: if l not in point["values"]: point["values"][l] = -9999 r = template % tuple((str(point["values"][l]) for l in layers)) result += "\n{},{},{:.1f},{:.1f}".format(str(point["dist"]), r, point["x"], point["y"]) return set_common_headers( self.request, "profile", NO_CACHE, response=Response(result, headers={ "Content-Disposition": 'attachment; filename="profile.csv"', }), content_type="text/csv; charset=utf-8", vary=True )
def _build_response( self, resp, content, cache_control, service_name, headers=None, headers_update=None, content_type=None ): if headers_update is None: headers_update = {} headers = dict(resp) if headers is None else headers # Hop-by-hop Headers are not supported by WSGI # See: # https://www.python.org/dev/peps/pep-3333/#other-http-features # chapter 13.5.1 at http://www.faqs.org/rfcs/rfc2616.html for header in [ "connection", "keep-alive", "proxy-authenticate", "proxy-authorization", "te", "trailers", "transfer-encoding", "upgrade" ]: # pragma: no cover if header in headers: del headers[header] # Other problematic headers for header in ["content-length", "content-location"]: # pragma: no cover if header in headers: del headers[header] headers.update(headers_update) response = Response(content, status=resp.status, headers=headers) return set_common_headers( self.request, service_name, cache_control, response=response, content_type=content_type, )
def view(request): # pragma: no cover from c2cgeoportal_geoportal.lib.caching import set_common_headers, NO_CACHE return set_common_headers(request, service, NO_CACHE)
def create(self): if "url" not in self.request.params: raise HTTPBadRequest("The parameter url is required") url = self.request.params["url"] # see: http://httpd.apache.org/docs/2.2/mod/core.html#limitrequestline if len(url) > 8190: # pragma: no cover raise HTTPBadRequest("The parameter url is too long ({} > {})".format(len(url), 8190)) # Check that it is an internal URL... uri_parts = urlparse(url) hostname = uri_parts.hostname if "allowed_hosts" in self.settings: if hostname not in self.settings["allowed_hosts"]: # pragma: no cover raise HTTPBadRequest("The requested host is not allowed.") else: if hostname != self.request.server_name: raise HTTPBadRequest("The requested host '{0!s}' should be '{1!s}'".format( hostname, self.request.server_name )) shortened = False for base in self.short_bases: base_parts = urlparse(base) if uri_parts.path.startswith(base_parts.path): shortened = True ref = uri_parts.path.split("/")[-1] tries = 0 while not shortened: ref = "".join( random.choice(string.ascii_letters + string.digits) for i in range(self.settings.get("length", 4)) ) test_url = DBSession.query(Shorturl).filter(Shorturl.ref == ref).all() if len(test_url) == 0: break tries += 1 # pragma: no cover if tries > 20: # pragma: no cover message = "No free ref found, considere to increase the length" logging.error(message) raise HTTPInternalServerError(message) user_email = self.request.user.email \ if self.request.user is not None else None email = self.request.params.get("email") if not shortened: short_url = Shorturl() short_url.url = url short_url.ref = ref short_url.creator_email = user_email short_url.creation = datetime.now() short_url.nb_hits = 0 DBSession.add(short_url) if "base_url" in self.settings: s_url = self.settings["base_url"] + ref else: s_url = self.request.route_url("shortener_get", ref=ref) email = email or user_email smtp_config = self.request.registry.settings.get("smtp", {}) if \ email is not None and \ "email_from" in self.settings and \ "email_subject" in self.settings and \ "email_body" in self.settings: # pragma: no cover text = self.settings["email_body"] % { "full_url": url, "short_url": s_url, "message": self.request.params.get("message", ""), } send_email( self.settings["email_from"], [email], text.encode("utf-8"), self.settings["email_subject"], smtp_config ) set_common_headers( self.request, "shortener", NO_CACHE ) return {"short_url": s_url}
def __init__(self, request): self.request = request set_common_headers(request, "fulltextsearch", NO_CACHE) self.settings = request.registry.settings.get("fulltextsearch", {}) self.languages = self.settings.get("languages", {})
def json(self): """answers to /profile.json""" _, points = self._compute_points() set_common_headers(self.request, "profile", NO_CACHE) return {"profile": points}
def other_error(exception, request): # pragma: no cover set_common_headers(request, "index", NO_CACHE) return _do_error(request, 500, exception)