Skip to content

Instantly share code, notes, and snippets.

@jystewart
Created November 5, 2013 22:44
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jystewart/7327684 to your computer and use it in GitHub Desktop.
Save jystewart/7327684 to your computer and use it in GitHub Desktop.
Very early proof of concept golang implementation of the GOV.UK Imminence API
package main
import (
"encoding/json"
"fmt"
"labix.org/v2/mgo"
"labix.org/v2/mgo/bson"
"net/http"
)
type Point struct {
Longitude float64
Latitude float64
}
// TODO: Implement correct JSON field names for serialization
type Place struct {
ServiceSlug string `bson:"service_slug"`
DataSet_version int `bson:"data_set_version"`
Name string `bson:"name"`
SourceAddress string `bson:"source_address"`
Address1 string `bson:"address1"`
Address2 string `bson:"address2"`
Town string `bson:"town"`
Postcode string `bson:"postcode"`
AccessNotes string `bson:"access_notes"`
GeneralNotes string `bson:"general_notes"`
Url string `bson:"url"`
Email string `bson:"email"`
Phone string `bson:"phone"`
Fax string `bson:"fax"`
TextPhone string `bson:"text_phone"`
// Location Point
}
func buildPlacesQuery(service string, version int, loc Point) bson.M {
return bson.M{
"service_slug": service,
"data_set_version": version,
"location": bson.M{
"$near": []float64{loc.Longitude, loc.Latitude},
"$maxDistance": 1000,
},
}
}
// TODO: extract from URL: service, version, prefered location, number of results
// TODO: implement maximum distance / number of results
func findPlaces(resp http.ResponseWriter, req *http.Request) {
service := "register-offices"
version := 2
location := Point{0, 0}
session := getMgoSession()
db := session.DB("imminence_development")
query := buildPlacesQuery(service, version, location)
var results []Place
err := db.C("places").Find(query).All(&results)
if err != nil {
http.Error(resp, err.Error(), http.StatusInternalServerError)
}
b, err := json.Marshal(results)
if err != nil {
http.Error(resp, err.Error(), http.StatusInternalServerError)
}
fmt.Fprintf(resp, string(b))
}
func Log(handler http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
fmt.Printf("%s %s %s\n", r.RemoteAddr, r.Method, r.URL)
handler.ServeHTTP(w, r)
})
}
var (
mgoSession *mgo.Session
)
func getMgoSession() *mgo.Session {
if mgoSession == nil {
var err error
mgoSession, err = mgo.Dial("localhost")
mgoSession.SetMode(mgo.Monotonic, true)
if err != nil {
panic(err)
}
}
return mgoSession.Clone()
}
func main() {
http.HandleFunc("/places/", findPlaces)
http.ListenAndServe(":9090", Log(http.DefaultServeMux))
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment