geovisio 2.10.0__py3-none-any.whl → 2.11.0__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.
Files changed (58) hide show
  1. geovisio/__init__.py +3 -1
  2. geovisio/admin_cli/user.py +7 -2
  3. geovisio/config_app.py +21 -7
  4. geovisio/translations/be/LC_MESSAGES/messages.mo +0 -0
  5. geovisio/translations/be/LC_MESSAGES/messages.po +886 -0
  6. geovisio/translations/da/LC_MESSAGES/messages.mo +0 -0
  7. geovisio/translations/da/LC_MESSAGES/messages.po +96 -5
  8. geovisio/translations/de/LC_MESSAGES/messages.mo +0 -0
  9. geovisio/translations/de/LC_MESSAGES/messages.po +171 -132
  10. geovisio/translations/en/LC_MESSAGES/messages.mo +0 -0
  11. geovisio/translations/en/LC_MESSAGES/messages.po +169 -146
  12. geovisio/translations/eo/LC_MESSAGES/messages.mo +0 -0
  13. geovisio/translations/eo/LC_MESSAGES/messages.po +3 -2
  14. geovisio/translations/fr/LC_MESSAGES/messages.mo +0 -0
  15. geovisio/translations/fr/LC_MESSAGES/messages.po +3 -2
  16. geovisio/translations/it/LC_MESSAGES/messages.mo +0 -0
  17. geovisio/translations/it/LC_MESSAGES/messages.po +1 -1
  18. geovisio/translations/messages.pot +159 -138
  19. geovisio/translations/nl/LC_MESSAGES/messages.mo +0 -0
  20. geovisio/translations/nl/LC_MESSAGES/messages.po +44 -2
  21. geovisio/translations/oc/LC_MESSAGES/messages.mo +0 -0
  22. geovisio/translations/oc/LC_MESSAGES/messages.po +9 -6
  23. geovisio/translations/pt/LC_MESSAGES/messages.mo +0 -0
  24. geovisio/translations/pt/LC_MESSAGES/messages.po +944 -0
  25. geovisio/translations/pt_BR/LC_MESSAGES/messages.mo +0 -0
  26. geovisio/translations/pt_BR/LC_MESSAGES/messages.po +942 -0
  27. geovisio/translations/sv/LC_MESSAGES/messages.mo +0 -0
  28. geovisio/translations/sv/LC_MESSAGES/messages.po +1 -1
  29. geovisio/translations/tr/LC_MESSAGES/messages.mo +0 -0
  30. geovisio/translations/tr/LC_MESSAGES/messages.po +927 -0
  31. geovisio/translations/uk/LC_MESSAGES/messages.mo +0 -0
  32. geovisio/translations/uk/LC_MESSAGES/messages.po +920 -0
  33. geovisio/utils/annotations.py +7 -4
  34. geovisio/utils/auth.py +33 -0
  35. geovisio/utils/cql2.py +20 -3
  36. geovisio/utils/pictures.py +16 -18
  37. geovisio/utils/sequences.py +104 -75
  38. geovisio/utils/upload_set.py +20 -10
  39. geovisio/utils/users.py +18 -0
  40. geovisio/web/annotations.py +96 -3
  41. geovisio/web/collections.py +169 -76
  42. geovisio/web/configuration.py +12 -0
  43. geovisio/web/docs.py +17 -3
  44. geovisio/web/items.py +129 -72
  45. geovisio/web/map.py +92 -54
  46. geovisio/web/pages.py +48 -4
  47. geovisio/web/params.py +56 -11
  48. geovisio/web/pictures.py +3 -3
  49. geovisio/web/prepare.py +4 -2
  50. geovisio/web/queryables.py +57 -0
  51. geovisio/web/stac.py +8 -2
  52. geovisio/web/upload_set.py +83 -26
  53. geovisio/web/users.py +85 -4
  54. geovisio/web/utils.py +24 -6
  55. {geovisio-2.10.0.dist-info → geovisio-2.11.0.dist-info}/METADATA +3 -2
  56. {geovisio-2.10.0.dist-info → geovisio-2.11.0.dist-info}/RECORD +58 -46
  57. {geovisio-2.10.0.dist-info → geovisio-2.11.0.dist-info}/WHEEL +0 -0
  58. {geovisio-2.10.0.dist-info → geovisio-2.11.0.dist-info}/licenses/LICENSE +0 -0
@@ -7,13 +7,9 @@ from psycopg.sql import SQL
7
7
  from flask import current_app, request, Blueprint, url_for
8
8
  from flask_babel import gettext as _, get_locale
9
9
  from geopic_tag_reader import sequence as geopic_sequence
10
- from geovisio.web.utils import accountIdOrDefault
10
+ from geovisio.web.utils import accountOrDefault
11
11
  from geovisio.utils.fields import parse_relative_heading
12
- from geovisio.web.params import (
13
- as_latitude,
14
- as_longitude,
15
- parse_datetime,
16
- )
12
+ from geovisio.web.params import as_latitude, as_longitude, parse_datetime, Visibility, check_visibility
17
13
  import logging
18
14
  from geovisio.utils import db
19
15
  from geovisio import utils
@@ -76,8 +72,16 @@ class UploadSetCreationParameter(BaseModel):
76
72
  """Semantic tags associated to the upload_set. Those tags will be added to all sequences linked to this upload set"""
77
73
  relative_heading: Optional[int] = None
78
74
  """The relative heading (in degrees), offset based on movement path (0° = looking forward, -90° = looking left, 90° = looking right). For single picture upload_sets, 0° is heading north). Headings are unchanged if this parameter is not set."""
75
+ visibility: Optional[Visibility] = None
76
+ """Visibility of the upload set. Can be set to:
77
+ * `anyone`: the upload is visible to anyone
78
+ * `owner-only`: the upload is visible to the owner and administrator only
79
+ * `logged-only`: the upload is visible to logged users only
79
80
 
80
- model_config = ConfigDict(use_attribute_docstrings=True)
81
+ This visibility can also be set for each picture individually, or each collections, using the `visibility` field of the pictures/collections.
82
+ If not set at those levels, it will default to the visibility of the `account` and if not set the default visibility of the instance."""
83
+
84
+ model_config = ConfigDict(use_enum_values=True, use_attribute_docstrings=True)
81
85
 
82
86
  def validate(self):
83
87
  if self.no_split is True and (self.split_distance is not None or self.split_time is not None):
@@ -92,6 +96,16 @@ class UploadSetCreationParameter(BaseModel):
92
96
  def parse_relative_heading(cls, value):
93
97
  return parse_relative_heading(value)
94
98
 
99
+ @field_validator("visibility", mode="after")
100
+ @classmethod
101
+ def validate_visibility(cls, visibility):
102
+ if not check_visibility(visibility):
103
+ raise errors.InvalidAPIUsage(
104
+ _("The logged-only visibility is not allowed on this instance since anybody can create an account"),
105
+ status_code=400,
106
+ )
107
+ return visibility
108
+
95
109
 
96
110
  class UploadSetUpdateParameter(BaseModel):
