c2cgeoportal-geoportal 2.7.1.156__py2.py3-none-any.whl → 2.8.1.180__py2.py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- c2cgeoportal_geoportal/__init__.py +24 -14
- c2cgeoportal_geoportal/lib/authentication.py +10 -14
- c2cgeoportal_geoportal/lib/caching.py +8 -6
- c2cgeoportal_geoportal/lib/checker.py +10 -6
- c2cgeoportal_geoportal/lib/common_headers.py +5 -8
- c2cgeoportal_geoportal/lib/dbreflection.py +8 -8
- c2cgeoportal_geoportal/lib/filter_capabilities.py +5 -1
- c2cgeoportal_geoportal/lib/lingua_extractor.py +11 -12
- c2cgeoportal_geoportal/lib/loader.py +1 -1
- c2cgeoportal_geoportal/lib/oauth2.py +217 -100
- c2cgeoportal_geoportal/lib/wmstparsing.py +8 -12
- c2cgeoportal_geoportal/scaffolds/advance_create/{{cookiecutter.project}}/geoportal/Dockerfile +9 -11
- c2cgeoportal_geoportal/scaffolds/advance_create/{{cookiecutter.project}}/geoportal/development.ini +1 -1
- c2cgeoportal_geoportal/scaffolds/advance_create/{{cookiecutter.project}}/geoportal/gunicorn.conf.py +0 -2
- c2cgeoportal_geoportal/scaffolds/advance_create/{{cookiecutter.project}}/geoportal/requirements.txt +1 -1
- c2cgeoportal_geoportal/scaffolds/advance_create/{{cookiecutter.project}}/geoportal/webpack.api.js +6 -4
- c2cgeoportal_geoportal/scaffolds/advance_create/{{cookiecutter.project}}/geoportal/webpack.apps.js +1 -3
- c2cgeoportal_geoportal/scaffolds/advance_create/{{cookiecutter.project}}/geoportal/webpack.commons.js +1 -0
- c2cgeoportal_geoportal/scaffolds/advance_create/{{cookiecutter.project}}/geoportal/{{cookiecutter.package}}_geoportal/__init__.py +1 -6
- c2cgeoportal_geoportal/scaffolds/advance_update/{{cookiecutter.project}}/geoportal/CONST_Makefile +0 -20
- c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/.github/workflows/main.yaml +20 -6
- c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/.github/workflows/update_l10n.yaml +4 -3
- c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/Dockerfile +22 -22
- c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/Makefile +58 -2
- c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/build +48 -24
- c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/ci/config.yaml +2 -5
- c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/ci/docker-compose-check +25 -0
- c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/ci/requirements.txt +1 -1
- c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/docker-compose-db.yaml +26 -0
- c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/docker-compose-lib.yaml +53 -26
- c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/docker-compose-qgis.yaml +23 -0
- c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/docker-compose.override.sample.yaml +0 -1
- c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/docker-compose.yaml +3 -3
- c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/env.default +21 -2
- c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/env.project +9 -0
- c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/geoportal/vars.yaml +38 -14
- c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/mapserver/data/Readme.txt +2 -2
- c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/mapserver/mapserver.conf +15 -0
- c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/mapserver/mapserver.map.tmpl +2 -3
- c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/print/print-apps/{{cookiecutter.package}}/A3_Landscape.jrxml +5 -0
- c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/print/print-apps/{{cookiecutter.package}}/A3_Portrait.jrxml +5 -0
- c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/print/print-apps/{{cookiecutter.package}}/A4_Landscape.jrxml +5 -0
- c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/print/print-apps/{{cookiecutter.package}}/A4_Portrait.jrxml +5 -0
- c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/print/print-apps/{{cookiecutter.package}}/config.yaml.tmpl +6 -0
- c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/pyproject.toml +4 -0
- c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/run_alembic.sh +3 -5
- c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/scripts/db-backup +1 -1
- c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/scripts/db-restore +1 -1
- c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/spell-ignore-words.txt +2 -0
- c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/tests/__init__.py +0 -0
- c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/tests/test_app.py +38 -0
- c2cgeoportal_geoportal/scaffolds/update/{{cookiecutter.project}}/.upgrade.yaml +2 -132
- c2cgeoportal_geoportal/scaffolds/update/{{cookiecutter.project}}/CONST_CHANGELOG.txt +210 -1097
- c2cgeoportal_geoportal/scaffolds/update/{{cookiecutter.project}}/CONST_create_template/tests/test_testapp.py +48 -0
- c2cgeoportal_geoportal/scaffolds/update/{{cookiecutter.project}}/geoportal/CONST_config-schema.yaml +17 -15
- c2cgeoportal_geoportal/scaffolds/update/{{cookiecutter.project}}/geoportal/CONST_vars.yaml +46 -2
- c2cgeoportal_geoportal/scripts/c2cupgrade.py +1 -2
- c2cgeoportal_geoportal/scripts/pcreate.py +8 -10
- c2cgeoportal_geoportal/scripts/theme2fts.py +58 -3
- c2cgeoportal_geoportal/views/__init__.py +1 -3
- c2cgeoportal_geoportal/views/dynamic.py +1 -1
- c2cgeoportal_geoportal/views/entry.py +2 -10
- c2cgeoportal_geoportal/views/fulltextsearch.py +1 -1
- c2cgeoportal_geoportal/views/geometry_processing.py +3 -3
- c2cgeoportal_geoportal/views/layers.py +10 -11
- c2cgeoportal_geoportal/views/login.py +63 -8
- c2cgeoportal_geoportal/views/mapserverproxy.py +2 -3
- c2cgeoportal_geoportal/views/ogcproxy.py +6 -2
- c2cgeoportal_geoportal/views/pdfreport.py +4 -4
- c2cgeoportal_geoportal/views/printproxy.py +2 -2
- c2cgeoportal_geoportal/views/profile.py +1 -1
- c2cgeoportal_geoportal/views/proxy.py +2 -4
- c2cgeoportal_geoportal/views/raster.py +2 -2
- c2cgeoportal_geoportal/views/resourceproxy.py +1 -1
- c2cgeoportal_geoportal/views/shortener.py +1 -2
- c2cgeoportal_geoportal/views/theme.py +97 -63
- c2cgeoportal_geoportal/views/tinyowsproxy.py +3 -12
- c2cgeoportal_geoportal/views/vector_tiles.py +1 -1
- {c2cgeoportal_geoportal-2.7.1.156.dist-info → c2cgeoportal_geoportal-2.8.1.180.dist-info}/METADATA +21 -15
- {c2cgeoportal_geoportal-2.7.1.156.dist-info → c2cgeoportal_geoportal-2.8.1.180.dist-info}/RECORD +96 -90
- {c2cgeoportal_geoportal-2.7.1.156.dist-info → c2cgeoportal_geoportal-2.8.1.180.dist-info}/entry_points.txt +1 -0
- tests/__init__.py +3 -2
- tests/test_cachebuster.py +3 -3
- tests/test_caching.py +7 -7
- tests/test_checker.py +1 -1
- tests/test_decimaljson.py +1 -1
- tests/test_headerstween.py +1 -1
- tests/test_i18n.py +1 -1
- tests/test_init.py +14 -15
- tests/test_locale_negociator.py +4 -4
- tests/test_mapserverproxy_route_predicate.py +1 -2
- tests/test_raster.py +15 -15
- tests/test_wmstparsing.py +10 -10
- tests/xmlstr.py +1 -3
- c2cgeoportal_geoportal/scaffolds/advance_create/{{cookiecutter.project}}/geoportal/tools/extract-messages.js +0 -41
- {c2cgeoportal_geoportal-2.7.1.156.dist-info → c2cgeoportal_geoportal-2.8.1.180.dist-info}/WHEEL +0 -0
- {c2cgeoportal_geoportal-2.7.1.156.dist-info → c2cgeoportal_geoportal-2.8.1.180.dist-info}/top_level.txt +0 -0
@@ -1,4 +1,4 @@
|
|
1
|
-
# Copyright (c) 2011-
|
1
|
+
# Copyright (c) 2011-2024, Camptocamp SA
|
2
2
|
# All rights reserved.
|
3
3
|
|
4
4
|
# Redistribution and use in source and binary forms, with or without
|
@@ -257,8 +257,8 @@ def _match_url_start(reference: str, value: List[str]) -> bool:
|
|
257
257
|
|
258
258
|
def is_valid_referrer(request: pyramid.request.Request, settings: Optional[Dict[str, Any]] = None) -> bool:
|
259
259
|
"""Check if the referrer is valid."""
|
260
|
-
if request.
|
261
|
-
referrer = urlsplit(request.
|
260
|
+
if request.referrer is not None:
|
261
|
+
referrer = urlsplit(request.referrer)._replace(query="", fragment="").geturl().rstrip("/").split("/")
|
262
262
|
if settings is None:
|
263
263
|
settings = request.registry.settings
|
264
264
|
list_ = settings.get("authorized_referers", [])
|
@@ -280,7 +280,8 @@ def create_get_user_from_request(
|
|
280
280
|
Return ``None`` if:
|
281
281
|
* user is anonymous
|
282
282
|
* it does not exist in the database
|
283
|
-
*
|
283
|
+
* it has been deactivated
|
284
|
+
* the referrer is invalid
|
284
285
|
"""
|
285
286
|
from c2cgeoportal_commons.models import DBSession # pylint: disable=import-outside-toplevel
|
286
287
|
from c2cgeoportal_commons.models.static import User # pylint: disable=import-outside-toplevel
|
@@ -288,7 +289,7 @@ def create_get_user_from_request(
|
|
288
289
|
if not hasattr(request, "is_valid_referer"):
|
289
290
|
request.is_valid_referer = is_valid_referrer(request, settings)
|
290
291
|
if not request.is_valid_referer:
|
291
|
-
LOG.debug("Invalid
|
292
|
+
LOG.debug("Invalid referrer for %s: %s", request.path_qs, repr(request.referrer))
|
292
293
|
return None
|
293
294
|
|
294
295
|
if not hasattr(request, "user_"):
|
@@ -299,7 +300,10 @@ def create_get_user_from_request(
|
|
299
300
|
# We know we will need the role object of the
|
300
301
|
# user so we use joined loading
|
301
302
|
request.user_ = (
|
302
|
-
DBSession.query(User)
|
303
|
+
DBSession.query(User)
|
304
|
+
.filter_by(username=username, deactivated=False)
|
305
|
+
.options(joinedload("roles"))
|
306
|
+
.first()
|
303
307
|
)
|
304
308
|
|
305
309
|
return cast(User, request.user_)
|
@@ -453,7 +457,7 @@ def includeme(config: pyramid.config.Configurator) -> None:
|
|
453
457
|
if metrics_config["total_python_object_memory"]:
|
454
458
|
add_provider(TotalPythonObjectMemoryProvider())
|
455
459
|
|
456
|
-
#
|
460
|
+
# Initialize DBSessions
|
457
461
|
init_db_sessions(settings, config, health_check)
|
458
462
|
|
459
463
|
checker.init(config, health_check)
|
@@ -468,13 +472,15 @@ def includeme(config: pyramid.config.Configurator) -> None:
|
|
468
472
|
for name, cache_config in settings["cache"].items():
|
469
473
|
caching.init_region(cache_config, name)
|
470
474
|
|
471
|
-
|
472
|
-
|
473
|
-
|
474
|
-
|
475
|
-
|
476
|
-
|
477
|
-
|
475
|
+
@zope.event.classhandler.handler(InvalidateCacheEvent) # type: ignore
|
476
|
+
def handle(event: InvalidateCacheEvent) -> None:
|
477
|
+
del event
|
478
|
+
caching.invalidate_region("ogc-server")
|
479
|
+
caching.invalidate_region("std")
|
480
|
+
caching.invalidate_region("obj")
|
481
|
+
if caching.MEMORY_CACHE_DICT:
|
482
|
+
caching.get_region("std").delete_multi(list(caching.MEMORY_CACHE_DICT.keys()))
|
483
|
+
caching.MEMORY_CACHE_DICT.clear()
|
478
484
|
|
479
485
|
# Register a tween to get back the cache buster path.
|
480
486
|
if "cache_path" not in config.get_settings():
|
@@ -496,8 +502,10 @@ def includeme(config: pyramid.config.Configurator) -> None:
|
|
496
502
|
config.add_directive("set_user_validator", set_user_validator)
|
497
503
|
config.set_user_validator(default_user_validator)
|
498
504
|
|
505
|
+
config.add_route("oauth2introspect", "/oauth/introspect", request_method="POST")
|
499
506
|
config.add_route("oauth2token", "/oauth/token", request_method="POST")
|
500
507
|
config.add_route("oauth2loginform", "/oauth/login", request_method="GET")
|
508
|
+
config.add_route("oauth2revoke_token", "/oauth/revoke_token", request_method="GET")
|
501
509
|
config.add_route("notlogin", "/notlogin", request_method="GET")
|
502
510
|
|
503
511
|
config.add_route("dynamic", "/dynamic.json", request_method="GET")
|
@@ -666,6 +674,8 @@ def includeme(config: pyramid.config.Configurator) -> None:
|
|
666
674
|
# Used memory in caches
|
667
675
|
config.add_route("memory", "/memory", request_method="GET")
|
668
676
|
|
677
|
+
config.add_route("ogc_server_clear_cache", "clear-ogc-server-cache/{id}", request_method="GET")
|
678
|
+
|
669
679
|
# Scan view decorator for adding routes
|
670
680
|
config.scan(
|
671
681
|
ignore=[
|
@@ -1,4 +1,4 @@
|
|
1
|
-
# Copyright (c) 2014-
|
1
|
+
# Copyright (c) 2014-2023, Camptocamp SA
|
2
2
|
# All rights reserved.
|
3
3
|
|
4
4
|
# Redistribution and use in source and binary forms, with or without
|
@@ -70,14 +70,14 @@ class UrlAuthenticationPolicy(CallbackAuthenticationPolicy): # type: ignore
|
|
70
70
|
return None
|
71
71
|
try:
|
72
72
|
if self.aeskey is None: # pragma: nocover
|
73
|
-
raise Exception("urllogin is not configured")
|
73
|
+
raise Exception("urllogin is not configured") # pylint: disable=broad-exception-raised
|
74
74
|
now = int(time.time())
|
75
75
|
data = binascii.unhexlify(auth_enc.encode("ascii"))
|
76
76
|
nonce = data[0:16]
|
77
77
|
tag = data[16:32]
|
78
78
|
ciphertext = data[32:]
|
79
79
|
cipher = AES.new(self.aeskey.encode("ascii"), AES.MODE_EAX, nonce)
|
80
|
-
auth = json.loads(cipher.decrypt_and_verify(ciphertext, tag).decode("utf-8"))
|
80
|
+
auth = json.loads(cipher.decrypt_and_verify(ciphertext, tag).decode("utf-8"))
|
81
81
|
|
82
82
|
if "t" in auth and "u" in auth and "p" in auth:
|
83
83
|
timestamp = int(auth["t"])
|
@@ -92,14 +92,12 @@ class UrlAuthenticationPolicy(CallbackAuthenticationPolicy): # type: ignore
|
|
92
92
|
|
93
93
|
return None
|
94
94
|
|
95
|
-
def remember(
|
96
|
-
self, request: pyramid.request.Request, userid: str, **kw: Any
|
97
|
-
) -> List[Dict[str, str]]:
|
95
|
+
def remember(self, request: pyramid.request.Request, userid: str, **kw: Any) -> List[Dict[str, str]]:
|
98
96
|
"""Do no-op."""
|
99
97
|
del request, userid, kw
|
100
98
|
return []
|
101
99
|
|
102
|
-
def forget(self, request: pyramid.request.Request) -> List[Dict[str, str]]:
|
100
|
+
def forget(self, request: pyramid.request.Request) -> List[Dict[str, str]]:
|
103
101
|
"""Do no-op."""
|
104
102
|
del request
|
105
103
|
return []
|
@@ -134,17 +132,15 @@ class OAuth2AuthenticationPolicy(CallbackAuthenticationPolicy): # type: ignore
|
|
134
132
|
if valid:
|
135
133
|
request.user_ = oauth2_request.user
|
136
134
|
|
137
|
-
return cast(str, request.
|
135
|
+
return cast(str, request.user.username)
|
138
136
|
return None
|
139
137
|
|
140
|
-
def remember(
|
141
|
-
self, request: pyramid.request.Request, userid: str, **kw: Any
|
142
|
-
) -> List[Dict[str, str]]:
|
138
|
+
def remember(self, request: pyramid.request.Request, userid: str, **kw: Any) -> List[Dict[str, str]]:
|
143
139
|
"""Do no-op."""
|
144
140
|
del request, userid, kw
|
145
141
|
return []
|
146
142
|
|
147
|
-
def forget(self, request: pyramid.request.Request) -> List[Dict[str, str]]:
|
143
|
+
def forget(self, request: pyramid.request.Request) -> List[Dict[str, str]]:
|
148
144
|
"""Do no-op."""
|
149
145
|
del request
|
150
146
|
return []
|
@@ -177,7 +173,7 @@ def create_authentication(settings: Dict[str, Any]) -> MultiAuthenticationPolicy
|
|
177
173
|
secret = settings["authtkt_secret"]
|
178
174
|
basicauth = settings.get("basicauth", "False").lower() in ("true", "yes", "1")
|
179
175
|
if len(secret) < 64:
|
180
|
-
raise Exception(
|
176
|
+
raise Exception( # pylint: disable=broad-exception-raised
|
181
177
|
'"authtkt_secret should be at least 64 characters.'
|
182
178
|
"See https://docs.pylonsproject.org/projects/pyramid/en/latest/api/session.html"
|
183
179
|
)
|
@@ -211,7 +207,7 @@ def create_authentication(settings: Dict[str, Any]) -> MultiAuthenticationPolicy
|
|
211
207
|
if basicauth:
|
212
208
|
if settings["authentication"].get("two_factor", False):
|
213
209
|
LOG.warning(
|
214
|
-
"Basic auth and
|
210
|
+
"Basic auth and two factor auth should not be enable together, "
|
215
211
|
"you should use OAuth2 instead of Basic auth"
|
216
212
|
)
|
217
213
|
|
@@ -1,4 +1,4 @@
|
|
1
|
-
# Copyright (c) 2012-
|
1
|
+
# Copyright (c) 2012-2023, Camptocamp SA
|
2
2
|
# All rights reserved.
|
3
3
|
|
4
4
|
# Redistribution and use in source and binary forms, with or without
|
@@ -30,13 +30,14 @@ import inspect
|
|
30
30
|
import logging
|
31
31
|
from typing import TYPE_CHECKING, Any, Callable, Dict, List, Optional
|
32
32
|
|
33
|
+
import pyramid.interfaces
|
33
34
|
import sqlalchemy.ext.declarative
|
35
|
+
import zope.interface
|
34
36
|
from dogpile.cache.api import NO_VALUE, CacheBackend
|
35
37
|
from dogpile.cache.backends.memory import MemoryBackend
|
36
38
|
from dogpile.cache.backends.redis import RedisBackend, RedisSentinelBackend
|
37
39
|
from dogpile.cache.region import CacheRegion, make_region
|
38
40
|
from dogpile.cache.util import sha1_mangle_key
|
39
|
-
from pyramid.request import Request
|
40
41
|
from sqlalchemy.orm.util import identity_key
|
41
42
|
|
42
43
|
from c2cgeoportal_commons.models import Base
|
@@ -82,7 +83,9 @@ def keygen_function(namespace: Any, function: Callable[..., Any]) -> Callable[..
|
|
82
83
|
parts.extend(namespace)
|
83
84
|
if ignore_first_argument:
|
84
85
|
args = args[1:]
|
85
|
-
new_args: List[str] = [
|
86
|
+
new_args: List[str] = [
|
87
|
+
arg for arg in args if pyramid.interfaces.IRequest not in zope.interface.implementedBy(type(arg))
|
88
|
+
]
|
86
89
|
parts.extend(map(str, map(map_dbobject, new_args)))
|
87
90
|
return "|".join(parts)
|
88
91
|
|
@@ -100,8 +103,7 @@ def _configure_region(conf: Dict[str, Any], cache_region: CacheRegion) -> None:
|
|
100
103
|
kwargs: Dict[str, Any] = {"replace_existing_backend": True}
|
101
104
|
backend = conf["backend"]
|
102
105
|
kwargs.update({k: conf[k] for k in conf if k != "backend"})
|
103
|
-
kwargs.setdefault("arguments", {})
|
104
|
-
kwargs["arguments"]["cache_dict"] = MEMORY_CACHE_DICT
|
106
|
+
kwargs.setdefault("arguments", {}).setdefault("cache_dict", MEMORY_CACHE_DICT)
|
105
107
|
cache_region.configure(backend, **kwargs)
|
106
108
|
|
107
109
|
|
@@ -124,7 +126,7 @@ def invalidate_region(region: Optional[str] = None) -> None:
|
|
124
126
|
class HybridRedisBackend(CacheBackend): # type: ignore
|
125
127
|
"""A Dogpile cache backend with a memory cache backend in front of a Redis backend for performance."""
|
126
128
|
|
127
|
-
def __init__(self, arguments: Dict[str, Any]):
|
129
|
+
def __init__(self, arguments: Dict[str, Any]):
|
128
130
|
self._use_memory_cache = not arguments.pop("disable_memory_cache", False)
|
129
131
|
self._memory = MemoryBackend({"cache_dict": arguments.pop("cache_dict", {})})
|
130
132
|
self._redis = RedisBackend(arguments)
|
@@ -1,4 +1,4 @@
|
|
1
|
-
# Copyright (c) 2011-
|
1
|
+
# Copyright (c) 2011-2023, Camptocamp SA
|
2
2
|
# All rights reserved.
|
3
3
|
|
4
4
|
# Redistribution and use in source and binary forms, with or without
|
@@ -122,7 +122,9 @@ def _pdf3(settings: Dict[str, Any], health_check: c2cwsgiutils.health_check.Heal
|
|
122
122
|
|
123
123
|
status = resp.json()
|
124
124
|
if "error" in status:
|
125
|
-
raise Exception(
|
125
|
+
raise Exception( # pylint: disable=broad-exception-raised
|
126
|
+
f"Failed to do the printing: {status['error']}",
|
127
|
+
)
|
126
128
|
done = status["done"]
|
127
129
|
|
128
130
|
path = request.route_path("printproxy_report_get", ref=job["ref"])
|
@@ -204,7 +206,9 @@ def _lang_files(
|
|
204
206
|
if type_ == "ngeo":
|
205
207
|
url = f"/etc/geomapfish/static/{lang}.json"
|
206
208
|
else:
|
207
|
-
raise Exception(
|
209
|
+
raise Exception( # pylint: disable=broad-exception-raised
|
210
|
+
f"Your language type value '{type_}' is not valid, available values [ngeo]",
|
211
|
+
)
|
208
212
|
|
209
213
|
name = f"checker_lang_{type_}_{lang}"
|
210
214
|
|
@@ -248,7 +252,7 @@ def _phantomjs(settings: Dict[str, Any], health_check: c2cwsgiutils.health_check
|
|
248
252
|
path = request.route_path(self.route["name"], _query=self.route.get("params", {}))
|
249
253
|
url: str = cast(str, build_url("Check", path, request)["url"])
|
250
254
|
|
251
|
-
cmd: List[str] = ["
|
255
|
+
cmd: List[str] = ["check-example", url]
|
252
256
|
env = dict(os.environ)
|
253
257
|
for name, value in self.route.get("environment", {}).items():
|
254
258
|
if isinstance(value, (list, dict)):
|
@@ -260,12 +264,12 @@ def _phantomjs(settings: Dict[str, Any], health_check: c2cwsgiutils.health_check
|
|
260
264
|
try:
|
261
265
|
subprocess.check_output(cmd, env=env, timeout=70)
|
262
266
|
except subprocess.CalledProcessError as exception:
|
263
|
-
raise Exception(
|
267
|
+
raise Exception( # pylint: disable=broad-exception-raised
|
264
268
|
f"{' '.join(exception.cmd)} exit with code: {exception.returncode}\n"
|
265
269
|
f"{exception.output.decode('utf-8')[:10000]}"
|
266
270
|
) from exception
|
267
271
|
except subprocess.TimeoutExpired as exception:
|
268
|
-
raise Exception(
|
272
|
+
raise Exception( # pylint: disable=broad-exception-raised
|
269
273
|
f"""Timeout:
|
270
274
|
command: {' '.join(exception.cmd)}
|
271
275
|
output:
|
@@ -1,4 +1,4 @@
|
|
1
|
-
# Copyright (c) 2012-
|
1
|
+
# Copyright (c) 2012-2024, Camptocamp SA
|
2
2
|
# All rights reserved.
|
3
3
|
|
4
4
|
# Redistribution and use in source and binary forms, with or without
|
@@ -33,8 +33,6 @@ from typing import Any, Dict, List, Optional, cast
|
|
33
33
|
import pyramid.request
|
34
34
|
import pyramid.response
|
35
35
|
|
36
|
-
from c2cgeoportal_geoportal.lib import is_intranet
|
37
|
-
|
38
36
|
_LOG = logging.getLogger(__name__)
|
39
37
|
|
40
38
|
|
@@ -119,6 +117,8 @@ def _set_common_headers(
|
|
119
117
|
) -> pyramid.response.Response:
|
120
118
|
"""Set the common headers."""
|
121
119
|
|
120
|
+
del request # Unused
|
121
|
+
|
122
122
|
response.headers.update(service_headers_settings.get("headers", {}))
|
123
123
|
|
124
124
|
if cache in (Cache.PRIVATE, Cache.PRIVATE_NO):
|
@@ -136,12 +136,9 @@ def _set_common_headers(
|
|
136
136
|
elif cache in (Cache.PUBLIC, Cache.PUBLIC_NO):
|
137
137
|
response.cache_control.public = True
|
138
138
|
elif cache in (Cache.PRIVATE, Cache.PRIVATE_NO):
|
139
|
-
|
140
|
-
response.cache_control.private = True
|
141
|
-
else:
|
142
|
-
response.cache_control.public = True
|
139
|
+
response.cache_control.private = True
|
143
140
|
else:
|
144
|
-
raise Exception("Invalid cache type")
|
141
|
+
raise Exception("Invalid cache type") # pylint: disable=broad-exception-raised
|
145
142
|
|
146
143
|
if content_type is not None:
|
147
144
|
response.content_type = content_type
|
@@ -1,4 +1,4 @@
|
|
1
|
-
# Copyright (c) 2011-
|
1
|
+
# Copyright (c) 2011-2023, Camptocamp SA
|
2
2
|
# All rights reserved.
|
3
3
|
|
4
4
|
# Redistribution and use in source and binary forms, with or without
|
@@ -176,16 +176,16 @@ def _create_class(
|
|
176
176
|
from c2cgeoportal_commons.models import Base # pylint: disable=import-outside-toplevel
|
177
177
|
|
178
178
|
exclude_properties = exclude_properties or ()
|
179
|
-
attributes =
|
180
|
-
__table__
|
181
|
-
__mapper_args__
|
182
|
-
__attributes_order__
|
183
|
-
__enumerations_config__
|
184
|
-
|
179
|
+
attributes = {
|
180
|
+
"__table__": table,
|
181
|
+
"__mapper_args__": {"exclude_properties": exclude_properties},
|
182
|
+
"__attributes_order__": attributes_order,
|
183
|
+
"__enumerations_config__": enumerations_config,
|
184
|
+
}
|
185
185
|
if pk_name is not None:
|
186
186
|
attributes[pk_name] = Column(Integer, primary_key=True)
|
187
187
|
# The randint is to fix the SAWarning: This declarative base already contains a class with the same
|
188
|
-
# class name and module
|
188
|
+
# class name and module name
|
189
189
|
cls = type(
|
190
190
|
f"{table.name.capitalize()}_{random.randint(0, 9999999)}", (GeoInterface, Base), attributes # nosec
|
191
191
|
)
|
@@ -34,6 +34,7 @@ from typing import Any, Callable, Dict, List, Optional, Set, Union
|
|
34
34
|
from xml.sax.saxutils import XMLFilterBase, XMLGenerator # nosec
|
35
35
|
|
36
36
|
import defusedxml.expatreader
|
37
|
+
import pyramid.httpexceptions
|
37
38
|
import pyramid.request
|
38
39
|
import requests
|
39
40
|
from owslib.map.wms111 import ContentMetadata as ContentMetadata111
|
@@ -153,6 +154,9 @@ def filter_wfst_capabilities(content: str, wfs_url: Url, request: pyramid.reques
|
|
153
154
|
|
154
155
|
writable_layers: Set[str] = set()
|
155
156
|
ogc_server_ids = get_ogc_server_wfs_url_ids(request, request.host).get(wfs_url.url())
|
157
|
+
if ogc_server_ids is None:
|
158
|
+
LOG.error("No OGC server found for WFS URL %s", wfs_url)
|
159
|
+
raise pyramid.httpexceptions.HTTPInternalServerError("No OGC server found for WFS URL")
|
156
160
|
|
157
161
|
for gmf_layer in list(get_writable_layers(request, ogc_server_ids).values()):
|
158
162
|
writable_layers |= set(gmf_layer.layer.split(","))
|
@@ -260,7 +264,7 @@ class _CapabilitiesFilter(XMLFilterBase):
|
|
260
264
|
def endPrefixMapping(self, prefix: str) -> None: # noqa: ignore=N802
|
261
265
|
self._downstream.endPrefixMapping(prefix) # type: ignore
|
262
266
|
|
263
|
-
def startElement(self, name: str, attrs:
|
267
|
+
def startElement(self, name: str, attrs: Dict[str, str]) -> None: # noqa: ignore=N802
|
264
268
|
if name == self.tag_name:
|
265
269
|
self.level += 1
|
266
270
|
if self.layers_path:
|
@@ -62,6 +62,10 @@ if TYPE_CHECKING:
|
|
62
62
|
from c2cgeoportal_commons.models import main # pylint: disable=ungrouped-imports,useless-suppression
|
63
63
|
|
64
64
|
|
65
|
+
class LinguaExtractorException(Exception):
|
66
|
+
"""Exception raised when an error occurs during the extraction."""
|
67
|
+
|
68
|
+
|
65
69
|
def _get_config(key: str, default: Optional[str] = None) -> Optional[str]:
|
66
70
|
"""
|
67
71
|
Return the config value for passed key.
|
@@ -170,8 +174,7 @@ class GeomapfishAngularExtractor(Extractor): # type: ignore
|
|
170
174
|
empty_template = Template("") # nosec
|
171
175
|
|
172
176
|
class Lookup(TemplateLookup): # type: ignore
|
173
|
-
|
174
|
-
def get_template(uri: str) -> Template:
|
177
|
+
def get_template(self, uri: str) -> Template:
|
175
178
|
del uri # unused
|
176
179
|
return empty_template
|
177
180
|
|
@@ -220,10 +223,7 @@ class GeomapfishAngularExtractor(Extractor): # type: ignore
|
|
220
223
|
print(traceback.format_exc())
|
221
224
|
|
222
225
|
# Path in geomapfish-tools
|
223
|
-
script_path = "geoportal/
|
224
|
-
if not os.path.isfile(script_path):
|
225
|
-
# Path in geomapfish runner
|
226
|
-
script_path = "/app/tools/extract-messages.js"
|
226
|
+
script_path = "/opt/c2cgeoportal/geoportal/extract-messages.js"
|
227
227
|
message_str = subprocess.check_output(["node", script_path, int_filename]).decode("utf-8")
|
228
228
|
if int_filename != filename:
|
229
229
|
os.unlink(int_filename)
|
@@ -246,8 +246,8 @@ def init_db(settings: Dict[str, Any]) -> None:
|
|
246
246
|
"""
|
247
247
|
Initialize the SQLAlchemy Session.
|
248
248
|
|
249
|
-
First test the connection, on
|
250
|
-
an exception ind
|
249
|
+
First test the connection, on when environment it should be OK, with the command line we should get
|
250
|
+
an exception ind initialize the connection.
|
251
251
|
"""
|
252
252
|
|
253
253
|
try:
|
@@ -257,7 +257,6 @@ def init_db(settings: Dict[str, Any]) -> None:
|
|
257
257
|
session = DBSession()
|
258
258
|
session.query(Theme).count()
|
259
259
|
except: # pylint: disable=bare-except
|
260
|
-
|
261
260
|
# Init db sessions
|
262
261
|
|
263
262
|
class R:
|
@@ -305,7 +304,7 @@ class GeomapfishConfigExtractor(Extractor): # type: ignore
|
|
305
304
|
# For the print config
|
306
305
|
if "templates" in gmf_config:
|
307
306
|
return self._collect_print_config(gmf_config, filename)
|
308
|
-
raise Exception("Not a known config file")
|
307
|
+
raise Exception("Not a known config file") # pylint: disable=broad-exception-raised
|
309
308
|
|
310
309
|
def _collect_app_config(self, filename: str) -> List[Message]:
|
311
310
|
config.init(filename)
|
@@ -797,7 +796,7 @@ class GeomapfishThemeExtractor(Extractor): # type: ignore
|
|
797
796
|
)
|
798
797
|
print(f"Response: {response.status_code} {response.reason}\n{response.text}")
|
799
798
|
if _get_config_str("IGNORE_I18N_ERRORS", "FALSE") != "TRUE":
|
800
|
-
raise
|
799
|
+
raise LinguaExtractorException(response.reason)
|
801
800
|
except Exception as e:
|
802
801
|
print(colorize(str(e), Color.RED))
|
803
802
|
rendered_headers = " ".join(
|
@@ -859,7 +858,7 @@ class GeomapfishThemeExtractor(Extractor): # type: ignore
|
|
859
858
|
)
|
860
859
|
if _get_config_str("IGNORE_I18N_ERRORS", "FALSE") == "TRUE":
|
861
860
|
return [], []
|
862
|
-
raise Exception("Aborted")
|
861
|
+
raise Exception("Aborted") # pylint: disable=broad-exception-raised
|
863
862
|
|
864
863
|
try:
|
865
864
|
describe = parseString(response.text)
|