Rework repairs again
This commit is contained in:
@@ -173,13 +173,13 @@ func (t *TorrentManager) repair(torrent *Torrent) {
|
||||
t.log.Debugf("Torrent %s has %d broken out of %d files", t.GetKey(torrent), len(brokenFiles), torrent.SelectedFiles.Count())
|
||||
brokenFileIDs := getFileIDs(brokenFiles)
|
||||
|
||||
// first solution: reinsert and see if the broken file is now working
|
||||
t.log.Debugf("repair_method#1: Redownloading whole torrent %s", t.GetKey(torrent))
|
||||
// first step: redownload the whole torrent
|
||||
t.log.Debugf("Repairing torrent %s by redownloading", t.GetKey(torrent))
|
||||
info, err := t.redownloadTorrent(torrent, "") // reinsert the torrent, passing ""
|
||||
if err != nil {
|
||||
t.log.Warnf("repair_method#1: Cannot repair torrent %s (error=%s)", t.GetKey(torrent), err.Error())
|
||||
t.log.Warnf("Cannot repair torrent %s by redownloading (error=%s)", t.GetKey(torrent), err.Error())
|
||||
} else if info != nil && info.Progress != 100 {
|
||||
t.log.Infof("repair_method#1: Torrent %s is still in progress but it should work once done (torrent is temporarily hidden until download has completed)", t.GetKey(torrent))
|
||||
t.log.Infof("Torrent %s is still in progress after redownloading but it should be repaired once done", t.GetKey(torrent))
|
||||
return
|
||||
} else if info != nil && info.IsDone() && !t.isStillBroken(info, brokenFiles) {
|
||||
selectedFiles := getSelectedFiles(info)
|
||||
@@ -192,28 +192,34 @@ func (t *TorrentManager) repair(torrent *Torrent) {
|
||||
}
|
||||
})
|
||||
t.saveTorrentChangesToDisk(torrent, nil)
|
||||
t.log.Infof("Successfully repaired torrent %s using repair_method#1", t.GetKey(torrent))
|
||||
t.log.Infof("Successfully repaired torrent %s by redownloading", t.GetKey(torrent))
|
||||
return
|
||||
}
|
||||
|
||||
if torrent.UnrepairableReason != "" {
|
||||
t.log.Debugf("Torrent %s has been marked as unfixable during repair_method#1 (%s), ending repair process early", t.GetKey(torrent), 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
|
||||
}
|
||||
|
||||
if len(brokenFiles) == torrent.SelectedFiles.Count() {
|
||||
t.log.Warnf("Torrent %s has all broken files, marking as unplayable", t.GetKey(torrent))
|
||||
// all files are broken, nothing we can do
|
||||
t.log.Warnf("Torrent %s has broken cached files (cached but cannot be downloaded), you can repair it manually, marking as unfixable", t.GetKey(torrent))
|
||||
t.markAsUnfixable(torrent, "broken cache")
|
||||
return
|
||||
}
|
||||
|
||||
// second solution: add only the broken files
|
||||
// second step: download the broken files
|
||||
if len(brokenFiles) > 0 {
|
||||
t.log.Infof("repair_method#2: Redownloading %dof%d files only for torrent %s", len(brokenFiles), torrent.SelectedFiles.Count(), t.GetKey(torrent))
|
||||
_, err := t.redownloadTorrent(torrent, brokenFileIDs)
|
||||
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))
|
||||
info, err := t.redownloadTorrent(torrent, brokenFileIDs)
|
||||
if err != nil {
|
||||
t.log.Warnf("repair_method#2: Cannot repair torrent %s (error=%s)", t.GetKey(torrent), err.Error())
|
||||
t.log.Warnf("Cannot repair torrent %s by downloading broken files (error=%s) giving up", t.GetKey(torrent), err.Error())
|
||||
return
|
||||
}
|
||||
if info != nil {
|
||||
t.fixerAddCommand(info.ID, "repair")
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
t.log.Infof("Torrent %s has no broken files to repair", t.GetKey(torrent))
|
||||
@@ -298,7 +304,7 @@ func (t *TorrentManager) redownloadTorrent(torrent *Torrent, selection string) (
|
||||
oldTorrentIDs := make([]string, 0)
|
||||
if selection == "" {
|
||||
// only delete the old torrent if we are redownloading all files
|
||||
oldTorrentIDs = torrent.DownloadedIDs.ToSlice()
|
||||
oldTorrentIDs = torrent.DownloadedIDs.Union(torrent.InProgressIDs).ToSlice()
|
||||
tmpSelection := ""
|
||||
torrent.SelectedFiles.IterCb(func(_ string, file *File) {
|
||||
tmpSelection += fmt.Sprintf("%d,", file.ID) // select all files
|
||||
@@ -336,7 +342,7 @@ func (t *TorrentManager) redownloadTorrent(torrent *Torrent, selection string) (
|
||||
newTorrentID := resp.ID
|
||||
err = t.Api.SelectTorrentFiles(newTorrentID, selection)
|
||||
if err != nil {
|
||||
t.Api.DeleteTorrent(newTorrentID)
|
||||
t.fixerAddCommand(newTorrentID, "delete")
|
||||
return nil, fmt.Errorf("cannot start redownloading: %v", err)
|
||||
}
|
||||
|
||||
@@ -346,7 +352,7 @@ func (t *TorrentManager) redownloadTorrent(torrent *Torrent, selection string) (
|
||||
// see if the torrent is ready
|
||||
info, err := t.Api.GetTorrentInfo(newTorrentID)
|
||||
if err != nil {
|
||||
t.Api.DeleteTorrent(newTorrentID)
|
||||
t.fixerAddCommand(newTorrentID, "delete")
|
||||
return nil, fmt.Errorf("cannot get info on redownloaded torrent %s (id=%s) : %v", t.GetKey(torrent), newTorrentID, err)
|
||||
}
|
||||
|
||||
@@ -361,30 +367,29 @@ func (t *TorrentManager) redownloadTorrent(torrent *Torrent, selection string) (
|
||||
}
|
||||
}
|
||||
if !isOkStatus {
|
||||
t.Api.DeleteTorrent(newTorrentID)
|
||||
t.fixerAddCommand(newTorrentID, "delete")
|
||||
return nil, fmt.Errorf("the redownloaded torrent %s (id=%s) is in error state: %s", t.GetKey(torrent), newTorrentID, info.Status)
|
||||
}
|
||||
|
||||
// check if incorrect number of links
|
||||
selectionCount := len(strings.Split(selection, ","))
|
||||
if info.Progress == 100 && len(info.Links) != selectionCount {
|
||||
t.Api.DeleteTorrent(newTorrentID)
|
||||
t.fixerAddCommand(newTorrentID, "delete")
|
||||
return nil, fmt.Errorf("it did not fix the issue for %s (id=%s), only got %d files but we need %d, undoing", t.GetKey(torrent), info.ID, len(info.Links), selectionCount)
|
||||
}
|
||||
|
||||
// looks like it's fixed
|
||||
|
||||
if len(oldTorrentIDs) > 0 {
|
||||
// replace the old torrent
|
||||
// replace the old torrent (empty selection)
|
||||
infoCache, _ := t.DirectoryMap.Get(INT_INFO_CACHE)
|
||||
for _, id := range oldTorrentIDs {
|
||||
t.log.Debugf("Deleting torrent %s (id=%s) to replace with repaired torrent", t.GetKey(torrent), id)
|
||||
torrent.DownloadedIDs.Remove(id)
|
||||
t.Api.DeleteTorrent(id)
|
||||
infoCache.Remove(id)
|
||||
t.deleteTorrentFile(id)
|
||||
}
|
||||
} else {
|
||||
// it's a fixer
|
||||
t.fixers.Set(newTorrentID, torrent)
|
||||
}
|
||||
return info, nil
|
||||
}
|
||||
@@ -503,48 +508,6 @@ func (t *TorrentManager) isStillBroken(info *realdebrid.TorrentInfo, brokenFiles
|
||||
return false
|
||||
}
|
||||
|
||||
func (t *TorrentManager) handleFixers(fixer realdebrid.Torrent) *Torrent {
|
||||
// since fixer is done, we can pop it from the fixers set
|
||||
torrent, _ := t.fixers.Pop(fixer.ID)
|
||||
if torrent == nil {
|
||||
t.log.Warnf("repair_method#2: Fixer for %s (id=%s) is done but torrent has been deleted, deleting fixer...", fixer.Name, fixer.ID)
|
||||
t.Api.DeleteTorrent(fixer.ID)
|
||||
return nil
|
||||
}
|
||||
|
||||
brokenFiles := getBrokenFiles(torrent)
|
||||
info, err := t.redownloadTorrent(torrent, "") // reinsert
|
||||
if err != nil {
|
||||
t.log.Warnf("repair_method#2: Cannot repair torrent %s (error=%s)", t.GetKey(torrent), err.Error())
|
||||
return nil
|
||||
}
|
||||
|
||||
if info.IsDone() {
|
||||
if !t.isStillBroken(info, brokenFiles) {
|
||||
selectedFiles := getSelectedFiles(info)
|
||||
torrent.SelectedFiles.IterCb(func(_ string, oldFile *File) {
|
||||
for _, newFile := range selectedFiles {
|
||||
if oldFile.Bytes == newFile.Bytes {
|
||||
oldFile.Link = newFile.Link
|
||||
break
|
||||
}
|
||||
}
|
||||
})
|
||||
t.saveTorrentChangesToDisk(torrent, nil)
|
||||
t.log.Infof("Successfully repaired torrent %s using repair_method#2", t.GetKey(torrent))
|
||||
} else {
|
||||
t.log.Warnf("repair_method#2: Fixer is done but torrent %s is still broken; let's keep the fixer", t.GetKey(torrent))
|
||||
t.Api.DeleteTorrent(info.ID)
|
||||
return t.getMoreInfo(fixer)
|
||||
}
|
||||
} else {
|
||||
t.log.Infof("repair_method#2: Torrent %s is still in progress but it should work once done (torrent is temporarily hidden until download has completed)", t.GetKey(torrent))
|
||||
}
|
||||
|
||||
t.Api.DeleteTorrent(fixer.ID) // delete the fixer
|
||||
return nil
|
||||
}
|
||||
|
||||
func getSelectedFiles(info *realdebrid.TorrentInfo) []*File {
|
||||
var selectedFiles []*File
|
||||
// if some Links are empty, we need to repair it
|
||||
|
||||
Reference in New Issue
Block a user