docs: expand configuration docs for admin and BadgerDB

Update README to explain startup config precedence (defaults/env/admin overrides),
document admin/bootstrap and feature toggles, and clarify storage locations under
WARPBOX_DATA_DIR including BadgerDB metadata. Also refresh project layout to
include new config and metastore packages.docs: expand configuration docs for admin and BadgerDB

Update README to explain startup config precedence (defaults/env/admin overrides),
document admin/bootstrap and feature toggles, and clarify storage locations under
WARPBOX_DATA_DIR including BadgerDB metadata. Also refresh project layout to
include new config and metastore packages.
This commit is contained in:
2026-04-28 21:11:37 +03:00
parent fc3de58b5b
commit a5d6d69be0
27 changed files with 3499 additions and 97 deletions

View File

@@ -1,42 +1,84 @@
package server
import (
"fmt"
"time"
"github.com/gin-contrib/gzip"
"github.com/gin-gonic/gin"
"warpbox/lib/boxstore"
"warpbox/lib/helpers"
"warpbox/lib/config"
"warpbox/lib/metastore"
"warpbox/lib/routing"
)
type App struct {
config *config.Config
store *metastore.Store
adminLoginEnabled bool
}
func Run(addr string) error {
cfg, err := config.Load()
if err != nil {
return err
}
if err := cfg.EnsureDirectories(); err != nil {
return err
}
boxstore.SetUploadRoot(cfg.UploadsDir)
store, err := metastore.Open(cfg.DBDir)
if err != nil {
return fmt.Errorf("open metadata database: %w", err)
}
defer store.Close()
overrides, err := store.ListSettings()
if err != nil {
return fmt.Errorf("load settings overrides: %w", err)
}
if err := cfg.ApplyOverrides(overrides); err != nil {
return fmt.Errorf("apply settings overrides: %w", err)
}
bootstrap, err := metastore.BootstrapAdmin(cfg, store)
if err != nil {
return fmt.Errorf("bootstrap admin metadata: %w", err)
}
app := &App{
config: cfg,
store: store,
adminLoginEnabled: bootstrap.AdminLoginEnabled,
}
router := gin.Default()
router.LoadHTMLGlob("templates/*.html")
routing.Register(router, routing.Handlers{
Index: handleIndex,
ShowBox: handleShowBox,
Index: app.handleIndex,
ShowBox: app.handleShowBox,
BoxLogin: handleBoxLogin,
BoxLoginPost: handleBoxLoginPost,
BoxStatus: handleBoxStatus,
DownloadBox: handleDownloadBox,
DownloadFile: handleDownloadFile,
DownloadThumbnail: handleDownloadThumbnail,
CreateBox: handleCreateBox,
ManifestFileUpload: handleManifestFileUpload,
FileStatusUpdate: handleFileStatusUpdate,
DirectBoxUpload: handleDirectBoxUpload,
LegacyUpload: handleLegacyUpload,
BoxStatus: app.handleBoxStatus,
DownloadBox: app.handleDownloadBox,
DownloadFile: app.handleDownloadFile,
DownloadThumbnail: app.handleDownloadThumbnail,
CreateBox: app.handleCreateBox,
ManifestFileUpload: app.handleManifestFileUpload,
FileStatusUpdate: app.handleFileStatusUpdate,
DirectBoxUpload: app.handleDirectBoxUpload,
LegacyUpload: app.handleLegacyUpload,
})
app.registerAdminRoutes(router)
compressed := router.Group("/", gzip.Gzip(gzip.DefaultCompression))
compressed.Static("/static", "./static")
batchSize := helpers.EnvInt("WARPBOX_THUMBNAIL_BATCH_SIZE", 10, 1)
intervalSeconds := helpers.EnvInt("WARPBOX_THUMBNAIL_INTERVAL_SECONDS", 30, 1)
boxstore.StartThumbnailWorker(batchSize, time.Duration(intervalSeconds)*time.Second)
boxstore.StartThumbnailWorker(cfg.ThumbnailBatchSize, time.Duration(cfg.ThumbnailIntervalSeconds)*time.Second)
return router.Run(addr)
}