Initial commit
This commit is contained in:
commit
be29af436f
8
.gitignore
vendored
Normal file
8
.gitignore
vendored
Normal file
|
@ -0,0 +1,8 @@
|
|||
# JetBrains IDEs
|
||||
.idea/
|
||||
|
||||
# macOS stuff
|
||||
.DS_Store
|
||||
|
||||
# go build output
|
||||
spaceapid
|
48
ccchh-template.json
Normal file
48
ccchh-template.json
Normal file
|
@ -0,0 +1,48 @@
|
|||
{
|
||||
"api_compatibility": [
|
||||
"14"
|
||||
],
|
||||
"space": "CCCHH",
|
||||
"logo": "https://next.hamburg.ccc.de/images/logo.svg",
|
||||
"ext_ccc": "erfa",
|
||||
"url": "https://hamburg.ccc.de/",
|
||||
"location": {
|
||||
"address": "Zeiseweg 9, 22765 Hamburg, Germany",
|
||||
"lon": 9.9445899999999998,
|
||||
"lat": 53.55836
|
||||
},
|
||||
"state": {
|
||||
"icon": {
|
||||
"open": "https://hamburg.ccc.de/dooris/open.png",
|
||||
"closed": "https://hamburg.ccc.de/dooris/close.png"
|
||||
}
|
||||
},
|
||||
"contact": {
|
||||
"phone": "",
|
||||
"irc": "ircs://irc.hackint.org:9999/ccchh",
|
||||
"mastodon": "@ccchh@chaos.social",
|
||||
"email": "mail@hamburg.ccc.de",
|
||||
"ml": "talk@hamburg.ccc.de",
|
||||
"matrix": "#ccchh:hamburg.ccc.de"
|
||||
},
|
||||
"feeds": {
|
||||
"blog": {
|
||||
"type": "application/atom+xml",
|
||||
"url": "https://hamburg.ccc.de/feed.xml"
|
||||
},
|
||||
"calendar": {
|
||||
"type": "ical",
|
||||
"url": "webcal://cloud.hamburg.ccc.de/remote.php/dav/public-calendars/QJAdExziSnNJEz5g/?export"
|
||||
}
|
||||
},
|
||||
"links": [
|
||||
{
|
||||
"name": "Wiki",
|
||||
"url": "https://wiki.ccchh.net"
|
||||
},
|
||||
{
|
||||
"name": "GitLab",
|
||||
"url": "https://gitlab.hamburg.ccc.de"
|
||||
}
|
||||
]
|
||||
}
|
100
main.go
Normal file
100
main.go
Normal file
|
@ -0,0 +1,100 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"io"
|
||||
"log"
|
||||
"net/http"
|
||||
"os"
|
||||
"slices"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"gitlab.hamburg.ccc.de/ccchh/spaceapid/types"
|
||||
)
|
||||
|
||||
func main() {
|
||||
validUsername, success := os.LookupEnv("DOORIS_USERNAME")
|
||||
if !success || validUsername == "" {
|
||||
log.Fatalln("Could not retrieve DOORIS_API_KEY env variable or variable is empty")
|
||||
}
|
||||
|
||||
validPassword, success := os.LookupEnv("DOORIS_PASSWORD")
|
||||
if !success || validPassword == "" {
|
||||
log.Fatalln("Could not retrieve DOORIS_API_KEY env variable or variable is empty")
|
||||
}
|
||||
|
||||
initialJson, success := os.LookupEnv("SPACE_API_JSON")
|
||||
if !success || initialJson == "" {
|
||||
log.Fatalln("Could not retrieve SPACE_API_JSON env variable or variable is empty")
|
||||
}
|
||||
|
||||
spaceApiResponse := new(types.SpaceAPIResponseV14)
|
||||
err := json.Unmarshal([]byte(initialJson), spaceApiResponse)
|
||||
if err != nil {
|
||||
log.Fatalln("Could not parse provided JSON")
|
||||
}
|
||||
if !slices.Contains(spaceApiResponse.APICompatibility, "14") {
|
||||
log.Fatalln("Provided JSON doesn't specify compatibility with API version 14")
|
||||
}
|
||||
|
||||
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
|
||||
if r.Method != http.MethodGet {
|
||||
log.Println("Wrong METHOD from", r.RemoteAddr)
|
||||
w.WriteHeader(http.StatusMethodNotAllowed)
|
||||
w.Header().Set("allow", http.MethodGet)
|
||||
return
|
||||
}
|
||||
|
||||
response, err := json.Marshal(spaceApiResponse)
|
||||
if err != nil {
|
||||
log.Println("Failed to serialize JSON response")
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
w.WriteHeader(http.StatusOK)
|
||||
_, _ = w.Write(response)
|
||||
})
|
||||
|
||||
http.HandleFunc("/state/open", func(w http.ResponseWriter, r *http.Request) {
|
||||
username, password, ok := r.BasicAuth()
|
||||
if !ok || username != validUsername || password != validPassword {
|
||||
log.Println("Unauthorized request from", r.RemoteAddr)
|
||||
w.WriteHeader(http.StatusUnauthorized)
|
||||
w.Header().Set("www-authentication", "Basic realm=\"space-api\"")
|
||||
return
|
||||
}
|
||||
|
||||
if r.Method != http.MethodPut {
|
||||
log.Println("Wrong METHOD from", r.RemoteAddr)
|
||||
w.WriteHeader(http.StatusMethodNotAllowed)
|
||||
w.Header().Set("allow", http.MethodPut)
|
||||
return
|
||||
}
|
||||
|
||||
body, err := io.ReadAll(r.Body)
|
||||
if err != nil {
|
||||
log.Println("Failed to read body status update request from", r.RemoteAddr)
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
_, _ = io.WriteString(w, "Failed reading HTTP request body")
|
||||
return
|
||||
}
|
||||
|
||||
newState, err := strconv.ParseBool(string(body))
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
_, _ = io.WriteString(w, "HTTP request body should either be true or false")
|
||||
return
|
||||
}
|
||||
|
||||
spaceApiResponse.State.Open = newState
|
||||
spaceApiResponse.State.LastChange = time.Now().Unix()
|
||||
|
||||
w.WriteHeader(http.StatusOK)
|
||||
_, _ = io.WriteString(w, "Update Successful")
|
||||
})
|
||||
|
||||
log.Println("Starting HTTP server...")
|
||||
log.Fatalln(http.ListenAndServe(":8080", nil))
|
||||
}
|
44
types/v14.go
Normal file
44
types/v14.go
Normal file
|
@ -0,0 +1,44 @@
|
|||
package types
|
||||
|
||||
type SpaceAPIResponseV14 struct {
|
||||
APICompatibility []string `json:"api_compatibility"`
|
||||
Space string `json:"space"`
|
||||
Logo string `json:"logo"`
|
||||
ExtCcc string `json:"ext_ccc"`
|
||||
URL string `json:"url"`
|
||||
Location struct {
|
||||
Address string `json:"address"`
|
||||
Lat float64 `json:"lat"`
|
||||
Lon float64 `json:"lon"`
|
||||
} `json:"location"`
|
||||
State struct {
|
||||
Open bool `json:"open"`
|
||||
LastChange int64 `json:"lastchange"`
|
||||
Icon struct {
|
||||
Closed string `json:"closed"`
|
||||
Open string `json:"open"`
|
||||
} `json:"icon"`
|
||||
} `json:"state"`
|
||||
Contact struct {
|
||||
Phone string `json:"phone"`
|
||||
Irc string `json:"irc"`
|
||||
Mastodon string `json:"mastodon"`
|
||||
Email string `json:"email"`
|
||||
Ml string `json:"ml"`
|
||||
Matrix string `json:"matrix"`
|
||||
} `json:"contact"`
|
||||
Feeds struct {
|
||||
Blog struct {
|
||||
Type string `json:"type"`
|
||||
URL string `json:"url"`
|
||||
} `json:"blog"`
|
||||
Calendar struct {
|
||||
Type string `json:"type"`
|
||||
URL string `json:"url"`
|
||||
} `json:"calendar"`
|
||||
} `json:"feeds"`
|
||||
Links []struct {
|
||||
Name string `json:"name"`
|
||||
URL string `json:"url"`
|
||||
} `json:"links"`
|
||||
}
|
Loading…
Reference in a new issue