Add standalone desktop workflow

This commit is contained in:
2026-04-24 11:54:33 +03:00
parent 75c6b928ae
commit 50246ada85
20 changed files with 1068 additions and 306 deletions

View File

@@ -26,15 +26,17 @@ const (
type SourceFolder struct {
Path string `json:"path"`
Enabled bool `json:"enabled"`
Root bool `json:"root,omitempty"`
}
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"`
MediaPath string `json:"media_path"`
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"`
FileReplicaCounts map[string]int `json:"file_replica_counts,omitempty"`
DiskReplicaFiles map[string][]string `json:"disk_replica_files,omitempty"`
}
@@ -67,6 +69,8 @@ func Load(path string) (*Config, error) {
} else {
cfg.DestFolder = defaults().DestFolder
}
cfg.MediaPath = NormalizeMediaPath(cfg.MediaPath)
cfg.Sources = NormalizeSources(cfg.Sources, cfg.MediaPath)
return &cfg, nil
}
@@ -86,6 +90,26 @@ func Save(path string, cfg *Config) error {
}
func (c *Config) Validate() error {
c.MediaPath = NormalizeMediaPath(c.MediaPath)
if c.MediaPath != "" {
info, err := os.Stat(c.MediaPath)
if err != nil {
return errors.New("media_path is not accessible")
}
if !info.IsDir() {
return errors.New("media_path must be a directory")
}
}
c.Sources = NormalizeSources(c.Sources, c.MediaPath)
for _, source := range c.Sources {
info, err := os.Stat(source.Path)
if err != nil {
return errors.New("source path is not accessible: " + source.Path)
}
if !info.IsDir() {
return errors.New("source path must be a directory: " + source.Path)
}
}
if c.ReserveFreeGB < 0 {
return errors.New("reserve_free_gb must be >= 0")
}
@@ -105,6 +129,46 @@ func (c *Config) Validate() error {
return nil
}
func NormalizeMediaPath(value string) string {
value = strings.TrimSpace(value)
if value == "" {
return ""
}
return filepath.Clean(value)
}
func NormalizeSources(items []SourceFolder, mediaPath string) []SourceFolder {
seen := make(map[string]struct{}, len(items))
result := make([]SourceFolder, 0, len(items))
for _, item := range items {
path := normalizeSourcePath(item.Path, mediaPath)
if path == "" {
continue
}
if _, ok := seen[path]; ok {
continue
}
seen[path] = struct{}{}
result = append(result, SourceFolder{
Path: path,
Enabled: item.Enabled,
Root: item.Root,
})
}
return result
}
func normalizeSourcePath(value string, mediaPath string) string {
value = strings.TrimSpace(value)
if value == "" {
return ""
}
if !filepath.IsAbs(value) && mediaPath != "" {
value = filepath.Join(mediaPath, value)
}
return filepath.Clean(value)
}
func NormalizeDestFolder(value string) (string, error) {
value = strings.TrimSpace(value)
if value == "" {