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

View File

@ -13,11 +13,19 @@ import (
"flag"
"time"
"text/template"
"github.com/thebaer/geo"
"github.com/thebaer/tildes/store"
)
const (
locDataJSON = "/home/bear/public_html/where.json"
)
func main() {
// Get arguments
outFilePtr := flag.String("f", "where", "Outputted HTML filename (without .html)")
geocodeAPIKeyPtr := flag.String("k", "", "Google Geocoding API key")
flag.Parse()
// Get online users with `who`
@ -26,18 +34,32 @@ func main() {
// Fetch user locations based on IP address
for i := range users {
getGeo(&users[i])
getFuzzyCoords(&users[i], *geocodeAPIKeyPtr)
}
// Write user coord data
cacheUserLocations(&users)
// Generate page
generate(users, *outFilePtr)
}
type user struct {
Name string
IP string
Region string
Country string
CurrentTime string
Name string `json:"name"`
IP string `json:"ip"`
Region string `json:"region"`
Country string `json:"country"`
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})")
@ -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 {
if region != "" {
return fmt.Sprintf("%s, %s", region, country)