Added bit of logging to debug downloader issues, upgraded packages, cleaned up C# code.
This commit is contained in:
parent
74b988effa
commit
3b72463663
35 changed files with 407 additions and 666 deletions
|
|
@ -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; }
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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.");
|
||||
}
|
||||
}
|
||||
|
|
@ -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}");
|
||||
|
|
|
|||
|
|
@ -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.");
|
||||
}
|
||||
}
|
||||
|
|
@ -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.");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
{
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
@ -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))
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -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
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
@ -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
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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 =>
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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" />
|
||||
|
|
|
|||
Loading…
Reference in a new issue