233 lines
4.6 KiB
Go
233 lines
4.6 KiB
Go
// backend\tray_stats.go
|
|
|
|
package main
|
|
|
|
import (
|
|
"fmt"
|
|
"strconv"
|
|
"strings"
|
|
"time"
|
|
|
|
godisk "github.com/shirou/gopsutil/v3/disk"
|
|
)
|
|
|
|
type TrayStats struct {
|
|
ActiveDownloads int
|
|
DownloadLimitEnabled bool
|
|
DownloadLimitMax int
|
|
DownloadLimitReached bool
|
|
|
|
PostworkWaiting int
|
|
PostworkRunning int
|
|
|
|
EnrichWaiting int
|
|
EnrichRunning int
|
|
|
|
AutostartPaused bool
|
|
AutostartPausedByUser bool
|
|
AutostartPausedByDisk bool
|
|
|
|
DiskFreeBytes uint64
|
|
HasDiskInfo bool
|
|
DiskEmergency bool
|
|
|
|
Uptime time.Duration
|
|
}
|
|
|
|
func buildTrayStats() TrayStats {
|
|
active := activeRecordingJobsCount()
|
|
|
|
limitEnabled, limitMax, _, limitReached := concurrentDownloadsLimitState()
|
|
if limitMax < 1 {
|
|
limitMax = 1
|
|
}
|
|
|
|
pwWaiting, pwRunning, _ := postWorkQ.Stats()
|
|
enWaiting, enRunning, _ := enrichQ.Stats()
|
|
|
|
auto := getAutostartStatePayload()
|
|
|
|
diskFree, hasDisk := getTrayDiskFreeBytes()
|
|
|
|
return TrayStats{
|
|
ActiveDownloads: active,
|
|
DownloadLimitEnabled: limitEnabled,
|
|
DownloadLimitMax: limitMax,
|
|
DownloadLimitReached: limitReached,
|
|
|
|
PostworkWaiting: pwWaiting,
|
|
PostworkRunning: pwRunning,
|
|
|
|
EnrichWaiting: enWaiting,
|
|
EnrichRunning: enRunning,
|
|
|
|
AutostartPaused: auto.Paused,
|
|
AutostartPausedByUser: auto.PausedByUser,
|
|
AutostartPausedByDisk: auto.PausedByDisk,
|
|
|
|
DiskFreeBytes: diskFree,
|
|
HasDiskInfo: hasDisk,
|
|
DiskEmergency: diskEmergencyActive(),
|
|
|
|
Uptime: time.Since(serverStartedAt).Round(time.Second),
|
|
}
|
|
}
|
|
|
|
func getTrayDiskFreeBytes() (uint64, bool) {
|
|
s := getSettings()
|
|
|
|
recordDir, err := resolvePathRelativeToApp(s.RecordDir)
|
|
if err != nil || strings.TrimSpace(recordDir) == "" {
|
|
recordDir = strings.TrimSpace(s.RecordDir)
|
|
}
|
|
if strings.TrimSpace(recordDir) == "" {
|
|
return 0, false
|
|
}
|
|
|
|
u, err := godisk.Usage(recordDir)
|
|
if err != nil || u == nil {
|
|
return 0, false
|
|
}
|
|
|
|
return u.Free, true
|
|
}
|
|
|
|
func diskEmergencyActive() bool {
|
|
return isAutostartPaused() && getAutostartStatePayload().PausedByDisk
|
|
}
|
|
|
|
func (s TrayStats) MenuTitle() string {
|
|
return fmt.Sprintf(
|
|
"Aktiv: %d • PW: %d/%d • Enrich: %d/%d",
|
|
s.ActiveDownloads,
|
|
s.PostworkRunning,
|
|
s.PostworkWaiting,
|
|
s.EnrichRunning,
|
|
s.EnrichWaiting,
|
|
)
|
|
}
|
|
|
|
func (s TrayStats) Tooltip() string {
|
|
return fmt.Sprintf(
|
|
"Recorder | Downloads %s | PW %d/%d | Enrich %d/%d",
|
|
s.downloadLimitText(),
|
|
s.PostworkRunning,
|
|
s.PostworkWaiting,
|
|
s.EnrichRunning,
|
|
s.EnrichWaiting,
|
|
)
|
|
}
|
|
|
|
func (s TrayStats) AutostartLine() string {
|
|
switch {
|
|
case s.AutostartPausedByDisk:
|
|
return "Autostart: Pausiert (Disk-Notbremse)"
|
|
case s.AutostartPausedByUser:
|
|
return "Autostart: Pausiert"
|
|
default:
|
|
return "Autostart: Aktiv"
|
|
}
|
|
}
|
|
|
|
func (s TrayStats) DownloadsLine() string {
|
|
if s.DownloadLimitEnabled {
|
|
if s.DownloadLimitReached {
|
|
return fmt.Sprintf(
|
|
"Downloads: %d/%d aktiv (Limit erreicht)",
|
|
s.ActiveDownloads,
|
|
s.DownloadLimitMax,
|
|
)
|
|
}
|
|
return fmt.Sprintf(
|
|
"Downloads: %d/%d aktiv",
|
|
s.ActiveDownloads,
|
|
s.DownloadLimitMax,
|
|
)
|
|
}
|
|
|
|
return fmt.Sprintf("Downloads: %d aktiv (kein Limit)", s.ActiveDownloads)
|
|
}
|
|
|
|
func (s TrayStats) PostworkLine() string {
|
|
return fmt.Sprintf(
|
|
"Postwork: %d läuft • %d wartend",
|
|
s.PostworkRunning,
|
|
s.PostworkWaiting,
|
|
)
|
|
}
|
|
|
|
func (s TrayStats) EnrichLine() string {
|
|
return fmt.Sprintf(
|
|
"Enrich: %d läuft • %d wartend",
|
|
s.EnrichRunning,
|
|
s.EnrichWaiting,
|
|
)
|
|
}
|
|
|
|
func (s TrayStats) DiskLine() string {
|
|
if !s.HasDiskInfo {
|
|
return "Freier Speicher: unbekannt"
|
|
}
|
|
|
|
if s.DiskEmergency {
|
|
return fmt.Sprintf(
|
|
"Freier Speicher: %s (kritisch)",
|
|
formatTrayBytes(s.DiskFreeBytes),
|
|
)
|
|
}
|
|
|
|
return fmt.Sprintf(
|
|
"Freier Speicher: %s",
|
|
formatTrayBytes(s.DiskFreeBytes),
|
|
)
|
|
}
|
|
|
|
func (s TrayStats) UptimeLine() string {
|
|
return "Uptime: " + formatTrayDuration(s.Uptime)
|
|
}
|
|
|
|
func (s TrayStats) ToggleAutostartTitle() string {
|
|
if s.AutostartPausedByDisk {
|
|
return "Autostart fortsetzen (gesperrt: Disk)"
|
|
}
|
|
if s.AutostartPaused {
|
|
return "Autostart fortsetzen"
|
|
}
|
|
return "Autostart pausieren"
|
|
}
|
|
|
|
func (s TrayStats) downloadLimitText() string {
|
|
if s.DownloadLimitEnabled {
|
|
return fmt.Sprintf("%d/%d", s.ActiveDownloads, s.DownloadLimitMax)
|
|
}
|
|
return strconv.Itoa(s.ActiveDownloads)
|
|
}
|
|
|
|
func formatTrayDuration(d time.Duration) string {
|
|
if d < 0 {
|
|
d = 0
|
|
}
|
|
|
|
total := int(d.Seconds())
|
|
h := total / 3600
|
|
m := (total % 3600) / 60
|
|
s := total % 60
|
|
|
|
return fmt.Sprintf("%02d:%02d:%02d", h, m, s)
|
|
}
|
|
|
|
func formatTrayBytes(b uint64) string {
|
|
const unit = 1000
|
|
if b < unit {
|
|
return fmt.Sprintf("%d B", b)
|
|
}
|
|
|
|
div, exp := uint64(unit), 0
|
|
for n := b / unit; n >= unit; n /= unit {
|
|
div *= unit
|
|
exp++
|
|
}
|
|
|
|
return fmt.Sprintf("%.1f %cB", float64(b)/float64(div), "kMGTPE"[exp])
|
|
}
|