示例#1
0
 def test_add_url_params_port(self):
     presult = urlparse(
         add_url_params("http://example.com:8480/toto", {"1": "2"}))
     self.assertEqual(presult.scheme, "http")
     self.assertEqual(presult.netloc, "example.com:8480")
     self.assertEqual(presult.path, "/toto")
     self.assertEqual(presult.params, "")
     self.assertEqual(presult.fragment, "")
     self.assertEqual(parse_qs(presult.query), {"1": ["2"]})
def wms_structure(wms_url, host, request):
    url = urlsplit(wms_url)
    wms_url = add_url_params(wms_url, {
        "SERVICE": "WMS",
        "VERSION": "1.1.1",
        "REQUEST": "GetCapabilities",
    })

    # Forward request to target (without Host Header)
    headers = dict()
    if url.hostname == "localhost" and host is not None:  # pragma: no cover
        headers["Host"] = host
    try:
        response = requests.get(wms_url,
                                headers=headers,
                                **request.registry.settings.get(
                                    "http_options", {}))
    except Exception:  # pragma: no cover
        raise HTTPBadGateway(
            "Unable to GetCapabilities from wms_url {0!s}".format(wms_url))

    if not response.ok:  # pragma: no cover
        raise HTTPBadGateway(
            "GetCapabilities from wms_url {0!s} return the error: {1:d} {2!s}".
            format(wms_url, response.status_code, response.reason))

    try:
        wms = WebMapService(None, xml=response.content)
        result = {}

        def _fill(name, parent):
            if parent is None:
                return
            if parent.name not in result:
                result[parent.name] = []
            result[parent.name].append(name)
            _fill(name, parent.parent)

        for layer in list(wms.contents.values()):
            _fill(layer.name, layer.parent)
        return result

    except AttributeError:  # pragma: no cover
        error = "WARNING! an error occurred while trying to " \
            "read the mapfile and recover the themes."
        error = "{0!s}\nurl: {1!s}\nxml:\n{2!s}".format(
            error, wms_url, response.text)
        log.exception(error)
        raise HTTPBadGateway(error)

    except SyntaxError:  # pragma: no cover
        error = "WARNING! an error occurred while trying to " \
            "read the mapfile and recover the themes."
        error = "{0!s}\nurl: {1!s}\nxml:\n{2!s}".format(
            error, wms_url, response.text)
        log.exception(error)
        raise HTTPBadGateway(error)
示例#3
0
 def test_add_url_params_encode2(self):
     presult = urlparse(
         add_url_params("http://example.com/toto?à=é", {"1": "2"}))
     self.assertEqual(presult.scheme, "http")
     self.assertEqual(presult.netloc, "example.com")
     self.assertEqual(presult.path, "/toto")
     self.assertEqual(presult.params, "")
     self.assertEqual(presult.fragment, "")
     self.assertEqual(parse_qs(presult.query), {"à": ["é"], "1": ["2"]})
def wms_structure(wms_url, host):
    url = urlsplit(wms_url)
    wms_url = add_url_params(wms_url, {
        "SERVICE": "WMS",
        "VERSION": "1.1.1",
        "REQUEST": "GetCapabilities",
    })

    # Forward request to target (without Host Header)
    http = httplib2.Http()
    headers = dict()
    if url.hostname == "localhost" and host is not None:  # pragma: no cover
        headers["Host"] = host
    try:
        resp, content = http.request(wms_url, method="GET", headers=headers)
    except Exception:  # pragma: no cover
        raise HTTPBadGateway("Unable to GetCapabilities from wms_url {0!s}".format(wms_url))

    if resp.status < 200 or resp.status >= 300:  # pragma: no cover
        raise HTTPBadGateway(
            "GetCapabilities from wms_url {0!s} return the error: {1:d} {2!s}".format(
                wms_url, resp.status, resp.reason
            )
        )

    try:
        wms = WebMapService(None, xml=content)
        result = {}

        def _fill(name, parent):
            if parent is None:
                return
            if parent.name not in result:
                result[parent.name] = []
            result[parent.name].append(name)
            _fill(name, parent.parent)

        for layer in list(wms.contents.values()):
            _fill(layer.name, layer.parent)
        return result

    except AttributeError:  # pragma: no cover
        error = "WARNING! an error occurred while trying to " \
            "read the mapfile and recover the themes."
        error = "{0!s}\nurl: {1!s}\nxml:\n{2!s}".format(error, wms_url, content)
        log.exception(error)
        raise HTTPBadGateway(error)

    except SyntaxError:  # pragma: no cover
        error = "WARNING! an error occurred while trying to " \
            "read the mapfile and recover the themes."
        error = "{0!s}\nurl: {1!s}\nxml:\n{2!s}".format(error, wms_url, content)
        log.exception(error)
        raise HTTPBadGateway(error)
