Files
geoip2/service/maxmind/mmdb/city.go
T

189 lines
4.8 KiB
Go

package mmdb
import (
"net/netip"
"git.kor-elf.net/kor-elf-shield/geoip2"
"git.kor-elf.net/kor-elf-shield/geoip2/internal/pkg"
"git.kor-elf.net/kor-elf-shield/geoip2/internal/service/maxmind/mmdb"
oschwaldGeoip2 "github.com/oschwald/geoip2-golang/v2"
)
const (
DownloadURLCityLite = "https://download.maxmind.com/geoip/databases/GeoLite2-City/download?suffix=tar.gz"
NameDirNameCityLite = "GeoLite2-City"
)
// City is a structure that contains information about the IP address.
type City struct {
// lang is a language.
lang Language
}
// NewCity creates a new City instance.
// @param download - an interface for downloading MaxMind GeoIP2 database
// @param logger - a logger
// @param dir - a directory for storing MaxMind GeoIP2 database
// @return geoip2.RefreshableGeoIP2 - a MaxMind GeoIP2 database service
func NewCity(download *Download, logger geoip2.Logger, dir string, language Language) geoip2.RefreshableGeoIP2 {
city := &City{
lang: language,
}
newDir := pkg.NewDir(dir, NameDirNameCityLite)
return mmdb.NewMMDB(download, city.infoCity, logger, newDir)
}
// infoCity returns information about the IP address.
// @param ip - IP address
// @param reader - MaxMind GeoIP2 database reader
// @return geoip2.Info - information about the IP address
// @return error - an error if the IP address could not be found
func (c *City) infoCity(ip netip.Addr, reader *oschwaldGeoip2.Reader) (geoip2.Info, error) {
record, err := reader.City(ip)
if err != nil {
return geoip2.Info{}, err
}
if !record.HasData() {
return geoip2.Info{}, geoip2.ErrNotFound
}
var timeZone string
if record.Location.HasData() {
timeZone = record.Location.TimeZone
}
return geoip2.Info{
IP: ip,
ISOCode: record.Country.ISOCode,
Country: c.country(record.Country),
City: c.city(record.City),
CitySubdivisions: c.subdivisions(record.Subdivisions),
TimeZone: timeZone,
Continent: c.continent(record.Continent),
}, nil
}
func (c *City) continent(continent oschwaldGeoip2.Continent) string {
if !continent.HasData() {
return ""
}
switch c.lang {
case LanguageRussian:
return continent.Names.Russian
case LanguageEnglish:
return continent.Names.English
case LanguageBrazilianPortuguese:
return continent.Names.BrazilianPortuguese
case LanguageSimplifiedChinese:
return continent.Names.SimplifiedChinese
case LanguageJapanese:
return continent.Names.Japanese
case LanguageGerman:
return continent.Names.German
case LanguageFrench:
return continent.Names.French
case LanguageSpanish:
return continent.Names.Spanish
default:
return continent.Names.English
}
}
func (c *City) country(country oschwaldGeoip2.CountryRecord) string {
if !country.HasData() {
return ""
}
switch c.lang {
case LanguageRussian:
return country.Names.Russian
case LanguageEnglish:
return country.Names.English
case LanguageBrazilianPortuguese:
return country.Names.BrazilianPortuguese
case LanguageSimplifiedChinese:
return country.Names.SimplifiedChinese
case LanguageJapanese:
return country.Names.Japanese
case LanguageGerman:
return country.Names.German
case LanguageFrench:
return country.Names.French
case LanguageSpanish:
return country.Names.Spanish
default:
return country.Names.English
}
}
func (c *City) city(city oschwaldGeoip2.CityRecord) string {
if !city.HasData() {
return ""
}
switch c.lang {
case LanguageRussian:
return city.Names.Russian
case LanguageEnglish:
return city.Names.English
case LanguageBrazilianPortuguese:
return city.Names.BrazilianPortuguese
case LanguageSimplifiedChinese:
return city.Names.SimplifiedChinese
case LanguageJapanese:
return city.Names.Japanese
case LanguageGerman:
return city.Names.German
case LanguageFrench:
return city.Names.French
case LanguageSpanish:
return city.Names.Spanish
default:
return city.Names.English
}
}
func (c *City) subdivisions(subdivisions []oschwaldGeoip2.CitySubdivision) []string {
var citySubdivisions []string
if len(subdivisions) == 0 {
return citySubdivisions
}
for _, subdivision := range subdivisions {
citySubdivisions = append(citySubdivisions, c.subdivision(subdivision))
}
return citySubdivisions
}
func (c *City) subdivision(subdivision oschwaldGeoip2.CitySubdivision) string {
if !subdivision.HasData() {
return ""
}
switch c.lang {
case LanguageRussian:
return subdivision.Names.Russian
case LanguageEnglish:
return subdivision.Names.English
case LanguageBrazilianPortuguese:
return subdivision.Names.BrazilianPortuguese
case LanguageSimplifiedChinese:
return subdivision.Names.SimplifiedChinese
case LanguageJapanese:
return subdivision.Names.Japanese
case LanguageGerman:
return subdivision.Names.German
case LanguageFrench:
return subdivision.Names.French
case LanguageSpanish:
return subdivision.Names.Spanish
default:
return subdivision.Names.English
}
}