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 }