mirror of
https://github.com/skidoodle/safebin.git
synced 2026-04-28 03:07:41 +02:00
refactor: embed web files
Signed-off-by: skidoodle <contact@albert.lol>
This commit is contained in:
@@ -26,7 +26,6 @@ archives:
|
|||||||
{{- else }}{{ .Arch }}{{ end }}
|
{{- else }}{{ .Arch }}{{ end }}
|
||||||
formats: ["tar.gz"]
|
formats: ["tar.gz"]
|
||||||
files:
|
files:
|
||||||
- web/**/*
|
|
||||||
- README.md
|
- README.md
|
||||||
|
|
||||||
dockers:
|
dockers:
|
||||||
@@ -37,8 +36,6 @@ dockers:
|
|||||||
goos: linux
|
goos: linux
|
||||||
goarch: amd64
|
goarch: amd64
|
||||||
dockerfile: Dockerfile.release
|
dockerfile: Dockerfile.release
|
||||||
extra_files:
|
|
||||||
- web
|
|
||||||
build_flag_templates:
|
build_flag_templates:
|
||||||
- "--platform=linux/amd64"
|
- "--platform=linux/amd64"
|
||||||
- "--label=org.opencontainers.image.title={{ .ProjectName }}"
|
- "--label=org.opencontainers.image.title={{ .ProjectName }}"
|
||||||
@@ -51,8 +48,6 @@ dockers:
|
|||||||
goos: linux
|
goos: linux
|
||||||
goarch: arm64
|
goarch: arm64
|
||||||
dockerfile: Dockerfile.release
|
dockerfile: Dockerfile.release
|
||||||
extra_files:
|
|
||||||
- web
|
|
||||||
build_flag_templates:
|
build_flag_templates:
|
||||||
- "--platform=linux/arm64"
|
- "--platform=linux/arm64"
|
||||||
- "--label=org.opencontainers.image.title={{ .ProjectName }}"
|
- "--label=org.opencontainers.image.title={{ .ProjectName }}"
|
||||||
|
|||||||
@@ -31,7 +31,6 @@ RUN useradd -m -u 10001 -s /bin/bash appuser
|
|||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
|
|
||||||
COPY --from=builder /app/safebin .
|
COPY --from=builder /app/safebin .
|
||||||
COPY --from=builder /app/web ./web
|
|
||||||
|
|
||||||
RUN mkdir -p /app/storage && chown 10001:10001 /app/storage
|
RUN mkdir -p /app/storage && chown 10001:10001 /app/storage
|
||||||
VOLUME ["/app/storage"]
|
VOLUME ["/app/storage"]
|
||||||
|
|||||||
@@ -9,7 +9,6 @@ RUN useradd -m -u 10001 -s /bin/bash appuser
|
|||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
|
|
||||||
COPY safebin .
|
COPY safebin .
|
||||||
COPY web ./web
|
|
||||||
|
|
||||||
RUN mkdir -p /app/storage && chown 10001:10001 /app/storage
|
RUN mkdir -p /app/storage && chown 10001:10001 /app/storage
|
||||||
VOLUME ["/app/storage"]
|
VOLUME ["/app/storage"]
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import (
|
|||||||
"flag"
|
"flag"
|
||||||
"fmt"
|
"fmt"
|
||||||
"html/template"
|
"html/template"
|
||||||
|
"io/fs"
|
||||||
"log/slog"
|
"log/slog"
|
||||||
"os"
|
"os"
|
||||||
"strconv"
|
"strconv"
|
||||||
@@ -50,6 +51,7 @@ type App struct {
|
|||||||
Tmpl *template.Template
|
Tmpl *template.Template
|
||||||
Logger *slog.Logger
|
Logger *slog.Logger
|
||||||
DB *bbolt.DB
|
DB *bbolt.DB
|
||||||
|
Assets fs.FS
|
||||||
}
|
}
|
||||||
|
|
||||||
func LoadConfig() Config {
|
func LoadConfig() Config {
|
||||||
@@ -93,6 +95,6 @@ func getEnvInt(key string, fallback int) int {
|
|||||||
return fallback
|
return fallback
|
||||||
}
|
}
|
||||||
|
|
||||||
func ParseTemplates() *template.Template {
|
func ParseTemplates(fsys fs.FS) *template.Template {
|
||||||
return template.Must(template.ParseGlob("./web/templates/*.html"))
|
return template.Must(template.ParseFS(fsys, "*.html"))
|
||||||
}
|
}
|
||||||
|
|||||||
+19
-3
@@ -5,13 +5,29 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (app *App) Routes() *http.ServeMux {
|
func (app *App) Routes() *http.ServeMux {
|
||||||
mux := http.NewServeMux()
|
mux := http.NewServeMux()
|
||||||
fileServer := http.FileServer(http.Dir("./web/static"))
|
|
||||||
|
|
||||||
mux.Handle("GET /static/", http.StripPrefix("/static/", fileServer))
|
fileServer := http.FileServer(http.FS(app.Assets))
|
||||||
|
|
||||||
|
staticHandler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
if r.URL.Path == "" || strings.HasSuffix(r.URL.Path, "/") {
|
||||||
|
http.NotFound(w, r)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if strings.HasSuffix(r.URL.Path, ".html") {
|
||||||
|
http.NotFound(w, r)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
fileServer.ServeHTTP(w, r)
|
||||||
|
})
|
||||||
|
|
||||||
|
mux.Handle("GET /static/", http.StripPrefix("/static/", staticHandler))
|
||||||
mux.HandleFunc("GET /{$}", app.HandleHome)
|
mux.HandleFunc("GET /{$}", app.HandleHome)
|
||||||
mux.HandleFunc("POST /{$}", app.HandleUpload)
|
mux.HandleFunc("POST /{$}", app.HandleUpload)
|
||||||
mux.HandleFunc("POST /upload/chunk", app.HandleChunk)
|
mux.HandleFunc("POST /upload/chunk", app.HandleChunk)
|
||||||
@@ -22,7 +38,7 @@ func (app *App) Routes() *http.ServeMux {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (app *App) HandleHome(writer http.ResponseWriter, request *http.Request) {
|
func (app *App) HandleHome(writer http.ResponseWriter, request *http.Request) {
|
||||||
err := app.Tmpl.ExecuteTemplate(writer, "base", map[string]any{
|
err := app.Tmpl.ExecuteTemplate(writer, "layout", map[string]any{
|
||||||
"MaxMB": app.Conf.MaxMB,
|
"MaxMB": app.Conf.MaxMB,
|
||||||
"Host": request.Host,
|
"Host": request.Host,
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ package app
|
|||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"fmt"
|
"fmt"
|
||||||
"html/template"
|
|
||||||
"io"
|
"io"
|
||||||
"log/slog"
|
"log/slog"
|
||||||
"mime/multipart"
|
"mime/multipart"
|
||||||
@@ -19,12 +18,14 @@ func setupTestApp(t *testing.T) (*App, string) {
|
|||||||
storageDir := t.TempDir()
|
storageDir := t.TempDir()
|
||||||
os.MkdirAll(filepath.Join(storageDir, TempDirName), 0700)
|
os.MkdirAll(filepath.Join(storageDir, TempDirName), 0700)
|
||||||
|
|
||||||
tmplDir := filepath.Join(storageDir, "templates")
|
webDir := filepath.Join(storageDir, "web")
|
||||||
os.MkdirAll(tmplDir, 0700)
|
os.MkdirAll(webDir, 0700)
|
||||||
os.WriteFile(filepath.Join(tmplDir, "base.html"), []byte(`{{define "base"}}{{template "content" .}}{{end}}`), 0600)
|
|
||||||
os.WriteFile(filepath.Join(tmplDir, "index.html"), []byte(`{{define "content"}}OK{{end}}`), 0600)
|
|
||||||
|
|
||||||
tmpl := template.Must(template.New("base").Parse(`{{define "base"}}OK{{end}}`))
|
os.WriteFile(filepath.Join(webDir, "layout.html"), []byte(`{{define "layout"}}{{template "content" .}}{{end}}`), 0600)
|
||||||
|
os.WriteFile(filepath.Join(webDir, "home.html"), []byte(`{{define "content"}}OK{{end}}`), 0600)
|
||||||
|
|
||||||
|
testFS := os.DirFS(webDir)
|
||||||
|
tmpl := ParseTemplates(testFS)
|
||||||
|
|
||||||
db, err := InitDB(storageDir)
|
db, err := InitDB(storageDir)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -39,6 +40,7 @@ func setupTestApp(t *testing.T) (*App, string) {
|
|||||||
},
|
},
|
||||||
Logger: discardLogger(),
|
Logger: discardLogger(),
|
||||||
Tmpl: tmpl,
|
Tmpl: tmpl,
|
||||||
|
Assets: testFS,
|
||||||
DB: db,
|
DB: db,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ import (
|
|||||||
"syscall"
|
"syscall"
|
||||||
|
|
||||||
"github.com/skidoodle/safebin/internal/app"
|
"github.com/skidoodle/safebin/internal/app"
|
||||||
|
"github.com/skidoodle/safebin/web"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
@@ -46,7 +47,8 @@ func main() {
|
|||||||
application := &app.App{
|
application := &app.App{
|
||||||
Conf: cfg,
|
Conf: cfg,
|
||||||
Logger: logger,
|
Logger: logger,
|
||||||
Tmpl: app.ParseTemplates(),
|
Tmpl: app.ParseTemplates(web.Assets),
|
||||||
|
Assets: web.Assets,
|
||||||
DB: db,
|
DB: db,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,6 @@
|
|||||||
|
package web
|
||||||
|
|
||||||
|
import "embed"
|
||||||
|
|
||||||
|
//go:embed *.html *.css *.js *.ico
|
||||||
|
var Assets embed.FS
|
||||||
Binary file not shown.
|
After Width: | Height: | Size: 1.1 KiB |
@@ -1,12 +1,12 @@
|
|||||||
{{define "base"}}
|
{{define "layout"}}
|
||||||
<!doctype html>
|
<!doctype html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8" />
|
<meta charset="UTF-8" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
<link rel="icon" href="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" />
|
<link rel="icon" type="image/vnd.microsoft.icon" href="/static/favicon.ico" />
|
||||||
<title>safebin</title>
|
<title>safebin</title>
|
||||||
<link rel="stylesheet" href="/static/css/style.css" />
|
<link rel="stylesheet" href="/static/style.css" />
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div class="container">
|
<div class="container">
|
||||||
@@ -31,7 +31,7 @@
|
|||||||
</section>
|
</section>
|
||||||
</div>
|
</div>
|
||||||
<input type="file" id="file-input" class="hidden" />
|
<input type="file" id="file-input" class="hidden" />
|
||||||
<script src="/static/js/app.js"></script>
|
<script src="/static/app.js"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
{{end}}
|
{{end}}
|
||||||
Reference in New Issue
Block a user