ui mvp ish
parent
e377a4f5db
commit
3e6d2874d5
|
|
@ -0,0 +1,20 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<header>
|
||||||
|
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/water.css@2/out/dark.css">
|
||||||
|
</header>
|
||||||
|
<body>
|
||||||
|
<div>
|
||||||
|
{{ range .Series }}
|
||||||
|
<div style="display: inline-block;">
|
||||||
|
<a href="/media/{{ .HREF }}">
|
||||||
|
<img src="/media/{{ .Thumbnail }}" alt="{{ .Thumbnail }}"/>
|
||||||
|
<p>{{ .Thumbnail }}</p>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
{{ end }}
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
<footer>
|
||||||
|
</footer>
|
||||||
|
</html>
|
||||||
|
|
@ -0,0 +1,120 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"embed"
|
||||||
|
_ "embed"
|
||||||
|
"flag"
|
||||||
|
"fmt"
|
||||||
|
"html/template"
|
||||||
|
"log"
|
||||||
|
"net"
|
||||||
|
"net/http"
|
||||||
|
"os"
|
||||||
|
"os/signal"
|
||||||
|
"path"
|
||||||
|
"strings"
|
||||||
|
"syscall"
|
||||||
|
|
||||||
|
"ffmpeg.d/pkg/fs"
|
||||||
|
)
|
||||||
|
|
||||||
|
//go:embed *.tmpl
|
||||||
|
var TMPL embed.FS
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
ctx, can := signal.NotifyContext(context.Background(), syscall.SIGINT)
|
||||||
|
defer can()
|
||||||
|
|
||||||
|
if err := Run(ctx, os.Args[1:]); err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func Run(ctx context.Context, args []string) error {
|
||||||
|
flags := flag.NewFlagSet(os.Args[0], flag.ContinueOnError)
|
||||||
|
d := flags.String("d", "./testdata/", "directory containing directories of (x.jpg,x.mp4)")
|
||||||
|
p := flags.Int("p", 8080, "port to listen on")
|
||||||
|
if err := flags.Parse(args); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
tmpl, err := template.ParseFS(TMPL, "*.tmpl")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
s := &http.Server{
|
||||||
|
Addr: fmt.Sprintf(":%d", *p),
|
||||||
|
Handler: http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
if strings.HasPrefix(r.URL.Path, "/media/") {
|
||||||
|
http.StripPrefix("/media/", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
log.Println(r.URL.Path, "vs", *d)
|
||||||
|
http.FileServer(http.Dir(*d)).ServeHTTP(w, r)
|
||||||
|
})).ServeHTTP(w, r)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
type Series struct {
|
||||||
|
HREF string
|
||||||
|
Thumbnail string
|
||||||
|
}
|
||||||
|
|
||||||
|
ds, err := fs.LsD(*d)
|
||||||
|
if err != nil {
|
||||||
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
seriesByKey := map[string]Series{}
|
||||||
|
for _, d := range ds {
|
||||||
|
files, err := fs.LsF(d)
|
||||||
|
if err != nil {
|
||||||
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
for _, f := range files {
|
||||||
|
key := strings.Split(path.Base(f), ".")[0]
|
||||||
|
v := seriesByKey[key]
|
||||||
|
switch path.Ext(f) {
|
||||||
|
case ".jpg":
|
||||||
|
v.Thumbnail = path.Join(path.Base(d), path.Base(f))
|
||||||
|
case ".mp4":
|
||||||
|
v.HREF = path.Join(path.Base(d), path.Base(f))
|
||||||
|
}
|
||||||
|
seriesByKey[key] = v
|
||||||
|
}
|
||||||
|
}
|
||||||
|
series := []Series{}
|
||||||
|
for _, v := range seriesByKey {
|
||||||
|
series = append(series, v)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := tmpl.Execute(w, map[string]any{
|
||||||
|
"Series": series,
|
||||||
|
}); err != nil {
|
||||||
|
log.Println(err, *d)
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
BaseContext: func(net.Listener) context.Context {
|
||||||
|
return ctx
|
||||||
|
},
|
||||||
|
}
|
||||||
|
defer s.Shutdown(ctx)
|
||||||
|
|
||||||
|
errs := make(chan error)
|
||||||
|
go func() {
|
||||||
|
defer close(errs)
|
||||||
|
|
||||||
|
errs <- s.ListenAndServe()
|
||||||
|
}()
|
||||||
|
|
||||||
|
select {
|
||||||
|
case err := <-errs:
|
||||||
|
return err
|
||||||
|
case <-ctx.Done():
|
||||||
|
s.Shutdown(ctx)
|
||||||
|
for range errs {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue