Add job for monitoring bw limit status of tokens
This commit is contained in:
@@ -111,8 +111,8 @@ func MainApp(configPath string) {
|
||||
)
|
||||
|
||||
workerCount := config.GetNumberOfWorkers()
|
||||
if workerCount < 10 {
|
||||
workerCount = 10
|
||||
if workerCount < 20 {
|
||||
workerCount = 20
|
||||
}
|
||||
workerPool, err := ants.NewPool(workerCount)
|
||||
if err != nil {
|
||||
@@ -129,6 +129,7 @@ func MainApp(configPath string) {
|
||||
config,
|
||||
log.Named("realdebrid"),
|
||||
)
|
||||
rd.MonitorExpiredTokens()
|
||||
|
||||
premium.MonitorPremiumStatus(
|
||||
workerPool,
|
||||
@@ -153,6 +154,7 @@ func MainApp(configPath string) {
|
||||
)
|
||||
|
||||
downloader := universal.NewDownloader(rd, workerPool)
|
||||
downloader.StartResetBandwidthCountersJob()
|
||||
|
||||
router := chi.NewRouter()
|
||||
handlers.AttachHandlers(
|
||||
|
||||
@@ -28,7 +28,7 @@ func loadV1Config(content []byte, log *logutil.Logger) (*ZurgConfigV1, error) {
|
||||
|
||||
// don't log token and password
|
||||
bufToken := configV1.Token
|
||||
configV1.Token = strings.Repeat("*", len(bufToken)-4) + bufToken[len(bufToken)-4:]
|
||||
configV1.Token = utils.MaskToken(configV1.Token)
|
||||
bufPassword := configV1.Password
|
||||
configV1.Password = strings.Repeat("*", len(bufPassword))
|
||||
log.Debugf("Config dump: %+v", configV1)
|
||||
|
||||
@@ -12,6 +12,7 @@ import (
|
||||
"github.com/debridmediamanager/zurg/internal/config"
|
||||
"github.com/debridmediamanager/zurg/internal/version"
|
||||
"github.com/debridmediamanager/zurg/pkg/realdebrid"
|
||||
"github.com/debridmediamanager/zurg/pkg/utils"
|
||||
)
|
||||
|
||||
type SponsorResponse struct {
|
||||
@@ -117,7 +118,7 @@ func (zr *Handlers) generateResponse(resp http.ResponseWriter, req *http.Request
|
||||
Paypal: "https://paypal.me/yowmamasita",
|
||||
},
|
||||
Config: zr.cfg.GetConfig(),
|
||||
Token: strings.Replace(token, token[len(token)-48:], "*****", 1),
|
||||
Token: utils.MaskToken(token),
|
||||
IDsToDelete: sortedIDs,
|
||||
Hosts: zr.hosts,
|
||||
}, nil
|
||||
|
||||
@@ -219,7 +219,7 @@ func (t *TorrentManager) applyMediaInfoDetails(torrent *Torrent) error {
|
||||
return
|
||||
}
|
||||
unrestrict, err := t.UnrestrictFile(file)
|
||||
if utils.IsBWLimitExceeded(err) {
|
||||
if utils.AreAllTokensExpired(err) {
|
||||
bwLimitReached = true
|
||||
return
|
||||
}
|
||||
@@ -337,6 +337,7 @@ func (t *TorrentManager) mountNewDownloads() {
|
||||
downloads := t.rd.GetDownloads()
|
||||
mountedCount := 0
|
||||
for i := range downloads {
|
||||
downloads[i].Token = token
|
||||
isRealDebrid := strings.HasPrefix(downloads[i].Link, "https://real-debrid.com/d/")
|
||||
if !isRealDebrid {
|
||||
filename := filepath.Base(downloads[i].Filename)
|
||||
|
||||
@@ -294,16 +294,15 @@ func (t *TorrentManager) mergeTorrents(existing, toMerge *Torrent) *Torrent {
|
||||
newer.SelectedFiles.IterCb(func(key string, file *File) {
|
||||
mergedTorrent.SelectedFiles.SetIfAbsent(key, file)
|
||||
})
|
||||
older.SelectedFiles.IterCb(func(key string, file *File) {
|
||||
mediaInfo := file.MediaInfo
|
||||
f, ok := mergedTorrent.SelectedFiles.Get(key)
|
||||
if !ok || !f.State.Is("ok_file") {
|
||||
mergedTorrent.SelectedFiles.Set(key, file)
|
||||
older.SelectedFiles.IterCb(func(key string, olderFile *File) {
|
||||
file, ok := mergedTorrent.SelectedFiles.Get(key)
|
||||
if !ok || (file.State.Is("broken_file") && olderFile.State.Is("ok_file")) {
|
||||
mergedTorrent.SelectedFiles.Set(key, olderFile)
|
||||
}
|
||||
// get the file again, set the media info
|
||||
f, ok = mergedTorrent.SelectedFiles.Get(key)
|
||||
if ok && f.MediaInfo == nil && mediaInfo != nil {
|
||||
f.MediaInfo = mediaInfo
|
||||
file, ok = mergedTorrent.SelectedFiles.Get(key)
|
||||
if ok && file.MediaInfo == nil && olderFile.MediaInfo != nil {
|
||||
file.MediaInfo = olderFile.MediaInfo
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
@@ -19,6 +19,7 @@ const (
|
||||
EXPIRED_LINK_TOLERANCE_HOURS = 24
|
||||
)
|
||||
|
||||
// StartRepairJob is a permanent job that runs every periodically to repair broken torrents
|
||||
func (t *TorrentManager) StartRepairJob() {
|
||||
if !t.Config.EnableRepair() {
|
||||
t.repairLog.Warn("Repair is disabled, skipping repair job")
|
||||
@@ -34,7 +35,6 @@ func (t *TorrentManager) StartRepairJob() {
|
||||
t.repairLog.Debug("Starting periodic repair job")
|
||||
repairTicker := time.NewTicker(time.Duration(t.Config.GetRepairEveryMins()) * time.Minute)
|
||||
defer repairTicker.Stop()
|
||||
|
||||
for {
|
||||
select {
|
||||
case <-repairTicker.C:
|
||||
@@ -192,11 +192,12 @@ func (t *TorrentManager) repair(torrent *Torrent, wg *sync.WaitGroup) {
|
||||
bwLimitReached := false
|
||||
// check for other broken file
|
||||
torrent.SelectedFiles.IterCb(func(_ string, file *File) {
|
||||
// we will only check for working files, we ignore broken and deleted files
|
||||
if bwLimitReached || !file.State.Is("ok_file") {
|
||||
return
|
||||
}
|
||||
_, err := t.UnrestrictFile(file)
|
||||
if utils.IsBWLimitExceeded(err) {
|
||||
if utils.AreAllTokensExpired(err) {
|
||||
bwLimitReached = true
|
||||
return
|
||||
}
|
||||
@@ -252,7 +253,7 @@ 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 {
|
||||
err = t.checkIfBroken(info, brokenFiles)
|
||||
if utils.IsBWLimitExceeded(err) {
|
||||
if utils.AreAllTokensExpired(err) {
|
||||
t.repairLog.Warnf("Your account has reached the bandwidth limit, cannot continue repairing torrent %s", t.GetKey(torrent))
|
||||
return
|
||||
}
|
||||
@@ -332,14 +333,13 @@ func (t *TorrentManager) assignLinks(torrent *Torrent) bool {
|
||||
expiredCount := 0
|
||||
rarCount := 0
|
||||
unassignedCount := 0
|
||||
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, err := t.rd.UnrestrictAndVerify(link)
|
||||
if utils.IsBWLimitExceeded(err) {
|
||||
if utils.AreAllTokensExpired(err) {
|
||||
bwLimitReached = true
|
||||
return true
|
||||
}
|
||||
@@ -377,7 +377,18 @@ func (t *TorrentManager) assignLinks(torrent *Torrent) bool {
|
||||
// it's possible that it is already repaired
|
||||
t.repairLog.Warnf("Cannot assign %s to any file in torrent %s", unrestrict.Filename, t.GetKey(torrent))
|
||||
}
|
||||
newUnassignedLinks.Set(link, unrestrict)
|
||||
|
||||
torrent.SelectedFiles.Set(unrestrict.Filename, &File{
|
||||
File: realdebrid.File{
|
||||
ID: 0,
|
||||
Path: unrestrict.Filename,
|
||||
Bytes: unrestrict.Filesize,
|
||||
Selected: 0,
|
||||
},
|
||||
Ended: torrent.Added,
|
||||
Link: unrestrict.Link,
|
||||
State: NewFileState("ok_file"),
|
||||
})
|
||||
}
|
||||
|
||||
processedCount := assignedCount + unassignedCount + expiredCount
|
||||
@@ -416,20 +427,6 @@ func (t *TorrentManager) assignLinks(torrent *Torrent) bool {
|
||||
return false // end repair
|
||||
}
|
||||
|
||||
newUnassignedLinks.IterCb(func(_ string, unassigned *realdebrid.Download) {
|
||||
torrent.SelectedFiles.Set(unassigned.Filename, &File{
|
||||
File: realdebrid.File{
|
||||
ID: 0,
|
||||
Path: unassigned.Filename,
|
||||
Bytes: unassigned.Filesize,
|
||||
Selected: 0,
|
||||
},
|
||||
Ended: torrent.Added,
|
||||
Link: unassigned.Link,
|
||||
State: NewFileState("ok_file"),
|
||||
})
|
||||
})
|
||||
|
||||
if action == "extract" {
|
||||
videoFiles := []string{}
|
||||
torrent.SelectedFiles.IterCb(func(_ string, file *File) {
|
||||
|
||||
@@ -27,11 +27,14 @@ type Downloader struct {
|
||||
}
|
||||
|
||||
func NewDownloader(rd *realdebrid.RealDebrid, workerPool *ants.Pool) *Downloader {
|
||||
dl := &Downloader{
|
||||
return &Downloader{
|
||||
rd: rd,
|
||||
workerPool: workerPool,
|
||||
}
|
||||
}
|
||||
|
||||
// StartResetBandwidthCountersJob is a permanent job that resets the bandwidth counters at 12AM CET
|
||||
func (dl *Downloader) StartResetBandwidthCountersJob() {
|
||||
// track bandwidth usage and reset at 12AM CET
|
||||
now := time.Now()
|
||||
tomorrow := now.AddDate(0, 0, 1)
|
||||
@@ -42,19 +45,17 @@ func NewDownloader(rd *realdebrid.RealDebrid, workerPool *ants.Pool) *Downloader
|
||||
nextMidnightInCET := time.Date(tomorrow.Year(), tomorrow.Month(), tomorrow.Day(), 0, 0, 0, 0, cetTZ)
|
||||
duration := nextMidnightInCET.Sub(now)
|
||||
timer := time.NewTimer(duration)
|
||||
// permanent job for bandwidth reset
|
||||
workerPool.Submit(func() {
|
||||
|
||||
dl.workerPool.Submit(func() {
|
||||
<-timer.C
|
||||
ticker := time.NewTicker(24 * time.Hour)
|
||||
for {
|
||||
rd.TokenManager.ResetAllTokens()
|
||||
dl.rd.TokenManager.ResetAllTokens()
|
||||
dl.RequestedBytes.Store(0)
|
||||
dl.TotalBytes.Store(0)
|
||||
<-ticker.C
|
||||
}
|
||||
})
|
||||
|
||||
return dl
|
||||
}
|
||||
|
||||
// DownloadFile handles a GET request for files in torrents
|
||||
@@ -90,7 +91,7 @@ func (dl *Downloader) DownloadFile(
|
||||
}
|
||||
|
||||
unrestrict, err := torMgr.UnrestrictFile(file)
|
||||
if utils.IsBWLimitExceeded(err) {
|
||||
if utils.AreAllTokensExpired(err) {
|
||||
// log.Errorf("Your account has reached the bandwidth limit, please try again after 12AM CET")
|
||||
http.Error(resp, "File is not available (bandwidth limit reached)", http.StatusBadRequest)
|
||||
return
|
||||
@@ -164,7 +165,8 @@ func (dl *Downloader) streamFileToResponse(
|
||||
}
|
||||
|
||||
downloadResp, err := dl.rd.DownloadFile(dlReq)
|
||||
if utils.IsBWLimitExceeded(err) {
|
||||
if utils.IsBytesLimitReached(err) {
|
||||
dl.rd.TokenManager.SetTokenAsExpired(unrestrict.Token, "bandwidth limit exceeded")
|
||||
// log.Errorf("Your account has reached the bandwidth limit, please try again after 12AM CET")
|
||||
http.Error(resp, "File is not available (bandwidth limit reached)", http.StatusBadRequest)
|
||||
return
|
||||
|
||||
Reference in New Issue
Block a user