Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 6 additions & 39 deletions api/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@

import api.models as models
from api.admin_classes import RegionRestrictedAdmin
from api.event_sources import SOURCES
from api.management.commands.index_and_notify import Command as Notify
from lang.admin import TranslationAdmin, TranslationInlineModelAdmin
from notifications.models import RecordType, SubscriptionType
Expand Down Expand Up @@ -158,38 +157,6 @@ def queryset(self, request, queryset):
return queryset.filter(is_featured=False)


class EventSourceFilter(admin.SimpleListFilter):
title = _("source")
parameter_name = "event_source"

def lookups(self, request, model_admin):
return (
("input", _("Manual input")),
("gdacs", _("GDACs scraper")),
("who", _("WHO scraper")),
("report_ingest", _("Field report ingest")),
("report_admin", _("Field report admin")),
("appeal_admin", _("Appeals admin")),
("unknown", _("Unknown automated")),
)

def queryset(self, request, queryset):
if self.value() == "input":
return queryset.filter(auto_generated=False)
elif self.value() == "gdacs":
return queryset.filter(auto_generated_source=SOURCES["gdacs"])
elif self.value() == "who":
return queryset.filter(auto_generated_source__startswith="www.who.int")
elif self.value() == "report_ingest":
return queryset.filter(auto_generated_source=SOURCES["report_ingest"])
elif self.value() == "report_admin":
return queryset.filter(auto_generated_source=SOURCES["report_admin"])
elif self.value() == "appeal_admin":
return queryset.filter(auto_generated_source=SOURCES["appeal_admin"])
elif self.value() == "unknown":
return queryset.filter(auto_generated=True).filter(auto_generated_source__isnull=True)


class DisasterTypeAdmin(CompareVersionAdmin, TranslationAdmin, admin.ModelAdmin):
search_fields = ("name",)

