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')
예제 #3
0
    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')
예제 #4
0
    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")
예제 #6
0
    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')