geovisio 2.7.1__py3-none-any.whl → 2.8.1__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 (66) hide show
  1. geovisio/__init__.py +25 -4
  2. geovisio/admin_cli/__init__.py +3 -1
  3. geovisio/admin_cli/user.py +75 -0
  4. geovisio/config_app.py +86 -4
  5. geovisio/templates/main.html +2 -2
  6. geovisio/templates/viewer.html +3 -3
  7. geovisio/translations/br/LC_MESSAGES/messages.mo +0 -0
  8. geovisio/translations/br/LC_MESSAGES/messages.po +762 -0
  9. geovisio/translations/da/LC_MESSAGES/messages.mo +0 -0
  10. geovisio/translations/da/LC_MESSAGES/messages.po +859 -0
  11. geovisio/translations/de/LC_MESSAGES/messages.mo +0 -0
  12. geovisio/translations/de/LC_MESSAGES/messages.po +106 -1
  13. geovisio/translations/el/LC_MESSAGES/messages.mo +0 -0
  14. geovisio/translations/en/LC_MESSAGES/messages.mo +0 -0
  15. geovisio/translations/en/LC_MESSAGES/messages.po +218 -133
  16. geovisio/translations/eo/LC_MESSAGES/messages.mo +0 -0
  17. geovisio/translations/eo/LC_MESSAGES/messages.po +856 -0
  18. geovisio/translations/es/LC_MESSAGES/messages.mo +0 -0
  19. geovisio/translations/es/LC_MESSAGES/messages.po +4 -3
  20. geovisio/translations/fi/LC_MESSAGES/messages.mo +0 -0
  21. geovisio/translations/fr/LC_MESSAGES/messages.mo +0 -0
  22. geovisio/translations/fr/LC_MESSAGES/messages.po +66 -3
  23. geovisio/translations/hu/LC_MESSAGES/messages.mo +0 -0
  24. geovisio/translations/hu/LC_MESSAGES/messages.po +4 -3
  25. geovisio/translations/it/LC_MESSAGES/messages.mo +0 -0
  26. geovisio/translations/it/LC_MESSAGES/messages.po +884 -0
  27. geovisio/translations/ja/LC_MESSAGES/messages.mo +0 -0
  28. geovisio/translations/ja/LC_MESSAGES/messages.po +807 -0
  29. geovisio/translations/ko/LC_MESSAGES/messages.mo +0 -0
  30. geovisio/translations/messages.pot +191 -122
  31. geovisio/translations/nl/LC_MESSAGES/messages.mo +0 -0
  32. geovisio/translations/pl/LC_MESSAGES/messages.mo +0 -0
  33. geovisio/translations/pl/LC_MESSAGES/messages.po +728 -0
  34. geovisio/translations/zh_Hant/LC_MESSAGES/messages.mo +0 -0
  35. geovisio/translations/zh_Hant/LC_MESSAGES/messages.po +719 -0
  36. geovisio/utils/auth.py +80 -8
  37. geovisio/utils/link.py +3 -2
  38. geovisio/utils/loggers.py +14 -0
  39. geovisio/utils/model_query.py +55 -0
  40. geovisio/utils/params.py +7 -4
  41. geovisio/utils/pictures.py +12 -43
  42. geovisio/utils/semantics.py +120 -0
  43. geovisio/utils/sequences.py +10 -1
  44. geovisio/utils/tokens.py +5 -3
  45. geovisio/utils/upload_set.py +71 -22
  46. geovisio/utils/website.py +53 -0
  47. geovisio/web/annotations.py +17 -0
  48. geovisio/web/auth.py +11 -6
  49. geovisio/web/collections.py +217 -61
  50. geovisio/web/configuration.py +17 -1
  51. geovisio/web/docs.py +67 -67
  52. geovisio/web/items.py +220 -96
  53. geovisio/web/map.py +48 -18
  54. geovisio/web/pages.py +240 -0
  55. geovisio/web/params.py +17 -0
  56. geovisio/web/prepare.py +165 -0
  57. geovisio/web/stac.py +17 -4
  58. geovisio/web/tokens.py +14 -4
  59. geovisio/web/upload_set.py +108 -14
  60. geovisio/web/users.py +203 -44
  61. geovisio/workers/runner_pictures.py +61 -22
  62. {geovisio-2.7.1.dist-info → geovisio-2.8.1.dist-info}/METADATA +8 -6
  63. geovisio-2.8.1.dist-info/RECORD +92 -0
  64. {geovisio-2.7.1.dist-info → geovisio-2.8.1.dist-info}/WHEEL +1 -1
  65. geovisio-2.7.1.dist-info/RECORD +0 -70
  66. {geovisio-2.7.1.dist-info → geovisio-2.8.1.dist-info/licenses}/LICENSE +0 -0
@@ -6,13 +6,14 @@ from geovisio.utils import db, sequences, upload_set
6
6
  import psycopg
7
7
  from psycopg.rows import dict_row
8
8
  from psycopg.sql import SQL
9
+ from psycopg.types.json import Jsonb
9
10
  import sentry_sdk
10
11
  from geovisio import errors
11
12
  from dataclasses import dataclass
12
13
  import logging
13
14
  from contextlib import contextmanager
14
15
  from enum import Enum
15
- from typing import Any, Optional
16
+ from typing import Any, Dict, Optional
16
17
  import threading
17
18
  from uuid import UUID
18
19
  from croniter import croniter
@@ -21,7 +22,7 @@ import geovisio.utils.filesystems
21
22
 
22
23
  log = logging.getLogger("geovisio.runner_pictures")
23
24
 
24
- PICTURE_PROCESS_MAX_RETRY = 10 # Number of times a job will be retryed if there is a `RecoverableProcessException` during process (like if the blurring api is not reachable).
25
+ PROCESS_MAX_RETRY = 5 # Number of times a job will be retryed if there is a `RecoverableProcessException` during process (like if the blurring api is not reachable).
25
26
 
26
27
 
27
28
  class PictureBackgroundProcessor(object):
@@ -50,9 +51,6 @@ class PictureBackgroundProcessor(object):
50
51
  return self.executor.submit(worker.process_jobs)
51
52
 
52
53
 
53
- # background_processor = PictureBackgroundProcessor()
54
-
55
-
56
54
  class ProcessTask(str, Enum):
57
55
  prepare = "prepare"
58
56
  delete = "delete"
@@ -64,6 +62,7 @@ class ProcessTask(str, Enum):
64
62
  class DbPicture:
65
63
  id: UUID
66
64
  metadata: dict
65
+ skip_blurring: bool
67
66
 
68
67
  def blurred_by_author(self):
69
68
  return self.metadata.get("blurredByAuthor", False)
@@ -118,7 +117,7 @@ def processPictureFiles(pic: DbPicture, config):
118
117
  config : dict
119
118
  Flask app.config (passed as param to allow using ThreadPoolExecutor)
120
119
  """
121
- skipBlur = pic.blurred_by_author() or config.get("API_BLUR_URL") is None
120
+ skipBlur = pic.skip_blurring or config.get("API_BLUR_URL") is None
122
121
  fses = config["FILESYSTEMS"]
123
122
  fs = fses.permanent if skipBlur else fses.tmp
124
123
  picHdPath = utils.pictures.getHDPicturePath(pic.id)
@@ -132,8 +131,6 @@ def processPictureFiles(pic: DbPicture, config):
132
131
  raise Exception(f"Impossible to find picture file: {picHdPath}")
133
132
 
134
133
  with fs.openbin(picHdPath) as pictureBytes:
135
- picture = Image.open(pictureBytes)
136
-
137
134
  # Create picture folders for this specific picture
138
135
  picDerivatesFolder = utils.pictures.getPictureFolderPath(pic.id)
139
136
  fses.derivates.makedirs(picDerivatesFolder, recreate=True)
@@ -143,9 +140,14 @@ def processPictureFiles(pic: DbPicture, config):
143
140
  if not skipBlur:
144
141
  with sentry_sdk.start_span(description="Blurring picture"):
145
142
  try:
146
- picture = utils.pictures.createBlurredHDPicture(fses.permanent, config.get("API_BLUR_URL"), pictureBytes, picHdPath)
143
+ picture = utils.pictures.createBlurredHDPicture(
144
+ fses.permanent,
145
+ config.get("API_BLUR_URL"),
146
+ pictureBytes,
147
+ picHdPath,
148
+ )
147
149
  except Exception as e:
148
- logging.exception(e)
150
+ log.exception(f"impossible to blur picture {pic.id}")
149
151
  raise RecoverableProcessException("Blur API failure: " + errors.getMessageFromException(e)) from e
150
152
 
151
153
  # Delete original unblurred file
@@ -166,15 +168,26 @@ def processPictureFiles(pic: DbPicture, config):
166
168
  else:
167
169
  # Make sure image rotation is always applied
168
170
  # -> Not necessary on pictures from blur API, as SGBlur ensures rotation is always applied
171
+ picture = Image.open(pictureBytes)
169
172
  picture = ImageOps.exif_transpose(picture)
170
173
 
171
174
  # Always pre-generate thumbnail
172
- utils.pictures.createThumbPicture(fses.derivates, picture, picDerivatesFolder + "/thumb.jpg", pic.metadata["type"])
175
+ utils.pictures.createThumbPicture(
176
+ fses.derivates,
177
+ picture,
178
+ picDerivatesFolder + "/thumb.jpg",
179
+ pic.metadata["type"],
180
+ )
173
181
 
174
182
  # Create SD and tiles
175
183
  if config.get("PICTURE_PROCESS_DERIVATES_STRATEGY") == "PREPROCESS":
176
184
  utils.pictures.generatePictureDerivates(
177
- fses.derivates, picture, pic.metadata, picDerivatesFolder, pic.metadata["type"], skipThumbnail=True
185
+ fses.derivates,
186
+ picture,
187
+ pic.metadata,
188
+ picDerivatesFolder,
189
+ pic.metadata["type"],
190
+ skipThumbnail=True,
178
191
  )
179
192
 
180
193
 
@@ -300,7 +313,11 @@ def process_next_job(app):
300
313
  _delete_picture(job.pic)
301
314
  elif job.task == ProcessTask.dispatch and job.upload_set:
302
315
  with utils.time.log_elapsed(f"Dispatching upload set {job.upload_set.id}"):
303
- upload_set.dispatch(job.upload_set.id)
316
+ try:
317
+ upload_set.dispatch(job.upload_set.id)
318
+ except Exception as e:
319
+ log.exception(f"impossible to dispatch upload set {job.upload_set.id}")
320
+ raise RecoverableProcessException("Upload set dispatch error: " + errors.getMessageFromException(e)) from e
304
321
  elif job.task == ProcessTask.finalize and job.seq:
305
322
  with utils.time.log_elapsed(f"Finalizing sequence {job.seq.id}"):
306
323
  with job.reporting_conn.cursor(row_factory=dict_row) as cursor:
@@ -323,7 +340,7 @@ def _get_next_job(app):
323
340
  with app.pool.connection() as locking_transaction:
324
341
  with locking_transaction.transaction(), locking_transaction.cursor(row_factory=dict_row) as cursor:
325
342
  r = cursor.execute(
326
- """SELECT j.id, j.picture_id, j.upload_set_id, j.sequence_id, j.task, j.picture_to_delete_id, p.metadata
343
+ """SELECT j.id, j.picture_id, j.upload_set_id, j.sequence_id, j.task, j.picture_to_delete_id, p.metadata, j.args
327
344
  FROM job_queue j
328
345
  LEFT JOIN pictures p ON p.id = j.picture_id
329
346
  ORDER by
@@ -341,7 +358,11 @@ def _get_next_job(app):
341
358
  # picture id can either be in `picture_id` (and it will be a foreign key to picture) or in `picture_to_delete_id`
342
359
  # (and it will not a foreign key since the picture's row will already have been deleted from the db)
343
360
  pic_id = r["picture_id"] or r["picture_to_delete_id"]
344
- db_pic = DbPicture(id=pic_id, metadata=r["metadata"]) if pic_id is not None else None
361
+ db_pic = (
362
+ DbPicture(id=pic_id, metadata=r["metadata"], skip_blurring=(r["args"] or {}).get("skip_blurring", False))
363
+ if pic_id is not None
364
+ else None
365
+ )
345
366
  db_seq = DbSequence(id=r["sequence_id"]) if r["sequence_id"] is not None else None
346
367
  db_upload_set = DbUploadSet(id=r["upload_set_id"]) if r["upload_set_id"] is not None else None
347
368
 
@@ -353,6 +374,7 @@ def _get_next_job(app):
353
374
  db_seq=db_seq,
354
375
  db_upload_set=db_upload_set,
355
376
  task=ProcessTask(r["task"]),
377
+ args=r["args"],
356
378
  )
357
379
  try:
358
380
  yield job
@@ -363,7 +385,13 @@ def _get_next_job(app):
363
385
  except RecoverableProcessException as e:
364
386
  _mark_process_as_error(locking_transaction, job, e, recoverable=True)
365
387
  except RetryLaterProcessException as e:
366
- _mark_process_as_error(locking_transaction, job, e, recoverable=True, mark_as_error=False)
388
+ _mark_process_as_error(
389
+ locking_transaction,
390
+ job,
391
+ e,
392
+ recoverable=True,
393
+ mark_as_error=False,
394
+ )
367
395
  except InterruptedError as interruption:
368
396
  log.error(f"Interruption received, stoping job {job.label()}")
369
397
  # starts a new connection, since the current one can be corrupted by the exception
@@ -410,7 +438,10 @@ def _finalize_job(conn, job: DbJob):
410
438
  try:
411
439
  # we try to see if our job_history row is still here.
412
440
  # It can have been removed if the object this job was preparing has been deleted during the process (since the job_history table store foreign keys)
413
- job.reporting_conn.execute("SELECT id FROM job_history WHERE id = %(id)s FOR UPDATE NOWAIT", {"id": job.job_history_id})
441
+ job.reporting_conn.execute(
442
+ "SELECT id FROM job_history WHERE id = %(id)s FOR UPDATE NOWAIT",
443
+ {"id": job.job_history_id},
444
+ )
414
445
  except psycopg.errors.LockNotAvailable:
415
446
  logging.info(
416
447
  f"The job {job.job_history_id} ({job.label()}) has likely been deleted during the process (it can happen if the picture/upload_set/sequence has been deleted by another process), we don't need to finalize it"
@@ -423,7 +454,7 @@ def _finalize_job(conn, job: DbJob):
423
454
  if job.task == ProcessTask.prepare and job.pic:
424
455
  # Note: the status is slowly been deprecated by replacing it with more precise status, and in the end it will be removed
425
456
  job.reporting_conn.execute(
426
- "UPDATE pictures SET status = 'ready', preparing_status = 'prepared' WHERE id = %(pic_id)s",
457
+ "UPDATE pictures SET status = (CASE WHEN status = 'hidden' THEN 'hidden' ELSE 'ready' END)::picture_status, preparing_status = 'prepared' WHERE id = %(pic_id)s",
427
458
  {"pic_id": job.pic.id},
428
459
  )
429
460
 
@@ -440,10 +471,11 @@ def _initialize_job(
440
471
  db_seq: Optional[DbSequence],
441
472
  db_upload_set: Optional[DbUploadSet],
442
473
  task: ProcessTask,
474
+ args: Optional[Dict[Any, Any]],
443
475
  ) -> DbJob:
444
476
  r = reporting_conn.execute(
445
- """INSERT INTO job_history(job_id, picture_id, sequence_id, upload_set_id, picture_to_delete_id, job_task)
446
- VALUES (%(job_id)s, %(pic_id)s, %(seq_id)s, %(us_id)s, %(pic_to_delete)s, %(task)s)
477
+ """INSERT INTO job_history(job_id, picture_id, sequence_id, upload_set_id, picture_to_delete_id, job_task, args)
478
+ VALUES (%(job_id)s, %(pic_id)s, %(seq_id)s, %(us_id)s, %(pic_to_delete)s, %(task)s, %(args)s)
447
479
  RETURNING id""",