97
111
  """Parameters used to update an UploadSet"""
@@ -130,8 +144,16 @@ class UploadSetUpdateParameter(BaseModel):
130
144
  """
131
145
  relative_heading: Optional[int] = None
132
146
  """The relative heading (in degrees), offset based on movement path (0° = looking forward, -90° = looking left, 90° = looking right). For single picture upload_sets, 0° is heading north). Headings are unchanged if this parameter is not set."""
147
+ visibility: Optional[Visibility] = None
148
+ """Visibility of the upload set. Can be set to:
149
+ * `anyone`: the upload is visible to anyone
150
+ * `owner-only`: the upload is visible to the owner and administrator only
151
+ * `logged-only`: the upload is visible to logged users only
133
152
 
134
- model_config = ConfigDict(use_attribute_docstrings=True, extra="forbid")
153
+ This visibility can also be set for each picture individually, or each collections, using the `visibility` field of the pictures/collections.
154
+ If not set at those levels, it will default to the visibility of the `account` and if not set the default visibility of the instance."""
155
+
156
+ model_config = ConfigDict(use_enum_values=True, use_attribute_docstrings=True, extra="forbid")
135
157
 
136
158
  def validate(self):
137
159
  if self.no_split is True and (self.split_distance is not None or self.split_time is not None):
@@ -141,6 +163,16 @@ class UploadSetUpdateParameter(BaseModel):
141
163
  "The `no_deduplication` parameter is incompatible with specifying `duplicate_distance` / `duplicate_rotation`"
142
164
  )
143
165
 
166
+ @field_validator("visibility", mode="after")
167
+ @classmethod
168
+ def validate_visibility(cls, visibility):
169
+ if not check_visibility(visibility):
170
+ raise errors.InvalidAPIUsage(
171
+ _("The logged-only visibility is not allowed on this instance since anybody can create an account"),
172
+ status_code=400,
173
+ )
174
+ return visibility
175
+
144
176
  def has_only_semantics_updates(self):
145
177
  return self.model_fields_set == {"semantics"}
146
178
 
@@ -153,15 +185,24 @@ class UploadSetUpdateParameter(BaseModel):
153
185
  def create_upload_set(params: UploadSetCreationParameter, accountId: UUID) -> UploadSet:
154
186
  sem = params.semantics
155
187
  params.semantics = None
188
+ # we handle visibility a bit differently, to be able to default to the account's default visibility / instance's default visibility
189
+ visibility = params.visibility
190
+ params.visibility = None
156
191
  db_params = model_query.get_db_params_and_values(params, account_id=accountId)
192
+
157
193
  with db.conn(current_app) as conn, conn.transaction():
158
194
 
159
195
  with conn.cursor(row_factory=class_row(UploadSet)) as cursor:
160
196
  db_upload_set = cursor.execute(
161
- SQL("INSERT INTO upload_sets({fields}) VALUES({values}) RETURNING *").format(
162
- fields=db_params.fields(), values=db_params.placeholders()
163
- ),
164
- db_params.params_as_dict,
197
+ SQL(
198
+ """INSERT INTO upload_sets({fields}, visibility)
199
+ VALUES({values},
200
+ (COALESCE(%(visibility)s,
201
+ (SELECT default_visibility FROM accounts WHERE id = %(account_id)s),
202
+ (SELECT default_visibility FROM configurations LIMIT 1))))
203
+ RETURNING *"""
204
+ ).format(fields=db_params.fields(), values=db_params.placeholders()),
205
+ db_params.params_as_dict | {"visibility": visibility},
165
206
  ).fetchone()
166
207
 
167
208
  if db_upload_set is None:
@@ -222,8 +263,22 @@ def update_upload_set(upload_set_id: UUID, params: UploadSetUpdateParameter, acc
222
263
  SQL("UPDATE upload_sets SET {fields} WHERE id = %(upload_set_id)s").format(fields=db_params.fields_for_set()),
223
264
  db_params.params_as_dict | {"upload_set_id": upload_set_id},
224
265
  )
266
+ if params.visibility is not None:
267
+ # if we change the visibility, we check if some collections have been created to change their visibility too
268
+ with conn.cursor() as cursor:
269
+ us_dispatched = cursor.execute(
270
+ SQL("SELECT dispatched FROM upload_sets WHERE id = %(upload_set_id)s"),
271
+ {"upload_set_id": upload_set_id},
272
+ ).fetchone()
273
+
274
+ if us_dispatched[0] is True:
275
+ cursor.execute(
276
+ SQL("UPDATE sequences SET visibility = %(visibility)s WHERE upload_set_id = %(upload_set_id)s"),
277
+ {"visibility": params.visibility, "upload_set_id": upload_set_id},
278
+ )
279
+
225
280
  # we get a full uploadset response
226
- return get_upload_set(upload_set_id)
281
+ return get_upload_set(upload_set_id, account_to_query=account.id if account else None)
227
282
 
228
283
 
229
284
  @bp.route("/upload_sets", methods=["POST"])
@@ -270,7 +325,7 @@ def postUploadSet(account=None):
270
325
  raise errors.InvalidAPIUsage(_("Parameter for creating an UploadSet should be a valid JSON"), status_code=415)
271
326
 
272
327
  params.validate()
273
- account_id = UUID(accountIdOrDefault(account))
328
+ account_id = UUID(accountOrDefault(account).id)
274
329
 
275
330
  upload_set = create_upload_set(params, account_id)
276
331
 
@@ -334,14 +389,14 @@ def patchUploadSet(upload_set_id, account=None):
334
389
  if upload_set is None:
335
390
  raise errors.InvalidAPIUsage(_("UploadSet doesn't exist"), status_code=404)
336
391
 
337
- if account and str(upload_set.account_id) != account.id:
338
- if not params.has_only_semantics_updates():
339
- raise errors.InvalidAPIUsage(_("You are not allowed to update this upload set"), status_code=403)
340
-
341
392
  if not params.model_fields_set:
342
393
  # nothing to update, return the upload set
343
- upload_set = get_upload_set(upload_set_id)
394
+ upload_set = get_upload_set(upload_set_id, account_to_query=account.id if account else None)
344
395
  else:
396
+ if account and str(upload_set.account_id) != account.id:
397
+ if not params.has_only_semantics_updates() and not account.can_edit_upload_set(str(upload_set.account_id)):
398
+ raise errors.InvalidAPIUsage(_("You are not allowed to update this upload set"), status_code=403)
399
+
345
400
  upload_set = update_upload_set(upload_set_id, params, account)
346
401
 
347
402
  return upload_set.model_dump_json(exclude_none=True), 200, {"Content-Type": "application/json"}
@@ -374,7 +429,7 @@ def getUploadSet(upload_set_id):
374
429
  schema:
375
430
  $ref: '#/components/schemas/GeoVisioUploadSet'
376
431
  """
377
- upload_set = get_upload_set(upload_set_id)
432
+ upload_set = get_upload_set(upload_set_id, account_to_query=auth.get_current_account_id())
378
433
  if upload_set is None:
