package admin import ( "fmt" "net/http" "aether/internal/audit" "aether/internal/thumbnails" "aether/pkg/response" ) /* POST /api/v1/admin/thumbnails/rebuild – Vorschaubilder neu erzeugen. Anlass: Bis heute wurde die EXIF-Drehung beim Erzeugen nicht ausgewertet. Jedes hochkant aufgenommene Foto liegt im bestehenden Bestand deshalb quer, während dasselbe Bild in der großen Ansicht aufrecht steht – der Browser befolgt die Notiz von selbst, der Server tat es nicht. Beim Hochladen entstehen Vorschaubilder von allein; für das, was schon da ist, braucht es diesen einen Anstoß. Er läuft im Vordergrund und meldet Zahlen: Ein Vorgang, der den halben Bestand neu schreibt, soll nicht stumm im Hintergrund verschwinden. */ func (h *Handler) RebuildThumbnails(w http.ResponseWriter, r *http.Request) { if _, ok := requireAdmin(r); !ok { response.Error(w, http.StatusForbidden, "admin required") return } list, err := h.files.ImageFiles(r.Context()) if err != nil { response.Error(w, http.StatusInternalServerError, "could not list images") return } var rebuilt, failed int for _, f := range list { if !thumbnails.SupportedMIME(f.MimeType) { continue } rc, err := h.storage.Get(r.Context(), f.StorageKey) if err != nil { failed++ continue } err = thumbnails.Generate(r.Context(), h.storage, f.ID.String(), f.MimeType, rc) rc.Close() if err != nil { failed++ continue } // Auch setzen, wenn es schon stand: Dateien, bei denen die Erzeugung // beim Hochladen fehlschlug, bekommen so nachträglich eines. if err := h.files.UpdateThumbnail(r.Context(), f.ID, true); err != nil { failed++ continue } rebuilt++ } h.logAdmin(r, audit.ActionGarbageCollect, "storage", "", "", fmt.Sprintf("thumbnails rebuilt: %d of %d images, %d failed", rebuilt, len(list), failed)) response.JSON(w, http.StatusOK, map[string]any{ "images": len(list), "rebuilt": rebuilt, "failed": failed, }) }