geovisio 2.10.0__py3-none-any.whl → 2.12.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 (252) hide show
  1. geovisio/__init__.py +32 -2
  2. geovisio/admin_cli/db.py +1 -1
  3. geovisio/admin_cli/user.py +7 -2
  4. geovisio/config_app.py +21 -7
  5. geovisio/db_migrations.py +2 -2
  6. geovisio/migrations/20221201_01_wpCGc-initial-schema.rollback.sql +9 -0
  7. geovisio/migrations/20221201_01_wpCGc-initial-schema.sql +71 -0
  8. geovisio/migrations/20221201_02_ZG8AR-camera-information.rollback.sql +5 -0
  9. geovisio/migrations/20221201_02_ZG8AR-camera-information.sql +10 -0
  10. geovisio/migrations/20221222_01_fsB6f-add-account.rollback.sql +7 -0
  11. geovisio/migrations/20221222_01_fsB6f-add-account.sql +33 -0
  12. geovisio/migrations/20230113_01_0co97-rm-metadata-duplicates.rollback.sql +5 -0
  13. geovisio/migrations/20230113_01_0co97-rm-metadata-duplicates.sql +5 -0
  14. geovisio/migrations/20230116_01_9PkjZ-add-oauth-provider.rollback.sql +12 -0
  15. geovisio/migrations/20230116_01_9PkjZ-add-oauth-provider.sql +10 -0
  16. geovisio/migrations/20230117_01_K71Pd-pictures-ts-index.rollback.sql +4 -0
  17. geovisio/migrations/20230117_01_K71Pd-pictures-ts-index.sql +4 -0
  18. geovisio/migrations/20230130_01_VRIv2-sequences-account.rollback.sql +5 -0
  19. geovisio/migrations/20230130_01_VRIv2-sequences-account.sql +25 -0
  20. geovisio/migrations/20230324_01_ba9WA-status.rollback.sql +35 -0
  21. geovisio/migrations/20230324_01_ba9WA-status.sql +11 -0
  22. geovisio/migrations/20230324_02_efgI6-picture-process.rollback.sql +20 -0
  23. geovisio/migrations/20230324_02_efgI6-picture-process.sql +44 -0
  24. geovisio/migrations/20230407_01_wofh1-computed-headings.rollback.sql +6 -0
  25. geovisio/migrations/20230407_01_wofh1-computed-headings.sql +6 -0
  26. geovisio/migrations/20230417_01_ZgLMY-add-exif-metadata-column-for-pictures.rollback.sql +4 -0
  27. geovisio/migrations/20230417_01_ZgLMY-add-exif-metadata-column-for-pictures.sql +4 -0
  28. geovisio/migrations/20230420_01_elaN3-remove-picture-and-sequence-file-paths.rollback.sql +5 -0
  29. geovisio/migrations/20230420_01_elaN3-remove-picture-and-sequence-file-paths.sql +5 -0
  30. geovisio/migrations/20230425_01_gYP77-pictures-edits-triggers.rollback.sql +5 -0
  31. geovisio/migrations/20230425_01_gYP77-pictures-edits-triggers.sql +64 -0
  32. geovisio/migrations/20230427_01_k5e5w-timestamps.rollback.sql +10 -0
  33. geovisio/migrations/20230427_01_k5e5w-timestamps.sql +19 -0
  34. geovisio/migrations/20230511_01_TdpKo-tokens.rollback.sql +7 -0
  35. geovisio/migrations/20230511_01_TdpKo-tokens.sql +34 -0
  36. geovisio/migrations/20230615_01_u7aRf-pic-delete-cascade.rollback.sql +10 -0
  37. geovisio/migrations/20230615_01_u7aRf-pic-delete-cascade.sql +12 -0
  38. geovisio/migrations/20230623_01_y1SiQ-pic-deletion-task.rollback.sql +39 -0
  39. geovisio/migrations/20230623_01_y1SiQ-pic-deletion-task.sql +36 -0
  40. geovisio/migrations/20230629_01_ZdB3i-compute-heading-0.sql +27 -0
  41. geovisio/migrations/20230711_01_JGSPB-inserted-at-index.rollback.sql +4 -0
  42. geovisio/migrations/20230711_01_JGSPB-inserted-at-index.sql +4 -0
  43. geovisio/migrations/20230720_01_EyQ0e-sequences-summary.rollback.sql +7 -0
  44. geovisio/migrations/20230720_01_EyQ0e-sequences-summary.sql +26 -0
  45. geovisio/migrations/20230803_01_aXusm-fix-sequence-computed.rollback.sql +4 -0
  46. geovisio/migrations/20230803_01_aXusm-fix-sequence-computed.sql +25 -0
  47. geovisio/migrations/20231018_01_4G3YE-pictures-exiv2.rollback.sql +165 -0
  48. geovisio/migrations/20231018_01_4G3YE-pictures-exiv2.sql +206 -0
  49. geovisio/migrations/20231103_01_ZVKEm-update-seq-on-pic-change.rollback.sql +7 -0
  50. geovisio/migrations/20231103_01_ZVKEm-update-seq-on-pic-change.sql +28 -0
  51. geovisio/migrations/20231110_01_3p070-jobs-error.rollback.sql +7 -0
  52. geovisio/migrations/20231110_01_3p070-jobs-error.sql +93 -0
  53. geovisio/migrations/20231121_01_v6oBF-more-specific-triggers.rollback.sql +36 -0
  54. geovisio/migrations/20231121_01_v6oBF-more-specific-triggers.sql +40 -0
  55. geovisio/migrations/20231121_02_1uZXT-deleted-tag.rollback.sql +19 -0
  56. geovisio/migrations/20231121_02_1uZXT-deleted-tag.sql +13 -0
  57. geovisio/migrations/20240115_01_FatLR-token-delete-cascade.rollback.sql +6 -0
  58. geovisio/migrations/20240115_01_FatLR-token-delete-cascade.sql +7 -0
  59. geovisio/migrations/20240220_01_9wZs0-sequence-current-sort.rollback.sql +6 -0
  60. geovisio/migrations/20240220_01_9wZs0-sequence-current-sort.sql +15 -0
  61. geovisio/migrations/20240223_01_LsMHB-remove-binary-fields.sql +80 -0
  62. geovisio/migrations/20240226_01_8iXl1-track-changes.rollback.sql +13 -0
  63. geovisio/migrations/20240226_01_8iXl1-track-changes.sql +123 -0
  64. geovisio/migrations/20240229_01_SgfQY-sequence-geom-multi-linestring.rollback.sql +67 -0
  65. geovisio/migrations/20240229_01_SgfQY-sequence-geom-multi-linestring.sql +101 -0
  66. geovisio/migrations/20240308_01_aF0Jb-migrate-sequence-geom-multi-linestring.sql +52 -0
  67. geovisio/migrations/20240409_01_jnhra-pictures-grid.rollback.sql +3 -0
  68. geovisio/migrations/20240409_01_jnhra-pictures-grid.sql +21 -0
  69. geovisio/migrations/20240416_01_FpyGs-pictures-stats-on-sequences.rollback.sql +7 -0
  70. geovisio/migrations/20240416_01_FpyGs-pictures-stats-on-sequences.sql +9 -0
  71. geovisio/migrations/20240416_02_A5KzC-fill-pictures-stats-on-sequences.rollback.sql +5 -0
  72. geovisio/migrations/20240416_02_A5KzC-fill-pictures-stats-on-sequences.sql +84 -0
  73. geovisio/migrations/20240507_01_eBfqZ-refresh-table.rollback.sql +5 -0
  74. geovisio/migrations/20240507_01_eBfqZ-refresh-table.sql +9 -0
  75. geovisio/migrations/20240507_02_dzVET-picture-grid-public.rollback.sql +21 -0
  76. geovisio/migrations/20240507_02_dzVET-picture-grid-public.sql +26 -0
  77. geovisio/migrations/20240514_01_IT7DD-picture-delete-cascade.rollback.sql +41 -0
  78. geovisio/migrations/20240514_01_IT7DD-picture-delete-cascade.sql +42 -0
  79. geovisio/migrations/20240611_01_jftHn-content-md5.rollback.sql +5 -0
  80. geovisio/migrations/20240611_01_jftHn-content-md5.sql +7 -0
  81. geovisio/migrations/20240612_01_yNcuE-upload-set.rollback.sql +6 -0
  82. geovisio/migrations/20240612_01_yNcuE-upload-set.sql +46 -0
  83. geovisio/migrations/20240617_01_tKtlx-md5-concurrent-index.rollback.sql +4 -0
  84. geovisio/migrations/20240617_01_tKtlx-md5-concurrent-index.sql +8 -0
  85. geovisio/migrations/20240625_01_XMZ24-fix-sequence-stat-on-pic-insertion.rollback.sql +30 -0
  86. geovisio/migrations/20240625_01_XMZ24-fix-sequence-stat-on-pic-insertion.sql +31 -0
  87. geovisio/migrations/20240708_01_Xn7IH-job-queue.rollback.sql +31 -0
  88. geovisio/migrations/20240708_01_Xn7IH-job-queue.sql +104 -0
  89. geovisio/migrations/20240715_01_Hca9V-upload-set-metadata.rollback.sql +4 -0
  90. geovisio/migrations/20240715_01_Hca9V-upload-set-metadata.sql +5 -0
  91. geovisio/migrations/20240723_01_ePGFe-upload-set-files.rollback.sql +7 -0
  92. geovisio/migrations/20240723_01_ePGFe-upload-set-files.sql +29 -0
  93. geovisio/migrations/20240729_01_HALjj-upload-set-sort.rollback.sql +18 -0
  94. geovisio/migrations/20240729_01_HALjj-upload-set-sort.sql +18 -0
  95. geovisio/migrations/20240730_01_2BaCy-improve-deletion-triggers.rollback.sql +34 -0
  96. geovisio/migrations/20240730_01_2BaCy-improve-deletion-triggers.sql +53 -0
  97. geovisio/migrations/20240730_02_aRymN-rejection-status.rollback.sql +10 -0
  98. geovisio/migrations/20240730_02_aRymN-rejection-status.sql +16 -0
  99. geovisio/migrations/20240801_01_DOqmf-reports.rollback.sql +11 -0
  100. geovisio/migrations/20240801_01_DOqmf-reports.sql +100 -0
  101. geovisio/migrations/20240801_01_uKqPo-remove-files-delete-cascade.rollback.sql +13 -0
  102. geovisio/migrations/20240801_01_uKqPo-remove-files-delete-cascade.sql +13 -0
  103. geovisio/migrations/20240813_01_T1XkO-sequences-geom-splits.rollback.sql +42 -0
  104. geovisio/migrations/20240813_01_T1XkO-sequences-geom-splits.sql +56 -0
  105. geovisio/migrations/20240820_01_aB2ZK-exclusion-zones.rollback.sql +6 -0
  106. geovisio/migrations/20240820_01_aB2ZK-exclusion-zones.sql +49 -0
  107. geovisio/migrations/20240902_01_MDqSj-user-agent.rollback.sql +5 -0
  108. geovisio/migrations/20240902_01_MDqSj-user-agent.sql +10 -0
  109. geovisio/migrations/20240904_01_gFjlV-files-rejection-msg.rollback.sql +4 -0
  110. geovisio/migrations/20240904_01_gFjlV-files-rejection-msg.sql +4 -0
  111. geovisio/migrations/20240905_01_C8F6U-conflicts.rollback.sql +13 -0
  112. geovisio/migrations/20240905_01_C8F6U-conflicts.sql +6 -0
  113. geovisio/migrations/20240905_01_E5Ki0-upload-set-delete.rollback.sql +5 -0
  114. geovisio/migrations/20240905_01_E5Ki0-upload-set-delete.sql +30 -0
  115. geovisio/migrations/20240909_01_Muc22-unique-grid-index.rollback.sql +4 -0
  116. geovisio/migrations/20240909_01_Muc22-unique-grid-index.sql +5 -0
  117. geovisio/migrations/20240912_01_dAALm-account-index.rollback.sql +4 -0
  118. geovisio/migrations/20240912_01_dAALm-account-index.sql +4 -0
  119. geovisio/migrations/20241004_01_d1zfe-pictures-grid-360.rollback.sql +22 -0
  120. geovisio/migrations/20241004_01_d1zfe-pictures-grid-360.sql +24 -0
  121. geovisio/migrations/20241011_01_e1j5C-pic-quality.rollback.sql +21 -0
  122. geovisio/migrations/20241011_01_e1j5C-pic-quality.sql +249 -0
  123. geovisio/migrations/20241017_01_GuOjF-pic-quality-update.rollback.sql +4 -0
  124. geovisio/migrations/20241017_01_GuOjF-pic-quality-update.sql +61 -0
  125. geovisio/migrations/20241017_01_RiFlm-pictures-to-delete.rollback.sql +43 -0
  126. geovisio/migrations/20241017_01_RiFlm-pictures-to-delete.sql +75 -0
  127. geovisio/migrations/20241104_01_yhRVu-rejection-details.rollback.sql +4 -0
  128. geovisio/migrations/20241104_01_yhRVu-rejection-details.sql +4 -0
  129. geovisio/migrations/20241128_01_ugthx-job-queue-args.rollback.sql +25 -0
  130. geovisio/migrations/20241128_01_ugthx-job-queue-args.sql +31 -0
  131. geovisio/migrations/20241224_01_xuN6n-delete-upload-set-on-last-picture-trg-statement.rollback.sql +27 -0
  132. geovisio/migrations/20241224_01_xuN6n-delete-upload-set-on-last-picture-trg-statement.sql +28 -0
  133. geovisio/migrations/20250102_01_EElhA-rm-cameras.rollback.sql +126 -0
  134. geovisio/migrations/20250102_01_EElhA-rm-cameras.sql +30 -0
  135. geovisio/migrations/20250107_01_EQN9v-tags-tables.rollback.sql +10 -0
  136. geovisio/migrations/20250107_01_EQN9v-tags-tables.sql +58 -0
  137. geovisio/migrations/20250109_01_4OOP4-pages.rollback.sql +4 -0
  138. geovisio/migrations/20250109_01_4OOP4-pages.sql +10 -0
  139. geovisio/migrations/20250114_01_ABaaL-collaborative-metadata-editing.rollback.sql +7 -0
  140. geovisio/migrations/20250114_01_ABaaL-collaborative-metadata-editing.sql +16 -0
  141. geovisio/migrations/20250123_01_Ececu-tos-acceptance.rollback.sql +5 -0
  142. geovisio/migrations/20250123_01_Ececu-tos-acceptance.sql +5 -0
  143. geovisio/migrations/20250206_01_PjrEL-annotation-semantics.rollback.sql +14 -0
  144. geovisio/migrations/20250206_01_PjrEL-annotation-semantics.sql +15 -0
  145. geovisio/migrations/20250306_01_58oju-semantics-views.rollback.sql +5 -0
  146. geovisio/migrations/20250306_01_58oju-semantics-views.sql +52 -0
  147. geovisio/migrations/20250318_01_pANl1-semantics-functions.rollback.sql +5 -0
  148. geovisio/migrations/20250318_01_pANl1-semantics-functions.sql +41 -0
  149. geovisio/migrations/20250331_01_kRKjo-store-detections-id.rollback.sql +7 -0
  150. geovisio/migrations/20250331_01_kRKjo-store-detections-id.sql +25 -0
  151. geovisio/migrations/20250424_01_RBGXC-semantics-indexes.rollback.sql +6 -0
  152. geovisio/migrations/20250424_01_RBGXC-semantics-indexes.sql +6 -0
  153. geovisio/migrations/20250502_01_ZNmkU-job-task-read-metadata.rollback.sql +24 -0
  154. geovisio/migrations/20250502_01_ZNmkU-job-task-read-metadata.sql +7 -0
  155. geovisio/migrations/20250509_01_kMatW-deactivate-upload-set-split-dedup.rollback.sql +12 -0
  156. geovisio/migrations/20250509_01_kMatW-deactivate-upload-set-split-dedup.sql +12 -0
  157. geovisio/migrations/20250509_01_s3hYk-semantic-delete-cascade.rollback.sql +11 -0
  158. geovisio/migrations/20250509_01_s3hYk-semantic-delete-cascade.sql +11 -0
  159. geovisio/migrations/20250513_01_8WkZC-upload-sets-default-config.rollback.sql +7 -0
  160. geovisio/migrations/20250513_01_8WkZC-upload-sets-default-config.sql +15 -0
  161. geovisio/migrations/20250523_01_b11eW-picture-update-index.rollback.sql +85 -0
  162. geovisio/migrations/20250523_01_b11eW-picture-update-index.sql +166 -0
  163. geovisio/migrations/20250523_02_5ZXXh-update-picture-updated-at.rollback.sql +4 -0
  164. geovisio/migrations/20250523_02_5ZXXh-update-picture-updated-at.sql +7 -0
  165. geovisio/migrations/20250624_01_SETp6-job-warnings.rollback.sql +4 -0
  166. geovisio/migrations/20250624_01_SETp6-job-warnings.sql +4 -0
  167. geovisio/migrations/20250701_01_kr371-upload-set-semantics.rollback.sql +6 -0
  168. geovisio/migrations/20250701_01_kr371-upload-set-semantics.sql +15 -0
  169. geovisio/migrations/20250703_01_p2WVV-sequence-upload-set-link.rollback.sql +4 -0
  170. geovisio/migrations/20250703_01_p2WVV-sequence-upload-set-link.sql +4 -0
  171. geovisio/migrations/20250703_02_q0s3D-sequence-upload-set-fill.rollback.sql +4 -0
  172. geovisio/migrations/20250703_02_q0s3D-sequence-upload-set-fill.sql +26 -0
  173. geovisio/migrations/20250716_01_f8tcJ-check-empty-annotation-late.rollback.sql +24 -0
  174. geovisio/migrations/20250716_01_f8tcJ-check-empty-annotation-late.sql +10 -0
  175. geovisio/migrations/20250728_01_2zgur-upload-set-relative-heading.rollback.sql +4 -0
  176. geovisio/migrations/20250728_01_2zgur-upload-set-relative-heading.sql +4 -0
  177. geovisio/migrations/20250825_01_nCgkN-file-deletion-after-delete-no-dup.rollback.sql +20 -0
  178. geovisio/migrations/20250825_01_nCgkN-file-deletion-after-delete-no-dup.sql +26 -0
  179. geovisio/migrations/20250902_01_k5UTq-visibility-status.rollback.sql +11 -0
  180. geovisio/migrations/20250902_01_k5UTq-visibility-status.sql +19 -0
  181. geovisio/migrations/20250904_01_3uVKX-visibility-functions.rollback.sql +20 -0
  182. geovisio/migrations/20250904_01_3uVKX-visibility-functions.sql +43 -0
  183. geovisio/migrations/20251110_01_bWEXo-report-visibility.rollback.sql +30 -0
  184. geovisio/migrations/20251110_01_bWEXo-report-visibility.sql +30 -0
  185. geovisio/migrations/20251124_01_0xdqi-page-updates.rollback.sql +6 -0
  186. geovisio/migrations/20251124_01_0xdqi-page-updates.sql +8 -0
  187. geovisio/migrations/20251127_01_S6Ci8-pictures-grid-visibility.rollback.sql +24 -0
  188. geovisio/migrations/20251127_01_S6Ci8-pictures-grid-visibility.sql +36 -0
  189. geovisio/migrations/20251202_01_Q3g59-pictures-grid-logged-only.rollback.sql +32 -0
  190. geovisio/migrations/20251202_01_Q3g59-pictures-grid-logged-only.sql +34 -0
  191. geovisio/templates/main.html +7 -58
  192. geovisio/templates/viewer.html +8 -15
  193. geovisio/translations/be/LC_MESSAGES/messages.mo +0 -0
  194. geovisio/translations/be/LC_MESSAGES/messages.po +886 -0
  195. geovisio/translations/cy/LC_MESSAGES/messages.mo +0 -0
  196. geovisio/translations/cy/LC_MESSAGES/messages.po +839 -0
  197. geovisio/translations/da/LC_MESSAGES/messages.mo +0 -0
  198. geovisio/translations/da/LC_MESSAGES/messages.po +96 -5
  199. geovisio/translations/de/LC_MESSAGES/messages.mo +0 -0
  200. geovisio/translations/de/LC_MESSAGES/messages.po +171 -132
  201. geovisio/translations/en/LC_MESSAGES/messages.mo +0 -0
  202. geovisio/translations/en/LC_MESSAGES/messages.po +211 -182
  203. geovisio/translations/eo/LC_MESSAGES/messages.mo +0 -0
  204. geovisio/translations/eo/LC_MESSAGES/messages.po +3 -2
  205. geovisio/translations/fr/LC_MESSAGES/messages.mo +0 -0
  206. geovisio/translations/fr/LC_MESSAGES/messages.po +3 -2
  207. geovisio/translations/it/LC_MESSAGES/messages.mo +0 -0
  208. geovisio/translations/it/LC_MESSAGES/messages.po +1 -1
  209. geovisio/translations/messages.pot +177 -175
  210. geovisio/translations/nl/LC_MESSAGES/messages.mo +0 -0
  211. geovisio/translations/nl/LC_MESSAGES/messages.po +44 -2
  212. geovisio/translations/oc/LC_MESSAGES/messages.mo +0 -0
  213. geovisio/translations/oc/LC_MESSAGES/messages.po +9 -6
  214. geovisio/translations/pt/LC_MESSAGES/messages.mo +0 -0
  215. geovisio/translations/pt/LC_MESSAGES/messages.po +944 -0
  216. geovisio/translations/pt_BR/LC_MESSAGES/messages.mo +0 -0
  217. geovisio/translations/pt_BR/LC_MESSAGES/messages.po +942 -0
  218. geovisio/translations/sv/LC_MESSAGES/messages.mo +0 -0
  219. geovisio/translations/sv/LC_MESSAGES/messages.po +1 -1
  220. geovisio/translations/tr/LC_MESSAGES/messages.mo +0 -0
  221. geovisio/translations/tr/LC_MESSAGES/messages.po +927 -0
  222. geovisio/translations/uk/LC_MESSAGES/messages.mo +0 -0
  223. geovisio/translations/uk/LC_MESSAGES/messages.po +920 -0
  224. geovisio/utils/annotations.py +7 -4
  225. geovisio/utils/auth.py +33 -0
  226. geovisio/utils/cql2.py +42 -20
  227. geovisio/utils/link.py +13 -3
  228. geovisio/utils/pictures.py +16 -18
  229. geovisio/utils/sequences.py +104 -75
  230. geovisio/utils/upload_set.py +62 -12
  231. geovisio/utils/users.py +18 -0
  232. geovisio/web/annotations.py +96 -3
  233. geovisio/web/collections.py +249 -116
  234. geovisio/web/configuration.py +12 -0
  235. geovisio/web/docs.py +18 -4
  236. geovisio/web/items.py +183 -76
  237. geovisio/web/map.py +92 -54
  238. geovisio/web/pages.py +48 -4
  239. geovisio/web/params.py +56 -11
  240. geovisio/web/pictures.py +3 -3
  241. geovisio/web/prepare.py +4 -2
  242. geovisio/web/queryables.py +57 -0
  243. geovisio/web/stac.py +8 -2
  244. geovisio/web/upload_set.py +82 -26
  245. geovisio/web/users.py +86 -5
  246. geovisio/web/utils.py +24 -6
  247. {geovisio-2.10.0.dist-info → geovisio-2.12.0.dist-info}/METADATA +8 -27
  248. geovisio-2.12.0.dist-info/RECORD +305 -0
  249. geovisio-2.12.0.dist-info/entry_points.txt +3 -0
  250. geovisio-2.10.0.dist-info/RECORD +0 -105
  251. {geovisio-2.10.0.dist-info → geovisio-2.12.0.dist-info}/WHEEL +0 -0
  252. {geovisio-2.10.0.dist-info → geovisio-2.12.0.dist-info}/licenses/LICENSE +0 -0