379
434
  raise errors.InvalidAPIUsage(_("UploadSet doesn't exist"), status_code=404)
380
435
 
@@ -468,7 +523,9 @@ def listUserUpload(account):
468
523
  except ValidationError as ve:
469
524
  raise errors.InvalidAPIUsage(_("Impossible to parse parameters"), payload=validation_error(ve))
470
525
 
471
- upload_sets = list_upload_sets(account_id=params.account_id, limit=params.limit, filter=params.filter)
526
+ upload_sets = list_upload_sets(
527
+ account_id=params.account_id, limit=params.limit, filter=params.filter, account_to_query=account.id if account else None
528
+ )
472
529
 
473
530
  return upload_sets.model_dump_json(exclude_none=True), 200, {"Content-Type": "application/json"}
474
531
 
@@ -749,7 +806,7 @@ def addFilesToUploadSet(upload_set_id: UUID, account=None):
749
806
  file_type=params.file_type,
750
807
  )
751
808
  # Compute various metadata
752
- accountId = accountIdOrDefault(account)
809
+ accountId = accountOrDefault(account).id
753
810
  raw_pic = params.file.read()
754
811
  filesize = len(raw_pic)
755
812
  file["size"] = filesize
@@ -918,7 +975,7 @@ def completeUploadSet(upload_set_id: UUID, account=None):
918
975
  raise errors.InvalidAPIUsage(_("UploadSet %(u)s does not exist", u=upload_set_id), status_code=404)
919
976
 
920
977
  # Account associated to uploadset doesn't match current user
921
- if account is not None and account.id != str(upload_set["account_id"]):
978
+ if account is not None and not account.can_edit_upload_set(str(upload_set["account_id"])):
922
979
  raise errors.InvalidAPIUsage(_("You're not authorized to complete this upload set"), status_code=403)
923
980
 
924
981
  cursor.execute("UPDATE upload_sets SET completed = True WHERE id = %(id)s", {"id": upload_set_id})
@@ -927,7 +984,7 @@ def completeUploadSet(upload_set_id: UUID, account=None):
927
984
  current_app.background_processor.process_pictures() # type: ignore
928
985
 
929
986
  # query again the upload set, to get the updated status
930
- upload_set = get_upload_set(upload_set_id)
987
+ upload_set = get_upload_set(upload_set_id, account_to_query=account.id if account else None)
931
988
  if upload_set is None:
932
989
  raise errors.InvalidAPIUsage(_("UploadSet doesn't exist"), status_code=404)
933
990
 
@@ -960,12 +1017,12 @@ def deleteUploadSet(upload_set_id: UUID, account=None):
960
1017
  description: The UploadSet has been correctly deleted
961
1018
  """
962
1019
 
963
- upload_set = get_upload_set(upload_set_id)
1020
+ upload_set = get_upload_set(upload_set_id, account_to_query=account.id if account else None)
964
1021
 
965
1022
  if not upload_set:
966
1023
  raise errors.InvalidAPIUsage(_("UploadSet %(u)s does not exist", u=upload_set_id), status_code=404)
967
1024
  # Account associated to uploadset doesn't match current user
968
- if account is not None and account.id != str(upload_set.account_id):
1025
+ if account is not None and not account.can_edit_upload_set(str(upload_set.account_id)):
969
1026
  raise errors.InvalidAPIUsage(_("You're not authorized to delete this upload set"), status_code=403)
970
1027
 
971
1028
  utils.upload_set.delete(upload_set)
geovisio/web/users.py CHANGED
@@ -3,6 +3,7 @@ from uuid import UUID
3
3
  import flask
4
4
  from flask import request, current_app, session, url_for
5
5
  from flask_babel import gettext as _
6
+ from dataclasses import dataclass
6
7
  from pydantic import BaseModel, ConfigDict, ValidationError, computed_field
7
8
  from geovisio.utils import auth, db
8
9
  from geovisio import errors
@@ -15,6 +16,7 @@ from geovisio.utils.params import validation_error
15
16
  from geovisio.web import stac
16
17
  from geovisio.web.auth import NEXT_URL_KEY
17
18
  from geovisio.web.utils import get_root_link
19
+ from geovisio.web.params import Visibility, check_visibility
18
20
 
19
21
  bp = flask.Blueprint("user", __name__, url_prefix="/api/users")
20
22
 
@@ -45,10 +47,17 @@ class UserInfo(BaseModel):
45
47
  tos_accepted: Optional[bool] = None
46
48
  """True means the user has accepted the terms of service (tos). Can only be seen by the user itself"""
47
49
 
50
+ tos_latest_change_read: Optional[bool] = None
51
+ """True means the user has read the latest changes to the terms of service (tos). Can only be seen by the user itself"""
52
+
48
53
  permissions: Optional[Permissions] = None
49
54
  """The user role and permissions. Can only be seen by the user itself"""
50
55
 
51
- model_config = ConfigDict(use_attribute_docstrings=True)
56
+ default_visibility: Optional[Visibility] = None
57
+ """Default visibility for all upload_sets/sequences/pictures of the user. The visibility can be overriden at the upload_set/sequence/picture level.
58
+ If not set, the default visibility of the instance will be used."""
59
+
60
+ model_config = ConfigDict(use_attribute_docstrings=True, use_enum_values=True)
52
61
 
53
62
  @computed_field
54
63
  @property
@@ -71,13 +80,43 @@ class UserInfo(BaseModel):
71
80
  ]
72
81
 
73
82
 
83
+ @dataclass
84
+ class AdditionalUserInfo:
85
+ default_visibility: Visibility
86
+ tos_latest_change_read: bool
87
+
88
+
89
+ def get_additional_user_info(account: auth.Account) -> AdditionalUserInfo:
90
+ """Get additional information about the user, like the default visibility"""
91
+ u = db.fetchone(
92
+ current_app,
93
+ """SELECT
94
+ COALESCE(default_visibility, (SELECT default_visibility FROM configurations LIMIT 1)) AS default_visibility,
95
+ CASE WHEN
96
+ tos_latest_change_read_at IS NULL THEN FALSE
97
+ ELSE COALESCE(tos_latest_change_read_at >= (SELECT MAX(updated_at) FROM pages WHERE name = 'terms-of-service'), TRUE)
98
+ END AS tos_latest_change_read
99
+ FROM accounts WHERE id = %s""",
100
+ [account.id],
101
+ row_factory=dict_row,
102
+ )
103
+ return AdditionalUserInfo(default_visibility=u["default_visibility"], tos_latest_change_read=u["tos_latest_change_read"])
104
+
105
+
74
106
  def _get_user_info(account: auth.Account):
75
107
  user_info = UserInfo(id=account.id, name=account.name, collaborative_metadata=account.collaborative_metadata)
76
108
  logged_account = auth.get_current_account()
77
- if logged_account is not None and account.id == logged_account.id:
109
+ if logged_account is not None and (account.id == logged_account.id or logged_account.can_see_all()):
78
110
  # we show the term of service acceptance only if the user is the logged user and if ToS are mandatory
111
+ # we also show all fields to the admins
79
112
  if flask.current_app.config["API_ENFORCE_TOS_ACCEPTANCE"]:
80
113
  user_info.tos_accepted = account.tos_accepted
114
+
115
+ # same, we only show the default visibility if the user is the logged user
116
+ additional_info = get_additional_user_info(account)
117
+ user_info.default_visibility = additional_info.default_visibility
118
+ user_info.tos_latest_change_read = additional_info.tos_latest_change_read
119
+
81
120
  user_info.permissions = Permissions(
82
121
  role=account.role,
83
122
  can_check_reports=account.can_check_reports(),
@@ -350,9 +389,22 @@ class UserConfiguration(BaseModel):
350
389
 
351
390
  If not set, it will default to the instance default collaborative editing policy."""