示例#5
0
 def test_add_url_params_encode1(self):
     presult = urlparse(add_url_params(
         "http://example.com/toto",
         {"à": "é"}
     ))
     self.assertEqual(presult.scheme, "http")
     self.assertEqual(presult.netloc, "example.com")
     self.assertEqual(presult.path, "/toto")
     self.assertEqual(presult.params, "")
     self.assertEqual(presult.fragment, "")
     self.assertEqual(parse_qs(presult.query), {
         "à": ["é"],
     })
示例#6
0
 def test_add_url_params_port(self):
     presult = urlparse(add_url_params(
         "http://example.com:8480/toto",
         {"1": "2"}
     ))
     self.assertEqual(presult.scheme, "http")
     self.assertEqual(presult.netloc, "example.com:8480")
     self.assertEqual(presult.path, "/toto")
     self.assertEqual(presult.params, "")
     self.assertEqual(presult.fragment, "")
     self.assertEqual(parse_qs(presult.query), {
         "1": ["2"],
     })
示例#7
0
 def _fill_legend_rule_query_string(layer_theme, layer, url):
     if layer.legend_rule and url:
         layer_theme["icon"] = add_url_params(
             url,
             {
                 "SERVICE": "WMS",
                 "VERSION": "1.1.1",
                 "REQUEST": "GetLegendGraphic",
                 "LAYER": layer.name,
                 "FORMAT": "image/png",
                 "TRANSPARENT": "TRUE",
                 "RULE": layer.legend_rule,
             },
         )
示例#8
0
    def test_add_url_params(self):
        from c2cgeoportal_geoportal.lib import add_url_params
        from urllib.parse import urlparse, parse_qs

        params = {"Name": "Bob", "Age": 18, "Nationality": "Việt Nam"}
        result = add_url_params("http://test/", params)
        presult = urlparse(result)
        self.assertEqual(presult.scheme, "http")
        self.assertEqual(presult.netloc, "test")
        self.assertEqual(presult.path, "/")
        self.assertEqual(presult.params, "")
        self.assertEqual(presult.fragment, "")
        self.assertEqual(
            parse_qs(presult.query), {"Name": ["Bob"], "Age": ["18"], "Nationality": ["Việt Nam"]}
        )
示例#9
0
 def test_add_url_params(self):
     from c2cgeoportal_geoportal.lib import add_url_params
     from urllib.parse import urlparse, parse_qs
     params = {"Name": "Bob", "Age": 18, "Nationality": "Việt Nam"}
     result = add_url_params("http://test/", params)
     presult = urlparse(result)
     self.assertEqual(presult.scheme, "http")
     self.assertEqual(presult.netloc, "test")
     self.assertEqual(presult.path, "/")
     self.assertEqual(presult.params, "")
     self.assertEqual(presult.fragment, "")
     self.assertEqual(parse_qs(presult.query), {
         "Name": ["Bob"],
         "Age": ["18"],
         "Nationality": ["Việt Nam"],
     })
示例#10
0
    async def _wms_get_features_type(self, wfs_url, preload=False):
        errors = set()

        params = {
            "SERVICE": "WFS",
            "VERSION": "1.0.0",
            "REQUEST": "DescribeFeatureType",
            "ROLE_ID": "0",
            "USER_ID": "0",
        }
        wfs_url = add_url_params(wfs_url, params)

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

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

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

        if not response.ok:  # pragma: no cover
            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:  # pragma: no cover
            errors.add(
                "Error '{}' on reading DescribeFeatureType from URL {}:\n{}".
                format(str(e), wfs_url, response.text))
            return None, errors
示例#11
0
    def _layer_attributes(self, url, layer):
        errors = set()

        request = _Request()
        request.registry.settings = self.config
        # Static schema will not be supported
        url = get_url2("Layer", url, request, errors)
        if len(errors) > 0:
            print("\n".join(errors))
            return [], []
        url, headers, kwargs = self._build_url(url)

        if url not in self.wmscap_cache:
            print("Get WMS GetCapabilities for URL: {}".format(url))
            self.wmscap_cache[url] = None

            wms_getcap_url = add_url_params(
                url, {
                    "SERVICE": "WMS",
                    "VERSION": "1.1.1",
                    "REQUEST": "GetCapabilities",
                })
            try:
                print("Get WMS GetCapabilities for URL {},\nwith headers: {}".
                      format(wms_getcap_url,
                             " ".join(["=".join(h) for h in headers.items()])))
                response = requests.get(wms_getcap_url,
                                        headers=headers,
                                        **kwargs)

                try:
                    self.wmscap_cache[url] = WebMapService(
                        None, xml=response.content)
                except Exception as e:
                    print(
                        colorize(
                            "ERROR! an error occurred while trying to "
                            "parse the GetCapabilities document.", RED))
                    print(colorize(str(e), RED))
                    print("URL: {}\nxml:\n{}".format(wms_getcap_url,
                                                     response.text))
                    if os.environ.get("IGNORE_I18N_ERRORS", "FALSE") != "TRUE":
                        raise
            except Exception as e:  # pragma: no cover
                print(colorize(str(e), RED))
                print(
                    colorize(
                        "ERROR! Unable to GetCapabilities from URL: {},\nwith headers: {}"
                        .format(
                            wms_getcap_url,
                            " ".join(["=".join(h) for h in headers.items()])),
                        RED,
                    ))
                if os.environ.get("IGNORE_I18N_ERRORS", "FALSE") != "TRUE":
                    raise

        wmscap = self.wmscap_cache[url]

        if url not in self.featuretype_cache:
            print("Get WFS DescribeFeatureType for URL: {}".format(url))
            self.featuretype_cache[url] = None

            wfs_descrfeat_url = add_url_params(
                url, {
                    "SERVICE": "WFS",
                    "VERSION": "1.1.0",
                    "REQUEST": "DescribeFeatureType",
                })
            try:
                response = requests.get(wfs_descrfeat_url,
                                        headers=headers,
                                        **kwargs)
            except Exception as e:  # pragma: no cover
                print(colorize(str(e), RED))
                print(
                    colorize(
                        "ERROR! Unable to DescribeFeatureType from URL: {}".
                        format(wfs_descrfeat_url),
                        RED,
                    ))
                if os.environ.get("IGNORE_I18N_ERRORS", "FALSE") == "TRUE":
                    return [], []
                else:
                    raise

            if not response.ok:  # pragma: no cover
                print(
                    colorize(
                        "ERROR! DescribeFeatureType from URL {} return the error: {:d} {}"
                        .format(wfs_descrfeat_url, response.status_code,
                                response.reason),
                        RED,
                    ))
                if os.environ.get("IGNORE_I18N_ERRORS", "FALSE") == "TRUE":
                    return [], []
                else:
                    raise Exception("Aborted")

            try:
                describe = parseString(response.text)
                featurestype = {}
                self.featuretype_cache[url] = featurestype
                for type_element in describe.getElementsByTagNameNS(
                        "http://www.w3.org/2001/XMLSchema", "complexType"):
                    featurestype[type_element.getAttribute(
                        "name")] = type_element
            except ExpatError as e:
                print(
                    colorize(
                        "ERROR! an error occurred while trying to "
                        "parse the DescribeFeatureType document.", RED))
                print(colorize(str(e), RED))
                print("URL: {}\nxml:\n{}".format(wfs_descrfeat_url,
                                                 response.text))
                if os.environ.get("IGNORE_I18N_ERRORS", "FALSE") == "TRUE":
                    return [], []
                else:
                    raise
            except AttributeError:
                print(
                    colorize(
                        "ERROR! an error occurred while trying to "
                        "read the Mapfile and recover the themes.", RED))
                print("URL: {}\nxml:\n{}".format(wfs_descrfeat_url,
                                                 response.text))
                if os.environ.get("IGNORE_I18N_ERRORS", "FALSE") == "TRUE":
                    return [], []
                else:
                    raise
        else:
            featurestype = self.featuretype_cache[url]

        if featurestype is None:
            return [], []

        layers = [layer]
        if wmscap is not None and layer in list(wmscap.contents):
            layer_obj = wmscap[layer]
            if len(layer_obj.layers) > 0:
                layers = [l.name for l in layer_obj.layers]

        attributes = []
        for sub_layer in layers:
            # Should probably be adapted for other king of servers
            type_element = featurestype.get("{}Type".format(sub_layer))
            if type_element is not None:
                for element in type_element.getElementsByTagNameNS(
                        "http://www.w3.org/2001/XMLSchema", "element"):
                    if not element.getAttribute("type").startswith("gml:"):
                        attributes.append(element.getAttribute("name"))

        return attributes, layers
