140 lines
3.8 KiB
Go
140 lines
3.8 KiB
Go
package main
|
|
|
|
import (
|
|
_ "embed"
|
|
"encoding/json"
|
|
"fmt"
|
|
"html/template"
|
|
"math"
|
|
"os"
|
|
"time"
|
|
|
|
"github.com/confusedpolarbear/intro_skipper_verifier/structs"
|
|
)
|
|
|
|
//go:embed report.html
|
|
var reportTemplate []byte
|
|
|
|
func compareReports(oldReportPath, newReportPath, destination string) {
|
|
start := time.Now()
|
|
|
|
// Populate the destination filename if none was provided
|
|
if destination == "" {
|
|
destination = fmt.Sprintf("report-%d.html", start.Unix())
|
|
}
|
|
|
|
// Open the report for writing
|
|
f, err := os.OpenFile(destination, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600)
|
|
if err != nil {
|
|
panic(err)
|
|
} else {
|
|
defer f.Close()
|
|
}
|
|
|
|
fmt.Printf("Started at: %s\n", start.Format(time.RFC1123))
|
|
fmt.Printf("First report: %s\n", oldReportPath)
|
|
fmt.Printf("Second report: %s\n", newReportPath)
|
|
fmt.Printf("Destination: %s\n\n", destination)
|
|
|
|
// Unmarshal both reports
|
|
oldReport, newReport := unmarshalReport(oldReportPath), unmarshalReport(newReportPath)
|
|
|
|
fmt.Println("[+] Comparing reports")
|
|
|
|
// Setup a function map with helper functions to use in the template
|
|
tmp := template.New("report")
|
|
|
|
funcs := make(template.FuncMap)
|
|
|
|
funcs["printTime"] = func(t time.Time) string {
|
|
return t.Format(time.RFC1123)
|
|
}
|
|
|
|
funcs["printDuration"] = func(d time.Duration) string {
|
|
return d.Round(time.Second).String()
|
|
}
|
|
|
|
funcs["printAnalysisSettings"] = func(pc structs.PluginConfiguration) string {
|
|
return pc.AnalysisSettings()
|
|
}
|
|
|
|
funcs["printIntroductionReqs"] = func(pc structs.PluginConfiguration) string {
|
|
return pc.IntroductionRequirements()
|
|
}
|
|
|
|
funcs["sortShows"] = templateSortShows
|
|
funcs["sortSeasons"] = templateSortSeason
|
|
funcs["compareEpisodes"] = templateCompareEpisodes
|
|
tmp.Funcs(funcs)
|
|
|
|
// Load the template or panic
|
|
report := template.Must(tmp.Parse(string(reportTemplate)))
|
|
|
|
err = report.Execute(f,
|
|
structs.TemplateReportData{
|
|
OldReport: oldReport,
|
|
NewReport: newReport,
|
|
})
|
|
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
// Log success
|
|
fmt.Printf("[+] Reports successfully compared in %s\n", time.Since(start).Round(time.Millisecond))
|
|
}
|
|
|
|
func unmarshalReport(path string) structs.Report {
|
|
// Read the provided report
|
|
contents, err := os.ReadFile(path)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
// Unmarshal
|
|
var report structs.Report
|
|
if err := json.Unmarshal(contents, &report); err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
// Setup maps and template data for later use
|
|
report.Path = path
|
|
report.Shows = make(map[string]structs.Seasons)
|
|
report.IntroMap = make(map[string]structs.Intro)
|
|
|
|
// Sort episodes by show and season
|
|
for _, intro := range report.Intros {
|
|
// Round the duration to the nearest second to avoid showing 8 decimal places in the report
|
|
intro.Duration = float32(math.Round(float64(intro.Duration)))
|
|
|
|
// Pretty print the intro start and end times
|
|
intro.FormattedStart = (time.Duration(intro.IntroStart) * time.Second).String()
|
|
intro.FormattedEnd = (time.Duration(intro.IntroEnd) * time.Second).String()
|
|
|
|
show, season := intro.Series, intro.Season
|
|
|
|
// If this show hasn't been seen before, allocate space for it
|
|
if _, ok := report.Shows[show]; !ok {
|
|
report.Shows[show] = make(structs.Seasons)
|
|
}
|
|
|
|
// Store this intro in the season of this show
|
|
episodes := report.Shows[show][season]
|
|
episodes = append(episodes, intro)
|
|
report.Shows[show][season] = episodes
|
|
|
|
// Store a reference to this intro in a lookup table
|
|
report.IntroMap[intro.EpisodeId] = intro
|
|
}
|
|
|
|
// Print report info
|
|
fmt.Printf("Report %s:\n", path)
|
|
fmt.Printf("Generated with Jellyfin %s running on %s\n", report.ServerInfo.Version, report.ServerInfo.OperatingSystem)
|
|
fmt.Printf("Analysis settings: %s\n", report.PluginConfig.AnalysisSettings())
|
|
fmt.Printf("Introduction reqs: %s\n", report.PluginConfig.IntroductionRequirements())
|
|
fmt.Printf("Episodes analyzed: %d\n", len(report.Intros))
|
|
fmt.Println()
|
|
|
|
return report
|
|
}
|