352
391
 
392
+ default_visibility: Optional[Visibility] = None
393
+ """Default visibility for all upload_sets/sequences/pictures of the user. The visibility can be overriden at the upload_set/sequence/picture level.
394
+ If not set, the default visibility of the instance will be used."""
395
+
353
396
  def has_override(self) -> bool:
354
397
  return bool(self.model_fields_set)
355
398
 
399
+ def validate(self):
400
+ if self.default_visibility and not check_visibility(self.default_visibility):
401
+ raise errors.InvalidAPIUsage(
402
+ _("The logged-only visibility is not allowed on this instance since anybody can create an account"),
403
+ status_code=400,
404
+ )
405
+
406
+ model_config = ConfigDict(use_enum_values=True, use_attribute_docstrings=True)
407
+
356
408
 
357
409
  @bp.route("/me", methods=["PATCH"])
358
410
  @auth.login_required()
@@ -387,8 +439,11 @@ def patchUserConfiguration(account):
387
439
 
388
440
  if not metadata:
389
441
  return _get_user_info(account)
390
- params = get_db_params_and_values(metadata)
442
+
443
+ metadata.validate()
444
+
391
445
  if metadata.has_override():
446
+ params = get_db_params_and_values(metadata)
392
447
 
393
448
  fields = params.fields_for_set_list()
394
449
 
@@ -421,7 +476,9 @@ def accept_tos(account: auth.Account):
421
476
  # Note: accepting twice does not change the accepted_at date
422
477
  account = db.fetchone(
423
478
  current_app,
424
- SQL("UPDATE accounts SET tos_accepted_at = COALESCE(tos_accepted_at, NOW()) WHERE id = %(account_id)s RETURNING *"),
479
+ SQL(
480
+ "UPDATE accounts SET tos_accepted_at = COALESCE(tos_accepted_at, NOW()), tos_latest_change_read_at = NOW() WHERE id = %(account_id)s RETURNING *"
481
+ ),
425
482
  {"account_id": account.id},
426
483
  row_factory=class_row(auth.Account),
427
484
  )
@@ -431,3 +488,27 @@ def accept_tos(account: auth.Account):
431
488
  session.permanent = True
432
489
 
433
490
  return _get_user_info(account)
491
+
492
+
493
+ @bp.route("/me/tos_read", methods=["POST"])
494
+ @auth.login_required()
495
+ def tos_read(account: auth.Account):
496
+ """
497
+ Mark the new terms of service changes as read.
498
+ ---
499
+ tags:
500
+ - Auth
501
+ responses:
502
+ 200:
503
+ description: Successfully marked the terms of service as read
504
+ content:
505
+ application/json: {}
506
+ """
507
+ account = db.fetchone(
508
+ current_app,
509
+ SQL("UPDATE accounts SET tos_latest_change_read_at = NOW() WHERE id = %(account_id)s RETURNING *"),
510
+ {"account_id": account.id},
511
+ row_factory=class_row(auth.Account),
512
+ )
513
+
514
+ return "", 200
geovisio/web/utils.py CHANGED
@@ -7,6 +7,7 @@ from geovisio import errors
7
7
  from geovisio.utils import db
8
8
  from flask import current_app, url_for
9
9
  from flask_babel import gettext as _
10
+ from psycopg.rows import dict_row
10
11
  from geovisio import __version__
11
12
  import subprocess
12
13
 
@@ -42,14 +43,31 @@ def cleanNoneInList(val: typing.List) -> typing.List:
42
43
  return list(filter(lambda e: e is not None, val))
43
44
 
44
45
 
45
- def accountIdOrDefault(account):
46
- # Get default account ID
46
+ def get_default_account():
47
+ from geovisio.utils import auth
48
+
49
+ r = db.fetchone(current_app, "SELECT id, name, role FROM accounts WHERE is_default", row_factory=dict_row)
50
+ if not r:
51
+ return None
52
+ return auth.Account(
53
+ id=r["id"],
54
+ name=r["name"],
55
+ role=auth.AccountRole(r["role"]),
56
+ )
57
+
58
+
59
+ def accountOrDefault(account):
60
+ # Get default account
47
61
  if account is not None:
48
- return account.id
49
- accountId = db.fetchone(current_app, "SELECT id FROM accounts WHERE is_default")
50
- if accountId is None:
62
+ return account
63
+ if current_app.config["API_FORCE_AUTH_ON_UPLOAD"]:
64
+ # if the API forces login on upload, we do not return the default account
65
+ return None
66
+ # if the API authorizes anonymous upload, we get the default account ID
67
+ def_account = get_default_account()
68
+ if def_account is None:
51
69
  raise errors.InternalError(_("No default account defined, please contact your instance administrator"))
52
- return str(accountId[0])
70
+ return def_account
53
71
 
54
72
 
55
73
  def get_license_link():
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: geovisio
3
- Version: 2.10.0
3
+ Version: 2.11.0
4
4
  Summary: GeoVisio API - Main
5
5
  Author-email: Adrien PAVIE <panieravide@riseup.net>, Antoine Desbordes <antoine.desbordes@gmail.com>
6
6
  Requires-Python: >=3.10
@@ -28,12 +28,13 @@ Requires-Dist: pygeofilter[backend-native] ~= 0.3.1
28
28
  Requires-Dist: python-dateutil ~= 2.9.0
29
29
  Requires-Dist: tzdata ~= 2025.2
30
30
  Requires-Dist: croniter ~= 6.0.0
31
- Requires-Dist: pydantic ~= 2.11
31
+ Requires-Dist: pydantic ~= 2.12
32
32
  Requires-Dist: pydantic-extra-types ~= 2.7
33
33
  Requires-Dist: flask-babel ~= 4.0.0
34
34
  Requires-Dist: geojson-pydantic ~= 2.0.0
35
35
  Requires-Dist: email-validator ~= 2.2.0
36
36
  Requires-Dist: multipart>=1.2.1
37
+ Requires-Dist: gunicorn ~= 23.0.0
37
38
  Requires-Dist: flit ~= 3.9.0 ; extra == "build"
38
39
  Requires-Dist: coverage ~= 7.9 ; extra == "dev"
39
40
  Requires-Dist: protobuf ~= 5.26 ; extra == "dev"
