Example #1
0
    async def _wfs_get_features_type(
        self, wfs_url: Url, ogc_server_name: str, preload: bool = False
    ) -> Tuple[Optional[etree.Element], Set[str]]:
        errors = set()

        wfs_url.add_query(
            {
                "SERVICE": "WFS",
                "VERSION": "1.0.0",
                "REQUEST": "DescribeFeatureType",
                "ROLE_IDS": "0",
                "USER_ID": "0",
            }
        )

        LOG.debug("WFS DescribeFeatureType for the URL: %s", wfs_url)

        # forward request to target (without Host Header)
        headers = dict(self.request.headers)
        if wfs_url.hostname != "localhost" and "Host" in headers:
            headers.pop("Host")

        headers = restrict_headers(headers, self.headers_whitelist, self.headers_blacklist)

        try:
            content, _ = await asyncio.get_event_loop().run_in_executor(
                None, get_http_cached, self.http_options, wfs_url, headers
            )
        except requests.exceptions.RequestException as exception:
            error = (
                f"Unable to get WFS DescribeFeatureType from the URL '{wfs_url.url()}' for "
                f"OGC server {ogc_server_name}, "
                + (
                    f"return the error: {exception.response.status_code} {exception.response.reason}"
                    if exception.response is not None
                    else f"{exception}"
                )
            )
            errors.add(error)
            LOG.exception(error)
            return None, errors
        except Exception:
            error = (
                f"Unable to get WFS DescribeFeatureType from the URL {wfs_url} for "
                f"OGC server {ogc_server_name}"
            )
            errors.add(error)
            LOG.exception(error)
            return None, errors

        if preload:
            return None, errors

        try:
            return lxml.XML(content), errors
        except Exception as e:
            errors.add(
                f"Error '{e!s}' on reading DescribeFeatureType from URL {wfs_url}:\n{content.decode()}"
            )
            return None, errors
Example #2
0
 def test_url_encode3(self):
     url = Url("http://example.com/toto?%C3%A0=%C3%A9")
     url.add_query({"1": "2"})
     self.assertEqual(url.scheme, "http")
     self.assertEqual(url.netloc, "example.com")
     self.assertEqual(url.path, "/toto")
     self.assertEqual(url.fragment, "")
     self.assertEqual(url.query, {"à": "é", "1": "2"})
Example #3
0
 def test_url_port(self):
     url = Url("http://example.com:8480/toto")
     url.add_query({"1": "2"})
     self.assertEqual(url.scheme, "http")
     self.assertEqual(url.hostname, "example.com")
     self.assertEqual(url.netloc, "example.com:8480")
     self.assertEqual(url.path, "/toto")
     self.assertEqual(url.fragment, "")
     self.assertEqual(url.query, {"1": "2"})
Example #4
0
 def test_url(self):
     url = Url("http://test/")
     url.add_query({"Name": "Bob", "Age": "18", "Nationality": "Việt Nam"})
     self.assertEqual(url.scheme, "http")
     self.assertEqual(url.netloc, "test")
     self.assertEqual(url.path, "/")
     self.assertEqual(url.fragment, "")
     self.assertEqual(url.query, {
         "Name": "Bob",
         "Age": "18",
         "Nationality": "Việt Nam"
     })
Example #5
0
    async def _wms_get_features_type(
            self,
            wfs_url: Url,
            preload: bool = False) -> Tuple[Optional[etree.Element], Set[str]]:
        errors = set()

        wfs_url.add_query({
            "SERVICE": "WFS",
            "VERSION": "1.0.0",
            "REQUEST": "DescribeFeatureType",
            "ROLE_ID": "0",
            "USER_ID": "0",
        })

        LOG.debug("WFS DescribeFeatureType for base URL: %s", wfs_url)

        # forward request to target (without Host Header)
        headers = dict(self.request.headers)
        if wfs_url.hostname != "localhost" and "Host" in headers:
            headers.pop("Host")

        try:
            response = await asyncio.get_event_loop().run_in_executor(
                None, get_http_cached, self.http_options, wfs_url, headers)
        except Exception:
            errors.add("Unable to get DescribeFeatureType from URL {}".format(
                wfs_url))
            return None, errors

        if not response.ok:
            errors.add(
                "DescribeFeatureType from URL {} return the error: {:d} {}".
                format(wfs_url, response.status_code, response.reason))
            return None, errors

        if preload:
            return None, errors

        try:
            return lxml.XML(response.text.encode("utf-8")), errors
        except Exception as e:
            errors.add(
                "Error '{}' on reading DescribeFeatureType from URL {}:\n{}".
                format(str(e), wfs_url, response.text))
            return None, errors
