Add photo galleries API and frontend for public and admin viewing.
Introduces the Go photo-api service, nginx/systemd deploy wiring, and Next.js gallery/lightbox pages so event photos can be managed and browsed. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,60 @@
|
||||
package imaging
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os/exec"
|
||||
)
|
||||
|
||||
// HEIC cannot be decoded in pure Go (HEVC), so conversion shells out to a
|
||||
// host-installed CLI. The Go binary itself stays cgo-free; the converter is
|
||||
// a runtime dependency (Debian: libvips-tools or libheif-examples).
|
||||
type HeicConverter struct {
|
||||
kind string // "vips" | "heif-convert" | "custom"
|
||||
path string
|
||||
}
|
||||
|
||||
// DetectHeicConverter honors an explicit HEIC_CONVERTER command, else
|
||||
// autodetects vips then heif-convert. Returns nil when none is available;
|
||||
// uploads of HEIC are then rejected with a clear message.
|
||||
func DetectHeicConverter(explicit string) *HeicConverter {
|
||||
if explicit != "" {
|
||||
if p, err := exec.LookPath(explicit); err == nil {
|
||||
return &HeicConverter{kind: "custom", path: p}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
if p, err := exec.LookPath("vips"); err == nil {
|
||||
return &HeicConverter{kind: "vips", path: p}
|
||||
}
|
||||
if p, err := exec.LookPath("heif-convert"); err == nil {
|
||||
return &HeicConverter{kind: "heif-convert", path: p}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (h *HeicConverter) Name() string { return h.path }
|
||||
|
||||
// ToJPEG converts src (a .heic file) to a JPEG at dst.
|
||||
func (h *HeicConverter) ToJPEG(src, dst string) error {
|
||||
var cmd *exec.Cmd
|
||||
switch h.kind {
|
||||
case "vips":
|
||||
cmd = exec.Command(h.path, "copy", src, dst+"[Q=95]")
|
||||
case "heif-convert":
|
||||
cmd = exec.Command(h.path, "-q", "95", src, dst)
|
||||
default:
|
||||
// custom converter contract: <cmd> <src> <dst>
|
||||
cmd = exec.Command(h.path, src, dst)
|
||||
}
|
||||
if out, err := cmd.CombinedOutput(); err != nil {
|
||||
return fmt.Errorf("heic conversion failed: %v: %s", err, truncate(string(out), 300))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func truncate(s string, n int) string {
|
||||
if len(s) > n {
|
||||
return s[:n]
|
||||
}
|
||||
return s
|
||||
}
|
||||
Reference in New Issue
Block a user