44from datetime import datetime
55from django .utils .timezone import make_aware
66from django .core .management .base import BaseCommand
7+ from django .core .files .base import File
78from django .conf import settings
89from django .db import models
910
10- from api .models import CronJob , CronJobStatus
11+ from main .utils import DownloadFileManager
12+ from api .models import Country
1113from country_plan .models import CountryPlan
1214
1315logger = 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
2023class 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 \n Exception:\n { str (ex )} " ,
91- 'status' : CronJobStatus .ERRONEOUS ,
92- })
93- return updated
94103
95- def handle (self , * args , ** kwargs ):
96- try :
97- logger .info ('\n Fetching 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 \n Exception:\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 ('\n Fetching data for country plans:: PRIVATE' )
110+ self .load (INTERNAL_SOURCE , 'internal_plan_file' , 'internal_plan_inserted_date' )
0 commit comments