Code and data push

This commit is contained in:
Alarig Le Lay 2020-11-30 11:35:07 +01:00
parent f489f1b852
commit 2b8f378a9d
No known key found for this signature in database
GPG key ID: C865491BF197B54F
7 changed files with 116750 additions and 1 deletions

4749
2020-1 SubdivisionCodes.csv Normal file

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

Binary file not shown.

View file

@ -1,3 +1,11 @@
# UNLOCODE-lookup
Python3 script to find a city 3-letters code from UN/LOCODE
## Usage
Every help should be avaible in the `--help` output.
## Updating data
To update data, go to
http://www.unece.org/cefact/codesfortrade/codes_index.html to download the CSV
archive and uncompress it in this directory.

94
get-city-code.py Executable file
View file

@ -0,0 +1,94 @@
#!/usr/bin/env python
import argparse
import csv
import os
import re
import sys
# CSV structure:
# 0 empty
# 1 iso country code
# 2 city code
# 3 full name
# the rest is unused
parser = argparse.ArgumentParser(description='''Find cities code from UNLOCODE.
If the exact name is found when a country code is given, only this match will
be shown, all the MATCHES are displayed otherwise. The font case isnt taken in
%s/EXACT_MATCH/EXACT_MATCH/account but the accents are. ''')
parser.add_argument('--city', dest='city', type=str, required=True,
help='City name, will be looked for inside the CSV files')
parser.add_argument('--country', dest='country', type=str, required=False,
default='', help='''Country name, in ISO-3166 format, to narrow queries if
needed''')
args = parser.parse_args()
files = [file for file in os.listdir('.') if os.path.isfile(file)]
if len(files) == 0:
print('ERROR: No CSV file has been found.')
sys.exit(1)
def csvprocessing(city):
"""Tries to find the wanted city code into the list `city`."""
if (args.city.lower() == city[3].lower() and
args.country.lower() == city[1].lower()):
EXACT_MATCH.append(city)
if args.city.lower() == city[3].lower() and len(args.country) == 0:
MULTIPLE_MATCHES.append(city)
elif args.city.lower() in city[3].lower():
MATCHES.append(city)
def csvloop(file):
"""Loop over the lines of the CSV file. We have one list per line."""
entries = csv.reader(file)
for entry in entries:
if len(args.country) > 0:
if args.country.lower() == entry[1].lower():
csvprocessing(entry)
else:
pass
else:
csvprocessing(entry)
def print_results(exactitude, result_list):
"""Stupid function to print results based on very basic formating
condition."""
for match in result_list:
if re.match(r"^([A-Z]+)$", match[1]) and len(match[2]) > 0:
print('{} {} found for {} from country {}'.format(
exactitude, match[2], match[3], match[1]
))
# Global variables needed on the used functions
global MATCHES
global EXACT_MATCH
global MULTIPLE_MATCHES
MATCHES = []
EXACT_MATCH = []
MULTIPLE_MATCHES = []
# We look for all the CSV files in the current dir
for dir_file in files:
if re.match(r".*\.csv", dir_file, re.I):
# We cant assume that CSV file is utf-8 encoded
try:
with open(dir_file) as csvfile:
csvloop(csvfile)
except UnicodeDecodeError:
with open(dir_file, encoding='latin-1') as csvfile:
csvloop(csvfile)
# If the country has been provided
if len(EXACT_MATCH) > 0:
print_results('Exact match', EXACT_MATCH)
# If the country hasnt been provided but the cit(y|es) exist(s)
elif len(MULTIPLE_MATCHES) > 0:
print_results('Multiple MATCHES', MULTIPLE_MATCHES)
# Otherwise, throw some garbage to the user
else:
print_results('Non-exact MATCHES', MATCHES)