Instant page serving and delayed status symbols

This commit is contained in:
Anton Reinhard 2023-06-02 04:55:01 +02:00
parent 89ee1e97f4
commit f25e48d084
3 changed files with 53 additions and 25 deletions

1
.gitignore vendored
View File

@ -21,3 +21,4 @@
# Go workspace file # Go workspace file
go.work go.work
main

View File

@ -1,3 +1,10 @@
# home-server-status # home-server-status
Website to show home server infrastructure up/down indicators Website to show home server infrastructure up/down indicators
## Build and run
```sh
$ go build main.go
$ go run main.go
```

View File

@ -1,6 +1,7 @@
package home_server_status package main
import ( import (
"encoding/json"
"fmt" "fmt"
"log" "log"
"net/http" "net/http"
@ -8,23 +9,15 @@ import (
"time" "time"
) )
type Website struct {
WebsiteUrl string
Description string
HasIcon bool
IconUrl string
}
type WebsiteStatus struct { type WebsiteStatus struct {
WebsiteUrl string WebsiteUrl string
Description string Description string
HasIcon bool HasIcon bool
IconUrl string IconUrl string
IsUp bool
} }
func main() { func main() {
websites := []Website{ websites := []WebsiteStatus{
{WebsiteUrl: "https://media.woubery.com", Description: "Jellyfin Server", HasIcon: true, IconUrl: "jellyfin.webp"}, {WebsiteUrl: "https://media.woubery.com", Description: "Jellyfin Server", HasIcon: true, IconUrl: "jellyfin.webp"},
{WebsiteUrl: "https://printing.woubery.com", Description: "OctoPrint", HasIcon: true, IconUrl: "octoprint.png"}, {WebsiteUrl: "https://printing.woubery.com", Description: "OctoPrint", HasIcon: true, IconUrl: "octoprint.png"},
{WebsiteUrl: "https://code.woubery.com", Description: "Gitea Server", HasIcon: true, IconUrl: "gitea.png"}, {WebsiteUrl: "https://code.woubery.com", Description: "Gitea Server", HasIcon: true, IconUrl: "gitea.png"},
@ -34,23 +27,13 @@ func main() {
} }
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
statuses := make([]WebsiteStatus, 0) renderTemplate(w, websites)
for _, website := range websites {
isUp := checkWebsite(website.WebsiteUrl) == nil
statuses = append(statuses, WebsiteStatus{
WebsiteUrl: website.WebsiteUrl,
Description: website.Description,
HasIcon: website.HasIcon,
IconUrl: website.IconUrl,
IsUp: isUp,
})
}
renderTemplate(w, statuses)
}) })
http.HandleFunc("/check", handleCheck)
http.Handle("/static/", http.StripPrefix("/static/", http.FileServer(http.Dir("static")))) http.Handle("/static/", http.StripPrefix("/static/", http.FileServer(http.Dir("static"))))
fmt.Println("Server listening on http://localhost:8080") fmt.Println("Server listening on http://localhost:8080")
log.Fatal(http.ListenAndServe(":8080", nil)) log.Fatal(http.ListenAndServe(":8080", nil))
} }
@ -72,6 +55,19 @@ func checkWebsite(website string) error {
return nil return nil
} }
func handleCheck(w http.ResponseWriter, r *http.Request) {
url := r.URL.Query().Get("url")
isUp := checkWebsite(url) == nil
response := struct {
IsUp bool `json:"isUp"`
}{
IsUp: isUp,
}
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(response)
}
func renderTemplate(w http.ResponseWriter, statuses []WebsiteStatus) { func renderTemplate(w http.ResponseWriter, statuses []WebsiteStatus) {
tmpl := ` tmpl := `
<html> <html>
@ -152,6 +148,30 @@ func renderTemplate(w http.ResponseWriter, statuses []WebsiteStatus) {
margin-right: 5px; margin-right: 5px;
} }
</style> </style>
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script>
$(document).ready(function() {
$(".website").each(function() {
var website = $(this);
var url = website.find(".website-url").attr("href");
$.ajax({
url: "/check?url=" + encodeURIComponent(url),
success: function(response) {
var isUp = response.isUp;
var statusElement = website.find(".status");
statusElement.removeClass("status-green status-red");
statusElement.addClass(isUp ? "status-green" : "status-red");
},
error: function() {
var statusElement = website.find(".status");
statusElement.removeClass("status-green");
statusElement.addClass("status-red");
}
});
});
});
</script>
</head> </head>
<body> <body>
<div class="container"> <div class="container">
@ -159,7 +179,7 @@ func renderTemplate(w http.ResponseWriter, statuses []WebsiteStatus) {
{{range .}} {{range .}}
<div class="website"> <div class="website">
<div class="website-text"> <div class="website-text">
<div class="status {{if .IsUp}}status-green{{else}}status-red{{end}}"></div> <div class="status"></div>
<div class="website-description" href="{{.WebsiteUrl}}"> <div class="website-description" href="{{.WebsiteUrl}}">
{{.Description}} {{.Description}}
</div> </div>