Code and data push
This commit is contained in:
parent
f489f1b852
commit
2b8f378a9d
4749
2020-1 SubdivisionCodes.csv
Normal file
4749
2020-1 SubdivisionCodes.csv
Normal file
File diff suppressed because it is too large
Load diff
50820
2020-1 UNLOCODE CodeListPart1.csv
Normal file
50820
2020-1 UNLOCODE CodeListPart1.csv
Normal file
File diff suppressed because it is too large
Load diff
27246
2020-1 UNLOCODE CodeListPart2.csv
Normal file
27246
2020-1 UNLOCODE CodeListPart2.csv
Normal file
File diff suppressed because it is too large
Load diff
33832
2020-1 UNLOCODE CodeListPart3.csv
Normal file
33832
2020-1 UNLOCODE CodeListPart3.csv
Normal file
File diff suppressed because it is too large
Load diff
BIN
2020-1 UNLOCODE SecretariatNotes.pdf
Normal file
BIN
2020-1 UNLOCODE SecretariatNotes.pdf
Normal file
Binary file not shown.
10
README.md
10
README.md
|
@ -1,3 +1,11 @@
|
||||||
# UNLOCODE-lookup
|
# UNLOCODE-lookup
|
||||||
|
|
||||||
Python3 script to find a city 3-letters code from UN/LOCODE
|
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
94
get-city-code.py
Executable 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 isn’t 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 can’t 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 hasn’t 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)
|
Loading…
Reference in a new issue