Add multi-disk copy workflow
This commit is contained in:
@@ -9,8 +9,9 @@ import (
|
||||
)
|
||||
|
||||
func (s *Server) handleCopyStart(w http.ResponseWriter, r *http.Request) {
|
||||
diskInfo := s.deps.Watcher.CurrentDisk()
|
||||
if diskInfo.State != disk.DiskKnown {
|
||||
diskID := r.PathValue("diskID")
|
||||
diskInfo, ok := s.deps.Watcher.DiskByID(diskID)
|
||||
if !ok || diskInfo.State != disk.DiskKnown {
|
||||
jsonErr(w, http.StatusUnprocessableEntity, "no known disk connected")
|
||||
return
|
||||
}
|
||||
@@ -54,7 +55,8 @@ func (s *Server) handleCopyStart(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
func (s *Server) handleCopyCancel(w http.ResponseWriter, r *http.Request) {
|
||||
s.deps.Copier.Cancel()
|
||||
diskID := r.PathValue("diskID")
|
||||
s.deps.Copier.Cancel(diskID)
|
||||
jsonOK(w, map[string]bool{"ok": true})
|
||||
}
|
||||
|
||||
|
||||
@@ -1,14 +1,13 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
|
||||
"jukebox_maker/internal/disk"
|
||||
)
|
||||
|
||||
func (s *Server) handleDiskStatus(w http.ResponseWriter, r *http.Request) {
|
||||
info := s.deps.Watcher.CurrentDisk()
|
||||
|
||||
type response struct {
|
||||
State disk.DiskState `json:"state"`
|
||||
DiskID string `json:"disk_id"`
|
||||
@@ -18,17 +17,57 @@ func (s *Server) handleDiskStatus(w http.ResponseWriter, r *http.Request) {
|
||||
ActiveTaskID string `json:"active_task_id,omitempty"`
|
||||
}
|
||||
|
||||
resp := response{
|
||||
State: info.State,
|
||||
DiskID: info.DiskID,
|
||||
TotalBytes: info.TotalBytes,
|
||||
FreeBytes: info.FreeBytes,
|
||||
MountPath: info.MountPath,
|
||||
disks := s.deps.Watcher.ListDisks()
|
||||
resp := make([]response, 0, len(disks))
|
||||
for _, info := range disks {
|
||||
item := response{
|
||||
State: info.State,
|
||||
DiskID: info.DiskID,
|
||||
TotalBytes: info.TotalBytes,
|
||||
FreeBytes: info.FreeBytes,
|
||||
MountPath: info.MountPath,
|
||||
}
|
||||
if info.DiskID != "" {
|
||||
if t, ok := s.deps.Tasks.ActiveTaskByDisk(info.DiskID); ok {
|
||||
item.ActiveTaskID = t.ID
|
||||
}
|
||||
}
|
||||
resp = append(resp, item)
|
||||
}
|
||||
|
||||
if t, ok := s.deps.Tasks.ActiveTask(); ok {
|
||||
resp.ActiveTaskID = t.ID
|
||||
}
|
||||
|
||||
jsonOK(w, resp)
|
||||
jsonOK(w, map[string]any{"items": resp})
|
||||
}
|
||||
|
||||
func (s *Server) handleDiskInit(w http.ResponseWriter, r *http.Request) {
|
||||
var req struct {
|
||||
MountPath string `json:"mount_path"`
|
||||
}
|
||||
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
|
||||
jsonErr(w, http.StatusBadRequest, "invalid JSON: "+err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
info, ok := s.deps.Watcher.DiskByMountPath(req.MountPath)
|
||||
if !ok {
|
||||
jsonErr(w, http.StatusNotFound, "disk not found")
|
||||
return
|
||||
}
|
||||
if info.State == disk.DiskAbsent {
|
||||
jsonErr(w, http.StatusUnprocessableEntity, "no disk connected")
|
||||
return
|
||||
}
|
||||
if info.State == disk.DiskKnown {
|
||||
jsonErr(w, http.StatusConflict, "disk already initialized")
|
||||
return
|
||||
}
|
||||
|
||||
diskID, err := disk.InitDisk(info.MountPath)
|
||||
if err != nil {
|
||||
jsonErr(w, http.StatusInternalServerError, "init disk: "+err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
s.deps.OnDiskInit(info.MountPath, diskID)
|
||||
s.deps.Watcher.ProbeNow()
|
||||
jsonOK(w, map[string]string{"disk_id": diskID})
|
||||
}
|
||||
|
||||
@@ -21,6 +21,8 @@ type Deps struct {
|
||||
Tasks *task.Store
|
||||
MediaPath string
|
||||
MountPath string
|
||||
// OnDiskInit вызывается при ручной инициализации диска через UI.
|
||||
OnDiskInit func(mountPath, diskID string)
|
||||
}
|
||||
|
||||
type Server struct {
|
||||
@@ -56,12 +58,13 @@ func (s *Server) routes() {
|
||||
s.mux.HandleFunc("GET /settings", s.handleSettings)
|
||||
|
||||
s.mux.HandleFunc("GET /health", s.handleHealth)
|
||||
s.mux.HandleFunc("GET /api/disk", s.handleDiskStatus)
|
||||
s.mux.HandleFunc("GET /api/disks", s.handleDiskStatus)
|
||||
s.mux.HandleFunc("POST /api/disks/init", s.handleDiskInit)
|
||||
s.mux.HandleFunc("GET /api/sources", s.handleSources)
|
||||
s.mux.HandleFunc("GET /api/config", s.handleGetConfig)
|
||||
s.mux.HandleFunc("PUT /api/config", s.handlePutConfig)
|
||||
s.mux.HandleFunc("POST /api/copy/start", s.handleCopyStart)
|
||||
s.mux.HandleFunc("POST /api/copy/cancel", s.handleCopyCancel)
|
||||
s.mux.HandleFunc("POST /api/disks/{diskID}/copy/start", s.handleCopyStart)
|
||||
s.mux.HandleFunc("POST /api/disks/{diskID}/copy/cancel", s.handleCopyCancel)
|
||||
s.mux.HandleFunc("GET /api/tasks/{id}", s.handleTaskGet)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user