renamed classes; added series search call

This commit is contained in:
Flaminel
2024-11-10 03:17:43 +02:00
parent 781210e978
commit c48090db2f
6 changed files with 81 additions and 52 deletions
+1 -1
View File
@@ -2,5 +2,5 @@
public sealed class QuartzConfig public sealed class QuartzConfig
{ {
public required string FrozenTorrentTrigger { get; init; } public required string BlockedTorrentTrigger { get; init; }
} }
+9 -9
View File
@@ -1,6 +1,6 @@
using Common.Configuration; using Common.Configuration;
using Executable.Jobs; using Executable.Jobs;
using Infrastructure.Verticals.FrozenTorrent; using Infrastructure.Verticals.BlockedTorrent;
namespace Executable; namespace Executable;
using Quartz; using Quartz;
@@ -23,8 +23,8 @@ public static class DependencyInjection
private static IServiceCollection AddServices(this IServiceCollection services) => private static IServiceCollection AddServices(this IServiceCollection services) =>
services services
.AddTransient<FrozenTorrentJob>() .AddTransient<BlockedTorrentJob>()
.AddTransient<FrozenTorrentHandler>(); .AddTransient<BlockedTorrentHandler>();
private static IServiceCollection AddQuartzServices(this IServiceCollection services, IConfiguration configuration) => private static IServiceCollection AddQuartzServices(this IServiceCollection services, IConfiguration configuration) =>
services services
@@ -37,24 +37,24 @@ public static class DependencyInjection
throw new NullReferenceException("Quartz configuration is null"); throw new NullReferenceException("Quartz configuration is null");
} }
q.AddFrozenTorrentJob(config.FrozenTorrentTrigger); q.AddBlockedTorrentJob(config.BlockedTorrentTrigger);
}) })
.AddQuartzHostedService(opt => .AddQuartzHostedService(opt =>
{ {
opt.WaitForJobsToComplete = true; opt.WaitForJobsToComplete = true;
}); });
private static void AddFrozenTorrentJob(this IServiceCollectionQuartzConfigurator q, string trigger) private static void AddBlockedTorrentJob(this IServiceCollectionQuartzConfigurator q, string trigger)
{ {
q.AddJob<FrozenTorrentJob>(opts => q.AddJob<BlockedTorrentJob>(opts =>
{ {
opts.WithIdentity(nameof(FrozenTorrentJob)); opts.WithIdentity(nameof(BlockedTorrentJob));
}); });
q.AddTrigger(opts => q.AddTrigger(opts =>
{ {
opts.ForJob(nameof(FrozenTorrentJob)) opts.ForJob(nameof(BlockedTorrentJob))
.WithIdentity($"{nameof(FrozenTorrentJob)}-trigger") .WithIdentity($"{nameof(BlockedTorrentJob)}-trigger")
.WithCronSchedule(trigger); .WithCronSchedule(trigger);
}); });
} }
+29
View File
@@ -0,0 +1,29 @@
using Infrastructure.Verticals.BlockedTorrent;
using Quartz;
namespace Executable.Jobs;
[DisallowConcurrentExecution]
public sealed class BlockedTorrentJob : IJob
{
private ILogger<BlockedTorrentJob> _logger;
private BlockedTorrentHandler _handler;
public BlockedTorrentJob(ILogger<BlockedTorrentJob> logger, BlockedTorrentHandler handler)
{
_logger = logger;
_handler = handler;
}
public async Task Execute(IJobExecutionContext context)
{
try
{
await _handler.HandleAsync();
}
catch (Exception ex)
{
_logger.LogError(ex, $"{nameof(BlockedTorrentJob)} failed");
}
}
}
-29
View File
@@ -1,29 +0,0 @@
using Infrastructure.Verticals.FrozenTorrent;
using Quartz;
namespace Executable.Jobs;
[DisallowConcurrentExecution]
public sealed class FrozenTorrentJob : IJob
{
private ILogger<FrozenTorrentJob> _logger;
private FrozenTorrentHandler _handler;
public FrozenTorrentJob(ILogger<FrozenTorrentJob> logger, FrozenTorrentHandler handler)
{
_logger = logger;
_handler = handler;
}
public async Task Execute(IJobExecutionContext context)
{
try
{
await _handler.HandleAsync();
}
catch (Exception ex)
{
_logger.LogError(ex, $"{nameof(FrozenTorrentJob)} failed");
}
}
}
+1 -1
View File
@@ -8,7 +8,7 @@
} }
}, },
"QuartzConfig": { "QuartzConfig": {
"FrozenTorrentTrigger": "0 0/5 * * * ?" "BlockedTorrentTrigger": "0 0/5 * * * ?"
}, },
"QBitConfig": { "QBitConfig": {
"Url": "http://localhost:8080", "Url": "http://localhost:8080",
@@ -1,25 +1,27 @@
using Common.Configuration; using System.Text;
using Common.Configuration;
using Domain.Sonarr.Queue; using Domain.Sonarr.Queue;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options; using Microsoft.Extensions.Options;
using Newtonsoft.Json; using Newtonsoft.Json;
using QBittorrent.Client; using QBittorrent.Client;
namespace Infrastructure.Verticals.FrozenTorrent; namespace Infrastructure.Verticals.BlockedTorrent;
public sealed class FrozenTorrentHandler public sealed class BlockedTorrentHandler
{ {
private readonly ILogger<FrozenTorrentHandler> _logger; private readonly ILogger<BlockedTorrentHandler> _logger;
private readonly QBitConfig _qBitConfig; private readonly QBitConfig _qBitConfig;
private readonly SonarrConfig _sonarrConfig; private readonly SonarrConfig _sonarrConfig;
private readonly HttpClient _httpClient; private readonly HttpClient _httpClient;
private const string SonarListUriTemplate = "/api/v3/queue?page={0}&pageSize=200&sortKey=timeleft"; private const string QueueListPathTemplate = "/api/v3/queue?page={0}&pageSize=200&sortKey=timeleft";
private const string SonarDeleteUriTemplate = "/api/v3/queue/{0}?removeFromClient=true&blocklist=true&skipRedownload=true&changeCategory=false"; private const string QueueDeletePathTemplate = "/api/v3/queue/{0}?removeFromClient=true&blocklist=true&skipRedownload=true&changeCategory=false";
private const string SonarrCommandUriPath = "/api/v3/command";
private const string SearchCommandPayloadTemplate = "{\"name\":\"SeriesSearch\",\"seriesId\":{0}}";
public FrozenTorrentHandler( public BlockedTorrentHandler(
ILogger<FrozenTorrentHandler> logger, ILogger<BlockedTorrentHandler> logger,
IOptions<QBitConfig> qBitConfig, IOptions<QBitConfig> qBitConfig,
IOptions<SonarrConfig> sonarrConfig, IOptions<SonarrConfig> sonarrConfig,
IHttpClientFactory httpClientFactory) IHttpClientFactory httpClientFactory)
@@ -41,10 +43,11 @@ public sealed class FrozenTorrentHandler
ushort page = 1; ushort page = 1;
int totalRecords = 0; int totalRecords = 0;
int processedRecords = 0; int processedRecords = 0;
List<int> seriesToBeRefreshed = [];
do do
{ {
Uri sonarrUri = new(sonarrInstance.Url, string.Format(SonarListUriTemplate, page)); Uri sonarrUri = new(sonarrInstance.Url, string.Format(QueueListPathTemplate, page));
HttpRequestMessage sonarrRequest = new(HttpMethod.Get, sonarrUri); HttpRequestMessage sonarrRequest = new(HttpMethod.Get, sonarrUri);
sonarrRequest.Headers.Add("x-api-key", sonarrInstance.ApiKey); sonarrRequest.Headers.Add("x-api-key", sonarrInstance.ApiKey);
@@ -80,7 +83,9 @@ public sealed class FrozenTorrentHandler
continue; continue;
} }
sonarrUri = new(sonarrInstance.Url, string.Format(SonarDeleteUriTemplate, record.Id)); seriesToBeRefreshed.Add(record.SeriesId);
sonarrUri = new(sonarrInstance.Url, string.Format(QueueDeletePathTemplate, record.Id));
sonarrRequest = new(HttpMethod.Delete, sonarrUri); sonarrRequest = new(HttpMethod.Delete, sonarrUri);
sonarrRequest.Headers.Add("x-api-key", sonarrInstance.ApiKey); sonarrRequest.Headers.Add("x-api-key", sonarrInstance.ApiKey);
@@ -97,6 +102,30 @@ public sealed class FrozenTorrentHandler
} }
} }
foreach (int id in seriesToBeRefreshed)
{
sonarrUri = new(sonarrInstance.Url, SonarrCommandUriPath);
sonarrRequest = new(HttpMethod.Post, sonarrUri);
sonarrRequest.Content = new StringContent(
SearchCommandPayloadTemplate.Replace("{0}", id.ToString()),
Encoding.UTF8,
"application/json"
);
sonarrRequest.Headers.Add("x-api-key", sonarrInstance.ApiKey);
response = await _httpClient.SendAsync(sonarrRequest);
try
{
response.EnsureSuccessStatusCode();
}
catch
{
_logger.LogError("series search failed | series id: {id}", id);
throw;
}
}
if (queueResponse.Records.Count is 0) if (queueResponse.Records.Count is 0)
{ {
break; break;