def test_lang_is_available(self): from c2cgeoportal import locale_negotiator from pyramid.threadlocal import get_current_registry from pyramid.request import Request request = Request.blank("/") request.registry = get_current_registry() request.registry.settings = { "default_locale_name": "de", "available_locale_names": ["de", "es"] } request.accept_language = "en-us,en;q=0.3,es;q=0.7" lang = locale_negotiator(request) self.assertEquals(lang, "es")
def test_lang_is_available(self): from c2cgeoportal import locale_negotiator from pyramid.threadlocal import get_current_registry from pyramid.request import Request request = Request.blank('/') request.registry = get_current_registry() request.registry.settings = { 'default_locale_name': 'de', 'available_locale_names': ['de', 'es'] } request.accept_language = 'en-us,en;q=0.3,es;q=0.7' lang = locale_negotiator(request) self.assertEquals(lang, 'es')
def fulltextsearch(self): lang = locale_negotiator(self.request) try: language = self.languages[lang] except KeyError: return HTTPInternalServerError( detail="%s not defined in languages" % lang) if "query" not in self.request.params: return HTTPBadRequest(detail="no query") query = self.request.params.get("query") maxlimit = self.settings.get("maxlimit", 200) try: limit = int(self.request.params.get( "limit", self.settings.get("defaultlimit", 30))) except ValueError: return HTTPBadRequest(detail="limit value is incorrect") if limit > maxlimit: limit = maxlimit try: partitionlimit = int(self.request.params.get("partitionlimit", 0)) except ValueError: return HTTPBadRequest(detail="partitionlimit value is incorrect") if partitionlimit > maxlimit: partitionlimit = maxlimit terms = "&".join(re.sub("'", "''", w) + ":*" for w in query.split(" ") if w != "") _filter = expression.text( "%(tsvector)s @@ to_tsquery('%(lang)s', '%(terms)s')" % { "tsvector": "ts", "lang": language, "terms": terms } ) if self.request.user is None or self.request.user.role is None: _filter = and_(_filter, FullTextSearch.public.is_(True)) else: _filter = and_( _filter, or_( FullTextSearch.public.is_(True), FullTextSearch.role_id.is_(None), FullTextSearch.role_id == self.request.user.role.id ) ) if "interface" in self.request.params: _filter = and_(_filter, or_( FullTextSearch.interface_id.is_(None), FullTextSearch.interface_id == self._get_interface_id( self.request.params["interface"] ) )) else: _filter = and_(_filter, FullTextSearch.interface_id.is_(None)) _filter = and_(_filter, or_( FullTextSearch.lang.is_(None), FullTextSearch.lang == lang, )) # The numbers used in ts_rank_cd() below indicate a normalization method. # Several normalization methods can be combined using |. # 2 divides the rank by the document length # 8 divides the rank by the number of unique words in document # By combining them, shorter results seem to be preferred over longer ones # with the same ratio of matching words. But this relies only on testing it # and on some assumptions about how it might be calculated # (the normalization is applied two times with the combination of 2 and 8, # so the effect on at least the one-word-results is therefore stronger). rank = expression.text( "ts_rank_cd(%(tsvector)s, to_tsquery('%(lang)s', '%(terms)s'), 2|8)" % { "tsvector": "ts", "lang": language, "terms": terms } ) if partitionlimit: # Here we want to partition the search results based on # layer_name and limit each partition. row_number = func.row_number().over( partition_by=FullTextSearch.layer_name, order_by=(desc(rank), FullTextSearch.label) ).label("row_number") subq = DBSession.query(FullTextSearch) \ .add_columns(row_number).filter(_filter).subquery() query = DBSession.query( subq.c.id, subq.c.label, subq.c.params, subq.c.layer_name, subq.c.the_geom, subq.c.actions ) query = query.filter(subq.c.row_number <= partitionlimit) else: query = DBSession.query(FullTextSearch).filter(_filter) query = query.order_by(desc(rank)) query = query.order_by(FullTextSearch.label) query = query.limit(limit) objs = query.all() features = [] for o in objs: properties = { "label": o.label, } if o.layer_name is not None: properties["layer_name"] = o.layer_name if o.params is not None: properties["params"] = o.params if o.actions is not None: properties["actions"] = o.actions if o.actions is None and o.layer_name is not None: properties["actions"] = [{ "action": "add_layer", "data": o.layer_name, }] if o.the_geom is not None: geom = to_shape(o.the_geom) feature = Feature( id=o.id, geometry=geom, properties=properties, bbox=geom.bounds ) features.append(feature) else: feature = Feature( id=o.id, properties=properties ) features.append(feature) # TODO: add callback function if provided in self.request, else return geojson return FeatureCollection(features)
def test_lang_param(self): from c2cgeoportal import locale_negotiator request = testing.DummyRequest(params=dict(lang="fr")) lang = locale_negotiator(request) self.assertEquals(lang, "fr")
def test_lang_param(self): from c2cgeoportal import locale_negotiator request = testing.DummyRequest(params=dict(lang='fr')) lang = locale_negotiator(request) self.assertEquals(lang, 'fr')