- Заменить ручное копирование на 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>
92 lines
1.9 KiB
Go
92 lines
1.9 KiB
Go
package config
|
|
|
|
import (
|
|
"encoding/json"
|
|
"errors"
|
|
"os"
|
|
"path/filepath"
|
|
)
|
|
|
|
type OverwriteMode string
|
|
type FileSelectMode string
|
|
|
|
const (
|
|
OverwriteSkip OverwriteMode = "skip"
|
|
OverwriteDelete OverwriteMode = "delete"
|
|
|
|
SelectNew FileSelectMode = "new"
|
|
SelectAll FileSelectMode = "all"
|
|
)
|
|
|
|
type SourceFolder struct {
|
|
Path string `json:"path"`
|
|
Enabled bool `json:"enabled"`
|
|
}
|
|
|
|
type Config struct {
|
|
ReserveFreeGB float64 `json:"reserve_free_gb"`
|
|
DestFolder string `json:"dest_folder"`
|
|
Sources []SourceFolder `json:"sources"`
|
|
OverwriteMode OverwriteMode `json:"overwrite_mode"`
|
|
FileSelectMode FileSelectMode `json:"file_select_mode"`
|
|
AutoCopy bool `json:"auto_copy"`
|
|
}
|
|
|
|
func defaults() Config {
|
|
return Config{
|
|
ReserveFreeGB: 2.0,
|
|
DestFolder: "media",
|
|
OverwriteMode: OverwriteSkip,
|
|
FileSelectMode: SelectNew,
|
|
AutoCopy: false,
|
|
}
|
|
}
|
|
|
|
func Load(path string) (*Config, error) {
|
|
data, err := os.ReadFile(path)
|
|
if errors.Is(err, os.ErrNotExist) {
|
|
cfg := defaults()
|
|
return &cfg, nil
|
|
}
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
cfg := defaults()
|
|
if err := json.Unmarshal(data, &cfg); err != nil {
|
|
return nil, err
|
|
}
|
|
return &cfg, nil
|
|
}
|
|
|
|
func Save(path string, cfg *Config) error {
|
|
if err := os.MkdirAll(filepath.Dir(path), 0o755); err != nil {
|
|
return err
|
|
}
|
|
data, err := json.MarshalIndent(cfg, "", " ")
|
|
if err != nil {
|
|
return err
|
|
}
|
|
tmp := path + ".tmp"
|
|
if err := os.WriteFile(tmp, data, 0o644); err != nil {
|
|
return err
|
|
}
|
|
return os.Rename(tmp, path)
|
|
}
|
|
|
|
func (c *Config) Validate() error {
|
|
if c.ReserveFreeGB < 0 {
|
|
return errors.New("reserve_free_gb must be >= 0")
|
|
}
|
|
switch c.OverwriteMode {
|
|
case OverwriteSkip, OverwriteDelete:
|
|
default:
|
|
return errors.New("overwrite_mode must be 'skip' or 'delete'")
|
|
}
|
|
switch c.FileSelectMode {
|
|
case SelectNew, SelectAll:
|
|
default:
|
|
return errors.New("file_select_mode must be 'new' or 'all'")
|
|
}
|
|
return nil
|
|
}
|