Hotfixes:
- Fix % error in url encode - FIx alldebrid downloading bug - Fix dupicate checks for newly added torrents
This commit is contained in:
@@ -198,15 +198,16 @@ func (ad *AllDebrid) UpdateTorrent(t *types.Torrent) error {
|
||||
t.Folder = name
|
||||
t.MountPath = ad.MountPath
|
||||
t.Debrid = ad.Name
|
||||
t.Bytes = data.Size
|
||||
t.Seeders = data.Seeders
|
||||
if status == "downloaded" {
|
||||
t.Bytes = data.Size
|
||||
|
||||
t.Progress = float64((data.Downloaded / data.Size) * 100)
|
||||
t.Speed = data.DownloadSpeed
|
||||
t.Seeders = data.Seeders
|
||||
t.Progress = 100
|
||||
index := -1
|
||||
files := flattenFiles(data.Files, "", &index)
|
||||
t.Files = files
|
||||
} else {
|
||||
t.Progress = float64(data.Downloaded) / float64(data.Size) * 100
|
||||
t.Speed = data.DownloadSpeed
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -269,7 +270,7 @@ func (ad *AllDebrid) GenerateDownloadLinks(t *types.Torrent) error {
|
||||
}
|
||||
file.DownloadLink = link
|
||||
if link != nil {
|
||||
errCh <- fmt.Errorf("error getting download links %w", err)
|
||||
errCh <- fmt.Errorf("download link is empty")
|
||||
return
|
||||
}
|
||||
filesCh <- file
|
||||
@@ -310,9 +311,13 @@ func (ad *AllDebrid) GetDownloadLink(t *types.Torrent, file *types.File) (*types
|
||||
if err = json.Unmarshal(resp, &data); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if data.Error != nil {
|
||||
return nil, fmt.Errorf("error getting download link: %s", data.Error.Message)
|
||||
}
|
||||
link := data.Data.Link
|
||||
if link == "" {
|
||||
return nil, fmt.Errorf("error getting download links %s", data.Error.Message)
|
||||
return nil, fmt.Errorf("download link is empty")
|
||||
}
|
||||
return &types.DownloadLink{
|
||||
Link: file.Link,
|
||||
|
||||
+35
-22
@@ -194,7 +194,6 @@ func (c *Cache) load() (map[string]*CachedTorrent, error) {
|
||||
wg.Add(1)
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
now := time.Now()
|
||||
|
||||
for {
|
||||
file, ok := <-workChan
|
||||
@@ -227,11 +226,10 @@ func (c *Cache) load() (map[string]*CachedTorrent, error) {
|
||||
}
|
||||
|
||||
if isComplete {
|
||||
addedOn, err := time.Parse(time.RFC3339, ct.Added)
|
||||
if err != nil {
|
||||
addedOn = now
|
||||
|
||||
if addedOn, err := time.Parse(time.RFC3339, ct.Added); err == nil {
|
||||
ct.AddedOn = addedOn
|
||||
}
|
||||
ct.AddedOn = addedOn
|
||||
ct.IsComplete = true
|
||||
ct.Name = path.Clean(ct.Name)
|
||||
results.Store(ct.Id, &ct)
|
||||
@@ -278,9 +276,9 @@ func (c *Cache) Sync() error {
|
||||
c.logger.Info().Msgf("Got %d torrents from %s", len(torrents), c.client.GetName())
|
||||
|
||||
newTorrents := make([]*types.Torrent, 0)
|
||||
idStore := make(map[string]struct{}, len(torrents))
|
||||
idStore := make(map[string]string, len(torrents))
|
||||
for _, t := range torrents {
|
||||
idStore[t.Id] = struct{}{}
|
||||
idStore[t.Id] = t.Added
|
||||
if _, ok := cachedTorrents[t.Id]; !ok {
|
||||
newTorrents = append(newTorrents, t)
|
||||
}
|
||||
@@ -289,6 +287,10 @@ func (c *Cache) Sync() error {
|
||||
// Check for deleted torrents
|
||||
deletedTorrents := make([]string, 0)
|
||||
for _, t := range cachedTorrents {
|
||||
t.Added = idStore[t.Id]
|
||||
if addedOn, err := time.Parse(time.RFC3339, t.Added); err == nil {
|
||||
t.AddedOn = addedOn
|
||||
}
|
||||
if _, ok := idStore[t.Id]; !ok {
|
||||
deletedTorrents = append(deletedTorrents, t.Id)
|
||||
}
|
||||
@@ -399,20 +401,35 @@ func (c *Cache) GetTorrentFolder(torrent *types.Torrent) string {
|
||||
|
||||
func (c *Cache) setTorrent(t *CachedTorrent) {
|
||||
c.torrents.Store(t.Id, t)
|
||||
|
||||
c.torrentsNames.Store(c.GetTorrentFolder(t.Torrent), t)
|
||||
|
||||
torrentKey := c.GetTorrentFolder(t.Torrent)
|
||||
if o, ok := c.torrentsNames.Load(torrentKey); ok && o.Id != t.Id {
|
||||
// Save the most recent torrent
|
||||
if t.AddedOn.After(o.AddedOn) {
|
||||
c.torrentsNames.Delete(torrentKey)
|
||||
} else {
|
||||
t = o
|
||||
}
|
||||
}
|
||||
c.torrentsNames.Store(torrentKey, t)
|
||||
c.SaveTorrent(t)
|
||||
}
|
||||
|
||||
func (c *Cache) setTorrents(torrents map[string]*CachedTorrent) {
|
||||
for _, t := range torrents {
|
||||
c.torrents.Store(t.Id, t)
|
||||
c.torrentsNames.Store(c.GetTorrentFolder(t.Torrent), t)
|
||||
torrentKey := c.GetTorrentFolder(t.Torrent)
|
||||
if o, ok := c.torrentsNames.Load(torrentKey); ok && o.Id != t.Id {
|
||||
// Save the most recent torrent
|
||||
if t.AddedOn.After(o.AddedOn) {
|
||||
c.torrentsNames.Delete(torrentKey)
|
||||
} else {
|
||||
t = o
|
||||
}
|
||||
}
|
||||
c.torrentsNames.Store(torrentKey, t)
|
||||
}
|
||||
|
||||
c.RefreshListings(true)
|
||||
|
||||
c.RefreshListings(false)
|
||||
c.SaveTorrents()
|
||||
}
|
||||
|
||||
@@ -552,13 +569,6 @@ func (c *Cache) ProcessTorrent(t *types.Torrent) error {
|
||||
|
||||
if !isComplete(t.Files) {
|
||||
c.logger.Debug().Msgf("Torrent %s is still not complete. Triggering a reinsert(disabled)", t.Id)
|
||||
//err := c.reInsertTorrent(t)
|
||||
//if err != nil {
|
||||
// c.logger.Error().Err(err).Msgf("Failed to reinsert torrent %s", t.Id)
|
||||
// return err
|
||||
//}
|
||||
//c.logger.Debug().Msgf("Reinserted torrent %s", ct.Id)
|
||||
|
||||
} else {
|
||||
addedOn, err := time.Parse(time.RFC3339, t.Added)
|
||||
if err != nil {
|
||||
@@ -601,10 +611,12 @@ func (c *Cache) GetDownloadLink(torrentId, filename, fileLink string) string {
|
||||
if file.Link == "" {
|
||||
c.logger.Debug().Msgf("File link is empty for %s. Release is probably nerfed", filename)
|
||||
// Try to reinsert the torrent?
|
||||
if err := c.reInsertTorrent(ct); err != nil {
|
||||
newCt, err := c.reInsertTorrent(ct)
|
||||
if err != nil {
|
||||
c.logger.Error().Err(err).Msgf("Failed to reinsert torrent %s", ct.Name)
|
||||
return ""
|
||||
}
|
||||
ct = newCt
|
||||
file = ct.Files[filename]
|
||||
c.logger.Debug().Msgf("Reinserted torrent %s", ct.Name)
|
||||
}
|
||||
@@ -614,11 +626,12 @@ func (c *Cache) GetDownloadLink(torrentId, filename, fileLink string) string {
|
||||
if err != nil {
|
||||
if errors.Is(err, request.HosterUnavailableError) {
|
||||
c.logger.Error().Err(err).Msgf("Hoster is unavailable. Triggering repair for %s", ct.Name)
|
||||
err := c.reInsertTorrent(ct)
|
||||
newCt, err := c.reInsertTorrent(ct)
|
||||
if err != nil {
|
||||
c.logger.Error().Err(err).Msgf("Failed to reinsert torrent %s", ct.Name)
|
||||
return ""
|
||||
}
|
||||
ct = newCt
|
||||
c.logger.Debug().Msgf("Reinserted torrent %s", ct.Name)
|
||||
file = ct.Files[filename]
|
||||
// Retry getting the download link
|
||||
|
||||
@@ -109,11 +109,11 @@ func (c *Cache) refreshTorrents() {
|
||||
if len(newTorrents) == 0 {
|
||||
return
|
||||
}
|
||||
c.logger.Debug().Msgf("Found %d new torrents", len(newTorrents))
|
||||
|
||||
workChan := make(chan *types.Torrent, min(100, len(newTorrents)))
|
||||
errChan := make(chan error, len(newTorrents))
|
||||
var wg sync.WaitGroup
|
||||
counter := 0
|
||||
|
||||
for i := 0; i < c.workers; i++ {
|
||||
wg.Add(1)
|
||||
@@ -121,13 +121,12 @@ func (c *Cache) refreshTorrents() {
|
||||
defer wg.Done()
|
||||
for t := range workChan {
|
||||
select {
|
||||
case <-c.ctx.Done():
|
||||
return
|
||||
default:
|
||||
}
|
||||
if err := c.ProcessTorrent(t); err != nil {
|
||||
c.logger.Error().Err(err).Msgf("Failed to process new torrent %s", t.Id)
|
||||
errChan <- err
|
||||
if err := c.ProcessTorrent(t); err != nil {
|
||||
c.logger.Error().Err(err).Msgf("Failed to process new torrent %s", t.Id)
|
||||
errChan <- err
|
||||
}
|
||||
counter++
|
||||
}
|
||||
}
|
||||
}()
|
||||
@@ -135,8 +134,6 @@ func (c *Cache) refreshTorrents() {
|
||||
|
||||
for _, t := range newTorrents {
|
||||
select {
|
||||
case <-c.ctx.Done():
|
||||
break
|
||||
default:
|
||||
workChan <- t
|
||||
}
|
||||
@@ -146,7 +143,7 @@ func (c *Cache) refreshTorrents() {
|
||||
|
||||
c.RefreshListings(true)
|
||||
|
||||
c.logger.Debug().Msgf("Processed %d new torrents", len(newTorrents))
|
||||
c.logger.Debug().Msgf("Processed %d new torrents", counter)
|
||||
}
|
||||
|
||||
func (c *Cache) RefreshRclone() error {
|
||||
|
||||
+25
-22
@@ -37,6 +37,11 @@ func (c *Cache) IsTorrentBroken(t *CachedTorrent, filenames []string) bool {
|
||||
}
|
||||
}
|
||||
|
||||
if t == nil || t.Torrent == nil {
|
||||
c.logger.Error().Str("torrentId", t.Torrent.Id).Msg("Failed to refresh torrent")
|
||||
return true
|
||||
}
|
||||
|
||||
files = t.Files
|
||||
|
||||
for _, f := range files {
|
||||
@@ -58,13 +63,11 @@ func (c *Cache) IsTorrentBroken(t *CachedTorrent, filenames []string) bool {
|
||||
// Try to reinsert the torrent if it's broken
|
||||
if cfg.Repair.ReInsert && isBroken && t.Torrent != nil {
|
||||
// Check if the torrent is already in progress
|
||||
if err := c.reInsertTorrent(t); err != nil {
|
||||
if _, err := c.reInsertTorrent(t); err != nil {
|
||||
c.logger.Error().Err(err).Str("torrentId", t.Torrent.Id).Msg("Failed to reinsert torrent")
|
||||
return true
|
||||
} else {
|
||||
c.logger.Debug().Str("torrentId", t.Torrent.Id).Msg("Reinserted torrent")
|
||||
return false
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
return isBroken
|
||||
@@ -86,7 +89,7 @@ func (c *Cache) repairWorker() {
|
||||
switch req.Type {
|
||||
case RepairTypeReinsert:
|
||||
c.logger.Debug().Str("torrentId", torrentId).Msg("Reinserting torrent")
|
||||
if err := c.reInsertTorrent(cachedTorrent); err != nil {
|
||||
if _, err := c.reInsertTorrent(cachedTorrent); err != nil {
|
||||
c.logger.Error().Err(err).Str("torrentId", cachedTorrent.Id).Msg("Failed to reinsert torrent")
|
||||
continue
|
||||
}
|
||||
@@ -100,12 +103,12 @@ func (c *Cache) repairWorker() {
|
||||
}
|
||||
}
|
||||
|
||||
func (c *Cache) reInsertTorrent(ct *CachedTorrent) error {
|
||||
func (c *Cache) reInsertTorrent(ct *CachedTorrent) (*CachedTorrent, error) {
|
||||
// Check if Magnet is not empty, if empty, reconstruct the magnet
|
||||
torrent := ct.Torrent
|
||||
oldID := torrent.Id // Store the old ID
|
||||
if _, ok := c.repairsInProgress.Load(oldID); ok {
|
||||
return fmt.Errorf("repair already in progress for torrent %s", torrent.Id)
|
||||
return ct, fmt.Errorf("repair already in progress for torrent %s", torrent.Id)
|
||||
}
|
||||
c.repairsInProgress.Store(oldID, struct{}{})
|
||||
defer c.repairsInProgress.Delete(oldID)
|
||||
@@ -120,53 +123,53 @@ func (c *Cache) reInsertTorrent(ct *CachedTorrent) error {
|
||||
torrent, err = c.client.SubmitMagnet(torrent)
|
||||
if err != nil {
|
||||
// Remove the old torrent from the cache and debrid service
|
||||
return fmt.Errorf("failed to submit magnet: %w", err)
|
||||
return ct, fmt.Errorf("failed to submit magnet: %w", err)
|
||||
}
|
||||
|
||||
// Check if the torrent was submitted
|
||||
if torrent == nil || torrent.Id == "" {
|
||||
return fmt.Errorf("failed to submit magnet: empty torrent")
|
||||
return ct, fmt.Errorf("failed to submit magnet: empty torrent")
|
||||
}
|
||||
torrent.DownloadUncached = false // Set to false, avoid re-downloading
|
||||
torrent, err = c.client.CheckStatus(torrent, true)
|
||||
if err != nil && torrent != nil {
|
||||
// Torrent is likely in progress
|
||||
_ = c.DeleteTorrent(torrent.Id)
|
||||
|
||||
return fmt.Errorf("failed to check status: %w", err)
|
||||
return ct, fmt.Errorf("failed to check status: %w", err)
|
||||
}
|
||||
|
||||
if torrent == nil {
|
||||
return fmt.Errorf("failed to check status: empty torrent")
|
||||
return ct, fmt.Errorf("failed to check status: empty torrent")
|
||||
}
|
||||
|
||||
// Update the torrent in the cache
|
||||
addedOn, err := time.Parse(time.RFC3339, torrent.Added)
|
||||
if err != nil {
|
||||
addedOn = time.Now()
|
||||
}
|
||||
for _, f := range torrent.Files {
|
||||
if f.Link == "" {
|
||||
// Delete the new torrent
|
||||
_ = c.DeleteTorrent(torrent.Id)
|
||||
return fmt.Errorf("failed to reinsert torrent: empty link")
|
||||
return ct, fmt.Errorf("failed to reinsert torrent: empty link")
|
||||
}
|
||||
}
|
||||
if err != nil {
|
||||
addedOn = time.Now()
|
||||
}
|
||||
|
||||
// We can safely delete the old torrent here
|
||||
if oldID != "" {
|
||||
if err := c.DeleteTorrent(oldID); err != nil {
|
||||
return fmt.Errorf("failed to delete old torrent: %w", err)
|
||||
return ct, fmt.Errorf("failed to delete old torrent: %w", err)
|
||||
}
|
||||
}
|
||||
ct.Torrent = torrent
|
||||
ct.IsComplete = len(torrent.Files) > 0
|
||||
ct.AddedOn = addedOn
|
||||
ct = &CachedTorrent{
|
||||
Torrent: torrent,
|
||||
AddedOn: addedOn,
|
||||
IsComplete: len(torrent.Files) > 0,
|
||||
}
|
||||
c.setTorrent(ct)
|
||||
c.RefreshListings(true)
|
||||
c.logger.Debug().Str("torrentId", torrent.Id).Msg("Reinserted torrent")
|
||||
|
||||
return nil
|
||||
return ct, nil
|
||||
}
|
||||
|
||||
func (c *Cache) resetInvalidLinks() {
|
||||
|
||||
Reference in New Issue
Block a user