nsfwapp/backend/record_job_progress.go
2026-02-12 11:33:21 +01:00

106 lines
2.5 KiB
Go

package main
import (
"math"
"strings"
)
func setJobProgress(job *RecordJob, phase string, pct int) {
phase = strings.TrimSpace(phase)
phaseLower := strings.ToLower(phase)
// clamp pct 0..100
if pct < 0 {
pct = 0
}
if pct > 100 {
pct = 100
}
// "globale" Zielbereiche pro Phase (dein Pipeline-Modell)
// postwork wartet: 70..72
// remuxing: 72..78
// moving: 78..84
// probe: 84..86
// assets: 86..99
type rng struct{ start, end int }
rangeFor := func(ph string) rng {
switch ph {
case "postwork":
return rng{0, 5}
case "remuxing":
return rng{5, 65}
case "moving":
return rng{65, 75}
case "probe":
return rng{75, 80}
case "assets":
return rng{80, 99}
default:
return rng{0, 100}
}
}
jobsMu.Lock()
defer jobsMu.Unlock()
// Sobald Postwork läuft oder Aufnahme beendet ist -> Recorder darf NICHTS mehr überschreiben.
inPostwork := job.EndedAt != nil || (strings.TrimSpace(job.Phase) != "" && strings.ToLower(strings.TrimSpace(job.Phase)) != "recording")
if inPostwork {
// harte Blockade: alte recording-Updates dürfen weder Phase noch Progress anfassen
if phaseLower == "" || phaseLower == "recording" {
return
}
}
// Phase aktualisieren (aber nur wenn nicht leer)
if phase != "" {
job.Phase = phase
}
// ✅ Sonderfall: "wartet auf Nachbearbeitung" => Progress bleibt 0%
// Erwartung: Caller sendet phase="postwork" und pct=0 solange nur gewartet wird.
// Muss vor "niemals rückwärts" passieren, sonst käme man von Recording-Progress nicht mehr auf 0.
if phaseLower == "postwork" && pct == 0 {
job.Progress = 0
return
}
// Progress-Logik:
// - wenn wir in Postwork sind und jemand phasenlokale 0..100 liefert (z.B. remuxing 25),
// mappe das in den globalen Bereich der Phase.
// - danach: niemals rückwärts.
mapped := pct
if inPostwork {
r := rangeFor(phaseLower)
if r.end >= r.start {
// Heuristik:
// - Wenn pct bereits im globalen Bereich der Phase liegt => als global interpretieren, clampen.
// - Sonst => als lokales 0..100 interpretieren und in [start..end] mappen.
if pct >= r.start && pct <= r.end {
// schon global
mapped = pct
} else {
// lokal 0..100 -> global
width := float64(r.end - r.start)
mapped = r.start + int(math.Round((float64(pct)/100.0)*width))
}
// clamp in den Bereich
if mapped < r.start {
mapped = r.start
}
if mapped > r.end {
mapped = r.end
}
}
}
// niemals rückwärts
if mapped < job.Progress {
mapped = job.Progress
}
job.Progress = mapped
}