diff --git a/internal/torrent/refresh.go b/internal/torrent/refresh.go index 9dc7e2d..d23b052 100644 --- a/internal/torrent/refresh.go +++ b/internal/torrent/refresh.go @@ -37,31 +37,26 @@ func (t *TorrentManager) RefreshTorrents() []string { freshKeys := mapset.NewSet[string]() allTorrents, _ := t.DirectoryMap.Get(INT_ALL) - toReinsert := mapset.NewSet[string]() noInfoCount := 0 for info := range infoChan { if info == nil { noInfoCount++ continue } - torrentIDs := info.DownloadedIDs.ToSlice() - if !info.AnyInProgress() && len(torrentIDs) > 0 && t.onlyForRepair.Contains(info.DownloadedIDs.ToSlice()[0]) { - torrentID := info.DownloadedIDs.ToSlice()[0] - // if it's 100% and it's a temp repair, remove it - t.Api.DeleteTorrent(torrentID) - toReinsert.Add(t.GetKey(info)) - infoChan <- nil - t.onlyForRepair.Remove(torrentID) + + accessKey := t.GetKey(info) + + if t.handleRepairTorrents(info) { continue } if !info.AnyInProgress() { - freshKeys.Add(t.GetKey(info)) + freshKeys.Add(accessKey) } - if torrent, exists := allTorrents.Get(t.GetKey(info)); !exists { - allTorrents.Set(t.GetKey(info), info) + if torrent, exists := allTorrents.Get(accessKey); !exists { + allTorrents.Set(accessKey, info) } else if !info.DownloadedIDs.Difference(torrent.DownloadedIDs).IsEmpty() { mainTorrent := t.mergeToMain(torrent, info) - allTorrents.Set(t.GetKey(info), &mainTorrent) + allTorrents.Set(accessKey, &mainTorrent) } } t.log.Infof("Compiled into %d torrents, %d were missing info", allTorrents.Count(), noInfoCount) @@ -94,12 +89,6 @@ func (t *TorrentManager) RefreshTorrents() []string { return false }) - toReinsert.Each(func(accessKey string) bool { - torrent, _ := allTorrents.Get(accessKey) - t.reinsertTorrent(torrent, "") - return false - }) - return updatedPaths } diff --git a/internal/torrent/repair.go b/internal/torrent/repair.go index 7b65ea7..17704d3 100644 --- a/internal/torrent/repair.go +++ b/internal/torrent/repair.go @@ -216,7 +216,7 @@ func (t *TorrentManager) repair(torrent *Torrent) { if len(brokenFiles) > 0 { t.log.Infof("Redownloading %dof%d files for torrent %s", len(brokenFiles), torrent.SelectedFiles.Count(), t.GetKey(torrent)) brokenFileIDs := strings.Join(getFileIDs(brokenFiles), ",") - if t.reinsertTorrent(torrent, brokenFileIDs) { + if t.redownloadTorrent(torrent, brokenFileIDs) { t.log.Infof("Successfully downloaded torrent %s to repair it", t.GetKey(torrent)) } else { t.log.Warnf("Cannot repair torrent %s", t.GetKey(torrent)) @@ -226,14 +226,15 @@ func (t *TorrentManager) repair(torrent *Torrent) { } } -func (t *TorrentManager) reinsertTorrent(torrent *Torrent, brokenFiles string) bool { - // broken files means broken links +func (t *TorrentManager) redownloadTorrent(torrent *Torrent, brokenFiles string) bool { + t.log.Debugf("Redownloading torrent %s, broken files=%s (all if empty)", t.GetKey(torrent), brokenFiles) oldTorrentIDs := make([]string, 0) + // broken files means broken links // if brokenFiles is not provided if brokenFiles == "" { - // only replace the torrent if we are reinserting all files + // only replace the torrent if we are redownloading all files oldTorrentIDs = torrent.DownloadedIDs.ToSlice() tmpSelection := "" torrent.SelectedFiles.IterCb(func(_ string, file *File) { @@ -310,7 +311,7 @@ func (t *TorrentManager) reinsertTorrent(torrent *Torrent, brokenFiles string) b return false } - t.log.Infof("Repair successful id=%s", newTorrentID) + t.log.Infof("Redownload successful id=%s", newTorrentID) t.onlyForRepair.Add(newTorrentID) if len(oldTorrentIDs) > 0 { for _, id := range oldTorrentIDs { @@ -385,3 +386,30 @@ func (t *TorrentManager) markAsUnfixable(torrent *Torrent) { return false }) } + +func (t *TorrentManager) handleRepairTorrents(info *Torrent) bool { + allTorrents, _ := t.DirectoryMap.Get(INT_ALL) + accessKey := t.GetKey(info) + torrentIDs := info.DownloadedIDs.ToSlice() + inRepairList := false + for _, torrentID := range torrentIDs { + if t.onlyForRepair.Contains(torrentID) { + inRepairList = true + break + } + } + if !info.AnyInProgress() && inRepairList { + t.log.Debugf("Newly downloaded %s (id=%s) is in repair list", info.Name, torrentIDs[0]) + torrent, stillExists := allTorrents.Get(accessKey) + if stillExists && t.redownloadTorrent(torrent, "") { + t.log.Debugf("Deleting repair temp id=%s because it has served its purpose", torrentIDs[0]) + // if it's 100% and it's a temp repair, remove it + for _, torrentID := range torrentIDs { + t.Api.DeleteTorrent(torrentID) + t.onlyForRepair.Remove(torrentID) + } + return true + } + } + return false +}