mirror of
https://github.com/dcarrillo/whatismyip.git
synced 2024-11-16 07:21:13 +00:00
144 lines
3.2 KiB
Go
144 lines
3.2 KiB
Go
package router
|
|
|
|
import (
|
|
"fmt"
|
|
"net"
|
|
"net/http"
|
|
"sort"
|
|
"strings"
|
|
|
|
"github.com/dcarrillo/whatismyip/models"
|
|
"github.com/dcarrillo/whatismyip/service"
|
|
"github.com/gin-gonic/gin"
|
|
)
|
|
|
|
type geoDataFormatter struct {
|
|
title string
|
|
format func(*models.GeoRecord) string
|
|
}
|
|
|
|
type asnDataFormatter struct {
|
|
title string
|
|
format func(*models.ASNRecord) string
|
|
}
|
|
|
|
var geoOutput = map[string]geoDataFormatter{
|
|
"country": {
|
|
title: "Country",
|
|
format: func(record *models.GeoRecord) string {
|
|
return record.Country.Names["en"]
|
|
},
|
|
},
|
|
"country_code": {
|
|
title: "Country Code",
|
|
format: func(record *models.GeoRecord) string {
|
|
return record.Country.ISOCode
|
|
},
|
|
},
|
|
"city": {
|
|
title: "City",
|
|
format: func(record *models.GeoRecord) string {
|
|
return record.City.Names["en"]
|
|
},
|
|
},
|
|
"latitude": {
|
|
title: "Latitude",
|
|
format: func(record *models.GeoRecord) string {
|
|
return fmt.Sprintf("%f", record.Location.Latitude)
|
|
},
|
|
},
|
|
"longitude": {
|
|
title: "Longitude",
|
|
format: func(record *models.GeoRecord) string {
|
|
return fmt.Sprintf("%f", record.Location.Longitude)
|
|
},
|
|
},
|
|
"postal_code": {
|
|
title: "Postal Code",
|
|
format: func(record *models.GeoRecord) string {
|
|
return record.Postal.Code
|
|
},
|
|
},
|
|
"time_zone": {
|
|
title: "Time Zone",
|
|
format: func(record *models.GeoRecord) string {
|
|
return record.Location.TimeZone
|
|
},
|
|
},
|
|
}
|
|
|
|
var asnOutput = map[string]asnDataFormatter{
|
|
"number": {
|
|
title: "ASN Number",
|
|
format: func(record *models.ASNRecord) string {
|
|
return fmt.Sprintf("%d", record.AutonomousSystemNumber)
|
|
},
|
|
},
|
|
"organization": {
|
|
title: "ASN Organization",
|
|
format: func(record *models.ASNRecord) string {
|
|
return record.AutonomousSystemOrganization
|
|
},
|
|
},
|
|
}
|
|
|
|
func getGeoAsString(ctx *gin.Context) {
|
|
field := strings.ToLower(ctx.Params.ByName("field"))
|
|
ip := service.Geo{IP: net.ParseIP(ctx.ClientIP())}
|
|
record := ip.LookUpCity()
|
|
|
|
if field == "" {
|
|
ctx.String(http.StatusOK, geoCityRecordToString(record))
|
|
} else if g, ok := geoOutput[field]; ok {
|
|
ctx.String(http.StatusOK, g.format(record))
|
|
} else {
|
|
ctx.String(http.StatusNotFound, http.StatusText(http.StatusNotFound))
|
|
}
|
|
}
|
|
|
|
func getASNAsString(ctx *gin.Context) {
|
|
field := strings.ToLower(ctx.Params.ByName("field"))
|
|
ip := service.Geo{IP: net.ParseIP(ctx.ClientIP())}
|
|
record := ip.LookUpASN()
|
|
|
|
if field == "" {
|
|
ctx.String(http.StatusOK, geoASNRecordToString(record))
|
|
} else if g, ok := asnOutput[field]; ok {
|
|
ctx.String(http.StatusOK, g.format(record))
|
|
} else {
|
|
ctx.String(http.StatusNotFound, http.StatusText(http.StatusNotFound))
|
|
}
|
|
}
|
|
|
|
func geoCityRecordToString(record *models.GeoRecord) string {
|
|
var output string
|
|
|
|
keys := make([]string, 0, len(geoOutput))
|
|
for k := range geoOutput {
|
|
keys = append(keys, k)
|
|
}
|
|
sort.Strings(keys)
|
|
|
|
for _, k := range keys {
|
|
output += fmt.Sprintf("%s: %v\n", geoOutput[k].title, geoOutput[k].format(record))
|
|
}
|
|
|
|
return output
|
|
}
|
|
|
|
func geoASNRecordToString(record *models.ASNRecord) string {
|
|
var output string
|
|
|
|
keys := make([]string, 0, len(asnOutput))
|
|
for k := range asnOutput {
|
|
keys = append(keys, k)
|
|
}
|
|
sort.Strings(keys)
|
|
|
|
for _, k := range keys {
|
|
output += fmt.Sprintf("%s: %v\n", asnOutput[k].title, asnOutput[k].format(record))
|
|
}
|
|
|
|
return output
|
|
}
|