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,175 @@
1
+ import logging
2
+
3
+ from django.contrib.contenttypes.models import ContentType
4
+ from django.dispatch import receiver
5
+ from django.utils.timezone import now
6
+ from ipware import get_client_ip
7
+
8
+ from slm import signals as slm_signals
9
+
10
+ logger = logging.getLogger(__name__)
11
+
12
+
13
+ @receiver(slm_signals.site_published)
14
+ def log_publish(sender, site, user, timestamp, request, section, **kwargs):
15
+ from slm.defines import LogEntryType
16
+ from slm.models import LogEntry
17
+
18
+ LogEntry.objects.get_or_create(
19
+ type=LogEntryType.PUBLISH,
20
+ site=site,
21
+ section=(ContentType.objects.get_for_model(section) if section else None),
22
+ subsection=getattr(section, "subsection", None),
23
+ timestamp=timestamp or now(),
24
+ defaults={"user": user, "ip": get_client_ip(request)[0] if request else None},
25
+ )
26
+
27
+
28
+ @receiver(slm_signals.site_proposed)
29
+ def log_propose(sender, site, user, timestamp, request, agencies, **kwargs):
30
+ from slm.defines import LogEntryType
31
+ from slm.models import LogEntry
32
+
33
+ LogEntry.objects.get_or_create(
34
+ type=LogEntryType.SITE_PROPOSED,
35
+ site=site,
36
+ timestamp=timestamp or now(),
37
+ defaults={"user": user, "ip": get_client_ip(request)[0] if request else None},
38
+ )
39
+
40
+
41
+ @receiver(slm_signals.section_edited)
42
+ def log_edit(sender, site, user, timestamp, request, section, fields, **kwargs):
43
+ from slm.defines import LogEntryType
44
+ from slm.models import LogEntry
45
+
46
+ LogEntry.objects.get_or_create(
47
+ type=LogEntryType.UPDATE,
48
+ site=site,
49
+ section=(ContentType.objects.get_for_model(section) if section else None),
50
+ subsection=getattr(section, "subsection", None),
51
+ timestamp=timestamp or now(),
52
+ defaults={
53
+ "user": user,
54
+ "ip": get_client_ip(request)[0] if request else None,
55
+ },
56
+ )
57
+
58
+
59
+ @receiver(slm_signals.section_added)
60
+ def log_add(sender, site, user, timestamp, request, section, **kwargs):
61
+ from slm.defines import LogEntryType
62
+ from slm.models import LogEntry
63
+
64
+ LogEntry.objects.get_or_create(
65
+ type=LogEntryType.ADD,
66
+ site=site,
67
+ section=(ContentType.objects.get_for_model(section) if section else None),
68
+ subsection=getattr(section, "subsection", None),
69
+ timestamp=timestamp or now(),
70
+ defaults={"user": user, "ip": get_client_ip(request)[0] if request else None},
71
+ )
72
+
73
+
74
+ @receiver(slm_signals.section_deleted)
75
+ def log_delete(sender, site, user, timestamp, request, section, **kwargs):
76
+ from slm.defines import LogEntryType
77
+ from slm.models import LogEntry
78
+
79
+ entry_type = LogEntryType.DELETE
80
+ if not getattr(section, "published", True):
81
+ entry_type = LogEntryType.REVERT
82
+ LogEntry.objects.get_or_create(
83
+ type=entry_type,
84
+ site=site,
85
+ section=(ContentType.objects.get_for_model(section) if section else None),
86
+ subsection=getattr(section, "subsection", None),
87
+ timestamp=timestamp or now(),
88
+ defaults={"user": user, "ip": get_client_ip(request)[0] if request else None},
89
+ )
90
+
91
+
92
+ @receiver(slm_signals.site_file_uploaded)
93
+ def log_file_upload(sender, site, user, timestamp, request, upload, **kwargs):
94
+ from slm.defines import LogEntryType, SLMFileType
95
+ from slm.models import LogEntry
96
+
97
+ LogEntry.objects.get_or_create(
98
+ type=(
99
+ {
100
+ SLMFileType.SITE_IMAGE: LogEntryType.IMAGE_UPLOAD,
101
+ SLMFileType.SITE_LOG: LogEntryType.LOG_UPLOAD,
102
+ SLMFileType.ATTACHMENT: LogEntryType.ATTACHMENT_UPLOAD,
103
+ }.get(upload.file_type, LogEntryType.LOG_UPLOAD)
104
+ ),
105
+ site=site,
106
+ timestamp=timestamp or now(),
107
+ defaults={
108
+ "user": user,
109
+ "ip": get_client_ip(request)[0] if request else None,
110
+ "file": upload,
111
+ },
112
+ )
113
+
114
+
115
+ @receiver(slm_signals.site_file_published)
116
+ def log_file_published(sender, site, user, timestamp, request, upload, **kwargs):
117
+ from slm.defines import LogEntryType, SLMFileType
118
+ from slm.models import LogEntry
119
+
120
+ LogEntry.objects.get_or_create(
121
+ type=(
122
+ LogEntryType.IMAGE_PUBLISH
123
+ if upload.file_type == SLMFileType.SITE_IMAGE
124
+ else LogEntryType.ATTACHMENT_PUBLISH
125
+ ),
126
+ site=site,
127
+ timestamp=timestamp or now(),
128
+ defaults={
129
+ "user": user,
130
+ "file": upload,
131
+ "ip": get_client_ip(request)[0] if request else None,
132
+ },
133
+ )
134
+
135
+
136
+ @receiver(slm_signals.site_file_unpublished)
137
+ def log_file_unpublished(sender, site, user, timestamp, request, upload, **kwargs):
138
+ from slm.defines import LogEntryType, SLMFileType
139
+ from slm.models import LogEntry
140
+
141
+ LogEntry.objects.get_or_create(
142
+ type=(
143
+ LogEntryType.IMAGE_UNPUBLISH
144
+ if upload.file_type == SLMFileType.SITE_IMAGE
145
+ else LogEntryType.ATTACHMENT_UNPUBLISH
146
+ ),
147
+ site=site,
148
+ timestamp=timestamp or now(),
149
+ defaults={
150
+ "user": user,
151
+ "file": upload,
152
+ "ip": get_client_ip(request)[0] if request else None,
153
+ },
154
+ )
155
+
156
+
157
+ @receiver(slm_signals.site_file_deleted)
158
+ def log_file_deleted(sender, site, user, timestamp, request, upload, **kwargs):
159
+ from slm.defines import LogEntryType, SLMFileType
160
+ from slm.models import LogEntry
161
+
162
+ LogEntry.objects.get_or_create(
163
+ type=(
164
+ LogEntryType.IMAGE_DELETE
165
+ if upload.file_type == SLMFileType.SITE_IMAGE
166
+ else LogEntryType.ATTACHMENT_DELETE
167
+ ),
168
+ site=site,
169
+ timestamp=timestamp or now(),
170
+ defaults={
171
+ "user": user,
172
+ "file": None,
173
+ "ip": get_client_ip(request)[0] if request else None,
174
+ },
175
+ )
slm/receivers/index.py ADDED
@@ -0,0 +1,67 @@
1
+ from django.dispatch import receiver
2
+
3
+ from slm import signals as slm_signals
4
+ from slm.defines import SiteLogStatus
5
+
6
+
7
+ @receiver(slm_signals.site_status_changed)
8
+ def index_site(sender, site, previous_status, new_status, **kwargs):
9
+ from slm.models import ArchiveIndex
10
+
11
+ if site.last_publish and (
12
+ previous_status in SiteLogStatus.active_states()
13
+ and new_status not in SiteLogStatus.active_states()
14
+ ):
15
+ ArchiveIndex.objects.close_index(site)
16
+ elif (
17
+ site.last_publish
18
+ and previous_status in SiteLogStatus.active_states()
19
+ and previous_status is not SiteLogStatus.PUBLISHED
20
+ and new_status is SiteLogStatus.PUBLISHED
21
+ ):
22
+ # catch an edge case where a section publish triggers a whole log publish
23
+ # these signals/edit state diagram needs to be cleaned up. this code is
24
+ # too hard to follow.
25
+ ArchiveIndex.objects.add_index(site)
26
+
27
+
28
+ @receiver(slm_signals.site_published)
29
+ def publish_site(sender, site, **kwargs):
30
+ from slm.models import ArchiveIndex
31
+
32
+ ArchiveIndex.objects.add_index(site)
33
+
34
+
35
+ # for image and file attachment changes we simply regenerate the GeodesyML file
36
+ # at the current index. This can lead to some GeodesyML files with different
37
+ # attachment lists but the same file name in circulation. An alternative
38
+ # approach would be to generate a new index for each attachment change but this
39
+ # would produce lots of identical legacy logs with different timestamps/names.
40
+ # The current approach is fine for now - the attachments are largely of
41
+ # ancillary benefit.
42
+ @receiver(slm_signals.site_file_published)
43
+ def log_file_published(sender, site, user, timestamp, request, upload, **kwargs):
44
+ from slm.defines import SiteLogFormat
45
+ from slm.models import ArchiveIndex
46
+
47
+ ArchiveIndex.objects.regenerate(site, log_format=SiteLogFormat.GEODESY_ML)
48
+
49
+
50
+ @receiver(slm_signals.site_file_unpublished)
51
+ def log_file_unpublished(sender, site, user, timestamp, request, upload, **kwargs):
52
+ from slm.defines import SiteLogFormat
53
+ from slm.models import ArchiveIndex
54
+
55
+ ArchiveIndex.objects.regenerate(site, log_format=SiteLogFormat.GEODESY_ML)
56
+
57
+
58
+ @receiver(slm_signals.site_file_deleted)
59
+ def log_file_deleted(sender, site, user, timestamp, request, upload, **kwargs):
60
+ from slm.defines import SiteFileUploadStatus, SiteLogFormat, SLMFileType
61
+ from slm.models import ArchiveIndex
62
+
63
+ if upload.status is SiteFileUploadStatus.PUBLISHED and upload.file_type in [
64
+ SLMFileType.SITE_IMAGE,
65
+ SLMFileType.ATTACHMENT,
66
+ ]:
67
+ ArchiveIndex.objects.regenerate(site, log_format=SiteLogFormat.GEODESY_ML)
@@ -0,0 +1,55 @@
1
+ import sys
2
+
3
+ import importlib_resources
4
+
5
+
6
+ class _NotGiven:
7
+ pass
8
+
9
+
10
+ def set_default(var_name, default, set_if_none=True):
11
+ """
12
+ Set the value of the given variable in the calling scope to a default value if it has been not been previously
13
+ defined.
14
+
15
+ :param var_name: The name of the variable to set in the calling scope.
16
+ :param default: The value to set the variable to if its undefined
17
+ :param set_if_none: Treat the variable as undefined if it is None, default: True
18
+ :return: the variable that was set
19
+ """
20
+ scope = sys._getframe(1).f_globals
21
+ if var_name not in scope or set_if_none and scope[var_name] is None:
22
+ scope[var_name] = default
23
+ return scope[var_name]
24
+
25
+
26
+ def is_defined(var_name):
27
+ """
28
+ Returns true if the given variable has been defined in the calling scope.
29
+
30
+ :param var_name: The name of the variable to check for
31
+ :return: True if the variable is defined, false otherwise
32
+ """
33
+ return var_name in sys._getframe(1).f_globals
34
+
35
+
36
+ def get_setting(var_name, default=_NotGiven):
37
+ """
38
+ Returns the value of the setting if it exists, if it does not exist the value
39
+ given to default is returned. If no default value is given and the setting
40
+ does not exist a NameError is raised
41
+
42
+ :param var_name: The name of the variable to check for
43
+ :param default: The default value to return if the variable does not exist
44
+ :raises NameError: if the name is undefined and no default is given.
45
+ """
46
+ value = sys._getframe(1).f_globals.get(var_name, default)
47
+ if value is _NotGiven:
48
+ raise NameError(f"{var_name} setting variable is not defined.", name=var_name)
49
+ return value
50
+
51
+
52
+ def resource(package, file):
53
+ profile2 = importlib_resources.files(package) / file
54
+ with importlib_resources.as_file(profile2) as profile2_path:
55
+ return str(profile2_path)
slm/settings/auth.py ADDED
@@ -0,0 +1,15 @@
1
+ ACCOUNT_LOGIN_ON_PASSWORD_RESET = True
2
+ ACCOUNT_UNIQUE_EMAIL = True
3
+ ACCOUNT_USER_MODEL_USERNAME_FIELD = None
4
+ ACCOUNT_EMAIL_REQUIRED = True
5
+ ACCOUNT_USERNAME_REQUIRED = False
6
+ ACCOUNT_AUTHENTICATION_METHOD = "email"
7
+ LOGIN_URL = "/accounts/login/"
8
+ LOGIN_REDIRECT_URL = "/"
9
+
10
+ AUTHENTICATION_BACKENDS = [
11
+ # Needed to login by username in Django admin, regardless of `allauth`
12
+ "django.contrib.auth.backends.ModelBackend",
13
+ # `allauth` specific authentication methods, such as login by e-mail
14
+ "allauth.account.auth_backends.AuthenticationBackend",
15
+ ]
@@ -0,0 +1,14 @@
1
+ from slm.settings import get_setting, set_default
2
+
3
+ # your webserver should be configured to bypass Django and server
4
+ # MEDIA_ROOT / CKEDITOR_UPLOAD_PATH directly
5
+ CKEDITOR_UPLOAD_PATH = get_setting("MEDIA_ROOT") / "public/"
6
+
7
+ CKEDITOR_CONFIGS = {
8
+ "richtextinput": {
9
+ "width": "100%",
10
+ },
11
+ "default": {},
12
+ }
13
+
14
+ set_default("SILENCED_SYSTEM_CHECKS", []).append("ckeditor.W001")
slm/settings/debug.py ADDED
@@ -0,0 +1,47 @@
1
+ from importlib.util import find_spec
2
+
3
+ from django.core.exceptions import ImproperlyConfigured
4
+
5
+ from slm.settings import get_setting, set_default
6
+
7
+ if get_setting("DJANGO_DEBUG_TOOLBAR", None):
8
+ if not find_spec("debug_toolbar"):
9
+ raise ImproperlyConfigured(
10
+ "DJANGO_DEBUG_TOOLBAR is True, but django-debug-toolbar is not" "installed."
11
+ )
12
+
13
+ # list any middlewares that might be encountered on the stack that must
14
+ # have higher precedence than debug middelware
15
+
16
+ MIDDLEWARE = get_setting("MIDDLEWARE", [])
17
+ if "debug_toolbar.middleware.DebugToolbarMiddleware" not in MIDDLEWARE:
18
+ must_come_after = ["django.middleware.gzip.GZipMiddleware"]
19
+ position = None
20
+ for middleware in must_come_after:
21
+ try:
22
+ middleware_idx = MIDDLEWARE.index(middleware)
23
+ if position is None or middleware_idx > position:
24
+ position = middleware_idx
25
+ except ValueError:
26
+ pass
27
+ MIDDLEWARE.insert(
28
+ position or 0, "debug_toolbar.middleware.DebugToolbarMiddleware"
29
+ )
30
+
31
+ INSTALLED_APPS = get_setting("INSTALLED_APPS", [])
32
+ if "debug_toolbar" not in INSTALLED_APPS:
33
+ INSTALLED_APPS.append("debug_toolbar")
34
+
35
+ import socket # only if you haven't already imported this
36
+
37
+ try:
38
+ _, _, ips = socket.gethostbyname_ex(socket.gethostname())
39
+ except OSError:
40
+ _, _, ips = socket.gethostbyname_ex("localhost")
41
+
42
+ INTERNAL_IPS = get_setting("INTERNAL_IPS", [])
43
+ INTERNAL_IPS.extend(
44
+ [ip[: ip.rfind(".")] + ".1" for ip in ips] + ["127.0.0.1", "10.0.2.2"]
45
+ )
46
+
47
+ set_default("DEBUG_TOOLBAR_CONFIG", {"SHOW_TOOLBAR_CALLBACK": lambda _: True})
@@ -0,0 +1,12 @@
1
+ # Internationalization
2
+ # https://docs.djangoproject.com/en/stable/topics/i18n/
3
+
4
+ LANGUAGE_CODE = "en"
5
+
6
+ # ALL TIMES IN THE DB SHOULD BE STORED IN UTC - The web interface can then
7
+ # reliably translate this into browser local time
8
+ TIME_ZONE = "UTC"
9
+
10
+ USE_I18N = False
11
+
12
+ USE_TZ = True
@@ -0,0 +1,113 @@
1
+ import os
2
+ from logging import Filter
3
+
4
+ from slm.settings import get_setting
5
+
6
+ DEBUG = get_setting("DEBUG", False)
7
+ DEFAULT_LOG_LEVEL = "DEBUG" if DEBUG else "INFO"
8
+ LOG_DIR = get_setting("LOG_DIR", get_setting("SITE_DIR") / "logs")
9
+ SLM_MANAGEMENT_MODE = get_setting("SLM_MANAGEMENT_MODE", False)
10
+
11
+
12
+ class SquelchStackTraces(Filter):
13
+ def filter(self, record):
14
+ record.exc_info = None
15
+ return super().filter(record)
16
+
17
+
18
+ LOGGING = {
19
+ "version": 1,
20
+ "disable_existing_loggers": False,
21
+ "handlers": {
22
+ "file": {
23
+ "level": DEFAULT_LOG_LEVEL, # set in deployment routine
24
+ "class": "logging.handlers.TimedRotatingFileHandler",
25
+ "formatter": "verbose" if DEBUG else "simple", # set in deployment routine
26
+ "filename": LOG_DIR
27
+ / f'{get_setting("SLM_SITE_NAME", "").lower()}{"_manage" if SLM_MANAGEMENT_MODE else ""}.log',
28
+ "when": "midnight",
29
+ "interval": 1,
30
+ "backupCount": 14,
31
+ },
32
+ "mail_admins": {
33
+ "level": "ERROR",
34
+ "class": "django.utils.log.AdminEmailHandler",
35
+ "include_html": True,
36
+ },
37
+ },
38
+ "formatters": {
39
+ "verbose": {
40
+ "format": "%(levelname)s %(process)d %(asctime)s %(name)s %(process)d %(thread)d %(message)s"
41
+ },
42
+ "simple": {
43
+ "format": "%(levelname)s %(process)d %(asctime)s %(name)s %(message)s"
44
+ },
45
+ "management": {"format": "%(message)s"},
46
+ },
47
+ "filters": {
48
+ "squelch_traces": {
49
+ "()": SquelchStackTraces,
50
+ },
51
+ },
52
+ "loggers": {
53
+ "django.request": {
54
+ "handlers": ["mail_admins"],
55
+ "level": "ERROR",
56
+ "propagate": True,
57
+ },
58
+ "django": {
59
+ "handlers": ["file"],
60
+ "level": DEFAULT_LOG_LEVEL,
61
+ "propagate": False,
62
+ },
63
+ "django.db.backends": {
64
+ "handlers": ["file"],
65
+ "level": "INFO", # super noisy
66
+ "propagate": False,
67
+ },
68
+ "django.template": {
69
+ "handlers": ["file"],
70
+ "filters": ["squelch_traces"],
71
+ "level": "INFO",
72
+ "propagate": False,
73
+ },
74
+ "django.utils.autoreload": {
75
+ "handlers": ["file"],
76
+ "level": "WARNING", # this logger got really noisy in django 2.2
77
+ "propagate": False,
78
+ },
79
+ "django_auth_ldap": {"level": DEFAULT_LOG_LEVEL, "propagate": True},
80
+ },
81
+ "root": {
82
+ "handlers": ["file", "mail_admins"],
83
+ "level": DEFAULT_LOG_LEVEL, # set in deployment routine
84
+ },
85
+ }
86
+
87
+ if DEBUG and not SLM_MANAGEMENT_MODE:
88
+ LOGGING["loggers"]["core.middleware.RequestLogger"] = {
89
+ "handlers": ["file"],
90
+ "level": "DEBUG",
91
+ "propagate": False,
92
+ }
93
+
94
+ if SLM_MANAGEMENT_MODE:
95
+ LOGGING.setdefault("handlers", {})["console"] = {
96
+ "level": "INFO",
97
+ "class": "logging.StreamHandler",
98
+ "formatter": "management",
99
+ }
100
+
101
+ if "root" in LOGGING:
102
+ if "console" not in LOGGING["root"]["handlers"]:
103
+ LOGGING["root"]["handlers"].append("console")
104
+
105
+ for name, config in LOGGING.get("loggers", {}).items():
106
+ if "handlers" in config and "console" not in config["handlers"]:
107
+ config["handlers"].append("console")
108
+
109
+ # create logging dirs if necessary
110
+ for name, handler_spec in LOGGING["handlers"].items():
111
+ filename = handler_spec.get("filename", None)
112
+ if filename:
113
+ os.makedirs(os.path.dirname(filename), exist_ok=True)
File without changes
@@ -0,0 +1,10 @@
1
+ # this is the default location Postgres.app with postgres will install the postgis libraries to
2
+ # if your system is different, or you use a different postgres package you will have to
3
+ # override these
4
+
5
+ GDAL_LIBRARY_PATH = (
6
+ "/Applications/Postgres.app/Contents/Versions/latest/lib/libgdal.dylib"
7
+ )
8
+ GEOS_LIBRARY_PATH = (
9
+ "/Applications/Postgres.app/Contents/Versions/latest/lib/libgeos_c.dylib"
10
+ )
slm/settings/rest.py ADDED
@@ -0,0 +1,21 @@
1
+ """
2
+ Django rest framework configuration parameters
3
+
4
+ https://www.django-rest-framework.org/
5
+ """
6
+
7
+ REST_FRAMEWORK = {
8
+ "DEFAULT_AUTHENTICATION_CLASSES": [
9
+ "rest_framework.authentication.SessionAuthentication",
10
+ #'slm.authentication.SignatureAuthentication', TODO library authentication
11
+ ],
12
+ "DEFAULT_PERMISSION_CLASSES": [
13
+ "rest_framework.permissions.IsAuthenticatedOrReadOnly"
14
+ ],
15
+ "DEFAULT_RENDERER_CLASSES": [
16
+ "rest_framework.renderers.JSONRenderer",
17
+ "rest_framework.renderers.BrowsableAPIRenderer",
18
+ #'drf_renderer_xlsx.renderers.XLSXRenderer',
19
+ #'rest_framework_csv.renderers.CSVRenderer'
20
+ ],
21
+ }
slm/settings/root.py ADDED
@@ -0,0 +1,152 @@
1
+ """
2
+ Django settings for SLM.
3
+
4
+ For more information on this file, see
5
+ https://docs.djangoproject.com/en/stable/topics/settings/
6
+
7
+ For the full list of settings and their values, see
8
+ https://docs.djangoproject.com/en/stable/ref/settings/
9
+ """
10
+
11
+ import platform
12
+ from pathlib import Path
13
+
14
+ from django.contrib.messages import constants as message_constants
15
+ from split_settings.tools import include, optional
16
+
17
+ from slm.settings import get_setting, set_default
18
+
19
+ DEBUG = get_setting("DEBUG", False)
20
+
21
+ # Build paths inside the project like this: BASE_DIR / 'subdir'.
22
+ BASE_DIR = get_setting("BASE_DIR", Path(__file__).resolve().parent.parent)
23
+ SITE_DIR = get_setting("SITE_DIR", BASE_DIR)
24
+ DJANGO_DEBUG_TOOLBAR = get_setting("DJANGO_DEBUG_TOOLBAR", False)
25
+
26
+ # Quick-start development settings - unsuitable for production
27
+ # See https://docs.djangoproject.com/en/3.2/howto/deployment/checklist/
28
+
29
+ ALLOWED_HOSTS = get_setting("ALLOWED_HOSTS", [])
30
+ if ALLOWED_HOSTS:
31
+ set_default("SERVER_EMAIL", f"noreply@{ALLOWED_HOSTS[0]}")
32
+
33
+ # Application definition
34
+
35
+ # django.contrib.___ gives us useful tools for authentication, etc.
36
+ INSTALLED_APPS = [
37
+ # "slm.map",
38
+ "slm",
39
+ "crispy_forms",
40
+ "crispy_bootstrap5",
41
+ "ckeditor_uploader",
42
+ "ckeditor",
43
+ "polymorphic",
44
+ "rest_framework",
45
+ "rest_framework_gis",
46
+ "render_static",
47
+ "django_routines",
48
+ "django_typer",
49
+ "django_filters",
50
+ "compressor",
51
+ "widget_tweaks",
52
+ #'django.contrib.postgres',
53
+ "django.contrib.admin",
54
+ "django.contrib.auth",
55
+ "django.contrib.contenttypes",
56
+ "django.contrib.sessions",
57
+ "django.contrib.messages",
58
+ "django.contrib.staticfiles",
59
+ "django.contrib.sites",
60
+ "django.contrib.gis",
61
+ "allauth",
62
+ "allauth.account",
63
+ ]
64
+
65
+ CRISPY_ALLOWED_TEMPLATE_PACKS = "bootstrap5"
66
+ CRISPY_TEMPLATE_PACK = "bootstrap5"
67
+
68
+ STATICFILES_FINDERS = (
69
+ "django.contrib.staticfiles.finders.FileSystemFinder",
70
+ "django.contrib.staticfiles.finders.AppDirectoriesFinder",
71
+ "compressor.finders.CompressorFinder",
72
+ )
73
+
74
+ # this statement was added during creation of custom user model
75
+ AUTH_USER_MODEL = "slm.User"
76
+
77
+ MIDDLEWARE = [
78
+ "django.middleware.security.SecurityMiddleware",
79
+ "django.contrib.sessions.middleware.SessionMiddleware",
80
+ "django.middleware.common.CommonMiddleware",
81
+ "django.middleware.csrf.CsrfViewMiddleware",
82
+ "django.contrib.auth.middleware.AuthenticationMiddleware",
83
+ "allauth.account.middleware.AccountMiddleware",
84
+ "slm.middleware.SetLastVisitMiddleware",
85
+ "django.contrib.messages.middleware.MessageMiddleware",
86
+ "django.middleware.clickjacking.XFrameOptionsMiddleware",
87
+ ]
88
+
89
+ ROOT_URLCONF = "slm.settings.urls"
90
+
91
+ # Password validation
92
+ # https://docs.djangoproject.com/en/3.2/ref/settings/#auth-password-validators
93
+
94
+ AUTH_PASSWORD_VALIDATORS = [
95
+ {
96
+ "NAME": "django.contrib.auth.password_validation.UserAttributeSimilarityValidator",
97
+ },
98
+ {
99
+ "NAME": "django.contrib.auth.password_validation.MinimumLengthValidator",
100
+ },
101
+ {
102
+ "NAME": "django.contrib.auth.password_validation.CommonPasswordValidator",
103
+ },
104
+ {
105
+ "NAME": "django.contrib.auth.password_validation.NumericPasswordValidator",
106
+ },
107
+ ]
108
+
109
+
110
+ # Static files (CSS, JavaScript, Images)
111
+ # https://docs.djangoproject.com/en/3.2/howto/static-files/
112
+
113
+ # Following two statements added to assist with handling of static files
114
+ STATIC_URL = "/static/"
115
+
116
+ # Default primary key field type
117
+ # https://docs.djangoproject.com/en/3.2/ref/settings/#default-auto-field
118
+
119
+ DEFAULT_AUTO_FIELD = "django.db.models.BigAutoField"
120
+
121
+ set_default("SITE_ID", 1)
122
+
123
+ STATIC_ROOT = get_setting("STATIC_ROOT", SITE_DIR / "static")
124
+
125
+ COMPRESS_OFFLINE = True
126
+ COMPRESS_ROOT = STATIC_ROOT
127
+ COMPRESS_URL = STATIC_URL
128
+
129
+
130
+ include("internationalization.py")
131
+ include("slm.py")
132
+ include("secrets.py")
133
+ include("logging.py")
134
+ include("templates.py")
135
+ include("static_templates.py")
136
+ include("routines.py")
137
+ include("auth.py")
138
+ include("rest.py")
139
+ include("debug.py")
140
+ include("uploads.py")
141
+ include("ckeditor.py")
142
+ include("security.py")
143
+ include("validation.py")
144
+
145
+ # will either be darwin, windows or linux
146
+ include(optional(f"./platform/{platform.system().lower()}.py"))
147
+
148
+
149
+ # Path(STATIC_ROOT).mkdir(parents=True, exist_ok=True)
150
+ # Path(MEDIA_ROOT).mkdir(parents=True, exist_ok=True)
151
+
152
+ MESSAGE_LEVEL = message_constants.DEBUG if DEBUG else message_constants.INFO