- Add support for merging files from torrents with the same name

- Add infohash as a folder naming
- Other minor bugs
This commit is contained in:
Mukhtar Akere
2025-04-22 19:32:55 +01:00
parent 2139d3a175
commit fb39e92a88
5 changed files with 45 additions and 13 deletions
+13 -13
View File
@@ -17,6 +17,7 @@ import (
"os"
path "path/filepath"
"strconv"
"strings"
"sync"
"sync/atomic"
"time"
@@ -30,6 +31,7 @@ const (
WebDavUseFileNameNoExt WebDavFolderNaming = "filename_no_ext"
WebDavUseOriginalNameNoExt WebDavFolderNaming = "original_no_ext"
WebDavUseID WebDavFolderNaming = "id"
WebdavUseHash WebDavFolderNaming = "infohash"
)
type PropfindResponse struct {
@@ -396,6 +398,8 @@ func (c *Cache) GetTorrentFolder(torrent *types.Torrent) string {
return path.Clean(utils.RemoveExtension(torrent.OriginalFilename))
case WebDavUseID:
return torrent.Id
case WebdavUseHash:
return strings.ToLower(torrent.InfoHash)
default:
return path.Clean(torrent.Filename)
}
@@ -404,13 +408,12 @@ func (c *Cache) GetTorrentFolder(torrent *types.Torrent) string {
func (c *Cache) setTorrent(t *CachedTorrent) {
c.torrents.Store(t.Id, t)
torrentKey := c.GetTorrentFolder(t.Torrent)
if o, ok := c.torrentsNames.Load(torrentKey); ok && o.Id != t.Id {
// Save the most recent torrent
if t.AddedOn.After(o.AddedOn) {
c.torrentsNames.Delete(torrentKey)
} else {
t = o
}
if o, ok := c.torrentsNames.Load(torrentKey); ok {
// If another torrent with the same name exists, merge the files, if the same file exists,
// keep the one with the most recent added date
mergedFiles := mergeFiles(t, o)
t.Files = mergedFiles
}
c.torrentsNames.Store(torrentKey, t)
c.SaveTorrent(t)
@@ -420,13 +423,10 @@ func (c *Cache) setTorrents(torrents map[string]*CachedTorrent) {
for _, t := range torrents {
c.torrents.Store(t.Id, t)
torrentKey := c.GetTorrentFolder(t.Torrent)
if o, ok := c.torrentsNames.Load(torrentKey); ok && o.Id != t.Id {
if o, ok := c.torrentsNames.Load(torrentKey); ok {
// Save the most recent torrent
if t.AddedOn.After(o.AddedOn) {
c.torrentsNames.Delete(torrentKey)
} else {
t = o
}
mergedFiles := mergeFiles(t, o)
t.Files = mergedFiles
}
c.torrentsNames.Store(torrentKey, t)
}
+27
View File
@@ -0,0 +1,27 @@
package debrid
import (
"github.com/sirrobot01/decypharr/pkg/debrid/types"
"sort"
)
// MergeFiles merges the files from multiple torrents into a single map.
// It uses the file name as the key and the file object as the value.
// This is useful for deduplicating files across multiple torrents.
// The order of the torrents is determined by the AddedOn time, with the earliest added torrent first.
// If a file with the same name exists in multiple torrents, the last one will be used.
func mergeFiles(torrents ...*CachedTorrent) map[string]types.File {
merged := make(map[string]types.File)
// order torrents by added time
sort.Slice(torrents, func(i, j int) bool {
return torrents[i].AddedOn.Before(torrents[j].AddedOn)
})
for _, torrent := range torrents {
for _, file := range torrent.Files {
merged[file.Name] = file
}
}
return merged
}
+1
View File
@@ -77,6 +77,7 @@ func (t *Torrent) GetMountFolder(rClonePath string) (string, error) {
}
type File struct {
TorrentId string `json:"torrent_id"`
Id string `json:"id"`
Name string `json:"name"`
Size int64 `json:"size"`