This commit is contained in:
parent
9d2519c085
commit
7d037be106
4 changed files with 58 additions and 21 deletions
|
@ -104,6 +104,7 @@ func Start(_conf config.Config, tmplFS embed.FS, staticFS embed.FS, migrationsFS
|
|||
mux.HandleFunc("/ffmpeg_commands", handleFfmpegCommands)
|
||||
mux.HandleFunc("/queue_enable", HandleSetQueueEnable)
|
||||
mux.HandleFunc("/stats", handleStats)
|
||||
mux.HandleFunc("/stats/{id}", handleStats)
|
||||
|
||||
mux.HandleFunc("/", handleIndex)
|
||||
|
||||
|
|
|
@ -18,7 +18,9 @@ import (
|
|||
)
|
||||
|
||||
type StatsDisplay struct {
|
||||
Charts []ChartData
|
||||
Charts []ChartData
|
||||
Libraries []Library
|
||||
SelectedLibrary string
|
||||
}
|
||||
|
||||
type ChartData struct {
|
||||
|
@ -83,14 +85,14 @@ func generatePie(name string, data []opts.PieData) ChartData {
|
|||
}
|
||||
}
|
||||
|
||||
func generateStats(ctx context.Context) ([]ChartData, error) {
|
||||
func generateStats(ctx context.Context, library_id string) ([]ChartData, error) {
|
||||
data := []ChartData{}
|
||||
|
||||
rows, err := db.Query(ctx,
|
||||
`SELECT COALESCE(jsonb_path_query_first(ffprobe_data, '$.streams[*] ? (@.codec_type == "video") ? (@.disposition.attached_pic == 0).codec_name')::text, 'Unknown') AS name, COUNT(*) AS value
|
||||
FROM files
|
||||
WHERE ffprobe_data IS NOT NULL
|
||||
GROUP BY 1;`)
|
||||
WHERE ffprobe_data IS NOT NULL AND ($1 = "" OR library_id = $1)
|
||||
GROUP BY 1;`, library_id)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Query Codecs: %w", err)
|
||||
}
|
||||
|
@ -111,8 +113,8 @@ func generateStats(ctx context.Context) ([]ChartData, error) {
|
|||
rows, err = db.Query(ctx,
|
||||
`SELECT COALESCE(jsonb_path_query_first(ffprobe_data, '$.streams[*] ? (@.codec_type == "video") ? (@.disposition.attached_pic == 0).width')::text, 'Unknown') AS name, COUNT(*) AS value
|
||||
FROM files
|
||||
WHERE ffprobe_data IS NOT NULL
|
||||
GROUP BY 1;`)
|
||||
WHERE ffprobe_data IS NOT NULL AND ($1 = "" OR library_id = $1)
|
||||
GROUP BY 1;`, library_id)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Query Resolution: %w", err)
|
||||
}
|
||||
|
@ -133,8 +135,8 @@ func generateStats(ctx context.Context) ([]ChartData, error) {
|
|||
rows, err = db.Query(ctx,
|
||||
`SELECT COALESCE(jsonb_path_query_first(ffprobe_data, '$.format.format_name')::text, 'Unknown') AS name, COUNT(*) AS value
|
||||
FROM files
|
||||
WHERE ffprobe_data IS NOT NULL
|
||||
GROUP BY 1;`)
|
||||
WHERE ffprobe_data IS NOT NULL AND ($1 = "" OR library_id = $1)
|
||||
GROUP BY 1;`, library_id)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Query Container: %w", err)
|
||||
}
|
||||
|
@ -154,8 +156,8 @@ func generateStats(ctx context.Context) ([]ChartData, error) {
|
|||
|
||||
rows, err = db.Query(ctx,
|
||||
`SELECT health AS id, COUNT(*) AS value
|
||||
FROM files
|
||||
GROUP BY 1;`)
|
||||
FROM files WHERE ($1 = "" OR library_id = $1)
|
||||
GROUP BY 1;`, library_id)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Query Health: %w", err)
|
||||
}
|
||||
|
@ -175,8 +177,8 @@ func generateStats(ctx context.Context) ([]ChartData, error) {
|
|||
|
||||
rows, err = db.Query(ctx,
|
||||
`SELECT transcode AS id, COUNT(*) AS value
|
||||
FROM files
|
||||
GROUP BY 1;`)
|
||||
FROM files WHERE ($1 = "" OR library_id = $1)
|
||||
GROUP BY 1;`, library_id)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Query Transcode: %w", err)
|
||||
}
|
||||
|
@ -195,9 +197,10 @@ func generateStats(ctx context.Context) ([]ChartData, error) {
|
|||
data = append(data, generatePie("Transcode Status", res))
|
||||
|
||||
rows, err = db.Query(ctx,
|
||||
`SELECT status AS id, COUNT(*) AS value
|
||||
FROM tasks
|
||||
GROUP BY 1;`)
|
||||
`SELECT tasks.status AS id, COUNT(*) AS value
|
||||
FROM tasks INNER JOIN files ON files.id = tasks.file_id
|
||||
WHERE ($1 = "" OR files.library_id = $1)
|
||||
GROUP BY 1;`, library_id)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Query Task Status: %w", err)
|
||||
}
|
||||
|
@ -222,11 +225,11 @@ func generateStats(ctx context.Context) ([]ChartData, error) {
|
|||
}
|
||||
|
||||
rows, err = db.Query(ctx,
|
||||
`SELECT date_trunc('day', updated_at) date, status, COUNT(*) AS count
|
||||
FROM tasks
|
||||
WHERE updated_at > current_date - 7 AND (status = $1 OR status = $2)
|
||||
`SELECT date_trunc('day', tasks.updated_at) date, tasks.status, COUNT(*) AS count
|
||||
FROM tasks INNER JOIN files ON files.id = tasks.file_id
|
||||
WHERE ($1 = "" OR files.library_id = $1) AND tasks.updated_at > tasks.current_date - 7 AND (tasks.status = $2 OR tasks.status = $3)
|
||||
GROUP BY 1,2
|
||||
ORDER BY date;`, constants.TASK_STATUS_SUCCESS, constants.TASK_STATUS_FAILED)
|
||||
ORDER BY date;`, library_id, constants.TASK_STATUS_SUCCESS, constants.TASK_STATUS_FAILED)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Query Task Status Day: %w", err)
|
||||
}
|
||||
|
@ -289,17 +292,36 @@ func generateStats(ctx context.Context) ([]ChartData, error) {
|
|||
}
|
||||
|
||||
func handleStats(w http.ResponseWriter, r *http.Request) {
|
||||
id := r.PathValue("id")
|
||||
|
||||
data, err := generateStats(r.Context())
|
||||
data, err := generateStats(r.Context(), id)
|
||||
if err != nil {
|
||||
slog.ErrorContext(r.Context(), "Generate Stats:", "err", err)
|
||||
http.Error(w, "Generate Stats: "+err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
rows, err := db.Query(r.Context(),
|
||||
`SELECT *
|
||||
FROM libraries;`)
|
||||
if err != nil {
|
||||
slog.ErrorContext(r.Context(), "Query Libraries", "err", err)
|
||||
http.Error(w, "Query Libraries: "+err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
libraries, err := pgx.CollectRows(rows, pgx.RowToStructByName[Library])
|
||||
if err != nil {
|
||||
slog.ErrorContext(r.Context(), "Collect Libraries", "err", err)
|
||||
http.Error(w, "Collect Libraries: "+err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
buf := bytes.Buffer{}
|
||||
err = templates.ExecuteTemplate(&buf, constants.STATS_TEMPLATE_NAME, StatsDisplay{
|
||||
Charts: data,
|
||||
Libraries: libraries,
|
||||
SelectedLibrary: id,
|
||||
Charts: data,
|
||||
})
|
||||
if err != nil {
|
||||
slog.ErrorContext(r.Context(), "Executing Stats Template", "err", err)
|
||||
|
|
7
static/js/library_filter.js
Normal file
7
static/js/library_filter.js
Normal file
|
@ -0,0 +1,7 @@
|
|||
function setLibrary(library_id) {
|
||||
if (library_id === "") {
|
||||
} else {
|
||||
window.location.href = "/stats";
|
||||
}
|
||||
window.location.href = "/stats/" + library_id;
|
||||
}
|
|
@ -1,5 +1,12 @@
|
|||
{{template "head"}}
|
||||
<h2>Stats</h2>
|
||||
<label for="library">Library:</label>
|
||||
<select id="library" name="library" onchange="setLibrary(this.value)" class="short-button">
|
||||
<option {{if e .SelectedLibrary "" }} selected {{end}}value="">ALL</option>
|
||||
{{range $l := .Libraries}}
|
||||
<option {{if e .SelectedLibrary $l.ID }} selected {{end}}value="{{$l.ID}}">{{$l.Name}}</option>
|
||||
{{end}}
|
||||
</select>
|
||||
<div class="stats">
|
||||
{{range $c := .Charts}}
|
||||
{{$c.Element}} {{$c.Script}}
|
||||
|
|
Loading…
Add table
Reference in a new issue