Expand Down Expand Up @@ -246,9 +213,9 @@ def level_updated_at(self, obj):
"cc_status",
"glide",
"auto_generated",
"auto_generated_source",
"source",
)
list_filter = [IsFeaturedFilter, EventSourceFilter]
list_filter = [IsFeaturedFilter, "source"]
actions = ["create_field_reports"]
search_fields = (
"name",
Expand Down Expand Up @@ -369,7 +336,7 @@ def changeform_view(self, request, object_id=None, form_url="", extra_context=No
self.readonly_fields = (
"appeals",
"field_reports",
"auto_generated_source",
"source",
"parent_event",
"created_at",
"updated_at",
Expand All @@ -378,7 +345,7 @@ def changeform_view(self, request, object_id=None, form_url="", extra_context=No
self.readonly_fields = (
"appeals",
"field_reports",
"auto_generated_source",
"source",
"created_at",
"updated_at",
)
Expand Down Expand Up @@ -651,7 +618,7 @@ def create_events(self, request, queryset):
dtype=getattr(report, "dtype"),
disaster_start_date=getattr(report, "created_at"),
auto_generated=True,
auto_generated_source=SOURCES["report_admin"],
source=models.Event.EventSources.REPORT_ADMIN,
)
if getattr(report, "countries").exists():
for country in report.countries.all():
Expand Down Expand Up @@ -760,7 +727,7 @@ def create_events(self, request, queryset):
dtype=getattr(appeal, "dtype"),
disaster_start_date=getattr(appeal, "start_date"),
auto_generated=True,
auto_generated_source=SOURCES["appeal_admin"],
source=models.Event.EventSources.APPEAL_ADMIN,
)
if appeal.country is not None:
event.countries.add(appeal.country)
Expand Down
37 changes: 35 additions & 2 deletions api/drf_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@
Export,
ExternalPartner,
FieldReport,
KeyFigure,
MainContact,
Profile,
Region,
Expand Down Expand Up @@ -122,6 +123,7 @@
CountrySupportingPartnerSerializer,
CountryTableauSerializer,
DeploymentsByEventSerializer,
DetailEmergencySerializer,
DetailEventSerializer,
DisasterTypeSerializer,
DistrictSerializer,
Expand Down Expand Up @@ -751,7 +753,7 @@ def get_queryset(self, *args, **kwargs):
if self.action == "response_activity_events":
return (
qset.filter(parent_event__isnull=True)
.filter(Q(auto_generated=False) | Q(auto_generated_source="New field report"))
.filter(Q(auto_generated=False) | Q(source=Event.EventSources.NEW_REPORT))
.select_related("dtype")
)
return (
Expand Down Expand Up @@ -1344,7 +1346,7 @@ class SupportedActivityViewset(viewsets.ReadOnlyModelViewSet):
# summary=report.description or "",
# disaster_start_date=report.start_date,
# auto_generated=True,
# auto_generated_source=SOURCES["new_report"],
# source=Event.EventSources.NEW_REPORT,
# visibility=report.visibility,
# **{TRANSLATOR_ORIGINAL_LANGUAGE_FIELD_NAME: django_get_language()},
# )
Expand Down Expand Up @@ -1542,3 +1544,34 @@ class CountrySupportingPartnerViewSet(viewsets.ModelViewSet):

def get_queryset(self):
return CountrySupportingPartner.objects.select_related("country")


class EmergencyViewset(viewsets.ReadOnlyModelViewSet):
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We might need to use the ReadOnlyVisibilityViewset class, same as EventViewset.


queryset = Event.objects.all()
Comment on lines +1549 to +1551
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
class EmergencyViewset(viewsets.ReadOnlyModelViewSet):
queryset = Event.objects.all()
class EmergencyViewset(viewsets.ReadOnlyModelViewSet):
queryset = Event.objects.all()

lookup_field = "id"
serializer_class = DetailEmergencySerializer
filterset_class = EventFilter

def get_queryset(self):
return (
super()
.get_queryset()
.select_related(
"dtype",
"parent_event",
)
.prefetch_related(
"regions",
"countries",
"countries_for_preview",
Prefetch("key_figures", queryset=KeyFigure.objects.all()),
Prefetch("contacts", queryset=EventContact.objects.all()),
)
.annotate(
latest_field_report_id=Subquery(
FieldReport.objects.filter(event=OuterRef("pk")).order_by("-created_at").values("id")[:1]
),
Comment on lines +1572 to +1574
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need to filter this out from the Field Report number.

fr_num = models.IntegerField(verbose_name=_("field report number"), null=True, blank=True)

appeal_id=Subquery(Appeal.objects.filter(event=OuterRef("pk")).order_by("-created_at").values("id")[:1]),
)
Comment on lines +1575 to +1576
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Check this logic against how it was done in the frontend before. @shreeyash07

)
1 change: 1 addition & 0 deletions api/enums.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,5 @@
"action_category": models.ActionCategory,
"profile_org_types": models.Profile.OrgTypes,
"supporting_type": models.CountrySupportingPartner.SupportingPartnerType,
"event_source": models.Event.EventSources,
}
9 changes: 8 additions & 1 deletion api/factories/event.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
AppealHistory,
AppealType,
Event,
EventContact,
EventFeaturedDocument,
EventLink,
)
Expand Down Expand Up @@ -72,7 +73,7 @@ def regions(self, create, extracted, **kwargs):
previous_update = fuzzy.FuzzyDateTime(datetime.datetime(2008, 1, 1, tzinfo=pytz.utc))

auto_generated = fuzzy.FuzzyChoice([True, False])
auto_generated_source = fuzzy.FuzzyText(length=50)
source = fuzzy.FuzzyChoice(Event.EventSources.values)

is_featured = fuzzy.FuzzyChoice([True, False])
is_featured_region = fuzzy.FuzzyChoice([True, False])
Expand Down Expand Up @@ -133,3 +134,9 @@ class AppealHistoryFactory(factory.django.DjangoModelFactory):

class Meta:
model = AppealHistory


class EventContactFactory(factory.django.DjangoModelFactory):

class Meta:
model = EventContact
7 changes: 2 additions & 5 deletions api/filter_set.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
from django.contrib.auth.models import User
from django.db import models

from api.event_sources import SOURCES
from api.models import (
Admin2,
Appeal,
Expand Down Expand Up @@ -182,10 +181,8 @@ class EventFilter(filters.FilterSet):
countries__in = ListFilter(field_name="countries__id")
regions__in = ListFilter(field_name="regions__id")
id = filters.NumberFilter(field_name="id", lookup_expr="exact")
auto_generated_source = filters.ChoiceFilter(
label="Auto generated source choices",
choices=[(v, v) for v in SOURCES.values()],
)
source = filters.ChoiceFilter(choices=Event.EventSources.choices, lookup_expr="exact")

is_subscribed = filters.BooleanFilter(label="is_subscribed", method="get_is_subcribed_event")

class Meta:
Expand Down
3 changes: 1 addition & 2 deletions api/management/commands/create_events.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
from django.core.management.base import BaseCommand

from api.event_sources import SOURCES
from api.models import Appeal, Event


Expand All @@ -18,7 +17,7 @@ def handle(self, *args, **options):
"dtype": appeal.dtype,
"disaster_start_date": appeal.start_date,
"auto_generated": True,
"auto_generated_source": SOURCES["appeal_admin"],
"source": Event.EventSources.APPEAL_ADMIN,
}
event = Event.objects.create(**fields)
if appeal.country is not None:
Expand Down
2 changes: 1 addition & 1 deletion api/management/commands/index_and_notify.py
Original file line number Diff line number Diff line change
Expand Up @@ -1035,7 +1035,7 @@ def handle(self, *args, **options):
condR = Q(real_data_update__gte=time_diff) # instead of modified at
cond2 = ~Q(previous_update__gte=time_diff_1_day) # negate (~) no previous_update in the last day, so send once a day
condF = Q(
auto_generated_source="New field report"
source=Event.EventSources.NEW_REPORT
) # exclude those events that were generated from field reports, to avoid 2x notif.
condE = Q(status=CronJobStatus.ERRONEOUS)

Expand Down
3 changes: 1 addition & 2 deletions api/management/commands/ingest_gdacs.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
from dateutil.parser import parse
from django.core.management.base import BaseCommand

from api.event_sources import SOURCES
from api.logger import logger
from api.models import Country, CronJob, CronJobStatus, DisasterType, Event, GDACSEvent

Expand Down Expand Up @@ -104,7 +103,7 @@ def handle(self, *args, **options):
"summary": data["description"],
"disaster_start_date": data["publication_date"],
"auto_generated": True,
"auto_generated_source": SOURCES["gdacs"],
"source": Event.EventSources.GDACS,
"ifrc_severity_level": data["alert_level"],
}
event = Event.objects.create(**fields)
Expand Down
3 changes: 1 addition & 2 deletions api/management/commands/ingest_mdb.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
from django.core.management.base import BaseCommand
from django.utils import timezone

