Fix duplicate links for files

This commit is contained in:
Mukhtar Akere
2025-03-24 20:39:35 +01:00
parent 9469c98df7
commit 56bca562f4
5 changed files with 83 additions and 23 deletions

View File

@@ -27,10 +27,6 @@ const (
WebDavUseOriginalNameNoExt WebDavFolderNaming = "original_no_ext"
)
type DownloadLinkCache struct {
Link string `json:"download_link"`
}
type PropfindResponse struct {
Data []byte
GzippedData []byte
@@ -112,8 +108,6 @@ func (c *Cache) setTorrent(t *CachedTorrent) {
c.torrentsNames[c.GetTorrentFolder(t.Torrent)] = t
c.torrentsMutex.Unlock()
c.refreshListings()
go func() {
if err := c.SaveTorrent(t); err != nil {
c.logger.Debug().Err(err).Msgf("Failed to save torrent %s", t.Id)
@@ -224,6 +218,19 @@ func (c *Cache) load() (map[string]*CachedTorrent, error) {
}
if len(ct.Files) != 0 {
// We can assume the torrent is complete
// Make sure no file has a duplicate link
linkStore := make(map[string]bool)
for _, f := range ct.Files {
if _, ok := linkStore[f.Link]; ok {
// Duplicate link, refresh the torrent
ct = *c.refreshTorrent(&ct)
break
} else {
linkStore[f.Link] = true
}
}
ct.IsComplete = true
torrents[ct.Id] = &ct
}
@@ -369,7 +376,7 @@ func (c *Cache) sync(torrents []*types.Torrent) error {
return // Channel closed, exit goroutine
}
if err := c.ProcessTorrent(t, true); err != nil {
if err := c.ProcessTorrent(t, false); err != nil {
c.logger.Error().Err(err).Str("torrent", t.Name).Msg("sync error")
atomic.AddInt64(&errorCount, 1)
}
@@ -402,6 +409,7 @@ func (c *Cache) sync(torrents []*types.Torrent) error {
// Wait for all workers to complete
wg.Wait()
c.refreshListings()
c.logger.Info().Msgf("Sync complete: %d torrents processed, %d errors", len(torrents), errorCount)
return nil
}
@@ -412,13 +420,16 @@ func (c *Cache) ProcessTorrent(t *types.Torrent, refreshRclone bool) error {
return fmt.Errorf("failed to update torrent: %w", err)
}
}
ct := &CachedTorrent{
Torrent: t,
LastRead: time.Now(),
IsComplete: len(t.Files) > 0,
}
c.setTorrent(ct)
if refreshRclone {
c.refreshListings()
}
return nil
}
@@ -447,7 +458,6 @@ func (c *Cache) GetDownloadLink(torrentId, filename, fileLink string) string {
file = ct.Files[filename]
}
}
c.logger.Trace().Msgf("Getting download link for %s", ct.Name)
link, err := c.client.GetDownloadLink(ct.Torrent, &file)
if err != nil {
@@ -463,6 +473,39 @@ func (c *Cache) GetDownloadLink(torrentId, filename, fileLink string) string {
return file.DownloadLink
}
func (c *Cache) GenerateDownloadLinks(t *CachedTorrent) {
if err := c.client.GenerateDownloadLinks(t.Torrent); err != nil {
c.logger.Error().Err(err).Msg("Failed to generate download links")
}
for _, file := range t.Files {
c.updateDownloadLink(file)
}
go func() {
if err := c.SaveTorrent(t); err != nil {
c.logger.Debug().Err(err).Msgf("Failed to save torrent %s", t.Id)
}
}()
}
func (c *Cache) AddTorrent(t *types.Torrent) error {
if len(t.Files) == 0 {
if err := c.client.UpdateTorrent(t); err != nil {
return fmt.Errorf("failed to update torrent: %w", err)
}
}
ct := &CachedTorrent{
Torrent: t,
LastRead: time.Now(),
IsComplete: len(t.Files) > 0,
}
c.setTorrent(ct)
c.refreshListings()
go c.GenerateDownloadLinks(ct)
return nil
}
func (c *Cache) updateDownloadLink(file types.File) {
c.downloadLinksMutex.Lock()
defer c.downloadLinksMutex.Unlock()
@@ -489,6 +532,8 @@ func (c *Cache) DeleteTorrent(id string) {
delete(c.torrentsNames, t.Name)
c.removeFromDB(id)
c.refreshListings()
}
}
@@ -500,9 +545,10 @@ func (c *Cache) DeleteTorrents(ids []string) {
if t, ok := c.torrents[id]; ok {
delete(c.torrents, id)
delete(c.torrentsNames, c.GetTorrentFolder(t.Torrent))
c.removeFromDB(id)
go c.removeFromDB(id)
}
}
c.refreshListings()
}
func (c *Cache) removeFromDB(torrentId string) {

View File

@@ -18,7 +18,7 @@ func (c *Cache) RefreshXml() error {
return fmt.Errorf("failed to refresh XML for %s: %v", parent, err)
}
}
c.logger.Trace().Msgf("Refreshed XML cache for %s", c.client.GetName())
c.logger.Debug().Msgf("Refreshed XML cache for %s", c.client.GetName())
return nil
}

View File

@@ -74,12 +74,6 @@ func getTorrentFiles(t *types.Torrent, data TorrentInfo, validate bool) map[stri
_link = data.Links[idx]
}
if a, ok := t.Files[name]; ok {
a.Link = _link
files[name] = a
continue
}
file := types.File{
Name: name,
Path: name,
@@ -268,17 +262,15 @@ func (r *RealDebrid) DeleteTorrent(torrentId string) {
func (r *RealDebrid) GenerateDownloadLinks(t *types.Torrent) error {
url := fmt.Sprintf("%s/unrestrict/link/", r.Host)
files := make(map[string]types.File)
for _, f := range t.Files {
if f.DownloadLink != "" {
// Or check the generated link
continue
}
payload := gourl.Values{
"link": {f.Link},
}
req, _ := http.NewRequest(http.MethodPost, url, strings.NewReader(payload.Encode()))
resp, err := r.client.MakeRequest(req)
if err != nil {
fmt.Println(err)
return err
}
var data UnrestrictResponse
@@ -287,8 +279,9 @@ func (r *RealDebrid) GenerateDownloadLinks(t *types.Torrent) error {
}
f.DownloadLink = data.Download
f.Generated = time.Now()
t.Files[f.Name] = f
files[f.Name] = f
}
t.Files = files
return nil
}