Files
jukebox_maker/internal/api/handlers_copy.go
Michael Chus 8f36d4e824 copier: rsync с возобновлением, папка назначения, права 777
- Заменить ручное копирование на rsync --partial --append-verify
- Структура на диске: <mount>/<dest_folder>/<rel path from /media>
- dest_folder настраивается (default: media)
- Права на диске: --no-perms --chmod=ugo=rwx
- rsync добавлен в Dockerfile
- Режим "удалить": удаляет только dest_folder, а не весь диск

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-23 21:56:26 +03:00

70 lines
1.6 KiB
Go

package api
import (
"context"
"net/http"
"jukebox_maker/internal/copier"
"jukebox_maker/internal/disk"
)
func (s *Server) handleCopyStart(w http.ResponseWriter, r *http.Request) {
diskInfo := s.deps.Watcher.CurrentDisk()
if diskInfo.State != disk.DiskKnown {
jsonErr(w, http.StatusUnprocessableEntity, "no known disk connected")
return
}
cfg := s.deps.Config
var enabledSources []string
for _, src := range cfg.Sources {
if src.Enabled {
enabledSources = append(enabledSources, src.Path)
}
}
if len(enabledSources) == 0 {
jsonErr(w, http.StatusUnprocessableEntity, "no sources enabled")
return
}
opts := copier.Options{
DiskID: diskInfo.DiskID,
MountPath: diskInfo.MountPath,
MediaPath: s.deps.MediaPath,
DestFolder: cfg.DestFolder,
EnabledSources: enabledSources,
ReserveFreeGB: cfg.ReserveFreeGB,
OverwriteMode: cfg.OverwriteMode,
FileSelectMode: cfg.FileSelectMode,
}
taskID, err := s.deps.Copier.Start(context.Background(), opts)
if err != nil {
switch err.Error() {
case "copy already running":
jsonErr(w, http.StatusConflict, err.Error())
default:
jsonErr(w, http.StatusUnprocessableEntity, err.Error())
}
return
}
w.WriteHeader(http.StatusAccepted)
jsonOK(w, map[string]string{"task_id": taskID})
}
func (s *Server) handleCopyCancel(w http.ResponseWriter, r *http.Request) {
s.deps.Copier.Cancel()
jsonOK(w, map[string]bool{"ok": true})
}
func (s *Server) handleTaskGet(w http.ResponseWriter, r *http.Request) {
id := r.PathValue("id")
t, ok := s.deps.Tasks.Get(id)
if !ok {
jsonErr(w, http.StatusNotFound, "task not found")
return
}
jsonOK(w, t)
}