Refactor web build process and update documentation
- Removed Node.js build artifacts from .gitignore and adjusted Makefile to reflect changes in web UI build process, now using server-rendered Go templates instead of React. - Updated README to clarify the new web UI architecture and output formats, emphasizing the removal of the Node.js build step. - Added a command to set the number of frames per render task in manager configuration, enhancing user control over rendering settings. - Improved Gitea workflow by removing unnecessary npm install step, streamlining the CI process.
This commit is contained in:
@@ -59,6 +59,7 @@ type Manager struct {
|
||||
secrets *authpkg.Secrets
|
||||
storage *storage.Storage
|
||||
router *chi.Mux
|
||||
ui *uiRenderer
|
||||
|
||||
// WebSocket connections
|
||||
wsUpgrader websocket.Upgrader
|
||||
@@ -125,10 +126,24 @@ type ClientConnection struct {
|
||||
type UploadSession struct {
|
||||
SessionID string
|
||||
UserID int64
|
||||
TempDir string
|
||||
Progress float64
|
||||
Status string // "uploading", "processing", "extracting_metadata", "creating_context", "completed", "error"
|
||||
Phase string // "upload", "processing", "ready", "error", "action_required"
|
||||
Message string
|
||||
CreatedAt time.Time
|
||||
// Result fields set when Status is "completed" (for async processing)
|
||||
ResultContextArchive string
|
||||
ResultMetadata interface{} // *types.BlendMetadata when set
|
||||
ResultMainBlendFile string
|
||||
ResultFileName string
|
||||
ResultFileSize int64
|
||||
ResultZipExtracted bool
|
||||
ResultExtractedFilesCnt int
|
||||
ResultMetadataExtracted bool
|
||||
ResultMetadataError string // set when Status is "completed" but metadata extraction failed
|
||||
ErrorMessage string // set when Status is "error"
|
||||
ResultBlendFiles []string // set when Status is "select_blend" (relative paths for user to pick)
|
||||
}
|
||||
|
||||
// NewManager creates a new manager server
|
||||
@@ -137,6 +152,10 @@ func NewManager(db *database.DB, cfg *config.Config, auth *authpkg.Auth, storage
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to initialize secrets: %w", err)
|
||||
}
|
||||
ui, err := newUIRenderer()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to initialize UI renderer: %w", err)
|
||||
}
|
||||
|
||||
s := &Manager{
|
||||
db: db,
|
||||
@@ -145,6 +164,7 @@ func NewManager(db *database.DB, cfg *config.Config, auth *authpkg.Auth, storage
|
||||
secrets: secrets,
|
||||
storage: storage,
|
||||
router: chi.NewRouter(),
|
||||
ui: ui,
|
||||
startTime: time.Now(),
|
||||
wsUpgrader: websocket.Upgrader{
|
||||
CheckOrigin: checkWebSocketOrigin,
|
||||
@@ -450,6 +470,7 @@ func (w *gzipResponseWriter) WriteHeader(statusCode int) {
|
||||
func (s *Manager) setupRoutes() {
|
||||
// Health check endpoint (unauthenticated)
|
||||
s.router.Get("/api/health", s.handleHealthCheck)
|
||||
s.setupUIRoutes()
|
||||
|
||||
// Public routes (with stricter rate limiting for auth endpoints)
|
||||
s.router.Route("/api/auth", func(r chi.Router) {
|
||||
@@ -477,6 +498,7 @@ func (s *Manager) setupRoutes() {
|
||||
})
|
||||
r.Post("/", s.handleCreateJob)
|
||||
r.Post("/upload", s.handleUploadFileForJobCreation) // Upload before job creation
|
||||
r.Get("/upload/status", s.handleUploadStatus) // Poll upload processing status (session_id query param)
|
||||
r.Get("/", s.handleListJobs)
|
||||
r.Get("/summary", s.handleListJobsSummary)
|
||||
r.Post("/batch", s.handleBatchGetJobs)
|
||||
@@ -487,6 +509,7 @@ func (s *Manager) setupRoutes() {
|
||||
r.Get("/{id}/files", s.handleListJobFiles)
|
||||
r.Get("/{id}/files/count", s.handleGetJobFilesCount)
|
||||
r.Get("/{id}/context", s.handleListContextArchive)
|
||||
r.Get("/{id}/files/exr-zip", s.handleDownloadEXRZip)
|
||||
r.Get("/{id}/files/{fileId}/download", s.handleDownloadJobFile)
|
||||
r.Get("/{id}/files/{fileId}/preview-exr", s.handlePreviewEXR)
|
||||
r.Get("/{id}/video", s.handleStreamVideo)
|
||||
@@ -522,7 +545,6 @@ func (s *Manager) setupRoutes() {
|
||||
r.Delete("/{id}", s.handleDeleteRunnerAPIKey)
|
||||
})
|
||||
r.Get("/", s.handleListRunnersAdmin)
|
||||
r.Post("/{id}/verify", s.handleVerifyRunner)
|
||||
r.Delete("/{id}", s.handleDeleteRunner)
|
||||
})
|
||||
r.Route("/users", func(r chi.Router) {
|
||||
@@ -555,6 +577,7 @@ func (s *Manager) setupRoutes() {
|
||||
return http.HandlerFunc(s.runnerAuthMiddleware(next.ServeHTTP))
|
||||
})
|
||||
r.Get("/blender/download", s.handleDownloadBlender)
|
||||
r.Get("/jobs/{jobId}/status", s.handleGetJobStatusForRunner)
|
||||
r.Get("/jobs/{jobId}/files", s.handleGetJobFilesForRunner)
|
||||
r.Get("/jobs/{jobId}/metadata", s.handleGetJobMetadataForRunner)
|
||||
r.Get("/files/{jobId}/{fileName}", s.handleDownloadFileForRunner)
|
||||
@@ -564,8 +587,8 @@ func (s *Manager) setupRoutes() {
|
||||
// Blender versions API (public, for job submission page)
|
||||
s.router.Get("/api/blender/versions", s.handleGetBlenderVersions)
|
||||
|
||||
// Serve static files (embedded React app with SPA fallback)
|
||||
s.router.Handle("/*", web.SPAHandler())
|
||||
// Static assets for server-rendered UI.
|
||||
s.router.Handle("/assets/*", web.StaticHandler())
|
||||
}
|
||||
|
||||
// ServeHTTP implements http.Handler
|
||||
|
||||
Reference in New Issue
Block a user