示例#12
0
 def test_add_url_params_noparam(self):
     self.assertEqual(add_url_params("http://example.com/", {}),
                      "http://example.com/")
示例#13
0
 def test_add_url_params_noparam(self):
     self.assertEqual(add_url_params(
         "http://example.com/", {}
     ), "http://example.com/")
示例#14
0
    def _layer_attributes(self, url, layer):
        errors = set()

        class Registry:
            setting = None

        class Request:
            registry = Registry()

        request = Request()
        request.registry.settings = self.config
        # static schema will not be supported
        url = get_url2("Layer", url, request, errors)
        if len(errors) > 0:
            print("\n".join(errors))
            return []

        wms_getcap_url = add_url_params(url, {
            "SERVICE": "WMS",
            "VERSION": "1.1.1",
            "REQUEST": "GetCapabilities",
        })

        hostname = urlsplit(url).hostname
        if url not in self.wmscap_cache:
            print("Get WMS GetCapabilities for URL: {}".format(url))
            self.wmscap_cache[url] = None

            # forward request to target (without Host Header)
            http = httplib2.Http()
            h = {}
            if hostname == "localhost":  # pragma: no cover
                h["Host"] = self.package["host"]
            try:
                resp, content = http.request(wms_getcap_url,
                                             method="GET",
                                             headers=h)

                try:
                    self.wmscap_cache[url] = WebMapService(None, xml=content)
                except Exception as e:
                    print(
                        colorize(
                            "ERROR! an error occurred while trying to "
                            "parse the GetCapabilities document.", RED))
                    print(colorize(str(e), RED))
                    print("URL: {}\nxml:\n{}".format(wms_getcap_url, content))
                    if os.environ.get("IGNORE_I18N_ERRORS", "FALSE") != "TRUE":
                        raise
            except Exception as e:  # pragma: no cover
                print(colorize(str(e), RED))
                print(
                    colorize(
                        "ERROR! Unable to GetCapabilities from URL: {}".format(
                            wms_getcap_url),
                        RED,
                    ))
                if os.environ.get("IGNORE_I18N_ERRORS", "FALSE") != "TRUE":
                    raise

        wmscap = self.wmscap_cache[url]

        wfs_descrfeat_url = add_url_params(
            url, {
                "SERVICE": "WFS",
                "VERSION": "1.1.0",
                "REQUEST": "DescribeFeatureType",
            })

        if url not in self.featuretype_cache:
            print("Get WFS DescribeFeatureType for URL: {}".format(
                wfs_descrfeat_url))
            self.featuretype_cache[url] = None

            # forward request to target (without Host Header)
            http = httplib2.Http()
            h = {}
            if hostname == "localhost":  # pragma: no cover
                h["Host"] = self.package["host"]
            try:
                resp, content = http.request(wfs_descrfeat_url,
                                             method="GET",
                                             headers=h)
            except Exception as e:  # pragma: no cover
                print(colorize(str(e), RED))
                print(
                    colorize(
                        "ERROR! Unable to DescribeFeatureType from URL: {}".
                        format(wfs_descrfeat_url),
                        RED,
                    ))
                if os.environ.get("IGNORE_I18N_ERRORS", "FALSE") == "TRUE":
                    return []
                else:
                    raise

            if resp.status < 200 or resp.status >= 300:  # pragma: no cover
                print(
                    colorize(
                        "ERROR! DescribeFeatureType from URL {} return the error: {1:d} {}"
                        .format(wfs_descrfeat_url, resp.status, resp.reason),
                        RED,
                    ))
                if os.environ.get("IGNORE_I18N_ERRORS", "FALSE") == "TRUE":
                    return []
                else:
                    raise Exception("Aborted")

            try:
                describe = parseString(content)
                featurestype = {}
                self.featuretype_cache[url] = featurestype
                for type_element in describe.getElementsByTagNameNS(
                        "http://www.w3.org/2001/XMLSchema", "complexType"):
                    featurestype[type_element.getAttribute(
                        "name")] = type_element
            except ExpatError as e:
                print(
                    colorize(
                        "ERROR! an error occurred while trying to "
                        "parse the DescribeFeatureType document.", RED))
                print(colorize(str(e), RED))
                print("URL: {}\nxml:\n{}".format(wfs_descrfeat_url, content))
                if os.environ.get("IGNORE_I18N_ERRORS", "FALSE") == "TRUE":
                    return []
                else:
                    raise
            except AttributeError:
                print(
                    colorize(
                        "ERROR! an error occurred while trying to "
                        "read the Mapfile and recover the themes.", RED))
                print("URL: {}\nxml:\n{}".format(wfs_descrfeat_url, content))
                if os.environ.get("IGNORE_I18N_ERRORS", "FALSE") == "TRUE":
                    return []
                else:
                    raise
        else:
            featurestype = self.featuretype_cache[url]

        if featurestype is None:
            return []

        layers = [layer]
        if wmscap is not None and layer in list(wmscap.contents):
            layer_obj = wmscap[layer]
            if len(layer_obj.layers) > 0:
                layers = [l.name for l in layer_obj.layers]

        attributes = []
        for sub_layer in layers:
            # Should probably be adapted for other king of servers
            type_element = featurestype.get("{}Type".format(sub_layer))
            if type_element is not None:
                for element in type_element.getElementsByTagNameNS(
                        "http://www.w3.org/2001/XMLSchema", "element"):
                    if not element.getAttribute("type").startswith("gml:"):
                        attributes.append(element.getAttribute("name"))

        return attributes
