assigned links
This commit is contained in:
@@ -47,7 +47,7 @@ func ServeTorrentsListForInfuse(directory string, torMgr *torrent.TorrentManager
|
|||||||
if !ok || tor.AllInProgress() {
|
if !ok || tor.AllInProgress() {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
buf.WriteString(dav.BaseDirectory(torMgr.GetKey(tor), tor.LatestAdded))
|
buf.WriteString(dav.BaseDirectory(torMgr.GetKey(tor), tor.Added))
|
||||||
}
|
}
|
||||||
buf.WriteString("</d:multistatus>")
|
buf.WriteString("</d:multistatus>")
|
||||||
return buf.Bytes(), nil
|
return buf.Bytes(), nil
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ func ServeTorrentsList(directory string, torMgr *torrent.TorrentManager) ([]byte
|
|||||||
if !ok || tor.AllInProgress() {
|
if !ok || tor.AllInProgress() {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
buf.WriteString(dav.Directory(torMgr.GetKey(tor), tor.LatestAdded))
|
buf.WriteString(dav.Directory(torMgr.GetKey(tor), tor.Added))
|
||||||
}
|
}
|
||||||
buf.WriteString("</d:multistatus>")
|
buf.WriteString("</d:multistatus>")
|
||||||
return buf.Bytes(), nil
|
return buf.Bytes(), nil
|
||||||
@@ -74,7 +74,7 @@ func ServeFilesList(directory, torrentName string, torMgr *torrent.TorrentManage
|
|||||||
|
|
||||||
var buf bytes.Buffer
|
var buf bytes.Buffer
|
||||||
buf.WriteString("<?xml version=\"1.0\" encoding=\"utf-8\"?><d:multistatus xmlns:d=\"DAV:\">")
|
buf.WriteString("<?xml version=\"1.0\" encoding=\"utf-8\"?><d:multistatus xmlns:d=\"DAV:\">")
|
||||||
buf.WriteString(dav.BaseDirectory(filepath.Join(directory, torMgr.GetKey(tor)), tor.LatestAdded))
|
buf.WriteString(dav.BaseDirectory(filepath.Join(directory, torMgr.GetKey(tor)), tor.Added))
|
||||||
filenames := tor.SelectedFiles.Keys()
|
filenames := tor.SelectedFiles.Keys()
|
||||||
sort.Strings(filenames)
|
sort.Strings(filenames)
|
||||||
for _, filename := range filenames {
|
for _, filename := range filenames {
|
||||||
@@ -113,7 +113,7 @@ func HandleSingleFile(directory, torrentName, fileName string, torMgr *torrent.T
|
|||||||
|
|
||||||
var buf bytes.Buffer
|
var buf bytes.Buffer
|
||||||
buf.WriteString("<?xml version=\"1.0\" encoding=\"utf-8\"?><d:multistatus xmlns:d=\"DAV:\">")
|
buf.WriteString("<?xml version=\"1.0\" encoding=\"utf-8\"?><d:multistatus xmlns:d=\"DAV:\">")
|
||||||
buf.WriteString(dav.BaseDirectory(filepath.Join(directory, torMgr.GetKey(tor)), tor.LatestAdded))
|
buf.WriteString(dav.BaseDirectory(filepath.Join(directory, torMgr.GetKey(tor)), tor.Added))
|
||||||
buf.WriteString(dav.File(fileName, file.Bytes, file.Ended))
|
buf.WriteString(dav.File(fileName, file.Bytes, file.Ended))
|
||||||
buf.WriteString("</d:multistatus>")
|
buf.WriteString("</d:multistatus>")
|
||||||
return buf.Bytes(), nil
|
return buf.Bytes(), nil
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ func (t *TorrentManager) CheckDeletedStatus(torrent *Torrent) bool {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
t.writeTorrentToFile(id, info, false)
|
t.writeTorrentToFile(id, info)
|
||||||
return false
|
return false
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -185,7 +185,7 @@ func (t *TorrentManager) GetKey(torrent *Torrent) string {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *TorrentManager) writeTorrentToFile(instanceID string, torrent *Torrent, overwriteNames bool) {
|
func (t *TorrentManager) writeTorrentToFile(instanceID string, torrent *Torrent) {
|
||||||
filePath := "data/" + instanceID + ".json"
|
filePath := "data/" + instanceID + ".json"
|
||||||
file, err := os.Create(filePath)
|
file, err := os.Create(filePath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -194,13 +194,6 @@ func (t *TorrentManager) writeTorrentToFile(instanceID string, torrent *Torrent,
|
|||||||
}
|
}
|
||||||
defer file.Close()
|
defer file.Close()
|
||||||
|
|
||||||
if !overwriteNames {
|
|
||||||
infoCache, _ := t.DirectoryMap.Get(INT_INFO_CACHE)
|
|
||||||
if cachedTorrent, exists := infoCache.Get(instanceID); exists {
|
|
||||||
torrent.Name = cachedTorrent.Name
|
|
||||||
torrent.OriginalName = cachedTorrent.OriginalName
|
|
||||||
}
|
|
||||||
}
|
|
||||||
torrent.Version = t.requiredVersion
|
torrent.Version = t.requiredVersion
|
||||||
|
|
||||||
jsonData, err := json.Marshal(torrent)
|
jsonData, err := json.Marshal(torrent)
|
||||||
|
|||||||
@@ -114,14 +114,30 @@ func (t *TorrentManager) startRefreshJob() {
|
|||||||
// getMoreInfo gets original name, size and files for a torrent
|
// getMoreInfo gets original name, size and files for a torrent
|
||||||
func (t *TorrentManager) getMoreInfo(rdTorrent realdebrid.Torrent) *Torrent {
|
func (t *TorrentManager) getMoreInfo(rdTorrent realdebrid.Torrent) *Torrent {
|
||||||
infoCache, _ := t.DirectoryMap.Get(INT_INFO_CACHE)
|
infoCache, _ := t.DirectoryMap.Get(INT_INFO_CACHE)
|
||||||
if torrentFromCache, exists := infoCache.Get(rdTorrent.ID); exists && !torrentFromCache.AnyInProgress() && torrentFromCache.SelectedFiles.Count() == len(rdTorrent.Links) {
|
if torrentFromCache, exists := infoCache.Get(rdTorrent.ID); exists &&
|
||||||
|
!torrentFromCache.AnyInProgress() &&
|
||||||
|
torrentFromCache.SelectedFiles.Count() == len(rdTorrent.Links) {
|
||||||
|
|
||||||
return torrentFromCache
|
return torrentFromCache
|
||||||
}
|
}
|
||||||
|
|
||||||
torrentFromFile := t.readTorrentFromFile(rdTorrent.ID)
|
torrentFromFile := t.readTorrentFromFile(rdTorrent.ID)
|
||||||
if torrentFromFile != nil && !torrentFromFile.AnyInProgress() && torrentFromFile.SelectedFiles.Count() == len(rdTorrent.Links) {
|
if torrentFromFile != nil &&
|
||||||
|
!torrentFromFile.AnyInProgress() &&
|
||||||
|
torrentFromFile.SelectedFiles.Count() == len(rdTorrent.Links) {
|
||||||
|
|
||||||
|
hasBrokenFiles := false
|
||||||
|
torrentFromFile.SelectedFiles.IterCb(func(filepath string, file *File) {
|
||||||
|
if !strings.HasPrefix(file.Link, "http") && file.Link != "unselect" {
|
||||||
|
hasBrokenFiles = true
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
if !hasBrokenFiles {
|
||||||
infoCache.Set(rdTorrent.ID, torrentFromFile)
|
infoCache.Set(rdTorrent.ID, torrentFromFile)
|
||||||
return torrentFromFile
|
return torrentFromFile
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
info, err := t.Api.GetTorrentInfo(rdTorrent.ID)
|
info, err := t.Api.GetTorrentInfo(rdTorrent.ID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -132,7 +148,7 @@ func (t *TorrentManager) getMoreInfo(rdTorrent realdebrid.Torrent) *Torrent {
|
|||||||
torrent := Torrent{
|
torrent := Torrent{
|
||||||
Name: info.Name,
|
Name: info.Name,
|
||||||
OriginalName: info.OriginalName,
|
OriginalName: info.OriginalName,
|
||||||
LatestAdded: info.Added,
|
Added: info.Added,
|
||||||
Hash: info.Hash,
|
Hash: info.Hash,
|
||||||
}
|
}
|
||||||
// SelectedFiles is a subset of Files with only the selected ones
|
// SelectedFiles is a subset of Files with only the selected ones
|
||||||
@@ -182,8 +198,8 @@ func (t *TorrentManager) getMoreInfo(rdTorrent realdebrid.Torrent) *Torrent {
|
|||||||
}
|
}
|
||||||
torrent.BrokenLinks = mapset.NewSet[string]()
|
torrent.BrokenLinks = mapset.NewSet[string]()
|
||||||
|
|
||||||
t.writeTorrentToFile(rdTorrent.ID, &torrent, true)
|
|
||||||
infoCache.Set(rdTorrent.ID, &torrent)
|
infoCache.Set(rdTorrent.ID, &torrent)
|
||||||
|
t.writeTorrentToFile(rdTorrent.ID, &torrent)
|
||||||
|
|
||||||
return &torrent
|
return &torrent
|
||||||
}
|
}
|
||||||
@@ -198,6 +214,7 @@ func (t *TorrentManager) mergeToMain(existing, toMerge *Torrent) Torrent {
|
|||||||
InProgressIDs: mapset.NewSet[string](),
|
InProgressIDs: mapset.NewSet[string](),
|
||||||
Unfixable: existing.Unfixable || toMerge.Unfixable,
|
Unfixable: existing.Unfixable || toMerge.Unfixable,
|
||||||
UnassignedLinks: existing.UnassignedLinks.Union(toMerge.UnassignedLinks),
|
UnassignedLinks: existing.UnassignedLinks.Union(toMerge.UnassignedLinks),
|
||||||
|
BrokenLinks: existing.BrokenLinks.Union(toMerge.BrokenLinks),
|
||||||
}
|
}
|
||||||
|
|
||||||
// this function triggers only when we have a new DownloadedID
|
// this function triggers only when we have a new DownloadedID
|
||||||
@@ -219,8 +236,8 @@ func (t *TorrentManager) mergeToMain(existing, toMerge *Torrent) Torrent {
|
|||||||
// if it doesn't exist in the main torrent, add it
|
// if it doesn't exist in the main torrent, add it
|
||||||
mainTorrent.SelectedFiles.Set(filepath, fileToMerge)
|
mainTorrent.SelectedFiles.Set(filepath, fileToMerge)
|
||||||
} else if originalFile.Link != "unselect" {
|
} else if originalFile.Link != "unselect" {
|
||||||
// if it exists, compare the LatestAdded property and the link
|
// if it exists, compare the Added property and the link
|
||||||
if existing.LatestAdded < toMerge.LatestAdded {
|
if existing.Added < toMerge.Added {
|
||||||
// && strings.HasPrefix(fileToMerge.Link, "http")
|
// && strings.HasPrefix(fileToMerge.Link, "http")
|
||||||
// if torrentToMerge is more recent and its file has a link, update the main torrent's file
|
// if torrentToMerge is more recent and its file has a link, update the main torrent's file
|
||||||
mainTorrent.SelectedFiles.Set(filepath, fileToMerge)
|
mainTorrent.SelectedFiles.Set(filepath, fileToMerge)
|
||||||
@@ -229,10 +246,10 @@ func (t *TorrentManager) mergeToMain(existing, toMerge *Torrent) Torrent {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
if existing.LatestAdded < toMerge.LatestAdded {
|
if existing.Added < toMerge.Added {
|
||||||
mainTorrent.LatestAdded = toMerge.LatestAdded
|
mainTorrent.Added = toMerge.Added
|
||||||
} else {
|
} else {
|
||||||
mainTorrent.LatestAdded = existing.LatestAdded
|
mainTorrent.Added = existing.Added
|
||||||
}
|
}
|
||||||
|
|
||||||
return mainTorrent
|
return mainTorrent
|
||||||
|
|||||||
@@ -113,7 +113,7 @@ func (t *TorrentManager) Repair(torrent *Torrent) {
|
|||||||
return file.Link == link
|
return file.Link == link
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
t.writeTorrentToFile(id, info, false)
|
t.writeTorrentToFile(id, info)
|
||||||
return false
|
return false
|
||||||
})
|
})
|
||||||
_ = t.workerPool.Submit(func() {
|
_ = t.workerPool.Submit(func() {
|
||||||
@@ -129,7 +129,6 @@ func (t *TorrentManager) repair(torrent *Torrent) {
|
|||||||
t.log.Infof("Torrent %s is in progress, skipping repair until download is done", t.GetKey(torrent))
|
t.log.Infof("Torrent %s is in progress, skipping repair until download is done", t.GetKey(torrent))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
torrent.InProgressIDs.Add(REPAIR_SEMAPHORE)
|
torrent.InProgressIDs.Add(REPAIR_SEMAPHORE)
|
||||||
|
|
||||||
proceed := t.canCapacityHandle() // blocks for approx 45 minutes if active torrents are full
|
proceed := t.canCapacityHandle() // blocks for approx 45 minutes if active torrents are full
|
||||||
@@ -158,9 +157,12 @@ func (t *TorrentManager) repair(torrent *Torrent) {
|
|||||||
assignedCount := 0
|
assignedCount := 0
|
||||||
rarCount := 0
|
rarCount := 0
|
||||||
unassignedDownloads := make([]*realdebrid.Download, 0)
|
unassignedDownloads := make([]*realdebrid.Download, 0)
|
||||||
|
assignedLinks := make([]string, 0)
|
||||||
torrent.UnassignedLinks.Each(func(link string) bool {
|
torrent.UnassignedLinks.Each(func(link string) bool {
|
||||||
unrestrict := t.UnrestrictUntilOk(link)
|
unrestrict := t.UnrestrictUntilOk(link)
|
||||||
if unrestrict != nil {
|
if unrestrict == nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
// assign to a selected file
|
// assign to a selected file
|
||||||
assigned := false
|
assigned := false
|
||||||
torrent.SelectedFiles.IterCb(func(_ string, file *File) {
|
torrent.SelectedFiles.IterCb(func(_ string, file *File) {
|
||||||
@@ -176,10 +178,12 @@ func (t *TorrentManager) repair(torrent *Torrent) {
|
|||||||
rarCount++
|
rarCount++
|
||||||
}
|
}
|
||||||
unassignedDownloads = append(unassignedDownloads, unrestrict)
|
unassignedDownloads = append(unassignedDownloads, unrestrict)
|
||||||
}
|
} else {
|
||||||
|
assignedLinks = append(assignedLinks, unrestrict.Link)
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
})
|
})
|
||||||
|
torrent.UnassignedLinks = torrent.UnassignedLinks.Difference(mapset.NewSet(assignedLinks...))
|
||||||
|
|
||||||
if assignedCount > 0 {
|
if assignedCount > 0 {
|
||||||
t.log.Infof("Assigned %d links to selected files for torrent %s", assignedCount, t.GetKey(torrent))
|
t.log.Infof("Assigned %d links to selected files for torrent %s", assignedCount, t.GetKey(torrent))
|
||||||
@@ -197,7 +201,7 @@ func (t *TorrentManager) repair(torrent *Torrent) {
|
|||||||
Bytes: unassigned.Filesize,
|
Bytes: unassigned.Filesize,
|
||||||
Selected: 1,
|
Selected: 1,
|
||||||
},
|
},
|
||||||
Ended: torrent.LatestAdded,
|
Ended: torrent.Added,
|
||||||
Link: unassigned.Link,
|
Link: unassigned.Link,
|
||||||
}
|
}
|
||||||
torrent.SelectedFiles.Set(unassigned.Filename, newFile)
|
torrent.SelectedFiles.Set(unassigned.Filename, newFile)
|
||||||
@@ -377,7 +381,7 @@ func (t *TorrentManager) markAsUnfixable(torrent *Torrent) {
|
|||||||
torrent.DownloadedIDs.Each(func(id string) bool {
|
torrent.DownloadedIDs.Each(func(id string) bool {
|
||||||
info, _ := infoCache.Get(id)
|
info, _ := infoCache.Get(id)
|
||||||
info.Unfixable = true
|
info.Unfixable = true
|
||||||
t.writeTorrentToFile(id, info, false)
|
t.writeTorrentToFile(id, info)
|
||||||
return false
|
return false
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,17 +14,17 @@ import (
|
|||||||
var json = jsoniter.ConfigCompatibleWithStandardLibrary
|
var json = jsoniter.ConfigCompatibleWithStandardLibrary
|
||||||
|
|
||||||
type Torrent struct {
|
type Torrent struct {
|
||||||
Name string `json:"Name"`
|
Hash string `json:"Hash"` // immutable
|
||||||
OriginalName string `json:"OriginalName"`
|
Added string `json:"Added"` // immutable
|
||||||
Rename string `json:"Rename"`
|
UnassignedLinks mapset.Set[string] `json:"UnassignedLinks"` // immutable
|
||||||
Hash string `json:"Hash"`
|
DownloadedIDs mapset.Set[string] `json:"DownloadedIDs"` // immutable
|
||||||
SelectedFiles cmap.ConcurrentMap[string, *File] `json:"-"`
|
InProgressIDs mapset.Set[string] `json:"InProgressIDs"` // immutable
|
||||||
LatestAdded string `json:"LatestAdded"`
|
Name string `json:"Name"` // immutable
|
||||||
Unfixable bool `json:"Unfixable"`
|
OriginalName string `json:"OriginalName"` // immutable
|
||||||
DownloadedIDs mapset.Set[string] `json:"DownloadedIDs"`
|
Rename string `json:"Rename"` // modified over time
|
||||||
InProgressIDs mapset.Set[string] `json:"InProgressIDs"`
|
SelectedFiles cmap.ConcurrentMap[string, *File] `json:"-"` // modified over time
|
||||||
UnassignedLinks mapset.Set[string] `json:"UnassignedLinks"`
|
Unfixable bool `json:"Unfixable"` // modified over time
|
||||||
BrokenLinks mapset.Set[string] `json:"BrokenLinks"`
|
BrokenLinks mapset.Set[string] `json:"BrokenLinks"` // only relevant on repair
|
||||||
|
|
||||||
Version string `json:"Version"` // only used for files
|
Version string `json:"Version"` // only used for files
|
||||||
}
|
}
|
||||||
@@ -160,11 +160,11 @@ func (t *Torrent) ComputeBiggestFileSize() int64 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (t *Torrent) OlderThanDuration(duration time.Duration) bool {
|
func (t *Torrent) OlderThanDuration(duration time.Duration) bool {
|
||||||
latestAdded, err := time.Parse(time.RFC3339, t.LatestAdded)
|
added, err := time.Parse(time.RFC3339, t.Added)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
return time.Since(latestAdded) > duration
|
return time.Since(added) > duration
|
||||||
}
|
}
|
||||||
|
|
||||||
type File struct {
|
type File struct {
|
||||||
|
|||||||
Reference in New Issue
Block a user