geovisio/__init__.py CHANGED
@@ -1,14 +1,16 @@
1
1
  """GeoVisio API - Main"""
2
2
 
3
- __version__ = "2.10.0"
3
+ __version__ = "2.12.0"
4
4
 
5
5
  import os
6
6
  from flask import Flask, jsonify, stream_template, send_from_directory, redirect, request, url_for
7
- from flask.cli import with_appcontext
7
+ from flask.cli import with_appcontext, FlaskGroup
8
8
  from flask_cors import CORS
9
9
  from flask_compress import Compress
10
10
  from flask_babel import Babel
11
11
  from flasgger import Swagger
12
+ import click
13
+ import atexit
12
14
  import logging
13
15
  from logging.config import dictConfig
14
16
 
@@ -31,6 +33,7 @@ from geovisio.web import (
31
33
  prepare,
32
34
  pages,
33
35
  annotations,
36
+ queryables,
34
37
  )
35
38
  from geovisio.workers import runner_pictures
36
39
 
@@ -65,6 +68,21 @@ LOGGING_CONFIG = {
65
68
  dictConfig(LOGGING_CONFIG)
66
69
 
67
70
 
71
+ def cleanup_app(app):
72
+ """Cleanup app before closing it"""
73
+ if not app.pool.closed:
74
+ app.pool.close()
75
+ if not app.long_queries_pool.closed:
76
+ app.long_queries_pool.close()
77
+ app.background_processor.stop()
78
+
79
+
80
+ def on_app_exit(app):
81
+ """Explicitly cleanup before exiting, to make sure all the database connections are closed, and the background processes stopped
82
+ This is necessary because python 3.13 changed the way the threads bahave at interpreter shutdown"""
83
+ cleanup_app(app)
84
+
85
+
68
86
  # Init i18n
69
87
  def get_locale():
70
88
  try:
@@ -136,6 +154,7 @@ def create_app(test_config=None, app=None):
136
154
  app.register_blueprint(prepare.bp)
137
155
  app.register_blueprint(pages.bp)
138
156
  app.register_blueprint(annotations.bp)
157
+ app.register_blueprint(queryables.bp)
139
158
 
140
159
  # Register CLI comands
141
160
  app.register_blueprint(admin_cli.bp, cli_group=None)
@@ -159,6 +178,8 @@ def create_app(test_config=None, app=None):
159
178
 
160
179
  template_vars = {"API_VERSION_MAJOR_MINOR": ".".join(__version__.split(".")[0:2])}
161
180
 
181
+ atexit.register(on_app_exit, app=app)
182
+
162
183
  # Main page
163
184
  @app.route("/")
164
185
  def index():
@@ -251,3 +272,12 @@ def createDirNoFailure(directory):
251
272
  os.makedirs(directory)
252
273
  except OSError:
253
274
  pass
275
+
276
+
277
+ @click.group(cls=FlaskGroup, create_app=create_app)
278
+ def cli():
279
+ """Panoramax backend management commands"""
280
+ # Note: This makes it possible to do:
281
+ # `panoramax_backend db upgrade` instead of `flask --app geovisio db upgrade` (but the later still works)
282
+ # since this `cli` function is used as a project.scripts
283
+ pass
geovisio/admin_cli/db.py CHANGED
@@ -20,7 +20,7 @@ def upgrade():
20
20
  is_flag=True,
21
21
  default=False,
22
22
  show_default=True,
23
- help="rollbacks all migrations instead, meaning everything created by Geovisio in database is deleted",
23
+ help="rollbacks all migrations instead, meaning everything created by Panoramax in database is deleted",
24
24
  )
