dl-rename/media.go
2025-04-25 11:55:28 +02:00

163 lines
3.7 KiB
Go

package main
import (
"fmt"
"path/filepath"
"regexp"
"strconv"
"strings"
)
type mediaElement struct {
Directory string
Name string
Year int
Episode string
Title string
Tags []string
Extension string
}
func newMediaElement(p string) *mediaElement {
episodeMatch := regexp.MustCompile(`[.\- ]?(S\d\dE\d\d)[.\- ]?`)
yearMatch := regexp.MustCompile(`[.\- ]?(\d{4})[.\- ]?`)
name := filepath.Base(p)
ext := filepath.Ext(name)
name = strings.TrimSuffix(name, ext)
parentDir := filepath.Dir(p)
// use parent directory if it starts similarly and is longer
dir := filepath.Base(parentDir)
if len(dir) >= len(name) && dir[0:3] == name[0:3] {
parentDir = filepath.Dir(parentDir)
name = dir
fmt.Println(dir)
}
name = strings.ReplaceAll(name, ".", " ")
name = strings.ReplaceAll(name, "-", " ")
name = strings.ReplaceAll(name, "_", " ")
element := &mediaElement{
Directory: parentDir,
Extension: ext,
}
title := ""
// get first group of regex match from episodeMatch
match := episodeMatch.FindStringSubmatch(name)
if len(match) > 0 {
element.Episode = match[1]
indexOfEpisode := strings.Index(name, match[0])
name = strings.Replace(name, match[0], "", -1)
title = name[indexOfEpisode:]
name = name[:indexOfEpisode]
}
match = yearMatch.FindStringSubmatch(name)
if len(match) > 0 {
year, err := strconv.Atoi(match[1])
if err == nil {
element.Year = year
}
indexOfYear := strings.Index(name, match[0])
name = strings.Replace(name, match[0], "", -1)
title = name[indexOfYear:]
name = name[:indexOfYear]
}
element.Name = strings.TrimSpace(name)
words := strings.Split(title, " ")
titleWords := []string{}
for i := len(words) - 1; i >= 0; i-- {
word := words[i]
upperWord := strings.ToUpper(word)
switch upperWord {
case "SYNCED":
fallthrough
case "BD":
fallthrough
case "DL":
fallthrough
case "TVS":
continue
case "EN":
fallthrough
case "DE":
fallthrough
case "FORCED":
fallthrough
case "3D":
fallthrough
case "UNCUT":
element.Tags = append(element.Tags, upperWord)
case "GERMAN":
element.Tags = append(element.Tags, "DE")
case "1080P":
element.Tags = append(element.Tags, "1080p")
case "X264":
element.Tags = append(element.Tags, "x264")
case "H264":
element.Tags = append(element.Tags, "x264")
case "X265":
element.Tags = append(element.Tags, "x265")
case "H265":
element.Tags = append(element.Tags, "x265")
default:
titleWords = append(titleWords, word)
}
}
title = ""
first := true
for i := len(titleWords) - 1; i >= 0; i-- {
if !first {
title += " "
}
title += titleWords[i]
first = false
}
if element.Episode != "" {
element.Title = strings.TrimSpace(title)
}
return element
}
func (element *mediaElement) String() string {
result := ""
result += fmt.Sprintf("Directory: %s\n", element.Directory)
result += fmt.Sprintf("Name: %s\n", element.Name)
result += fmt.Sprintf("Episode: %s\n", element.Episode)
result += fmt.Sprintf("Title: %s\n", element.Title)
result += fmt.Sprintf("Extension: %s\n", element.Extension)
result += fmt.Sprintf("Year: %d\n", element.Year)
result += "Tags:"
for _, tag := range element.Tags {
result += " " + tag
}
return result
}
func (element *mediaElement) Path() string {
result := element.Name
if element.Episode != "" {
result += " - " + element.Episode
}
if element.Title != "" {
if result != "" {
result += " - "
}
result += element.Title
}
if element.Year != 0 {
result += " (" + strconv.Itoa(element.Year) + ")"
}
for i := len(element.Tags) - 1; i >= 0; i-- {
result += " " + element.Tags[i]
}
result += element.Extension
return filepath.Join(element.Directory, result)
}