Catch bw limit errors and prevent repair loops
This commit is contained in:
@@ -9,6 +9,7 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/debridmediamanager/zurg/internal/config"
|
||||
"github.com/debridmediamanager/zurg/pkg/http"
|
||||
"github.com/debridmediamanager/zurg/pkg/realdebrid"
|
||||
"github.com/debridmediamanager/zurg/pkg/utils"
|
||||
mapset "github.com/deckarep/golang-set/v2"
|
||||
@@ -189,16 +190,30 @@ func (t *TorrentManager) repair(torrent *Torrent, wg *sync.WaitGroup) {
|
||||
return
|
||||
}
|
||||
|
||||
bwLimitReached := false
|
||||
// check for other broken file
|
||||
torrent.SelectedFiles.IterCb(func(_ string, file *File) {
|
||||
if bwLimitReached {
|
||||
return
|
||||
}
|
||||
if !file.State.Is("ok_file") {
|
||||
return
|
||||
}
|
||||
if t.UnrestrictFile(file, true) == nil {
|
||||
_, err := t.UnrestrictFile(file, true)
|
||||
if dlErr, ok := err.(*http.DownloadErrorResponse); ok && dlErr.Message == "bytes_limit_reached" {
|
||||
bwLimitReached = true
|
||||
return
|
||||
}
|
||||
if err != nil {
|
||||
file.State.Event(context.Background(), "break_file")
|
||||
}
|
||||
})
|
||||
|
||||
if bwLimitReached {
|
||||
t.repairLog.Warnf("Your account has reached the bandwidth limit, cannot continue repairing torrent %s", t.GetKey(torrent))
|
||||
return
|
||||
}
|
||||
|
||||
brokenFiles, allBroken := t.getBrokenFiles(torrent)
|
||||
|
||||
// check if broken files are playable
|
||||
@@ -240,7 +255,12 @@ func (t *TorrentManager) repair(torrent *Torrent, wg *sync.WaitGroup) {
|
||||
|
||||
info, err := t.redownloadTorrent(torrent, []string{}) // reinsert the whole torrent, passing empty selection
|
||||
if info != nil && info.Progress == 100 {
|
||||
if !t.isStillBroken(info, brokenFiles) {
|
||||
err = t.checkIfBroken(info, brokenFiles)
|
||||
if dlErr, ok := err.(*http.DownloadErrorResponse); ok && dlErr.Message == "bytes_limit_reached" {
|
||||
t.repairLog.Warnf("Your account has reached the bandwidth limit, cannot continue repairing torrent %s", t.GetKey(torrent))
|
||||
return
|
||||
}
|
||||
if err == nil {
|
||||
// delete the torrents it replaced
|
||||
oldDownloadedIDs.Each(func(torrentID string) bool {
|
||||
t.DeleteByID(torrentID)
|
||||
@@ -249,10 +269,7 @@ func (t *TorrentManager) repair(torrent *Torrent, wg *sync.WaitGroup) {
|
||||
t.repairLog.Infof("Successfully repaired torrent %s by redownloading whole torrent", t.GetKey(torrent))
|
||||
return
|
||||
}
|
||||
|
||||
// if it's still broken, let's delete the newly downloaded torrent
|
||||
t.DeleteByID(info.ID)
|
||||
err = fmt.Errorf("links are still broken")
|
||||
|
||||
} else if info != nil && info.Progress != 100 {
|
||||
// it's faster to download just the broken files, so let's delete the newly downloaded torrent
|
||||
@@ -322,9 +339,14 @@ func (t *TorrentManager) assignLinks(torrent *Torrent) bool {
|
||||
newUnassignedLinks := cmap.New[*realdebrid.Download]()
|
||||
var assignedLinks []string
|
||||
|
||||
bwLimitReached := false
|
||||
torrent.UnassignedLinks.Clone().Each(func(link string) bool {
|
||||
// unrestrict each unassigned link that was filled out during torrent init
|
||||
unrestrict := t.UnrestrictLink(link, true)
|
||||
unrestrict, err := t.UnrestrictLink(link, true)
|
||||
if dlErr, ok := err.(*http.DownloadErrorResponse); ok && dlErr.Message == "bytes_limit_reached" {
|
||||
bwLimitReached = true
|
||||
return true
|
||||
}
|
||||
if unrestrict == nil {
|
||||
expiredCount++
|
||||
return false // next unassigned link
|
||||
@@ -376,6 +398,11 @@ func (t *TorrentManager) assignLinks(torrent *Torrent) bool {
|
||||
return false // next unassigned link
|
||||
})
|
||||
|
||||
if bwLimitReached {
|
||||
t.repairLog.Warnf("Your account has reached the bandwidth limit, cannot continue assigning links to torrent %s", t.GetKey(torrent))
|
||||
return false
|
||||
}
|
||||
|
||||
// empty/reset the unassigned links as we have assigned them already
|
||||
if unassignedTotal > 0 {
|
||||
torrent.UnassignedLinks = mapset.NewSet[string]()
|
||||
@@ -617,9 +644,9 @@ func (t *TorrentManager) getBrokenFiles(torrent *Torrent) ([]*File, bool) {
|
||||
return brokenFiles, allBroken
|
||||
}
|
||||
|
||||
// isStillBroken checks if the torrent is still broken
|
||||
// checkIfBroken checks if the torrent is still broken
|
||||
// if it's not broken anymore, it will assign the links to the files
|
||||
func (t *TorrentManager) isStillBroken(info *realdebrid.TorrentInfo, brokenFiles []*File) bool {
|
||||
func (t *TorrentManager) checkIfBroken(info *realdebrid.TorrentInfo, brokenFiles []*File) error {
|
||||
var selectedFiles []*File
|
||||
for _, file := range info.Files {
|
||||
if file.Selected == 0 {
|
||||
@@ -633,7 +660,7 @@ func (t *TorrentManager) isStillBroken(info *realdebrid.TorrentInfo, brokenFiles
|
||||
})
|
||||
}
|
||||
if len(selectedFiles) != len(info.Links) {
|
||||
return true
|
||||
return fmt.Errorf("number of selected files and links do not match")
|
||||
}
|
||||
|
||||
for i, file := range selectedFiles {
|
||||
@@ -652,12 +679,15 @@ func (t *TorrentManager) isStillBroken(info *realdebrid.TorrentInfo, brokenFiles
|
||||
// check if the broken files can now be unrestricted and downloaded
|
||||
for _, oldFile := range brokenFiles {
|
||||
for idx, newFile := range selectedFiles {
|
||||
if oldFile.ID == newFile.ID && t.UnrestrictFile(selectedFiles[idx], true) == nil {
|
||||
return true
|
||||
if oldFile.ID != newFile.ID {
|
||||
continue
|
||||
}
|
||||
if _, err := t.UnrestrictFile(selectedFiles[idx], true); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
return false
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t *TorrentManager) ResetRepairState() {
|
||||
|
||||
Reference in New Issue
Block a user