diff --git a/server/RdtClient.Data/Enums/DownloadClient.cs b/server/RdtClient.Data/Enums/DownloadClient.cs index dd31e51..7b2c9d0 100644 --- a/server/RdtClient.Data/Enums/DownloadClient.cs +++ b/server/RdtClient.Data/Enums/DownloadClient.cs @@ -4,9 +4,6 @@ namespace RdtClient.Data.Enums; public enum DownloadClient { - [Description("Internal Downloader")] - Internal, - [Description("Bezzad Downloader")] Bezzad, diff --git a/server/RdtClient.Data/Migrations/20251007021253_Settings_Migrate_InternalDownloader2.Designer.cs b/server/RdtClient.Data/Migrations/20251007021253_Settings_Migrate_InternalDownloader2.Designer.cs new file mode 100644 index 0000000..7ffbe94 --- /dev/null +++ b/server/RdtClient.Data/Migrations/20251007021253_Settings_Migrate_InternalDownloader2.Designer.cs @@ -0,0 +1,482 @@ +// +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("20251007021253_Settings_Migrate_InternalDownloader2")] + partial class Settings_Migrate_InternalDownloader2 + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder.HasAnnotation("ProductVersion", "9.0.9"); + + 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("ClientKind") + .HasColumnType("INTEGER"); + + 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("FinishedActionDelay") + .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/20251007021253_Settings_Migrate_InternalDownloader2.cs b/server/RdtClient.Data/Migrations/20251007021253_Settings_Migrate_InternalDownloader2.cs new file mode 100644 index 0000000..7676c92 --- /dev/null +++ b/server/RdtClient.Data/Migrations/20251007021253_Settings_Migrate_InternalDownloader2.cs @@ -0,0 +1,25 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace RdtClient.Data.Migrations +{ + /// + public partial class Settings_Migrate_InternalDownloader2 : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.Sql("UPDATE Settings SET Value = 0 WHERE SettingId = 'DownloadClient:Client' AND Value = 1"); + migrationBuilder.Sql("UPDATE Settings SET Value = 1 WHERE SettingId = 'DownloadClient:Client' AND Value = 2"); + migrationBuilder.Sql("UPDATE Settings SET Value = 2 WHERE SettingId = 'DownloadClient:Client' AND Value = 3"); + migrationBuilder.Sql("UPDATE Settings SET Value = 3 WHERE SettingId = 'DownloadClient:Client' AND Value = 4"); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + + } + } +} diff --git a/server/RdtClient.Data/Migrations/DataContextModelSnapshot.cs b/server/RdtClient.Data/Migrations/DataContextModelSnapshot.cs index 8dfc00b..ba14f0f 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", "9.0.5"); + modelBuilder.HasAnnotation("ProductVersion", "9.0.9"); modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b => { diff --git a/server/RdtClient.Data/Models/Internal/DbSettings.cs b/server/RdtClient.Data/Models/Internal/DbSettings.cs index 1c24cf7..03bd0cb 100644 --- a/server/RdtClient.Data/Models/Internal/DbSettings.cs +++ b/server/RdtClient.Data/Models/Internal/DbSettings.cs @@ -97,7 +97,7 @@ public class DbSettingsDownloadClient [DisplayName("Download client")] [Description(@"Select which download client to use, see the README for the various options.")] - public DownloadClient Client { get; set; } = DownloadClient.Internal; + public DownloadClient Client { get; set; } = DownloadClient.Bezzad; [DisplayName("Download path")] [Description("Path in the docker container to download files to (i.e. /data/downloads), or a local path when using as a service.")] diff --git a/server/RdtClient.Data/RdtClient.Data.csproj b/server/RdtClient.Data/RdtClient.Data.csproj index 1df0e10..3a82264 100644 --- a/server/RdtClient.Data/RdtClient.Data.csproj +++ b/server/RdtClient.Data/RdtClient.Data.csproj @@ -8,11 +8,11 @@ - - - - - + + + + + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/server/RdtClient.Service.Test/RdtClient.Service.Test.csproj b/server/RdtClient.Service.Test/RdtClient.Service.Test.csproj index 820bb4a..3313d85 100644 --- a/server/RdtClient.Service.Test/RdtClient.Service.Test.csproj +++ b/server/RdtClient.Service.Test/RdtClient.Service.Test.csproj @@ -15,13 +15,13 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive - + - - - + + + - + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/server/RdtClient.Service/RdtClient.Service.csproj b/server/RdtClient.Service/RdtClient.Service.csproj index 21b33fa..3d042d8 100644 --- a/server/RdtClient.Service/RdtClient.Service.csproj +++ b/server/RdtClient.Service/RdtClient.Service.csproj @@ -12,20 +12,19 @@ - - - - + + + - + - - + + diff --git a/server/RdtClient.Service/Services/DownloadClient.cs b/server/RdtClient.Service/Services/DownloadClient.cs index 989c9c7..6cf2499 100644 --- a/server/RdtClient.Service/Services/DownloadClient.cs +++ b/server/RdtClient.Service/Services/DownloadClient.cs @@ -65,7 +65,6 @@ public class DownloadClient(Download download, Torrent torrent, String destinati Downloader = Type switch { - Data.Enums.DownloadClient.Internal => new InternalDownloader(download.Link, filePath), Data.Enums.DownloadClient.Bezzad => new BezzadDownloader(download.Link, filePath), Data.Enums.DownloadClient.Aria2c => new Aria2cDownloader(download.RemoteId, download.Link, filePath, downloadPath, category), Data.Enums.DownloadClient.Symlink => new SymlinkDownloader(download.Link, filePath, downloadPath, torrent.ClientKind), diff --git a/server/RdtClient.Service/Services/Downloaders/InternalDownloader.cs b/server/RdtClient.Service/Services/Downloaders/InternalDownloader.cs deleted file mode 100644 index 11e02da..0000000 --- a/server/RdtClient.Service/Services/Downloaders/InternalDownloader.cs +++ /dev/null @@ -1,173 +0,0 @@ -using Serilog; - -namespace RdtClient.Service.Services.Downloaders; - -public class InternalDownloader : IDownloader -{ - public event EventHandler? DownloadComplete; - public event EventHandler? DownloadProgress; - - private readonly DownloaderNET.Downloader _downloadService; - private readonly DownloaderNET.Settings _downloadConfiguration; - - private readonly String _filePath; - private readonly String _uri; - - private readonly ILogger _logger; - - private readonly CancellationTokenSource _cancellationToken = new(); - - private Boolean _finished; - - public InternalDownloader(String uri, String filePath) - { - _logger = Log.ForContext(); - _logger.Debug($"Instantiated new Internal Downloader for URI {uri} to filePath {filePath}"); - - _uri = uri; - _filePath = filePath; - - _downloadConfiguration = new(); - - SetSettings(); - - _downloadService = new(_uri, _filePath, _downloadConfiguration); - - _downloadService.OnLog += (message, level) => - { - if (message.Exception != null || level == 4) - { - _logger.Error(message.Exception, message.Message); - } - - switch (level) - { - case 0: - _logger.Verbose(message.Message); - break; - case 1: - _logger.Debug(message.Message); - break; - case 2: - _logger.Information(message.Message); - break; - case 3: - _logger.Warning(message.Message); - break; - } - }; - - _downloadService.OnProgress += (chunks, _) => - { - if (DownloadProgress == null) - { - return; - } - - DownloadProgress.Invoke(this, - new() - { - Speed = (Int64)chunks.Where(m => m.IsActive).Sum(m => m.Speed), - BytesDone = chunks.Sum(m => m.DownloadBytes), - BytesTotal = chunks.Sum(m => m.LengthBytes) - }); - }; - - _downloadService.OnComplete += (_, error) => - { - DownloadComplete?.Invoke(this, - new() - { - Error = error?.Message - }); - - _finished = true; - - return Task.CompletedTask; - }; - } - - public async Task Download() - { - _logger.Debug($"Starting download of {_uri}, writing to path: {_filePath}"); - - await _downloadService.Download(_cancellationToken.Token); - _ = Task.Run(StartTimer); - - return Guid.NewGuid().ToString(); - } - - public Task Cancel() - { - _logger.Debug($"Cancelling download {_uri}"); - - _cancellationToken.Cancel(false); - - return Task.CompletedTask; - } - - public Task Pause() - { - return Task.CompletedTask; - } - - public Task Resume() - { - return Task.CompletedTask; - } - - private void SetSettings() - { - var settingBufferSize = Settings.Get.DownloadClient.BufferSize; - - if (settingBufferSize <= 4096) - { - settingBufferSize = 4096; - } - - var settingDownloadParallelCount = Settings.Get.DownloadClient.ParallelCount; - - if (settingDownloadParallelCount <= 0) - { - settingDownloadParallelCount = 1; - } - - var settingDownloadMaxSpeed = Settings.Get.DownloadClient.MaxSpeed; - - if (settingDownloadMaxSpeed <= 0) - { - settingDownloadMaxSpeed = 0; - } - settingDownloadMaxSpeed /= Math.Max(TorrentRunner.ActiveDownloadClients.Count, 1); - settingDownloadMaxSpeed = settingDownloadMaxSpeed * 1024 * 1024; - - var settingDownloadTimeout = Settings.Get.DownloadClient.Timeout; - - if (settingDownloadTimeout <= 0) - { - settingDownloadTimeout = 1000; - } - - _downloadConfiguration.BufferSize = settingBufferSize; - _downloadConfiguration.LogLevel = (Int32)Settings.Get.DownloadClient.LogLevel; - _downloadConfiguration.Parallel = settingDownloadParallelCount; - _downloadConfiguration.MaximumBytesPerSecond = settingDownloadMaxSpeed; - _downloadConfiguration.Timeout = settingDownloadTimeout; - _downloadConfiguration.RetryCount = 5; - } - - private async Task StartTimer() - { - using var timer = new PeriodicTimer(TimeSpan.FromSeconds(5)); - - while (await timer.WaitForNextTickAsync()) - { - if (_finished) - { - return; - } - - SetSettings(); - } - } -} \ No newline at end of file diff --git a/server/RdtClient.Web/Controllers/SettingsController.cs b/server/RdtClient.Web/Controllers/SettingsController.cs index f98942a..7d6bbcf 100644 --- a/server/RdtClient.Web/Controllers/SettingsController.cs +++ b/server/RdtClient.Web/Controllers/SettingsController.cs @@ -103,7 +103,7 @@ public class SettingsController(Settings settings, Torrents torrents) : Controll Link = "https://34.download.real-debrid.com/speedtest/testDefault.rar", Torrent = new() { - DownloadClient = Settings.Get.DownloadClient.Client == Data.Enums.DownloadClient.Symlink ? Data.Enums.DownloadClient.Internal : Settings.Get.DownloadClient.Client, + DownloadClient = Settings.Get.DownloadClient.Client == Data.Enums.DownloadClient.Symlink ? Data.Enums.DownloadClient.Bezzad : Settings.Get.DownloadClient.Client, RdName = "testDefault.rar" } }; diff --git a/server/RdtClient.Web/RdtClient.Web.csproj b/server/RdtClient.Web/RdtClient.Web.csproj index 10c5c95..9cf16e9 100644 --- a/server/RdtClient.Web/RdtClient.Web.csproj +++ b/server/RdtClient.Web/RdtClient.Web.csproj @@ -30,15 +30,15 @@ - - - - + + + + all runtime; build; native; contentfiles; analyzers; buildtransitive - - + +