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})[.\- ]?`) text := filepath.Base(p) ext := filepath.Ext(text) text = strings.TrimSuffix(text, ext) text = strings.ReplaceAll(text, ".", " ") text = strings.ReplaceAll(text, "-", " ") element := &mediaElement{ Directory: filepath.Dir(p), Extension: ext, } title := "" // get first group of regex match from episodeMatch match := episodeMatch.FindStringSubmatch(text) if len(match) > 0 { element.Episode = match[1] indexOfEpisode := strings.Index(text, match[0]) text = strings.Replace(text, match[0], "", -1) title = text[indexOfEpisode:] text = text[:indexOfEpisode] } match = yearMatch.FindStringSubmatch(text) if len(match) > 0 { year, err := strconv.Atoi(match[1]) if err == nil { element.Year = year } indexOfYear := strings.Index(text, match[0]) text = strings.Replace(text, match[0], "", -1) title = text[indexOfYear:] text = text[:indexOfYear] } element.Name = strings.TrimSpace(text) words := strings.Split(title, " ") titleWords := []string{} for i := len(words) - 1; i >= 0; i-- { word := words[i] upperWord := strings.ToUpper(word) switch upperWord { case "EN": fallthrough case "DE": fallthrough case "FORCED": fallthrough case "3D": fallthrough case "1080P": fallthrough case "X265": fallthrough case "UNCUT": element.Tags = append(element.Tags, upperWord) case "GERMAN": element.Tags = append(element.Tags, "DE") 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) }