25
25
  @with_appcontext
26
26
  def rollback(all):
@@ -6,6 +6,7 @@ from flask.cli import with_appcontext
6
6
  from geovisio.utils import db
7
7
  from geovisio.utils.auth import AccountRole
8
8
  from psycopg.rows import dict_row
9
+ from geovisio.utils.users import delete_user_data
9
10
 
10
11
  bp = Blueprint("user", __name__)
11
12
 
@@ -18,10 +19,11 @@ class Account:
18
19
 
19
20
  @bp.cli.command("user")
20
21
  @click.argument("account_id_or_name")
21
- @click.option("--set-role", required=True, help="Role you want to give to the account. Must be one of: admin or user")
22
+ @click.option("--set-role", help="Role you want to give to the account. Must be one of: admin or user")
22
23
  @click.option("--create", is_flag=True, show_default=True, default=False, help="If provided, create the account if it does not exist")
24
+ @click.option("--delete-data", is_flag=True, show_default=True, default=False, help="If provided, delete all the user's pictures")
23
25
  @with_appcontext
24
- def update_user(account_id_or_name, set_role=None, create=False):
26
+ def update_user(account_id_or_name, set_role=None, create=False, delete_data=False):
25
27
  """
26
28
  Update some information about a user.
27
29
  To identify the account, either the account_id or the account_name must be provided.
@@ -33,6 +35,9 @@ def update_user(account_id_or_name, set_role=None, create=False):
33
35
  if set_role is not None:
34
36
  update_role(cursor, account, set_role)
35
37
 
38
+ if delete_data:
39
+ delete_user_data(conn, account)
40
+
36
41
 
37
42
  def get_account(cursor, account_id_or_name, create):
38
43
  account_id = None
geovisio/config_app.py CHANGED
@@ -9,7 +9,7 @@ from pydantic import BaseModel, EmailStr
9
9
  from pydantic.color import Color
10
10
  from pydantic.networks import HttpUrl
11
11
  import json
12
- from flask import Flask, current_app
12
+ from flask import Flask
13
13
 
14
14
  from geovisio.utils import website
15
15
  from geovisio.utils.model_query import get_db_params_and_values
@@ -53,7 +53,8 @@ class DefaultConfig:
53
53
  API_WEBSITE_URL = (
54
54
  website.WEBSITE_UNDER_SAME_HOST
55
55
  ) # by default we consider that there is a panoramax website on the same host as the API
56
- API_REGISTRATION_IS_OPEN = False # tells that anyone can create an account. Only used for reference in the federation for the moment
56
+ API_REGISTRATION_IS_OPEN = False # tells that anyone can create an account. Used for reference in the federation and to know if we can have a `logged-only` visibility.
57
+ API_DEFAULT_PICTURE_VISIBILITY = "anyone"
57
58
 
58
59
 
59
60
  def read_config(app, test_config):
@@ -96,6 +97,7 @@ def read_config(app, test_config):
96
97
  "API_ENFORCE_TOS_ACCEPTANCE",
97
98
  "API_WEBSITE_URL",
98
99
  "API_REGISTRATION_IS_OPEN",
100
+ "API_DEFAULT_PICTURE_VISIBILITY",
99
101
  # Picture process
100
102
  "PICTURE_PROCESS_DERIVATES_STRATEGY",
101
103
  "PICTURE_PROCESS_THREADS_LIMIT",
@@ -229,6 +231,10 @@ def read_config(app, test_config):
229
231
  if not croniter.croniter.is_valid(cron_val):
230
232
  raise Exception(f"PICTURE_PROCESS_REFRESH_CRON should be a valid cron syntax, got '{cron_val}'")
231
233
 
234
+ default_visibility = app.config["API_DEFAULT_PICTURE_VISIBILITY"]
235
+ if default_visibility not in ["anyone", "owner-only", "logged-only"]:
236
+ raise Exception(f"API_DEFAULT_PICTURE_VISIBILITY should be 'anyone', 'owner-only' or 'logged-only', got '{default_visibility}'")
237
+
232
238
  app.config["PICTURE_PROCESS_KEEP_UNBLURRED_PARTS"] = _read_bool(app.config, "PICTURE_PROCESS_KEEP_UNBLURRED_PARTS")
233
239
 
234
240
  app.config["API_ACCEPT_DUPLICATE"] = _read_bool(app.config, "API_ACCEPT_DUPLICATE")
@@ -302,6 +308,7 @@ class DBConfiguration(BaseModel):
302
308
  Not all configurations are meant to be persisted in the database"""
