Merge pull request #746 from Cucumberrbob/refactor/get-download-info
refactor: use `GetDownloadInfo` - a richer version of `GetDownloadLinks`
This commit is contained in:
commit
2e028ed17c
13 changed files with 159 additions and 140 deletions
|
|
@ -1,4 +1,5 @@
|
|||
using Microsoft.EntityFrameworkCore;
|
||||
using RdtClient.Data.Models.Data;
|
||||
using Download = RdtClient.Data.Models.Data.Download;
|
||||
|
||||
namespace RdtClient.Data.Data;
|
||||
|
|
@ -29,13 +30,14 @@ public class DownloadData(DataContext dataContext)
|
|||
.FirstOrDefaultAsync(m => m.TorrentId == torrentId && m.Path == path);
|
||||
}
|
||||
|
||||
public async Task<Download> Add(Guid torrentId, String path)
|
||||
public async Task<Download> Add(Guid torrentId, DownloadInfo downloadInfo)
|
||||
{
|
||||
var download = new Download
|
||||
{
|
||||
DownloadId = Guid.NewGuid(),
|
||||
TorrentId = torrentId,
|
||||
Path = path,
|
||||
FileName = downloadInfo.FileName,
|
||||
Path = downloadInfo.RestrictedLink,
|
||||
Added = DateTimeOffset.UtcNow,
|
||||
DownloadQueued = DateTimeOffset.UtcNow,
|
||||
RetryCount = 0
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ public class Download
|
|||
public DateTimeOffset? Completed { get; set; }
|
||||
|
||||
public Int32 RetryCount { get; set; }
|
||||
|
||||
|
||||
public String? Error { get; set; }
|
||||
|
||||
public String? RemoteId { get; set; }
|
||||
|
|
@ -41,4 +41,20 @@ public class Download
|
|||
|
||||
[NotMapped]
|
||||
public Int64 Speed { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Used to create <see cref="Download"/>s
|
||||
/// </summary>
|
||||
public class DownloadInfo
|
||||
{
|
||||
/// <summary>
|
||||
/// The name of the file. Should not include directory.
|
||||
/// If the filename is not known, set tn null and `GetFileName` will be called with the unrestricted link.
|
||||
/// </summary>
|
||||
public required String? FileName;
|
||||
/// <summary>
|
||||
/// The restricted link to download this download. If the debrid serice in question does not have restricted links, use either a fake or the unrestricted link
|
||||
/// </summary>
|
||||
public required String RestrictedLink;
|
||||
}
|
||||
|
|
@ -405,7 +405,7 @@ public class AllDebridTorrentClientTest
|
|||
}
|
||||
|
||||
[Fact]
|
||||
public async Task GetDownloadLinks_WhenTorrentRdIdNull_ReturnsNull()
|
||||
public async Task GetDownloadInfos_WhenTorrentRdIdNull_ReturnsNull()
|
||||
{
|
||||
// Arrange
|
||||
var mocks = new Mocks();
|
||||
|
|
@ -418,7 +418,7 @@ public class AllDebridTorrentClientTest
|
|||
var allDebridTorrentClient = new AllDebridTorrentClient(mocks.LoggerMock.Object, mocks.AllDebridClientFactoryMock.Object, mocks.FileFilterMock.Object);
|
||||
|
||||
// Act
|
||||
var result = await allDebridTorrentClient.GetDownloadLinks(torrent);
|
||||
var result = await allDebridTorrentClient.GetDownloadInfos(torrent);
|
||||
|
||||
// Assert
|
||||
Assert.Null(result);
|
||||
|
|
@ -426,7 +426,7 @@ public class AllDebridTorrentClientTest
|
|||
}
|
||||
|
||||
[Fact]
|
||||
public async Task GetDownloadLinks_UsesFileFilter()
|
||||
public async Task GetDownloadInfos_UsesFileFilter()
|
||||
{
|
||||
// Arrange
|
||||
var mocks = new Mocks();
|
||||
|
|
@ -467,16 +467,16 @@ public class AllDebridTorrentClientTest
|
|||
var allDebridTorrentClient = new AllDebridTorrentClient(mocks.LoggerMock.Object, mocks.AllDebridClientFactoryMock.Object, mocks.FileFilterMock.Object);
|
||||
|
||||
// Act
|
||||
var result = await allDebridTorrentClient.GetDownloadLinks(torrent);
|
||||
var result = await allDebridTorrentClient.GetDownloadInfos(torrent);
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(result);
|
||||
Assert.Single(result);
|
||||
Assert.Contains("https://fake.url/file1.txt", result);
|
||||
Assert.Single(result.Where(info => info.RestrictedLink == "https://fake.url/file1.txt"));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task GetDownloadLinks_WhenAllFilesExcluded_ReturnsEmptyList()
|
||||
public async Task GetDownloadInfos_WhenAllFilesExcluded_ReturnsEmptyList()
|
||||
{
|
||||
// Arrange
|
||||
var mocks = new Mocks();
|
||||
|
|
@ -501,14 +501,14 @@ public class AllDebridTorrentClientTest
|
|||
DownloadLink = "https://fake.url/file-2.txt"
|
||||
}
|
||||
];
|
||||
|
||||
|
||||
mocks.AllDebridClientMock.Setup(c => c.Magnet.FilesAsync(Int64.Parse(torrent.RdId), It.IsAny<CancellationToken>())).ReturnsAsync(files);
|
||||
mocks.FileFilterMock.Setup(f => f.IsDownloadable(torrent, It.IsAny<String>(), It.IsAny<Int64>())).Returns(false);
|
||||
|
||||
var allDebridTorrentClient = new AllDebridTorrentClient(mocks.LoggerMock.Object, mocks.AllDebridClientFactoryMock.Object, mocks.FileFilterMock.Object);
|
||||
|
||||
// Act
|
||||
var result = await allDebridTorrentClient.GetDownloadLinks(torrent);
|
||||
var result = await allDebridTorrentClient.GetDownloadInfos(torrent);
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(result);
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
using RdtClient.Data.Data;
|
||||
using RdtClient.Data.Models.Data;
|
||||
using Download = RdtClient.Data.Models.Data.Download;
|
||||
|
||||
namespace RdtClient.Service.Services;
|
||||
|
|
@ -20,9 +21,9 @@ public class Downloads(DownloadData downloadData) : IDownloads
|
|||
return await downloadData.Get(torrentId, path);
|
||||
}
|
||||
|
||||
public async Task<Download> Add(Guid torrentId, String path)
|
||||
public async Task<Download> Add(Guid torrentId, DownloadInfo downloadInfo)
|
||||
{
|
||||
return await downloadData.Add(torrentId, path);
|
||||
return await downloadData.Add(torrentId, downloadInfo);
|
||||
}
|
||||
|
||||
public async Task UpdateUnrestrictedLink(Guid downloadId, String unrestrictedLink)
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ public interface IDownloads
|
|||
Task<List<Download>> GetForTorrent(Guid torrentId);
|
||||
Task<Download?> GetById(Guid downloadId);
|
||||
Task<Download?> Get(Guid torrentId, String path);
|
||||
Task<Download> Add(Guid torrentId, String path);
|
||||
Task<Download> Add(Guid torrentId, DownloadInfo downloadInfo);
|
||||
Task UpdateUnrestrictedLink(Guid downloadId, String unrestrictedLink);
|
||||
Task UpdateFileName(Guid downloadId, String fileName);
|
||||
Task UpdateDownloadStarted(Guid downloadId, DateTimeOffset? dateTime);
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
using AllDebridNET;
|
||||
using System.Diagnostics;
|
||||
using AllDebridNET;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Newtonsoft.Json;
|
||||
using RdtClient.Data.Enums;
|
||||
using RdtClient.Data.Models.TorrentClient;
|
||||
using RdtClient.Service.Helpers;
|
||||
using System.Web;
|
||||
using RdtClient.Data.Models.Data;
|
||||
using File = AllDebridNET.File;
|
||||
using Torrent = RdtClient.Data.Models.Data.Torrent;
|
||||
|
|
@ -245,34 +245,33 @@ public class AllDebridTorrentClient(ILogger<AllDebridTorrentClient> logger, IAll
|
|||
return torrent;
|
||||
}
|
||||
|
||||
public async Task<IList<String>?> GetDownloadLinks(Torrent torrent)
|
||||
public async Task<IList<DownloadInfo>?> GetDownloadInfos(Torrent torrent)
|
||||
{
|
||||
if (torrent.RdId == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
Log($"Getting download links", torrent);
|
||||
|
||||
|
||||
var allFiles = await allDebridNetClientFactory.GetClient().Magnet.FilesAsync(Int64.Parse(torrent.RdId));
|
||||
|
||||
var files = GetFiles(allFiles);
|
||||
|
||||
files = files.Where(f => fileFilter.IsDownloadable(torrent, f.Path, f.Bytes)).ToList();
|
||||
|
||||
return files.Where(m => m.DownloadLink != null).Select(m => m.DownloadLink!.ToString()).ToList();
|
||||
|
||||
return files.Where(f => fileFilter.IsDownloadable(torrent, f.Path, f.Bytes) && f.DownloadLink != null).Select(f => new DownloadInfo
|
||||
{
|
||||
FileName = Path.GetFileName(f.Path),
|
||||
RestrictedLink = f.DownloadLink!
|
||||
}).ToList();
|
||||
}
|
||||
|
||||
public Task<String> GetFileName(String downloadUrl)
|
||||
/// <inheritdoc />
|
||||
public Task<String> GetFileName(Download download)
|
||||
{
|
||||
if (String.IsNullOrWhiteSpace(downloadUrl))
|
||||
{
|
||||
return Task.FromResult("");
|
||||
}
|
||||
|
||||
var uri = new Uri(downloadUrl);
|
||||
|
||||
return Task.FromResult(HttpUtility.UrlDecode(uri.Segments.Last()));
|
||||
// FileName is set in GetDownlaadInfos
|
||||
Debug.Assert(download.FileName != null);
|
||||
|
||||
return Task.FromResult(download.FileName);
|
||||
}
|
||||
|
||||
private async Task<TorrentClientTorrent> GetInfo(String torrentId)
|
||||
|
|
|
|||
|
|
@ -1,12 +1,13 @@
|
|||
using Microsoft.Extensions.Logging;
|
||||
using System.Diagnostics;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Newtonsoft.Json;
|
||||
using DebridLinkFrNET;
|
||||
using RdtClient.Data.Enums;
|
||||
using RdtClient.Data.Models.TorrentClient;
|
||||
using RdtClient.Service.Helpers;
|
||||
using DebridLinkFrNET.Models;
|
||||
using System.Web;
|
||||
using RdtClient.Data.Models.Data;
|
||||
using Download = RdtClient.Data.Models.Data.Download;
|
||||
using Torrent = DebridLinkFrNET.Models.Torrent;
|
||||
|
||||
namespace RdtClient.Service.Services.TorrentClients;
|
||||
|
||||
|
|
@ -234,7 +235,7 @@ public class DebridLinkClient(ILogger<DebridLinkClient> logger, IHttpClientFacto
|
|||
return torrent;
|
||||
}
|
||||
|
||||
public async Task<IList<String>?> GetDownloadLinks(Data.Models.Data.Torrent torrent)
|
||||
public async Task<IList<DownloadInfo>?> GetDownloadInfos(Data.Models.Data.Torrent torrent)
|
||||
{
|
||||
if (torrent.RdId == null)
|
||||
{
|
||||
|
|
@ -248,19 +249,14 @@ public class DebridLinkClient(ILogger<DebridLinkClient> logger, IHttpClientFacto
|
|||
return null;
|
||||
}
|
||||
|
||||
var downloadLinks = rdTorrent.Files?
|
||||
.Where(m => fileFilter.IsDownloadable(torrent, m.Path, m.Bytes) && m.DownloadLink != null)
|
||||
.Select(m => m.DownloadLink!)
|
||||
.ToList() ?? [];
|
||||
|
||||
Log($"Found {downloadLinks.Count} links", torrent);
|
||||
|
||||
foreach (var link in downloadLinks)
|
||||
{
|
||||
Log($"{link}", torrent);
|
||||
}
|
||||
|
||||
return downloadLinks;
|
||||
return rdTorrent.Files?
|
||||
.Where(m => fileFilter.IsDownloadable(torrent, m.Path, m.Bytes) && m.DownloadLink != null)
|
||||
.Select(m => new DownloadInfo
|
||||
{
|
||||
RestrictedLink = m.DownloadLink!,
|
||||
FileName = Path.GetFileName(m.Path)
|
||||
})
|
||||
.ToList();
|
||||
}
|
||||
|
||||
private async Task<TorrentClientTorrent> GetInfo(String torrentId)
|
||||
|
|
@ -280,16 +276,13 @@ public class DebridLinkClient(ILogger<DebridLinkClient> logger, IHttpClientFacto
|
|||
logger.LogDebug(message);
|
||||
}
|
||||
|
||||
public Task<String> GetFileName(String downloadUrl)
|
||||
/// <inheritdoc />
|
||||
public Task<String> GetFileName(Download download)
|
||||
{
|
||||
if (String.IsNullOrWhiteSpace(downloadUrl))
|
||||
{
|
||||
return Task.FromResult("");
|
||||
}
|
||||
|
||||
var uri = new Uri(downloadUrl);
|
||||
|
||||
return Task.FromResult(HttpUtility.UrlDecode(uri.Segments.Last()));
|
||||
// FileName is set in GetDownlaadInfos
|
||||
Debug.Assert(download.FileName != null);
|
||||
|
||||
return Task.FromResult(download.FileName);
|
||||
}
|
||||
|
||||
public static String? GetSymlinkPath(Data.Models.Data.Torrent torrent, Download download)
|
||||
|
|
|
|||
|
|
@ -14,6 +14,12 @@ public interface ITorrentClient
|
|||
Task Delete(String torrentId);
|
||||
Task<String> Unrestrict(String link);
|
||||
Task<Torrent> UpdateData(Torrent torrent, TorrentClientTorrent? torrentClientTorrent);
|
||||
Task<IList<String>?> GetDownloadLinks(Torrent torrent);
|
||||
Task<String> GetFileName(String downloadUrl);
|
||||
Task<IList<DownloadInfo>?> GetDownloadInfos(Torrent torrent);
|
||||
/// <summary>
|
||||
/// To be called only when <see cref="Data.Models.Data.Download" />.<see cref="Data.Models.Data.Download.FileName" /> is not set by
|
||||
/// <see cref="GetDownloadInfos" />
|
||||
/// </summary>
|
||||
/// <param name="download">The download to get the filename of</param>
|
||||
/// <returns>The filename of the download</returns>
|
||||
Task<String> GetFileName(Download download);
|
||||
}
|
||||
|
|
@ -1,10 +1,11 @@
|
|||
using Microsoft.Extensions.Logging;
|
||||
using System.Diagnostics;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Newtonsoft.Json;
|
||||
using PremiumizeNET;
|
||||
using RdtClient.Data.Enums;
|
||||
using RdtClient.Data.Models.TorrentClient;
|
||||
using RdtClient.Service.Helpers;
|
||||
using System.Web;
|
||||
using RdtClient.Data.Models.Data;
|
||||
using Torrent = RdtClient.Data.Models.Data.Torrent;
|
||||
|
||||
namespace RdtClient.Service.Services.TorrentClients;
|
||||
|
|
@ -197,7 +198,7 @@ public class PremiumizeTorrentClient(ILogger<PremiumizeTorrentClient> logger, IH
|
|||
return torrent;
|
||||
}
|
||||
|
||||
public async Task<IList<String>?> GetDownloadLinks(Torrent torrent)
|
||||
public async Task<IList<DownloadInfo>?> GetDownloadInfos(Torrent torrent)
|
||||
{
|
||||
if (torrent.RdId == null)
|
||||
{
|
||||
|
|
@ -212,7 +213,7 @@ public class PremiumizeTorrentClient(ILogger<PremiumizeTorrentClient> logger, IH
|
|||
|
||||
Log($"Found transfer {transfer.Name} ({transfer.Id})", torrent);
|
||||
|
||||
var downloadLinks = await GetAllDownloadLinks(torrent, transfer.FolderId);
|
||||
var downloadInfos = await GetAllDownloadInfos(torrent, transfer.FolderId);
|
||||
|
||||
if (!String.IsNullOrWhiteSpace(transfer.FileId))
|
||||
{
|
||||
|
|
@ -225,34 +226,31 @@ public class PremiumizeTorrentClient(ILogger<PremiumizeTorrentClient> logger, IH
|
|||
Log($"File {file.Name} ({file.Id}) does not contain a link", torrent);
|
||||
}
|
||||
|
||||
downloadLinks.Add(file.Link);
|
||||
downloadInfos.Add(new () {RestrictedLink = file.Link, FileName = file.Name });
|
||||
}
|
||||
|
||||
if (downloadLinks.Count == 0)
|
||||
if (downloadInfos.Count == 0)
|
||||
{
|
||||
Log($"No download links found for transfer {transfer.Name} ({transfer.Id})", torrent);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
foreach (var link in downloadLinks)
|
||||
foreach (var info in downloadInfos)
|
||||
{
|
||||
Log($"Found {link}", torrent);
|
||||
Log($"Found {info.RestrictedLink}", torrent);
|
||||
}
|
||||
|
||||
return downloadLinks;
|
||||
return downloadInfos;
|
||||
}
|
||||
|
||||
public Task<String> GetFileName(String downloadUrl)
|
||||
/// <inheritdoc />
|
||||
public Task<String> GetFileName(Download download)
|
||||
{
|
||||
if (String.IsNullOrWhiteSpace(downloadUrl))
|
||||
{
|
||||
return Task.FromResult("");
|
||||
}
|
||||
|
||||
var uri = new Uri(downloadUrl);
|
||||
|
||||
return Task.FromResult(HttpUtility.UrlDecode(uri.Segments.Last()));
|
||||
// FileName is set in GetDownlaadInfos
|
||||
Debug.Assert(download.FileName != null);
|
||||
|
||||
return Task.FromResult(download.FileName);
|
||||
}
|
||||
|
||||
private async Task<TorrentClientTorrent> GetInfo(String id)
|
||||
|
|
@ -263,13 +261,12 @@ public class PremiumizeTorrentClient(ILogger<PremiumizeTorrentClient> logger, IH
|
|||
return Map(result);
|
||||
}
|
||||
|
||||
private async Task<List<String>> GetAllDownloadLinks(Torrent torrent, String folderId)
|
||||
private async Task<List<DownloadInfo>> GetAllDownloadInfos(Torrent torrent, String folderId)
|
||||
{
|
||||
var downloadLinks = new List<String>();
|
||||
|
||||
if (String.IsNullOrWhiteSpace(folderId))
|
||||
{
|
||||
return downloadLinks;
|
||||
return [];
|
||||
}
|
||||
|
||||
var folder = await GetClient().Folder.ListAsync(folderId);
|
||||
|
|
@ -277,11 +274,13 @@ public class PremiumizeTorrentClient(ILogger<PremiumizeTorrentClient> logger, IH
|
|||
if (folder.Content == null)
|
||||
{
|
||||
Log($"Found no items in folder {folder.Name} ({folderId})", torrent);
|
||||
return downloadLinks;
|
||||
return [];
|
||||
}
|
||||
|
||||
Log($"Found {folder.Content.Count} items in folder {folder.Name} ({folderId})", torrent);
|
||||
|
||||
var downloadInfos = new List<DownloadInfo>();
|
||||
|
||||
foreach (var item in folder.Content)
|
||||
{
|
||||
if (item.Type == "file")
|
||||
|
|
@ -300,7 +299,7 @@ public class PremiumizeTorrentClient(ILogger<PremiumizeTorrentClient> logger, IH
|
|||
|
||||
Log($"Found item {item.Name} in folder {folder.Name} ({folderId})", torrent);
|
||||
|
||||
downloadLinks.Add(item.Link);
|
||||
downloadInfos.Add(new () { RestrictedLink = item.Link, FileName = item.Name});
|
||||
}
|
||||
else if (item.Type == "folder")
|
||||
{
|
||||
|
|
@ -311,8 +310,8 @@ public class PremiumizeTorrentClient(ILogger<PremiumizeTorrentClient> logger, IH
|
|||
}
|
||||
|
||||
Log($"Found subfolder {item.Name} in {folder.Name} ({folderId}), searching subfolder for files", torrent);
|
||||
var subDownloadLinks = await GetAllDownloadLinks(torrent, item.Id);
|
||||
downloadLinks.AddRange(subDownloadLinks);
|
||||
var subDownloadLinks = await GetAllDownloadInfos(torrent, item.Id);
|
||||
downloadInfos.AddRange(subDownloadLinks);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -320,7 +319,7 @@ public class PremiumizeTorrentClient(ILogger<PremiumizeTorrentClient> logger, IH
|
|||
}
|
||||
}
|
||||
|
||||
return downloadLinks;
|
||||
return downloadInfos;
|
||||
}
|
||||
|
||||
private void Log(String message, Torrent? torrent = null)
|
||||
|
|
|
|||
|
|
@ -3,8 +3,11 @@ using Microsoft.Extensions.Logging;
|
|||
using Newtonsoft.Json;
|
||||
using RDNET;
|
||||
using RdtClient.Data.Enums;
|
||||
using RdtClient.Data.Models.Data;
|
||||
using RdtClient.Data.Models.TorrentClient;
|
||||
using RdtClient.Service.Helpers;
|
||||
using Download = RdtClient.Data.Models.Data.Download;
|
||||
using Torrent = RDNET.Torrent;
|
||||
|
||||
namespace RdtClient.Service.Services.TorrentClients;
|
||||
|
||||
|
|
@ -265,7 +268,7 @@ public class RealDebridTorrentClient(ILogger<RealDebridTorrentClient> logger, IH
|
|||
return torrent;
|
||||
}
|
||||
|
||||
public async Task<IList<String>?> GetDownloadLinks(Data.Models.Data.Torrent torrent)
|
||||
public async Task<IList<DownloadInfo>?> GetDownloadInfos(Data.Models.Data.Torrent torrent)
|
||||
{
|
||||
if (torrent.RdId == null)
|
||||
{
|
||||
|
|
@ -279,7 +282,14 @@ public class RealDebridTorrentClient(ILogger<RealDebridTorrentClient> logger, IH
|
|||
return null;
|
||||
}
|
||||
|
||||
var downloadLinks = rdTorrent.Links.Where(m => !String.IsNullOrWhiteSpace(m)).ToList();
|
||||
var downloadLinks = rdTorrent.Links
|
||||
.Where(m => !String.IsNullOrWhiteSpace(m))
|
||||
.Select(l => new DownloadInfo
|
||||
{
|
||||
RestrictedLink = l,
|
||||
FileName = null
|
||||
})
|
||||
.ToList();
|
||||
|
||||
Log($"Found {downloadLinks.Count} links", torrent);
|
||||
|
||||
|
|
@ -326,14 +336,15 @@ public class RealDebridTorrentClient(ILogger<RealDebridTorrentClient> logger, IH
|
|||
return null;
|
||||
}
|
||||
|
||||
public Task<String> GetFileName(String downloadUrl)
|
||||
/// <inheritdoc />
|
||||
public Task<String> GetFileName(Download download)
|
||||
{
|
||||
if (String.IsNullOrWhiteSpace(downloadUrl))
|
||||
if (String.IsNullOrWhiteSpace(download.Link))
|
||||
{
|
||||
return Task.FromResult("");
|
||||
}
|
||||
|
||||
var uri = new Uri(downloadUrl);
|
||||
var uri = new Uri(download.Link);
|
||||
|
||||
return Task.FromResult(HttpUtility.UrlDecode(uri.Segments.Last()));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
using System.Reflection;
|
||||
using System.Diagnostics;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Newtonsoft.Json;
|
||||
using TorBoxNET;
|
||||
using RdtClient.Data.Enums;
|
||||
using RdtClient.Data.Models.TorrentClient;
|
||||
using System.Web;
|
||||
using RdtClient.Data.Models.Data;
|
||||
using RdtClient.Service.Helpers;
|
||||
|
||||
|
|
@ -285,7 +285,7 @@ public class TorBoxTorrentClient(ILogger<TorBoxTorrentClient> logger, IHttpClien
|
|||
return torrent;
|
||||
}
|
||||
|
||||
public async Task<IList<String>?> GetDownloadLinks(Torrent torrent)
|
||||
public async Task<IList<DownloadInfo>?> GetDownloadInfos(Torrent torrent)
|
||||
{
|
||||
var torrentId = await GetClient().Torrents.GetHashInfoAsync(torrent.Hash, skipCache: true);
|
||||
var downloadableFiles = torrent.Files.Where(file => fileFilter.IsDownloadable(torrent, file.Path, file.Bytes)).ToList();
|
||||
|
|
@ -293,51 +293,36 @@ public class TorBoxTorrentClient(ILogger<TorBoxTorrentClient> logger, IHttpClien
|
|||
if (downloadableFiles.Count == torrent.Files.Count && torrent.DownloadClient != Data.Enums.DownloadClient.Symlink)
|
||||
{
|
||||
logger.LogDebug("Downloading files from TorBox as a zip.");
|
||||
return [$"https://torbox.app/fakedl/{torrentId?.Id}/zip"];
|
||||
|
||||
return
|
||||
[
|
||||
new DownloadInfo
|
||||
{
|
||||
RestrictedLink = $"https://torbox.app/fakedl/{torrentId?.Id}/zip",
|
||||
FileName = $"{torrent.RdName}.zip"
|
||||
}
|
||||
];
|
||||
}
|
||||
else
|
||||
{
|
||||
logger.LogDebug("Downloading files from TorBox individually.");
|
||||
return downloadableFiles.Select(file => $"https://torbox.app/fakedl/{torrentId?.Id}/{file.Id}").ToList();
|
||||
|
||||
return downloadableFiles.Select(file => new DownloadInfo
|
||||
{
|
||||
RestrictedLink = $"https://torbox.app/fakedl/{torrentId?.Id}/{file.Id}",
|
||||
FileName = Path.GetFileName(file.Path)
|
||||
})
|
||||
.ToList();
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<String> GetFileName(String downloadUrl)
|
||||
/// <inheritdoc />
|
||||
public Task<String> GetFileName(Download download)
|
||||
{
|
||||
if (String.IsNullOrWhiteSpace(downloadUrl))
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
var uri = new Uri(downloadUrl);
|
||||
|
||||
using (HttpClient client = new())
|
||||
{
|
||||
client.Timeout = TimeSpan.FromSeconds(Settings.Get.Provider.Timeout);
|
||||
var request = new HttpRequestMessage(HttpMethod.Head, uri);
|
||||
var response = await client.SendAsync(request);
|
||||
if (response.Content.Headers.ContentDisposition != null)
|
||||
{
|
||||
var fileName = response.Content.Headers.ContentDisposition.FileName;
|
||||
if (!String.IsNullOrWhiteSpace(fileName))
|
||||
{
|
||||
return fileName.Trim('"');
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (response.Content.Headers.ContentType?.MediaType == "application/zip")
|
||||
{
|
||||
return $"download-{new Random().Next(1, 10001)}.zip";
|
||||
}
|
||||
else
|
||||
{
|
||||
logger.LogDebug($"Failed to get filename for URI {downloadUrl}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return HttpUtility.UrlDecode(uri.Segments.Last());
|
||||
// FileName is set in GetDownlaadInfos
|
||||
Debug.Assert(download.FileName != null);
|
||||
|
||||
return Task.FromResult(download.FileName);
|
||||
}
|
||||
|
||||
private DateTimeOffset? ChangeTimeZone(DateTimeOffset? dateTimeOffset)
|
||||
|
|
|
|||
|
|
@ -362,8 +362,11 @@ public class TorrentRunner(ILogger<TorrentRunner> logger, Torrents torrents, Dow
|
|||
var downloadLink = await torrents.UnrestrictLink(download.DownloadId);
|
||||
download.Link = downloadLink;
|
||||
|
||||
var fileName = await torrents.RetrieveFileName(download.DownloadId);
|
||||
download.FileName = fileName;
|
||||
if (download.FileName == null)
|
||||
{
|
||||
var fileName = await torrents.RetrieveFileName(download.DownloadId);
|
||||
download.FileName = fileName;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
|
|
|
|||
|
|
@ -235,14 +235,14 @@ public class Torrents(
|
|||
return;
|
||||
}
|
||||
|
||||
var downloadLinks = await TorrentClient.GetDownloadLinks(torrent);
|
||||
var downloadInfos = await TorrentClient.GetDownloadInfos(torrent);
|
||||
|
||||
if (downloadLinks == null)
|
||||
if (downloadInfos == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (downloadLinks.Count == 0)
|
||||
if (downloadInfos.Count == 0)
|
||||
{
|
||||
logger.LogInformation("All files excluded by filters (IncludeRegex: {includeRegex}, ExcludeRegex: {excludeRegex}, DownloadMinSize: {downloadMinSize} {torrentInfo}",
|
||||
torrent.IncludeRegex,
|
||||
|
|
@ -256,14 +256,14 @@ public class Torrents(
|
|||
return;
|
||||
}
|
||||
|
||||
foreach (var downloadLink in downloadLinks)
|
||||
foreach (var downloadInfo in downloadInfos)
|
||||
{
|
||||
// Make sure downloads don't get added multiple times
|
||||
var downloadExists = await downloads.Get(torrent.TorrentId, downloadLink);
|
||||
var downloadExists = await downloads.Get(torrent.TorrentId, downloadInfo.RestrictedLink);
|
||||
|
||||
if (downloadExists == null && !String.IsNullOrWhiteSpace(downloadLink))
|
||||
if (downloadExists == null && !String.IsNullOrWhiteSpace(downloadInfo.RestrictedLink))
|
||||
{
|
||||
await downloads.Add(torrent.TorrentId, downloadLink);
|
||||
await downloads.Add(torrent.TorrentId, downloadInfo);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -390,13 +390,17 @@ public class Torrents(
|
|||
return unrestrictedLink;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// To be called only when <see cref="Data.Models.Data.Download" />.<see cref="Data.Models.Data.Download.FileName" /> is not set by
|
||||
/// <see cref="ITorrentClient.GetDownloadInfos" />
|
||||
/// </summary>
|
||||
public async Task<String> RetrieveFileName(Guid downloadId)
|
||||
{
|
||||
var download = await downloads.GetById(downloadId) ?? throw new($"Download with ID {downloadId} not found");
|
||||
|
||||
Log($"Retrieving filename for", download, download.Torrent);
|
||||
|
||||
var fileName = await TorrentClient.GetFileName(download.Link!);
|
||||
var fileName = await TorrentClient.GetFileName(download!);
|
||||
|
||||
await downloads.UpdateFileName(downloadId, fileName);
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue