Fixers and repairs

This commit is contained in:
Ben Sarmiento
2024-01-19 03:02:21 +01:00
parent c0b9fc8c55
commit 7b1e34c705
4 changed files with 35 additions and 17 deletions

View File

@@ -27,8 +27,8 @@ type TorrentManager struct {
DirectoryMap cmap.ConcurrentMap[string, cmap.ConcurrentMap[string, *Torrent]] // directory -> accessKey -> Torrent DirectoryMap cmap.ConcurrentMap[string, cmap.ConcurrentMap[string, *Torrent]] // directory -> accessKey -> Torrent
DownloadCache cmap.ConcurrentMap[string, *realdebrid.Download] DownloadCache cmap.ConcurrentMap[string, *realdebrid.Download]
DownloadMap cmap.ConcurrentMap[string, *realdebrid.Download] DownloadMap cmap.ConcurrentMap[string, *realdebrid.Download]
onlyForRepair cmap.ConcurrentMap[string, *Torrent] fixers cmap.ConcurrentMap[string, *Torrent]
Repairs mapset.Set[string] repairs mapset.Set[string]
allAccessKeys mapset.Set[string] allAccessKeys mapset.Set[string]
latestState *LibraryState latestState *LibraryState
requiredVersion string requiredVersion string
@@ -47,8 +47,8 @@ func NewTorrentManager(cfg config.ConfigInterface, api *realdebrid.RealDebrid, w
DirectoryMap: cmap.New[cmap.ConcurrentMap[string, *Torrent]](), DirectoryMap: cmap.New[cmap.ConcurrentMap[string, *Torrent]](),
DownloadCache: cmap.New[*realdebrid.Download](), DownloadCache: cmap.New[*realdebrid.Download](),
DownloadMap: cmap.New[*realdebrid.Download](), DownloadMap: cmap.New[*realdebrid.Download](),
onlyForRepair: cmap.New[*Torrent](), fixers: cmap.New[*Torrent](),
Repairs: mapset.NewSet[string](), repairs: mapset.NewSet[string](),
allAccessKeys: mapset.NewSet[string](), allAccessKeys: mapset.NewSet[string](),
latestState: &LibraryState{}, latestState: &LibraryState{},
requiredVersion: "11.01.2024", requiredVersion: "11.01.2024",

View File

@@ -28,16 +28,30 @@ func (t *TorrentManager) RefreshTorrents() []string {
wg.Add(1) wg.Add(1)
_ = t.workerPool.Submit(func() { _ = t.workerPool.Submit(func() {
defer wg.Done() defer wg.Done()
if instances[idx].Progress == 100 && t.onlyForRepair.Has(instances[idx].ID) { if instances[idx].IsDone() && t.fixers.Has(instances[idx].ID) {
torrent, _ := t.onlyForRepair.Get(instances[idx].ID) fixer := instances[idx]
torrent, _ := t.fixers.Pop(fixer.ID)
brokenFiles := getBrokenFiles(torrent) brokenFiles := getBrokenFiles(torrent)
info, err := t.redownloadTorrent(torrent, "") info, err := t.redownloadTorrent(torrent, "")
if err == nil && info.IsDone() && !t.isStillBroken(info, brokenFiles) { if err == nil {
t.Api.DeleteTorrent(instances[idx].ID) if info.IsDone() {
t.onlyForRepair.Remove(instances[idx].ID) 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 <- nil infoChan <- t.getMoreInfo(fixer)
return
} else { } 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)
}
} else if !t.fixers.Has(instances[idx].ID) {
infoChan <- t.getMoreInfo(instances[idx]) infoChan <- t.getMoreInfo(instances[idx])
} }
}) })
@@ -204,7 +218,7 @@ func (t *TorrentManager) getMoreInfo(rdTorrent realdebrid.Torrent) *Torrent {
} }
torrent.DownloadedIDs = mapset.NewSet[string]() torrent.DownloadedIDs = mapset.NewSet[string]()
torrent.InProgressIDs = mapset.NewSet[string]() torrent.InProgressIDs = mapset.NewSet[string]()
if info.Progress == 100 { if info.IsDone() {
torrent.DownloadedIDs.Add(info.ID) torrent.DownloadedIDs.Add(info.ID)
} else { } else {
torrent.InProgressIDs.Add(info.ID) torrent.InProgressIDs.Add(info.ID)

View File

@@ -104,11 +104,11 @@ func (t *TorrentManager) Repair(torrent *Torrent) {
t.log.Warnf("Torrent %s is unfixable, skipping repair", t.GetKey(torrent)) t.log.Warnf("Torrent %s is unfixable, skipping repair", t.GetKey(torrent))
return 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)) t.log.Warnf("Torrent %s is already being repaired, skipping repair", t.GetKey(torrent))
return return
} }
t.Repairs.Add(t.GetKey(torrent)) t.repairs.Add(t.GetKey(torrent))
// save the broken files to the file cache // save the broken files to the file cache
infoCache, _ := t.DirectoryMap.Get(INT_INFO_CACHE) infoCache, _ := t.DirectoryMap.Get(INT_INFO_CACHE)
torrent.DownloadedIDs.Each(func(id string) bool { torrent.DownloadedIDs.Each(func(id string) bool {
@@ -126,7 +126,7 @@ func (t *TorrentManager) Repair(torrent *Torrent) {
}) })
_ = t.workerPool.Submit(func() { _ = t.workerPool.Submit(func() {
t.repair(torrent) 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) t.Api.DeleteTorrent(id)
} }
} else { } else {
t.onlyForRepair.Set(newTorrentID, torrent) t.fixers.Set(newTorrentID, torrent)
} }
return info, nil return info, nil
} }
@@ -330,7 +330,7 @@ func (t *TorrentManager) redownloadTorrent(torrent *Torrent, brokenFiles string)
t.Api.DeleteTorrent(id) t.Api.DeleteTorrent(id)
} }
} else { } else {
t.onlyForRepair.Set(newTorrentID, torrent) t.fixers.Set(newTorrentID, torrent)
} }
return info, nil return info, nil
} }

View File

@@ -50,6 +50,10 @@ type Torrent struct {
Added string `json:"-"` Added string `json:"-"`
} }
func (i *Torrent) IsDone() bool {
return i.Progress == 100 && len(i.Links) > 0
}
func (i *Torrent) UnmarshalJSON(data []byte) error { func (i *Torrent) UnmarshalJSON(data []byte) error {
type Alias Torrent type Alias Torrent
aux := &struct { aux := &struct {