Add jukebox_maker web app v1.0
Go web application for filling USB drives with media files. Runs in Docker on Unraid with /media, /mnt/usb, /config volumes. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
88
internal/task/task.go
Normal file
88
internal/task/task.go
Normal file
@@ -0,0 +1,88 @@
|
||||
package task
|
||||
|
||||
import (
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/google/uuid"
|
||||
)
|
||||
|
||||
type Status string
|
||||
|
||||
const (
|
||||
StatusQueued Status = "queued"
|
||||
StatusRunning Status = "running"
|
||||
StatusSuccess Status = "success"
|
||||
StatusFailed Status = "failed"
|
||||
StatusCanceled Status = "canceled"
|
||||
)
|
||||
|
||||
type Task struct {
|
||||
ID string `json:"id"`
|
||||
Type string `json:"type"`
|
||||
Status Status `json:"status"`
|
||||
Progress int `json:"progress"`
|
||||
Message string `json:"message"`
|
||||
Error string `json:"error"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
}
|
||||
|
||||
func (t *Task) IsTerminal() bool {
|
||||
return t.Status == StatusSuccess || t.Status == StatusFailed || t.Status == StatusCanceled
|
||||
}
|
||||
|
||||
type Store struct {
|
||||
mu sync.RWMutex
|
||||
tasks map[string]*Task
|
||||
}
|
||||
|
||||
func NewStore() *Store {
|
||||
return &Store{tasks: make(map[string]*Task)}
|
||||
}
|
||||
|
||||
func (s *Store) Create(taskType string) *Task {
|
||||
t := &Task{
|
||||
ID: uuid.New().String(),
|
||||
Type: taskType,
|
||||
Status: StatusQueued,
|
||||
CreatedAt: time.Now().UTC(),
|
||||
UpdatedAt: time.Now().UTC(),
|
||||
}
|
||||
s.mu.Lock()
|
||||
s.tasks[t.ID] = t
|
||||
s.mu.Unlock()
|
||||
return t
|
||||
}
|
||||
|
||||
func (s *Store) Get(id string) (*Task, bool) {
|
||||
s.mu.RLock()
|
||||
defer s.mu.RUnlock()
|
||||
t, ok := s.tasks[id]
|
||||
if !ok {
|
||||
return nil, false
|
||||
}
|
||||
copy := *t
|
||||
return ©, true
|
||||
}
|
||||
|
||||
func (s *Store) Update(id string, fn func(*Task)) {
|
||||
s.mu.Lock()
|
||||
defer s.mu.Unlock()
|
||||
if t, ok := s.tasks[id]; ok {
|
||||
fn(t)
|
||||
t.UpdatedAt = time.Now().UTC()
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Store) ActiveTask() (*Task, bool) {
|
||||
s.mu.RLock()
|
||||
defer s.mu.RUnlock()
|
||||
for _, t := range s.tasks {
|
||||
if t.Status == StatusQueued || t.Status == StatusRunning {
|
||||
copy := *t
|
||||
return ©, true
|
||||
}
|
||||
}
|
||||
return nil, false
|
||||
}
|
||||
Reference in New Issue
Block a user