hswaw/site: add checkinator integration

Change-Id: I19a72da67410332d6d82d49e3a54f1dc0f81ff65
changes/16/1016/3
q3k 2021-07-11 21:26:37 +00:00
parent 8ef457feee
commit d2271ded0d
5 changed files with 93 additions and 6 deletions

View File

@ -4,6 +4,7 @@ load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library")
go_library( go_library(
name = "go_default_library", name = "go_default_library",
srcs = [ srcs = [
"at.go",
"feeds.go", "feeds.go",
"main.go", "main.go",
"views.go", "views.go",

48
hswaw/site/at.go Normal file
View File

@ -0,0 +1,48 @@
package main
import (
"context"
"encoding/json"
"fmt"
"net/http"
)
const (
atURL = "https://at.hackerspace.pl/api"
)
// atStatus is the result of queruing checkinator/at (Hackerspace presence
// service).
type atStatus struct {
// Users is the list of present and publicly visible users.
Users []atUser `json:"users"`
// ESPs is the number of ESP{8266,32} devices.
ESPs int `json:"esps"`
// Kektops is the number of nettop “Kektop” devices.
Kektops int `json:"kektops"`
// Unknown is the number of unknown devices in the network.
Unknown int `json:"unknown"`
}
type atUser struct {
Login string `json:"login"`
}
func getAt(ctx context.Context) (*atStatus, error) {
r, err := http.NewRequestWithContext(ctx, "GET", atURL, nil)
if err != nil {
return nil, fmt.Errorf("NewRequest(%q): %w", atURL, err)
}
res, err := http.DefaultClient.Do(r)
if err != nil {
return nil, fmt.Errorf("GET: %w", err)
}
defer res.Body.Close()
var status atStatus
if err := json.NewDecoder(res.Body).Decode(&status); err != nil {
return nil, fmt.Errorf("when decoding JSON: %w", err)
}
return &status, nil
}

View File

@ -141,9 +141,19 @@ li i {
opacity: 60%; opacity: 60%;
} }
#quicklinks { .atlist {
float: right; display: inline;
font-family: monospace; list-style: none;
font-size: 14px; }
margin: 2rem;
.atlist li {
display: inline;
}
.atlist li:after {
content: ", ";
}
.atlist li:last-child:after {
content: ".";
} }

View File

@ -36,6 +36,28 @@ ul. Wolność 2A
<p> <p>
<b>Hackerspace nie zna barier.</b> Jeśli masz ciekawy pomysł i szukasz ludzi chętnych do współpracy lub po prostu potrzebujesz miejsca i sprzętu - <a href="">zapraszamy</a>! <b>Hackerspace nie zna barier.</b> Jeśli masz ciekawy pomysł i szukasz ludzi chętnych do współpracy lub po prostu potrzebujesz miejsca i sprzętu - <a href="">zapraszamy</a>!
</p> </p>
<h3>Kto jest teraz w spejsie?</h3>
<p>
{{ if ne .AtError nil }}
<i>Ups, nie udało się załadować stanu checkinatora.</i>
{{ else }}
{{ $count := len .AtStatus.Users }}
{{ if gt $count 4 }}
Według <a href="https://at.hackerspace.pl">naszych instrumentów</a> w spejsie obecnie znajduje się {{ $count }} osób:
{{ else if gt $count 1 }}
Według <a href="https://at.hackerspace.pl">naszych instrumentów</a> w spejsie obecnie znajdują się {{ $count }} osoby:
{{ else if gt $count 0 }}
Według <a href="https://at.hackerspace.pl">naszych instrumentów</a> w spejsie obecnie znajduje się jedna osoba:
{{ else }}
Według <a href="https://at.hackerspace.pl">naszych instrumentów</a> w spejsie obecnie nie ma nikogo.
{{ end }}
<ul class="atlist">
{{ range .AtStatus.Users }}
<li>{{ .Login }}</li>
{{ end }}
</ul>
{{ end }}
</p>
</div> </div>
<div class="blog"> <div class="blog">
<h2>Blog</h2> <h2>Blog</h2>

View File

@ -53,7 +53,13 @@ func render(w http.ResponseWriter, t *template.Template, data interface{}) {
// handleIndex handles rendering the main page at /. // handleIndex handles rendering the main page at /.
func (s *service) handleIndex(w http.ResponseWriter, r *http.Request) { func (s *service) handleIndex(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
atStatus, atError := getAt(ctx)
render(w, tmplIndex, map[string]interface{}{ render(w, tmplIndex, map[string]interface{}{
"Entries": s.getFeeds(), "Entries": s.getFeeds(),
"AtStatus": atStatus,
"AtError": atError,
}) })
} }