Ejemplo n.º 1
0
    def test_check_layers(self, cap_mock, web_request, dbsession):
        from c2cgeoportal_commons.models import main

        server = ogc_server()
        dbsession.add(server)

        layer1 = main.LayerWMS(name="layer1", layer="layer1")
        layer1.ogc_server = server
        dbsession.add(layer1)

        layer_missing = main.LayerWMS(name="layer_missing", layer="layer_missing")
        layer_missing.ogc_server = server
        dbsession.add(layer_missing)

        style_missing = main.LayerWMS(name="style_missing", layer="layer1")
        style_missing.ogc_server = server
        style_missing.style = "style_missing"
        dbsession.add(style_missing)

        dbsession.flush()

        layers = dbsession.query(main.LayerWMS).filter(main.LayerWMS.ogc_server == server)
        assert layers.count() == 3

        synchronizer = self.synchronizer(web_request, server)
        synchronizer.check_layers()
        assert synchronizer.report() == (
            "Layer layer_missing does not exists on OGC server\n"
            "Style style_missing does not exists in Layer layer1\n"
            "Checked 3 layers, 2 are invalid\n"
        )
    def do_synchronize(self) -> None:
        self._items_found = 0
        self._themes_added = 0
        self._groups_added = 0
        self._groups_removed = 0
        self._layers_added = 0
        self._layers_removed = 0

        self._default_wms = cast(
            main.LayerWMS, main.LayerWMS.get_default(self._request.dbsession) or main.LayerWMS()
        )
        self._interfaces = self._request.dbsession.query(main.Interface).all()

        capabilities = ElementTree.fromstring(self.wms_capabilities())
        theme_layers = capabilities.findall("Capability/Layer/Layer")
        for theme_layer in theme_layers:
            self.synchronize_layer(theme_layer)

        if self._clean:
            self.check_layers()

        self._logger.info("%s items found", self._items_found)
        self._logger.info("%s themes added", self._themes_added)
        self._logger.info("%s groups added", self._groups_added)
        self._logger.info("%s groups removed", self._groups_removed)
        self._logger.info("%s layers added", self._layers_added)
        self._logger.info("%s layers removed", self._layers_removed)
Ejemplo n.º 3
0
    def test_get_layer_wms_defaut_style_not_exists(self, web_request, dbsession):
        """We should not copy style from default LayerWMS if does not exist in capabilities"""
        from c2cgeoportal_commons.models import main

        synchronizer = self.synchronizer(web_request)

        default_wms = main.LayerWMS()
        default_wms.style = "not_existing_style"
        synchronizer._default_wms = default_wms

        synchronizer._interfaces = []

        el = etree.fromstring(
            """
<Layer>
    <Name>layer1</Name>
    <Style>
        <Name>default</Name>
        <Title>default</Title>
    </Style>
</Layer>
"""
        )

        layer = synchronizer.get_layer_wms(el, None)
        assert layer.style is None
Ejemplo n.º 4
0
    def test_search_alias(self, dbsession, settings, test_data):
        from c2cgeoportal_commons.models import main
        from c2cgeoportal_geoportal.scripts.theme2fts import Import

        alias_layer = main.LayerWMS(name="alias_layer")
        alias_layer.ogc_server = test_data["ogc_server"]
        alias_layer.interfaces = list(test_data["interfaces"].values())
        add_parent(dbsession, alias_layer,
                   test_data["groups"]["first_level_group"])
        alias_layer.metadatas = [
            main.Metadata(name="searchAlias", value="myalias,mykeyword"),
            main.Metadata(name="searchAlias",
                          value="myotheralias,myotherkeyword"),
        ]
        dbsession.add(alias_layer)
        dbsession.flush()

        Import(dbsession, settings, options())

        for lang in settings["available_locale_names"]:
            for interface in test_data["interfaces"].values():
                if interface.name == "api":
                    continue
                expected = [
                    {
                        "label":
                        f"alias_layer_{lang}",
                        "role":
                        None,
                        "interface":
                        interface,
                        "lang":
                        lang,
                        "public":
                        True,
                        "ts": {
                            "fr":
                            "'ali':1 'fr':3 'lai':2 'myali':4 'mykeyword':5 'myotherali':6 'myotherkeyword':7",
                            "en":
                            "'alia':1 'en':3 'layer':2 'myalia':4 'mykeyword':5 'myotheralia':6 'myotherkeyword':7",
                            "de":
                            "'alias':1 'de':3 'lay':2 'myalias':4 'mykeyword':5 'myotheralias':6 'myotherkeyword':7",
                            "it":
                            "'alias':1 'it':3 'layer':2 'myalias':4 'mykeyword':5 'myotheralias':6 'myotherkeyword':7",
                        },
                        "actions": [{
                            "action": "add_layer",
                            "data": "alias_layer"
                        }],
                    },
                ]
                for e in expected:
                    self.assert_fts(dbsession, e)
