183 lines
4.0 KiB
Go
183 lines
4.0 KiB
Go
|
package gountries
|
||
|
|
||
|
import (
|
||
|
"fmt"
|
||
|
"io/ioutil"
|
||
|
"path"
|
||
|
"path/filepath"
|
||
|
"strings"
|
||
|
|
||
|
"gopkg.in/yaml.v2"
|
||
|
)
|
||
|
|
||
|
// New creates an Query object and unmarshals the json file.
|
||
|
func New() *Query {
|
||
|
|
||
|
dataPath := filepath.Join("data", "yaml")
|
||
|
|
||
|
return NewFromPath(dataPath)
|
||
|
}
|
||
|
|
||
|
// NewFromPath creates a Query object from data folder in provided path
|
||
|
func NewFromPath(dataPath string) *Query {
|
||
|
|
||
|
if queryInited == false {
|
||
|
queryInstance = &Query{
|
||
|
Countries: populateCountries(dataPath),
|
||
|
Subdivisions: populateSubdivisions(dataPath),
|
||
|
}
|
||
|
queryInstance.NameToAlpha2 = populateNameIndex(queryInstance.Countries)
|
||
|
queryInstance.Alpha3ToAlpha2 = populateAlphaIndex(queryInstance.Countries)
|
||
|
queryInited = true
|
||
|
}
|
||
|
|
||
|
return queryInstance
|
||
|
}
|
||
|
|
||
|
func populateNameIndex(countries map[string]Country) map[string]string {
|
||
|
index := make(map[string]string)
|
||
|
for alpha2, country := range countries {
|
||
|
name := strings.ToLower(country.Name.Common)
|
||
|
officialName := strings.ToLower(country.Name.Official)
|
||
|
index[name] = alpha2
|
||
|
index[officialName] = alpha2
|
||
|
}
|
||
|
return index
|
||
|
}
|
||
|
|
||
|
func populateAlphaIndex(countries map[string]Country) map[string]string {
|
||
|
index := make(map[string]string)
|
||
|
for alpha2, country := range countries {
|
||
|
index[country.Codes.Alpha3] = alpha2
|
||
|
}
|
||
|
return index
|
||
|
}
|
||
|
|
||
|
func populateCountries(dataPath string) map[string]Country {
|
||
|
|
||
|
// Load countries into memory
|
||
|
//
|
||
|
//
|
||
|
var countries = make(map[string]Country)
|
||
|
|
||
|
countriesPath := path.Join(dataPath, "countries")
|
||
|
|
||
|
// Try packed data first before custom data directory
|
||
|
if yamlFileList, err := AssetDir("data/yaml/countries"); err == nil {
|
||
|
return populateCountriesFromPackedData(yamlFileList, "data/yaml/countries")
|
||
|
}
|
||
|
|
||
|
if info, err := ioutil.ReadDir(countriesPath); err == nil {
|
||
|
|
||
|
var file []byte
|
||
|
|
||
|
for _, v := range info {
|
||
|
|
||
|
if !v.IsDir() {
|
||
|
|
||
|
if file, err = ioutil.ReadFile(filepath.Join(countriesPath, v.Name())); err == nil {
|
||
|
|
||
|
country := Country{}
|
||
|
if err = yaml.Unmarshal(file, &country); err == nil {
|
||
|
|
||
|
// Save
|
||
|
countries[country.Codes.Alpha2] = country
|
||
|
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
} else {
|
||
|
panic(fmt.Errorf("Error loading Countries: %s", err))
|
||
|
}
|
||
|
return countries
|
||
|
}
|
||
|
|
||
|
func populateCountriesFromPackedData(fileList []string, path string) map[string]Country {
|
||
|
var data []byte
|
||
|
var err error
|
||
|
var countries = make(map[string]Country)
|
||
|
|
||
|
for _, yamlFile := range fileList {
|
||
|
var country Country
|
||
|
data, err = Asset(filepath.Join(path, yamlFile))
|
||
|
if err != nil {
|
||
|
continue
|
||
|
}
|
||
|
if err = yaml.Unmarshal(data, &country); err != nil {
|
||
|
continue
|
||
|
}
|
||
|
countries[country.Codes.Alpha2] = country
|
||
|
}
|
||
|
return countries
|
||
|
}
|
||
|
|
||
|
func populateSubdivisions(dataPath string) (list map[string][]SubDivision) {
|
||
|
|
||
|
// Load countries into memory
|
||
|
//
|
||
|
|
||
|
list = map[string][]SubDivision{}
|
||
|
|
||
|
subdivisionsPath := path.Join(dataPath, "subdivisions")
|
||
|
|
||
|
// Try packed data first before custom data directory
|
||
|
if yamlFileList, err := AssetDir("data/yaml/subdivisions"); err == nil {
|
||
|
return populateSubdivisionsFromPackedData(yamlFileList, "data/yaml/subdivisions")
|
||
|
}
|
||
|
|
||
|
if info, err := ioutil.ReadDir(subdivisionsPath); err == nil {
|
||
|
|
||
|
for _, v := range info {
|
||
|
|
||
|
if !v.IsDir() {
|
||
|
|
||
|
if file, err := ioutil.ReadFile(filepath.Join(subdivisionsPath, v.Name())); err == nil {
|
||
|
|
||
|
subdivisions := []SubDivision{}
|
||
|
|
||
|
if err := yaml.Unmarshal(file, &subdivisions); err == nil {
|
||
|
|
||
|
// Save
|
||
|
//subdivisions = append(subdivisions, subdivision...)
|
||
|
list[strings.Split(v.Name(), ".")[0]] = subdivisions
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
} else {
|
||
|
panic("Error loading Subdivisions")
|
||
|
}
|
||
|
|
||
|
return
|
||
|
}
|
||
|
|
||
|
func populateSubdivisionsFromPackedData(fileList []string, path string) map[string][]SubDivision {
|
||
|
var data []byte
|
||
|
var err error
|
||
|
sd := make(map[string][]SubDivision)
|
||
|
|
||
|
for _, yamlFile := range fileList {
|
||
|
data, err = Asset(filepath.Join(path, yamlFile))
|
||
|
if err != nil {
|
||
|
continue
|
||
|
}
|
||
|
var subdivisions []SubDivision
|
||
|
if err = yaml.Unmarshal(data, &subdivisions); err != nil {
|
||
|
continue
|
||
|
}
|
||
|
alpha2 := strings.Split(yamlFile, ".")[0]
|
||
|
|
||
|
sd[alpha2] = subdivisions
|
||
|
}
|
||
|
return sd
|
||
|
}
|