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.
- igs_slm-0.1.0b0.dist-info/LICENSE +21 -0
- igs_slm-0.1.0b0.dist-info/METADATA +151 -0
- igs_slm-0.1.0b0.dist-info/RECORD +447 -0
- igs_slm-0.1.0b0.dist-info/WHEEL +4 -0
- igs_slm-0.1.0b0.dist-info/entry_points.txt +3 -0
- igs_tools/__init__.py +0 -0
- igs_tools/connection.py +88 -0
- igs_tools/defines/__init__.py +8 -0
- igs_tools/defines/constellation.py +21 -0
- igs_tools/defines/data_center.py +75 -0
- igs_tools/defines/rinex.py +49 -0
- igs_tools/directory.py +247 -0
- igs_tools/utils.py +66 -0
- slm/__init__.py +21 -0
- slm/admin.py +674 -0
- slm/api/edit/__init__.py +0 -0
- slm/api/edit/serializers.py +316 -0
- slm/api/edit/views.py +1632 -0
- slm/api/fields.py +89 -0
- slm/api/filter.py +504 -0
- slm/api/pagination.py +55 -0
- slm/api/permissions.py +65 -0
- slm/api/public/__init__.py +0 -0
- slm/api/public/serializers.py +249 -0
- slm/api/public/views.py +606 -0
- slm/api/serializers.py +132 -0
- slm/api/views.py +148 -0
- slm/apps.py +323 -0
- slm/authentication.py +198 -0
- slm/bin/__init__.py +0 -0
- slm/bin/startproject.py +262 -0
- slm/bin/templates/{{ project_dir }}/pyproject.toml +35 -0
- slm/bin/templates/{{ project_dir }}/sites/__init__.py +0 -0
- slm/bin/templates/{{ project_dir }}/sites/{{ site }}/__init__.py +0 -0
- slm/bin/templates/{{ project_dir }}/sites/{{ site }}/base.py +15 -0
- slm/bin/templates/{{ project_dir }}/sites/{{ site }}/develop/__init__.py +56 -0
- slm/bin/templates/{{ project_dir }}/sites/{{ site }}/develop/local.py +4 -0
- slm/bin/templates/{{ project_dir }}/sites/{{ site }}/develop/wsgi.py +16 -0
- slm/bin/templates/{{ project_dir }}/sites/{{ site }}/manage.py +34 -0
- slm/bin/templates/{{ project_dir }}/sites/{{ site }}/production/__init__.py +61 -0
- slm/bin/templates/{{ project_dir }}/sites/{{ site }}/production/wsgi.py +16 -0
- slm/bin/templates/{{ project_dir }}/sites/{{ site }}/urls.py +7 -0
- slm/bin/templates/{{ project_dir }}/sites/{{ site }}/validation.py +11 -0
- slm/bin/templates/{{ project_dir }}/{{ extension_app }}/__init__.py +0 -0
- slm/bin/templates/{{ project_dir }}/{{ extension_app }}/admin.py +5 -0
- slm/bin/templates/{{ project_dir }}/{{ extension_app }}/apps.py +14 -0
- slm/bin/templates/{{ project_dir }}/{{ extension_app }}/management/__init__.py +0 -0
- slm/bin/templates/{{ project_dir }}/{{ extension_app }}/management/commands/__init__.py +0 -0
- slm/bin/templates/{{ project_dir }}/{{ extension_app }}/management/commands/import_archive.py +64 -0
- slm/bin/templates/{{ project_dir }}/{{ extension_app }}/migrations/__init__.py +0 -0
- slm/bin/templates/{{ project_dir }}/{{ extension_app }}/models.py +6 -0
- slm/bin/templates/{{ project_dir }}/{{ extension_app }}/templates/slm/base.html +8 -0
- slm/bin/templates/{{ project_dir }}/{{ extension_app }}/urls.py +10 -0
- slm/bin/templates/{{ project_dir }}/{{ extension_app }}/views.py +5 -0
- slm/defines/AlertLevel.py +24 -0
- slm/defines/AntennaCalibration.py +25 -0
- slm/defines/AntennaFeatures.py +27 -0
- slm/defines/AntennaReferencePoint.py +22 -0
- slm/defines/Aspiration.py +13 -0
- slm/defines/CardinalDirection.py +19 -0
- slm/defines/CollocationStatus.py +12 -0
- slm/defines/EquipmentState.py +22 -0
- slm/defines/FlagSeverity.py +14 -0
- slm/defines/FractureSpacing.py +15 -0
- slm/defines/FrequencyStandardType.py +15 -0
- slm/defines/GeodesyMLVersion.py +48 -0
- slm/defines/ISOCountry.py +1194 -0
- slm/defines/Instrumentation.py +19 -0
- slm/defines/LogEntryType.py +30 -0
- slm/defines/SLMFileType.py +18 -0
- slm/defines/SiteFileUploadStatus.py +61 -0
- slm/defines/SiteLogFormat.py +49 -0
- slm/defines/SiteLogStatus.py +78 -0
- slm/defines/TectonicPlates.py +28 -0
- slm/defines/__init__.py +46 -0
- slm/forms.py +1126 -0
- slm/jinja2/slm/sitelog/ascii_9char.log +346 -0
- slm/jinja2/slm/sitelog/legacy.log +346 -0
- slm/jinja2/slm/sitelog/xsd/0.4/collocationInformation.xml +12 -0
- slm/jinja2/slm/sitelog/xsd/0.4/condition.xml +12 -0
- slm/jinja2/slm/sitelog/xsd/0.4/contact.xml +52 -0
- slm/jinja2/slm/sitelog/xsd/0.4/formInformation.xml +5 -0
- slm/jinja2/slm/sitelog/xsd/0.4/frequencyStandard.xml +12 -0
- slm/jinja2/slm/sitelog/xsd/0.4/gnssAntenna.xml +16 -0
- slm/jinja2/slm/sitelog/xsd/0.4/gnssReceiver.xml +11 -0
- slm/jinja2/slm/sitelog/xsd/0.4/humiditySensor.xml +13 -0
- slm/jinja2/slm/sitelog/xsd/0.4/localEpisodicEffect.xml +10 -0
- slm/jinja2/slm/sitelog/xsd/0.4/moreInformation.xml +22 -0
- slm/jinja2/slm/sitelog/xsd/0.4/multipathSource.xml +10 -0
- slm/jinja2/slm/sitelog/xsd/0.4/otherInstrumentation.xml +5 -0
- slm/jinja2/slm/sitelog/xsd/0.4/pressureSensor.xml +12 -0
- slm/jinja2/slm/sitelog/xsd/0.4/radioInterference.xml +11 -0
- slm/jinja2/slm/sitelog/xsd/0.4/sensor.xml +16 -0
- slm/jinja2/slm/sitelog/xsd/0.4/signalObstruction.xml +10 -0
- slm/jinja2/slm/sitelog/xsd/0.4/siteIdentification.xml +22 -0
- slm/jinja2/slm/sitelog/xsd/0.4/siteLocation.xml +21 -0
- slm/jinja2/slm/sitelog/xsd/0.4/surveyedLocalTie.xml +20 -0
- slm/jinja2/slm/sitelog/xsd/0.4/temperatureSensor.xml +13 -0
- slm/jinja2/slm/sitelog/xsd/0.4/waterVaporSensor.xml +11 -0
- slm/jinja2/slm/sitelog/xsd/0.5/document.xml +10 -0
- slm/jinja2/slm/sitelog/xsd/geodesyml_0.4.xml +99 -0
- slm/jinja2/slm/sitelog/xsd/geodesyml_0.5.xml +112 -0
- slm/management/__init__.py +0 -0
- slm/management/commands/__init__.py +53 -0
- slm/management/commands/build_index.py +96 -0
- slm/management/commands/generate_sinex.py +675 -0
- slm/management/commands/head_from_index.py +541 -0
- slm/management/commands/import_archive.py +908 -0
- slm/management/commands/import_equipment.py +351 -0
- slm/management/commands/set_site.py +56 -0
- slm/management/commands/sitelog.py +144 -0
- slm/management/commands/synchronize.py +60 -0
- slm/management/commands/update_data_availability.py +167 -0
- slm/management/commands/validate_db.py +186 -0
- slm/management/commands/validate_gml.py +73 -0
- slm/map/__init__.py +1 -0
- slm/map/admin.py +5 -0
- slm/map/api/__init__.py +0 -0
- slm/map/api/edit/__init__.py +0 -0
- slm/map/api/edit/serializers.py +28 -0
- slm/map/api/edit/views.py +46 -0
- slm/map/api/public/__init__.py +0 -0
- slm/map/api/public/serializers.py +29 -0
- slm/map/api/public/views.py +64 -0
- slm/map/apps.py +7 -0
- slm/map/defines.py +53 -0
- slm/map/migrations/0001_initial.py +115 -0
- slm/map/migrations/__init__.py +0 -0
- slm/map/models.py +63 -0
- slm/map/static/slm/css/map.css +86 -0
- slm/map/static/slm/js/map.js +159 -0
- slm/map/templates/slm/map.html +374 -0
- slm/map/templates/slm/station/base.html +11 -0
- slm/map/templates/slm/station/edit.html +10 -0
- slm/map/templates/slm/top_nav.html +17 -0
- slm/map/templatetags/__init__.py +0 -0
- slm/map/templatetags/slm_map.py +18 -0
- slm/map/urls.py +25 -0
- slm/map/views.py +36 -0
- slm/middleware.py +29 -0
- slm/migrations/0001_alter_siteantenna_marker_enu_alter_sitelocation_llh_and_more.py +47 -0
- slm/migrations/0001_initial.py +4826 -0
- slm/migrations/0002_alter_dataavailability_site.py +22 -0
- slm/migrations/0003_remove_logentry_slm_logentr_site_lo_7a2af7_idx_and_more.py +80 -0
- slm/migrations/0004_alter_logentry_timestamp_and_more.py +25 -0
- slm/migrations/0005_alter_logentry_options_alter_logentry_section_and_more.py +46 -0
- slm/migrations/0006_alter_logentry_options_alter_logentry_index_together.py +24 -0
- slm/migrations/0007_alter_dataavailability_rate.py +23 -0
- slm/migrations/0008_alter_archiveindex_options_and_more.py +64 -0
- slm/migrations/0009_alter_archiveindex_end.py +21 -0
- slm/migrations/0010_alter_dataavailability_rinex_version_and_more.py +844 -0
- slm/migrations/0011_alter_siteidentification_fracture_spacing.py +33 -0
- slm/migrations/0012_alter_logentry_type.py +36 -0
- slm/migrations/0013_unpublishedfilesalert.py +48 -0
- slm/migrations/0014_sitelogpublished.py +48 -0
- slm/migrations/0015_alter_siteantenna_options_and_more.py +181 -0
- slm/migrations/0016_alter_antenna_description_alter_radome_description_and_more.py +42 -0
- slm/migrations/0017_alter_logentry_unique_together_and_more.py +54 -0
- slm/migrations/0018_afix_deleted.py +34 -0
- slm/migrations/0018_alter_siteantenna_options_and_more.py +244 -0
- slm/migrations/0019_remove_siteantenna_marker_enu_siteantenna_marker_une_and_more.py +101 -0
- slm/migrations/0020_alter_manufacturer_options.py +16 -0
- slm/migrations/0021_alter_siteform_report_type.py +23 -0
- slm/migrations/0022_rename_antcal_antenna_radome_slm_antcal_antenna_20827a_idx_and_more.py +297 -0
- slm/migrations/0023_archivedsitelog_gml_version_and_more.py +55 -0
- slm/migrations/0024_alter_agency_name_alter_agency_shortname.py +24 -0
- slm/migrations/0025_alter_archivedsitelog_log_format_and_more.py +61 -0
- slm/migrations/0026_alter_archivedsitelog_log_format_and_more.py +61 -0
- slm/migrations/0027_importalert_file_contents_importalert_findings_and_more.py +41 -0
- slm/migrations/0028_antenna_replaced_manufacturer_url_radome_replaced_and_more.py +46 -0
- slm/migrations/0029_manufacturer_full_name.py +17 -0
- slm/migrations/0030_alter_antenna_state_alter_radome_state_and_more.py +43 -0
- slm/migrations/__init__.py +0 -0
- slm/migrations/load_satellitesystems.py +27 -0
- slm/models/__init__.py +118 -0
- slm/models/about.py +14 -0
- slm/models/alerts.py +1204 -0
- slm/models/data.py +58 -0
- slm/models/equipment.py +229 -0
- slm/models/help.py +14 -0
- slm/models/index.py +428 -0
- slm/models/sitelog.py +4279 -0
- slm/models/system.py +723 -0
- slm/models/user.py +304 -0
- slm/parsing/__init__.py +786 -0
- slm/parsing/legacy/__init__.py +4 -0
- slm/parsing/legacy/binding.py +817 -0
- slm/parsing/legacy/parser.py +377 -0
- slm/parsing/xsd/__init__.py +34 -0
- slm/parsing/xsd/binding.py +86 -0
- slm/parsing/xsd/geodesyml/0.4/commonTypes.xsd +133 -0
- slm/parsing/xsd/geodesyml/0.4/contact.xsd +29 -0
- slm/parsing/xsd/geodesyml/0.4/dataStreams.xsd +129 -0
- slm/parsing/xsd/geodesyml/0.4/document.xsd +64 -0
- slm/parsing/xsd/geodesyml/0.4/equipment.xsd +427 -0
- slm/parsing/xsd/geodesyml/0.4/fieldMeasurement.xsd +170 -0
- slm/parsing/xsd/geodesyml/0.4/geodesyML.xsd +71 -0
- slm/parsing/xsd/geodesyml/0.4/geodeticEquipment.xsd +343 -0
- slm/parsing/xsd/geodesyml/0.4/geodeticMonument.xsd +147 -0
- slm/parsing/xsd/geodesyml/0.4/lineage.xsd +614 -0
- slm/parsing/xsd/geodesyml/0.4/localInterferences.xsd +131 -0
- slm/parsing/xsd/geodesyml/0.4/measurement.xsd +473 -0
- slm/parsing/xsd/geodesyml/0.4/monumentInfo.xsd +251 -0
- slm/parsing/xsd/geodesyml/0.4/observationSystem.xsd +429 -0
- slm/parsing/xsd/geodesyml/0.4/project.xsd +38 -0
- slm/parsing/xsd/geodesyml/0.4/quality.xsd +176 -0
- slm/parsing/xsd/geodesyml/0.4/referenceFrame.xsd +194 -0
- slm/parsing/xsd/geodesyml/0.4/siteLog.xsd +71 -0
- slm/parsing/xsd/geodesyml/0.5/commonTypes.xsd +133 -0
- slm/parsing/xsd/geodesyml/0.5/contact.xsd +29 -0
- slm/parsing/xsd/geodesyml/0.5/dataStreams.xsd +129 -0
- slm/parsing/xsd/geodesyml/0.5/document.xsd +64 -0
- slm/parsing/xsd/geodesyml/0.5/equipment.xsd +427 -0
- slm/parsing/xsd/geodesyml/0.5/fieldMeasurement.xsd +170 -0
- slm/parsing/xsd/geodesyml/0.5/geodesyML.xsd +71 -0
- slm/parsing/xsd/geodesyml/0.5/geodeticEquipment.xsd +343 -0
- slm/parsing/xsd/geodesyml/0.5/geodeticMonument.xsd +147 -0
- slm/parsing/xsd/geodesyml/0.5/lineage.xsd +614 -0
- slm/parsing/xsd/geodesyml/0.5/localInterferences.xsd +131 -0
- slm/parsing/xsd/geodesyml/0.5/measurement.xsd +473 -0
- slm/parsing/xsd/geodesyml/0.5/monumentInfo.xsd +306 -0
- slm/parsing/xsd/geodesyml/0.5/observationSystem.xsd +429 -0
- slm/parsing/xsd/geodesyml/0.5/project.xsd +38 -0
- slm/parsing/xsd/geodesyml/0.5/quality.xsd +176 -0
- slm/parsing/xsd/geodesyml/0.5/referenceFrame.xsd +194 -0
- slm/parsing/xsd/geodesyml/0.5/siteLog.xsd +73 -0
- slm/parsing/xsd/parser.py +116 -0
- slm/parsing/xsd/resolver.py +28 -0
- slm/receivers/__init__.py +11 -0
- slm/receivers/alerts.py +87 -0
- slm/receivers/cleanup.py +41 -0
- slm/receivers/event_loggers.py +175 -0
- slm/receivers/index.py +67 -0
- slm/settings/__init__.py +55 -0
- slm/settings/auth.py +15 -0
- slm/settings/ckeditor.py +14 -0
- slm/settings/debug.py +47 -0
- slm/settings/internationalization.py +12 -0
- slm/settings/logging.py +113 -0
- slm/settings/platform/__init__.py +0 -0
- slm/settings/platform/darwin.py +10 -0
- slm/settings/rest.py +21 -0
- slm/settings/root.py +152 -0
- slm/settings/routines.py +43 -0
- slm/settings/secrets.py +37 -0
- slm/settings/security.py +5 -0
- slm/settings/slm.py +188 -0
- slm/settings/static_templates.py +53 -0
- slm/settings/templates.py +29 -0
- slm/settings/uploads.py +8 -0
- slm/settings/urls.py +126 -0
- slm/settings/validation.py +196 -0
- slm/signals.py +250 -0
- slm/singleton.py +49 -0
- slm/static/rest_framework/css/bootstrap-tweaks.css +204 -0
- slm/static/rest_framework/css/bootstrap.min.css +7 -0
- slm/static/rest_framework/css/bootstrap.min.css.map +1 -0
- slm/static/rest_framework/css/default.css +82 -0
- slm/static/rest_framework/css/prettify.css +30 -0
- slm/static/rest_framework/docs/css/base.css +344 -0
- slm/static/rest_framework/docs/css/highlight.css +125 -0
- slm/static/rest_framework/docs/css/jquery.json-view.min.css +11 -0
- slm/static/rest_framework/docs/img/favicon.ico +0 -0
- slm/static/rest_framework/docs/img/grid.png +0 -0
- slm/static/rest_framework/docs/js/api.js +321 -0
- slm/static/rest_framework/docs/js/highlight.pack.js +2 -0
- slm/static/rest_framework/docs/js/jquery.json-view.min.js +7 -0
- slm/static/rest_framework/img/grid.png +0 -0
- slm/static/rest_framework/js/ajax-form.js +127 -0
- slm/static/rest_framework/js/bootstrap.bundle.min.js +7 -0
- slm/static/rest_framework/js/bootstrap.bundle.min.js.map +1 -0
- slm/static/rest_framework/js/bootstrap.min.js.map +1 -0
- slm/static/rest_framework/js/coreapi-0.1.1.js +2043 -0
- slm/static/rest_framework/js/csrf.js +52 -0
- slm/static/rest_framework/js/default.js +47 -0
- slm/static/rest_framework/js/jquery-3.5.1.min.js +2 -0
- slm/static/rest_framework/js/prettify-min.js +28 -0
- slm/static/slm/css/admin.css +3 -0
- slm/static/slm/css/defines.css +82 -0
- slm/static/slm/css/forms.css +1 -0
- slm/static/slm/css/style.css +1004 -0
- slm/static/slm/img/email-branding.png +0 -0
- slm/static/slm/img/favicon.ico +0 -0
- slm/static/slm/img/login-bg.jpg +0 -0
- slm/static/slm/img/slm-logo.svg +4 -0
- slm/static/slm/js/autocomplete.js +341 -0
- slm/static/slm/js/enums.js +322 -0
- slm/static/slm/js/fileIcons.js +30 -0
- slm/static/slm/js/form.js +404 -0
- slm/static/slm/js/formWidget.js +23 -0
- slm/static/slm/js/persistable.js +33 -0
- slm/static/slm/js/slm.js +1028 -0
- slm/static/slm/js/time24.js +212 -0
- slm/static_templates/slm/css/defines.css +26 -0
- slm/static_templates/slm/js/enums.js +28 -0
- slm/static_templates/slm/js/fileIcons.js +16 -0
- slm/static_templates/slm/js/urls.js +5 -0
- slm/templates/account/base.html +20 -0
- slm/templates/account/email/base.html +43 -0
- slm/templates/account/email/base_message.txt +7 -0
- slm/templates/account/email/email_confirmation_message.html +16 -0
- slm/templates/account/email/email_confirmation_message.txt +7 -0
- slm/templates/account/email/email_confirmation_signup_message.html +1 -0
- slm/templates/account/email/email_confirmation_signup_message.txt +1 -0
- slm/templates/account/email/email_confirmation_signup_subject.txt +1 -0
- slm/templates/account/email/email_confirmation_subject.txt +4 -0
- slm/templates/account/email/password_reset_key_message.html +28 -0
- slm/templates/account/email/password_reset_key_message.txt +9 -0
- slm/templates/account/email/password_reset_key_subject.txt +4 -0
- slm/templates/account/email/unknown_account_message.html +25 -0
- slm/templates/account/email/unknown_account_message.txt +12 -0
- slm/templates/account/email/unknown_account_subject.txt +4 -0
- slm/templates/account/login.html +67 -0
- slm/templates/account/logout.html +38 -0
- slm/templates/account/password_change.html +48 -0
- slm/templates/account/password_reset.html +51 -0
- slm/templates/account/password_reset_done.html +20 -0
- slm/templates/account/password_reset_from_key.html +52 -0
- slm/templates/account/password_reset_from_key_done.html +17 -0
- slm/templates/admin/base.html +7 -0
- slm/templates/messages.html +8 -0
- slm/templates/rest_framework/README +16 -0
- slm/templates/rest_framework/admin/detail.html +10 -0
- slm/templates/rest_framework/admin/dict_value.html +11 -0
- slm/templates/rest_framework/admin/list.html +32 -0
- slm/templates/rest_framework/admin/list_value.html +11 -0
- slm/templates/rest_framework/admin/simple_list_value.html +2 -0
- slm/templates/rest_framework/admin.html +282 -0
- slm/templates/rest_framework/api.html +3 -0
- slm/templates/rest_framework/base.html +334 -0
- slm/templates/rest_framework/docs/auth/basic.html +42 -0
- slm/templates/rest_framework/docs/auth/session.html +40 -0
- slm/templates/rest_framework/docs/auth/token.html +41 -0
- slm/templates/rest_framework/docs/document.html +37 -0
- slm/templates/rest_framework/docs/error.html +71 -0
- slm/templates/rest_framework/docs/index.html +55 -0
- slm/templates/rest_framework/docs/interact.html +57 -0
- slm/templates/rest_framework/docs/langs/javascript-intro.html +5 -0
- slm/templates/rest_framework/docs/langs/javascript.html +15 -0
- slm/templates/rest_framework/docs/langs/python-intro.html +3 -0
- slm/templates/rest_framework/docs/langs/python.html +13 -0
- slm/templates/rest_framework/docs/langs/shell-intro.html +3 -0
- slm/templates/rest_framework/docs/langs/shell.html +6 -0
- slm/templates/rest_framework/docs/link.html +113 -0
- slm/templates/rest_framework/docs/sidebar.html +78 -0
- slm/templates/rest_framework/filters/base.html +16 -0
- slm/templates/rest_framework/filters/ordering.html +17 -0
- slm/templates/rest_framework/filters/search.html +13 -0
- slm/templates/rest_framework/horizontal/checkbox.html +23 -0
- slm/templates/rest_framework/horizontal/checkbox_multiple.html +32 -0
- slm/templates/rest_framework/horizontal/dict_field.html +11 -0
- slm/templates/rest_framework/horizontal/fieldset.html +16 -0
- slm/templates/rest_framework/horizontal/form.html +6 -0
- slm/templates/rest_framework/horizontal/input.html +21 -0
- slm/templates/rest_framework/horizontal/list_field.html +11 -0
- slm/templates/rest_framework/horizontal/list_fieldset.html +13 -0
- slm/templates/rest_framework/horizontal/radio.html +42 -0
- slm/templates/rest_framework/horizontal/select.html +36 -0
- slm/templates/rest_framework/horizontal/select_multiple.html +38 -0
- slm/templates/rest_framework/horizontal/textarea.html +21 -0
- slm/templates/rest_framework/inline/checkbox.html +8 -0
- slm/templates/rest_framework/inline/checkbox_multiple.html +14 -0
- slm/templates/rest_framework/inline/dict_field.html +9 -0
- slm/templates/rest_framework/inline/fieldset.html +6 -0
- slm/templates/rest_framework/inline/form.html +8 -0
- slm/templates/rest_framework/inline/input.html +9 -0
- slm/templates/rest_framework/inline/list_field.html +9 -0
- slm/templates/rest_framework/inline/list_fieldset.html +3 -0
- slm/templates/rest_framework/inline/radio.html +25 -0
- slm/templates/rest_framework/inline/select.html +24 -0
- slm/templates/rest_framework/inline/select_multiple.html +25 -0
- slm/templates/rest_framework/inline/textarea.html +9 -0
- slm/templates/rest_framework/login.html +3 -0
- slm/templates/rest_framework/login_base.html +65 -0
- slm/templates/rest_framework/pagination/numbers.html +47 -0
- slm/templates/rest_framework/pagination/previous_and_next.html +21 -0
- slm/templates/rest_framework/raw_data_form.html +11 -0
- slm/templates/rest_framework/schema.js +3 -0
- slm/templates/rest_framework/vertical/checkbox.html +16 -0
- slm/templates/rest_framework/vertical/checkbox_multiple.html +30 -0
- slm/templates/rest_framework/vertical/dict_field.html +7 -0
- slm/templates/rest_framework/vertical/fieldset.html +13 -0
- slm/templates/rest_framework/vertical/form.html +6 -0
- slm/templates/rest_framework/vertical/input.html +17 -0
- slm/templates/rest_framework/vertical/list_field.html +7 -0
- slm/templates/rest_framework/vertical/list_fieldset.html +7 -0
- slm/templates/rest_framework/vertical/radio.html +40 -0
- slm/templates/rest_framework/vertical/select.html +34 -0
- slm/templates/rest_framework/vertical/select_multiple.html +31 -0
- slm/templates/rest_framework/vertical/textarea.html +17 -0
- slm/templates/slm/about.html +21 -0
- slm/templates/slm/alerts/alert.html +15 -0
- slm/templates/slm/alerts/geodesymlinvalid.html +8 -0
- slm/templates/slm/alerts/importalert.html +10 -0
- slm/templates/slm/alerts.html +18 -0
- slm/templates/slm/auth_menu.html +41 -0
- slm/templates/slm/base.html +195 -0
- slm/templates/slm/emails/alert_issued.html +31 -0
- slm/templates/slm/emails/alert_issued.txt +9 -0
- slm/templates/slm/emails/base.html +6 -0
- slm/templates/slm/emails/changes_rejected.txt +7 -0
- slm/templates/slm/emails/review_requested.txt +7 -0
- slm/templates/slm/forms/widgets/auto_complete.html +21 -0
- slm/templates/slm/forms/widgets/auto_complete_multiple.html +18 -0
- slm/templates/slm/forms/widgets/checkbox_multiple.html +6 -0
- slm/templates/slm/forms/widgets/inline_multi.html +1 -0
- slm/templates/slm/forms/widgets/splitdatetime.html +14 -0
- slm/templates/slm/forms/widgets/time24.html +37 -0
- slm/templates/slm/help.html +54 -0
- slm/templates/slm/messages.html +13 -0
- slm/templates/slm/new_site.html +88 -0
- slm/templates/slm/profile.html +57 -0
- slm/templates/slm/register.html +40 -0
- slm/templates/slm/reports/file_log.html +43 -0
- slm/templates/slm/reports/head_log.html +23 -0
- slm/templates/slm/reports/head_report.html +55 -0
- slm/templates/slm/reports/index_log.html +23 -0
- slm/templates/slm/reports/index_report.html +71 -0
- slm/templates/slm/station/alert.html +8 -0
- slm/templates/slm/station/alerts.html +19 -0
- slm/templates/slm/station/base.html +104 -0
- slm/templates/slm/station/download.html +87 -0
- slm/templates/slm/station/edit.html +283 -0
- slm/templates/slm/station/form.html +110 -0
- slm/templates/slm/station/log.html +18 -0
- slm/templates/slm/station/review.html +461 -0
- slm/templates/slm/station/upload.html +295 -0
- slm/templates/slm/station/uploads/attachment.html +20 -0
- slm/templates/slm/station/uploads/geodesyml.html +1 -0
- slm/templates/slm/station/uploads/image.html +27 -0
- slm/templates/slm/station/uploads/json.html +0 -0
- slm/templates/slm/station/uploads/legacy.html +77 -0
- slm/templates/slm/top_nav.html +14 -0
- slm/templates/slm/user_activity.html +16 -0
- slm/templates/slm/widgets/alert_scroll.html +135 -0
- slm/templates/slm/widgets/filelist.html +258 -0
- slm/templates/slm/widgets/legend.html +12 -0
- slm/templates/slm/widgets/log_scroll.html +88 -0
- slm/templates/slm/widgets/stationlist.html +233 -0
- slm/templatetags/__init__.py +0 -0
- slm/templatetags/jinja2.py +9 -0
- slm/templatetags/slm.py +459 -0
- slm/urls.py +148 -0
- slm/utils.py +299 -0
- slm/validators.py +297 -0
- slm/views.py +654 -0
- 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)
|
slm/settings/__init__.py
ADDED
|
@@ -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
|
+
]
|
slm/settings/ckeditor.py
ADDED
|
@@ -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
|
slm/settings/logging.py
ADDED
|
@@ -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
|