igs-slm 0.1.0b0__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 (447) hide show
  1. igs_slm-0.1.0b0.dist-info/LICENSE +21 -0
  2. igs_slm-0.1.0b0.dist-info/METADATA +151 -0
  3. igs_slm-0.1.0b0.dist-info/RECORD +447 -0
  4. igs_slm-0.1.0b0.dist-info/WHEEL +4 -0
  5. igs_slm-0.1.0b0.dist-info/entry_points.txt +3 -0
  6. igs_tools/__init__.py +0 -0
  7. igs_tools/connection.py +88 -0
  8. igs_tools/defines/__init__.py +8 -0
  9. igs_tools/defines/constellation.py +21 -0
  10. igs_tools/defines/data_center.py +75 -0
  11. igs_tools/defines/rinex.py +49 -0
  12. igs_tools/directory.py +247 -0
  13. igs_tools/utils.py +66 -0
  14. slm/__init__.py +21 -0
  15. slm/admin.py +674 -0
  16. slm/api/edit/__init__.py +0 -0
  17. slm/api/edit/serializers.py +316 -0
  18. slm/api/edit/views.py +1632 -0
  19. slm/api/fields.py +89 -0
  20. slm/api/filter.py +504 -0
  21. slm/api/pagination.py +55 -0
  22. slm/api/permissions.py +65 -0
  23. slm/api/public/__init__.py +0 -0
  24. slm/api/public/serializers.py +249 -0
  25. slm/api/public/views.py +606 -0
  26. slm/api/serializers.py +132 -0
  27. slm/api/views.py +148 -0
  28. slm/apps.py +323 -0
  29. slm/authentication.py +198 -0
  30. slm/bin/__init__.py +0 -0
  31. slm/bin/startproject.py +262 -0
  32. slm/bin/templates/{{ project_dir }}/pyproject.toml +35 -0
  33. slm/bin/templates/{{ project_dir }}/sites/__init__.py +0 -0
  34. slm/bin/templates/{{ project_dir }}/sites/{{ site }}/__init__.py +0 -0
  35. slm/bin/templates/{{ project_dir }}/sites/{{ site }}/base.py +15 -0
  36. slm/bin/templates/{{ project_dir }}/sites/{{ site }}/develop/__init__.py +56 -0
  37. slm/bin/templates/{{ project_dir }}/sites/{{ site }}/develop/local.py +4 -0
  38. slm/bin/templates/{{ project_dir }}/sites/{{ site }}/develop/wsgi.py +16 -0
  39. slm/bin/templates/{{ project_dir }}/sites/{{ site }}/manage.py +34 -0
  40. slm/bin/templates/{{ project_dir }}/sites/{{ site }}/production/__init__.py +61 -0
  41. slm/bin/templates/{{ project_dir }}/sites/{{ site }}/production/wsgi.py +16 -0
  42. slm/bin/templates/{{ project_dir }}/sites/{{ site }}/urls.py +7 -0
  43. slm/bin/templates/{{ project_dir }}/sites/{{ site }}/validation.py +11 -0
  44. slm/bin/templates/{{ project_dir }}/{{ extension_app }}/__init__.py +0 -0
  45. slm/bin/templates/{{ project_dir }}/{{ extension_app }}/admin.py +5 -0
  46. slm/bin/templates/{{ project_dir }}/{{ extension_app }}/apps.py +14 -0
  47. slm/bin/templates/{{ project_dir }}/{{ extension_app }}/management/__init__.py +0 -0
  48. slm/bin/templates/{{ project_dir }}/{{ extension_app }}/management/commands/__init__.py +0 -0
  49. slm/bin/templates/{{ project_dir }}/{{ extension_app }}/management/commands/import_archive.py +64 -0
  50. slm/bin/templates/{{ project_dir }}/{{ extension_app }}/migrations/__init__.py +0 -0
  51. slm/bin/templates/{{ project_dir }}/{{ extension_app }}/models.py +6 -0
  52. slm/bin/templates/{{ project_dir }}/{{ extension_app }}/templates/slm/base.html +8 -0
  53. slm/bin/templates/{{ project_dir }}/{{ extension_app }}/urls.py +10 -0
  54. slm/bin/templates/{{ project_dir }}/{{ extension_app }}/views.py +5 -0
  55. slm/defines/AlertLevel.py +24 -0
  56. slm/defines/AntennaCalibration.py +25 -0
  57. slm/defines/AntennaFeatures.py +27 -0
  58. slm/defines/AntennaReferencePoint.py +22 -0
  59. slm/defines/Aspiration.py +13 -0
  60. slm/defines/CardinalDirection.py +19 -0
  61. slm/defines/CollocationStatus.py +12 -0
  62. slm/defines/EquipmentState.py +22 -0
  63. slm/defines/FlagSeverity.py +14 -0
  64. slm/defines/FractureSpacing.py +15 -0
  65. slm/defines/FrequencyStandardType.py +15 -0
  66. slm/defines/GeodesyMLVersion.py +48 -0
  67. slm/defines/ISOCountry.py +1194 -0
  68. slm/defines/Instrumentation.py +19 -0
  69. slm/defines/LogEntryType.py +30 -0
  70. slm/defines/SLMFileType.py +18 -0
  71. slm/defines/SiteFileUploadStatus.py +61 -0
  72. slm/defines/SiteLogFormat.py +49 -0
  73. slm/defines/SiteLogStatus.py +78 -0
  74. slm/defines/TectonicPlates.py +28 -0
  75. slm/defines/__init__.py +46 -0
  76. slm/forms.py +1126 -0
  77. slm/jinja2/slm/sitelog/ascii_9char.log +346 -0
  78. slm/jinja2/slm/sitelog/legacy.log +346 -0
  79. slm/jinja2/slm/sitelog/xsd/0.4/collocationInformation.xml +12 -0
  80. slm/jinja2/slm/sitelog/xsd/0.4/condition.xml +12 -0
  81. slm/jinja2/slm/sitelog/xsd/0.4/contact.xml +52 -0
  82. slm/jinja2/slm/sitelog/xsd/0.4/formInformation.xml +5 -0
  83. slm/jinja2/slm/sitelog/xsd/0.4/frequencyStandard.xml +12 -0
  84. slm/jinja2/slm/sitelog/xsd/0.4/gnssAntenna.xml +16 -0
  85. slm/jinja2/slm/sitelog/xsd/0.4/gnssReceiver.xml +11 -0
  86. slm/jinja2/slm/sitelog/xsd/0.4/humiditySensor.xml +13 -0
  87. slm/jinja2/slm/sitelog/xsd/0.4/localEpisodicEffect.xml +10 -0
  88. slm/jinja2/slm/sitelog/xsd/0.4/moreInformation.xml +22 -0
  89. slm/jinja2/slm/sitelog/xsd/0.4/multipathSource.xml +10 -0
  90. slm/jinja2/slm/sitelog/xsd/0.4/otherInstrumentation.xml +5 -0
  91. slm/jinja2/slm/sitelog/xsd/0.4/pressureSensor.xml +12 -0
  92. slm/jinja2/slm/sitelog/xsd/0.4/radioInterference.xml +11 -0
  93. slm/jinja2/slm/sitelog/xsd/0.4/sensor.xml +16 -0
  94. slm/jinja2/slm/sitelog/xsd/0.4/signalObstruction.xml +10 -0
  95. slm/jinja2/slm/sitelog/xsd/0.4/siteIdentification.xml +22 -0
  96. slm/jinja2/slm/sitelog/xsd/0.4/siteLocation.xml +21 -0
  97. slm/jinja2/slm/sitelog/xsd/0.4/surveyedLocalTie.xml +20 -0
  98. slm/jinja2/slm/sitelog/xsd/0.4/temperatureSensor.xml +13 -0
  99. slm/jinja2/slm/sitelog/xsd/0.4/waterVaporSensor.xml +11 -0
  100. slm/jinja2/slm/sitelog/xsd/0.5/document.xml +10 -0
  101. slm/jinja2/slm/sitelog/xsd/geodesyml_0.4.xml +99 -0
  102. slm/jinja2/slm/sitelog/xsd/geodesyml_0.5.xml +112 -0
  103. slm/management/__init__.py +0 -0
  104. slm/management/commands/__init__.py +53 -0
  105. slm/management/commands/build_index.py +96 -0
  106. slm/management/commands/generate_sinex.py +675 -0
  107. slm/management/commands/head_from_index.py +541 -0
  108. slm/management/commands/import_archive.py +908 -0
  109. slm/management/commands/import_equipment.py +351 -0
  110. slm/management/commands/set_site.py +56 -0
  111. slm/management/commands/sitelog.py +144 -0
  112. slm/management/commands/synchronize.py +60 -0
  113. slm/management/commands/update_data_availability.py +167 -0
  114. slm/management/commands/validate_db.py +186 -0
  115. slm/management/commands/validate_gml.py +73 -0
  116. slm/map/__init__.py +1 -0
  117. slm/map/admin.py +5 -0
  118. slm/map/api/__init__.py +0 -0
  119. slm/map/api/edit/__init__.py +0 -0
  120. slm/map/api/edit/serializers.py +28 -0
  121. slm/map/api/edit/views.py +46 -0
  122. slm/map/api/public/__init__.py +0 -0
  123. slm/map/api/public/serializers.py +29 -0
  124. slm/map/api/public/views.py +64 -0
  125. slm/map/apps.py +7 -0
  126. slm/map/defines.py +53 -0
  127. slm/map/migrations/0001_initial.py +115 -0
  128. slm/map/migrations/__init__.py +0 -0
  129. slm/map/models.py +63 -0
  130. slm/map/static/slm/css/map.css +86 -0
  131. slm/map/static/slm/js/map.js +159 -0
  132. slm/map/templates/slm/map.html +374 -0
  133. slm/map/templates/slm/station/base.html +11 -0
  134. slm/map/templates/slm/station/edit.html +10 -0
  135. slm/map/templates/slm/top_nav.html +17 -0
  136. slm/map/templatetags/__init__.py +0 -0
  137. slm/map/templatetags/slm_map.py +18 -0
  138. slm/map/urls.py +25 -0
  139. slm/map/views.py +36 -0
  140. slm/middleware.py +29 -0
  141. slm/migrations/0001_alter_siteantenna_marker_enu_alter_sitelocation_llh_and_more.py +47 -0
  142. slm/migrations/0001_initial.py +4826 -0
  143. slm/migrations/0002_alter_dataavailability_site.py +22 -0
  144. slm/migrations/0003_remove_logentry_slm_logentr_site_lo_7a2af7_idx_and_more.py +80 -0
  145. slm/migrations/0004_alter_logentry_timestamp_and_more.py +25 -0
  146. slm/migrations/0005_alter_logentry_options_alter_logentry_section_and_more.py +46 -0
  147. slm/migrations/0006_alter_logentry_options_alter_logentry_index_together.py +24 -0
  148. slm/migrations/0007_alter_dataavailability_rate.py +23 -0
  149. slm/migrations/0008_alter_archiveindex_options_and_more.py +64 -0
  150. slm/migrations/0009_alter_archiveindex_end.py +21 -0
  151. slm/migrations/0010_alter_dataavailability_rinex_version_and_more.py +844 -0
  152. slm/migrations/0011_alter_siteidentification_fracture_spacing.py +33 -0
  153. slm/migrations/0012_alter_logentry_type.py +36 -0
  154. slm/migrations/0013_unpublishedfilesalert.py +48 -0
  155. slm/migrations/0014_sitelogpublished.py +48 -0
  156. slm/migrations/0015_alter_siteantenna_options_and_more.py +181 -0
  157. slm/migrations/0016_alter_antenna_description_alter_radome_description_and_more.py +42 -0
  158. slm/migrations/0017_alter_logentry_unique_together_and_more.py +54 -0
  159. slm/migrations/0018_afix_deleted.py +34 -0
  160. slm/migrations/0018_alter_siteantenna_options_and_more.py +244 -0
  161. slm/migrations/0019_remove_siteantenna_marker_enu_siteantenna_marker_une_and_more.py +101 -0
  162. slm/migrations/0020_alter_manufacturer_options.py +16 -0
  163. slm/migrations/0021_alter_siteform_report_type.py +23 -0
  164. slm/migrations/0022_rename_antcal_antenna_radome_slm_antcal_antenna_20827a_idx_and_more.py +297 -0
  165. slm/migrations/0023_archivedsitelog_gml_version_and_more.py +55 -0
  166. slm/migrations/0024_alter_agency_name_alter_agency_shortname.py +24 -0
  167. slm/migrations/0025_alter_archivedsitelog_log_format_and_more.py +61 -0
  168. slm/migrations/0026_alter_archivedsitelog_log_format_and_more.py +61 -0
  169. slm/migrations/0027_importalert_file_contents_importalert_findings_and_more.py +41 -0
  170. slm/migrations/0028_antenna_replaced_manufacturer_url_radome_replaced_and_more.py +46 -0
  171. slm/migrations/0029_manufacturer_full_name.py +17 -0
  172. slm/migrations/0030_alter_antenna_state_alter_radome_state_and_more.py +43 -0
  173. slm/migrations/__init__.py +0 -0
  174. slm/migrations/load_satellitesystems.py +27 -0
  175. slm/models/__init__.py +118 -0
  176. slm/models/about.py +14 -0
  177. slm/models/alerts.py +1204 -0
  178. slm/models/data.py +58 -0
  179. slm/models/equipment.py +229 -0
  180. slm/models/help.py +14 -0
  181. slm/models/index.py +428 -0
  182. slm/models/sitelog.py +4279 -0
  183. slm/models/system.py +723 -0
  184. slm/models/user.py +304 -0
  185. slm/parsing/__init__.py +786 -0
  186. slm/parsing/legacy/__init__.py +4 -0
  187. slm/parsing/legacy/binding.py +817 -0
  188. slm/parsing/legacy/parser.py +377 -0
  189. slm/parsing/xsd/__init__.py +34 -0
  190. slm/parsing/xsd/binding.py +86 -0
  191. slm/parsing/xsd/geodesyml/0.4/commonTypes.xsd +133 -0
  192. slm/parsing/xsd/geodesyml/0.4/contact.xsd +29 -0
  193. slm/parsing/xsd/geodesyml/0.4/dataStreams.xsd +129 -0
  194. slm/parsing/xsd/geodesyml/0.4/document.xsd +64 -0
  195. slm/parsing/xsd/geodesyml/0.4/equipment.xsd +427 -0
  196. slm/parsing/xsd/geodesyml/0.4/fieldMeasurement.xsd +170 -0
  197. slm/parsing/xsd/geodesyml/0.4/geodesyML.xsd +71 -0
  198. slm/parsing/xsd/geodesyml/0.4/geodeticEquipment.xsd +343 -0
  199. slm/parsing/xsd/geodesyml/0.4/geodeticMonument.xsd +147 -0
  200. slm/parsing/xsd/geodesyml/0.4/lineage.xsd +614 -0
  201. slm/parsing/xsd/geodesyml/0.4/localInterferences.xsd +131 -0
  202. slm/parsing/xsd/geodesyml/0.4/measurement.xsd +473 -0
  203. slm/parsing/xsd/geodesyml/0.4/monumentInfo.xsd +251 -0
  204. slm/parsing/xsd/geodesyml/0.4/observationSystem.xsd +429 -0
  205. slm/parsing/xsd/geodesyml/0.4/project.xsd +38 -0
  206. slm/parsing/xsd/geodesyml/0.4/quality.xsd +176 -0
  207. slm/parsing/xsd/geodesyml/0.4/referenceFrame.xsd +194 -0
  208. slm/parsing/xsd/geodesyml/0.4/siteLog.xsd +71 -0
  209. slm/parsing/xsd/geodesyml/0.5/commonTypes.xsd +133 -0
  210. slm/parsing/xsd/geodesyml/0.5/contact.xsd +29 -0
  211. slm/parsing/xsd/geodesyml/0.5/dataStreams.xsd +129 -0
  212. slm/parsing/xsd/geodesyml/0.5/document.xsd +64 -0
  213. slm/parsing/xsd/geodesyml/0.5/equipment.xsd +427 -0
  214. slm/parsing/xsd/geodesyml/0.5/fieldMeasurement.xsd +170 -0
  215. slm/parsing/xsd/geodesyml/0.5/geodesyML.xsd +71 -0
  216. slm/parsing/xsd/geodesyml/0.5/geodeticEquipment.xsd +343 -0
  217. slm/parsing/xsd/geodesyml/0.5/geodeticMonument.xsd +147 -0
  218. slm/parsing/xsd/geodesyml/0.5/lineage.xsd +614 -0
  219. slm/parsing/xsd/geodesyml/0.5/localInterferences.xsd +131 -0
  220. slm/parsing/xsd/geodesyml/0.5/measurement.xsd +473 -0
  221. slm/parsing/xsd/geodesyml/0.5/monumentInfo.xsd +306 -0
  222. slm/parsing/xsd/geodesyml/0.5/observationSystem.xsd +429 -0
  223. slm/parsing/xsd/geodesyml/0.5/project.xsd +38 -0
  224. slm/parsing/xsd/geodesyml/0.5/quality.xsd +176 -0
  225. slm/parsing/xsd/geodesyml/0.5/referenceFrame.xsd +194 -0
  226. slm/parsing/xsd/geodesyml/0.5/siteLog.xsd +73 -0
  227. slm/parsing/xsd/parser.py +116 -0
  228. slm/parsing/xsd/resolver.py +28 -0
  229. slm/receivers/__init__.py +11 -0
  230. slm/receivers/alerts.py +87 -0
  231. slm/receivers/cleanup.py +41 -0
  232. slm/receivers/event_loggers.py +175 -0
  233. slm/receivers/index.py +67 -0
  234. slm/settings/__init__.py +55 -0
  235. slm/settings/auth.py +15 -0
  236. slm/settings/ckeditor.py +14 -0
  237. slm/settings/debug.py +47 -0
  238. slm/settings/internationalization.py +12 -0
  239. slm/settings/logging.py +113 -0
  240. slm/settings/platform/__init__.py +0 -0
  241. slm/settings/platform/darwin.py +10 -0
  242. slm/settings/rest.py +21 -0
  243. slm/settings/root.py +152 -0
  244. slm/settings/routines.py +43 -0
  245. slm/settings/secrets.py +37 -0
  246. slm/settings/security.py +5 -0
  247. slm/settings/slm.py +188 -0
  248. slm/settings/static_templates.py +53 -0
  249. slm/settings/templates.py +29 -0
  250. slm/settings/uploads.py +8 -0
  251. slm/settings/urls.py +126 -0
  252. slm/settings/validation.py +196 -0
  253. slm/signals.py +250 -0
  254. slm/singleton.py +49 -0
  255. slm/static/rest_framework/css/bootstrap-tweaks.css +204 -0
  256. slm/static/rest_framework/css/bootstrap.min.css +7 -0
  257. slm/static/rest_framework/css/bootstrap.min.css.map +1 -0
  258. slm/static/rest_framework/css/default.css +82 -0
  259. slm/static/rest_framework/css/prettify.css +30 -0
  260. slm/static/rest_framework/docs/css/base.css +344 -0
  261. slm/static/rest_framework/docs/css/highlight.css +125 -0
  262. slm/static/rest_framework/docs/css/jquery.json-view.min.css +11 -0
  263. slm/static/rest_framework/docs/img/favicon.ico +0 -0
  264. slm/static/rest_framework/docs/img/grid.png +0 -0
  265. slm/static/rest_framework/docs/js/api.js +321 -0
  266. slm/static/rest_framework/docs/js/highlight.pack.js +2 -0
  267. slm/static/rest_framework/docs/js/jquery.json-view.min.js +7 -0
  268. slm/static/rest_framework/img/grid.png +0 -0
  269. slm/static/rest_framework/js/ajax-form.js +127 -0
  270. slm/static/rest_framework/js/bootstrap.bundle.min.js +7 -0
  271. slm/static/rest_framework/js/bootstrap.bundle.min.js.map +1 -0
  272. slm/static/rest_framework/js/bootstrap.min.js.map +1 -0
  273. slm/static/rest_framework/js/coreapi-0.1.1.js +2043 -0
  274. slm/static/rest_framework/js/csrf.js +52 -0
  275. slm/static/rest_framework/js/default.js +47 -0
  276. slm/static/rest_framework/js/jquery-3.5.1.min.js +2 -0
  277. slm/static/rest_framework/js/prettify-min.js +28 -0
  278. slm/static/slm/css/admin.css +3 -0
  279. slm/static/slm/css/defines.css +82 -0
  280. slm/static/slm/css/forms.css +1 -0
  281. slm/static/slm/css/style.css +1004 -0
  282. slm/static/slm/img/email-branding.png +0 -0
  283. slm/static/slm/img/favicon.ico +0 -0
  284. slm/static/slm/img/login-bg.jpg +0 -0
  285. slm/static/slm/img/slm-logo.svg +4 -0
  286. slm/static/slm/js/autocomplete.js +341 -0
  287. slm/static/slm/js/enums.js +322 -0
  288. slm/static/slm/js/fileIcons.js +30 -0
  289. slm/static/slm/js/form.js +404 -0
  290. slm/static/slm/js/formWidget.js +23 -0
  291. slm/static/slm/js/persistable.js +33 -0
  292. slm/static/slm/js/slm.js +1028 -0
  293. slm/static/slm/js/time24.js +212 -0
  294. slm/static_templates/slm/css/defines.css +26 -0
  295. slm/static_templates/slm/js/enums.js +28 -0
  296. slm/static_templates/slm/js/fileIcons.js +16 -0
  297. slm/static_templates/slm/js/urls.js +5 -0
  298. slm/templates/account/base.html +20 -0
  299. slm/templates/account/email/base.html +43 -0
  300. slm/templates/account/email/base_message.txt +7 -0
  301. slm/templates/account/email/email_confirmation_message.html +16 -0
  302. slm/templates/account/email/email_confirmation_message.txt +7 -0
  303. slm/templates/account/email/email_confirmation_signup_message.html +1 -0
  304. slm/templates/account/email/email_confirmation_signup_message.txt +1 -0
  305. slm/templates/account/email/email_confirmation_signup_subject.txt +1 -0
  306. slm/templates/account/email/email_confirmation_subject.txt +4 -0
  307. slm/templates/account/email/password_reset_key_message.html +28 -0
  308. slm/templates/account/email/password_reset_key_message.txt +9 -0
  309. slm/templates/account/email/password_reset_key_subject.txt +4 -0
  310. slm/templates/account/email/unknown_account_message.html +25 -0
  311. slm/templates/account/email/unknown_account_message.txt +12 -0
  312. slm/templates/account/email/unknown_account_subject.txt +4 -0
  313. slm/templates/account/login.html +67 -0
  314. slm/templates/account/logout.html +38 -0
  315. slm/templates/account/password_change.html +48 -0
  316. slm/templates/account/password_reset.html +51 -0
  317. slm/templates/account/password_reset_done.html +20 -0
  318. slm/templates/account/password_reset_from_key.html +52 -0
  319. slm/templates/account/password_reset_from_key_done.html +17 -0
  320. slm/templates/admin/base.html +7 -0
  321. slm/templates/messages.html +8 -0
  322. slm/templates/rest_framework/README +16 -0
  323. slm/templates/rest_framework/admin/detail.html +10 -0
  324. slm/templates/rest_framework/admin/dict_value.html +11 -0
  325. slm/templates/rest_framework/admin/list.html +32 -0
  326. slm/templates/rest_framework/admin/list_value.html +11 -0
  327. slm/templates/rest_framework/admin/simple_list_value.html +2 -0
  328. slm/templates/rest_framework/admin.html +282 -0
  329. slm/templates/rest_framework/api.html +3 -0
  330. slm/templates/rest_framework/base.html +334 -0
  331. slm/templates/rest_framework/docs/auth/basic.html +42 -0
  332. slm/templates/rest_framework/docs/auth/session.html +40 -0
  333. slm/templates/rest_framework/docs/auth/token.html +41 -0
  334. slm/templates/rest_framework/docs/document.html +37 -0
  335. slm/templates/rest_framework/docs/error.html +71 -0
  336. slm/templates/rest_framework/docs/index.html +55 -0
  337. slm/templates/rest_framework/docs/interact.html +57 -0
  338. slm/templates/rest_framework/docs/langs/javascript-intro.html +5 -0
  339. slm/templates/rest_framework/docs/langs/javascript.html +15 -0
  340. slm/templates/rest_framework/docs/langs/python-intro.html +3 -0
  341. slm/templates/rest_framework/docs/langs/python.html +13 -0
  342. slm/templates/rest_framework/docs/langs/shell-intro.html +3 -0
  343. slm/templates/rest_framework/docs/langs/shell.html +6 -0
  344. slm/templates/rest_framework/docs/link.html +113 -0
  345. slm/templates/rest_framework/docs/sidebar.html +78 -0
  346. slm/templates/rest_framework/filters/base.html +16 -0
  347. slm/templates/rest_framework/filters/ordering.html +17 -0
  348. slm/templates/rest_framework/filters/search.html +13 -0
  349. slm/templates/rest_framework/horizontal/checkbox.html +23 -0
  350. slm/templates/rest_framework/horizontal/checkbox_multiple.html +32 -0
  351. slm/templates/rest_framework/horizontal/dict_field.html +11 -0
  352. slm/templates/rest_framework/horizontal/fieldset.html +16 -0
  353. slm/templates/rest_framework/horizontal/form.html +6 -0
  354. slm/templates/rest_framework/horizontal/input.html +21 -0
  355. slm/templates/rest_framework/horizontal/list_field.html +11 -0
  356. slm/templates/rest_framework/horizontal/list_fieldset.html +13 -0
  357. slm/templates/rest_framework/horizontal/radio.html +42 -0
  358. slm/templates/rest_framework/horizontal/select.html +36 -0
  359. slm/templates/rest_framework/horizontal/select_multiple.html +38 -0
  360. slm/templates/rest_framework/horizontal/textarea.html +21 -0
  361. slm/templates/rest_framework/inline/checkbox.html +8 -0
  362. slm/templates/rest_framework/inline/checkbox_multiple.html +14 -0
  363. slm/templates/rest_framework/inline/dict_field.html +9 -0
  364. slm/templates/rest_framework/inline/fieldset.html +6 -0
  365. slm/templates/rest_framework/inline/form.html +8 -0
  366. slm/templates/rest_framework/inline/input.html +9 -0
  367. slm/templates/rest_framework/inline/list_field.html +9 -0
  368. slm/templates/rest_framework/inline/list_fieldset.html +3 -0
  369. slm/templates/rest_framework/inline/radio.html +25 -0
  370. slm/templates/rest_framework/inline/select.html +24 -0
  371. slm/templates/rest_framework/inline/select_multiple.html +25 -0
  372. slm/templates/rest_framework/inline/textarea.html +9 -0
  373. slm/templates/rest_framework/login.html +3 -0
  374. slm/templates/rest_framework/login_base.html +65 -0
  375. slm/templates/rest_framework/pagination/numbers.html +47 -0
  376. slm/templates/rest_framework/pagination/previous_and_next.html +21 -0
  377. slm/templates/rest_framework/raw_data_form.html +11 -0
  378. slm/templates/rest_framework/schema.js +3 -0
  379. slm/templates/rest_framework/vertical/checkbox.html +16 -0
  380. slm/templates/rest_framework/vertical/checkbox_multiple.html +30 -0
  381. slm/templates/rest_framework/vertical/dict_field.html +7 -0
  382. slm/templates/rest_framework/vertical/fieldset.html +13 -0
  383. slm/templates/rest_framework/vertical/form.html +6 -0
  384. slm/templates/rest_framework/vertical/input.html +17 -0
  385. slm/templates/rest_framework/vertical/list_field.html +7 -0
  386. slm/templates/rest_framework/vertical/list_fieldset.html +7 -0
  387. slm/templates/rest_framework/vertical/radio.html +40 -0
  388. slm/templates/rest_framework/vertical/select.html +34 -0
  389. slm/templates/rest_framework/vertical/select_multiple.html +31 -0
  390. slm/templates/rest_framework/vertical/textarea.html +17 -0
  391. slm/templates/slm/about.html +21 -0
  392. slm/templates/slm/alerts/alert.html +15 -0
  393. slm/templates/slm/alerts/geodesymlinvalid.html +8 -0
  394. slm/templates/slm/alerts/importalert.html +10 -0
  395. slm/templates/slm/alerts.html +18 -0
  396. slm/templates/slm/auth_menu.html +41 -0
  397. slm/templates/slm/base.html +195 -0
  398. slm/templates/slm/emails/alert_issued.html +31 -0
  399. slm/templates/slm/emails/alert_issued.txt +9 -0
  400. slm/templates/slm/emails/base.html +6 -0
  401. slm/templates/slm/emails/changes_rejected.txt +7 -0
  402. slm/templates/slm/emails/review_requested.txt +7 -0
  403. slm/templates/slm/forms/widgets/auto_complete.html +21 -0
  404. slm/templates/slm/forms/widgets/auto_complete_multiple.html +18 -0
  405. slm/templates/slm/forms/widgets/checkbox_multiple.html +6 -0
  406. slm/templates/slm/forms/widgets/inline_multi.html +1 -0
  407. slm/templates/slm/forms/widgets/splitdatetime.html +14 -0
  408. slm/templates/slm/forms/widgets/time24.html +37 -0
  409. slm/templates/slm/help.html +54 -0
  410. slm/templates/slm/messages.html +13 -0
  411. slm/templates/slm/new_site.html +88 -0
  412. slm/templates/slm/profile.html +57 -0
  413. slm/templates/slm/register.html +40 -0
  414. slm/templates/slm/reports/file_log.html +43 -0
  415. slm/templates/slm/reports/head_log.html +23 -0
  416. slm/templates/slm/reports/head_report.html +55 -0
  417. slm/templates/slm/reports/index_log.html +23 -0
  418. slm/templates/slm/reports/index_report.html +71 -0
  419. slm/templates/slm/station/alert.html +8 -0
  420. slm/templates/slm/station/alerts.html +19 -0
  421. slm/templates/slm/station/base.html +104 -0
  422. slm/templates/slm/station/download.html +87 -0
  423. slm/templates/slm/station/edit.html +283 -0
  424. slm/templates/slm/station/form.html +110 -0
  425. slm/templates/slm/station/log.html +18 -0
  426. slm/templates/slm/station/review.html +461 -0
  427. slm/templates/slm/station/upload.html +295 -0
  428. slm/templates/slm/station/uploads/attachment.html +20 -0
  429. slm/templates/slm/station/uploads/geodesyml.html +1 -0
  430. slm/templates/slm/station/uploads/image.html +27 -0
  431. slm/templates/slm/station/uploads/json.html +0 -0
  432. slm/templates/slm/station/uploads/legacy.html +77 -0
  433. slm/templates/slm/top_nav.html +14 -0
  434. slm/templates/slm/user_activity.html +16 -0
  435. slm/templates/slm/widgets/alert_scroll.html +135 -0
  436. slm/templates/slm/widgets/filelist.html +258 -0
  437. slm/templates/slm/widgets/legend.html +12 -0
  438. slm/templates/slm/widgets/log_scroll.html +88 -0
  439. slm/templates/slm/widgets/stationlist.html +233 -0
  440. slm/templatetags/__init__.py +0 -0
  441. slm/templatetags/jinja2.py +9 -0
  442. slm/templatetags/slm.py +459 -0
  443. slm/urls.py +148 -0
  444. slm/utils.py +299 -0
  445. slm/validators.py +297 -0
  446. slm/views.py +654 -0
  447. slm/widgets.py +134 -0
