|
|
@@ -754,6 +754,7 @@ func main() {
|
|
|
http.HandleFunc("/movement.json", withDB(db, movementHandler))
|
|
|
http.HandleFunc("/performance.json", withDB(db, performanceHandler))
|
|
|
http.HandleFunc("/blockstats.json", withDB(db, blockStatsHandler))
|
|
|
+ http.HandleFunc("/locations.json", withDB(db, locationsHandler))
|
|
|
http.Handle("/static/", http.StripPrefix("/static/", http.FileServer(http.Dir("static"))))
|
|
|
|
|
|
go cacheRefresher(db)
|
|
|
@@ -765,9 +766,10 @@ func main() {
|
|
|
}
|
|
|
|
|
|
var (
|
|
|
- cacheData []byte
|
|
|
- cacheTime time.Time
|
|
|
- cacheMut sync.Mutex
|
|
|
+ cachedIndex []byte
|
|
|
+ cachedLocations []byte
|
|
|
+ cacheTime time.Time
|
|
|
+ cacheMut sync.Mutex
|
|
|
)
|
|
|
|
|
|
const maxCacheTime = 15 * time.Minute
|
|
|
@@ -791,8 +793,15 @@ func refreshCacheLocked(db *sql.DB) error {
|
|
|
if err != nil {
|
|
|
return err
|
|
|
}
|
|
|
- cacheData = buf.Bytes()
|
|
|
+ cachedIndex = buf.Bytes()
|
|
|
cacheTime = time.Now()
|
|
|
+
|
|
|
+ locs := rep["locations"].(map[location]int)
|
|
|
+ wlocs := make([]weightedLocation, 0, len(locs))
|
|
|
+ for loc, w := range locs {
|
|
|
+ wlocs = append(wlocs, weightedLocation{loc, w})
|
|
|
+ }
|
|
|
+ cachedLocations, _ = json.Marshal(wlocs)
|
|
|
return nil
|
|
|
}
|
|
|
|
|
|
@@ -810,13 +819,29 @@ func rootHandler(db *sql.DB, w http.ResponseWriter, r *http.Request) {
|
|
|
}
|
|
|
|
|
|
w.Header().Set("Content-Type", "text/html; charset=utf-8")
|
|
|
- w.Write(cacheData)
|
|
|
+ w.Write(cachedIndex)
|
|
|
} else {
|
|
|
http.Error(w, "Not found", 404)
|
|
|
return
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+func locationsHandler(db *sql.DB, w http.ResponseWriter, r *http.Request) {
|
|
|
+ cacheMut.Lock()
|
|
|
+ defer cacheMut.Unlock()
|
|
|
+
|
|
|
+ if time.Since(cacheTime) > maxCacheTime {
|
|
|
+ if err := refreshCacheLocked(db); err != nil {
|
|
|
+ log.Println(err)
|
|
|
+ http.Error(w, "Template Error", http.StatusInternalServerError)
|
|
|
+ return
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ w.Header().Set("Content-Type", "application/json; charset=utf-8")
|
|
|
+ w.Write(cachedLocations)
|
|
|
+}
|
|
|
+
|
|
|
func newDataHandler(db *sql.DB, w http.ResponseWriter, r *http.Request) {
|
|
|
defer r.Body.Close()
|
|
|
|
|
|
@@ -1016,8 +1041,13 @@ func inc(storage map[string]int, key string, i interface{}) {
|
|
|
}
|
|
|
|
|
|
type location struct {
|
|
|
- Latitude float64
|
|
|
- Longitude float64
|
|
|
+ Latitude float64 `json:"lat"`
|
|
|
+ Longitude float64 `json:"lon"`
|
|
|
+}
|
|
|
+
|
|
|
+type weightedLocation struct {
|
|
|
+ location
|
|
|
+ Weight int `json:"weight"`
|
|
|
}
|
|
|
|
|
|
func getReport(db *sql.DB) map[string]interface{} {
|