From 0aca34fae146f19cc7536f016cc6736f65ca82db Mon Sep 17 00:00:00 2001 From: Juan Date: Wed, 19 Dec 2018 10:18:52 -0400 Subject: [PATCH 01/34] #344 Added organization link field to the organization form. --- src/dataloaderinterface/forms.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/dataloaderinterface/forms.py b/src/dataloaderinterface/forms.py index f78a5152..cdbf7d4a 100644 --- a/src/dataloaderinterface/forms.py +++ b/src/dataloaderinterface/forms.py @@ -91,13 +91,15 @@ class Meta: help_texts = { 'organization_code': 'Enter a brief, but unique code to identify your organization (e.g., "USU" or "USGS")', 'organization_name': 'Enter the name of your organization', - 'organization_description': 'Enter a description for your organization' + 'organization_description': 'Enter a description for your organization', + 'organization_link': 'Enter a URL that links to the organization website' } fields = [ 'organization_code', 'organization_name', 'organization_type', - 'organization_description' + 'organization_description', + 'organization_link' ] From 7c2662f8baadf65a641c598f101a0daa935c55f1 Mon Sep 17 00:00:00 2001 From: Juan Date: Thu, 20 Dec 2018 12:29:26 -0400 Subject: [PATCH 02/34] #340 Added list display fields for the Organization, Equipment Model, Variable, Units, and Instrument Output Variable models. --- src/dataloaderinterface/admin.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/dataloaderinterface/admin.py b/src/dataloaderinterface/admin.py index c5d7bcf4..b567ce29 100644 --- a/src/dataloaderinterface/admin.py +++ b/src/dataloaderinterface/admin.py @@ -31,12 +31,13 @@ class SiteRegistrationAdmin(admin.ModelAdmin): @admin.register(Organization) class OrganizationAdmin(admin.ModelAdmin): - pass + list_display = ('organization_code', 'organization_name', 'organization_type', 'organization_link') @admin.register(EquipmentModel) class EquipmentModelAdmin(admin.ModelAdmin): sensor_fields = ['equipment_model_id'] + list_display = ('model_name', 'model_manufacturer', 'model_description', 'model_link') def save_model(self, request, obj, form, change): if change: @@ -48,6 +49,7 @@ def save_model(self, request, obj, form, change): @admin.register(Variable) class VariableAdmin(admin.ModelAdmin): sensor_fields = ['variable_id'] + list_display = ('variable_code', 'variable_name', 'variable_type', 'no_data_value') def save_model(self, request, obj, form, change): if change: @@ -59,6 +61,7 @@ def save_model(self, request, obj, form, change): @admin.register(Unit) class UnitAdmin(admin.ModelAdmin): sensor_fields = ['unit_id'] + list_display = ('unit_name', 'unit_type', 'unit_abbreviation', 'unit_link') def save_model(self, request, obj, form, change): if change: @@ -69,6 +72,8 @@ def save_model(self, request, obj, form, change): @admin.register(InstrumentOutputVariable) class InstrumentOutputVariableAdmin(admin.ModelAdmin): + list_display = ('variable', 'model', 'instrument_raw_output_unit', 'instrument_accuracy') + def get_changelist_form(self, request, **kwargs): return super(InstrumentOutputVariableAdmin, self).get_changelist_form(request, **kwargs) From bc25e4bf73afc66b044f5cdf0de987616e9253cf Mon Sep 17 00:00:00 2001 From: Juan Date: Thu, 20 Dec 2018 13:00:39 -0400 Subject: [PATCH 03/34] #191 Added select2 library for the admin dropdowns. This allows for free-text searching and better usability of the admin. --- src/WebSDL/settings/base.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/WebSDL/settings/base.py b/src/WebSDL/settings/base.py index 7e342e5c..9dfa3b9d 100644 --- a/src/WebSDL/settings/base.py +++ b/src/WebSDL/settings/base.py @@ -52,6 +52,7 @@ 'dataloaderinterface.apps.DataloaderinterfaceConfig', 'hydroshare', 'leafpack', + 'django_admin_select2', 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', From 69a95b2597162c33582da61fe5846b490dddf3aa Mon Sep 17 00:00:00 2001 From: Juan Date: Thu, 20 Dec 2018 13:08:09 -0400 Subject: [PATCH 04/34] #190 #191 Changed the text that appears when displaying units. --- src/dataloader/models.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dataloader/models.py b/src/dataloader/models.py index da83d178..a7ed132d 100644 --- a/src/dataloader/models.py +++ b/src/dataloader/models.py @@ -714,7 +714,7 @@ class Unit(models.Model): unit_link = models.CharField(db_column='unitslink', blank=True, max_length=255) def __str__(self): - return '%s: %s (%s)' % (self.unit_type_id, self.unit_name, self.unit_abbreviation) + return '%s - %s (%s)' % (self.unit_name, self.unit_abbreviation, self.unit_type_id) def __repr__(self): return "" % ( From 79e3812273319a8b199799f809692ee15fea8c36 Mon Sep 17 00:00:00 2001 From: Maurier Date: Thu, 20 Dec 2018 10:44:51 -0700 Subject: [PATCH 05/34] [#337] Remove variables from Site Details page --- .../templates/leafpack/leafpack_detail.html | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/src/dataloaderinterface/templates/leafpack/leafpack_detail.html b/src/dataloaderinterface/templates/leafpack/leafpack_detail.html index 1505bf03..cf33df6a 100644 --- a/src/dataloaderinterface/templates/leafpack/leafpack_detail.html +++ b/src/dataloaderinterface/templates/leafpack/leafpack_detail.html @@ -84,16 +84,6 @@
Placement Information
°C - - - Deployment Type - {{ leafpack.deployment_type|default:"N/A" }} - - - - Content - {{ leafpack.content|default:"N/A" }} - From 600923671299e793afa38eaafd3128785d14d496 Mon Sep 17 00:00:00 2001 From: Maurier Date: Thu, 20 Dec 2018 11:28:40 -0700 Subject: [PATCH 06/34] [#337] Remove variables from Site Details page --- .../templates/dataloaderinterface/site_details.html | 9 --------- 1 file changed, 9 deletions(-) diff --git a/src/dataloaderinterface/templates/dataloaderinterface/site_details.html b/src/dataloaderinterface/templates/dataloaderinterface/site_details.html index 1caa7668..d830edd8 100644 --- a/src/dataloaderinterface/templates/dataloaderinterface/site_details.html +++ b/src/dataloaderinterface/templates/dataloaderinterface/site_details.html @@ -495,23 +495,14 @@
- {# #} - {# #} - - {% for leafpack in leafpacks %} - {# TODO: Populate field experiment_type #} - {# #} - {# #} - - + + + + @@ -503,6 +507,10 @@
{% for leafpack in leafpacks %}
+ + + +
Experiment IDExperiment TypeBegin DateContentDeployment Type
{{ leafpack.id }}{{ leafpack.experiment_type }}{{ leafpack.placement_date }}{{ leafpack.content }}{{ leafpack.deployment_type }} From 69f9fea918cce848e47125a6c952ad48922e76ad Mon Sep 17 00:00:00 2001 From: Maurier Date: Thu, 20 Dec 2018 11:40:01 -0700 Subject: [PATCH 07/34] [#337] Add content from summary table in Site Details page --- .../templates/dataloaderinterface/site_details.html | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/dataloaderinterface/templates/dataloaderinterface/site_details.html b/src/dataloaderinterface/templates/dataloaderinterface/site_details.html index d830edd8..fb7663b6 100644 --- a/src/dataloaderinterface/templates/dataloaderinterface/site_details.html +++ b/src/dataloaderinterface/templates/dataloaderinterface/site_details.html @@ -496,6 +496,10 @@
Begin DateTotal Number of Individuals FoundBiotic IndexWater Quality CategoryPercent EPT
{{ leafpack.placement_date }}{{ leafpack.taxon_count }}{{ leafpack.biotic_index|floatformat:2 }}{{ leafpack.water_quality }}{{ leafpack.percent_EPT|floatformat:2 }}% From e39607d3a84a69120cd908b794cec3e92c963f99 Mon Sep 17 00:00:00 2001 From: Maurier Date: Thu, 20 Dec 2018 12:05:02 -0700 Subject: [PATCH 08/34] [#345] Allow file name text to wrap --- .../static/dataloaderinterface/css/style.css | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/dataloaderinterface/static/dataloaderinterface/css/style.css b/src/dataloaderinterface/static/dataloaderinterface/css/style.css index 08fd0c0b..98796a4c 100644 --- a/src/dataloaderinterface/static/dataloaderinterface/css/style.css +++ b/src/dataloaderinterface/static/dataloaderinterface/css/style.css @@ -1438,6 +1438,10 @@ div.file-preview { padding: 1em; } +div.file-preview .file-name { + word-break: break-word; +} + i.file-icon { font-size: 30px; color: #66cbcb; From c4669d01e07c88060941a10ef62c7aca133e2388 Mon Sep 17 00:00:00 2001 From: Maurier Date: Thu, 20 Dec 2018 12:18:04 -0700 Subject: [PATCH 09/34] [#338] Edit text under Intellectual Property in Terms of Use page --- .../dataloaderinterface/terms_of_use.html | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/src/dataloaderinterface/templates/dataloaderinterface/terms_of_use.html b/src/dataloaderinterface/templates/dataloaderinterface/terms_of_use.html index 4f144182..d3aadcef 100644 --- a/src/dataloaderinterface/templates/dataloaderinterface/terms_of_use.html +++ b/src/dataloaderinterface/templates/dataloaderinterface/terms_of_use.html @@ -165,14 +165,13 @@ Research Center and LimnoTech to you any Stroud Water Research Center, LimnoTech, or third-party intellectual property, and all right, title, and interest in and to such property will remain (as between the parties) solely with Stroud Water Research Center and - LimnoTech. Stroud Water Research Center and LimnoTech, MonitorMyWatershed.org, the - MonitorMyWatershed.org logo, and all other trademarks, service marks, graphics and logos - used in connection with the websites named above, or the Website are trademarks or - registered trademarks of Stroud Water Research Center or Stroud Water Research Center's - licensors. Other trademarks, service marks, graphics, and logos used in connection with the - Website may be the trademarks of other third parties. Your use of the Website grants you no - right or license to reproduce or otherwise use any Stroud Water Research Center, LimnoTech, - or third-party trademarks. + LimnoTech. Stroud Water Research Center, EnviroDIY, Leaf Pack Network, Model My Watershed, + Monitor My Watershed, WikiWatershed, and all other trademarks, service marks, graphics, and + logos used in connection with the websites named above are trademarks or registered + trademarks of Stroud Water Research Center. Other trademarks, service marks, graphics, and + logos used in connection with the Website are the property of their respective holders. Your + use of the Website grants you no right or license to reproduce or otherwise use any Stroud + Water Research Center, LimnoTech, or third-party trademarks.
  • Changes. Stroud Water Research Center and LimnoTech reserve the right, at their sole discretion, to modify or replace any part of this Agreement. It is your From db7671ed661ebef27fc7d05af6ff51536f22b07c Mon Sep 17 00:00:00 2001 From: Maurier Date: Thu, 20 Dec 2018 12:23:13 -0700 Subject: [PATCH 10/34] [#335] Update page titles for Home page and Sign Up page --- src/accounts/templates/registration/register.html | 2 +- src/dataloaderinterface/templates/dataloaderinterface/home.html | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/accounts/templates/registration/register.html b/src/accounts/templates/registration/register.html index 3f2f44cb..2dd83dbc 100644 --- a/src/accounts/templates/registration/register.html +++ b/src/accounts/templates/registration/register.html @@ -3,7 +3,7 @@ {% load static %} {% block page_title %} - Join the EnviroDIY Data Portal + Join Monitor My Watershed {% endblock %} {% block content %} diff --git a/src/dataloaderinterface/templates/dataloaderinterface/home.html b/src/dataloaderinterface/templates/dataloaderinterface/home.html index a9644815..fdc746e9 100644 --- a/src/dataloaderinterface/templates/dataloaderinterface/home.html +++ b/src/dataloaderinterface/templates/dataloaderinterface/home.html @@ -7,7 +7,7 @@ {% endblock %} {% block page_title %} - Data Sharing Portal + Monitor My Watershed {% endblock %} {% block home_page_banner %} From 7b7e181a55887c44c715960be5f71ad97933208f Mon Sep 17 00:00:00 2001 From: Maurier Date: Thu, 20 Dec 2018 12:49:55 -0700 Subject: [PATCH 11/34] [#324] Add cookie policy page --- .../dataloaderinterface/cookie_policy.html | 69 +++++++++++++++++++ .../templates/dataloaderinterface/footer.html | 3 +- src/dataloaderinterface/urls.py | 3 +- src/dataloaderinterface/views.py | 4 ++ 4 files changed, 77 insertions(+), 2 deletions(-) create mode 100644 src/dataloaderinterface/templates/dataloaderinterface/cookie_policy.html diff --git a/src/dataloaderinterface/templates/dataloaderinterface/cookie_policy.html b/src/dataloaderinterface/templates/dataloaderinterface/cookie_policy.html new file mode 100644 index 00000000..95092112 --- /dev/null +++ b/src/dataloaderinterface/templates/dataloaderinterface/cookie_policy.html @@ -0,0 +1,69 @@ +{% extends 'dataloaderinterface/base.html' %} +{% load staticfiles %} + +{% block styles %} + {{ block.super }} +{% endblock %} + +{% block page_title %} + Cookie Policy +{% endblock %} + +{% block content %} +
    +
    +
    +
    +
    +
    Monitor My Watershed® Cookie Policy
    +
    +
    +

    Our Privacy Policy explains our principles when it comes to the + collection, processing, and + storage of your information. This cookie policy specifically explains how we deploy cookies, as + well as the options you have to control them.

    +
    What Are Cookies?
    +

    Cookies are small pieces of data, stored in text files, that are stored on your computer or other + device when websites are loaded in a browser. They are widely used to “remember” you and your + preferences, either for a single visit (through a “session cookie”) or for multiple repeat + visits (using a “persistent cookie”). They ensure a consistent and efficient experience for + visitors, and perform essential functions such as allowing users to register and remain logged + in. Cookies may be set by the site that you are visiting (known as “first-party cookies”), or by + third parties, such as those who serve content or provide advertising or analytics services on + the website (“third-party cookies”).

    +
    Cookies Set by MonitorMyWatershed.org
    +

    We use cookies for a number of different purposes. Some cookies are necessary for technical + reasons, some enable a personalized experience for both visitors and registered users. Some of + these cookies may be set when a page is loaded, or only when a visitor takes a particular + action.

    +
    Forms-Related Cookies
    +

    When you submit data through a form, cookies may be set to remember your user details.

    +
    Third-Party Cookies
    +

    This site uses Google Analytics which is one of the most widespread and trusted analytics + solution on the web for helping us to understand how you use the site and ways that we can + improve your experience. These cookies may track things such as how long you spend on the site + and the pages that you visit so we can continue to produce engaging content. Visit + this page for + more information on Google Analytics cookies.

    +
    Controlling Cookies
    +

    Visitors may wish to restrict the use of cookies, or completely prevent them from being set. Most + browsers provide for ways to control cookie behavior such as the length of time they are stored + — either through built-in functionality or by utilizing third-party plugins.

    +

    It’s important to note that restricting or disabling the use of cookies can limit the + functionality of websites, or prevent them from working correctly at all.

    +

    To find out more on how to manage and delete cookies, visit aboutcookies.org. For more details + on advertising cookies, and how to manage them, visit youronlinechoices.eu (EU-based), or + aboutads.info (US-based).

    +

    Some specific opt-out programs are available here:

    + +
    +
    +
    +
    +{% endblock %} \ No newline at end of file diff --git a/src/dataloaderinterface/templates/dataloaderinterface/footer.html b/src/dataloaderinterface/templates/dataloaderinterface/footer.html index ed236efa..457cc9e1 100644 --- a/src/dataloaderinterface/templates/dataloaderinterface/footer.html +++ b/src/dataloaderinterface/templates/dataloaderinterface/footer.html @@ -17,7 +17,8 @@
    All content on this website is licensed as
    POLICIES
    Terms of Use
    - Privacy + Privacy
    + Cookies
    diff --git a/src/dataloaderinterface/urls.py b/src/dataloaderinterface/urls.py index 9759eb7a..6a61a16b 100644 --- a/src/dataloaderinterface/urls.py +++ b/src/dataloaderinterface/urls.py @@ -17,7 +17,7 @@ from dataloaderinterface.views import SitesListView, SiteDetailView, SiteRegistrationView, SensorListUpdateView, \ HomeView, BrowseSitesListView, SiteUpdateView, SiteDeleteView, StatusListView, LeafPackListUpdateView, \ - TermsOfUseView, DMCAView, PrivacyView + TermsOfUseView, DMCAView, PrivacyView, CookiePolicyView urlpatterns = [ url(r'^$', HomeView.as_view(), name='home'), @@ -25,6 +25,7 @@ url(r'^terms/$', TermsOfUseView.as_view(), name='terms_of_use'), url(r'^dmca/$', DMCAView.as_view(), name='dmca'), url(r'^privacy/$', PrivacyView.as_view(), name='privacy'), + url(r'^cookies/$', CookiePolicyView.as_view(), name='cookie_policy'), url(r'^status/$', StatusListView.as_view(), name='status'), url(r'^browse/$', BrowseSitesListView.as_view(), name='browse_sites'), url(r'^sites/register/$', SiteRegistrationView.as_view(), name='site_registration'), diff --git a/src/dataloaderinterface/views.py b/src/dataloaderinterface/views.py index 7e82766a..2534edeb 100644 --- a/src/dataloaderinterface/views.py +++ b/src/dataloaderinterface/views.py @@ -42,6 +42,10 @@ class PrivacyView(TemplateView): template_name = 'dataloaderinterface/privacy.html' +class CookiePolicyView(TemplateView): + template_name = 'dataloaderinterface/cookie_policy.html' + + class SitesListView(LoginRequiredMixin, ListView): model = SiteRegistration context_object_name = 'sites' From ec39011095d825b4fb3e7f7ba3671d69bdb13a6b Mon Sep 17 00:00:00 2001 From: Maurier Date: Thu, 20 Dec 2018 12:52:40 -0700 Subject: [PATCH 12/34] [#324] Link cookie policy page in Privacy page --- .../templates/dataloaderinterface/privacy.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/dataloaderinterface/templates/dataloaderinterface/privacy.html b/src/dataloaderinterface/templates/dataloaderinterface/privacy.html index cc40a012..22420d8f 100644 --- a/src/dataloaderinterface/templates/dataloaderinterface/privacy.html +++ b/src/dataloaderinterface/templates/dataloaderinterface/privacy.html @@ -71,8 +71,8 @@
    Cookies

    A cookie is a string of information that a website stores on a visitor's computer, and that the visitor's browser provides to the website each time the visitor returns. Stroud Water Research Center and LimnoTech use cookies to help us identify and track visitors, their usage of our - websites, and their website access preferences. For more information, please see our Cookie - Policy.

    + websites, and their website access preferences. For more information, please see our Cookie Policy.

    Analytics

    Stroud Water Research Center and LimnoTech use Google Analytics to collect statistics about the behavior of visitors to their websites. To ensure that Google Analytics does not store From 10357c7cc3b8a8c16ad1c52db29bda3ec63b59c1 Mon Sep 17 00:00:00 2001 From: Maurier Date: Fri, 21 Dec 2018 09:09:02 -0700 Subject: [PATCH 13/34] [#324] Update link --- .../templates/dataloaderinterface/cookie_policy.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dataloaderinterface/templates/dataloaderinterface/cookie_policy.html b/src/dataloaderinterface/templates/dataloaderinterface/cookie_policy.html index 95092112..4eb53a4a 100644 --- a/src/dataloaderinterface/templates/dataloaderinterface/cookie_policy.html +++ b/src/dataloaderinterface/templates/dataloaderinterface/cookie_policy.html @@ -53,7 +53,7 @@

    Controlling Cookies

    It’s important to note that restricting or disabling the use of cookies can limit the functionality of websites, or prevent them from working correctly at all.

    To find out more on how to manage and delete cookies, visit aboutcookies.org. For more details + href="https://cookies.insites.com/" target="_blank">cookies.insites.com. For more details on advertising cookies, and how to manage them, visit youronlinechoices.eu (EU-based), or aboutads.info (US-based).

    From 9f3e0fd576a70a8a69f3a66aee96d04b608690e5 Mon Sep 17 00:00:00 2001 From: Maurier Date: Fri, 21 Dec 2018 09:28:13 -0700 Subject: [PATCH 14/34] [#347] Minor alignment fixes --- .../templates/dataloaderinterface/manage_sensors.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/dataloaderinterface/templates/dataloaderinterface/manage_sensors.html b/src/dataloaderinterface/templates/dataloaderinterface/manage_sensors.html index 89ae9047..2c561fa8 100644 --- a/src/dataloaderinterface/templates/dataloaderinterface/manage_sensors.html +++ b/src/dataloaderinterface/templates/dataloaderinterface/manage_sensors.html @@ -176,13 +176,13 @@ No file chosen. - From c96ffc4a9fb371a3a51f0f3e9395b9ac2f788507 Mon Sep 17 00:00:00 2001 From: Maurier Date: Fri, 21 Dec 2018 11:07:22 -0700 Subject: [PATCH 15/34] [#347] Allow user dismissible messages --- .../static/dataloaderinterface/css/style.css | 4 ++ .../dataloaderinterface/js/manage-sensors.js | 6 +-- .../dataloaderinterface/js/websdl-utils.js | 44 ++++++++++++++++--- .../templates/dataloaderinterface/base.html | 2 +- .../dataloaderinterface/manage_sensors.html | 12 +++-- 5 files changed, 54 insertions(+), 14 deletions(-) diff --git a/src/dataloaderinterface/static/dataloaderinterface/css/style.css b/src/dataloaderinterface/static/dataloaderinterface/css/style.css index 98796a4c..61f170e2 100644 --- a/src/dataloaderinterface/static/dataloaderinterface/css/style.css +++ b/src/dataloaderinterface/static/dataloaderinterface/css/style.css @@ -1442,6 +1442,10 @@ div.file-preview .file-name { word-break: break-word; } +#file-preview-default { + align-self: center; +} + i.file-icon { font-size: 30px; color: #66cbcb; diff --git a/src/dataloaderinterface/static/dataloaderinterface/js/manage-sensors.js b/src/dataloaderinterface/static/dataloaderinterface/js/manage-sensors.js index 98046b54..7b75c974 100644 --- a/src/dataloaderinterface/static/dataloaderinterface/js/manage-sensors.js +++ b/src/dataloaderinterface/static/dataloaderinterface/js/manage-sensors.js @@ -391,16 +391,16 @@ $(document).ready(function () { contentType: false, processData: false }).done(function (response) { - console.log(response); + // console.log(response); snackbarMsg("Data was uploaded successfully!"); uploadFileButton.prop("disabled", false); }).fail(function (error) { console.log(error); try { - snackbarMsg("Failed to upload data. " + error.responseJSON.error) + snackbarMsg("Failed to upload data. " + error.responseJSON.error, true) } catch (err) { - snackbarMsg("Failed to upload data.") + snackbarMsg("Failed to upload data.", true) } uploadFileButton.prop("disabled", true); diff --git a/src/dataloaderinterface/static/dataloaderinterface/js/websdl-utils.js b/src/dataloaderinterface/static/dataloaderinterface/js/websdl-utils.js index 727e366f..70f53559 100644 --- a/src/dataloaderinterface/static/dataloaderinterface/js/websdl-utils.js +++ b/src/dataloaderinterface/static/dataloaderinterface/js/websdl-utils.js @@ -39,14 +39,46 @@ $(document).on('click', ".menu-order li", function () { localStorage.setItem("UISortState", JSON.stringify(UISortState)); }); -function snackbarMsg(message, duration = 3000) { - var snackbarContainer = document.querySelector('#clipboard-snackbar'); - snackbarContainer.MaterialSnackbar.showSnackbar({ - message: message, - timeout: duration - }); +// Displays a snack bar message +function snackbarMsg(message, persistent = false) { + var snackbar = document.querySelector('#clipboard-snackbar'); + if (!persistent) { + snackbar.MaterialSnackbar.showSnackbar({ + message: message, + }); + } + else { + snackbar.MaterialSnackbar.showSnackbar({ + message: message, + actionHandler: function () {}, // Just needs a function reference + actionText: "Dismiss", + timeout: -1 // Makes it persistent + }); + } } +// Override to allow persistent messages +MaterialSnackbar.prototype.displaySnackbar_ = function () { + this.element_.setAttribute('aria-hidden', 'true'); + if (this.actionHandler_) { + this.actionElement_.textContent = this.actionText_; + this.actionElement_.addEventListener('click', this.actionHandler_); + this.setActionHidden_(false); + } + this.textElement_.textContent = this.message_; + this.element_.classList.add(this.cssClasses_.ACTIVE); + this.element_.setAttribute('aria-hidden', 'false'); + + if (this.timeout_ > -1) { + setTimeout(this.cleanup_.bind(this), this.timeout_); + } + else { + this.actionElement_.addEventListener('click', function () { + setTimeout(this.cleanup_.bind(this), 0); + }.bind(this)); + } +}; + // Taken from https://stackoverflow.com/questions/15900485/correct-way-to-convert-size-in-bytes-to-kb-mb-gb-in-javascript function formatBytes(bytes, decimals) { if (bytes == 0) return '0 Bytes'; diff --git a/src/dataloaderinterface/templates/dataloaderinterface/base.html b/src/dataloaderinterface/templates/dataloaderinterface/base.html index 8ec850b0..4f2ab142 100644 --- a/src/dataloaderinterface/templates/dataloaderinterface/base.html +++ b/src/dataloaderinterface/templates/dataloaderinterface/base.html @@ -126,7 +126,7 @@ {% block content %}{% endblock %}
    - +
    diff --git a/src/dataloaderinterface/templates/dataloaderinterface/manage_sensors.html b/src/dataloaderinterface/templates/dataloaderinterface/manage_sensors.html index 2c561fa8..af8e56c1 100644 --- a/src/dataloaderinterface/templates/dataloaderinterface/manage_sensors.html +++ b/src/dataloaderinterface/templates/dataloaderinterface/manage_sensors.html @@ -173,16 +173,20 @@
    - + No file chosen. From 209c6b26b558e26fe6f50c1731482fbe542f081c Mon Sep 17 00:00:00 2001 From: Maurier Date: Fri, 21 Dec 2018 11:11:10 -0700 Subject: [PATCH 16/34] [#347] Move inline css --- .../static/dataloaderinterface/css/style.css | 5 +++++ .../templates/dataloaderinterface/manage_sensors.html | 3 +-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/dataloaderinterface/static/dataloaderinterface/css/style.css b/src/dataloaderinterface/static/dataloaderinterface/css/style.css index 61f170e2..7950e304 100644 --- a/src/dataloaderinterface/static/dataloaderinterface/css/style.css +++ b/src/dataloaderinterface/static/dataloaderinterface/css/style.css @@ -1433,6 +1433,11 @@ textarea[name="sensor_notes"] { top: 10px; } +#btn-upload-file { + margin-left: 10px; + align-self: center; +} + div.file-preview { height: auto; padding: 1em; diff --git a/src/dataloaderinterface/templates/dataloaderinterface/manage_sensors.html b/src/dataloaderinterface/templates/dataloaderinterface/manage_sensors.html index af8e56c1..401bd754 100644 --- a/src/dataloaderinterface/templates/dataloaderinterface/manage_sensors.html +++ b/src/dataloaderinterface/templates/dataloaderinterface/manage_sensors.html @@ -185,8 +185,7 @@
    From ee9556a84ad2a297b3104aef320517d3b4dec6c0 Mon Sep 17 00:00:00 2001 From: Maurier Date: Fri, 21 Dec 2018 12:03:41 -0700 Subject: [PATCH 17/34] [#307] Add overlapping markers logic to Browse Sites page --- .../dataloaderinterface/js/browse-sites.js | 9 +++++- .../dataloaderinterface/js/vendor/oms.min.js | 28 +++++++++++++++++++ .../dataloaderinterface/browse-sites.html | 1 + 3 files changed, 37 insertions(+), 1 deletion(-) create mode 100644 src/dataloaderinterface/static/dataloaderinterface/js/vendor/oms.min.js diff --git a/src/dataloaderinterface/static/dataloaderinterface/js/browse-sites.js b/src/dataloaderinterface/static/dataloaderinterface/js/browse-sites.js index dfd75224..9bed6c04 100644 --- a/src/dataloaderinterface/static/dataloaderinterface/js/browse-sites.js +++ b/src/dataloaderinterface/static/dataloaderinterface/js/browse-sites.js @@ -100,6 +100,12 @@ function initMap() { dataString = dataString.replace(/[\u0000-\u0019]+/g, ""); // from https://stackoverflow.com/questions/14432165/uncaught-syntaxerror-unexpected-token-with-json-parse + let oms = new OverlappingMarkerSpiderfier(map, { + markersWontMove: true, + markersWontHide: true, + basicFormatEvents: true + }); + let markerData = JSON.parse(dataString); markerData.forEach(function(site) { @@ -115,7 +121,7 @@ function initMap() { marker[filters[f].key] = site[filters[f].key]; } - marker.addListener('click', function () { + marker.addListener('spider_click', function () { if (prevMarker) { prevMarker.setZIndex(prevZIndex); } @@ -130,6 +136,7 @@ function initMap() { marker.setZIndex(google.maps.Marker.MAX_ZINDEX + 1); // Bring the marker to the front }); + oms.addMarker(marker); markers.push(marker); }); diff --git a/src/dataloaderinterface/static/dataloaderinterface/js/vendor/oms.min.js b/src/dataloaderinterface/static/dataloaderinterface/js/vendor/oms.min.js new file mode 100644 index 00000000..7558b761 --- /dev/null +++ b/src/dataloaderinterface/static/dataloaderinterface/js/vendor/oms.min.js @@ -0,0 +1,28 @@ +/* + OverlappingMarkerSpiderfier +https://github.com/jawj/OverlappingMarkerSpiderfier +Copyright (c) 2011 - 2017 George MacKerron +Released under the MIT licence: http://opensource.org/licenses/mit-license +Note: The Google Maps API v3 must be included *before* this code +*/ +(function(){var m,t,w,y,u,z={}.hasOwnProperty,A=[].slice;this.OverlappingMarkerSpiderfier=function(){function r(a,d){var b,f,e;this.map=a;null==d&&(d={});null==this.constructor.N&&(this.constructor.N=!0,h=google.maps,l=h.event,p=h.MapTypeId,c.keepSpiderfied=!1,c.ignoreMapClick=!1,c.markersWontHide=!1,c.markersWontMove=!1,c.basicFormatEvents=!1,c.nearbyDistance=20,c.circleSpiralSwitchover=9,c.circleFootSeparation=23,c.circleStartAngle=x/12,c.spiralFootSeparation=26,c.spiralLengthStart=11,c.spiralLengthFactor= +4,c.spiderfiedZIndex=h.Marker.MAX_ZINDEX+2E4,c.highlightedLegZIndex=h.Marker.MAX_ZINDEX+1E4,c.usualLegZIndex=h.Marker.MAX_ZINDEX+1,c.legWeight=1.5,c.legColors={usual:{},highlighted:{}},e=c.legColors.usual,f=c.legColors.highlighted,e[p.HYBRID]=e[p.SATELLITE]="#fff",f[p.HYBRID]=f[p.SATELLITE]="#f00",e[p.TERRAIN]=e[p.ROADMAP]="#444",f[p.TERRAIN]=f[p.ROADMAP]="#f00",this.constructor.j=function(a){return this.setMap(a)},this.constructor.j.prototype=new h.OverlayView,this.constructor.j.prototype.draw=function(){}); +for(b in d)z.call(d,b)&&(f=d[b],this[b]=f);this.g=new this.constructor.j(this.map);this.C();this.c={};this.B=this.l=null;this.addListener("click",function(a,b){return l.trigger(a,"spider_click",b)});this.addListener("format",function(a,b){return l.trigger(a,"spider_format",b)});this.ignoreMapClick||l.addListener(this.map,"click",function(a){return function(){return a.unspiderfy()}}(this));l.addListener(this.map,"maptypeid_changed",function(a){return function(){return a.unspiderfy()}}(this));l.addListener(this.map, +"zoom_changed",function(a){return function(){a.unspiderfy();if(!a.basicFormatEvents)return a.h()}}(this))}var l,h,m,v,p,c,t,x,u;c=r.prototype;t=[r,c];m=0;for(v=t.length;md)return this;g=this.s.splice(d,1)[0];b=0;for(f=g.length;bb||this.c[a].splice(b,1);return this};c.clearListeners=function(a){this.c[a]=[];return this};c.trigger=function(){var a,d,b,f,e,g;d=arguments[0];a=2<=arguments.length?A.call(arguments,1):[];d=null!=(b=this.c[d])?b:[];g=[];f=0;for(e=d.length;fa;b=0<=a?++e:--e)b= +this.circleStartAngle+b*f,c.push(new h.Point(d.x+g*Math.cos(b),d.y+g*Math.sin(b)));return c};c.M=function(a,d){var b,f,e,c,k;c=this.spiralLengthStart;b=0;k=[];for(f=e=0;0<=a?ea;f=0<=a?++e:--e)b+=this.spiralFootSeparation/c+5E-4*f,f=new h.Point(d.x+c*Math.cos(b),d.y+c*Math.sin(b)),c+=x*this.spiralLengthFactor/b,k.push(f);return k};c.V=function(a,d){var b,f,e,c,k,q,n,l,h;(q=null!=a._omsData)&&this.keepSpiderfied||this.unspiderfy();if(q||this.map.getStreetView().getVisible()||"GoogleEarthAPI"=== +this.map.getMapTypeId())return this.trigger("click",a,d);q=[];n=[];b=this.nearbyDistance;l=b*b;k=this.f(a.position);h=this.a;b=0;for(f=h.length;b=this.circleSpiralSwitchover?this.M(r,b).reverse():this.L(r,b);b=function(){var b,d,f;f=[];b=0;for(d=g.length;b + {% endblock %} \ No newline at end of file From d1cfb8d30e498f3884ab9ac016ca0a7897781298 Mon Sep 17 00:00:00 2001 From: Maurier Date: Fri, 21 Dec 2018 12:07:46 -0700 Subject: [PATCH 18/34] [#307] Add overlapping markers logic to My Sites page --- .../static/dataloaderinterface/js/my-sites.js | 9 ++++++++- .../templates/dataloaderinterface/my-sites.html | 1 + 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/dataloaderinterface/static/dataloaderinterface/js/my-sites.js b/src/dataloaderinterface/static/dataloaderinterface/js/my-sites.js index 55d264fd..6561c1e1 100644 --- a/src/dataloaderinterface/static/dataloaderinterface/js/my-sites.js +++ b/src/dataloaderinterface/static/dataloaderinterface/js/my-sites.js @@ -54,6 +54,12 @@ function initMap() { var prevMarker; var prevZIndex; + let oms = new OverlappingMarkerSpiderfier(map, { + markersWontMove: true, + markersWontHide: true, + basicFormatEvents: true + }); + markerData.forEach(function(site) { var marker = new google.maps.Marker({ position: { lat: site.latitude, lng: site.longitude }, @@ -64,7 +70,7 @@ function initMap() { bounds.extend(marker.getPosition()); - marker.addListener('click', function () { + marker.addListener('spider_click', function () { if (prevMarker) { prevMarker.setZIndex(prevZIndex); } @@ -92,6 +98,7 @@ function initMap() { scrollTop: 0 }, 150); }); + oms.addMarker(marker); }); if (!sessionStorage.getItem('MY_CURRENT_CENTER')){ diff --git a/src/dataloaderinterface/templates/dataloaderinterface/my-sites.html b/src/dataloaderinterface/templates/dataloaderinterface/my-sites.html index e2b06c03..3daa70a2 100644 --- a/src/dataloaderinterface/templates/dataloaderinterface/my-sites.html +++ b/src/dataloaderinterface/templates/dataloaderinterface/my-sites.html @@ -376,5 +376,6 @@ + {% endblock %} \ No newline at end of file From d28c53580e531cbb5daae80c37cc8eefb4fe70f9 Mon Sep 17 00:00:00 2001 From: Maurier Date: Fri, 21 Dec 2018 12:45:37 -0700 Subject: [PATCH 19/34] Remove unnecessary timeout --- .../static/dataloaderinterface/js/websdl-utils.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dataloaderinterface/static/dataloaderinterface/js/websdl-utils.js b/src/dataloaderinterface/static/dataloaderinterface/js/websdl-utils.js index 70f53559..cef15e97 100644 --- a/src/dataloaderinterface/static/dataloaderinterface/js/websdl-utils.js +++ b/src/dataloaderinterface/static/dataloaderinterface/js/websdl-utils.js @@ -74,7 +74,7 @@ MaterialSnackbar.prototype.displaySnackbar_ = function () { } else { this.actionElement_.addEventListener('click', function () { - setTimeout(this.cleanup_.bind(this), 0); + this.cleanup_(); }.bind(this)); } }; From ccd16ba3b587a220d66fbef0a082c558d4da7bbf Mon Sep 17 00:00:00 2001 From: Maurier Date: Sun, 23 Dec 2018 08:17:51 -0700 Subject: [PATCH 20/34] Update sort methods --- .../static/dataloaderinterface/js/websdl-utils.js | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/src/dataloaderinterface/static/dataloaderinterface/js/websdl-utils.js b/src/dataloaderinterface/static/dataloaderinterface/js/websdl-utils.js index cef15e97..178d541b 100644 --- a/src/dataloaderinterface/static/dataloaderinterface/js/websdl-utils.js +++ b/src/dataloaderinterface/static/dataloaderinterface/js/websdl-utils.js @@ -24,13 +24,10 @@ $(document).on('click', ".menu-order li", function () { var sortBy = $(this).parent().find("li[data-sort-by].active").attr("data-sort-by"); var order = $(this).parent().find("li[data-order].active").attr("data-order"); + var orderInt = order === "asc" ? 1 : -1; $(target + ' .sortable').sort(function (a, b) { - if (order == "asc") { - return (a.dataset[sortBy].toUpperCase() > b.dataset[sortBy].toUpperCase()); - } - - return (a.dataset[sortBy].toUpperCase() < b.dataset[sortBy].toUpperCase()); + return (a.dataset[sortBy] > b.dataset[sortBy] ? orderInt : -orderInt); }).appendTo(target); var UISortState = JSON.parse(localStorage.getItem("UISortState")) || {}; @@ -96,17 +93,14 @@ $(document).ready(function () { for (var item in UISortState) { var sortBy = UISortState[item].sortBy; var order = UISortState[item].order; + var orderInt = order === "asc" ? 1 : -1; var ul = $("ul[data-sort-target='" + item + "']"); ul.find("[data-sort-by='" + sortBy + "']").addClass("active"); ul.find("[data-order='" + order + "']").addClass("active"); $(item + ' .sortable').sort(function (a, b) { - if (order == "asc") { - return (a.dataset[sortBy] > b.dataset[sortBy]); - } - - return (a.dataset[sortBy] < b.dataset[sortBy]); + return (a.dataset[sortBy] > b.dataset[sortBy] ? orderInt : -orderInt); }).appendTo(item); $(item).addClass("sorted"); From afdd69407412aa0543da2a2ea8aad940da392647 Mon Sep 17 00:00:00 2001 From: Maurier Date: Sun, 23 Dec 2018 09:42:03 -0700 Subject: [PATCH 21/34] Add logic to disable button during form submit --- .../static/dataloaderinterface/css/style.css | 8 ++++++++ .../static/dataloaderinterface/js/websdl-utils.js | 14 ++++++++++++++ .../templates/leafpack/leafpack_registration.html | 8 ++------ 3 files changed, 24 insertions(+), 6 deletions(-) diff --git a/src/dataloaderinterface/static/dataloaderinterface/css/style.css b/src/dataloaderinterface/static/dataloaderinterface/css/style.css index 7950e304..258c6f87 100644 --- a/src/dataloaderinterface/static/dataloaderinterface/css/style.css +++ b/src/dataloaderinterface/static/dataloaderinterface/css/style.css @@ -1466,4 +1466,12 @@ i.file-icon { top: 0; width: 300px; z-index: 4; +} + +.button--disabled { + color: rgba(0, 0, 0, .26) !important; + background-color: rgba(0, 0, 0, .12) !important; + box-shadow: none !important; + pointer-events: none !important; + cursor: default !important; } \ No newline at end of file diff --git a/src/dataloaderinterface/static/dataloaderinterface/js/websdl-utils.js b/src/dataloaderinterface/static/dataloaderinterface/js/websdl-utils.js index 178d541b..cfa7999f 100644 --- a/src/dataloaderinterface/static/dataloaderinterface/js/websdl-utils.js +++ b/src/dataloaderinterface/static/dataloaderinterface/js/websdl-utils.js @@ -36,6 +36,20 @@ $(document).on('click', ".menu-order li", function () { localStorage.setItem("UISortState", JSON.stringify(UISortState)); }); +$(document).on('click', ".button--disable-after", function () { + let form = $(this).closest("form"); + if (form[0].checkValidity()) { + if ($(this).text().trim().toUpperCase() == "SAVE EDITS") { + $(this).text("Saving..."); + } + else if ($(this).text().trim().toUpperCase() == "SUBMIT") { + $(this).text("Submitting..."); + } + + $(this).toggleClass("button--disabled", true); + } +}); + // Displays a snack bar message function snackbarMsg(message, persistent = false) { var snackbar = document.querySelector('#clipboard-snackbar'); diff --git a/src/dataloaderinterface/templates/leafpack/leafpack_registration.html b/src/dataloaderinterface/templates/leafpack/leafpack_registration.html index 0a3c6563..baa762b7 100644 --- a/src/dataloaderinterface/templates/leafpack/leafpack_registration.html +++ b/src/dataloaderinterface/templates/leafpack/leafpack_registration.html @@ -273,12 +273,8 @@
    Is there anything else you’d like to tell href="{% url 'leafpack:view' sampling_feature_code leafpack.id %}" {% endif %} >Cancel - From e2b80ba146558be34d8b7c2064d179fc4cc52243 Mon Sep 17 00:00:00 2001 From: Juan Date: Thu, 31 Jan 2019 10:21:54 -0400 Subject: [PATCH 22/34] Created an InfluxDB helper class to better manage connections and data transfer to the database. --- src/WebSDL/settings/base.py | 2 + src/dataloader/helpers.py | 86 +++++++++++++++++++ .../commands/fix_last_measurement_data.py | 39 +++++++++ .../commands/fix_site_deployment_date.py | 27 ------ .../commands/generate_influx_data.py | 35 ++++++++ src/dataloaderinterface/models.py | 6 +- 6 files changed, 167 insertions(+), 28 deletions(-) create mode 100644 src/dataloader/helpers.py create mode 100644 src/dataloaderinterface/management/commands/fix_last_measurement_data.py delete mode 100644 src/dataloaderinterface/management/commands/fix_site_deployment_date.py create mode 100644 src/dataloaderinterface/management/commands/generate_influx_data.py diff --git a/src/WebSDL/settings/base.py b/src/WebSDL/settings/base.py index 7e342e5c..28e95819 100644 --- a/src/WebSDL/settings/base.py +++ b/src/WebSDL/settings/base.py @@ -122,6 +122,8 @@ 'TEST': database['test'] if 'test' in database else {}, } +INFLUX_CONNECTION = data['influx_connection'] + # Password validation # https://docs.djangoproject.com/en/1.9/ref/settings/#auth-password-validators diff --git a/src/dataloader/helpers.py b/src/dataloader/helpers.py new file mode 100644 index 00000000..eb57586f --- /dev/null +++ b/src/dataloader/helpers.py @@ -0,0 +1,86 @@ +from datetime import datetime + +import pandas as pd +import numpy as np + +from django.conf import settings +from django.db.models import F + +from influxdb import DataFrameClient +from influxdb.exceptions import InfluxDBClientError + +from dataloader.models import TimeSeriesResultValue + + +class InfluxHelper(object): + class MissingConnectionException(Exception): + """Client is not defined or connected""" + pass + + def __init__(self, *args, **kwargs): + self.client = None + self.batch_size = 10000 + self.connection_info = settings.INFLUX_CONNECTION + + def connect_to_dataframe_client(self): + self.client = DataFrameClient( + host=self.connection_info['host'], + port=self.connection_info['port'], + username=self.connection_info['username'], + password=self.connection_info['password'], + database=self.connection_info['database'] + ) + + def recreate_database(self): + read_user = self.connection_info['read_username'] + database_name = self.connection_info['database'] + + if not self.client: + raise InfluxHelper.MissingConnectionException('InfluxDB client is not connected.') + + self.client.drop_database(database_name) + self.client.create_database(database_name) + self.client.grant_privilege('read', database_name, read_user) + + def write_all_sensor_values(self, sensor): + self.write_sensor_values(sensor, datetime.min) + + def get_series_last_value(self, identifier): + query_string = 'select last(DataValue), time from {identifier}'.format(identifier=identifier) + result = self.client.query(query_string, database=self.connection_info['database']) + if result and len(result) == 1: + dataframe = result[identifier] # type: pd.DataFrame + return dataframe.first_valid_index().to_pydatetime() + + def write_sensor_values(self, sensor, starting_datetime): + values = TimeSeriesResultValue.objects.filter(value_datetime__gt=starting_datetime, result_id=sensor.result_id)\ + .annotate(DateTime=F('value_datetime'))\ + .annotate(UTCOffset=F('value_datetime_utc_offset'))\ + .annotate(DataValue=F('data_value')) + values_dataframe = self.prepare_data_values(values) + if values_dataframe.empty: + return 0 + + result = self.add_dataframe_to_database(values_dataframe, sensor.influx_identifier) + del values_dataframe + return result + + def prepare_data_values(self, values_queryset): + dataframe = pd.DataFrame.from_records(values_queryset.values('DateTime', 'UTCOffset', 'DataValue')) + if dataframe.empty: + return dataframe + + dataframe['DateTime'] = pd.to_datetime(dataframe['DateTime']) + dataframe.set_index(['DateTime'], inplace=True) + dataframe['DataValue'] = pd.to_numeric(dataframe['DataValue'], errors='coerce').astype(np.float64) + dataframe['UTCOffset'] = pd.to_numeric(dataframe['UTCOffset'], errors='coerce').astype(np.float64) + dataframe.dropna(how='any', inplace=True) + return dataframe + + def add_dataframe_to_database(self, dataframe, identifier): + try: + write_success = self.client.write_points(dataframe, identifier, time_precision='s', batch_size=self.batch_size) + return len(dataframe) if write_success else 0 + except InfluxDBClientError as e: + print 'Error while writing to database {}: {}'.format(identifier, e.message) + return 0 diff --git a/src/dataloaderinterface/management/commands/fix_last_measurement_data.py b/src/dataloaderinterface/management/commands/fix_last_measurement_data.py new file mode 100644 index 00000000..763d55bd --- /dev/null +++ b/src/dataloaderinterface/management/commands/fix_last_measurement_data.py @@ -0,0 +1,39 @@ +from datetime import timedelta + +from django.core.management.base import BaseCommand +from django.db.models import Count +from django.db.models.aggregates import Min + +from dataloader.models import TimeSeriesResult +from dataloaderinterface.models import SiteRegistration, SiteSensor, SensorMeasurement + + +class Command(BaseCommand): + help = '' + + def handle(self, *args, **options): + print('- Getting results') + results = TimeSeriesResult.objects.annotate(values_count=Count('values')).all() + print('- {} results found'.format(results.count())) + + for result in results: + sensor = SiteSensor.objects.filter(result_id=result.result_id).first() + if not sensor: + continue + + if not result.values_count: + continue + + print('- creating last measurement data for {}'.format(sensor.sensor_identity)) + last_data_value = result.values.latest('value_datetime') + + last_measurement = SensorMeasurement.objects.filter(sensor=sensor).first() + last_measurement and last_measurement.delete() + + SensorMeasurement.objects.create( + sensor=sensor, + value_datetime=last_data_value.value_datetime, + value_datetime_utc_offset=timedelta(hours=last_data_value.value_datetime_utc_offset), + data_value=last_data_value.data_value + ) + print('- Done!') diff --git a/src/dataloaderinterface/management/commands/fix_site_deployment_date.py b/src/dataloaderinterface/management/commands/fix_site_deployment_date.py deleted file mode 100644 index a202eb9c..00000000 --- a/src/dataloaderinterface/management/commands/fix_site_deployment_date.py +++ /dev/null @@ -1,27 +0,0 @@ -from django.core.management.base import BaseCommand -from django.db.models.aggregates import Min - -from dataloaderinterface.models import SiteRegistration - - -class Command(BaseCommand): - help = '' - - def update_sensors_activation_date(self, site): - for sensor in site.sensors.all(): - series_result = sensor.result.timeseriesresult # ouch is this incredibly slow - if series_result.values.count() == 0: # lol even more so - continue - - earliest_value = series_result.values.earliest('value_datetime') - sensor.activation_date = earliest_value.value_datetime - sensor.activation_date_utc_offset = earliest_value.value_datetime_utc_offset - sensor.save(update_fields=['activation_date', 'activation_date_utc_offset']) - - def handle(self, *args, **options): - sites = SiteRegistration.objects.prefetch_related('sensors').all() - for site in sites: - self.update_sensors_activation_date(site) - min_datetime = site.sensors.aggregate(first_light=Min('activation_date')) - site.deployment_date = min_datetime['first_light'] - site.save(update_fields=['deployment_date']) \ No newline at end of file diff --git a/src/dataloaderinterface/management/commands/generate_influx_data.py b/src/dataloaderinterface/management/commands/generate_influx_data.py new file mode 100644 index 00000000..5f5ec834 --- /dev/null +++ b/src/dataloaderinterface/management/commands/generate_influx_data.py @@ -0,0 +1,35 @@ +from datetime import datetime + +from django.core.management import BaseCommand + +from dataloader.helpers import InfluxHelper +from dataloaderinterface.models import SiteSensor + + +class Command(BaseCommand): + help = 'Copy data values over to the InfluxDB instance.' + + def add_arguments(self, parser): + parser.add_argument( + '--clean', + action='store_true', + dest='clean', + help='Drop the influx database before filling up data.', + ) + + def handle(self, *args, **options): + recreate_database = options.get('clean') + + helper = InfluxHelper() + helper.connect_to_dataframe_client() + sensors = SiteSensor.objects.all() + + if recreate_database: + helper.recreate_database() + + for sensor in sensors: + print('- writing data to sensor {}'.format(sensor.sensor_identity)) + last_value = helper.get_series_last_value(sensor.influx_identifier) + starting_point = last_value and last_value.replace(tzinfo=None) or datetime.min + result = helper.write_sensor_values(sensor, starting_point) + print('-- {} points written.'.format(result)) diff --git a/src/dataloaderinterface/models.py b/src/dataloaderinterface/models.py index 8c963e02..f288d790 100644 --- a/src/dataloaderinterface/models.py +++ b/src/dataloaderinterface/models.py @@ -187,11 +187,15 @@ def influx_url(self): return return settings.INFLUX_URL_QUERY.format( - result_uuid=str(self.result_uuid).replace('-', '_'), + result_uuid=self.influx_identifier, last_measurement=self.last_measurement.value_datetime.strftime('%Y-%m-%dT%H:%M:%SZ'), days_of_data=settings.SENSOR_DATA_PERIOD ) + @property + def influx_identifier(self): + return 'uuid_{}'.format(str(self.result_uuid).replace('-', '_')) + def __str__(self): return '%s' % (self.sensor_identity) From c94b6891b9f94dbed8c820cb04abcacfda533803 Mon Sep 17 00:00:00 2001 From: Juan Date: Thu, 31 Jan 2019 10:26:32 -0400 Subject: [PATCH 23/34] Created command to copy data values over from one odm2 database to another. --- .../management/commands/copy_data_values.py | 43 +++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 src/dataloaderinterface/management/commands/copy_data_values.py diff --git a/src/dataloaderinterface/management/commands/copy_data_values.py b/src/dataloaderinterface/management/commands/copy_data_values.py new file mode 100644 index 00000000..06bf9d47 --- /dev/null +++ b/src/dataloaderinterface/management/commands/copy_data_values.py @@ -0,0 +1,43 @@ +from datetime import datetime + +from django.core.management.base import BaseCommand +from django.db import IntegrityError + +from dataloader.models import TimeSeriesResultValue + + +class Command(BaseCommand): + help = 'Copy the data values from a production database over to a staging or testing database.' + + def add_arguments(self, parser): + parser.add_argument('source', type=str, help='The source database name as specified in settings.json.') + parser.add_argument('destination', type=str, help='The destination database name as specified in settings.json.') + parser.add_argument('date', type=str, help='The starting date for the data copy in UTC time with the ISO 8601 format (%Y-%m-%dT%H:%M:%S).') + + def handle(self, *args, **options): + source = options['source'] + destination = options['destination'] + start_date = datetime.strptime(options['date'], "%Y-%m-%dT%H:%M:%S") + + print('- Getting data values.') + data_values = TimeSeriesResultValue.objects.using(source).filter(value_datetime__gte=start_date) + print('- {} data values found.'.format(data_values.count())) + + for data_value in data_values: + try: + copied_value = TimeSeriesResultValue.objects.using(destination).create( + value_datetime=data_value.value_datetime, + value_datetime_utc_offset=data_value.value_datetime_utc_offset, + result_id=data_value.result_id, + data_value=data_value.data_value, + censor_code=data_value.censor_code, + quality_code=data_value.quality_code, + time_aggregation_interval=data_value.time_aggregation_interval, + time_aggregation_interval_unit=data_value.time_aggregation_interval_unit + ) + print('{} - {} in result {}'.format(copied_value.pk, copied_value.value_datetime, copied_value.result_id)) + + except IntegrityError as ve: + print('already exists {} - {} in result {}'.format(data_value.pk, data_value.value_datetime, data_value.result_id)) + + print('All {} values copied over to {}!'.format(source, destination)) From cf762c79bc5dc62bec47e56e6b7260393c3bbbe9 Mon Sep 17 00:00:00 2001 From: Juan Date: Thu, 31 Jan 2019 11:10:49 -0400 Subject: [PATCH 24/34] Wrote a `help` text on each django command. --- release_commands.txt | 4 ---- .../management/commands/check_data_loss.py | 5 +++-- .../management/commands/fix_last_measurement_data.py | 2 +- .../management/commands/generate_sensor_outputs.py | 2 +- .../management/commands/rebuild_tsa_catalog.py | 2 +- .../management/commands/update_controlled_vocabularies.py | 2 +- 6 files changed, 7 insertions(+), 10 deletions(-) diff --git a/release_commands.txt b/release_commands.txt index 0fe4718f..e69de29b 100644 --- a/release_commands.txt +++ b/release_commands.txt @@ -1,4 +0,0 @@ -dataloaderinterface/change_datetimes_to_utc -dataloaderinterface/generate_new_models_data -dataloaderinterface/set_leafpackdb_defaults -accounts/migrate_odm2user_model \ No newline at end of file diff --git a/src/dataloaderinterface/management/commands/check_data_loss.py b/src/dataloaderinterface/management/commands/check_data_loss.py index 75e7d81e..bccf6a1a 100644 --- a/src/dataloaderinterface/management/commands/check_data_loss.py +++ b/src/dataloaderinterface/management/commands/check_data_loss.py @@ -9,7 +9,8 @@ class Command(BaseCommand): - help = '' + help = 'Checks for sites that haven\'t received any data for longer than the threshold ' \ + 'set by the user who set up the alert, and sends an email alert.' @staticmethod def send_email(email_address, subject, message): @@ -46,4 +47,4 @@ def handle(self, *args, **options): success = Command.send_email(site_alert.user.email, subject, message) if success: site_alert.last_alerted = datetime.utcnow() - site_alert.save() \ No newline at end of file + site_alert.save() diff --git a/src/dataloaderinterface/management/commands/fix_last_measurement_data.py b/src/dataloaderinterface/management/commands/fix_last_measurement_data.py index 763d55bd..df764b2a 100644 --- a/src/dataloaderinterface/management/commands/fix_last_measurement_data.py +++ b/src/dataloaderinterface/management/commands/fix_last_measurement_data.py @@ -9,7 +9,7 @@ class Command(BaseCommand): - help = '' + help = 'Create `Last Measurement` objects for all sensors.' def handle(self, *args, **options): print('- Getting results') diff --git a/src/dataloaderinterface/management/commands/generate_sensor_outputs.py b/src/dataloaderinterface/management/commands/generate_sensor_outputs.py index 6f89bff6..c6a0b33f 100644 --- a/src/dataloaderinterface/management/commands/generate_sensor_outputs.py +++ b/src/dataloaderinterface/management/commands/generate_sensor_outputs.py @@ -6,7 +6,7 @@ class Command(BaseCommand): - help = '' + help = 'Generate `SensorOutput` objects for each Instrument Output Variable with every sampled medium.' def handle(self, *args, **options): sampled_media = SiteSensorForm.allowed_sampled_medium diff --git a/src/dataloaderinterface/management/commands/rebuild_tsa_catalog.py b/src/dataloaderinterface/management/commands/rebuild_tsa_catalog.py index 93240658..eaf0ae04 100644 --- a/src/dataloaderinterface/management/commands/rebuild_tsa_catalog.py +++ b/src/dataloaderinterface/management/commands/rebuild_tsa_catalog.py @@ -10,7 +10,7 @@ class Command(BaseCommand): - help = '' + help = 'Delete and rebuild the TSA Catalog table.' def handle(self, *args, **options): sensors = SiteSensor.objects.select_related('registration').prefetch_related('last_measurement', 'sensor_output')\ diff --git a/src/dataloaderinterface/management/commands/update_controlled_vocabularies.py b/src/dataloaderinterface/management/commands/update_controlled_vocabularies.py index fd888777..ef90afc3 100644 --- a/src/dataloaderinterface/management/commands/update_controlled_vocabularies.py +++ b/src/dataloaderinterface/management/commands/update_controlled_vocabularies.py @@ -39,7 +39,7 @@ class Command(BaseCommand): - help = '' + help = 'Update the ODM2 Controlled Vocabularies tables with the CVs in vocabulary.odm2.org' def handle(self, *args, **options): # TODO: These values should go in the settings.json file and not hardcoded. From dd6fc3800b327620a6abd1378dd0b5b2adeb427a Mon Sep 17 00:00:00 2001 From: Juan Date: Thu, 31 Jan 2019 11:11:13 -0400 Subject: [PATCH 25/34] Updated requirements file for this milestone. --- requirements.txt | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 036ddf51..47f5e6d0 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,7 +1,7 @@ beautifulsoup4==4.5.1 codegen==1.0 coverage==4.2 -Django==1.11.15 +Django==1.11.18 django-debug-toolbar==1.6 django-discover-runner==1.0 django-webtest==1.8.0 @@ -23,3 +23,6 @@ python-crontab==2.2.8 oauthlib==2.0.* django-reset-migrations==0.3.1 google-api-python-client==1.6.7 +django-admin-select2==1.0.1 +pandas==0.23.4 +influxdb==5.2.1 From 8123ac7370d97845023fee75cc31c9ef7a773c3a Mon Sep 17 00:00:00 2001 From: Juan Date: Thu, 31 Jan 2019 21:25:09 -0400 Subject: [PATCH 26/34] #365 Changed affiliation's queryset to only show the ones associated with a user. --- src/dataloaderinterface/forms.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/dataloaderinterface/forms.py b/src/dataloaderinterface/forms.py index cdbf7d4a..4e1643c6 100644 --- a/src/dataloaderinterface/forms.py +++ b/src/dataloaderinterface/forms.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- - +from django.contrib.auth import get_user_model from django.forms import NumberInput from django.forms.widgets import HiddenInput @@ -14,6 +14,12 @@ 'Storm sewer', 'Stream gage', 'Tidal stream', 'Water quality station', 'Weather station', 'Wetland', 'Other' ] +user_affiliations = [ + affiliation[0] + for affiliation + in get_user_model().objects.filter(affiliation_id__isnull=False).values_list('affiliation_id') +] + class SiteTypeSelect(forms.Select): site_types = { @@ -43,7 +49,7 @@ def label_from_instance(self, obj): class SiteRegistrationForm(forms.ModelForm): affiliation_id = forms.ModelChoiceField( - queryset=Affiliation.objects.for_display(), + queryset=Affiliation.objects.filter(affiliation_id__in=(user_affiliations)).for_display(), required=False, help_text='Select the user that deployed or manages the site', label='Deployed By' From cb826db4dacdbd8f33517f97bcb499080bab7c0f Mon Sep 17 00:00:00 2001 From: Anthony Aufdenkampe Date: Tue, 4 Jun 2019 10:24:30 -0500 Subject: [PATCH 27/34] Update for Django 1.11.20 Addressing #380. @jcaraballo17, can you confirm that everything else is correct? Were there any other silent updates? --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 47f5e6d0..0d26f230 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,7 +1,7 @@ beautifulsoup4==4.5.1 codegen==1.0 coverage==4.2 -Django==1.11.18 +Django==1.11.20 django-debug-toolbar==1.6 django-discover-runner==1.0 django-webtest==1.8.0 From 67a59b88b4aa3f71687ccecfe1229a51fe08c538 Mon Sep 17 00:00:00 2001 From: Juan Date: Thu, 13 Jun 2019 15:19:09 -0400 Subject: [PATCH 28/34] Updating with changed in hotfix-service-deployment-data. --- src/dataloaderservices/views.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dataloaderservices/views.py b/src/dataloaderservices/views.py index 79333a52..513d20db 100644 --- a/src/dataloaderservices/views.py +++ b/src/dataloaderservices/views.py @@ -598,7 +598,7 @@ def post(self, request, format=None): if not site_sensor.registration.deployment_date: site_sensor.registration.deployment_date = measurement_datetime - site_sensor.registration.deployment_date_utc_offset = utc_offset + #site_sensor.registration.deployment_date_utc_offset = utc_offset site_sensor.registration.save(update_fields=['deployment_date']) result.save(update_fields=[ From 73815c626317360939d1eb330b342404d8c2353b Mon Sep 17 00:00:00 2001 From: Juan Date: Thu, 13 Jun 2019 15:42:47 -0400 Subject: [PATCH 29/34] Updating with changes to tsa helper to make it use a separate influx server address. --- src/tsa/helpers.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/tsa/helpers.py b/src/tsa/helpers.py index 982fec7d..4ce101db 100644 --- a/src/tsa/helpers.py +++ b/src/tsa/helpers.py @@ -112,7 +112,7 @@ def generate_data_series(self, sensor, odm2_metadata, server_data): organization_id=registration.organization_id ), get_data_influx=self.influx_get_url.format( - database_server=server_data['database_server'], + database_server=server_data['influx_server'], influx_identifier=get_influx_identifier(sensor) ), no_data_value=get_no_data_value(sensor) @@ -157,6 +157,7 @@ def retrieve_server_data(): data = json.load(data_file) server_data['server'] = data['host'] server_data['database_server'] = next(db_connection['host'] for db_connection in data['databases'] if db_connection['name'] == 'tsa_catalog') + server_data['influx_server'] = data['influx_server'] if 'influx_server' in data else server_data['database_server'] except IOError: print('Error reading settings.json file') From de88a67cf71e8bec87ec3b4616722ba3a1e8f207 Mon Sep 17 00:00:00 2001 From: Juan Date: Thu, 13 Jun 2019 15:49:00 -0400 Subject: [PATCH 30/34] Updating with changes to base settings file to fix email server issues. --- src/WebSDL/settings/base.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/WebSDL/settings/base.py b/src/WebSDL/settings/base.py index cceae55a..180aad92 100644 --- a/src/WebSDL/settings/base.py +++ b/src/WebSDL/settings/base.py @@ -184,6 +184,13 @@ EMAIL_HOST = EMAIL_SERVER[0] if isinstance(EMAIL_SERVER, tuple) else EMAIL_SERVER +EMAIL_HOST_USER = data['email_user'] if 'email_user' in data else '' + +EMAIL_HOST_PASSWORD = data['email_password'] if 'email_password' in data else '' + +EMAIL_USE_TLS = True + + DATETIME_FORMAT = "N j, Y g:i a" HYDROSHARE_UTIL_CONFIG = { From 5a2f865369d7a45448b3f051f9b311c221c1fa99 Mon Sep 17 00:00:00 2001 From: Juan Date: Mon, 17 Jun 2019 10:08:28 -0400 Subject: [PATCH 31/34] Adding a temporary hotfix that was implemented in the server but wasn't in the repository. --- src/dataloaderservices/views.py | 32 ++++++++++++++++++++------------ 1 file changed, 20 insertions(+), 12 deletions(-) diff --git a/src/dataloaderservices/views.py b/src/dataloaderservices/views.py index 513d20db..9ae4e468 100644 --- a/src/dataloaderservices/views.py +++ b/src/dataloaderservices/views.py @@ -601,19 +601,27 @@ def post(self, request, format=None): #site_sensor.registration.deployment_date_utc_offset = utc_offset site_sensor.registration.save(update_fields=['deployment_date']) - result.save(update_fields=[ - 'result_datetime', 'value_count', 'result_datetime_utc_offset', - 'valid_datetime', 'valid_datetime_utc_offset' - ]) + try: + result.save(update_fields=[ + 'result_datetime', 'value_count', 'result_datetime_utc_offset', + 'valid_datetime', 'valid_datetime_utc_offset' + ]) + except Exception as e: + # Temporary fix. TODO: Use logger and be more specific. exception catch is too broad. + pass # Insert data value into influx instance. - influx_request_url = settings.INFLUX_UPDATE_URL - influx_request_body = settings.INFLUX_UPDATE_BODY.format( - result_uuid=str(site_sensor.result_uuid).replace('-', '_'), - data_value=result_value.data_value, - utc_offset=result_value.value_datetime_utc_offset, - timestamp_s=long((result_value.value_datetime - datetime.utcfromtimestamp(0)).total_seconds()), - ) - requests.post(influx_request_url, influx_request_body.encode()) + try: + influx_request_url = settings.INFLUX_UPDATE_URL + influx_request_body = settings.INFLUX_UPDATE_BODY.format( + result_uuid=str(site_sensor.result_uuid).replace('-', '_'), + data_value=result_value.data_value, + utc_offset=result_value.value_datetime_utc_offset, + timestamp_s=long((result_value.value_datetime - datetime.utcfromtimestamp(0)).total_seconds()), + ) + requests.post(influx_request_url, influx_request_body.encode()) + except Exception as e: + # Temporary fix. TODO: Use logger and be more specific. exception catch is too broad. + continue return Response({}, status.HTTP_201_CREATED) From 86d7307622949c9c73037e7e10b93704d81f2235 Mon Sep 17 00:00:00 2001 From: Juan Date: Mon, 17 Jun 2019 11:58:24 -0400 Subject: [PATCH 32/34] Deleting unnecessary python settings files. --- src/WebSDL/settings/macos_sandbox.py | 48 -------------------------- src/WebSDL/settings/production.py | 14 -------- src/WebSDL/settings/sandbox.py | 12 ------- src/WebSDL/settings/windows_sandbox.py | 17 --------- 4 files changed, 91 deletions(-) delete mode 100644 src/WebSDL/settings/macos_sandbox.py delete mode 100644 src/WebSDL/settings/production.py delete mode 100644 src/WebSDL/settings/sandbox.py delete mode 100644 src/WebSDL/settings/windows_sandbox.py diff --git a/src/WebSDL/settings/macos_sandbox.py b/src/WebSDL/settings/macos_sandbox.py deleted file mode 100644 index c96ca362..00000000 --- a/src/WebSDL/settings/macos_sandbox.py +++ /dev/null @@ -1,48 +0,0 @@ -from WebSDL.settings.base import * - -DEBUG = True - -ALLOWED_HOSTS = ['127.0.0.1', 'localhost'] -if "host" in data: - ALLOWED_HOSTS.append(data["host"]) -if "host_alt" in data: - ALLOWED_HOSTS.append(data["host_alt"]) -if "host_staging" in data: - ALLOWED_HOSTS.append(data["host_staging"]) - -STATIC_ROOT = data["static_root"] -SITE_ROOT = "/opt/websdlenvironment/" -STATIC_URL = '/static/' -SITE_URL = '' - -""" -Installing postgreSQL on MacOS ------------------------------- -1. Setting up Homebrew - 1a. If you don't have Homebrew installed, visit https://brew.sh/ for installation instructions - 1b. If Homebrew is already installed, run: - brew doctor - brew update - -2. Install postgres by running the following commands: - - brew update - - brew install postgres - - brew tap homebrew/services - -3. To start up postgres, run: - brew services start postgresql - -4. To stop postgres, run: - brew services stop postgresql - -5. To restart postgres, run: - brew services restart postgresql - -6. To create a new user: - createuser --interactive - -7. To connect to a database: - psql [-U ] - -""" - diff --git a/src/WebSDL/settings/production.py b/src/WebSDL/settings/production.py deleted file mode 100644 index d279642f..00000000 --- a/src/WebSDL/settings/production.py +++ /dev/null @@ -1,14 +0,0 @@ -import django -from WebSDL.settings.base import * - -DEBUG = False - -ALLOWED_HOSTS = ['localhost', '127.0.0.1', data['host']] - -SITE_ROOT = os.environ['APPL_PHYSICAL_PATH'] -SITE_URL = os.environ['APPL_VIRTUAL_PATH'] + '/' - -STATIC_ROOT = os.path.join(SITE_ROOT, 'static') -STATIC_URL = SITE_URL + 'static/' - -django.setup() diff --git a/src/WebSDL/settings/sandbox.py b/src/WebSDL/settings/sandbox.py deleted file mode 100644 index 77d073a5..00000000 --- a/src/WebSDL/settings/sandbox.py +++ /dev/null @@ -1,12 +0,0 @@ -import django -from WebSDL.settings.base import * - -DEBUG = True - -SITE_ROOT = os.environ['APPL_PHYSICAL_PATH'] -SITE_URL = os.environ['APPL_VIRTUAL_PATH'] + '/' - -STATIC_ROOT = os.path.join(SITE_ROOT, 'static') -STATIC_URL = SITE_URL + 'static/' - -django.setup() diff --git a/src/WebSDL/settings/windows_sandbox.py b/src/WebSDL/settings/windows_sandbox.py deleted file mode 100644 index c02d97f9..00000000 --- a/src/WebSDL/settings/windows_sandbox.py +++ /dev/null @@ -1,17 +0,0 @@ -from WebSDL.settings.base import * - -DEBUG = True - -ALLOWED_HOSTS = ['127.0.0.1', 'localhost'] - -if "host" in data: - ALLOWED_HOSTS.append(data["host"]) -if "host_alt" in data: - ALLOWED_HOSTS.append(data["host_alt"]) -if "host_staging" in data: - ALLOWED_HOSTS.append(data["host_staging"]) - -STATIC_ROOT = data["static_root"] -SITE_ROOT = "C:\Users\crbla\Projects\ODM2DataSharingPortal" -STATIC_URL = '/static/' -SITE_URL = '' From ca095fd3ebf188c103d15920820bcb3e5b0b0389 Mon Sep 17 00:00:00 2001 From: Juan Date: Thu, 1 Aug 2019 17:07:25 -0400 Subject: [PATCH 33/34] #190 Changed the default sorting of the Units model to use Units Name instead of Units Type. --- src/dataloader/models.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dataloader/models.py b/src/dataloader/models.py index a7ed132d..644136c5 100644 --- a/src/dataloader/models.py +++ b/src/dataloader/models.py @@ -723,7 +723,7 @@ def __repr__(self): class Meta: db_table = 'units' - ordering = ['unit_type_id', 'unit_name'] + ordering = ['unit_name', 'unit_type_id'] @python_2_unicode_compatible From 045fd301229b69cfa0b140aba854cc69a4a8df01 Mon Sep 17 00:00:00 2001 From: Juan Date: Fri, 2 Aug 2019 12:23:13 -0400 Subject: [PATCH 34/34] Changed the name of linux settings file to `linux_server.py`, and made it so it pulls whether or not it's on debug mode from the settings.json file. --- src/WebSDL/settings/base.py | 2 ++ src/WebSDL/settings/{linux_sandbox.py => linux_server.py} | 2 -- src/WebSDL/settings/settings_template.json | 1 + src/WebSDL/wsgi.py | 2 +- 4 files changed, 4 insertions(+), 3 deletions(-) rename src/WebSDL/settings/{linux_sandbox.py => linux_server.py} (96%) diff --git a/src/WebSDL/settings/base.py b/src/WebSDL/settings/base.py index 180aad92..f9f1b634 100644 --- a/src/WebSDL/settings/base.py +++ b/src/WebSDL/settings/base.py @@ -220,3 +220,5 @@ GOOGLE_API_CONF = data.get('google_api_conf', None) AUTH_USER_MODEL = 'accounts.User' + +DEBUG = True if 'debug_mode' in data and data['debug_mode'] == "True" else False diff --git a/src/WebSDL/settings/linux_sandbox.py b/src/WebSDL/settings/linux_server.py similarity index 96% rename from src/WebSDL/settings/linux_sandbox.py rename to src/WebSDL/settings/linux_server.py index 0406705d..5be03f91 100644 --- a/src/WebSDL/settings/linux_sandbox.py +++ b/src/WebSDL/settings/linux_server.py @@ -1,7 +1,5 @@ from WebSDL.settings.base import * -DEBUG = False - ALLOWED_HOSTS = ['127.0.0.1', 'localhost'] if "host" in data: ALLOWED_HOSTS.append(data["host"]) diff --git a/src/WebSDL/settings/settings_template.json b/src/WebSDL/settings/settings_template.json index f8c56d49..1b1e1e07 100644 --- a/src/WebSDL/settings/settings_template.json +++ b/src/WebSDL/settings/settings_template.json @@ -1,5 +1,6 @@ { "secret_key": "", + "debug_mode": "True/False, False by default", "host": "-optional", "recaptcha_secret_key": "-optional", "recaptcha_user_key": "-optional", diff --git a/src/WebSDL/wsgi.py b/src/WebSDL/wsgi.py index 07ee0893..88b99d1b 100644 --- a/src/WebSDL/wsgi.py +++ b/src/WebSDL/wsgi.py @@ -12,7 +12,7 @@ from django.core.wsgi import get_wsgi_application -os.environ.setdefault("DJANGO_SETTINGS_MODULE", "WebSDL.settings.linux_sandbox") +os.environ.setdefault("DJANGO_SETTINGS_MODULE", "WebSDL.settings.linux_server") crontab_jobs.start_jobs()