@@ -1,5 +1,5 @@
1
- geovisio/__init__.py,sha256=LcHU6JLcjjGDdaFgc83jbxUV_Zc8YXUkD_dIBA7u-nQ,7952
2
- geovisio/config_app.py,sha256=cS4TtW7ESy5jeaHi_9neJYWwA21VBNNrh4IDgf2iMmI,14848
1
+ geovisio/__init__.py,sha256=qiKebVarRNYXuusmrwXN0aa7ZhgVQ7Qz5U0-fv-5tqE,8010
2
+ geovisio/config_app.py,sha256=idDlUutkym9vVFyl5BEwG47khSsfe5LSGJSIbs3XHKA,15913
3
3
  geovisio/db_migrations.py,sha256=9lHkyG_RiCWzrFkfwhkslScUsbCZScN-KVhkXrtnPDo,4560
4
4
  geovisio/errors.py,sha256=uTn-kI7SUl5OPB8Mv3Qqu7Ucp5JvcqWPQFfgLCqsEpI,1376
5
5
  geovisio/admin_cli/__init__.py,sha256=1e0hX771-3iG8eBcNmVvUYyg8qXnpng-9YWvi3MI3Kg,3248
@@ -8,54 +8,64 @@ geovisio/admin_cli/db.py,sha256=mJ-cGuOAAsg-ovbP9L1kyL4xE0C4bYRuozzqQkaFyw8,897
8
8
  geovisio/admin_cli/default_account_tokens.py,sha256=W-v5uPjCBvAujjAUx1HrfgjPj-tEyncb-EUMLpsWc9w,469
9
9
  geovisio/admin_cli/reorder_sequences.py,sha256=LKKzdO2w4N-cQmi6rqKHKYG5YGzPxYRTbnfcPKakuYM,2826
10
10
  geovisio/admin_cli/sequence_heading.py,sha256=BEPuRfCDXXpqSSzK2ysrxHf0OD4THzrMI_YK2uXQlGk,633
11
- geovisio/admin_cli/user.py,sha256=4ml2E_aphz3I3NcuUPB2dwe_jXhcE7AGa0R5VTm3_ik,2753
11
+ geovisio/admin_cli/user.py,sha256=f_FjJ2Wf882xLJKR34aUiAdNFmYAcGs1KHGH8JMHYHE,3007
12
12
  geovisio/templates/main.html,sha256=VDVQwCZ1mNjH7sH4VOIdn8gM09R9LJZX49SPtA2VEzM,2963
13
13
  geovisio/templates/viewer.html,sha256=JErXdU2ujj4LdMHgQbYNCTfKuYGEXbJTQwBE-K_MNXQ,892
14
- geovisio/translations/messages.pot,sha256=zSzcuOQtONiGQrZE2hRkrB7thd5UGyC41dox867kV88,20827
14
+ geovisio/translations/messages.pot,sha256=ra2ATxNX4fRAg1tQDHsc2V-t9PZrEkzeodsCXBnaTyA,21569
15
15
  geovisio/translations/ar/LC_MESSAGES/messages.mo,sha256=2OvIx-hvvhBbjXvVhc5MaQ-0QnzTWISmNeb4vPthffM,516
16
16
  geovisio/translations/ar/LC_MESSAGES/messages.po,sha256=WcdpU3LH1Qf39WiIXQ8UMy1SyL7DHiWCbv0BVG_crW4,20816
17
+ geovisio/translations/be/LC_MESSAGES/messages.mo,sha256=ELIYTUJZPBMyC80GZlt9Be6omSNm9Gcd8WVW_AkHzqY,29148
18
+ geovisio/translations/be/LC_MESSAGES/messages.po,sha256=KTiqYgX7xkXEGj4ECIKjHkx08Vk5DstvKoucbBmb0SU,37820
17
19
  geovisio/translations/br/LC_MESSAGES/messages.mo,sha256=FjvUouzaLCBxvVH51A4PVwGGFk6mAepYasnI4v8LcnQ,719
18
20
  geovisio/translations/br/LC_MESSAGES/messages.po,sha256=tGJK1DoeKM-fRHuGa716xHkYtprVoKSNcB4oIqL0JtY,19433
19
- geovisio/translations/da/LC_MESSAGES/messages.mo,sha256=ketqWtB3ymB0tUaHEp2_nnqFrRX25pwuE2AcCno9W-Q,21197
20
- geovisio/translations/da/LC_MESSAGES/messages.po,sha256=af7uax57NEw_JFNO11lFKGPGYJ05bOQCGryw15wP8Ms,29397
21
- geovisio/translations/de/LC_MESSAGES/messages.mo,sha256=4YJijXlC1Dix39oX6CxNYd0J6k-I4AFx5jXyZq7Jib4,24359
22
- geovisio/translations/de/LC_MESSAGES/messages.po,sha256=6S7rJpu7qfq78_YwZ9M5ueF4-TpvlZmF14b13g_aF8Y,33121
21
+ geovisio/translations/da/LC_MESSAGES/messages.mo,sha256=PodrgH22QW991b1SJQUWjGYn61y1WDygCFWYG8jPLec,24006
22
+ geovisio/translations/da/LC_MESSAGES/messages.po,sha256=XyovCUCvQlqOlV0lIUWT3Fkwc2DoigDNtFGTm3nhiHU,32891
23
+ geovisio/translations/de/LC_MESSAGES/messages.mo,sha256=6XAhcucCmxWjFRFTh5otFC8kRBA3s8filEzNCDUlIhM,25662
24
+ geovisio/translations/de/LC_MESSAGES/messages.po,sha256=v-82HhVnkmY3HXVxLXuI43Rp4usUq7vMiaYhFyBHHHM,34735
23
25
  geovisio/translations/el/LC_MESSAGES/messages.mo,sha256=vy1jtEG6mLS5sYWPfQIr5U4XsZ21ZzSbsHAJHGQXZSY,433
24
26
  geovisio/translations/el/LC_MESSAGES/messages.po,sha256=kIz9QJr_GPk_Eh7bJ2vxjsFbIGyvt_-hwra0zVlupyM,17404
25
- geovisio/translations/en/LC_MESSAGES/messages.mo,sha256=i7HmGj2_mAgGDV9b5dZwSNawx7WNlVBqV5T5uXVl8ok,21397
26
- geovisio/translations/en/LC_MESSAGES/messages.po,sha256=KD-Fq-gCywKcQnBw7B-Rhfk0s2-xAraXiBqUEPmNjNo,29920
27
- geovisio/translations/eo/LC_MESSAGES/messages.mo,sha256=AdSbZMS6Fj10_w5dQVpgLgjfs32EHw5m87eTp0IaFmo,22387
28
- geovisio/translations/eo/LC_MESSAGES/messages.po,sha256=0vgsW6aWR0xUZptAym4HyO8pQh1yEShbojurjZvp0nU,30954
27
+ geovisio/translations/en/LC_MESSAGES/messages.mo,sha256=dLOibccRT4YtJK-lrd5jCD6lMHQTcveO8SqLxLa3YI0,22007
28
+ geovisio/translations/en/LC_MESSAGES/messages.po,sha256=0eG5vFnAjUrKQvGM71t7nYmNtkRqhf4GXsIZjoLBaLA,30946
29
+ geovisio/translations/eo/LC_MESSAGES/messages.mo,sha256=M_GTAP9gC_SOkN2laCt0xNYb1ASN-iea3yCLcXP3_aM,22336
30
+ geovisio/translations/eo/LC_MESSAGES/messages.po,sha256=EcgNC11FIn1YR81lg4hYoQB6XGtUEDlp8dez7xbRRDw,30973
29
31
  geovisio/translations/es/LC_MESSAGES/messages.mo,sha256=R5JmcfauTrQxIynQNT7asjdLEJC9-VEMXYrcugfBbsY,18950
