Skip to content

Commit b2745ea

Browse files
committed
Add internal plan to ingest_country_plan_file
1 parent c803175 commit b2745ea

File tree

3 files changed

+73
-63
lines changed

3 files changed

+73
-63
lines changed

country_plan/management/commands/ingest_country_plan_file.py

Lines changed: 48 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,20 @@
44
from datetime import datetime
55
from django.utils.timezone import make_aware
66
from django.core.management.base import BaseCommand
7+
from django.core.files.base import File
78
from django.conf import settings
89
from django.db import models
910

10-
from api.models import CronJob, CronJobStatus
11+
from main.utils import DownloadFileManager
12+
from api.models import Country
1113
from country_plan.models import CountryPlan
1214

1315
logger = logging.getLogger(__name__)
1416

15-
NAME = 'ingest_country_plan_file'
1617
# Ref: https://github.com/IFRCGo/go-api/issues/1614
17-
SOURCE = 'https://go-api.ifrc.org/api/publicsiteappeals?AppealsTypeID=1851&Hidden=false'
18+
PUBLIC_SOURCE = 'https://go-api.ifrc.org/api/publicsiteappeals?AppealsTypeID=1851&Hidden=false'
19+
# Ref: https://github.com/IFRCGo/go-api/issues/1648
20+
INTERNAL_SOURCE = 'https://go-api.ifrc.org/Api/FedNetAppeals?AppealsTypeId=1844&Hidden=false'
1821

1922

2023
class Command(BaseCommand):
@@ -33,7 +36,15 @@ def parse_date(text: str) -> Union[datetime, None]:
3336
datetime.strptime(text, '%Y-%m-%dT%H:%M:%S')
3437
)
3538

