- 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:
@@ -54,5 +54,8 @@ func IsMediaFile(path string) bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func IsSampleFile(path string) bool {
|
func IsSampleFile(path string) bool {
|
||||||
|
if strings.HasSuffix(strings.ToLower(path), "sample.mkv") {
|
||||||
|
return true
|
||||||
|
}
|
||||||
return RegexMatch(SAMPLEMATCH, path)
|
return RegexMatch(SAMPLEMATCH, path)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
path "path/filepath"
|
path "path/filepath"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
"time"
|
"time"
|
||||||
@@ -30,6 +31,7 @@ const (
|
|||||||
WebDavUseFileNameNoExt WebDavFolderNaming = "filename_no_ext"
|
WebDavUseFileNameNoExt WebDavFolderNaming = "filename_no_ext"
|
||||||
WebDavUseOriginalNameNoExt WebDavFolderNaming = "original_no_ext"
|
WebDavUseOriginalNameNoExt WebDavFolderNaming = "original_no_ext"
|
||||||
WebDavUseID WebDavFolderNaming = "id"
|
WebDavUseID WebDavFolderNaming = "id"
|
||||||
|
WebdavUseHash WebDavFolderNaming = "infohash"
|
||||||
)
|
)
|
||||||
|
|
||||||
type PropfindResponse struct {
|
type PropfindResponse struct {
|
||||||
@@ -396,6 +398,8 @@ func (c *Cache) GetTorrentFolder(torrent *types.Torrent) string {
|
|||||||
return path.Clean(utils.RemoveExtension(torrent.OriginalFilename))
|
return path.Clean(utils.RemoveExtension(torrent.OriginalFilename))
|
||||||
case WebDavUseID:
|
case WebDavUseID:
|
||||||
return torrent.Id
|
return torrent.Id
|
||||||
|
case WebdavUseHash:
|
||||||
|
return strings.ToLower(torrent.InfoHash)
|
||||||
default:
|
default:
|
||||||
return path.Clean(torrent.Filename)
|
return path.Clean(torrent.Filename)
|
||||||
}
|
}
|
||||||
@@ -404,13 +408,12 @@ func (c *Cache) GetTorrentFolder(torrent *types.Torrent) string {
|
|||||||
func (c *Cache) setTorrent(t *CachedTorrent) {
|
func (c *Cache) setTorrent(t *CachedTorrent) {
|
||||||
c.torrents.Store(t.Id, t)
|
c.torrents.Store(t.Id, t)
|
||||||
torrentKey := c.GetTorrentFolder(t.Torrent)
|
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 another torrent with the same name exists, merge the files, if the same file exists,
|
||||||
if t.AddedOn.After(o.AddedOn) {
|
// keep the one with the most recent added date
|
||||||
c.torrentsNames.Delete(torrentKey)
|
|
||||||
} else {
|
mergedFiles := mergeFiles(t, o)
|
||||||
t = o
|
t.Files = mergedFiles
|
||||||
}
|
|
||||||
}
|
}
|
||||||
c.torrentsNames.Store(torrentKey, t)
|
c.torrentsNames.Store(torrentKey, t)
|
||||||
c.SaveTorrent(t)
|
c.SaveTorrent(t)
|
||||||
@@ -420,13 +423,10 @@ func (c *Cache) setTorrents(torrents map[string]*CachedTorrent) {
|
|||||||
for _, t := range torrents {
|
for _, t := range torrents {
|
||||||
c.torrents.Store(t.Id, t)
|
c.torrents.Store(t.Id, t)
|
||||||
torrentKey := c.GetTorrentFolder(t.Torrent)
|
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
|
// Save the most recent torrent
|
||||||
if t.AddedOn.After(o.AddedOn) {
|
mergedFiles := mergeFiles(t, o)
|
||||||
c.torrentsNames.Delete(torrentKey)
|
t.Files = mergedFiles
|
||||||
} else {
|
|
||||||
t = o
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
c.torrentsNames.Store(torrentKey, t)
|
c.torrentsNames.Store(torrentKey, t)
|
||||||
}
|
}
|
||||||
|
|||||||
27
pkg/debrid/debrid/misc.go
Normal file
27
pkg/debrid/debrid/misc.go
Normal 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
|
||||||
|
}
|
||||||
@@ -77,6 +77,7 @@ func (t *Torrent) GetMountFolder(rClonePath string) (string, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type File struct {
|
type File struct {
|
||||||
|
TorrentId string `json:"torrent_id"`
|
||||||
Id string `json:"id"`
|
Id string `json:"id"`
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
Size int64 `json:"size"`
|
Size int64 `json:"size"`
|
||||||
|
|||||||
@@ -291,6 +291,7 @@
|
|||||||
<option value="original">Original name</option>
|
<option value="original">Original name</option>
|
||||||
<option value="original_no_ext">Original name with No Ext</option>
|
<option value="original_no_ext">Original name with No Ext</option>
|
||||||
<option value="id">Use ID</option>
|
<option value="id">Use ID</option>
|
||||||
|
<option value="infohash">Use Infohash</option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-3 mb-3">
|
<div class="col-md-3 mb-3">
|
||||||
|
|||||||
Reference in New Issue
Block a user