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,30 @@
1
+ if (typeof slm === 'undefined' || slm == null) { var slm = {}; }
2
+
3
+
4
+ slm.iconMap = {
5
+ 'zip': 'bi bi-file-zip',
6
+ 'x-tar': 'bi bi-file-zip',
7
+ 'plain': 'bi bi-filetype-txt',
8
+ 'jpeg': 'bi bi-filetype-jpg',
9
+ 'svg+xml': 'bi bi-filetype-svg',
10
+ 'xml': 'bi bi-filetype-xml',
11
+ 'json': 'bi bi-filetype-json',
12
+ 'png': 'bi bi-filetype-png',
13
+ 'tiff': 'bi bi-filetype-tiff',
14
+ 'pdf': 'bi bi-filetype-pdf',
15
+ 'gif': 'bi bi-filetype-gif',
16
+ 'csv': 'bi bi-filetype-csv',
17
+ 'bmp': 'bi bi-filetype-bmp',
18
+ 'vnd.openxmlformats-officedocument.wordprocessingml.document': 'bi bi-filetype-doc',
19
+ 'msword': 'bi bi-filetype-doc'
20
+ };
21
+
22
+ slm.fileIcon = function(mimetype) {
23
+ if (mimetype) {
24
+ let subtype = mimetype.substring(mimetype.indexOf('/') + 1);
25
+ if (slm.iconMap.hasOwnProperty(subtype)) {
26
+ return slm.iconMap[subtype];
27
+ }
28
+ }
29
+ return "bi bi-file-earmark";
30
+ };
@@ -0,0 +1,404 @@
1
+ import { Persistable } from "./persistable.js";
2
+
3
+ export class Form extends Persistable {
4
+ /**
5
+ * This class encapsulates reading and writing json data to/from html forms.
6
+ * This is less trivial than you might assume and there are some special case
7
+ * SLM field behavior (namely composition/decomposition) and custom input
8
+ * widgets that are handled.
9
+ */
10
+
11
+ element;
12
+ #initial; // the "clear" state of the form
13
+ fields;
14
+ widgets; // object keyed on field name where the values are widgets
15
+ last; // last serialized data
16
+
17
+ #multi;
18
+ #composite;
19
+
20
+ #changeCallbacks;
21
+
22
+ static ELEMENTS = ['input', 'select', 'textarea'];
23
+
24
+ static toBool = function(value) {
25
+ /**
26
+ * Convert a value to a boolean. Special string cases are handled.
27
+ */
28
+ if (typeof value === 'string' || value instanceof String) {
29
+ value = value.toLowerCase();
30
+ if (['yes', 'y', 'true', '1', 'on'].includes(value)) {
31
+ return true;
32
+ } else if (['no', 'n', 'false', '0', 'off'].includes(value)) {
33
+ return false;
34
+ }
35
+ else {
36
+ return null;
37
+ }
38
+ }
39
+ return Boolean(value);
40
+ }
41
+
42
+ static differs = function(state1, state2) {
43
+ /**
44
+ * Returns true if the given form states differ, false otherwise.
45
+ */
46
+ for (const [key, value] of Object.entries(state1)) {
47
+ if (state2.hasOwnProperty(key)) {
48
+ if (Array.isArray(value)) {
49
+ if (
50
+ Array.isArray(state2[key]) &&
51
+ value.length === state2[key].length
52
+ ) {
53
+ for (let idx = 0; idx < value.length; idx++) {
54
+ if (value[idx] !== state2[key][idx]) {
55
+ return true;
56
+ }
57
+ }
58
+ } else {
59
+ return true;
60
+ }
61
+ } else if (
62
+ Array.isArray(state2[key]) ||
63
+ value !== state2[key]
64
+ ) { return true; }
65
+ }
66
+ }
67
+ return false;
68
+ }
69
+
70
+ static stripNulls = function(data) {
71
+ /**
72
+ * Strip empty arrays and values from the query data.
73
+ * @type {{}}
74
+ */
75
+ const stripped = {};
76
+ for (const [key, value] of Object.entries(data)) {
77
+ if (value) { stripped[key] = value;}
78
+ }
79
+ return stripped;
80
+ }
81
+
82
+ static toQueryString = function(data) {
83
+ /**
84
+ * Convert query data to a url query string. No ? will be added
85
+ * to the front. This will strip nulls.
86
+ */
87
+ const params = [];
88
+ for (const [key, value] of Object.entries(data)) {
89
+ if (value) {
90
+ params.push(`${key}=${value}`);
91
+ }
92
+ }
93
+ return params.join('&');
94
+ }
95
+
96
+ get excluded() {
97
+ /** fields excluded from persistence */
98
+ return ['csrfmiddlewaretoken'];
99
+ }
100
+
101
+ get initial() {
102
+ /**
103
+ * Returns a copy of the initial form settings (i.e. the "clear" state
104
+ * of the form.
105
+ */
106
+ return JSON.parse(JSON.stringify(this.#initial));
107
+ }
108
+
109
+ set initial(initial) {
110
+ /**
111
+ * Set the initial (i.e. clear) state of the form - some fields may
112
+ * have default values.
113
+ *
114
+ * The initial state of each field is determined in order of precedence
115
+ * by:
116
+ *
117
+ * 1) The value defined for the field in data-slm-initial on the form
118
+ * element.
119
+ * 2) The current value of the form on initialization for any excluded
120
+ * fields.
121
+ * 3) The default (see default()) value for field type.
122
+ */
123
+ this.#initial = initial;
124
+ if (this.excluded.length > 0) {
125
+ const data = this.data;
126
+ for (const field of this.excluded) {
127
+ if (this.fields.has(field)) {
128
+ this.#initial[field] = data[field];
129
+ }
130
+ }
131
+ }
132
+ for (const field of this.fields) {
133
+ if (!this.#initial.hasOwnProperty(field)) {
134
+ this.#initial[field] = this.default(field);
135
+ }
136
+ }
137
+ }
138
+
139
+ get data() {
140
+ /**
141
+ * Get the JSON representing the form.
142
+ *
143
+ * If multiple input elements exist with the same name and different
144
+ * types, that is considered a composite field. It will be combined
145
+ * into a single field using compose. The reverse operation is
146
+ * decompose.
147
+ *
148
+ * Multiple input elements that exist with the same name and the same
149
+ * type will be turned into arrays where the array elements are the
150
+ * values of the activated elements (checkboxes and selects).
151
+ *
152
+ */
153
+ const data = {};
154
+
155
+ const coerceValue = function(fieldName, value) {
156
+ if (!this.isMulti(fieldName) && this.type(fieldName) === 'checkbox') {
157
+ return Form.toBool(value);
158
+ }
159
+ return value;
160
+ }.bind(this);
161
+
162
+ // flatten name/value objects into name: value or name: array[values]
163
+ for (const field of this.element.serializeArray()) {
164
+ let value = coerceValue(field.name, field.value);
165
+ if (this.isMulti(field.name)) {
166
+ if (Array.isArray(data[field.name])) {
167
+ data[field.name].push(value);
168
+ } else {
169
+ data[field.name] = [value];
170
+ }
171
+ } else {
172
+ data[field.name] = value;
173
+ }
174
+ }
175
+
176
+ // compose any composite fields
177
+ for (const [field, value] of Object.entries(data)) {
178
+ if (this.isComposite(field)) {
179
+ data[field] = this.compose(this.type(field), value);
180
+ }
181
+ }
182
+
183
+ for (const field of this.fields) {
184
+ if (!data.hasOwnProperty(field)) {
185
+ data[field] = this.default(field);
186
+ }
187
+ }
188
+
189
+ return data;
190
+ }
191
+
192
+ set data(data) {
193
+ /**
194
+ * Populates a form from the given json object. Keys should correspond
195
+ * to element names. Values are either singular or are arrays. Array
196
+ * values are expected to correspond to the value attributes of select
197
+ * options or checkboxes.
198
+ *
199
+ * If a form has multiple fields of different types with the same name
200
+ * that field value is decomposed using decompose() into a value for
201
+ * each input element.
202
+ *
203
+ * @type {any}
204
+ */
205
+
206
+ // form updates must be total - any missing fields will be defaulted
207
+ data = Object.assign(this.initial, data);
208
+
209
+ const setField = function(ipt, value) {
210
+ switch (ipt.prop('type')) {
211
+ case 'radio':
212
+ case 'checkbox':
213
+ ipt.each(function () {
214
+ $(this).prop('checked', Form.toBool(value));
215
+ });
216
+ break;
217
+ default:
218
+ ipt.val(value);
219
+ }
220
+ }
221
+
222
+ $.each(data, function (field, value) {
223
+ const ipt = this.field(field);
224
+ if (Array.isArray(value)) {
225
+ switch (ipt.prop('type')) {
226
+ case 'select': case 'select-multiple':
227
+ const selected = [];
228
+ for (const val of value) { selected.push(`option[value="${val}"]`); }
229
+ ipt.find(selected.join(', ')).prop('selected', true);
230
+ ipt.find('option').not(selected).prop('selected', false);
231
+ break;
232
+ case 'checkbox':
233
+ let checked = [];
234
+ for (const val of value) { checked.push(`[name="${field}"][value="${val}"]:checkbox`); }
235
+ checked = this.element.find(checked.join(', '));
236
+ checked.prop('checked', true);
237
+ this.element.find(`[name="${field}"]:checkbox`).not(checked).prop('checked', false);
238
+ break;
239
+ default:
240
+ if (ipt.length > 0) {
241
+ throw TypeError(`Array given for form data type: ${ipt.prop('type')}`);
242
+ }
243
+ }
244
+ } else if (ipt.length > 1) {
245
+ const types = [];
246
+ ipt.each(function () { types.push($(this).prop('type')); });
247
+ const values = this.decompose(types, value);
248
+ ipt.map((e, i) => { setField(e, values[i]); });
249
+ } else { setField(ipt, value); }
250
+ }.bind(this));
251
+
252
+ for (const widget of Object.values(this.widgets)) {
253
+ widget.changed();
254
+ }
255
+ }
256
+
257
+ constructor(element) {
258
+ super(element);
259
+ this.element = element;
260
+ this.#composite = {};
261
+ this.#multi = new Set();
262
+ this.#changeCallbacks = [];
263
+ this.widgets = {};
264
+
265
+ // Step one is to determine which names are not unique. These fields are
266
+ // either array-value fields or if the types differ they are composed.
267
+ this.fields = new Set();
268
+ this.element.find(Form.ELEMENTS.join(',')).each((idx, ipt) => {
269
+ this.fields.add($(ipt).prop('name'));
270
+ })
271
+ for (const field of this.fields) {
272
+ const inputs = this.element.find(this.field(field));
273
+ if (inputs.data('widget')) {
274
+ this.widgets[field] = inputs.data('widget');
275
+ }
276
+ if (inputs.length > 1) {
277
+ const types = new Set();
278
+ inputs.each((idx, element) => {
279
+ types.add($(element).prop('type'));
280
+ });
281
+ types.size > 1 ? this.#composite[field] = types : this.#multi.add(field);
282
+ } else if (inputs.get(0).hasAttribute('multiple')) {
283
+ this.#multi.add(field);
284
+ }
285
+ }
286
+
287
+ if (this.element.data('slmInitial')) {
288
+ this.initial = this.element.data('slmInitial');
289
+ } else {
290
+ this.initial = {};
291
+ }
292
+
293
+ this.element.data('slmForm', this);
294
+
295
+ this.element.find(':input').on('change', function() {
296
+ const data = this.data;
297
+ if (Form.differs(data, this.last)) {
298
+ for (const changed of this.#changeCallbacks) { changed(this); }
299
+ this.last = data;
300
+ }
301
+ }.bind(this));
302
+
303
+ this.last = this.data;
304
+ }
305
+
306
+ decompose(types, value) {
307
+ switch (types) {
308
+ case ['date', 'time']:
309
+ if (value) { return value.split('T'); }
310
+ return ['', ''];
311
+ default:
312
+ throw TypeError(`Unexpected decomposition types: ${types}`);
313
+ }
314
+ }
315
+
316
+ compose(types, inputs) {
317
+ switch (types) {
318
+ case ['date', 'time']:
319
+ return `${inputs.get(0).value}T${inputs.get(1).value || "00:00"}Z`
320
+ default:
321
+ throw TypeError(`Unexpected composition types: ${types}`);
322
+ }
323
+ }
324
+
325
+ clear() {
326
+ this.data = this.initial;
327
+ }
328
+
329
+ isComposite(field) {
330
+ return this.#composite.hasOwnProperty(field);
331
+ }
332
+
333
+ isMulti(field) {
334
+ return this.#multi.has(field);
335
+ }
336
+
337
+ type(field) {
338
+ if (this.isComposite(field)) {
339
+ return this.#composite[field];
340
+ }
341
+ return this.field(field).prop('type');
342
+ }
343
+
344
+ default(field) {
345
+ if (this.isMulti(field)) {
346
+ return [];
347
+ } else if (this.isComposite(field)) {
348
+ return this.decompose(this.type(field), '');
349
+ }
350
+ switch(this.type(field)) {
351
+ case 'checkbox':
352
+ case 'radio':
353
+ return false;
354
+ default:
355
+ return '';
356
+ }
357
+ }
358
+
359
+ field(name) {
360
+ return this.element.find(
361
+ Form.ELEMENTS.join(`[name="${name}"],`) + `[name="${name}"]`
362
+ );
363
+ }
364
+
365
+ hasChanged() {
366
+ /**
367
+ * Returns true if this form differs from its initial "clear" state and
368
+ * false otherwise.
369
+ */
370
+ return Form.differs(this.data, this.initial);
371
+ }
372
+
373
+ persist() {
374
+ /**
375
+ * Persist this form's current state to session memory.
376
+ */
377
+ const current = this.data;
378
+ // never persist excluded fields
379
+ for (const field of this.excluded) {
380
+ if (current.hasOwnProperty(field)) {
381
+ delete current[field];
382
+ }
383
+ }
384
+ this.persisted = current;
385
+ for (const widget of Object.values(this.widgets)) {
386
+ widget.persist();
387
+ }
388
+ }
389
+
390
+ revive() {
391
+ /**
392
+ * Revive this form's current state from session memory, if it has
393
+ * been persisted.
394
+ */
395
+ this.data = this.persisted;
396
+ for (const widget of Object.values(this.widgets)) {
397
+ widget.revive();
398
+ }
399
+ }
400
+
401
+ onChange(callback) {
402
+ this.#changeCallbacks.push(callback);
403
+ }
404
+ }
@@ -0,0 +1,23 @@
1
+ import { Persistable } from './persistable.js'
2
+
3
+ export class FormWidget extends Persistable {
4
+
5
+ #container;
6
+
7
+ get container() {
8
+ return this.#container;
9
+ }
10
+
11
+ constructor(container) {
12
+ super(container.get(0).getAttribute('id'));
13
+ this.#container = container;
14
+ }
15
+
16
+ changed() {
17
+ /**
18
+ * Deriving widgets should implement this callback which is invoked
19
+ * when the underlying widget's state has changed.
20
+ */
21
+ }
22
+
23
+ }
@@ -0,0 +1,33 @@
1
+ export class Persistable {
2
+ /**
3
+ * A simple interface defining a persistable component. Data is persisted
4
+ * in session memory.
5
+ */
6
+
7
+ key;
8
+
9
+ get persisted() {
10
+ const store = sessionStorage.getItem(this.key);
11
+ if (store) {
12
+ return JSON.parse(sessionStorage.getItem(this.key));
13
+ }
14
+ return {}
15
+ }
16
+
17
+ set persisted(data) {
18
+ sessionStorage.setItem(this.key, JSON.stringify(data));
19
+ }
20
+
21
+ constructor(key) {
22
+ this.key = key;
23
+ }
24
+
25
+ persist() {/* Deriving classes define their own persist logic */}
26
+
27
+ revive() {
28
+ /*
29
+ * Deriving classes define their own revival logic, this method
30
+ * should restore persisted state to the component
31
+ */
32
+ }
33
+ }