Skip to content

Commit cd0ec4f

Browse files
Merge pull request #2174 from IFRCGo/feature/countrypage-cronjon
Country page cronjobs scheduled to every week
2 parents 14d13d5 + af900bc commit cd0ec4f

29 files changed

+439
-140
lines changed

api/management/commands/cron_job_monitor.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
from django.conf import settings
66
from django.core.management.base import BaseCommand
77

8-
from main.sentry import SentryMonitor
8+
from main.sentry import SentryMonitor, SentryMonitorConfig
99
from main.settings import SENTRY_DSN
1010

1111
logger = logging.getLogger(__name__)
@@ -48,6 +48,10 @@ def handle(self, *args, **options):
4848
"type": "crontab",
4949
"value": str(schedule),
5050
},
51+
"tz": settings.TIME_ZONE,
52+
"checkin_margin": SentryMonitorConfig.get_checkin_margin(cronjob),
53+
"failure_issue_threshold": SentryMonitorConfig.get_failure_issue_threshold(cronjob),
54+
"recovery_threshold": SentryMonitorConfig.get_recovery_threshold(cronjob),
5155
},
5256
"environment": settings.GO_ENVIRONMENT,
5357
"status": "ok",

api/management/commands/index_and_notify.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,6 @@
6767
}
6868

6969

70-
@monitor(monitor_slug=SentryMonitor.INDEX_AND_NOTIFY)
7170
class Command(BaseCommand):
7271
help = "Index and send notifications about new/changed records"
7372

@@ -920,6 +919,7 @@ def check_ingest_issues(self, having_ingest_issue):
920919
+ ", notification sent to IM team"
921920
)
922921

922+
@monitor(monitor_slug=SentryMonitor.INDEX_AND_NOTIFY)
923923
def handle(self, *args, **options):
924924
if self.is_digest_mode():
925925
time_diff = self.diff_1_week() # in digest mode (once a week, for new_entities only) we use a bigger interval

api/management/commands/ingest_appeals.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,6 @@
3333
GEC_CODES = GECCode.objects.select_related("country").all()
3434

3535

36-
@monitor(monitor_slug=SentryMonitor.INGEST_APPEALS)
3736
class Command(BaseCommand):
3837
help = "Add new entries from Access database file"
3938

@@ -292,6 +291,7 @@ def parse_appeal_record(self, r, **options):
292291

293292
return fields
294293

294+
@monitor(monitor_slug=SentryMonitor.INGEST_APPEALS)
295295
def handle(self, *args, **options):
296296
logger.info("Starting appeals ingest")
297297
start_appeals_count = Appeal.objects.all().count()

api/management/commands/ingest_disaster_law.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,17 @@
11
import requests
22
from bs4 import BeautifulSoup
33
from django.core.management.base import BaseCommand
4+
from sentry_sdk.crons import monitor
45

56
from api.logger import logger
67
from api.models import Country, CronJob, CronJobStatus
8+
from main.sentry import SentryMonitor
79

810

911
class Command(BaseCommand):
1012
help = "Add ICRC data"
1113

14+
@monitor(monitor_slug=SentryMonitor.INGEST_DISASTER_LAW)
1215
def handle(self, *args, **kwargs):
1316
logger.info("Starting Disaster Law data")
1417
home_url = "https://disasterlaw.ifrc.org/"

api/management/commands/ingest_icrc.py

Lines changed: 20 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,26 @@
11
import requests
22
from bs4 import BeautifulSoup
33
from django.core.management.base import BaseCommand
4+
from sentry_sdk.crons import monitor
45

56
from api.logger import logger
67
from api.models import Country, CountryICRCPresence, CronJob, CronJobStatus
8+
from main.sentry import SentryMonitor
79

810

911
class Command(BaseCommand):
1012
help = "Add ICRC data"
1113

14+
@monitor(monitor_slug=SentryMonitor.INGEST_ICRC)
1215
def handle(self, *args, **kwargs):
1316
logger.info("Strating ICRC data ingest")
14-
response = requests.get(url="https://www.icrc.org/en/where-we-work", headers={"User-Agent": ""})
17+
HEADERS = {
18+
"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36", # noqa
19+
}
20+
response = requests.get(
21+
url="https://www.icrc.org/en/where-we-work",
22+
headers=HEADERS,
23+
)
1524
if response.status_code != 200:
1625
text_to_log = "Error querying ICRC feed at https://www.icrc.org/en/where-we-work"
1726
logger.error(text_to_log)
@@ -57,19 +66,19 @@ def handle(self, *args, **kwargs):
5766
"Description": description,
5867
}
5968
)
69+
6070
added = 0
6171
for data in country_list:
62-
country = Country.objects.filter(name__exact=data["Country"])
63-
if country.exists():
64-
dict_data = {
65-
"country": country.first(),
66-
"icrc_presence": data["ICRC presence"],
67-
"url": data["URL"],
68-
"key_operation": data["Key operation"],
69-
"description": data["Description"],
70-
}
72+
country = Country.objects.filter(name__exact=data["Country"]).first()
73+
if country:
74+
country_icrc_presence, _ = CountryICRCPresence.objects.get_or_create(country=country)
75+
76+
country_icrc_presence.icrc_presence = data["ICRC presence"]
77+
country_icrc_presence.url = data["URL"]
78+
country_icrc_presence.key_operation = data["Key operation"]
79+
country_icrc_presence.description = data["Description"]
80+
country_icrc_presence.save()
7181
added += 1
72-
CountryICRCPresence.objects.create(**dict_data)
7382

