From 59c47bfe1a31634a667af88778f8e11923320ac4 Mon Sep 17 00:00:00 2001 From: Wald764 Date: Sun, 22 Oct 2023 00:14:52 +0200 Subject: [PATCH 01/14] :tada: add support of DebridLinkFr --- client/src/app/navbar/navbar.component.ts | 3 + client/src/app/setup/setup.component.html | 12 +- server/RdtClient.Data/Enums/Provider.cs | 3 + .../Models/Internal/DbSettings.cs | 5 +- server/RdtClient.Service/DiConfig.cs | 1 + .../RdtClient.Service.csproj | 1 + .../DebridLinkFrTorrentClient.cs | 317 ++++++++++++++++++ server/RdtClient.Service/Services/Torrents.cs | 10 +- 8 files changed, 346 insertions(+), 6 deletions(-) create mode 100644 server/RdtClient.Service/Services/TorrentClients/DebridLinkFrTorrentClient.cs diff --git a/client/src/app/navbar/navbar.component.ts b/client/src/app/navbar/navbar.component.ts index 95c8067..a07406d 100644 --- a/client/src/app/navbar/navbar.component.ts +++ b/client/src/app/navbar/navbar.component.ts @@ -35,6 +35,9 @@ export class NavbarComponent implements OnInit { case 'Premiumize': this.providerLink = 'https://www.premiumize.me/'; break; + case 'DebridLinkFr': + this.providerLink = 'https://debrid-link.fr/'; + break; case 'TorBox': this.providerLink = 'https://torbox.app/'; break; diff --git a/client/src/app/setup/setup.component.html b/client/src/app/setup/setup.component.html index 28c81e3..fda6219 100644 --- a/client/src/app/setup/setup.component.html +++ b/client/src/app/setup/setup.component.html @@ -56,6 +56,9 @@ >Use this link to sign up to Premiumize.
+ Use this link to sign up to DebridLinkFr. Use this link to sign up to TorBox.
@@ -68,7 +71,8 @@ - + + @@ -99,6 +103,12 @@ You can find your API key here: https://torbox.app/settings.

+

+ You can find your API key here: + https://debrid-link.com/webapp/apikey. +

diff --git a/server/RdtClient.Data/Enums/Provider.cs b/server/RdtClient.Data/Enums/Provider.cs index ff372dc..00e3da4 100644 --- a/server/RdtClient.Data/Enums/Provider.cs +++ b/server/RdtClient.Data/Enums/Provider.cs @@ -13,6 +13,9 @@ public enum Provider [Description("Premiumize")] Premiumize, + [Description("DebridLinkFr")] + DebridLinkFr, + [Description("TorBox")] TorBox } \ No newline at end of file diff --git a/server/RdtClient.Data/Models/Internal/DbSettings.cs b/server/RdtClient.Data/Models/Internal/DbSettings.cs index dba1ff3..e90e258 100644 --- a/server/RdtClient.Data/Models/Internal/DbSettings.cs +++ b/server/RdtClient.Data/Models/Internal/DbSettings.cs @@ -159,6 +159,7 @@ public class DbSettingsProvider https://real-debrid.com https://alldebrid.com https://www.premiumize.me/ +https://debrid-link.com/ https://torbox.app/ At this point only 1 provider can be used at the time.")] public Provider Provider { get; set; } = Provider.RealDebrid; @@ -171,7 +172,9 @@ or or https://www.premiumize.me/account/ or -https://torbox.app/settings/")] +https://torbox.app/settings/ +or +https://debrid-link.com/webapp/apikey")] public String ApiKey { get; set; } = ""; [DisplayName("Automatically import and process torrents added to provider")] diff --git a/server/RdtClient.Service/DiConfig.cs b/server/RdtClient.Service/DiConfig.cs index 695443f..e61c71a 100644 --- a/server/RdtClient.Service/DiConfig.cs +++ b/server/RdtClient.Service/DiConfig.cs @@ -27,6 +27,7 @@ public static class DiConfig services.AddScoped(); services.AddScoped(); services.AddScoped(); + services.AddScoped(); services.AddSingleton(); diff --git a/server/RdtClient.Service/RdtClient.Service.csproj b/server/RdtClient.Service/RdtClient.Service.csproj index 90ad249..a3a60b5 100644 --- a/server/RdtClient.Service/RdtClient.Service.csproj +++ b/server/RdtClient.Service/RdtClient.Service.csproj @@ -11,6 +11,7 @@ + diff --git a/server/RdtClient.Service/Services/TorrentClients/DebridLinkFrTorrentClient.cs b/server/RdtClient.Service/Services/TorrentClients/DebridLinkFrTorrentClient.cs new file mode 100644 index 0000000..ea7927c --- /dev/null +++ b/server/RdtClient.Service/Services/TorrentClients/DebridLinkFrTorrentClient.cs @@ -0,0 +1,317 @@ +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; + +namespace RdtClient.Service.Services.TorrentClients; + +public class DebridLinkFrClient : ITorrentClient +{ + private readonly ILogger _logger; + private readonly IHttpClientFactory _httpClientFactory; + + public DebridLinkFrClient(ILogger logger, IHttpClientFactory httpClientFactory) + { + _logger = logger; + _httpClientFactory = httpClientFactory; + } + + private DebridLinkFrNETClient GetClient() + { + try + { + var apiKey = Settings.Get.Provider.ApiKey; + + if (String.IsNullOrWhiteSpace(apiKey)) + { + throw new Exception("Real-Debrid API Key not set in the settings"); + } + + var httpClient = _httpClientFactory.CreateClient(); + httpClient.Timeout = TimeSpan.FromSeconds(Settings.Get.Provider.Timeout); + + var debridLinkFrClient = new DebridLinkFrNETClient(apiKey, httpClient); + + return debridLinkFrClient; + } + catch (AggregateException ae) + { + foreach (var inner in ae.InnerExceptions) + { + _logger.LogError(inner, $"The connection to DebridLinkFr has failed: {inner.Message}"); + } + + throw; + } + catch (TaskCanceledException ex) when (ex.InnerException is TimeoutException) + { + _logger.LogError(ex, $"The connection to DebridLinkFr has timed out: {ex.Message}"); + + throw; + } + catch (TaskCanceledException ex) + { + _logger.LogError(ex, $"The connection to DebridLinkFr has timed out: {ex.Message}"); + + throw; + } + } + + private TorrentClientTorrent Map(Torrent torrent) + { + return new TorrentClientTorrent + { + Id = torrent.Id ?? "", + Filename = torrent.Name ?? "", + OriginalFilename = torrent.Name ?? "", + Hash = torrent.HashString ?? "", + Bytes = torrent.TotalSize, + OriginalBytes = 0, + Host = torrent.ServerId ?? "", + Split = 0, + Progress = torrent.DownloadPercent, + Status = torrent.Status.ToString(), + Added = DateTimeOffset.FromUnixTimeSeconds(torrent.Created), + Files = (torrent.Files ?? new List()).Select((m, i) => new TorrentClientFile + { + Path = m.Name ?? "", + Bytes = m.Size, + Id = i, + Selected = true + }).ToList(), + Links = torrent.Files?.Select(m => m.DownloadUrl.ToString()).ToList(), + Ended = null, + Speed = torrent.UploadSpeed, + Seeders = torrent.PeersConnected, + }; + } + + public async Task> GetTorrents() + { + var page = 0; + var results = new List(); + + while (true) + { + var pagedResults = await GetClient().Seedbox.ListAsync(null,page, 50); + + results.AddRange(pagedResults); + + if (pagedResults.Count == 0) + { + break; + } + + page += 1; + } + + return results.Select(Map).ToList(); + } + + public async Task GetUser() + { + var user = await GetClient().Account.Infos(); + + return new TorrentClientUser + { + Username = user.Username, + Expiration = user.PremiumLeft > 0 ? DateTimeOffset.Now.AddSeconds(user.PremiumLeft) : null + }; + } + + public async Task AddMagnet(String magnetLink) + { + var result = await GetClient().Seedbox.AddTorrentAsync(magnetLink); + + return result.Id ?? ""; + } + + public async Task AddFile(Byte[] bytes) + { + var result = await GetClient().Seedbox.AddTorrentByFileAsync(bytes); + + return result.Id ?? ""; + } + + public async Task> GetAvailableFiles(String hash) + { + var result = await GetClient().Seedbox.CachedAsync(hash); + + var files = result.First().Value.Files ?? new List(); + + var groups = files.Where(m => m.Name != null).GroupBy(m => $"{m.Name}-{m.Size}"); + + var torrentClientAvailableFiles = groups.Select(m => new TorrentClientAvailableFile + { + Filename = m.First().Name!, + Filesize = m.First().Size + }).ToList(); + + return torrentClientAvailableFiles; + } + + public Task SelectFiles(Data.Models.Data.Torrent torrent) + { + return Task.CompletedTask; + } + + public async Task Delete(String torrentId) + { + await GetClient().Seedbox.DeleteAsync(torrentId); + } + + public async Task Unrestrict(String link) + { + return link; + } + + public async Task UpdateData(Data.Models.Data.Torrent torrent, TorrentClientTorrent? torrentClientTorrent) + { + try + { + if (torrent.RdId == null) + { + return torrent; + } + + var rdTorrent = await GetInfo(torrent.RdId); + + if (rdTorrent == null) + { + throw new Exception($"Resource not found"); + } + + if (!String.IsNullOrWhiteSpace(rdTorrent.Filename)) + { + torrent.RdName = rdTorrent.Filename; + } + + if (!String.IsNullOrWhiteSpace(rdTorrent.OriginalFilename)) + { + torrent.RdName = rdTorrent.OriginalFilename; + } + + if (rdTorrent.Bytes > 0) + { + torrent.RdSize = rdTorrent.Bytes; + } + else if (rdTorrent.OriginalBytes > 0) + { + torrent.RdSize = rdTorrent.OriginalBytes; + } + + if (rdTorrent.Files != null) + { + torrent.RdFiles = JsonConvert.SerializeObject(rdTorrent.Files); + } + + torrent.RdHost = rdTorrent.Host; + torrent.RdSplit = rdTorrent.Split; + torrent.RdProgress = rdTorrent.Progress; + torrent.RdAdded = rdTorrent.Added; + torrent.RdEnded = rdTorrent.Ended; + torrent.RdSpeed = rdTorrent.Speed; + torrent.RdSeeders = rdTorrent.Seeders; + torrent.RdStatusRaw = rdTorrent.Status; + /** + * + * 0 Torrent is stopped + * 1 Torrent is queued to verify local data + * 2 Torrent is verifying local data + * 3 Torrent is queued to download + * 4 Torrent is downloading + * 5 Torrent is queued to seed + * 6 Torrent is seeding + * 100 Torrent is stored + */ + torrent.RdStatus = rdTorrent.Status switch + { + "100" => TorrentStatus.Finished, + "1" => TorrentStatus.Processing, + "2" => TorrentStatus.Processing, + "3" => TorrentStatus.Processing, + "4" => TorrentStatus.Downloading, + "5" => TorrentStatus.Finished, + "6" => TorrentStatus.Finished, + _ => TorrentStatus.Error + }; + } + catch (Exception ex) + { + if (ex.Message == "Resource not found") + { + torrent.RdStatusRaw = "deleted"; + } + else + { + throw; + } + } + + return torrent; + } + + public async Task?> GetDownloadLinks(Data.Models.Data.Torrent torrent) + { + if (torrent.RdId == null) + { + return null; + } + + var rdTorrent = await GetInfo(torrent.RdId); + + if (rdTorrent.Links == null) + { + return null; + } + + var downloadLinks = rdTorrent.Links.Where(m => !String.IsNullOrWhiteSpace(m)).ToList(); + + Log($"Found {downloadLinks.Count} links", torrent); + + foreach (var link in downloadLinks) + { + Log($"{link}", torrent); + } + + // Check if all the links are set that have been selected + if (torrent.Files.Count(m => m.Selected) == downloadLinks.Count) + { + return downloadLinks; + } + + // Check if all all the links are set for manual selection + if (torrent.ManualFiles.Count == downloadLinks.Count) + { + return downloadLinks; + } + + // If there is only 1 link, delay for 1 minute to see if more links pop up. + if (downloadLinks.Count == 1 && torrent.RdEnded.HasValue && DateTime.UtcNow > torrent.RdEnded.Value.ToUniversalTime().AddMinutes(1)) + { + return downloadLinks; + } + + return null; + } + + private async Task GetInfo(String torrentId) + { + var result = await GetClient().Seedbox.ListAsync(torrentId); + + return Map(result.First()); + } + + private void Log(String message, Data.Models.Data.Torrent? torrent = null) + { + if (torrent != null) + { + message = $"{message} {torrent.ToLog()}"; + } + + _logger.LogDebug(message); + } +} \ No newline at end of file diff --git a/server/RdtClient.Service/Services/Torrents.cs b/server/RdtClient.Service/Services/Torrents.cs index 97d93bc..877314f 100644 --- a/server/RdtClient.Service/Services/Torrents.cs +++ b/server/RdtClient.Service/Services/Torrents.cs @@ -23,6 +23,7 @@ public class Torrents( AllDebridTorrentClient allDebridTorrentClient, PremiumizeTorrentClient premiumizeTorrentClient, RealDebridTorrentClient realDebridTorrentClient, + DebridLinkFrClient debridLinkFrClient, TorBoxTorrentClient torBoxTorrentClient) { private static readonly SemaphoreSlim RealDebridUpdateLock = new(1, 1); @@ -41,6 +42,7 @@ public class Torrents( Provider.Premiumize => premiumizeTorrentClient, Provider.RealDebrid => realDebridTorrentClient, Provider.AllDebrid => allDebridTorrentClient, + Provider.DebridLinkFr => debridLinkFrClient, Provider.TorBox => torBoxTorrentClient, _ => throw new("Invalid Provider") }; @@ -575,7 +577,7 @@ public class Torrents( await torrentData.UpdateComplete(download.TorrentId, null, null, false); } - + public async Task UpdateComplete(Guid torrentId, String? error, DateTimeOffset datetime, Boolean retry) { await torrentData.UpdateComplete(torrentId, error, datetime, retry); @@ -657,7 +659,7 @@ public class Torrents( Torrent torrent) { await RealDebridUpdateLock.WaitAsync(); - + try { var existingTorrent = await torrentData.GetByHash(infoHash); @@ -732,7 +734,7 @@ public class Torrents( var outputSb = new StringBuilder(); using var process = new Process(); - + process.StartInfo.FileName = fileName; process.StartInfo.Arguments = arguments; process.StartInfo.CreateNoWindow = true; @@ -758,7 +760,7 @@ public class Torrents( errorSb.AppendLine(data.Data.Trim()); }; - + process.Start(); process.BeginOutputReadLine(); process.BeginErrorReadLine(); From 4198b6ab557b4610376c11128f5916365269aeb0 Mon Sep 17 00:00:00 2001 From: Wald764 Date: Sun, 2 Feb 2025 16:26:46 +0100 Subject: [PATCH 02/14] :bug: fixes about the providers order and addition of GetFileName to DebridLinkFrTorrentClient --- client/src/app/navbar/navbar.component.ts | 6 +++--- client/src/app/setup/setup.component.html | 12 ++++++------ .../TorrentClients/DebridLinkFrTorrentClient.cs | 13 +++++++++++++ 3 files changed, 22 insertions(+), 9 deletions(-) diff --git a/client/src/app/navbar/navbar.component.ts b/client/src/app/navbar/navbar.component.ts index a07406d..2880814 100644 --- a/client/src/app/navbar/navbar.component.ts +++ b/client/src/app/navbar/navbar.component.ts @@ -35,12 +35,12 @@ export class NavbarComponent implements OnInit { case 'Premiumize': this.providerLink = 'https://www.premiumize.me/'; break; - case 'DebridLinkFr': - this.providerLink = 'https://debrid-link.fr/'; - break; case 'TorBox': this.providerLink = 'https://torbox.app/'; break; + case 'DebridLinkFr': + this.providerLink = 'https://debrid-link.com/'; + break; } }); } diff --git a/client/src/app/setup/setup.component.html b/client/src/app/setup/setup.component.html index fda6219..a096260 100644 --- a/client/src/app/setup/setup.component.html +++ b/client/src/app/setup/setup.component.html @@ -42,7 +42,7 @@
To be able to use the Real-Debrid Client you need a premium subscription to download torrents.

