spaceapi/main.go

123 lines
2.9 KiB
Go

package main
import (
"encoding/json"
"fmt"
"log"
"net/http"
"os"
"strconv"
"time"
)
type Config struct {
PORT string
PRESENCEAPI string
SPACEAPI string
}
type SpaceAPI struct {
API string `json:"api"`
Space string `json:"space"`
Logo string `json:"logo"`
URL string `json:"url"`
Location struct {
Address string `json:"address,omitempty"`
Lon float64 `json:"lon"`
Lat float64 `json:"lat"`
} `json:"location"`
Contact struct {
Email string `json:"email,omitempty"`
Irc string `json:"irc,omitempty"`
Ml string `json:"ml,omitempty"`
Twitter string `json:"twitter,omitempty"`
Matrix string `json:"matrix,omitempty"`
} `json:"contact"`
IssueReportChannels []string `json:"issue_report_channels"`
State struct {
Icon struct {
Open string `json:"open"`
Closed string `json:"closed"`
} `json:"icon,omitempty"`
Open bool `json:"open"`
Message string `json:"message,omitempty"`
LastChange int64 `json:"lastchange,omitempty"`
} `json:"state"`
Projects []string `json:"projects,omitempty"`
}
type Status struct {
FuzIsOpen bool `json:"fuzIsOpen"`
LastSeenAsOpen bool `json:"lastSeenAsOpen"`
LastSeen time.Time `json:"lastSeen"`
LastOpened time.Time `json:"lastOpened"`
LastClosed time.Time `json:"lastClosed"`
}
var (
config = Config{
PORT: "8080",
}
spaceAPI = SpaceAPI{
API: "0.13",
}
)
func init() {
port := os.Getenv("PORT")
if val, _ := strconv.Atoi(port); val > 0 {
config.PORT = port
}
config.PRESENCEAPI = os.Getenv("PRESENCEAPI")
if config.PRESENCEAPI == "" {
panic("PRESENCEAPI is empty")
}
config.SPACEAPI = os.Getenv("SPACEAPI")
if config.SPACEAPI == "" {
panic("SPACEAPI is empty")
}
err := json.Unmarshal([]byte(config.SPACEAPI), &spaceAPI)
if err != nil {
panic(fmt.Sprintf("SPACEAPI is not valid JSON: %v", err))
}
}
func rootHandler(w http.ResponseWriter, r *http.Request) {
if r.URL.Path != "/" {
http.NotFound(w, r)
return
}
resp, err := http.Get(config.PRESENCEAPI)
if err != nil {
w.WriteHeader(http.StatusServiceUnavailable)
fmt.Fprintf(w, "err: unable to request presence API: %v", err)
return
}
defer resp.Body.Close()
var status Status
err = json.NewDecoder(resp.Body).Decode(&status)
if err != nil {
w.WriteHeader(http.StatusServiceUnavailable)
fmt.Fprintf(w, "err: bad json from presence API: %v", err)
return
}
spaceAPI.State.Open = status.FuzIsOpen
if status.FuzIsOpen {
spaceAPI.State.LastChange = status.LastOpened.Unix()
} else {
spaceAPI.State.LastChange = status.LastClosed.Unix()
}
w.Header().Set("Content-Type", "application/json")
w.Header().Set("Access-Control-Allow-Origin", "*")
w.Header().Set("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept")
e := json.NewEncoder(w)
e.SetIndent("", " ")
e.Encode(spaceAPI)
}
func main() {
http.HandleFunc("/", rootHandler)
log.Fatal(http.ListenAndServe(":"+config.PORT, nil))
}