diff --git a/admin/c2cgeoportal_admin/__init__.py b/admin/c2cgeoportal_admin/__init__.py index 4d4227d3880..6913ce8e753 100644 --- a/admin/c2cgeoportal_admin/__init__.py +++ b/admin/c2cgeoportal_admin/__init__.py @@ -93,7 +93,9 @@ def get_tm_session( ) # Add fake user as we do not have authentication from geoportal - from c2cgeoportal_commons.models.static import User # pylint: disable=import-outside-toplevel + from c2cgeoportal_commons.models.static import ( + User, # pylint: disable=import-outside-toplevel + ) config.add_request_method( lambda request: User( diff --git a/admin/c2cgeoportal_admin/lib/ogcserver_synchronizer.py b/admin/c2cgeoportal_admin/lib/ogcserver_synchronizer.py index 64905a6f478..ddd47e7d7a8 100644 --- a/admin/c2cgeoportal_admin/lib/ogcserver_synchronizer.py +++ b/admin/c2cgeoportal_admin/lib/ogcserver_synchronizer.py @@ -29,16 +29,15 @@ import functools import logging from io import StringIO -from typing import Any, Optional, cast +from typing import Any, cast from xml.etree.ElementTree import Element # nosec import pyramid.request import requests -from defusedxml import ElementTree -from sqlalchemy.orm.session import Session - from c2cgeoportal_commons.lib.url import get_url2 from c2cgeoportal_commons.models import main +from defusedxml import ElementTree +from sqlalchemy.orm.session import Session class dry_run_transaction: # noqa ignore=N801: class names should use CapWords convention @@ -238,7 +237,7 @@ def get_theme(self, el: ElementTree) -> main.Theme: name = name_el.text theme = cast( - Optional[main.Theme], + main.Theme | None, self._request.dbsession.query(main.Theme).filter(main.Theme.name == name).one_or_none(), ) @@ -263,7 +262,7 @@ def get_layer_group(self, el: Element, parent: main.TreeGroup) -> main.LayerGrou assert name is not None group = cast( - Optional[main.LayerGroup], + main.LayerGroup | None, ( self._request.dbsession.query(main.LayerGroup) .filter(main.LayerGroup.name == name) @@ -294,7 +293,7 @@ def get_layer_wms(self, el: Element, parent: main.TreeGroup | None = None) -> ma assert name is not None layer = cast( - Optional[main.LayerWMS], + main.LayerWMS | None, self._request.dbsession.query(main.LayerWMS).filter(main.LayerWMS.name == name).one_or_none(), ) diff --git a/admin/c2cgeoportal_admin/schemas/dimensions.py b/admin/c2cgeoportal_admin/schemas/dimensions.py index 3326057d167..4a9fb0c27e0 100644 --- a/admin/c2cgeoportal_admin/schemas/dimensions.py +++ b/admin/c2cgeoportal_admin/schemas/dimensions.py @@ -30,11 +30,10 @@ import colander from c2cgeoform.schema import GeoFormSchemaNode +from c2cgeoportal_commons.models.main import Dimension from deform.widget import MappingWidget, SequenceWidget from sqlalchemy.orm.attributes import InstrumentedAttribute -from c2cgeoportal_commons.models.main import Dimension - def dimensions_schema_node( prop: InstrumentedAttribute[Any], # pylint: disable=unsubscriptable-object diff --git a/admin/c2cgeoportal_admin/schemas/functionalities.py b/admin/c2cgeoportal_admin/schemas/functionalities.py index 327aa56b56a..a05d5440328 100644 --- a/admin/c2cgeoportal_admin/schemas/functionalities.py +++ b/admin/c2cgeoportal_admin/schemas/functionalities.py @@ -31,12 +31,11 @@ import colander from c2cgeoform.ext.deform_ext import RelationCheckBoxListWidget from c2cgeoform.schema import GeoFormManyToManySchemaNode, manytomany_validator +from c2cgeoportal_commons.models.main import Functionality from sqlalchemy import inspect, select from sqlalchemy.orm.attributes import InstrumentedAttribute from sqlalchemy.sql.functions import concat -from c2cgeoportal_commons.models.main import Functionality - def available_functionalities_for(settings: dict[str, Any], model: type[Any]) -> list[dict[str, Any]]: """Return filtered list of functionality definitions.""" @@ -81,7 +80,6 @@ def functionalities_schema_node( prop: InstrumentedAttribute[Any], model: type[Any] ) -> colander.SequenceSchema: """Get the schema of the functionalities.""" - return colander.SequenceSchema( GeoFormManyToManySchemaNode(Functionality, None), name=prop.key, diff --git a/admin/c2cgeoportal_admin/schemas/interfaces.py b/admin/c2cgeoportal_admin/schemas/interfaces.py index 212aefc3c13..2bf697e42ab 100644 --- a/admin/c2cgeoportal_admin/schemas/interfaces.py +++ b/admin/c2cgeoportal_admin/schemas/interfaces.py @@ -31,9 +31,8 @@ import colander from c2cgeoform.ext.deform_ext import RelationCheckBoxListWidget from c2cgeoform.schema import GeoFormManyToManySchemaNode, manytomany_validator -from sqlalchemy.orm.attributes import InstrumentedAttribute - from c2cgeoportal_commons.models.main import Interface +from sqlalchemy.orm.attributes import InstrumentedAttribute def interfaces_schema_node( diff --git a/admin/c2cgeoportal_admin/schemas/metadata.py b/admin/c2cgeoportal_admin/schemas/metadata.py index 4fa216ff611..cb0c7383923 100644 --- a/admin/c2cgeoportal_admin/schemas/metadata.py +++ b/admin/c2cgeoportal_admin/schemas/metadata.py @@ -31,14 +31,14 @@ import colander import pyramid.request from c2cgeoform.schema import GeoFormSchemaNode +from c2cgeoportal_commons.lib.validators import url +from c2cgeoportal_commons.models.main import Metadata from deform.widget import MappingWidget, SelectWidget, SequenceWidget, TextAreaWidget from sqlalchemy import inspect from sqlalchemy.orm.attributes import InstrumentedAttribute from sqlalchemy.orm.mapper import Mapper from c2cgeoportal_admin import _ -from c2cgeoportal_commons.lib.validators import url -from c2cgeoportal_commons.models.main import Metadata def get_relevant_for(model: type[Any] | Mapper[Any]) -> set[str]: @@ -202,7 +202,6 @@ def _translate_available_metadata( def metadata_schema_node(prop: InstrumentedAttribute[Any], model: type[Any]) -> colander.SequenceSchema: """Get the schema of a collection of metadata.""" - # Deferred which returns a dictionary with metadata name as key and metadata definition as value. # Needed to get the metadata types on UI side. metadata_definitions_dict = colander.deferred( diff --git a/admin/c2cgeoportal_admin/schemas/restriction_areas.py b/admin/c2cgeoportal_admin/schemas/restriction_areas.py index d13e70b3de6..cd22bd6ea24 100644 --- a/admin/c2cgeoportal_admin/schemas/restriction_areas.py +++ b/admin/c2cgeoportal_admin/schemas/restriction_areas.py @@ -31,9 +31,8 @@ import colander from c2cgeoform.ext.deform_ext import RelationCheckBoxListWidget from c2cgeoform.schema import GeoFormManyToManySchemaNode, manytomany_validator -from sqlalchemy.orm.attributes import InstrumentedAttribute - from c2cgeoportal_commons.models.main import RestrictionArea +from sqlalchemy.orm.attributes import InstrumentedAttribute def restrictionareas_schema_node( diff --git a/admin/c2cgeoportal_admin/schemas/roles.py b/admin/c2cgeoportal_admin/schemas/roles.py index 308a322b43d..8ec1357ee3e 100644 --- a/admin/c2cgeoportal_admin/schemas/roles.py +++ b/admin/c2cgeoportal_admin/schemas/roles.py @@ -31,9 +31,8 @@ import colander from c2cgeoform.ext.deform_ext import RelationCheckBoxListWidget from c2cgeoform.schema import GeoFormManyToManySchemaNode, manytomany_validator -from sqlalchemy.orm.attributes import InstrumentedAttribute - from c2cgeoportal_commons.models.main import Role +from sqlalchemy.orm.attributes import InstrumentedAttribute def roles_schema_node( diff --git a/admin/c2cgeoportal_admin/schemas/treegroup.py b/admin/c2cgeoportal_admin/schemas/treegroup.py index ea47cb501d5..e0e7151012e 100644 --- a/admin/c2cgeoportal_admin/schemas/treegroup.py +++ b/admin/c2cgeoportal_admin/schemas/treegroup.py @@ -34,13 +34,13 @@ import pyramid.request import sqlalchemy from c2cgeoform.schema import GeoFormSchemaNode +from c2cgeoportal_commons.lib.literal import Literal +from c2cgeoportal_commons.models.main import LayergroupTreeitem, TreeGroup, TreeItem from sqlalchemy.orm import aliased from sqlalchemy.sql.expression import case, func from c2cgeoportal_admin import _ from c2cgeoportal_admin.widgets import ChildrenWidget, ChildWidget -from c2cgeoportal_commons.lib.literal import Literal -from c2cgeoportal_commons.models.main import LayergroupTreeitem, TreeGroup, TreeItem _LOG = logging.getLogger(__name__) @@ -74,7 +74,8 @@ def treeitems( assert isinstance(dbsession, sqlalchemy.orm.Session) group = case( - (func.count(LayergroupTreeitem.id) == 0, "Unlinked"), else_="Others" # pylint: disable=not-callable + (func.count(LayergroupTreeitem.id) == 0, "Unlinked"), + else_="Others", # pylint: disable=not-callable ) query = ( @@ -123,7 +124,7 @@ def treeitems( def children_validator(node, cstruct): """Get the validator on the children nodes.""" for dict_ in cstruct: - if not dict_["treeitem_id"] in [item["id"] for item in node.candidates]: + if dict_["treeitem_id"] not in [item["id"] for item in node.candidates]: raise colander.Invalid( node, _("Value {} does not exist in table {} or is not allowed to avoid cycles").format( diff --git a/admin/c2cgeoportal_admin/views/__init__.py b/admin/c2cgeoportal_admin/views/__init__.py index 611546b28bd..189e9351845 100644 --- a/admin/c2cgeoportal_admin/views/__init__.py +++ b/admin/c2cgeoportal_admin/views/__init__.py @@ -4,9 +4,7 @@ class IsAdminPredicate: - """ - A custom predicate that checks if the request is for the admin interface. - """ + """A custom predicate that checks if the request is for the admin interface.""" def __init__(self, val, info): del info diff --git a/admin/c2cgeoportal_admin/views/dimension_layers.py b/admin/c2cgeoportal_admin/views/dimension_layers.py index 169627eb40d..51209e88914 100644 --- a/admin/c2cgeoportal_admin/views/dimension_layers.py +++ b/admin/c2cgeoportal_admin/views/dimension_layers.py @@ -32,10 +32,10 @@ import sqlalchemy.orm.query from c2cgeoform.views.abstract_views import ListField +from c2cgeoportal_commons.models.main import DimensionLayer from sqlalchemy.orm import subqueryload from c2cgeoportal_admin.views.layers import LayerViews -from c2cgeoportal_commons.models.main import DimensionLayer _list_field = partial(ListField, DimensionLayer) diff --git a/admin/c2cgeoportal_admin/views/functionalities.py b/admin/c2cgeoportal_admin/views/functionalities.py index 71de35fcfc8..ea4ab57a41e 100644 --- a/admin/c2cgeoportal_admin/views/functionalities.py +++ b/admin/c2cgeoportal_admin/views/functionalities.py @@ -40,12 +40,12 @@ ObjectResponse, SaveResponse, ) +from c2cgeoportal_commons.models.main import Functionality from deform.widget import FormWidget from pyramid.view import view_config, view_defaults from c2cgeoportal_admin import _ from c2cgeoportal_admin.views.logged_views import LoggedViews -from c2cgeoportal_commons.models.main import Functionality _list_field = partial(ListField, Functionality) @@ -103,7 +103,9 @@ def delete(self) -> DeleteResponse: return super().delete() @view_config( - route_name="c2cgeoform_item_duplicate", request_method="GET", renderer="../templates/edit.jinja2" # type: ignore[misc] + route_name="c2cgeoform_item_duplicate", + request_method="GET", + renderer="../templates/edit.jinja2", # type: ignore[misc] ) def duplicate(self) -> ObjectResponse: return super().duplicate() diff --git a/admin/c2cgeoportal_admin/views/interfaces.py b/admin/c2cgeoportal_admin/views/interfaces.py index 806534cc6a2..2a8b6406ae2 100644 --- a/admin/c2cgeoportal_admin/views/interfaces.py +++ b/admin/c2cgeoportal_admin/views/interfaces.py @@ -37,10 +37,10 @@ ObjectResponse, SaveResponse, ) +from c2cgeoportal_commons.models.main import Interface from pyramid.view import view_config, view_defaults from c2cgeoportal_admin.views.logged_views import LoggedViews -from c2cgeoportal_commons.models.main import Interface _list_field = partial(ListField, Interface) diff --git a/admin/c2cgeoportal_admin/views/layer_groups.py b/admin/c2cgeoportal_admin/views/layer_groups.py index fc5a61d93ae..ae68c2f2f5c 100644 --- a/admin/c2cgeoportal_admin/views/layer_groups.py +++ b/admin/c2cgeoportal_admin/views/layer_groups.py @@ -39,6 +39,7 @@ ObjectResponse, SaveResponse, ) +from c2cgeoportal_commons.models.main import LayerGroup, TreeGroup from deform.widget import FormWidget from pyramid.view import view_config, view_defaults @@ -46,7 +47,6 @@ from c2cgeoportal_admin.schemas.treegroup import children_schema_node from c2cgeoportal_admin.schemas.treeitem import parent_id_node from c2cgeoportal_admin.views.treeitems import TreeItemViews -from c2cgeoportal_commons.models.main import LayerGroup, TreeGroup _list_field = partial(ListField, LayerGroup) diff --git a/admin/c2cgeoportal_admin/views/layers.py b/admin/c2cgeoportal_admin/views/layers.py index 038472b15fb..b2b47521bd5 100644 --- a/admin/c2cgeoportal_admin/views/layers.py +++ b/admin/c2cgeoportal_admin/views/layers.py @@ -32,10 +32,10 @@ import sqlalchemy import sqlalchemy.orm.query from c2cgeoform.views.abstract_views import ListField +from c2cgeoportal_commons.models.main import Interface, Layer from sqlalchemy.orm import subqueryload from c2cgeoportal_admin.views.treeitems import TreeItemViews -from c2cgeoportal_commons.models.main import Interface, Layer _list_field = partial(ListField, Layer) diff --git a/admin/c2cgeoportal_admin/views/layers_cog.py b/admin/c2cgeoportal_admin/views/layers_cog.py index 7ba329eba93..f655304baf5 100644 --- a/admin/c2cgeoportal_admin/views/layers_cog.py +++ b/admin/c2cgeoportal_admin/views/layers_cog.py @@ -40,6 +40,8 @@ ObjectResponse, SaveResponse, ) +from c2cgeoportal_commons.lib.literal import Literal +from c2cgeoportal_commons.models.main import LayerCOG, LayerGroup from deform.widget import FormWidget from pyramid.httpexceptions import HTTPNotFound from pyramid.view import view_config, view_defaults @@ -50,8 +52,6 @@ from c2cgeoportal_admin.schemas.restriction_areas import restrictionareas_schema_node from c2cgeoportal_admin.schemas.treeitem import parent_id_node from c2cgeoportal_admin.views.layers import LayerViews -from c2cgeoportal_commons.lib.literal import Literal -from c2cgeoportal_commons.models.main import LayerCOG, LayerGroup _list_field = partial(ListField, LayerCOG) diff --git a/admin/c2cgeoportal_admin/views/layers_vectortiles.py b/admin/c2cgeoportal_admin/views/layers_vectortiles.py index c451da41288..6648c9ddf80 100644 --- a/admin/c2cgeoportal_admin/views/layers_vectortiles.py +++ b/admin/c2cgeoportal_admin/views/layers_vectortiles.py @@ -40,6 +40,8 @@ ObjectResponse, SaveResponse, ) +from c2cgeoportal_commons.lib.literal import Literal +from c2cgeoportal_commons.models.main import LayerGroup, LayerVectorTiles from deform.widget import FormWidget from pyramid.httpexceptions import HTTPNotFound from pyramid.view import view_config, view_defaults @@ -50,8 +52,6 @@ from c2cgeoportal_admin.schemas.restriction_areas import restrictionareas_schema_node from c2cgeoportal_admin.schemas.treeitem import parent_id_node from c2cgeoportal_admin.views.dimension_layers import DimensionLayerViews -from c2cgeoportal_commons.lib.literal import Literal -from c2cgeoportal_commons.models.main import LayerGroup, LayerVectorTiles _list_field = partial(ListField, LayerVectorTiles) diff --git a/admin/c2cgeoportal_admin/views/layers_wms.py b/admin/c2cgeoportal_admin/views/layers_wms.py index 8acd8bab2be..520fd2ffd8f 100644 --- a/admin/c2cgeoportal_admin/views/layers_wms.py +++ b/admin/c2cgeoportal_admin/views/layers_wms.py @@ -40,6 +40,14 @@ ObjectResponse, SaveResponse, ) +from c2cgeoportal_commons.models.main import ( + LayerGroup, + LayerWMS, + LayerWMTS, + LogAction, + OGCServer, + TreeItem, +) from deform.widget import FormWidget from pyramid.view import view_config, view_defaults from sqlalchemy import delete, insert, inspect, update @@ -52,7 +60,6 @@ from c2cgeoportal_admin.schemas.restriction_areas import restrictionareas_schema_node from c2cgeoportal_admin.schemas.treeitem import parent_id_node from c2cgeoportal_admin.views.dimension_layers import DimensionLayerViews -from c2cgeoportal_commons.models.main import LayerGroup, LayerWMS, LayerWMTS, LogAction, OGCServer, TreeItem _list_field = partial(ListField, LayerWMS) diff --git a/admin/c2cgeoportal_admin/views/layers_wmts.py b/admin/c2cgeoportal_admin/views/layers_wmts.py index 1798d6317c6..cdbf4416ba3 100644 --- a/admin/c2cgeoportal_admin/views/layers_wmts.py +++ b/admin/c2cgeoportal_admin/views/layers_wmts.py @@ -40,6 +40,14 @@ ObjectResponse, SaveResponse, ) +from c2cgeoportal_commons.models.main import ( + LayerGroup, + LayerWMS, + LayerWMTS, + LogAction, + OGCServer, + TreeItem, +) from deform.widget import FormWidget from pyramid.view import view_config, view_defaults from sqlalchemy import delete, insert, inspect, update @@ -52,7 +60,6 @@ from c2cgeoportal_admin.schemas.restriction_areas import restrictionareas_schema_node from c2cgeoportal_admin.schemas.treeitem import parent_id_node from c2cgeoportal_admin.views.dimension_layers import DimensionLayerViews -from c2cgeoportal_commons.models.main import LayerGroup, LayerWMS, LayerWMTS, LogAction, OGCServer, TreeItem _list_field = partial(ListField, LayerWMTS) diff --git a/admin/c2cgeoportal_admin/views/layertree.py b/admin/c2cgeoportal_admin/views/layertree.py index c9a1b5ebabf..e229418c340 100644 --- a/admin/c2cgeoportal_admin/views/layertree.py +++ b/admin/c2cgeoportal_admin/views/layertree.py @@ -30,12 +30,18 @@ import pyramid.request from c2cgeoform.views.abstract_views import DeleteResponse, ItemAction +from c2cgeoportal_commons.models.main import ( + Interface, + Layer, + LayergroupTreeitem, + Theme, + TreeItem, +) from pyramid.httpexceptions import HTTPNotFound from pyramid.view import view_config, view_defaults from translationstring import TranslationStringFactory from c2cgeoportal_admin import _ -from c2cgeoportal_commons.models.main import Interface, Layer, LayergroupTreeitem, Theme, TreeItem itemtypes_tables = { "theme": "themes", diff --git a/admin/c2cgeoportal_admin/views/logged_views.py b/admin/c2cgeoportal_admin/views/logged_views.py index 85f287ecbea..da1464c16f5 100644 --- a/admin/c2cgeoportal_admin/views/logged_views.py +++ b/admin/c2cgeoportal_admin/views/logged_views.py @@ -29,10 +29,9 @@ from typing import Generic, TypeVar from c2cgeoform.views.abstract_views import AbstractViews, DeleteResponse, SaveResponse -from pyramid.httpexceptions import HTTPFound - from c2cgeoportal_commons.models import Base from c2cgeoportal_commons.models.main import Log, LogAction +from pyramid.httpexceptions import HTTPFound _T = TypeVar("_T", bound=Log) diff --git a/admin/c2cgeoportal_admin/views/logs.py b/admin/c2cgeoportal_admin/views/logs.py index 922df76cb0d..0e20869e1cb 100644 --- a/admin/c2cgeoportal_admin/views/logs.py +++ b/admin/c2cgeoportal_admin/views/logs.py @@ -28,11 +28,16 @@ from functools import partial from c2cgeoform import JSONDict -from c2cgeoform.views.abstract_views import AbstractViews, GridResponse, IndexResponse, ItemAction, ListField -from pyramid.view import view_config, view_defaults - +from c2cgeoform.views.abstract_views import ( + AbstractViews, + GridResponse, + IndexResponse, + ItemAction, + ListField, +) from c2cgeoportal_commons.models import _ from c2cgeoportal_commons.models.main import AbstractLog +from pyramid.view import view_config, view_defaults _list_field = partial(ListField, AbstractLog) diff --git a/admin/c2cgeoportal_admin/views/oauth2_clients.py b/admin/c2cgeoportal_admin/views/oauth2_clients.py index e30d5618a55..44297b2b491 100644 --- a/admin/c2cgeoportal_admin/views/oauth2_clients.py +++ b/admin/c2cgeoportal_admin/views/oauth2_clients.py @@ -37,10 +37,10 @@ ObjectResponse, SaveResponse, ) +from c2cgeoportal_commons.models.static import Log, OAuth2Client from pyramid.view import view_config, view_defaults from c2cgeoportal_admin.views.logged_views import LoggedViews -from c2cgeoportal_commons.models.static import Log, OAuth2Client _list_field = partial(ListField, OAuth2Client) diff --git a/admin/c2cgeoportal_admin/views/ogc_servers.py b/admin/c2cgeoportal_admin/views/ogc_servers.py index 92e97c6b445..a1599cf0edf 100644 --- a/admin/c2cgeoportal_admin/views/ogc_servers.py +++ b/admin/c2cgeoportal_admin/views/ogc_servers.py @@ -45,6 +45,9 @@ SaveResponse, UserMessage, ) +from c2cgeoportal_commons.lib.literal import Literal +from c2cgeoportal_commons.models import cache_invalidate_cb +from c2cgeoportal_commons.models.main import LogAction, OGCServer from deform.widget import FormWidget from pyramid.httpexceptions import HTTPFound from pyramid.view import view_config, view_defaults @@ -53,9 +56,6 @@ from c2cgeoportal_admin import _ from c2cgeoportal_admin.lib.ogcserver_synchronizer import OGCServerSynchronizer from c2cgeoportal_admin.views.logged_views import LoggedViews -from c2cgeoportal_commons.lib.literal import Literal -from c2cgeoportal_commons.models import cache_invalidate_cb -from c2cgeoportal_commons.models.main import LogAction, OGCServer _list_field = partial(ListField, OGCServer) diff --git a/admin/c2cgeoportal_admin/views/restriction_areas.py b/admin/c2cgeoportal_admin/views/restriction_areas.py index 17b63d499f7..3edcb63f3fe 100644 --- a/admin/c2cgeoportal_admin/views/restriction_areas.py +++ b/admin/c2cgeoportal_admin/views/restriction_areas.py @@ -39,6 +39,7 @@ ObjectResponse, SaveResponse, ) +from c2cgeoportal_commons.models.main import Layer, RestrictionArea from deform.widget import FormWidget from pyramid.view import view_config, view_defaults from sqlalchemy.orm import subqueryload @@ -47,7 +48,6 @@ from c2cgeoportal_admin.schemas.treegroup import treeitem_edit_url from c2cgeoportal_admin.views.logged_views import LoggedViews from c2cgeoportal_admin.widgets import ChildrenWidget, ChildWidget -from c2cgeoportal_commons.models.main import Layer, RestrictionArea _list_field = partial(ListField, RestrictionArea) diff --git a/admin/c2cgeoportal_admin/views/roles.py b/admin/c2cgeoportal_admin/views/roles.py index ec8ee1706dd..f26e1572d50 100644 --- a/admin/c2cgeoportal_admin/views/roles.py +++ b/admin/c2cgeoportal_admin/views/roles.py @@ -39,6 +39,8 @@ ObjectResponse, SaveResponse, ) +from c2cgeoportal_commons.models.main import Role +from c2cgeoportal_commons.models.static import User from deform.widget import FormWidget from pyramid.view import view_config, view_defaults from sqlalchemy.orm import subqueryload @@ -47,8 +49,6 @@ from c2cgeoportal_admin.schemas.restriction_areas import restrictionareas_schema_node from c2cgeoportal_admin.views.logged_views import LoggedViews from c2cgeoportal_admin.widgets import ChildrenWidget, ChildWidget -from c2cgeoportal_commons.models.main import Role -from c2cgeoportal_commons.models.static import User _list_field = partial(ListField, Role) diff --git a/admin/c2cgeoportal_admin/views/themes.py b/admin/c2cgeoportal_admin/views/themes.py index 15fc45980d4..79149888840 100644 --- a/admin/c2cgeoportal_admin/views/themes.py +++ b/admin/c2cgeoportal_admin/views/themes.py @@ -39,6 +39,7 @@ ObjectResponse, SaveResponse, ) +from c2cgeoportal_commons.models.main import Functionality, Interface, Role, Theme from deform.widget import FormWidget from pyramid.view import view_config, view_defaults from sqlalchemy.orm import subqueryload @@ -50,7 +51,6 @@ from c2cgeoportal_admin.schemas.roles import roles_schema_node from c2cgeoportal_admin.schemas.treegroup import children_schema_node from c2cgeoportal_admin.views.treeitems import TreeItemViews -from c2cgeoportal_commons.models.main import Functionality, Interface, Role, Theme _list_field = partial(ListField, Theme) diff --git a/admin/c2cgeoportal_admin/views/themes_ordering.py b/admin/c2cgeoportal_admin/views/themes_ordering.py index c9faa7175a8..5833794c175 100644 --- a/admin/c2cgeoportal_admin/views/themes_ordering.py +++ b/admin/c2cgeoportal_admin/views/themes_ordering.py @@ -29,6 +29,7 @@ import colander from c2cgeoform.schema import GeoFormSchemaNode from c2cgeoform.views.abstract_views import AbstractViews, ObjectResponse, SaveResponse +from c2cgeoportal_commons.models.main import Theme, TreeItem from deform import ValidationFailure from pyramid.httpexceptions import HTTPFound from pyramid.view import view_config @@ -36,7 +37,6 @@ from c2cgeoportal_admin import _ from c2cgeoportal_admin.schemas.treegroup import treeitem_edit_url from c2cgeoportal_admin.widgets import ChildrenWidget, ChildWidget -from c2cgeoportal_commons.models.main import Theme, TreeItem class ThemeOrderSchema(GeoFormSchemaNode): # pylint: disable=abstract-method @@ -61,7 +61,7 @@ def themes(node, kw): # pylint: disable=unused-argument def themes_validator(node, cstruct): """Validate the theme.""" for dict_ in cstruct: - if not dict_["id"] in [item["id"] for item in node.candidates]: + if dict_["id"] not in [item["id"] for item in node.candidates]: raise colander.Invalid( node, _("Value {} does not exist in table {}").format(dict_["id"], Theme.__tablename__), diff --git a/admin/c2cgeoportal_admin/views/treeitems.py b/admin/c2cgeoportal_admin/views/treeitems.py index f762d9f22bd..0c3d2a5196d 100644 --- a/admin/c2cgeoportal_admin/views/treeitems.py +++ b/admin/c2cgeoportal_admin/views/treeitems.py @@ -31,12 +31,17 @@ import sqlalchemy from c2cgeoform.views.abstract_views import ListField, SaveResponse +from c2cgeoportal_commons.models.main import ( + LayergroupTreeitem, + Metadata, + TreeGroup, + TreeItem, +) from pyramid.view import view_config from sqlalchemy.orm import subqueryload from sqlalchemy.sql.functions import concat from c2cgeoportal_admin.views.logged_views import LoggedViews -from c2cgeoportal_commons.models.main import LayergroupTreeitem, Metadata, TreeGroup, TreeItem _list_field = partial(ListField, TreeItem) diff --git a/admin/c2cgeoportal_admin/views/users.py b/admin/c2cgeoportal_admin/views/users.py index 769de9aa640..f42c4943a99 100644 --- a/admin/c2cgeoportal_admin/views/users.py +++ b/admin/c2cgeoportal_admin/views/users.py @@ -38,6 +38,9 @@ ObjectResponse, SaveResponse, ) +from c2cgeoportal_commons.lib.email_ import send_email_config +from c2cgeoportal_commons.models.main import Role +from c2cgeoportal_commons.models.static import Log, User from deform.widget import FormWidget from passwordgenerator import pwgenerator from pyramid.httpexceptions import HTTPFound @@ -46,9 +49,6 @@ from c2cgeoportal_admin.schemas.roles import roles_schema_node from c2cgeoportal_admin.views.logged_views import LoggedViews -from c2cgeoportal_commons.lib.email_ import send_email_config -from c2cgeoportal_commons.models.main import Role -from c2cgeoportal_commons.models.static import Log, User _list_field = partial(ListField, User) diff --git a/admin/c2cgeoportal_admin/widgets.py b/admin/c2cgeoportal_admin/widgets.py index bce6599c963..57c8e1a07a2 100644 --- a/admin/c2cgeoportal_admin/widgets.py +++ b/admin/c2cgeoportal_admin/widgets.py @@ -29,12 +29,11 @@ import colander import pyramid.request +from c2cgeoportal_commons.models.main import TreeItem from colander import Mapping, SchemaNode from deform import widget from deform.widget import MappingWidget, SequenceWidget -from c2cgeoportal_commons.models.main import TreeItem - registry = widget.default_resource_registry registry.set_js_resources( "magicsuggest", None, "c2cgeoportal_admin:node_modules/magicsuggest-alpine/magicsuggest-min.js" diff --git a/admin/tests/lib/test_ogcserver_synchronizer.py b/admin/tests/lib/test_ogcserver_synchronizer.py index c193facbb54..9d333f602a0 100644 --- a/admin/tests/lib/test_ogcserver_synchronizer.py +++ b/admin/tests/lib/test_ogcserver_synchronizer.py @@ -38,9 +38,7 @@ def wms_capabilities(content=DEFAULT_CONTENT): {} -""".format( - content - ) +""".format(content) @pytest.fixture(scope="function") diff --git a/commons/c2cgeoportal_commons/alembic/env.py b/commons/c2cgeoportal_commons/alembic/env.py index 6c05079fe3c..99667969b5f 100755 --- a/commons/c2cgeoportal_commons/alembic/env.py +++ b/commons/c2cgeoportal_commons/alembic/env.py @@ -103,7 +103,11 @@ def run_migrations_online() -> None: # Autogenerate config alembic_name = context.config.get_main_option("type") - from c2cgeoportal_commons.models import Base, main, static # pylint: disable=import-outside-toplevel + from c2cgeoportal_commons.models import ( # pylint: disable=import-outside-toplevel + Base, + main, + static, + ) _schema = main._schema if alembic_name == "main" else static._schema # pylint: disable=protected-access diff --git a/commons/c2cgeoportal_commons/alembic/main/166ff2dcc48d_create_database.py b/commons/c2cgeoportal_commons/alembic/main/166ff2dcc48d_create_database.py index 3b40b6fddb4..50a78e8ac1b 100644 --- a/commons/c2cgeoportal_commons/alembic/main/166ff2dcc48d_create_database.py +++ b/commons/c2cgeoportal_commons/alembic/main/166ff2dcc48d_create_database.py @@ -40,7 +40,15 @@ from alembic import op from c2c.template.config import config from sqlalchemy import Column, ForeignKey, MetaData, Table -from sqlalchemy.types import Boolean, DateTime, Float, Integer, String, Unicode, UserDefinedType +from sqlalchemy.types import ( + Boolean, + DateTime, + Float, + Integer, + String, + Unicode, + UserDefinedType, +) # revision identifiers, used by Alembic. revision = "166ff2dcc48d" @@ -94,8 +102,8 @@ def upgrade() -> None: schema=schema, ) op.execute( - "SELECT AddGeometryColumn('%(schema)s', 'restrictionarea', " - "'area', %(srid)s, 'POLYGON', 2)" % {"schema": schema, "srid": srid} + f"SELECT AddGeometryColumn('{schema}', 'restrictionarea', " + f"'area', {srid}, 'POLYGON', 2)" ) op.create_table( "shorturl", @@ -117,8 +125,8 @@ def upgrade() -> None: schema=schema, ) op.execute( - "SELECT AddGeometryColumn('%(schema)s', 'role', " - "'extent', %(srid)s, 'POLYGON', 2)" % {"schema": schema, "srid": srid} + f"SELECT AddGeometryColumn('{schema}', 'role', " + f"'extent', {srid}, 'POLYGON', 2)" ) role = Table("role", MetaData(), Column("name", Unicode, unique=True, nullable=False), schema=schema) op.bulk_insert(role, [{"name": "role_admin"}]) @@ -173,8 +181,8 @@ def upgrade() -> None: schema=schema, ) op.execute( - "SELECT AddGeometryColumn('%(schema)s', 'tsearch', 'the_geom', " - "%(srid)s, 'GEOMETRY', 2)" % {"schema": schema, "srid": srid} + f"SELECT AddGeometryColumn('{schema}', 'tsearch', 'the_geom', " + f"{srid}, 'GEOMETRY', 2)" ) op.create_index("tsearch_ts_idx", "tsearch", ["ts"], schema=schema, postgresql_using="gin") op.create_table( diff --git a/commons/c2cgeoportal_commons/alembic/main/21f11066f8ec_trigger_on_role_updates_user_in_static.py b/commons/c2cgeoportal_commons/alembic/main/21f11066f8ec_trigger_on_role_updates_user_in_static.py index 777bdf654f9..b2ad419528a 100644 --- a/commons/c2cgeoportal_commons/alembic/main/21f11066f8ec_trigger_on_role_updates_user_in_static.py +++ b/commons/c2cgeoportal_commons/alembic/main/21f11066f8ec_trigger_on_role_updates_user_in_static.py @@ -71,7 +71,7 @@ def downgrade() -> None: schema = config["schema"] op.execute( - """ + f""" CREATE OR REPLACE FUNCTION {schema}.on_role_name_change() RETURNS trigger AS $$ @@ -82,7 +82,5 @@ def downgrade() -> None: RETURN NEW; END; $$ -LANGUAGE plpgsql""".format( - schema=schema - ) +LANGUAGE plpgsql""" ) diff --git a/commons/c2cgeoportal_commons/alembic/main/56dc90838d90_fix_removing_layerv1.py b/commons/c2cgeoportal_commons/alembic/main/56dc90838d90_fix_removing_layerv1.py index c6298f22324..392f6ea245b 100644 --- a/commons/c2cgeoportal_commons/alembic/main/56dc90838d90_fix_removing_layerv1.py +++ b/commons/c2cgeoportal_commons/alembic/main/56dc90838d90_fix_removing_layerv1.py @@ -50,11 +50,11 @@ def upgrade() -> None: schema = config["schema"] op.execute( - ( - "DELETE from {schema}.layer_restrictionarea WHERE layer_id IN (" - "SELECT id from {schema}.treeitem WHERE type = 'layerv1'" + + f"DELETE from {schema}.layer_restrictionarea WHERE layer_id IN (" + f"SELECT id from {schema}.treeitem WHERE type = 'layerv1'" ");" - ).format(schema=schema) + ) op.execute(f"DELETE from {schema}.treeitem WHERE type = 'layerv1';") diff --git a/commons/c2cgeoportal_commons/alembic/main/7530011a66a7_trigger_on_role_updates_user_in_static.py b/commons/c2cgeoportal_commons/alembic/main/7530011a66a7_trigger_on_role_updates_user_in_static.py index 4107a44967f..0a8278fe29e 100644 --- a/commons/c2cgeoportal_commons/alembic/main/7530011a66a7_trigger_on_role_updates_user_in_static.py +++ b/commons/c2cgeoportal_commons/alembic/main/7530011a66a7_trigger_on_role_updates_user_in_static.py @@ -71,7 +71,7 @@ def downgrade() -> None: schema = config["schema"] op.execute( - """ + f""" CREATE OR REPLACE FUNCTION {schema}.on_role_name_change() RETURNS trigger AS $$ @@ -82,7 +82,5 @@ def downgrade() -> None: RETURN NEW; END; $$ -LANGUAGE plpgsql""".format( - schema=schema - ) +LANGUAGE plpgsql""" ) diff --git a/commons/c2cgeoportal_commons/alembic/main/7d271f4527cd_add_layer_column_in_layerv1_table.py b/commons/c2cgeoportal_commons/alembic/main/7d271f4527cd_add_layer_column_in_layerv1_table.py index 1129d0194a5..ed914b6974f 100644 --- a/commons/c2cgeoportal_commons/alembic/main/7d271f4527cd_add_layer_column_in_layerv1_table.py +++ b/commons/c2cgeoportal_commons/alembic/main/7d271f4527cd_add_layer_column_in_layerv1_table.py @@ -53,10 +53,10 @@ def upgrade() -> None: op.add_column("layerv1", Column("layer", Unicode), schema=schema) op.execute( - "UPDATE {schema}.layerv1 AS l1 " + f"UPDATE {schema}.layerv1 AS l1 " "SET layer = name " - "FROM {schema}.treeitem AS ti " - "WHERE l1.id = ti.id".format(schema=schema) + f"FROM {schema}.treeitem AS ti " + "WHERE l1.id = ti.id" ) diff --git a/commons/c2cgeoportal_commons/alembic/main/9268a1dffac0_add_trigger_to_be_able_to_correctly_.py b/commons/c2cgeoportal_commons/alembic/main/9268a1dffac0_add_trigger_to_be_able_to_correctly_.py index 143943fe90e..de7fef02973 100644 --- a/commons/c2cgeoportal_commons/alembic/main/9268a1dffac0_add_trigger_to_be_able_to_correctly_.py +++ b/commons/c2cgeoportal_commons/alembic/main/9268a1dffac0_add_trigger_to_be_able_to_correctly_.py @@ -50,7 +50,7 @@ def upgrade() -> None: schema = config["schema"] op.execute( - """ + f""" CREATE FUNCTION {schema}.on_role_name_change() RETURNS trigger AS $$ @@ -61,14 +61,12 @@ def upgrade() -> None: RETURN NEW; END; $$ -LANGUAGE plpgsql""".format( - schema=schema - ) +LANGUAGE plpgsql""" ) op.execute( - "CREATE TRIGGER on_role_name_change AFTER UPDATE ON {schema}.role FOR EACH ROW " - "EXECUTE PROCEDURE {schema}.on_role_name_change()".format(schema=schema) + f"CREATE TRIGGER on_role_name_change AFTER UPDATE ON {schema}.role FOR EACH ROW " + f"EXECUTE PROCEDURE {schema}.on_role_name_change()" ) diff --git a/commons/c2cgeoportal_commons/alembic/main/eeb345672454_merge_2_4_and_master_branches.py b/commons/c2cgeoportal_commons/alembic/main/eeb345672454_merge_2_4_and_master_branches.py index 50ba1783b8f..190e3b33809 100644 --- a/commons/c2cgeoportal_commons/alembic/main/eeb345672454_merge_2_4_and_master_branches.py +++ b/commons/c2cgeoportal_commons/alembic/main/eeb345672454_merge_2_4_and_master_branches.py @@ -35,7 +35,6 @@ Create Date: 2019-09-03 09:11:57.786920 """ - # revision identifiers, used by Alembic. revision = "eeb345672454" down_revision = ("78fd093c8393", "56dc90838d90") diff --git a/commons/c2cgeoportal_commons/alembic/static/1da396a88908_move_user_table_to_static_schema.py b/commons/c2cgeoportal_commons/alembic/static/1da396a88908_move_user_table_to_static_schema.py index 68f7f3294a5..b21d92d217f 100644 --- a/commons/c2cgeoportal_commons/alembic/static/1da396a88908_move_user_table_to_static_schema.py +++ b/commons/c2cgeoportal_commons/alembic/static/1da396a88908_move_user_table_to_static_schema.py @@ -82,20 +82,13 @@ def upgrade() -> None: try: op.execute( - "INSERT INTO %(staticschema)s.user " - "(type, username, password, email, is_password_changed, role_name%(parent_column)s) (" + f"INSERT INTO {staticschema}.user " + f"(type, username, password, email, is_password_changed, role_name{parent_column}) (" "SELECT u.type, u.username, u.password, u.email, " - "u.is_password_changed, r.name%(parent_select)s " - "FROM %(schema)s.user AS u " - "LEFT OUTER JOIN %(schema)s.role AS r ON (r.id = u.role_id) %(parent_join)s" + f"u.is_password_changed, r.name{parent_select} " + f"FROM {schema}.user AS u " + f"LEFT OUTER JOIN {schema}.role AS r ON (r.id = u.role_id) {parent_join}" ")" - % { - "staticschema": staticschema, - "schema": schema, - "parent_select": parent_select, - "parent_column": parent_column, - "parent_join": parent_join, - } ) op.drop_table("user", schema=schema) except Exception: # pylint: disable=broad-exception-caught @@ -135,20 +128,13 @@ def downgrade() -> None: parent_join = f"LEFT OUTER JOIN {parentschema}.role AS pr ON (pr.name = u.parent_role_name)" op.execute( - "INSERT INTO %(schema)s.user " - "(type, username, password, email, is_password_changed, role_id%(parent_column)s) (" + f"INSERT INTO {schema}.user " + f"(type, username, password, email, is_password_changed, role_id{parent_column}) (" "SELECT u.type, u.username, u.password, u.email, " - "u.is_password_changed, r.id%(parent_select)s " - "FROM %(staticschema)s.user AS u " - "LEFT OUTER JOIN %(schema)s.role AS r ON (r.name = u.role_name) %(parent_join)s" + f"u.is_password_changed, r.id{parent_select} " + f"FROM {staticschema}.user AS u " + f"LEFT OUTER JOIN {schema}.role AS r ON (r.name = u.role_name) {parent_join}" ")" - % { - "staticschema": staticschema, - "schema": schema, - "parent_select": parent_select, - "parent_column": parent_column, - "parent_join": parent_join, - } ) op.drop_table("user", schema=staticschema) diff --git a/commons/c2cgeoportal_commons/alembic/static/53d671b17b20_add_timezone_on_datetime_fields.py b/commons/c2cgeoportal_commons/alembic/static/53d671b17b20_add_timezone_on_datetime_fields.py index 99d9d4ee71a..1d5917363c0 100644 --- a/commons/c2cgeoportal_commons/alembic/static/53d671b17b20_add_timezone_on_datetime_fields.py +++ b/commons/c2cgeoportal_commons/alembic/static/53d671b17b20_add_timezone_on_datetime_fields.py @@ -50,14 +50,12 @@ def upgrade() -> None: staticschema = config["schema_static"] op.execute( - """ + f""" SET TIME ZONE 'UTC'; ALTER TABLE {staticschema}.user ALTER COLUMN last_login TYPE timestamp with time zone; SET TIME ZONE LOCAL; ALTER TABLE {staticschema}.user ALTER COLUMN expire_on TYPE timestamp with time zone; -""".format( - staticschema=staticschema - ) +""" ) @@ -66,12 +64,10 @@ def downgrade() -> None: staticschema = config["schema_static"] op.execute( - """ + f""" SET TIME ZONE 'UTC'; ALTER TABLE {staticschema}.user ALTER COLUMN last_login TYPE timestamp without time zone; SET TIME ZONE LOCAL; ALTER TABLE {staticschema}.user ALTER COLUMN expire_on TYPE timestamp without time zone; -""".format( - staticschema=staticschema - ) +""" ) diff --git a/commons/c2cgeoportal_commons/alembic/static/aa41e9613256_wip_add_openid_connect_support.py b/commons/c2cgeoportal_commons/alembic/static/aa41e9613256_wip_add_openid_connect_support.py index 59b750d8008..5f3625a9561 100644 --- a/commons/c2cgeoportal_commons/alembic/static/aa41e9613256_wip_add_openid_connect_support.py +++ b/commons/c2cgeoportal_commons/alembic/static/aa41e9613256_wip_add_openid_connect_support.py @@ -35,7 +35,6 @@ Create Date: 2024-08-30 15:56:31.163378 """ - from alembic import op from c2c.template.config import config diff --git a/commons/c2cgeoportal_commons/models/main.py b/commons/c2cgeoportal_commons/models/main.py index ffc87dd9f43..7920aef09a9 100644 --- a/commons/c2cgeoportal_commons/models/main.py +++ b/commons/c2cgeoportal_commons/models/main.py @@ -56,7 +56,13 @@ from c2cgeoform.ext.colander_ext import Geometry as ColanderGeometry from c2cgeoform.ext.deform_ext import MapWidget, RelationSelect2Widget from colander import drop - from deform.widget import CheckboxWidget, HiddenWidget, SelectWidget, TextAreaWidget, TextInputWidget + from deform.widget import ( + CheckboxWidget, + HiddenWidget, + SelectWidget, + TextAreaWidget, + TextInputWidget, + ) colander_null = colander.null except ModuleNotFoundError: @@ -84,7 +90,6 @@ def __init__(self, *args: Any, **kwargs: Any): def state_str(state: Any) -> str: """Return a string describing an instance via its InstanceState.""" - return "None" if state is None else f"<{state.class_.__name__} {state.obj()}>" # In the original function sqlalchemy use the id of the object that don't allow us to give some useful @@ -367,11 +372,7 @@ def is_in_interface(self, name: str) -> bool: if not hasattr(self, "interfaces"): return False - for interface in self.interfaces: - if interface.name == name: - return True - - return False + return any(interface.name == name for interface in self.interfaces) def get_metadata(self, name: str) -> list["Metadata"]: return [metadata for metadata in self.metadatas if metadata.name == name] @@ -1035,7 +1036,7 @@ def __init__( @staticmethod def get_default(dbsession: Session) -> DimensionLayer | None: return cast( - Optional[DimensionLayer], + DimensionLayer | None, dbsession.query(LayerWMS).filter(LayerWMS.name == "wms-defaults").one_or_none(), ) @@ -1179,7 +1180,7 @@ def __init__(self, name: str = "", public: bool = True, image_type: ImageType = @staticmethod def get_default(dbsession: Session) -> DimensionLayer | None: return cast( - Optional[DimensionLayer], + DimensionLayer | None, dbsession.query(LayerWMTS).filter(LayerWMTS.name == "wmts-defaults").one_or_none(), ) @@ -1374,7 +1375,7 @@ def __init__(self, name: str = "", public: bool = True, style: str = "", sql: st @staticmethod def get_default(dbsession: Session) -> DimensionLayer | None: return cast( - Optional[DimensionLayer], + DimensionLayer | None, dbsession.query(LayerVectorTiles) .filter(LayerVectorTiles.name == "vector-tiles-defaults") .one_or_none(), diff --git a/commons/c2cgeoportal_commons/testing/__init__.py b/commons/c2cgeoportal_commons/testing/__init__.py index 14a6ff17afe..90f6f6728b9 100644 --- a/commons/c2cgeoportal_commons/testing/__init__.py +++ b/commons/c2cgeoportal_commons/testing/__init__.py @@ -78,7 +78,6 @@ def get_tm_session( def generate_mappers() -> None: """Initialize the model for a Pyramid app.""" - # import or define all models here to ensure they are attached to the # Base.metadata prior to any initialization routines import c2cgeoportal_commons.models.main # pylint: disable=unused-import,import-outside-toplevel diff --git a/commons/c2cgeoportal_commons/testing/initializedb.py b/commons/c2cgeoportal_commons/testing/initializedb.py index e3951d17c64..d1d3d868da2 100644 --- a/commons/c2cgeoportal_commons/testing/initializedb.py +++ b/commons/c2cgeoportal_commons/testing/initializedb.py @@ -64,8 +64,12 @@ def truncate_tables(connection: Connection) -> None: def setup_test_data(dbsession: Session) -> None: """Initialize the testing data.""" - from c2cgeoportal_commons.models.main import Role # pylint: disable=import-outside-toplevel - from c2cgeoportal_commons.models.static import User # pylint: disable=import-outside-toplevel + from c2cgeoportal_commons.models.main import ( + Role, # pylint: disable=import-outside-toplevel + ) + from c2cgeoportal_commons.models.static import ( + User, # pylint: disable=import-outside-toplevel + ) role_admin = dbsession.merge(Role(name="role_admin")) role_user = dbsession.merge(Role(name="role_user")) diff --git a/geoportal/c2cgeoportal_geoportal/__init__.py b/geoportal/c2cgeoportal_geoportal/__init__.py index 2e38add0feb..792e19d67c8 100644 --- a/geoportal/c2cgeoportal_geoportal/__init__.py +++ b/geoportal/c2cgeoportal_geoportal/__init__.py @@ -37,6 +37,7 @@ from typing import TYPE_CHECKING, Any, Optional, cast import c2cgeoform +import c2cgeoportal_commons.models import c2cwsgiutils import c2cwsgiutils.db import c2cwsgiutils.index @@ -50,6 +51,7 @@ import sqlalchemy.orm import zope.event.classhandler from c2cgeoform import translator +from c2cgeoportal_commons.models import InvalidateCacheEvent from c2cwsgiutils.health_check import HealthCheck from c2cwsgiutils.prometheus import MemoryMapCollector from deform import Form @@ -62,10 +64,14 @@ from pyramid_mako import add_mako_renderer from sqlalchemy.orm import joinedload -import c2cgeoportal_commons.models import c2cgeoportal_geoportal.views -from c2cgeoportal_commons.models import InvalidateCacheEvent -from c2cgeoportal_geoportal.lib import C2CPregenerator, caching, check_collector, checker, oidc +from c2cgeoportal_geoportal.lib import ( + C2CPregenerator, + caching, + check_collector, + checker, + oidc, +) from c2cgeoportal_geoportal.lib.cacheversion import version_cache_buster from c2cgeoportal_geoportal.lib.caching import get_region from c2cgeoportal_geoportal.lib.common_headers import Cache, set_common_headers @@ -79,7 +85,9 @@ from c2cgeoportal_geoportal.views.entry import Entry, canvas_view, custom_view if TYPE_CHECKING: - from c2cgeoportal_commons.models import static # pylint: disable=ungrouped-imports,useless-suppression + from c2cgeoportal_commons.models import ( + static, # pylint: disable=ungrouped-imports,useless-suppression + ) _LOG = logging.getLogger(__name__) @@ -174,7 +182,6 @@ def add_interface_ngeo( permission: str | None = None, ) -> None: """Add the ngeo interfaces views and routes.""" - config.add_route(route_name, route, request_method="GET") # Permalink theme: recover the theme for generating custom viewer.js url config.add_route( @@ -202,7 +209,6 @@ def add_interface_canvas( permission: str | None = None, ) -> None: """Add the ngeo interfaces views and routes.""" - renderer = f"/etc/geomapfish/interfaces/{route_name}.html.mako" config.add_route(route_name, route, request_method="GET") # Permalink theme: recover the theme for generating custom viewer.js URL @@ -235,7 +241,6 @@ def add_interface_custom( permission: str | None = None, ) -> None: """Add custom interfaces views and routes.""" - config.add_route(route_name, route, request_method="GET") # Permalink theme: recover the theme for generating custom viewer.js URL config.add_route( @@ -259,7 +264,6 @@ def add_interface_custom( def add_admin_interface(config: pyramid.config.Configurator) -> None: """Add the administration interface views and routes.""" - assert c2cgeoportal_commons.models.DBSession is not None config.add_request_method( @@ -318,7 +322,6 @@ def is_allowed_url( Allowed if URL netloc is request host or is found in allowed hosts. """ - url_netloc = urllib.parse.urlparse(url).netloc return url_netloc, url_netloc == request.host or url_netloc in _get_netlocs(allowed_hosts) @@ -329,7 +332,6 @@ def is_allowed_host(request: pyramid.request.Request) -> bool: Allowed if URL netloc is request host or is found in allowed hosts. """ - return request.host in request.registry.settings.get("allowed_hosts", []) @@ -354,7 +356,7 @@ def is_valid_referrer(request: pyramid.request.Request, settings: dict[str, Any] def create_get_user_from_request( - settings: dict[str, Any] + settings: dict[str, Any], ) -> Callable[[pyramid.request.Request, str | None], Optional["static.User"]]: """Get the get_user_from_request function.""" @@ -370,8 +372,12 @@ def get_user_from_request( * it has been deactivated * the referrer is invalid """ - from c2cgeoportal_commons.models import DBSession # pylint: disable=import-outside-toplevel - from c2cgeoportal_commons.models.static import User # pylint: disable=import-outside-toplevel + from c2cgeoportal_commons.models import ( + DBSession, # pylint: disable=import-outside-toplevel + ) + from c2cgeoportal_commons.models.static import ( + User, # pylint: disable=import-outside-toplevel + ) assert DBSession is not None @@ -467,8 +473,12 @@ def default_user_validator(request: pyramid.request.Request, username: str, pass otherwise. """ del request # unused - from c2cgeoportal_commons.models import DBSession # pylint: disable=import-outside-toplevel - from c2cgeoportal_commons.models.static import User # pylint: disable=import-outside-toplevel + from c2cgeoportal_commons.models import ( + DBSession, # pylint: disable=import-outside-toplevel + ) + from c2cgeoportal_commons.models.static import ( + User, # pylint: disable=import-outside-toplevel + ) assert DBSession is not None @@ -930,7 +940,9 @@ def init_db_sessions( ) c2cgeoportal_commons.models.Base.metadata.clear() - from c2cgeoportal_commons.models import main # pylint: disable=import-outside-toplevel + from c2cgeoportal_commons.models import ( + main, # pylint: disable=import-outside-toplevel + ) if health_check is not None: for name, session in c2cgeoportal_commons.models.DBSessions.items(): diff --git a/geoportal/c2cgeoportal_geoportal/lib/__init__.py b/geoportal/c2cgeoportal_geoportal/lib/__init__.py index 35906491655..67fdeda3f01 100644 --- a/geoportal/c2cgeoportal_geoportal/lib/__init__.py +++ b/geoportal/c2cgeoportal_geoportal/lib/__init__.py @@ -38,10 +38,10 @@ import dateutil import pyramid.request import pyramid.response +from c2cgeoportal_commons.lib.url import get_url2 from pyramid.interfaces import IRoutePregenerator from zope.interface import implementer -from c2cgeoportal_commons.lib.url import get_url2 from c2cgeoportal_geoportal.lib.cacheversion import get_cache_version from c2cgeoportal_geoportal.lib.caching import get_region @@ -145,8 +145,12 @@ def get_setting(settings: Any, path: Iterable[str], default: Any = None) -> Any: @_CACHE_REGION_OBJ.cache_on_arguments() def get_ogc_server_wms_url_ids(request: pyramid.request.Request, host: str) -> dict[str, list[int]]: """Get the OGCServer ids mapped on the WMS URL.""" - from c2cgeoportal_commons.models import DBSession # pylint: disable=import-outside-toplevel - from c2cgeoportal_commons.models.main import OGCServer # pylint: disable=import-outside-toplevel + from c2cgeoportal_commons.models import ( + DBSession, # pylint: disable=import-outside-toplevel + ) + from c2cgeoportal_commons.models.main import ( + OGCServer, # pylint: disable=import-outside-toplevel + ) del host # used for cache assert DBSession is not None @@ -163,8 +167,12 @@ def get_ogc_server_wms_url_ids(request: pyramid.request.Request, host: str) -> d @_CACHE_REGION_OBJ.cache_on_arguments() def get_ogc_server_wfs_url_ids(request: pyramid.request.Request, host: str) -> dict[str, list[int]]: """Get the OGCServer ids mapped on the WFS URL.""" - from c2cgeoportal_commons.models import DBSession # pylint: disable=import-outside-toplevel - from c2cgeoportal_commons.models.main import OGCServer # pylint: disable=import-outside-toplevel + from c2cgeoportal_commons.models import ( + DBSession, # pylint: disable=import-outside-toplevel + ) + from c2cgeoportal_commons.models.main import ( + OGCServer, # pylint: disable=import-outside-toplevel + ) del host # used for cache assert DBSession is not None @@ -218,7 +226,10 @@ def _get_intranet_networks( @_CACHE_REGION.cache_on_arguments() def get_role_id(name: str) -> int: """Get the role ID.""" - from c2cgeoportal_commons.models import DBSession, main # pylint: disable=import-outside-toplevel + from c2cgeoportal_commons.models import ( # pylint: disable=import-outside-toplevel + DBSession, + main, + ) assert DBSession is not None @@ -250,7 +261,4 @@ def get_roles_name(request: pyramid.request.Request) -> pyramid.response.Respons def is_intranet(request: pyramid.request.Request) -> bool: """Get if it's an intranet user.""" address = ipaddress.ip_address(request.client_addr) - for network in _get_intranet_networks(request): - if address in network: - return True - return False + return any(address in network for network in _get_intranet_networks(request)) diff --git a/geoportal/c2cgeoportal_geoportal/lib/authentication.py b/geoportal/c2cgeoportal_geoportal/lib/authentication.py index b8feb9dd2e3..e311524f3a0 100644 --- a/geoportal/c2cgeoportal_geoportal/lib/authentication.py +++ b/geoportal/c2cgeoportal_geoportal/lib/authentication.py @@ -67,7 +67,7 @@ def __init__( self.debug = debug def unauthenticated_userid(self, request: pyramid.request.Request) -> str | None: - if not request.method == "GET" or "auth" not in request.params: + if request.method != "GET" or "auth" not in request.params: return None auth_enc = request.params.get("auth") if auth_enc is None: diff --git a/geoportal/c2cgeoportal_geoportal/lib/caching.py b/geoportal/c2cgeoportal_geoportal/lib/caching.py index 826c5ef2546..f887b7c7281 100644 --- a/geoportal/c2cgeoportal_geoportal/lib/caching.py +++ b/geoportal/c2cgeoportal_geoportal/lib/caching.py @@ -33,6 +33,7 @@ import pyramid.interfaces import zope.interface +from c2cgeoportal_commons.models import Base from dogpile.cache.api import NO_VALUE, CacheBackend, CachedValue, NoValue from dogpile.cache.backends.memory import MemoryBackend from dogpile.cache.backends.redis import RedisBackend, RedisSentinelBackend @@ -40,8 +41,6 @@ from dogpile.cache.util import sha1_mangle_key from sqlalchemy.orm.util import identity_key -from c2cgeoportal_commons.models import Base - if TYPE_CHECKING: from dogpile.cache.api import SerializedReturnType else: @@ -65,7 +64,6 @@ def keygen_function(namespace: Any, function: Callable[..., Any]) -> Callable[.. This is used by :meth:`.CacheRegion.cache_on_arguments` to generate a cache key from a decorated function. """ - if namespace is None: namespace = (function.__module__, function.__name__) else: @@ -140,7 +138,7 @@ def get(self, key: str) -> CachedValue | bytes | NoValue: assert isinstance(val, bytes) value = self._redis.deserializer(val) # type: ignore[misc] if value != NO_VALUE and self._use_memory_cache: - assert isinstance(value, (CachedValue, bytes)) + assert isinstance(value, CachedValue | bytes) self._memory.set(key, value) return value diff --git a/geoportal/c2cgeoportal_geoportal/lib/checker.py b/geoportal/c2cgeoportal_geoportal/lib/checker.py index 710ba551ae3..1b9925361de 100644 --- a/geoportal/c2cgeoportal_geoportal/lib/checker.py +++ b/geoportal/c2cgeoportal_geoportal/lib/checker.py @@ -156,8 +156,12 @@ def check(_request: pyramid.request.Request, response: pyramid.response.Response def _themes_errors(settings: dict[str, Any], health_check: c2cwsgiutils.health_check.HealthCheck) -> None: - from c2cgeoportal_commons.models import DBSession # pylint: disable=import-outside-toplevel - from c2cgeoportal_commons.models.main import Interface # pylint: disable=import-outside-toplevel + from c2cgeoportal_commons.models import ( + DBSession, # pylint: disable=import-outside-toplevel + ) + from c2cgeoportal_commons.models.main import ( + Interface, # pylint: disable=import-outside-toplevel + ) assert DBSession is not None @@ -256,7 +260,7 @@ def __call__(self, request: pyramid.request.Request) -> None: cmd: list[str] = ["check-example", url] env = dict(os.environ) for name, value in self.route.get("environment", {}).items(): - if isinstance(value, (list, dict)): + if isinstance(value, list | dict): value = json.dumps(value) elif not isinstance(value, str): value = str(value) diff --git a/geoportal/c2cgeoportal_geoportal/lib/common_headers.py b/geoportal/c2cgeoportal_geoportal/lib/common_headers.py index c80a59c271f..3d276abfcc2 100644 --- a/geoportal/c2cgeoportal_geoportal/lib/common_headers.py +++ b/geoportal/c2cgeoportal_geoportal/lib/common_headers.py @@ -123,7 +123,6 @@ def _set_common_headers( content_type: str | None, ) -> pyramid.response.Response: """Set the common headers.""" - response.headers.update(service_headers_settings.get("headers", {})) if cache in (Cache.PRIVATE, Cache.PRIVATE_NO): diff --git a/geoportal/c2cgeoportal_geoportal/lib/dbreflection.py b/geoportal/c2cgeoportal_geoportal/lib/dbreflection.py index 6fcaaaa8b50..3ffada0c26a 100644 --- a/geoportal/c2cgeoportal_geoportal/lib/dbreflection.py +++ b/geoportal/c2cgeoportal_geoportal/lib/dbreflection.py @@ -76,7 +76,9 @@ def __get__( return getattr(target, self.value_attr) if target else None def __set__(self, obj: str, val: str) -> None: - from c2cgeoportal_commons.models import DBSession # pylint: disable=import-outside-toplevel + from c2cgeoportal_commons.models import ( + DBSession, # pylint: disable=import-outside-toplevel + ) assert DBSession is not None @@ -118,8 +120,10 @@ def get_table( engine = session.bind.engine metadata = MetaData() else: - from c2cgeoportal_commons.models import Base # pylint: disable=import-outside-toplevel - from c2cgeoportal_commons.models import DBSession # pylint: disable=import-outside-toplevel + from c2cgeoportal_commons.models import ( + Base, # pylint: disable=import-outside-toplevel + DBSession, # pylint: disable=import-outside-toplevel + ) assert DBSession is not None assert DBSession.bind is not None @@ -162,7 +166,6 @@ def get_class( valid string. If there is no table identified by tablename in the database a NoSuchTableError SQLAlchemy exception is raised. """ - tablename, schema = _get_schema(tablename) table = get_table(tablename, schema, None, primary_key=primary_key) @@ -187,7 +190,9 @@ def _create_class( readonly_attributes: list[str] | None = None, pk_name: str | None = None, ) -> type: - from c2cgeoportal_commons.models import Base # pylint: disable=import-outside-toplevel + from c2cgeoportal_commons.models import ( + Base, # pylint: disable=import-outside-toplevel + ) exclude_properties = exclude_properties or () attributes = { diff --git a/geoportal/c2cgeoportal_geoportal/lib/filter_capabilities.py b/geoportal/c2cgeoportal_geoportal/lib/filter_capabilities.py index c1f2f566b87..805102883e4 100644 --- a/geoportal/c2cgeoportal_geoportal/lib/filter_capabilities.py +++ b/geoportal/c2cgeoportal_geoportal/lib/filter_capabilities.py @@ -39,14 +39,22 @@ import pyramid.httpexceptions import pyramid.request import requests +from c2cgeoportal_commons.lib.url import Url from owslib.map.wms111 import ContentMetadata as ContentMetadata111 from owslib.map.wms130 import ContentMetadata as ContentMetadata130 from owslib.wms import WebMapService from pyramid.httpexceptions import HTTPBadGateway -from c2cgeoportal_commons.lib.url import Url -from c2cgeoportal_geoportal.lib import caching, get_ogc_server_wfs_url_ids, get_ogc_server_wms_url_ids -from c2cgeoportal_geoportal.lib.layers import get_private_layers, get_protected_layers, get_writable_layers +from c2cgeoportal_geoportal.lib import ( + caching, + get_ogc_server_wfs_url_ids, + get_ogc_server_wms_url_ids, +) +from c2cgeoportal_geoportal.lib.layers import ( + get_private_layers, + get_protected_layers, + get_writable_layers, +) _CACHE_REGION = caching.get_region("std") _LOG = logging.getLogger(__name__) @@ -111,7 +119,6 @@ def filter_capabilities( request: pyramid.request.Request, content: str, wms: bool, url: Url, headers: dict[str, str] ) -> str: """Filter the WMS/WFS capabilities.""" - wms_structure_ = wms_structure(request, url, headers.get("Host")) ogc_server_ids = ( @@ -153,7 +160,6 @@ def filter_capabilities( def filter_wfst_capabilities(content: str, wfs_url: Url, request: pyramid.request.Request) -> str: """Filter the WTS capabilities.""" - writable_layers: set[str] = set() ogc_server_ids = get_ogc_server_wfs_url_ids(request, request.host).get(wfs_url.url()) if ogc_server_ids is None: @@ -312,7 +318,7 @@ def _keep_layer(self, layer_name: str) -> bool: ) def characters(self, content: str) -> None: - if self.in_name and self.layers_path and not self.layers_path[-1].self_hidden is True: + if self.in_name and self.layers_path and self.layers_path[-1].self_hidden is not True: layer_name = normalize_typename(content) if self._keep_layer(layer_name): for layer in self.layers_path: @@ -342,9 +348,8 @@ def normalize_tag(tag: str) -> str: e.g. '{https://....}TypeName' -> 'TypeName' """ normalized = tag - if len(tag) >= 3: - if tag[0] == "{": - normalized = tag[1:].split("}")[1] + if len(tag) >= 3 and tag[0] == "{": + normalized = tag[1:].split("}")[1] return normalized.lower() diff --git a/geoportal/c2cgeoportal_geoportal/lib/functionality.py b/geoportal/c2cgeoportal_geoportal/lib/functionality.py index bcc2179f94c..c9d86691aaf 100644 --- a/geoportal/c2cgeoportal_geoportal/lib/functionality.py +++ b/geoportal/c2cgeoportal_geoportal/lib/functionality.py @@ -30,9 +30,9 @@ from typing import Any, cast import pyramid.request +from c2cgeoportal_commons.models import main, static from sqlalchemy.orm import joinedload -from c2cgeoportal_commons.models import main, static from c2cgeoportal_geoportal.lib import get_typed, get_types_map, is_intranet from c2cgeoportal_geoportal.lib.caching import get_region @@ -43,7 +43,9 @@ @_CACHE_REGION_OBJ.cache_on_arguments() def _get_role(name: str) -> dict[str, Any]: - from c2cgeoportal_commons.models import DBSession # pylint: disable=import-outside-toplevel + from c2cgeoportal_commons.models import ( + DBSession, # pylint: disable=import-outside-toplevel + ) assert DBSession is not None diff --git a/geoportal/c2cgeoportal_geoportal/lib/layers.py b/geoportal/c2cgeoportal_geoportal/lib/layers.py index 99fdb221655..a02dc9239a9 100644 --- a/geoportal/c2cgeoportal_geoportal/lib/layers.py +++ b/geoportal/c2cgeoportal_geoportal/lib/layers.py @@ -42,7 +42,10 @@ def _get_layers_query(request: Request, what: sqlalchemy.orm.Mapper[Any] | type[Any]) -> Query[Any]: - from c2cgeoportal_commons.models import DBSession, main # pylint: disable=import-outside-toplevel + from c2cgeoportal_commons.models import ( # pylint: disable=import-outside-toplevel + DBSession, + main, + ) assert DBSession is not None @@ -64,7 +67,9 @@ def get_protected_layers_query( Private layers but accessible to the user. """ - from c2cgeoportal_commons.models import main # pylint: disable=import-outside-toplevel + from c2cgeoportal_commons.models import ( + main, # pylint: disable=import-outside-toplevel + ) q = _get_layers_query(request, what) q = q.filter(main.Layer.public.is_(False)) @@ -76,7 +81,9 @@ def get_protected_layers_query( def get_writable_layers_query(request: Request, ogc_server_ids: Iterable[int]) -> Query["main.LayerWMS"]: """Get the writable layers query.""" - from c2cgeoportal_commons.models import main # pylint: disable=import-outside-toplevel + from c2cgeoportal_commons.models import ( + main, # pylint: disable=import-outside-toplevel + ) q = _get_layers_query(request, main.LayerWMS) return ( @@ -92,7 +99,10 @@ def get_protected_layers(request: Request, ogc_server_ids: Iterable[int]) -> dic Private layers but accessible to the user. """ - from c2cgeoportal_commons.models import DBSession, main # pylint: disable=import-outside-toplevel + from c2cgeoportal_commons.models import ( # pylint: disable=import-outside-toplevel + DBSession, + main, + ) assert DBSession is not None @@ -104,7 +114,9 @@ def get_protected_layers(request: Request, ogc_server_ids: Iterable[int]) -> dic def get_writable_layers(request: Request, ogc_server_ids: Iterable[int]) -> dict[int, "main.LayerWMS"]: """Get the writable layers.""" - from c2cgeoportal_commons.models import DBSession # pylint: disable=import-outside-toplevel + from c2cgeoportal_commons.models import ( + DBSession, # pylint: disable=import-outside-toplevel + ) assert DBSession is not None @@ -117,7 +129,10 @@ def get_writable_layers(request: Request, ogc_server_ids: Iterable[int]) -> dict @CACHE_REGION.cache_on_arguments() def get_private_layers(ogc_server_ids: Iterable[int]) -> dict[int, "main.LayerWMS"]: """Get the private layers.""" - from c2cgeoportal_commons.models import DBSession, main # pylint: disable=import-outside-toplevel + from c2cgeoportal_commons.models import ( # pylint: disable=import-outside-toplevel + DBSession, + main, + ) assert DBSession is not None diff --git a/geoportal/c2cgeoportal_geoportal/lib/lingva_extractor.py b/geoportal/c2cgeoportal_geoportal/lib/lingva_extractor.py index 253606f9fa1..21efbba9f52 100644 --- a/geoportal/c2cgeoportal_geoportal/lib/lingva_extractor.py +++ b/geoportal/c2cgeoportal_geoportal/lib/lingva_extractor.py @@ -32,7 +32,7 @@ import subprocess import traceback from collections.abc import Callable -from typing import TYPE_CHECKING, Any, Optional, cast +from typing import TYPE_CHECKING, Any, cast from xml.dom import Node from xml.parsers.expat import ExpatError @@ -42,6 +42,7 @@ import yaml from bottle import MakoTemplate, template from c2c.template.config import config +from c2cgeoportal_commons.lib.url import Url, get_url2 from defusedxml.minidom import parseString from geoalchemy2.types import Geometry from lingva.extractors import Extractor, Message @@ -54,13 +55,14 @@ from sqlalchemy.orm.util import class_mapper import c2cgeoportal_geoportal -from c2cgeoportal_commons.lib.url import Url, get_url2 from c2cgeoportal_geoportal.lib.bashcolor import Color, colorize from c2cgeoportal_geoportal.lib.caching import init_region from c2cgeoportal_geoportal.views.layers import Layers, get_layer_class if TYPE_CHECKING: - from c2cgeoportal_commons.models import main # pylint: disable=ungrouped-imports,useless-suppression + from c2cgeoportal_commons.models import ( + main, # pylint: disable=ungrouped-imports,useless-suppression + ) class LinguaExtractorException(Exception): @@ -76,7 +78,7 @@ def _get_config(key: str, default: str | None = None) -> str | None: """ request = pyramid.threadlocal.get_current_request() if request is not None: - return cast(Optional[str], request.params.get(key.lower(), default)) + return cast(str | None, request.params.get(key.lower(), default)) return os.environ.get(key, default) @@ -252,10 +254,13 @@ def init_db(settings: dict[str, Any]) -> None: First test the connection, on when environment it should be OK, with the command line we should get an exception ind initialize the connection. """ - try: - from c2cgeoportal_commons.models import DBSession # pylint: disable=import-outside-toplevel - from c2cgeoportal_commons.models.main import Theme # pylint: disable=import-outside-toplevel + from c2cgeoportal_commons.models import ( + DBSession, # pylint: disable=import-outside-toplevel + ) + from c2cgeoportal_commons.models.main import ( + Theme, # pylint: disable=import-outside-toplevel + ) assert DBSession is not None @@ -332,7 +337,9 @@ def _collect_app_config(self, filename: str) -> list[Message]: DBSession, DBSessions, ) - from c2cgeoportal_commons.models.main import Metadata # pylint: disable=import-outside-toplevel + from c2cgeoportal_commons.models.main import ( + Metadata, # pylint: disable=import-outside-toplevel + ) assert DBSession is not None @@ -385,7 +392,7 @@ def _collect_app_config(self, filename: str) -> list[Message]: interface_config.get("constants", {}) .get("gmfDisplayQueryGridOptions", {}) .get("mergeTabs", {}) - .keys() + ): location = ( f"interfaces_config/{interface}/constants/gmfDisplayQueryGridOptions/" @@ -479,7 +486,9 @@ def __call__( try: init_db(self.config) - from c2cgeoportal_commons.models import DBSession # pylint: disable=import-outside-toplevel + from c2cgeoportal_commons.models import ( + DBSession, # pylint: disable=import-outside-toplevel + ) assert DBSession is not None @@ -588,8 +597,12 @@ def _import( has_interfaces: bool = True, name_regex: str = ".*", ) -> None: - from c2cgeoportal_commons.models import DBSession # pylint: disable=import-outside-toplevel - from c2cgeoportal_commons.models.main import Interface # pylint: disable=import-outside-toplevel + from c2cgeoportal_commons.models import ( + DBSession, # pylint: disable=import-outside-toplevel + ) + from c2cgeoportal_commons.models.main import ( + Interface, # pylint: disable=import-outside-toplevel + ) assert DBSession is not None @@ -667,8 +680,12 @@ def _import_layer_wms(self, layer: "main.Layer", messages: list[str]) -> None: raise def _import_layer_wmts(self, layer: "main.Layer", messages: list[str]) -> None: - from c2cgeoportal_commons.models import DBSession # pylint: disable=import-outside-toplevel - from c2cgeoportal_commons.models.main import OGCServer # pylint: disable=import-outside-toplevel + from c2cgeoportal_commons.models import ( + DBSession, # pylint: disable=import-outside-toplevel + ) + from c2cgeoportal_commons.models.main import ( + OGCServer, # pylint: disable=import-outside-toplevel + ) assert DBSession is not None diff --git a/geoportal/c2cgeoportal_geoportal/lib/oauth2.py b/geoportal/c2cgeoportal_geoportal/lib/oauth2.py index a43daed74f3..83c04bea8b7 100644 --- a/geoportal/c2cgeoportal_geoportal/lib/oauth2.py +++ b/geoportal/c2cgeoportal_geoportal/lib/oauth2.py @@ -30,12 +30,12 @@ from typing import Any, TypedDict import basicauth +import c2cgeoportal_commons import oauthlib.common import oauthlib.oauth2 import pyramid.threadlocal from pyramid.httpexceptions import HTTPBadRequest -import c2cgeoportal_commons from c2cgeoportal_geoportal.lib.caching import get_region _LOG = logging.getLogger(__name__) @@ -74,7 +74,6 @@ def authenticate_client( request.client_id for client_id in the URL query. Keyword Arguments: - request: oauthlib.common.Request Returns: True or False @@ -86,6 +85,7 @@ def authenticate_client( - Refresh Token Grant .. _`HTTP Basic Authentication Scheme`: https://tools.ietf.org/html/rfc1945#section-11.1 + """ del args, kwargs @@ -117,7 +117,10 @@ def authenticate_client_id( _LOG.debug("authenticate_client_id %s", client_id) - from c2cgeoportal_commons.models import DBSession, static # pylint: disable=import-outside-toplevel + from c2cgeoportal_commons.models import ( # pylint: disable=import-outside-toplevel + DBSession, + static, + ) assert DBSession is not None @@ -164,7 +167,6 @@ def client_authentication_required( `Section 6`_ Keyword Arguments: - request: oauthlib.common.Request Returns: True or False @@ -177,6 +179,7 @@ def client_authentication_required( .. _`Section 4.3.2`: https://tools.ietf.org/html/rfc6749#section-4.3.2 .. _`Section 4.1.3`: https://tools.ietf.org/html/rfc6749#section-4.1.3 .. _`Section 6`: https://tools.ietf.org/html/rfc6749#section-6 + """ del request, args, kwargs @@ -206,7 +209,6 @@ def confirm_redirect_uri( code was saved. Keyword Arguments: - client_id: Unicode client identifier code: Unicode authorization_code. redirect_uri: Unicode absolute URI @@ -217,12 +219,16 @@ def confirm_redirect_uri( Method is used by: - Authorization Code Grant (during token request) + """ del args, kwargs _LOG.debug("confirm_redirect_uri %s %s", client_id, redirect_uri) - from c2cgeoportal_commons.models import DBSession, static # pylint: disable=import-outside-toplevel + from c2cgeoportal_commons.models import ( # pylint: disable=import-outside-toplevel + DBSession, + static, + ) assert DBSession is not None @@ -249,7 +255,6 @@ def get_default_redirect_uri( Get the default redirect URI for the client. Keyword Arguments: - client_id: Unicode client identifier request: The HTTP Request @@ -258,6 +263,7 @@ def get_default_redirect_uri( Method is used by: - Authorization Code Grant - Implicit Grant + """ del request, args, kwargs @@ -276,7 +282,6 @@ def get_default_scopes( Get the default scopes for the client. Keyword Arguments: - client_id: Unicode client identifier request: The HTTP Request @@ -287,6 +292,7 @@ def get_default_scopes( - Implicit Grant - Resource Owner Password Credentials Grant - Client Credentials grant + """ del request, args, kwargs @@ -305,7 +311,6 @@ def get_original_scopes( Get the list of scopes associated with the refresh token. Keyword Arguments: - refresh_token: Unicode refresh token request: The HTTP Request @@ -313,6 +318,7 @@ def get_original_scopes( Method is used by: - Refresh token grant + """ del refresh_token, request, args, kwargs @@ -353,7 +359,6 @@ def introspect_token( The dict of claims is added to request.token after this method. Keyword Arguments: - token: The token string. token_type_hint: access_token or refresh_token. request: OAuthlib request. @@ -363,6 +368,7 @@ def introspect_token( .. _`Introspect Claims`: https://tools.ietf.org/html/rfc7662#section-2.2 .. _`JWT Claims`: https://tools.ietf.org/html/rfc7519#section-4 + """ del token, request, args, kwargs @@ -382,19 +388,22 @@ def invalidate_authorization_code( Invalidate an authorization code after use. Keyword Arguments: - client_id: Unicode client identifier code: The authorization code grant (request.code). request: The HTTP Request Method is used by: - Authorization Code Grant + """ del args, kwargs _LOG.debug("invalidate_authorization_code %s", client_id) - from c2cgeoportal_commons.models import DBSession, static # pylint: disable=import-outside-toplevel + from c2cgeoportal_commons.models import ( # pylint: disable=import-outside-toplevel + DBSession, + static, + ) assert DBSession is not None @@ -427,13 +436,13 @@ def is_within_original_scope( get_original_scopes is not practical. Keyword Arguments: - request_scopes: A list of scopes that were requested by client refresh_token: Unicode refresh_token request: The HTTP Request Method is used by: - Refresh token grant + """ del request, args, kwargs @@ -453,13 +462,13 @@ def revoke_token( Revoke an access or refresh token. Keyword Arguments: - token: The token string. token_type_hint: access_token or refresh_token. request: The HTTP Request Method is used by: - Revocation Endpoint + """ del token, request, args, kwargs @@ -476,11 +485,11 @@ def rotate_refresh_token(self, request: oauthlib.common.Request) -> bool: and False for keeping original. Keyword Arguments: - request: oauthlib.common.Request Method is used by: - Refresh Token Grant + """ del request @@ -516,7 +525,6 @@ def save_authorization_code( 'validate_code'. Keyword Arguments: - client_id: Unicode client identifier code: A dict of the authorization code grant and, optionally, state. request: The HTTP Request @@ -528,12 +536,16 @@ def save_authorization_code( Code Challenge (request.code_challenge) and Code Challenge Method (request.code_challenge_method) + """ del args, kwargs _LOG.debug("save_authorization_code %s", client_id) - from c2cgeoportal_commons.models import DBSession, static # pylint: disable=import-outside-toplevel + from c2cgeoportal_commons.models import ( # pylint: disable=import-outside-toplevel + DBSession, + static, + ) assert DBSession is not None @@ -605,7 +617,6 @@ def save_bearer_token( the original list is still available in request.scopes Keyword Arguments: - client_id: Unicode client identifier token: A Bearer token dict request: The HTTP Request @@ -617,12 +628,16 @@ def save_bearer_token( - Implicit Grant - Resource Owner Password Credentials Grant (might not associate a client) - Client Credentials grant + """ del args, kwargs _LOG.debug("save_bearer_token") - from c2cgeoportal_commons.models import DBSession, static # pylint: disable=import-outside-toplevel + from c2cgeoportal_commons.models import ( # pylint: disable=import-outside-toplevel + DBSession, + static, + ) assert DBSession is not None @@ -655,7 +670,6 @@ def validate_bearer_token( Ensure the Bearer token is valid and authorized access to scopes. Keyword Arguments: - token: A string of random characters. scopes: A list of scopes associated with the protected resource. request: The HTTP Request @@ -691,7 +705,6 @@ def validate_bearer_token( in all protected views as keyword arguments. Keyword Arguments: - token: Unicode Bearer token scopes: List of scopes (defined by you) request: The HTTP Request @@ -701,11 +714,14 @@ def validate_bearer_token( - Implicit Grant - Resource Owner Password Credentials Grant - Client Credentials Grant - """ + """ _LOG.debug("validate_bearer_token %s", scopes) - from c2cgeoportal_commons.models import DBSession, static # pylint: disable=import-outside-toplevel + from c2cgeoportal_commons.models import ( # pylint: disable=import-outside-toplevel + DBSession, + static, + ) assert DBSession is not None @@ -737,19 +753,22 @@ def validate_client_id( given client_id. Keyword Arguments: - client_id: Unicode client identifier request: oauthlib.common.Request Method is used by: - Authorization Code Grant - Implicit Grant + """ del args, kwargs _LOG.debug("validate_client_id") - from c2cgeoportal_commons.models import DBSession, static # pylint: disable=import-outside-toplevel + from c2cgeoportal_commons.models import ( # pylint: disable=import-outside-toplevel + DBSession, + static, + ) assert DBSession is not None @@ -785,7 +804,6 @@ def validate_code( must also be set. Keyword Arguments: - client_id: Unicode client identifier code: Unicode authorization code client: Client object set by you, see authenticate_client. @@ -793,12 +811,16 @@ def validate_code( Method is used by: - Authorization Code Grant + """ del args, kwargs _LOG.debug("validate_code %s", client_id) - from c2cgeoportal_commons.models import DBSession, static # pylint: disable=import-outside-toplevel + from c2cgeoportal_commons.models import ( # pylint: disable=import-outside-toplevel + DBSession, + static, + ) assert DBSession is not None @@ -840,7 +862,6 @@ def validate_grant_type( Ensure client is authorized to use the grant_type requested. Keyword Arguments: - client_id: Unicode client identifier grant_type: Unicode grant type, i.e. authorization_code, password. client: Client object set by you, see authenticate_client. @@ -851,6 +872,7 @@ def validate_grant_type( - Resource Owner Password Credentials Grant - Client Credentials Grant - Refresh Token Grant + """ del client, request, args, kwargs @@ -878,7 +900,6 @@ def validate_redirect_uri( to redirect to. The registration is outside of the scope of oauthlib. Keyword Arguments: - client_id: Unicode client identifier redirect_uri: Unicode absolute URI request: The HTTP Request @@ -886,12 +907,16 @@ def validate_redirect_uri( Method is used by: - Authorization Code Grant - Implicit Grant + """ del request, args, kwargs _LOG.debug("validate_redirect_uri %s %s", client_id, redirect_uri) - from c2cgeoportal_commons.models import DBSession, static # pylint: disable=import-outside-toplevel + from c2cgeoportal_commons.models import ( # pylint: disable=import-outside-toplevel + DBSession, + static, + ) assert DBSession is not None @@ -919,7 +944,6 @@ def validate_refresh_token( associated with this refresh token. Keyword Arguments: - refresh_token: Unicode refresh token client: Client object set by you, see authenticate_client. request: The HTTP Request @@ -928,12 +952,16 @@ def validate_refresh_token( - Authorization Code Grant (indirectly by issuing refresh tokens) - Resource Owner Password Credentials Grant (also indirectly) - Refresh Token Grant + """ del args, kwargs _LOG.debug("validate_refresh_token %s", client.client_id if client else None) - from c2cgeoportal_commons.models import DBSession, static # pylint: disable=import-outside-toplevel + from c2cgeoportal_commons.models import ( # pylint: disable=import-outside-toplevel + DBSession, + static, + ) assert DBSession is not None @@ -962,7 +990,6 @@ def validate_response_type( Ensure client is authorized to use the response_type requested. Keyword Arguments: - client_id: Unicode client identifier response_type: Unicode response type, i.e. code, token. client: Client object set by you, see authenticate_client. @@ -971,6 +998,7 @@ def validate_response_type( Method is used by: - Authorization Code Grant - Implicit Grant + """ del client, request, args, kwargs @@ -991,7 +1019,6 @@ def validate_scopes( Ensure the client is authorized access to requested scopes. Keyword Arguments: - client_id: Unicode client identifier scopes: List of scopes (defined by you) client: Client object set by you, see authenticate_client. @@ -1002,6 +1029,7 @@ def validate_scopes( - Implicit Grant - Resource Owner Password Credentials Grant - Client Credentials Grant + """ del client, request, args, kwargs @@ -1027,7 +1055,6 @@ def validate_user( persistence method used (commonly, save_bearer_token). Keyword Arguments: - username: Unicode username password: Unicode password client: Client object set by you, see authenticate_client. @@ -1035,6 +1062,7 @@ def validate_user( Method is used by: - Resource Owner Password Credentials Grant + """ del password, client, request, args, kwargs @@ -1057,7 +1085,6 @@ def is_pkce_required(self, client_id: int, request: oauthlib.common.Request) -> (PKCE, pronounced “pixy”). See RFC7636. Keyword Arguments: - client_id: Client identifier. request (oauthlib.common.Request): OAuthlib request. @@ -1068,7 +1095,10 @@ def is_pkce_required(self, client_id: int, request: oauthlib.common.Request) -> """ - from c2cgeoportal_commons.models import DBSession, static # pylint: disable=import-outside-toplevel + from c2cgeoportal_commons.models import ( # pylint: disable=import-outside-toplevel + DBSession, + static, + ) assert DBSession is not None @@ -1097,19 +1127,21 @@ def get_code_challenge(self, code: str, request: oauthlib.common.Request) -> str be associated to any challenges. Keyword Arguments: - code: Authorization code. request: OAuthlib request. Return: - code_challenge string Method is used by: Authorization Code Grant - when PKCE is active + """ - from c2cgeoportal_commons.models import DBSession, static # pylint: disable=import-outside-toplevel + from c2cgeoportal_commons.models import ( # pylint: disable=import-outside-toplevel + DBSession, + static, + ) assert DBSession is not None @@ -1137,7 +1169,6 @@ def get_code_challenge_method(self, code: str, request: oauthlib.common.Request) AuthorizationCodeGrant class. Keyword Arguments: - code: Authorization code. request: OAuthlib request. @@ -1148,8 +1179,12 @@ def get_code_challenge_method(self, code: str, request: oauthlib.common.Request) Method is used by: Authorization Code Grant - when PKCE is active + """ - from c2cgeoportal_commons.models import DBSession, static # pylint: disable=import-outside-toplevel + from c2cgeoportal_commons.models import ( # pylint: disable=import-outside-toplevel + DBSession, + static, + ) assert DBSession is not None diff --git a/geoportal/c2cgeoportal_geoportal/lib/oidc.py b/geoportal/c2cgeoportal_geoportal/lib/oidc.py index 083aa2b116e..71964b445c1 100644 --- a/geoportal/c2cgeoportal_geoportal/lib/oidc.py +++ b/geoportal/c2cgeoportal_geoportal/lib/oidc.py @@ -34,7 +34,11 @@ import pyramid.response import simple_openid_connect.client import simple_openid_connect.data -from pyramid.httpexceptions import HTTPBadRequest, HTTPInternalServerError, HTTPUnauthorized +from pyramid.httpexceptions import ( + HTTPBadRequest, + HTTPInternalServerError, + HTTPUnauthorized, +) from pyramid.security import remember from c2cgeoportal_geoportal.lib.caching import get_region @@ -48,9 +52,7 @@ # User create on demand class DynamicUser(NamedTuple): - """ - User created dynamically. - """ + """User created dynamically.""" id: int username: str @@ -62,10 +64,7 @@ class DynamicUser(NamedTuple): @_CACHE_REGION_OBJ.cache_on_arguments() def get_oidc_client(request: pyramid.request.Request, host: str) -> simple_openid_connect.client.OpenidClient: - """ - Get the OpenID Connect client from the request settings. - """ - + """Get the OpenID Connect client from the request settings.""" del host # used for cache key authentication_settings = request.registry.settings.get("authentication", {}) @@ -83,9 +82,7 @@ def get_oidc_client(request: pyramid.request.Request, host: str) -> simple_openi class OidcRememberObject(TypedDict): - """ - The JSON object that is stored in a cookie to remember the user. - """ + """The JSON object that is stored in a cookie to remember the user.""" access_token: str access_token_expires: str @@ -146,11 +143,13 @@ def get_user_from_remember( :param settings: The OpenID Connect configuration. :param update_create_user: If the user should be updated or created if it does not exist. """ - # Those imports are here to avoid initializing the models module before the database schema are # correctly initialized. from c2cgeoportal_commons import models # pylint: disable=import-outside-toplevel - from c2cgeoportal_commons.models import main, static # pylint: disable=import-outside-toplevel + from c2cgeoportal_commons.models import ( # pylint: disable=import-outside-toplevel + main, + static, + ) assert models.DBSession is not None @@ -213,9 +212,7 @@ def get_user_from_remember( class OidcRemember: - """ - Build the abject that we want to remember in the cookie. - """ + """Build the abject that we want to remember in the cookie.""" def __init__(self, request: pyramid.request.Request): self.request = request @@ -229,10 +226,7 @@ def remember( ), host: str, ) -> OidcRememberObject: - """ - Remember the user in the cookie. - """ - + """Remember the user in the cookie.""" del host # Used for cache key if isinstance(token_response, simple_openid_connect.data.TokenErrorResponse): @@ -297,8 +291,6 @@ def remember( def includeme(config: pyramid.config.Configurator) -> None: - """ - Pyramid includeme function. - """ + """Pyramid includeme function.""" config.add_request_method(get_remember_from_user_info, name="get_remember_from_user_info") config.add_request_method(get_user_from_remember, name="get_user_from_remember") diff --git a/geoportal/c2cgeoportal_geoportal/lib/wmstparsing.py b/geoportal/c2cgeoportal_geoportal/lib/wmstparsing.py index c6d4c1d7f1d..3ea748cf4ee 100644 --- a/geoportal/c2cgeoportal_geoportal/lib/wmstparsing.py +++ b/geoportal/c2cgeoportal_geoportal/lib/wmstparsing.py @@ -57,10 +57,10 @@ class TimeInformation: Collect the WMS time information. Arguments: - extent: A time extent instance (``TimeExtentValue`` or ``TimeExtentInterval``) mode: The layer mode ("single", "range" or "disabled") widget: The layer mode ("slider" (default) or "datepicker") + """ def __init__(self) -> None: @@ -98,7 +98,7 @@ def merge_mode(self, mode: str) -> None: self.mode = mode def merge_widget(self, widget: str | None) -> None: - widget = "slider" if not widget else widget + widget = widget if widget else "slider" assert widget is not None if self.widget is not None: @@ -134,11 +134,11 @@ def __init__( Initialize. Arguments: - values: A set() of datetime resolution: The resolution from the mapfile time definition min_def_value: the minimum default value as a datetime max_def_value: the maximum default value as a datetime + """ self.values = values self.resolution = resolution @@ -183,13 +183,13 @@ def __init__( Initialize. Arguments: - start: The start value as a datetime end: The end value as a datetime interval: The interval as a tuple (years, months, days, seconds) resolution: The resolution from the mapfile time definition min_def_value: the minimum default value as a datetime max_def_value: the maximum default value as a datetime + """ self.start = start self.end = end diff --git a/geoportal/c2cgeoportal_geoportal/lib/xsd.py b/geoportal/c2cgeoportal_geoportal/lib/xsd.py index 96611f793e5..43f6ae1cf64 100644 --- a/geoportal/c2cgeoportal_geoportal/lib/xsd.py +++ b/geoportal/c2cgeoportal_geoportal/lib/xsd.py @@ -42,10 +42,9 @@ def _element_callback(tb: str, column: sqlalchemy.sql.elements.NamedColumn[Any]) -> None: if column.info.get("readonly"): - with tag(tb, "xsd:annotation"): - with tag(tb, "xsd:appinfo"): - with tag(tb, "readonly", {"value": "true"}): - pass + with tag(tb, "xsd:annotation"), tag(tb, "xsd:appinfo"): + with tag(tb, "readonly", {"value": "true"}): + pass class XSDGenerator(PapyrusXSDGenerator): # type: ignore @@ -105,7 +104,9 @@ def add_column_property_xsd(self, tb: str, column_property: ColumnProperty[Any]) super().add_column_property_xsd(tb, column_property) def add_association_proxy_xsd(self, tb: str, column_property: ColumnProperty[Any]) -> None: - from c2cgeoportal_commons.models import DBSession # pylint: disable=import-outside-toplevel + from c2cgeoportal_commons.models import ( + DBSession, # pylint: disable=import-outside-toplevel + ) assert DBSession is not None diff --git a/geoportal/c2cgeoportal_geoportal/scripts/c2cupgrade.py b/geoportal/c2cgeoportal_geoportal/scripts/c2cupgrade.py index dd311ef5137..3d863eef133 100644 --- a/geoportal/c2cgeoportal_geoportal/scripts/c2cupgrade.py +++ b/geoportal/c2cgeoportal_geoportal/scripts/c2cupgrade.py @@ -38,7 +38,7 @@ from collections.abc import Callable from json.decoder import JSONDecodeError from subprocess import call, check_call, check_output -from typing import Any, Union, cast +from typing import Any, cast import pkg_resources import requests @@ -176,7 +176,7 @@ def get_upgrade(section: str) -> list[Any] | dict[str, Any]: sys.exit(1) with open(".upgrade.yaml", encoding="utf8") as project_file: - return cast(Union[list[Any], dict[str, Any]], yaml.safe_load(project_file)[section]) + return cast(list[Any] | dict[str, Any], yaml.safe_load(project_file)[section]) def print_step( self, @@ -603,10 +603,7 @@ def is_managed(self, file_: str, files_to_get: bool = False) -> bool: if not managed: for files in self.project["managed_files"]: - if isinstance(files, str): - pattern = files - else: - pattern = files["pattern"] + pattern = files if isinstance(files, str) else files["pattern"] if re.match(pattern + "$", file_): print(f"File '{file_}' included by project config pattern `managed_files` '{pattern}'.") print("managed", file_, pattern) diff --git a/geoportal/c2cgeoportal_geoportal/scripts/manage_users.py b/geoportal/c2cgeoportal_geoportal/scripts/manage_users.py index 9890e2ed825..754f67712d9 100644 --- a/geoportal/c2cgeoportal_geoportal/scripts/manage_users.py +++ b/geoportal/c2cgeoportal_geoportal/scripts/manage_users.py @@ -37,7 +37,6 @@ def get_argparser() -> argparse.ArgumentParser: """Get the argument parser for this script.""" - usage = """Reset a user password. The username is used as password if the password is not provided with the corresponding option. User can be created if it does not exist yet.""" @@ -66,7 +65,6 @@ def main() -> None: to get the options list, do: docker compose exec geoportal manage-users --help """ - parser = get_argparser() options = parser.parse_args() username = options.user @@ -76,8 +74,12 @@ def main() -> None: session = get_session(settings, transaction.manager) # Must be done only once we have loaded the project config - from c2cgeoportal_commons.models.main import Role # pylint: disable=import-outside-toplevel - from c2cgeoportal_commons.models.static import User # pylint: disable=import-outside-toplevel + from c2cgeoportal_commons.models.main import ( + Role, # pylint: disable=import-outside-toplevel + ) + from c2cgeoportal_commons.models.static import ( + User, # pylint: disable=import-outside-toplevel + ) print("\n") diff --git a/geoportal/c2cgeoportal_geoportal/scripts/pcreate.py b/geoportal/c2cgeoportal_geoportal/scripts/pcreate.py index c292b002d9f..6422bbca2fd 100644 --- a/geoportal/c2cgeoportal_geoportal/scripts/pcreate.py +++ b/geoportal/c2cgeoportal_geoportal/scripts/pcreate.py @@ -32,7 +32,7 @@ import subprocess import sys from argparse import ArgumentParser -from typing import Any, Union, cast +from typing import Any, cast import pkg_resources import requests @@ -46,7 +46,6 @@ def get_argparser() -> ArgumentParser: """Get the argument parser for this script.""" - parser = ArgumentParser( prog=sys.argv[0], add_help=True, @@ -246,7 +245,7 @@ def read_project_file(self) -> dict[str, str | int]: if os.path.exists(project_file): with open(project_file, encoding="utf8") as f: project = yaml.safe_load(f) - return cast(dict[str, Union[str, int]], project.get("template_vars", {})) + return cast(dict[str, str | int], project.get("template_vars", {})) else: return {} @@ -280,16 +279,12 @@ def epsg2bbox(srid: int) -> list[str] | None: r = requests.get(f"https://epsg.io/?format=json&q={srid}", timeout=60) bbox = r.json()["results"][0]["bbox"] r = requests.get( - "https://epsg.io/trans?s_srs=4326&t_srs={srid}&data={bbox[1]},{bbox[0]}".format( - srid=srid, bbox=bbox - ), + f"https://epsg.io/trans?s_srs=4326&t_srs={srid}&data={bbox[1]},{bbox[0]}", timeout=60, ) r1 = r.json()[0] r = requests.get( - "https://epsg.io/trans?s_srs=4326&t_srs={srid}&data={bbox[3]},{bbox[2]}".format( - srid=srid, bbox=bbox - ), + f"https://epsg.io/trans?s_srs=4326&t_srs={srid}&data={bbox[3]},{bbox[2]}", timeout=60, ) r2 = r.json()[0] diff --git a/geoportal/c2cgeoportal_geoportal/scripts/theme2fts.py b/geoportal/c2cgeoportal_geoportal/scripts/theme2fts.py index 3256786eff3..92d615f9102 100644 --- a/geoportal/c2cgeoportal_geoportal/scripts/theme2fts.py +++ b/geoportal/c2cgeoportal_geoportal/scripts/theme2fts.py @@ -95,7 +95,6 @@ def get_argparser() -> ArgumentParser: def main() -> None: """Run the command.""" - options = get_argparser().parse_args() settings = get_appsettings(options) @@ -180,7 +179,9 @@ def _add_fts( action: str, role: Optional["c2cgeoportal_commons.models.main.Role"], ) -> None: - from c2cgeoportal_commons.models.main import FullTextSearch # pylint: disable=import-outside-toplevel + from c2cgeoportal_commons.models.main import ( + FullTextSearch, # pylint: disable=import-outside-toplevel + ) key = ( item.name if self.options.name else item.id, @@ -248,7 +249,9 @@ def _add_group( export: bool, role: Optional["c2cgeoportal_commons.models.main.Role"], ) -> bool: - from c2cgeoportal_commons.models.main import LayerGroup # pylint: disable=import-outside-toplevel + from c2cgeoportal_commons.models.main import ( + LayerGroup, # pylint: disable=import-outside-toplevel + ) fill = False for child in group.children: diff --git a/geoportal/c2cgeoportal_geoportal/scripts/urllogin.py b/geoportal/c2cgeoportal_geoportal/scripts/urllogin.py index bedf0e61536..a1fb840214d 100644 --- a/geoportal/c2cgeoportal_geoportal/scripts/urllogin.py +++ b/geoportal/c2cgeoportal_geoportal/scripts/urllogin.py @@ -56,7 +56,6 @@ def create_token(aeskey: str, user: str, password: str, valid: bool) -> str: def get_argparser() -> argparse.ArgumentParser: """Get the argument parser for this script.""" - parser = argparse.ArgumentParser(description="Generate an auth token") fill_arguments(parser, use_attribute=True) parser.add_argument("user", help="The username") @@ -67,7 +66,6 @@ def get_argparser() -> argparse.ArgumentParser: def main() -> None: """Run the command.""" - args = get_argparser().parse_args() settings = get_appsettings(args) urllogin = settings.get("urllogin", {}) diff --git a/geoportal/c2cgeoportal_geoportal/views/dev.py b/geoportal/c2cgeoportal_geoportal/views/dev.py index dc11dad84f6..240eb742452 100644 --- a/geoportal/c2cgeoportal_geoportal/views/dev.py +++ b/geoportal/c2cgeoportal_geoportal/views/dev.py @@ -31,10 +31,10 @@ import pyramid.request import pyramid.response +from c2cgeoportal_commons.lib.url import Url from pyramid.httpexceptions import HTTPFound from pyramid.view import view_config -from c2cgeoportal_commons.lib.url import Url from c2cgeoportal_geoportal.views.proxy import Proxy logger = logging.getLogger(__name__) diff --git a/geoportal/c2cgeoportal_geoportal/views/dynamic.py b/geoportal/c2cgeoportal_geoportal/views/dynamic.py index 7441ab71ab6..b12813a7a20 100644 --- a/geoportal/c2cgeoportal_geoportal/views/dynamic.py +++ b/geoportal/c2cgeoportal_geoportal/views/dynamic.py @@ -31,12 +31,12 @@ from typing import Any, cast import pyramid.request +from c2cgeoportal_commons import models +from c2cgeoportal_commons.models import main from pyramid.httpexceptions import HTTPNotFound from pyramid.view import view_config from sqlalchemy import func -from c2cgeoportal_commons import models -from c2cgeoportal_commons.models import main from c2cgeoportal_geoportal import is_allowed_host from c2cgeoportal_geoportal.lib.cacheversion import get_cache_version from c2cgeoportal_geoportal.lib.caching import get_region @@ -78,13 +78,12 @@ def _interface( Get the interface configuration. Arguments: - interface_config: Current interface configuration interface_name: Interface name (we use in the configuration) original_interface_name: Original interface name (directly for the query string) dynamic: The values that's dynamically generated - """ + """ if "extends" in interface_config: constants = self._interface( self.interfaces_config[interface_config["extends"]], diff --git a/geoportal/c2cgeoportal_geoportal/views/entry.py b/geoportal/c2cgeoportal_geoportal/views/entry.py index ec566170c3f..444008d203f 100644 --- a/geoportal/c2cgeoportal_geoportal/views/entry.py +++ b/geoportal/c2cgeoportal_geoportal/views/entry.py @@ -114,7 +114,6 @@ def _get_ngeo_resources(pattern: str) -> list[str]: def canvas_view(request: pyramid.request.Request, interface_config: dict[str, Any]) -> dict[str, Any]: """Get view used as entry point of a canvas interface.""" - js_files = _get_ngeo_resources(f"{interface_config.get('layout', interface_config['name'])}*.js") css_files = _get_ngeo_resources(f"{interface_config.get('layout', interface_config['name'])}*.css") css = "\n ".join( @@ -149,7 +148,6 @@ def custom_view( request: pyramid.request.Request, interface_config: dict[str, Any] ) -> pyramid.response.Response: """Get view used as entry point of a canvas interface.""" - set_common_headers(request, "index", Cache.PUBLIC_NO, content_type="text/html") html_filename = interface_config.get("html_filename", f"{interface_config['name']}.html") diff --git a/geoportal/c2cgeoportal_geoportal/views/fulltextsearch.py b/geoportal/c2cgeoportal_geoportal/views/fulltextsearch.py index d2f1f8cbd15..ee041b8e21e 100644 --- a/geoportal/c2cgeoportal_geoportal/views/fulltextsearch.py +++ b/geoportal/c2cgeoportal_geoportal/views/fulltextsearch.py @@ -29,14 +29,14 @@ import re import pyramid.request +from c2cgeoportal_commons.models import DBSession +from c2cgeoportal_commons.models.main import FullTextSearch, Interface from geoalchemy2.shape import to_shape from geojson import Feature, FeatureCollection from pyramid.httpexceptions import HTTPBadRequest, HTTPInternalServerError from pyramid.view import view_config from sqlalchemy import ColumnElement, and_, desc, func, or_ -from c2cgeoportal_commons.models import DBSession -from c2cgeoportal_commons.models.main import FullTextSearch, Interface from c2cgeoportal_geoportal import locale_negotiator from c2cgeoportal_geoportal.lib.caching import get_region from c2cgeoportal_geoportal.lib.common_headers import Cache, set_common_headers diff --git a/geoportal/c2cgeoportal_geoportal/views/geometry_processing.py b/geoportal/c2cgeoportal_geoportal/views/geometry_processing.py index 47f66abdc77..de7620570db 100644 --- a/geoportal/c2cgeoportal_geoportal/views/geometry_processing.py +++ b/geoportal/c2cgeoportal_geoportal/views/geometry_processing.py @@ -27,6 +27,7 @@ import pyramid.request +from c2cgeoportal_commons.models import DBSession from geoalchemy2.shape import from_shape, to_shape from geojson import loads from pyramid.httpexceptions import HTTPBadRequest @@ -35,8 +36,6 @@ from shapely.geometry.base import BaseGeometry from sqlalchemy import func -from c2cgeoportal_commons.models import DBSession - class GeometryProcessing: """ diff --git a/geoportal/c2cgeoportal_geoportal/views/i18n.py b/geoportal/c2cgeoportal_geoportal/views/i18n.py index aa21d76eed7..5e7cdb1e781 100644 --- a/geoportal/c2cgeoportal_geoportal/views/i18n.py +++ b/geoportal/c2cgeoportal_geoportal/views/i18n.py @@ -68,7 +68,6 @@ def locale(request: pyramid.request.Request) -> pyramid.response.Response: @view_config(route_name="localepot") # type: ignore def localepot(request: pyramid.request.Request) -> pyramid.response.Response: """Get the pot from an HTTP request.""" - # Build the list of files to be processed sources = [] sources += glob.glob(f"/app/{request.registry.package_name}/static-ngeo/js/apps/*.html.ejs") diff --git a/geoportal/c2cgeoportal_geoportal/views/layers.py b/geoportal/c2cgeoportal_geoportal/views/layers.py index 491d2a8e145..468f13be411 100644 --- a/geoportal/c2cgeoportal_geoportal/views/layers.py +++ b/geoportal/c2cgeoportal_geoportal/views/layers.py @@ -40,6 +40,7 @@ import sqlalchemy.ext.declarative import sqlalchemy.orm import sqlalchemy.orm.query +from c2cgeoportal_commons import models from geoalchemy2 import Geometry from geoalchemy2.shape import from_shape, to_shape from geojson.feature import Feature, FeatureCollection @@ -56,19 +57,27 @@ from shapely import unary_union from shapely.errors import TopologicalError from sqlalchemy import Enum, Numeric, String, Text, Unicode, UnicodeText, exc, func -from sqlalchemy.orm.exc import MultipleResultsFound, NoResultFound # type: ignore[attr-defined] +from sqlalchemy.orm.exc import ( # type: ignore[attr-defined] + MultipleResultsFound, + NoResultFound, +) from sqlalchemy.orm.properties import ColumnProperty from sqlalchemy.orm.util import class_mapper from sqlalchemy.sql import and_, or_ -from c2cgeoportal_commons import models from c2cgeoportal_geoportal.lib import get_roles_id from c2cgeoportal_geoportal.lib.caching import get_region from c2cgeoportal_geoportal.lib.common_headers import Cache, set_common_headers -from c2cgeoportal_geoportal.lib.dbreflection import _AssociationProxy, get_class, get_table +from c2cgeoportal_geoportal.lib.dbreflection import ( + _AssociationProxy, + get_class, + get_table, +) if TYPE_CHECKING: - from c2cgeoportal_commons.models import main # pylint: disable=ungrouped-imports.useless-suppression + from c2cgeoportal_commons.models import ( + main, # pylint: disable=ungrouped-imports.useless-suppression + ) _LOG = logging.getLogger(__name__) @@ -222,7 +231,9 @@ def _get_geom_col_info(layer: "main.Layer") -> tuple[str, int]: @staticmethod def _get_layer(layer_id: int) -> "main.Layer": """Return a ``Layer`` object for ``layer_id``.""" - from c2cgeoportal_commons.models.main import Layer # pylint: disable=import-outside-toplevel + from c2cgeoportal_commons.models.main import ( + Layer, # pylint: disable=import-outside-toplevel + ) assert models.DBSession is not None @@ -281,7 +292,6 @@ def _get_protocol_for_request(self) -> Protocol: def _proto_read(self, layer: "main.Layer") -> FeatureCollection: """Read features for the layer based on the self.request.""" - from c2cgeoportal_commons.models.main import ( # pylint: disable=import-outside-toplevel Layer, RestrictionArea, @@ -541,15 +551,14 @@ def get_layer_class(layer: "main.Layer", with_last_update_columns: bool = False) Get the SQLAlchemy class to edit a GeoMapFish layer. Keyword Arguments: - layer: The GeoMapFish layer with_last_update_columns: False to just have a class to access to the table and be able to modify the last_update_columns, True to have a correct class to build the UI (without the hidden column). Returns: SQLAlchemy class - """ + """ assert layer.geo_table is not None # Exclude the columns used to record the last features update @@ -616,7 +625,6 @@ class ColumnProperties(TypedDict, total=False): def get_layer_metadata(layer: "main.Layer") -> list[ColumnProperties]: """Get the metadata related to a layer.""" - assert models.DBSession is not None cls = get_layer_class(layer, with_last_update_columns=True) @@ -690,7 +698,7 @@ def _convert_column_type(column_type: object) -> ColumnProperties: return restriction # String type - if isinstance(column_type, (String, Text, Unicode, UnicodeText)): + if isinstance(column_type, String | Text | Unicode | UnicodeText): if column_type.length is None: return {"type": "xsd:string"} return {"type": "xsd:string", "maxLength": int(column_type.length)} diff --git a/geoportal/c2cgeoportal_geoportal/views/login.py b/geoportal/c2cgeoportal_geoportal/views/login.py index 2d812a3c94b..acecbc92c1b 100644 --- a/geoportal/c2cgeoportal_geoportal/views/login.py +++ b/geoportal/c2cgeoportal_geoportal/views/login.py @@ -38,6 +38,9 @@ import pyotp import pyramid.request import pyramid.response +from c2cgeoportal_commons import models +from c2cgeoportal_commons.lib.email_ import send_email_config +from c2cgeoportal_commons.models import static from pyramid.httpexceptions import ( HTTPBadRequest, HTTPForbidden, @@ -50,9 +53,6 @@ from pyramid.view import forbidden_view_config, view_config from sqlalchemy.orm.exc import NoResultFound # type: ignore[attr-defined] -from c2cgeoportal_commons import models -from c2cgeoportal_commons.lib.email_ import send_email_config -from c2cgeoportal_commons.models import static from c2cgeoportal_geoportal import is_allowed_url, is_valid_referrer from c2cgeoportal_geoportal.lib import get_setting, is_intranet, oauth2, oidc from c2cgeoportal_geoportal.lib.common_headers import Cache, set_common_headers @@ -126,9 +126,7 @@ def loginform(self) -> dict[str, Any]: @staticmethod def _validate_2fa_totp(user: static.User, otp: str) -> bool: - if pyotp.TOTP(user.tech_data.get("2fa_totp_secret", "")).verify(otp): - return True - return False + return bool(pyotp.TOTP(user.tech_data.get("2fa_totp_secret", "")).verify(otp)) @view_config(route_name="login") # type: ignore def login(self) -> pyramid.response.Response: diff --git a/geoportal/c2cgeoportal_geoportal/views/mapserverproxy.py b/geoportal/c2cgeoportal_geoportal/views/mapserverproxy.py index 474530112f8..3e9875a416e 100644 --- a/geoportal/c2cgeoportal_geoportal/views/mapserverproxy.py +++ b/geoportal/c2cgeoportal_geoportal/views/mapserverproxy.py @@ -29,13 +29,18 @@ import logging from typing import Any -from pyramid.httpexceptions import HTTPForbidden, HTTPFound, HTTPInternalServerError, HTTPUnauthorized +from c2cgeoportal_commons.lib.url import Url +from c2cgeoportal_commons.models import main +from pyramid.httpexceptions import ( + HTTPForbidden, + HTTPFound, + HTTPInternalServerError, + HTTPUnauthorized, +) from pyramid.request import Request from pyramid.response import Response from pyramid.view import view_config -from c2cgeoportal_commons.lib.url import Url -from c2cgeoportal_commons.models import main from c2cgeoportal_geoportal.lib import get_roles_id, get_roles_name from c2cgeoportal_geoportal.lib.caching import get_region from c2cgeoportal_geoportal.lib.common_headers import Cache diff --git a/geoportal/c2cgeoportal_geoportal/views/ogcproxy.py b/geoportal/c2cgeoportal_geoportal/views/ogcproxy.py index ca0298e3de3..dd1d12c2ca8 100644 --- a/geoportal/c2cgeoportal_geoportal/views/ogcproxy.py +++ b/geoportal/c2cgeoportal_geoportal/views/ogcproxy.py @@ -28,11 +28,11 @@ import logging import pyramid.request +from c2cgeoportal_commons.lib.url import Url, get_url2 +from c2cgeoportal_commons.models import DBSession, main from pyramid.httpexceptions import HTTPBadRequest from sqlalchemy.orm.exc import NoResultFound # type: ignore[attr-defined] -from c2cgeoportal_commons.lib.url import Url, get_url2 -from c2cgeoportal_commons.models import DBSession, main from c2cgeoportal_geoportal.lib.caching import get_region from c2cgeoportal_geoportal.views.proxy import Proxy diff --git a/geoportal/c2cgeoportal_geoportal/views/pdfreport.py b/geoportal/c2cgeoportal_geoportal/views/pdfreport.py index 4342daf0cd1..32d24e7248d 100644 --- a/geoportal/c2cgeoportal_geoportal/views/pdfreport.py +++ b/geoportal/c2cgeoportal_geoportal/views/pdfreport.py @@ -31,12 +31,12 @@ import pyramid.request import pyramid.response -from pyramid.httpexceptions import HTTPBadRequest, HTTPForbidden -from pyramid.view import view_config - from c2cgeoportal_commons import models from c2cgeoportal_commons.lib.url import Url from c2cgeoportal_commons.models import main +from pyramid.httpexceptions import HTTPBadRequest, HTTPForbidden +from pyramid.view import view_config + from c2cgeoportal_geoportal.lib.common_headers import Cache from c2cgeoportal_geoportal.lib.layers import get_private_layers, get_protected_layers from c2cgeoportal_geoportal.views.ogcproxy import OGCProxy diff --git a/geoportal/c2cgeoportal_geoportal/views/printproxy.py b/geoportal/c2cgeoportal_geoportal/views/printproxy.py index a46f2736f88..2cd8bc13840 100644 --- a/geoportal/c2cgeoportal_geoportal/views/printproxy.py +++ b/geoportal/c2cgeoportal_geoportal/views/printproxy.py @@ -33,10 +33,10 @@ import pyramid.request import pyramid.response import requests +from c2cgeoportal_commons.lib.url import Url from pyramid.httpexceptions import HTTPBadGateway, HTTPFound from pyramid.view import view_config -from c2cgeoportal_commons.lib.url import Url from c2cgeoportal_geoportal.lib import is_intranet from c2cgeoportal_geoportal.lib.caching import get_region from c2cgeoportal_geoportal.lib.common_headers import Cache diff --git a/geoportal/c2cgeoportal_geoportal/views/proxy.py b/geoportal/c2cgeoportal_geoportal/views/proxy.py index f18a2c8c805..427308ebcfa 100644 --- a/geoportal/c2cgeoportal_geoportal/views/proxy.py +++ b/geoportal/c2cgeoportal_geoportal/views/proxy.py @@ -33,9 +33,9 @@ import pyramid.request import pyramid.response import requests +from c2cgeoportal_commons.lib.url import Url from pyramid.httpexceptions import HTTPBadGateway, exception_response -from c2cgeoportal_commons.lib.url import Url from c2cgeoportal_geoportal.lib.caching import get_region from c2cgeoportal_geoportal.lib.common_headers import Cache, set_common_headers from c2cgeoportal_geoportal.views import restrict_headers diff --git a/geoportal/c2cgeoportal_geoportal/views/raster.py b/geoportal/c2cgeoportal_geoportal/views/raster.py index 5f476cc2b65..11a0481b592 100644 --- a/geoportal/c2cgeoportal_geoportal/views/raster.py +++ b/geoportal/c2cgeoportal_geoportal/views/raster.py @@ -36,11 +36,11 @@ import numpy import pyramid.request import zope.event.classhandler +from c2cgeoportal_commons.models import InvalidateCacheEvent from pyramid.httpexceptions import HTTPBadRequest, HTTPNotFound from pyramid.view import view_config from rasterio.io import DatasetReader -from c2cgeoportal_commons.models import InvalidateCacheEvent from c2cgeoportal_geoportal.lib.common_headers import Cache, set_common_headers if TYPE_CHECKING: @@ -108,7 +108,9 @@ def _get_data(self, layer: dict[str, Any], name: str) -> "fiona.collection.Colle path = layer["file"] if layer.get("type", "shp_index") == "shp_index": # Avoid loading if not needed - from fiona.collection import Collection # pylint: disable=import-outside-toplevel + from fiona.collection import ( + Collection, # pylint: disable=import-outside-toplevel + ) self.data[name] = Collection(path) elif layer.get("type") == "gdal": diff --git a/geoportal/c2cgeoportal_geoportal/views/resourceproxy.py b/geoportal/c2cgeoportal_geoportal/views/resourceproxy.py index 3ccef3c0672..460c9423d1f 100644 --- a/geoportal/c2cgeoportal_geoportal/views/resourceproxy.py +++ b/geoportal/c2cgeoportal_geoportal/views/resourceproxy.py @@ -65,7 +65,7 @@ def proxy(self) -> pyramid.response.Response: response = self._build_response( response, response.content, cache_control, "externalresource", content_type=content_type ) - for header in response.headers.keys(): + for header in response.headers: if header not in self.settings["allowed_headers"]: response.headers.pop(header) return response diff --git a/geoportal/c2cgeoportal_geoportal/views/shortener.py b/geoportal/c2cgeoportal_geoportal/views/shortener.py index 2480734a62b..cbbd120599b 100644 --- a/geoportal/c2cgeoportal_geoportal/views/shortener.py +++ b/geoportal/c2cgeoportal_geoportal/views/shortener.py @@ -34,11 +34,16 @@ from urllib.parse import urlparse import pyramid.request -from pyramid.httpexceptions import HTTPBadRequest, HTTPFound, HTTPInternalServerError, HTTPNotFound -from pyramid.view import view_config - from c2cgeoportal_commons.lib.email_ import send_email_config from c2cgeoportal_commons.models import DBSession, static +from pyramid.httpexceptions import ( + HTTPBadRequest, + HTTPFound, + HTTPInternalServerError, + HTTPNotFound, +) +from pyramid.view import view_config + from c2cgeoportal_geoportal import is_allowed_url from c2cgeoportal_geoportal.lib.common_headers import Cache, set_common_headers diff --git a/geoportal/c2cgeoportal_geoportal/views/theme.py b/geoportal/c2cgeoportal_geoportal/views/theme.py index 42f2b2c5fbf..29566bb9e0e 100644 --- a/geoportal/c2cgeoportal_geoportal/views/theme.py +++ b/geoportal/c2cgeoportal_geoportal/views/theme.py @@ -35,7 +35,7 @@ import time from collections import Counter from math import sqrt -from typing import Any, Optional, Union, cast +from typing import Any, Union, cast import dogpile.cache.api import pyramid.httpexceptions @@ -43,6 +43,9 @@ import requests import sqlalchemy import sqlalchemy.orm.query +from c2cgeoportal_commons import models +from c2cgeoportal_commons.lib.url import Url, get_url2 +from c2cgeoportal_commons.models import cache_invalidate_cb, main from c2cwsgiutils.auth import auth_view from defusedxml import lxml from lxml import etree # nosec @@ -51,11 +54,13 @@ from sqlalchemy.orm import subqueryload from sqlalchemy.orm.exc import NoResultFound # type: ignore[attr-defined] -from c2cgeoportal_commons import models -from c2cgeoportal_commons.lib.url import Url, get_url2 -from c2cgeoportal_commons.models import cache_invalidate_cb, main from c2cgeoportal_geoportal import is_allowed_host, is_allowed_url -from c2cgeoportal_geoportal.lib import get_roles_id, get_typed, get_types_map, is_intranet +from c2cgeoportal_geoportal.lib import ( + get_roles_id, + get_typed, + get_types_map, + is_intranet, +) from c2cgeoportal_geoportal.lib.caching import get_region from c2cgeoportal_geoportal.lib.common_headers import Cache, set_common_headers from c2cgeoportal_geoportal.lib.functionality import get_mapserver_substitution_params @@ -323,7 +328,6 @@ async def _wms_getcap_cached( def _create_layer_query(self, interface: str) -> sqlalchemy.orm.query.RowReturningQuery[tuple[str]]: """Create an SQLAlchemy query for Layer and for the role identified to by ``role_id``.""" - assert models.DBSession is not None query: sqlalchemy.orm.query.RowReturningQuery[tuple[str]] = models.DBSession.query( @@ -596,7 +600,6 @@ def _layer_included(tree_item: main.TreeItem) -> bool: def _get_ogc_servers(self, group: main.LayerGroup, depth: int) -> set[str | bool]: """Get unique identifier for each child by recursing on all the children.""" - ogc_servers: set[str | bool] = set() # escape loop @@ -713,15 +716,14 @@ async def _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() + if org_depth == 1 and 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() + group_theme["dimensions"] = dim.get_dimensions() return group_theme, errors return None, errors @@ -775,7 +777,6 @@ async def _themes( self, interface: str = "desktop", filter_themes: bool = True, min_levels: int = 1 ) -> tuple[list[dict[str, Any]], set[str]]: """Return theme information for the role identified by ``role_id``.""" - assert models.DBSession is not None self._load_tree_items() @@ -894,7 +895,7 @@ def _get_role_ids(self) -> set[int] | None: async def _wfs_get_features_type( self, wfs_url: Url, ogc_server: main.OGCServer, preload: bool = False, cache: bool = True - ) -> tuple[Optional[etree.Element], set[str]]: # pylint: disable=c-extension-no-member + ) -> tuple[etree.Element | None, set[str]]: # pylint: disable=c-extension-no-member errors = set() wfs_url.add_query( @@ -987,7 +988,8 @@ async def _preload(self, errors: set[str]) -> None: for ogc_server, nb_layers in ( models.DBSession.query( - main.OGCServer, sqlalchemy.func.count(main.LayerWMS.id) # pylint: disable=not-callable + main.OGCServer, + sqlalchemy.func.count(main.LayerWMS.id), # pylint: disable=not-callable ) .filter(main.LayerWMS.ogc_server_id == main.OGCServer.id) .group_by(main.OGCServer.id) @@ -1037,7 +1039,7 @@ def _get_features_attributes_cache( "available namespaces: %s (OGC server: %s)", type_namespace, name, - ", ".join([str(k) for k in child.nsmap.keys()]), + ", ".join([str(k) for k in child.nsmap]), ogc_server_name, ) elif child.nsmap[type_namespace] != namespace: @@ -1069,7 +1071,7 @@ def _get_features_attributes_cache( "available namespaces: %s (OGC server: %s)", type_namespace, name, - ", ".join([str(k) for k in child.nsmap.keys()]), + ", ".join([str(k) for k in child.nsmap]), ogc_server_name, ) for key, value in children.attrib.items(): @@ -1114,7 +1116,6 @@ def _get_features_attributes_cache( @view_config(route_name="themes", renderer="json") # type: ignore[misc] def themes(self) -> dict[str, dict[str, dict[str, Any]] | list[str]]: - is_allowed_host(self.request) interface = self.request.params.get("interface", "desktop") @@ -1145,7 +1146,8 @@ async def get_theme() -> dict[str, dict[str, Any] | list[str]]: result["ogcServers"] = {} for ogc_server, nb_layers in ( models.DBSession.query( - main.OGCServer, sqlalchemy.func.count(main.LayerWMS.id) # pylint: disable=not-callable + main.OGCServer, + sqlalchemy.func.count(main.LayerWMS.id), # pylint: disable=not-callable ) .filter(main.LayerWMS.ogc_server_id == main.OGCServer.id) .group_by(main.OGCServer.id) @@ -1239,7 +1241,7 @@ def get_theme_anonymous( if self.request.user is None: return cast( - dict[str, Union[dict[str, dict[str, Any]], list[str]]], + dict[str, dict[str, dict[str, Any]] | list[str]], get_theme_anonymous( is_intranet(self.request), interface, diff --git a/geoportal/c2cgeoportal_geoportal/views/tinyowsproxy.py b/geoportal/c2cgeoportal_geoportal/views/tinyowsproxy.py index 9edd8efb1f1..dacb73b62d4 100644 --- a/geoportal/c2cgeoportal_geoportal/views/tinyowsproxy.py +++ b/geoportal/c2cgeoportal_geoportal/views/tinyowsproxy.py @@ -30,13 +30,18 @@ from typing import Any import pyramid.request -from defusedxml import ElementTree -from pyramid.httpexceptions import HTTPBadRequest, HTTPForbidden, HTTPInternalServerError, HTTPUnauthorized -from pyramid.view import view_config - from c2cgeoportal_commons import models from c2cgeoportal_commons.lib.url import Url from c2cgeoportal_commons.models import main +from defusedxml import ElementTree +from pyramid.httpexceptions import ( + HTTPBadRequest, + HTTPForbidden, + HTTPInternalServerError, + HTTPUnauthorized, +) +from pyramid.view import view_config + from c2cgeoportal_geoportal.lib.common_headers import Cache from c2cgeoportal_geoportal.lib.filter_capabilities import ( filter_wfst_capabilities, diff --git a/geoportal/c2cgeoportal_geoportal/views/vector_tiles.py b/geoportal/c2cgeoportal_geoportal/views/vector_tiles.py index 9fd929ba9eb..78c8062bd44 100644 --- a/geoportal/c2cgeoportal_geoportal/views/vector_tiles.py +++ b/geoportal/c2cgeoportal_geoportal/views/vector_tiles.py @@ -28,6 +28,7 @@ import logging import sqlalchemy +from c2cgeoportal_commons.models import DBSession, main from pyramid.httpexceptions import HTTPNotFound from pyramid.request import Request from pyramid.response import Response @@ -35,7 +36,6 @@ from tilecloud import TileCoord from tilecloud.grid.free import FreeTileGrid -from c2cgeoportal_commons.models import DBSession, main from c2cgeoportal_geoportal.lib.common_headers import Cache, set_common_headers _LOG = logging.getLogger(__name__)