Initial Commit
This commit is contained in:
parent
51c00fb7ec
commit
89ee1e97f4
189
home-server-status.go
Normal file
189
home-server-status.go
Normal file
@ -0,0 +1,189 @@
|
||||
package home_server_status
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"net/http"
|
||||
"text/template"
|
||||
"time"
|
||||
)
|
||||
|
||||
type Website struct {
|
||||
WebsiteUrl string
|
||||
Description string
|
||||
HasIcon bool
|
||||
IconUrl string
|
||||
}
|
||||
|
||||
type WebsiteStatus struct {
|
||||
WebsiteUrl string
|
||||
Description string
|
||||
HasIcon bool
|
||||
IconUrl string
|
||||
IsUp bool
|
||||
}
|
||||
|
||||
func main() {
|
||||
websites := []Website{
|
||||
{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://code.woubery.com", Description: "Gitea Server", HasIcon: true, IconUrl: "gitea.png"},
|
||||
{WebsiteUrl: "https://stream.woubery.com", Description: "Owncast Server", HasIcon: true, IconUrl: "owncast.png"},
|
||||
{WebsiteUrl: "https://julia.woubery.com", Description: "Julia JupyterHub Notebook", HasIcon: true, IconUrl: "julia.png"},
|
||||
{WebsiteUrl: "https://cloud.woubery.com", Description: "Cloud Server", HasIcon: false, IconUrl: ""},
|
||||
}
|
||||
|
||||
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
|
||||
statuses := make([]WebsiteStatus, 0)
|
||||
|
||||
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.Handle("/static/", http.StripPrefix("/static/", http.FileServer(http.Dir("static"))))
|
||||
|
||||
fmt.Println("Server listening on http://localhost:8080")
|
||||
log.Fatal(http.ListenAndServe(":8080", nil))
|
||||
}
|
||||
|
||||
func checkWebsite(website string) error {
|
||||
client := &http.Client{
|
||||
Timeout: 5 * time.Second, // Set a timeout for the request
|
||||
}
|
||||
|
||||
response, err := client.Head(website)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer response.Body.Close()
|
||||
|
||||
if response.StatusCode != http.StatusOK {
|
||||
return fmt.Errorf("status code: %d", response.StatusCode)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func renderTemplate(w http.ResponseWriter, statuses []WebsiteStatus) {
|
||||
tmpl := `
|
||||
<html>
|
||||
<head>
|
||||
<title>Website Status</title>
|
||||
<style>
|
||||
body {
|
||||
font-family: Arial, sans-serif;
|
||||
background-color: #f3f3f3;
|
||||
padding: 20px;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
h1 {
|
||||
color: #333;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.container {
|
||||
max-width: 800px;
|
||||
margin: 0 auto;
|
||||
background-color: #fff;
|
||||
padding: 20px;
|
||||
border-radius: 5px;
|
||||
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.website {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
margin-bottom: 10px;
|
||||
padding: 10px;
|
||||
border-radius: 5px;
|
||||
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
|
||||
background-color: #f8f8f8;
|
||||
}
|
||||
|
||||
.status {
|
||||
display: inline-block;
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
border-radius: 2px;
|
||||
margin-right: 5px;
|
||||
}
|
||||
|
||||
.status-green {
|
||||
background-color: #27ae60;
|
||||
}
|
||||
|
||||
.status-red {
|
||||
background-color: #e74c3c;
|
||||
}
|
||||
|
||||
.website-text {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.website-description {
|
||||
margin-left: 10px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.website-url {
|
||||
margin-left: 10px;
|
||||
color: #333;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.website-url:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.icon {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
margin-right: 5px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<h1>Ruby's Home Server Status</h1>
|
||||
{{range .}}
|
||||
<div class="website">
|
||||
<div class="website-text">
|
||||
<div class="status {{if .IsUp}}status-green{{else}}status-red{{end}}"></div>
|
||||
<div class="website-description" href="{{.WebsiteUrl}}">
|
||||
{{.Description}}
|
||||
</div>
|
||||
</div>
|
||||
<a class="website-url" href="{{.WebsiteUrl}}" target="_blank">
|
||||
{{.WebsiteUrl}}
|
||||
{{if .HasIcon}}
|
||||
<img class="icon" src="/static/{{.IconUrl}}" alt="Icon">
|
||||
{{end}}
|
||||
</a>
|
||||
</div>
|
||||
{{end}}
|
||||
</div>
|
||||
</body>
|
||||
</html>`
|
||||
|
||||
t, err := template.New("webpage").Parse(tmpl)
|
||||
if err != nil {
|
||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
err = t.Execute(w, statuses)
|
||||
if err != nil {
|
||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||
}
|
||||
}
|
BIN
static/cloud.jpg
Normal file
BIN
static/cloud.jpg
Normal file
Binary file not shown.
After ![]() (image error) Size: 9.5 KiB |
BIN
static/gitea.png
Normal file
BIN
static/gitea.png
Normal file
Binary file not shown.
After ![]() (image error) Size: 94 KiB |
BIN
static/jellyfin.png
Normal file
BIN
static/jellyfin.png
Normal file
Binary file not shown.
After ![]() (image error) Size: 22 KiB |
BIN
static/jellyfin.webp
Normal file
BIN
static/jellyfin.webp
Normal file
Binary file not shown.
After ![]() (image error) Size: 9.1 KiB |
BIN
static/julia.png
Normal file
BIN
static/julia.png
Normal file
Binary file not shown.
After ![]() (image error) Size: 4.3 KiB |
BIN
static/octoprint.png
Normal file
BIN
static/octoprint.png
Normal file
Binary file not shown.
After ![]() (image error) Size: 15 KiB |
BIN
static/owncast.png
Normal file
BIN
static/owncast.png
Normal file
Binary file not shown.
After ![]() (image error) Size: 79 KiB |
Loading…
x
Reference in New Issue
Block a user