7483
text_to_log = "%s ICRC added" % added
7584
logger.info(text_to_log)

api/management/commands/ingest_ns_capacity.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,17 @@
11
import requests
22
from django.conf import settings
33
from django.core.management.base import BaseCommand
4+
from sentry_sdk.crons import monitor
45

56
from api.logger import logger
67
from api.models import Country, CountryCapacityStrengthening, CronJob, CronJobStatus
8+
from main.sentry import SentryMonitor
79

810

911
class Command(BaseCommand):
1012
help = "Add ns contact details"
1113

14+
@monitor(monitor_slug=SentryMonitor.INGEST_NS_CAPACITY)
1215
def handle(self, *args, **kwargs):
1316
logger.info("Starting NS Contacts")
1417

@@ -44,7 +47,7 @@ def handle(self, *args, **kwargs):
4447
text_to_log = "%s Ns capacity added" % ocaa_count
4548
logger.info(text_to_log)
4649
body = {
47-
"name": "ingest_ns_capaciity",
50+
"name": "ingest_ns_capacity",
4851
"message": text_to_log,
4952
"num_result": ocaa_count,
5053
"status": CronJobStatus.SUCCESSFUL,

api/management/commands/ingest_ns_contact.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,20 @@
55
import xmltodict
66
from django.conf import settings
77
from django.core.management.base import BaseCommand
8+
from django.db import transaction
89
from requests.auth import HTTPBasicAuth
10+
from sentry_sdk.crons import monitor
911

1012
from api.logger import logger
1113
from api.models import Country, CronJob, CronJobStatus
14+
from main.sentry import SentryMonitor
1215

1316

1417
class Command(BaseCommand):
1518
help = "Add ns contact details"
1619

20+
@monitor(monitor_slug=SentryMonitor.INGEST_NS_CONTACT)
21+
@transaction.atomic
1722
def handle(self, *args, **kwargs):
1823
logger.info("Starting NS Contacts")
1924
url = "https://go-api.ifrc.org/"

api/management/commands/ingest_ns_directory.py

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,26 @@
22
import xmltodict
33
from django.conf import settings
44
from django.core.management.base import BaseCommand
5+
from django.db import transaction
56
from requests.auth import HTTPBasicAuth
7+
from sentry_sdk.crons import monitor
68

79
from api.logger import logger
810
from api.models import Country, CountryDirectory, CronJob, CronJobStatus
11+
from main.sentry import SentryMonitor
912

1013

1114
class Command(BaseCommand):
1215
help = "Add ns contact details"
1316

17+
@monitor(monitor_slug=SentryMonitor.INGEST_NS_DIRECTORY)
18+
@transaction.atomic
1419
def handle(self, *args, **kwargs):
20+
def postprocessor(path, key, value):
21+
if key == "@i:nil":
22+
return None
23+
return key, value
24+
1525
logger.info("Starting NS Contacts")
1626
url = "https://go-api.ifrc.org/"
1727
headers = {"accept": "application/xml;q=0.9, */*;q=0.8"}
@@ -33,7 +43,8 @@ def handle(self, *args, **kwargs):
3343
raise Exception("Error querying NationalSocietiesContacts")
3444

3545
added = 0
36-
dict_data = xmltodict.parse(response.content)
46+
created_country_directory_ids = []
47+
dict_data = xmltodict.parse(response.content, postprocessor=postprocessor)
3748
for data in dict_data["ArrayOfNationalSocietiesContacts"]["NationalSocietiesContacts"]:
3849
country_name = data["CON_country"] if isinstance(data["CON_country"], str) else None
3950
if country_name is not None:
@@ -54,7 +65,15 @@ def handle(self, *args, **kwargs):
5465
"position": data["CON_title"],
5566
"country": country,
5667
}
57-
CountryDirectory.objects.create(**data)
68+
country_directory, _ = CountryDirectory.objects.get_or_create(
69+
country=country,
70+
first_name__iexact=data["first_name"],
71+
last_name__iexact=data["last_name"],
72+
position__iexact=data["position"],
73+
)
74+
created_country_directory_ids.append(country_directory.pk)
75+
# NOTE: Deleting the country directory which are not available in the source
76+
CountryDirectory.objects.exclude(id__in=created_country_directory_ids).delete()
5877
text_to_log = "%s Ns Directory added" % added
5978
logger.info(text_to_log)
6079
body = {"name": "ingest_ns_directory", "message": text_to_log, "num_result": added, "status": CronJobStatus.SUCCESSFUL}

api/management/commands/ingest_ns_document.py

Lines changed: 36 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,19 @@
55
import requests
66
from django.conf import settings
77
from django.core.management.base import BaseCommand
8+
from django.db import transaction
9+
from sentry_sdk.crons import monitor
810

