Skip to content

Commit 64a98d3

Browse files
authored
Merge pull request #160 from cmu-delphi/OKRS24-223
OKRS24-223
2 parents c390176 + 21c54cf commit 64a98d3

File tree

8 files changed

+78
-7
lines changed

8 files changed

+78
-7
lines changed

src/base/admin.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212

1313
class DescriptedFilterFieldInline(admin.TabularInline):
1414
model = DescriptedFilterField
15-
fields = ('description',)
15+
fields = ('description', 'filter_field')
1616
extra = 0
1717
can_create = False
1818

src/signals/filters.py

+6
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,9 @@ class SignalFilter(django_filters.FilterSet):
5252
field_name="source_id__external_name",
5353
to_field_name='external_name')
5454
time_type = django_filters.MultipleChoiceFilter(choices=TimeTypeChoices.choices)
55+
from_date = django_filters.DateFilter(field_name='from_date', lookup_expr='gte')
56+
to_date = django_filters.DateFilter(field_name='to_date', lookup_expr='lte')
57+
signal_availability_days = django_filters.NumberFilter(field_name='signal_availability_days', lookup_expr='gte')
5558

5659
def __init__(self, data, *args, **kwargs):
5760
data = data.copy()
@@ -74,6 +77,9 @@ class Meta:
7477
'geographic_scope',
7578
'source',
7679
'time_type',
80+
'from_date',
81+
'to_date',
82+
'signal_availability_days',
7783
]
7884

7985
def filter_search(self, queryset, name, value) -> Any:

src/signals/forms.py

+10-1
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,10 @@ class SignalFilterForm(forms.ModelForm):
3636
geographic_scope = forms.ModelMultipleChoiceField(queryset=GeographicScope.objects.all(), widget=forms.CheckboxSelectMultiple())
3737
severenity_pyramid_rungs = forms.ChoiceField(choices=SeverityPyramidRungsChoices.choices, widget=forms.CheckboxSelectMultiple())
3838

39+
from_date = forms.DateField(widget=forms.DateInput(attrs={'type': 'date'}), required=False)
40+
to_date = forms.DateField(widget=forms.DateInput(attrs={'type': 'date'}), required=False)
41+
signal_availability_days = forms.IntegerField(required=False)
42+
3943
class Meta:
4044
model = Signal
4145
fields: list[str] = [
@@ -49,6 +53,9 @@ class Meta:
4953
'source',
5054
'time_type',
5155
'geographic_scope',
56+
'from_date',
57+
'to_date',
58+
'signal_availability_days',
5259
]
5360

5461
widgets = {
@@ -68,7 +75,6 @@ class Meta:
6875
'data-bs-toggle': 'tooltip',
6976
'data-bs-placement': 'bottom',
7077
}),
71-
7278
}
7379

7480
def __init__(self, *args, **kwargs) -> None:
@@ -87,3 +93,6 @@ def __init__(self, *args, **kwargs) -> None:
8793
field.required = False
8894
field.help_text = ''
8995
field.label = ''
96+
self.fields['from_date'].label = _('Available Since')
97+
self.fields['to_date'].label = _('Available Until')
98+
self.fields['signal_availability_days'].label = _('Available for at least (days)')
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
# Generated by Django 4.2.10 on 2024-06-20 06:31
2+
3+
from django.db import migrations, models
4+
5+
6+
class Migration(migrations.Migration):
7+
8+
dependencies = [
9+
('signals', '0019_alter_signal_severenity_pyramid_rungs'),
10+
]
11+
12+
operations = [
13+
migrations.AddField(
14+
model_name='signal',
15+
name='signal_availability_days',
16+
field=models.IntegerField(blank=True, help_text='Number of days the signal is available for', null=True),
17+
),
18+
]

src/signals/models.py

+6
Original file line numberDiff line numberDiff line change
@@ -518,6 +518,12 @@ class Signal(TimeStampedModel):
518518
blank=True
519519
)
520520

