From a3bc9e75f536de5c8df7ae05d434a70ad44c9c86 Mon Sep 17 00:00:00 2001 From: Ben Sarmiento Date: Tue, 30 Apr 2024 03:41:20 +0200 Subject: [PATCH] Repair adjustments --- internal/torrent/refresh.go | 5 ++-- internal/torrent/repair.go | 56 +++++++++++++++++-------------------- 2 files changed, 28 insertions(+), 33 deletions(-) diff --git a/internal/torrent/refresh.go b/internal/torrent/refresh.go index a44834e..34d23d4 100644 --- a/internal/torrent/refresh.go +++ b/internal/torrent/refresh.go @@ -143,8 +143,7 @@ func (t *TorrentManager) getMoreInfo(rdTorrent realdebrid.Torrent) *Torrent { return cachedTor - } else if diskTor := t.readTorrentFromFile(rdTorrent.ID); diskTor != nil && - diskTor.SelectedFiles.Count() == len(rdTorrent.Links) { + } else if diskTor := t.readTorrentFromFile(rdTorrent.ID); diskTor != nil && !diskTor.AllInProgress() { infoCache.Set(rdTorrent.ID, diskTor) t.ResetSelectedFiles(diskTor) @@ -217,7 +216,7 @@ func (t *TorrentManager) getMoreInfo(rdTorrent realdebrid.Torrent) *Torrent { return &torrent } -// ResetSelectedFiles will rename the file based on config +// ResetSelectedFiles resets the selected files for a torrent func (t *TorrentManager) ResetSelectedFiles(torrent *Torrent) { // reset selected files newSelectedFiles := cmap.New[*File]() diff --git a/internal/torrent/repair.go b/internal/torrent/repair.go index 73ab937..9c5d658 100644 --- a/internal/torrent/repair.go +++ b/internal/torrent/repair.go @@ -157,6 +157,7 @@ func (t *TorrentManager) repair(torrent *Torrent) { t.log.Infof("Started repair process for torrent %s (ids=%v)", t.GetKey(torrent), torrent.DownloadedIDs.Union(torrent.InProgressIDs).ToSlice()) // handle torrents with incomplete links for selected files + // torrent can be rare'ed by RD, so we need to check for that if !t.assignUnassignedLinks(torrent) { t.log.Debugf("Ending repair process early for torrent %s", t.GetKey(torrent)) return @@ -169,9 +170,7 @@ func (t *TorrentManager) repair(torrent *Torrent) { // first step: redownload the whole torrent info, err := t.redownloadTorrent(torrent, "") // reinsert the torrent, passing "" - if err != nil { - t.log.Warnf("Cannot repair torrent %s by redownloading (error=%s)", t.GetKey(torrent), err.Error()) - } else if info != nil && info.Progress != 100 { + if info != nil && info.Progress != 100 { torrent.InProgressIDs.Add(info.ID) t.saveTorrentChangesToDisk(torrent, nil) t.log.Infof("Torrent %s (files=%s) is still in progress after redownloading but it should be repaired once done", t.GetKey(torrent), brokenFileIDs) @@ -192,13 +191,14 @@ func (t *TorrentManager) repair(torrent *Torrent) { t.log.Infof("Successfully repaired torrent %s (files=%s) by redownloading", t.GetKey(torrent), brokenFileIDs) return } + t.log.Warnf("Cannot repair torrent %s by redownloading (error=%s)", t.GetKey(torrent), err.Error()) if torrent.UnrepairableReason != "" { t.log.Debugf("Torrent %s has been marked as unfixable during redownload (%s), ending repair process early", t.GetKey(torrent), torrent.UnrepairableReason) return } - // second step: download the broken files + // second step: download just the broken files if len(brokenFiles) == 1 && allBroken { // if all files are broken, we can't do anything @@ -207,21 +207,7 @@ func (t *TorrentManager) repair(torrent *Torrent) { return } else if len(brokenFiles) > 1 { - if !allBroken { - t.log.Infof("Repairing by downloading only the %d broken out of %d files of torrent %s", len(brokenFiles), torrent.SelectedFiles.Count(), t.GetKey(torrent)) - redownloadedInfo, err := t.redownloadTorrent(torrent, brokenFileIDs) - if err != nil { - t.log.Warnf("Cannot repair torrent %s by downloading broken files (error=%s) giving up", t.GetKey(torrent), err.Error()) - return - } - if redownloadedInfo != nil { - t.fixerAddCommand(redownloadedInfo.ID, "repaired") - return - } - t.log.Error("This is not supposed to happen, we should have repaired the torrent by now") - } - - t.log.Infof("Repairing by downloading 2 batches of the broken %d files of torrent %s", len(brokenFiles), t.GetKey(torrent)) + t.log.Infof("Repairing by downloading 2 batches of the %d broken files of torrent %s", len(brokenFiles), t.GetKey(torrent)) oldTorrentIDs := torrent.DownloadedIDs.Union(torrent.InProgressIDs).ToSlice() // divide the broken files into 2 groups @@ -254,24 +240,24 @@ func (t *TorrentManager) repair(torrent *Torrent) { return } } - - } else { - t.log.Infof("Torrent %s has no broken files to repair", t.GetKey(torrent)) } } func (t *TorrentManager) assignUnassignedLinks(torrent *Torrent) bool { - t.log.Infof("Trying to assign %d links to incomplete torrent %s", torrent.UnassignedLinks.Cardinality(), t.GetKey(torrent)) + unassignedTotal := torrent.UnassignedLinks.Cardinality() + t.log.Infof("Trying to assign %d links to the %d selected of incomplete torrent %s", unassignedTotal, torrent.SelectedFiles.Count(), t.GetKey(torrent)) // handle torrents with incomplete links for selected files assignedCount := 0 + expiredCount := 0 rarCount := 0 newUnassignedLinks := cmap.New[*realdebrid.Download]() torrent.UnassignedLinks.Each(func(link string) bool { // unrestrict each unassigned link that was filled out during torrent init unrestrict := t.UnrestrictLinkUntilOk(link) if unrestrict == nil { - newUnassignedLinks.Set(link, nil) + expiredCount++ + // newUnassignedLinks.Set(link, nil) return false // next } @@ -279,7 +265,7 @@ func (t *TorrentManager) assignUnassignedLinks(torrent *Torrent) bool { assigned := false torrent.SelectedFiles.IterCb(func(_ string, file *File) { // base it on size because why not? - if file.Bytes == unrestrict.Filesize { + if file.Bytes == unrestrict.Filesize || strings.HasSuffix(strings.ToLower(file.Path), strings.ToLower(unrestrict.Filename)) { file.Link = link file.IsBroken = false assigned = true @@ -291,12 +277,21 @@ func (t *TorrentManager) assignUnassignedLinks(torrent *Torrent) bool { // if not assigned and is a rar, likely it was rar'ed by RD if strings.HasSuffix(strings.ToLower(unrestrict.Filename), ".rar") { rarCount++ + } else { + t.log.Warnf("Cannot assign %s to any file in torrent %s", unrestrict.Filename, t.GetKey(torrent)) } newUnassignedLinks.Set(link, unrestrict) } + + processedCount := assignedCount + newUnassignedLinks.Count() + expiredCount + if processedCount%10 == 0 { + t.log.Infof("Processed %d out of %d links (%d expired) to torrent %s", processedCount, unassignedTotal, expiredCount, t.GetKey(torrent)) + } + return false }) - if assignedCount == 0 && rarCount > 0 && newUnassignedLinks.Count() > 0 { + + if assignedCount == 0 && rarCount == 1 { // this is a rar'ed torrent, nothing we can do if t.Config.ShouldDeleteRarFiles() { t.log.Warnf("Torrent %s is rar'ed and we cannot repair it, deleting it as configured", t.GetKey(torrent)) @@ -304,9 +299,9 @@ func (t *TorrentManager) assignUnassignedLinks(torrent *Torrent) bool { } else { t.log.Warnf("Torrent %s is rar'ed and we cannot repair it", t.GetKey(torrent)) newUnassignedLinks.IterCb(func(_ string, unassigned *realdebrid.Download) { - if unassigned == nil { - return - } + // if unassigned == nil { + // return + // } newFile := &File{ File: realdebrid.File{ ID: 0, @@ -326,7 +321,8 @@ func (t *TorrentManager) assignUnassignedLinks(torrent *Torrent) bool { } return false } - // empty the unassigned links as we have assigned them + + // empty/reset the unassigned links as we have assigned them already if torrent.UnassignedLinks.Cardinality() > 0 { t.saveTorrentChangesToDisk(torrent, func(info *Torrent) { info.UnassignedLinks = mapset.NewSet[string]()