448
480
  {
449
481
  "job_id": job_queue_id,
@@ -452,6 +484,7 @@ def _initialize_job(
452
484
  "pic_to_delete": db_pic.id if db_pic and task == ProcessTask.delete else None,
453
485
  "us_id": db_upload_set.id if db_upload_set else None,
454
486
  "task": task.value,
487
+ "args": Jsonb(args),
455
488
  },
456
489
  ).fetchone()
457
490
 
@@ -469,7 +502,13 @@ def _initialize_job(
469
502
  )
470
503
 
471
504
 
472
- def _mark_process_as_error(conn, job: DbJob, e: Exception, recoverable: bool = False, mark_as_error: bool = True):
505
+ def _mark_process_as_error(
506
+ conn,
507
+ job: DbJob,
508
+ e: Exception,
509
+ recoverable: bool = False,
510
+ mark_as_error: bool = True,
511
+ ):
473
512
  job.reporting_conn.execute(
474
513
  """UPDATE job_history SET
475
514
  error = %(err)s, finished_at = CURRENT_TIMESTAMP
@@ -485,7 +524,7 @@ def _mark_process_as_error(conn, job: DbJob, e: Exception, recoverable: bool = F
485
524
  RETURNING nb_errors""",
486
525
  {"err": str(e), "id": job.job_queue_id},
487
526
  ).fetchone()
488
- if nb_error and nb_error[0] > PICTURE_PROCESS_MAX_RETRY:
527
+ if nb_error and nb_error[0] > PROCESS_MAX_RETRY:
489
528
  logging.info(f"Job {job.label()} has failed {nb_error} times, we stop trying to process it.")
490
529
  recoverable = False
491
530
  else:
@@ -1,18 +1,19 @@
1
- Metadata-Version: 2.3
1
+ Metadata-Version: 2.4
2
2
  Name: geovisio
3
- Version: 2.7.1
3
+ Version: 2.8.1
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
7
7
  Description-Content-Type: text/markdown
8
8
  Classifier: License :: OSI Approved :: MIT License
9
+ License-File: LICENSE
9
10
  Requires-Dist: Flask ~= 2.3
10
11
  Requires-Dist: psycopg[pool] ~= 3.1
11
12
  Requires-Dist: flasgger ~= 0.9.7