30
32
  geovisio/translations/es/LC_MESSAGES/messages.po,sha256=sn3UQXBk6pg7ny4ndaPxbvZzTBzNFQBsmJY2lJxTXFQ,26779
31
33
  geovisio/translations/fi/LC_MESSAGES/messages.mo,sha256=6-WCesFiV00MkNM_Wpi7-D51DOZRNg_QOM2sL7-UPhA,626
32
34
  geovisio/translations/fi/LC_MESSAGES/messages.po,sha256=AS-VBD2kM0lXQXCvMu_CqaPxGtZj1uzkJJV8ex7coVU,14684
33
- geovisio/translations/fr/LC_MESSAGES/messages.mo,sha256=i1RnE28Jom-bzN6lzf6qO8AuXpJ5bTNLjerwU2P1y34,25063
34
- geovisio/translations/fr/LC_MESSAGES/messages.po,sha256=Q_VNX6EdCjwilbptnB4PaWJToPMZ0NkxtXXYfCESpzY,33759
35
+ geovisio/translations/fr/LC_MESSAGES/messages.mo,sha256=ZGXfI_R0z5xsLPkgK_b3OvID4CBVMT_OCHG0vCiPBDQ,25015
36
+ geovisio/translations/fr/LC_MESSAGES/messages.po,sha256=APiScIDdgR_CE0b-767h_ti0xhrtPf0DY3ijRAa0vlo,33786
35
37
  geovisio/translations/hu/LC_MESSAGES/messages.mo,sha256=0Hb7mv7p1BVM8QqZIYUtF3LRym8Sl9HFWfZAa00TobU,20013
36
38
  geovisio/translations/hu/LC_MESSAGES/messages.po,sha256=HudkPHKwEdCoY-vwCtSilSqPe88jcDIn8_hF6U6CThg,27493
37
- geovisio/translations/it/LC_MESSAGES/messages.mo,sha256=8vLUUFP157568oUM25eft0UJtA6AcTTUykRNZ-WiQpc,24087
38
- geovisio/translations/it/LC_MESSAGES/messages.po,sha256=uMme7kN5KJobxs2J611WG-jEuxVCt9G6IjCRzmRyJZo,32828
39
+ geovisio/translations/it/LC_MESSAGES/messages.mo,sha256=cqfdKf1s7B4d2D4OIENd7vceJS2U1k7JtCIPBrQtzWc,24087
40
+ geovisio/translations/it/LC_MESSAGES/messages.po,sha256=657foSFciNtjJeGtSDThVFBOG-jXgNKVbC-VDPzpp3o,32828
39
41
  geovisio/translations/ja/LC_MESSAGES/messages.mo,sha256=ZPHJrNdf4bgiNFjxP8W41fkZ2OTJ7Swrqt-Hkh5LfO8,24194
40
42
  geovisio/translations/ja/LC_MESSAGES/messages.po,sha256=JWjqZnlmM_decqpVrFAc79sV3yIxAF9nkGSiB5ocZtU,32626
41
43
  geovisio/translations/ko/LC_MESSAGES/messages.mo,sha256=eKuQS9zLcJ9s-DzbfR-QK2INBJL10jTIQ1kuSTdJ9Rg,426
42
44
  geovisio/translations/ko/LC_MESSAGES/messages.po,sha256=Bdj_LmU69MWZCmajgCm_QNxlKETmN8jzaJnmemuftHg,17404
43
- geovisio/translations/nl/LC_MESSAGES/messages.mo,sha256=ZSjPgkgVdFD1EU39I9MvbS0WmCz_GiZb-gS-GbbiEWg,22878
44
- geovisio/translations/nl/LC_MESSAGES/messages.po,sha256=dUg-xm7cr6yL1eKITjNJQBLPxgkQYE_34H1EgNrOQ6c,32005
45
- geovisio/translations/oc/LC_MESSAGES/messages.mo,sha256=zaKy9mleHCTWd7rLFV2Ced4KvdD-rZhxVafQEIBuQnY,433
46
- geovisio/translations/oc/LC_MESSAGES/messages.po,sha256=-sLU4ULuSarTqt26XCq5xU6pwTTr_xGpcogmYnb7xqI,20816
45
+ geovisio/translations/nl/LC_MESSAGES/messages.mo,sha256=GeS_psHAJ74WnChUPAsNbrBdv_qT_pkuyXP1lOjz1A4,24109
46
+ geovisio/translations/nl/LC_MESSAGES/messages.po,sha256=hUvDXi6E1b4BwMgaZ3iNYM9itej6b36WwxLu327c0iA,33669
47
+ geovisio/translations/oc/LC_MESSAGES/messages.mo,sha256=txjLreM246r5zAKjfE-71pNX5wsV090nEHMJ6Pc5WzE,705
48
+ geovisio/translations/oc/LC_MESSAGES/messages.po,sha256=AURuUaDJHny8N2jmDGqXtaHn1UoxYArzzXyQigpAefI,21052
47
49
  geovisio/translations/pl/LC_MESSAGES/messages.mo,sha256=0iFTAhma7jjyl13DCLr2Xr0hgDSN-_fOqcKoYcdDwGE,9912
48
50
  geovisio/translations/pl/LC_MESSAGES/messages.po,sha256=p2SV3x0LvOJFT41eaJ0_p1COHt78N2AiZoQhbwJS98k,22186
