ffd4daf031
Co-authored-by: afkarxyz <mzamzamafkarhadiq@gmail.com>
110 lines
3.4 KiB
Go
110 lines
3.4 KiB
Go
package backend
|
|
|
|
import (
|
|
"fmt"
|
|
"path/filepath"
|
|
"regexp"
|
|
"strings"
|
|
)
|
|
|
|
// BuildExpectedFilename builds the expected filename based on track metadata and settings
|
|
func BuildExpectedFilename(trackName, artistName, filenameFormat string, includeTrackNumber bool, position int, useAlbumTrackNumber bool) string {
|
|
// Sanitize track name and artist name
|
|
safeTitle := sanitizeFilename(trackName)
|
|
safeArtist := sanitizeFilename(artistName)
|
|
|
|
var filename string
|
|
|
|
// Check if format is a template (contains {})
|
|
if strings.Contains(filenameFormat, "{") {
|
|
filename = filenameFormat
|
|
filename = strings.ReplaceAll(filename, "{title}", safeTitle)
|
|
filename = strings.ReplaceAll(filename, "{artist}", safeArtist)
|
|
|
|
// Handle track number - if position is 0, remove {track} and surrounding separators
|
|
if position > 0 {
|
|
filename = strings.ReplaceAll(filename, "{track}", fmt.Sprintf("%02d", position))
|
|
} else {
|
|
// Remove {track} with common separators like ". " or " - " or ". "
|
|
filename = regexp.MustCompile(`\{track\}\.\s*`).ReplaceAllString(filename, "")
|
|
filename = regexp.MustCompile(`\{track\}\s*-\s*`).ReplaceAllString(filename, "")
|
|
filename = regexp.MustCompile(`\{track\}\s*`).ReplaceAllString(filename, "")
|
|
}
|
|
} else {
|
|
// Legacy format support
|
|
switch filenameFormat {
|
|
case "artist-title":
|
|
filename = fmt.Sprintf("%s - %s", safeArtist, safeTitle)
|
|
case "title":
|
|
filename = safeTitle
|
|
default: // "title-artist"
|
|
filename = fmt.Sprintf("%s - %s", safeTitle, safeArtist)
|
|
}
|
|
|
|
// Add track number prefix if enabled (legacy behavior)
|
|
if includeTrackNumber && position > 0 {
|
|
filename = fmt.Sprintf("%02d. %s", position, filename)
|
|
}
|
|
}
|
|
|
|
return filename + ".flac"
|
|
}
|
|
|
|
// sanitizeFilename removes invalid characters from filename
|
|
func sanitizeFilename(name string) string {
|
|
re := regexp.MustCompile(`[<>:"/\\|?*]`)
|
|
sanitized := re.ReplaceAllString(name, "_")
|
|
sanitized = strings.TrimSpace(sanitized)
|
|
if sanitized == "" {
|
|
return "Unknown"
|
|
}
|
|
return sanitized
|
|
}
|
|
|
|
// SanitizeFolderPath sanitizes each component of a folder path and normalizes separators
|
|
func SanitizeFolderPath(folderPath string) string {
|
|
// Normalize all forward slashes to backslashes on Windows
|
|
normalizedPath := strings.ReplaceAll(folderPath, "/", string(filepath.Separator))
|
|
|
|
// Detect separator
|
|
sep := string(filepath.Separator)
|
|
|
|
// Split path into components
|
|
parts := strings.Split(normalizedPath, sep)
|
|
sanitizedParts := make([]string, 0, len(parts))
|
|
|
|
for i, part := range parts {
|
|
// Keep drive letter intact on Windows (e.g., "C:")
|
|
if i == 0 && len(part) == 2 && part[1] == ':' {
|
|
sanitizedParts = append(sanitizedParts, part)
|
|
continue
|
|
}
|
|
|
|
// Keep empty first part for absolute paths on Unix (e.g., "/Users/...")
|
|
if i == 0 && part == "" {
|
|
sanitizedParts = append(sanitizedParts, part)
|
|
continue
|
|
}
|
|
|
|
// Sanitize each folder name (but don't replace / or \ since we already normalized)
|
|
sanitized := sanitizeFolderName(part)
|
|
if sanitized != "" {
|
|
sanitizedParts = append(sanitizedParts, sanitized)
|
|
}
|
|
}
|
|
|
|
return strings.Join(sanitizedParts, sep)
|
|
}
|
|
|
|
// sanitizeFolderName removes invalid characters from a single folder name
|
|
func sanitizeFolderName(name string) string {
|
|
// Remove or replace invalid characters for folder names (excluding path separators)
|
|
re := regexp.MustCompile(`[<>:"|?*]`)
|
|
sanitized := re.ReplaceAllString(name, "_")
|
|
sanitized = strings.TrimSpace(sanitized)
|
|
if sanitized == "" {
|
|
return "Unknown"
|
|
}
|
|
return sanitized
|
|
}
|