12
13
  Requires-Dist: Pillow ~= 9.4
13
14
  Requires-Dist: Flask-Cors ~= 4.0
14
15
  Requires-Dist: fs ~= 2.4
15
- Requires-Dist: fs-s3fs-forked ~= 1.1.3
16
+ Requires-Dist: fs-s3fs-forked ~= 1.1.4
16
17
  Requires-Dist: flask-compress ~= 1.14
17
18
  Requires-Dist: requests ~= 2.31
18
19
  Requires-Dist: yoyo-migrations ~= 8.2
@@ -20,17 +21,18 @@ Requires-Dist: psycopg-binary ~= 3.1
20
21
  Requires-Dist: python-dotenv ~= 0.21
21
22
  Requires-Dist: authlib ~= 1.2
22
23
  Requires-Dist: Flask-Executor ~= 1.0
23
- Requires-Dist: geopic-tag-reader[write-exif] == 1.3.1
24
+ Requires-Dist: geopic-tag-reader[write-exif] == 1.4.2
24
25
  Requires-Dist: rfeed ~= 1.1.1
25
26
  Requires-Dist: sentry-sdk[flask] ~= 1.31
26
27
  Requires-Dist: pygeofilter[backend-native] ~= 0.2.4
27
- Requires-Dist: python-dateutil ~= 2.8.2
28
+ Requires-Dist: python-dateutil ~= 2.9.0
28
29
  Requires-Dist: tzdata ~= 2024.1
29
30
  Requires-Dist: croniter ~= 2.0.5
30
31
  Requires-Dist: pydantic ~= 2.7
31
32
  Requires-Dist: pydantic-extra-types ~= 2.7
32
33
  Requires-Dist: flask-babel ~= 4.0.0
33
34
  Requires-Dist: geojson-pydantic ~= 1.1.0
35
+ Requires-Dist: email-validator ~= 2.2.0
34
36
  Requires-Dist: flit ~= 3.9.0 ; extra == "build"
35
37
  Requires-Dist: coverage ~= 6.5 ; extra == "dev"
36
38
  Requires-Dist: protobuf ~= 4.21 ; extra == "dev"
@@ -45,7 +47,7 @@ Requires-Dist: black ~= 24.1 ; extra == "dev"
45
47
  Requires-Dist: pre-commit ~= 3.3 ; extra == "dev"
46
48
  Requires-Dist: pyyaml ~= 6.0 ; extra == "dev"
47
49
  Requires-Dist: openapi-spec-validator ~= 0.7 ; extra == "dev"
48
- Requires-Dist: stac-api-validator ~= 0.6.3 ; extra == "dev"
50
+ Requires-Dist: stac-api-validator ~= 0.6.4 ; extra == "dev"
49
51
  Requires-Dist: mkdocs-material ~= 9.5.21 ; extra == "docs"
50
52
  Requires-Dist: mkdocs-swagger-ui-tag ~= 0.6.10 ; extra == "docs"
51
53
  Project-URL: Home, https://gitlab.com/panoramax/server/api