303
309
 
304
310
  collaborative_metadata: Optional[bool] = None
311
+ default_visibility: Optional[str] = None
305
312
 
306
313
 
307
314
  def persist_config(app: Flask):
@@ -312,13 +319,13 @@ def persist_config(app: Flask):
312
319
  """
313
320
  from geovisio.utils import db
314
321
  from psycopg.rows import class_row
315
- from psycopg.sql import SQL, Literal
316
- from psycopg.errors import UndefinedTable
322
+ from psycopg.sql import SQL
323
+ from psycopg.errors import UndefinedTable, UndefinedColumn
317
324
 
318
- with db.conn(app) as conn, conn.transaction() as tr, conn.cursor(row_factory=class_row(DBConfiguration)) as cur:
325
+ with db.conn(app) as conn, conn.transaction(), conn.cursor(row_factory=class_row(DBConfiguration)) as cur:
319
326
  try:
320
- db_config = cur.execute("SELECT * FROM configurations LIMIT 1").fetchone()
321
- except UndefinedTable:
327
+ db_config = cur.execute("SELECT collaborative_metadata, default_visibility FROM configurations LIMIT 1").fetchone()
328
+ except (UndefinedTable, UndefinedColumn):
322
329
  logging.warning("Database schema has not been updated yet, configuration will not be persisted")
323
330
  return
324
331
  if not db_config:
@@ -333,6 +340,13 @@ def persist_config(app: Flask):
333
340
  logging.warning(
334
341
  "The environment variable `API_DEFAULT_COLLABORATIVE_METADATA_EDITING` has a different value than its value in the database, it will be ignored. Update the `collaborative_metadata` field in the database if you want to change it."
335
342
  )
343
+ default_visibility = app.config["API_DEFAULT_PICTURE_VISIBILITY"]
344
+ if db_config.default_visibility is None:
345
+ config_to_persist.default_visibility = default_visibility
346
+ elif db_config.default_visibility != default_visibility and default_visibility is not None:
347
+ logging.warning(
348
+ "The environment variable `API_DEFAULT_PICTURE_VISIBILITY` has a different value than its value in the database, it will be ignored. Update the `default_visibility` field in the database if you want to change it."
349
+ )
336
350
 
337
351
  params_as_dict = get_db_params_and_values(config_to_persist)
338
352
  fields = params_as_dict.fields_for_set()
geovisio/db_migrations.py CHANGED
@@ -67,7 +67,7 @@ ALTER DATABASE {dbName.as_string()} SET TIMEZONE TO 'UTC';"""
67
67
  # * nor for the tests
