hswaw/site: add spaceapi
Change-Id: I81b223981c47ccdbfc8fe637e2f0cc11fce8c317
diff --git a/hswaw/site/BUILD.bazel b/hswaw/site/BUILD.bazel
index a34f5b4..5cb3b99 100644
--- a/hswaw/site/BUILD.bazel
+++ b/hswaw/site/BUILD.bazel
@@ -7,12 +7,14 @@
"at.go",
"feeds.go",
"main.go",
+ "spaceapi.go",
"views.go",
],
importpath = "code.hackerspace.pl/hscloud/hswaw/site",
visibility = ["//visibility:private"],
deps = [
"//go/mirko:go_default_library",
+ "//hswaw/site/calendar:go_default_library",
"//hswaw/site/static:static_go",
"//hswaw/site/templates:templates_go",
"@com_github_golang_glog//:go_default_library",
@@ -26,8 +28,8 @@
)
container_image(
- name="latest",
- base="@prodimage-bionic//image",
+ name = "latest",
+ base = "@prodimage-bionic//image",
files = [":site"],
directory = "/hswaw/site/",
entrypoint = ["/hswaw/site/site"],
diff --git a/hswaw/site/calendar/BUILD.bazel b/hswaw/site/calendar/BUILD.bazel
index 297fde3..fcdac53 100644
--- a/hswaw/site/calendar/BUILD.bazel
+++ b/hswaw/site/calendar/BUILD.bazel
@@ -3,12 +3,12 @@
go_library(
name = "go_default_library",
srcs = [
- "load.go",
"event.go",
+ "load.go",
"time.go",
],
importpath = "code.hackerspace.pl/hscloud/hswaw/site/calendar",
- visibility = ["//visibility:private"],
+ visibility = ["//hswaw/site:__subpackages__"],
deps = [
"@com_github_arran4_golang_ical//:go_default_library",
"@com_github_golang_glog//:go_default_library",
diff --git a/hswaw/site/calendar/load.go b/hswaw/site/calendar/load.go
index 5ea9198..5b36b9c 100644
--- a/hswaw/site/calendar/load.go
+++ b/hswaw/site/calendar/load.go
@@ -14,8 +14,8 @@
)
const (
- // eventsURL is the calendar from which we load public Hackerspace events.
- eventsURL = "https://owncloud.hackerspace.pl/remote.php/dav/public-calendars/g8toktZrA9fyAHNi/?export"
+ // EventsURL is the calendar from which we load public Hackerspace events.
+ EventsURL = "https://owncloud.hackerspace.pl/remote.php/dav/public-calendars/g8toktZrA9fyAHNi/?export"
)
// eventsBySooner sorts upcoming events so the one that happens the soonest
@@ -107,13 +107,13 @@
// relative to the given time 'now' as per the Warsaw Hackerspace public
// calender (from owncloud.hackerspace.pl).
func GetUpcomingEvents(ctx context.Context, now time.Time) ([]*UpcomingEvent, error) {
- r, err := http.NewRequestWithContext(ctx, "GET", eventsURL, nil)
+ r, err := http.NewRequestWithContext(ctx, "GET", EventsURL, nil)
if err != nil {
- return nil, fmt.Errorf("NewRequest(%q): %w", eventsURL, err)
+ return nil, fmt.Errorf("NewRequest(%q): %w", EventsURL, err)
}
res, err := http.DefaultClient.Do(r)
if err != nil {
- return nil, fmt.Errorf("Do(%q): %w", eventsURL, err)
+ return nil, fmt.Errorf("Do(%q): %w", EventsURL, err)
}
defer res.Body.Close()
return parseUpcomingEvents(now, res.Body)
diff --git a/hswaw/site/main.go b/hswaw/site/main.go
index a7f3e54..c4437bc 100644
--- a/hswaw/site/main.go
+++ b/hswaw/site/main.go
@@ -102,5 +102,6 @@
func (s *service) registerHTTP(mux *http.ServeMux) {
mux.HandleFunc("/static/", s.handleHTTPStatic)
+ mux.HandleFunc("/spaceapi", s.handleSpaceAPI)
mux.HandleFunc("/", s.handleIndex)
}
diff --git a/hswaw/site/spaceapi.go b/hswaw/site/spaceapi.go
new file mode 100644
index 0000000..13c5aad
--- /dev/null
+++ b/hswaw/site/spaceapi.go
@@ -0,0 +1,119 @@
+package main
+
+import (
+ "context"
+
+ "code.hackerspace.pl/hscloud/hswaw/site/calendar"
+ "github.com/golang/glog"
+)
+
+// SpaceAPIResponse, per https://spaceapi.io/ - kinda. Mostly rewritten from
+// old implementation, someone should update this to use the official schema.
+type SpaceAPIResponse struct {
+ API string `json:"api"`
+ Space string `json:"space"`
+ Logo string `json:"logo"`
+ URL string `json:"url"`
+ Location SpaceAPILocation `json:"location"`
+ State SpaceAPIState `json:"state"`
+ Contact map[string]string `json:"contact"`
+ IssueReportChannels []string `json:"issue_report_channels"`
+ Projects []string `json:"projects"`
+ Feeds map[string]SpaceAPIFeed `json:"feeds"`
+ Sensors map[string][]SpaceAPISensor `json:"sensors"`
+}
+
+type SpaceAPILocation struct {
+ Latitude float64 `json:"lat"`
+ Longitude float64 `json:"lon"`
+ Address string `json:"address"`
+}
+
+type SpaceAPIState struct {
+ Open bool `json:"open"`
+ Message string `json:"message"`
+ Icon struct {
+ Open string `json:"open"`
+ Closed string `json:"closed"`
+ } `json:"icon"`
+}
+
+type SpaceAPIFeed struct {
+ Type string `json:"type"`
+ URL string `json:"url"`
+}
+
+type SpaceAPISensor struct {
+ Value int `json:"value"`
+ Names []string `json:"names"`
+}
+
+func generateSpaceAPIResponse(ctx context.Context) SpaceAPIResponse {
+ state := SpaceAPIState{}
+ state.Icon.Open = "https://static.hackerspace.pl/img/status-open-small.png"
+ state.Icon.Closed = "https://static.hackerspace.pl/img/status-closed-small.png"
+ // TODO(q3k): post-coronavirus, make automatically open based on calendar
+ // events and Open Thursdays.
+ open := false
+ if open {
+ state.Open = true
+ state.Message = "open for public"
+ } else {
+ state.Open = false
+ state.Message = "members only"
+ }
+
+ peopleNowPresent := SpaceAPISensor{}
+ atState, err := getAt(ctx)
+ if err != nil {
+ glog.Errorf("Failed to get checkinator status: %v", err)
+ } else {
+ peopleNowPresent.Names = make([]string, len(atState.Users))
+ for i, u := range atState.Users {
+ peopleNowPresent.Names[i] = u.Login
+ }
+ peopleNowPresent.Value = len(peopleNowPresent.Names)
+ }
+
+ res := SpaceAPIResponse{
+ API: "0.13",
+ Space: "Warsaw Hackerspace",
+ Logo: "https://static.hackerspace.pl/img/syrenka-black.png",
+ URL: "https://hackerspace.pl",
+ Location: SpaceAPILocation{
+ Latitude: 52.24160,
+ Longitude: 20.98485,
+ Address: "ul. Wolność 2A, 01-018 Warszawa, Poland",
+ },
+ State: state,
+ Contact: map[string]string{
+ "irc": "irc://irc.libera.chat/#hswaw",
+ "twitter": "@hackerspacepl",
+ "facebook": "hackerspacepl",
+ "ml": "waw@lists.hackerspace.pl",
+ },
+ IssueReportChannels: []string{"irc"},
+ Projects: []string{
+ "https://wiki.hackerspace.pl/projects",
+ },
+ Feeds: map[string]SpaceAPIFeed{
+ "blog": SpaceAPIFeed{
+ Type: "atom",
+ URL: feedsURLs["blog"],
+ },
+ "calendar": SpaceAPIFeed{
+ Type: "ical",
+ URL: calendar.EventsURL,
+ },
+ "wiki": SpaceAPIFeed{
+ Type: "rss",
+ URL: "https://wiki.hackerspace.pl/feed.php",
+ },
+ },
+ Sensors: map[string][]SpaceAPISensor{
+ "people_now_present": []SpaceAPISensor{peopleNowPresent},
+ },
+ }
+
+ return res
+}
diff --git a/hswaw/site/views.go b/hswaw/site/views.go
index ef1f1fa..09755b2 100644
--- a/hswaw/site/views.go
+++ b/hswaw/site/views.go
@@ -1,6 +1,7 @@
package main
import (
+ "encoding/json"
"fmt"
"html/template"
"net/http"
@@ -63,3 +64,9 @@
"AtError": atError,
})
}
+
+func (s *service) handleSpaceAPI(w http.ResponseWriter, r *http.Request) {
+ ctx := r.Context()
+ w.Header().Set("Content-Type", "application/json")
+ json.NewEncoder(w).Encode(generateSpaceAPIResponse(ctx))
+}