mirror of
				https://github.com/mpolden/echoip.git
				synced 2025-11-04 10:49:10 +01:00 
			
		
		
		
	
		
			
				
	
	
		
			104 lines
		
	
	
		
			2.1 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			104 lines
		
	
	
		
			2.1 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
package geo
 | 
						|
 | 
						|
import (
 | 
						|
	"math"
 | 
						|
	"net"
 | 
						|
 | 
						|
	geoip2 "github.com/oschwald/geoip2-golang"
 | 
						|
)
 | 
						|
 | 
						|
type Reader interface {
 | 
						|
	Country(net.IP) (Country, error)
 | 
						|
	City(net.IP) (City, error)
 | 
						|
	IsEmpty() bool
 | 
						|
}
 | 
						|
 | 
						|
type Country struct {
 | 
						|
	Name              string
 | 
						|
	ISO               string
 | 
						|
	IsInEuropeanUnion bool
 | 
						|
}
 | 
						|
 | 
						|
type City struct {
 | 
						|
	Name      string
 | 
						|
	Latitude  float64
 | 
						|
	Longitude float64
 | 
						|
}
 | 
						|
 | 
						|
type geoip struct {
 | 
						|
	country *geoip2.Reader
 | 
						|
	city    *geoip2.Reader
 | 
						|
}
 | 
						|
 | 
						|
func Open(countryDB, cityDB string) (Reader, error) {
 | 
						|
	var country, city *geoip2.Reader
 | 
						|
	if countryDB != "" {
 | 
						|
		r, err := geoip2.Open(countryDB)
 | 
						|
		if err != nil {
 | 
						|
			return nil, err
 | 
						|
		}
 | 
						|
		country = r
 | 
						|
	}
 | 
						|
	if cityDB != "" {
 | 
						|
		r, err := geoip2.Open(cityDB)
 | 
						|
		if err != nil {
 | 
						|
			return nil, err
 | 
						|
		}
 | 
						|
		city = r
 | 
						|
	}
 | 
						|
	return &geoip{country: country, city: city}, nil
 | 
						|
}
 | 
						|
 | 
						|
func (g *geoip) Country(ip net.IP) (Country, error) {
 | 
						|
	country := Country{}
 | 
						|
	if g.country == nil {
 | 
						|
		return country, nil
 | 
						|
	}
 | 
						|
	record, err := g.country.Country(ip)
 | 
						|
	if err != nil {
 | 
						|
		return country, err
 | 
						|
	}
 | 
						|
	if c, exists := record.Country.Names["en"]; exists {
 | 
						|
		country.Name = c
 | 
						|
	}
 | 
						|
	if c, exists := record.RegisteredCountry.Names["en"]; exists && country.Name == "" {
 | 
						|
		country.Name = c
 | 
						|
	}
 | 
						|
	if record.Country.IsoCode != "" {
 | 
						|
		country.ISO = record.Country.IsoCode
 | 
						|
	}
 | 
						|
	if record.RegisteredCountry.IsoCode != "" && country.ISO == "" {
 | 
						|
		country.ISO = record.RegisteredCountry.IsoCode
 | 
						|
	}
 | 
						|
	country.IsInEuropeanUnion = record.Country.IsInEuropeanUnion
 | 
						|
	if record.RegisteredCountry.IsoCode != "" && country.ISO == "" {
 | 
						|
		country.IsInEuropeanUnion = record.RegisteredCountry.IsInEuropeanUnion
 | 
						|
	}
 | 
						|
	return country, nil
 | 
						|
}
 | 
						|
 | 
						|
func (g *geoip) City(ip net.IP) (City, error) {
 | 
						|
	city := City{}
 | 
						|
	if g.city == nil {
 | 
						|
		return city, nil
 | 
						|
	}
 | 
						|
	record, err := g.city.City(ip)
 | 
						|
	if err != nil {
 | 
						|
		return city, err
 | 
						|
	}
 | 
						|
	if c, exists := record.City.Names["en"]; exists {
 | 
						|
		city.Name = c
 | 
						|
	}
 | 
						|
	if !math.IsNaN(record.Location.Latitude) {
 | 
						|
		city.Latitude = record.Location.Latitude
 | 
						|
	}
 | 
						|
	if !math.IsNaN(record.Location.Longitude) {
 | 
						|
		city.Longitude = record.Location.Longitude
 | 
						|
	}
 | 
						|
	return city, nil
 | 
						|
}
 | 
						|
 | 
						|
func (g *geoip) IsEmpty() bool {
 | 
						|
	return g.country == nil && g.city == nil
 | 
						|
}
 |