From 4b35e838e75662f9a55287513c95219059a319a5 Mon Sep 17 00:00:00 2001 From: Dmytro Trotsko Date: Fri, 28 Feb 2025 17:36:44 +0200 Subject: [PATCH] FIxed epiweek calculation --- Pipfile | 1 + Pipfile.lock | 11 ++- src/assets/css/style.css | 6 +- src/assets/js/signal_sets.js | 79 ++++++++++++---------- src/signal_sets/urls.py | 3 +- src/signal_sets/views.py | 20 +++++- src/templates/signal_sets/signal_sets.html | 2 + 7 files changed, 82 insertions(+), 40 deletions(-) diff --git a/Pipfile b/Pipfile index 3bb8889..2fa1d05 100644 --- a/Pipfile +++ b/Pipfile @@ -40,6 +40,7 @@ sphinxcontrib-django = "*" sqlalchemy = "*" types-requests = "*" tzdata = "*" +epiweeks = "*" [dev-packages] flake8 = "*" diff --git a/Pipfile.lock b/Pipfile.lock index b827063..1fed6bc 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "dcfee6e13b22e7381970bc928dd36a0169abd3b290b4a72a59f5f7ae5871348f" + "sha256": "86779d3f0c119371b35c4a2f4c61fdc5e674855267f81045b19fbb53d1ae57fe" }, "pipfile-spec": 6, "requires": { @@ -483,6 +483,15 @@ "markers": "python_version >= '3.7'", "version": "==0.27.2" }, + "epiweeks": { + "hashes": [ + "sha256:3c64ee0b217d0a03f0896fce3c35b73c848c3717790504893cb4eb61b9364bac", + "sha256:e60f31f0bb7021cb62d6a366fc90b69798b3f78b2aa929ad78709be9e0cb35a8" + ], + "index": "pypi", + "markers": "python_version >= '3.8'", + "version": "==2.3.0" + }, "factory-boy": { "hashes": [ "sha256:a2cdbdb63228177aa4f1c52f4b6d83fab2b8623bf602c7dedd7eb83c0f69c04c", diff --git a/src/assets/css/style.css b/src/assets/css/style.css index 7dac78b..ef0d4da 100644 --- a/src/assets/css/style.css +++ b/src/assets/css/style.css @@ -1421,4 +1421,8 @@ div.dt-button-collection { @keyframes spin { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } - } \ No newline at end of file + } + +div[name="choose_date"] { + display: none; +} \ No newline at end of file diff --git a/src/assets/js/signal_sets.js b/src/assets/js/signal_sets.js index 42abd13..5da83f3 100644 --- a/src/assets/js/signal_sets.js +++ b/src/assets/js/signal_sets.js @@ -227,19 +227,37 @@ function exportData() { var endDate = document.getElementById('end_date').value; var manualDataExport = "To download data, please click on the link or copy/paste command into your terminal: \n\n" + var requests = []; checkedSignalMembers.forEach((signal) => { geoTypes.forEach((geoType) => { var geoValues = geographicValues[geoType].map((el) => (typeof el.id === 'string') ? el.id.toLowerCase() : el.id).join(","); if (signal["time_type"] === "week") { - startDate = getDateYearWeek(new Date(startDate)); - endDate = getDateYearWeek(new Date(endDate)); - }; - var exportUrl = `https://api.delphi.cmu.edu/epidata/covidcast/csv?signal=${signal["data_source"]}:${signal["signal"]}&start_day=${startDate}&end_day=${endDate}&geo_type=${geoType}&geo_values=${geoValues}`; - manualDataExport += `wget --content-disposition ${exportUrl}\n` + var request = $.ajax({ + url: "get_epiweek/", + type: 'POST', + async: true, + data: { + csrfmiddlewaretoken: csrf_token, + start_date: startDate, + end_date: endDate, + }, + success: function (result) { + var exportUrl = `https://api.delphi.cmu.edu/epidata/covidcast/csv?signal=${signal["data_source"]}:${signal["signal"]}&start_day=${result.start_date}&end_day=${result.end_date}&geo_type=${geoType}&geo_values=${geoValues}`; + manualDataExport += `wget --content-disposition ${exportUrl}\n` + } + }) + requests.push(request); + } else { + var exportUrl = `https://api.delphi.cmu.edu/epidata/covidcast/csv?signal=${signal["data_source"]}:${signal["signal"]}&start_day=${startDate}&end_day=${endDate}&geo_type=${geoType}&geo_values=${geoValues}`; + manualDataExport += `wget --content-disposition ${exportUrl}\n` + } }); }); - $('#modeSubmitResult').html(manualDataExport); + $.when.apply($, requests).then(function() { + $('#modeSubmitResult').html(manualDataExport); + }) + } function previewData() { @@ -248,12 +266,27 @@ function previewData() { var geoTypes = Object.keys(geographicValues); var previewExample = []; var requests = []; + + var startDate = document.getElementById("start_date").value; + var endDate = document.getElementById("end_date").value; + checkedSignalMembers.forEach((signal) => { - var startDate = document.getElementById("start_date").value; - var endDate = document.getElementById("end_date").value; + var timeValues; + if (signal["time_type"] === "week") { - startDate = getDateYearWeek(new Date(startDate)); - endDate = getDateYearWeek(new Date(endDate)); + $.ajax({ + url: "get_epiweek/", + type: 'POST', + async: false, + data: { + csrfmiddlewaretoken: csrf_token, + start_date: startDate, + end_date: endDate, + }, + success: function (result) { + timeValues = `${result.start_date}-${result.end_date}`; + } + }) }; var requestSent = false; @@ -261,7 +294,7 @@ function previewData() { geoTypes.forEach((geoType) => { var geoValues = geographicValues[geoType].map((el) => (typeof el.id === 'string') ? el.id.toLowerCase() : el.id).join(","); $('#loader').show(); - var timeValues = signal["time_type"] === "week" ? `${startDate}-${endDate}` : `${startDate}--${endDate}`; + timeValues = signal["time_type"] === "week" ? timeValues : `${startDate}--${endDate}`; var request = $.ajax({ url: "epidata/covidcast/", type: 'GET', @@ -375,30 +408,6 @@ $('#geographic_value').on('select2:select', function (e) { } }); -function getDateYearWeek(date) { - const currentDate = - (typeof date === 'object') ? date : new Date(); - const januaryFirst = - new Date(currentDate.getFullYear(), 0, 1); - const daysToNextMonday = - (januaryFirst.getDay() === 1) ? 0 : - (7 - januaryFirst.getDay()) % 7; - const nextMonday = - new Date(currentDate.getFullYear(), 0, - januaryFirst.getDate() + daysToNextMonday); - - var weekNumber = (currentDate < nextMonday) ? 52 : - (currentDate > nextMonday ? Math.ceil( - (currentDate - nextMonday) / (24 * 3600 * 1000) / 7) : 1); - - if (weekNumber < 10) { - weekNumber = `0${weekNumber}`; - } - - const year = currentDate.getFullYear() - - return `${year}${weekNumber}`; -} function submitMode(event) { event.preventDefault(); diff --git a/src/signal_sets/urls.py b/src/signal_sets/urls.py index f1eb7f3..e575ffc 100644 --- a/src/signal_sets/urls.py +++ b/src/signal_sets/urls.py @@ -1,9 +1,10 @@ from django.urls import path, re_path from django.urls.resolvers import URLPattern -from signal_sets.views import SignalSetListView, epidata +from signal_sets.views import SignalSetListView, epidata, get_epiweek urlpatterns: list[URLPattern] = [ path("", SignalSetListView.as_view(), name="signal_sets"), re_path(r'^epidata/(?P.*)/$', epidata, name="epidata"), + path("get_epiweek/", get_epiweek, name="get_epiweek"), ] diff --git a/src/signal_sets/views.py b/src/signal_sets/views.py index 6de6ee6..cc92cc5 100644 --- a/src/signal_sets/views.py +++ b/src/signal_sets/views.py @@ -1,7 +1,8 @@ import requests import logging -from typing import Any, Dict +from typing import Any import json +from datetime import datetime as dtime from django.conf import settings from django.db.models.query import QuerySet @@ -14,6 +15,8 @@ from signal_sets.filters import SignalSetFilter from signal_sets.forms import SignalSetFilterForm +from epiweeks import Week + logger = logging.getLogger(__name__) @@ -130,9 +133,22 @@ def get_context_data(self, **kwargs: Any) -> dict[str, Any]: return context -def epidata(request, endpoint=''): +def epidata(request, endpoint=""): params = request.GET.dict() params["api_key"] = settings.EPIDATA_API_KEY url = f"{settings.EPIDATA_URL}{endpoint}" response = requests.get(url, params=params) return JsonResponse(response.json(), safe=False) + + +def get_epiweek(request): + start_date = dtime.strptime(request.POST["start_date"], "%Y-%m-%d") + start_date = Week.fromdate(start_date) + end_date = dtime.strptime(request.POST["end_date"], "%Y-%m-%d") + end_date = Week.fromdate(end_date) + return JsonResponse( + { + "start_date": f"{start_date.year}{start_date.week if start_date.week >= 10 else '0' + str(start_date.week)}", + "end_date": f"{end_date.year}{end_date.week if end_date.week >= 10 else '0' + str(end_date.week)}", + } + ) diff --git a/src/templates/signal_sets/signal_sets.html b/src/templates/signal_sets/signal_sets.html index 4da5635..44fc235 100644 --- a/src/templates/signal_sets/signal_sets.html +++ b/src/templates/signal_sets/signal_sets.html @@ -413,6 +413,7 @@