@@ -0,0 +1,459 @@
1
+ import json
2
+ import os
3
+ from datetime import datetime, timezone
4
+ from enum import Enum
5
+ from html import unescape
6
+ from typing import Iterable
7
+
8
+ from chardet import detect
9
+ from django import template
10
+ from django.conf import settings
11
+ from django.urls import resolve
12
+ from django.utils.translation import gettext as _
13
+
14
+ from slm.utils import build_absolute_url, decimal_to_dddmmssss, to_snake_case
15
+
16
+ register = template.Library()
17
+
18
+
19
+ @register.filter(name="pad_diff")
20
+ def pad_diff(int1, int2):
21
+ return " " * (int(int1) - int(int2))
22
+
23
+
24
+ @register.filter(name="div")
25
+ def div(numerator, denominator):
26
+ if denominator == 0:
27
+ return None
28
+ return numerator / denominator
29
+
30
+
31
+ @register.filter(name="section_name")
32
+ def section_name(form):
33
+ return form.section_name()
34
+
35
+
36
+ @register.filter(name="to_snake")
37
+ def to_snake(string):
38
+ return to_snake_case(string)
39
+
40
+
41
+ @register.filter(name="arg")
42
+ def arg(arg1, arg2):
43
+ if isinstance(arg1, list):
44
+ return arg1 + [arg2]
45
+ return [arg1, arg2]
46
+
47
+
48
+ @register.filter(name="to_id")
49
+ def to_id(arg1, arg2):
50
+ if not isinstance(arg1, list):
51
+ arg1 = [arg1]
52
+ return "-".join([to_snake_case(str(arg)) for arg in arg1 + [arg2] if arg])
53
+
54
+
55
+ @register.filter(name="key_value")
56
+ def key_value(dictionary, key):
57
+ return dictionary.get(key, None)
58
+
59
+
60
+ @register.filter(name="value_filter")
61
+ def value_filter(value):
62
+ if value is None:
63
+ return _("empty")
64
+ str_val = str(value)
65
+ if str_val is None or value == "":
66
+ return _("empty")
67
+ return str_val
68
+
69
+
70
+ @register.filter(name="strip_ms")
71
+ def strip_ms(timestamp):
72
+ if isinstance(timestamp, datetime):
73
+ timestamp = timestamp.isoformat()
74
+ return ":".join(timestamp.split(":")[0:2])
75
+
76
+
77
+ @register.filter(name="help_text")
78
+ def help_text(model, field):
79
+ return model._meta.get_field(field).help_text
80
+
81
+
82
+ @register.filter(name="simple_utc")
83
+ def simple_utc(datetime_field):
84
+ """
85
+ Return a datetime string in UTC, in the format YYYY-MM-DD HH:MM
86
+
87
+ :param datetime_field: A datetime object
88
+ :return: formatted datetime string
89
+ """
90
+ if datetime_field:
91
+ if isinstance(datetime_field, datetime):
92
+ return datetime_field.astimezone(timezone.utc).strftime("%Y-%m-%d %H:%M")
93
+ return datetime_field.strftime("%Y-%m-%d")
94
+ return ""
95
+
96
+
97
+ @register.filter(name="iso_utc")
98
+ def iso_utc(datetime_field):
99
+ if datetime_field:
100
+ return datetime_field.astimezone(timezone.utc).strftime("%Y-%m-%dT%H:%MZ")
101
+ return ""
102
+
103
+
104
+ @register.filter(name="iso_utc_full")
105
+ def iso_utc_full(datetime_field):
106
+ if datetime_field:
107
+ return datetime_field.astimezone(timezone.utc).strftime("%Y-%m-%dT%H:%M:%SZ")
108
+ return ""
109
+
110
+
111
+ @register.filter(name="multi_line")
112
+ def multi_line(text):
113
+ if text:
114
+ limit = 47
115
+ lines = [line.rstrip() for line in text.split("\n")]
116
+ limited = []
117
+ for line in lines:
118
+ while len(line) > limit:
119
+ mark = limit
120
+
121
+ # only chop on white space if we can
122
+ for ridx, char in enumerate(reversed(line[0:limit])):
123
+ if not char.strip():
124
+ mark = limit - ridx
125
+ break
126
+
127
+ limited.append(unescape(line[0:mark]))
128
+ line = line[mark:]
129
+ limited.append(unescape(line))
130
+ return f'\n{" "*30}: '.join([line for line in limited if line.strip()])
131
+ return ""
132
+
133
+
134
+ @register.filter(name="iso6709")
135
+ def iso6709(decimal_degrees, padding):
136
+ if decimal_degrees:
137
+ dddmmssss = decimal_to_dddmmssss(decimal_degrees)
138
+ number = f"{dddmmssss:.2f}"
139
+ integer, dec = number.split(".") if "." in number else (number, None)
140
+ iso_frmt = f"{abs(int(integer)):0{int(padding)}}{'.' if dec else ''}{dec}"
141
+ return f'{"+" if float(dddmmssss) > 0 else "-"}{iso_frmt}'
142
+ return ""
143
+
144
+
145
+ @register.filter(name="epsg7912")
146
+ def epsg7912(lat_lng, prec=10):
147
+ return precision(lat_lng, prec)
148
+
149
+
150
+ @register.filter(name="precision")
151
+ def precision(number, prec):
152
+ if number or number == 0:
153
+ return f"{number:.{prec}f}".rstrip("0").rstrip(".")
154
+ return ""
155
+
156
+
157
+ @register.filter(name="precision_full")
158
+ def precision_full(alt, prec):
159
+ if alt or alt == 0:
160
+ return f"{alt:.{prec}f}"
161
+ return ""
162
+
163
+
164
+ @register.filter(name="pos")
165
+ def pos(number):
166
+ if number or number == 0:
167
+ if float(number) > 0:
168
+ return f"+{number}"
169
+ return number
170
+ return ""
171
+
172
+
173
+ @register.filter(name="none2empty")
174
+ def none2empty(number, suffix=""):
175
+ if number or number == 0:
176
+ return f"{number}{suffix}"
177
+ return ""
178
+
179
+
180
+ @register.filter(name="enum_str")
181
+ def enum_str(value):
182
+ if value is None:
183
+ return ""
184
+ if isinstance(value, Enum):
185
+ return value.label
186
+ return value
187
+
188
+
189
+ @register.filter(name="satellite_str")
190
+ def satellite_str(satellite_systems):
191
+ if satellite_systems:
192
+ return "+".join([system.name for system in satellite_systems.all()])
193
+ return ""
194
+
195
+
196
+ @register.filter(name="inspect")
197
+ def inspect(obj):
198
+ from pprint import pprint
199
+
200
+ pprint(f"{obj}:")
201
+ pprint(dir(obj))
202
+
203
+
204
+ @register.filter(name="get_key")
205
+ def get_key(obj, key):
206
+ return obj.get(key)
207
+
208
+
209
+ @register.filter(name="has_key")
210
+ def has_key(obj, key):
211
+ try:
212
+ return key in obj
213
+ except TypeError:
214
+ return hasattr(obj, key)
215
+
216
+
217
+ @register.filter(name="merge")
218
+ def merge(obj1, obj2):
219
+ return obj1.merge(obj2)
220
+
221
+
222
+ @register.filter(name="antenna_radome")
223
+ def antenna_radome(antenna):
224
+ spacing = max(abs(16 - len(antenna.antenna_type.model)), 1)
225
+ radome = "NONE"
226
+ if hasattr(antenna, "radome_type"):
227
+ radome = antenna.radome_type.model
228
+ return f'{antenna.antenna_type.model}{" " * spacing}{radome}'
229
+
230
+
231
+ @register.filter(name="antenna_codelist")
232
+ def antenna_codelist(antenna):
233
+ radome = "NONE"
234
+ if hasattr(antenna, "radome_type"):
235
+ radome = antenna.radome_type.model
236
+ return f"{antenna.antenna_type.model} {radome}"
237
+
238
+
239
+ @register.filter(name="rpad_space")
240
+ def rpad_space(text, length):
241
+ return f'{text}{" " * (int(length) - len(str(text)))}'
242
+
243
+
244
+ @register.filter(name="file_icon")
245
+ def file_icon(file):
246
+ subtype = ""
247
+ if file:
248
+ subtype = getattr(
249
+ file, "mimetype", file if isinstance(file, str) else ""
250
+ ).split("/")[-1]
251
+ return getattr(settings, "SLM_FILE_ICONS", {}).get(subtype, "bi bi-file-earmark")
252
+
253
+
254
+ @register.filter(name="file_lines")
255
+ def file_lines(file):
256
+ if isinstance(file, str):
257
+ return file.split("\n")
258
+ if file and os.path.exists(file.file.path):
259
+ content = file.file.open().read()
260
+ try:
261
+ return content.decode(detect(content).get("encoding", "utf-8")).split("\n")
262
+ except (UnicodeDecodeError, LookupError, ValueError):
263
+ return [
264
+ _(
265
+ "** Unable to determine text encoding - please upload as "
266
+ "UTF-8. **"
267
+ )
268
+ ]
269
+ return [""]
270
+
271
+
272
+ @register.filter(name="finding_class")
273
+ def finding_class(findings, line_number):
274
+ # in json keys can't be integers and our findings context might be integers
275
+ # or strings if its gone through a json cycle so we try both
276
+ if findings:
277
+ return {
278
+ "E": "slm-parse-error",
279
+ "W": "slm-parse-warning",
280
+ "I": "slm-parse-ignore",
281
+ }.get(findings.get(str(line_number), findings.get(int(line_number), [""]))[0])
282
+ return ""
283
+
284
+
285
+ @register.filter(name="finding_content")
286
+ def finding_content(findings, line_number):
287
+ if findings:
288
+ return findings.get(
289
+ str(line_number), findings.get(int(line_number), [None, ""])
290
+ )[1]
291
+ return ""
292
+
293
+
294
+ @register.filter(name="finding_title")
295
+ def finding_title(findings, line_number):
296
+ if findings:
297
+ return {"E": "Error", "W": "Warning", "I": "Ignored"}.get(
298
+ findings.get(str(line_number), findings.get(int(line_number), [""]))[0]
299
+ )
300
+ return ""
301
+
302
+
303
+ @register.filter(name="split_rows")
304
+ def split_rows(iterable, row_length):
305
+ rows = []
306
+ row = []
307
+ for idx, item in enumerate(iterable):
308
+ row.append(item)
309
+ if idx + 1 % row_length == 0:
310
+ rows.append(row)
311
+ row = []
312
+ if row:
313
+ rows.append(row)
314
+ return rows
315
+
316
+
317
+ @register.filter(name="rstrip")
318
+ def rstrip(to_strip, characters):
319
+ if to_strip:
320
+ return to_strip.rstrip(characters)
321
+ return to_strip
322
+
323
+
324
+ @register.filter(name="lstrip")
325
+ def lstrip(to_strip, characters):
326
+ if to_strip:
327
+ return to_strip.lstrip(characters)
328
+ return to_strip
329
+
330
+
331
+ @register.filter(name="absolute_url")
332
+ def absolute_url(path, request=None):
333
+ return build_absolute_url(path, request=request)
334
+
335
+
336
+ @register.filter(name="file_url")
337
+ def file_url(path, request=None):
338
+ file_domain = getattr(settings, "SLM_FILE_DOMAIN", None)
339
+ if file_domain:
340
+ return f'{file_domain.rstrip("/")}/{path.lstrip("/")}'
341
+ return absolute_url(path, request=request)
342
+
343
+
344
+ @register.filter(name="contact")
345
+ def contact(agency, ctype):
346
+ return {
347
+ field: getattr(agency, f"{ctype}_{field}")
348
+ for field in ["name", "phone1", "phone2", "fax", "email"]
349
+ if getattr(agency, f"{ctype}_{field}", None)
350
+ }
351
+
352
+
353
+ @register.filter(name="format_temp_stab")
354
+ def format_temp_stab(temp, temp_stab):
355
+ temp = precision(temp, 1)
356
+ temp_stab = precision(temp_stab, 1)
357
+ if temp and temp_stab:
358
+ return f"{temp} +/- {temp_stab} C"
359
+ elif temp:
360
+ return f"{temp} C"
361
+ elif temp_stab:
362
+ return f"+/- {temp_stab} C"
363
+ return ""
364
+
365
+
366
+ @register.filter(name="class_name")
367
+ def class_name(cls):
368
+ if isinstance(cls, type):
369
+ return cls.__name__
370
+ return cls.__class__.__name__
371
+
372
+
373
+ @register.filter(name="model_meta")
374
+ def model_meta(cls, parameter):
375
+ return getattr(cls._meta, parameter)
376
+
377
+
378
+ @register.filter(name="params")
379
+ def params(iterable, parameter):
380
+ return (getattr(obj, parameter) for obj in iterable)
381
+
382
+
383
+ @register.filter(name="section_field_classes")
384
+ def section_field_classes(field, form):
385
+ classes = [
386
+ {"checkbox": ""}.get( #'form-check-input'
387
+ getattr(field.field.widget, "input_type", None), "form-control"
388
+ )
389
+ ]
390
+ if form.flags.get(field.name, None):
391
+ classes.append("is-invalid")
392
+ elif form.diff.get(field.name, None):
393
+ classes.append("is-invalid")
394
+ classes.append("slm-form-unpublished")
395
+ return " ".join(classes)
396
+
397
+
398
+ @register.filter(name="alert_class")
399
+ def alert_class(message):
400
+ """Get the css class for a Django message"""
401
+ return {"error": "danger", "debug": "secondary", "info": "primary"}.get(
402
+ message.level_tag, message.level_tag
403
+ )
404
+
405
+
406
+ @register.filter(name="autocomplete_values")
407
+ def autocomplete_values(widget):
408
+ """
409
+ Return a list of json strings representing the default values of
410
+ autocomplete fields -see forms. We have to do some snooping around the api
411
+ and call the serializer directly.
412
+ """
413
+ values = widget.get("value", None)
414
+ if "optgroups" in widget:
415
+ values = []
416
+ for _, choices, _ in widget.get("optgroups"):
417
+ values.extend([str(choice["value"]) for choice in choices])
418
+
419
+ items = []
420
+ if values:
421
+ if isinstance(values, str) or not isinstance(values, Iterable):
422
+ values = [values]
423
+
424
+ service_url = widget.get("attrs", {}).get("data-service-url")
425
+
426
+ value_map = {
427
+ item["value"]: item
428
+ for item in json.loads(
429
+ str(widget.get("attrs", {}).get("data-source", "[]"))
430
+ )
431
+ }
432
+ if value_map:
433
+ for value in values:
434
+ if value in value_map:
435
+ items.append(json.dumps(value_map[value]))
436
+
437
+ elif service_url:
438
+ view, _, _ = resolve(service_url)
439
+ Serializer = view.cls.serializer_class
440
+ field = widget.get("attrs", {}).get("data-value-param", "pk")
441
+ serializer = Serializer(
442
+ Serializer.Meta.model.objects.filter(**{f"{field}__in": values}),
443
+ many=True,
444
+ )
445
+ for value in serializer.data:
446
+ items.append(json.dumps(value))
447
+
448
+ return items
449
+
450
+
451
+ @register.simple_tag(takes_context=True)
452
+ def set_global(context, name, val):
453
+ context.render_context[name] = val
454
+ return ""
455
+
456
+
457
+ @register.simple_tag(takes_context=True)
458
+ def get_global(context, name):
459
+ return context.render_context.get(name, None)
slm/urls.py ADDED
@@ -0,0 +1,148 @@
1
+ from datetime import datetime
2
+
3
+ from django.urls import path, register_converter
4
+
5
+ from slm.api.edit import views as edit_views
6
+ from slm.api.public import views as public_views
7
+ from slm.views import (
8
+ AboutView,
9
+ AlertsView,
10
+ AlertView,
11
+ DownloadView,
12
+ EditView,
13
+ HelpView,
14
+ IndexView,
15
+ LogView,
16
+ NewSiteView,
17
+ StationAlertsView,
18
+ StationReviewView,
19
+ UploadView,
20
+ UserActivityLogView,
21
+ UserProfileView,
22
+ )
23
+
24
+ SLM_INCLUDE = True
25
+
26
+ APIS = {
27
+ "edit": [
28
+ ("stations", edit_views.StationListViewSet),
29
+ ("profile", edit_views.UserProfileViewSet),
30
+ ("download", edit_views.SiteLogDownloadViewSet),
31
+ ("files/(?P<site>[^/.]+)", edit_views.SiteFileUploadViewSet, "files"),
32
+ ("siteform", edit_views.SiteFormViewSet),
33
+ ("siteidentification", edit_views.SiteIdentificationViewSet),
34
+ ("sitelocation", edit_views.SiteLocationViewSet),
35
+ ("sitereceiver", edit_views.SiteReceiverViewSet),
36
+ ("siteantenna", edit_views.SiteAntennaViewSet),
37
+ ("sitesurveyedlocalties", edit_views.SiteSurveyedLocalTiesViewSet),
38
+ ("sitefrequencystandard", edit_views.SiteFrequencyStandardViewSet),
39
+ ("sitecollocation", edit_views.SiteCollocationViewSet),
40
+ ("sitehumiditysensor", edit_views.SiteHumiditySensorViewSet),
41
+ ("sitepressuresensor", edit_views.SitePressureSensorViewSet),
42
+ ("sitetemperaturesensor", edit_views.SiteTemperatureSensorViewSet),
43
+ ("sitewatervaporradiometer", edit_views.SiteWaterVaporRadiometerViewSet),
44
+ ("siteotherinstrumentation", edit_views.SiteOtherInstrumentationViewSet),
45
+ ("siteradiointerferences", edit_views.SiteRadioInterferencesViewSet),
46
+ ("sitemultipathsources", edit_views.SiteMultiPathSourcesViewSet),
47
+ ("sitesignalobstructions", edit_views.SiteSignalObstructionsViewSet),
48
+ ("sitelocalepisodiceffects", edit_views.SiteLocalEpisodicEffectsViewSet),
49
+ ("siteoperationalcontact", edit_views.SiteOperationalContactViewSet),
50
+ ("siteresponsibleagency", edit_views.SiteResponsibleAgencyViewSet),
51
+ ("sitemoreinformation", edit_views.SiteMoreInformationViewSet),
52
+ ("logentries", edit_views.LogEntryViewSet),
53
+ ("alerts", edit_views.AlertViewSet),
54
+ ("request_review", edit_views.ReviewRequestView),
55
+ ("reject_updates", edit_views.RejectUpdatesView),
56
+ ("agency", edit_views.AgencyViewSet),
57
+ ("network", edit_views.NetworkViewSet),
58
+ ("image", edit_views.ImageOperationsViewSet),
59
+ ],
60
+ "public": [
61
+ ("stations", public_views.StationListViewSet),
62
+ ("name", public_views.StationNameViewSet),
63
+ ("receiver", public_views.ReceiverViewSet),
64
+ ("antenna", public_views.AntennaViewSet),
65
+ ("radome", public_views.RadomeViewSet),
66
+ ("manufacturer", public_views.ManufacturerViewSet),
67
+ ("download", public_views.SiteLogDownloadViewSet),
68
+ ("files", public_views.SiteFileUploadViewSet),
69
+ ("archive", public_views.ArchiveViewSet),
70
+ ("agency", public_views.AgencyViewSet),
71
+ ("network", public_views.NetworkViewSet),
72
+ ],
73
+ }
74
+
75
+
76
+ class SiteLogFormatConverter:
77
+ regex = "(legacy)|(gml)"
78
+ placeholder = "legacy"
79
+
80
+ def to_python(self, value):
81
+ return value
82
+
83
+ def to_url(self, value):
84
+ return value
85
+
86
+
87
+ class StationConverter:
88
+ regex = "[0-9a-zA-Z]+"
89
+ placeholder = "AAAAAAAAA"
90
+
91
+ def to_python(self, value):
92
+ return value
93
+
94
+ def to_url(self, value):
95
+ return value
96
+
97
+
98
+ class DateTimeConverter:
99
+ regex = r"\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}[.]\d{3,6}"
100
+ placeholder = "2022-06-20T01:49:04.566687"
101
+
102
+ def to_python(self, value: str) -> datetime:
103
+ print(value)
104
+ return datetime.fromisoformat(value)
105
+
106
+ def to_url(self, value: datetime) -> str:
107
+ if isinstance(value, str):
108
+ return value
109
+ return value.isoformat()
110
+
111
+
112
+ register_converter(SiteLogFormatConverter, "format")
113
+ register_converter(StationConverter, "station")
114
+ register_converter(DateTimeConverter, "datetime")
115
+
116
+
117
+ app_name = "slm"
118
+
119
+ urlpatterns = [
120
+ path("", IndexView.as_view(), name="home"),
121
+ path("edit/<station:station>", EditView.as_view(), name="edit"),
122
+ path("edit/<station:station>/<str:section>", EditView.as_view(), name="edit"),
123
+ path("newsite/", NewSiteView.as_view(), name="new_site"),
124
+ path("profile/", UserProfileView.as_view(), name="profile"),
125
+ path("alerts/", AlertsView.as_view(), name="alerts"),
126
+ path("alerts/<station:station>", StationAlertsView.as_view(), name="alerts"),
127
+ path("upload/<station:station>", UploadView.as_view(), name="upload"),
128
+ path("upload/<station:station>/<int:file>", UploadView.as_view(), name="upload"),
129
+ path("download/<station:station>", DownloadView.as_view(), name="download"),
130
+ path("review/<station:station>", StationReviewView.as_view(), name="review"),
131
+ path(
132
+ "review/<station:station>/<datetime:epoch>",
133
+ StationReviewView.as_view(),
134
+ name="review",
135
+ ),
136
+ path("log/<station:station>", LogView.as_view(), name="log"),
137
+ path("about/", AboutView.as_view(), name="about"),
138
+ path("help/", HelpView.as_view(), name="help"),
139
+ path("activity/", UserActivityLogView.as_view(), name="user_activity"),
140
+ path(
141
+ "activity/<int:log_user>", UserActivityLogView.as_view(), name="user_activity"
142
+ ),
143
+ path(
144
+ "alert/<int:alert>",
145
+ AlertView.as_view(),
146
+ name="alert",
147
+ ),
148
+ ]