// Compile all information exported through the hackerspace API and send it // back to the requestor. func (a *SpaceAPI) ServeHTTP(rw http.ResponseWriter, req *http.Request) { var msg = proto.Clone(a.conf.SpaceapiMd) var md *doorky.SpaceAPIMetadata var door *doorky.DoorSecret var out []byte var err error var ok bool md, ok = msg.(*doorky.SpaceAPIMetadata) if !ok { log.Print("Error: message is not of type SpaceAPIMetadata") http.Error(rw, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) } for _, door = range a.conf.Secret { var lockInfo = new(doorky.SpaceAPIDoorLockSensor) var name = door.GetName() var ts time.Time var isOpen bool ts, isOpen, err = a.ts.LastValue(name) if err != nil { log.Print("Error fetching door status for ", name, ": ", err) continue } lockInfo.Value = proto.Bool(!isOpen) lockInfo.Location = proto.String(door.GetLocation()) lockInfo.Name = proto.String(name) lockInfo.Description = proto.String("Last update: " + ts.String()) if md.Sensors == nil { md.Sensors = new(doorky.SpaceAPISensors) } md.Sensors.DoorLocked = append(md.Sensors.DoorLocked, lockInfo) if a.conf.PrimaryDoor != nil && a.conf.GetPrimaryDoor() == name { md.State.Open = proto.Bool(isOpen) md.State.Lastchange = proto.Int64(ts.Unix()) } } out, err = json.MarshalIndent(md, " ", " ") if err != nil { log.Print("Error marshalling JSON: ", err) http.Error(rw, http.StatusText(http.StatusInternalServerError)+": "+ "Error marshalling response: "+err.Error(), http.StatusInternalServerError) } _, err = rw.Write(out) if err != nil { log.Print("Error writing response: ", err) } }
func main() { var secrets = make(map[string][]byte) var secret *doorky.DoorSecret var ts *doorky.Timeseries var wapi *WriteAPI var sapi *SpaceAPI var config doorky.DoorkyConfig var configPath string var configData []byte var bindAddress string var err error flag.StringVar(&configPath, "config", "Path to the configuration file", "") flag.StringVar(&bindAddress, "bind", "host:port pair to bind the HTTP server to", ":8080") flag.Parse() configData, err = ioutil.ReadFile(configPath) if err != nil { log.Fatal("Error reading config file ", configPath, ": ", err) } err = proto.UnmarshalText(string(configData), &config) if err != nil { log.Fatal("Error reading config file: ", err) } for _, secret = range config.GetSecret() { var secretInfo = sha256.Sum256([]byte(secret.GetSecret())) secrets[secret.GetName()] = secretInfo[:] } ts, err = doorky.NewTimeseries(config.GetDbServer(), time.Duration(config.GetDbTimeout())*time.Millisecond, config.GetDbCredentials(), config.GetKeyspace()) if err != nil { log.Fatal("Error connecting to timeseries database: ", err) } wapi = NewWriteAPI(ts, secrets) http.Handle("/api/doorstatus", wapi) if config.SpaceapiMd != nil { sapi = NewSpaceAPI(ts, &config) http.Handle("/api/spaceapi", sapi) } err = http.ListenAndServe(bindAddress, nil) if err != nil { log.Fatal("Error listening to ", bindAddress, ": ", err) } }