From 187a428ba766ddfc88810ef5d54a9eec0672782c Mon Sep 17 00:00:00 2001 From: Roger Far Date: Tue, 18 Oct 2022 12:06:03 -0600 Subject: [PATCH] Add setting to skip downloading the files to the host. --- README.md | 4 +- .../add-new-torrent.component.html | 17 +- .../add-new-torrent.component.ts | 4 + client/src/app/models/torrent.model.ts | 1 + client/src/app/torrent/torrent.component.html | 9 +- server/RdtClient.Data/Data/TorrentData.cs | 1 + .../Enums/TorrentHostDownloadAction.cs | 12 + ...orrents_Add_HostDownloadAction.Designer.cs | 463 ++++++++++++++++++ ...8174415_Torrents_Add_HostDownloadAction.cs | 26 + .../Migrations/DataContextModelSnapshot.cs | 5 +- server/RdtClient.Data/Models/Data/Torrent.cs | 1 + .../Models/Internal/DbSettings.cs | 17 +- .../BackgroundServices/WatchFolderChecker.cs | 1 + .../RdtClient.Service/Services/QBittorrent.cs | 2 + .../TorrentClients/RealDebridTorrentClient.cs | 2 +- .../Services/TorrentRunner.cs | 10 +- 16 files changed, 561 insertions(+), 14 deletions(-) create mode 100644 server/RdtClient.Data/Enums/TorrentHostDownloadAction.cs create mode 100644 server/RdtClient.Data/Migrations/20221018174415_Torrents_Add_HostDownloadAction.Designer.cs create mode 100644 server/RdtClient.Data/Migrations/20221018174415_Torrents_Add_HostDownloadAction.cs diff --git a/README.md b/README.md index 3a2e7c7..d69949a 100644 --- a/README.md +++ b/README.md @@ -5,8 +5,8 @@ This is a web interface to manage your torrents on Real-Debrid or AllDebrid. It - Add new torrents through magnets or files - Download all files from Real-Debrid or AllDebrid to your local machine automatically - Unpack all files when finished downloading -- Implements a fake qBittorrent API so you can hook up other applications like Sonarr or Couchpotato. -- Built with Angular 13 and .NET 6 +- Implements a fake qBittorrent API so you can hook up other applications like Sonarr, Radarr or Couchpotato. +- Built with Angular 14 and .NET 6 **You will need a Premium service at Real-Debrid or AllDebrid!** diff --git a/client/src/app/add-new-torrent/add-new-torrent.component.html b/client/src/app/add-new-torrent/add-new-torrent.component.html index 1c2142e..cf2fd43 100644 --- a/client/src/app/add-new-torrent/add-new-torrent.component.html +++ b/client/src/app/add-new-torrent/add-new-torrent.component.html @@ -37,7 +37,21 @@
- + +
+ +
+

+ When a torrent is finished downloading on the provider, perform this action. Use this setting if you only want + to add files to Real-Debrid but not download them to the host. +

+
+ +
+
+

When a torrent is fully downloaded on the provider, perform this action.

This option is only available for RealDebrid. AllDebrid will always download the full torrent.

