Add internal downloader logger.

This commit is contained in:
Roger Far 2024-04-06 16:28:03 -06:00
parent c21d578a23
commit bec2dcd20b
17 changed files with 140 additions and 125 deletions

View file

@ -13,7 +13,7 @@ public class SettingData(DataContext dataContext, ILogger<SettingData> logger)
public static IList<SettingProperty> GetAll()
{
return GetSettings(Get, null).ToList();
return GetSettings(Get, null);
}
public async Task Update(IList<SettingProperty> settings)
@ -75,7 +75,7 @@ public class SettingData(DataContext dataContext, ILogger<SettingData> logger)
var newSettings = expectedSettings.Where(m => dbSettings.All(p => p.SettingId != m.SettingId)).ToList();
if (newSettings.Any())
if (newSettings.Count > 0)
{
await dataContext.Settings.AddRangeAsync(newSettings);
await dataContext.SaveChangesAsync();
@ -83,14 +83,14 @@ public class SettingData(DataContext dataContext, ILogger<SettingData> logger)
var oldSettings = dbSettings.Where(m => expectedSettings.All(p => p.SettingId != m.SettingId)).ToList();
if (oldSettings.Any())
if (oldSettings.Count > 0)
{
dataContext.Settings.RemoveRange(oldSettings);
await dataContext.SaveChangesAsync();
}
}
private static IEnumerable<SettingProperty> GetSettings(Object defaultSetting, String? parent)
private static List<SettingProperty> GetSettings(Object defaultSetting, String? parent)
{
var result = new List<SettingProperty>();
@ -124,7 +124,7 @@ public class SettingData(DataContext dataContext, ILogger<SettingData> logger)
if (property.PropertyType.IsEnum)
{
settingProperty.Type = "Enum";
settingProperty.EnumValues = new();
settingProperty.EnumValues = [];
foreach (var e in Enum.GetValues(property.PropertyType).Cast<Enum>())
{
@ -173,8 +173,18 @@ public class SettingData(DataContext dataContext, ILogger<SettingData> logger)
{
if (property.PropertyType.IsEnum)
{
var newValue = Enum.Parse(property.PropertyType, setting.Value ?? "0");
property.SetValue(defaultSetting, newValue);
try
{
var newValue = Enum.Parse(property.PropertyType, setting.Value ?? "0");
property.SetValue(defaultSetting, newValue);
}
catch
{
logger.LogWarning("Invalid value for setting {propertyName}: {setting.Value}", propertyName, setting.Value);
var defaultValue = property.GetValue(defaultSetting);
property.SetValue(defaultSetting, defaultValue);
}
}
else
{
@ -191,7 +201,10 @@ public class SettingData(DataContext dataContext, ILogger<SettingData> logger)
}
else
{
logger.LogWarning($"Invalid value for setting {propertyName}: {setting.Value}");
logger.LogWarning("Invalid value for setting {propertyName}: {setting.Value}", propertyName, setting.Value);
var defaultValue = property.GetValue(defaultSetting);
property.SetValue(defaultSetting, defaultValue);
}
}
}

View file

@ -21,7 +21,7 @@ public class TorrentData(DataContext dataContext)
.Include(m => m.Downloads)
.ToListAsync();
return _torrentCache.OrderBy(m => m.Priority ?? 9999).ThenBy(m => m.Added).ToList();
return [.. _torrentCache.OrderBy(m => m.Priority ?? 9999).ThenBy(m => m.Added)];
}
finally
{
@ -51,10 +51,12 @@ public class TorrentData(DataContext dataContext)
public async Task<Torrent?> GetByHash(String hash)
{
#pragma warning disable CA1862 // Use the 'StringComparison' method overloads to perform case-insensitive string comparisons
var dbTorrent = await dataContext.Torrents
.AsNoTracking()
.Include(m => m.Downloads)
.FirstOrDefaultAsync(m => m.Hash.ToLower() == hash.ToLower());
#pragma warning restore CA1862 // Use the 'StringComparison' method overloads to perform case-insensitive string comparisons
if (dbTorrent == null)
{
@ -189,7 +191,7 @@ public class TorrentData(DataContext dataContext)
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())
if (downloadWithErrors.Count > 0)
{
error = $"{downloadWithErrors.Count}/{downloads.Count} downloads failed with errors";
}

View file

@ -11,7 +11,7 @@ public static class DiConfig
{
if (String.IsNullOrWhiteSpace(appSettings.Database?.Path))
{
throw new Exception("Invalid database path found in appSettings");
throw new("Invalid database path found in appSettings");
}
var connectionString = $"Data Source={appSettings.Database.Path}";

View file

@ -0,0 +1,24 @@
using System.ComponentModel;
namespace RdtClient.Data.Enums;
public enum DownloadClientLogLevel
{
[Description("Verbose")]
Verbose,
[Description("Debug")]
Debug,
[Description("Information")]
Information,
[Description("Warning")]
Warning,
[Description("Error")]
Error,
[Description("None")]
None
}

View file

@ -4,6 +4,9 @@ namespace RdtClient.Data.Enums;
public enum LogLevel
{
[Description("Verbose")]
Verbose,
[Description("Debug")]
Debug,

View file

@ -42,7 +42,7 @@ public class Torrent
public String? Error { get; set; }
[InverseProperty("Torrent")]
public IList<Download> Downloads { get; set; } = new List<Download>();
public IList<Download> Downloads { get; set; } = [];
public String? RdId { get; set; }
public String? RdName { get; set; }
@ -65,16 +65,16 @@ public class Torrent
{
if (String.IsNullOrWhiteSpace(RdFiles))
{
return new List<TorrentClientFile>();
return [];
}
try
{
return JsonSerializer.Deserialize<List<TorrentClientFile>>(RdFiles) ?? new List<TorrentClientFile>();
return JsonSerializer.Deserialize<List<TorrentClientFile>>(RdFiles) ?? [];
}
catch
{
return new List<TorrentClientFile>();
return [];
}
}
}
@ -86,7 +86,7 @@ public class Torrent
{
if (String.IsNullOrWhiteSpace(DownloadManualFiles))
{
return new List<String>();
return [];
}
return DownloadManualFiles.Split(",");

View file

@ -36,7 +36,7 @@ public class DbSettingsGeneral
{
[DisplayName("Log level")]
[Description("Recommended level is Warning, set to Debug to get the most info.")]
public LogLevel LogLevel { get; set; } = LogLevel.Warning;
public LogLevel LogLevel { get; set; } = LogLevel.Error;
[DisplayName("Maximum parallel downloads")]
[Description("Maximum amount of torrents that get downloaded to your host at the same time.")]
@ -127,6 +127,10 @@ http://127.0.0.1:6800/jsonrpc.")]
[DisplayName("Rclone mount path (only used for the Symlink Downloader)")]
[Description("Path where Rclone is mounted. Required for Symlink Downloader.")]
public String RcloneMountPath { get; set; } = "/mnt/rd/";
[DisplayName("Log level")]
[Description("Only set when trying to debug a download client, can generate a lot of logs.")]
public DownloadClientLogLevel LogLevel { get; set; } = DownloadClientLogLevel.None;
}
public class DbSettingsProvider

View file

@ -1,5 +1,4 @@
using System.Net.Http.Headers;
using System.Reflection;
using System.Reflection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
@ -36,7 +35,7 @@ public class UpdateChecker(ILogger<UpdateChecker> logger) : BackgroundService
try
{
var httpClient = new HttpClient();
httpClient.DefaultRequestHeaders.UserAgent.Add(new ProductInfoHeaderValue("RdtClient", CurrentVersion));
httpClient.DefaultRequestHeaders.UserAgent.Add(new("RdtClient", CurrentVersion));
var response = await httpClient.GetStringAsync($"https://api.github.com/repos/rogerfar/rdt-client/tags?per_page=1", stoppingToken);
var gitHubReleases = JsonConvert.DeserializeObject<List<GitHubReleasesResponse>>(response);

View file

@ -24,7 +24,7 @@ public class RequestLoggingMiddleware(RequestDelegate next, ILoggerFactory logge
requestLog += $", QueryString: {context.Request.QueryString}";
}
if (context.Request.HasFormContentType && context.Request.Form.Count == 0)
if (context.Request.HasFormContentType && context.Request.Form.Count > 0)
{
requestLog += $", Form: {String.Join(", ", context.Request.Form.Select(f => $"{f.Key}: {f.Value}"))}";
}

View file

@ -12,7 +12,7 @@
<PackageReference Include="AllDebrid.NET" Version="1.0.12" />
<PackageReference Include="Aria2.NET" Version="1.0.5" />
<PackageReference Include="Downloader" Version="3.0.6" />
<PackageReference Include="Downloader.NET" Version="1.0.9" />
<PackageReference Include="Downloader.NET" Version="1.0.11" />
<PackageReference Include="MonoTorrent" Version="2.0.7" />
<PackageReference Include="Premiumize.NET" Version="1.0.4" />
<PackageReference Include="RD.NET" Version="2.1.4" />

View file

@ -38,7 +38,7 @@ public class Authentication(SignInManager<IdentityUser> signInManager, UserManag
public async Task<IdentityResult> Update(String newUserName, String newPassword)
{
var user = await GetUser() ?? throw new Exception("No logged in user found");
var user = await GetUser() ?? throw new("No logged in user found");
if (!String.IsNullOrWhiteSpace(newUserName))
{

View file

@ -33,7 +33,29 @@ public class InternalDownloader : IDownloader
_downloadService = new(_uri, _filePath, _downloadConfiguration);
//_downloadService.OnLog += message => Debug.WriteLine(message.Message);
_downloadService.OnLog += (message, level) =>
{
if (message.Exception != null || level == 4)
{
_logger.Error(message.Exception, message.Message);
}
switch (level)
{
case 0:
_logger.Verbose(message.Message);
break;
case 1:
_logger.Debug(message.Message);
break;
case 2:
_logger.Information(message.Message);
break;
case 3:
_logger.Warning(message.Message);
break;
}
};
_downloadService.OnProgress += (chunks, _) =>
{
@ -118,7 +140,8 @@ public class InternalDownloader : IDownloader
{
settingDownloadTimeout = 1000;
}
_downloadConfiguration.LogLevel = (Int32)Settings.Get.DownloadClient.LogLevel;
_downloadConfiguration.Parallel = settingDownloadParallelCount;
_downloadConfiguration.MaximumBytesPerSecond = settingDownloadMaxSpeed;
_downloadConfiguration.Timeout = settingDownloadTimeout;

View file

@ -48,6 +48,7 @@ public class Settings(SettingData settingData)
LoggingLevelSwitch.MinimumLevel = Settings.Get.General.LogLevel switch
{
LogLevel.Verbose => LogEventLevel.Verbose,
LogLevel.Debug => LogEventLevel.Debug,
LogLevel.Information => LogEventLevel.Information,
LogLevel.Warning => LogEventLevel.Warning,

View file

@ -19,7 +19,7 @@ public class AllDebridTorrentClient(ILogger<AllDebridTorrentClient> logger, IHtt
if (String.IsNullOrWhiteSpace(apiKey))
{
throw new Exception("All-Debrid API Key not set in the settings");
throw new("All-Debrid API Key not set in the settings");
}
var httpClient = httpClientFactory.CreateClient();
@ -45,7 +45,7 @@ public class AllDebridTorrentClient(ILogger<AllDebridTorrentClient> logger, IHtt
private static TorrentClientTorrent Map(Magnet torrent)
{
return new TorrentClientTorrent
return new()
{
Id = torrent.Id.ToString(),
Filename = torrent.Filename,
@ -81,14 +81,9 @@ public class AllDebridTorrentClient(ILogger<AllDebridTorrentClient> logger, IHtt
public async Task<TorrentClientUser> GetUser()
{
var user = await GetClient().User.GetAsync();
var user = await GetClient().User.GetAsync() ?? throw new("Unable to get user");
if (user == null)
{
throw new Exception("Unable to get user");
}
return new TorrentClientUser
return new()
{
Username = user.Username,
Expiration = user.PremiumUntil > 0 ? new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc).AddSeconds(user.PremiumUntil) : null
@ -101,15 +96,10 @@ public class AllDebridTorrentClient(ILogger<AllDebridTorrentClient> logger, IHtt
if (result?.Id == null)
{
throw new Exception("Unable to add magnet link");
throw new("Unable to add magnet link");
}
var resultId = result.Id.ToString();
if (resultId == null)
{
throw new Exception($"Invalid responseID {result.Id}");
}
var resultId = result.Id.ToString() ?? throw new($"Invalid responseID {result.Id}");
return resultId;
}
@ -120,15 +110,10 @@ public class AllDebridTorrentClient(ILogger<AllDebridTorrentClient> logger, IHtt
if (result?.Id == null)
{
throw new Exception("Unable to add torrent file");
throw new("Unable to add torrent file");
}
var resultId = result.Id.ToString();
if (resultId == null)
{
throw new Exception($"Invalid responseID {result.Id}");
}
var resultId = result.Id.ToString() ?? throw new($"Invalid responseID {result.Id}");
return resultId;
}
@ -139,17 +124,17 @@ public class AllDebridTorrentClient(ILogger<AllDebridTorrentClient> logger, IHtt
if (isAvailable)
{
return new List<TorrentClientAvailableFile>
{
return
[
new()
{
Filename = "All files",
Filesize = 0
}
};
];
}
return new List<TorrentClientAvailableFile>();
return [];
}
public Task SelectFiles(Torrent torrent)
@ -168,7 +153,7 @@ public class AllDebridTorrentClient(ILogger<AllDebridTorrentClient> logger, IHtt
if (result.Link == null)
{
throw new Exception("Invalid result link");
throw new("Invalid result link");
}
return result.Link;
@ -294,17 +279,12 @@ public class AllDebridTorrentClient(ILogger<AllDebridTorrentClient> logger, IHtt
private async Task<TorrentClientTorrent> GetInfo(String torrentId)
{
var result = await GetClient().Magnet.StatusAsync(torrentId);
if (result == null)
{
throw new Exception($"Unable to find magnet with ID {torrentId}");
}
var result = await GetClient().Magnet.StatusAsync(torrentId) ?? throw new($"Unable to find magnet with ID {torrentId}");
return Map(result);
}
private static IEnumerable<String> GetFiles(IList<File> files, String parent)
private static List<String> GetFiles(IList<File> files, String parent)
{
var result = new List<String>();
@ -324,7 +304,7 @@ public class AllDebridTorrentClient(ILogger<AllDebridTorrentClient> logger, IHtt
return result;
}
private static IEnumerable<String> GetFiles(IList<FileE1> files, String parent)
private static List<String> GetFiles(IList<FileE1> files, String parent)
{
var result = new List<String>();
@ -344,7 +324,7 @@ public class AllDebridTorrentClient(ILogger<AllDebridTorrentClient> logger, IHtt
return result;
}
private static IEnumerable<String> GetFiles(IList<FileE2> files, String parent)
private static List<String> GetFiles(IList<FileE2> files, String parent)
{
var result = new List<String>();

View file

@ -18,7 +18,7 @@ public class PremiumizeTorrentClient(ILogger<PremiumizeTorrentClient> logger, IH
if (String.IsNullOrWhiteSpace(apiKey))
{
throw new Exception("Premiumize API Key not set in the settings");
throw new("Premiumize API Key not set in the settings");
}
var httpClient = httpClientFactory.CreateClient();
@ -44,7 +44,7 @@ public class PremiumizeTorrentClient(ILogger<PremiumizeTorrentClient> logger, IH
private static TorrentClientTorrent Map(Transfer transfer)
{
return new TorrentClientTorrent
return new()
{
Id = transfer.Id,
Filename = transfer.Name,
@ -59,11 +59,11 @@ public class PremiumizeTorrentClient(ILogger<PremiumizeTorrentClient> logger, IH
Message = transfer.Message,
StatusCode = 0,
Added = null,
Files = new List<TorrentClientFile>(),
Links = new List<String>
{
Files = [],
Links =
[
transfer.FolderId
},
],
Ended = null,
Speed = 0,
Seeders = 0
@ -78,14 +78,9 @@ public class PremiumizeTorrentClient(ILogger<PremiumizeTorrentClient> logger, IH
public async Task<TorrentClientUser> GetUser()
{
var user = await GetClient().Account.InfoAsync();
var user = await GetClient().Account.InfoAsync() ?? throw new("Unable to get user");
if (user == null)
{
throw new Exception("Unable to get user");
}
return new TorrentClientUser
return new()
{
Username = user.CustomerId.ToString(),
Expiration = user.PremiumUntil > 0 ? new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc).AddSeconds(user.PremiumUntil.Value) : null
@ -98,15 +93,10 @@ public class PremiumizeTorrentClient(ILogger<PremiumizeTorrentClient> logger, IH
if (result?.Id == null)
{
throw new Exception("Unable to add magnet link");
throw new("Unable to add magnet link");
}
var resultId = result.Id;
if (resultId == null)
{
throw new Exception($"Invalid responseID {result.Id}");
}
var resultId = result.Id ?? throw new($"Invalid responseID {result.Id}");
return resultId;
}
@ -117,15 +107,10 @@ public class PremiumizeTorrentClient(ILogger<PremiumizeTorrentClient> logger, IH
if (result?.Id == null)
{
throw new Exception("Unable to add torrent file");
throw new("Unable to add torrent file");
}
var resultId = result.Id;
if (resultId == null)
{
throw new Exception($"Invalid responseID {result.Id}");
}
var resultId = result.Id ?? throw new($"Invalid responseID {result.Id}");
return resultId;
}
@ -222,12 +207,7 @@ public class PremiumizeTorrentClient(ILogger<PremiumizeTorrentClient> logger, IH
Log($"Found {transfers.Count} transfers", torrent);
var transfer = transfers.FirstOrDefault(m => m.Id == torrent.RdId);
if (transfer == null)
{
throw new Exception($"Transfer {torrent.RdId} not found!");
}
var transfer = transfers.FirstOrDefault(m => m.Id == torrent.RdId) ?? throw new($"Transfer {torrent.RdId} not found!");
Log($"Found transfer {transfer.Name} ({transfer.Id})", torrent);
@ -265,12 +245,7 @@ public class PremiumizeTorrentClient(ILogger<PremiumizeTorrentClient> logger, IH
private async Task<TorrentClientTorrent> GetInfo(String id)
{
var results = await GetClient().Transfers.ListAsync();
var result = results.FirstOrDefault(m => m.Id == id);
if (result == null)
{
throw new Exception($"Unable to find transfer with ID {id}");
}
var result = results.FirstOrDefault(m => m.Id == id) ?? throw new($"Unable to find transfer with ID {id}");
return Map(result);
}

View file

@ -6,17 +6,8 @@ using RdtClient.Service.Services;
namespace RdtClient.Web.Controllers;
[Route("Api/Authentication")]
public class AuthController : Controller
public class AuthController(Authentication authentication, Settings settings) : Controller
{
private readonly Authentication _authentication;
private readonly Settings _settings;
public AuthController(Authentication authentication, Settings settings)
{
_authentication = authentication;
_settings = settings;
}
[AllowAnonymous]
[Route("IsLoggedIn")]
[HttpGet]
@ -29,7 +20,7 @@ public class AuthController : Controller
if (User.Identity?.IsAuthenticated == false)
{
var user = await _authentication.GetUser();
var user = await authentication.GetUser();
if (user == null)
{
@ -52,7 +43,7 @@ public class AuthController : Controller
return BadRequest();
}
var user = await _authentication.GetUser();
var user = await authentication.GetUser();
if (user != null)
{
@ -64,14 +55,14 @@ public class AuthController : Controller
return BadRequest("Invalid UserName or Password");
}
var registerResult = await _authentication.Register(request.UserName, request.Password);
var registerResult = await authentication.Register(request.UserName, request.Password);
if (!registerResult.Succeeded)
{
return BadRequest(registerResult.Errors.First().Description);
}
await _authentication.Login(request.UserName, request.Password);
await authentication.Login(request.UserName, request.Password);
return Ok();
}
@ -91,8 +82,8 @@ public class AuthController : Controller
return StatusCode(401);
}
await _settings.Update("Provider:Provider", request.Provider);
await _settings.Update("Provider:ApiKey", request.Token);
await settings.Update("Provider:Provider", request.Provider);
await settings.Update("Provider:ApiKey", request.Token);
return Ok();
}
@ -107,7 +98,7 @@ public class AuthController : Controller
return BadRequest();
}
var user = await _authentication.GetUser();
var user = await authentication.GetUser();
if (user == null)
{
@ -119,7 +110,7 @@ public class AuthController : Controller
return BadRequest("Invalid credentials");
}
var result = await _authentication.Login(request.UserName, request.Password);
var result = await authentication.Login(request.UserName, request.Password);
if (!result.Succeeded)
{
@ -133,7 +124,7 @@ public class AuthController : Controller
[HttpPost]
public async Task<ActionResult> Logout()
{
await _authentication.Logout();
await authentication.Logout();
return Ok();
}
@ -151,7 +142,7 @@ public class AuthController : Controller
return BadRequest("Invalid UserName or Password");
}
var updateResult = await _authentication.Update(request.UserName, request.Password);
var updateResult = await authentication.Update(request.UserName, request.Password);
if (!updateResult.Succeeded)
{

View file

@ -164,7 +164,7 @@ public class TorrentsController(ILogger<TorrentsController> logger, Torrents tor
return BadRequest();
}
logger.LogDebug($"Delete {torrentId}");
logger.LogDebug("Delete {torrentId}", torrentId);
await torrents.Delete(torrentId, request.DeleteData, request.DeleteRdTorrent, request.DeleteLocalFiles);
@ -175,7 +175,7 @@ public class TorrentsController(ILogger<TorrentsController> logger, Torrents tor
[Route("Retry/{torrentId:guid}")]
public async Task<ActionResult> Retry(Guid torrentId)
{
logger.LogDebug($"Retry {torrentId}");
logger.LogDebug("Retry {torrentId}", torrentId);
await torrents.UpdateRetry(torrentId, DateTimeOffset.UtcNow, 0);
await torrents.RetryTorrent(torrentId, 0);
@ -187,7 +187,7 @@ public class TorrentsController(ILogger<TorrentsController> logger, Torrents tor
[Route("RetryDownload/{downloadId:guid}")]
public async Task<ActionResult> RetryDownload(Guid downloadId)
{
logger.LogDebug($"Retry download {downloadId}");
logger.LogDebug("Retry download {downloadId}", downloadId);
await torrents.RetryDownload(downloadId);
@ -285,7 +285,7 @@ public class TorrentsController(ILogger<TorrentsController> logger, Torrents tor
}
else
{
selectedFiles = availableFiles.ToList();
selectedFiles = [.. availableFiles];
}
return Ok(new