From c34c62f87924abc5912d1b888bd1cef227961f37 Mon Sep 17 00:00:00 2001 From: Sam Heinz <54530346+asylumexp@users.noreply.github.com> Date: Tue, 10 Dec 2024 15:06:51 +1000 Subject: [PATCH 01/25] [TB] Move handling filenames from DownloadHelper to TorrentClients --- .../Helpers/DownloadHelper.cs | 8 ++---- .../TorrentClients/AllDebridTorrentClient.cs | 12 +++++++++ .../Services/TorrentClients/ITorrentClient.cs | 1 + .../TorrentClients/PremiumizeTorrentClient.cs | 13 +++++++++ .../TorrentClients/RealDebridTorrentClient.cs | 13 +++++++++ .../TorrentClients/TorBoxTorrentClient.cs | 27 +++++++++++++++++++ server/RdtClient.Service/Services/Torrents.cs | 4 ++- 7 files changed, 71 insertions(+), 7 deletions(-) diff --git a/server/RdtClient.Service/Helpers/DownloadHelper.cs b/server/RdtClient.Service/Helpers/DownloadHelper.cs index bbb1775..02d26f0 100644 --- a/server/RdtClient.Service/Helpers/DownloadHelper.cs +++ b/server/RdtClient.Service/Helpers/DownloadHelper.cs @@ -5,11 +5,11 @@ namespace RdtClient.Service.Helpers; public static class DownloadHelper { - public static String? GetDownloadPath(String downloadPath, Torrent torrent, Download download) + public static String? GetDownloadPath(String downloadPath, Torrent torrent, Download download, String? fileName) { var fileUrl = download.Link; - if (String.IsNullOrWhiteSpace(fileUrl) || torrent.RdName == null) + if (String.IsNullOrWhiteSpace(fileUrl) || torrent.RdName == null || fileName == null) { return null; } @@ -19,10 +19,6 @@ public static class DownloadHelper var uri = new Uri(fileUrl); var torrentPath = Path.Combine(downloadPath, directory); - var fileName = uri.Segments.Last(); - - fileName = HttpUtility.UrlDecode(fileName); - fileName = FileHelper.RemoveInvalidFileNameChars(fileName); var matchingTorrentFiles = torrent.Files.Where(m => m.Path.EndsWith(fileName)).Where(m => !String.IsNullOrWhiteSpace(m.Path)).ToList(); diff --git a/server/RdtClient.Service/Services/TorrentClients/AllDebridTorrentClient.cs b/server/RdtClient.Service/Services/TorrentClients/AllDebridTorrentClient.cs index bc0102c..540b3d3 100644 --- a/server/RdtClient.Service/Services/TorrentClients/AllDebridTorrentClient.cs +++ b/server/RdtClient.Service/Services/TorrentClients/AllDebridTorrentClient.cs @@ -4,6 +4,7 @@ using Newtonsoft.Json; using RdtClient.Data.Enums; using RdtClient.Data.Models.TorrentClient; using RdtClient.Service.Helpers; +using System.Web; using File = AllDebridNET.File; using Torrent = RdtClient.Data.Models.Data.Torrent; @@ -262,6 +263,17 @@ public class AllDebridTorrentClient(ILogger logger, IHtt return links.Select(m => m.LinkUrl.ToString()).ToList(); } + public Task GetFileName(Data.Models.Data.Download download) + { + if (String.IsNullOrWhiteSpace(download.Link)) + { + return Task.FromResult(null); + } + + var uri = new Uri(download.Link); + + return Task.FromResult(HttpUtility.UrlDecode(uri.Segments.Last())); + } private async Task GetInfo(String torrentId) { diff --git a/server/RdtClient.Service/Services/TorrentClients/ITorrentClient.cs b/server/RdtClient.Service/Services/TorrentClients/ITorrentClient.cs index da4aa39..95fb597 100644 --- a/server/RdtClient.Service/Services/TorrentClients/ITorrentClient.cs +++ b/server/RdtClient.Service/Services/TorrentClients/ITorrentClient.cs @@ -15,4 +15,5 @@ public interface ITorrentClient Task Unrestrict(String link); Task UpdateData(Torrent torrent, TorrentClientTorrent? torrentClientTorrent); Task?> GetDownloadLinks(Torrent torrent); + Task GetFileName(Download download); } \ No newline at end of file diff --git a/server/RdtClient.Service/Services/TorrentClients/PremiumizeTorrentClient.cs b/server/RdtClient.Service/Services/TorrentClients/PremiumizeTorrentClient.cs index cb170c2..ab33428 100644 --- a/server/RdtClient.Service/Services/TorrentClients/PremiumizeTorrentClient.cs +++ b/server/RdtClient.Service/Services/TorrentClients/PremiumizeTorrentClient.cs @@ -4,6 +4,7 @@ using PremiumizeNET; using RdtClient.Data.Enums; using RdtClient.Data.Models.TorrentClient; using RdtClient.Service.Helpers; +using System.Web; using Torrent = RdtClient.Data.Models.Data.Torrent; namespace RdtClient.Service.Services.TorrentClients; @@ -241,6 +242,18 @@ public class PremiumizeTorrentClient(ILogger logger, IH return downloadLinks; } + public Task GetFileName(Data.Models.Data.Download download) + { + if (String.IsNullOrWhiteSpace(download.Link)) + { + return Task.FromResult(null); + } + + var uri = new Uri(download.Link); + + return Task.FromResult(HttpUtility.UrlDecode(uri.Segments.Last())); + } + private async Task GetInfo(String id) { var results = await GetClient().Transfers.ListAsync(); diff --git a/server/RdtClient.Service/Services/TorrentClients/RealDebridTorrentClient.cs b/server/RdtClient.Service/Services/TorrentClients/RealDebridTorrentClient.cs index 9cc8ad0..ecf4337 100644 --- a/server/RdtClient.Service/Services/TorrentClients/RealDebridTorrentClient.cs +++ b/server/RdtClient.Service/Services/TorrentClients/RealDebridTorrentClient.cs @@ -1,4 +1,5 @@ using System.Text.RegularExpressions; +using System.Web; using Microsoft.Extensions.Logging; using Newtonsoft.Json; using RDNET; @@ -395,6 +396,18 @@ public class RealDebridTorrentClient(ILogger logger, IH return null; } + public Task GetFileName(Data.Models.Data.Download download) + { + if (String.IsNullOrWhiteSpace(download.Link)) + { + return Task.FromResult(null); + } + + var uri = new Uri(download.Link); + + return Task.FromResult(HttpUtility.UrlDecode(uri.Segments.Last())); + } + private DateTimeOffset? ChangeTimeZone(DateTimeOffset? dateTimeOffset) { if (_offset == null) diff --git a/server/RdtClient.Service/Services/TorrentClients/TorBoxTorrentClient.cs b/server/RdtClient.Service/Services/TorrentClients/TorBoxTorrentClient.cs index 088c928..485d8ce 100644 --- a/server/RdtClient.Service/Services/TorrentClients/TorBoxTorrentClient.cs +++ b/server/RdtClient.Service/Services/TorrentClients/TorBoxTorrentClient.cs @@ -3,6 +3,7 @@ using Newtonsoft.Json; using TorBoxNET; using RdtClient.Data.Enums; using RdtClient.Data.Models.TorrentClient; +using System.Web; namespace RdtClient.Service.Services.TorrentClients; @@ -300,6 +301,32 @@ public class TorBoxTorrentClient(ILogger logger, IHttpClien return files; } + public async Task GetFileName(Data.Models.Data.Download download) + { + if (String.IsNullOrWhiteSpace(download.Link)) + { + return null; + } + + var uri = new Uri(download.Link); + + using (HttpClient client = new HttpClient()) + { + HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Head, uri); + HttpResponseMessage 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('"'); + } + } + } + + return HttpUtility.UrlDecode(uri.Segments.Last()); + } + private DateTimeOffset? ChangeTimeZone(DateTimeOffset? dateTimeOffset) { if (_offset == null) diff --git a/server/RdtClient.Service/Services/Torrents.cs b/server/RdtClient.Service/Services/Torrents.cs index 25817cf..0d3d7ae 100644 --- a/server/RdtClient.Service/Services/Torrents.cs +++ b/server/RdtClient.Service/Services/Torrents.cs @@ -546,8 +546,10 @@ public class Torrents( } var downloadPath = DownloadPath(download.Torrent!); + + var fileName = await TorrentClient.GetFileName(download); - var filePath = DownloadHelper.GetDownloadPath(downloadPath, download.Torrent!, download); + var filePath = DownloadHelper.GetDownloadPath(downloadPath, download.Torrent!, download, fileName); if (filePath != null) { From dffce96a4514a92887c577fc661fca30af2ab82e Mon Sep 17 00:00:00 2001 From: Sam Heinz <54530346+asylumexp@users.noreply.github.com> Date: Tue, 10 Dec 2024 15:25:30 +1000 Subject: [PATCH 02/25] [TB] Add default for fileName in DownloadHelper --- server/RdtClient.Service/Helpers/DownloadHelper.cs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/server/RdtClient.Service/Helpers/DownloadHelper.cs b/server/RdtClient.Service/Helpers/DownloadHelper.cs index 02d26f0..a4cec3a 100644 --- a/server/RdtClient.Service/Helpers/DownloadHelper.cs +++ b/server/RdtClient.Service/Helpers/DownloadHelper.cs @@ -5,7 +5,7 @@ namespace RdtClient.Service.Helpers; public static class DownloadHelper { - public static String? GetDownloadPath(String downloadPath, Torrent torrent, Download download, String? fileName) + public static String? GetDownloadPath(String downloadPath, Torrent torrent, Download download, String? fileName = null) { var fileUrl = download.Link; @@ -19,6 +19,13 @@ public static class DownloadHelper var uri = new Uri(fileUrl); var torrentPath = Path.Combine(downloadPath, directory); + if (String.IsNullOrWhiteSpace(fileName)) + { + fileName = uri.Segments.Last(); + + fileName = HttpUtility.UrlDecode(fileName); + } + fileName = FileHelper.RemoveInvalidFileNameChars(fileName); var matchingTorrentFiles = torrent.Files.Where(m => m.Path.EndsWith(fileName)).Where(m => !String.IsNullOrWhiteSpace(m.Path)).ToList(); From 3364deecbb96a18d8a9675f1315a2e1f31f23df9 Mon Sep 17 00:00:00 2001 From: Sam Heinz <54530346+asylumexp@users.noreply.github.com> Date: Tue, 10 Dec 2024 15:25:45 +1000 Subject: [PATCH 03/25] [TB] Add download state for stalledDL --- .../Services/TorrentClients/TorBoxTorrentClient.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/server/RdtClient.Service/Services/TorrentClients/TorBoxTorrentClient.cs b/server/RdtClient.Service/Services/TorrentClients/TorBoxTorrentClient.cs index 485d8ce..07402ab 100644 --- a/server/RdtClient.Service/Services/TorrentClients/TorBoxTorrentClient.cs +++ b/server/RdtClient.Service/Services/TorrentClients/TorBoxTorrentClient.cs @@ -258,6 +258,7 @@ public class TorBoxTorrentClient(ILogger logger, IHttpClien "checking" => TorrentStatus.Processing, "checkingResumeData" => TorrentStatus.Processing, "paused" => TorrentStatus.Downloading, + "stalledDL" => TorrentStatus.Downloading, "downloading" => TorrentStatus.Downloading, "completed" => TorrentStatus.Downloading, "uploading" => TorrentStatus.Downloading, From a1599ee7166ca66f54f0649854b4e62ef1bdc6a4 Mon Sep 17 00:00:00 2001 From: Sam Heinz <54530346+asylumexp@users.noreply.github.com> Date: Tue, 10 Dec 2024 23:37:32 +1000 Subject: [PATCH 04/25] [TB] Add FileName value to Download model --- ...0071621_Downloads_Add_FileName.Designer.cs | 476 ++++++++++++++++++ .../20241210071621_Downloads_Add_FileName.cs | 28 ++ .../Migrations/DataContextModelSnapshot.cs | 5 +- server/RdtClient.Data/Models/Data/Download.cs | 2 + .../RdtClient.Service/Services/Downloads.cs | 5 + 5 files changed, 515 insertions(+), 1 deletion(-) create mode 100644 server/RdtClient.Data/Migrations/20241210071621_Downloads_Add_FileName.Designer.cs create mode 100644 server/RdtClient.Data/Migrations/20241210071621_Downloads_Add_FileName.cs diff --git a/server/RdtClient.Data/Migrations/20241210071621_Downloads_Add_FileName.Designer.cs b/server/RdtClient.Data/Migrations/20241210071621_Downloads_Add_FileName.Designer.cs new file mode 100644 index 0000000..f7c9a3c --- /dev/null +++ b/server/RdtClient.Data/Migrations/20241210071621_Downloads_Add_FileName.Designer.cs @@ -0,0 +1,476 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using RdtClient.Data.Data; + +#nullable disable + +namespace RdtClient.Data.Migrations +{ + [DbContext(typeof(DataContext))] + [Migration("20241210071621_Downloads_Add_FileName")] + partial class Downloads_Add_FileName + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder.HasAnnotation("ProductVersion", "9.0.0"); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("TEXT"); + + b.Property("Name") + .HasMaxLength(256) + .HasColumnType("TEXT"); + + b.Property("NormalizedName") + .HasMaxLength(256) + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("NormalizedName") + .IsUnique() + .HasDatabaseName("RoleNameIndex"); + + b.ToTable("AspNetRoles", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ClaimType") + .HasColumnType("TEXT"); + + b.Property("ClaimValue") + .HasColumnType("TEXT"); + + b.Property("RoleId") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("RoleId"); + + b.ToTable("AspNetRoleClaims", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUser", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("AccessFailedCount") + .HasColumnType("INTEGER"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("TEXT"); + + b.Property("Email") + .HasMaxLength(256) + .HasColumnType("TEXT"); + + b.Property("EmailConfirmed") + .HasColumnType("INTEGER"); + + b.Property("LockoutEnabled") + .HasColumnType("INTEGER"); + + b.Property("LockoutEnd") + .HasColumnType("TEXT"); + + b.Property("NormalizedEmail") + .HasMaxLength(256) + .HasColumnType("TEXT"); + + b.Property("NormalizedUserName") + .HasMaxLength(256) + .HasColumnType("TEXT"); + + b.Property("PasswordHash") + .HasColumnType("TEXT"); + + b.Property("PhoneNumber") + .HasColumnType("TEXT"); + + b.Property("PhoneNumberConfirmed") + .HasColumnType("INTEGER"); + + b.Property("SecurityStamp") + .HasColumnType("TEXT"); + + b.Property("TwoFactorEnabled") + .HasColumnType("INTEGER"); + + b.Property("UserName") + .HasMaxLength(256) + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("NormalizedEmail") + .HasDatabaseName("EmailIndex"); + + b.HasIndex("NormalizedUserName") + .IsUnique() + .HasDatabaseName("UserNameIndex"); + + b.ToTable("AspNetUsers", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ClaimType") + .HasColumnType("TEXT"); + + b.Property("ClaimValue") + .HasColumnType("TEXT"); + + b.Property("UserId") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("AspNetUserClaims", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.Property("LoginProvider") + .HasColumnType("TEXT"); + + b.Property("ProviderKey") + .HasColumnType("TEXT"); + + b.Property("ProviderDisplayName") + .HasColumnType("TEXT"); + + b.Property("UserId") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("LoginProvider", "ProviderKey"); + + b.HasIndex("UserId"); + + b.ToTable("AspNetUserLogins", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => + { + b.Property("UserId") + .HasColumnType("TEXT"); + + b.Property("RoleId") + .HasColumnType("TEXT"); + + b.HasKey("UserId", "RoleId"); + + b.HasIndex("RoleId"); + + b.ToTable("AspNetUserRoles", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.Property("UserId") + .HasColumnType("TEXT"); + + b.Property("LoginProvider") + .HasColumnType("TEXT"); + + b.Property("Name") + .HasColumnType("TEXT"); + + b.Property("Value") + .HasColumnType("TEXT"); + + b.HasKey("UserId", "LoginProvider", "Name"); + + b.ToTable("AspNetUserTokens", (string)null); + }); + + modelBuilder.Entity("RdtClient.Data.Models.Data.Download", b => + { + b.Property("DownloadId") + .ValueGeneratedOnAdd() + .HasColumnType("TEXT"); + + b.Property("Added") + .HasColumnType("TEXT"); + + b.Property("Completed") + .HasColumnType("TEXT"); + + b.Property("DownloadFinished") + .HasColumnType("TEXT"); + + b.Property("DownloadQueued") + .HasColumnType("TEXT"); + + b.Property("DownloadStarted") + .HasColumnType("TEXT"); + + b.Property("Error") + .HasColumnType("TEXT"); + + b.Property("FileName") + .HasColumnType("TEXT"); + + b.Property("Link") + .HasColumnType("TEXT"); + + b.Property("Path") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("RemoteId") + .HasColumnType("TEXT"); + + b.Property("RetryCount") + .HasColumnType("INTEGER"); + + b.Property("TorrentId") + .HasColumnType("TEXT"); + + b.Property("UnpackingFinished") + .HasColumnType("TEXT"); + + b.Property("UnpackingQueued") + .HasColumnType("TEXT"); + + b.Property("UnpackingStarted") + .HasColumnType("TEXT"); + + b.HasKey("DownloadId"); + + b.HasIndex("TorrentId"); + + b.ToTable("Downloads"); + }); + + modelBuilder.Entity("RdtClient.Data.Models.Data.Setting", b => + { + b.Property("SettingId") + .HasColumnType("TEXT"); + + b.Property("Value") + .HasColumnType("TEXT"); + + b.HasKey("SettingId"); + + b.ToTable("Settings"); + }); + + modelBuilder.Entity("RdtClient.Data.Models.Data.Torrent", b => + { + b.Property("TorrentId") + .ValueGeneratedOnAdd() + .HasColumnType("TEXT"); + + b.Property("Added") + .HasColumnType("TEXT"); + + b.Property("Category") + .HasColumnType("TEXT"); + + b.Property("Completed") + .HasColumnType("TEXT"); + + b.Property("DeleteOnError") + .HasColumnType("INTEGER"); + + b.Property("DownloadAction") + .HasColumnType("INTEGER"); + + b.Property("DownloadClient") + .HasColumnType("INTEGER"); + + b.Property("DownloadManualFiles") + .HasColumnType("TEXT"); + + b.Property("DownloadMinSize") + .HasColumnType("INTEGER"); + + b.Property("DownloadRetryAttempts") + .HasColumnType("INTEGER"); + + b.Property("Error") + .HasColumnType("TEXT"); + + b.Property("ExcludeRegex") + .HasColumnType("TEXT"); + + b.Property("FileOrMagnet") + .HasColumnType("TEXT"); + + b.Property("FilesSelected") + .HasColumnType("TEXT"); + + b.Property("FinishedAction") + .HasColumnType("INTEGER"); + + b.Property("Hash") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("HostDownloadAction") + .HasColumnType("INTEGER"); + + b.Property("IncludeRegex") + .HasColumnType("TEXT"); + + b.Property("IsFile") + .HasColumnType("INTEGER"); + + b.Property("Lifetime") + .HasColumnType("INTEGER"); + + b.Property("Priority") + .HasColumnType("INTEGER"); + + b.Property("RdAdded") + .HasColumnType("TEXT"); + + b.Property("RdEnded") + .HasColumnType("TEXT"); + + b.Property("RdFiles") + .HasColumnType("TEXT"); + + b.Property("RdHost") + .HasColumnType("TEXT"); + + b.Property("RdId") + .HasColumnType("TEXT"); + + b.Property("RdName") + .HasColumnType("TEXT"); + + b.Property("RdProgress") + .HasColumnType("INTEGER"); + + b.Property("RdSeeders") + .HasColumnType("INTEGER"); + + b.Property("RdSize") + .HasColumnType("INTEGER"); + + b.Property("RdSpeed") + .HasColumnType("INTEGER"); + + b.Property("RdSplit") + .HasColumnType("INTEGER"); + + b.Property("RdStatus") + .HasColumnType("INTEGER"); + + b.Property("RdStatusRaw") + .HasColumnType("TEXT"); + + b.Property("Retry") + .HasColumnType("TEXT"); + + b.Property("RetryCount") + .HasColumnType("INTEGER"); + + b.Property("TorrentRetryAttempts") + .HasColumnType("INTEGER"); + + b.HasKey("TorrentId"); + + b.ToTable("Torrents"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + }); + + modelBuilder.Entity("RdtClient.Data.Models.Data.Download", b => + { + b.HasOne("RdtClient.Data.Models.Data.Torrent", "Torrent") + .WithMany("Downloads") + .HasForeignKey("TorrentId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.Navigation("Torrent"); + }); + + modelBuilder.Entity("RdtClient.Data.Models.Data.Torrent", b => + { + b.Navigation("Downloads"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/server/RdtClient.Data/Migrations/20241210071621_Downloads_Add_FileName.cs b/server/RdtClient.Data/Migrations/20241210071621_Downloads_Add_FileName.cs new file mode 100644 index 0000000..94a8666 --- /dev/null +++ b/server/RdtClient.Data/Migrations/20241210071621_Downloads_Add_FileName.cs @@ -0,0 +1,28 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace RdtClient.Data.Migrations +{ + /// + public partial class Downloads_Add_FileName : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.AddColumn( + name: "FileName", + table: "Downloads", + type: "TEXT", + nullable: true); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropColumn( + name: "FileName", + table: "Downloads"); + } + } +} diff --git a/server/RdtClient.Data/Migrations/DataContextModelSnapshot.cs b/server/RdtClient.Data/Migrations/DataContextModelSnapshot.cs index a3edd7b..ce27f40 100644 --- a/server/RdtClient.Data/Migrations/DataContextModelSnapshot.cs +++ b/server/RdtClient.Data/Migrations/DataContextModelSnapshot.cs @@ -15,7 +15,7 @@ namespace RdtClient.Data.Migrations protected override void BuildModel(ModelBuilder modelBuilder) { #pragma warning disable 612, 618 - modelBuilder.HasAnnotation("ProductVersion", "8.0.3"); + modelBuilder.HasAnnotation("ProductVersion", "9.0.0"); modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b => { @@ -233,6 +233,9 @@ namespace RdtClient.Data.Migrations b.Property("Error") .HasColumnType("TEXT"); + b.Property("FileName") + .HasColumnType("TEXT"); + b.Property("Link") .HasColumnType("TEXT"); diff --git a/server/RdtClient.Data/Models/Data/Download.cs b/server/RdtClient.Data/Models/Data/Download.cs index e8e54b1..d078356 100644 --- a/server/RdtClient.Data/Models/Data/Download.cs +++ b/server/RdtClient.Data/Models/Data/Download.cs @@ -31,6 +31,8 @@ public class Download public String? RemoteId { get; set; } + public String? FileName { get; set; } + [NotMapped] public Int64 BytesTotal { get; set; } diff --git a/server/RdtClient.Service/Services/Downloads.cs b/server/RdtClient.Service/Services/Downloads.cs index e66954f..020b36d 100644 --- a/server/RdtClient.Service/Services/Downloads.cs +++ b/server/RdtClient.Service/Services/Downloads.cs @@ -30,6 +30,11 @@ public class Downloads(DownloadData downloadData) await downloadData.UpdateUnrestrictedLink(downloadId, unrestrictedLink); } + public async Task UpdateFileName(Guid downloadId, String fileName) + { + await downloadData.UpdateFileName(downloadId, fileName); + } + public async Task UpdateDownloadStarted(Guid downloadId, DateTimeOffset? dateTime) { await downloadData.UpdateDownloadStarted(downloadId, dateTime); From 350185b702607d4f59430a8ab62face65c2ef9b1 Mon Sep 17 00:00:00 2001 From: Sam Heinz <54530346+asylumexp@users.noreply.github.com> Date: Tue, 10 Dec 2024 23:45:13 +1000 Subject: [PATCH 05/25] [TB] Refactor GetFileName in Torrent Clients --- .../TorrentClients/AllDebridTorrentClient.cs | 6 +++--- .../Services/TorrentClients/ITorrentClient.cs | 2 +- .../TorrentClients/PremiumizeTorrentClient.cs | 6 +++--- .../TorrentClients/RealDebridTorrentClient.cs | 6 +++--- .../Services/TorrentClients/TorBoxTorrentClient.cs | 12 ++++++------ 5 files changed, 16 insertions(+), 16 deletions(-) diff --git a/server/RdtClient.Service/Services/TorrentClients/AllDebridTorrentClient.cs b/server/RdtClient.Service/Services/TorrentClients/AllDebridTorrentClient.cs index 540b3d3..3c7c789 100644 --- a/server/RdtClient.Service/Services/TorrentClients/AllDebridTorrentClient.cs +++ b/server/RdtClient.Service/Services/TorrentClients/AllDebridTorrentClient.cs @@ -263,14 +263,14 @@ public class AllDebridTorrentClient(ILogger logger, IHtt return links.Select(m => m.LinkUrl.ToString()).ToList(); } - public Task GetFileName(Data.Models.Data.Download download) + public Task GetFileName(String downloadUrl) { - if (String.IsNullOrWhiteSpace(download.Link)) + if (String.IsNullOrWhiteSpace(downloadUrl)) { return Task.FromResult(null); } - var uri = new Uri(download.Link); + var uri = new Uri(downloadUrl); return Task.FromResult(HttpUtility.UrlDecode(uri.Segments.Last())); } diff --git a/server/RdtClient.Service/Services/TorrentClients/ITorrentClient.cs b/server/RdtClient.Service/Services/TorrentClients/ITorrentClient.cs index 95fb597..2813da8 100644 --- a/server/RdtClient.Service/Services/TorrentClients/ITorrentClient.cs +++ b/server/RdtClient.Service/Services/TorrentClients/ITorrentClient.cs @@ -15,5 +15,5 @@ public interface ITorrentClient Task Unrestrict(String link); Task UpdateData(Torrent torrent, TorrentClientTorrent? torrentClientTorrent); Task?> GetDownloadLinks(Torrent torrent); - Task GetFileName(Download download); + Task GetFileName(String downloadUrl); } \ No newline at end of file diff --git a/server/RdtClient.Service/Services/TorrentClients/PremiumizeTorrentClient.cs b/server/RdtClient.Service/Services/TorrentClients/PremiumizeTorrentClient.cs index ab33428..b91790b 100644 --- a/server/RdtClient.Service/Services/TorrentClients/PremiumizeTorrentClient.cs +++ b/server/RdtClient.Service/Services/TorrentClients/PremiumizeTorrentClient.cs @@ -242,14 +242,14 @@ public class PremiumizeTorrentClient(ILogger logger, IH return downloadLinks; } - public Task GetFileName(Data.Models.Data.Download download) + public Task GetFileName(String downloadUrl) { - if (String.IsNullOrWhiteSpace(download.Link)) + if (String.IsNullOrWhiteSpace(downloadUrl)) { return Task.FromResult(null); } - var uri = new Uri(download.Link); + var uri = new Uri(downloadUrl); return Task.FromResult(HttpUtility.UrlDecode(uri.Segments.Last())); } diff --git a/server/RdtClient.Service/Services/TorrentClients/RealDebridTorrentClient.cs b/server/RdtClient.Service/Services/TorrentClients/RealDebridTorrentClient.cs index ecf4337..459cb7a 100644 --- a/server/RdtClient.Service/Services/TorrentClients/RealDebridTorrentClient.cs +++ b/server/RdtClient.Service/Services/TorrentClients/RealDebridTorrentClient.cs @@ -396,14 +396,14 @@ public class RealDebridTorrentClient(ILogger logger, IH return null; } - public Task GetFileName(Data.Models.Data.Download download) + public Task GetFileName(String downloadUrl) { - if (String.IsNullOrWhiteSpace(download.Link)) + if (String.IsNullOrWhiteSpace(downloadUrl)) { return Task.FromResult(null); } - var uri = new Uri(download.Link); + var uri = new Uri(downloadUrl); return Task.FromResult(HttpUtility.UrlDecode(uri.Segments.Last())); } diff --git a/server/RdtClient.Service/Services/TorrentClients/TorBoxTorrentClient.cs b/server/RdtClient.Service/Services/TorrentClients/TorBoxTorrentClient.cs index 07402ab..6ebe877 100644 --- a/server/RdtClient.Service/Services/TorrentClients/TorBoxTorrentClient.cs +++ b/server/RdtClient.Service/Services/TorrentClients/TorBoxTorrentClient.cs @@ -161,7 +161,7 @@ public class TorBoxTorrentClient(ILogger logger, IHttpClien { var availability = await GetClient().Torrents.GetAvailabilityAsync(hash, listFiles: true); - if (availability.Data != null) + if (availability.Data != null || availability.Data?.Count < 0) { return (availability.Data[0]?.Files ?? []).Select(file => new TorrentClientAvailableFile { @@ -302,18 +302,18 @@ public class TorBoxTorrentClient(ILogger logger, IHttpClien return files; } - public async Task GetFileName(Data.Models.Data.Download download) + public async Task GetFileName(String downloadUrl) { - if (String.IsNullOrWhiteSpace(download.Link)) + if (String.IsNullOrWhiteSpace(downloadUrl)) { return null; } - var uri = new Uri(download.Link); + var uri = new Uri(downloadUrl); - using (HttpClient client = new HttpClient()) + using (HttpClient client = new()) { - HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Head, uri); + HttpRequestMessage request = new(HttpMethod.Head, uri); HttpResponseMessage response = await client.SendAsync(request); if (response.Content.Headers.ContentDisposition != null) { From 9d03c20aaafa4036fbc41b85feb8d7067ac6e087 Mon Sep 17 00:00:00 2001 From: Sam Heinz <54530346+asylumexp@users.noreply.github.com> Date: Tue, 10 Dec 2024 23:47:55 +1000 Subject: [PATCH 06/25] [TB] Change DownloadHelper to use download.FileName Also adds the UpdateFileName function to DownloadHelper & DownloadData to push FileName to DB --- server/RdtClient.Data/Data/DownloadData.cs | 17 +++++++++++++++++ .../RdtClient.Service/Helpers/DownloadHelper.cs | 15 ++++++++++----- .../RdtClient.Service/Services/TorrentRunner.cs | 3 +++ server/RdtClient.Service/Services/Torrents.cs | 17 ++++++++++++++--- 4 files changed, 44 insertions(+), 8 deletions(-) diff --git a/server/RdtClient.Data/Data/DownloadData.cs b/server/RdtClient.Data/Data/DownloadData.cs index 4488b9d..9d141f9 100644 --- a/server/RdtClient.Data/Data/DownloadData.cs +++ b/server/RdtClient.Data/Data/DownloadData.cs @@ -67,6 +67,23 @@ public class DownloadData(DataContext dataContext) await TorrentData.VoidCache(); } + public async Task UpdateFileName(Guid downloadId, String fileName) + { + var dbDownload = await dataContext.Downloads + .FirstOrDefaultAsync(m => m.DownloadId == downloadId); + + if (dbDownload == null) + { + return; + } + + dbDownload.FileName = fileName; + + await dataContext.SaveChangesAsync(); + + await TorrentData.VoidCache(); + } + public async Task UpdateDownloadStarted(Guid downloadId, DateTimeOffset? dateTime) { var dbDownload = await dataContext.Downloads diff --git a/server/RdtClient.Service/Helpers/DownloadHelper.cs b/server/RdtClient.Service/Helpers/DownloadHelper.cs index a4cec3a..06724ad 100644 --- a/server/RdtClient.Service/Helpers/DownloadHelper.cs +++ b/server/RdtClient.Service/Helpers/DownloadHelper.cs @@ -5,11 +5,11 @@ namespace RdtClient.Service.Helpers; public static class DownloadHelper { - public static String? GetDownloadPath(String downloadPath, Torrent torrent, Download download, String? fileName = null) + public static String? GetDownloadPath(String downloadPath, Torrent torrent, Download download) { var fileUrl = download.Link; - if (String.IsNullOrWhiteSpace(fileUrl) || torrent.RdName == null || fileName == null) + if (String.IsNullOrWhiteSpace(fileUrl) || torrent.RdName == null) { return null; } @@ -19,6 +19,8 @@ public static class DownloadHelper var uri = new Uri(fileUrl); var torrentPath = Path.Combine(downloadPath, directory); + var fileName = download.FileName; + if (String.IsNullOrWhiteSpace(fileName)) { fileName = uri.Segments.Last(); @@ -66,11 +68,14 @@ public static class DownloadHelper var uri = new Uri(fileUrl); var torrentPath = RemoveInvalidPathChars(torrent.RdName); - var fileName = uri.Segments.Last(); + var fileName = download.FileName; - fileName = HttpUtility.UrlDecode(fileName); + if (String.IsNullOrWhiteSpace(fileName)) + { + fileName = uri.Segments.Last(); - fileName = FileHelper.RemoveInvalidFileNameChars(fileName); + fileName = HttpUtility.UrlDecode(fileName); + } var matchingTorrentFiles = torrent.Files.Where(m => m.Path.EndsWith(fileName)).Where(m => !String.IsNullOrWhiteSpace(m.Path)).ToList(); diff --git a/server/RdtClient.Service/Services/TorrentRunner.cs b/server/RdtClient.Service/Services/TorrentRunner.cs index 6b55c83..0774d0c 100644 --- a/server/RdtClient.Service/Services/TorrentRunner.cs +++ b/server/RdtClient.Service/Services/TorrentRunner.cs @@ -349,6 +349,9 @@ public class TorrentRunner(ILogger logger, Torrents torrents, Dow var downloadLink = await torrents.UnrestrictLink(download.DownloadId); download.Link = downloadLink; + + var fileName = await torrents.RetrieveFileName(download.DownloadId); + download.FileName = fileName; } } catch (Exception ex) diff --git a/server/RdtClient.Service/Services/Torrents.cs b/server/RdtClient.Service/Services/Torrents.cs index 0d3d7ae..4f7b0a5 100644 --- a/server/RdtClient.Service/Services/Torrents.cs +++ b/server/RdtClient.Service/Services/Torrents.cs @@ -370,6 +370,19 @@ public class Torrents( return unrestrictedLink; } + public async Task RetrieveFileName(Guid downloadId) + { + var download = await downloads.GetById(downloadId) ?? throw new($"Download with ID {downloadId} not found"); + + Log($"Unrestricting link", download, download.Torrent); + + var fileName = await TorrentClient.GetFileName(download.Link!); + + await downloads.UpdateFileName(downloadId, fileName); + + return fileName; + } + public async Task GetProfile() { var user = await TorrentClient.GetUser(); @@ -547,9 +560,7 @@ public class Torrents( var downloadPath = DownloadPath(download.Torrent!); - var fileName = await TorrentClient.GetFileName(download); - - var filePath = DownloadHelper.GetDownloadPath(downloadPath, download.Torrent!, download, fileName); + var filePath = DownloadHelper.GetDownloadPath(downloadPath, download.Torrent!, download); if (filePath != null) { From ac6300a5040da6d613d7a0ad1f0af70117e9af6f Mon Sep 17 00:00:00 2001 From: Sam Heinz <54530346+asylumexp@users.noreply.github.com> Date: Wed, 11 Dec 2024 00:03:43 +1000 Subject: [PATCH 07/25] [TB] Replace null with empty string for filenames in TorrentClient Not sure if its better to do this or allow null value to db, but i had this originally and it worked so i think im better off leaving it for now, but idk. Also got fix for incorrect log --- .../Services/TorrentClients/AllDebridTorrentClient.cs | 6 +++--- .../Services/TorrentClients/ITorrentClient.cs | 2 +- .../Services/TorrentClients/PremiumizeTorrentClient.cs | 6 +++--- .../Services/TorrentClients/RealDebridTorrentClient.cs | 6 +++--- .../Services/TorrentClients/TorBoxTorrentClient.cs | 4 ++-- server/RdtClient.Service/Services/Torrents.cs | 2 +- 6 files changed, 13 insertions(+), 13 deletions(-) diff --git a/server/RdtClient.Service/Services/TorrentClients/AllDebridTorrentClient.cs b/server/RdtClient.Service/Services/TorrentClients/AllDebridTorrentClient.cs index 3c7c789..dd3f424 100644 --- a/server/RdtClient.Service/Services/TorrentClients/AllDebridTorrentClient.cs +++ b/server/RdtClient.Service/Services/TorrentClients/AllDebridTorrentClient.cs @@ -263,16 +263,16 @@ public class AllDebridTorrentClient(ILogger logger, IHtt return links.Select(m => m.LinkUrl.ToString()).ToList(); } - public Task GetFileName(String downloadUrl) + public Task GetFileName(String downloadUrl) { if (String.IsNullOrWhiteSpace(downloadUrl)) { - return Task.FromResult(null); + return Task.FromResult(""); } var uri = new Uri(downloadUrl); - return Task.FromResult(HttpUtility.UrlDecode(uri.Segments.Last())); + return Task.FromResult(HttpUtility.UrlDecode(uri.Segments.Last())); } private async Task GetInfo(String torrentId) diff --git a/server/RdtClient.Service/Services/TorrentClients/ITorrentClient.cs b/server/RdtClient.Service/Services/TorrentClients/ITorrentClient.cs index 2813da8..38121ae 100644 --- a/server/RdtClient.Service/Services/TorrentClients/ITorrentClient.cs +++ b/server/RdtClient.Service/Services/TorrentClients/ITorrentClient.cs @@ -15,5 +15,5 @@ public interface ITorrentClient Task Unrestrict(String link); Task UpdateData(Torrent torrent, TorrentClientTorrent? torrentClientTorrent); Task?> GetDownloadLinks(Torrent torrent); - Task GetFileName(String downloadUrl); + Task GetFileName(String downloadUrl); } \ No newline at end of file diff --git a/server/RdtClient.Service/Services/TorrentClients/PremiumizeTorrentClient.cs b/server/RdtClient.Service/Services/TorrentClients/PremiumizeTorrentClient.cs index b91790b..4a1745b 100644 --- a/server/RdtClient.Service/Services/TorrentClients/PremiumizeTorrentClient.cs +++ b/server/RdtClient.Service/Services/TorrentClients/PremiumizeTorrentClient.cs @@ -242,16 +242,16 @@ public class PremiumizeTorrentClient(ILogger logger, IH return downloadLinks; } - public Task GetFileName(String downloadUrl) + public Task GetFileName(String downloadUrl) { if (String.IsNullOrWhiteSpace(downloadUrl)) { - return Task.FromResult(null); + return Task.FromResult(""); } var uri = new Uri(downloadUrl); - return Task.FromResult(HttpUtility.UrlDecode(uri.Segments.Last())); + return Task.FromResult(HttpUtility.UrlDecode(uri.Segments.Last())); } private async Task GetInfo(String id) diff --git a/server/RdtClient.Service/Services/TorrentClients/RealDebridTorrentClient.cs b/server/RdtClient.Service/Services/TorrentClients/RealDebridTorrentClient.cs index 459cb7a..42b06d2 100644 --- a/server/RdtClient.Service/Services/TorrentClients/RealDebridTorrentClient.cs +++ b/server/RdtClient.Service/Services/TorrentClients/RealDebridTorrentClient.cs @@ -396,16 +396,16 @@ public class RealDebridTorrentClient(ILogger logger, IH return null; } - public Task GetFileName(String downloadUrl) + public Task GetFileName(String downloadUrl) { if (String.IsNullOrWhiteSpace(downloadUrl)) { - return Task.FromResult(null); + return Task.FromResult(""); } var uri = new Uri(downloadUrl); - return Task.FromResult(HttpUtility.UrlDecode(uri.Segments.Last())); + return Task.FromResult(HttpUtility.UrlDecode(uri.Segments.Last())); } private DateTimeOffset? ChangeTimeZone(DateTimeOffset? dateTimeOffset) diff --git a/server/RdtClient.Service/Services/TorrentClients/TorBoxTorrentClient.cs b/server/RdtClient.Service/Services/TorrentClients/TorBoxTorrentClient.cs index 6ebe877..1782391 100644 --- a/server/RdtClient.Service/Services/TorrentClients/TorBoxTorrentClient.cs +++ b/server/RdtClient.Service/Services/TorrentClients/TorBoxTorrentClient.cs @@ -302,11 +302,11 @@ public class TorBoxTorrentClient(ILogger logger, IHttpClien return files; } - public async Task GetFileName(String downloadUrl) + public async Task GetFileName(String downloadUrl) { if (String.IsNullOrWhiteSpace(downloadUrl)) { - return null; + return ""; } var uri = new Uri(downloadUrl); diff --git a/server/RdtClient.Service/Services/Torrents.cs b/server/RdtClient.Service/Services/Torrents.cs index 4f7b0a5..28a45b2 100644 --- a/server/RdtClient.Service/Services/Torrents.cs +++ b/server/RdtClient.Service/Services/Torrents.cs @@ -374,7 +374,7 @@ public class Torrents( { var download = await downloads.GetById(downloadId) ?? throw new($"Download with ID {downloadId} not found"); - Log($"Unrestricting link", download, download.Torrent); + Log($"Retrieving filename for", download, download.Torrent); var fileName = await TorrentClient.GetFileName(download.Link!); From e92b197ddb1f9fac55a3b9807a292772ce0f8427 Mon Sep 17 00:00:00 2001 From: Sam Heinz <54530346+asylumexp@users.noreply.github.com> Date: Wed, 11 Dec 2024 18:59:21 +1000 Subject: [PATCH 08/25] [TB] Fix UI errors --- client/src/app/setup/setup.component.html | 1 + server/RdtClient.Data/Models/Internal/DbSettings.cs | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/client/src/app/setup/setup.component.html b/client/src/app/setup/setup.component.html index 643e618..28c81e3 100644 --- a/client/src/app/setup/setup.component.html +++ b/client/src/app/setup/setup.component.html @@ -55,6 +55,7 @@ Use this link to sign up to Premiumize. +
Use this link to sign up to TorBox.
diff --git a/server/RdtClient.Data/Models/Internal/DbSettings.cs b/server/RdtClient.Data/Models/Internal/DbSettings.cs index 9402b33..a641f13 100644 --- a/server/RdtClient.Data/Models/Internal/DbSettings.cs +++ b/server/RdtClient.Data/Models/Internal/DbSettings.cs @@ -152,11 +152,11 @@ At this point only 1 provider can be used at the time.")] [Description(@"You can find your API key here: https://real-debrid.com/apitoken or -https://alldebrid.com/apikeys/ +https://alldebrid.com/apikeys/ or https://www.premiumize.me/account/ or -https://torbox.app/settings/")] +https://torbox.app/settings/")] public String ApiKey { get; set; } = ""; [DisplayName("Automatically import and process torrents added to provider")] From 1a27be830983d16b95107c9bf7e891931ec381bd Mon Sep 17 00:00:00 2001 From: Roger Far Date: Wed, 11 Dec 2024 20:13:42 -0700 Subject: [PATCH 09/25] Update packages. --- server/RdtClient.Web/RdtClient.Web.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/RdtClient.Web/RdtClient.Web.csproj b/server/RdtClient.Web/RdtClient.Web.csproj index adfbda3..5f07b60 100644 --- a/server/RdtClient.Web/RdtClient.Web.csproj +++ b/server/RdtClient.Web/RdtClient.Web.csproj @@ -39,7 +39,7 @@ - + From ea364eefc52cbb07a4d5483dc896fdfd876a8c2f Mon Sep 17 00:00:00 2001 From: Roger Far Date: Wed, 11 Dec 2024 20:15:25 -0700 Subject: [PATCH 10/25] Cleanup, bump to 91. --- CHANGELOG.md | 4 ++++ client/src/app/navbar/navbar.component.html | 2 +- package.json | 2 +- .../Services/TorrentClients/TorBoxTorrentClient.cs | 8 ++++---- server/RdtClient.Web/RdtClient.Web.csproj | 2 +- 5 files changed, 11 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index da04f8e..5f330ad 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,10 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [2.0.91] - 2024-12-11 +### Changed +- Torbox fixes. + ## [2.0.90] - 2024-12-06 ### Changed - Download individual files from Torbox instead of a zip file. diff --git a/client/src/app/navbar/navbar.component.html b/client/src/app/navbar/navbar.component.html index 55ee2b7..f917993 100644 --- a/client/src/app/navbar/navbar.component.html +++ b/client/src/app/navbar/navbar.component.html @@ -55,7 +55,7 @@ Profile Logout - Version 2.0.90 + Version 2.0.91 diff --git a/package.json b/package.json index 8c177b6..fc920bd 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "rdt-client", - "version": "2.0.90", + "version": "2.0.91", "description": "This is a web interface to manage your torrents on Real-Debrid.", "main": "index.js", "dependencies": { diff --git a/server/RdtClient.Service/Services/TorrentClients/TorBoxTorrentClient.cs b/server/RdtClient.Service/Services/TorrentClients/TorBoxTorrentClient.cs index 1782391..3fc3138 100644 --- a/server/RdtClient.Service/Services/TorrentClients/TorBoxTorrentClient.cs +++ b/server/RdtClient.Service/Services/TorrentClients/TorBoxTorrentClient.cs @@ -71,10 +71,10 @@ public class TorBoxTorrentClient(ILogger logger, IHttpClien OriginalBytes = torrent.Size, Host = torrent.DownloadPresent.ToString(), Split = 0, - Progress = (Int64)((torrent.Progress) * 100.0), + Progress = (Int64)(torrent.Progress * 100.0), Status = torrent.DownloadState, Added = ChangeTimeZone(torrent.CreatedAt)!.Value, - Files = (torrent.Files ?? []).Select(m => new TorrentClientFile + Files = (torrent.Files).Select(m => new TorrentClientFile { Path = String.Join("/", m.Name.Split('/').Skip(1)), Bytes = m.Size, @@ -313,8 +313,8 @@ public class TorBoxTorrentClient(ILogger logger, IHttpClien using (HttpClient client = new()) { - HttpRequestMessage request = new(HttpMethod.Head, uri); - HttpResponseMessage response = await client.SendAsync(request); + 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; diff --git a/server/RdtClient.Web/RdtClient.Web.csproj b/server/RdtClient.Web/RdtClient.Web.csproj index 5f07b60..3647d33 100644 --- a/server/RdtClient.Web/RdtClient.Web.csproj +++ b/server/RdtClient.Web/RdtClient.Web.csproj @@ -4,7 +4,7 @@ net9.0 Exe 94c24cba-f03f-4453-a671-3640b517c573 - 2.0.90 + 2.0.91 enable enable latest From 1ad3dc51dd706bf28fd3ba5ee116388d45913c21 Mon Sep 17 00:00:00 2001 From: Sam Heinz <54530346+asylumexp@users.noreply.github.com> Date: Thu, 12 Dec 2024 17:46:46 +1000 Subject: [PATCH 11/25] [TB] Fix source parameter null log spam #618 --- .../Services/TorrentClients/TorBoxTorrentClient.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/RdtClient.Service/Services/TorrentClients/TorBoxTorrentClient.cs b/server/RdtClient.Service/Services/TorrentClients/TorBoxTorrentClient.cs index 3fc3138..7a523e7 100644 --- a/server/RdtClient.Service/Services/TorrentClients/TorBoxTorrentClient.cs +++ b/server/RdtClient.Service/Services/TorrentClients/TorBoxTorrentClient.cs @@ -74,7 +74,7 @@ public class TorBoxTorrentClient(ILogger logger, IHttpClien Progress = (Int64)(torrent.Progress * 100.0), Status = torrent.DownloadState, Added = ChangeTimeZone(torrent.CreatedAt)!.Value, - Files = (torrent.Files).Select(m => new TorrentClientFile + Files = (torrent.Files ?? []).Select(m => new TorrentClientFile { Path = String.Join("/", m.Name.Split('/').Skip(1)), Bytes = m.Size, From 9a2d59afe0629ebc01deaed667b0ad3827127c1a Mon Sep 17 00:00:00 2001 From: Roger Versluis Date: Wed, 18 Dec 2024 07:23:44 -0700 Subject: [PATCH 12/25] no message --- CHANGELOG.md | 4 ++++ client/src/app/navbar/navbar.component.html | 2 +- package.json | 2 +- server/RdtClient.Web/RdtClient.Web.csproj | 2 +- 4 files changed, 7 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5f330ad..6c2c51b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,10 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [2.0.92] - 2024-12-18 +### Changed +- Torbox fixes. + ## [2.0.91] - 2024-12-11 ### Changed - Torbox fixes. diff --git a/client/src/app/navbar/navbar.component.html b/client/src/app/navbar/navbar.component.html index f917993..b5737f9 100644 --- a/client/src/app/navbar/navbar.component.html +++ b/client/src/app/navbar/navbar.component.html @@ -55,7 +55,7 @@ Profile Logout - Version 2.0.91 + Version 2.0.92 diff --git a/package.json b/package.json index fc920bd..d5031ff 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "rdt-client", - "version": "2.0.91", + "version": "2.0.92", "description": "This is a web interface to manage your torrents on Real-Debrid.", "main": "index.js", "dependencies": { diff --git a/server/RdtClient.Web/RdtClient.Web.csproj b/server/RdtClient.Web/RdtClient.Web.csproj index 3647d33..dea7f25 100644 --- a/server/RdtClient.Web/RdtClient.Web.csproj +++ b/server/RdtClient.Web/RdtClient.Web.csproj @@ -4,7 +4,7 @@ net9.0 Exe 94c24cba-f03f-4453-a671-3640b517c573 - 2.0.91 + 2.0.92 enable enable latest From e21dc7279a7726b316d711b981541809f9fd9469 Mon Sep 17 00:00:00 2001 From: Sam Heinz <54530346+asylumexp@users.noreply.github.com> Date: Sat, 28 Dec 2024 01:36:21 +1000 Subject: [PATCH 13/25] [TB] Fix Index was out of range error put < when shouldve put > --- .../TorrentClients/TorBoxTorrentClient.cs | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/server/RdtClient.Service/Services/TorrentClients/TorBoxTorrentClient.cs b/server/RdtClient.Service/Services/TorrentClients/TorBoxTorrentClient.cs index 7a523e7..765e535 100644 --- a/server/RdtClient.Service/Services/TorrentClients/TorBoxTorrentClient.cs +++ b/server/RdtClient.Service/Services/TorrentClients/TorBoxTorrentClient.cs @@ -40,20 +40,20 @@ public class TorBoxTorrentClient(ILogger logger, IHttpClien { foreach (var inner in ae.InnerExceptions) { - logger.LogError(inner, $"The connection to RealDebrid has failed: {inner.Message}"); + logger.LogError(inner, $"The connection to TorBox has failed: {inner.Message}"); } throw; } catch (TaskCanceledException ex) when (ex.InnerException is TimeoutException) { - logger.LogError(ex, $"The connection to RealDebrid has timed out: {ex.Message}"); + logger.LogError(ex, $"The connection to TorBox has timed out: {ex.Message}"); throw; } catch (TaskCanceledException ex) { - logger.LogError(ex, $"The connection to RealDebrid has timed out: {ex.Message}"); + logger.LogError(ex, $"The connection to TorBox has timed out: {ex.Message}"); throw; } @@ -161,17 +161,16 @@ public class TorBoxTorrentClient(ILogger logger, IHttpClien { var availability = await GetClient().Torrents.GetAvailabilityAsync(hash, listFiles: true); - if (availability.Data != null || availability.Data?.Count < 0) + if (availability.Data != null && availability.Data.Count > 0) { return (availability.Data[0]?.Files ?? []).Select(file => new TorrentClientAvailableFile - { - Filename = file.Name, - Filesize = file.Size - }) - .ToList(); + { + Filename = file.Name, + Filesize = file.Size + }).ToList(); } - return []; + return new List(); } public Task SelectFiles(Data.Models.Data.Torrent torrent) From 78daeeeaf37f71d6273f58996699e87d6bf15018 Mon Sep 17 00:00:00 2001 From: Sam Heinz <54530346+asylumexp@users.noreply.github.com> Date: Sat, 28 Dec 2024 16:52:45 +1000 Subject: [PATCH 14/25] [TB] Update TorBox.NET to 1.3.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 0ab2013..723a133 100644 --- a/server/RdtClient.Service/RdtClient.Service.csproj +++ b/server/RdtClient.Service/RdtClient.Service.csproj @@ -22,7 +22,7 @@ - + From 6afef148551680db0baabc52b366f569aee2d67d Mon Sep 17 00:00:00 2001 From: Sam Heinz <54530346+asylumexp@users.noreply.github.com> Date: Thu, 2 Jan 2025 13:10:36 +1000 Subject: [PATCH 15/25] [TB] Download via zip if file count is over 50 Due to rate limiting issues this is implemented again, it works now since TB reenabled HEAD method for zip downloads on their backend --- .../Services/TorrentClients/TorBoxTorrentClient.cs | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/server/RdtClient.Service/Services/TorrentClients/TorBoxTorrentClient.cs b/server/RdtClient.Service/Services/TorrentClients/TorBoxTorrentClient.cs index 765e535..ad472f0 100644 --- a/server/RdtClient.Service/Services/TorrentClients/TorBoxTorrentClient.cs +++ b/server/RdtClient.Service/Services/TorrentClients/TorBoxTorrentClient.cs @@ -292,11 +292,19 @@ public class TorBoxTorrentClient(ILogger logger, IHttpClien var torrentId = await GetClient().Torrents.GetHashInfoAsync(torrent.Hash, skipCache: true); - foreach (var file in torrent.Files) + if (torrent.Files.Count >= 50) { - var newFile = $"https://torbox.app/fakedl/{torrentId?.Id}/{file.Id}"; + var newFile = $"https://torbox.app/fakedl/{torrentId?.Id}/zip"; files.Add(newFile); } + else + { + foreach (var file in torrent.Files) + { + var newFile = $"https://torbox.app/fakedl/{torrentId?.Id}/{file.Id}"; + files.Add(newFile); + } + } return files; } From 065afe9461a36c821082132ad54fd97b187853b3 Mon Sep 17 00:00:00 2001 From: Sam Heinz <54530346+asylumexp@users.noreply.github.com> Date: Thu, 2 Jan 2025 13:15:42 +1000 Subject: [PATCH 16/25] [TB] Set seeding based on website seeding setting The default seed value for website dash is used to set whether to seed or not for new uncached torrents added via rdtclient --- .../Services/TorrentClients/TorBoxTorrentClient.cs | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/server/RdtClient.Service/Services/TorrentClients/TorBoxTorrentClient.cs b/server/RdtClient.Service/Services/TorrentClients/TorBoxTorrentClient.cs index ad472f0..6146d54 100644 --- a/server/RdtClient.Service/Services/TorrentClients/TorBoxTorrentClient.cs +++ b/server/RdtClient.Service/Services/TorrentClients/TorBoxTorrentClient.cs @@ -120,13 +120,9 @@ public class TorBoxTorrentClient(ILogger logger, IHttpClien public async Task AddMagnet(String magnetLink) { - // var seeding = Settings.Get.Integrations.Default.FinishedAction; + var user = await GetClient().User.GetAsync(true); - // Line is not working right now, will disable seeding and fix in december when I have time again. - // var seed = (seeding == TorrentFinishedAction.RemoveAllTorrents || seeding == TorrentFinishedAction.RemoveRealDebrid) ? 3 : 2; - - var seed = 3; - var result = await GetClient().Torrents.AddMagnetAsync(magnetLink, seed, false); + var result = await GetClient().Torrents.AddMagnetAsync(magnetLink, user.Data?.Settings?.SeedTorrents ?? 3, false); if (result.Error == "ACTIVE_LIMIT") { @@ -141,11 +137,9 @@ public class TorBoxTorrentClient(ILogger logger, IHttpClien public async Task AddFile(Byte[] bytes) { - // Line is not working right now, will disable seeding and fix in december when I have time again. - // var seed = (seeding == TorrentFinishedAction.RemoveAllTorrents || seeding == TorrentFinishedAction.RemoveRealDebrid) ? 3 : 2; - const Int32 seed = 3; + var user = await GetClient().User.GetAsync(true); - var result = await GetClient().Torrents.AddFileAsync(bytes, seed); + var result = await GetClient().Torrents.AddFileAsync(bytes, user.Data?.Settings?.SeedTorrents ?? 3); if (result.Error == "ACTIVE_LIMIT") { using var stream = new MemoryStream(bytes); From fa0f535858b857776024c7bfad5d59174266ef0a Mon Sep 17 00:00:00 2001 From: Sam Heinz <54530346+asylumexp@users.noreply.github.com> Date: Thu, 2 Jan 2025 13:15:59 +1000 Subject: [PATCH 17/25] [TB] Update TorBox.NET to 1.3.2 --- 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 723a133..f17b86d 100644 --- a/server/RdtClient.Service/RdtClient.Service.csproj +++ b/server/RdtClient.Service/RdtClient.Service.csproj @@ -22,7 +22,7 @@ - + From 409e47920e53393b2293e6118a63d4eb6eec3e3c Mon Sep 17 00:00:00 2001 From: Sam Heinz <54530346+asylumexp@users.noreply.github.com> Date: Thu, 2 Jan 2025 21:21:52 +1000 Subject: [PATCH 18/25] Revert "[TB] Download via zip if file count is over 50" This reverts commit 6afef148551680db0baabc52b366f569aee2d67d. --- .../Services/TorrentClients/TorBoxTorrentClient.cs | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/server/RdtClient.Service/Services/TorrentClients/TorBoxTorrentClient.cs b/server/RdtClient.Service/Services/TorrentClients/TorBoxTorrentClient.cs index 6146d54..1a9e5dc 100644 --- a/server/RdtClient.Service/Services/TorrentClients/TorBoxTorrentClient.cs +++ b/server/RdtClient.Service/Services/TorrentClients/TorBoxTorrentClient.cs @@ -286,19 +286,11 @@ public class TorBoxTorrentClient(ILogger logger, IHttpClien var torrentId = await GetClient().Torrents.GetHashInfoAsync(torrent.Hash, skipCache: true); - if (torrent.Files.Count >= 50) + foreach (var file in torrent.Files) { - var newFile = $"https://torbox.app/fakedl/{torrentId?.Id}/zip"; + var newFile = $"https://torbox.app/fakedl/{torrentId?.Id}/{file.Id}"; files.Add(newFile); } - else - { - foreach (var file in torrent.Files) - { - var newFile = $"https://torbox.app/fakedl/{torrentId?.Id}/{file.Id}"; - files.Add(newFile); - } - } return files; } From 34aec3d45da89d601b891ace09b0546a7f7e89c4 Mon Sep 17 00:00:00 2001 From: Roger Versluis Date: Fri, 3 Jan 2025 15:54:43 -0700 Subject: [PATCH 19/25] no message --- CHANGELOG.md | 4 ++++ package.json | 2 +- .../Services/TorrentClients/TorBoxTorrentClient.cs | 2 +- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6c2c51b..b1ef0f2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,10 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [2.0.93] - 2025-01-03 +### Changed +- Torbox fixes. + ## [2.0.92] - 2024-12-18 ### Changed - Torbox fixes. diff --git a/package.json b/package.json index d5031ff..d88bfe2 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "rdt-client", - "version": "2.0.92", + "version": "2.0.93", "description": "This is a web interface to manage your torrents on Real-Debrid.", "main": "index.js", "dependencies": { diff --git a/server/RdtClient.Service/Services/TorrentClients/TorBoxTorrentClient.cs b/server/RdtClient.Service/Services/TorrentClients/TorBoxTorrentClient.cs index 1a9e5dc..8775072 100644 --- a/server/RdtClient.Service/Services/TorrentClients/TorBoxTorrentClient.cs +++ b/server/RdtClient.Service/Services/TorrentClients/TorBoxTorrentClient.cs @@ -164,7 +164,7 @@ public class TorBoxTorrentClient(ILogger logger, IHttpClien }).ToList(); } - return new List(); + return []; } public Task SelectFiles(Data.Models.Data.Torrent torrent) From 8518cc1e103ec390146168957d617e8030d754c0 Mon Sep 17 00:00:00 2001 From: Roger Versluis Date: Fri, 3 Jan 2025 15:54:55 -0700 Subject: [PATCH 20/25] no message --- client/src/app/navbar/navbar.component.html | 2 +- server/RdtClient.Web/RdtClient.Web.csproj | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/client/src/app/navbar/navbar.component.html b/client/src/app/navbar/navbar.component.html index b5737f9..e97ae99 100644 --- a/client/src/app/navbar/navbar.component.html +++ b/client/src/app/navbar/navbar.component.html @@ -55,7 +55,7 @@ Profile Logout - Version 2.0.92 + Version 2.0.93 diff --git a/server/RdtClient.Web/RdtClient.Web.csproj b/server/RdtClient.Web/RdtClient.Web.csproj index dea7f25..cdc6cf8 100644 --- a/server/RdtClient.Web/RdtClient.Web.csproj +++ b/server/RdtClient.Web/RdtClient.Web.csproj @@ -4,7 +4,7 @@ net9.0 Exe 94c24cba-f03f-4453-a671-3640b517c573 - 2.0.92 + 2.0.93 enable enable latest From 0026541dcada0db4cdb29cf4985307fae3fc8f3f Mon Sep 17 00:00:00 2001 From: Sculas Date: Sat, 4 Jan 2025 04:29:26 +0100 Subject: [PATCH 21/25] fix(AllDebrid): Implement filters & fix file paths --- .../TorrentClients/AllDebridTorrentClient.cs | 89 +++++++++++++++---- 1 file changed, 72 insertions(+), 17 deletions(-) diff --git a/server/RdtClient.Service/Services/TorrentClients/AllDebridTorrentClient.cs b/server/RdtClient.Service/Services/TorrentClients/AllDebridTorrentClient.cs index dd3f424..6e9e178 100644 --- a/server/RdtClient.Service/Services/TorrentClients/AllDebridTorrentClient.cs +++ b/server/RdtClient.Service/Services/TorrentClients/AllDebridTorrentClient.cs @@ -1,4 +1,5 @@ -using AllDebridNET; +using System.Text.RegularExpressions; +using AllDebridNET; using Microsoft.Extensions.Logging; using Newtonsoft.Json; using RdtClient.Data.Enums; @@ -6,6 +7,7 @@ using RdtClient.Data.Models.TorrentClient; using RdtClient.Service.Helpers; using System.Web; using File = AllDebridNET.File; +using LogLevel = Microsoft.Extensions.Logging.LogLevel; using Torrent = RdtClient.Data.Models.Data.Torrent; namespace RdtClient.Service.Services.TorrentClients; @@ -62,7 +64,7 @@ public class AllDebridTorrentClient(ILogger logger, IHtt Added = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc).AddSeconds(torrent.UploadDate), Files = torrent.Links.Select((m, i) => new TorrentClientFile { - Path = m.Filename, + Path = GetFiles(m.Files), Bytes = m.Size, Id = i, Selected = true, @@ -242,6 +244,53 @@ public class AllDebridTorrentClient(ILogger logger, IHtt Log($"Found {links.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(); + foreach (var link in links) + { + var path = GetFiles(link.Files); + if (Regex.IsMatch(path, torrent.IncludeRegex)) + { + Log($"* Including {path}", torrent); + newLinks.Add(link); + } + else + { + Log($"* Excluding {path}", torrent); + } + } + + links = newLinks; + + Log($"Found {newLinks.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(); + foreach (var link in links) + { + var path = GetFiles(link.Files); + if (!Regex.IsMatch(path, torrent.ExcludeRegex)) + { + Log($"* Including {path}", torrent); + newLinks.Add(link); + } + else + { + Log($"* Excluding {path}", torrent); + } + } + + links = newLinks; + + Log($"Found {newLinks.Count} files that match the regex", torrent); + } if (links.Count == 0) { @@ -250,15 +299,16 @@ public class AllDebridTorrentClient(ILogger logger, IHtt links = magnet.Links; } - Log($"Selecting links:"); - - foreach (var link in links) + if (logger.IsEnabled(LogLevel.Debug)) { - var fileList = GetFiles(link.Files, ""); + Log($"Selecting links:"); - Log($"{link.Filename} ({link.Size}b) {link.LinkUrl}, contains files:{Environment.NewLine}{String.Join(Environment.NewLine, fileList)}"); + foreach (var link in links) + { + Log($"{GetFiles(link.Files)} ({link.Size}b) {link.LinkUrl}"); + } } - + Log("", torrent); return links.Select(m => m.LinkUrl.ToString()).ToList(); @@ -282,7 +332,7 @@ public class AllDebridTorrentClient(ILogger logger, IHtt return Map(result); } - private static List GetFiles(IList files, String parent) + private static String GetFiles(IList files) { var result = new List(); @@ -290,19 +340,24 @@ public class AllDebridTorrentClient(ILogger logger, IHtt { if (!String.IsNullOrWhiteSpace(file.N)) { - result.Add($"{parent}/{file.N}"); + result.Add(file.N); } if (file.E != null && file.E.Value.PurpleEArray != null && file.E.Value.PurpleEArray.Count > 0) { - result.AddRange(GetFiles(file.E.Value.PurpleEArray, file.N)); + if (file.E.Value.PurpleEArray.Count != 1) + { + throw new("Unexpected number of nested files"); + } + + result.AddRange(GetFiles(file.E.Value.PurpleEArray)); } } - return result; + return String.Join("/", result); } - private static List GetFiles(IList files, String parent) + private static List GetFiles(IList files) { var result = new List(); @@ -310,19 +365,19 @@ public class AllDebridTorrentClient(ILogger logger, IHtt { if (!String.IsNullOrWhiteSpace(file.N)) { - result.Add($"{parent}/{file.N}"); + result.Add(file.N); } if (file.E != null && file.E.Count > 0) { - result.AddRange(GetFiles(file.E, file.N)); + result.AddRange(GetFiles(file.E)); } } return result; } - private static List GetFiles(IList files, String parent) + private static List GetFiles(IList files) { var result = new List(); @@ -330,7 +385,7 @@ public class AllDebridTorrentClient(ILogger logger, IHtt { if (!String.IsNullOrWhiteSpace(file.N)) { - result.Add($"{parent}/{file.N}"); + result.Add(file.N); } } From 79164d54ca5dfe679113c80a3e86b8e8846a44da Mon Sep 17 00:00:00 2001 From: Roger Far Date: Sun, 5 Jan 2025 11:03:18 -0700 Subject: [PATCH 22/25] no message --- CHANGELOG.md | 4 ++++ client/src/app/navbar/navbar.component.html | 2 +- package.json | 2 +- server/RdtClient.Web/RdtClient.Web.csproj | 2 +- 4 files changed, 7 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b1ef0f2..2577c06 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,10 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [2.0.94] - 2025-01-05 +### Changed +- AllDebrid path fixes. + ## [2.0.93] - 2025-01-03 ### Changed - Torbox fixes. diff --git a/client/src/app/navbar/navbar.component.html b/client/src/app/navbar/navbar.component.html index e97ae99..c620099 100644 --- a/client/src/app/navbar/navbar.component.html +++ b/client/src/app/navbar/navbar.component.html @@ -55,7 +55,7 @@ Profile Logout - Version 2.0.93 + Version 2.0.94 diff --git a/package.json b/package.json index d88bfe2..69cd004 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "rdt-client", - "version": "2.0.93", + "version": "2.0.94", "description": "This is a web interface to manage your torrents on Real-Debrid.", "main": "index.js", "dependencies": { diff --git a/server/RdtClient.Web/RdtClient.Web.csproj b/server/RdtClient.Web/RdtClient.Web.csproj index cdc6cf8..a0eface 100644 --- a/server/RdtClient.Web/RdtClient.Web.csproj +++ b/server/RdtClient.Web/RdtClient.Web.csproj @@ -4,7 +4,7 @@ net9.0 Exe 94c24cba-f03f-4453-a671-3640b517c573 - 2.0.93 + 2.0.94 enable enable latest From 268bb6826c8e9a0d57b118523aade250863064a0 Mon Sep 17 00:00:00 2001 From: Sculas Date: Sun, 5 Jan 2025 22:17:22 +0100 Subject: [PATCH 23/25] fix: Fix invalid download path with single-file torrents --- .../RdtClient.Service/Helpers/DownloadHelper.cs | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/server/RdtClient.Service/Helpers/DownloadHelper.cs b/server/RdtClient.Service/Helpers/DownloadHelper.cs index 06724ad..609224e 100644 --- a/server/RdtClient.Service/Helpers/DownloadHelper.cs +++ b/server/RdtClient.Service/Helpers/DownloadHelper.cs @@ -43,6 +43,14 @@ public static class DownloadHelper subPath = subPath.Trim('/').Trim('\\'); torrentPath = Path.Combine(torrentPath, subPath); + } else if (torrent.Files.Count == 1) + { + if (directory != fileName) + { + throw new($"Torrent path {torrentPath} does not match file name {fileName}. This is a requirement for single file torrents."); + } + + return torrentPath; } } @@ -90,6 +98,14 @@ public static class DownloadHelper subPath = subPath.Trim('/').Trim('\\'); torrentPath = Path.Combine(torrentPath, subPath); + } else if (torrent.Files.Count == 1) + { + if (torrentPath != fileName) + { + throw new($"Torrent path {torrentPath} does not match file name {fileName}. This is a requirement for single file torrents."); + } + + return torrentPath; } } From d43774d9b56bedee0231262854158450d1aeeddd Mon Sep 17 00:00:00 2001 From: Roger Far Date: Sun, 5 Jan 2025 20:49:55 -0700 Subject: [PATCH 24/25] Fix hanging Aria2 downloads when files are being copied or cannot be found on the host. --- .../Services/Downloaders/Aria2cDownloader.cs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/server/RdtClient.Service/Services/Downloaders/Aria2cDownloader.cs b/server/RdtClient.Service/Services/Downloaders/Aria2cDownloader.cs index 1b2d172..8ab4cf3 100644 --- a/server/RdtClient.Service/Services/Downloaders/Aria2cDownloader.cs +++ b/server/RdtClient.Service/Services/Downloaders/Aria2cDownloader.cs @@ -203,6 +203,13 @@ public class Aria2cDownloader : IDownloader var retryCount = 0; while (true) { + DownloadProgress?.Invoke(this, new() + { + BytesDone = download.CompletedLength, + BytesTotal = download.TotalLength, + Speed = download.DownloadSpeed + }); + if (retryCount >= 10) { DownloadComplete?.Invoke(this, new() From d5ee5d209c24fedb0b9fe5812ce253a3fa9107f2 Mon Sep 17 00:00:00 2001 From: Roger Far Date: Sun, 5 Jan 2025 20:56:37 -0700 Subject: [PATCH 25/25] Changed how files are saved. --- .../Helpers/DownloadHelper.cs | 94 +++++++------------ 1 file changed, 34 insertions(+), 60 deletions(-) diff --git a/server/RdtClient.Service/Helpers/DownloadHelper.cs b/server/RdtClient.Service/Helpers/DownloadHelper.cs index 609224e..7a5d794 100644 --- a/server/RdtClient.Service/Helpers/DownloadHelper.cs +++ b/server/RdtClient.Service/Helpers/DownloadHelper.cs @@ -17,7 +17,6 @@ public static class DownloadHelper var directory = RemoveInvalidPathChars(torrent.RdName); var uri = new Uri(fileUrl); - var torrentPath = Path.Combine(downloadPath, directory); var fileName = download.FileName; @@ -30,31 +29,51 @@ public static class DownloadHelper fileName = FileHelper.RemoveInvalidFileNameChars(fileName); - var matchingTorrentFiles = torrent.Files.Where(m => m.Path.EndsWith(fileName)).Where(m => !String.IsNullOrWhiteSpace(m.Path)).ToList(); + var torrentPath = downloadPath; - if (matchingTorrentFiles.Count > 0) + if (torrent.Files.Count > 1) { - var matchingTorrentFile = matchingTorrentFiles[0]; + torrentPath = Path.Combine(downloadPath, directory); - var subPath = Path.GetDirectoryName(matchingTorrentFile.Path); + var matchingTorrentFiles = torrent.Files.Where(m => m.Path.EndsWith(fileName)).Where(m => !String.IsNullOrWhiteSpace(m.Path)).ToList(); + + if (matchingTorrentFiles.Count > 0) + { + var matchingTorrentFile = matchingTorrentFiles[0]; + + var subPath = Path.GetDirectoryName(matchingTorrentFile.Path); + + if (!String.IsNullOrWhiteSpace(subPath)) + { + subPath = subPath.Trim('/').Trim('\\'); + + torrentPath = Path.Combine(torrentPath, subPath); + } + else if (torrent.Files.Count == 1) + { + if (directory != fileName) + { + throw new($"Torrent path {torrentPath} does not match file name {fileName}. This is a requirement for single file torrents."); + } + + return torrentPath; + } + } + } + else if (torrent.Files.Count == 1) + { + var torrentFile = torrent.Files[0]; + var subPath = Path.GetDirectoryName(torrentFile.Path); if (!String.IsNullOrWhiteSpace(subPath)) { subPath = subPath.Trim('/').Trim('\\'); torrentPath = Path.Combine(torrentPath, subPath); - } else if (torrent.Files.Count == 1) - { - if (directory != fileName) - { - throw new($"Torrent path {torrentPath} does not match file name {fileName}. This is a requirement for single file torrents."); - } - - return torrentPath; } } - if (!Directory.Exists(torrentPath)) + if (!String.IsNullOrWhiteSpace(torrentPath) && !Directory.Exists(torrentPath)) { Directory.CreateDirectory(torrentPath); } @@ -66,52 +85,7 @@ public static class DownloadHelper public static String? GetDownloadPath(Torrent torrent, Download download) { - var fileUrl = download.Link; - - if (String.IsNullOrWhiteSpace(fileUrl) || torrent.RdName == null) - { - return null; - } - - var uri = new Uri(fileUrl); - var torrentPath = RemoveInvalidPathChars(torrent.RdName); - - var fileName = download.FileName; - - if (String.IsNullOrWhiteSpace(fileName)) - { - fileName = uri.Segments.Last(); - - fileName = HttpUtility.UrlDecode(fileName); - } - - var matchingTorrentFiles = torrent.Files.Where(m => m.Path.EndsWith(fileName)).Where(m => !String.IsNullOrWhiteSpace(m.Path)).ToList(); - - if (matchingTorrentFiles.Count > 0) - { - var matchingTorrentFile = matchingTorrentFiles[0]; - - var subPath = Path.GetDirectoryName(matchingTorrentFile.Path); - - if (!String.IsNullOrWhiteSpace(subPath)) - { - subPath = subPath.Trim('/').Trim('\\'); - - torrentPath = Path.Combine(torrentPath, subPath); - } else if (torrent.Files.Count == 1) - { - if (torrentPath != fileName) - { - throw new($"Torrent path {torrentPath} does not match file name {fileName}. This is a requirement for single file torrents."); - } - - return torrentPath; - } - } - - var filePath = Path.Combine(torrentPath, fileName); - - return filePath; + return GetDownloadPath("", torrent, download); } private static String RemoveInvalidPathChars(String path)