assigned links

This commit is contained in:
Ben Sarmiento
2024-01-12 01:12:34 +01:00
parent cc37a92d75
commit ebab40d3e6
7 changed files with 71 additions and 57 deletions

View File

@@ -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

View File

@@ -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

View File

@@ -23,7 +23,7 @@ func (t *TorrentManager) CheckDeletedStatus(torrent *Torrent) bool {
} }
} }
}) })
t.writeTorrentToFile(id, info, false) t.writeTorrentToFile(id, info)
return false return false
}) })
} }

View File

@@ -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)

View File

@@ -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

View File

@@ -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
}) })
} }

View File

@@ -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 {