- Not premium yet? You have the choice of 4 providers: + Not premium yet? You have the choice of 5 providers:
Use this link to sign up to Real-Debrid.Use this link to sign up to Premiumize.
- Use this link to sign up to DebridLinkFr. Use this link to sign up to TorBox.
+ Use this link to sign up to DebridLink. (Referal links)
@@ -71,8 +71,8 @@ - - + +
diff --git a/server/RdtClient.Service/Services/TorrentClients/DebridLinkFrTorrentClient.cs b/server/RdtClient.Service/Services/TorrentClients/DebridLinkFrTorrentClient.cs index ea7927c..6d1b219 100644 --- a/server/RdtClient.Service/Services/TorrentClients/DebridLinkFrTorrentClient.cs +++ b/server/RdtClient.Service/Services/TorrentClients/DebridLinkFrTorrentClient.cs @@ -5,6 +5,7 @@ using RdtClient.Data.Enums; using RdtClient.Data.Models.TorrentClient; using RdtClient.Service.Helpers; using DebridLinkFrNET.Models; +using System.Web; namespace RdtClient.Service.Services.TorrentClients; @@ -314,4 +315,16 @@ public class DebridLinkFrClient : ITorrentClient _logger.LogDebug(message); } + + public Task GetFileName(string downloadUrl) + { + if (String.IsNullOrWhiteSpace(downloadUrl)) + { + return Task.FromResult(""); + } + + var uri = new Uri(downloadUrl); + + return Task.FromResult(HttpUtility.UrlDecode(uri.Segments.Last())); + } } \ No newline at end of file From 7902f56d6658f4f9a7408553078c68ad4634527a Mon Sep 17 00:00:00 2001 From: Wald764 Date: Sun, 2 Feb 2025 16:46:35 +0100 Subject: [PATCH 03/14] :bug: endpoint /seedbox/cached removed by DebridLink --- .../TorrentClients/DebridLinkFrTorrentClient.cs | 16 ++-------------- 1 file changed, 2 insertions(+), 14 deletions(-) diff --git a/server/RdtClient.Service/Services/TorrentClients/DebridLinkFrTorrentClient.cs b/server/RdtClient.Service/Services/TorrentClients/DebridLinkFrTorrentClient.cs index 6d1b219..d21a1ce 100644 --- a/server/RdtClient.Service/Services/TorrentClients/DebridLinkFrTorrentClient.cs +++ b/server/RdtClient.Service/Services/TorrentClients/DebridLinkFrTorrentClient.cs @@ -137,21 +137,9 @@ public class DebridLinkFrClient : ITorrentClient return result.Id ?? ""; } - public async Task> GetAvailableFiles(String hash) + public Task> GetAvailableFiles(String hash) { - var result = await GetClient().Seedbox.CachedAsync(hash); - - var files = result.First().Value.Files ?? new List(); - - var groups = files.Where(m => m.Name != null).GroupBy(m => $"{m.Name}-{m.Size}"); - - var torrentClientAvailableFiles = groups.Select(m => new TorrentClientAvailableFile - { - Filename = m.First().Name!, - Filesize = m.First().Size - }).ToList(); - - return torrentClientAvailableFiles; + return Task.FromResult>([]); } public Task SelectFiles(Data.Models.Data.Torrent torrent) From d6d1813340115364e30b0f7e6b866abb277590bd Mon Sep 17 00:00:00 2001 From: Wald764 Date: Sun, 2 Feb 2025 17:10:41 +0100 Subject: [PATCH 04/14] :bug: implement PR suggestions --- server/RdtClient.Data/Enums/Provider.cs | 8 ++++---- server/RdtClient.Data/Models/Data/Torrent.cs | 3 ++- .../Services/TorrentClients/DebridLinkFrTorrentClient.cs | 3 ++- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/server/RdtClient.Data/Enums/Provider.cs b/server/RdtClient.Data/Enums/Provider.cs index 00e3da4..ca63c8f 100644 --- a/server/RdtClient.Data/Enums/Provider.cs +++ b/server/RdtClient.Data/Enums/Provider.cs @@ -13,9 +13,9 @@ public enum Provider [Description("Premiumize")] Premiumize, - [Description("DebridLinkFr")] - DebridLinkFr, - [Description("TorBox")] - TorBox + TorBox, + + [Description("DebridLinkFr")] + DebridLinkFr } \ No newline at end of file diff --git a/server/RdtClient.Data/Models/Data/Torrent.cs b/server/RdtClient.Data/Models/Data/Torrent.cs index f928e3e..70b273d 100644 --- a/server/RdtClient.Data/Models/Data/Torrent.cs +++ b/server/RdtClient.Data/Models/Data/Torrent.cs @@ -99,6 +99,7 @@ public class Torrent AllDebrid, Premiumize, RealDebrid, - TorBox + TorBox, + DebridLink } } \ No newline at end of file diff --git a/server/RdtClient.Service/Services/TorrentClients/DebridLinkFrTorrentClient.cs b/server/RdtClient.Service/Services/TorrentClients/DebridLinkFrTorrentClient.cs index d21a1ce..e55bcad 100644 --- a/server/RdtClient.Service/Services/TorrentClients/DebridLinkFrTorrentClient.cs +++ b/server/RdtClient.Service/Services/TorrentClients/DebridLinkFrTorrentClient.cs @@ -78,7 +78,7 @@ public class DebridLinkFrClient : ITorrentClient Added = DateTimeOffset.FromUnixTimeSeconds(torrent.Created), Files = (torrent.Files ?? new List()).Select((m, i) => new TorrentClientFile { - Path = m.Name ?? "", + Path = m.Name, Bytes = m.Size, Id = i, Selected = true @@ -197,6 +197,7 @@ public class DebridLinkFrClient : ITorrentClient torrent.RdFiles = JsonConvert.SerializeObject(rdTorrent.Files); } + torrent.ClientKind = Data.Models.Data.Torrent.TorrentClientKind.DebridLink; torrent.RdHost = rdTorrent.Host; torrent.RdSplit = rdTorrent.Split; torrent.RdProgress = rdTorrent.Progress; From 20fbf8833a289baec465fb3d60cc4ee2d1c769ad Mon Sep 17 00:00:00 2001 From: Wald764 Date: Sun, 2 Feb 2025 17:19:41 +0100 Subject: [PATCH 05/14] :recycle: rename occurrences of debridlinkfr to debridlink --- client/src/app/navbar/navbar.component.ts | 2 +- server/RdtClient.Data/Enums/Provider.cs | 4 ++-- server/RdtClient.Service/DiConfig.cs | 2 +- ...rrentClient.cs => DebridLinkTorrentClient.cs} | 16 ++++++++-------- server/RdtClient.Service/Services/Torrents.cs | 4 ++-- 5 files changed, 14 insertions(+), 14 deletions(-) rename server/RdtClient.Service/Services/TorrentClients/{DebridLinkFrTorrentClient.cs => DebridLinkTorrentClient.cs} (93%) diff --git a/client/src/app/navbar/navbar.component.ts b/client/src/app/navbar/navbar.component.ts index 2880814..7550699 100644 --- a/client/src/app/navbar/navbar.component.ts +++ b/client/src/app/navbar/navbar.component.ts @@ -38,7 +38,7 @@ export class NavbarComponent implements OnInit { case 'TorBox': this.providerLink = 'https://torbox.app/'; break; - case 'DebridLinkFr': + case 'DebridLink': this.providerLink = 'https://debrid-link.com/'; break; } diff --git a/server/RdtClient.Data/Enums/Provider.cs b/server/RdtClient.Data/Enums/Provider.cs index ca63c8f..4c6084b 100644 --- a/server/RdtClient.Data/Enums/Provider.cs +++ b/server/RdtClient.Data/Enums/Provider.cs @@ -16,6 +16,6 @@ public enum Provider [Description("TorBox")] TorBox, - [Description("DebridLinkFr")] - DebridLinkFr + [Description("DebridLink")] + DebridLink } \ No newline at end of file diff --git a/server/RdtClient.Service/DiConfig.cs b/server/RdtClient.Service/DiConfig.cs index e61c71a..71de2b4 100644 --- a/server/RdtClient.Service/DiConfig.cs +++ b/server/RdtClient.Service/DiConfig.cs @@ -27,7 +27,7 @@ public static class DiConfig services.AddScoped(); services.AddScoped(); services.AddScoped(); - services.AddScoped(); + services.AddScoped(); services.AddSingleton(); diff --git a/server/RdtClient.Service/Services/TorrentClients/DebridLinkFrTorrentClient.cs b/server/RdtClient.Service/Services/TorrentClients/DebridLinkTorrentClient.cs similarity index 93% rename from server/RdtClient.Service/Services/TorrentClients/DebridLinkFrTorrentClient.cs rename to server/RdtClient.Service/Services/TorrentClients/DebridLinkTorrentClient.cs index e55bcad..435b656 100644 --- a/server/RdtClient.Service/Services/TorrentClients/DebridLinkFrTorrentClient.cs +++ b/server/RdtClient.Service/Services/TorrentClients/DebridLinkTorrentClient.cs @@ -9,12 +9,12 @@ using System.Web; namespace RdtClient.Service.Services.TorrentClients; -public class DebridLinkFrClient : ITorrentClient +public class DebridLinkClient : ITorrentClient { - private readonly ILogger _logger; + private readonly ILogger _logger; private readonly IHttpClientFactory _httpClientFactory; - public DebridLinkFrClient(ILogger logger, IHttpClientFactory httpClientFactory) + public DebridLinkClient(ILogger logger, IHttpClientFactory httpClientFactory) { _logger = logger; _httpClientFactory = httpClientFactory; @@ -34,28 +34,28 @@ public class DebridLinkFrClient : ITorrentClient var httpClient = _httpClientFactory.CreateClient(); httpClient.Timeout = TimeSpan.FromSeconds(Settings.Get.Provider.Timeout); - var debridLinkFrClient = new DebridLinkFrNETClient(apiKey, httpClient); + var DebridLinkClient = new DebridLinkFrNETClient(apiKey, httpClient); - return debridLinkFrClient; + return DebridLinkClient; } catch (AggregateException ae) { foreach (var inner in ae.InnerExceptions) { - _logger.LogError(inner, $"The connection to DebridLinkFr has failed: {inner.Message}"); + _logger.LogError(inner, $"The connection to DebridLink has failed: {inner.Message}"); } throw; } catch (TaskCanceledException ex) when (ex.InnerException is TimeoutException) { - _logger.LogError(ex, $"The connection to DebridLinkFr has timed out: {ex.Message}"); + _logger.LogError(ex, $"The connection to DebridLink has timed out: {ex.Message}"); throw; } catch (TaskCanceledException ex) { - _logger.LogError(ex, $"The connection to DebridLinkFr has timed out: {ex.Message}"); + _logger.LogError(ex, $"The connection to DebridLink has timed out: {ex.Message}"); throw; } diff --git a/server/RdtClient.Service/Services/Torrents.cs b/server/RdtClient.Service/Services/Torrents.cs index 877314f..0c06cb7 100644 --- a/server/RdtClient.Service/Services/Torrents.cs +++ b/server/RdtClient.Service/Services/Torrents.cs @@ -23,7 +23,7 @@ public class Torrents( AllDebridTorrentClient allDebridTorrentClient, PremiumizeTorrentClient premiumizeTorrentClient, RealDebridTorrentClient realDebridTorrentClient, - DebridLinkFrClient debridLinkFrClient, + DebridLinkClient DebridLinkClient, TorBoxTorrentClient torBoxTorrentClient) { private static readonly SemaphoreSlim RealDebridUpdateLock = new(1, 1); @@ -42,7 +42,7 @@ public class Torrents( Provider.Premiumize => premiumizeTorrentClient, Provider.RealDebrid => realDebridTorrentClient, Provider.AllDebrid => allDebridTorrentClient, - Provider.DebridLinkFr => debridLinkFrClient, + Provider.DebridLink => DebridLinkClient, Provider.TorBox => torBoxTorrentClient, _ => throw new("Invalid Provider") }; From f2207be000ac30c63ec23027fc26564b756026c4 Mon Sep 17 00:00:00 2001 From: Wald764 Date: Sun, 2 Feb 2025 17:35:04 +0100 Subject: [PATCH 06/14] :memo: update `readme` to include `DebridLink` in debrid services --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 22eaffc..2cc71c8 100644 --- a/README.md +++ b/README.md @@ -16,6 +16,8 @@ This is a web interface to manage your torrents on Real-Debrid, AllDebrid or Pre [Click here to sign up for Premiumize.](https://www.premiumize.me/) +[Click here to sign up for DebridLink.](https://debrid-link.fr/) + (referal links so I can get a few free premium days) ## Docker Setup From 303244127bd18042b3bcb24024c9a138fac6f452 Mon Sep 17 00:00:00 2001 From: Wald764 Date: Sun, 2 Feb 2025 17:50:51 +0100 Subject: [PATCH 07/14] :recycle: fix typo in Torrents.cs --- server/RdtClient.Service/Services/Torrents.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/server/RdtClient.Service/Services/Torrents.cs b/server/RdtClient.Service/Services/Torrents.cs index 0c06cb7..0edb19f 100644 --- a/server/RdtClient.Service/Services/Torrents.cs +++ b/server/RdtClient.Service/Services/Torrents.cs @@ -23,7 +23,7 @@ public class Torrents( AllDebridTorrentClient allDebridTorrentClient, PremiumizeTorrentClient premiumizeTorrentClient, RealDebridTorrentClient realDebridTorrentClient, - DebridLinkClient DebridLinkClient, + DebridLinkClient debridLinkClient, TorBoxTorrentClient torBoxTorrentClient) { private static readonly SemaphoreSlim RealDebridUpdateLock = new(1, 1); @@ -42,7 +42,7 @@ public class Torrents( Provider.Premiumize => premiumizeTorrentClient, Provider.RealDebrid => realDebridTorrentClient, Provider.AllDebrid => allDebridTorrentClient, - Provider.DebridLink => DebridLinkClient, + Provider.DebridLink => debridLinkClient, Provider.TorBox => torBoxTorrentClient, _ => throw new("Invalid Provider") }; From 56a61ad012bb36106807131c9c5000ce8ead010e Mon Sep 17 00:00:00 2001 From: Cucumberrbob <128094686+Cucumberrbob@users.noreply.github.com> Date: Sun, 2 Feb 2025 20:58:51 +0000 Subject: [PATCH 08/14] :sparkles: Use exact path for symlink source when using SymlinkDownloader --- .../Services/DownloadClient.cs | 5 +++++ .../Services/Downloaders/SymlinkDownloader.cs | 2 +- .../TorrentClients/DebridLinkTorrentClient.cs | 18 ++++++++++++++++++ 3 files changed, 24 insertions(+), 1 deletion(-) diff --git a/server/RdtClient.Service/Services/DownloadClient.cs b/server/RdtClient.Service/Services/DownloadClient.cs index 23d0f1e..df7b05b 100644 --- a/server/RdtClient.Service/Services/DownloadClient.cs +++ b/server/RdtClient.Service/Services/DownloadClient.cs @@ -45,6 +45,11 @@ public class DownloadClient(Download download, Torrent torrent, String destinati downloadPath = AllDebridTorrentClient.GetSymlinkPath(torrent, download); } + if (torrent.ClientKind == Torrent.TorrentClientKind.DebridLink && Type == Data.Enums.DownloadClient.Symlink) + { + downloadPath = DebridLinkClient.GetSymlinkPath(torrent, download); + } + if (filePath == null || downloadPath == null) { throw new("Invalid download path"); diff --git a/server/RdtClient.Service/Services/Downloaders/SymlinkDownloader.cs b/server/RdtClient.Service/Services/Downloaders/SymlinkDownloader.cs index 74db7c0..cf91f04 100644 --- a/server/RdtClient.Service/Services/Downloaders/SymlinkDownloader.cs +++ b/server/RdtClient.Service/Services/Downloaders/SymlinkDownloader.cs @@ -62,7 +62,7 @@ public class SymlinkDownloader(String uri, String destinationPath, String path, var shouldSearch = true; // When resolving symlinks for AllDebrid, we know the exact file path, so we can skip the search. - if (clientKind == Torrent.TorrentClientKind.AllDebrid) + if (clientKind is Torrent.TorrentClientKind.AllDebrid or Torrent.TorrentClientKind.DebridLink) { var potentialFilePath = Path.Combine(rcloneMountPath, path); diff --git a/server/RdtClient.Service/Services/TorrentClients/DebridLinkTorrentClient.cs b/server/RdtClient.Service/Services/TorrentClients/DebridLinkTorrentClient.cs index 435b656..262f712 100644 --- a/server/RdtClient.Service/Services/TorrentClients/DebridLinkTorrentClient.cs +++ b/server/RdtClient.Service/Services/TorrentClients/DebridLinkTorrentClient.cs @@ -6,6 +6,8 @@ using RdtClient.Data.Models.TorrentClient; using RdtClient.Service.Helpers; using DebridLinkFrNET.Models; using System.Web; +using RdtClient.Data.Models.Data; +using Torrent = RdtClient.Data.Models.Data.Torrent; namespace RdtClient.Service.Services.TorrentClients; @@ -316,4 +318,20 @@ public class DebridLinkClient : ITorrentClient return Task.FromResult(HttpUtility.UrlDecode(uri.Segments.Last())); } + + public static String? GetSymlinkPath(Torrent torrent, Download download) + { + if (torrent.RdName == null || download.FileName == null) + { + return null; + } + + // Single file torrents always have that file at `/mnt-root/Seedbox/filename.ext` + if (torrent.Files?.Count == 1) + { + return download.FileName; + } + + return Path.Combine(torrent.RdName, download.FileName); + } } \ No newline at end of file From 48766e3d442a39e254ac5ddd9750b493e3aa1870 Mon Sep 17 00:00:00 2001 From: Cucumberrbob <128094686+Cucumberrbob@users.noreply.github.com> Date: Sun, 2 Feb 2025 22:48:47 +0000 Subject: [PATCH 09/14] :bug: Fix build errors by not `using Torrent =` in `DebridLinkTorrentClient` use `Data.Models.Data.Torrent`instead of `Torrent` and `Download = RdtClient.Data.Models.Torrent` --- .../Services/TorrentClients/DebridLinkTorrentClient.cs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/server/RdtClient.Service/Services/TorrentClients/DebridLinkTorrentClient.cs b/server/RdtClient.Service/Services/TorrentClients/DebridLinkTorrentClient.cs index 262f712..92225d5 100644 --- a/server/RdtClient.Service/Services/TorrentClients/DebridLinkTorrentClient.cs +++ b/server/RdtClient.Service/Services/TorrentClients/DebridLinkTorrentClient.cs @@ -6,8 +6,7 @@ using RdtClient.Data.Models.TorrentClient; using RdtClient.Service.Helpers; using DebridLinkFrNET.Models; using System.Web; -using RdtClient.Data.Models.Data; -using Torrent = RdtClient.Data.Models.Data.Torrent; +using Download = RdtClient.Data.Models.Data.Download; namespace RdtClient.Service.Services.TorrentClients; @@ -319,7 +318,7 @@ public class DebridLinkClient : ITorrentClient return Task.FromResult(HttpUtility.UrlDecode(uri.Segments.Last())); } - public static String? GetSymlinkPath(Torrent torrent, Download download) + public static String? GetSymlinkPath(Data.Models.Data.Torrent torrent, Download download) { if (torrent.RdName == null || download.FileName == null) { From f1bdc7d8b416aca96d84197b9205f9615f198e30 Mon Sep 17 00:00:00 2001 From: Wald764 Date: Mon, 3 Feb 2025 00:49:07 +0100 Subject: [PATCH 10/14] :recycle: fix a reference to RD instead of DL in DebridLinkTorrentClient --- .../Services/TorrentClients/DebridLinkTorrentClient.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/RdtClient.Service/Services/TorrentClients/DebridLinkTorrentClient.cs b/server/RdtClient.Service/Services/TorrentClients/DebridLinkTorrentClient.cs index 92225d5..edbc911 100644 --- a/server/RdtClient.Service/Services/TorrentClients/DebridLinkTorrentClient.cs +++ b/server/RdtClient.Service/Services/TorrentClients/DebridLinkTorrentClient.cs @@ -29,7 +29,7 @@ public class DebridLinkClient : ITorrentClient if (String.IsNullOrWhiteSpace(apiKey)) { - throw new Exception("Real-Debrid API Key not set in the settings"); + throw new Exception("DebridLink API Key not set in the settings"); } var httpClient = _httpClientFactory.CreateClient(); From 82b44cccde6c8b80760f8db909ad906fa26f0661 Mon Sep 17 00:00:00 2001 From: Sam Heinz <54530346+asylumexp@users.noreply.github.com> Date: Sat, 8 Feb 2025 16:40:57 +1000 Subject: [PATCH 11/14] [TB] Update TorBox.NET to v1.4.0 --- server/RdtClient.Service/RdtClient.Service.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/RdtClient.Service/RdtClient.Service.csproj b/server/RdtClient.Service/RdtClient.Service.csproj index 90ad249..d71195c 100644 --- a/server/RdtClient.Service/RdtClient.Service.csproj +++ b/server/RdtClient.Service/RdtClient.Service.csproj @@ -23,7 +23,7 @@ - + From 780d0e51188e56e2f55f99bcac001ed91ffba175 Mon Sep 17 00:00:00 2001 From: Roger Far Date: Wed, 12 Feb 2025 19:48:48 -0700 Subject: [PATCH 12/14] Add fixes for AllDebrid and their new API. --- .../Models/TorrentClient/TorrentClientFile.cs | 1 + server/RdtClient.Data/RdtClient.Data.csproj | 10 +- .../RdtClient.Service.csproj | 10 +- .../TorrentClients/AllDebridTorrentClient.cs | 199 ++++++++---------- server/RdtClient.Web/RdtClient.Web.csproj | 12 +- 5 files changed, 107 insertions(+), 125 deletions(-) diff --git a/server/RdtClient.Data/Models/TorrentClient/TorrentClientFile.cs b/server/RdtClient.Data/Models/TorrentClient/TorrentClientFile.cs index 62bf096..7f5ccbd 100644 --- a/server/RdtClient.Data/Models/TorrentClient/TorrentClientFile.cs +++ b/server/RdtClient.Data/Models/TorrentClient/TorrentClientFile.cs @@ -6,4 +6,5 @@ public class TorrentClientFile public String Path { get; set; } = default!; public Int64 Bytes { get; set; } public Boolean Selected { get; set; } + public String? DownloadLink { get; set; } } \ No newline at end of file diff --git a/server/RdtClient.Data/RdtClient.Data.csproj b/server/RdtClient.Data/RdtClient.Data.csproj index f21d4fd..37af83e 100644 --- a/server/RdtClient.Data/RdtClient.Data.csproj +++ b/server/RdtClient.Data/RdtClient.Data.csproj @@ -8,11 +8,11 @@ - - - - - + + + + + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/server/RdtClient.Service/RdtClient.Service.csproj b/server/RdtClient.Service/RdtClient.Service.csproj index 90ad249..ac3645f 100644 --- a/server/RdtClient.Service/RdtClient.Service.csproj +++ b/server/RdtClient.Service/RdtClient.Service.csproj @@ -9,21 +9,21 @@ - + - - + + - + - + diff --git a/server/RdtClient.Service/Services/TorrentClients/AllDebridTorrentClient.cs b/server/RdtClient.Service/Services/TorrentClients/AllDebridTorrentClient.cs index 9ab8875..306da68 100644 --- a/server/RdtClient.Service/Services/TorrentClients/AllDebridTorrentClient.cs +++ b/server/RdtClient.Service/Services/TorrentClients/AllDebridTorrentClient.cs @@ -8,13 +8,16 @@ using RdtClient.Service.Helpers; using System.Web; using RdtClient.Data.Models.Data; using File = AllDebridNET.File; -using LogLevel = Microsoft.Extensions.Logging.LogLevel; using Torrent = RdtClient.Data.Models.Data.Torrent; namespace RdtClient.Service.Services.TorrentClients; public class AllDebridTorrentClient(ILogger logger, IHttpClientFactory httpClientFactory) : ITorrentClient { + private static readonly Int64 SessionId = DateTimeOffset.UtcNow.ToUnixTimeSeconds(); + private static List _cache = []; + private static Int64 _sessionCounter = 0; + private AllDebridNETClient GetClient() { try @@ -49,30 +52,24 @@ public class AllDebridTorrentClient(ILogger logger, IHtt private static TorrentClientTorrent Map(Magnet torrent) { + var files = GetFiles(torrent.Files); return new() { Id = torrent.Id.ToString(), - Filename = torrent.Filename, + Filename = torrent.Filename ?? "", OriginalFilename = torrent.Filename, - Hash = torrent.Hash, - Bytes = torrent.Size, - OriginalBytes = torrent.Size, + Hash = torrent.Hash ?? "", + Bytes = torrent.Size ?? 0, + OriginalBytes = torrent.Size ?? 0, Host = null, Split = 0, - Progress = (Int64)Math.Round(torrent.Downloaded * 100.0 / torrent.Size), + Progress = (Int64)Math.Round((torrent.Downloaded ?? 0) * 100.0 / (torrent.Size ?? 1)), Status = torrent.Status, - StatusCode = torrent.StatusCode, - Added = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc).AddSeconds(torrent.UploadDate), - Files = torrent.Links.Select((m, i) => new TorrentClientFile - { - Path = GetFiles(m.Files), - Bytes = m.Size, - Id = i, - Selected = true, - }) - .ToList(), - Links = torrent.Links.Select(m => m.LinkUrl.ToString()).ToList(), - Ended = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc).AddSeconds(torrent.CompletionDate), + StatusCode = torrent.StatusCode ?? 0, + Added = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc).AddSeconds(torrent.UploadDate ?? 0), + Files = files, + Links = [], + Ended = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc).AddSeconds(torrent.CompletionDate ?? 0), Speed = torrent.DownloadSpeed, Seeders = torrent.Seeders }; @@ -80,9 +77,31 @@ public class AllDebridTorrentClient(ILogger logger, IHtt public async Task> GetTorrents() { - var results = await GetClient().Magnet.StatusAllAsync(); + var results = await GetClient().Magnet.StatusLiveAsync(SessionId, _sessionCounter); - return results.Select(Map).ToList(); + _sessionCounter = results.Counter; + + if (results.Fullsync == true) + { + _cache = (results.Magnets ?? []).Select(Map).ToList(); + } + else + { + // Replace the existing items in the cache with the new ones based on the ID + foreach (var result in results.Magnets ?? []) + { + var existing = _cache.FirstOrDefault(m => m.Id == result.Id.ToString()); + if (existing != null) + { + _cache.Remove(existing); + } + _cache.Add(Map(result)); + } + } + + _cache = _cache.Where(m => m.Status != null).ToList(); + + return _cache; } public async Task GetUser() @@ -226,14 +245,9 @@ public class AllDebridTorrentClient(ILogger logger, IHtt return null; } - var magnet = await GetClient().Magnet.StatusAsync(torrent.RdId); + var allFiles = await GetClient().Magnet.FilesAsync(Int64.Parse(torrent.RdId)); - if (magnet == null) - { - return null; - } - - var links = magnet.Links; + var files = GetFiles(allFiles); Log($"Getting download links", torrent); @@ -243,83 +257,74 @@ public class AllDebridTorrentClient(ILogger logger, IHtt Log($"Determining which files are over {minFileSize} bytes", torrent); - links = links.Where(m => m.Size > minFileSize) + files = files.Where(m => m.Bytes > minFileSize) .ToList(); - Log($"Found {links.Count} files that match the minimum file size criterea", torrent); + Log($"Found {files.Count} files that match the minimum file size criterea", torrent); } if (!String.IsNullOrWhiteSpace(torrent.IncludeRegex)) { Log($"Using regular expression {torrent.IncludeRegex} to include only files matching this regex", torrent); - var newLinks = new List(); + var newFiles = new List(); - foreach (var link in links) + foreach (var file in files) { - var path = GetFiles(link.Files); - - if (Regex.IsMatch(path, torrent.IncludeRegex)) + if (Regex.IsMatch(file.Path, torrent.IncludeRegex)) { - Log($"* Including {path}", torrent); - newLinks.Add(link); + Log($"* Including {file.Path}", torrent); + newFiles.Add(file); } else { - Log($"* Excluding {path}", torrent); + Log($"* Excluding {file.Path}", torrent); } } - links = newLinks; + files = newFiles; - Log($"Found {newLinks.Count} files that match the regex", torrent); + Log($"Found {newFiles.Count} files that match the regex", torrent); } else if (!String.IsNullOrWhiteSpace(torrent.ExcludeRegex)) { Log($"Using regular expression {torrent.IncludeRegex} to ignore files matching this regex", torrent); - var newLinks = new List(); + var newLinks = new List(); - foreach (var link in links) + foreach (var link in files) { - var path = GetFiles(link.Files); - - if (!Regex.IsMatch(path, torrent.ExcludeRegex)) + if (!Regex.IsMatch(link.Path, torrent.ExcludeRegex)) { - Log($"* Including {path}", torrent); + Log($"* Including {link.Path}", torrent); newLinks.Add(link); } else { - Log($"* Excluding {path}", torrent); + Log($"* Excluding {link.Path}", torrent); } } - links = newLinks; + files = newLinks; Log($"Found {newLinks.Count} files that match the regex", torrent); } - if (links.Count == 0) + if (files.Count == 0) { Log($"Filtered all files out! Downloading ALL files instead!", torrent); - links = magnet.Links; + files = GetFiles(allFiles); } - if (logger.IsEnabled(LogLevel.Debug)) + Log($"Selecting links:"); + + foreach (var file in files) { - Log($"Selecting links:"); - - foreach (var link in links) - { - Log($"{GetFiles(link.Files)} ({link.Size}b) {link.LinkUrl}"); - } + Log($"{file.Path} ({file.Bytes}b) {file.DownloadLink}"); } - - Log("", torrent); - - return links.Select(m => m.LinkUrl.ToString()).ToList(); + + return files.Where(m => m.DownloadLink != null).Select(m => m.DownloadLink!.ToString()).ToList(); } public Task GetFileName(String downloadUrl) @@ -340,65 +345,41 @@ public class AllDebridTorrentClient(ILogger logger, IHtt return Map(result); } - - private static String GetFiles(IList files) + + private static List GetFiles(List? files, String parentPath = "") { - var result = new List(); - - foreach (var file in files) + if (files == null) { - if (!String.IsNullOrWhiteSpace(file.N)) - { - result.Add(file.N); - } + return []; + } - if (file.E != null && file.E.Value.PurpleEArray != null && file.E.Value.PurpleEArray.Count > 0) + return files.SelectMany(file => + { + var currentPath = String.IsNullOrEmpty(parentPath) + ? file.FolderOrFileName + : Path.Combine(parentPath, file.FolderOrFileName); + + var result = new List(); + + // If it's a file (has size) + if (file.Size.HasValue) { - if (file.E.Value.PurpleEArray.Count != 1) + result.Add(new() { - throw new("Unexpected number of nested files"); - } - - result.AddRange(GetFiles(file.E.Value.PurpleEArray)); + Path = currentPath, + Bytes = file.Size.Value, + DownloadLink = file.DownloadLink + }); } - } - return String.Join("/", result); - } - - private static List GetFiles(IList files) - { - var result = new List(); - - foreach (var file in files) - { - if (!String.IsNullOrWhiteSpace(file.N)) + // Process sub-nodes if they exist + if (file.SubNodes != null) { - result.Add(file.N); + result.AddRange(GetFiles(file.SubNodes, currentPath)); } - if (file.E != null && file.E.Count > 0) - { - result.AddRange(GetFiles(file.E)); - } - } - - return result; - } - - private static List GetFiles(IList files) - { - var result = new List(); - - foreach (var file in files) - { - if (!String.IsNullOrWhiteSpace(file.N)) - { - result.Add(file.N); - } - } - - return result; + return result; + }).ToList(); } private void Log(String message, Torrent? torrent = null) diff --git a/server/RdtClient.Web/RdtClient.Web.csproj b/server/RdtClient.Web/RdtClient.Web.csproj index f64d20b..383e53f 100644 --- a/server/RdtClient.Web/RdtClient.Web.csproj +++ b/server/RdtClient.Web/RdtClient.Web.csproj @@ -29,15 +29,15 @@ - - - - + + + + all runtime; build; native; contentfiles; analyzers; buildtransitive - - + + From f58b7d3e7237fda939202929ef4f6a2cf1c5ea8f Mon Sep 17 00:00:00 2001 From: Roger Far Date: Wed, 12 Feb 2025 20:24:22 -0700 Subject: [PATCH 13/14] Refactored TorrentClientKind to Provider. Upgrade Downloader.NET --- server/RdtClient.Data/Models/Data/Torrent.cs | 10 +--------- server/RdtClient.Service/RdtClient.Service.csproj | 2 +- server/RdtClient.Service/Services/DownloadClient.cs | 5 +++-- .../Services/Downloaders/SymlinkDownloader.cs | 6 +++--- server/RdtClient.Service/Services/QBittorrent.cs | 2 +- .../Services/TorrentClients/AllDebridTorrentClient.cs | 2 +- .../Services/TorrentClients/PremiumizeTorrentClient.cs | 2 +- .../Services/TorrentClients/RealDebridTorrentClient.cs | 2 +- .../Services/TorrentClients/TorBoxTorrentClient.cs | 2 +- 9 files changed, 13 insertions(+), 20 deletions(-) diff --git a/server/RdtClient.Data/Models/Data/Torrent.cs b/server/RdtClient.Data/Models/Data/Torrent.cs index f928e3e..57efdbf 100644 --- a/server/RdtClient.Data/Models/Data/Torrent.cs +++ b/server/RdtClient.Data/Models/Data/Torrent.cs @@ -44,7 +44,7 @@ public class Torrent [InverseProperty("Torrent")] public IList Downloads { get; set; } = []; - public TorrentClientKind? ClientKind { get; set; } + public Provider? ClientKind { get; set; } public String? RdId { get; set; } public String? RdName { get; set; } public Int64? RdSize { get; set; } @@ -93,12 +93,4 @@ public class Torrent return DownloadManualFiles.Split(","); } } - - public enum TorrentClientKind - { - AllDebrid, - Premiumize, - RealDebrid, - TorBox - } } \ No newline at end of file diff --git a/server/RdtClient.Service/RdtClient.Service.csproj b/server/RdtClient.Service/RdtClient.Service.csproj index ac3645f..8f2c179 100644 --- a/server/RdtClient.Service/RdtClient.Service.csproj +++ b/server/RdtClient.Service/RdtClient.Service.csproj @@ -12,7 +12,7 @@ - + diff --git a/server/RdtClient.Service/Services/DownloadClient.cs b/server/RdtClient.Service/Services/DownloadClient.cs index 23d0f1e..07cdbec 100644 --- a/server/RdtClient.Service/Services/DownloadClient.cs +++ b/server/RdtClient.Service/Services/DownloadClient.cs @@ -1,4 +1,5 @@ -using RdtClient.Data.Models.Data; +using RdtClient.Data.Enums; +using RdtClient.Data.Models.Data; using RdtClient.Service.Helpers; using RdtClient.Service.Services.Downloaders; using RdtClient.Service.Services.TorrentClients; @@ -40,7 +41,7 @@ public class DownloadClient(Download download, Torrent torrent, String destinati var filePath = DownloadHelper.GetDownloadPath(destinationPath, torrent, download); var downloadPath = DownloadHelper.GetDownloadPath(torrent, download); - if (torrent.ClientKind == Torrent.TorrentClientKind.AllDebrid && Type == Data.Enums.DownloadClient.Symlink) + if (torrent.ClientKind == Provider.AllDebrid && Type == Data.Enums.DownloadClient.Symlink) { downloadPath = AllDebridTorrentClient.GetSymlinkPath(torrent, download); } diff --git a/server/RdtClient.Service/Services/Downloaders/SymlinkDownloader.cs b/server/RdtClient.Service/Services/Downloaders/SymlinkDownloader.cs index 74db7c0..4ea8f79 100644 --- a/server/RdtClient.Service/Services/Downloaders/SymlinkDownloader.cs +++ b/server/RdtClient.Service/Services/Downloaders/SymlinkDownloader.cs @@ -1,10 +1,10 @@ -using RdtClient.Data.Models.Data; +using RdtClient.Data.Enums; using RdtClient.Service.Helpers; using Serilog; namespace RdtClient.Service.Services.Downloaders; -public class SymlinkDownloader(String uri, String destinationPath, String path, Torrent.TorrentClientKind? clientKind) : IDownloader +public class SymlinkDownloader(String uri, String destinationPath, String path, Provider? clientKind) : IDownloader { public event EventHandler? DownloadComplete; public event EventHandler? DownloadProgress; @@ -62,7 +62,7 @@ public class SymlinkDownloader(String uri, String destinationPath, String path, var shouldSearch = true; // When resolving symlinks for AllDebrid, we know the exact file path, so we can skip the search. - if (clientKind == Torrent.TorrentClientKind.AllDebrid) + if (clientKind == Provider.AllDebrid) { var potentialFilePath = Path.Combine(rcloneMountPath, path); diff --git a/server/RdtClient.Service/Services/QBittorrent.cs b/server/RdtClient.Service/Services/QBittorrent.cs index d066fab..3c12685 100644 --- a/server/RdtClient.Service/Services/QBittorrent.cs +++ b/server/RdtClient.Service/Services/QBittorrent.cs @@ -209,7 +209,7 @@ public class QBittorrent(ILogger logger, Settings settings, Authent if (!String.IsNullOrWhiteSpace(torrent.RdName)) { // Alldebrid stores single file torrents at the root folder. - if (torrent.ClientKind == Torrent.TorrentClientKind.AllDebrid && torrent.Files.Count == 1) + if (torrent.ClientKind == Provider.AllDebrid && torrent.Files.Count == 1) { torrentPath = Path.Combine(downloadPath, torrent.Files[0].Path); } else diff --git a/server/RdtClient.Service/Services/TorrentClients/AllDebridTorrentClient.cs b/server/RdtClient.Service/Services/TorrentClients/AllDebridTorrentClient.cs index 306da68..ed8249a 100644 --- a/server/RdtClient.Service/Services/TorrentClients/AllDebridTorrentClient.cs +++ b/server/RdtClient.Service/Services/TorrentClients/AllDebridTorrentClient.cs @@ -196,7 +196,7 @@ public class AllDebridTorrentClient(ILogger logger, IHtt torrent.RdFiles = JsonConvert.SerializeObject(torrentClientTorrent.Files); } - torrent.ClientKind = Torrent.TorrentClientKind.AllDebrid; + torrent.ClientKind = Provider.AllDebrid; torrent.RdHost = torrentClientTorrent.Host; torrent.RdSplit = torrentClientTorrent.Split; torrent.RdProgress = torrentClientTorrent.Progress; diff --git a/server/RdtClient.Service/Services/TorrentClients/PremiumizeTorrentClient.cs b/server/RdtClient.Service/Services/TorrentClients/PremiumizeTorrentClient.cs index 438fe29..59da932 100644 --- a/server/RdtClient.Service/Services/TorrentClients/PremiumizeTorrentClient.cs +++ b/server/RdtClient.Service/Services/TorrentClients/PremiumizeTorrentClient.cs @@ -162,7 +162,7 @@ public class PremiumizeTorrentClient(ILogger logger, IH torrent.RdFiles = JsonConvert.SerializeObject(torrentClientTorrent.Files); } - torrent.ClientKind = Torrent.TorrentClientKind.Premiumize; + torrent.ClientKind = Provider.Premiumize; torrent.RdHost = torrentClientTorrent.Host; torrent.RdSplit = torrentClientTorrent.Split; torrent.RdProgress = torrentClientTorrent.Progress; diff --git a/server/RdtClient.Service/Services/TorrentClients/RealDebridTorrentClient.cs b/server/RdtClient.Service/Services/TorrentClients/RealDebridTorrentClient.cs index 29493fd..368e733 100644 --- a/server/RdtClient.Service/Services/TorrentClients/RealDebridTorrentClient.cs +++ b/server/RdtClient.Service/Services/TorrentClients/RealDebridTorrentClient.cs @@ -295,7 +295,7 @@ public class RealDebridTorrentClient(ILogger logger, IH torrent.RdFiles = JsonConvert.SerializeObject(torrentClientTorrent.Files); } - torrent.ClientKind = Data.Models.Data.Torrent.TorrentClientKind.RealDebrid; + torrent.ClientKind = Provider.RealDebrid; torrent.RdHost = torrentClientTorrent.Host; torrent.RdSplit = torrentClientTorrent.Split; torrent.RdProgress = torrentClientTorrent.Progress; diff --git a/server/RdtClient.Service/Services/TorrentClients/TorBoxTorrentClient.cs b/server/RdtClient.Service/Services/TorrentClients/TorBoxTorrentClient.cs index 45f562b..1a542f4 100644 --- a/server/RdtClient.Service/Services/TorrentClients/TorBoxTorrentClient.cs +++ b/server/RdtClient.Service/Services/TorrentClients/TorBoxTorrentClient.cs @@ -230,7 +230,7 @@ public class TorBoxTorrentClient(ILogger logger, IHttpClien torrent.RdFiles = JsonConvert.SerializeObject(rdTorrent.Files); } - torrent.ClientKind = Torrent.TorrentClientKind.TorBox; + torrent.ClientKind = Provider.TorBox; torrent.RdHost = rdTorrent.Host; torrent.RdSplit = rdTorrent.Split; torrent.RdProgress = rdTorrent.Progress; From 56c25770c3ebfdab27f21f665bffe17df4c8ccf2 Mon Sep 17 00:00:00 2001 From: Roger Far Date: Wed, 12 Feb 2025 20:27:29 -0700 Subject: [PATCH 14/14] Cleanup. --- .../Services/DownloadClient.cs | 2 +- .../TorrentClients/DebridLinkTorrentClient.cs | 73 ++++++++----------- 2 files changed, 31 insertions(+), 44 deletions(-) diff --git a/server/RdtClient.Service/Services/DownloadClient.cs b/server/RdtClient.Service/Services/DownloadClient.cs index 0ad6df4..8c9d7b2 100644 --- a/server/RdtClient.Service/Services/DownloadClient.cs +++ b/server/RdtClient.Service/Services/DownloadClient.cs @@ -46,7 +46,7 @@ public class DownloadClient(Download download, Torrent torrent, String destinati downloadPath = AllDebridTorrentClient.GetSymlinkPath(torrent, download); } - if (torrent.ClientKind == Torrent.TorrentClientKind.DebridLink && Type == Data.Enums.DownloadClient.Symlink) + if (torrent.ClientKind == Provider.DebridLink && Type == Data.Enums.DownloadClient.Symlink) { downloadPath = DebridLinkClient.GetSymlinkPath(torrent, download); } diff --git a/server/RdtClient.Service/Services/TorrentClients/DebridLinkTorrentClient.cs b/server/RdtClient.Service/Services/TorrentClients/DebridLinkTorrentClient.cs index edbc911..385fec6 100644 --- a/server/RdtClient.Service/Services/TorrentClients/DebridLinkTorrentClient.cs +++ b/server/RdtClient.Service/Services/TorrentClients/DebridLinkTorrentClient.cs @@ -10,17 +10,8 @@ using Download = RdtClient.Data.Models.Data.Download; namespace RdtClient.Service.Services.TorrentClients; -public class DebridLinkClient : ITorrentClient +public class DebridLinkClient(ILogger logger, IHttpClientFactory httpClientFactory) : ITorrentClient { - private readonly ILogger _logger; - private readonly IHttpClientFactory _httpClientFactory; - - public DebridLinkClient(ILogger logger, IHttpClientFactory httpClientFactory) - { - _logger = logger; - _httpClientFactory = httpClientFactory; - } - private DebridLinkFrNETClient GetClient() { try @@ -29,34 +20,34 @@ public class DebridLinkClient : ITorrentClient if (String.IsNullOrWhiteSpace(apiKey)) { - throw new Exception("DebridLink API Key not set in the settings"); + throw new("DebridLink API Key not set in the settings"); } - var httpClient = _httpClientFactory.CreateClient(); + var httpClient = httpClientFactory.CreateClient(); httpClient.Timeout = TimeSpan.FromSeconds(Settings.Get.Provider.Timeout); - var DebridLinkClient = new DebridLinkFrNETClient(apiKey, httpClient); + var debridLinkClient = new DebridLinkFrNETClient(apiKey, httpClient); - return DebridLinkClient; + return debridLinkClient; } catch (AggregateException ae) { foreach (var inner in ae.InnerExceptions) { - _logger.LogError(inner, $"The connection to DebridLink has failed: {inner.Message}"); + logger.LogError(inner, $"The connection to DebridLink has failed: {inner.Message}"); } throw; } catch (TaskCanceledException ex) when (ex.InnerException is TimeoutException) { - _logger.LogError(ex, $"The connection to DebridLink has timed out: {ex.Message}"); + logger.LogError(ex, $"The connection to DebridLink has timed out: {ex.Message}"); throw; } catch (TaskCanceledException ex) { - _logger.LogError(ex, $"The connection to DebridLink has timed out: {ex.Message}"); + logger.LogError(ex, $"The connection to DebridLink has timed out: {ex.Message}"); throw; } @@ -64,7 +55,7 @@ public class DebridLinkClient : ITorrentClient private TorrentClientTorrent Map(Torrent torrent) { - return new TorrentClientTorrent + return new() { Id = torrent.Id ?? "", Filename = torrent.Name ?? "", @@ -77,9 +68,9 @@ public class DebridLinkClient : ITorrentClient Progress = torrent.DownloadPercent, Status = torrent.Status.ToString(), Added = DateTimeOffset.FromUnixTimeSeconds(torrent.Created), - Files = (torrent.Files ?? new List()).Select((m, i) => new TorrentClientFile + Files = (torrent.Files ?? []).Select((m, i) => new TorrentClientFile { - Path = m.Name, + Path = m.Name ?? "", Bytes = m.Size, Id = i, Selected = true @@ -117,7 +108,7 @@ public class DebridLinkClient : ITorrentClient { var user = await GetClient().Account.Infos(); - return new TorrentClientUser + return new() { Username = user.Username, Expiration = user.PremiumLeft > 0 ? DateTimeOffset.Now.AddSeconds(user.PremiumLeft) : null @@ -153,9 +144,9 @@ public class DebridLinkClient : ITorrentClient await GetClient().Seedbox.DeleteAsync(torrentId); } - public async Task Unrestrict(String link) + public Task Unrestrict(String link) { - return link; + return Task.FromResult(link); } public async Task UpdateData(Data.Models.Data.Torrent torrent, TorrentClientTorrent? torrentClientTorrent) @@ -167,12 +158,7 @@ public class DebridLinkClient : ITorrentClient return torrent; } - var rdTorrent = await GetInfo(torrent.RdId); - - if (rdTorrent == null) - { - throw new Exception($"Resource not found"); - } + var rdTorrent = await GetInfo(torrent.RdId) ?? throw new($"Resource not found"); if (!String.IsNullOrWhiteSpace(rdTorrent.Filename)) { @@ -198,7 +184,7 @@ public class DebridLinkClient : ITorrentClient torrent.RdFiles = JsonConvert.SerializeObject(rdTorrent.Files); } - torrent.ClientKind = Data.Models.Data.Torrent.TorrentClientKind.DebridLink; + torrent.ClientKind = Provider.DebridLink; torrent.RdHost = rdTorrent.Host; torrent.RdSplit = rdTorrent.Split; torrent.RdProgress = rdTorrent.Progress; @@ -207,17 +193,18 @@ public class DebridLinkClient : ITorrentClient torrent.RdSpeed = rdTorrent.Speed; torrent.RdSeeders = rdTorrent.Seeders; torrent.RdStatusRaw = rdTorrent.Status; - /** - * - * 0 Torrent is stopped - * 1 Torrent is queued to verify local data - * 2 Torrent is verifying local data - * 3 Torrent is queued to download - * 4 Torrent is downloading - * 5 Torrent is queued to seed - * 6 Torrent is seeding - * 100 Torrent is stored + + /* + 0 Torrent is stopped + 1 Torrent is queued to verify local data + 2 Torrent is verifying local data + 3 Torrent is queued to download + 4 Torrent is downloading + 5 Torrent is queued to seed + 6 Torrent is seeding + 100 Torrent is stored */ + torrent.RdStatus = rdTorrent.Status switch { "100" => TorrentStatus.Finished, @@ -303,10 +290,10 @@ public class DebridLinkClient : ITorrentClient message = $"{message} {torrent.ToLog()}"; } - _logger.LogDebug(message); + logger.LogDebug(message); } - public Task GetFileName(string downloadUrl) + public Task GetFileName(String downloadUrl) { if (String.IsNullOrWhiteSpace(downloadUrl)) { @@ -326,7 +313,7 @@ public class DebridLinkClient : ITorrentClient } // Single file torrents always have that file at `/mnt-root/Seedbox/filename.ext` - if (torrent.Files?.Count == 1) + if (torrent.Files.Count == 1) { return download.FileName; }