Skip to content
Closed
Show file tree
Hide file tree
Changes from 1 commit
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
Prev Previous commit
Next Next commit
Add continent code(s) assignment
  • Loading branch information
BostX committed Mar 29, 2020
commit 937648e722f34b361b08b2ecc06b223473c8c75a
20 changes: 17 additions & 3 deletions app/location/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from ..coordinates import Coordinates
from ..utils import countries
from ..utils import countries, continents
from ..utils.populations import country_population


Expand All @@ -26,12 +26,25 @@ def __init__(self, id, country, province, coordinates, last_updated, confirmed,
@property
def country_code(self):
"""
Gets the alpha-2 code represention of the country. Returns 'XX' if none is found.
Gets the alpha-2 code representation of the country. Returns 'XX' if none is found.

:returns: The country code.
:rtype: str
"""
return (countries.country_code(self.country) or countries.default_country_code).upper()
return countries.country_code(self.country) or countries.default_country_code

@property
def continent_codes_list(self):
"""
Gets the alpha-3 code representations of the continent codes where the
country represented by the country code is located. Returns 'CCC' if
none is found.

:returns: The list of continent codes.
:rtype: list
"""
country_code = countries.country_code(self.country)
return continents.continent_codes_list(country_code) or continents.default_continent_codes_list

@property
def country_population(self):
Expand All @@ -55,6 +68,7 @@ def serialize(self):
"id": self.id,
"country": self.country,
"country_code": self.country_code,
"continent_codes_list": self.continent_codes_list,
"country_population": self.country_population,
"province": self.province,
# Coordinates.
Expand Down
1 change: 1 addition & 0 deletions app/models/location.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ class Location(BaseModel):
id: int
country: str
country_code: str
continent_codes_list: list = []
country_population: int = None
province: str = ""
county: str = ""
Expand Down
1 change: 1 addition & 0 deletions app/router/v2/locations.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ def get_locations(
request: Request,
source: Sources = "jhu",
country_code: str = None,
continent_codes_list: list = [],
province: str = None,
county: str = None,
timelines: bool = False,
Expand Down
7 changes: 5 additions & 2 deletions app/services/location/jhu.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
from ...coordinates import Coordinates
from ...location import TimelinedLocation
from ...timeline import Timeline
from ...utils import countries
from ...utils import countries, continents
from ...utils import date as date_util
from . import LocationService

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

country_code = countries.country_code(country)

# Normalize the item and append to locations.
locations.append(
{
# General info.
"country": country,
"country_code": countries.country_code(country),
"country_code": country_code,
"continent_codes_list" : continents.continent_codes_list(country_code),
"province": item["Province/State"],
# Coordinates.
"coordinates": {"lat": item["Lat"], "long": item["Long"],},
Expand Down
311 changes: 311 additions & 0 deletions app/utils/continents.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,311 @@
import logging
from itertools import chain
from . import countries

LOGGER = logging.getLogger(__name__)

default_continent_codes_list = ["CCC"]

continent_names__continent_codes = {
"Africa" : "AFR",
"North America" : "NAC", # "NAM" clashes with "Namibia"
"Oceania" : "OCE",
"Antarctica" : "ANA", # "ANT" clashes with "Netherlands Antilles"
"Asia" : "ASI",
"Europe" : "EUR",
"South America" : "SAC",
"Others" : default_continent_codes_list[0],
}

country_code__continent_codes_list = {
"AF" : ["ASI"],
"XK" : ["EUR"],
"AL" : ["EUR"],
"AQ" : ["ANA"],
"DZ" : ["AFR"],
"AS" : ["OCE"],
"AD" : ["EUR"],
"AO" : ["AFR"],
"AG" : ["NAC"],
"AZ" : ["EUR", "ASI"],
"AR" : ["SAC"],
"AU" : ["OCE"],
"AT" : ["EUR"],
"BS" : ["NAC"],
"BH" : ["ASI"],
"BD" : ["ASI"],
"AM" : ["EUR", "ASI"],
"BB" : ["NAC"],
"BE" : ["EUR"],
"BM" : ["NAC"],
"BT" : ["ASI"],
"BO" : ["SAC"],
"BA" : ["EUR"],
"BW" : ["AFR"],
"BV" : ["ANA"],
"BR" : ["SAC"],
"BZ" : ["NAC"],
"IO" : ["ASI"],
"SB" : ["OCE"],
"VG" : ["NAC"],
"BN" : ["ASI"],
"BG" : ["EUR"],
"MM" : ["ASI"],
"BI" : ["AFR"],
"BY" : ["EUR"],
"KH" : ["ASI"],
"CM" : ["AFR"],
"CA" : ["NAC"],
"CV" : ["AFR"],
"KY" : ["NAC"],
"CF" : ["AFR"],
"LK" : ["ASI"],
"TD" : ["AFR"],
"CL" : ["SAC"],
"CN" : ["ASI"],
"TW" : ["ASI"],
"CX" : ["ASI"],
"CC" : ["ASI"],
"CO" : ["SAC"],
"KM" : ["AFR"],
"YT" : ["AFR"],
"CG" : ["AFR"],
"CD" : ["AFR"],
"CK" : ["OCE"],
"CR" : ["NAC"],
"HR" : ["EUR"],
"CU" : ["NAC"],
"CY" : ["EUR", "ASI"],
"CZ" : ["EUR"],
"BJ" : ["AFR"],
"DK" : ["EUR"],
"DM" : ["NAC"],
"DO" : ["NAC"],
"EC" : ["SAC"],
"SV" : ["NAC"],
"GQ" : ["AFR"],
"ET" : ["AFR"],
"ER" : ["AFR"],
"EE" : ["EUR"],
"FO" : ["EUR"],
"FK" : ["SAC"],
"GS" : ["ANA"],
"FJ" : ["OCE"],
"FI" : ["EUR"],
"AX" : ["EUR"],
"FR" : ["EUR"],
"GF" : ["SAC"],
"PF" : ["OCE"],
"TF" : ["ANA"],
"DJ" : ["AFR"],
"GA" : ["AFR"],
"GE" : ["EUR", "ASI"],
"GM" : ["AFR"],
"DE" : ["EUR"],
"GH" : ["AFR"],
"GI" : ["EUR"],
"KI" : ["OCE"],
"GR" : ["EUR"],
"GL" : ["NAC"],
"GD" : ["NAC"],
"GP" : ["NAC"],
"GU" : ["OCE"],
"GT" : ["NAC"],
"GN" : ["AFR"],
"GY" : ["SAC"],
"HT" : ["NAC"],
"HM" : ["ANA"],
"VA" : ["EUR"],
"HN" : ["NAC"],
"HK" : ["ASI"],
"HU" : ["EUR"],
"IS" : ["EUR"],
"IN" : ["ASI"],
"ID" : ["ASI"],
"IR" : ["ASI"],
"IQ" : ["ASI"],
"IE" : ["EUR"],
"IL" : ["ASI"],
"IT" : ["EUR"],
"CI" : ["AFR"],
"JM" : ["NAC"],
"JP" : ["ASI"],
"KZ" : ["EUR", "ASI"],
"JO" : ["ASI"],
"KE" : ["AFR"],
"KP" : ["ASI"],
"KR" : ["ASI"],
"KW" : ["ASI"],
"KG" : ["ASI"],
"LA" : ["ASI"],
"LB" : ["ASI"],
"LS" : ["AFR"],
"LV" : ["EUR"],
"LR" : ["AFR"],
"LY" : ["AFR"],
"LI" : ["EUR"],
"LT" : ["EUR"],
"LU" : ["EUR"],
"MO" : ["ASI"],
"MG" : ["AFR"],
"MW" : ["AFR"],
"MY" : ["ASI"],
"MV" : ["ASI"],
"ML" : ["AFR"],
"MT" : ["EUR"],
"MQ" : ["NAC"],
"MR" : ["AFR"],
"MU" : ["AFR"],
"MX" : ["NAC"],
"MC" : ["EUR"],
"MN" : ["ASI"],
"MD" : ["EUR"],
"ME" : ["EUR"],
"MS" : ["NAC"],
"MA" : ["AFR"],
"MZ" : ["AFR"],
"OM" : ["ASI"],
"NA" : ["AFR"],
"NR" : ["OCE"],
"NP" : ["ASI"],
"NL" : ["EUR"],
"AN" : ["NAC"],
"CW" : ["NAC"],
"AW" : ["NAC"],
"SX" : ["NAC"],
"BQ" : ["NAC"],
"NC" : ["OCE"],
"VU" : ["OCE"],
"NZ" : ["OCE"],
"NI" : ["NAC"],
"NE" : ["AFR"],
"NG" : ["AFR"],
"NU" : ["OCE"],
"NF" : ["OCE"],
"NO" : ["EUR"],
"MP" : ["OCE"],
"UM" : ["OCE", "NAC"],
"FM" : ["OCE"],
"MH" : ["OCE"],
"PW" : ["OCE"],
"PK" : ["ASI"],
"PS" : ["ASI"],
"PA" : ["NAC"],
"PG" : ["OCE"],
"PY" : ["SAC"],
"PE" : ["SAC"],
"PH" : ["ASI"],
"PN" : ["OCE"],
"PL" : ["EUR"],
"PT" : ["EUR"],
"GW" : ["AFR"],
"TL" : ["ASI"],
"PR" : ["NAC"],
"QA" : ["ASI"],
"RE" : ["AFR"],
"RO" : ["EUR"],
"RU" : ["EUR", "ASI"],
"RW" : ["AFR"],
"BL" : ["NAC"],
"SH" : ["AFR"],
"KN" : ["NAC"],
"AI" : ["NAC"],
"LC" : ["NAC"],
"MF" : ["NAC"],
"PM" : ["NAC"],
"VC" : ["NAC"],
"SM" : ["EUR"],
"ST" : ["AFR"],
"SA" : ["ASI"],
"SN" : ["AFR"],
"RS" : ["EUR"],
"SC" : ["AFR"],
"SL" : ["AFR"],
"SG" : ["ASI"],
"SK" : ["EUR"],
"VN" : ["ASI"],
"SI" : ["EUR"],
"SO" : ["AFR"],
"ZA" : ["AFR"],
"ZW" : ["AFR"],
"ES" : ["EUR"],
"SS" : ["AFR"],
"SD" : ["AFR"],
"EH" : ["AFR"],
"SR" : ["SAC"],
"SJ" : ["EUR"],
"SZ" : ["AFR"],
"SE" : ["EUR"],
"CH" : ["EUR"],
"SY" : ["ASI"],
"TJ" : ["ASI"],
"TH" : ["ASI"],
"TG" : ["AFR"],
"TK" : ["OCE"],
"TO" : ["OCE"],
"TT" : ["NAC"],
"AE" : ["ASI"],
"TN" : ["AFR"],
"TR" : ["EUR", "ASI"],
"TM" : ["ASI"],
"TC" : ["NAC"],
"TV" : ["OCE"],
"UG" : ["AFR"],
"UA" : ["EUR"],
"MK" : ["EUR"],
"EG" : ["AFR"],
"GB" : ["EUR"],
"GG" : ["EUR"],
"JE" : ["EUR"],
"IM" : ["EUR"],
"TZ" : ["AFR"],
"US" : ["NAC"],
"VI" : ["NAC"],
"BF" : ["AFR"],
"UY" : ["SAC"],
"UZ" : ["ASI"],
"VE" : ["SAC"],
"WF" : ["OCE"],
"WS" : ["OCE"],
"YE" : ["ASI"],
"ZM" : ["AFR"],
"XD" : ["ASI"],
"XE" : ["ASI"],
"XS" : ["ASI"],
# TODO "XX - Disputed Territory" conflicts with `default_country_code`
# "XX" : ["OCE"],
countries.default_country_code : default_continent_codes_list,
}

def continent_codes_list(s):
"""
Return a list(!) of three letter continent codes (Alpha-3) inspired
by https://datahub.io/core/continent-codes#resource-continent-codes.
(We could not find any relevant ISO norm)
Defaults to ["CCC"].

As of now (March 2020) following countries are located on more than one
continent:

OCE - Oceania and NAC - North America:
UM - United States Minor Outlying Islands

EUR - Europe and ASI - Asia:
RU - Russian Federation
AM - Armenia
GE - Georgia
CY - Cyprus
TR - Turkey
KZ - Kazakhstan
AZ - Azerbaijan
"""
codes = country_code__continent_codes_list.get(s, default_continent_codes_list)
if codes == default_continent_codes_list:
# TODO probably would be better to return an empty list or even better
# to create a union type `CountryCode` so that any misspelled country
# code would lead to a type error (thrown early on, so it could be
# dealt with early on too)
LOGGER.warning(f"No list of continent codes found for '{s}'. "+
f"Using '{codes}'!")

return codes
Loading