116 lines
3.1 KiB
Go
116 lines
3.1 KiB
Go
package api
|
|
|
|
import (
|
|
"encoding/json"
|
|
"net/http"
|
|
"time"
|
|
|
|
"jukebox_maker/internal/disk"
|
|
)
|
|
|
|
func (s *Server) diskResponse(info disk.DiskInfo) map[string]any {
|
|
item := map[string]any{
|
|
"state": info.State,
|
|
"disk_id": info.DiskID,
|
|
"total_bytes": info.TotalBytes,
|
|
"free_bytes": info.FreeBytes,
|
|
"mount_path": info.MountPath,
|
|
}
|
|
if info.DiskID != "" {
|
|
if s.deps.OnDiskInit != nil {
|
|
s.deps.OnDiskInit(info.MountPath, info.DiskID)
|
|
}
|
|
if lastCopiedAt, ok, err := s.deps.Copier.LastCopiedAt(info.DiskID); err == nil && ok {
|
|
item["last_copied_at"] = lastCopiedAt.Format(time.RFC3339)
|
|
}
|
|
if t, ok := s.deps.Tasks.ActiveTaskByDisk(info.DiskID); ok {
|
|
item["active_task_id"] = t.ID
|
|
}
|
|
}
|
|
return item
|
|
}
|
|
|
|
func (s *Server) handleDiskStatus(w http.ResponseWriter, r *http.Request) {
|
|
type response struct {
|
|
State disk.DiskState `json:"state"`
|
|
DiskID string `json:"disk_id"`
|
|
TotalBytes int64 `json:"total_bytes"`
|
|
FreeBytes int64 `json:"free_bytes"`
|
|
MountPath string `json:"mount_path"`
|
|
LastCopiedAt string `json:"last_copied_at,omitempty"`
|
|
ActiveTaskID string `json:"active_task_id,omitempty"`
|
|
}
|
|
|
|
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 payload := s.diskResponse(info); payload != nil {
|
|
if v, ok := payload["last_copied_at"].(string); ok {
|
|
item.LastCopiedAt = v
|
|
}
|
|
if v, ok := payload["active_task_id"].(string); ok {
|
|
item.ActiveTaskID = v
|
|
}
|
|
}
|
|
resp = append(resp, item)
|
|
}
|
|
|
|
jsonOK(w, map[string]any{"items": resp})
|
|
}
|
|
|
|
func (s *Server) handleDiskProbe(w http.ResponseWriter, r *http.Request) {
|
|
mountPath := r.URL.Query().Get("mount_path")
|
|
info, err := s.deps.ProbeDisk(mountPath)
|
|
if err != nil {
|
|
jsonErr(w, http.StatusBadRequest, err.Error())
|
|
return
|
|
}
|
|
jsonOK(w, s.diskResponse(info))
|
|
}
|
|
|
|
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, err := s.deps.ProbeDisk(req.MountPath)
|
|
if err != nil {
|
|
jsonErr(w, http.StatusBadRequest, err.Error())
|
|
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
|
|
}
|
|
if err := disk.CheckWritable(info.MountPath); err != nil {
|
|
jsonErr(w, http.StatusUnprocessableEntity, "disk is not writable: "+err.Error())
|
|
return
|
|
}
|
|
|
|
diskID, err := disk.InitDisk(info.MountPath)
|
|
if err != nil {
|
|
jsonErr(w, http.StatusInternalServerError, "init disk: "+err.Error())
|
|
return
|
|
}
|
|
|
|
if s.deps.OnDiskInit != nil {
|
|
s.deps.OnDiskInit(info.MountPath, diskID)
|
|
}
|
|
jsonOK(w, map[string]string{"disk_id": diskID})
|
|
}
|