diff --git a/client/src/app/add-new-torrent/add-new-torrent.component.ts b/client/src/app/add-new-torrent/add-new-torrent.component.ts index fb93eef..94d50d9 100644 --- a/client/src/app/add-new-torrent/add-new-torrent.component.ts +++ b/client/src/app/add-new-torrent/add-new-torrent.component.ts @@ -17,6 +17,7 @@ export class AddNewTorrentComponent implements OnInit { public provider: string; public category: string; + public hostDownloadAction: number = 0; public downloadAction: number = 0; public finishedAction: number = 0; public downloadMinSize: number = 0; @@ -47,6 +48,8 @@ export class AddNewTorrentComponent implements OnInit { this.provider = providerSetting.enumValues[providerSetting.value as number]; this.category = settings.first((m) => m.key === 'Gui:Default:Category')?.value as string; + this.hostDownloadAction = this.downloadAction = settings.first((m) => m.key === 'Gui:Default:HostDownloadAction') + ?.value as number; this.downloadAction = settings.first((m) => m.key === 'Gui:Default:OnlyDownloadAvailableFiles')?.value === true ? 1 : 0; this.finishedAction = settings.first((m) => m.key === 'Gui:Default:FinishedAction')?.value as number; @@ -119,6 +122,7 @@ export class AddNewTorrentComponent implements OnInit { const torrent = new Torrent(); torrent.category = this.category; + torrent.hostDownloadAction = this.hostDownloadAction; torrent.downloadAction = this.downloadAction; torrent.finishedAction = this.finishedAction; torrent.downloadMinSize = this.downloadMinSize; diff --git a/client/src/app/models/torrent.model.ts b/client/src/app/models/torrent.model.ts index 1ce98b0..4e1bd07 100644 --- a/client/src/app/models/torrent.model.ts +++ b/client/src/app/models/torrent.model.ts @@ -4,6 +4,7 @@ export class Torrent { public torrentId: string; public hash: string; public category: string; + public hostDownloadAction: number; public downloadAction: number; public finishedAction: number; public downloadMinSize: number; diff --git a/client/src/app/torrent/torrent.component.html b/client/src/app/torrent/torrent.component.html index a1df642..2050e19 100644 --- a/client/src/app/torrent/torrent.component.html +++ b/client/src/app/torrent/torrent.component.html @@ -52,7 +52,14 @@ {{ torrent.category || "(no category set)" }}
- + + + Download all files to host + Don't download files to host + +
+
+ Download all files above a certain size +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("20221018174415_Torrents_Add_HostDownloadAction")] + partial class Torrents_Add_HostDownloadAction + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder.HasAnnotation("ProductVersion", "6.0.10"); + + 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("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("DownloadManualFiles") + .HasColumnType("TEXT"); + + b.Property("DownloadMinSize") + .HasColumnType("INTEGER"); + + b.Property("DownloadRetryAttempts") + .HasColumnType("INTEGER"); + + b.Property("Error") + .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("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/20221018174415_Torrents_Add_HostDownloadAction.cs b/server/RdtClient.Data/Migrations/20221018174415_Torrents_Add_HostDownloadAction.cs new file mode 100644 index 0000000..3a17a59 --- /dev/null +++ b/server/RdtClient.Data/Migrations/20221018174415_Torrents_Add_HostDownloadAction.cs @@ -0,0 +1,26 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace RdtClient.Data.Migrations +{ + public partial class Torrents_Add_HostDownloadAction : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.AddColumn( + name: "HostDownloadAction", + table: "Torrents", + type: "INTEGER", + nullable: false, + defaultValue: 0); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropColumn( + name: "HostDownloadAction", + table: "Torrents"); + } + } +} diff --git a/server/RdtClient.Data/Migrations/DataContextModelSnapshot.cs b/server/RdtClient.Data/Migrations/DataContextModelSnapshot.cs index e8be86a..b1ad3bc 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", "6.0.5"); + modelBuilder.HasAnnotation("ProductVersion", "6.0.10"); modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b => { @@ -324,6 +324,9 @@ namespace RdtClient.Data.Migrations .IsRequired() .HasColumnType("TEXT"); + b.Property("HostDownloadAction") + .HasColumnType("INTEGER"); + b.Property("IsFile") .HasColumnType("INTEGER"); diff --git a/server/RdtClient.Data/Models/Data/Torrent.cs b/server/RdtClient.Data/Models/Data/Torrent.cs index 1282975..5dd3c52 100644 --- a/server/RdtClient.Data/Models/Data/Torrent.cs +++ b/server/RdtClient.Data/Models/Data/Torrent.cs @@ -17,6 +17,7 @@ public class Torrent public TorrentDownloadAction DownloadAction { get; set; } public TorrentFinishedAction FinishedAction { get; set; } + public TorrentHostDownloadAction HostDownloadAction { get; set; } public Int32 DownloadMinSize { get; set; } public String? DownloadManualFiles { get; set; } diff --git a/server/RdtClient.Data/Models/Internal/DbSettings.cs b/server/RdtClient.Data/Models/Internal/DbSettings.cs index 03caf72..abb49e0 100644 --- a/server/RdtClient.Data/Models/Internal/DbSettings.cs +++ b/server/RdtClient.Data/Models/Internal/DbSettings.cs @@ -147,12 +147,12 @@ or public class DbSettingsIntegrations { - public DbSettingsDefaults Default { get; set; } = new(); + public DbSettingsDefaultsWithDownload Default { get; set; } = new(); } public class DbSettingsGui { - public DbSettingsDefaultsWithCategory Default { get; set; } = new(); + public DbSettingsDefaultsWithDownload Default { get; set; } = new(); } public class DbSettingsWatch @@ -166,7 +166,14 @@ public class DbSettingsWatch public Int32 Interval { get; set; } = 60; [DisplayName("Import Defaults")] - public DbSettingsDefaultsWithCategory Default { get; set; } = new(); + public DbSettingsDefaultsWithDownload Default { get; set; } = new(); +} + +public class DbSettingsDefaultsWithDownload : DbSettingsDefaultsWithCategory +{ + [DisplayName("Post Torrent Download Action")] + [Description("When a torrent is finished downloading on the provider, perform this action. Use this setting if you only want to add files to Real-Debrid but not download them to the host.")] + public TorrentHostDownloadAction HostDownloadAction { get; set; } } public class DbSettingsDefaultsWithCategory : DbSettingsDefaults @@ -175,8 +182,8 @@ public class DbSettingsDefaultsWithCategory : DbSettingsDefaults [Description("When a torrent is imported assign it this category.")] public String? Category { get; set; } = null; - [DisplayName("Finished Action")] - [Description("When a torrent is finished, perform this action.")] + [DisplayName("Post Download Action")] + [Description("When all files are downloaded from the provider to the host, perform this action.")] public TorrentFinishedAction FinishedAction { get; set; } = TorrentFinishedAction.RemoveAllTorrents; } diff --git a/server/RdtClient.Service/BackgroundServices/WatchFolderChecker.cs b/server/RdtClient.Service/BackgroundServices/WatchFolderChecker.cs index 1b1812b..3e99397 100644 --- a/server/RdtClient.Service/BackgroundServices/WatchFolderChecker.cs +++ b/server/RdtClient.Service/BackgroundServices/WatchFolderChecker.cs @@ -81,6 +81,7 @@ public class WatchFolderChecker : BackgroundService var torrent = new Torrent { Category = Settings.Get.Watch.Default.Category, + HostDownloadAction = Settings.Get.Watch.Default.HostDownloadAction, DownloadAction = Settings.Get.Watch.Default.OnlyDownloadAvailableFiles ? TorrentDownloadAction.DownloadAvailableFiles : TorrentDownloadAction.DownloadAll, FinishedAction = Settings.Get.Watch.Default.FinishedAction, DownloadMinSize = Settings.Get.Watch.Default.MinFileSize, diff --git a/server/RdtClient.Service/Services/QBittorrent.cs b/server/RdtClient.Service/Services/QBittorrent.cs index 2450a73..49ad1f2 100644 --- a/server/RdtClient.Service/Services/QBittorrent.cs +++ b/server/RdtClient.Service/Services/QBittorrent.cs @@ -420,6 +420,7 @@ public class QBittorrent var torrent = new Torrent { Category = category, + HostDownloadAction = Settings.Get.Integrations.Default.HostDownloadAction, DownloadAction = Settings.Get.Integrations.Default.OnlyDownloadAvailableFiles ? TorrentDownloadAction.DownloadAvailableFiles : TorrentDownloadAction.DownloadAll, FinishedAction = TorrentFinishedAction.None, DownloadMinSize = Settings.Get.Integrations.Default.MinFileSize, @@ -438,6 +439,7 @@ public class QBittorrent var torrent = new Torrent { Category = category, + HostDownloadAction = Settings.Get.Integrations.Default.HostDownloadAction, DownloadAction = Settings.Get.Integrations.Default.OnlyDownloadAvailableFiles ? TorrentDownloadAction.DownloadAvailableFiles : TorrentDownloadAction.DownloadAll, FinishedAction = TorrentFinishedAction.None, DownloadMinSize = Settings.Get.Integrations.Default.MinFileSize, diff --git a/server/RdtClient.Service/Services/TorrentClients/RealDebridTorrentClient.cs b/server/RdtClient.Service/Services/TorrentClients/RealDebridTorrentClient.cs index 02ce967..fb920ff 100644 --- a/server/RdtClient.Service/Services/TorrentClients/RealDebridTorrentClient.cs +++ b/server/RdtClient.Service/Services/TorrentClients/RealDebridTorrentClient.cs @@ -147,7 +147,7 @@ public class RealDebridTorrentClient : ITorrentClient { Filename = m.First().Filename!, Filesize = m.First().Filesize - } ).ToList(); + }).ToList(); return torrentClientAvailableFiles; } diff --git a/server/RdtClient.Service/Services/TorrentRunner.cs b/server/RdtClient.Service/Services/TorrentRunner.cs index c1dba8f..056d5eb 100644 --- a/server/RdtClient.Service/Services/TorrentRunner.cs +++ b/server/RdtClient.Service/Services/TorrentRunner.cs @@ -501,12 +501,16 @@ public class TorrentRunner { Log($"Creating downloads", torrent); - await _torrents.CreateDownloads(torrent.TorrentId); + if (torrent.HostDownloadAction == TorrentHostDownloadAction.DownloadAll) + { + await _torrents.CreateDownloads(torrent.TorrentId); + } } } - // Check if torrent is complete - if (torrent.Downloads.Count > 0) + // Check if torrent is complete, or if we don't want to download any files to the host. + if ((torrent.Downloads.Count > 0) || + torrent.RdStatus == TorrentStatus.Finished && torrent.HostDownloadAction == TorrentHostDownloadAction.DownloadNone) { var allComplete = torrent.Downloads.Count(m => m.Completed != null);