Added bit of logging to debug downloader issues, upgraded packages, cleaned up C# code.

This commit is contained in:
Roger Far 2024-04-06 13:54:58 -06:00
parent 74b988effa
commit 3b72463663
35 changed files with 407 additions and 666 deletions

View file

@ -6,12 +6,8 @@ namespace RdtClient.Data.Data;
#nullable disable
public class DataContext : IdentityDbContext
public class DataContext(DbContextOptions options) : IdentityDbContext(options)
{
public DataContext(DbContextOptions options) : base(options)
{
}
public DbSet<Download> Downloads { get; set; }
public DbSet<Setting> Settings { get; set; }
public DbSet<Torrent> Torrents { get; set; }

View file

@ -3,18 +3,11 @@ using Download = RdtClient.Data.Models.Data.Download;
namespace RdtClient.Data.Data;
public class DownloadData
public class DownloadData(DataContext dataContext)
{
private readonly DataContext _dataContext;
public DownloadData(DataContext dataContext)
{
_dataContext = dataContext;
}
public async Task<List<Download>> GetForTorrent(Guid torrentId)
{
return await _dataContext.Downloads
return await dataContext.Downloads
.AsNoTracking()
.Where(m => m.TorrentId == torrentId)
.ToListAsync();
@ -22,7 +15,7 @@ public class DownloadData
public async Task<Download?> GetById(Guid downloadId)
{
return await _dataContext.Downloads
return await dataContext.Downloads
.Include(m => m.Torrent)
.AsNoTracking()
.FirstOrDefaultAsync(m => m.DownloadId == downloadId);
@ -30,7 +23,7 @@ public class DownloadData
public async Task<Download?> Get(Guid torrentId, String path)
{
return await _dataContext.Downloads
return await dataContext.Downloads
.Include(m => m.Torrent)
.AsNoTracking()
.FirstOrDefaultAsync(m => m.TorrentId == torrentId && m.Path == path);
@ -48,9 +41,9 @@ public class DownloadData
RetryCount = 0
};
await _dataContext.Downloads.AddAsync(download);
await dataContext.Downloads.AddAsync(download);
await _dataContext.SaveChangesAsync();
await dataContext.SaveChangesAsync();
await TorrentData.VoidCache();
@ -59,7 +52,7 @@ public class DownloadData
public async Task UpdateUnrestrictedLink(Guid downloadId, String unrestrictedLink)
{
var dbDownload = await _dataContext.Downloads
var dbDownload = await dataContext.Downloads
.FirstOrDefaultAsync(m => m.DownloadId == downloadId);
if (dbDownload == null)
@ -69,14 +62,14 @@ public class DownloadData
dbDownload.Link = unrestrictedLink;
await _dataContext.SaveChangesAsync();
await dataContext.SaveChangesAsync();
await TorrentData.VoidCache();
}
public async Task UpdateDownloadStarted(Guid downloadId, DateTimeOffset? dateTime)
{
var dbDownload = await _dataContext.Downloads
var dbDownload = await dataContext.Downloads
.FirstOrDefaultAsync(m => m.DownloadId == downloadId);
if (dbDownload == null)
@ -86,14 +79,14 @@ public class DownloadData
dbDownload.DownloadStarted = dateTime;
await _dataContext.SaveChangesAsync();
await dataContext.SaveChangesAsync();
await TorrentData.VoidCache();
}
public async Task UpdateDownloadFinished(Guid downloadId, DateTimeOffset? dateTime)
{
var dbDownload = await _dataContext.Downloads
var dbDownload = await dataContext.Downloads
.FirstOrDefaultAsync(m => m.DownloadId == downloadId);
if (dbDownload == null)
@ -103,14 +96,14 @@ public class DownloadData
dbDownload.DownloadFinished = dateTime;
await _dataContext.SaveChangesAsync();
await dataContext.SaveChangesAsync();
await TorrentData.VoidCache();
}
public async Task UpdateUnpackingQueued(Guid downloadId, DateTimeOffset? dateTime)
{
var dbDownload = await _dataContext.Downloads
var dbDownload = await dataContext.Downloads
.FirstOrDefaultAsync(m => m.DownloadId == downloadId);
if (dbDownload == null)
@ -120,14 +113,14 @@ public class DownloadData
dbDownload.UnpackingQueued = dateTime;
await _dataContext.SaveChangesAsync();
await dataContext.SaveChangesAsync();
await TorrentData.VoidCache();
}
public async Task UpdateUnpackingStarted(Guid downloadId, DateTimeOffset? dateTime)
{
var dbDownload = await _dataContext.Downloads
var dbDownload = await dataContext.Downloads
.FirstOrDefaultAsync(m => m.DownloadId == downloadId);
if (dbDownload == null)
@ -137,14 +130,14 @@ public class DownloadData
dbDownload.UnpackingStarted = dateTime;
await _dataContext.SaveChangesAsync();
await dataContext.SaveChangesAsync();
await TorrentData.VoidCache();
}
public async Task UpdateUnpackingFinished(Guid downloadId, DateTimeOffset? dateTime)
{
var dbDownload = await _dataContext.Downloads
var dbDownload = await dataContext.Downloads
.FirstOrDefaultAsync(m => m.DownloadId == downloadId);
if (dbDownload == null)
@ -154,14 +147,14 @@ public class DownloadData
dbDownload.UnpackingFinished = dateTime;
await _dataContext.SaveChangesAsync();
await dataContext.SaveChangesAsync();
await TorrentData.VoidCache();
}
public async Task UpdateCompleted(Guid downloadId, DateTimeOffset? dateTime)
{
var dbDownload = await _dataContext.Downloads
var dbDownload = await dataContext.Downloads
.FirstOrDefaultAsync(m => m.DownloadId == downloadId);
if (dbDownload == null)
@ -171,14 +164,14 @@ public class DownloadData
dbDownload.Completed = dateTime;
await _dataContext.SaveChangesAsync();
await dataContext.SaveChangesAsync();
await TorrentData.VoidCache();
}
public async Task UpdateError(Guid downloadId, String? error)
{
var dbDownload = await _dataContext.Downloads
var dbDownload = await dataContext.Downloads
.FirstOrDefaultAsync(m => m.DownloadId == downloadId);
if (dbDownload == null)
@ -188,14 +181,14 @@ public class DownloadData
dbDownload.Error = error;
await _dataContext.SaveChangesAsync();
await dataContext.SaveChangesAsync();
await TorrentData.VoidCache();
}
public async Task UpdateRetryCount(Guid downloadId, Int32 retryCount)
{
var dbDownload = await _dataContext.Downloads
var dbDownload = await dataContext.Downloads
.FirstOrDefaultAsync(m => m.DownloadId == downloadId);
if (dbDownload == null)
@ -205,14 +198,14 @@ public class DownloadData
dbDownload.RetryCount = retryCount;
await _dataContext.SaveChangesAsync();
await dataContext.SaveChangesAsync();
await TorrentData.VoidCache();
}
public async Task UpdateRemoteId(Guid downloadId, String remoteId)
{
var dbDownload = await _dataContext.Downloads
var dbDownload = await dataContext.Downloads
.FirstOrDefaultAsync(m => m.DownloadId == downloadId);
if (dbDownload == null)
@ -222,25 +215,25 @@ public class DownloadData
dbDownload.RemoteId = remoteId;
await _dataContext.SaveChangesAsync();
await dataContext.SaveChangesAsync();
}
public async Task DeleteForTorrent(Guid torrentId)
{
var downloads = await _dataContext.Downloads
var downloads = await dataContext.Downloads
.Where(m => m.TorrentId == torrentId)
.ToListAsync();
_dataContext.Downloads.RemoveRange(downloads);
dataContext.Downloads.RemoveRange(downloads);
await _dataContext.SaveChangesAsync();
await dataContext.SaveChangesAsync();
await TorrentData.VoidCache();
}
public async Task Reset(Guid downloadId)
{
var dbDownload = await _dataContext.Downloads
var dbDownload = await dataContext.Downloads
.FirstOrDefaultAsync(m => m.DownloadId == downloadId);
if (dbDownload == null)
@ -260,7 +253,7 @@ public class DownloadData
dbDownload.Completed = null;
dbDownload.Error = null;
await _dataContext.SaveChangesAsync();
await dataContext.SaveChangesAsync();
await TorrentData.VoidCache();
}

View file

@ -7,11 +7,8 @@ using RdtClient.Data.Models.Internal;
namespace RdtClient.Data.Data;
public class SettingData
public class SettingData(DataContext dataContext, ILogger<SettingData> logger)
{
private readonly DataContext _dataContext;
private readonly ILogger<SettingData> _logger;
public static DbSettings Get { get; } = new DbSettings();
public static IList<SettingProperty> GetAll()
@ -19,15 +16,9 @@ public class SettingData
return GetSettings(Get, null).ToList();
}
public SettingData(DataContext dataContext, ILogger<SettingData> logger)
{
_dataContext = dataContext;
_logger = logger;
}
public async Task Update(IList<SettingProperty> settings)
{
var dbSettings = await _dataContext.Settings.ToListAsync();
var dbSettings = await dataContext.Settings.ToListAsync();
foreach (var dbSetting in dbSettings)
{
@ -39,14 +30,14 @@ public class SettingData
}
}
await _dataContext.SaveChangesAsync();
await dataContext.SaveChangesAsync();
await ResetCache();
}
public async Task Update(String settingId, Object? value)
{
var dbSetting = await _dataContext.Settings.FirstOrDefaultAsync(m => m.SettingId == settingId);
var dbSetting = await dataContext.Settings.FirstOrDefaultAsync(m => m.SettingId == settingId);
if (dbSetting == null)
{
@ -55,14 +46,14 @@ public class SettingData
dbSetting.Value = value?.ToString();
await _dataContext.SaveChangesAsync();
await dataContext.SaveChangesAsync();
await ResetCache();
}
public async Task ResetCache()
{
var settings = await _dataContext.Settings.AsNoTracking().ToListAsync();
var settings = await dataContext.Settings.AsNoTracking().ToListAsync();
if (settings.Count == 0)
{
@ -74,7 +65,7 @@ public class SettingData
public async Task Seed()
{
var dbSettings = await _dataContext.Settings.AsNoTracking().ToListAsync();
var dbSettings = await dataContext.Settings.AsNoTracking().ToListAsync();
var expectedSettings = GetSettings(Get, null).Where(m => m.Type != "Object").Select(m => new Setting
{
@ -86,16 +77,16 @@ public class SettingData
if (newSettings.Any())
{
await _dataContext.Settings.AddRangeAsync(newSettings);
await _dataContext.SaveChangesAsync();
await dataContext.Settings.AddRangeAsync(newSettings);
await dataContext.SaveChangesAsync();
}
var oldSettings = dbSettings.Where(m => expectedSettings.All(p => p.SettingId != m.SettingId)).ToList();
if (oldSettings.Any())
{
_dataContext.Settings.RemoveRange(oldSettings);
await _dataContext.SaveChangesAsync();
dataContext.Settings.RemoveRange(oldSettings);
await dataContext.SaveChangesAsync();
}
}
@ -200,7 +191,7 @@ public class SettingData
}
else
{
_logger.LogWarning($"Invalid value for setting {propertyName}: {setting.Value}");
logger.LogWarning($"Invalid value for setting {propertyName}: {setting.Value}");
}
}
}

View file

@ -4,26 +4,19 @@ using RdtClient.Data.Models.Data;
namespace RdtClient.Data.Data;
public class TorrentData
public class TorrentData(DataContext dataContext)
{
private static IList<Torrent>? _torrentCache;
private static readonly SemaphoreSlim TorrentCacheLock = new(1, 1);
private readonly DataContext _dataContext;
public TorrentData(DataContext dataContext)
{
_dataContext = dataContext;
}
public async Task<IList<Torrent>> Get()
{
await TorrentCacheLock.WaitAsync();
try
{
_torrentCache ??= await _dataContext.Torrents
_torrentCache ??= await dataContext.Torrents
.AsNoTracking()
.Include(m => m.Downloads)
.ToListAsync();
@ -38,7 +31,7 @@ public class TorrentData
public async Task<Torrent?> GetById(Guid torrentId)
{
var dbTorrent = await _dataContext.Torrents
var dbTorrent = await dataContext.Torrents
.AsNoTracking()
.Include(m => m.Downloads)
.FirstOrDefaultAsync(m => m.TorrentId == torrentId);
@ -58,7 +51,7 @@ public class TorrentData
public async Task<Torrent?> GetByHash(String hash)
{
var dbTorrent = await _dataContext.Torrents
var dbTorrent = await dataContext.Torrents
.AsNoTracking()
.Include(m => m.Downloads)
.FirstOrDefaultAsync(m => m.Hash.ToLower() == hash.ToLower());
@ -107,9 +100,9 @@ public class TorrentData
Lifetime = torrent.Lifetime
};
await _dataContext.Torrents.AddAsync(newTorrent);
await dataContext.Torrents.AddAsync(newTorrent);
await _dataContext.SaveChangesAsync();
await dataContext.SaveChangesAsync();
await VoidCache();
@ -118,7 +111,7 @@ public class TorrentData
public async Task UpdateRdData(Torrent torrent)
{
var dbTorrent = await _dataContext.Torrents.FirstOrDefaultAsync(m => m.TorrentId == torrent.TorrentId);
var dbTorrent = await dataContext.Torrents.FirstOrDefaultAsync(m => m.TorrentId == torrent.TorrentId);
if (dbTorrent == null)
{
@ -138,14 +131,14 @@ public class TorrentData
dbTorrent.RdSeeders = torrent.RdSeeders;
dbTorrent.RdFiles = torrent.RdFiles;
await _dataContext.SaveChangesAsync();
await dataContext.SaveChangesAsync();
await VoidCache();
}
public async Task Update(Torrent torrent)
{
var dbTorrent = await _dataContext.Torrents.FirstOrDefaultAsync(m => m.TorrentId == torrent.TorrentId);
var dbTorrent = await dataContext.Torrents.FirstOrDefaultAsync(m => m.TorrentId == torrent.TorrentId);
if (dbTorrent == null)
{
@ -161,14 +154,14 @@ public class TorrentData
dbTorrent.DeleteOnError = torrent.DeleteOnError;
dbTorrent.Lifetime = torrent.Lifetime;
await _dataContext.SaveChangesAsync();
await dataContext.SaveChangesAsync();
await VoidCache();
}
public async Task UpdateCategory(Guid torrentId, String? category)
{
var dbTorrent = await _dataContext.Torrents.FirstOrDefaultAsync(m => m.TorrentId == torrentId);
var dbTorrent = await dataContext.Torrents.FirstOrDefaultAsync(m => m.TorrentId == torrentId);
if (dbTorrent == null)
{
@ -177,14 +170,14 @@ public class TorrentData
dbTorrent.Category = category;
await _dataContext.SaveChangesAsync();
await dataContext.SaveChangesAsync();
await VoidCache();
}
public async Task UpdateComplete(Guid torrentId, String? error, DateTimeOffset? datetime, Boolean retry)
{
var dbTorrent = await _dataContext.Torrents.FirstOrDefaultAsync(m => m.TorrentId == torrentId);
var dbTorrent = await dataContext.Torrents.FirstOrDefaultAsync(m => m.TorrentId == torrentId);
if (dbTorrent == null)
{
@ -193,7 +186,7 @@ public class TorrentData
if (String.IsNullOrWhiteSpace(error))
{
var downloads = await _dataContext.Downloads.AsNoTracking().Where(m => m.TorrentId == torrentId).ToListAsync();
var downloads = await dataContext.Downloads.AsNoTracking().Where(m => m.TorrentId == torrentId).ToListAsync();
var downloadWithErrors = downloads.Where(m => !String.IsNullOrWhiteSpace(m.Error)).ToList();
if (downloadWithErrors.Any())
@ -214,14 +207,14 @@ public class TorrentData
dbTorrent.Completed = datetime;
dbTorrent.Error = error;
await _dataContext.SaveChangesAsync();
await dataContext.SaveChangesAsync();
await VoidCache();
}
public async Task UpdateFilesSelected(Guid torrentId, DateTimeOffset datetime)
{
var dbTorrent = await _dataContext.Torrents.FirstOrDefaultAsync(m => m.TorrentId == torrentId);
var dbTorrent = await dataContext.Torrents.FirstOrDefaultAsync(m => m.TorrentId == torrentId);
if (dbTorrent == null)
{
@ -230,14 +223,14 @@ public class TorrentData
dbTorrent.FilesSelected = datetime;
await _dataContext.SaveChangesAsync();
await dataContext.SaveChangesAsync();
await VoidCache();
}
public async Task UpdatePriority(Guid torrentId, Int32? priority)
{
var dbTorrent = await _dataContext.Torrents.FirstOrDefaultAsync(m => m.TorrentId == torrentId);
var dbTorrent = await dataContext.Torrents.FirstOrDefaultAsync(m => m.TorrentId == torrentId);
if (dbTorrent == null)
{
@ -246,14 +239,14 @@ public class TorrentData
dbTorrent.Priority = priority;
await _dataContext.SaveChangesAsync();
await dataContext.SaveChangesAsync();
await VoidCache();
}
public async Task UpdateRetry(Guid torrentId, DateTimeOffset? dateTime, Int32 retryCount)
{
var dbTorrent = await _dataContext.Torrents.FirstOrDefaultAsync(m => m.TorrentId == torrentId);
var dbTorrent = await dataContext.Torrents.FirstOrDefaultAsync(m => m.TorrentId == torrentId);
if (dbTorrent == null)
{
@ -263,14 +256,14 @@ public class TorrentData
dbTorrent.RetryCount = retryCount;
dbTorrent.Retry = dateTime;
await _dataContext.SaveChangesAsync();
await dataContext.SaveChangesAsync();
await VoidCache();
}
public async Task UpdateError(Guid torrentId, String error)
{
var dbTorrent = await _dataContext.Torrents.FirstOrDefaultAsync(m => m.TorrentId == torrentId);
var dbTorrent = await dataContext.Torrents.FirstOrDefaultAsync(m => m.TorrentId == torrentId);
if (dbTorrent == null)
{
@ -279,23 +272,23 @@ public class TorrentData
dbTorrent.Error = error;
await _dataContext.SaveChangesAsync();
await dataContext.SaveChangesAsync();
await VoidCache();
}
public async Task Delete(Guid torrentId)
{
var dbTorrent = await _dataContext.Torrents.FirstOrDefaultAsync(m => m.TorrentId == torrentId);
var dbTorrent = await dataContext.Torrents.FirstOrDefaultAsync(m => m.TorrentId == torrentId);
if (dbTorrent == null)
{
return;
}
_dataContext.Torrents.Remove(dbTorrent);
dataContext.Torrents.Remove(dbTorrent);
await _dataContext.SaveChangesAsync();
await dataContext.SaveChangesAsync();
await VoidCache();
}

View file

@ -3,17 +3,10 @@ using Microsoft.EntityFrameworkCore;
namespace RdtClient.Data.Data;
public class UserData
public class UserData(DataContext dataContext)
{
private readonly DataContext _dataContext;
public UserData(DataContext dataContext)
{
_dataContext = dataContext;
}
public async Task<IdentityUser?> GetUser()
{
return await _dataContext.Users.OrderBy(m => m.Id).FirstOrDefaultAsync();
return await dataContext.Users.OrderBy(m => m.Id).FirstOrDefaultAsync();
}
}

View file

@ -8,11 +8,11 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="8.0.1" />
<PackageReference Include="Microsoft.Data.Sqlite" Version="8.0.1" />
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="8.0.1" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite.Core" Version="8.0.1" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="8.0.1">
<PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="8.0.3" />
<PackageReference Include="Microsoft.Data.Sqlite" Version="8.0.3" />
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="8.0.3" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite.Core" Version="8.0.3" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="8.0.3">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>

View file

@ -5,18 +5,9 @@ using RdtClient.Service.Services;
namespace RdtClient.Service.BackgroundServices;
public class ProviderUpdater : BackgroundService
public class ProviderUpdater(ILogger<TaskRunner> logger, IServiceProvider serviceProvider) : BackgroundService
{
private readonly ILogger<TaskRunner> _logger;
private readonly IServiceProvider _serviceProvider;
private static DateTime _nextUpdate = DateTime.UtcNow;
public ProviderUpdater(ILogger<TaskRunner> logger, IServiceProvider serviceProvider)
{
_logger = logger;
_serviceProvider = serviceProvider;
}
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
@ -25,10 +16,10 @@ public class ProviderUpdater : BackgroundService
await Task.Delay(1000, stoppingToken);
}
using var scope = _serviceProvider.CreateScope();
using var scope = serviceProvider.CreateScope();
var torrentService = scope.ServiceProvider.GetRequiredService<Torrents>();
_logger.LogInformation("ProviderUpdater started.");
logger.LogInformation("ProviderUpdater started.");
while (!stoppingToken.IsCancellationRequested)
{
@ -38,7 +29,7 @@ public class ProviderUpdater : BackgroundService
if (_nextUpdate < DateTime.UtcNow && ((torrents.Count > 0 && !Settings.Get.Provider.AutoImport) || Settings.Get.Provider.AutoImport))
{
_logger.LogDebug($"Updating torrent info from debrid provider");
logger.LogDebug($"Updating torrent info from debrid provider");
var updateTime = Settings.Get.Provider.CheckInterval * 3;
@ -61,17 +52,17 @@ public class ProviderUpdater : BackgroundService
await torrentService.UpdateRdData();
_logger.LogDebug($"Finished updating torrent info from debrid provider, next update in {updateTime} seconds");
logger.LogDebug($"Finished updating torrent info from debrid provider, next update in {updateTime} seconds");
}
}
catch (Exception ex)
{
_logger.LogError(ex, $"Unexpected error occurred in ProviderUpdater: {ex.Message}");
logger.LogError(ex, $"Unexpected error occurred in ProviderUpdater: {ex.Message}");
}
await Task.Delay(TimeSpan.FromSeconds(1), stoppingToken);
}
_logger.LogInformation("ProviderUpdater stopped.");
logger.LogInformation("ProviderUpdater stopped.");
}
}

View file

@ -9,22 +9,15 @@ using RdtClient.Service.Services;
namespace RdtClient.Service.BackgroundServices;
public class Startup : IHostedService
public class Startup(IServiceProvider serviceProvider) : IHostedService
{
public static Boolean Ready { get; private set; }
private readonly IServiceProvider _serviceProvider;
public Startup(IServiceProvider serviceProvider)
{
_serviceProvider = serviceProvider;
}
public async Task StartAsync(CancellationToken cancellationToken)
{
var version = Assembly.GetEntryAssembly()?.GetName().Version;
using var scope = _serviceProvider.CreateScope();
using var scope = serviceProvider.CreateScope();
var logger = scope.ServiceProvider.GetRequiredService<ILogger<Startup>>();
logger.LogWarning($"Starting host on version {version}");

View file

@ -7,17 +7,8 @@ using RdtClient.Service.Services;
namespace RdtClient.Service.BackgroundServices;
public class TaskRunner : BackgroundService
public class TaskRunner(ILogger<TaskRunner> logger, IServiceProvider serviceProvider) : BackgroundService
{
private readonly ILogger<TaskRunner> _logger;
private readonly IServiceProvider _serviceProvider;
public TaskRunner(ILogger<TaskRunner> logger, IServiceProvider serviceProvider)
{
_logger = logger;
_serviceProvider = serviceProvider;
}
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
while (!Startup.Ready)
@ -25,10 +16,10 @@ public class TaskRunner : BackgroundService
await Task.Delay(1000, stoppingToken);
}
using var scope = _serviceProvider.CreateScope();
using var scope = serviceProvider.CreateScope();
var torrentRunner = scope.ServiceProvider.GetRequiredService<TorrentRunner>();
_logger.LogInformation("TaskRunner started.");
logger.LogInformation("TaskRunner started.");
await torrentRunner.Initialize();
@ -45,21 +36,21 @@ public class TaskRunner : BackgroundService
var proposedValues = entry.CurrentValues;
var databaseValues = await entry.GetDatabaseValuesAsync(stoppingToken);
_logger.LogWarning("DbUpdateConcurrencyException occurred:");
_logger.LogWarning("Proposed Values:");
_logger.LogWarning(JsonSerializer.Serialize(proposedValues));
_logger.LogWarning("Database Values:");
_logger.LogWarning(JsonSerializer.Serialize(databaseValues));
logger.LogWarning("DbUpdateConcurrencyException occurred:");
logger.LogWarning("Proposed Values:");
logger.LogWarning(JsonSerializer.Serialize(proposedValues));
logger.LogWarning("Database Values:");
logger.LogWarning(JsonSerializer.Serialize(databaseValues));
}
}
catch (Exception ex)
{
_logger.LogError(ex, $"Unexpected error occurred in TorrentDownloadManager.Tick: {ex.Message}");
logger.LogError(ex, $"Unexpected error occurred in TorrentDownloadManager.Tick: {ex.Message}");
}
await Task.Delay(TimeSpan.FromSeconds(1), stoppingToken);
}
_logger.LogInformation("TaskRunner stopped.");
logger.LogInformation("TaskRunner stopped.");
}
}

View file

@ -6,18 +6,11 @@ using Newtonsoft.Json;
namespace RdtClient.Service.BackgroundServices;
public class UpdateChecker : BackgroundService
public class UpdateChecker(ILogger<UpdateChecker> logger) : BackgroundService
{
public static String? CurrentVersion { get; private set; }
public static String? LatestVersion { get; private set; }
private readonly ILogger<UpdateChecker> _logger;
public UpdateChecker(ILogger<UpdateChecker> logger)
{
_logger = logger;
}
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
while (!Startup.Ready)
@ -36,7 +29,7 @@ public class UpdateChecker : BackgroundService
CurrentVersion = $"v{version[..version.LastIndexOf(".", StringComparison.Ordinal)]}";
_logger.LogInformation("UpdateChecker started, currently on version {CurrentVersion}.", CurrentVersion);
logger.LogInformation("UpdateChecker started, currently on version {CurrentVersion}.", CurrentVersion);
while (!stoppingToken.IsCancellationRequested)
{
@ -57,26 +50,26 @@ public class UpdateChecker : BackgroundService
if (latestRelease == null)
{
_logger.LogWarning($"Unable to find latest version on GitHub");
logger.LogWarning($"Unable to find latest version on GitHub");
return;
}
if (latestRelease != CurrentVersion)
{
_logger.LogInformation("New version found on GitHub: {latestRelease}", latestRelease);
logger.LogInformation("New version found on GitHub: {latestRelease}", latestRelease);
}
LatestVersion = latestRelease;
}
catch (Exception ex)
{
_logger.LogDebug(ex, "Unexpected error occurred while checking for updates. This error is safe to ignore.");
logger.LogDebug(ex, "Unexpected error occurred while checking for updates. This error is safe to ignore.");
}
await Task.Delay(TimeSpan.FromHours(1), stoppingToken);
}
_logger.LogInformation("UpdateChecker stopped.");
logger.LogInformation("UpdateChecker stopped.");
}
}

View file

@ -8,19 +8,10 @@ using LogLevel = Microsoft.Extensions.Logging.LogLevel;
namespace RdtClient.Service.BackgroundServices;
public class WatchFolderChecker : BackgroundService
public class WatchFolderChecker(ILogger<WatchFolderChecker> logger, IServiceProvider serviceProvider) : BackgroundService
{
private readonly ILogger<WatchFolderChecker> _logger;
private readonly IServiceProvider _serviceProvider;
private DateTime _prevCheck = DateTime.MinValue;
public WatchFolderChecker(ILogger<WatchFolderChecker> logger, IServiceProvider serviceProvider)
{
_logger = logger;
_serviceProvider = serviceProvider;
}
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
while (!Startup.Ready)
@ -28,10 +19,10 @@ public class WatchFolderChecker : BackgroundService
await Task.Delay(1000, stoppingToken);
}
using var scope = _serviceProvider.CreateScope();
using var scope = serviceProvider.CreateScope();
var torrentService = scope.ServiceProvider.GetRequiredService<Torrents>();
_logger.LogInformation("WatchFolderChecker started.");
logger.LogInformation("WatchFolderChecker started.");
while (!stoppingToken.IsCancellationRequested)
{
@ -84,7 +75,7 @@ public class WatchFolderChecker : BackgroundService
try
{
_logger.Log(LogLevel.Debug, "Processing {torrentFile}", torrentFile);
logger.Log(LogLevel.Debug, "Processing {torrentFile}", torrentFile);
var torrent = new Torrent
{
@ -125,7 +116,7 @@ public class WatchFolderChecker : BackgroundService
File.Move(torrentFile, processedPath);
_logger.Log(LogLevel.Debug, "Moved {torrentFile} to {processedPath}", torrentFile, processedPath);
logger.Log(LogLevel.Debug, "Moved {torrentFile} to {processedPath}", torrentFile, processedPath);
}
catch
{
@ -141,7 +132,7 @@ public class WatchFolderChecker : BackgroundService
}
catch (Exception ex)
{
_logger.LogError(ex, $"Unexpected error occurred in ProviderUpdater: {ex.Message}");
logger.LogError(ex, $"Unexpected error occurred in ProviderUpdater: {ex.Message}");
}
}
}

View file

@ -3,15 +3,8 @@ using Microsoft.AspNetCore.Http;
namespace RdtClient.Service.Middleware;
public class AuthorizeMiddleware
public class AuthorizeMiddleware(RequestDelegate next)
{
private readonly RequestDelegate _next;
public AuthorizeMiddleware(RequestDelegate next)
{
_next = next;
}
/// <summary>
/// Return a 403 instead of a 401, it's quirk that QBittorrent has.
/// </summary>
@ -19,7 +12,7 @@ public class AuthorizeMiddleware
/// <returns></returns>
public async Task Invoke(HttpContext context)
{
await _next(context);
await next(context);
if (context.Response.StatusCode == (Int32) HttpStatusCode.Unauthorized)
{

View file

@ -3,16 +3,9 @@ using Microsoft.AspNetCore.Http;
namespace RdtClient.Service.Middleware;
public class BaseHrefMiddleware
public class BaseHrefMiddleware(RequestDelegate next, String basePath)
{
private readonly RequestDelegate _next;
private readonly String _basePath;
public BaseHrefMiddleware(RequestDelegate next, String basePath)
{
_next = next;
_basePath = $"/{basePath.TrimStart('/').TrimEnd('/')}/";
}
private readonly String _basePath = $"/{basePath.TrimStart('/').TrimEnd('/')}/";
public async Task InvokeAsync(HttpContext context)
{
@ -24,7 +17,7 @@ public class BaseHrefMiddleware
context.Response.Body = newBody;
await _next(context);
await next(context);
context.Response.Body = originalBody;
newBody.Seek(0, SeekOrigin.Begin);

View file

@ -4,22 +4,15 @@ using System.Text;
namespace RdtClient.Service.Middleware;
public class RequestLoggingMiddleware
public class RequestLoggingMiddleware(RequestDelegate next, ILoggerFactory loggerFactory)
{
private readonly RequestDelegate _next;
private readonly ILogger _logger;
public RequestLoggingMiddleware(RequestDelegate next, ILoggerFactory loggerFactory)
{
_next = next;
_logger = loggerFactory.CreateLogger<RequestLoggingMiddleware>();
}
private readonly ILogger _logger = loggerFactory.CreateLogger<RequestLoggingMiddleware>();
public async Task Invoke(HttpContext context)
{
if (!_logger.IsEnabled(LogLevel.Debug) || (!context.Request.Path.StartsWithSegments("/api/v2") && !context.Request.Path.StartsWithSegments("/api/torrents")))
{
await _next(context);
await next(context);
return;
}
@ -43,7 +36,7 @@ public class RequestLoggingMiddleware
_logger.LogDebug(requestLog);
await _next(context);
await next(context);
}
private static async Task<String> ReadRequestBodyAsync(HttpRequest request)

View file

@ -3,24 +3,13 @@ using RdtClient.Data.Data;
namespace RdtClient.Service.Services;
public class Authentication
public class Authentication(SignInManager<IdentityUser> signInManager, UserManager<IdentityUser> userManager, UserData userData)
{
private readonly SignInManager<IdentityUser> _signInManager;
private readonly UserManager<IdentityUser> _userManager;
private readonly UserData _userData;
public Authentication(SignInManager<IdentityUser> signInManager, UserManager<IdentityUser> userManager, UserData userData)
{
_signInManager = signInManager;
_userManager = userManager;
_userData = userData;
}
public async Task<IdentityResult> Register(String userName, String password)
{
var user = new IdentityUser(userName);
var result = await _userManager.CreateAsync(user, password);
var result = await userManager.CreateAsync(user, password);
return result;
}
@ -32,41 +21,36 @@ public class Authentication
return SignInResult.Failed;
}
var result = await _signInManager.PasswordSignInAsync(userName, password, true, false);
var result = await signInManager.PasswordSignInAsync(userName, password, true, false);
return result;
}
public async Task<IdentityUser?> GetUser()
{
return await _userData.GetUser();
return await userData.GetUser();
}
public async Task Logout()
{
await _signInManager.SignOutAsync();
await signInManager.SignOutAsync();
}
public async Task<IdentityResult> Update(String newUserName, String newPassword)
{
var user = await GetUser();
if (user == null)
{
throw new Exception("No logged in user found");
}
var user = await GetUser() ?? throw new Exception("No logged in user found");
if (!String.IsNullOrWhiteSpace(newUserName))
{
user.UserName = newUserName;
}
await _userManager.UpdateAsync(user);
await userManager.UpdateAsync(user);
if (!String.IsNullOrWhiteSpace(newPassword))
{
var token = await _userManager.GeneratePasswordResetTokenAsync(user);
var result = await _userManager.ResetPasswordAsync(user, token, newPassword);
var token = await userManager.GeneratePasswordResetTokenAsync(user);
var result = await userManager.ResetPasswordAsync(user, token, newPassword);
return result;
}

View file

@ -4,12 +4,12 @@ using RdtClient.Service.Services.Downloaders;
namespace RdtClient.Service.Services;
public class DownloadClient
public class DownloadClient(Download download, Torrent torrent, String destinationPath)
{
private readonly String _destinationPath;
private readonly String _destinationPath = destinationPath;
private readonly Download _download;
private readonly Torrent _torrent;
private readonly Download _download = download;
private readonly Torrent _torrent = torrent;
public IDownloader? Downloader;
@ -23,13 +23,6 @@ public class DownloadClient
public Int64 BytesTotal { get; private set; }
public Int64 BytesDone { get; private set; }
public DownloadClient(Download download, Torrent torrent, String destinationPath)
{
_download = download;
_torrent = torrent;
_destinationPath = destinationPath;
}
public async Task<String?> Start()
{
BytesDone = 0;

View file

@ -22,6 +22,8 @@ public class Aria2cDownloader : IDownloader
public Aria2cDownloader(String? gid, String uri, String filePath, String downloadPath)
{
_logger = Log.ForContext<Aria2cDownloader>();
_logger.Debug($"Instantiated new Aria2c Downloader for URI {uri} to filePath {filePath} and downloadPath {downloadPath} and GID {gid}");
_gid = gid;
_uri = uri;
_filePath = filePath;
@ -45,13 +47,7 @@ public class Aria2cDownloader : IDownloader
public async Task<String?> Download()
{
var path = Path.GetDirectoryName(_remotePath);
if (path == null)
{
throw new Exception($"Invalid file path {_filePath}");
}
var path = Path.GetDirectoryName(_remotePath) ?? throw new Exception($"Invalid file path {_filePath}");
var fileName = Path.GetFileName(_filePath);
_logger.Debug($"Starting download of {_uri}, writing to path: {_filePath} (on aria2: {_remotePath}), fileName: {fileName}");
@ -85,10 +81,9 @@ public class Aria2cDownloader : IDownloader
}
}
_gid ??= await _aria2NetClient.AddUriAsync(new List<String>
{
_gid ??= await _aria2NetClient.AddUriAsync([
_uri
},
],
new Dictionary<String, Object>
{
{

View file

@ -22,6 +22,7 @@ public class BezzadDownloader : IDownloader
public BezzadDownloader(String uri, String filePath)
{
_logger = Log.ForContext<BezzadDownloader>();
_logger.Debug($"Instantiated new Bezzad Downloader for URI {uri} to filePath {filePath}");
_uri = uri;
_filePath = filePath;

View file

@ -22,6 +22,7 @@ public class InternalDownloader : IDownloader
public InternalDownloader(String uri, String filePath)
{
_logger = Log.ForContext<InternalDownloader>();
_logger.Debug($"Instantiated new Internal Downloader for URI {uri} to filePath {filePath}");
_uri = uri;
_filePath = filePath;

View file

@ -17,6 +17,7 @@ public class SymlinkDownloader : IDownloader
public SymlinkDownloader(String uri, String filePath)
{
_logger = Log.ForContext<SymlinkDownloader>();
_logger.Debug($"Instantiated new Symlink Downloader for URI {uri} to filePath {filePath}");
_uri = uri;
_filePath = filePath;
@ -38,13 +39,13 @@ public class SymlinkDownloader : IDownloader
_logger.Debug($"Searching {Settings.Get.DownloadClient.RcloneMountPath} for {fileName}");
// Recursively search for the fileName in the rclone mount location.
var foundFiles = Directory.GetFiles(Settings.Get.DownloadClient.RcloneMountPath, fileName, SearchOption.AllDirectories);
var foundFiles = Directory.GetFiles(Settings.Get.DownloadClient.RcloneMountPath, fileName, SearchOption.AllDirectories).ToList();
if (foundFiles.Any())
if (foundFiles.Count > 0)
{
if (foundFiles.Length > 1)
if (foundFiles.Count > 1)
{
_logger.Warning($"Found {foundFiles.Length} files named {fileName}");
_logger.Warning($"Found {foundFiles.Count} files named {fileName}");
}
// Assume first matching filename is the one we want.

View file

@ -3,92 +3,85 @@ using Download = RdtClient.Data.Models.Data.Download;
namespace RdtClient.Service.Services;
public class Downloads
public class Downloads(DownloadData downloadData)
{
private readonly DownloadData _downloadData;
public Downloads(DownloadData downloadData)
{
_downloadData = downloadData;
}
public async Task<List<Download>> GetForTorrent(Guid torrentId)
{
return await _downloadData.GetForTorrent(torrentId);
return await downloadData.GetForTorrent(torrentId);
}
public async Task<Download?> GetById(Guid downloadId)
{
return await _downloadData.GetById(downloadId);
return await downloadData.GetById(downloadId);
}
public async Task<Download?> Get(Guid torrentId, String path)
{
return await _downloadData.Get(torrentId, path);
return await downloadData.Get(torrentId, path);
}
public async Task<Download> Add(Guid torrentId, String path)
{
return await _downloadData.Add(torrentId, path);
return await downloadData.Add(torrentId, path);
}
public async Task UpdateUnrestrictedLink(Guid downloadId, String unrestrictedLink)
{
await _downloadData.UpdateUnrestrictedLink(downloadId, unrestrictedLink);
await downloadData.UpdateUnrestrictedLink(downloadId, unrestrictedLink);
}
public async Task UpdateDownloadStarted(Guid downloadId, DateTimeOffset? dateTime)
{
await _downloadData.UpdateDownloadStarted(downloadId, dateTime);
await downloadData.UpdateDownloadStarted(downloadId, dateTime);
}
public async Task UpdateDownloadFinished(Guid downloadId, DateTimeOffset? dateTime)
{
await _downloadData.UpdateDownloadFinished(downloadId, dateTime);
await downloadData.UpdateDownloadFinished(downloadId, dateTime);
}
public async Task UpdateUnpackingQueued(Guid downloadId, DateTimeOffset? dateTime)
{
await _downloadData.UpdateUnpackingQueued(downloadId, dateTime);
await downloadData.UpdateUnpackingQueued(downloadId, dateTime);
}
public async Task UpdateUnpackingStarted(Guid downloadId, DateTimeOffset? dateTime)
{
await _downloadData.UpdateUnpackingStarted(downloadId, dateTime);
await downloadData.UpdateUnpackingStarted(downloadId, dateTime);
}
public async Task UpdateUnpackingFinished(Guid downloadId, DateTimeOffset? dateTime)
{
await _downloadData.UpdateUnpackingFinished(downloadId, dateTime);
await downloadData.UpdateUnpackingFinished(downloadId, dateTime);
}
public async Task UpdateCompleted(Guid downloadId, DateTimeOffset? dateTime)
{
await _downloadData.UpdateCompleted(downloadId, dateTime);
await downloadData.UpdateCompleted(downloadId, dateTime);
}
public async Task UpdateError(Guid downloadId, String? error)
{
await _downloadData.UpdateError(downloadId, error);
await downloadData.UpdateError(downloadId, error);
}
public async Task UpdateRetryCount(Guid downloadId, Int32 retryCount)
{
await _downloadData.UpdateRetryCount(downloadId, retryCount);
await downloadData.UpdateRetryCount(downloadId, retryCount);
}
public async Task UpdateRemoteId(Guid downloadId, String remoteId)
{
await _downloadData.UpdateRemoteId(downloadId, remoteId);
await downloadData.UpdateRemoteId(downloadId, remoteId);
}
public async Task DeleteForTorrent(Guid torrentId)
{
await _downloadData.DeleteForTorrent(torrentId);
await downloadData.DeleteForTorrent(torrentId);
}
public async Task Reset(Guid downloadId)
{
await _downloadData.Reset(downloadId);
await downloadData.Reset(downloadId);
}
}

View file

@ -5,37 +5,22 @@ using RdtClient.Data.Models.QBittorrent;
namespace RdtClient.Service.Services;
public class QBittorrent
public class QBittorrent(ILogger<QBittorrent> logger, Settings settings, Authentication authentication, Torrents torrents, Downloads downloads)
{
private readonly Authentication _authentication;
private readonly ILogger<QBittorrent> _logger;
private readonly Settings _settings;
private readonly Torrents _torrents;
private readonly Downloads _downloads;
public QBittorrent(ILogger<QBittorrent> logger, Settings settings, Authentication authentication, Torrents torrents, Downloads downloads)
{
_logger = logger;
_settings = settings;
_authentication = authentication;
_torrents = torrents;
_downloads = downloads;
}
public async Task<Boolean> AuthLogin(String userName, String password)
{
_logger.LogDebug("Auth login");
logger.LogDebug("Auth login");
var login = await _authentication.Login(userName, password);
var login = await authentication.Login(userName, password);
return login.Succeeded;
}
public async Task AuthLogout()
{
_logger.LogDebug("Auth logout");
logger.LogDebug("Auth logout");
await _authentication.Logout();
await authentication.Logout();
}
public async Task<AppPreferences> AppPreferences()
@ -189,7 +174,7 @@ public class QBittorrent
preferences.SavePath = savePath;
preferences.TempPath = $"{savePath}temp{Path.DirectorySeparatorChar}";
var user = await _authentication.GetUser();
var user = await authentication.GetUser();
if (user != null)
{
@ -205,13 +190,13 @@ public class QBittorrent
var results = new List<TorrentInfo>();
var torrents = await _torrents.Get();
var torrents1 = await torrents.Get();
var prio = 0;
Decimal? downloadProgress = 0;
foreach (var torrent in torrents)
foreach (var torrent in torrents1)
{
var downloadPath = savePath;
@ -312,7 +297,7 @@ public class QBittorrent
{
var results = new List<TorrentFileItem>();
var torrent = await _torrents.GetByHash(hash);
var torrent = await torrents.GetByHash(hash);
if (torrent == null)
{
@ -336,7 +321,7 @@ public class QBittorrent
{
var savePath = Settings.AppDefaultSavePath;
var torrent = await _torrents.GetByHash(hash);
var torrent = await torrents.GetByHash(hash);
if (torrent == null)
{
@ -403,14 +388,14 @@ public class QBittorrent
{
if (deleteFiles)
{
_logger.LogDebug($"Delete {hash}, with files");
logger.LogDebug($"Delete {hash}, with files");
}
else
{
_logger.LogDebug($"Delete {hash}, no files");
logger.LogDebug($"Delete {hash}, no files");
}
var torrent = await _torrents.GetByHash(hash);
var torrent = await torrents.GetByHash(hash);
if (torrent == null)
{
@ -420,26 +405,26 @@ public class QBittorrent
switch (Settings.Get.Integrations.Default.FinishedAction)
{
case TorrentFinishedAction.RemoveAllTorrents:
_logger.LogDebug("Removing torrents from debrid provider and RDT-Client, no files");
await _torrents.Delete(torrent.TorrentId, true, true, deleteFiles);
logger.LogDebug("Removing torrents from debrid provider and RDT-Client, no files");
await torrents.Delete(torrent.TorrentId, true, true, deleteFiles);
break;
case TorrentFinishedAction.RemoveRealDebrid:
_logger.LogDebug("Removing torrents from debrid provider, no files");
await _torrents.Delete(torrent.TorrentId, false, true, deleteFiles);
logger.LogDebug("Removing torrents from debrid provider, no files");
await torrents.Delete(torrent.TorrentId, false, true, deleteFiles);
break;
case TorrentFinishedAction.RemoveClient:
_logger.LogDebug("Removing torrents from client, no files");
await _torrents.Delete(torrent.TorrentId, true, false, deleteFiles);
logger.LogDebug("Removing torrents from client, no files");
await torrents.Delete(torrent.TorrentId, true, false, deleteFiles);
break;
case TorrentFinishedAction.None:
_logger.LogDebug("Not removing torrents or files");
logger.LogDebug("Not removing torrents or files");
break;
default:
_logger.LogDebug($"Invalid torrent FinishedAction {torrent.FinishedAction}", torrent);
logger.LogDebug($"Invalid torrent FinishedAction {torrent.FinishedAction}", torrent);
break;
}
@ -447,7 +432,7 @@ public class QBittorrent
public async Task TorrentsAddMagnet(String magnetLink, String? category, Int32? priority)
{
_logger.LogDebug($"Add magnet {category}");
logger.LogDebug($"Add magnet {category}");
var torrent = new Torrent
{
@ -466,12 +451,12 @@ public class QBittorrent
Priority = priority ?? (Settings.Get.Integrations.Default.Priority > 0 ? Settings.Get.Integrations.Default.Priority : null)
};
await _torrents.UploadMagnet(magnetLink, torrent);
await torrents.UploadMagnet(magnetLink, torrent);
}
public async Task TorrentsAddFile(Byte[] fileBytes, String? category, Int32? priority)
{
_logger.LogDebug($"Add file {category}");
logger.LogDebug($"Add file {category}");
var torrent = new Torrent
{
@ -490,19 +475,19 @@ public class QBittorrent
Priority = priority ?? (Settings.Get.Integrations.Default.Priority > 0 ? Settings.Get.Integrations.Default.Priority : null)
};
await _torrents.UploadFile(fileBytes, torrent);
await torrents.UploadFile(fileBytes, torrent);
}
public async Task TorrentsSetCategory(String hash, String? category)
{
await _torrents.UpdateCategory(hash, category);
await torrents.UpdateCategory(hash, category);
}
public async Task<IDictionary<String, TorrentCategory>> TorrentsCategories()
{
var torrents = await _torrents.Get();
var torrents1 = await torrents.Get();
var torrentsToGroup = torrents.Where(m => !String.IsNullOrWhiteSpace(m.Category))
var torrentsToGroup = torrents1.Where(m => !String.IsNullOrWhiteSpace(m.Category))
.Select(m => m.Category!.ToLower())
.ToList();
@ -554,7 +539,7 @@ public class QBittorrent
categoriesSetting = String.Join(",", categoryList);
await _settings.Update("General:Categories", categoriesSetting);
await settings.Update("General:Categories", categoriesSetting);
}
public async Task CategoryRemove(String? category)
@ -578,26 +563,26 @@ public class QBittorrent
categoriesSetting = String.Join(",", categoryList);
await _settings.Update("General:Categories", categoriesSetting);
await settings.Update("General:Categories", categoriesSetting);
}
public async Task TorrentsTopPrio(String hash)
{
await _torrents.UpdatePriority(hash, 1);
await torrents.UpdatePriority(hash, 1);
}
public async Task TorrentPause(String hash)
{
var torrent = await _torrents.GetByHash(hash);
var torrent = await torrents.GetByHash(hash);
if (torrent == null)
{
return;
}
var downloads = await _downloads.GetForTorrent(torrent.TorrentId);
var downloads1 = await downloads.GetForTorrent(torrent.TorrentId);
foreach (var download in downloads)
foreach (var download in downloads1)
{
if (TorrentRunner.ActiveDownloadClients.TryGetValue(download.DownloadId, out var downloadClient))
{
@ -608,16 +593,16 @@ public class QBittorrent
public async Task TorrentResume(String hash)
{
var torrent = await _torrents.GetByHash(hash);
var torrent = await torrents.GetByHash(hash);
if (torrent == null)
{
return;
}
var downloads = await _downloads.GetForTorrent(torrent.TorrentId);
var downloads1 = await downloads.GetForTorrent(torrent.TorrentId);
foreach (var download in downloads)
foreach (var download in downloads1)
{
if (TorrentRunner.ActiveDownloadClients.TryGetValue(download.DownloadId, out var downloadClient))
{

View file

@ -2,31 +2,22 @@
namespace RdtClient.Service.Services;
public class RemoteService
public class RemoteService(IHubContext<RdtHub> hub, Torrents torrents)
{
private readonly IHubContext<RdtHub> _hub;
private readonly Torrents _torrents;
public RemoteService(IHubContext<RdtHub> hub, Torrents torrents)
{
_hub = hub;
_torrents = torrents;
}
public async Task Update()
{
var torrents = await _torrents.Get();
var torrents1 = await torrents.Get();
// Prevent infinite recursion when serializing
foreach (var file in torrents.SelectMany(torrent => torrent.Downloads))
foreach (var file in torrents1.SelectMany(torrent => torrent.Downloads))
{
file.Torrent = null;
}
await _hub.Clients.All.SendCoreAsync("update",
await hub.Clients.All.SendCoreAsync("update",
new Object[]
{
torrents
torrents1
});
}
}

View file

@ -6,17 +6,10 @@ using Serilog.Events;
namespace RdtClient.Service.Services;
public class Settings
public class Settings(SettingData settingData)
{
public static readonly LoggingLevelSwitch LoggingLevelSwitch = new(LogEventLevel.Debug);
private readonly SettingData _settingData;
public Settings(SettingData settingData)
{
_settingData = settingData;
}
public static DbSettings Get => SettingData.Get;
public static String AppDefaultSavePath
@ -36,22 +29,22 @@ public class Settings
public async Task Update(IList<SettingProperty> settings)
{
await _settingData.Update(settings);
await settingData.Update(settings);
}
public async Task Update(String settingId, Object? value)
{
await _settingData.Update(settingId, value);
await settingData.Update(settingId, value);
}
public async Task Seed()
{
await _settingData.Seed();
await settingData.Seed();
}
public async Task ResetCache()
{
await _settingData.ResetCache();
await settingData.ResetCache();
LoggingLevelSwitch.MinimumLevel = Settings.Get.General.LogLevel switch
{

View file

@ -9,17 +9,8 @@ using Torrent = RdtClient.Data.Models.Data.Torrent;
namespace RdtClient.Service.Services.TorrentClients;
public class AllDebridTorrentClient : ITorrentClient
public class AllDebridTorrentClient(ILogger<AllDebridTorrentClient> logger, IHttpClientFactory httpClientFactory) : ITorrentClient
{
private readonly ILogger<AllDebridTorrentClient> _logger;
private readonly IHttpClientFactory _httpClientFactory;
public AllDebridTorrentClient(ILogger<AllDebridTorrentClient> logger, IHttpClientFactory httpClientFactory)
{
_logger = logger;
_httpClientFactory = httpClientFactory;
}
private AllDebridNETClient GetClient()
{
try
@ -31,7 +22,7 @@ public class AllDebridTorrentClient : ITorrentClient
throw new Exception("All-Debrid API Key not set in the settings");
}
var httpClient = _httpClientFactory.CreateClient();
var httpClient = httpClientFactory.CreateClient();
httpClient.Timeout = TimeSpan.FromSeconds(10);
var allDebridNetClient = new AllDebridNETClient("RealDebridClient", apiKey, httpClient);
@ -40,13 +31,13 @@ public class AllDebridTorrentClient : ITorrentClient
}
catch (TaskCanceledException ex) when (ex.InnerException is TimeoutException)
{
_logger.LogError(ex, $"The connection to AllDebrid has timed out: {ex.Message}");
logger.LogError(ex, $"The connection to AllDebrid has timed out: {ex.Message}");
throw;
}
catch (TaskCanceledException ex)
{
_logger.LogError(ex, $"The connection to AllDebrid has timed out: {ex.Message}");
logger.LogError(ex, $"The connection to AllDebrid has timed out: {ex.Message}");
throw;
}
@ -375,6 +366,6 @@ public class AllDebridTorrentClient : ITorrentClient
message = $"{message} {torrent.ToLog()}";
}
_logger.LogDebug(message);
logger.LogDebug(message);
}
}

View file

@ -8,17 +8,8 @@ using Torrent = RdtClient.Data.Models.Data.Torrent;
namespace RdtClient.Service.Services.TorrentClients;
public class PremiumizeTorrentClient : ITorrentClient
public class PremiumizeTorrentClient(ILogger<PremiumizeTorrentClient> logger, IHttpClientFactory httpClientFactory) : ITorrentClient
{
private readonly ILogger<PremiumizeTorrentClient> _logger;
private readonly IHttpClientFactory _httpClientFactory;
public PremiumizeTorrentClient(ILogger<PremiumizeTorrentClient> logger, IHttpClientFactory httpClientFactory)
{
_logger = logger;
_httpClientFactory = httpClientFactory;
}
private PremiumizeNETClient GetClient()
{
try
@ -30,7 +21,7 @@ public class PremiumizeTorrentClient : ITorrentClient
throw new Exception("Premiumize API Key not set in the settings");
}
var httpClient = _httpClientFactory.CreateClient();
var httpClient = httpClientFactory.CreateClient();
httpClient.Timeout = TimeSpan.FromSeconds(10);
var premiumizeNetClient = new PremiumizeNETClient(apiKey, httpClient);
@ -39,13 +30,13 @@ public class PremiumizeTorrentClient : ITorrentClient
}
catch (TaskCanceledException ex) when (ex.InnerException is TimeoutException)
{
_logger.LogError(ex, $"The connection to Premiumize has timed out: {ex.Message}");
logger.LogError(ex, $"The connection to Premiumize has timed out: {ex.Message}");
throw;
}
catch (TaskCanceledException ex)
{
_logger.LogError(ex, $"The connection to Premiumize has timed out: {ex.Message}");
logger.LogError(ex, $"The connection to Premiumize has timed out: {ex.Message}");
throw;
}
@ -329,6 +320,6 @@ public class PremiumizeTorrentClient : ITorrentClient
message = $"{message} {torrent.ToLog()}";
}
_logger.LogDebug(message);
logger.LogDebug(message);
}
}

View file

@ -8,18 +8,10 @@ using RdtClient.Service.Helpers;
namespace RdtClient.Service.Services.TorrentClients;
public class RealDebridTorrentClient : ITorrentClient
public class RealDebridTorrentClient(ILogger<RealDebridTorrentClient> logger, IHttpClientFactory httpClientFactory) : ITorrentClient
{
private readonly ILogger<RealDebridTorrentClient> _logger;
private readonly IHttpClientFactory _httpClientFactory;
private TimeSpan? _offset;
public RealDebridTorrentClient(ILogger<RealDebridTorrentClient> logger, IHttpClientFactory httpClientFactory)
{
_logger = logger;
_httpClientFactory = httpClientFactory;
}
private RdNetClient GetClient()
{
try
@ -31,7 +23,7 @@ public class RealDebridTorrentClient : ITorrentClient
throw new Exception("Real-Debrid API Key not set in the settings");
}
var httpClient = _httpClientFactory.CreateClient();
var httpClient = httpClientFactory.CreateClient();
httpClient.Timeout = TimeSpan.FromSeconds(Settings.Get.Provider.Timeout);
var rdtNetClient = new RdNetClient(null, httpClient, 5);
@ -50,20 +42,20 @@ public class RealDebridTorrentClient : ITorrentClient
{
foreach (var inner in ae.InnerExceptions)
{
_logger.LogError(inner, $"The connection to RealDebrid has failed: {inner.Message}");
logger.LogError(inner, $"The connection to RealDebrid 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 RealDebrid 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 RealDebrid has timed out: {ex.Message}");
throw;
}
@ -451,6 +443,6 @@ public class RealDebridTorrentClient : ITorrentClient
message = $"{message} {torrent.ToLog()}";
}
_logger.LogDebug(message);
logger.LogDebug(message);
}
}

View file

@ -12,29 +12,15 @@ using RdtClient.Service.Services.Downloaders;
namespace RdtClient.Service.Services;
public class TorrentRunner
public class TorrentRunner(ILogger<TorrentRunner> logger, Torrents torrents, Downloads downloads, RemoteService remoteService)
{
public static readonly ConcurrentDictionary<Guid, DownloadClient> ActiveDownloadClients = new();
public static readonly ConcurrentDictionary<Guid, UnpackClient> ActiveUnpackClients = new();
private readonly ILogger<TorrentRunner> _logger;
private readonly Torrents _torrents;
private readonly Downloads _downloads;
private readonly RemoteService _remoteService;
private readonly HttpClient _httpClient;
public TorrentRunner(ILogger<TorrentRunner> logger, Torrents torrents, Downloads downloads, RemoteService remoteService)
private readonly HttpClient _httpClient = new()
{
_logger = logger;
_torrents = torrents;
_downloads = downloads;
_remoteService = remoteService;
_httpClient = new HttpClient
{
Timeout = TimeSpan.FromSeconds(10)
};
}
Timeout = TimeSpan.FromSeconds(10)
};
public async Task Initialize()
{
@ -51,13 +37,13 @@ public class TorrentRunner
}
// When starting up reset any pending downloads or unpackings so that they are restarted.
var torrents = await _torrents.Get();
var torrents1 = await torrents.Get();
torrents = torrents.Where(m => m.Completed == null).ToList();
torrents1 = torrents1.Where(m => m.Completed == null).ToList();
Log($"Found {torrents.Count} not completed torrents");
Log($"Found {torrents1.Count} not completed torrents");
foreach (var torrent in torrents)
foreach (var torrent in torrents1)
{
foreach (var download in torrent.Downloads)
{
@ -65,14 +51,14 @@ public class TorrentRunner
{
Log("Resetting download status", download, torrent);
await _downloads.UpdateDownloadStarted(download.DownloadId, null);
await downloads.UpdateDownloadStarted(download.DownloadId, null);
}
if (download.UnpackingQueued != null && download.UnpackingStarted != null && download.UnpackingFinished == null && download.Error == null)
{
Log("Resetting unpack status", download, torrent);
await _downloads.UpdateUnpackingStarted(download.DownloadId, null);
await downloads.UpdateUnpackingStarted(download.DownloadId, null);
}
}
}
@ -103,7 +89,7 @@ public class TorrentRunner
var settingDownloadPath = Settings.Get.DownloadClient.DownloadPath;
if (String.IsNullOrWhiteSpace(settingDownloadPath))
{
_logger.LogError("No DownloadPath set in settings");
logger.LogError("No DownloadPath set in settings");
return;
}
@ -145,7 +131,7 @@ public class TorrentRunner
foreach (var (downloadId, downloadClient) in completedActiveDownloads)
{
var download = await _downloads.GetById(downloadId);
var download = await downloads.GetById(downloadId);
if (download == null)
{
@ -168,23 +154,23 @@ public class TorrentRunner
{
Log($"Retrying download", download, download.Torrent);
await _downloads.Reset(downloadId);
await _downloads.UpdateRetryCount(downloadId, download.RetryCount + 1);
await downloads.Reset(downloadId);
await downloads.UpdateRetryCount(downloadId, download.RetryCount + 1);
}
else
{
Log($"Not retrying download", download, download.Torrent);
await _downloads.UpdateError(downloadId, downloadClient.Error);
await _downloads.UpdateCompleted(downloadId, DateTimeOffset.UtcNow);
await downloads.UpdateError(downloadId, downloadClient.Error);
await downloads.UpdateCompleted(downloadId, DateTimeOffset.UtcNow);
}
}
else
{
Log($"Download finished successfully", download, download.Torrent);
await _downloads.UpdateDownloadFinished(downloadId, DateTimeOffset.UtcNow);
await _downloads.UpdateUnpackingQueued(downloadId, DateTimeOffset.UtcNow);
await downloads.UpdateDownloadFinished(downloadId, DateTimeOffset.UtcNow);
await downloads.UpdateUnpackingQueued(downloadId, DateTimeOffset.UtcNow);
}
ActiveDownloadClients.TryRemove(downloadId, out _);
@ -202,7 +188,7 @@ public class TorrentRunner
foreach (var (downloadId, unpackClient) in completedUnpacks)
{
var download = await _downloads.GetById(downloadId);
var download = await downloads.GetById(downloadId);
if (download == null)
{
@ -217,15 +203,15 @@ public class TorrentRunner
{
Log($"Unpack reported an error: {unpackClient.Error}", download, download.Torrent);
await _downloads.UpdateError(downloadId, unpackClient.Error);
await _downloads.UpdateCompleted(downloadId, DateTimeOffset.UtcNow);
await downloads.UpdateError(downloadId, unpackClient.Error);
await downloads.UpdateCompleted(downloadId, DateTimeOffset.UtcNow);
}
else
{
Log($"Unpack finished successfully", download, download.Torrent);
await _downloads.UpdateUnpackingFinished(downloadId, DateTimeOffset.UtcNow);
await _downloads.UpdateCompleted(downloadId, DateTimeOffset.UtcNow);
await downloads.UpdateUnpackingFinished(downloadId, DateTimeOffset.UtcNow);
await downloads.UpdateCompleted(downloadId, DateTimeOffset.UtcNow);
}
ActiveUnpackClients.TryRemove(downloadId, out _);
@ -234,12 +220,12 @@ public class TorrentRunner
}
}
var torrents = await _torrents.Get();
var torrents1 = await torrents.Get();
// Check for deleted torrents that are stuck in the ActiveDownloads or ActiveUnpacks
foreach (var activeDownload in ActiveDownloadClients)
{
var download = torrents.SelectMany(m => m.Downloads).FirstOrDefault(m => m.DownloadId == activeDownload.Key);
var download = torrents1.SelectMany(m => m.Downloads).FirstOrDefault(m => m.DownloadId == activeDownload.Key);
if (download == null)
{
@ -251,7 +237,7 @@ public class TorrentRunner
foreach (var activeUnpacks in ActiveUnpackClients)
{
var download = torrents.SelectMany(m => m.Downloads).FirstOrDefault(m => m.DownloadId == activeUnpacks.Key);
var download = torrents1.SelectMany(m => m.Downloads).FirstOrDefault(m => m.DownloadId == activeUnpacks.Key);
if (download == null)
{
@ -262,7 +248,7 @@ public class TorrentRunner
}
// Process torrent retries
foreach (var torrent in torrents.Where(m => m.Retry != null))
foreach (var torrent in torrents1.Where(m => m.Retry != null))
{
try
{
@ -270,22 +256,22 @@ public class TorrentRunner
if (torrent.RetryCount > torrent.TorrentRetryAttempts)
{
await _torrents.UpdateRetry(torrent.TorrentId, null, torrent.RetryCount);
await torrents.UpdateRetry(torrent.TorrentId, null, torrent.RetryCount);
Log($"Torrent reach max retry count");
continue;
}
await _torrents.RetryTorrent(torrent.TorrentId, torrent.RetryCount);
await torrents.RetryTorrent(torrent.TorrentId, torrent.RetryCount);
}
catch (Exception ex)
{
await _torrents.UpdateRetry(torrent.TorrentId, null, torrent.RetryCount);
await _torrents.UpdateError(torrent.TorrentId, ex.Message);
await torrents.UpdateRetry(torrent.TorrentId, null, torrent.RetryCount);
await torrents.UpdateError(torrent.TorrentId, ex.Message);
}
}
// Process torrent errors
foreach (var torrent in torrents.Where(m => m.Error != null && m.DeleteOnError > 0))
foreach (var torrent in torrents1.Where(m => m.Error != null && m.DeleteOnError > 0))
{
if (torrent.Completed == null)
{
@ -299,11 +285,11 @@ public class TorrentRunner
Log($"Removing torrent because it has been {torrent.DeleteOnError} minutes in the error state", torrent);
await _torrents.Delete(torrent.TorrentId, true, true, true);
await torrents.Delete(torrent.TorrentId, true, true, true);
}
// Process torrent lifetime
foreach (var torrent in torrents.Where(m => m.Downloads.Count == 0 && m.Completed == null && m.Lifetime > 0))
foreach (var torrent in torrents1.Where(m => m.Downloads.Count == 0 && m.Completed == null && m.Lifetime > 0))
{
if (torrent.Added.AddMinutes(torrent.Lifetime) > DateTime.UtcNow)
{
@ -312,20 +298,20 @@ public class TorrentRunner
Log($"Torrent has reached its {torrent.Lifetime} minutes lifetime, marking as error", torrent);
await _torrents.UpdateRetry(torrent.TorrentId, null, torrent.TorrentRetryAttempts);
await _torrents.UpdateComplete(torrent.TorrentId, $"Torrent lifetime of {torrent.Lifetime} minutes reached", DateTimeOffset.UtcNow, false);
await torrents.UpdateRetry(torrent.TorrentId, null, torrent.TorrentRetryAttempts);
await torrents.UpdateComplete(torrent.TorrentId, $"Torrent lifetime of {torrent.Lifetime} minutes reached", DateTimeOffset.UtcNow, false);
}
torrents = await _torrents.Get();
torrents1 = await torrents.Get();
torrents = torrents.Where(m => m.Completed == null).ToList();
torrents1 = torrents1.Where(m => m.Completed == null).ToList();
if (torrents.Count > 0)
if (torrents1.Count > 0)
{
Log($"Processing {torrents.Count} torrents");
Log($"Processing {torrents1.Count} torrents");
}
foreach (var torrent in torrents)
foreach (var torrent in torrents1)
{
try
{
@ -359,15 +345,15 @@ public class TorrentRunner
{
Log($"Unrestricting links", download, torrent);
var downloadLink = await _torrents.UnrestrictLink(download.DownloadId);
var downloadLink = await torrents.UnrestrictLink(download.DownloadId);
download.Link = downloadLink;
}
catch (Exception ex)
{
_logger.LogError(ex, "Cannot unrestrict link: {ex.Message}", ex.Message);
logger.LogError(ex, "Cannot unrestrict link: {ex.Message}", ex.Message);
await _downloads.UpdateError(download.DownloadId, ex.Message);
await _downloads.UpdateCompleted(download.DownloadId, DateTimeOffset.UtcNow);
await downloads.UpdateError(download.DownloadId, ex.Message);
await downloads.UpdateCompleted(download.DownloadId, DateTimeOffset.UtcNow);
download.Error = ex.Message;
download.Completed = DateTimeOffset.UtcNow;
@ -399,12 +385,12 @@ public class TorrentRunner
Log($"Received ID {remoteId}", download, torrent);
download.RemoteId = remoteId;
await _downloads.UpdateRemoteId(download.DownloadId, remoteId);
await downloads.UpdateRemoteId(download.DownloadId, remoteId);
Log($"Marking download as started", download, torrent);
download.DownloadStarted = DateTime.UtcNow;
await _downloads.UpdateDownloadStarted(download.DownloadId, download.DownloadStarted);
await downloads.UpdateDownloadStarted(download.DownloadId, download.DownloadStarted);
ActiveDownloadClients.TryAdd(download.DownloadId, downloadClient);
}
@ -423,8 +409,8 @@ public class TorrentRunner
{
Log($"No download link found", download, torrent);
await _downloads.UpdateError(download.DownloadId, "Download Link cannot be null");
await _downloads.UpdateCompleted(download.DownloadId, DateTimeOffset.UtcNow);
await downloads.UpdateError(download.DownloadId, "Download Link cannot be null");
await downloads.UpdateCompleted(download.DownloadId, DateTimeOffset.UtcNow);
continue;
}
@ -447,9 +433,9 @@ public class TorrentRunner
download.UnpackingFinished = DateTimeOffset.UtcNow;
download.Completed = DateTimeOffset.UtcNow;
await _downloads.UpdateUnpackingStarted(download.DownloadId, download.UnpackingStarted);
await _downloads.UpdateUnpackingFinished(download.DownloadId, download.UnpackingFinished);
await _downloads.UpdateCompleted(download.DownloadId, download.Completed);
await downloads.UpdateUnpackingStarted(download.DownloadId, download.UnpackingStarted);
await downloads.UpdateUnpackingFinished(download.DownloadId, download.UnpackingFinished);
await downloads.UpdateCompleted(download.DownloadId, download.Completed);
continue;
}
@ -470,7 +456,7 @@ public class TorrentRunner
}
download.UnpackingStarted = DateTimeOffset.UtcNow;
await _downloads.UpdateUnpackingStarted(download.DownloadId, download.UnpackingStarted);
await downloads.UpdateUnpackingStarted(download.DownloadId, download.UnpackingStarted);
var downloadPath = settingDownloadPath;
@ -502,7 +488,7 @@ public class TorrentRunner
Log($"Received RealDebrid error: {torrent.RdStatusRaw}, not processing further", torrent);
await _torrents.UpdateComplete(torrent.TorrentId, $"Received RealDebrid error: {torrent.RdStatusRaw}.", DateTimeOffset.UtcNow, true);
await torrents.UpdateComplete(torrent.TorrentId, $"Received RealDebrid error: {torrent.RdStatusRaw}.", DateTimeOffset.UtcNow, true);
continue;
}
@ -514,9 +500,9 @@ public class TorrentRunner
{
Log($"Selecting files", torrent);
await _torrents.SelectFiles(torrent.TorrentId);
await torrents.SelectFiles(torrent.TorrentId);
await _torrents.UpdateFilesSelected(torrent.TorrentId, DateTime.UtcNow);
await torrents.UpdateFilesSelected(torrent.TorrentId, DateTime.UtcNow);
}
// Debrid provider finished downloading the torrent, process the file to host.
@ -529,7 +515,7 @@ public class TorrentRunner
if (torrent.HostDownloadAction == TorrentHostDownloadAction.DownloadAll)
{
await _torrents.CreateDownloads(torrent.TorrentId);
await torrents.CreateDownloads(torrent.TorrentId);
}
}
}
@ -554,15 +540,15 @@ public class TorrentRunner
{
Log($"All downloads complete, marking torrent as complete", torrent);
await _torrents.UpdateComplete(torrent.TorrentId, null, DateTimeOffset.UtcNow, true);
await torrents.UpdateComplete(torrent.TorrentId, null, DateTimeOffset.UtcNow, true);
try
{
await _torrents.RunTorrentComplete(torrent.TorrentId);
await torrents.RunTorrentComplete(torrent.TorrentId);
}
catch (Exception ex)
{
_logger.LogError(ex.Message, "Unable to run post process: {Message}", ex.Message);
logger.LogError(ex.Message, "Unable to run post process: {Message}", ex.Message);
}
if (torrent.DownloadClient == Data.Enums.DownloadClient.Symlink)
@ -586,17 +572,17 @@ public class TorrentRunner
{
case TorrentFinishedAction.RemoveAllTorrents:
Log($"Removing torrents from debrid provider and RDT-Client, no files", torrent);
await _torrents.Delete(torrent.TorrentId, true, true, false);
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);
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);
await torrents.Delete(torrent.TorrentId, true, false, false);
break;
case TorrentFinishedAction.None:
@ -617,12 +603,12 @@ public class TorrentRunner
}
catch (Exception ex)
{
_logger.LogError(ex.Message, "Torrent processing result in an unexpected exception: {Message}", ex.Message);
await _torrents.UpdateComplete(torrent.TorrentId, ex.Message, DateTimeOffset.UtcNow, true);
logger.LogError(ex.Message, "Torrent processing result in an unexpected exception: {Message}", ex.Message);
await torrents.UpdateComplete(torrent.TorrentId, ex.Message, DateTimeOffset.UtcNow, true);
}
}
await _remoteService.Update();
await remoteService.Update();
sw.Stop();
@ -644,7 +630,7 @@ public class TorrentRunner
message = $"{message} {torrent.ToLog()}";
}
_logger.LogDebug(message);
logger.LogDebug(message);
}
private void Log(String message, Torrent? torrent = null)
@ -654,7 +640,7 @@ public class TorrentRunner
message = $"{message} {torrent.ToLog()}";
}
_logger.LogDebug(message);
logger.LogDebug(message);
}
private void LogError(String message, Download? download, Torrent? torrent)
@ -669,6 +655,6 @@ public class TorrentRunner
message = $"{message} {torrent.ToLog()}";
}
_logger.LogError(message);
logger.LogError(message);
}
}

View file

@ -16,27 +16,25 @@ using Torrent = RdtClient.Data.Models.Data.Torrent;
namespace RdtClient.Service.Services;
public class Torrents
public class Torrents(
ILogger<Torrents> logger,
TorrentData torrentData,
Downloads downloads,
AllDebridTorrentClient allDebridTorrentClient,
PremiumizeTorrentClient premiumizeTorrentClient,
RealDebridTorrentClient realDebridTorrentClient)
{
private static readonly SemaphoreSlim RealDebridUpdateLock = new(1, 1);
private readonly ILogger<Torrents> _logger;
private readonly TorrentData _torrentData;
private readonly Downloads _downloads;
private readonly AllDebridTorrentClient _allDebridTorrentClient;
private readonly PremiumizeTorrentClient _premiumizeTorrentClient;
private readonly RealDebridTorrentClient _realDebridTorrentClient;
private ITorrentClient TorrentClient
{
get
{
return Settings.Get.Provider.Provider switch
{
Provider.Premiumize => _premiumizeTorrentClient,
Provider.RealDebrid => _realDebridTorrentClient,
Provider.AllDebrid => _allDebridTorrentClient,
Provider.Premiumize => premiumizeTorrentClient,
Provider.RealDebrid => realDebridTorrentClient,
Provider.AllDebrid => allDebridTorrentClient,
_ => throw new Exception("Invalid Provider")
};
}
@ -44,24 +42,9 @@ public class Torrents
private static readonly SemaphoreSlim TorrentResetLock = new(1, 1);
public Torrents(ILogger<Torrents> logger,
TorrentData torrentData,
Downloads downloads,
AllDebridTorrentClient allDebridTorrentClient,
PremiumizeTorrentClient premiumizeTorrentClient,
RealDebridTorrentClient realDebridTorrentClient)
{
_logger = logger;
_torrentData = torrentData;
_downloads = downloads;
_allDebridTorrentClient = allDebridTorrentClient;
_premiumizeTorrentClient = premiumizeTorrentClient;
_realDebridTorrentClient = realDebridTorrentClient;
}
public async Task<IList<Torrent>> Get()
{
var torrents = await _torrentData.Get();
var torrents = await torrentData.Get();
foreach (var torrent in torrents)
{
@ -87,7 +70,7 @@ public class Torrents
public async Task<Torrent?> GetByHash(String hash)
{
var torrent = await _torrentData.GetByHash(hash);
var torrent = await torrentData.GetByHash(hash);
if (torrent != null)
{
@ -99,7 +82,7 @@ public class Torrents
public async Task UpdateCategory(String hash, String? category)
{
var torrent = await _torrentData.GetByHash(hash);
var torrent = await torrentData.GetByHash(hash);
if (torrent == null)
{
@ -108,7 +91,7 @@ public class Torrents
Log($"Update category to {category}", torrent);
await _torrentData.UpdateCategory(torrent.TorrentId, category);
await torrentData.UpdateCategory(torrent.TorrentId, category);
}
public async Task<Torrent> UploadMagnet(String magnetLink, Torrent torrent)
@ -121,7 +104,7 @@ public class Torrents
}
catch (Exception ex)
{
_logger.LogError(ex, "{ex.Message}, trying to parse {magnetLink}", ex.Message, magnetLink);
logger.LogError(ex, "{ex.Message}, trying to parse {magnetLink}", ex.Message, magnetLink);
throw new Exception($"{ex.Message}, trying to parse {magnetLink}");
}
@ -153,7 +136,7 @@ public class Torrents
}
catch (Exception ex)
{
_logger.LogError(ex, $"Unable to create torrent blackhole directory: {Settings.Get.General.CopyAddedTorrents}: {ex.Message}");
logger.LogError(ex, $"Unable to create torrent blackhole directory: {Settings.Get.General.CopyAddedTorrents}: {ex.Message}");
}
}
@ -165,7 +148,7 @@ public class Torrents
MonoTorrent.Torrent monoTorrent;
var fileAsBase64 = Convert.ToBase64String(bytes);
_logger.LogDebug($"bytes {bytes}");
logger.LogDebug($"bytes {bytes}");
try
{
@ -204,7 +187,7 @@ public class Torrents
}
catch (Exception ex)
{
_logger.LogError(ex, $"Unable to create torrent blackhole directory: {Settings.Get.General.CopyAddedTorrents}: {ex.Message}");
logger.LogError(ex, $"Unable to create torrent blackhole directory: {Settings.Get.General.CopyAddedTorrents}: {ex.Message}");
}
}
@ -249,11 +232,11 @@ public class Torrents
foreach (var downloadLink in downloadLinks)
{
// Make sure downloads don't get added multiple times
var downloadExists = await _downloads.Get(torrent.TorrentId, downloadLink);
var downloadExists = await downloads.Get(torrent.TorrentId, downloadLink);
if (downloadExists == null && !String.IsNullOrWhiteSpace(downloadLink))
{
await _downloads.Add(torrent.TorrentId, downloadLink);
await downloads.Add(torrent.TorrentId, downloadLink);
}
}
}
@ -314,8 +297,8 @@ public class Torrents
{
Log($"Deleting RdtClient data", torrent);
await _downloads.DeleteForTorrent(torrent.TorrentId);
await _torrentData.Delete(torrentId);
await downloads.DeleteForTorrent(torrent.TorrentId);
await torrentData.Delete(torrentId);
}
if (deleteRdTorrent && torrent.RdId != null)
@ -369,7 +352,7 @@ public class Torrents
public async Task<String> UnrestrictLink(Guid downloadId)
{
var download = await _downloads.GetById(downloadId);
var download = await downloads.GetById(downloadId);
if (download == null)
{
@ -380,7 +363,7 @@ public class Torrents
var unrestrictedLink = await TorrentClient.Unrestrict(download.Path);
await _downloads.UpdateUnrestrictedLink(downloadId, unrestrictedLink);
await downloads.UpdateUnrestrictedLink(downloadId, unrestrictedLink);
return unrestrictedLink;
}
@ -440,7 +423,7 @@ public class Torrents
continue;
}
torrent = await _torrentData.Add(rdTorrent.Id, rdTorrent.Hash, null, false, Settings.Get.DownloadClient.Client, newTorrent);
torrent = await torrentData.Add(rdTorrent.Id, rdTorrent.Hash, null, false, Settings.Get.DownloadClient.Client, newTorrent);
await UpdateTorrentClientData(torrent, rdTorrent);
}
@ -472,7 +455,7 @@ public class Torrents
try
{
var torrent = await _torrentData.GetById(torrentId);
var torrent = await torrentData.GetById(torrentId);
if (torrent?.Retry == null)
{
@ -486,8 +469,8 @@ public class Torrents
foreach (var download in torrent.Downloads)
{
await _downloads.UpdateError(download.DownloadId, null);
await _downloads.UpdateCompleted(download.DownloadId, DateTimeOffset.UtcNow);
await downloads.UpdateError(download.DownloadId, null);
await downloads.UpdateCompleted(download.DownloadId, DateTimeOffset.UtcNow);
}
foreach (var download in torrent.Downloads)
@ -527,7 +510,7 @@ public class Torrents
newTorrent = await UploadMagnet(torrent.FileOrMagnet, torrent);
}
await _torrentData.UpdateRetry(newTorrent.TorrentId, null, retryCount);
await torrentData.UpdateRetry(newTorrent.TorrentId, null, retryCount);
}
finally
{
@ -537,7 +520,7 @@ public class Torrents
public async Task RetryDownload(Guid downloadId)
{
var download = await _downloads.GetById(downloadId);
var download = await downloads.GetById(downloadId);
if (download == null)
{
@ -573,46 +556,46 @@ public class Torrents
Log($"Resetting", download, download.Torrent);
await _downloads.Reset(downloadId);
await downloads.Reset(downloadId);
await _torrentData.UpdateComplete(download.TorrentId, null, null, false);
await torrentData.UpdateComplete(download.TorrentId, null, null, false);
}
public async Task UpdateComplete(Guid torrentId, String? error, DateTimeOffset datetime, Boolean retry)
{
await _torrentData.UpdateComplete(torrentId, error, datetime, retry);
await torrentData.UpdateComplete(torrentId, error, datetime, retry);
}
public async Task UpdateFilesSelected(Guid torrentId, DateTimeOffset datetime)
{
await _torrentData.UpdateFilesSelected(torrentId, datetime);
await torrentData.UpdateFilesSelected(torrentId, datetime);
}
public async Task UpdatePriority(String hash, Int32 priority)
{
var torrent = await _torrentData.GetByHash(hash);
var torrent = await torrentData.GetByHash(hash);
if (torrent == null)
{
return;
}
await _torrentData.UpdatePriority(torrent.TorrentId, priority);
await torrentData.UpdatePriority(torrent.TorrentId, priority);
}
public async Task UpdateRetry(Guid torrentId, DateTimeOffset? datetime, Int32 retry)
{
await _torrentData.UpdateRetry(torrentId, datetime, retry);
await torrentData.UpdateRetry(torrentId, datetime, retry);
}
public async Task UpdateError(Guid torrentId, String error)
{
await _torrentData.UpdateError(torrentId, error);
await torrentData.UpdateError(torrentId, error);
}
public async Task<Torrent?> GetById(Guid torrentId)
{
var torrent = await _torrentData.GetById(torrentId);
var torrent = await torrentData.GetById(torrentId);
if (torrent == null)
{
@ -662,14 +645,14 @@ public class Torrents
try
{
var existingTorrent = await _torrentData.GetByHash(infoHash);
var existingTorrent = await torrentData.GetByHash(infoHash);
if (existingTorrent != null)
{
return existingTorrent;
}
var newTorrent = await _torrentData.Add(rdTorrentId,
var newTorrent = await torrentData.Add(rdTorrentId,
infoHash,
fileOrMagnetContents,
isFile,
@ -688,7 +671,7 @@ public class Torrents
public async Task Update(Torrent torrent)
{
await _torrentData.Update(torrent);
await torrentData.Update(torrent);
}
public async Task RunTorrentComplete(Guid torrentId)
@ -698,14 +681,14 @@ public class Torrents
return;
}
var torrent = await _torrentData.GetById(torrentId);
var torrent = await torrentData.GetById(torrentId);
if (torrent == null)
{
throw new Exception($"Cannot find Torrent with ID {torrentId}");
}
var downloads = await _downloads.GetForTorrent(torrentId);
var downloads1 = await downloads.GetForTorrent(torrentId);
var fileName = Settings.Get.General.RunOnTorrentCompleteFileName;
var arguments = Settings.Get.General.RunOnTorrentCompleteArguments ?? "";
@ -729,7 +712,7 @@ public class Torrents
arguments = arguments.Replace("%F", $"\"{filePath}\"");
arguments = arguments.Replace("%R", $"\"{downloadPath}\"");
arguments = arguments.Replace("%D", $"\"{torrentPath}\"");
arguments = arguments.Replace("%C", downloads.Count.ToString(CultureInfo.InvariantCulture).Replace(",", "").Replace(".", ""));
arguments = arguments.Replace("%C", downloads1.Count.ToString(CultureInfo.InvariantCulture).Replace(",", "").Replace(".", ""));
arguments = arguments.Replace("%Z", torrent.RdSize?.ToString(CultureInfo.InvariantCulture).Replace(",", "").Replace(".", ""));
arguments = arguments.Replace("%I", torrent.Hash);
@ -811,7 +794,7 @@ public class Torrents
if (originalTorrent != newTorrent)
{
await _torrentData.UpdateRdData(torrent);
await torrentData.UpdateRdData(torrent);
}
}
catch
@ -832,7 +815,7 @@ public class Torrents
message = $"{message} {torrent.ToLog()}";
}
_logger.LogDebug(message);
logger.LogDebug(message);
}
private void Log(String message, Torrent? torrent = null)
@ -842,6 +825,6 @@ public class Torrents
message = $"{message} {torrent.ToLog()}";
}
_logger.LogDebug(message);
logger.LogDebug(message);
}
}

View file

@ -7,34 +7,25 @@ using SharpCompress.Archives.Zip;
namespace RdtClient.Service.Services;
public class UnpackClient
public class UnpackClient(Download download, String destinationPath)
{
public Boolean Finished { get; private set; }
public String? Error { get; private set; }
public Int32 Progess { get; private set; }
private readonly Download _download;
private readonly String _destinationPath;
private readonly Torrent _torrent;
private readonly Torrent _torrent = download.Torrent ?? throw new Exception($"Torrent is null");
private readonly CancellationTokenSource _cancellationTokenSource = new CancellationTokenSource();
public UnpackClient(Download download, String destinationPath)
{
_download = download;
_destinationPath = destinationPath;
_torrent = download.Torrent ?? throw new Exception($"Torrent is null");
}
public void Start()
{
Progess = 0;
try
{
var filePath = DownloadHelper.GetDownloadPath(_destinationPath, _torrent, _download);
var filePath = DownloadHelper.GetDownloadPath(destinationPath, _torrent, download);
if (filePath == null)
{
@ -51,7 +42,7 @@ public class UnpackClient
}
catch (Exception ex)
{
Error = $"An unexpected error occurred preparing download {_download.Link} for torrent {_torrent.RdName}: {ex.Message}";
Error = $"An unexpected error occurred preparing download {download.Link} for torrent {_torrent.RdName}: {ex.Message}";
Finished = true;
}
}
@ -70,14 +61,14 @@ public class UnpackClient
return;
}
var extractPath = _destinationPath;
var extractPath = destinationPath;
String? extractPathTemp = null;
var archiveEntries = await GetArchiveFiles(filePath);
if (!archiveEntries.Any(m => m.StartsWith(_torrent.RdName + @"\")) && !archiveEntries.Any(m => m.StartsWith(_torrent.RdName + "/")))
{
extractPath = Path.Combine(_destinationPath, _torrent.RdName!);
extractPath = Path.Combine(destinationPath, _torrent.RdName!);
}
if (archiveEntries.Any(m => m.Contains(".r00")))
@ -119,7 +110,7 @@ public class UnpackClient
}
catch (Exception ex)
{
Error = $"An unexpected error occurred unpacking {_download.Link} for torrent {_torrent.RdName}: {ex.Message}";
Error = $"An unexpected error occurred unpacking {download.Link} for torrent {_torrent.RdName}: {ex.Message}";
}
finally
{

View file

@ -12,30 +12,21 @@ namespace RdtClient.Web.Controllers;
/// </summary>
[ApiController]
[Route("api/v2")]
public class QBittorrentController : Controller
public class QBittorrentController(ILogger<QBittorrentController> logger, QBittorrent qBittorrent) : Controller
{
private readonly ILogger<QBittorrentController> _logger;
private readonly QBittorrent _qBittorrent;
public QBittorrentController(ILogger<QBittorrentController> logger, QBittorrent qBittorrent)
{
_logger = logger;
_qBittorrent = qBittorrent;
}
[AllowAnonymous]
[Route("auth/login")]
[HttpGet]
public async Task<ActionResult> AuthLogin([FromQuery] QBAuthLoginRequest request)
{
_logger.LogDebug($"Auth login");
logger.LogDebug($"Auth login");
if (String.IsNullOrWhiteSpace(request.UserName) || String.IsNullOrEmpty(request.Password))
{
return Ok("Fails.");
}
var result = await _qBittorrent.AuthLogin(request.UserName, request.Password);
var result = await qBittorrent.AuthLogin(request.UserName, request.Password);
if (result)
{
@ -59,9 +50,9 @@ public class QBittorrentController : Controller
[HttpPost]
public async Task<ActionResult> AuthLogout()
{
_logger.LogDebug($"Auth logout");
logger.LogDebug($"Auth logout");
await _qBittorrent.AuthLogout();
await qBittorrent.AuthLogout();
return Ok();
}
@ -113,7 +104,7 @@ public class QBittorrentController : Controller
[HttpPost]
public async Task<ActionResult<AppPreferences>> AppPreferences()
{
var result = await _qBittorrent.AppPreferences();
var result = await qBittorrent.AppPreferences();
return Ok(result);
}
@ -142,7 +133,7 @@ public class QBittorrentController : Controller
[HttpPost]
public async Task<ActionResult<IList<TorrentInfo>>> TorrentsInfo([FromQuery] QBTorrentsInfoRequest request)
{
var results = await _qBittorrent.TorrentInfo();
var results = await qBittorrent.TorrentInfo();
if (!String.IsNullOrWhiteSpace(request.Category))
{
@ -170,7 +161,7 @@ public class QBittorrentController : Controller
return BadRequest();
}
var result = await _qBittorrent.TorrentFileContents(request.Hash);
var result = await qBittorrent.TorrentFileContents(request.Hash);
if (result == null)
{
@ -198,7 +189,7 @@ public class QBittorrentController : Controller
return BadRequest();
}
var result = await _qBittorrent.TorrentProperties(request.Hash);
var result = await qBittorrent.TorrentProperties(request.Hash);
if (result == null)
{
@ -230,7 +221,7 @@ public class QBittorrentController : Controller
foreach (var hash in hashes)
{
await _qBittorrent.TorrentPause(hash);
await qBittorrent.TorrentPause(hash);
}
return Ok();
@ -258,7 +249,7 @@ public class QBittorrentController : Controller
foreach (var hash in hashes)
{
await _qBittorrent.TorrentResume(hash);
await qBittorrent.TorrentResume(hash);
}
return Ok();
@ -291,13 +282,13 @@ public class QBittorrentController : Controller
return BadRequest();
}
_logger.LogDebug($"Delete {request.Hashes}");
logger.LogDebug($"Delete {request.Hashes}");
var hashes = request.Hashes.Split("|");
foreach (var hash in hashes)
{
await _qBittorrent.TorrentsDelete(hash, request.DeleteFiles);
await qBittorrent.TorrentsDelete(hash, request.DeleteFiles);
}
return Ok();
@ -327,13 +318,13 @@ public class QBittorrentController : Controller
{
if (url.StartsWith("magnet"))
{
await _qBittorrent.TorrentsAddMagnet(url.Trim(), request.Category, null);
await qBittorrent.TorrentsAddMagnet(url.Trim(), request.Category, null);
}
else if (url.StartsWith("http"))
{
var httpClient = new HttpClient();
var result = await httpClient.GetByteArrayAsync(url);
await _qBittorrent.TorrentsAddFile(result, request.Category, null);
await qBittorrent.TorrentsAddFile(result, request.Category, null);
}
else
{
@ -358,7 +349,7 @@ public class QBittorrentController : Controller
await file.CopyToAsync(target);
var fileBytes = target.ToArray();
await _qBittorrent.TorrentsAddFile(fileBytes, request.Category, request.Priority);
await qBittorrent.TorrentsAddFile(fileBytes, request.Category, request.Priority);
}
}
@ -384,7 +375,7 @@ public class QBittorrentController : Controller
foreach (var hash in hashes)
{
await _qBittorrent.TorrentsSetCategory(hash, request.Category);
await qBittorrent.TorrentsSetCategory(hash, request.Category);
}
return Ok();
@ -404,7 +395,7 @@ public class QBittorrentController : Controller
[HttpPost]
public async Task<ActionResult<IDictionary<String, TorrentCategory>>> TorrentsCategories()
{
var categories = await _qBittorrent.TorrentsCategories();
var categories = await qBittorrent.TorrentsCategories();
return Ok(categories);
}
@ -420,7 +411,7 @@ public class QBittorrentController : Controller
return BadRequest("category name is empty");
}
await _qBittorrent.CategoryCreate(request.Category.Trim());
await qBittorrent.CategoryCreate(request.Category.Trim());
return Ok();
}
@ -440,7 +431,7 @@ public class QBittorrentController : Controller
foreach (var category in categories)
{
await _qBittorrent.CategoryRemove(category.Trim());
await qBittorrent.CategoryRemove(category.Trim());
}
return Ok();
@ -469,7 +460,7 @@ public class QBittorrentController : Controller
foreach (var hash in hashes)
{
await _qBittorrent.TorrentsTopPrio(hash);
await qBittorrent.TorrentsTopPrio(hash);
}
return Ok();
@ -488,7 +479,7 @@ public class QBittorrentController : Controller
[HttpGet]
public async Task<ActionResult> SyncMainData()
{
var result = await _qBittorrent.SyncMainData();
var result = await qBittorrent.SyncMainData();
return Ok(result);
}

View file

@ -13,17 +13,8 @@ namespace RdtClient.Web.Controllers;
[Authorize(Policy = "AuthSetting")]
[Route("Api/Settings")]
public class SettingsController : Controller
public class SettingsController(Settings settings, Torrents torrents) : Controller
{
private readonly Settings _settings;
private readonly Torrents _torrents;
public SettingsController(Settings settings, Torrents torrents)
{
_settings = settings;
_torrents = torrents;
}
[HttpGet]
[Route("")]
public ActionResult Get()
@ -34,14 +25,14 @@ public class SettingsController : Controller
[HttpPut]
[Route("")]
public async Task<ActionResult> Update([FromBody] IList<SettingProperty>? settings)
public async Task<ActionResult> Update([FromBody] IList<SettingProperty>? settings1)
{
if (settings == null)
if (settings1 == null)
{
return BadRequest();
}
await _settings.Update(settings);
await settings.Update(settings1);
return Ok();
}
@ -50,7 +41,7 @@ public class SettingsController : Controller
[Route("Profile")]
public async Task<ActionResult<Profile>> Profile()
{
var profile = await _torrents.GetProfile();
var profile = await torrents.GetProfile();
return Ok(profile);
}

View file

@ -11,24 +11,13 @@ namespace RdtClient.Web.Controllers;
[Authorize(Policy = "AuthSetting")]
[Route("Api/Torrents")]
public class TorrentsController : Controller
public class TorrentsController(ILogger<TorrentsController> logger, Torrents torrents, TorrentRunner torrentRunner) : Controller
{
private readonly TorrentRunner _torrentRunner;
private readonly ILogger<TorrentsController> _logger;
private readonly Torrents _torrents;
public TorrentsController(ILogger<TorrentsController> logger, Torrents torrents, TorrentRunner torrentRunner)
{
_logger = logger;
_torrents = torrents;
_torrentRunner = torrentRunner;
}
[HttpGet]
[Route("")]
public async Task<ActionResult<IList<Torrent>>> GetAll()
{
var results = await _torrents.Get();
var results = await torrents.Get();
// Prevent infinite recursion when serializing
foreach (var file in results.SelectMany(torrent => torrent.Downloads))
@ -43,7 +32,7 @@ public class TorrentsController : Controller
[Route("Get/{torrentId:guid}")]
public async Task<ActionResult<Torrent>> GetById(Guid torrentId)
{
var torrent = await _torrents.GetById(torrentId);
var torrent = await torrents.GetById(torrentId);
if (torrent?.Downloads != null)
{
@ -64,7 +53,7 @@ public class TorrentsController : Controller
[Route("Tick")]
public async Task<ActionResult> Tick()
{
await _torrentRunner.Tick();
await torrentRunner.Tick();
return Ok();
}
@ -85,7 +74,7 @@ public class TorrentsController : Controller
return BadRequest("Invalid Torrent");
}
_logger.LogDebug($"Add file");
logger.LogDebug($"Add file");
var fileStream = file.OpenReadStream();
@ -95,7 +84,7 @@ public class TorrentsController : Controller
var bytes = memoryStream.ToArray();
await _torrents.UploadFile(bytes, formData.Torrent);
await torrents.UploadFile(bytes, formData.Torrent);
return Ok();
}
@ -119,9 +108,9 @@ public class TorrentsController : Controller
return BadRequest("Invalid Torrent");
}
_logger.LogDebug($"Add magnet");
logger.LogDebug($"Add magnet");
await _torrents.UploadMagnet(request.MagnetLink, request.Torrent);
await torrents.UploadMagnet(request.MagnetLink, request.Torrent);
return Ok();
}
@ -145,7 +134,7 @@ public class TorrentsController : Controller
var torrent = await MonoTorrent.Torrent.LoadAsync(bytes);
var result = await _torrents.GetAvailableFiles(torrent.InfoHash.ToHex());
var result = await torrents.GetAvailableFiles(torrent.InfoHash.ToHex());
return Ok(result);
}
@ -161,7 +150,7 @@ public class TorrentsController : Controller
var magnet = MagnetLink.Parse(request.MagnetLink);
var result = await _torrents.GetAvailableFiles(magnet.InfoHash.ToHex());
var result = await torrents.GetAvailableFiles(magnet.InfoHash.ToHex());
return Ok(result);
}
@ -175,9 +164,9 @@ public class TorrentsController : Controller
return BadRequest();
}
_logger.LogDebug($"Delete {torrentId}");
logger.LogDebug($"Delete {torrentId}");
await _torrents.Delete(torrentId, request.DeleteData, request.DeleteRdTorrent, request.DeleteLocalFiles);
await torrents.Delete(torrentId, request.DeleteData, request.DeleteRdTorrent, request.DeleteLocalFiles);
return Ok();
}
@ -186,10 +175,10 @@ public class TorrentsController : Controller
[Route("Retry/{torrentId:guid}")]
public async Task<ActionResult> Retry(Guid torrentId)
{
_logger.LogDebug($"Retry {torrentId}");
logger.LogDebug($"Retry {torrentId}");
await _torrents.UpdateRetry(torrentId, DateTimeOffset.UtcNow, 0);
await _torrents.RetryTorrent(torrentId, 0);
await torrents.UpdateRetry(torrentId, DateTimeOffset.UtcNow, 0);
await torrents.RetryTorrent(torrentId, 0);
return Ok();
}
@ -198,9 +187,9 @@ public class TorrentsController : Controller
[Route("RetryDownload/{downloadId:guid}")]
public async Task<ActionResult> RetryDownload(Guid downloadId)
{
_logger.LogDebug($"Retry download {downloadId}");
logger.LogDebug($"Retry download {downloadId}");
await _torrents.RetryDownload(downloadId);
await torrents.RetryDownload(downloadId);
return Ok();
}
@ -214,7 +203,7 @@ public class TorrentsController : Controller
return BadRequest();
}
await _torrents.Update(torrent);
await torrents.Update(torrent);
return Ok();
}
@ -237,7 +226,7 @@ public class TorrentsController : Controller
{
var magnet = MagnetLink.Parse(request.MagnetLink);
availableFiles = await _torrents.GetAvailableFiles(magnet.InfoHash.ToHex());
availableFiles = await torrents.GetAvailableFiles(magnet.InfoHash.ToHex());
}
else if (file != null)
{
@ -251,7 +240,7 @@ public class TorrentsController : Controller
var torrent = await MonoTorrent.Torrent.LoadAsync(bytes);
availableFiles = await _torrents.GetAvailableFiles(torrent.InfoHash.ToHex());
availableFiles = await torrents.GetAvailableFiles(torrent.InfoHash.ToHex());
}
else
{

View file

@ -68,13 +68,10 @@ builder.Services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationSc
options.SlidingExpiration = true;
});
builder.Services.AddAuthorization( options =>
{
options.AddPolicy("AuthSetting",
policyCorrectUser =>
{
policyCorrectUser.Requirements.Add(new AuthSettingRequirement());
});
builder.Services.AddAuthorizationBuilder().AddPolicy("AuthSetting", policyCorrectUser =>
{
policyCorrectUser.Requirements.Add(new AuthSettingRequirement());
});
@ -178,12 +175,10 @@ try
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapHub<RdtHub>("/hub");
endpoints.MapControllers();
});
app.MapHub<RdtHub>("/hub");
app.MapControllers();
app.MapWhen(x => !x.Request.Path.StartsWithSegments("/api"), routeBuilder =>
{

View file

@ -29,15 +29,15 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.SpaServices.Extensions" Version="8.0.1" />
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="8.0.1" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite.Core" Version="8.0.1" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="8.0.1">
<PackageReference Include="Microsoft.AspNetCore.SpaServices.Extensions" Version="8.0.3" />
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="8.0.3" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite.Core" Version="8.0.3" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="8.0.3">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.Extensions.Hosting.WindowsServices" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.Identity.Core" Version="8.0.1" />
<PackageReference Include="Microsoft.Extensions.Identity.Core" Version="8.0.3" />
<PackageReference Include="Serilog" Version="3.1.1" />
<PackageReference Include="Serilog.AspNetCore" Version="8.0.1" />
<PackageReference Include="Serilog.Sinks.File" Version="5.0.0" />