521+
signal_availability_days: models.IntegerField = models.IntegerField(
522+
help_text=_('Number of days the signal is available for'),
523+
null=True,
524+
blank=True
525+
)
526+
521527
temporal_scope_start: models.CharField = models.CharField(
522528
help_text=_('Temporal Scope Start'),
523529
null=True,

src/signals/tools.py

+8-5
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ class SignalLastUpdatedParser:
1010

1111
def __init__(self, covidcast_meta_data: list) -> None:
1212
self.covidcast_meta_data = covidcast_meta_data
13-
self.year_month_date_format = '%Y%m'
13+
self.year_week_date_format = '%Y-%W-%w'
1414
self.year_month_day_date_format = '%Y%m%d'
1515

1616
def format_date(self, date: str,) -> datetime:
@@ -23,7 +23,9 @@ def format_date(self, date: str,) -> datetime:
2323
"""
2424
formated_date: datetime
2525
if len(date) == 6:
26-
formated_date = datetime.strptime(date, self.year_month_date_format)
26+
year, week = date[:4], date[4:]
27+
logger.info(f"Date: {date}, year: {year}, week: {int(week)-1}")
28+
formated_date = datetime.strptime(f"{int(year)}-{int(week)-1}-1", self.year_week_date_format)
2729
elif len(date) == 8:
2830
formated_date = datetime.strptime(date, self.year_month_day_date_format)
2931
return formated_date
@@ -36,14 +38,15 @@ def set_data(self) -> None:
3638
for db_source in self.covidcast_meta_data:
3739
for signal_data in db_source['signals']:
3840
try:
39-
signal = Signal.objects.get(name=signal_data['signal_basename'], source__name=signal_data['source'])
41+
signal = Signal.objects.get(name=signal_data['signal'], source__name=signal_data['source'])
4042
except Signal.DoesNotExist:
4143
logger.warning(
42-
f"Signal {signal_data['signal_basename']} not found in db. Update failed."
44+
f"Signal {signal_data['signal']} not found in db. Update failed."
4345
)
4446
continue
4547
signal.last_updated = self.format_date(str(signal_data['max_issue']))
4648
signal.from_date = self.format_date(str(signal_data['min_time']))
4749
signal.to_date = self.format_date(str(signal_data['max_time']))
50+
signal.signal_availability_days = abs((signal.to_date - signal.from_date).days)
4851
signal.save()
49-
logger.info(f"Signal {signal_data['signal_basename']} successfully updated.")
52+
logger.info(f"Signal {signal_data['signal']} successfully updated.")

src/signals/views.py

+3
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,9 @@ def get_url_params(self):
5757
else None,
5858
"source": [el for el in self.request.GET.getlist("source")],
5959
"time_type": [el for el in self.request.GET.getlist("time_type")],
60+
"from_date": self.request.GET.get("from_date"),
61+
"to_date": self.request.GET.get("to_date"),
62+
"signal_availability_days": self.request.GET.get("signal_availability_days"),
6063
}
6164
url_params_str = ""
6265
for param_name, param_value in url_params_dict.items():

src/templates/signals/signals.html

+26
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,32 @@ <h2 class="accordion-header" id="time_type-heading">
189189
</div>
190190
</div>
191191
</div>
192+
<div class="accordion-item">
193+
<h2 class="accordion-header" id="signal_availability-heading">
194+
<button class="accordion-button collapsed" type="button" data-bs-toggle="collapse"
195+
data-bs-target="#signal_availability-collapse" aria-expanded="false" aria-controls="signal_availability-collapse">
196+
<label for="id_signal_availability" class="form-label">
197+
Signal Availability
198+
<a tabindex="0" role="button" class="info-button" data-bs-toggle="popover"
199+
data-bs-title="Availability"
200+
data-bs-content="{{ filters_descriptions.SignalFilter.signal_availability }}">
201+
<i class="bi bi-info-circle"></i>
202+
</a>
203+
</label>
204+
</button>
205+
</h2>
206+
{% if form.from_date.value or form.to_date.value or form.signal_availability_days.value %}
207+
<div id="signal_availability-collapse" class="accordion-collapse" aria-labelledby="signal_availability-heading">
208+
{% else %}
209+
<div id="signal_availability-collapse" class="accordion-collapse collapse" aria-labelledby="signal_availability-heading">
210+
{% endif %}
211+
<div class="accordion-body">
212+
{{ form.from_date|as_crispy_field }}
213+
{{ form.to_date|as_crispy_field }}
214+
{{ form.signal_availability_days|as_crispy_field }}
215+
</div>
216+
</div>
217+
</div>
192218
</div>
193219
<div class="card-body">
194220
<div class="d-grid gap-2 mt-3">

0 commit comments

Comments
 (0)