From 03b6a2bf4c7cba08e42d07da3222f5857df5c037 Mon Sep 17 00:00:00 2001 From: Daniel Tam Date: Tue, 22 Nov 2022 00:51:28 -0600 Subject: [PATCH] Add README; add cli args; finish program --- README.md | 53 +++++++++++++++++++++++++++++++++++++++ fix-subs.go | 72 ++++++++++++++++++++++++++++++++++++++++++++++------- 2 files changed, 116 insertions(+), 9 deletions(-) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 0000000..54d18ff --- /dev/null +++ b/README.md @@ -0,0 +1,53 @@ +# fix-subs + +Some shows will have their subtitles nested in a `Subs/` folder that is within the season itself. This causes some issues +with Plex as it will not find the subtitles if they are nested. An example of this nested structure is: +``` +Show Name/ + |- Season 01/ + |- S01E01.mp4 + |- S01E02.mp4 + |- S01E03.mp4 + |- Subs/ + |- S01E01/ + |- Subtitle 1.srt + |- Subtitle 2.srt + |- S01E02/ + |- Subtitle 1.srt + |- Subtitle 2.srt + |- S01E03/ + |- Subtitle 1.srt + |- Subtitle 2.srt + |- Season 02/ + |- S02E01.mp4 + |- S02E02.mp4 + |- S02E03.mp4 + |- Subs/ + |- S02E01/ + |- Subtitle 1.srt + |- Subtitle 2.srt + |- S02E02/ + |- Subtitle 1.srt + |- Subtitle 2.srt + |- S02E03/ + |- Subtitle 1.srt + |- Subtitle 2.srt +``` + +This short program will go through the folders and grab the subtitles files (.srt) and place them in the appropriate season folder. +It will also rename the folder correctly (Season xx format). It will then remove the old `Subs/` folder within the season. +Plex should then be able to search for these subtitle files and load them correctly. + +## Building / Running +Compiled with golang 1.19.3 amd64 linux: + +``` +go build fix-subs.go +``` +Or run without building +``` +go run fix-subs.go +``` + +## TODO +- Set goroutines to cycle through directories simultaneously \ No newline at end of file diff --git a/fix-subs.go b/fix-subs.go index 7383316..b6cbf54 100644 --- a/fix-subs.go +++ b/fix-subs.go @@ -32,8 +32,6 @@ func processSeason(seasonDir string) { return } - fmt.Println(seasonDir) - // Go through each file for _, seasonsDirItems := range seasonsDirList { @@ -55,16 +53,62 @@ func processSeason(seasonDir string) { filename := strings.TrimSuffix(seasonsDirItems.Name(), filepath.Ext(seasonsDirItems.Name())) // Ensure the directory within subs exist matching this filename + episodeSubsDir := seasonDir + "/" + subsDir + "/" + filename + if _, err := os.Stat(episodeSubsDir); !os.IsNotExist(err) { + episodeSubsList, err := os.ReadDir(episodeSubsDir) + if err != nil { + log.Fatal(err) + } - // Move the srt files within the directory into the season's directory + // Go through sub's directory, sort for English only + for _, episodeSubsItems := range episodeSubsList { + ensureLanguage, _ := regexp.MatchString(`_[Ee]nglish.srt`, episodeSubsItems.Name()) - fmt.Println(filename) + // Move the srt files within the directory into the season's directory + if ensureLanguage { + newSubsName := filename + "_" + episodeSubsItems.Name() + err := os.Rename(episodeSubsDir+"/"+episodeSubsItems.Name(), seasonDir+"/"+newSubsName) + if err != nil { + log.Fatal(err) + } + } + } + } } + // Delete Subs folder + err = os.RemoveAll(seasonDir + "/" + subsDir) + if err != nil { + log.Fatal(err) + } +} + +func formatSeason(seasonNumber string) string { + // If it starts with a '.', it is in the '.Sxx.' format + if seasonNumber[0] == '.' { + return seasonNumber[2 : len(seasonNumber)-1] + } + + // Else, it is in the 'Season xx' format (do nothing) + return seasonNumber } func main() { - topDir := "/mnt/z/From Scratch (2022) [tvdb-400691]/" + cliArgs := os.Args + fmt.Println() + if len(cliArgs) < 2 { + fmt.Println("Missing directory!") + os.Exit(1) + } + topDir := os.Args[1] + + // Confirm directory + fmt.Print("Press to confirm with directory: \n\t" + topDir) + _, err := fmt.Scanln() + if err != nil { + log.Fatal(err) + } + // Read in the top directory topDirList, err := os.ReadDir(topDir) if err != nil { @@ -74,17 +118,27 @@ func main() { // Each of the seasons directories for _, seasonsDir := range topDirList { - // Ensure there's a Sxx in the name (for the season number) - ensureSeason, _ := regexp.MatchString(`.[sS][0-9]{1,2}.`, seasonsDir.Name()) + // Ensure there's a 'Sxx' in the name (for the season number) + seasonRegex := regexp.MustCompile(`.[sS][0-9]{1,2}.`) + ensureSeason := seasonRegex.MatchString(seasonsDir.Name()) - // Or if the folder is just called Season xx + // Or if the folder is just called 'Season xx' if !ensureSeason { - ensureSeason, _ = regexp.MatchString(`[sS]eason\s[0-9]{1,2}`, seasonsDir.Name()) + seasonRegex = regexp.MustCompile(`[sS]eason\s[0-9]{1,2}`) + ensureSeason = seasonRegex.MatchString(seasonsDir.Name()) } // Process the season if it is a season folder if ensureSeason { processSeason(topDir + seasonsDir.Name()) + + // Rename the season folder to 'Season xx' + seasonFound := seasonRegex.FindStringSubmatch(seasonsDir.Name()) + seasonNumber := formatSeason(seasonFound[0]) + err := os.Rename(topDir+seasonsDir.Name(), topDir+"Season "+seasonNumber) + if err != nil { + log.Fatal(err) + } } fmt.Println("Complete")