@@ -0,0 +1,92 @@
1
+ geovisio/__init__.py,sha256=h7zC88f4S9UjmjGNmSux7v1JqN2Vo05f_8Pv97Zq8Hg,7754
2
+ geovisio/config_app.py,sha256=u44GidJcV4HzCESONi0PsnbfGZqzQ3sxdRXKhpji22o,14198
3
+ geovisio/db_migrations.py,sha256=9lHkyG_RiCWzrFkfwhkslScUsbCZScN-KVhkXrtnPDo,4560
4
+ geovisio/errors.py,sha256=uTn-kI7SUl5OPB8Mv3Qqu7Ucp5JvcqWPQFfgLCqsEpI,1376
5
+ geovisio/admin_cli/__init__.py,sha256=1e0hX771-3iG8eBcNmVvUYyg8qXnpng-9YWvi3MI3Kg,3248
6
+ geovisio/admin_cli/cleanup.py,sha256=G85I7rrfPJwaArL6MQAnC04Ye9wWciA-Yqu5iv23uJ0,4862
7
+ geovisio/admin_cli/db.py,sha256=mJ-cGuOAAsg-ovbP9L1kyL4xE0C4bYRuozzqQkaFyw8,897
8
+ geovisio/admin_cli/default_account_tokens.py,sha256=W-v5uPjCBvAujjAUx1HrfgjPj-tEyncb-EUMLpsWc9w,469
9
+ geovisio/admin_cli/reorder_sequences.py,sha256=LKKzdO2w4N-cQmi6rqKHKYG5YGzPxYRTbnfcPKakuYM,2826
10
+ geovisio/admin_cli/sequence_heading.py,sha256=BEPuRfCDXXpqSSzK2ysrxHf0OD4THzrMI_YK2uXQlGk,633
11
+ geovisio/admin_cli/user.py,sha256=4ml2E_aphz3I3NcuUPB2dwe_jXhcE7AGa0R5VTm3_ik,2753
12
+ geovisio/templates/main.html,sha256=VDVQwCZ1mNjH7sH4VOIdn8gM09R9LJZX49SPtA2VEzM,2963
13
+ geovisio/templates/viewer.html,sha256=JErXdU2ujj4LdMHgQbYNCTfKuYGEXbJTQwBE-K_MNXQ,892
14
+ geovisio/translations/messages.pot,sha256=SUPAgov3RzwVw0LNOMn2NkTthXfirbBDIQK_2BaZ2FI,19445
15
+ geovisio/translations/br/LC_MESSAGES/messages.mo,sha256=FjvUouzaLCBxvVH51A4PVwGGFk6mAepYasnI4v8LcnQ,719
16
+ geovisio/translations/br/LC_MESSAGES/messages.po,sha256=rHkbb3QTngCJxz0WmoBqMl4H-x2bXKYKxdZCEZv2P9w,19434
17
+ geovisio/translations/da/LC_MESSAGES/messages.mo,sha256=46hqJP4gsM3ZK2DG3L47GeC9Q-xFWrY36_OkAJCkuIg,21262
18
+ geovisio/translations/da/LC_MESSAGES/messages.po,sha256=MRmMNc6oQL9R8rvDewHCUhZMSH2TbsfskspCFQzKk2s,29393
19
+ geovisio/translations/de/LC_MESSAGES/messages.mo,sha256=hWb_yaHUHan3tFTyTbnDKJgfnD4wuaeO2nhc24V2ARM,22831
20
+ geovisio/translations/de/LC_MESSAGES/messages.po,sha256=nmlWG_BmcvksfDW9H8d3bTTgIgd-8ucF9lcLg3WB6us,31078
21
+ geovisio/translations/el/LC_MESSAGES/messages.mo,sha256=vy1jtEG6mLS5sYWPfQIr5U4XsZ21ZzSbsHAJHGQXZSY,433
22
+ geovisio/translations/el/LC_MESSAGES/messages.po,sha256=gDr-pDCsQGrCXBMBcDwlfsxcGWF1NIEqGrqPcZy65-4,17405
23
+ geovisio/translations/en/LC_MESSAGES/messages.mo,sha256=KzPxb2olWNvZrUZE9hY0ComHM6t1B2kV5bWvQQ9GUMo,20018
24
+ geovisio/translations/en/LC_MESSAGES/messages.po,sha256=RRfEZ2nZFNWhrbZOPzigy63TVK8cbp8vRikXIj0ibT4,28041
25
+ geovisio/translations/eo/LC_MESSAGES/messages.mo,sha256=67UES-hJwqciW0AiJ2fwcN0K34dBkYNRG2SqVQn3va8,21029
26
+ geovisio/translations/eo/LC_MESSAGES/messages.po,sha256=rzlHUGUoaRkYZY431Y3d7GaAbEcvo9NUL1wSn9Gzapw,29177
27
+ geovisio/translations/es/LC_MESSAGES/messages.mo,sha256=R5JmcfauTrQxIynQNT7asjdLEJC9-VEMXYrcugfBbsY,18950
28
+ geovisio/translations/es/LC_MESSAGES/messages.po,sha256=XzVBY4dISzRcZWw7jMmbGsnDrJvyhzX2L_o9k5B14Hw,26780
29
+ geovisio/translations/fi/LC_MESSAGES/messages.mo,sha256=6-WCesFiV00MkNM_Wpi7-D51DOZRNg_QOM2sL7-UPhA,626
30
+ geovisio/translations/fi/LC_MESSAGES/messages.po,sha256=UFT4YCfEazxLij8Ovk2vZqx55e2Yctbf_3xM5KDrXhw,14685
31
+ geovisio/translations/fr/LC_MESSAGES/messages.mo,sha256=tvecIWSq7ocm_Q_dd3F1dqZz0GvAWeR685cC7pnQi4g,22297
32
+ geovisio/translations/fr/LC_MESSAGES/messages.po,sha256=unb6P5I9cAMQt5oUr0HhEPmVR3jb7LMnr_e0gAjWwBU,30292
33
+ geovisio/translations/hu/LC_MESSAGES/messages.mo,sha256=0Hb7mv7p1BVM8QqZIYUtF3LRym8Sl9HFWfZAa00TobU,20013
34
+ geovisio/translations/hu/LC_MESSAGES/messages.po,sha256=0nLbjStLDrj7U9mqdIf5gnQ_XzSnhnGQeJ1wLK8l8GM,27494
35
+ geovisio/translations/it/LC_MESSAGES/messages.mo,sha256=a9vR4JuHQY0kwET-OUAD51FgUcCGf68_Cg-P-UOpxRc,22533
36
+ geovisio/translations/it/LC_MESSAGES/messages.po,sha256=kKMX_OabFjzMfYwKA4Gu_n1kND1OKokYwAGs9SSXcj0,30669
37
+ geovisio/translations/ja/LC_MESSAGES/messages.mo,sha256=ZPHJrNdf4bgiNFjxP8W41fkZ2OTJ7Swrqt-Hkh5LfO8,24194
38
+ geovisio/translations/ja/LC_MESSAGES/messages.po,sha256=hE6WOQPaLPjury-bFO3xUJin7bWlcwv0ewSsCpScDdY,32627
39
+ geovisio/translations/ko/LC_MESSAGES/messages.mo,sha256=eKuQS9zLcJ9s-DzbfR-QK2INBJL10jTIQ1kuSTdJ9Rg,426
40
+ geovisio/translations/ko/LC_MESSAGES/messages.po,sha256=uq19EZaeRB-obmE1hYnckA8T12JuuU3nXYyKaMR4tiU,17405
41
+ geovisio/translations/nl/LC_MESSAGES/messages.mo,sha256=aKM90Hp4Eh9vCQba_tlfjEWlhygLXWGq_SVYqBw9IA4,1592
42
+ geovisio/translations/nl/LC_MESSAGES/messages.po,sha256=m69xfphxpgfPOuUrBK51XrR8UFwqCEBZpnb_5B1mGOU,15302
43
+ geovisio/translations/pl/LC_MESSAGES/messages.mo,sha256=0iFTAhma7jjyl13DCLr2Xr0hgDSN-_fOqcKoYcdDwGE,9912
44
+ geovisio/translations/pl/LC_MESSAGES/messages.po,sha256=e8HW1RKsdkR-aL7peBMuqRUQoqKvzr6Eq0sC1in5XY0,22187
45
+ geovisio/translations/zh_Hant/LC_MESSAGES/messages.mo,sha256=TmRUyfTGoBpU-2BE-nKjhwdr9r0ikDioVQU-JQ_ih90,431
46
+ geovisio/translations/zh_Hant/LC_MESSAGES/messages.po,sha256=LnnKlHy8t_54nNsLDBqC1eEPwPx49h1Um9mQj6l9hv0,18357
47
+ geovisio/utils/__init__.py,sha256=g4SWVoV73cSXjf5-5D9-HmyB5xKmHSuxxOGWnx7W3V0,71
48
+ geovisio/utils/auth.py,sha256=_vvkBTvjRXYlnyaHziNWJjiGKulomMqex-CDbv1dbKQ,13845
49
+ geovisio/utils/db.py,sha256=DFyCEB5-xTUo6sn79SYJCzuvlgFNDVyNJ48Mana5vPI,2625
50
+ geovisio/utils/excluded_areas.py,sha256=6f3wwsgNpJKxAXnHH8RKlktgHpsG-0QVNTWDDTFqPZ8,2585
51
+ geovisio/utils/extent.py,sha256=vzOHvbG6lpSNt7KrsaonBOx7Tz46S1J603gLbZvs36g,557
52
+ geovisio/utils/fields.py,sha256=sNAmrSJ4e-nqm0-LoyO3l4Zynb-Jy8swhwmL3UcDN_o,2129
53
+ geovisio/utils/filesystems.py,sha256=W_wH7TlvdEux_q4FP0XInxruxlbepFSEpJbPLO9Cnr4,4133
54
+ geovisio/utils/link.py,sha256=u9x4xJa57L1448neD7uPJuAA76_sFXVE0-9_zPW-bJM,490
55
+ geovisio/utils/loggers.py,sha256=_OrGXME4o5qQz8VBaLxYopHVK0DY0QgzXu6O2W0WBjo,477
56
+ geovisio/utils/model_query.py,sha256=PtvYCjKVygmicvqqYpCpEKWUIEvwdEG6QMh-JL5E8AQ,2031
57
+ geovisio/utils/params.py,sha256=Yj9-PwC8jxb9LjQZ5K8TERimSsWKwJBHPhUxlzDVMhg,714
58
+ geovisio/utils/pictures.py,sha256=cDDOABzZaTn98Bg8lYgoMlkTNklS9-y-qB-HXTcJ0YM,23092
59
+ geovisio/utils/reports.py,sha256=PgU0Td48WJg6XCq043he8Jif3WCA9nOTaGE0Yovo3h0,5626
60
+ geovisio/utils/semantics.py,sha256=bsPo4n0R0_pU5NdL7-dkx-bMYPhtyVq85z4nHNLptto,4572
61
+ geovisio/utils/sentry.py,sha256=Dw0rW2sNFbcpGojzpa-vjtJ5S7BH_XhsqfuGYBjHCG0,3759
62
+ geovisio/utils/sequences.py,sha256=S3OaMozzk9viYJMgHyzGYP1hZFsYjF8Ez2hXFTIBimI,25307
63
+ geovisio/utils/time.py,sha256=-hOs7FSx-8eiGmMQtTOrCoF8d_yMlj2306vfxJftEr8,642
64
+ geovisio/utils/tokens.py,sha256=tkihnnXqgQeIME_d12tC8PVrPN90A0i9k6UPEbgZ9TQ,3047
65
+ geovisio/utils/upload_set.py,sha256=OVChyYFVd6maXcoMoiT-tA1n6tPIezTEJiRdipw_hIw,27247
66
+ geovisio/utils/website.py,sha256=812_leydUaI_gPZAnkVizGH1ZJqJkoAE1usFCrRNHCI,1959
67
+ geovisio/web/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
68
+ geovisio/web/annotations.py,sha256=TdivDOcVh83HRkBXBTxFD7J-VbZ1gnVesPfTNY-3uW4,653
69
+ geovisio/web/auth.py,sha256=d0g3EweC74_OOvD9fxb71M-VuQLD_BdlOcKtpwH4t5o,7143
70
+ geovisio/web/collections.py,sha256=pt181nK3bTa1UYn9qpi3RBGH5h5I8VKMOb_Kfa-c-EU,46470
71
+ geovisio/web/configuration.py,sha256=tWZYxOoqI2MQwmuHk1I9J2DKzDqpLBVmWRDSsx18U7E,2177
72
+ geovisio/web/docs.py,sha256=UgiX_uXAdzjk08Q5Slp40-ayfhhfaHMZn88SU8IBQAg,55660
73
+ geovisio/web/excluded_areas.py,sha256=5BNSZ0UqgFMtgvgrJ73eYGJXPJRnV-mGEs36WDRRxTk,13024
74
+ geovisio/web/items.py,sha256=1a_O5tes2NL4DHqDWsgJn_PQQYx4Ft6v4t7ibzkgtdw,61357
75
+ geovisio/web/map.py,sha256=DaigXevz4lL7WGjPFCsKbXvjdDevFj9gpH0-22JsJOI,25328
76
+ geovisio/web/pages.py,sha256=Hkc3KJFE6D38vGnkCK5WUBJ8KQemI1f1wGXpxeiOiNo,6632
77
+ geovisio/web/params.py,sha256=Ip2qFR2Z28OTP7Fe1EuineHKUMmlZ_u5dFW77MqdLD0,21071
78
+ geovisio/web/pictures.py,sha256=qbhgLsI6YtpFxXn1a3dzO66nnVrWglRZSXWmlfJr1tU,6394
79
+ geovisio/web/prepare.py,sha256=R10_xf6O9dmAAwOMC-vsaxgNTdc9BkDJLATqH6MKtCw,5620
80
+ geovisio/web/reports.py,sha256=8v9a4PMM9RsvSGadZEN2o5PTKG_TohjyMMEBfFeY13E,14123
81
+ geovisio/web/rss.py,sha256=NLUd2Or92tcKRaGUHAze6QMLWczHyzag9ybOzrA8djE,2962
82
+ geovisio/web/stac.py,sha256=1uoSUOgCxOdH4UQuUvt-0xJaPLtPcAD54WvQg0lvxwM,14850
83
+ geovisio/web/tokens.py,sha256=l7CAM0FQ6qAcoUhtIRysKc9Gndlji_wOMpkXLsPP1pI,9599
84
+ geovisio/web/upload_set.py,sha256=lFryohoh40UaGoHPL-RV7ypWrYlOwYlW6Y5m65dkEyA,34251
85
+ geovisio/web/users.py,sha256=PeB2hcyyLvNDi98iNl8P4wr3X4r3Yz6FVP8Yx_U6Nac,14054
86
+ geovisio/web/utils.py,sha256=kudTbV4Tgtkbd4oUWFTFpyWNINpxAa-VQNbxYEiR6pM,3640
87
+ geovisio/workers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
88
+ geovisio/workers/runner_pictures.py,sha256=Y4x345tp0Y3RAFnoYpcDhyg6dJS1OYx79XGGDIttcps,22898
89
+ geovisio-2.8.1.dist-info/licenses/LICENSE,sha256=iRFSz7MJ7_j4hh3hvIgzNbS2buy5NMva8lulaixd3IE,1069
90
+ geovisio-2.8.1.dist-info/WHEEL,sha256=_2ozNFCLWc93bK4WKHCO-eDUENDlo-dgc9cU3qokYO4,82
91
+ geovisio-2.8.1.dist-info/METADATA,sha256=r3Tlh_xpB_BVY27DjaV8W6UVjz__db7Z55zWHj536zQ,4321
92
+ geovisio-2.8.1.dist-info/RECORD,,
@@ -1,4 +1,4 @@
1
1
  Wheel-Version: 1.0
