Instant page serving and delayed status symbols
This commit is contained in:
parent
89ee1e97f4
commit
f25e48d084
1
.gitignore
vendored
1
.gitignore
vendored
@ -21,3 +21,4 @@
|
|||||||
# Go workspace file
|
# Go workspace file
|
||||||
go.work
|
go.work
|
||||||
|
|
||||||
|
main
|
||||||
|
@ -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
|
||||||
|
```
|
||||||
|
@ -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>
|
Loading…
x
Reference in New Issue
Block a user