Skip to content

Commit 937648e

Browse files
committed
Add continent code(s) assignment
1 parent 0ca8f68 commit 937648e

File tree

14 files changed

+439
-16
lines changed

14 files changed

+439
-16
lines changed

app/location/__init__.py

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
from ..coordinates import Coordinates
2-
from ..utils import countries
2+
from ..utils import countries, continents
33
from ..utils.populations import country_population
44

55

@@ -26,12 +26,25 @@ def __init__(self, id, country, province, coordinates, last_updated, confirmed,
2626
@property
2727
def country_code(self):
2828
"""
29-
Gets the alpha-2 code represention of the country. Returns 'XX' if none is found.
29+
Gets the alpha-2 code representation of the country. Returns 'XX' if none is found.
3030
3131
:returns: The country code.
3232
:rtype: str
3333
"""
34-
return (countries.country_code(self.country) or countries.default_country_code).upper()
34+
return countries.country_code(self.country) or countries.default_country_code
35+
36+
@property
37+
def continent_codes_list(self):
38+
"""
39+
Gets the alpha-3 code representations of the continent codes where the
40+
country represented by the country code is located. Returns 'CCC' if
41+
none is found.
42+
43+
:returns: The list of continent codes.
44+
:rtype: list
45+
"""
46+
country_code = countries.country_code(self.country)
47+
return continents.continent_codes_list(country_code) or continents.default_continent_codes_list
3548

3649
@property
3750
def country_population(self):
@@ -55,6 +68,7 @@ def serialize(self):
5568
"id": self.id,
5669
"country": self.country,
5770
"country_code": self.country_code,
71+
"continent_codes_list": self.continent_codes_list,
5872
"country_population": self.country_population,
5973
"province": self.province,
6074
# Coordinates.

app/models/location.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ class Location(BaseModel):
1414
id: int
1515
country: str
1616
country_code: str
17+
continent_codes_list: list = []
1718
country_population: int = None
1819
province: str = ""
1920
county: str = ""

app/router/v2/locations.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ def get_locations(
1111
request: Request,
1212
source: Sources = "jhu",
1313
country_code: str = None,
14+
continent_codes_list: list = [],
1415
province: str = None,
1516
county: str = None,
1617
timelines: bool = False,

app/services/location/jhu.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
from ...coordinates import Coordinates
88
from ...location import TimelinedLocation
99
from ...timeline import Timeline
10-
from ...utils import countries
10+
from ...utils import countries, continents
1111
from ...utils import date as date_util
1212
from . import LocationService
1313

@@ -75,12 +75,15 @@ def get_category(category):
7575
# Latest data insert value.
7676
latest = list(history.values())[-1]
7777

78+
country_code = countries.country_code(country)
79+
7880
# Normalize the item and append to locations.
7981
locations.append(
8082
{
8183
# General info.
8284
"country": country,
83-
"country_code": countries.country_code(country),
85+
"country_code": country_code,
86+
"continent_codes_list" : continents.continent_codes_list(country_code),
8487
"province": item["Province/State"],
8588
# Coordinates.
8689
"coordinates": {"lat": item["Lat"], "long": item["Long"],},

app/utils/continents.py

Lines changed: 311 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,311 @@
1+
import logging
2+
from itertools import chain
3+
from . import countries
4+
5+
LOGGER = logging.getLogger(__name__)
6+
7+
default_continent_codes_list = ["CCC"]
8+
9+
continent_names__continent_codes = {
10+
"Africa" : "AFR",
11+
"North America" : "NAC", # "NAM" clashes with "Namibia"
12+
"Oceania" : "OCE",
13+
"Antarctica" : "ANA", # "ANT" clashes with "Netherlands Antilles"
14+
"Asia" : "ASI",
15+
"Europe" : "EUR",
16+
"South America" : "SAC",
17+
"Others" : default_continent_codes_list[0],
18+
}
19+
20+
country_code__continent_codes_list = {
21+
"AF" : ["ASI"],
22+
"XK" : ["EUR"],
23+
"AL" : ["EUR"],
24+
"AQ" : ["ANA"],
25+
"DZ" : ["AFR"],
26+
"AS" : ["OCE"],
27+
"AD" : ["EUR"],
28+
"AO" : ["AFR"],
29+
"AG" : ["NAC"],
30+
"AZ" : ["EUR", "ASI"],
31+
"AR" : ["SAC"],
32+
"AU" : ["OCE"],
33+
"AT" : ["EUR"],
34+
"BS" : ["NAC"],
35+
"BH" : ["ASI"],
36+
"BD" : ["ASI"],
37+
"AM" : ["EUR", "ASI"],
38+
"BB" : ["NAC"],
39+
"BE" : ["EUR"],
40+
"BM" : ["NAC"],
41+
"BT" : ["ASI"],
42+
"BO" : ["SAC"],
43+
"BA" : ["EUR"],
44+
"BW" : ["AFR"],
45+
"BV" : ["ANA"],
46+
"BR" : ["SAC"],
47+
"BZ" : ["NAC"],
48+
"IO" : ["ASI"],
49+
"SB" : ["OCE"],
50+
"VG" : ["NAC"],
51+
"BN" : ["ASI"],
52+
"BG" : ["EUR"],
53+
"MM" : ["ASI"],
54+
"BI" : ["AFR"],
55+
"BY" : ["EUR"],
56+
"KH" : ["ASI"],
57+
"CM" : ["AFR"],
58+
"CA" : ["NAC"],
59+
"CV" : ["AFR"],
60+
"KY" : ["NAC"],
61+
"CF" : ["AFR"],
62+
"LK" : ["ASI"],
63+
"TD" : ["AFR"],
64+
"CL" : ["SAC"],
65+
"CN" : ["ASI"],
66+
"TW" : ["ASI"],
67+
"CX" : ["ASI"],
68+
"CC" : ["ASI"],
69+
"CO" : ["SAC"],
70+
"KM" : ["AFR"],
71+
"YT" : ["AFR"],
72+
"CG" : ["AFR"],
73+
"CD" : ["AFR"],
74+
"CK" : ["OCE"],
75+
"CR" : ["NAC"],
76+
"HR" : ["EUR"],
77+
"CU" : ["NAC"],
78+
"CY" : ["EUR", "ASI"],
79+
"CZ" : ["EUR"],
80+
"BJ" : ["AFR"],
81+
"DK" : ["EUR"],
82+
"DM" : ["NAC"],
83+
"DO" : ["NAC"],
84+
"EC" : ["SAC"],
85+
"SV" : ["NAC"],
86+
"GQ" : ["AFR"],
87+
"ET" : ["AFR"],
88+
"ER" : ["AFR"],
89+
"EE" : ["EUR"],
90+
"FO" : ["EUR"],
91+
"FK" : ["SAC"],
92+
"GS" : ["ANA"],
93+
"FJ" : ["OCE"],
94+
"FI" : ["EUR"],
95+
"AX" : ["EUR"],
96+
"FR" : ["EUR"],
97+
"GF" : ["SAC"],
98+
"PF" : ["OCE"],
99+
"TF" : ["ANA"],
100+
"DJ" : ["AFR"],
101+
"GA" : ["AFR"],
102+
"GE" : ["EUR", "ASI"],
103+
"GM" : ["AFR"],
104+
"DE" : ["EUR"],
105+
"GH" : ["AFR"],
106+
"GI" : ["EUR"],
107+
"KI" : ["OCE"],
108+
"GR" : ["EUR"],
109+
"GL" : ["NAC"],
110+
"GD" : ["NAC"],
111+
"GP" : ["NAC"],
112+
"GU" : ["OCE"],
113+
"GT" : ["NAC"],
114+
"GN" : ["AFR"],
115+
"GY" : ["SAC"],
116+
"HT" : ["NAC"],
117+
"HM" : ["ANA"],
118+
"VA" : ["EUR"],
119+
"HN" : ["NAC"],
120+
"HK" : ["ASI"],
121+
"HU" : ["EUR"],
122+
"IS" : ["EUR"],
123+
"IN" : ["ASI"],
124+
"ID" : ["ASI"],
125+
"IR" : ["ASI"],
126+
"IQ" : ["ASI"],
127+
"IE" : ["EUR"],
128+
"IL" : ["ASI"],
129+
"IT" : ["EUR"],
130+
"CI" : ["AFR"],
131+
"JM" : ["NAC"],
132+
"JP" : ["ASI"],
133+
"KZ" : ["EUR", "ASI"],
134+
"JO" : ["ASI"],
135+
"KE" : ["AFR"],
136+
"KP" : ["ASI"],
137+
"KR" : ["ASI"],
138+
"KW" : ["ASI"],
139+
"KG" : ["ASI"],
140+
"LA" : ["ASI"],
141+
"LB" : ["ASI"],
142+
"LS" : ["AFR"],
143+
"LV" : ["EUR"],
144+
"LR" : ["AFR"],
145+
"LY" : ["AFR"],
146+
"LI" : ["EUR"],
147+
"LT" : ["EUR"],
148+
"LU" : ["EUR"],
149+
"MO" : ["ASI"],
150+
"MG" : ["AFR"],
151+
"MW" : ["AFR"],
152+
"MY" : ["ASI"],
153+
"MV" : ["ASI"],
154+
"ML" : ["AFR"],
155+
"MT" : ["EUR"],
156+
"MQ" : ["NAC"],
157+
"MR" : ["AFR"],
158+
"MU" : ["AFR"],
159+
"MX" : ["NAC"],
160+
"MC" : ["EUR"],
161+
"MN" : ["ASI"],
162+
"MD" : ["EUR"],
163+
"ME" : ["EUR"],
164+
"MS" : ["NAC"],
165+
"MA" : ["AFR"],
166+
"MZ" : ["AFR"],
167+
"OM" : ["ASI"],
168+
"NA" : ["AFR"],
169+
"NR" : ["OCE"],
170+
"NP" : ["ASI"],
171+
"NL" : ["EUR"],
172+
"AN" : ["NAC"],
173+
"CW" : ["NAC"],
174+
"AW" : ["NAC"],
175+
"SX" : ["NAC"],
176+
"BQ" : ["NAC"],
177+
"NC" : ["OCE"],
178+
"VU" : ["OCE"],
179+
"NZ" : ["OCE"],
180+
"NI" : ["NAC"],
181+
"NE" : ["AFR"],
182+
"NG" : ["AFR"],
183+
"NU" : ["OCE"],
184+
"NF" : ["OCE"],
185+
"NO" : ["EUR"],
186+
"MP" : ["OCE"],
187+
"UM" : ["OCE", "NAC"],
188+
"FM" : ["OCE"],
189+
"MH" : ["OCE"],
190+
"PW" : ["OCE"],
191+
"PK" : ["ASI"],
192+
"PS" : ["ASI"],
193+
"PA" : ["NAC"],
194+
"PG" : ["OCE"],
195+
"PY" : ["SAC"],
196+
"PE" : ["SAC"],
197+
"PH" : ["ASI"],
198+
"PN" : ["OCE"],
199+
"PL" : ["EUR"],
200+
"PT" : ["EUR"],
201+
"GW" : ["AFR"],
202+
"TL" : ["ASI"],
203+
"PR" : ["NAC"],
204+
"QA" : ["ASI"],
205+
"RE" : ["AFR"],
206+
"RO" : ["EUR"],
207+
"RU" : ["EUR", "ASI"],
208+
"RW" : ["AFR"],
209+
"BL" : ["NAC"],
210+
"SH" : ["AFR"],
211+
"KN" : ["NAC"],
212+
"AI" : ["NAC"],
213+
"LC" : ["NAC"],
214+
"MF" : ["NAC"],
215+
"PM" : ["NAC"],
216+
"VC" : ["NAC"],
217+
"SM" : ["EUR"],
218+
"ST" : ["AFR"],
219+
"SA" : ["ASI"],
220+
"SN" : ["AFR"],
221+
"RS" : ["EUR"],
222+
"SC" : ["AFR"],
223+
"SL" : ["AFR"],
224+
"SG" : ["ASI"],
225+
"SK" : ["EUR"],
226+
"VN" : ["ASI"],
227+
"SI" : ["EUR"],
228+
"SO" : ["AFR"],
229+
"ZA" : ["AFR"],
230+
"ZW" : ["AFR"],
231+
"ES" : ["EUR"],
232+
"SS" : ["AFR"],
233+
"SD" : ["AFR"],
234+
"EH" : ["AFR"],
235+
"SR" : ["SAC"],
236+
"SJ" : ["EUR"],
237+
"SZ" : ["AFR"],
238+
"SE" : ["EUR"],
239+
"CH" : ["EUR"],
240+
"SY" : ["ASI"],
241+
"TJ" : ["ASI"],
242+
"TH" : ["ASI"],
243+
"TG" : ["AFR"],
244+
"TK" : ["OCE"],
245+
"TO" : ["OCE"],
246+
"TT" : ["NAC"],
247+
"AE" : ["ASI"],
248+
"TN" : ["AFR"],
249+
"TR" : ["EUR", "ASI"],
250+
"TM" : ["ASI"],
251+
"TC" : ["NAC"],
252+
"TV" : ["OCE"],
253+
"UG" : ["AFR"],
254+
"UA" : ["EUR"],
255+
"MK" : ["EUR"],
256+
"EG" : ["AFR"],
257+
"GB" : ["EUR"],
258+
"GG" : ["EUR"],
259+
"JE" : ["EUR"],
260+
"IM" : ["EUR"],
261+
"TZ" : ["AFR"],
262+
"US" : ["NAC"],
263+
"VI" : ["NAC"],
264+
"BF" : ["AFR"],
265+
"UY" : ["SAC"],
266+
"UZ" : ["ASI"],
267+
"VE" : ["SAC"],
268+
"WF" : ["OCE"],
269+
"WS" : ["OCE"],
270+
"YE" : ["ASI"],
271+
"ZM" : ["AFR"],
272+
"XD" : ["ASI"],
273+
"XE" : ["ASI"],
274+
"XS" : ["ASI"],
275+
# TODO "XX - Disputed Territory" conflicts with `default_country_code`
276+
# "XX" : ["OCE"],
277+
countries.default_country_code : default_continent_codes_list,
278+
}
279+
280+
def continent_codes_list(s):
281+
"""
282+
Return a list(!) of three letter continent codes (Alpha-3) inspired
283+
by https://datahub.io/core/continent-codes#resource-continent-codes.
284+
(We could not find any relevant ISO norm)
285+
Defaults to ["CCC"].
286+
287+
As of now (March 2020) following countries are located on more than one
288+
continent:
289+
290+
OCE - Oceania and NAC - North America:
291+
UM - United States Minor Outlying Islands
292+
293+
EUR - Europe and ASI - Asia:
294+
RU - Russian Federation
295+
AM - Armenia
296+
GE - Georgia
297+
CY - Cyprus
298+
TR - Turkey
299+
KZ - Kazakhstan
300+
AZ - Azerbaijan
301+
"""
302+
codes = country_code__continent_codes_list.get(s, default_continent_codes_list)
303+
if codes == default_continent_codes_list:
304+
# TODO probably would be better to return an empty list or even better
305+
# to create a union type `CountryCode` so that any misspelled country
306+
# code would lead to a type error (thrown early on, so it could be
307+
# dealt with early on too)
308+
LOGGER.warning(f"No list of continent codes found for '{s}'. "+
309+
f"Using '{codes}'!")
310+
311+
return codes

0 commit comments

Comments
 (0)