2
- Generator: flit 3.10.1
2
+ Generator: flit 3.11.0
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
@@ -1,70 +0,0 @@
1
- geovisio/__init__.py,sha256=YQ1w0Jdd8BNH-F9pXAt5nOFm0dVoGJ2k0ajzaN_vS5E,6949
2
- geovisio/config_app.py,sha256=TiG90GE4JXr0Le4a5bRMqTP02TBivb4deWmPLLd94Fc,10349
3
- geovisio/db_migrations.py,sha256=9lHkyG_RiCWzrFkfwhkslScUsbCZScN-KVhkXrtnPDo,4560
4
- geovisio/errors.py,sha256=uTn-kI7SUl5OPB8Mv3Qqu7Ucp5JvcqWPQFfgLCqsEpI,1376
5
- geovisio/admin_cli/__init__.py,sha256=8xlb3WN1DtEVurW9B0VuOFtI33oRV5TvxV6hOkUUpM0,3173
6
- geovisio/admin_cli/cleanup.py,sha256=G85I7rrfPJwaArL6MQAnC04Ye9wWciA-Yqu5iv23uJ0,4862
7
- geovisio/admin_cli/db.py,sha256=mJ-cGuOAAsg-ovbP9L1kyL4xE0C4bYRuozzqQkaFyw8,897
8
- geovisio/admin_cli/default_account_tokens.py,sha256=W-v5uPjCBvAujjAUx1HrfgjPj-tEyncb-EUMLpsWc9w,469
9
- geovisio/admin_cli/reorder_sequences.py,sha256=LKKzdO2w4N-cQmi6rqKHKYG5YGzPxYRTbnfcPKakuYM,2826
10
- geovisio/admin_cli/sequence_heading.py,sha256=BEPuRfCDXXpqSSzK2ysrxHf0OD4THzrMI_YK2uXQlGk,633
11
- geovisio/templates/main.html,sha256=7s4eKMfWKCkpspRqeCx-G_euEq932ac-PLP5uBYGa48,2949
12
- geovisio/templates/viewer.html,sha256=XIHlaKV_a_iOxmjcTdUdToVjt5nB2NkZlMhQLoDfTAg,865
13
- geovisio/translations/messages.pot,sha256=9jePFA0WLcBr5CxIJOpprkfUG4To_L3ZHM_OtW43SUY,17534
14
- geovisio/translations/de/LC_MESSAGES/messages.mo,sha256=oWorVGWoibgKafGKa3xKk2BL0YHE2-gJHhPzDvRdGIw,20026
15
- geovisio/translations/de/LC_MESSAGES/messages.po,sha256=KdBvM1KzhYtFPEfKlwVbjibE6YSQ571vl-SdMgCHqp0,27501
16
- geovisio/translations/el/LC_MESSAGES/messages.mo,sha256=ywsI-kQbsqracOEo-NXgF48oyNxol67_HyHkKFs8l0Y,433
17
- geovisio/translations/el/LC_MESSAGES/messages.po,sha256=gDr-pDCsQGrCXBMBcDwlfsxcGWF1NIEqGrqPcZy65-4,17405
18
- geovisio/translations/en/LC_MESSAGES/messages.mo,sha256=hM0CH68goVaF3NjZLu-qpx7szqW9MxDZjpFZgi6o880,17813
19
- geovisio/translations/en/LC_MESSAGES/messages.po,sha256=EEf4oVUWSErhs5hdxtQkTL-eW3A4mbr2sAnBSa1pATg,25027
20
- geovisio/translations/es/LC_MESSAGES/messages.mo,sha256=R1uvDSt0uKMV0gVr0foc_0iiYBLc1ls2ryBlWHVZ_DQ,19111
21
- geovisio/translations/es/LC_MESSAGES/messages.po,sha256=NoyuXR_2iugWHLTcoUZSNLUSCpt8jMyl0FUD4p7N99w,26775
22
- geovisio/translations/fi/LC_MESSAGES/messages.mo,sha256=Z52s0OukqMwi58FpfLnBd8ED429LPSGG4shba4HPFgY,626
23
- geovisio/translations/fi/LC_MESSAGES/messages.po,sha256=UFT4YCfEazxLij8Ovk2vZqx55e2Yctbf_3xM5KDrXhw,14685
24
- geovisio/translations/fr/LC_MESSAGES/messages.mo,sha256=QhYUtdkZAXYafaIS2WhXCnMG3V6WbucoYaW57cqaqpw,20612
25
- geovisio/translations/fr/LC_MESSAGES/messages.po,sha256=jLg0FOEXbt-Wi8LMjAw-vVDUaoMeZni9H553bJjsu4Y,28019
26
- geovisio/translations/hu/LC_MESSAGES/messages.mo,sha256=GypxSE6y8GS2SKAXZIXwBCa15xXLFiZ9JEXNX7hh1Uw,20156
27
- geovisio/translations/hu/LC_MESSAGES/messages.po,sha256=Cs1EaEfVISyIsKxnK-f0gy0ocJdey5o-620mkvW1SAs,27472
28
- geovisio/translations/ko/LC_MESSAGES/messages.mo,sha256=cqo1DInz1VObD4Cj_2Tqmm5dGoNQfpssRiyv8BaxxF4,426
29
- geovisio/translations/ko/LC_MESSAGES/messages.po,sha256=uq19EZaeRB-obmE1hYnckA8T12JuuU3nXYyKaMR4tiU,17405
30
- geovisio/translations/nl/LC_MESSAGES/messages.mo,sha256=nrfZTHMVY-yqWq6BDfZhbepUhoweGvAsNEshNYoiBRg,1592
31
- geovisio/translations/nl/LC_MESSAGES/messages.po,sha256=m69xfphxpgfPOuUrBK51XrR8UFwqCEBZpnb_5B1mGOU,15302
32
- geovisio/utils/__init__.py,sha256=g4SWVoV73cSXjf5-5D9-HmyB5xKmHSuxxOGWnx7W3V0,71
33
- geovisio/utils/auth.py,sha256=iIssHEDqAWp5D514pmYjoAzr-Jy6VDSDM3STtM8M56o,10810
34
- geovisio/utils/db.py,sha256=DFyCEB5-xTUo6sn79SYJCzuvlgFNDVyNJ48Mana5vPI,2625
35
- geovisio/utils/excluded_areas.py,sha256=6f3wwsgNpJKxAXnHH8RKlktgHpsG-0QVNTWDDTFqPZ8,2585
36
- geovisio/utils/extent.py,sha256=vzOHvbG6lpSNt7KrsaonBOx7Tz46S1J603gLbZvs36g,557
37
- geovisio/utils/fields.py,sha256=sNAmrSJ4e-nqm0-LoyO3l4Zynb-Jy8swhwmL3UcDN_o,2129
38
- geovisio/utils/filesystems.py,sha256=W_wH7TlvdEux_q4FP0XInxruxlbepFSEpJbPLO9Cnr4,4133
39
- geovisio/utils/link.py,sha256=lMWSUcAjQzq-r-U6VEIMR2ViVs5K8PVX7coF6XMFrmk,378
40
- geovisio/utils/params.py,sha256=s9kBPHm4gRhMx10SD7mOPdG0tR_n_O-g_rgL8Fife6s,630
41
- geovisio/utils/pictures.py,sha256=VhtKHczgWhmg-boF4EcDcJR6fXEYWwI1EzD7sOV-8-Y,24106
42
- geovisio/utils/reports.py,sha256=PgU0Td48WJg6XCq043he8Jif3WCA9nOTaGE0Yovo3h0,5626
43
- geovisio/utils/sentry.py,sha256=Dw0rW2sNFbcpGojzpa-vjtJ5S7BH_XhsqfuGYBjHCG0,3759
44
- geovisio/utils/sequences.py,sha256=mp6ezvo8PODgJIcM_leZmJV13Z2ukHYWiFh8PNYOV5o,24927
45
- geovisio/utils/time.py,sha256=-hOs7FSx-8eiGmMQtTOrCoF8d_yMlj2306vfxJftEr8,642
46
- geovisio/utils/tokens.py,sha256=evcboxseJ1jt0LAOkQz-ZEZ--v2P3Lh9JsaldQeHzLg,2890
47
- geovisio/utils/upload_set.py,sha256=a_fxBuHPpk3VQun9jIqg98TgDUnEXYhmcCyuHrP6nvI,24357
48
- geovisio/web/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
49
- geovisio/web/auth.py,sha256=bpMb6ch6LJ8FIIfzYcrAjLS2yvwO4ohrLXfxdSYGLsQ,6882
50
- geovisio/web/collections.py,sha256=8tXzI9Uj4PI5HSN03uSl3iNgKgs6_YCRWlXFEnuAbwM,38810
51
- geovisio/web/configuration.py,sha256=8pHGG6LEID1NqaiAq0qg4kdRG5_uuM_F25afLt62_G0,1706
52
- geovisio/web/docs.py,sha256=hDeJVbV-W_ROJpNOiCcUUxtACfAnPTZifunVH-TI1N4,54685
53
- geovisio/web/excluded_areas.py,sha256=5BNSZ0UqgFMtgvgrJ73eYGJXPJRnV-mGEs36WDRRxTk,13024
54
- geovisio/web/items.py,sha256=M9IO9t35y9gKlKHFifWWe_EhxRWEwfcBQLyVM_A6JeA,54982
55
- geovisio/web/map.py,sha256=0-owIu56n7FKfC6jYCglRoiutBgg4pAqu_R8d5yXcI0,24062
56
- geovisio/web/params.py,sha256=1hO3MQuEXJBk5ZQAk-Mau9gRxwWUITxQkgtSnDEN06E,20542
57
- geovisio/web/pictures.py,sha256=qbhgLsI6YtpFxXn1a3dzO66nnVrWglRZSXWmlfJr1tU,6394
58
- geovisio/web/reports.py,sha256=8v9a4PMM9RsvSGadZEN2o5PTKG_TohjyMMEBfFeY13E,14123
59
- geovisio/web/rss.py,sha256=NLUd2Or92tcKRaGUHAze6QMLWczHyzag9ybOzrA8djE,2962
60
- geovisio/web/stac.py,sha256=V00aTv74faiCQRslsv1_dWZpZTNXAB5YryOA4O_sJh4,14382
61
- geovisio/web/tokens.py,sha256=AeQE_Xkqb988wRNnT5fkPOB7xsrHDqyI2GXM7drqzIo,8904
62
- geovisio/web/upload_set.py,sha256=4lGiHTrQowmxSeLzNL_UF1TKXg02ksitRSPkRXPM4ic,30554
63
- geovisio/web/users.py,sha256=HN6vcoTwi4VPoCofw2_o6HO7tLWh6mA6KfOe8w8Sv9c,8468
64
- geovisio/web/utils.py,sha256=kudTbV4Tgtkbd4oUWFTFpyWNINpxAa-VQNbxYEiR6pM,3640
65
- geovisio/workers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
66
- geovisio/workers/runner_pictures.py,sha256=Q5NykdGynyVBrWcDRYOZBDZb4N7H0LjbafnqZPpjH0M,21747
67
- geovisio-2.7.1.dist-info/LICENSE,sha256=iRFSz7MJ7_j4hh3hvIgzNbS2buy5NMva8lulaixd3IE,1069
68
- geovisio-2.7.1.dist-info/WHEEL,sha256=CpUCUxeHQbRN5UGRQHYRJorO5Af-Qy_fHMctcQ8DSGI,82
69
- geovisio-2.7.1.dist-info/METADATA,sha256=AFnBR_FpjCPW-PZf1rDUh408ps8f5YEZUE24lIbIz0o,4259
70
- geovisio-2.7.1.dist-info/RECORD,,