package server import ( "bytes" "log/slog" "net/http" "git.lastassault.de/speatzle/morffix/constants" "git.lastassault.de/speatzle/morffix/types" "github.com/jackc/pgx/v5" ) type IndexData struct { Counter []int Workers []IndexWorker Tasks []Task } type IndexWorker struct { Worker Status *types.WorkerStatus } type Task struct { ID int `db:"id"` Library int `db:"library"` Worker *string `db:"worker"` Type int `db:"type"` Status int `db:"status"` File string `db:"file"` } func handleIndex(w http.ResponseWriter, r *http.Request) { data := IndexData{ Workers: []IndexWorker{}, } func() { WorkersMutex.Lock() defer WorkersMutex.Unlock() for i := range Workers { if Workers[i].Connected { var status types.WorkerStatus _, err := rpcServer.Call(r.Context(), Workers[i].Conn, "status", nil, &status) if err != nil { w.Write([]byte(err.Error())) slog.ErrorContext(r.Context(), "Error Getting Worker Status", "err", err) return } slog.InfoContext(r.Context(), "Got Worker Status", "id", i, "status", status) data.Workers = append(data.Workers, IndexWorker{ Worker: *Workers[i], Status: &status, }) } else { data.Workers = append(data.Workers, IndexWorker{ Worker: *Workers[i], Status: nil, }) } } }() var size int err := db.QueryRow(r.Context(), "SELECT SUM(size) AS size FROM files WHERE missing = $1", false).Scan(&size) if err != nil { size = 0 } data.Counter = splitInt(size) rows, err := db.Query(r.Context(), "SELECT t.id AS id, l.id AS library, t.worker_id AS worker, t.type AS type, t.status AS status, f.path AS file FROM tasks t INNER JOIN files f ON f.id = t.file_id INNER JOIN libraries l ON l.id = f.library_id") if err != nil { slog.ErrorContext(r.Context(), "Query Tasks", "err", err) http.Error(w, "Error Query Tasks: "+err.Error(), http.StatusInternalServerError) return } tasks, err := pgx.CollectRows[Task](rows, pgx.RowToStructByName[Task]) if err != nil { slog.ErrorContext(r.Context(), "Executing index Template", "err", err) http.Error(w, "Error Query Tasks: "+err.Error(), http.StatusInternalServerError) return } data.Tasks = tasks buf := bytes.Buffer{} err = templates.ExecuteTemplate(&buf, constants.INDEX_TEMPLATE_NAME, data) if err != nil { slog.ErrorContext(r.Context(), "Executing index Template", "err", err) http.Error(w, "Error Executing Template: "+err.Error(), http.StatusInternalServerError) return } _, err = w.Write(buf.Bytes()) if err != nil { slog.ErrorContext(r.Context(), "Writing http Response", "err", err) } } func splitInt(n int) []int { slc := []int{} for n > 0 { slc = append(slc, n%10) n /= 10 } result := []int{} for i := range slc { result = append(result, slc[len(slc)-1-i]) } return result }