repair fixes!

This commit is contained in:
Ben Sarmiento
2023-11-19 01:04:48 +01:00
parent d77caa7575
commit 0b21b8d58c
6 changed files with 47 additions and 40 deletions

View File

@@ -15,7 +15,7 @@ import (
"github.com/debridmediamanager.com/zurg/internal/version" "github.com/debridmediamanager.com/zurg/internal/version"
"github.com/panjf2000/ants/v2" "github.com/panjf2000/ants/v2"
// zurghttp "github.com/debridmediamanager.com/zurg/pkg/http" zurghttp "github.com/debridmediamanager.com/zurg/pkg/http"
"github.com/debridmediamanager.com/zurg/pkg/logutil" "github.com/debridmediamanager.com/zurg/pkg/logutil"
"github.com/debridmediamanager.com/zurg/pkg/realdebrid" "github.com/debridmediamanager.com/zurg/pkg/realdebrid"
"github.com/hashicorp/golang-lru/v2/expirable" "github.com/hashicorp/golang-lru/v2/expirable"
@@ -43,7 +43,8 @@ func main() {
cache := expirable.NewLRU[string, string](1e4, nil, time.Hour) cache := expirable.NewLRU[string, string](1e4, nil, time.Hour)
rd := realdebrid.NewRealDebrid(config.GetToken(), logutil.NewLogger().Named("realdebrid")) client := zurghttp.NewHTTPClient(config.GetToken(), 3, nil)
rd := realdebrid.NewRealDebrid(config.GetToken(), client, logutil.NewLogger().Named("realdebrid"))
p, err := ants.NewPool(config.GetNumOfWorkers()) p, err := ants.NewPool(config.GetNumOfWorkers())
if err != nil { if err != nil {
@@ -70,7 +71,7 @@ func main() {
}() }()
// log.Debugf("Initializing chunk manager, cores: %d", runtime.NumCPU()) // log.Debugf("Initializing chunk manager, cores: %d", runtime.NumCPU())
// client := zurghttp.NewHTTPClient(config.GetToken(), 10, config) // client := zurghttp.NewHTTPClient(config.GetToken(), 3, config)
// chunkMgr, err := chunk.NewManager( // chunkMgr, err := chunk.NewManager(
// "", // in-memory chunks // "", // in-memory chunks
// 10485760, // 10MB chunk size // 10485760, // 10MB chunk size

View File

@@ -123,7 +123,8 @@ func NewTorrentManager(cfg config.ConfigInterface, api *realdebrid.RealDebrid, p
t.SetChecksum(t.getChecksum()) t.SetChecksum(t.getChecksum())
if t.cfg.EnableRepair() { if t.cfg.EnableRepair() {
go t.repairAll() t.log.Info("Checking for torrents to repair")
t.repairAll()
} }
go t.startRefreshJob() go t.startRefreshJob()
@@ -317,7 +318,8 @@ func (t *TorrentManager) startRefreshJob() {
t.SetChecksum(t.getChecksum()) t.SetChecksum(t.getChecksum())
if t.cfg.EnableRepair() { if t.cfg.EnableRepair() {
go t.repairAll() t.log.Info("Checking for torrents to repair")
t.repairAll()
} }
go OnLibraryUpdateHook(t.cfg) go OnLibraryUpdateHook(t.cfg)
} }
@@ -371,11 +373,11 @@ func (t *TorrentManager) getMoreInfo(rdTorrent realdebrid.Torrent) *Torrent {
var isChaotic bool var isChaotic bool
selectedFiles, isChaotic = t.organizeChaos(info.Links, selectedFiles) selectedFiles, isChaotic = t.organizeChaos(info.Links, selectedFiles)
if isChaotic { if isChaotic {
t.log.Warnf("Torrent id=%s %s is unplayable; it is always returning a rar file (it will no longer show up in your directories)", info.ID, info.Name) t.log.Warnf("Torrent id=%s %s is unplayable; it is always returning a rar file (it will no longer show up in your directories, zurg suggests you delete it)", info.ID, info.Name)
// t.log.Debugf("You can try fixing it yourself magnet:?xt=urn:btih:%s", info.Hash) // t.log.Debugf("You can try fixing it yourself magnet:?xt=urn:btih:%s", info.Hash)
return nil return nil
} else if streamableCount == 1 { } else if streamableCount == 1 {
t.log.Warnf("Torrent id=%s %s is unplayable; the lone streamable link has expired (it will no longer show up in your directories)", info.ID, info.Name) t.log.Warnf("Torrent id=%s %s is unplayable; the lone streamable link has expired (it will no longer show up in your directories, zurg suggests you delete it)", info.ID, info.Name)
// t.log.Debugf("You can try fixing it yourself magnet:?xt=urn:btih:%s", info.Hash) // t.log.Debugf("You can try fixing it yourself magnet:?xt=urn:btih:%s", info.Hash)
return nil return nil
} }
@@ -523,11 +525,15 @@ func (t *TorrentManager) organizeChaos(links []string, selectedFiles []*File) ([
} }
func (t *TorrentManager) repairAll() { func (t *TorrentManager) repairAll() {
t.log.Info("Checking for torrents to repair") proceed := t.canCapacityHandle() // blocks for approx 45 minutes if active torrents are full
if !proceed {
t.log.Error("Reached the max number of active torrents, cannot start repair")
return
}
allTorrents, _ := t.DirectoryMap.Get(ALL_TORRENTS) allTorrents, _ := t.DirectoryMap.Get(ALL_TORRENTS)
allTorrents.IterCb(func(_ string, torrent *Torrent) { allTorrents.IterCb(func(_ string, torrent *Torrent) {
if torrent.InProgress() { if torrent.InProgress() {
t.log.Infof("Torrent %s is in progress, cannot repair", torrent.AccessKey)
return return
} }
forRepair := false forRepair := false
@@ -537,7 +543,8 @@ func (t *TorrentManager) repairAll() {
} }
}) })
if forRepair { if forRepair {
t.Repair(torrent.AccessKey) t.log.Infof("Repairing %s", torrent.AccessKey)
go t.Repair(torrent.AccessKey)
} }
}) })
} }
@@ -551,7 +558,7 @@ func (t *TorrentManager) Repair(accessKey string) {
allTorrents, _ := t.DirectoryMap.Get(ALL_TORRENTS) allTorrents, _ := t.DirectoryMap.Get(ALL_TORRENTS)
torrent, _ := allTorrents.Get(accessKey) torrent, _ := allTorrents.Get(accessKey)
if torrent == nil { if torrent == nil {
t.log.Warnf("Cannot find torrent %s anymore to repair it", accessKey) t.log.Warnf("Cannot find torrent %s anymore so we are not repairing it", accessKey)
return return
} }
@@ -560,12 +567,6 @@ func (t *TorrentManager) Repair(accessKey string) {
return return
} }
proceed := t.canCapacityHandle() // blocks for approx 45 minutes
if !proceed {
t.log.Error("Cannot add more torrents, ignoring repair request")
return
}
// make the file messy // make the file messy
t.log.Infof("Evaluating whole torrent to find the correct files for torrent: %s", torrent.AccessKey) t.log.Infof("Evaluating whole torrent to find the correct files for torrent: %s", torrent.AccessKey)
@@ -593,6 +594,12 @@ func (t *TorrentManager) Repair(accessKey string) {
} }
} }
proceed := t.canCapacityHandle() // blocks for approx 45 minutes if active torrents are full
if !proceed {
t.log.Error("Reached the max number of active torrents, cannot continue with the repair")
return
}
// first solution: add the same selection, maybe it can be fixed by reinsertion? // first solution: add the same selection, maybe it can be fixed by reinsertion?
if t.reinsertTorrent(torrent, "") { if t.reinsertTorrent(torrent, "") {
t.log.Infof("Successfully downloaded torrent %s to repair it", torrent.AccessKey) t.log.Infof("Successfully downloaded torrent %s to repair it", torrent.AccessKey)

View File

@@ -19,7 +19,7 @@ import (
// HandleGetRequest handles a GET request universally for both WebDAV and HTTP // HandleGetRequest handles a GET request universally for both WebDAV and HTTP
func HandleGetRequest(w http.ResponseWriter, r *http.Request, t *intTor.TorrentManager, c config.ConfigInterface, cache *expirable.LRU[string, string]) { func HandleGetRequest(w http.ResponseWriter, r *http.Request, t *intTor.TorrentManager, c config.ConfigInterface, cache *expirable.LRU[string, string]) {
log := logutil.NewLogger().Named("uniget") log := logutil.NewLogger().Named("file")
requestPath := path.Clean(r.URL.Path) requestPath := path.Clean(r.URL.Path)
isDav := true isDav := true
@@ -80,12 +80,12 @@ func HandleGetRequest(w http.ResponseWriter, r *http.Request, t *intTor.TorrentM
resp := t.UnrestrictUntilOk(link) resp := t.UnrestrictUntilOk(link)
if resp == nil { if resp == nil {
log.Warnf("File %s is no longer available", file.Path)
file.Link = "" file.Link = ""
t.SetChecksum("") // force a recheck t.SetChecksum("") // force a recheck
log.Warnf("File %s is no longer available", file.Path)
streamErrorVideo("https://www.youtube.com/watch?v=gea_FJrtFVA", w, r, t, c, log) streamErrorVideo("https://www.youtube.com/watch?v=gea_FJrtFVA", w, r, t, c, log)
return } else {
} else if resp.Filename != filename { if resp.Filename != filename {
// this is possible if there's only 1 streamable file in the torrent // this is possible if there's only 1 streamable file in the torrent
// and then suddenly it's a rar file // and then suddenly it's a rar file
actualExt := filepath.Ext(resp.Filename) actualExt := filepath.Ext(resp.Filename)
@@ -101,6 +101,7 @@ func HandleGetRequest(w http.ResponseWriter, r *http.Request, t *intTor.TorrentM
cache.Add(requestPath, resp.Download) cache.Add(requestPath, resp.Download)
streamFileToResponse(file, resp.Download, w, r, t, c, log) streamFileToResponse(file, resp.Download, w, r, t, c, log)
} }
}
func streamFileToResponse(file *intTor.File, url string, w http.ResponseWriter, r *http.Request, torMgr *intTor.TorrentManager, cfg config.ConfigInterface, log *zap.SugaredLogger) { func streamFileToResponse(file *intTor.File, url string, w http.ResponseWriter, r *http.Request, torMgr *intTor.TorrentManager, cfg config.ConfigInterface, log *zap.SugaredLogger) {
// Create a new request for the file download. // Create a new request for the file download.

View File

@@ -13,7 +13,7 @@ import (
) )
func HandleHeadRequest(w http.ResponseWriter, r *http.Request, t *torrent.TorrentManager, cache *expirable.LRU[string, string]) { func HandleHeadRequest(w http.ResponseWriter, r *http.Request, t *torrent.TorrentManager, cache *expirable.LRU[string, string]) {
log := logutil.NewLogger().Named("unihead") log := logutil.NewLogger().Named("head")
requestPath := path.Clean(r.URL.Path) requestPath := path.Clean(r.URL.Path)
requestPath = strings.Replace(requestPath, "/http", "", 1) requestPath = strings.Replace(requestPath, "/http", "", 1)

View File

@@ -19,9 +19,7 @@ type RealDebrid struct {
client *zurghttp.HTTPClient client *zurghttp.HTTPClient
} }
func NewRealDebrid(accessToken string, log *zap.SugaredLogger) *RealDebrid { func NewRealDebrid(accessToken string, client *zurghttp.HTTPClient, log *zap.SugaredLogger) *RealDebrid {
maxRetries := 10
client := zurghttp.NewHTTPClient(accessToken, maxRetries, nil)
return &RealDebrid{ return &RealDebrid{
log: log, log: log,
client: client, client: client,
@@ -177,7 +175,7 @@ func (rd *RealDebrid) SelectTorrentFiles(id string, files string) error {
} }
defer resp.Body.Close() defer resp.Body.Close()
rd.log.Debugf("Started the download for torrent id=%s", len(strings.Split(files, ",")), id) rd.log.Debugf("Selected %d files and started the download for torrent id=%s", len(strings.Split(files, ",")), id)
return nil return nil
} }

View File

@@ -20,9 +20,9 @@ func (rd *RealDebrid) UnrestrictUntilOk(link string) *UnrestrictResponse {
} }
func retryUntilOk[T any](fn func() (T, error)) T { func retryUntilOk[T any](fn func() (T, error)) T {
const initialDelay = 2 * time.Second const initialDelay = 1 * time.Second
const maxDelay = 128 * time.Second const maxDelay = 128 * time.Second
const maxRetries = 5 // Maximum retries for non-429 errors const maxRetries = 2 // Maximum retries for non-429 errors
var result T var result T
var err error var err error