1
0
mirror of https://github.com/thebaer/tildes.git synced 2018-07-20 07:15:21 +00:00

Save fuzzy user coordinates to JSON file

Uses Google Geocoding API to get a fuzzy location based on the Region, Country from geo IP API.
This commit is contained in:
Matt Baer 2015-02-18 00:08:26 -05:00
parent 39577d0ecb
commit 31d5b9037b
2 changed files with 76 additions and 9 deletions

View File

@ -2,14 +2,26 @@ package store
import ( import (
"os" "os"
"fmt"
"bufio" "bufio"
"strings" "strings"
"io/ioutil"
) )
type Row struct { type Row struct {
Data []string Data []string
} }
func ReadData(path string) []byte {
d, err := ioutil.ReadFile(path)
if err != nil {
fmt.Println(err)
return []byte(``)
}
return d
}
func ReadRows(path, delimiter string) *[]Row { func ReadRows(path, delimiter string) *[]Row {
f, _ := os.Open(path) f, _ := os.Open(path)
@ -28,14 +40,14 @@ func ReadRows(path, delimiter string) *[]Row {
return &rows return &rows
} }
func WriteData(path, data, delimeter string) { func WriteData(path string, data []byte) {
f, err := os.OpenFile(path, os.O_CREATE | os.O_RDWR, 0644) f, err := os.OpenFile(path, os.O_CREATE | os.O_RDWR | os.O_TRUNC, 0644)
if err != nil { if err != nil {
fmt.Println(err) fmt.Println(err)
} }
defer f.Close() defer f.Close()
_, err = f.WriteString(data) _, err = f.Write(data)
if err != nil { if err != nil {
fmt.Println(err) fmt.Println(err)
} }
@ -48,7 +60,7 @@ func WriteRows(path string, rows *[]Row, delimeter string) {
} }
defer f.Close() defer f.Close()
for _, r := range rows { for _, r := range *rows {
_, err = f.WriteString(strings.Join(r.Data, delimeter)) _, err = f.WriteString(strings.Join(r.Data, delimeter))
if err != nil { if err != nil {
fmt.Println(err) fmt.Println(err)

View File

@ -13,11 +13,19 @@ import (
"flag" "flag"
"time" "time"
"text/template" "text/template"
"github.com/thebaer/geo"
"github.com/thebaer/tildes/store"
)
const (
locDataJSON = "/home/bear/public_html/where.json"
) )
func main() { func main() {
// Get arguments // Get arguments
outFilePtr := flag.String("f", "where", "Outputted HTML filename (without .html)") outFilePtr := flag.String("f", "where", "Outputted HTML filename (without .html)")
geocodeAPIKeyPtr := flag.String("k", "", "Google Geocoding API key")
flag.Parse() flag.Parse()
// Get online users with `who` // Get online users with `who`
@ -26,18 +34,32 @@ func main() {
// Fetch user locations based on IP address // Fetch user locations based on IP address
for i := range users { for i := range users {
getGeo(&users[i]) getGeo(&users[i])
getFuzzyCoords(&users[i], *geocodeAPIKeyPtr)
} }
// Write user coord data
cacheUserLocations(&users)
// Generate page // Generate page
generate(users, *outFilePtr) generate(users, *outFilePtr)
} }
type user struct { type user struct {
Name string Name string `json:"name"`
IP string IP string `json:"ip"`
Region string Region string `json:"region"`
Country string Country string `json:"country"`
CurrentTime string CurrentTime string `json:"current_time"`
Latitude float64 `json:"lat"`
Longitude float64 `json:"lng"`
}
type publicUser struct {
Name string `json:"name"`
Region string `json:"region"`
Country string `json:"country"`
Latitude float64 `json:"lat"`
Longitude float64 `json:"lng"`
} }
var ipRegex = regexp.MustCompile("(([0-9]{1,3}[.-]){3}[0-9]{1,3})") var ipRegex = regexp.MustCompile("(([0-9]{1,3}[.-]){3}[0-9]{1,3})")
@ -136,6 +158,39 @@ func getGeo(u *user) {
} }
} }
func getFuzzyCoords(u *user, apiKey string) {
fmt.Printf("Fetching %s fuzzy coordinates...\n", u.Name)
loc := prettyLocation(u.Region, u.Country)
addr, err := geo.Geocode(loc, apiKey)
if err != nil {
fmt.Println(err)
return
}
u.Latitude = addr.Lat
u.Longitude = addr.Lng
}
func cacheUserLocations(users *[]user) {
// Read user data
res := &map[string]publicUser{}
if err := json.Unmarshal(store.ReadData(locDataJSON), &res); err != nil {
fmt.Println(err)
}
// Update user data
for i := range *users {
u := (*users)[i]
(*res)[u.Name] = publicUser{Name: u.Name, Region: u.Region, Country: u.Country, Latitude: u.Latitude, Longitude: u.Longitude}
}
// Write user data
json, _ := json.Marshal(res)
store.WriteData(locDataJSON, json)
}
func prettyLocation(region, country string) string { func prettyLocation(region, country string) string {
if region != "" { if region != "" {
return fmt.Sprintf("%s, %s", region, country) return fmt.Sprintf("%s, %s", region, country)