67 lines
1.9 KiB
Go
67 lines
1.9 KiB
Go
package sorter
|
|
|
|
import (
|
|
"fmt"
|
|
"os"
|
|
"path/filepath"
|
|
"regexp"
|
|
|
|
"github.com/veggiedefender/torrent-client/internal/logger"
|
|
)
|
|
|
|
var (
|
|
tvShowRegex = regexp.MustCompile(`(?i)(s\d{2}e\d{2}|season\s*\d+|сезон\s*\d+)`)
|
|
movieRegex = regexp.MustCompile(`(?i)(1080p|720p|2160p|4k|bdrip|web-dl|bluray|camrip)`)
|
|
gameRegex = regexp.MustCompile(`(?i)(repack|fitgirl|dodi|skidrow|codex|crack|iso)`)
|
|
musicRegex = regexp.MustCompile(`(?i)(discography|flac|mp3\s*320)`)
|
|
)
|
|
|
|
// Categorize analyzes the torrent name and determines its category.
|
|
func Categorize(name string) string {
|
|
if tvShowRegex.MatchString(name) {
|
|
return "TV Shows"
|
|
}
|
|
if movieRegex.MatchString(name) {
|
|
return "Movies"
|
|
}
|
|
if gameRegex.MatchString(name) {
|
|
return "Games"
|
|
}
|
|
if musicRegex.MatchString(name) {
|
|
return "Music"
|
|
}
|
|
return "Other"
|
|
}
|
|
|
|
// SortAndMove moves the downloaded files (or folder) to a sub-folder based on its category.
|
|
func SortAndMove(outputRoot, torrentName string) (string, error) {
|
|
category := Categorize(torrentName)
|
|
if category == "Other" || category == "" {
|
|
return "", nil // Do not move if category is unknown
|
|
}
|
|
|
|
sourcePath := filepath.Join(outputRoot, torrentName)
|
|
if _, err := os.Stat(sourcePath); os.IsNotExist(err) {
|
|
return "", fmt.Errorf("source path does not exist: %s", sourcePath)
|
|
}
|
|
|
|
destDir := filepath.Join(outputRoot, category)
|
|
if err := os.MkdirAll(destDir, 0o755); err != nil {
|
|
return "", fmt.Errorf("failed to create category directory: %w", err)
|
|
}
|
|
|
|
destPath := filepath.Join(destDir, torrentName)
|
|
|
|
// If it already exists in the destination, maybe we resume/overwrite
|
|
if _, err := os.Stat(destPath); err == nil {
|
|
logger.Warn("SYS", "Destination path already exists, skipping move: %s", destPath)
|
|
return "", nil
|
|
}
|
|
|
|
if err := os.Rename(sourcePath, destPath); err != nil {
|
|
return "", fmt.Errorf("failed to move files to category folder: %w", err)
|
|
}
|
|
|
|
logger.Info("SYS", "Smart Sorter moved '%s' to '%s'", torrentName, category)
|
|
return destDir, nil
|
|
}
|