From d6fa1fc97aff58634385aead96a55a10a8d03608 Mon Sep 17 00:00:00 2001 From: Samuel Lorch Date: Sun, 5 May 2024 01:31:45 +0200 Subject: [PATCH] Add Library Pages --- server/libraries.go | 80 +++++++++++++++++++++++++++++++++++++++++++++ server/library.go | 79 ++++++++++++++++++++++++++++++++++++++++++++ server/server.go | 2 ++ tmpl/libraries.tmpl | 40 +++++++++++++++++++++++ tmpl/library.tmpl | 34 +++++++++++++++++++ 5 files changed, 235 insertions(+) create mode 100644 server/libraries.go create mode 100644 server/library.go create mode 100644 tmpl/libraries.tmpl create mode 100644 tmpl/library.tmpl diff --git a/server/libraries.go b/server/libraries.go new file mode 100644 index 0000000..b5d0f64 --- /dev/null +++ b/server/libraries.go @@ -0,0 +1,80 @@ +package server + +import ( + "bytes" + "fmt" + "log/slog" + "net/http" + + "git.lastassault.de/speatzle/morffix/constants" + "github.com/jackc/pgx/v5" +) + +type LibrariesData struct { + Libraries []Library +} + +type Library struct { + ID string `db:"id"` + Name string `db:"name"` + Path string `db:"path"` + Enable bool `db:"enable"` +} + +func handleLibraries(w http.ResponseWriter, r *http.Request) { + data := LibrariesData{} + + if r.Method == "POST" { + err := createLibrary(r) + if err != nil { + slog.ErrorContext(r.Context(), "Create Library", "err", err) + http.Error(w, "Error Create Library: "+err.Error(), http.StatusInternalServerError) + return + } + } + + rows, err := db.Query(r.Context(), "SELECT id, name, path, enable FROM libraries") + if err != nil { + slog.ErrorContext(r.Context(), "Query Libraries", "err", err) + http.Error(w, "Error Query Libraries: "+err.Error(), http.StatusInternalServerError) + return + } + libraries, err := pgx.CollectRows[Library](rows, pgx.RowToStructByName[Library]) + if err != nil { + slog.ErrorContext(r.Context(), "Collect Rows", "err", err) + http.Error(w, "Error Query Libraries: "+err.Error(), http.StatusInternalServerError) + return + } + data.Libraries = libraries + + buf := bytes.Buffer{} + err = templates.ExecuteTemplate(&buf, constants.LIBRARIES_TEMPLATE_NAME, data) + if err != nil { + slog.ErrorContext(r.Context(), "Executing Libraries 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 createLibrary(r *http.Request) error { + err := r.ParseForm() + if err != nil { + return fmt.Errorf("Parseing Form: %w", err) + } + name := r.FormValue("name") + path := r.FormValue("path") + enable := r.FormValue("enable") == "on" + slog.Info("Got Library Create", "name", name, "path", path, "enable", enable) + + _, err = db.Exec(r.Context(), "INSERT INTO Libraries (name, path, enable) VALUES ($1,$2,$3)", name, path, enable) + if err != nil { + return fmt.Errorf("Inserting Library: %w", err) + } + + return nil +} diff --git a/server/library.go b/server/library.go new file mode 100644 index 0000000..ae29948 --- /dev/null +++ b/server/library.go @@ -0,0 +1,79 @@ +package server + +import ( + "bytes" + "log/slog" + "net/http" + + "git.lastassault.de/speatzle/morffix/constants" + "github.com/jackc/pgx/v5" +) + +type LibraryData struct { + Library Library + Files []File +} + +type File struct { + ID int `db:"id"` + Path string `db:"path"` + Size int64 `db:"size"` + Missing bool `db:"missing"` +} + +func handleLibrary(w http.ResponseWriter, r *http.Request) { + id := r.PathValue("id") + if id == "" { + handleLibraries(w, r) + return + } + + data := LibraryData{} + + var name string + var path string + var enabled bool + err := db.QueryRow(r.Context(), "SELECT name, path, enable FROM libraries WHERE id = $1", id).Scan(&name, &path, &enabled) + if err != nil { + slog.ErrorContext(r.Context(), "Get Library", "err", err) + http.Error(w, "Error Get Library: "+err.Error(), http.StatusInternalServerError) + return + } + data.Library = Library{ + ID: id, + Name: name, + Path: path, + Enable: enabled, + } + + if r.Method == "PUT" { + // TODO + } + + rows, err := db.Query(r.Context(), "SELECT id, path, size, missing FROM files where library_id = $1", id) + if err != nil { + slog.ErrorContext(r.Context(), "Query Files", "err", err) + http.Error(w, "Error Query Files: "+err.Error(), http.StatusInternalServerError) + return + } + files, err := pgx.CollectRows[File](rows, pgx.RowToStructByName[File]) + if err != nil { + slog.ErrorContext(r.Context(), "Collect Rows", "err", err) + http.Error(w, "Error Query Files: "+err.Error(), http.StatusInternalServerError) + return + } + data.Files = files + + buf := bytes.Buffer{} + err = templates.ExecuteTemplate(&buf, constants.LIBRARY_TEMPLATE_NAME, data) + if err != nil { + slog.ErrorContext(r.Context(), "Executing Library 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) + } +} diff --git a/server/server.go b/server/server.go index 6251517..7a09678 100644 --- a/server/server.go +++ b/server/server.go @@ -71,6 +71,8 @@ func Start(_conf config.Config, tmplFS embed.FS, staticFS embed.FS, migrationsFS mux := http.NewServeMux() mux.HandleFunc("/worker", handleWorkerWebsocket) mux.Handle("/static/", fs) + mux.HandleFunc("/libraries/{id}", handleLibrary) + mux.HandleFunc("/libraries", handleLibraries) mux.HandleFunc("/", handleIndex) server := &http.Server{ diff --git a/tmpl/libraries.tmpl b/tmpl/libraries.tmpl new file mode 100644 index 0000000..9a87455 --- /dev/null +++ b/tmpl/libraries.tmpl @@ -0,0 +1,40 @@ +{{template "head"}} +

Libraries

+
+ + + + + + + + {{range $l := .Libraries}} + + + + + + + {{end}} +
IDNamePathEnable
+ {{ $l.ID }} + + {{ $l.Name }} + + {{ $l.Path }} + + {{ $l.Enable }} +
+
+ +

New Library

+
+
+
+
+
+
+
+ +
+{{template "tail"}} \ No newline at end of file diff --git a/tmpl/library.tmpl b/tmpl/library.tmpl new file mode 100644 index 0000000..ac17e3d --- /dev/null +++ b/tmpl/library.tmpl @@ -0,0 +1,34 @@ +{{template "head"}} +

Library {{.Library.Name}}

+

Enabled {{.Library.Enable}} +

Files

+
+ +
+
+ + + + + + + + {{range $f := .Files}} + + + + + + + {{end}} +
IDPathSizeMissing
+ {{ $f.ID }} + + {{ $f.Path }} + + {{ $f.Size }} + + {{ $f.Missing }} +
+
+{{template "tail"}} \ No newline at end of file