Ersetzen von Dashboard zu Statuses

This commit is contained in:
Simon Rieger 2025-03-10 00:07:11 +01:00
parent 158db4da66
commit 1c7797d5e5
3 changed files with 64 additions and 54 deletions

View file

@ -1 +1,2 @@
TRAEWELLING_TOKEN= TRAEWELLING_TOKEN=
TRAEWELLING_USERNAMES=

View file

@ -10,6 +10,7 @@ services:
restart: always # Neustart bei Fehlern oder Updates restart: always # Neustart bei Fehlern oder Updates
environment: environment:
- TRAEWELLING_TOKEN=${TRAEWELLING_TOKEN} - TRAEWELLING_TOKEN=${TRAEWELLING_TOKEN}
- TRAEWELLING_USERNAMES=${TRAEWELLING_USERNAMES}
networks: networks:
default: default:
dns: dns:

View file

@ -5,6 +5,7 @@ import (
"fmt" "fmt"
"net/http" "net/http"
"os" "os"
"strings"
"time" "time"
"github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus"
@ -12,7 +13,7 @@ import (
"github.com/prometheus/client_golang/prometheus/promhttp" "github.com/prometheus/client_golang/prometheus/promhttp"
) )
type DashboardResponse struct { type StatusResponse struct {
Data []struct { Data []struct {
ID int `json:"id"` ID int `json:"id"`
User struct { User struct {
@ -65,8 +66,8 @@ var (
) )
) )
func fetchTraewellingData() (*DashboardResponse, error) { func fetchStatuses(username string) (*StatusResponse, error) {
url := "https://traewelling.de/api/v1/dashboard" url := fmt.Sprintf("https://traewelling.de/api/v1/user/%s/statuses", username)
client := &http.Client{Timeout: 10 * time.Second} client := &http.Client{Timeout: 10 * time.Second}
req, err := http.NewRequest("GET", url, nil) req, err := http.NewRequest("GET", url, nil)
if err != nil { if err != nil {
@ -82,79 +83,86 @@ func fetchTraewellingData() (*DashboardResponse, error) {
resp, err := client.Do(req) resp, err := client.Do(req)
if err != nil { if err != nil {
return nil, fmt.Errorf("Fehler beim Senden der Anfrage: %v", err) return nil, fmt.Errorf("Fehler beim Senden der Anfrage für Benutzer '%s': %v", username, err)
} }
defer resp.Body.Close() defer resp.Body.Close()
if resp.StatusCode != http.StatusOK { if resp.StatusCode != http.StatusOK {
return nil, fmt.Errorf("Fehlerhafte Antwort: %d", resp.StatusCode) return nil, fmt.Errorf("Fehlerhafte Antwort für Benutzer '%s': %d", username, resp.StatusCode)
} }
var apiResponse DashboardResponse var apiResponse StatusResponse
err = json.NewDecoder(resp.Body).Decode(&apiResponse) err = json.NewDecoder(resp.Body).Decode(&apiResponse)
if err != nil { if err != nil {
return nil, fmt.Errorf("Fehler beim Parsen der JSON-Daten: %v", err) return nil, fmt.Errorf("Fehler beim Parsen der JSON-Daten für Benutzer '%s': %v", username, err)
} }
return &apiResponse, nil return &apiResponse, nil
} }
func processAndPrintTripDetails(data *DashboardResponse) { func processAndPrintTripDetails(username string, data *StatusResponse) {
fmt.Println("Fahrtdetails der Benutzer:") fmt.Printf("Fahrtdetails für Benutzer '%s':\n", username)
fmt.Println("==========================") fmt.Println("==========================")
userStats := make(map[string]struct { var totalDuration float64
TotalDuration float64 var totalPoints int
TotalPoints int var totalDistance float64
TotalDistance float64
})
for _, trip := range data.Data { for _, trip := range data.Data {
fmt.Printf("Benutzer: %s (@%s)\n", trip.User.DisplayName, trip.User.Username) fmt.Printf("Fahrt-ID: %d\n", trip.Train.Trip)
fmt.Printf("Fahrt-ID: %d\n", trip.Train.Trip) fmt.Printf("Kategorie: %s\n", trip.Train.Category)
fmt.Printf("Kategorie: %s\n", trip.Train.Category) fmt.Printf("Linie: %s (Nummer: %d)\n", trip.Train.LineName, trip.Train.JourneyNumber)
fmt.Printf("Linie: %s (Nummer: %d)\n", trip.Train.LineName, trip.Train.JourneyNumber) fmt.Printf("Startbahnhof: %s\n", trip.Train.Origin.Name)
fmt.Printf("Startbahnhof: %s\n", trip.Train.Origin.Name) fmt.Printf("\tGeplante Abfahrt: %s\n", trip.Train.Origin.DeparturePlanned)
fmt.Printf("\tGeplante Abfahrt: %s\n", trip.Train.Origin.DeparturePlanned) fmt.Printf("\tTatsächliche Abfahrt: %s\n", trip.Train.Origin.DepartureReal)
fmt.Printf("\tTatsächliche Abfahrt: %s\n", trip.Train.Origin.DepartureReal) fmt.Printf("Zielbahnhof: %s\n", trip.Train.Destination.Name)
fmt.Printf("Zielbahnhof: %s\n", trip.Train.Destination.Name) fmt.Printf("\tGeplante Ankunft: %s\n", trip.Train.Destination.ArrivalPlanned)
fmt.Printf("\tGeplante Ankunft: %s\n", trip.Train.Destination.ArrivalPlanned) fmt.Printf("\tTatsächliche Ankunft: %s\n", trip.Train.Destination.ArrivalReal)
fmt.Printf("\tTatsächliche Ankunft: %s\n", trip.Train.Destination.ArrivalReal) fmt.Printf("Dauer: %d Minuten\n", trip.Train.Duration)
fmt.Printf("Dauer: %d Minuten\n", trip.Train.Duration) fmt.Printf("Entfernung: %.2f km\n", trip.Train.Distance/1000)
fmt.Printf("Entfernung: %.2f km\n", trip.Train.Distance/1000) fmt.Printf("Punkte: %d\n", trip.Train.Points)
fmt.Printf("Punkte: %d\n", trip.Train.Points) fmt.Println("--------------------------")
fmt.Println("--------------------------")
stats := userStats[trip.User.Username] totalDuration += float64(trip.Train.Duration)
stats.TotalDuration += float64(trip.Train.Duration) totalPoints += trip.Train.Points
stats.TotalPoints += trip.Train.Points totalDistance += trip.Train.Distance / 1000
stats.TotalDistance += trip.Train.Distance / 1000 }
userStats[trip.User.Username] = stats
}
for username, stats := range userStats { totalTripDuration.WithLabelValues(username).Set(totalDuration)
totalTripDuration.WithLabelValues(username).Set(stats.TotalDuration) totalTripPoints.WithLabelValues(username).Set(float64(totalPoints))
totalTripPoints.WithLabelValues(username).Set(float64(stats.TotalPoints)) totalTripDistance.WithLabelValues(username).Set(totalDistance)
totalTripDistance.WithLabelValues(username).Set(stats.TotalDistance)
} fmt.Printf("\nGesamtfahrzeit für %s: %.2f Minuten\n", username, totalDuration)
fmt.Printf("Gesamtpunkte für %s: %d Punkte\n", username, totalPoints)
fmt.Printf("Gesamtentfernung für %s: %.2f km\n", username, totalDistance)
} }
func updateMetrics() { func updateMetrics() {
data, err := fetchTraewellingData() usernames := os.Getenv("TRAEWELLING_USERNAMES")
if err != nil { if usernames == "" {
fmt.Printf("Fehler beim Abrufen der Daten: %v\n", err) fmt.Println("TRAEWELLING_USERNAMES ist nicht gesetzt")
return return
} }
processAndPrintTripDetails(data)
for _, username := range strings.Split(usernames, ",") {
username = strings.TrimSpace(username) // Entferne Leerzeichen
data, err := fetchStatuses(username)
if err != nil {
fmt.Printf("Fehler beim Abrufen der Daten für Benutzer '%s': %v\n", username, err)
continue
}
processAndPrintTripDetails(username, data)
}
} }
func main() { func main() {
go func() { go func() {
for { for {
updateMetrics() updateMetrics()
time.Sleep(5 * time.Minute) time.Sleep(5 * time.Minute) // Aktualisierung alle 5 Minuten
} }
}() }()
http.Handle("/metrics", promhttp.Handler()) http.Handle("/metrics", promhttp.Handler())
fmt.Println("Server läuft auf Port 8080...") fmt.Println("Server läuft auf Port 8080...")