From 7b1e34c7059772fa419d7d42997bb268b33a4405 Mon Sep 17 00:00:00 2001 From: Ben Sarmiento Date: Fri, 19 Jan 2024 03:02:21 +0100 Subject: [PATCH] Fixers and repairs --- internal/torrent/manager.go | 8 ++++---- internal/torrent/refresh.go | 30 ++++++++++++++++++++++-------- internal/torrent/repair.go | 10 +++++----- pkg/realdebrid/types.go | 4 ++++ 4 files changed, 35 insertions(+), 17 deletions(-) diff --git a/internal/torrent/manager.go b/internal/torrent/manager.go index bb6aa40..42a8589 100644 --- a/internal/torrent/manager.go +++ b/internal/torrent/manager.go @@ -27,8 +27,8 @@ type TorrentManager struct { DirectoryMap cmap.ConcurrentMap[string, cmap.ConcurrentMap[string, *Torrent]] // directory -> accessKey -> Torrent DownloadCache cmap.ConcurrentMap[string, *realdebrid.Download] DownloadMap cmap.ConcurrentMap[string, *realdebrid.Download] - onlyForRepair cmap.ConcurrentMap[string, *Torrent] - Repairs mapset.Set[string] + fixers cmap.ConcurrentMap[string, *Torrent] + repairs mapset.Set[string] allAccessKeys mapset.Set[string] latestState *LibraryState requiredVersion string @@ -47,8 +47,8 @@ func NewTorrentManager(cfg config.ConfigInterface, api *realdebrid.RealDebrid, w DirectoryMap: cmap.New[cmap.ConcurrentMap[string, *Torrent]](), DownloadCache: cmap.New[*realdebrid.Download](), DownloadMap: cmap.New[*realdebrid.Download](), - onlyForRepair: cmap.New[*Torrent](), - Repairs: mapset.NewSet[string](), + fixers: cmap.New[*Torrent](), + repairs: mapset.NewSet[string](), allAccessKeys: mapset.NewSet[string](), latestState: &LibraryState{}, requiredVersion: "11.01.2024", diff --git a/internal/torrent/refresh.go b/internal/torrent/refresh.go index 6267af0..96aef03 100644 --- a/internal/torrent/refresh.go +++ b/internal/torrent/refresh.go @@ -28,16 +28,30 @@ func (t *TorrentManager) RefreshTorrents() []string { wg.Add(1) _ = t.workerPool.Submit(func() { defer wg.Done() - if instances[idx].Progress == 100 && t.onlyForRepair.Has(instances[idx].ID) { - torrent, _ := t.onlyForRepair.Get(instances[idx].ID) + if instances[idx].IsDone() && t.fixers.Has(instances[idx].ID) { + fixer := instances[idx] + torrent, _ := t.fixers.Pop(fixer.ID) brokenFiles := getBrokenFiles(torrent) info, err := t.redownloadTorrent(torrent, "") - if err == nil && info.IsDone() && !t.isStillBroken(info, brokenFiles) { - t.Api.DeleteTorrent(instances[idx].ID) - t.onlyForRepair.Remove(instances[idx].ID) + if err == nil { + if info.IsDone() { + if t.isStillBroken(info, brokenFiles) { + t.log.Warnf("Fixer is done but torrent %s is still broken; let's keep the fixer", t.GetKey(torrent)) + infoChan <- t.getMoreInfo(fixer) + return + } else { + t.log.Infof("Fixer resolved issues for torrent %s, broken files are repaired", t.GetKey(torrent)) + } + } else { + t.log.Warnf("Torrent %s is still not done after redownload; likely the fixer did its job", t.GetKey(torrent)) + } + t.Api.DeleteTorrent(fixer.ID) // delete the fixer + infoChan <- nil + return + } else { + t.log.Warnf("Cannot redownload torrent %s after fixer is done: %v", t.GetKey(torrent), err) } - infoChan <- nil - } else { + } else if !t.fixers.Has(instances[idx].ID) { infoChan <- t.getMoreInfo(instances[idx]) } }) @@ -204,7 +218,7 @@ func (t *TorrentManager) getMoreInfo(rdTorrent realdebrid.Torrent) *Torrent { } torrent.DownloadedIDs = mapset.NewSet[string]() torrent.InProgressIDs = mapset.NewSet[string]() - if info.Progress == 100 { + if info.IsDone() { torrent.DownloadedIDs.Add(info.ID) } else { torrent.InProgressIDs.Add(info.ID) diff --git a/internal/torrent/repair.go b/internal/torrent/repair.go index 5a99a8d..73add72 100644 --- a/internal/torrent/repair.go +++ b/internal/torrent/repair.go @@ -104,11 +104,11 @@ func (t *TorrentManager) Repair(torrent *Torrent) { t.log.Warnf("Torrent %s is unfixable, skipping repair", t.GetKey(torrent)) return } - if t.Repairs.Contains(t.GetKey(torrent)) { + if t.repairs.Contains(t.GetKey(torrent)) { t.log.Warnf("Torrent %s is already being repaired, skipping repair", t.GetKey(torrent)) return } - t.Repairs.Add(t.GetKey(torrent)) + t.repairs.Add(t.GetKey(torrent)) // save the broken files to the file cache infoCache, _ := t.DirectoryMap.Get(INT_INFO_CACHE) torrent.DownloadedIDs.Each(func(id string) bool { @@ -126,7 +126,7 @@ func (t *TorrentManager) Repair(torrent *Torrent) { }) _ = t.workerPool.Submit(func() { t.repair(torrent) - t.Repairs.Remove(t.GetKey(torrent)) + t.repairs.Remove(t.GetKey(torrent)) }) } @@ -312,7 +312,7 @@ func (t *TorrentManager) redownloadTorrent(torrent *Torrent, brokenFiles string) t.Api.DeleteTorrent(id) } } else { - t.onlyForRepair.Set(newTorrentID, torrent) + t.fixers.Set(newTorrentID, torrent) } return info, nil } @@ -330,7 +330,7 @@ func (t *TorrentManager) redownloadTorrent(torrent *Torrent, brokenFiles string) t.Api.DeleteTorrent(id) } } else { - t.onlyForRepair.Set(newTorrentID, torrent) + t.fixers.Set(newTorrentID, torrent) } return info, nil } diff --git a/pkg/realdebrid/types.go b/pkg/realdebrid/types.go index 79ac035..600c4d0 100644 --- a/pkg/realdebrid/types.go +++ b/pkg/realdebrid/types.go @@ -50,6 +50,10 @@ type Torrent struct { Added string `json:"-"` } +func (i *Torrent) IsDone() bool { + return i.Progress == 100 && len(i.Links) > 0 +} + func (i *Torrent) UnmarshalJSON(data []byte) error { type Alias Torrent aux := &struct {