Merge pull request #857 from Cucumberrbob/feat/completed-torrent-grace-period

add setting to delay `FinishedAction`
This commit is contained in:
Roger Far 2025-07-28 22:00:31 -06:00 committed by GitHub
commit 25032a4e65
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
14 changed files with 604 additions and 50 deletions

View file

@ -151,6 +151,17 @@
</div>
</div>
<div class="field">
<label class="label">Finished Action Delay (minutes)</label>
<div class="control is-fullwidth">
<input class="input" type="number" [(ngModel)]="finishedActionDelay" />
</div>
<p class="help">
When a torrent is finished downloading on the provider, perform this action. Use this setting if you only want
to add files to your debrid provider but not download them to the host.
</p>
</div>
<div class="field">
<label class="label">Category</label>
<div class="control">

View file

@ -23,6 +23,7 @@ export class AddNewTorrentComponent implements OnInit {
public hostDownloadAction: number = 0;
public downloadAction: number = 0;
public finishedAction: number = 0;
public finishedActionDelay: number = 0;
public downloadMinSize: number = 0;
public includeRegex: string = '';
public excludeRegex: string = '';
@ -49,11 +50,11 @@ export class AddNewTorrentComponent implements OnInit {
private router: Router,
private torrentService: TorrentService,
private settingsService: SettingsService,
private activatedRoute: ActivatedRoute
private activatedRoute: ActivatedRoute,
) {}
ngOnInit(): void {
this.activatedRoute.queryParams.subscribe(params => {
this.activatedRoute.queryParams.subscribe((params) => {
if (params['magnet']) {
this.magnetLink = decodeURIComponent(params['magnet']);
}
@ -69,6 +70,7 @@ export class AddNewTorrentComponent implements OnInit {
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;
this.finishedActionDelay = settings.first((m) => m.key == 'Gui:Default:FinishedActionDelay')?.value as number;
this.downloadMinSize = settings.first((m) => m.key === 'Gui:Default:MinFileSize')?.value as number;
this.includeRegex = settings.first((m) => m.key === 'Gui:Default:IncludeRegex')?.value as string;
this.excludeRegex = settings.first((m) => m.key === 'Gui:Default:ExcludeRegex')?.value as string;
@ -155,6 +157,7 @@ export class AddNewTorrentComponent implements OnInit {
torrent.hostDownloadAction = this.hostDownloadAction;
torrent.downloadAction = this.downloadAction;
torrent.finishedAction = this.finishedAction;
torrent.finishedActionDelay = this.finishedActionDelay;
torrent.downloadMinSize = this.downloadMinSize;
torrent.includeRegex = this.includeRegex;
torrent.excludeRegex = this.excludeRegex;

View file

@ -8,6 +8,7 @@ export class Torrent {
public hostDownloadAction: number;
public downloadAction: number;
public finishedAction: number;
public finishedActionDelay: number;
public downloadMinSize: number;
public includeRegex: string;
public excludeRegex: string;

View file

@ -116,6 +116,15 @@
}
}
</div>
<div class="field">
<label class="label">Finished action delay</label>
{{ torrent.finishedActionDelay || 0 }}
@if (torrent.finishedActionDelay === 1) {
minute
} @else {
minutes
}
</div>
<div class="field">
<label class="label">Minimum file size to download</label>
{{ torrent.downloadMinSize }}MB

View file

@ -86,6 +86,7 @@ public class TorrentData(DataContext dataContext) : ITorrentData
Hash = hash.ToLower(),
Category = torrent.Category,
HostDownloadAction = torrent.HostDownloadAction,
FinishedActionDelay = torrent.FinishedActionDelay,
DownloadAction = torrent.DownloadAction,
FinishedAction = torrent.FinishedAction,
DownloadMinSize = torrent.DownloadMinSize,

View file

@ -0,0 +1,482 @@
// <auto-generated />
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("20250706204358_AddFinishedActionDelay")]
partial class AddFinishedActionDelay
{
/// <inheritdoc />
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder.HasAnnotation("ProductVersion", "9.0.5");
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b =>
{
b.Property<string>("Id")
.HasColumnType("TEXT");
b.Property<string>("ConcurrencyStamp")
.IsConcurrencyToken()
.HasColumnType("TEXT");
b.Property<string>("Name")
.HasMaxLength(256)
.HasColumnType("TEXT");
b.Property<string>("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<string>", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<string>("ClaimType")
.HasColumnType("TEXT");
b.Property<string>("ClaimValue")
.HasColumnType("TEXT");
b.Property<string>("RoleId")
.IsRequired()
.HasColumnType("TEXT");
b.HasKey("Id");
b.HasIndex("RoleId");
b.ToTable("AspNetRoleClaims", (string)null);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUser", b =>
{
b.Property<string>("Id")
.HasColumnType("TEXT");
b.Property<int>("AccessFailedCount")
.HasColumnType("INTEGER");
b.Property<string>("ConcurrencyStamp")
.IsConcurrencyToken()
.HasColumnType("TEXT");
b.Property<string>("Email")
.HasMaxLength(256)
.HasColumnType("TEXT");
b.Property<bool>("EmailConfirmed")
.HasColumnType("INTEGER");
b.Property<bool>("LockoutEnabled")
.HasColumnType("INTEGER");
b.Property<DateTimeOffset?>("LockoutEnd")
.HasColumnType("TEXT");
b.Property<string>("NormalizedEmail")
.HasMaxLength(256)
.HasColumnType("TEXT");
b.Property<string>("NormalizedUserName")
.HasMaxLength(256)
.HasColumnType("TEXT");
b.Property<string>("PasswordHash")
.HasColumnType("TEXT");
b.Property<string>("PhoneNumber")
.HasColumnType("TEXT");
b.Property<bool>("PhoneNumberConfirmed")
.HasColumnType("INTEGER");
b.Property<string>("SecurityStamp")
.HasColumnType("TEXT");
b.Property<bool>("TwoFactorEnabled")
.HasColumnType("INTEGER");
b.Property<string>("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<string>", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<string>("ClaimType")
.HasColumnType("TEXT");
b.Property<string>("ClaimValue")
.HasColumnType("TEXT");
b.Property<string>("UserId")
.IsRequired()
.HasColumnType("TEXT");
b.HasKey("Id");
b.HasIndex("UserId");
b.ToTable("AspNetUserClaims", (string)null);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b =>
{
b.Property<string>("LoginProvider")
.HasColumnType("TEXT");
b.Property<string>("ProviderKey")
.HasColumnType("TEXT");
b.Property<string>("ProviderDisplayName")
.HasColumnType("TEXT");
b.Property<string>("UserId")
.IsRequired()
.HasColumnType("TEXT");
b.HasKey("LoginProvider", "ProviderKey");
b.HasIndex("UserId");
b.ToTable("AspNetUserLogins", (string)null);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<string>", b =>
{
b.Property<string>("UserId")
.HasColumnType("TEXT");
b.Property<string>("RoleId")
.HasColumnType("TEXT");
b.HasKey("UserId", "RoleId");
b.HasIndex("RoleId");
b.ToTable("AspNetUserRoles", (string)null);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<string>", b =>
{
b.Property<string>("UserId")
.HasColumnType("TEXT");
b.Property<string>("LoginProvider")
.HasColumnType("TEXT");
b.Property<string>("Name")
.HasColumnType("TEXT");
b.Property<string>("Value")
.HasColumnType("TEXT");
b.HasKey("UserId", "LoginProvider", "Name");
b.ToTable("AspNetUserTokens", (string)null);
});
modelBuilder.Entity("RdtClient.Data.Models.Data.Download", b =>
{
b.Property<Guid>("DownloadId")
.ValueGeneratedOnAdd()
.HasColumnType("TEXT");
b.Property<DateTimeOffset>("Added")
.HasColumnType("TEXT");
b.Property<DateTimeOffset?>("Completed")
.HasColumnType("TEXT");
b.Property<DateTimeOffset?>("DownloadFinished")
.HasColumnType("TEXT");
b.Property<DateTimeOffset?>("DownloadQueued")
.HasColumnType("TEXT");
b.Property<DateTimeOffset?>("DownloadStarted")
.HasColumnType("TEXT");
b.Property<string>("Error")
.HasColumnType("TEXT");
b.Property<string>("FileName")
.HasColumnType("TEXT");
b.Property<string>("Link")
.HasColumnType("TEXT");
b.Property<string>("Path")
.IsRequired()
.HasColumnType("TEXT");
b.Property<string>("RemoteId")
.HasColumnType("TEXT");
b.Property<int>("RetryCount")
.HasColumnType("INTEGER");
b.Property<Guid>("TorrentId")
.HasColumnType("TEXT");
b.Property<DateTimeOffset?>("UnpackingFinished")
.HasColumnType("TEXT");
b.Property<DateTimeOffset?>("UnpackingQueued")
.HasColumnType("TEXT");
b.Property<DateTimeOffset?>("UnpackingStarted")
.HasColumnType("TEXT");
b.HasKey("DownloadId");
b.HasIndex("TorrentId");
b.ToTable("Downloads");
});
modelBuilder.Entity("RdtClient.Data.Models.Data.Setting", b =>
{
b.Property<string>("SettingId")
.HasColumnType("TEXT");
b.Property<string>("Value")
.HasColumnType("TEXT");
b.HasKey("SettingId");
b.ToTable("Settings");
});
modelBuilder.Entity("RdtClient.Data.Models.Data.Torrent", b =>
{
b.Property<Guid>("TorrentId")
.ValueGeneratedOnAdd()
.HasColumnType("TEXT");
b.Property<DateTimeOffset>("Added")
.HasColumnType("TEXT");
b.Property<string>("Category")
.HasColumnType("TEXT");
b.Property<int?>("ClientKind")
.HasColumnType("INTEGER");
b.Property<DateTimeOffset?>("Completed")
.HasColumnType("TEXT");
b.Property<int>("DeleteOnError")
.HasColumnType("INTEGER");
b.Property<int>("DownloadAction")
.HasColumnType("INTEGER");
b.Property<int>("DownloadClient")
.HasColumnType("INTEGER");
b.Property<string>("DownloadManualFiles")
.HasColumnType("TEXT");
b.Property<int>("DownloadMinSize")
.HasColumnType("INTEGER");
b.Property<int>("DownloadRetryAttempts")
.HasColumnType("INTEGER");
b.Property<string>("Error")
.HasColumnType("TEXT");
b.Property<string>("ExcludeRegex")
.HasColumnType("TEXT");
b.Property<string>("FileOrMagnet")
.HasColumnType("TEXT");
b.Property<DateTimeOffset?>("FilesSelected")
.HasColumnType("TEXT");
b.Property<int>("FinishedAction")
.HasColumnType("INTEGER");
b.Property<int>("FinishedActionDelay")
.HasColumnType("INTEGER");
b.Property<string>("Hash")
.IsRequired()
.HasColumnType("TEXT");
b.Property<int>("HostDownloadAction")
.HasColumnType("INTEGER");
b.Property<string>("IncludeRegex")
.HasColumnType("TEXT");
b.Property<bool>("IsFile")
.HasColumnType("INTEGER");
b.Property<int>("Lifetime")
.HasColumnType("INTEGER");
b.Property<int?>("Priority")
.HasColumnType("INTEGER");
b.Property<DateTimeOffset?>("RdAdded")
.HasColumnType("TEXT");
b.Property<DateTimeOffset?>("RdEnded")
.HasColumnType("TEXT");
b.Property<string>("RdFiles")
.HasColumnType("TEXT");
b.Property<string>("RdHost")
.HasColumnType("TEXT");
b.Property<string>("RdId")
.HasColumnType("TEXT");
b.Property<string>("RdName")
.HasColumnType("TEXT");
b.Property<long?>("RdProgress")
.HasColumnType("INTEGER");
b.Property<long?>("RdSeeders")
.HasColumnType("INTEGER");
b.Property<long?>("RdSize")
.HasColumnType("INTEGER");
b.Property<long?>("RdSpeed")
.HasColumnType("INTEGER");
b.Property<long?>("RdSplit")
.HasColumnType("INTEGER");
b.Property<int?>("RdStatus")
.HasColumnType("INTEGER");
b.Property<string>("RdStatusRaw")
.HasColumnType("TEXT");
b.Property<DateTimeOffset?>("Retry")
.HasColumnType("TEXT");
b.Property<int>("RetryCount")
.HasColumnType("INTEGER");
b.Property<int>("TorrentRetryAttempts")
.HasColumnType("INTEGER");
b.HasKey("TorrentId");
b.ToTable("Torrents");
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<string>", b =>
{
b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null)
.WithMany()
.HasForeignKey("RoleId")
.OnDelete(DeleteBehavior.Restrict)
.IsRequired();
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<string>", b =>
{
b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null)
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Restrict)
.IsRequired();
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b =>
{
b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null)
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Restrict)
.IsRequired();
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<string>", 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<string>", 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
}
}
}

View file

@ -0,0 +1,29 @@
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace RdtClient.Data.Migrations
{
/// <inheritdoc />
public partial class AddFinishedActionDelay : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddColumn<int>(
name: "FinishedActionDelay",
table: "Torrents",
type: "INTEGER",
nullable: false,
defaultValue: 0);
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropColumn(
name: "FinishedActionDelay",
table: "Torrents");
}
}
}

View file

@ -15,7 +15,7 @@ namespace RdtClient.Data.Migrations
protected override void BuildModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder.HasAnnotation("ProductVersion", "9.0.0");
modelBuilder.HasAnnotation("ProductVersion", "9.0.5");
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b =>
{
@ -332,6 +332,9 @@ namespace RdtClient.Data.Migrations
b.Property<int>("FinishedAction")
.HasColumnType("INTEGER");
b.Property<int>("FinishedActionDelay")
.HasColumnType("INTEGER");
b.Property<string>("Hash")
.IsRequired()
.HasColumnType("TEXT");

View file

@ -17,6 +17,7 @@ public class Torrent
public TorrentDownloadAction DownloadAction { get; set; }
public TorrentFinishedAction FinishedAction { get; set; }
public Int32 FinishedActionDelay { get; set; }
public TorrentHostDownloadAction HostDownloadAction { get; set; }
public Int32 DownloadMinSize { get; set; }
public String? IncludeRegex { get; set; }

View file

@ -269,6 +269,10 @@ public class DbSettingsDefaultsWithCategory : DbSettingsDefaults
[DisplayName("Post Download Action")]
[Description("When all files are downloaded from the provider to the host, perform this action. Does not apply when using the symlink downloader.")]
public TorrentFinishedAction FinishedAction { get; set; } = TorrentFinishedAction.RemoveAllTorrents;
[DisplayName("Finished Action Delay")]
[Description("When all files are downloaded from the provider to the host, wait this many minutes before performing the action above.")]
public Int32 FinishedActionDelay { get; set; } = 0;
}
public class DbSettingsDefaults

View file

@ -82,6 +82,7 @@ public class WatchFolderChecker(ILogger<WatchFolderChecker> logger, IServiceProv
DownloadClient = Settings.Get.DownloadClient.Client,
Category = Settings.Get.Watch.Default.Category,
HostDownloadAction = Settings.Get.Watch.Default.HostDownloadAction,
FinishedActionDelay = Settings.Get.Watch.Default.FinishedActionDelay,
DownloadAction = Settings.Get.Watch.Default.OnlyDownloadAvailableFiles
? TorrentDownloadAction.DownloadAvailableFiles
: TorrentDownloadAction.DownloadAll,

View file

@ -462,6 +462,7 @@ public class QBittorrent(ILogger<QBittorrent> logger, Settings settings, Authent
Category = category,
DownloadClient = Settings.Get.DownloadClient.Client,
HostDownloadAction = Settings.Get.Integrations.Default.HostDownloadAction,
FinishedActionDelay = Settings.Get.Integrations.Default.FinishedActionDelay,
DownloadAction = Settings.Get.Integrations.Default.OnlyDownloadAvailableFiles ? TorrentDownloadAction.DownloadAvailableFiles : TorrentDownloadAction.DownloadAll,
FinishedAction = TorrentFinishedAction.None,
DownloadMinSize = Settings.Get.Integrations.Default.MinFileSize,
@ -486,6 +487,7 @@ public class QBittorrent(ILogger<QBittorrent> logger, Settings settings, Authent
Category = category,
DownloadClient = Settings.Get.DownloadClient.Client,
HostDownloadAction = Settings.Get.Integrations.Default.HostDownloadAction,
FinishedActionDelay = Settings.Get.Integrations.Default.FinishedActionDelay,
DownloadAction = Settings.Get.Integrations.Default.OnlyDownloadAvailableFiles ? TorrentDownloadAction.DownloadAvailableFiles : TorrentDownloadAction.DownloadAll,
FinishedAction = TorrentFinishedAction.None,
DownloadMinSize = Settings.Get.Integrations.Default.MinFileSize,

View file

@ -348,14 +348,64 @@ public class TorrentRunner(ILogger<TorrentRunner> logger, Torrents torrents, Dow
allTorrents = await torrents.Get();
allTorrents = allTorrents.Where(m => m.Completed == null).ToList();
var completeTorrents = allTorrents.Where(m => m.Completed != null);
var torrentsToDelete = completeTorrents.Where(m => DateTimeOffset.UtcNow >= m.Completed?.AddMinutes(m.FinishedActionDelay) && m.Error == null);
if (allTorrents.Count > 0)
foreach (var torrent in torrentsToDelete)
{
if (torrent.DownloadClient == Data.Enums.DownloadClient.Symlink)
{
switch (torrent.FinishedAction)
{
case TorrentFinishedAction.RemoveAllTorrents:
Log($"Force setting FinishedAction to RemoveClient as download client is Symlink and FinishedAction is RemoveAllTorrents", torrent);
torrent.FinishedAction = TorrentFinishedAction.RemoveClient;
break;
case TorrentFinishedAction.RemoveRealDebrid:
Log($"Force setting FinishedAction to TorrentFinishedAction.None as download client is Symlink and FinishedAction is RemoveRealDebrid", torrent);
torrent.FinishedAction = TorrentFinishedAction.None;
break;
}
}
switch (torrent.FinishedAction)
{
case TorrentFinishedAction.RemoveAllTorrents:
Log($"Removing torrents from debrid provider and RDT-Client, no files", torrent);
await torrents.Delete(torrent.TorrentId, true, true, false);
break;
case TorrentFinishedAction.RemoveRealDebrid:
Log($"Removing torrents from debrid provider, no files", torrent);
await torrents.Delete(torrent.TorrentId, false, true, false);
break;
case TorrentFinishedAction.RemoveClient:
Log($"Removing torrents from client, no files", torrent);
await torrents.Delete(torrent.TorrentId, true, false, false);
break;
case TorrentFinishedAction.None:
Log($"Not removing torrents or files", torrent);
break;
default:
Log($"Invalid torrent FinishedAction {torrent.FinishedAction}", torrent);
break;
}
}
var incompleteTorrents = allTorrents.Where(m => m.Completed == null).ToList();
if (incompleteTorrents.Count > 0)
{
Log($"Processing {allTorrents.Count} torrents");
}
foreach (var torrent in allTorrents)
foreach (var torrent in incompleteTorrents)
{
try
{
@ -611,50 +661,6 @@ public class TorrentRunner(ILogger<TorrentRunner> logger, Torrents torrents, Dow
{
logger.LogError(ex.Message, "Unable to run post process: {Message}", ex.Message);
}
if (torrent.DownloadClient == Data.Enums.DownloadClient.Symlink)
{
switch (torrent.FinishedAction)
{
case TorrentFinishedAction.RemoveAllTorrents:
Log($"Force setting FinishedAction to RemoveClient as download client is Symlink and FinishedAction is RemoveAllTorrents", torrent);
torrent.FinishedAction = TorrentFinishedAction.RemoveClient;
break;
case TorrentFinishedAction.RemoveRealDebrid:
Log($"Force setting FinishedAction to TorrentFinishedAction.None as download client is Symlink and FinishedAction is RemoveRealDebrid", torrent);
torrent.FinishedAction = TorrentFinishedAction.None;
break;
}
}
switch (torrent.FinishedAction)
{
case TorrentFinishedAction.RemoveAllTorrents:
Log($"Removing torrents from debrid provider and RDT-Client, no files", torrent);
await torrents.Delete(torrent.TorrentId, true, true, false);
break;
case TorrentFinishedAction.RemoveRealDebrid:
Log($"Removing torrents from debrid provider, no files", torrent);
await torrents.Delete(torrent.TorrentId, false, true, false);
break;
case TorrentFinishedAction.RemoveClient:
Log($"Removing torrents from client, no files", torrent);
await torrents.Delete(torrent.TorrentId, true, false, false);
break;
case TorrentFinishedAction.None:
Log($"Not removing torrents or files", torrent);
break;
default:
Log($"Invalid torrent FinishedAction {torrent.FinishedAction}", torrent);
break;
}
}
else
{

View file

@ -514,6 +514,7 @@ public class Torrents(
DownloadClient = Settings.Get.DownloadClient.Client,
DownloadAction = Settings.Get.Provider.Default.OnlyDownloadAvailableFiles ? TorrentDownloadAction.DownloadAvailableFiles : TorrentDownloadAction.DownloadAll,
HostDownloadAction = Settings.Get.Provider.Default.HostDownloadAction,
FinishedActionDelay = Settings.Get.Provider.Default.FinishedActionDelay,
FinishedAction = Settings.Get.Provider.Default.FinishedAction,
DownloadMinSize = Settings.Get.Provider.Default.MinFileSize,
IncludeRegex = Settings.Get.Provider.Default.IncludeRegex,