49
- geovisio/translations/sv/LC_MESSAGES/messages.mo,sha256=k7Ssr8tax43wmVy_wVsL5oM03qykV0WeG8-ClxkSZoE,20659
50
- geovisio/translations/sv/LC_MESSAGES/messages.po,sha256=yglWtKCyLiivuMfKI-ret2GLs98aRYaAOvk6YTCBkO4,28760
51
+ geovisio/translations/pt/LC_MESSAGES/messages.mo,sha256=XWpzkBiU_5LrIyaB5y1RplX0BU87A9VKtwTkQYYfgac,24167
52
+ geovisio/translations/pt/LC_MESSAGES/messages.po,sha256=4KbkzYooZrjYuWwUe93YQPu6BnXycT5Wrzo5GxKRJpY,33112
53
+ geovisio/translations/pt_BR/LC_MESSAGES/messages.mo,sha256=jtLg359ohyUkDTwi6SDPkF8QTNuTo5k47l7t4BAt7Jc,24522
54
+ geovisio/translations/pt_BR/LC_MESSAGES/messages.po,sha256=Z_7Yxe7-seoetY6_eBVc2NepKfdlqYiaH6tEQquxSD0,33461
55
+ geovisio/translations/sv/LC_MESSAGES/messages.mo,sha256=UuhkVLpOMy5UcT8odozHlTRF2JqW6l5tEoiquubm8Kg,20659
56
+ geovisio/translations/sv/LC_MESSAGES/messages.po,sha256=h54AxKcmcg12VD6-JSnsY82PGEoppLcPbpb_t9gbPSU,28760
51
57
  geovisio/translations/ti/LC_MESSAGES/messages.mo,sha256=YeCBuScoL_qi-ZSA4v2O-h0PxKWjRWDgh_de3sJaUas,433
52
58
  geovisio/translations/ti/LC_MESSAGES/messages.po,sha256=4Oju5eWJkD3DxjKoOseSr4geWPnZ8iOUIZR8ApvYyPc,19433
59
+ geovisio/translations/tr/LC_MESSAGES/messages.mo,sha256=aBNjeD81YHLE1V7TTt_1pES8uWp08bkOTxHWwkbnQFY,23861
60
+ geovisio/translations/tr/LC_MESSAGES/messages.po,sha256=OlvkKnWsFjrllHKdnrcjo__CtYQvH0RWv2d9zCTuQ3w,32749
61
+ geovisio/translations/uk/LC_MESSAGES/messages.mo,sha256=xTsURpjzC5goiRidfmfzxOOncoP2IU6FEwUCFCOjkgU,30668
62
+ geovisio/translations/uk/LC_MESSAGES/messages.po,sha256=Y8e26jdTrx4FRFf5pEo8GshmAjIuZyxkkQ5eBsN3k0A,39539
53
63
  geovisio/translations/zh_Hant/LC_MESSAGES/messages.mo,sha256=TmRUyfTGoBpU-2BE-nKjhwdr9r0ikDioVQU-JQ_ih90,431
54
64
  geovisio/translations/zh_Hant/LC_MESSAGES/messages.po,sha256=HcorbHk7OpRWL6v3oEiWxeifaentdF5xgcY_oFAOGEI,18356
55
65
  geovisio/utils/__init__.py,sha256=g4SWVoV73cSXjf5-5D9-HmyB5xKmHSuxxOGWnx7W3V0,71
56
- geovisio/utils/annotations.py,sha256=vLP6YRJgqFUfGHvX9qQabBduMaHGLWiivEk8YH9fdEA,6884
57
- geovisio/utils/auth.py,sha256=WDwllPHp7WI38SilT2mf29IinRsPR5nnbBVxGjYKkQQ,13934
58
- geovisio/utils/cql2.py,sha256=42igfsnpTAW8Ee70uvq7wAeTrDZ9JwDyIOWJuV_hkDI,4720
66
+ geovisio/utils/annotations.py,sha256=gRFM2cTpx79-hJZ6TjlWF-YpgtBeNTjwZ_EfsWnC6Yc,7282
67
+ geovisio/utils/auth.py,sha256=qyTOH2M6bZaJUF_fBDxEcZADgiWpjAlzNu31rY0Ehfs,15541
68
+ geovisio/utils/cql2.py,sha256=o1r6yQBRJ_akEiaQICVXycBe7s8hDPuX1DdHTjYqZt4,5836
59
69
  geovisio/utils/db.py,sha256=cxetPL-URdeOxmDMPwxKovB93yQYLNlOL8UHvP4DHg0,2856
60
70
  geovisio/utils/excluded_areas.py,sha256=6f3wwsgNpJKxAXnHH8RKlktgHpsG-0QVNTWDDTFqPZ8,2585
61
71
  geovisio/utils/extent.py,sha256=vzOHvbG6lpSNt7KrsaonBOx7Tz46S1J603gLbZvs36g,557
@@ -67,39 +77,41 @@ geovisio/utils/loggers.py,sha256=_OrGXME4o5qQz8VBaLxYopHVK0DY0QgzXu6O2W0WBjo,477
67
77
  geovisio/utils/model_query.py,sha256=Rdd0_mWJp5nmABVNzzVapaai413PxjgMzmo9NjjUrmI,2074
68
78
  geovisio/utils/params.py,sha256=Yj9-PwC8jxb9LjQZ5K8TERimSsWKwJBHPhUxlzDVMhg,714
69
79
  geovisio/utils/pic_shape.py,sha256=1HVlhgxNDtGpSFumL_GUc7JOsYWOi1wjtAtkhCijxGo,2271
70
- geovisio/utils/pictures.py,sha256=Xv3eOIPp4fycGRNAs3VJRt3kArOajQ4t3QtjF8A83M8,28889
80
+ geovisio/utils/pictures.py,sha256=71ghwzOa1-r9KPe-bH5HT_G8oIw6LJnNs-WVDgOWWs0,29037
71
81
  geovisio/utils/reports.py,sha256=3simWHf6t_OuLw2hh2HPYj8vsji00Pz9iRnJOqbTnPs,5227
72
82
  geovisio/utils/semantics.py,sha256=MCJtxFSIsuDez8807hGHdlkOuVey6ThCFvUfJvva9f0,9832
73
83
  geovisio/utils/sentry.py,sha256=lGDhm0ROW2Z-Ugtzq_M9R8yTKalYN4Etq19Uz63c6Tk,3737
74
- geovisio/utils/sequences.py,sha256=1rPkUjOrat6jl1Ev3As_idhRMAmPQ6fTJpjfl5ql9-s,30735
84
+ geovisio/utils/sequences.py,sha256=zy3WIKnwhKfduS-WWoHp-Js7pDM6hQqoWx0bkQfFUGg,32191
75
85
  geovisio/utils/tags.py,sha256=GyihW-TgQk1ZCpqYPMoN64qOZ6PCFCvCLK9HQnZhtY8,868
76
86
  geovisio/utils/time.py,sha256=-hOs7FSx-8eiGmMQtTOrCoF8d_yMlj2306vfxJftEr8,642
77
87
  geovisio/utils/tokens.py,sha256=tkihnnXqgQeIME_d12tC8PVrPN90A0i9k6UPEbgZ9TQ,3047
78
- geovisio/utils/upload_set.py,sha256=Aym0K93PlNe8JzHPpdTEvKOPOdQ3mDOAGemc0fDTFQI,31038
88
+ geovisio/utils/upload_set.py,sha256=w0i9p_2vDLqHVIpzsWctTG8a57vOv4sXxVYrQzkwzHo,31865
89
+ geovisio/utils/users.py,sha256=zU-OPeSgeldO9vtE2T84uAkKKX4hihrgd9xrfDEmsT0,1054
79
90
  geovisio/utils/website.py,sha256=3U9-WL0WGLKPDQHU8N08QCmUL6rKp54yRatpQ64kQhM,1958