Ejemplo n.º 5
0
    def __init__(self, request: pyramid.request.Request, ogc_server: main.OGCServer) -> None:
        self._request = request
        self._ogc_server = ogc_server
        self._default_wms = main.LayerWMS()
        self._interfaces = None

        self._logger = logging.Logger(str(self), logging.INFO)
        self._log = StringIO()
        self._log_handler = logging.StreamHandler(self._log)
        self._logger.addHandler(self._log_handler)

        self._items_found = 0
        self._themes_added = 0
        self._groups_added = 0
        self._layers_added = 0
    def __init__(
        self,
        request: pyramid.request.Request,
        ogc_server: main.OGCServer,
        force_parents: bool = False,
        force_ordering: bool = False,
        clean: bool = False,
    ) -> None:
        """
        Initialize the Synchronizer.

        request
            The current pyramid request object. Used to retrieve the SQLAlchemy Session object,
            and to construct the capabilities URL.

        ogc_server
            The considered OGCServer from witch to import the capabilities.

        force_parents
            When set to True, overwrite parents of each node with those from the capabilities.

        force_ordering
            When set to True, sort children of each node in order from the capabilities.

        clean
            When set to True, remove layers which do not exist in capabilities and remove all empty groups.
        """
        self._request = request
        self._ogc_server = ogc_server
        self._force_parents = force_parents
        self._force_ordering = force_ordering
        self._clean = clean

        self._default_wms = main.LayerWMS()
        self._interfaces = None

        self._logger = logging.Logger(str(self), logging.INFO)
        self._log = StringIO()
        self._log_handler = logging.StreamHandler(self._log)
        self._logger.addHandler(self._log_handler)

        self._items_found = 0
        self._themes_added = 0
        self._groups_added = 0
        self._groups_removed = 0
        self._layers_added = 0
        self._layers_removed = 0
Ejemplo n.º 7
0
    def test_get_layer_wms_defaut(self, web_request, dbsession):
        """We should copy properties from default LayerWMS"""
        from c2cgeoportal_commons.models import main

        synchronizer = self.synchronizer(web_request)

        default_wms = main.LayerWMS()
        default_wms.description = "Default description"
        default_wms.metadatas = [main.Metadata(name="isExpanded", value="True")]
        default_wms.exclude_properties = "excluded_property"
        default_wms.interfaces = [main.Interface("interface")]
        default_wms.dimensions = [
            main.Dimension(name="dim", value=None, field="dim", description="description")
        ]
        default_wms.style = "default_style"

        el = etree.fromstring(
            """
<Layer>
    <Name>layer1</Name>
    <Style>
        <Name>default_style</Name>
        <Title>default_style</Title>
    </Style>
</Layer>
"""
        )

        with patch.object(synchronizer, "_default_wms", default_wms):
            layer = synchronizer.get_layer_wms(el, None)

            assert layer.description == "Default description"
            assert len(layer.metadatas) == 1
            assert layer.metadatas[0].name == "isExpanded"
            assert layer.metadatas[0].value == "True"
            assert layer.exclude_properties == "excluded_property"
            assert len(layer.interfaces) == 1
            assert layer.interfaces[0].name == "interface"
            assert len(layer.dimensions) == 1
            assert layer.dimensions[0].name == "dim"
            assert layer.dimensions[0].value is None
            assert layer.dimensions[0].field == "dim"
            assert layer.dimensions[0].description == "description"
            assert layer.style == "default_style"
    def test_extract_layer_wms(self, dbsession, transact):
        from c2cgeoportal_commons.models import main

        del transact

        ogc_server = main.OGCServer(name="mapserver",
                                    url="http://mapserver:8080")
        layer_wms = main.LayerWMS(name="layer_wms")
        layer_wms.ogc_server = ogc_server
        layer_wms.layer = "testpoint_unprotected"
        dbsession.add(layer_wms)
        dbsession.flush()

        messages = self.extract()

        assert {m.msgid
                for m in messages} == {
                    "layer_wms",
                    "testpoint_unprotected",
                    "city",
                    "country",
                    "name",
                }
    def get_layer_wms(self, el: Element, parent: Optional[main.TreeGroup] = None) -> main.LayerWMS:
        name_el = el.find("Name")
        assert name_el is not None
        name = name_el.text

        layer = cast(
            Optional[main.LayerWMS],
            self._request.dbsession.query(main.LayerWMS).filter(main.LayerWMS.name == name).one_or_none(),
        )

        if layer is None:
            layer = main.LayerWMS()

            # TreeItem
            layer.name = name
            layer.description = self._default_wms.description
            layer.metadatas = [main.Metadata(name=m.name, value=m.value) for m in self._default_wms.metadatas]

            # Layer
            layer.public = False
            layer.geo_table = None
            layer.exclude_properties = self._default_wms.exclude_properties
            layer.interfaces = list(self._default_wms.interfaces) or self._interfaces

            # DimensionLayer
            layer.dimensions = [
                main.Dimension(
                    name=d.name,
                    value=d.value,
                    field=d.field,
                    description=d.description,
                )
                for d in self._default_wms.dimensions
            ]

            # LayerWMS
            layer.ogc_server = self._ogc_server
            layer.layer = name
            layer.style = (
                self._default_wms.style
                if el.find(f"./Style/Name[.='{self._default_wms.style}']") is not None
                else None
            )
            # layer.time_mode =
            # layer.time_widget =

            self._request.dbsession.add(layer)
            if not isinstance(parent, main.LayerGroup):
                self._logger.info("Layer %s added as new layer with no parent", name)
            else:
                layer.parents_relation.append(main.LayergroupTreeitem(group=parent))
                self._logger.info("Layer %s added as new layer in group %s", name, parent.name)
            self._layers_added += 1

        else:
            self._items_found += 1
            if layer.ogc_server is not self._ogc_server:
                self._logger.info(
                    "Layer %s: another layer already exists with the same name in OGC server %s",
                    name,
                    self._ogc_server.name,
                )

            parents = [parent] if isinstance(parent, main.LayerGroup) else []
            if self._force_parents and layer.parents != parents:
                layer.parents_relation = [main.LayergroupTreeitem(group=parent) for parent in parents]
                self._logger.info("Layer %s moved to %s", name, parent.name if parent else "root")

        return layer
Ejemplo n.º 10
0
def test_data(dbsession, transact):
    from c2cgeoportal_commons.models import main

    ogc_server = main.OGCServer(name="ogc_server")
    dbsession.add(ogc_server)

    interfaces = {
        i.name: i
        for i in
        [main.Interface(name=name) for name in ["desktop", "mobile", "api"]]
    }
    dbsession.add_all(interfaces.values())

    role = main.Role(name="role")
    dbsession.add(role)

    public_theme = main.Theme(name="public_theme")
    public_theme.interfaces = list(interfaces.values())

    private_theme = main.Theme(name="private_theme")
    private_theme.public = False
    private_theme.interfaces = list(interfaces.values())
    private_theme.restricted_roles = [role]

    themes = {t.name: t for t in [public_theme, private_theme]}
    dbsession.add_all(themes.values())

    first_level_group = main.LayerGroup(name="first_level_group")
    add_parent(dbsession, first_level_group, public_theme)
    add_parent(dbsession, first_level_group, private_theme)

    second_level_group = main.LayerGroup(name="second_level_group")
    add_parent(dbsession, second_level_group, first_level_group)

    groups = {g.name: g for g in [first_level_group, second_level_group]}
    dbsession.add_all(groups.values())

    public_layer = main.LayerWMS(name="public_layer")
    public_layer.ogc_server = ogc_server
    public_layer.interfaces = list(interfaces.values())
    add_parent(dbsession, public_layer, first_level_group)

    private_layer = main.LayerWMS(name="private_layer", public=False)
    private_layer.ogc_server = ogc_server
    private_layer.interfaces = list(interfaces.values())
    add_parent(dbsession, private_layer, second_level_group)

    layers = {layer.name: layer for layer in [public_layer, private_layer]}
    dbsession.add_all(layers.values())

    ra = main.RestrictionArea(name="ra")
    ra.roles = [role]
    ra.layers = [private_layer]
    dbsession.add(ra)

    dbsession.flush()  # Flush here to detect integrity errors now.

    yield {
        "ogc_server": ogc_server,
        "interfaces": interfaces,
        "role": role,
        "themes": themes,
        "groups": groups,
        "layers": layers,
        "restriction_area": ra,
    }