Catch bw limit errors and prevent repair loops

This commit is contained in:
Ben Adrian Sarmiento
2024-06-24 00:38:57 +02:00
parent a0c13af94b
commit 449c0f71cf
5 changed files with 139 additions and 83 deletions

View File

@@ -2,6 +2,7 @@ package torrent
import (
"context"
"fmt"
"io"
"os"
"path/filepath"
@@ -11,6 +12,7 @@ import (
"github.com/debridmediamanager/zurg/internal/config"
"github.com/debridmediamanager/zurg/internal/fs"
"github.com/debridmediamanager/zurg/pkg/http"
"github.com/debridmediamanager/zurg/pkg/logutil"
"github.com/debridmediamanager/zurg/pkg/realdebrid"
"github.com/debridmediamanager/zurg/pkg/utils"
@@ -138,33 +140,34 @@ func NewTorrentManager(cfg config.ConfigInterface, api *realdebrid.RealDebrid, w
}
// proxy function
func (t *TorrentManager) UnrestrictLink(link string, verifyURL bool) *realdebrid.Download {
func (t *TorrentManager) UnrestrictFile(file *File, checkFirstByte bool) (*realdebrid.Download, error) {
if file.State.Is("deleted_file") {
return nil, fmt.Errorf("file %s has been deleted", file.Path)
} else if file.State.Is("broken_file") {
return nil, fmt.Errorf("file %s is broken", file.Path)
}
return t.UnrestrictLink(file.Link, checkFirstByte)
}
func (t *TorrentManager) UnrestrictLink(link string, verifyURL bool) (*realdebrid.Download, error) {
isRealDebrid := strings.HasPrefix(link, "https://real-debrid.com/d/")
if isRealDebrid && t.UnrestrictMap.Has(link[0:39]) {
ret, _ := t.UnrestrictMap.Get(link[0:39])
return ret
return ret, nil
} else if !isRealDebrid && t.UnrestrictMap.Has(link) {
ret, _ := t.UnrestrictMap.Get(link)
return ret
return ret, nil
}
ret, err := t.api.UnrestrictLink(link, verifyURL)
if err != nil {
t.log.Warnf("Cannot unrestrict link %s: %v", link, err)
return nil
return nil, err
}
if isRealDebrid {
t.UnrestrictMap.Set(ret.Link[0:39], ret)
} else {
t.UnrestrictMap.Set(ret.Link, ret)
}
return ret
}
func (t *TorrentManager) UnrestrictFile(file *File, checkFirstByte bool) *realdebrid.Download {
if !file.State.Is("ok_file") {
return nil
}
return t.UnrestrictLink(file.Link, checkFirstByte)
return ret, nil
}
func (t *TorrentManager) GetKey(torrent *Torrent) string {
@@ -228,14 +231,22 @@ func (t *TorrentManager) writeTorrentToFile(torrent *Torrent) {
// t.log.Debugf("Saved torrent %s to file", t.GetKey(torrent))
}
func (t *TorrentManager) applyMediaInfoDetails(torrent *Torrent) {
func (t *TorrentManager) applyMediaInfoDetails(torrent *Torrent) error {
changesApplied := false
bwLimitReached := false
torrent.SelectedFiles.IterCb(func(_ string, file *File) {
if bwLimitReached {
return
}
isPlayable := utils.IsVideo(file.Path) || t.IsPlayable(file.Path)
if file.MediaInfo != nil || !file.State.Is("ok_file") || !isPlayable {
return
}
unrestrict := t.UnrestrictFile(file, true)
unrestrict, err := t.UnrestrictFile(file, true)
if dlErr, ok := err.(*http.DownloadErrorResponse); ok && dlErr.Message == "bytes_limit_reached" {
bwLimitReached = true
return
}
if unrestrict == nil {
file.State.Event(context.Background(), "break_file")
t.EnqueueForRepair(torrent)
@@ -253,9 +264,13 @@ func (t *TorrentManager) applyMediaInfoDetails(torrent *Torrent) {
changesApplied = true
})
if changesApplied {
t.assignDirectory(torrent, true)
t.writeTorrentToFile(torrent)
}
if bwLimitReached {
t.log.Warnf("Your account has reached the bandwidth limit, cannot apply media info details to the rest of the files")
return fmt.Errorf("bandwidth limit reached")
}
return nil
}
func (t *TorrentManager) readTorrentFromFile(filePath string) *Torrent {
@@ -437,11 +452,22 @@ func (t *TorrentManager) analyzeAllTorrents() {
totalCount := allTorrents.Count()
t.log.Infof("Applying media info details to all %d torrents", totalCount)
idx := 0
skipTheRest := false
allTorrents.IterCb(func(_ string, torrent *Torrent) {
t.applyMediaInfoDetails(torrent)
if skipTheRest {
return
}
err := t.applyMediaInfoDetails(torrent)
if err != nil && err.Error() == "bandwidth limit reached" {
skipTheRest = true
return
}
idx++
t.log.Debugf("Applied media info details to torrent %s (%d/%d)", t.GetKey(torrent), idx, totalCount)
})
if skipTheRest {
t.log.Warnf("Bandwidth limit reached, skipped the rest of the torrents")
}
}
// StartMediaAnalysisJob: permanent job for analyzing media info (triggered by the user)