from api.event_sources import SOURCES
from api.fixtures.dtype_map import PK_MAP
from api.logger import logger
from api.models import (
Expand Down Expand Up @@ -249,7 +248,7 @@ def handle(self, *args, **options):
"dtype": report_dtype,
"disaster_start_date": datetime.utcnow().replace(tzinfo=timezone.utc),
"auto_generated": True,
"auto_generated_source": SOURCES["report_ingest"],
"source": Event.EventSources.REPORT_INGEST,
}
event = Event(**event_record)
event.save()
Expand Down
4 changes: 2 additions & 2 deletions api/management/commands/ingest_who.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ class Command(BaseCommand):
help = "Add new event (=emergency) entries from WHO API"

def handle(self, *args, **options):
guids = [e.auto_generated_source for e in Event.objects.filter(auto_generated_source__startswith="www.who.int")]
guids = [e.source for e in Event.objects.filter(source=Event.EventSources.WHO)]

logger.info("Querying WHO RSS feed for new emergency data")
# get latest
Expand Down Expand Up @@ -131,7 +131,7 @@ def handle(self, *args, **options):
"summary": summary,
"disaster_start_date": date,
"auto_generated": True,
"auto_generated_source": data["guid"],
"source": Event.EventSources.WHO,
"ifrc_severity_level": alert_level,
}
# TODO: fields['name'] sometimes exceeds 100 maxlength, so will need some altering if this will be used
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@

from django.db import migrations, models


def migrate_sources(apps, schema_editor):
"""
Populate the source field for Event records:
- Non auto generated events are mapped to MANUAL_INPUT
- Events that are auto generated and have auto_generated_source are mapped to the corresponding enum value
- Events that are auto generated and auto_generated_source is null or unrecognized are mapped to UNKNOWN
"""

Model = apps.get_model("api", "Event")
for obj in Model.objects.iterator():
if not obj.auto_generated:
value = 100

else:
src = (obj.auto_generated_source or "").lower()

if "who.int" in src:
value = 120
elif "gdacs" in src:
value = 110
elif "field report dmis ingest" in src:
value = 130
elif "field report admin" in src:
value = 140
elif "appeal" in src:
value = 150
elif "new field report" in src:
value = 160
else:
value = 180

obj.source = value
obj.save(update_fields=["source"])


class Migration(migrations.Migration):

dependencies = [
('api', '0230_alter_districtgeoms_district'),
]

operations = [

migrations.AddField(
model_name='event',
name='source',
field=models.IntegerField(choices=[(100, 'Manual input'), (110, 'GDACs scraper'), (120, 'WHO scraper'), (130, 'Field report DMIS ingest'), (140, 'Field report admin'), (150, 'Appeal admin'), (160, 'New field report'), (170, 'DREF'), (180, 'Unknown')], default=100, verbose_name='Event source'),
),
migrations.RunPython(migrate_sources,reverse_code=migrations.RunPython.noop),

migrations.RemoveField(
model_name='event',
name='auto_generated_source',
),
]
Loading
Loading