package main
import (
"fmt"
"os"
)
type ReviewEntry struct {
FrameNum int
Timestamp string
SpO2Value int
SpO2LeftDigit int // tens digit (for compatibility)
SpO2LeftConf float64 // confidence score
SpO2RightDigit int // ones digit (for compatibility)
SpO2RightConf float64 // same as SpO2LeftConf for whole-number matching
HRValue int
HRLeftDigit int
HRLeftConf float64
HRRightDigit int
HRRightConf float64
Failed bool
FailureReason string
Unstable bool
UnstableReason string
}
// initReviewHTML creates the HTML file with header and opens the table
func initReviewHTML() error {
html := `
Pulse-Ox Recognition Review
×
Pulse-Ox Recognition Review (Live)
Tip: Type correct number in input box and press Enter to save as template
Refresh page to see latest frames...
| Frame |
Time |
SpO2 / HR |
`
return os.WriteFile("review/review.html", []byte(html), 0644)
}
// appendReviewEntry appends a single entry to the HTML file
func appendReviewEntry(e ReviewEntry) error {
confClass := func(conf float64) string {
if conf >= 95 {
return "conf-high"
}
return "conf-low"
}
// Use left conf as the whole-number confidence
spo2Conf := e.SpO2LeftConf
hrConf := e.HRLeftConf
needsReview := spo2Conf < 95 || hrConf < 95
reviewMarker := ""
if needsReview {
reviewMarker = " ⚠️CHECK"
}
var rowHTML string
if e.Failed {
// Failed recognition entry
rowHTML = fmt.Sprintf(`
| %d%s |
%s |
❌ %s
|
`, e.FrameNum, reviewMarker, e.Timestamp,
e.FailureReason,
e.FrameNum, e.FrameNum, e.FrameNum,
e.SpO2Value, confClass(spo2Conf), spo2Conf, e.FrameNum,
e.FrameNum, e.FrameNum, e.FrameNum,
e.HRValue, confClass(hrConf), hrConf, e.FrameNum)
} else {
// Successful recognition entry
unstableMarker := ""
if e.Unstable {
unstableMarker = fmt.Sprintf("
⚠️ %s", e.UnstableReason)
}
rowHTML = fmt.Sprintf(`
| %d%s%s |
%s |
|
`, e.FrameNum, reviewMarker, unstableMarker, e.Timestamp,
e.FrameNum, e.FrameNum, e.FrameNum,
e.SpO2Value, confClass(spo2Conf), spo2Conf, e.FrameNum,
e.FrameNum, e.FrameNum, e.FrameNum,
e.HRValue, confClass(hrConf), hrConf, e.FrameNum)
}
// Open file in append mode
f, err := os.OpenFile("review/review.html", os.O_APPEND|os.O_WRONLY, 0644)
if err != nil {
return err
}
defer f.Close()
_, err = f.WriteString(rowHTML)
return err
}
// closeReviewHTML writes the closing tags
func closeReviewHTML() error {
footer := `
Color coding:
Green ≥95%,
Red <95%
`
f, err := os.OpenFile("review/review.html", os.O_APPEND|os.O_WRONLY, 0644)
if err != nil {
return err
}
defer f.Close()
_, err = f.WriteString(footer)
return err
}
// writeReviewHTML - kept for backward compatibility (final shutdown)
func writeReviewHTML(entries []ReviewEntry) error {
// Just close the HTML properly - entries already appended
return closeReviewHTML()
}