goodmap 0.5.2__tar.gz → 1.0.1__tar.gz
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-0.5.2 → goodmap-1.0.1}/PKG-INFO +5 -3
- {goodmap-0.5.2 → goodmap-1.0.1}/goodmap/core_api.py +60 -88
- goodmap-1.0.1/goodmap/db.py +1282 -0
- {goodmap-0.5.2 → goodmap-1.0.1}/goodmap/goodmap.py +6 -1
- {goodmap-0.5.2 → goodmap-1.0.1}/goodmap/templates/map.html +1 -0
- {goodmap-0.5.2 → goodmap-1.0.1}/pyproject.toml +26 -3
- goodmap-0.5.2/goodmap/db.py +0 -564
- {goodmap-0.5.2 → goodmap-1.0.1}/LICENSE.md +0 -0
- {goodmap-0.5.2 → goodmap-1.0.1}/README.md +0 -0
- {goodmap-0.5.2 → goodmap-1.0.1}/goodmap/__init__.py +0 -0
- {goodmap-0.5.2 → goodmap-1.0.1}/goodmap/core.py +0 -0
- {goodmap-0.5.2 → goodmap-1.0.1}/goodmap/data_models/location.py +0 -0
- {goodmap-0.5.2 → goodmap-1.0.1}/goodmap/data_validator.py +0 -0
- {goodmap-0.5.2 → goodmap-1.0.1}/goodmap/formatter.py +0 -0
- {goodmap-0.5.2 → goodmap-1.0.1}/goodmap/templates/goodmap-admin.html +0 -0
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
2
|
Name: goodmap
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 1.0.1
|
|
4
4
|
Summary: Map engine to serve all the people :)
|
|
5
|
+
License-File: LICENSE.md
|
|
5
6
|
Author: Krzysztof Kolodzinski
|
|
6
7
|
Author-email: krzysztof.kolodzinski@problematy.pl
|
|
7
8
|
Requires-Python: >=3.10,<4.0
|
|
@@ -10,6 +11,7 @@ Classifier: Programming Language :: Python :: 3.10
|
|
|
10
11
|
Classifier: Programming Language :: Python :: 3.11
|
|
11
12
|
Classifier: Programming Language :: Python :: 3.12
|
|
12
13
|
Classifier: Programming Language :: Python :: 3.13
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
13
15
|
Requires-Dist: Babel (>=2.10.3,<3.0.0)
|
|
14
16
|
Requires-Dist: Flask (==3.0.3)
|
|
15
17
|
Requires-Dist: Flask-Babel (>=4.0.0,<5.0.0)
|
|
@@ -22,7 +24,7 @@ Requires-Dist: google-cloud-storage (>=2.7.0,<3.0.0)
|
|
|
22
24
|
Requires-Dist: gql (>=3.4.0,<4.0.0)
|
|
23
25
|
Requires-Dist: gunicorn (>=20.1.0,<21.0.0)
|
|
24
26
|
Requires-Dist: humanize (>=4.6.0,<5.0.0)
|
|
25
|
-
Requires-Dist: platzky (>=0.
|
|
27
|
+
Requires-Dist: platzky (>=0.4.0,<0.5.0)
|
|
26
28
|
Requires-Dist: pydantic (>=2.7.1,<3.0.0)
|
|
27
29
|
Description-Content-Type: text/markdown
|
|
28
30
|
|
|
@@ -13,76 +13,22 @@ def make_tuple_translation(keys_to_translate):
|
|
|
13
13
|
return [(x, gettext(x)) for x in keys_to_translate]
|
|
14
14
|
|
|
15
15
|
|
|
16
|
-
def
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
Args:
|
|
21
|
-
items: The list of items to paginate
|
|
22
|
-
raw_params: The query parameters dictionary
|
|
23
|
-
|
|
24
|
-
Returns:
|
|
25
|
-
Tuple of (paginated_items, pagination_metadata)
|
|
26
|
-
"""
|
|
27
|
-
# Extract pagination parameters
|
|
28
|
-
try:
|
|
29
|
-
page = int(raw_params.pop("page", ["1"])[0])
|
|
30
|
-
except ValueError:
|
|
31
|
-
page = 1
|
|
32
|
-
|
|
33
|
-
per_page_raw = raw_params.pop("per_page", [None])[0]
|
|
34
|
-
if per_page_raw is None:
|
|
35
|
-
per_page = 20
|
|
36
|
-
elif per_page_raw == "all":
|
|
37
|
-
per_page = None
|
|
38
|
-
else:
|
|
39
|
-
try:
|
|
40
|
-
per_page = max(1, int(per_page_raw))
|
|
41
|
-
except ValueError:
|
|
42
|
-
per_page = 20
|
|
43
|
-
|
|
44
|
-
sort_by = raw_params.pop("sort_by", [None])[0] or sort_by_default
|
|
45
|
-
sort_order = raw_params.pop("sort_order", ["asc"])[0].lower()
|
|
46
|
-
|
|
47
|
-
def get_sort_key(item):
|
|
48
|
-
if not sort_by:
|
|
49
|
-
return None
|
|
50
|
-
|
|
51
|
-
value = None
|
|
52
|
-
if isinstance(item, dict):
|
|
53
|
-
value = item.get(sort_by)
|
|
16
|
+
def get_or_none(data, *keys):
|
|
17
|
+
for key in keys:
|
|
18
|
+
if isinstance(data, dict):
|
|
19
|
+
data = data.get(key)
|
|
54
20
|
else:
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
return (value is not None, value)
|
|
58
|
-
|
|
59
|
-
if sort_by:
|
|
60
|
-
reverse = sort_order == "desc"
|
|
61
|
-
items.sort(key=get_sort_key, reverse=reverse)
|
|
62
|
-
|
|
63
|
-
# Apply pagination
|
|
64
|
-
total = len(items)
|
|
65
|
-
if per_page:
|
|
66
|
-
start = (page - 1) * per_page
|
|
67
|
-
end = start + per_page
|
|
68
|
-
page_items = items[start:end]
|
|
69
|
-
total_pages = (total + per_page - 1) // per_page
|
|
70
|
-
else:
|
|
71
|
-
page_items = items
|
|
72
|
-
total_pages = 1
|
|
73
|
-
page = 1
|
|
74
|
-
per_page = total
|
|
75
|
-
|
|
76
|
-
return page_items, {
|
|
77
|
-
"total": total,
|
|
78
|
-
"page": page,
|
|
79
|
-
"per_page": per_page,
|
|
80
|
-
"total_pages": total_pages,
|
|
81
|
-
}
|
|
21
|
+
return None
|
|
22
|
+
return data
|
|
82
23
|
|
|
83
24
|
|
|
84
25
|
def core_pages(
|
|
85
|
-
database,
|
|
26
|
+
database,
|
|
27
|
+
languages: LanguagesMapping,
|
|
28
|
+
notifier_function,
|
|
29
|
+
csrf_generator,
|
|
30
|
+
location_model,
|
|
31
|
+
feature_flags={},
|
|
86
32
|
) -> Blueprint:
|
|
87
33
|
core_api_blueprint = Blueprint("api", __name__, url_prefix="/api")
|
|
88
34
|
core_api = Api(core_api_blueprint, doc="/doc", version="0.1")
|
|
@@ -193,9 +139,22 @@ def core_pages(
|
|
|
193
139
|
class Categories(Resource):
|
|
194
140
|
def get(self):
|
|
195
141
|
"""Shows all available categories"""
|
|
196
|
-
|
|
197
|
-
categories = make_tuple_translation(
|
|
198
|
-
|
|
142
|
+
raw_categories = database.get_categories()
|
|
143
|
+
categories = make_tuple_translation(raw_categories)
|
|
144
|
+
|
|
145
|
+
if not feature_flags.get("CATEGORIES_HELP", False):
|
|
146
|
+
return jsonify(categories)
|
|
147
|
+
else:
|
|
148
|
+
category_data = database.get_category_data()
|
|
149
|
+
categories_help = category_data["categories_help"]
|
|
150
|
+
proper_categories_help = []
|
|
151
|
+
if categories_help is not None:
|
|
152
|
+
for option in categories_help:
|
|
153
|
+
proper_categories_help.append(
|
|
154
|
+
{option: gettext(f"categories_help_{option}")}
|
|
155
|
+
)
|
|
156
|
+
|
|
157
|
+
return jsonify({"categories": categories, "categories_help": proper_categories_help})
|
|
199
158
|
|
|
200
159
|
@core_api.route("/languages")
|
|
201
160
|
class Languages(Resource):
|
|
@@ -207,9 +166,27 @@ def core_pages(
|
|
|
207
166
|
class CategoryTypes(Resource):
|
|
208
167
|
def get(self, category_type):
|
|
209
168
|
"""Shows all available types in category"""
|
|
210
|
-
|
|
211
|
-
local_data = make_tuple_translation(
|
|
212
|
-
|
|
169
|
+
category_data = database.get_category_data(category_type)
|
|
170
|
+
local_data = make_tuple_translation(category_data["categories"][category_type])
|
|
171
|
+
|
|
172
|
+
categories_options_help = get_or_none(
|
|
173
|
+
category_data, "categories_options_help", category_type
|
|
174
|
+
)
|
|
175
|
+
proper_categories_options_help = []
|
|
176
|
+
if categories_options_help is not None:
|
|
177
|
+
for option in categories_options_help:
|
|
178
|
+
proper_categories_options_help.append(
|
|
179
|
+
{option: gettext(f"categories_options_help_{option}")}
|
|
180
|
+
)
|
|
181
|
+
if not feature_flags.get("CATEGORIES_HELP", False):
|
|
182
|
+
return jsonify(local_data)
|
|
183
|
+
else:
|
|
184
|
+
return jsonify(
|
|
185
|
+
{
|
|
186
|
+
"categories_options": local_data,
|
|
187
|
+
"categories_options_help": proper_categories_options_help,
|
|
188
|
+
}
|
|
189
|
+
)
|
|
213
190
|
|
|
214
191
|
@core_api.route("/generate-csrf-token")
|
|
215
192
|
class CsrfToken(Resource):
|
|
@@ -224,14 +201,11 @@ def core_pages(
|
|
|
224
201
|
Shows full list of locations, with optional server-side pagination, sorting,
|
|
225
202
|
and filtering.
|
|
226
203
|
"""
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
)
|
|
233
|
-
items = [x.model_dump() for x in page_items]
|
|
234
|
-
return jsonify({"items": items, **pagination})
|
|
204
|
+
query_params = request.args.to_dict(flat=False)
|
|
205
|
+
if "sort_by" not in query_params:
|
|
206
|
+
query_params["sort_by"] = ["name"]
|
|
207
|
+
result = database.get_locations_paginated(query_params)
|
|
208
|
+
return jsonify(result)
|
|
235
209
|
|
|
236
210
|
def post(self):
|
|
237
211
|
"""
|
|
@@ -284,10 +258,9 @@ def core_pages(
|
|
|
284
258
|
List location suggestions, with optional server-side pagination, sorting,
|
|
285
259
|
and filtering by status.
|
|
286
260
|
"""
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
return jsonify({"items": page_items, **pagination})
|
|
261
|
+
query_params = request.args.to_dict(flat=False)
|
|
262
|
+
result = database.get_suggestions_paginated(query_params)
|
|
263
|
+
return jsonify(result)
|
|
291
264
|
|
|
292
265
|
@core_api.route("/admin/suggestions/<suggestion_id>")
|
|
293
266
|
class AdminManageSuggestion(Resource):
|
|
@@ -320,10 +293,9 @@ def core_pages(
|
|
|
320
293
|
List location reports, with optional server-side pagination, sorting,
|
|
321
294
|
and filtering by status/priority.
|
|
322
295
|
"""
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
return jsonify({"items": page_items, **pagination})
|
|
296
|
+
query_params = request.args.to_dict(flat=False)
|
|
297
|
+
result = database.get_reports_paginated(query_params)
|
|
298
|
+
return jsonify(result)
|
|
327
299
|
|
|
328
300
|
@core_api.route("/admin/reports/<report_id>")
|
|
329
301
|
class AdminManageReport(Resource):
|