80
91
  geovisio/web/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
81
- geovisio/web/annotations.py,sha256=Sz-n6eYyiWtwFUo0wjQE-CDepsJtWkmtzAXGXE0P6sw,12178
92
+ geovisio/web/annotations.py,sha256=BZZTsL0ohUEduJC-nZbu0I9HqW3FepIdrUQAvpTVXZE,15137
82
93
  geovisio/web/auth.py,sha256=coY35MzOXJQ8QocmAopWztecBUTVT4YBPTovXQhxEpw,7142
83
- geovisio/web/collections.py,sha256=ABFOhrUqqIERBTi-hr1dexWFw1LFEf42SijmVgsC9lg,48054
84
- geovisio/web/configuration.py,sha256=uRSfRQIBZqAfH09QFZP_8ofu-bajJUvrhToev1DgzJE,3143
85
- geovisio/web/docs.py,sha256=b-tBrKRrtF7UsblOhKaL247c9pmM9MDavzdg1YILJLc,62741
94
+ geovisio/web/collections.py,sha256=rVRCEbg5-NQwp4tVR8s8glDDz2lc322JxC55omEzVTw,53110
95
+ geovisio/web/configuration.py,sha256=fXipGlnvsYfOeup663jG4u_Wdq-dr5Ssh77NcZF0pqA,3549
96
+ geovisio/web/docs.py,sha256=5MXA0qrzo7RcWSWpJW6qogI1IVvQ6VYMSRBC9M1LDak,63595
86
97
  geovisio/web/excluded_areas.py,sha256=5BNSZ0UqgFMtgvgrJ73eYGJXPJRnV-mGEs36WDRRxTk,13024
87
- geovisio/web/items.py,sha256=cFEJevQWP0a-9rrXBPK5ogWSfIGpy564HkPPylvT9pk,65090
88
- geovisio/web/map.py,sha256=hzVC0vS-71mFEvRmfCxAprums2Zz5baP6EFTL0uW02M,26136
89
- geovisio/web/pages.py,sha256=Hkc3KJFE6D38vGnkCK5WUBJ8KQemI1f1wGXpxeiOiNo,6632
90
- geovisio/web/params.py,sha256=W1wLGFjSztAx9Xl-zzqQSNPtD28trsxqr_qc5fzL6Dw,21523
91
- geovisio/web/pictures.py,sha256=dr-oSl2_k-sl1ZmfrwyW2HZPxPsSzxOHtY5a0-9u_Gk,7471
92
- geovisio/web/prepare.py,sha256=R10_xf6O9dmAAwOMC-vsaxgNTdc9BkDJLATqH6MKtCw,5620
98
+ geovisio/web/items.py,sha256=akFfuL7H2F2IpCCtkwzOcBib6a4Az-Go9a8LMV58pBE,68556
99
+ geovisio/web/map.py,sha256=HDtsfOfTfBpgIkG7mzaSlUH7HtEcFl7RqM7gqY2SqAY,27816
100
+ geovisio/web/pages.py,sha256=A7IO3nxUN6UNp_VjEu3Lzpn3OBiEpcTLYOPUGvf6jPA,7814
101
+ geovisio/web/params.py,sha256=tGLZ68oOeoSSI0CbEEf11hm9Bu55X0MVBLialGf7YLI,23483
102
+ geovisio/web/pictures.py,sha256=LCzB1rfIIReabozZ7bZYkVdFS2CLl360ke6uuHfIA1I,7588
103
+ geovisio/web/prepare.py,sha256=AXOAYt9hTiDj2RjrMxBlP1NO9JDKM9iPHcFtbpVB3bc,5702
104
+ geovisio/web/queryables.py,sha256=4BuRFKXlVUm-f42BJR3UymhrknY96DTJ5C4d8Py7VfQ,2308
93
105
  geovisio/web/reports.py,sha256=8v9a4PMM9RsvSGadZEN2o5PTKG_TohjyMMEBfFeY13E,14123
94
106
  geovisio/web/rss.py,sha256=NLUd2Or92tcKRaGUHAze6QMLWczHyzag9ybOzrA8djE,2962
95
- geovisio/web/stac.py,sha256=PQqbUHBDi0xqVmYjH1oC16qtuaZbU8P0SufM0gdiG9w,14853
107
+ geovisio/web/stac.py,sha256=W0U46lcmErLuWwLnpKJP3oV8sa26Prv5-l2zSBVSEew,15246
96
108
  geovisio/web/tokens.py,sha256=natYQT1kdmlT2h0t3R1y0B6W4qhGfFmQR3UER9_KvkQ,11215
97
- geovisio/web/upload_set.py,sha256=64Hr5Kv3Ixp57CMZavOCf1XL11kO7KiQ6L89j2cXSMM,41231
98
- geovisio/web/users.py,sha256=DNbg7fKqoP__TKTD-xSIb250rYEBftyi17kclGlBXeg,14056
99
- geovisio/web/utils.py,sha256=43zf8qAnRn6L_tEvf4h14mLQXKQHmuAW4EN3yYGKP7o,3638
109
+ geovisio/web/upload_set.py,sha256=u54b6rtBfPBDGLLPXXt-hPTCF9M-Zqsh8a-EuMoAyJs,44858
110
+ geovisio/web/users.py,sha256=2ImLwXPcJCt3zeGhiolCYkR1jACiEMVxVR3f9f6ua5g,17287
111
+ geovisio/web/utils.py,sha256=XjTE1QJ8l7M8NKdlyd5ndza3gbRDtVqr_1T1wcJGVNw,4176
100
112
  geovisio/workers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
101
113
  geovisio/workers/runner_pictures.py,sha256=0EMTR1N_3VhpLA66nrQcRkKONl7Ojf8SyT8BXlF5pOw,30359
102
- geovisio-2.10.0.dist-info/licenses/LICENSE,sha256=iRFSz7MJ7_j4hh3hvIgzNbS2buy5NMva8lulaixd3IE,1069
103
- geovisio-2.10.0.dist-info/WHEEL,sha256=G2gURzTEtmeR8nrdXUJfNiB3VYVxigPQ-bEQujpNiNs,82
104
- geovisio-2.10.0.dist-info/METADATA,sha256=yUEAR-PkyLi9ZhTnZJmzJ5bR5cdTiqo_Bq9U7TARFUs,4355
105
- geovisio-2.10.0.dist-info/RECORD,,
114
+ geovisio-2.11.0.dist-info/licenses/LICENSE,sha256=iRFSz7MJ7_j4hh3hvIgzNbS2buy5NMva8lulaixd3IE,1069
115
+ geovisio-2.11.0.dist-info/WHEEL,sha256=G2gURzTEtmeR8nrdXUJfNiB3VYVxigPQ-bEQujpNiNs,82
116
+ geovisio-2.11.0.dist-info/METADATA,sha256=fNQrycQyvf8SGr0RvRroapsNKxDsOQj36NJMubq-46Y,4389
117
+ geovisio-2.11.0.dist-info/RECORD,,