def test_merge_modes(self):
     from c2cgeoportal_geoportal.lib.wmstparsing import TimeInformation
     ti = TimeInformation()
     self.assertFalse(ti.has_time())
     self.assertTrue(ti.to_dict() is None)
     ti.merge_mode("single")
     self.assertEqual(ti.mode, "single")
     ti.merge_mode("single")
     self.assertEqual(ti.mode, "single")
예제 #2
0
    def _layer(
        self,
        layer: main.Layer,
        time_: TimeInformation = None,
        dim: DimensionInformation = None,
        mixed: bool = True,
    ) -> Tuple[Optional[Dict[str, Any]], Set[str]]:
        errors: Set[str] = set()
        layer_info = {
            "id": layer.id,
            "name": layer.name,
            "metadata": self._get_metadatas(layer, errors)
        }
        if re.search("[/?#]", layer.name):
            errors.add("The layer has an unsupported name '{}'.".format(
                layer.name))
        if isinstance(layer, main.LayerWMS) and re.search(
                "[/?#]", layer.layer):
            errors.add("The layer has an unsupported layers '{}'.".format(
                layer.layer))
        if layer.geo_table:
            errors |= self._fill_editable(layer_info, layer)
        if mixed:
            assert time_ is None
            time_ = TimeInformation()
        assert time_ is not None
        assert dim is not None

        errors |= dim.merge(layer, layer_info, mixed)

        if isinstance(layer, main.LayerWMS):
            wms, wms_errors = self._wms_layers(layer.ogc_server)
            errors |= wms_errors
            if wms is None:
                return None if errors else layer_info, errors
            if layer.layer is None or layer.layer == "":
                errors.add("The layer '{}' do not have any layers".format(
                    layer.name))
                return None, errors
            layer_info["type"] = "WMS"
            layer_info["layers"] = layer.layer
            self._fill_wms(layer_info, layer, errors, mixed=mixed)
            errors |= self._merge_time(time_, layer_info, layer, wms)

        elif isinstance(layer, main.LayerWMTS):
            layer_info["type"] = "WMTS"
            self._fill_wmts(layer_info, layer, errors)

        elif isinstance(layer, main.LayerVectorTiles):
            layer_info["type"] = "VectorTiles"
            self._vectortiles_layers(layer_info, layer)

        return None if errors else layer_info, errors
예제 #3
0
    def test_merge_different_widgets(self):
        from c2cgeoportal_geoportal.lib.wmstparsing import TimeInformation

        ti = TimeInformation()
        ti.merge_widget("single")
        self.assertRaises(ValueError, ti.merge_widget, "datepicker")
예제 #4
0
    def test_merge_different_modes(self):
        from c2cgeoportal_geoportal.lib.wmstparsing import TimeInformation

        ti = TimeInformation()
        ti.merge_mode("single")
        self.assertRaises(ValueError, ti.merge_mode, "range")
예제 #5
0
    async def _group(
        self,
        path: str,
        group: main.LayerGroup,
        layers: List[str],
        depth: int = 1,
        min_levels: int = 1,
        mixed: bool = True,
        time_: Optional[TimeInformation] = None,
        dim: Optional[DimensionInformation] = None,
        wms_layers: Optional[List[str]] = None,
        layers_name: Optional[List[str]] = None,
        **kwargs: Any,
    ) -> Tuple[Optional[Dict[str, Any]], Set[str]]:
        if wms_layers is None:
            wms_layers = []
        if layers_name is None:
            layers_name = []
        children = []
        errors = set()

        if re.search("[/?#]", group.name):
            errors.add(f"The group has an unsupported name '{group.name}'.")

        # escape loop
        if depth > 30:
            errors.add(f"Too many recursions with group '{group.name}'")
            return None, errors

        ogc_servers = None
        org_depth = depth
        if depth == 1:
            ogc_servers = list(self._get_ogc_servers(group, 1))
            # check if mixed content
            mixed = self.is_mixed(ogc_servers)
            if not mixed:
                time_ = TimeInformation()
            dim = DimensionInformation()

        for tree_item in group.children:
            if isinstance(tree_item, main.LayerGroup):
                group_theme, gp_errors = await self._group(
                    f"{path}/{tree_item.name}",
                    tree_item,
                    layers,
                    depth=depth + 1,
                    min_levels=min_levels,
                    mixed=mixed,
                    time_=time_,
                    dim=dim,
                    wms_layers=wms_layers,
                    layers_name=layers_name,
                    **kwargs,
                )
                errors |= gp_errors
                if group_theme is not None:
                    children.append(group_theme)
            elif self._layer_included(tree_item):
                if tree_item.name in layers:
                    layers_name.append(tree_item.name)
                    if isinstance(tree_item, main.LayerWMS):
                        wms_layers.extend(tree_item.layer.split(","))

                    layer_theme, l_errors = await self._layer(tree_item, mixed=mixed, time_=time_, dim=dim)
                    errors |= l_errors
                    if layer_theme is not None:
                        if depth < min_levels:
                            errors.add(
                                f"The Layer '{path + '/' + tree_item.name}' is under indented "
                                f"({depth:d}/{min_levels:d})."
                            )
                        else:
                            children.append(layer_theme)

        if children:
            group_theme = {
                "id": group.id,
                "name": group.name,
                "children": children,
                "metadata": self._get_metadata_list(group, errors),
                "mixed": False,
            }
            if not mixed:
                name: str
                for name, nb in Counter(layers_name).items():
                    if nb > 1:
                        errors.add(
                            f"The GeoMapFish layer name '{name}', cannot be two times "
                            "in the same block (first level group)."
                        )

            group_theme["mixed"] = mixed
            if org_depth == 1:
                if not mixed:
                    assert time_ is not None
                    assert dim is not None
                    group_theme["ogcServer"] = cast(List[Any], ogc_servers)[0]
                    if time_.has_time() and time_.layer is None:
                        group_theme["time"] = time_.to_dict()

                    group_theme["dimensions"] = dim.get_dimensions()

            return group_theme, errors
        return None, errors
