Skip to content

Commit

Permalink
Add small improvements
Browse files Browse the repository at this point in the history
  • Loading branch information
night-codes committed Apr 15, 2018
1 parent 20d9f82 commit 6b94677
Show file tree
Hide file tree
Showing 8 changed files with 168 additions and 42 deletions.
8 changes: 4 additions & 4 deletions examples/bench.go → examples/bench/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,19 @@ package main

import (
"fmt"
"gopkg.in/night-codes/go-sypexgeo.v1"
"github.com/night-codes/go-sypexgeo"
"math/rand"
"strconv"
"time"
)

func main() {
geo := sypexgeo.New("SxGeoCity.dat")
geo := sypexgeo.New("../SxGeoCity.dat")

t := time.Now()
for i := 0; i < 100000; i++ {
for i := 0; i < 1000000; i++ {
ip := strconv.Itoa(rand.Intn(222)) + "." + strconv.Itoa(rand.Intn(222)) + "." + strconv.Itoa(rand.Intn(222)) + "." + strconv.Itoa(rand.Intn(222))
geo.GetCityFull(ip)
geo.Info(ip)
}
fmt.Printf("The call took %v to run.\n", time.Now().Sub(t))
}
4 changes: 2 additions & 2 deletions examples/clib/sp.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,8 @@ static void spxFree(spxInfo s) {
*/
import "C"
import (
"gopkg.in/mirrr/go-sypexgeo.v1"
"gopkg.in/mirrr/types.v1"
"github.com/night-codes/go-sypexgeo"
"gopkg.in/night-codes/types.v1"
)

var geo sypexgeo.SxGEO
Expand Down
1 change: 0 additions & 1 deletion examples/clib/test.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
#include <stdio.h>
#include "sp.h"


void printInfo(spxInfo info) {
Expand Down
24 changes: 0 additions & 24 deletions examples/geoAPI.go

This file was deleted.

25 changes: 25 additions & 0 deletions examples/geoAPI/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package main

import (
"encoding/json"
"fmt"
"github.com/night-codes/go-sypexgeo"
"github.com/night-codes/tokay"
"time"
)

func main() {
geo := sypexgeo.New("../SxGeoCity.dat")
router := tokay.New()

router.Any("/spxgeo/<ip>", func(c *tokay.Context) {
c.Header("Expires", time.Now().String())
c.Header("Cache-Control", "no-cache")
info, _ := geo.Info(c.Param("ip"))
j, _ := json.MarshalIndent(info, "", "\t")
c.String(200, string(j))
})

fmt.Println("Server started at http://localhost:3000")
router.Run(":3000")
}
6 changes: 3 additions & 3 deletions examples/simple.go → examples/simple/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@ package main
import (
"encoding/json"
"fmt"
"gopkg.in/night-codes/go-sypexgeo.v1"
"github.com/night-codes/go-sypexgeo"
)

func main() {
geo := sypexgeo.New("SxGeoCity.dat")
printJSON(geo.GetCityFull("93.73.35.74"))
geo := sypexgeo.New("../SxGeoCity.dat")
printJSON(geo.Info("93.73.35.74"))
}

func printJSON(t ...interface{}) {
Expand Down
126 changes: 126 additions & 0 deletions sypex.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,43 @@ type (
Version float32
Updated uint32
}
// Country struct
Country struct {
ID uint8
ISO string
NameEn string
NameRu string
Lon float32
Lat float32
}
// Region struct
Region struct {
ID uint32
ISO string
NameEn string
NameRu string
}
// City struct
City struct {
ID uint32
NameEn string
NameRu string
Lon float32
Lat float32
}
// Result of geoip lookup
Result struct {
Country Country
Region Region
City City
}
)

/*func test() {
a := &SxGEO{}
a.Get
}*/

func (f *finder) getLocationOffset(IP string) (uint32, error) {
firstByte, err := getIPByte(IP, 0)
if err != nil {
Expand Down Expand Up @@ -181,6 +216,68 @@ func (f *finder) unpack(seek, uType uint32) (map[string]interface{}, error) {
return ret, nil
}

func (f *finder) parseToStruct(seek uint32, full bool) (Result, error) {
ret := Result{}
result, err := f.parseCity(seek, full)
if err == nil {
if countryIfce, exists := result["country"]; exists {
country, _ := countryIfce.(map[string]interface{})
if f, ok := country["id"]; ok {
ret.Country.ID, _ = f.(uint8)
}
if f, ok := country["name_en"]; ok {
ret.Country.NameEn, _ = f.(string)
}
if f, ok := country["name_ru"]; ok {
ret.Country.NameRu, _ = f.(string)
}
if f, ok := country["lat"]; ok {
ret.Country.Lat, _ = f.(float32)
}
if f, ok := country["lon"]; ok {
ret.Country.Lon, _ = f.(float32)
}
if f, ok := country["iso"]; ok {
ret.Country.ISO, _ = f.(string)
}
}
if cregionIfce, exists := result["region"]; exists {
region, _ := cregionIfce.(map[string]interface{})
if f, ok := region["id"]; ok {
ret.Region.ID, _ = f.(uint32)
}
if f, ok := region["name_en"]; ok {
ret.Region.NameEn, _ = f.(string)
}
if f, ok := region["name_ru"]; ok {
ret.Region.NameRu, _ = f.(string)
}
if f, ok := region["iso"]; ok {
ret.Region.ISO, _ = f.(string)
}
}
if cityIfce, exists := result["city"]; exists {
city, _ := cityIfce.(map[string]interface{})
if f, ok := city["id"]; ok {
ret.City.ID, _ = f.(uint32)
}
if f, ok := city["name_en"]; ok {
ret.City.NameEn, _ = f.(string)
}
if f, ok := city["name_ru"]; ok {
ret.City.NameRu, _ = f.(string)
}
if f, ok := city["lat"]; ok {
ret.City.Lat, _ = f.(float32)
}
if f, ok := city["lon"]; ok {
ret.City.Lon, _ = f.(float32)
}
}
}
return ret, err
}

func (f *finder) parseCity(seek uint32, full bool) (map[string]interface{}, error) {
if f.PackLen == 0 {
return obj(), errors.New("Pack methods not found")
Expand Down Expand Up @@ -263,6 +360,35 @@ func (s *SxGEO) GetCityFull(IP string) (map[string]interface{}, error) {
return s.finder.parseCity(seek, true)
}

// Info by IP
func (s *SxGEO) Info(IP string) (Result, error) {
seek, err := s.finder.getLocationOffset(IP)
if err != nil {
return Result{}, err
}
return s.finder.parseToStruct(seek, true)
}

// City info by IP
func (s *SxGEO) City(IP string) (City, error) {
seek, err := s.finder.getLocationOffset(IP)
if err != nil {
return City{}, err
}
ret, err2 := s.finder.parseToStruct(seek, false)
return ret.City, err2
}

// Country info by IP
func (s *SxGEO) Country(IP string) (Country, error) {
seek, err := s.finder.getLocationOffset(IP)
if err != nil {
return Country{}, err
}
ret, err2 := s.finder.parseToStruct(seek, true)
return ret.Country, err2
}

// GetCity get short info by IP
func (s *SxGEO) GetCity(IP string) (map[string]interface{}, error) {
seek, err := s.finder.getLocationOffset(IP)
Expand Down
16 changes: 8 additions & 8 deletions sypex_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,11 @@ func TestGetCityFull1(t *testing.T) {
if err != nil {
t.Error(err)
}
if info["city"].(Obj)["name_en"].(string) != "Kiev" {
t.Error("`name_en` not equal `Kiev`:", info["city"].(Obj)["name_en"])
if info["city"].(map[string]interface{})["name_en"].(string) != "Kiev" {
t.Error("`name_en` not equal `Kiev`:", info["city"].(map[string]interface{})["name_en"])
}
if info["region"].(Obj)["name_en"].(string) != "Kyiv" {
t.Error("`name_en` not equal `Kyiv`", info["region"].(Obj)["name_en"])
if info["region"].(map[string]interface{})["name_en"].(string) != "Kyiv" {
t.Error("`name_en` not equal `Kyiv`", info["region"].(map[string]interface{})["name_en"])
}
_, err = geo.GetCityFull("0.0.0.0")
if err == nil {
Expand All @@ -45,8 +45,8 @@ func TestGetCityFull2(t *testing.T) {
if err != nil {
t.Error(err)
}
if info["country"].(Obj)["name_en"].(string) != "Malaysia" {
t.Error("`name_en` not equal `Malaysia`:", info["country"].(Obj)["name_en"])
if info["country"].(map[string]interface{})["name_en"].(string) != "Malaysia" {
t.Error("`name_en` not equal `Malaysia`:", info["country"].(map[string]interface{})["name_en"])
}
fmt.Println("PASS")
}
Expand All @@ -57,8 +57,8 @@ func TestGetCity(t *testing.T) {
if err != nil {
t.Error(err)
}
if info["city"].(Obj)["name_en"].(string) != "Cupertino" {
t.Error("`name_en` not equal `Cupertino`", info["city"].(Obj)["name_en"])
if info["city"].(map[string]interface{})["name_en"].(string) != "Cupertino" {
t.Error("`name_en` not equal `Cupertino`", info["city"].(map[string]interface{})["name_en"])
}
fmt.Println("PASS")
}
Expand Down

0 comments on commit 6b94677

Please sign in to comment.