add betteruptime support
All checks were successful
Build and Push Docker Image to GHCR / build-and-push (push) Successful in 16m31s
All checks were successful
Build and Push Docker Image to GHCR / build-and-push (push) Successful in 16m31s
This commit is contained in:
2
.github/workflows/docker-publish.yml
vendored
2
.github/workflows/docker-publish.yml
vendored
@@ -10,8 +10,6 @@ on:
|
||||
|
||||
jobs:
|
||||
build-and-push:
|
||||
env:
|
||||
RUNNER_TOOL_CACHE: /toolcache
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
permissions:
|
||||
|
||||
@@ -6,7 +6,7 @@ RUN apt update && apt install -y upx unzip
|
||||
RUN curl -fsSL https://bun.com/install | BUN_INSTALL=/usr bash
|
||||
|
||||
|
||||
RUN go install github.com/juls0730/zqdgr@latest
|
||||
RUN go install github.com/juls0730/zqdgr@v0.0.6-1
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
|
||||
17
README.md
17
README.md
@@ -10,10 +10,10 @@ Passport is a simple, fast, and lightweight web dashboard/new tab replacement.
|
||||
|
||||
### Prerequisites
|
||||
|
||||
- [ZQDGR](https://github.com/juls0730/zqdgr)
|
||||
- [Go](https://go.dev/doc/install)
|
||||
- [sqlite3](https://www.sqlite.org/download.html)
|
||||
- [TailwdinCSS CLI](https://github.com/tailwindlabs/tailwindcss/releases/latest)
|
||||
- [ZQDGR](https://github.com/juls0730/zqdgr)
|
||||
- [Go](https://go.dev/doc/install)
|
||||
- [sqlite3](https://www.sqlite.org/download.html)
|
||||
- [TailwdinCSS CLI](https://github.com/tailwindlabs/tailwindcss/releases/latest)
|
||||
|
||||
## Usage
|
||||
|
||||
@@ -85,10 +85,11 @@ The weather integration is optional, and will be enabled automatically if you pr
|
||||
|
||||
The uptime integration is optional, and will be enabled automatically if you provide an API key. The following only applies if you are using the UptimeRobot integration.
|
||||
|
||||
| Environment Variable | Description | Required | Default |
|
||||
| ------------------------- | ------------------------------------------------- | -------- | ------- |
|
||||
| `PASSPORT_UPTIME_API_KEY` | The UptimeRobot API key | true | |
|
||||
| `UPTIME_UPDATE_INTERVAL` | The interval in seconds to update the uptime data | false | 300 |
|
||||
| Environment Variable | Description | Required | Default |
|
||||
| ------------------------- | ------------------------------------------------------------------ | -------- | ----------- |
|
||||
| `UPTIME_PROVIDER` | The uptime provider to use, either `uptimerobot` or `betteruptime` | false | uptimerobot |
|
||||
| `PASSPORT_UPTIME_API_KEY` | The UptimeRobot API key | true | |
|
||||
| `UPTIME_UPDATE_INTERVAL` | The interval in seconds to update the uptime data | false | 300 |
|
||||
|
||||
### Adding links and categories
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@ import (
|
||||
"io"
|
||||
"log"
|
||||
"net/http"
|
||||
"sort"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
@@ -16,19 +17,20 @@ type DepricatedUptimeConfig struct {
|
||||
}
|
||||
|
||||
type UptimeConfig struct {
|
||||
Provider string `env:"UPTIME_PROVIDER" envDefault:"uptimerobot"`
|
||||
APIKey string
|
||||
UpdateInterval int `env:"UPTIME_UPDATE_INTERVAL" envDefault:"300"`
|
||||
}
|
||||
|
||||
type UptimeRobotSite struct {
|
||||
FriendlyName string `json:"friendly_name"`
|
||||
Url string `json:"url"`
|
||||
Status int `json:"status"`
|
||||
Up bool `json:"-"`
|
||||
type UptimeSite struct {
|
||||
FriendlyName string
|
||||
Url string
|
||||
Up bool
|
||||
}
|
||||
|
||||
type UptimeManager struct {
|
||||
sites []UptimeRobotSite
|
||||
provider string
|
||||
sites []UptimeSite
|
||||
lastUpdate time.Time
|
||||
mutex sync.RWMutex
|
||||
updateChan chan struct{}
|
||||
@@ -38,7 +40,7 @@ type UptimeManager struct {
|
||||
|
||||
func NewUptimeManager(config *UptimeConfig) *UptimeManager {
|
||||
if config.APIKey == "" {
|
||||
log.Fatalln("UptimeRobot API Key is required!")
|
||||
log.Fatalln("An API Key is required to use Uptime Monitoring!")
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -48,10 +50,11 @@ func NewUptimeManager(config *UptimeConfig) *UptimeManager {
|
||||
}
|
||||
|
||||
uptimeManager := &UptimeManager{
|
||||
provider: config.Provider,
|
||||
updateChan: make(chan struct{}),
|
||||
updateInterval: updateInterval,
|
||||
apiKey: config.APIKey,
|
||||
sites: []UptimeRobotSite{},
|
||||
sites: []UptimeSite{},
|
||||
}
|
||||
|
||||
go uptimeManager.updateWorker()
|
||||
@@ -61,7 +64,7 @@ func NewUptimeManager(config *UptimeConfig) *UptimeManager {
|
||||
return uptimeManager
|
||||
}
|
||||
|
||||
func (u *UptimeManager) GetUptime() []UptimeRobotSite {
|
||||
func (u *UptimeManager) GetUptime() []UptimeSite {
|
||||
u.mutex.RLock()
|
||||
defer u.mutex.RUnlock()
|
||||
return u.sites
|
||||
@@ -81,36 +84,119 @@ func (u *UptimeManager) updateWorker() {
|
||||
}
|
||||
}
|
||||
|
||||
type UptimeRobotSite struct {
|
||||
FriendlyName string `json:"friendly_name"`
|
||||
Url string `json:"url"`
|
||||
Status int `json:"status"`
|
||||
}
|
||||
|
||||
type UptimeRobotResponse struct {
|
||||
Monitors []UptimeRobotSite `json:"monitors"`
|
||||
}
|
||||
|
||||
type BetterUptimeSite struct {
|
||||
MonitorType string `json:"type"`
|
||||
Attributes struct {
|
||||
PronounceableName string `json:"pronounceable_name"`
|
||||
Url string `json:"url"`
|
||||
Status string `json:"status"`
|
||||
} `json:"attributes"`
|
||||
}
|
||||
|
||||
type BetterUptimeResponse struct {
|
||||
Monitors []BetterUptimeSite `json:"data"`
|
||||
}
|
||||
|
||||
func (u *UptimeManager) update() {
|
||||
var monitors []UptimeSite
|
||||
switch u.provider {
|
||||
case "uptimerobot":
|
||||
monitors = u.updateUptimeRobot()
|
||||
case "betteruptime":
|
||||
monitors = u.updateBetterUptime()
|
||||
default:
|
||||
log.Fatalln("Invalid Uptime Provider!")
|
||||
}
|
||||
|
||||
u.mutex.Lock()
|
||||
u.sites = monitors
|
||||
u.lastUpdate = time.Now()
|
||||
u.mutex.Unlock()
|
||||
}
|
||||
|
||||
func (u *UptimeManager) updateUptimeRobot() []UptimeSite {
|
||||
resp, err := http.Post("https://api.uptimerobot.com/v2/getMonitors?api_key="+u.apiKey, "application/json", nil)
|
||||
if err != nil {
|
||||
fmt.Printf("Error fetching uptime data: %v\n", err)
|
||||
return
|
||||
return []UptimeSite{}
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
body, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
fmt.Printf("Error reading response: %v\n", err)
|
||||
return
|
||||
return []UptimeSite{}
|
||||
}
|
||||
|
||||
var monitors UptimeRobotResponse
|
||||
if err := json.Unmarshal(body, &monitors); err != nil {
|
||||
var rawMonitors UptimeRobotResponse
|
||||
if err := json.Unmarshal(body, &rawMonitors); err != nil {
|
||||
fmt.Printf("Error parsing uptime data: %v\n", err)
|
||||
return
|
||||
return []UptimeSite{}
|
||||
}
|
||||
|
||||
for i, monitor := range monitors.Monitors {
|
||||
monitors.Monitors[i].Up = monitor.Status == 2
|
||||
var monitors []UptimeSite
|
||||
for _, rawMonitor := range rawMonitors.Monitors {
|
||||
monitors = append(monitors, UptimeSite{
|
||||
FriendlyName: rawMonitor.FriendlyName,
|
||||
Url: rawMonitor.Url,
|
||||
Up: rawMonitor.Status == 2,
|
||||
})
|
||||
}
|
||||
|
||||
u.mutex.Lock()
|
||||
u.sites = monitors.Monitors
|
||||
u.lastUpdate = time.Now()
|
||||
u.mutex.Unlock()
|
||||
return monitors
|
||||
}
|
||||
|
||||
func (u *UptimeManager) updateBetterUptime() []UptimeSite {
|
||||
client := &http.Client{}
|
||||
req, err := http.NewRequest("GET", "https://uptime.betterstack.com/api/v2/monitors", nil)
|
||||
if err != nil {
|
||||
fmt.Printf("Error fetching uptime data: %v\n", err)
|
||||
return []UptimeSite{}
|
||||
}
|
||||
req.Header.Add("Authorization", "Bearer "+u.apiKey)
|
||||
|
||||
resp, err := client.Do(req)
|
||||
if err != nil {
|
||||
fmt.Printf("Error fetching uptime data: %v\n", err)
|
||||
return []UptimeSite{}
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
body, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
fmt.Printf("Error reading response: %v\n", err)
|
||||
return []UptimeSite{}
|
||||
}
|
||||
|
||||
var rawMonitors BetterUptimeResponse
|
||||
if err := json.Unmarshal(body, &rawMonitors); err != nil {
|
||||
fmt.Printf("Error parsing uptime data: %v\n", err)
|
||||
return []UptimeSite{}
|
||||
}
|
||||
|
||||
// alphabetically sort the monitors because UptimeRobot does, but BetterUptime doesnt (or sorts by something else?), and I want them to be consistent
|
||||
sort.Slice(rawMonitors.Monitors, func(i, j int) bool {
|
||||
return rawMonitors.Monitors[i].Attributes.PronounceableName < rawMonitors.Monitors[j].Attributes.PronounceableName
|
||||
})
|
||||
|
||||
var monitors []UptimeSite
|
||||
for _, rawMonitor := range rawMonitors.Monitors {
|
||||
monitors = append(monitors, UptimeSite{
|
||||
FriendlyName: rawMonitor.Attributes.PronounceableName,
|
||||
Url: rawMonitor.Attributes.Url,
|
||||
Up: rawMonitor.Attributes.Status == "up",
|
||||
})
|
||||
}
|
||||
|
||||
return monitors
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "passport",
|
||||
"version": "0.3.4",
|
||||
"version": "0.3.5",
|
||||
"description": "Passport is a simple, lightweight, and fast dashboard/new tab page for your browser.",
|
||||
"author": "juls0730",
|
||||
"license": "BSL-1.0",
|
||||
@@ -18,7 +18,7 @@
|
||||
"build:arm64": "zqdgr generate && GOOS=linux GOARCH=arm64 go build -tags netgo,prod -ldflags=\"-w -s\" -o passport-linux-arm64 src/main.go && upx passport-linux-arm64"
|
||||
},
|
||||
"pattern": "src/**/*.{go,hbs,css,js,svg,png,jpg,jpeg,webp,woff2,ico,webp}",
|
||||
"excluded_files": [
|
||||
"excluded_globs": [
|
||||
"src/assets/styles"
|
||||
],
|
||||
"shutdown_signal": "SIGINT"
|
||||
|
||||
Reference in New Issue
Block a user