예제 #6
0
    def _group(
        self,
        path,
        group,
        layers,
        depth=1,
        min_levels=1,
        mixed=True,
        time_=None,
        dim=None,
        wms_layers=None,
        layers_name=None,
        **kwargs,
    ):
        if wms_layers is None:
            wms_layers = []
        if layers_name is None:
            layers_name = []
        children = []
        errors = set()

        if re.search("[/?#]", group.name):  # pragma: no cover
            errors.add("The group has an unsupported name '{}'.".format(
                group.name))

        # escape loop
        if depth > 30:
            errors.add("Too many recursions with group '{}'".format(
                group.name))
            return None, errors

        ogc_servers = None
        org_depth = depth
        if depth == 1:
            ogc_servers = list(self._get_ogc_servers(group, 1))
            # check if mixed content
            mixed = len(ogc_servers) != 1 or ogc_servers[0] is False
            if not mixed:
                time_ = TimeInformation()
            dim = DimensionInformation()

        for tree_item in group.children:
            if isinstance(tree_item, main.LayerGroup):
                group_theme, gp_errors = self._group(
                    "{}/{}".format(path, tree_item.name),
                    tree_item,
                    layers,
                    depth=depth + 1,
                    min_levels=min_levels,
                    mixed=mixed,
                    time_=time_,
                    dim=dim,
                    wms_layers=wms_layers,
                    layers_name=layers_name,
                    **kwargs,
                )
                errors |= gp_errors
                if group_theme is not None:
                    children.append(group_theme)
            elif self._layer_included(tree_item):
                if tree_item.name in layers:
                    layers_name.append(tree_item.name)
                    if isinstance(tree_item, main.LayerWMS):
                        wms_layers.extend(tree_item.layer.split(","))

                    layer_theme, l_errors = self._layer(tree_item,
                                                        mixed=mixed,
                                                        time_=time_,
                                                        dim=dim,
                                                        **kwargs)
                    errors |= l_errors
                    if layer_theme is not None:
                        if depth < min_levels:
                            errors.add(
                                "The Layer '{}' is under indented ({:d}/{:d})."
                                .format(path + "/" + tree_item.name, depth,
                                        min_levels))
                        else:
                            children.append(layer_theme)

        if children:
            group_theme = {
                "id": group.id,
                "name": group.name,
                "children": children,
                "metadata": self._get_metadatas(group, errors),
                "mixed": False,
            }
            if not mixed:
                for name, nb in list(Counter(layers_name).items()):
                    if nb > 1:
                        errors.add(
                            "The GeoMapFish layer name '{}', cannot be two times "
                            "in the same block (first level group).".format(
                                name))

            group_theme["mixed"] = mixed
            if org_depth == 1:
                if not mixed:
                    group_theme["ogcServer"] = cast(List, ogc_servers)[0]
                    if time_.has_time() and time_.layer is None:
                        group_theme["time"] = time_.to_dict()

                    group_theme["dimensions"] = dim.get_dimensions()

            return group_theme, errors
        return None, errors