911
from api.logger import logger
1012
from api.models import Country, CountryKeyDocument, CronJob, CronJobStatus
13+
from main.sentry import SentryMonitor
1114

1215

1316
class Command(BaseCommand):
1417
help = "Add ns documents"
1518

19+
@monitor(monitor_slug=SentryMonitor.INGEST_NS_DOCUMENT)
20+
@transaction.atomic
1621
def handle(self, *args, **kwargs):
1722
logger.info("Starting NS Key Documents")
1823

@@ -95,21 +100,45 @@ def fetch_all_country_documents(self, api_key, country_table):
95100

96101
def save_documents_to_database(self, result):
97102
added = 0
103+
created_country_key_document_ids = []
98104
for document in result:
99105
country = Country.objects.filter(fdrs=document["country_code"]).first()
100-
if country:
101-
added += 1
102-
data = {
103-
"country": country,
106+
if country is None:
107+
continue
108+
109+
country_key_document, created = CountryKeyDocument.objects.get_or_create(
110+
country=country,
111+
url=document["url"],
112+
defaults={
104113
"name": document["name"],
105-
"url": document["url"],
106114
"thumbnail": document["thumbnail"],
107115
"document_type": document["document_type"],
108116
"year": document["year"],
109117
"end_year": document["end_year"],
110118
"year_text": document["year_text"],
111-
}
112-
CountryKeyDocument.objects.create(**data)
119+
},
120+
)
121+
if not created:
122+
country_key_document.name = document["name"]
123+
country_key_document.thumbnail = document["thumbnail"]
124+
country_key_document.document_type = document["document_type"]
125+
country_key_document.year = document["year"]
126+
country_key_document.end_year = document["end_year"]
127+
country_key_document.year_text = document["year_text"]
128+
country_key_document.save(
129+
update_fields=[
130+
"name",
131+
"thumbnail",
132+
"document_type",
133+
"year",
134+
"end_year",
135+
"year_text",
136+
]
137+
)
138+
created_country_key_document_ids.append(country_key_document.pk)
139+
added += 1
140+
# NOTE: Deleting the CountryKeyDocument that are not in the source
141+
CountryKeyDocument.objects.exclude(id__in=created_country_key_document_ids).delete()
113142
return added
114143

115144
def sync_cron_success(self, text_to_log, added):

api/management/commands/ingest_ns_initiatives.py

Lines changed: 27 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,19 @@
33
import requests
44
from django.conf import settings
55
from django.core.management.base import BaseCommand
6+
from django.db import transaction
7+
from sentry_sdk.crons import monitor
68

79
from api.logger import logger
810
from api.models import Country, CronJob, CronJobStatus, NSDInitiatives
11+
from main.sentry import SentryMonitor
912

1013

1114
class Command(BaseCommand):
1215
help = "Add ns initiatives"
1316

17+
@monitor(monitor_slug=SentryMonitor.INGEST_NS_INITIATIVES)
18+
@transaction.atomic
1419
def handle(self, *args, **kwargs):
1520
logger.info("Starting NS Inititatives")
1621
api_key = settings.NS_INITIATIVES_API_KEY
@@ -40,21 +45,33 @@ def handle(self, *args, **kwargs):
4045
],
4146
)
4247
funding_data = funding_data.replace({np.nan: None})
48+
created_ns_initiatives_pk = []
4349
for data in funding_data.values.tolist():
4450
# TODO: Filter not by society name
4551
country = Country.objects.filter(society_name__iexact=data[0]).first()
4652
if country:
47-
dict_data = {
48-
"country": country,
49-
"title": data[3],
50-
"fund_type": data[2],
51-
"allocation": data[5],
52-
"year": data[1],
53-
"funding_period": data[6],
54-
"categories": data[4],
55-
}
53+
nsd_initiatives, created = NSDInitiatives.objects.get_or_create(
54+
country=country,
55+
year=data[1],
56+
fund_type=data[2],
57+
defaults={
58+
"title": data[3],
59+
"categories": data[4],
60+
"allocation": data[5],
61+
"funding_period": data[6],
62+
},
63+
)
64+
if not created:
65+
nsd_initiatives.title = data[3]
66+
nsd_initiatives.categories = data[4]
67+
nsd_initiatives.allocation = data[5]
68+
nsd_initiatives.funding_period = data[6]
69+
nsd_initiatives.save(update_fields=["title", "categories", "allocation", "funding_period"])
70+
created_ns_initiatives_pk.append(nsd_initiatives.pk)
5671
added += 1
57-
NSDInitiatives.objects.create(**dict_data)
72+
# NOTE: Delete the NSDInitiatives that are not in the source
73+
NSDInitiatives.objects.exclude(id__in=created_ns_initiatives_pk).delete()
74+
5875
text_to_log = "%s Ns initiatives added" % added
5976
logger.info(text_to_log)
6077
body = {"name": "ingest_ns_initiatives", "message": text_to_log, "num_result": added, "status": CronJobStatus.SUCCESSFUL}

0 commit comments

Comments
 (0)