goodmap 1.1.8__py3-none-any.whl → 1.1.10__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.
- goodmap/config.py +1 -1
- goodmap/core_api.py +41 -8
- goodmap/goodmap.py +11 -0
- goodmap/templates/goodmap-admin.html +2 -0
- goodmap/templates/map.html +5 -0
- {goodmap-1.1.8.dist-info → goodmap-1.1.10.dist-info}/METADATA +2 -4
- goodmap-1.1.10.dist-info/RECORD +17 -0
- {goodmap-1.1.8.dist-info → goodmap-1.1.10.dist-info}/WHEEL +1 -1
- goodmap-1.1.8.dist-info/RECORD +0 -17
- {goodmap-1.1.8.dist-info/licenses → goodmap-1.1.10.dist-info}/LICENSE.md +0 -0
goodmap/config.py
CHANGED
|
@@ -10,7 +10,7 @@ class GoodmapConfig(PlatzkyConfig):
|
|
|
10
10
|
"""Extended configuration for Goodmap with additional frontend library URL."""
|
|
11
11
|
|
|
12
12
|
goodmap_frontend_lib_url: str = Field(
|
|
13
|
-
default="https://cdn.jsdelivr.net/npm/@problematy/goodmap@0.4
|
|
13
|
+
default="https://cdn.jsdelivr.net/npm/@problematy/goodmap@1.0.4",
|
|
14
14
|
alias="GOODMAP_FRONTEND_LIB_URL",
|
|
15
15
|
)
|
|
16
16
|
|
goodmap/core_api.py
CHANGED
|
@@ -2,6 +2,7 @@ import importlib.metadata
|
|
|
2
2
|
import logging
|
|
3
3
|
import uuid
|
|
4
4
|
|
|
5
|
+
import deprecation
|
|
5
6
|
import numpy
|
|
6
7
|
import pysupercluster
|
|
7
8
|
from flask import Blueprint, jsonify, make_response, request
|
|
@@ -105,7 +106,28 @@ def core_pages(
|
|
|
105
106
|
def post(self):
|
|
106
107
|
"""Suggest new location"""
|
|
107
108
|
try:
|
|
108
|
-
|
|
109
|
+
# Handle both multipart/form-data (with file uploads) and JSON
|
|
110
|
+
if request.content_type and request.content_type.startswith("multipart/form-data"):
|
|
111
|
+
# Parse form data dynamically
|
|
112
|
+
import json as json_lib
|
|
113
|
+
|
|
114
|
+
suggested_location = {}
|
|
115
|
+
|
|
116
|
+
for key in request.form:
|
|
117
|
+
value = request.form[key]
|
|
118
|
+
# Try to parse as JSON for complex types (arrays, objects, position)
|
|
119
|
+
try:
|
|
120
|
+
suggested_location[key] = json_lib.loads(value)
|
|
121
|
+
except ValueError: # JSONDecodeError inherits from ValueError
|
|
122
|
+
# If not JSON, use as-is (simple string values)
|
|
123
|
+
suggested_location[key] = value
|
|
124
|
+
|
|
125
|
+
# TODO: Handle photo file upload from request.files['photo']
|
|
126
|
+
# For now, we just ignore it as the backend doesn't store photos yet
|
|
127
|
+
else:
|
|
128
|
+
# Parse JSON data
|
|
129
|
+
suggested_location = request.get_json()
|
|
130
|
+
|
|
109
131
|
suggested_location.update({"uuid": str(uuid.uuid4())})
|
|
110
132
|
location = location_model.model_validate(suggested_location)
|
|
111
133
|
database.add_suggestion(location.model_dump())
|
|
@@ -115,7 +137,7 @@ def core_pages(
|
|
|
115
137
|
)
|
|
116
138
|
notifier_function(message)
|
|
117
139
|
except BadRequest:
|
|
118
|
-
logger.warning("Invalid
|
|
140
|
+
logger.warning("Invalid request data in suggest endpoint")
|
|
119
141
|
return make_response(jsonify({"message": ERROR_INVALID_REQUEST_DATA}), 400)
|
|
120
142
|
except LocationValidationError as e:
|
|
121
143
|
logger.warning(
|
|
@@ -244,6 +266,23 @@ def core_pages(
|
|
|
244
266
|
version_info = {"backend": importlib.metadata.version("goodmap")}
|
|
245
267
|
return jsonify(version_info)
|
|
246
268
|
|
|
269
|
+
@core_api.route("/generate-csrf-token")
|
|
270
|
+
class CsrfToken(Resource):
|
|
271
|
+
@deprecation.deprecated(
|
|
272
|
+
deprecated_in="1.1.8",
|
|
273
|
+
details="This endpoint for explicit CSRF token generation is deprecated. "
|
|
274
|
+
"CSRF protection remains active in the application.",
|
|
275
|
+
)
|
|
276
|
+
def get(self):
|
|
277
|
+
"""
|
|
278
|
+
Generate CSRF token (DEPRECATED)
|
|
279
|
+
|
|
280
|
+
This endpoint is deprecated and maintained only for backward compatibility.
|
|
281
|
+
CSRF protection remains active in the application.
|
|
282
|
+
"""
|
|
283
|
+
csrf_token = csrf_generator()
|
|
284
|
+
return {"csrf_token": csrf_token}
|
|
285
|
+
|
|
247
286
|
@core_api.route("/categories")
|
|
248
287
|
class Categories(Resource):
|
|
249
288
|
def get(self):
|
|
@@ -297,12 +336,6 @@ def core_pages(
|
|
|
297
336
|
}
|
|
298
337
|
)
|
|
299
338
|
|
|
300
|
-
@core_api.route("/generate-csrf-token")
|
|
301
|
-
class CsrfToken(Resource):
|
|
302
|
-
def get(self):
|
|
303
|
-
csrf_token = csrf_generator()
|
|
304
|
-
return {"csrf_token": csrf_token}
|
|
305
|
-
|
|
306
339
|
@core_api.route("/admin/locations")
|
|
307
340
|
class AdminManageLocations(Resource):
|
|
308
341
|
def get(self):
|
goodmap/goodmap.py
CHANGED
|
@@ -53,10 +53,21 @@ def create_app_from_config(config: GoodmapConfig) -> platzky.Engine:
|
|
|
53
53
|
|
|
54
54
|
@goodmap.route("/")
|
|
55
55
|
def index():
|
|
56
|
+
# Prepare location schema for frontend dynamic forms
|
|
57
|
+
# Convert categories dict_keys to a proper dict for JSON serialization
|
|
58
|
+
category_data = app.db.get_category_data()
|
|
59
|
+
categories = category_data.get("categories", {})
|
|
60
|
+
|
|
61
|
+
location_schema = {
|
|
62
|
+
"obligatory_fields": location_obligatory_fields,
|
|
63
|
+
"categories": categories,
|
|
64
|
+
}
|
|
65
|
+
|
|
56
66
|
return render_template(
|
|
57
67
|
"map.html",
|
|
58
68
|
feature_flags=config.feature_flags,
|
|
59
69
|
goodmap_frontend_lib_url=config.goodmap_frontend_lib_url,
|
|
70
|
+
location_schema=location_schema,
|
|
60
71
|
)
|
|
61
72
|
|
|
62
73
|
@goodmap.route("/goodmap-admin")
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
{% extends "admin.html" %}
|
|
2
2
|
|
|
3
3
|
{% block head_meta %}
|
|
4
|
+
<meta name="csrf-token" content="{{ csrf_token() }}">
|
|
5
|
+
|
|
4
6
|
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.7.1/dist/leaflet.css"
|
|
5
7
|
integrity="sha512-xodZBNTC5n17Xt2atTPuE1HxjVMSvLVW9ocqUKLsCC5CXdbqCmblAshOMAS6/keqq/sMZMZ19scR4PsZChSR7A=="
|
|
6
8
|
crossorigin=""/>
|
goodmap/templates/map.html
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
{% extends "base.html" %}
|
|
2
2
|
|
|
3
3
|
{% block head_meta %}
|
|
4
|
+
<meta name="csrf-token" content="{{ csrf_token() }}">
|
|
4
5
|
|
|
5
6
|
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.7.1/dist/leaflet.css"
|
|
6
7
|
integrity="sha512-xodZBNTC5n17Xt2atTPuE1HxjVMSvLVW9ocqUKLsCC5CXdbqCmblAshOMAS6/keqq/sMZMZ19scR4PsZChSR7A=="
|
|
@@ -119,6 +120,10 @@ window.USE_LAZY_LOADING = {{ feature_flags.USE_LAZY_LOADING | default(false) | t
|
|
|
119
120
|
window.USE_SERVER_SIDE_CLUSTERING = {{ feature_flags.USE_SERVER_SIDE_CLUSTERING | default(false) | tojson }};
|
|
120
121
|
window.SHOW_ACCESSIBILITY_TABLE = {{ feature_flags.SHOW_ACCESSIBILITY_TABLE | default(false) | tojson }};
|
|
121
122
|
window.FEATURE_FLAGS = {{ feature_flags | tojson }};
|
|
123
|
+
|
|
124
|
+
// Location schema for dynamic form building
|
|
125
|
+
// Contains required fields and available categories for new location suggestions
|
|
126
|
+
globalThis.LOCATION_SCHEMA = {{ location_schema | tojson }};
|
|
122
127
|
</script>
|
|
123
128
|
<script src="{{ goodmap_frontend_lib_url }}"></script>
|
|
124
129
|
{% endblock %}
|
|
@@ -1,8 +1,7 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.3
|
|
2
2
|
Name: goodmap
|
|
3
|
-
Version: 1.1.
|
|
3
|
+
Version: 1.1.10
|
|
4
4
|
Summary: Map engine to serve all the people :)
|
|
5
|
-
License-File: LICENSE.md
|
|
6
5
|
Author: Krzysztof Kolodzinski
|
|
7
6
|
Author-email: krzysztof.kolodzinski@problematy.pl
|
|
8
7
|
Requires-Python: >=3.10,<4.0
|
|
@@ -11,7 +10,6 @@ Classifier: Programming Language :: Python :: 3.10
|
|
|
11
10
|
Classifier: Programming Language :: Python :: 3.11
|
|
12
11
|
Classifier: Programming Language :: Python :: 3.12
|
|
13
12
|
Classifier: Programming Language :: Python :: 3.13
|
|
14
|
-
Classifier: Programming Language :: Python :: 3.14
|
|
15
13
|
Provides-Extra: docs
|
|
16
14
|
Requires-Dist: Babel (>=2.10.3,<3.0.0)
|
|
17
15
|
Requires-Dist: Flask (==3.0.3)
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
goodmap/__init__.py,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
|
|
2
|
+
goodmap/clustering.py,sha256=ULB-fPNOUDblgpBK4vzuo0o2yqIcvG84F3R6Za2X_l4,2905
|
|
3
|
+
goodmap/config.py,sha256=CsmC1zuvVab90VW50dtARHbFJpy2vfsIfbque8Zgc-U,1313
|
|
4
|
+
goodmap/core.py,sha256=rzMhOIYnR1jxTX6uHQJKIPLYxdUm4_v2d6LrtHtJpHU,1465
|
|
5
|
+
goodmap/core_api.py,sha256=Xzr9x89-K0gURcFvAypjKaboExdTKq1KfLfnGTvNG-Q,21144
|
|
6
|
+
goodmap/data_models/location.py,sha256=brDdaICyYPs8QrWEkRXkUybQS3IJaZGbkDWa6hqhFAg,2008
|
|
7
|
+
goodmap/data_validator.py,sha256=lBmVAPxvSmEOdUGeVYSjUvVVmKfPyq4CWoHfczTtEMM,4090
|
|
8
|
+
goodmap/db.py,sha256=TcqYGbK5yk6S735Si1AzjNqcbB1nsd9pFGOy5qN9Vec,46589
|
|
9
|
+
goodmap/exceptions.py,sha256=jkFAUoc5LHk8iPjxHxbcRp8W6qFCSEA25A8XaSwxwyo,2906
|
|
10
|
+
goodmap/formatter.py,sha256=VlUHcK1HtM_IEU0VE3S5TOkZLVheMdakvUeW2tCKdq0,783
|
|
11
|
+
goodmap/goodmap.py,sha256=LbmzYn4FHaP-Y5ZtQhMncGO2h18k2WYAsP5Hzw4oGUw,3392
|
|
12
|
+
goodmap/templates/goodmap-admin.html,sha256=LSiOZ9-n29CnlfVNwdgmXwT7Xe7t5gvGh1xSrFGqOIY,35669
|
|
13
|
+
goodmap/templates/map.html,sha256=Uk7FFrZwvHZvG0DDaQrGW5ZrIMD21XrJzMub76uIlAg,4348
|
|
14
|
+
goodmap-1.1.10.dist-info/LICENSE.md,sha256=nkCQOR7uheLRvHRfXmwx9LhBnMcPeBU9d4ebLojDiQU,1067
|
|
15
|
+
goodmap-1.1.10.dist-info/METADATA,sha256=KWMBhXpAOllMzB2HFpQxhyPyRVe1ZkL1CaRD9bNev3w,5793
|
|
16
|
+
goodmap-1.1.10.dist-info/WHEEL,sha256=IYZQI976HJqqOpQU6PHkJ8fb3tMNBFjg-Cn-pwAbaFM,88
|
|
17
|
+
goodmap-1.1.10.dist-info/RECORD,,
|
goodmap-1.1.8.dist-info/RECORD
DELETED
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
goodmap/__init__.py,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
|
|
2
|
-
goodmap/clustering.py,sha256=ULB-fPNOUDblgpBK4vzuo0o2yqIcvG84F3R6Za2X_l4,2905
|
|
3
|
-
goodmap/config.py,sha256=sseE4sceFB8OBuFsrRpQJvjv0Vg5KFdkzihBX_hbE2c,1313
|
|
4
|
-
goodmap/core.py,sha256=rzMhOIYnR1jxTX6uHQJKIPLYxdUm4_v2d6LrtHtJpHU,1465
|
|
5
|
-
goodmap/core_api.py,sha256=gzFYeek65_4kLET0NPMlSqTz1UGlQl7Dam6lxDtrTIk,19586
|
|
6
|
-
goodmap/data_models/location.py,sha256=brDdaICyYPs8QrWEkRXkUybQS3IJaZGbkDWa6hqhFAg,2008
|
|
7
|
-
goodmap/data_validator.py,sha256=lBmVAPxvSmEOdUGeVYSjUvVVmKfPyq4CWoHfczTtEMM,4090
|
|
8
|
-
goodmap/db.py,sha256=TcqYGbK5yk6S735Si1AzjNqcbB1nsd9pFGOy5qN9Vec,46589
|
|
9
|
-
goodmap/exceptions.py,sha256=jkFAUoc5LHk8iPjxHxbcRp8W6qFCSEA25A8XaSwxwyo,2906
|
|
10
|
-
goodmap/formatter.py,sha256=VlUHcK1HtM_IEU0VE3S5TOkZLVheMdakvUeW2tCKdq0,783
|
|
11
|
-
goodmap/goodmap.py,sha256=q6okPopWBH6jDkKJcGDegebaapHLFUVilJ3p3aKi97k,2960
|
|
12
|
-
goodmap/templates/goodmap-admin.html,sha256=39PJ1drk_xdkyzXgPZZNXYq9gA9oTVeR8hsgeae6E0g,35614
|
|
13
|
-
goodmap/templates/map.html,sha256=aEIL6M7AlBZ34asV5R1syKq9IA1tBZNhiBMA9ovco7I,4105
|
|
14
|
-
goodmap-1.1.8.dist-info/METADATA,sha256=yi1Z2yvFOSKXRRLWUo10UWJHinLEW3IHgP4PZs7M_uo,5868
|
|
15
|
-
goodmap-1.1.8.dist-info/WHEEL,sha256=zp0Cn7JsFoX2ATtOhtaFYIiE2rmFAD4OcMhtUki8W3U,88
|
|
16
|
-
goodmap-1.1.8.dist-info/licenses/LICENSE.md,sha256=nkCQOR7uheLRvHRfXmwx9LhBnMcPeBU9d4ebLojDiQU,1067
|
|
17
|
-
goodmap-1.1.8.dist-info/RECORD,,
|
|
File without changes
|