Initial commit
Test / test (push) Successful in 7m5s
Release / gates (push) Successful in 7m28s
Release / build (amd64, freebsd) (push) Successful in 2m52s
Release / build (amd64, linux) (push) Successful in 2m46s
Release / build (arm64, freebsd) (push) Successful in 2m22s
Release / build (arm64, linux) (push) Successful in 2m38s
Release / build (loong64, linux) (push) Successful in 2m7s
Release / build (riscv64, linux) (push) Successful in 2m17s
Release / release (push) Successful in 1m0s
Test / test (push) Successful in 7m5s
Release / gates (push) Successful in 7m28s
Release / build (amd64, freebsd) (push) Successful in 2m52s
Release / build (amd64, linux) (push) Successful in 2m46s
Release / build (arm64, freebsd) (push) Successful in 2m22s
Release / build (arm64, linux) (push) Successful in 2m38s
Release / build (loong64, linux) (push) Successful in 2m7s
Release / build (riscv64, linux) (push) Successful in 2m17s
Release / release (push) Successful in 1m0s
Assisted-by: GLM 5.3
This commit is contained in:
@@ -0,0 +1,63 @@
|
||||
// Copyright (c) 2026 Petr Balvín <opensource@petrbalvin.org> (https://petrbalvin.org)
|
||||
// SPDX-License-Identifier: PolyForm-Noncommercial-1.0.0
|
||||
|
||||
package admin
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
"sourcedock.dev/petrbalvin/volumen/internal/store"
|
||||
)
|
||||
|
||||
func (a *Admin) registerMediaRoutes(mux *http.ServeMux) {
|
||||
mux.HandleFunc("GET /admin/media", a.requireLogin(a.handleMediaLibrary))
|
||||
mux.HandleFunc("POST /admin/media/{name}/delete", a.requireLogin(a.handleMediaDelete))
|
||||
}
|
||||
|
||||
func (a *Admin) handleMediaLibrary(w http.ResponseWriter, r *http.Request) {
|
||||
data := a.pageData(r)
|
||||
items := a.deps.Store.ListMedia()
|
||||
data.MediaItems = mediaRows(items)
|
||||
data.MediaTotal = humanSize(totalSize(items))
|
||||
data.Crumbs = []Crumb{{Label: "Media", IsLast: true, UI: true}}
|
||||
a.renderPage(w, r, "media.html", data, http.StatusOK)
|
||||
}
|
||||
|
||||
// totalSize sums the byte sizes of the media library.
|
||||
func totalSize(items []store.Media) int64 {
|
||||
var total int64
|
||||
for _, item := range items {
|
||||
total += item.Size
|
||||
}
|
||||
return total
|
||||
}
|
||||
|
||||
// humanSize formats a byte count for the library summary: kilobytes
|
||||
// below a megabyte (rounded up, so nothing reads as zero), megabytes
|
||||
// above it, empty for an empty library.
|
||||
func humanSize(total int64) string {
|
||||
switch {
|
||||
case total <= 0:
|
||||
return ""
|
||||
case total < 1024*1024:
|
||||
kb := (total + 1023) / 1024
|
||||
return fmt.Sprintf("%d kB", kb)
|
||||
default:
|
||||
return fmt.Sprintf("%.1f MB", float64(total)/(1024*1024))
|
||||
}
|
||||
}
|
||||
|
||||
func (a *Admin) handleMediaDelete(w http.ResponseWriter, r *http.Request) {
|
||||
if !a.requireCSRF(w, r) {
|
||||
return
|
||||
}
|
||||
name := r.PathValue("name")
|
||||
if !a.deps.Store.DeleteMedia("/media/" + strings.TrimPrefix(name, "/")) {
|
||||
http.Error(w, "File not found", http.StatusNotFound)
|
||||
return
|
||||
}
|
||||
a.record(r, "media.deleted", fmt.Sprintf("/media/%s", name), nil)
|
||||
http.Redirect(w, r, "/admin/media", http.StatusSeeOther)
|
||||
}
|
||||
Reference in New Issue
Block a user