68
68
  if "db" not in sys.argv and "pytest" not in sys.modules:
69
69
  raise Exception(
70
- f"""Geovisio database schema needs an update !
70
+ f"""Panoramax database schema needs an update !
71
71
 
72
72
  The following database migrations are required:
73
73
  {migrationNames}
@@ -105,4 +105,4 @@ def get_yoyo_backend(dbUrl):
105
105
 
106
106
 
107
107
  def get_migrations():
108
- return yoyo.read_migrations(os.path.join(os.path.dirname(__file__), "../migrations"))
108
+ return yoyo.read_migrations(os.path.join(os.path.dirname(__file__), "migrations"))
@@ -0,0 +1,9 @@
1
+ -- initial schema
2
+ -- depends:
3
+
4
+ DROP TABLE IF EXISTS next_sequences CASCADE;
5
+ DROP TABLE IF EXISTS sequences_pictures CASCADE;
6
+ DROP TABLE IF EXISTS sequences CASCADE;
7
+ DROP TYPE IF EXISTS sequence_status;
8
+ DROP TABLE IF EXISTS pictures CASCADE;
9
+ DROP TYPE IF EXISTS picture_status;
@@ -0,0 +1,71 @@
1
+ -- initial schema
2
+ -- depends:
3
+
4
+
5
+ --
6
+ -- Script for database setup
7
+ --
8
+
9
+ CREATE EXTENSION IF NOT EXISTS postgis;
10
+ CREATE EXTENSION IF NOT EXISTS "uuid-ossp";
11
+ CREATE EXTENSION IF NOT EXISTS pg_trgm;
12
+
13
+
14
+ -- Pictures
15
+ CREATE TYPE picture_status AS ENUM (
16
+ 'preparing', -- Default state
17
+ 'broken', -- State when an error occured during import/blurring
18
+ 'ready', -- State when picture is ready to serve
19
+ 'hidden' -- State when admin disabled picture
20
+ );
21
+
22
+ CREATE TABLE pictures(
23
+ id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
24
+ file_path VARCHAR NOT NULL, -- Relative to instance storage path
25
+ status picture_status NOT NULL DEFAULT 'preparing',
26
+ ts TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
27
+ heading INT,
28
+ metadata JSONB,
29
+ geom GEOMETRY(Point, 4326) NOT NULL
30
+ );
31
+
32
+ CREATE INDEX pictures_geom_idx ON pictures USING GIST(geom);
33
+ CREATE INDEX pictures_status_idx ON pictures(status);
34
+
35
+ -- Sequences
36
+ CREATE TYPE sequence_status AS ENUM (
37
+ 'preparing', -- Default state
38
+ 'broken', -- State when an error occured during import
39
+ 'ready', -- State when sequence is ready to serve
40
+ 'hidden' -- State when admin disabled sequence
41
+ );
42
+
43
+ CREATE TABLE sequences(
44
+ id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
45
+ folder_path VARCHAR NOT NULL,
46
+ status sequence_status NOT NULL DEFAULT 'preparing',
47
+ metadata JSONB,
48
+ geom GEOMETRY(LineString, 4326)
49
+ );
50
+
51
+ CREATE INDEX sequences_geom_idx ON sequences USING GIST(geom);
52
+ CREATE INDEX sequences_status_idx ON sequences(status);
53
+ CREATE INDEX sequences_folder_path_idx ON sequences(folder_path);
54
+
55
+ -- Link between pictures and sequences
56
+ CREATE TABLE sequences_pictures(
57
+ seq_id UUID NOT NULL REFERENCES sequences(id),
58
+ rank BIGINT NOT NULL,
59
+ pic_id UUID NOT NULL REFERENCES pictures(id),
60
+ PRIMARY KEY (seq_id, rank)
61
+ );
62
+
63
+ CREATE INDEX sequences_pictures_pic_id_idx ON sequences_pictures(pic_id);
64
+
65
+ -- Link between sequences
66
+ CREATE TABLE next_sequences(
67
+ seq_id UUID NOT NULL REFERENCES sequences(id),
68
+ rank INT NOT NULL,
69
+ next_seq_id UUID NOT NULL REFERENCES sequences(id),
70
+ PRIMARY KEY (seq_id, rank)
71
+ );
@@ -0,0 +1,5 @@
1
+ -- add-account
2
+ -- depends: 20221201_01_wpCGc-initial-schema
3
+
4
+ -- the camera info has been deprecated since versions > 2.7.1__. Newer versions uses data from Geo-picture tag reader directly.
5
+ DROP TABLE IF EXISTS cameras;
@@ -0,0 +1,10 @@
1
+ -- add-account
2
+ -- depends: 20221201_01_wpCGc-initial-schema
3
+
4
+ -- the camera info has been deprecated since versions > 2.7.1__. Newer versions uses data from Geo-picture tag reader directly.
5
+ CREATE TABLE cameras(
6
+ model VARCHAR PRIMARY KEY,
7
+ sensor_width FLOAT NOT NULL
8
+ );
9
+
10
+ CREATE INDEX cameras_model_idx ON cameras USING GIST(model gist_trgm_ops);
@@ -0,0 +1,7 @@
1
+ -- add-account
2
+ -- depends: 20221201_02_ZG8AR-camera-information
3
+
4
+ ALTER TABLE pictures DROP CONSTRAINT account_fk_id;
5
+ ALTER TABLE pictures DROP COLUMN account_id;
6
+
7
+ DROP TABLE IF EXISTS accounts CASCADE;
@@ -0,0 +1,33 @@
1
+ -- add-account
2
+ -- depends: 20221201_02_ZG8AR-camera-information
3
+
4
+ CREATE TABLE accounts(
5
+ id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
6
+ name VARCHAR NOT NULL,
7
+ is_default BOOLEAN NOT NULL DEFAULT false,
8
+
9
+ CONSTRAINT name_unique UNIQUE (name)
10
+ );
11
+
12
+ -- At most one account can be the default one
13
+ CREATE UNIQUE INDEX at_most_one_default
14
+ ON accounts (is_default) WHERE (is_default);
15
+
16
+ -- Add a link betwen account and picture
17
+ ALTER TABLE pictures ADD COLUMN IF NOT EXISTS account_id UUID;
18
+ ALTER TABLE pictures ADD CONSTRAINT account_fk_id FOREIGN KEY (account_id) REFERENCES accounts (id);
19
+
20
+ -- Create default account and associate existing pictures to default account
21
+ WITH default_account AS (
22
+ INSERT INTO accounts(name, is_default)
23
+ VALUES('Default account', true)
24
+ ON CONFLICT DO NOTHING
25
+ RETURNING id
26
+ )
27
+ UPDATE pictures
28
+ SET account_id = default_account.id
29
+ FROM default_account
30
+ WHERE account_id IS NULL;
31
+
32
+ -- After initial init, set NOT NULL constraint on account_id
33
+ ALTER TABLE pictures ALTER COLUMN account_id SET NOT NULL;
@@ -0,0 +1,5 @@
1
+ -- rm-metadata-duplicates
2
+ -- depends: 20221222_01_fsB6f-add-account
3
+
4
+ UPDATE pictures
5
+ SET metadata = metadata || jsonb_build_object('lat', ST_Y(geom), 'lon', ST_X(geom), 'ts', EXTRACT(epoch FROM ts), 'heading', heading);
@@ -0,0 +1,5 @@
1
+ -- rm-metadata-duplicates
2
+ -- depends: 20221222_01_fsB6f-add-account
3
+
4
+ UPDATE pictures
5
+ SET metadata = metadata - '{lat,lon,ts,heading}'::text[];
@@ -0,0 +1,12 @@
1
+ -- add-provider-oidc
2
+ -- depends: 20230113_01_0co97-rm-metadata-duplicates
3
+
4
+ DROP INDEX oauth_id_idx;
5
+
6
+ ALTER TABLE accounts
7
+ DROP COLUMN oauth_provider,
8
+ DROP COLUMN oauth_id,
9
+ DROP COLUMN created_at;
10
+
11
+ ALTER TABLE accounts ADD CONSTRAINT name_unique UNIQUE (name);
12
+
@@ -0,0 +1,10 @@
1
+ -- add-provider-oidc
2
+ -- depends: 20230113_01_0co97-rm-metadata-duplicates
3
+
4
+
5
+ ALTER TABLE accounts ADD COLUMN IF NOT EXISTS oauth_provider VARCHAR;
6
+ ALTER TABLE accounts ADD COLUMN IF NOT EXISTS oauth_id VARCHAR;
7
+ ALTER TABLE accounts ADD COLUMN IF NOT EXISTS created_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP;
8
+ ALTER TABLE accounts DROP CONSTRAINT name_unique;
9
+
10
+ CREATE UNIQUE INDEX oauth_id_idx ON accounts (oauth_provider, oauth_id);
@@ -0,0 +1,4 @@
1
+ -- pictures-ts-index
2
+ -- depends: 20230113_01_0co97-rm-metadata-duplicates
3
+
4
+ DROP INDEX IF EXISTS pictures_ts_idx;
@@ -0,0 +1,4 @@
1
+ -- pictures-ts-index
2
+ -- depends: 20230113_01_0co97-rm-metadata-duplicates
3
+
4
+ CREATE INDEX pictures_ts_idx ON pictures(ts);
@@ -0,0 +1,5 @@
1
+ -- sequences-account
2
+ -- depends: 20230117_01_K71Pd-pictures-ts-index
3
+
4
+ -- Drop account column on sequences
5
+ ALTER TABLE sequences DROP COLUMN account_id;
@@ -0,0 +1,25 @@
1
+ -- sequences-account
2
+ -- depends: 20230117_01_K71Pd-pictures-ts-index
3
+
4
+ -- Add account column on sequences
5
+ ALTER TABLE sequences ADD COLUMN IF NOT EXISTS account_id UUID;
6
+ ALTER TABLE sequences ADD CONSTRAINT account_fk_id FOREIGN KEY (account_id) REFERENCES accounts (id);
7
+
8
+ -- Try to fill it with sequence's first picture account
9
+ UPDATE sequences
10
+ SET account_id = p.account_id
11
+ FROM (
12
+ SELECT DISTINCT ON (sp.seq_id) sp.seq_id, p.account_id, COUNT(*) as nb
13
+ FROM pictures p
14
+ JOIN sequences_pictures sp on sp.pic_id = p.id
15
+ GROUP BY sp.seq_id, p.account_id
16
+ ORDER BY sp.seq_id, nb DESC
17
+ ) p;
18
+
19
+ -- Otherwise, use default account
20
+ UPDATE sequences
21
+ SET account_id = (SELECT id FROM accounts WHERE is_default)
22
+ WHERE account_id IS NULL;
23
+
24
+ -- After initial init, set NOT NULL constraint on account_id
25
+ ALTER TABLE sequences ALTER COLUMN account_id SET NOT NULL;
@@ -0,0 +1,35 @@
1
+ -- status
2
+ -- depends: 20230116_01_9PkjZ-add-oauth-provider 20230130_01_VRIv2-sequences-account
3
+
4
+ UPDATE pictures SET status = 'preparing' WHERE status::text like 'preparing-' OR status = 'waiting-for-process';
5
+ -- Note: PG does not support removing enum values, so we need to rename and replace with another one
6
+
7
+ CREATE TYPE picture_status_new AS ENUM (
8
+ 'preparing',
9
+ 'broken',
10
+ 'ready',
11
+ 'hidden'
12
+ );
13
+
14
+
15
+ alter table pictures ALTER COLUMN status DROP DEFAULT;
16
+ alter table pictures ALTER COLUMN status TYPE picture_status_new USING status::text::picture_status_new;
17
+ alter table pictures ALTER COLUMN status SET DEFAULT 'preparing';
18
+ DROP TYPE picture_status;
19
+ ALTER TYPE picture_status_new RENAME TO picture_status;
20
+
21
+
22
+ CREATE TYPE sequence_status_new AS ENUM (
23
+ 'preparing',
24
+ 'broken',
25
+ 'ready',
26
+ 'hidden'
27
+ );
28
+
29
+
30
+ alter table sequences ALTER COLUMN status DROP DEFAULT;
31
+ alter table sequences ALTER COLUMN status TYPE sequence_status_new USING status::text::sequence_status_new;
32
+ alter table sequences ALTER COLUMN status SET DEFAULT 'preparing';
33
+
34
+ DROP TYPE sequence_status;
35
+ ALTER TYPE sequence_status_new RENAME TO sequence_status;
@@ -0,0 +1,11 @@
1
+ -- status
2
+ -- depends: 20230116_01_9PkjZ-add-oauth-provider 20230130_01_VRIv2-sequences-account
3
+
4
+ -- type cannot be altered in a transaction, so we ask yolo not to create one
5
+ -- transactional: false
6
+
7
+ ALTER TYPE picture_status ADD VALUE 'waiting-for-process';
8
+ ALTER TYPE picture_status ADD VALUE 'preparing-derivates';
9
+ ALTER TYPE picture_status ADD VALUE 'preparing-blur';
10
+
11
+ ALTER TYPE sequence_status ADD VALUE 'waiting-for-process';
@@ -0,0 +1,20 @@
1
+ -- status
2
+ -- depends: 20230324_01_ba9WA-status
3
+
4
+ ALTER TABLE pictures
5
+ DROP COLUMN IF EXISTS inserted_at,
6
+ DROP COLUMN IF EXISTS processed_at,
7
+ DROP COLUMN IF EXISTS nb_errors,
8
+ DROP COLUMN IF EXISTS process_error
9
+ ;
10
+
11
+ DROP TABLE pictures_to_process;
12
+
13
+ -- update default from 'waiting-for-process' to 'preparing'
14
+ UPDATE pictures SET status = 'preparing' WHERE status = 'waiting-for-process';
15
+ ALTER TABLE pictures ALTER COLUMN status SET DEFAULT 'preparing';
16
+
17
+ UPDATE sequences SET status = 'preparing' WHERE status = 'waiting-for-process';
18
+ ALTER TABLE sequences ALTER COLUMN status SET DEFAULT 'preparing';
19
+
20
+ DROP FUNCTION picture_insertion CASCADE;
@@ -0,0 +1,44 @@
1
+ -- status
2
+ -- depends: 20230324_01_ba9WA-status
3
+
4
+ ALTER TABLE pictures
5
+ ADD COLUMN IF NOT EXISTS inserted_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
6
+ ADD COLUMN IF NOT EXISTS processed_at TIMESTAMPTZ,
7
+ ADD COLUMN IF NOT EXISTS nb_errors INT NOT NULL DEFAULT 0,
8
+ ADD COLUMN IF NOT EXISTS process_error VARCHAR
9
+ ;
10
+
11
+ CREATE TABLE pictures_to_process(
12
+ picture_id UUID PRIMARY KEY,
13
+ ts TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP
14
+ );
15
+ ALTER TABLE pictures_to_process ADD CONSTRAINT picture_id_fk FOREIGN KEY (picture_id) REFERENCES pictures (id);
16
+
17
+ CREATE INDEX pictures_to_process_ts_idx ON pictures_to_process(ts);
18
+
19
+ -- update default from 'preparing' to 'waiting-for-process'
20
+ UPDATE pictures SET status = 'waiting-for-process' WHERE status = 'preparing';
21
+ ALTER TABLE pictures ALTER COLUMN status SET DEFAULT 'waiting-for-process';
22
+
23
+ CREATE INDEX pictures_processed_at_idx ON pictures(inserted_at);
24
+
25
+ UPDATE sequences SET status = 'waiting-for-process' WHERE status = 'preparing';
26
+ ALTER TABLE sequences ALTER COLUMN status SET DEFAULT 'waiting-for-process';
27
+
28
+ -- Create Trigger to insert each new picture into pictures_to_process
29
+ CREATE OR REPLACE FUNCTION picture_insertion() RETURNS TRIGGER AS
30
+ $BODY$
31
+ BEGIN
32
+ INSERT INTO
33
+ pictures_to_process(picture_id)
34
+ VALUES
35
+ (new.id);
36
+ RETURN new;
37
+ END;
38
+ $BODY$
39
+ language plpgsql;
40
+
41
+ CREATE TRIGGER trigger_process_picture_insertion
42
+ AFTER INSERT ON pictures
43
+ FOR EACH ROW
44
+ EXECUTE PROCEDURE picture_insertion();
@@ -0,0 +1,6 @@
1
+ -- computed_headings
2
+ -- depends: 20230324_02_efgI6-picture-process
3
+
4
+ -- We need to be able to tell if the heading have been computed or given as input
5
+
6
+ ALTER TABLE pictures DROP COLUMN IF EXISTS heading_computed;
@@ -0,0 +1,6 @@
1
+ -- computed_headings
2
+ -- depends: 20230324_02_efgI6-picture-process
3
+
4
+ -- We need to be able to tell if the heading have been computed or given as input
5
+
6
+ ALTER TABLE pictures ADD COLUMN IF NOT EXISTS heading_computed BOOLEAN NOT NULL DEFAULT false;
@@ -0,0 +1,4 @@
1
+ -- Add exif metadata column for pictures
2
+ -- depends: 20230407_01_wofh1-computed-headings
3
+
4
+ ALTER TABLE pictures DROP COLUMN exif;
@@ -0,0 +1,4 @@
1
+ -- Add exif metadata column for pictures
2
+ -- depends: 20230407_01_wofh1-computed-headings
3
+
4
+ ALTER TABLE pictures ADD COLUMN exif JSONB;
@@ -0,0 +1,5 @@
1
+ -- Remove picture and sequence file paths
2
+ -- depends: 20230417_01_ZgLMY-add-exif-metadata-column-for-pictures
3
+
4
+ ALTER TABLE pictures ADD COLUMN file_path VARCHAR;
5
+ ALTER TABLE sequences ADD COLUMN folder_path VARCHAR;
@@ -0,0 +1,5 @@
1
+ -- Remove picture and sequence file paths
2
+ -- depends: 20230417_01_ZgLMY-add-exif-metadata-column-for-pictures
3
+
4
+ ALTER TABLE pictures DROP COLUMN IF EXISTS file_path;
5
+ ALTER TABLE sequences DROP COLUMN IF EXISTS folder_path;
@@ -0,0 +1,5 @@
1
+ -- pictures_edits_triggers
2
+ -- depends: 20230420_01_elaN3-remove-picture-and-sequence-file-paths
3
+
4
+ DROP FUNCTION IF EXISTS pictures_update_sequence CASCADE;
5
+ DROP FUNCTION IF EXISTS sequences_pictures_delete CASCADE;