36-
def load_for_country(self, country_data):
39+
@staticmethod
40+
def load_file_to_country_plan(country_plan: CountryPlan, url: str, filename: str, field_name: str):
41+
with DownloadFileManager(url, suffix='.pdf') as f:
42+
getattr(country_plan, field_name).save(
43+
filename,
44+
File(f),
45+
)
46+
47+
def load_for_country(self, country_data, file_field, field_inserted_date_field):
3748
country_iso2 = country_data.get('LocationCountryCode')
3849
country_name = country_data.get('LocationCountryName')
3950
public_plan_url = country_data.get('BaseDirectory') or '' + country_data.get('BaseFileName') or ''
@@ -44,69 +55,56 @@ def load_for_country(self, country_data):
4455
inserted_date is None
4556
):
4657
return
47-
country_plan = CountryPlan.objects.filter(
48-
models.Q(country__iso__iexact=country_iso2) |
49-
models.Q(country__name__iexact=country_name)
50-
).first()
58+
country_qs = Country.objects.filter(
59+
models.Q(iso__iexact=country_iso2) |
60+
models.Q(name__iexact=country_name)
61+
)
62+
country_plan = CountryPlan.objects.filter(country__in=country_qs).first()
5163
if country_plan is None:
52-
logger.warning(f'{NAME} No country_plan found for: {(country_iso2, country_name)}')
53-
return
54-
if country_plan.appeal_api_inserted_date and country_plan.appeal_api_inserted_date >= inserted_date:
64+
country = country_qs.first()
65+
# If there is no country as well, show warning and return
66+
if not country:
67+
logger.warning(f'{file_field} No country found for: {(country_iso2, country_name)}')
68+
return
69+
# Else create one and continue
70+
country_plan = CountryPlan(country=country)
71+
existing_inserted_date = getattr(country_plan, field_inserted_date_field, None)
72+
if existing_inserted_date and existing_inserted_date >= inserted_date:
5573
# No need to do anything here
5674
return
75+
self.stdout.write(f'- Saving data for country:: {country_plan.country.name}')
5776
public_plan_url = country_data['BaseDirectory'] + country_data['BaseFileName']
58-
country_plan.appeal_api_inserted_date = inserted_date
59-
country_plan.load_file_to_country_plan(
77+
setattr(country_plan, field_inserted_date_field, inserted_date)
78+
self.load_file_to_country_plan(
79+
country_plan,
6080
public_plan_url,
6181
# NOTE: File provided are PDF,
62-
f"public-plan-{country_data['BaseFileName']}.pdf",
82+
f"{file_field.replace('_', '-').replace('file', '')}-{country_data['BaseFileName']}.pdf",
83+
file_field,
6384
)
6485
country_plan.is_publish = True
6586
country_plan.save(
6687
update_fields=(
67-
'appeal_api_inserted_date',
68-
'public_plan_file', # By load_file_to_country_plan
88+
field_inserted_date_field,
89+
file_field, # By load_file_to_country_plan
6990
'is_publish',
7091
)
7192
)
7293
return True
7394

74-
def load(self):
75-
updated = 0
95+
def load(self, url: str, file_field: str, field_inserted_date_field: str):
7696
auth = (settings.APPEALS_USER, settings.APPEALS_PASS)
77-
results = requests.get(SOURCE, auth=auth, headers={'Accept': 'application/json'}).json()
97+
results = requests.get(url, auth=auth, headers={'Accept': 'application/json'}).json()
7898
for result in results:
7999
try:
80-
if self.load_for_country(result):
81-
updated += 1
82-
except Exception as ex:
100+
self.load_for_country(result, file_field, field_inserted_date_field)
101+
except Exception:
83102
logger.error('Could not Updated countries plan', exc_info=True)
84-
country_info = (
85-
result.get('LocationCountryCode'),
86-
result.get('LocationCountryName'),
87-
)
88-
CronJob.sync_cron({
89-
'name': NAME,
90-
'message': f"Could not updated country plan for {country_info}\n\nException:\n{str(ex)}",
91-
'status': CronJobStatus.ERRONEOUS,
92-
})
93-
return updated
94103

95-
def handle(self, *args, **kwargs):
96-
try:
97-
logger.info('\nFetching data for country plans:: ')
98-
countries_plan_updated = self.load()
99-
CronJob.sync_cron({
100-
'name': NAME,
101-
'message': 'Updated countries plan',
102-
'num_result': countries_plan_updated,
103-
'status': CronJobStatus.SUCCESSFUL,
104-
})
105-
logger.info('Updated countries plan')
106-
except Exception as ex:
107-
logger.error('Could not Updated countries plan', exc_info=True)
108-
CronJob.sync_cron({
109-
'name': NAME,
110-
'message': f'Could not Updated countries plan\n\nException:\n{str(ex)}',
111-
'status': CronJobStatus.ERRONEOUS,
112-
})
104+
def handle(self, **_):
105+
# Public
106+
self.stdout.write('Fetching data for country plans:: PUBLIC')
107+
self.load(PUBLIC_SOURCE, 'public_plan_file', 'public_plan_inserted_date')
108+
# Private
109+
self.stdout.write('\nFetching data for country plans:: PRIVATE')
110+
self.load(INTERNAL_SOURCE, 'internal_plan_file', 'internal_plan_inserted_date')
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
# Generated by Django 3.2.16 on 2023-02-07 08:40
2+
3+
from django.db import migrations, models
4+
5+
6+
class Migration(migrations.Migration):
7+
8+
dependencies = [
9+
('country_plan', '0004_countryplan_appeal_api_inserted_date'),
10+
]
11+
12+
operations = [
13+
migrations.RenameField(
14+
model_name='countryplan',
15+
old_name='appeal_api_inserted_date',
16+
new_name='public_plan_inserted_date',
17+
),
18+
migrations.AddField(
19+
model_name='countryplan',
20+
name='internal_plan_inserted_date',
21+
field=models.DateTimeField(blank=True, null=True),
22+
),
23+
]

country_plan/models.py

Lines changed: 2 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,7 @@
33
from django.utils import timezone
44
from django.utils.translation import gettext_lazy as _
55
from django.core.validators import FileExtensionValidator
6-
from django.core.files.base import File
76

8-
from main.utils import DownloadFileManager
97
from api.models import Country
108

119

@@ -83,21 +81,12 @@ class CountryPlan(CountryPlanAbstract):
8381
is_publish = models.BooleanField(default=False, verbose_name=_('Published'))
8482

8583
# NOTE: Used to sync with Appeal API (ingest_country_plan_file.py for more info)
86-
appeal_api_inserted_date = models.DateTimeField(blank=True, null=True)
84+
public_plan_inserted_date = models.DateTimeField(blank=True, null=True)
85+
internal_plan_inserted_date = models.DateTimeField(blank=True, null=True)
8786

8887
def __str__(self):
8988
return f'{self.country}'
9089

91-
def load_file_to_country_plan(self, url: str, filename: str, commit=False):
92-
with DownloadFileManager(url, suffix='.pdf') as f:
93-
self.public_plan_file.save(
94-
filename,
95-
File(f),
96-
)
97-
if commit:
98-
self.save()
99-
100-
# NOTE: To be used by CountryPlanSerializer (From CountryPlanViewset)
10190
def full_country_plan_mc(self):
10291
all_mc = list(self.country_plan_mc.all())
10392
mc_by_ns_sector = {

0 commit comments

Comments
 (0)