Example #6
0
    def get_report(self) -> pyramid.response.Response:
        self.layername = self.request.matchdict["layername"]
        layer_config = self.config["layers"].get(self.layername)

        multiple = layer_config.get("multiple", False)
        ids = self.request.matchdict["ids"]
        if multiple:
            ids = ids.split(",")

        if layer_config is None:
            raise HTTPBadRequest("Layer not found")

        features_ids = ([self.layername + "." + id_ for id_ in ids]
                        if multiple else [self.layername + "." + ids])

        if layer_config["check_credentials"]:
            # FIXME: support of mapserver groups
            ogc_server = (models.DBSession.query(main.OGCServer).filter(
                main.OGCServer.name == layer_config["ogc_server"]).one())
            ogc_server_ids = [ogc_server]

            private_layers_object = get_private_layers(ogc_server_ids)
            private_layers_names = [
                private_layers_object[oid].name
                for oid in private_layers_object
            ]

            protected_layers_object = get_protected_layers(
                self.request.user, ogc_server_ids)
            protected_layers_names = [
                protected_layers_object[oid].name
                for oid in protected_layers_object
            ]

            if self.layername in private_layers_names and self.layername not in protected_layers_names:
                raise HTTPForbidden

        srs = layer_config["srs"]

        mapserv_url = self.request.route_url(
            "mapserverproxy", _query={"ogcserver": layer_config["ogc_server"]})
        url = Url(mapserv_url)
        url.add_query({
            "service": "WFS",
            "version": "1.1.0",
            "outputformat": "gml3",
            "request": "GetFeature",
            "typeName": self.layername,
            "featureid": ",".join(features_ids),
            "srsName": srs,
        })
        vector_request_url = url.url()

        spec = layer_config["spec"]
        if spec is None:
            spec = {
                "layout": self.layername,
                "outputFormat": "pdf",
                "attributes": {
                    "ids": [{
                        "id": id_
                    } for id_ in ids]
                } if multiple else {
                    "id": id
                },
            }
            map_config = layer_config.get("map")
            if map_config is not None:
                spec["attributes"]["map"] = self._build_map(
                    mapserv_url, vector_request_url, srs, map_config)

            maps_config = layer_config.get("maps")
            if maps_config is not None:
                spec["attributes"]["maps"] = []
                for map_config in maps_config:
                    spec["attributes"]["maps"].append(
                        self._build_map(mapserv_url, vector_request_url, srs,
                                        map_config))
        else:
            datasource = layer_config.get("datasource", True)
            if multiple and datasource:
                data = dumps(layer_config["data"])
                data_list = [
                    loads(
                        data % {
                            "layername": self.layername,
                            "id": id_,
                            "srs": srs,
                            "mapserv_url": mapserv_url,
                            "vector_request_url": vector_request_url,
                        }) for id_ in ids
                ]
                self.walker(spec, "%(datasource)s", data_list)
                spec = loads(
                    dumps(spec) % {
                        "layername": self.layername,
                        "srs": srs,
                        "mapserv_url": mapserv_url,
                        "vector_request_url": vector_request_url,
                    })
            elif multiple:
                spec = loads(
                    dumps(spec) % {
                        "layername": self.layername,
                        "ids": ",".join(ids),
                        "srs": srs,
                        "mapserv_url": mapserv_url,
                        "vector_request_url": vector_request_url,
                    })
            else:
                spec = loads(
                    dumps(spec) % {
                        "layername": self.layername,
                        "id": ids,
                        "srs": srs,
                        "mapserv_url": mapserv_url,
                        "vector_request_url": vector_request_url,
                    })

        return self._do_print(spec)
Example #7
0
 def test_url_noparam(self):
     url = Url("http://example.com/")
     url.add_query({})
     self.assertEqual(url.url(), "http://example.com/")