Update media handling

This commit is contained in:
2025-10-02 14:01:27 +02:00
parent 0e54a6019e
commit 3b24e64131
7 changed files with 205 additions and 49 deletions

View File

@@ -1,16 +1,18 @@
package server
import (
"errors"
"fmt"
"html"
"io/fs"
"log"
"net/http"
"os"
"path/filepath"
"runtime"
"strings"
"sync"
"time"
webbundle "luxtools/web"
)
const (
@@ -26,45 +28,53 @@ const (
`
)
// Config contains the runtime options for the HTTP server.
type Config struct {
MediaDir string
}
// Server hosts the Luxtools HTTP handlers.
type Server struct {
mux *http.ServeMux
indexPage []byte
staticRoot string
assetsRoot string
mux *http.ServeMux
indexPage []byte
staticFS fs.FS
mediaFS http.FileSystem
counterMu sync.Mutex
clickCount int
}
// New constructs a configured Server ready to serve requests.
func New() (*Server, error) {
projectRoot, err := goProjectRoot()
if err != nil {
return nil, err
func New(cfg Config) (*Server, error) {
if strings.TrimSpace(cfg.MediaDir) == "" {
return nil, fmt.Errorf("media directory is required")
}
indexPath := filepath.Join(projectRoot, "web", "templates", "index.html")
staticDir := filepath.Join(projectRoot, "web", "static")
assetsDir := filepath.Join(projectRoot, "assets")
mediaDir := filepath.Clean(cfg.MediaDir)
indexPage, err := os.ReadFile(indexPath)
info, err := os.Stat(mediaDir)
if err != nil {
return nil, fmt.Errorf("media directory check failed: %w", err)
}
if !info.IsDir() {
return nil, fmt.Errorf("media directory must be a directory: %s", mediaDir)
}
indexPage, err := webbundle.Content.ReadFile("templates/index.html")
if err != nil {
return nil, fmt.Errorf("failed to read index template: %w", err)
}
if _, err := os.Stat(staticDir); err != nil {
return nil, fmt.Errorf("static directory check failed: %w", err)
}
if _, err := os.Stat(assetsDir); err != nil {
return nil, fmt.Errorf("assets directory check failed: %w", err)
staticFS, err := fs.Sub(webbundle.Content, "static")
if err != nil {
return nil, fmt.Errorf("failed to prepare static assets: %w", err)
}
s := &Server{
mux: http.NewServeMux(),
indexPage: indexPage,
staticRoot: staticDir,
assetsRoot: assetsDir,
mux: http.NewServeMux(),
indexPage: indexPage,
staticFS: staticFS,
mediaFS: http.Dir(mediaDir),
}
s.registerRoutes()
@@ -82,8 +92,11 @@ func (s *Server) Address() string {
}
func (s *Server) registerRoutes() {
s.mux.Handle("/static/", http.StripPrefix("/static/", allowGetHead(http.FileServer(http.Dir(s.staticRoot)))))
s.mux.Handle("/assets/", http.StripPrefix("/assets/", allowGetHead(http.FileServer(http.Dir(s.assetsRoot)))))
staticHandler := http.FileServer(http.FS(s.staticFS))
mediaHandler := http.FileServer(s.mediaFS)
s.mux.Handle("/static/", http.StripPrefix("/static/", allowGetHead(staticHandler)))
s.mux.Handle("/media/", http.StripPrefix("/media/", allowGetHead(mediaHandler)))
s.mux.HandleFunc("/", s.handleRequest)
}
@@ -157,14 +170,3 @@ func allowGetHead(next http.Handler) http.Handler {
}
})
}
func goProjectRoot() (string, error) {
_, currentFile, _, ok := runtime.Caller(0)
if !ok {
return "", errors.New("unable to determine caller information")
}
dir := filepath.Dir(currentFile)
projectRoot := filepath.Clean(filepath.Join(dir, "..", ".."))
return projectRoot, nil
}