From c2bf62741343f402934ee396eeff91d40d6b2d40 Mon Sep 17 00:00:00 2001 From: Ben Sarmiento Date: Tue, 7 Nov 2023 17:20:54 +0100 Subject: [PATCH] Add retain_folder_name_extension option --- config.yml.example | 1 + internal/config/load.go | 1 + internal/config/types.go | 27 ++++++++++++++++----------- internal/dav/response.go | 3 +-- internal/http/response.go | 3 +-- internal/torrent/manager.go | 23 ++++++++++++----------- internal/universal/get.go | 14 ++++++-------- internal/universal/head.go | 4 +--- internal/universal/util.go | 5 ++--- pkg/davextra/util.go | 34 ---------------------------------- 10 files changed, 41 insertions(+), 74 deletions(-) diff --git a/config.yml.example b/config.yml.example index c4fc91b..3ce3565 100644 --- a/config.yml.example +++ b/config.yml.example @@ -11,6 +11,7 @@ enable_repair: true # BEWARE! THERE CAN ONLY BE 1 INSTANCE OF ZURG THAT SHOULD R on_library_update: | echo "hook" network_buffer_size: 32768 # 32KB +retain_folder_name_extension: false # if true, the folder name will contain the file extension when it is a torrent for a single file # List of directory definitions and their filtering rules directories: diff --git a/internal/config/load.go b/internal/config/load.go index 9cf2f1b..10139bd 100644 --- a/internal/config/load.go +++ b/internal/config/load.go @@ -22,6 +22,7 @@ type ConfigInterface interface { GetOnLibraryUpdate() string GetNetworkBufferSize() int GetMountPoint() string + EnableRetainFolderNameExtension() bool } func LoadZurgConfig(filename string) (ConfigInterface, error) { diff --git a/internal/config/types.go b/internal/config/types.go index 985ef60..ddca6a5 100644 --- a/internal/config/types.go +++ b/internal/config/types.go @@ -1,17 +1,18 @@ package config type ZurgConfig struct { - Version string `yaml:"zurg"` - Token string `yaml:"token"` - Host string `yaml:"host"` - Port string `yaml:"port"` - NumOfWorkers int `yaml:"concurrent_workers"` - RefreshEverySeconds int `yaml:"check_for_changes_every_secs"` - CacheTimeHours int `yaml:"info_cache_time_hours"` - CanRepair bool `yaml:"enable_repair"` - OnLibraryUpdate string `yaml:"on_library_update"` - NetworkBufferSize int `yaml:"network_buffer_size"` - MountPoint string `yaml:"mount_point"` + Version string `yaml:"zurg"` + Token string `yaml:"token"` + Host string `yaml:"host"` + Port string `yaml:"port"` + NumOfWorkers int `yaml:"concurrent_workers"` + RefreshEverySeconds int `yaml:"check_for_changes_every_secs"` + CacheTimeHours int `yaml:"info_cache_time_hours"` + CanRepair bool `yaml:"enable_repair"` + OnLibraryUpdate string `yaml:"on_library_update"` + NetworkBufferSize int `yaml:"network_buffer_size"` + MountPoint string `yaml:"mount_point"` + RetainFolderNameExtension bool `yaml:"retain_folder_name_extension"` } func (z *ZurgConfig) GetToken() string { @@ -68,3 +69,7 @@ func (z *ZurgConfig) GetNetworkBufferSize() int { func (z *ZurgConfig) GetMountPoint() string { return z.MountPoint } + +func (z *ZurgConfig) EnableRetainFolderNameExtension() bool { + return z.RetainFolderNameExtension +} diff --git a/internal/dav/response.go b/internal/dav/response.go index 5d1cfdf..6098b6f 100644 --- a/internal/dav/response.go +++ b/internal/dav/response.go @@ -49,14 +49,13 @@ func createSingleTorrentResponse(basePath string, torrents []torrent.Torrent) (* for _, torrent := range torrents { for _, file := range torrent.SelectedFiles { if file.Link == "" { + // TODO: fix the file? // log.Println("File has no link, skipping (repairing links take time)", file.Path) continue } filename := filepath.Base(file.Path) if finalName[filename] { - // fragment := davextra.GetLinkFragment(file.Link) - // filename = davextra.InsertLinkFragment(filename, fragment) continue } finalName[filename] = true diff --git a/internal/http/response.go b/internal/http/response.go index 68c0d94..f488257 100644 --- a/internal/http/response.go +++ b/internal/http/response.go @@ -40,14 +40,13 @@ func createSingleTorrentResponse(basePath string, torrents []torrent.Torrent) (s for _, torrent := range torrents { for _, file := range torrent.SelectedFiles { if file.Link == "" { + // TODO: fix the file? // log.Println("File has no link, skipping", file.Path) continue } filename := filepath.Base(file.Path) if finalName[filename] { - // fragment := davextra.GetLinkFragment(file.Link) - // filename = davextra.InsertLinkFragment(filename, fragment) continue } finalName[filename] = true diff --git a/internal/torrent/manager.go b/internal/torrent/manager.go index 28c4a0a..f1f43c8 100644 --- a/internal/torrent/manager.go +++ b/internal/torrent/manager.go @@ -35,7 +35,7 @@ type TorrentManager struct { // and store them in-memory; it is called only once at startup func NewTorrentManager(config config.ConfigInterface, cache *expirable.LRU[string, string]) *TorrentManager { t := &TorrentManager{ - requiredVersion: "4.11.2023", + requiredVersion: fmt.Sprintf("4.11.2023 - retain:%v", config.EnableRetainFolderNameExtension()), config: config, cache: cache, workerPool: make(chan bool, config.GetNumOfWorkers()), @@ -256,7 +256,7 @@ func (t *TorrentManager) addMoreInfo(torrent *Torrent) { // see if api data and file data still match // then it means data is still usable if len(torrentFromFile.Links) == len(torrent.Links) { - torrent.Name = getName(torrentFromFile) + torrent.Name = t.getName(torrentFromFile) torrent.ForRepair = torrentFromFile.ForRepair torrent.SelectedFiles = torrentFromFile.SelectedFiles[:] return @@ -323,7 +323,7 @@ func (t *TorrentManager) addMoreInfo(torrent *Torrent) { } // update file cache torrent.OriginalName = info.OriginalName - torrent.Name = getName(torrent) + torrent.Name = t.getName(torrent) if len(selectedFiles) > 0 { // update the torrent with more data! torrent.SelectedFiles = selectedFiles @@ -332,16 +332,17 @@ func (t *TorrentManager) addMoreInfo(torrent *Torrent) { } } -func getName(torrent *Torrent) string { - ret := "" - if torrent.OriginalName != "" { - ret = torrent.OriginalName +func (t *TorrentManager) getName(torrent *Torrent) string { + // drop the extension from the name + t.log.Debugf("Original name: %s", torrent.OriginalName) + t.log.Debugf("Name: %s", torrent.Name) + if t.config.EnableRetainFolderNameExtension() && strings.Contains(torrent.Name, torrent.OriginalName) { + return torrent.Name } else { - ret = torrent.Name + ret := strings.TrimSuffix(torrent.OriginalName, ".mp4") + ret = strings.TrimSuffix(ret, ".mkv") + return ret } - ret = strings.TrimSuffix(ret, ".mkv") - ret = strings.TrimSuffix(ret, ".mp4") - return ret } // mapToDirectories maps torrents to directories diff --git a/internal/universal/get.go b/internal/universal/get.go index 736f09b..8a8c3e9 100644 --- a/internal/universal/get.go +++ b/internal/universal/get.go @@ -11,7 +11,6 @@ import ( "github.com/debridmediamanager.com/zurg/internal/dav" intHttp "github.com/debridmediamanager.com/zurg/internal/http" "github.com/debridmediamanager.com/zurg/internal/torrent" - "github.com/debridmediamanager.com/zurg/pkg/davextra" "github.com/debridmediamanager.com/zurg/pkg/logutil" "github.com/debridmediamanager.com/zurg/pkg/realdebrid" "github.com/hashicorp/golang-lru/v2/expirable" @@ -58,8 +57,7 @@ func HandleGetRequest(w http.ResponseWriter, r *http.Request, t *torrent.Torrent return } - filenameV2, linkFragment := davextra.ExtractLinkFragment(filename) - torrent, file := getFile(torrents, filenameV2, linkFragment) + torrent, file := getFile(torrents, filename) if file == nil { log.Errorf("Cannot find file from path %s", requestPath) http.Error(w, "File not found", http.StatusNotFound) @@ -79,20 +77,20 @@ func HandleGetRequest(w http.ResponseWriter, r *http.Request, t *torrent.Torrent resp := realdebrid.RetryUntilOk(unrestrictFn) if resp == nil { if !file.Unavailable { - log.Errorf("Cannot unrestrict file %s %s", filenameV2, link) + log.Errorf("Cannot unrestrict file %s %s", filename, link) t.HideTheFile(torrent, file) } streamErrorVideo("https://www.youtube.com/watch?v=gea_FJrtFVA", w, r, c, log) return - } else if resp.Filename != filenameV2 { + } else if resp.Filename != filename { actualExt := filepath.Ext(resp.Filename) - expectedExt := filepath.Ext(filenameV2) + expectedExt := filepath.Ext(filename) if actualExt != expectedExt && resp.Streamable != 1 { - log.Errorf("File extension mismatch: %s and %s", filenameV2, resp.Filename) + log.Errorf("File extension mismatch: %s and %s", filename, resp.Filename) streamErrorVideo("https://www.youtube.com/watch?v=t9VgOriBHwE", w, r, c, log) return } else { - log.Errorf("Filename mismatch: %s and %s", filenameV2, resp.Filename) + log.Errorf("Filename mismatch: %s and %s", filename, resp.Filename) } } cache.Add(requestPath, resp.Download) diff --git a/internal/universal/head.go b/internal/universal/head.go index 58c452a..28d3803 100644 --- a/internal/universal/head.go +++ b/internal/universal/head.go @@ -9,7 +9,6 @@ import ( "github.com/debridmediamanager.com/zurg/internal/config" "github.com/debridmediamanager.com/zurg/internal/torrent" - "github.com/debridmediamanager.com/zurg/pkg/davextra" "github.com/debridmediamanager.com/zurg/pkg/logutil" "github.com/hashicorp/golang-lru/v2/expirable" ) @@ -53,8 +52,7 @@ func HandleHeadRequest(w http.ResponseWriter, r *http.Request, t *torrent.Torren return } - filenameV2, linkFragment := davextra.ExtractLinkFragment(filename) - _, file := getFile(torrents, filenameV2, linkFragment) + _, file := getFile(torrents, filename) if file == nil { log.Errorf("Cannot find file from path %s", requestPath) http.Error(w, "Cannot find file", http.StatusNotFound) diff --git a/internal/universal/util.go b/internal/universal/util.go index c8b4501..e9d5351 100644 --- a/internal/universal/util.go +++ b/internal/universal/util.go @@ -2,17 +2,16 @@ package universal import ( "path/filepath" - "strings" "github.com/debridmediamanager.com/zurg/internal/torrent" ) // getFile finds a link by a fragment, it might be wrong -func getFile(torrents []torrent.Torrent, filename, fragment string) (*torrent.Torrent, *torrent.File) { +func getFile(torrents []torrent.Torrent, filename string) (*torrent.Torrent, *torrent.File) { for t := range torrents { for f, file := range torrents[t].SelectedFiles { fname := filepath.Base(file.Path) - if filename == fname && strings.Contains(file.Link, fragment) { + if filename == fname { return &torrents[t], &torrents[t].SelectedFiles[f] } } diff --git a/pkg/davextra/util.go b/pkg/davextra/util.go index fdda349..4b18f17 100644 --- a/pkg/davextra/util.go +++ b/pkg/davextra/util.go @@ -1,11 +1,7 @@ package davextra import ( - "fmt" - "net/url" - "path/filepath" "regexp" - "strings" ) // GetLinkFragment returns the longest alphanumeric string from a link @@ -20,33 +16,3 @@ func GetLinkFragment(link string) string { } return longestMatch[:4] } - -// InsertLinkFragment inserts the link ID into a filename -// returns the new filename -func InsertLinkFragment(filename, dupeID string) string { - ext := filepath.Ext(filename) - name := strings.TrimSuffix(filename, ext) - return fmt.Sprintf("%s DMM%s%s", name, dupeID, ext) -} - -// ExtractLinkFragment extracts the link ID from a filename -// returns the original filename and the link ID -func ExtractLinkFragment(filename string) (string, string) { - filenameV2, err := url.PathUnescape(filename) - if err != nil { - filenameV2 = filename - } - ext := filepath.Ext(filenameV2) - name := strings.TrimSuffix(filenameV2, ext) - - r := regexp.MustCompile(`\sDMM(\w+)`) - matches := r.FindStringSubmatch(name) - if len(matches) < 2 { - // No ID found - return filenameV2, "" - } - - // Remove ID from filename - originalName := strings.Replace(name, matches[0], "", 1) - return originalName + ext, matches[1] -}