示例#15
0
    def get_report(self):
        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"]:
            # check user credentials
            role_id = None if self.request.user is None else self.request.user.role.id

            # FIXME: support of mapserver groups
            ogc_server_ids = [self.default_ogc_server.id]

            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(role_id, 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")
        vector_request_url = add_url_params(
            mapserv_url,
            {
                "service": "WFS",
                "version": "1.1.0",
                "outputformat": "gml3",
                "request": "GetFeature",
                "typeName": self.layername,
                "featureid": ",".join(features_ids),
                "srsName": "epsg:{}".format(srs)
            }
        )

        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"])
                datas = [
                    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", datas)
                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)
示例#16
0
    def _layer_attributes(self, url, layer):
        errors = set()

        request = _Request()
        request.registry.settings = self.config
        # static schema will not be supported
        url = get_url2("Layer", url, request, errors)
        if len(errors) > 0:
            print("\n".join(errors))
            return []

        wms_getcap_url = add_url_params(url, {
            "SERVICE": "WMS",
            "VERSION": "1.1.1",
            "REQUEST": "GetCapabilities",
        })

        hostname = urlsplit(url).hostname
        if url not in self.wmscap_cache:
            print("Get WMS GetCapabilities for URL: {}".format(url))
            self.wmscap_cache[url] = None

            # forward request to target (without Host Header)
            http = httplib2.Http()
            h = {}
            if hostname == "localhost":  # pragma: no cover
                h["Host"] = self.package["host"]
            try:
                resp, content = http.request(wms_getcap_url, method="GET", headers=h)

                try:
                    self.wmscap_cache[url] = WebMapService(None, xml=content)
                except Exception as e:
                    print(colorize(
                        "ERROR! an error occurred while trying to "
                        "parse the GetCapabilities document.",
                        RED))
                    print(colorize(str(e), RED))
                    print("URL: {}\nxml:\n{}".format(wms_getcap_url, content))
                    if os.environ.get("IGNORE_I18N_ERRORS", "FALSE") != "TRUE":
                        raise
            except Exception as e:  # pragma: no cover
                print(colorize(str(e), RED))
                print(colorize(
                    "ERROR! Unable to GetCapabilities from URL: {}".format(wms_getcap_url),
                    RED,
                ))
                if os.environ.get("IGNORE_I18N_ERRORS", "FALSE") != "TRUE":
                    raise

        wmscap = self.wmscap_cache[url]

        wfs_descrfeat_url = add_url_params(url, {
            "SERVICE": "WFS",
            "VERSION": "1.1.0",
            "REQUEST": "DescribeFeatureType",
        })

        if url not in self.featuretype_cache:
            print("Get WFS DescribeFeatureType for URL: {}".format(wfs_descrfeat_url))
            self.featuretype_cache[url] = None

            # forward request to target (without Host Header)
            http = httplib2.Http()
            h = {}
            if hostname == "localhost":  # pragma: no cover
                h["Host"] = self.package["host"]
            try:
                resp, content = http.request(wfs_descrfeat_url, method="GET", headers=h)
            except Exception as e:  # pragma: no cover
                print(colorize(str(e), RED))
                print(colorize(
                    "ERROR! Unable to DescribeFeatureType from URL: {}".format(wfs_descrfeat_url),
                    RED,
                ))
                if os.environ.get("IGNORE_I18N_ERRORS", "FALSE") == "TRUE":
                    return []
                else:
                    raise

            if resp.status < 200 or resp.status >= 300:  # pragma: no cover
                print(colorize(
                    "ERROR! DescribeFeatureType from URL {} return the error: {1:d} {}".format(
                        wfs_descrfeat_url, resp.status, resp.reason
                    ),
                    RED,
                ))
                if os.environ.get("IGNORE_I18N_ERRORS", "FALSE") == "TRUE":
                    return []
                else:
                    raise Exception("Aborted")

            try:
                describe = parseString(content)
                featurestype = {}
                self.featuretype_cache[url] = featurestype
                for type_element in describe.getElementsByTagNameNS(
                    "http://www.w3.org/2001/XMLSchema", "complexType"
                ):
                    featurestype[type_element.getAttribute("name")] = type_element
            except ExpatError as e:
                print(colorize(
                    "ERROR! an error occurred while trying to "
                    "parse the DescribeFeatureType document.",
                    RED
                ))
                print(colorize(str(e), RED))
                print("URL: {}\nxml:\n{}".format(wfs_descrfeat_url, content))
                if os.environ.get("IGNORE_I18N_ERRORS", "FALSE") == "TRUE":
                    return []
                else:
                    raise
            except AttributeError:
                print(colorize(
                    "ERROR! an error occurred while trying to "
                    "read the Mapfile and recover the themes.",
                    RED
                ))
                print("URL: {}\nxml:\n{}".format(wfs_descrfeat_url, content))
                if os.environ.get("IGNORE_I18N_ERRORS", "FALSE") == "TRUE":
                    return []
                else:
                    raise
        else:
            featurestype = self.featuretype_cache[url]

        if featurestype is None:
            return []

        layers = [layer]
        if wmscap is not None and layer in list(wmscap.contents):
            layer_obj = wmscap[layer]
            if len(layer_obj.layers) > 0:
                layers = [l.name for l in layer_obj.layers]

        attributes = []
        for sub_layer in layers:
            # Should probably be adapted for other king of servers
            type_element = featurestype.get("{}Type".format(sub_layer))
            if type_element is not None:
                for element in type_element.getElementsByTagNameNS(
                    "http://www.w3.org/2001/XMLSchema", "element"
                ):
                    if not element.getAttribute("type").startswith("gml:"):
                        attributes.append(element.getAttribute("name"))

        return attributes, layers
示例#17
0
    async def _wms_getcap_cached(self, ogc_server, _):
        """ _ is just for cache on the role id """

        errors: Set[str] = set()
        url = get_url2("The OGC server '{}'".format(ogc_server.name),
                       ogc_server.url, self.request, errors)
        if errors or url is None:  # pragma: no cover
            return url, None, errors

        # Add functionality params
        sparams = get_mapserver_substitution_params(self.request)
        url = add_url_params(url, sparams)

        url = add_url_params(
            url,
            {
                "SERVICE": "WMS",
                "VERSION": "1.1.1",
                "REQUEST": "GetCapabilities",
                "ROLE_ID": "0",
                "USER_ID": "0",
            },
        )

        LOG.debug("Get WMS GetCapabilities for url: %s", url)

        # Forward request to target (without Host Header)
        headers = dict(self.request.headers)

        # Add headers for Geoserver
        if ogc_server.auth == main.OGCSERVER_AUTH_GEOSERVER:
            headers["sec-username"] = "******"
            headers["sec-roles"] = "root"

        if urllib.parse.urlsplit(
                url
        ).hostname != "localhost" and "Host" in headers:  # pragma: no cover
            headers.pop("Host")

        try:
            response = await asyncio.get_event_loop().run_in_executor(
                None, get_http_cached, self.http_options, url, headers)
        except Exception:  # pragma: no cover
            error = "Unable to GetCapabilities from URL {}".format(url)
            errors.add(error)
            LOG.error(error, exc_info=True)
            return url, None, errors

        if not response.ok:  # pragma: no cover
            error = "GetCapabilities from URL {} return the error: {:d} {}".format(
                url, response.status_code, response.reason)
            errors.add(error)
            LOG.error(error)
            return url, None, errors

        # With wms 1.3 it returns text/xml also in case of error :-(
        if response.headers.get("Content-Type",
                                "").split(";")[0].strip() not in [
                                    "application/vnd.ogc.wms_xml",
                                    "text/xml",
                                ]:
            error = "GetCapabilities from URL {} returns a wrong Content-Type: {}\n{}".format(
                url, response.headers.get("Content-Type", ""), response.text)
            errors.add(error)
            LOG.error(error)
            return url, None, errors

        return url, response.content, errors
示例#18
0
    def get_report(self):
        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"]:
            # check user credentials
            role_id = None if self.request.user is None else self.request.user.role.id

            # FIXME: support of mapserver groups
            ogc_server_ids = [self.default_ogc_server.id]

            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(
                role_id, 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")
        vector_request_url = add_url_params(
            mapserv_url, {
                "service": "WFS",
                "version": "1.1.0",
                "outputformat": "gml3",
                "request": "GetFeature",
                "typeName": self.layername,
                "featureid": ",".join(features_ids),
                "srsName": "epsg:{}".format(srs)
            })

        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"])
                datas = [
                    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", datas)
                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)