diff --git a/README.md b/README.md
index 5208f9ea..2a16bab7 100644
--- a/README.md
+++ b/README.md
@@ -59,29 +59,6 @@ This tool is actively developed and still a work in progress. Join the Discord s
## Usage
-### Docker
-
-```
-docker run -d \
- -e TRIGGERS__QUEUECLEANER="0 0/5 * * * ?" \
- -e QBITTORRENT__ENABLED=true \
- -e QBITTORRENT__URL="http://localhost:8080" \
- -e QBITTORRENT__USERNAME="user" \
- -e QBITTORRENT__PASSWORD="pass" \
- -e SONARR__ENABLED=true \
- -e SONARR__INSTANCES__0__URL="http://localhost:8989" \
- -e SONARR__INSTANCES__0__APIKEY="secret1" \
- -e SONARR__INSTANCES__1__URL="http://localhost:8990" \
- -e SONARR__INSTANCES__1__APIKEY="secret2" \
- -e RADARR__ENABLED=true \
- -e RADARR__INSTANCES__0__URL="http://localhost:7878" \
- -e RADARR__INSTANCES__0__APIKEY="secret3" \
- -e RADARR__INSTANCES__1__URL="http://localhost:7879" \
- -e RADARR__INSTANCES__1__APIKEY="secret4" \
- ...
- flaminel/cleanuperr:latest
-```
-
### Docker compose yaml
```
@@ -94,6 +71,7 @@ services:
- LOGGING__LOGLEVEL=Information
- LOGGING__FILE__ENABLED=false
- LOGGING__FILE__PATH=/var/logs/
+ - LOGGING__ENHANCED=true
- TRIGGERS__QUEUECLEANER=0 0/5 * * * ?
- TRIGGERS__CONTENTBLOCKER=0 0/5 * * * ?
@@ -123,6 +101,7 @@ services:
# - TRANSMISSION__PASSWORD=testing
- SONARR__ENABLED=true
+ - SONARR__SEARCHTYPE=Episode
- SONARR__INSTANCES__0__URL=http://localhost:8989
- SONARR__INSTANCES__0__APIKEY=secret1
- SONARR__INSTANCES__1__URL=http://localhost:8990
@@ -133,7 +112,7 @@ services:
- RADARR__INSTANCES__0__APIKEY=secret3
- RADARR__INSTANCES__1__URL=http://localhost:7879
- RADARR__INSTANCES__1__APIKEY=secret4
- image: flaminel/cleanuperr:latest
+ image: ghcr.io/flmorg/cleanuperr:latest
restart: unless-stopped
```
@@ -144,6 +123,7 @@ services:
| LOGGING__LOGLEVEL | No | Can be `Verbose`, `Debug`, `Information`, `Warning`, `Error` or `Fatal` | `Information` |
| LOGGING__FILE__ENABLED | No | Enable or disable logging to file | false |
| LOGGING__FILE__PATH | No | Directory where to save the log files | empty |
+| LOGGING__ENHANCED | No | Enhance logs whenever possible
A more detailed description is provided [here](variables.md#LOGGING__ENHANCED) | true |
|||||
| TRIGGERS__QUEUECLEANER | Yes if queue cleaner is enabled | [Quartz cron trigger](https://www.quartz-scheduler.org/documentation/quartz-2.3.0/tutorials/crontrigger.html) | 0 0/5 * * * ? |
| TRIGGERS__CONTENTBLOCKER | Yes if content blocker is enabled | [Quartz cron trigger](https://www.quartz-scheduler.org/documentation/quartz-2.3.0/tutorials/crontrigger.html) | 0 0/5 * * * ? |
@@ -172,6 +152,7 @@ services:
| TRANSMISSION__PASSWORD | No | Transmission password | empty |
|||||
| SONARR__ENABLED | No | Enable or disable Sonarr cleanup | true |
+| SONARR__SEARCHTYPE | No | What to search for after removing a queue item
Can be `Episode`, `Season` or `Series` | `Episode` |
| SONARR__INSTANCES__0__URL | Yes | First Sonarr instance url | http://localhost:8989 |
| SONARR__INSTANCES__0__APIKEY | Yes | First Sonarr instance API key | empty |
|||||
diff --git a/code/Common/Configuration/ArrConfig.cs b/code/Common/Configuration/Arr/ArrConfig.cs
similarity index 79%
rename from code/Common/Configuration/ArrConfig.cs
rename to code/Common/Configuration/Arr/ArrConfig.cs
index cc28063f..4ecf19a1 100644
--- a/code/Common/Configuration/ArrConfig.cs
+++ b/code/Common/Configuration/Arr/ArrConfig.cs
@@ -1,4 +1,4 @@
-namespace Common.Configuration;
+namespace Common.Configuration.Arr;
public abstract record ArrConfig
{
diff --git a/code/Common/Configuration/ArrInstance.cs b/code/Common/Configuration/Arr/ArrInstance.cs
similarity index 76%
rename from code/Common/Configuration/ArrInstance.cs
rename to code/Common/Configuration/Arr/ArrInstance.cs
index a82f5dcf..eff7e62b 100644
--- a/code/Common/Configuration/ArrInstance.cs
+++ b/code/Common/Configuration/Arr/ArrInstance.cs
@@ -1,4 +1,4 @@
-namespace Common.Configuration;
+namespace Common.Configuration.Arr;
public sealed class ArrInstance
{
diff --git a/code/Common/Configuration/RadarrConfig.cs b/code/Common/Configuration/Arr/RadarrConfig.cs
similarity index 70%
rename from code/Common/Configuration/RadarrConfig.cs
rename to code/Common/Configuration/Arr/RadarrConfig.cs
index 211d422c..6f24c570 100644
--- a/code/Common/Configuration/RadarrConfig.cs
+++ b/code/Common/Configuration/Arr/RadarrConfig.cs
@@ -1,4 +1,4 @@
-namespace Common.Configuration;
+namespace Common.Configuration.Arr;
public sealed record RadarrConfig : ArrConfig
{
diff --git a/code/Common/Configuration/Arr/SonarrConfig.cs b/code/Common/Configuration/Arr/SonarrConfig.cs
new file mode 100644
index 00000000..97518cfb
--- /dev/null
+++ b/code/Common/Configuration/Arr/SonarrConfig.cs
@@ -0,0 +1,8 @@
+namespace Common.Configuration.Arr;
+
+public sealed record SonarrConfig : ArrConfig
+{
+ public const string SectionName = "Sonarr";
+
+ public SonarrSearchType SearchType { get; init; }
+}
\ No newline at end of file
diff --git a/code/Common/Configuration/Arr/SonarrSearchType.cs b/code/Common/Configuration/Arr/SonarrSearchType.cs
new file mode 100644
index 00000000..67fd7541
--- /dev/null
+++ b/code/Common/Configuration/Arr/SonarrSearchType.cs
@@ -0,0 +1,8 @@
+namespace Common.Configuration.Arr;
+
+public enum SonarrSearchType
+{
+ Episode,
+ Season,
+ Series
+}
\ No newline at end of file
diff --git a/code/Common/Configuration/DelugeConfig.cs b/code/Common/Configuration/DownloadClient/DelugeConfig.cs
similarity index 88%
rename from code/Common/Configuration/DelugeConfig.cs
rename to code/Common/Configuration/DownloadClient/DelugeConfig.cs
index dbf283d2..1340e5aa 100644
--- a/code/Common/Configuration/DelugeConfig.cs
+++ b/code/Common/Configuration/DownloadClient/DelugeConfig.cs
@@ -1,6 +1,4 @@
-using System.Security;
-
-namespace Common.Configuration;
+namespace Common.Configuration.DownloadClient;
public sealed record DelugeConfig : IConfig
{
diff --git a/code/Common/Configuration/QBitConfig.cs b/code/Common/Configuration/DownloadClient/QBitConfig.cs
similarity index 85%
rename from code/Common/Configuration/QBitConfig.cs
rename to code/Common/Configuration/DownloadClient/QBitConfig.cs
index 2bfaa2dd..2b1fe674 100644
--- a/code/Common/Configuration/QBitConfig.cs
+++ b/code/Common/Configuration/DownloadClient/QBitConfig.cs
@@ -1,6 +1,4 @@
-using System.ComponentModel.DataAnnotations;
-
-namespace Common.Configuration;
+namespace Common.Configuration.DownloadClient;
public sealed class QBitConfig : IConfig
{
diff --git a/code/Common/Configuration/TransmissionConfig.cs b/code/Common/Configuration/DownloadClient/TransmissionConfig.cs
similarity index 90%
rename from code/Common/Configuration/TransmissionConfig.cs
rename to code/Common/Configuration/DownloadClient/TransmissionConfig.cs
index 6c7ff223..a9e08dfe 100644
--- a/code/Common/Configuration/TransmissionConfig.cs
+++ b/code/Common/Configuration/DownloadClient/TransmissionConfig.cs
@@ -1,4 +1,4 @@
-namespace Common.Configuration;
+namespace Common.Configuration.DownloadClient;
public record TransmissionConfig
{
diff --git a/code/Common/Configuration/Logging/LoggingConfig.cs b/code/Common/Configuration/Logging/LoggingConfig.cs
index 269f0e6a..187a3911 100644
--- a/code/Common/Configuration/Logging/LoggingConfig.cs
+++ b/code/Common/Configuration/Logging/LoggingConfig.cs
@@ -8,6 +8,8 @@ public class LoggingConfig : IConfig
public LogEventLevel LogLevel { get; set; }
+ public bool Enhanced { get; set; }
+
public FileLogConfig? File { get; set; }
public void Validate()
diff --git a/code/Common/Configuration/SonarrConfig.cs b/code/Common/Configuration/SonarrConfig.cs
deleted file mode 100644
index 5735ff39..00000000
--- a/code/Common/Configuration/SonarrConfig.cs
+++ /dev/null
@@ -1,6 +0,0 @@
-namespace Common.Configuration;
-
-public sealed record SonarrConfig : ArrConfig
-{
- public const string SectionName = "Sonarr";
-}
\ No newline at end of file
diff --git a/code/Domain/Models/Arr/Queue/QueueRecord.cs b/code/Domain/Models/Arr/Queue/QueueRecord.cs
index 4af7404b..298fad0a 100644
--- a/code/Domain/Models/Arr/Queue/QueueRecord.cs
+++ b/code/Domain/Models/Arr/Queue/QueueRecord.cs
@@ -4,6 +4,7 @@ public record QueueRecord
{
public int SeriesId { get; init; }
public int EpisodeId { get; init; }
+ public int SeasonNumber { get; init; }
public int MovieId { get; init; }
public required string Title { get; init; }
public string Status { get; init; }
diff --git a/code/Domain/Models/Arr/SearchItem.cs b/code/Domain/Models/Arr/SearchItem.cs
new file mode 100644
index 00000000..c65036d8
--- /dev/null
+++ b/code/Domain/Models/Arr/SearchItem.cs
@@ -0,0 +1,21 @@
+namespace Domain.Models.Arr;
+
+public class SearchItem
+{
+ public long Id { get; set; }
+
+ public override bool Equals(object? obj)
+ {
+ if (obj is not SearchItem other)
+ {
+ return false;
+ }
+
+ return Id == other.Id;
+ }
+
+ public override int GetHashCode()
+ {
+ return Id.GetHashCode();
+ }
+}
\ No newline at end of file
diff --git a/code/Domain/Models/Arr/SonarrSearchItem.cs b/code/Domain/Models/Arr/SonarrSearchItem.cs
new file mode 100644
index 00000000..4ac7eeaa
--- /dev/null
+++ b/code/Domain/Models/Arr/SonarrSearchItem.cs
@@ -0,0 +1,21 @@
+namespace Domain.Models.Arr;
+
+public sealed class SonarrSearchItem : SearchItem
+{
+ public long SeriesId { get; set; }
+
+ public override bool Equals(object? obj)
+ {
+ if (obj is not SonarrSearchItem other)
+ {
+ return false;
+ }
+
+ return Id == other.Id && SeriesId == other.SeriesId;
+ }
+
+ public override int GetHashCode()
+ {
+ return HashCode.Combine(Id, SeriesId);
+ }
+}
\ No newline at end of file
diff --git a/code/Domain/Models/Radarr/Movie.cs b/code/Domain/Models/Radarr/Movie.cs
new file mode 100644
index 00000000..a9a839e6
--- /dev/null
+++ b/code/Domain/Models/Radarr/Movie.cs
@@ -0,0 +1,8 @@
+namespace Domain.Models.Radarr;
+
+public sealed record Movie
+{
+ public required long Id { get; init; }
+
+ public required string Title { get; init; }
+}
\ No newline at end of file
diff --git a/code/Domain/Models/Radarr/RadarrCommand.cs b/code/Domain/Models/Radarr/RadarrCommand.cs
index adf10471..f32a6855 100644
--- a/code/Domain/Models/Radarr/RadarrCommand.cs
+++ b/code/Domain/Models/Radarr/RadarrCommand.cs
@@ -4,5 +4,5 @@ public sealed record RadarrCommand
{
public required string Name { get; init; }
- public required HashSet MovieIds { get; init; }
+ public required List MovieIds { get; init; }
}
\ No newline at end of file
diff --git a/code/Domain/Models/Sonarr/Episode.cs b/code/Domain/Models/Sonarr/Episode.cs
new file mode 100644
index 00000000..2667b73d
--- /dev/null
+++ b/code/Domain/Models/Sonarr/Episode.cs
@@ -0,0 +1,12 @@
+namespace Domain.Models.Sonarr;
+
+public sealed record Episode
+{
+ public long Id { get; set; }
+
+ public int EpisodeNumber { get; set; }
+
+ public int SeasonNumber { get; set; }
+
+ public long SeriesId { get; set; }
+}
\ No newline at end of file
diff --git a/code/Domain/Models/Sonarr/Series.cs b/code/Domain/Models/Sonarr/Series.cs
new file mode 100644
index 00000000..c24cbb58
--- /dev/null
+++ b/code/Domain/Models/Sonarr/Series.cs
@@ -0,0 +1,8 @@
+namespace Domain.Models.Sonarr;
+
+public sealed record Series
+{
+ public required long Id { get; init; }
+
+ public required string Title { get; init; }
+}
\ No newline at end of file
diff --git a/code/Domain/Models/Sonarr/SonarrCommand.cs b/code/Domain/Models/Sonarr/SonarrCommand.cs
index 637b1131..0ff1f3ae 100644
--- a/code/Domain/Models/Sonarr/SonarrCommand.cs
+++ b/code/Domain/Models/Sonarr/SonarrCommand.cs
@@ -2,7 +2,11 @@
public sealed record SonarrCommand
{
- public required string Name { get; init; }
+ public string Name { get; set; }
- public required int SeriesId { get; set; }
+ public long? SeriesId { get; set; }
+
+ public long? SeasonNumber { get; set; }
+
+ public List? EpisodeIds { get; set; }
}
\ No newline at end of file
diff --git a/code/Executable/DependencyInjection/ConfigurationDI.cs b/code/Executable/DependencyInjection/ConfigurationDI.cs
index fee9adad..fd34bc7e 100644
--- a/code/Executable/DependencyInjection/ConfigurationDI.cs
+++ b/code/Executable/DependencyInjection/ConfigurationDI.cs
@@ -1,5 +1,8 @@
using Common.Configuration;
+using Common.Configuration.Arr;
using Common.Configuration.ContentBlocker;
+using Common.Configuration.DownloadClient;
+using Common.Configuration.Logging;
namespace Executable.DependencyInjection;
@@ -12,5 +15,6 @@ public static class ConfigurationDI
.Configure(configuration.GetSection(DelugeConfig.SectionName))
.Configure(configuration.GetSection(TransmissionConfig.SectionName))
.Configure(configuration.GetSection(SonarrConfig.SectionName))
- .Configure(configuration.GetSection(RadarrConfig.SectionName));
+ .Configure(configuration.GetSection(RadarrConfig.SectionName))
+ .Configure(configuration.GetSection(LoggingConfig.SectionName));
}
\ No newline at end of file
diff --git a/code/Executable/appsettings.Development.json b/code/Executable/appsettings.Development.json
index 37bbe3e2..bcc3d338 100644
--- a/code/Executable/appsettings.Development.json
+++ b/code/Executable/appsettings.Development.json
@@ -1,6 +1,7 @@
{
"Logging": {
"LogLevel": "Debug",
+ "Enhanced": true,
"File": {
"Enabled": false,
"Path": ""
@@ -44,6 +45,7 @@
},
"Sonarr": {
"Enabled": true,
+ "SearchType": "Episode",
"Instances": [
{
"Url": "http://localhost:8989",
diff --git a/code/Executable/appsettings.json b/code/Executable/appsettings.json
index a5d54542..c9c6d995 100644
--- a/code/Executable/appsettings.json
+++ b/code/Executable/appsettings.json
@@ -1,6 +1,7 @@
{
"Logging": {
"LogLevel": "Information",
+ "Enhanced": true,
"File": {
"Enabled": false,
"Path": ""
@@ -44,6 +45,7 @@
},
"Sonarr": {
"Enabled": true,
+ "SearchType": "Episode",
"Instances": [
{
"Url": "http://localhost:8989",
diff --git a/code/Infrastructure/Infrastructure.csproj b/code/Infrastructure/Infrastructure.csproj
index 809c810c..4aa497ef 100644
--- a/code/Infrastructure/Infrastructure.csproj
+++ b/code/Infrastructure/Infrastructure.csproj
@@ -1,4 +1,4 @@
-
+
net8.0
@@ -14,7 +14,6 @@
-
diff --git a/code/Infrastructure/Verticals/Arr/ArrClient.cs b/code/Infrastructure/Verticals/Arr/ArrClient.cs
index 18e6fb62..a95bc46c 100644
--- a/code/Infrastructure/Verticals/Arr/ArrClient.cs
+++ b/code/Infrastructure/Verticals/Arr/ArrClient.cs
@@ -1,19 +1,25 @@
using Common.Configuration;
+using Common.Configuration.Arr;
+using Common.Configuration.Logging;
using Domain.Arr.Queue;
+using Domain.Models.Arr;
using Microsoft.Extensions.Logging;
+using Microsoft.Extensions.Options;
using Newtonsoft.Json;
namespace Infrastructure.Verticals.Arr;
public abstract class ArrClient
{
- private protected ILogger _logger;
- private protected HttpClient _httpClient;
+ protected readonly ILogger _logger;
+ protected readonly HttpClient _httpClient;
+ protected readonly LoggingConfig _loggingConfig;
- protected ArrClient(ILogger logger, IHttpClientFactory httpClientFactory)
+ protected ArrClient(ILogger logger, IHttpClientFactory httpClientFactory, IOptions loggingConfig)
{
_logger = logger;
_httpClient = httpClientFactory.CreateClient();
+ _loggingConfig = loggingConfig.Value;
}
public virtual async Task GetQueueItemsAsync(ArrInstance arrInstance, int page)
@@ -68,7 +74,7 @@ public abstract class ArrClient
}
}
- public abstract Task RefreshItemsAsync(ArrInstance arrInstance, HashSet itemIds);
+ public abstract Task RefreshItemsAsync(ArrInstance arrInstance, ArrConfig config, HashSet? items);
protected virtual void SetApiKey(HttpRequestMessage request, string apiKey)
{
diff --git a/code/Infrastructure/Verticals/Arr/ArrQueueIterator.cs b/code/Infrastructure/Verticals/Arr/ArrQueueIterator.cs
index 9f70fe34..d5c01def 100644
--- a/code/Infrastructure/Verticals/Arr/ArrQueueIterator.cs
+++ b/code/Infrastructure/Verticals/Arr/ArrQueueIterator.cs
@@ -1,4 +1,5 @@
using Common.Configuration;
+using Common.Configuration.Arr;
using Domain.Arr.Queue;
using Microsoft.Extensions.Logging;
diff --git a/code/Infrastructure/Verticals/Arr/RadarrClient.cs b/code/Infrastructure/Verticals/Arr/RadarrClient.cs
index 16fe852e..a768a35a 100644
--- a/code/Infrastructure/Verticals/Arr/RadarrClient.cs
+++ b/code/Infrastructure/Verticals/Arr/RadarrClient.cs
@@ -1,30 +1,38 @@
using System.Text;
-using Common.Configuration;
+using Common.Configuration.Arr;
+using Common.Configuration.Logging;
+using Domain.Models.Arr;
using Domain.Models.Radarr;
using Microsoft.Extensions.Logging;
+using Microsoft.Extensions.Options;
using Newtonsoft.Json;
namespace Infrastructure.Verticals.Arr;
public sealed class RadarrClient : ArrClient
{
- public RadarrClient(ILogger logger, IHttpClientFactory httpClientFactory)
- : base(logger, httpClientFactory)
+ public RadarrClient(
+ ILogger logger,
+ IHttpClientFactory httpClientFactory,
+ IOptions loggingConfig
+ ) : base(logger, httpClientFactory, loggingConfig)
{
}
- public override async Task RefreshItemsAsync(ArrInstance arrInstance, HashSet itemIds)
+ public override async Task RefreshItemsAsync(ArrInstance arrInstance, ArrConfig config, HashSet? items)
{
- if (itemIds.Count is 0)
+ if (items?.Count is null or 0)
{
return;
}
+
+ List ids = items.Select(item => item.Id).ToList();
Uri uri = new(arrInstance.Url, "/api/v3/command");
RadarrCommand command = new()
{
Name = "MoviesSearch",
- MovieIds = itemIds
+ MovieIds = ids,
};
using HttpRequestMessage request = new(HttpMethod.Post, uri);
@@ -36,17 +44,72 @@ public sealed class RadarrClient : ArrClient
SetApiKey(request, arrInstance.ApiKey);
using HttpResponseMessage response = await _httpClient.SendAsync(request);
+ string? logContext = await ComputeCommandLogContextAsync(arrInstance, command);
try
{
response.EnsureSuccessStatusCode();
- _logger.LogInformation("movie search triggered | {url} | movie ids: {ids}", arrInstance.Url, string.Join(",", itemIds));
+ _logger.LogInformation("{log}", GetSearchLog(arrInstance.Url, command, true, logContext));
}
catch
{
- _logger.LogError("movie search failed | {url} | movie ids: {ids}", arrInstance.Url, string.Join(",", itemIds));
+ _logger.LogError("{log}", GetSearchLog(arrInstance.Url, command, false, logContext));
throw;
}
}
+
+ private static string GetSearchLog(Uri instanceUrl, RadarrCommand command, bool success, string? logContext)
+ {
+ string status = success ? "triggered" : "failed";
+ string message = logContext ?? $"movie ids: {string.Join(',', command.MovieIds)}";
+
+ return $"movie search {status} | {instanceUrl} | {message}";
+ }
+
+ private async Task ComputeCommandLogContextAsync(ArrInstance arrInstance, RadarrCommand command)
+ {
+ try
+ {
+ if (!_loggingConfig.Enhanced)
+ {
+ return null;
+ }
+
+ StringBuilder log = new();
+
+ foreach (long movieId in command.MovieIds)
+ {
+ Movie? movie = await GetMovie(arrInstance, movieId);
+
+ if (movie is null)
+ {
+ return null;
+ }
+
+ log.Append($"[{movie.Title}]");
+ }
+
+ return log.ToString();
+ }
+ catch (Exception exception)
+ {
+ _logger.LogDebug(exception, "failed to compute log context");
+ }
+
+ return null;
+ }
+
+ private async Task GetMovie(ArrInstance arrInstance, long movieId)
+ {
+ Uri uri = new(arrInstance.Url, $"api/v3/movie/{movieId}");
+ using HttpRequestMessage request = new(HttpMethod.Get, uri);
+ SetApiKey(request, arrInstance.ApiKey);
+
+ using HttpResponseMessage response = await _httpClient.SendAsync(request);
+ response.EnsureSuccessStatusCode();
+
+ string responseBody = await response.Content.ReadAsStringAsync();
+ return JsonConvert.DeserializeObject(responseBody);
+ }
}
\ No newline at end of file
diff --git a/code/Infrastructure/Verticals/Arr/SonarrClient.cs b/code/Infrastructure/Verticals/Arr/SonarrClient.cs
index fd3731ae..307eb155 100644
--- a/code/Infrastructure/Verticals/Arr/SonarrClient.cs
+++ b/code/Infrastructure/Verticals/Arr/SonarrClient.cs
@@ -1,50 +1,244 @@
using System.Text;
-using Common.Configuration;
+using Common.Configuration.Arr;
+using Common.Configuration.Logging;
+using Domain.Models.Arr;
using Domain.Models.Sonarr;
using Microsoft.Extensions.Logging;
+using Microsoft.Extensions.Options;
using Newtonsoft.Json;
namespace Infrastructure.Verticals.Arr;
public sealed class SonarrClient : ArrClient
{
- public SonarrClient(ILogger logger, IHttpClientFactory httpClientFactory)
- : base(logger, httpClientFactory)
+ public SonarrClient(
+ ILogger logger,
+ IHttpClientFactory httpClientFactory,
+ IOptions loggingConfig
+ ) : base(logger, httpClientFactory, loggingConfig)
{
}
- public override async Task RefreshItemsAsync(ArrInstance arrInstance, HashSet itemIds)
+ public override async Task RefreshItemsAsync(ArrInstance arrInstance, ArrConfig config, HashSet? items)
{
- foreach (int itemId in itemIds)
+ if (items?.Count is null or 0)
+ {
+ return;
+ }
+
+ SonarrConfig sonarrConfig = (SonarrConfig)config;
+
+ Uri uri = new(arrInstance.Url, "/api/v3/command");
+
+ foreach (SonarrCommand command in GetSearchCommands(sonarrConfig.SearchType, items))
{
- Uri uri = new(arrInstance.Url, "/api/v3/command");
- SonarrCommand command = new()
- {
- Name = "SeriesSearch",
- SeriesId = itemId
- };
-
using HttpRequestMessage request = new(HttpMethod.Post, uri);
request.Content = new StringContent(
- JsonConvert.SerializeObject(command),
+ JsonConvert.SerializeObject(command, new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore }),
Encoding.UTF8,
"application/json"
);
SetApiKey(request, arrInstance.ApiKey);
using HttpResponseMessage response = await _httpClient.SendAsync(request);
+ string? logContext = await ComputeCommandLogContextAsync(arrInstance, command, sonarrConfig.SearchType);
try
{
response.EnsureSuccessStatusCode();
- _logger.LogInformation("series search triggered | {url} | series id: {id}", arrInstance.Url, itemId);
+ _logger.LogInformation("{log}", GetSearchLog(sonarrConfig.SearchType, arrInstance.Url, command, true, logContext));
}
catch
{
- _logger.LogError("series search failed | {url} | series id: {id}", arrInstance.Url, itemId);
+ _logger.LogError("{log}", GetSearchLog(sonarrConfig.SearchType, arrInstance.Url, command, false, logContext));
throw;
}
}
}
+
+ private static string GetSearchLog(
+ SonarrSearchType searchType,
+ Uri instanceUrl,
+ SonarrCommand command,
+ bool success,
+ string? logContext
+ )
+ {
+ string status = success ? "triggered" : "failed";
+
+ return searchType switch
+ {
+ SonarrSearchType.Episode =>
+ $"episodes search {status} | {instanceUrl} | {logContext ?? $"episode ids: {string.Join(',', command.EpisodeIds)}"}",
+ SonarrSearchType.Season =>
+ $"season search {status} | {instanceUrl} | {logContext ?? $"season: {command.SeasonNumber} series id: {command.SeriesId}"}",
+ SonarrSearchType.Series => $"series search {status} | {instanceUrl} | {logContext ?? $"series id: {command.SeriesId}"}",
+ _ => throw new ArgumentOutOfRangeException(nameof(searchType), searchType, null)
+ };
+ }
+
+ private async Task ComputeCommandLogContextAsync(ArrInstance arrInstance, SonarrCommand command, SonarrSearchType searchType)
+ {
+ try
+ {
+ if (!_loggingConfig.Enhanced)
+ {
+ return null;
+ }
+
+ StringBuilder log = new();
+
+ if (searchType is SonarrSearchType.Episode)
+ {
+ var episodes = await GetEpisodesAsync(arrInstance, command.EpisodeIds);
+
+ if (episodes?.Count is null or 0)
+ {
+ return null;
+ }
+
+ var seriesIds = episodes
+ .Select(x => x.SeriesId)
+ .Distinct()
+ .ToList();
+
+ List series = [];
+
+ foreach (long id in seriesIds)
+ {
+ Series? show = await GetSeriesAsync(arrInstance, id);
+
+ if (show is null)
+ {
+ return null;
+ }
+
+ series.Add(show);
+ }
+
+ foreach (var group in command.EpisodeIds.GroupBy(id => episodes.First(x => x.Id == id).SeriesId))
+ {
+ var show = series.First(x => x.Id == group.Key);
+ var episode = episodes
+ .Where(ep => group.Any(x => x == ep.Id))
+ .OrderBy(x => x.SeasonNumber)
+ .ThenBy(x => x.EpisodeNumber)
+ .Select(x => $"S{x.SeasonNumber.ToString().PadLeft(2, '0')}E{x.EpisodeNumber.ToString().PadLeft(2, '0')}")
+ .ToList();
+
+ log.Append($"[{show.Title} {string.Join(',', episode)}]");
+ }
+ }
+
+ if (searchType is SonarrSearchType.Season)
+ {
+ Series? show = await GetSeriesAsync(arrInstance, command.SeriesId.Value);
+
+ if (show is null)
+ {
+ return null;
+ }
+
+ log.Append($"[{show.Title} season {command.SeasonNumber}]");
+ }
+
+ if (searchType is SonarrSearchType.Series)
+ {
+ Series? show = await GetSeriesAsync(arrInstance, command.SeriesId.Value);
+
+ if (show is null)
+ {
+ return null;
+ }
+
+ log.Append($"[{show.Title}]");
+ }
+
+ return log.ToString();
+ }
+ catch (Exception exception)
+ {
+ _logger.LogDebug(exception, "failed to compute log context");
+ }
+
+ return null;
+ }
+
+ private async Task?> GetEpisodesAsync(ArrInstance arrInstance, List episodeIds)
+ {
+ Uri uri = new(arrInstance.Url, $"api/v3/episode?{string.Join('&', episodeIds.Select(x => $"episodeIds={x}"))}");
+ using HttpRequestMessage request = new(HttpMethod.Get, uri);
+ SetApiKey(request, arrInstance.ApiKey);
+
+ using HttpResponseMessage response = await _httpClient.SendAsync(request);
+ response.EnsureSuccessStatusCode();
+
+ string responseBody = await response.Content.ReadAsStringAsync();
+ return JsonConvert.DeserializeObject>(responseBody);
+ }
+
+ private async Task GetSeriesAsync(ArrInstance arrInstance, long seriesId)
+ {
+ Uri uri = new(arrInstance.Url, $"api/v3/series/{seriesId}");
+ using HttpRequestMessage request = new(HttpMethod.Get, uri);
+ SetApiKey(request, arrInstance.ApiKey);
+
+ using HttpResponseMessage response = await _httpClient.SendAsync(request);
+ response.EnsureSuccessStatusCode();
+
+ string responseBody = await response.Content.ReadAsStringAsync();
+ return JsonConvert.DeserializeObject(responseBody);
+ }
+
+ private List GetSearchCommands(SonarrSearchType searchType, HashSet items)
+ {
+ const string episodeSearch = "EpisodeSearch";
+ const string seasonSearch = "SeasonSearch";
+ const string seriesSearch = "SeriesSearch";
+
+ List commands = new();
+
+ foreach (SearchItem item in items)
+ {
+ SonarrCommand command = searchType is SonarrSearchType.Episode
+ ? commands.FirstOrDefault() ?? new() { Name = episodeSearch, EpisodeIds = new() }
+ : new();
+
+ switch (searchType)
+ {
+ case SonarrSearchType.Episode when command.EpisodeIds is null:
+ command.EpisodeIds = [item.Id];
+ break;
+
+ case SonarrSearchType.Episode when command.EpisodeIds is not null:
+ command.EpisodeIds.Add(item.Id);
+ break;
+
+ case SonarrSearchType.Season:
+ command.Name = seasonSearch;
+ command.SeasonNumber = item.Id;
+ command.SeriesId = ((SonarrSearchItem)item).SeriesId;
+ break;
+
+ case SonarrSearchType.Series:
+ command.Name = seriesSearch;
+ command.SeriesId = item.Id;
+ break;
+
+ default:
+ throw new ArgumentOutOfRangeException(nameof(searchType), searchType, null);
+ }
+
+ if (searchType is SonarrSearchType.Episode && commands.Count > 0)
+ {
+ // only one command will be generated for episodes search
+ continue;
+ }
+
+ commands.Add(command);
+ }
+
+ return commands;
+ }
}
\ No newline at end of file
diff --git a/code/Infrastructure/Verticals/ContentBlocker/ContentBlocker.cs b/code/Infrastructure/Verticals/ContentBlocker/ContentBlocker.cs
index 590b0cfd..880530f8 100644
--- a/code/Infrastructure/Verticals/ContentBlocker/ContentBlocker.cs
+++ b/code/Infrastructure/Verticals/ContentBlocker/ContentBlocker.cs
@@ -1,4 +1,5 @@
using Common.Configuration;
+using Common.Configuration.Arr;
using Domain.Arr.Queue;
using Domain.Enums;
using Infrastructure.Verticals.Arr;
diff --git a/code/Infrastructure/Verticals/DownloadClient/Deluge/DelugeClient.cs b/code/Infrastructure/Verticals/DownloadClient/Deluge/DelugeClient.cs
index 94dc678f..45194f94 100644
--- a/code/Infrastructure/Verticals/DownloadClient/Deluge/DelugeClient.cs
+++ b/code/Infrastructure/Verticals/DownloadClient/Deluge/DelugeClient.cs
@@ -1,6 +1,7 @@
using System.Net.Http.Headers;
using System.Text.Json.Serialization;
using Common.Configuration;
+using Common.Configuration.DownloadClient;
using Domain.Models.Deluge.Exceptions;
using Domain.Models.Deluge.Request;
using Domain.Models.Deluge.Response;
diff --git a/code/Infrastructure/Verticals/DownloadClient/Deluge/DelugeService.cs b/code/Infrastructure/Verticals/DownloadClient/Deluge/DelugeService.cs
index c87ae05c..a3293586 100644
--- a/code/Infrastructure/Verticals/DownloadClient/Deluge/DelugeService.cs
+++ b/code/Infrastructure/Verticals/DownloadClient/Deluge/DelugeService.cs
@@ -1,4 +1,5 @@
using Common.Configuration;
+using Common.Configuration.DownloadClient;
using Domain.Models.Deluge.Response;
using Infrastructure.Verticals.ContentBlocker;
using Microsoft.Extensions.Logging;
diff --git a/code/Infrastructure/Verticals/DownloadClient/DownloadServiceFactory.cs b/code/Infrastructure/Verticals/DownloadClient/DownloadServiceFactory.cs
index 89e5f9ae..6f90fad7 100644
--- a/code/Infrastructure/Verticals/DownloadClient/DownloadServiceFactory.cs
+++ b/code/Infrastructure/Verticals/DownloadClient/DownloadServiceFactory.cs
@@ -1,4 +1,5 @@
using Common.Configuration;
+using Common.Configuration.DownloadClient;
using Infrastructure.Verticals.DownloadClient.Deluge;
using Infrastructure.Verticals.DownloadClient.QBittorrent;
using Infrastructure.Verticals.DownloadClient.Transmission;
diff --git a/code/Infrastructure/Verticals/DownloadClient/QBittorrent/QBitService.cs b/code/Infrastructure/Verticals/DownloadClient/QBittorrent/QBitService.cs
index 3e4fef09..1f2e4b03 100644
--- a/code/Infrastructure/Verticals/DownloadClient/QBittorrent/QBitService.cs
+++ b/code/Infrastructure/Verticals/DownloadClient/QBittorrent/QBitService.cs
@@ -1,4 +1,5 @@
using Common.Configuration;
+using Common.Configuration.DownloadClient;
using Infrastructure.Verticals.ContentBlocker;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
diff --git a/code/Infrastructure/Verticals/DownloadClient/Transmission/TransmissionService.cs b/code/Infrastructure/Verticals/DownloadClient/Transmission/TransmissionService.cs
index 130f828b..ecdd5b50 100644
--- a/code/Infrastructure/Verticals/DownloadClient/Transmission/TransmissionService.cs
+++ b/code/Infrastructure/Verticals/DownloadClient/Transmission/TransmissionService.cs
@@ -1,4 +1,5 @@
using Common.Configuration;
+using Common.Configuration.DownloadClient;
using Infrastructure.Verticals.ContentBlocker;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
diff --git a/code/Infrastructure/Verticals/Jobs/GenericHandler.cs b/code/Infrastructure/Verticals/Jobs/GenericHandler.cs
index 7cf6798c..e089b0e7 100644
--- a/code/Infrastructure/Verticals/Jobs/GenericHandler.cs
+++ b/code/Infrastructure/Verticals/Jobs/GenericHandler.cs
@@ -1,6 +1,7 @@
-using Common.Configuration;
+using Common.Configuration.Arr;
using Domain.Arr.Queue;
using Domain.Enums;
+using Domain.Models.Arr;
using Infrastructure.Verticals.Arr;
using Infrastructure.Verticals.DownloadClient;
using Microsoft.Extensions.Logging;
@@ -51,7 +52,7 @@ public abstract class GenericHandler : IDisposable
protected abstract Task ProcessInstanceAsync(ArrInstance instance, InstanceType instanceType);
- protected async Task ProcessArrConfigAsync(ArrConfig config, InstanceType instanceType)
+ private async Task ProcessArrConfigAsync(ArrConfig config, InstanceType instanceType)
{
if (!config.Enabled)
{
@@ -78,13 +79,36 @@ public abstract class GenericHandler : IDisposable
InstanceType.Radarr => _radarrClient,
_ => throw new NotImplementedException($"instance type {type} is not yet supported")
};
-
- protected int GetRecordId(InstanceType type, QueueRecord record) =>
+
+ protected ArrConfig GetConfig(InstanceType type) =>
type switch
{
- // TODO add episode id
- InstanceType.Sonarr => record.SeriesId,
- InstanceType.Radarr => record.MovieId,
+ InstanceType.Sonarr => _sonarrConfig,
+ InstanceType.Radarr => _radarrConfig,
+ _ => throw new NotImplementedException($"instance type {type} is not yet supported")
+ };
+
+ protected SearchItem GetRecordSearchItem(InstanceType type, QueueRecord record) =>
+ type switch
+ {
+ InstanceType.Sonarr when _sonarrConfig.SearchType is SonarrSearchType.Episode => new SonarrSearchItem
+ {
+ Id = record.EpisodeId,
+ SeriesId = record.SeriesId
+ },
+ InstanceType.Sonarr when _sonarrConfig.SearchType is SonarrSearchType.Season => new SonarrSearchItem
+ {
+ Id = record.SeasonNumber,
+ SeriesId = record.SeriesId
+ },
+ InstanceType.Sonarr when _sonarrConfig.SearchType is SonarrSearchType.Series => new SonarrSearchItem
+ {
+ Id = record.SeriesId,
+ },
+ InstanceType.Radarr => new SearchItem
+ {
+ Id = record.MovieId,
+ },
_ => throw new NotImplementedException($"instance type {type} is not yet supported")
};
}
\ No newline at end of file
diff --git a/code/Infrastructure/Verticals/QueueCleaner/QueueCleaner.cs b/code/Infrastructure/Verticals/QueueCleaner/QueueCleaner.cs
index c2220ecc..e9e7ae15 100644
--- a/code/Infrastructure/Verticals/QueueCleaner/QueueCleaner.cs
+++ b/code/Infrastructure/Verticals/QueueCleaner/QueueCleaner.cs
@@ -1,6 +1,8 @@
using Common.Configuration;
+using Common.Configuration.Arr;
using Domain.Arr.Queue;
using Domain.Enums;
+using Domain.Models.Arr;
using Infrastructure.Verticals.Arr;
using Infrastructure.Verticals.DownloadClient;
using Infrastructure.Verticals.Jobs;
@@ -25,7 +27,7 @@ public sealed class QueueCleaner : GenericHandler
protected override async Task ProcessInstanceAsync(ArrInstance instance, InstanceType instanceType)
{
- HashSet itemsToBeRefreshed = [];
+ HashSet itemsToBeRefreshed = [];
ArrClient arrClient = GetClient(instanceType);
await _arrArrQueueIterator.Iterate(arrClient, instance, async items =>
@@ -49,12 +51,12 @@ public sealed class QueueCleaner : GenericHandler
continue;
}
- itemsToBeRefreshed.Add(GetRecordId(instanceType, record));
+ itemsToBeRefreshed.Add(GetRecordSearchItem(instanceType, record));
await arrClient.DeleteQueueItemAsync(instance, record);
}
});
- await arrClient.RefreshItemsAsync(instance, itemsToBeRefreshed);
+ await arrClient.RefreshItemsAsync(instance, GetConfig(instanceType), itemsToBeRefreshed);
}
}
\ No newline at end of file
diff --git a/code/test/data/nginx/radarr_bad_single.xml b/code/test/data/nginx/radarr.xml
similarity index 63%
rename from code/test/data/nginx/radarr_bad_single.xml
rename to code/test/data/nginx/radarr.xml
index 067cfe88..87b5e427 100644
--- a/code/test/data/nginx/radarr_bad_single.xml
+++ b/code/test/data/nginx/radarr.xml
@@ -1,7 +1,7 @@
Test feed
- http://nginx/custom/radarr_bad_single.xml
+ http://nginx/custom/radarr.xml
Test
@@ -11,6 +11,17 @@
Tue, 5 Nov 2024 22:02:13 -0400
https://validator.w3.org/feed/docs/rss2.html
30
+ -
+ Speak.No.Evil.2024.2160p.MA.WEB-DL.DDP5.1.Atmos.H.265-HHWEB
+ Test
+ 4138858110
+ http://nginx/custom/radarr_bad_nested.torrent
+
+ 174674a88c8927f6f9057ac3f81efde384ed216cade43564ec450f2cb4677554
+
+ Sat, 24 Sep 2022 22:02:13 -0300
+
+
-
The.Wild.Robot.2024.2160p.AMZN.WEB-DL.DDP5.1.Atmos.H.265-FLUX
Test
diff --git a/code/test/data/nginx/radarr_bad_nested.xml b/code/test/data/nginx/radarr_bad_nested.xml
deleted file mode 100644
index e886aa4d..00000000
--- a/code/test/data/nginx/radarr_bad_nested.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-
-
- Test feed
- http://nginx/custom/radarr_bad_nested.xml
-
- Test
-
- en-CA
- Test
- Tue, 5 Nov 2024 22:02:13 -0400
- Tue, 5 Nov 2024 22:02:13 -0400
- https://validator.w3.org/feed/docs/rss2.html
- 30
-
-
- Speak.No.Evil.2024.2160p.MA.WEB-DL.DDP5.1.Atmos.H.265-HHWEB
- Test
- 4138858110
- http://nginx/custom/radarr_bad_nested.torrent
-
- 174674a88c8947f6f9057ac3f81efde384ed216cade43564ec450f2cb4677554
-
- Sat, 24 Sep 2022 22:02:13 -0300
-
-
-
\ No newline at end of file
diff --git a/code/test/data/nginx/sonarr.xml b/code/test/data/nginx/sonarr.xml
new file mode 100644
index 00000000..344d8fbf
--- /dev/null
+++ b/code/test/data/nginx/sonarr.xml
@@ -0,0 +1,69 @@
+
+
+ Test feed
+ http://nginx/custom/sonarr.xml
+
+ Test
+
+ en-CA
+ Test
+ Tue, 5 Nov 2024 22:02:13 -0400
+ Tue, 5 Nov 2024 22:02:13 -0400
+ https://validator.w3.org/feed/docs/rss2.html
+ 30
+ -
+ Agatha.All.Along.S01E01.Seekest.Thou.the.Road.2160p.APPS.WEB-DL.DDP5.1.Atmos.H.265-VARYG
+ Test
+ 4138858110
+ http://nginx/custom/sonarr_bad_nested.torrent
+
+ 174674a88c8947f6f9057a23f81efde384ed216cade43564ec450f2cb4677554
+
+ Sat, 24 Sep 2022 22:02:13 -0300
+
+
+ -
+ Agatha.All.Along.S01E02.Circle.Sewn.With.Fate.Unlock.Thy.Hidden.Gate.2160p.DSNP.WEB-DL.DDP5.1.Atmos.DV.HDR.H.265-FLUX
+ Test
+ 4138858110
+ http://nginx/custom/sonarr_bad_single.torrent
+
+ 174674a88c8947f689057ac3f81efde384ed216cade43564ec450f2cb4677554
+
+ Sat, 24 Sep 2022 22:02:13 -0300
+
+
+ -
+ Top.Gear.S23E01.720p.x265.HDTV.HEVC.-.YSTEAM
+ Test
+ 4138858110
+ magnet:?xt=urn:btih:cf82cf859b110af0ad3d94b846e006828417b193&dn=TPG.2301.720p.x265.yourserie.com.mkv
+
+ 174674a88c8947f6f5057ac3f81efde384ed216cade43564ec450f2cb4677554
+
+ Sat, 24 Sep 2022 22:02:13 -0300
+
+
+ -
+ Top.Gear.S23E01.720p.x265.HDTV.HEVC.-.YSTEAM
+ Test
+ 4138858110
+ http://nginx/custom/sonarr_bad_stuck_stalled.torrent
+
+ 174674a88c8947f6f9057ac3f81efde384ed216cade43564ec450f2cb4677554
+
+ Sat, 24 Sep 2022 22:02:13 -0300
+
+
+ -
+ Top.Gear.S23E02.720p.x265.HDTV.HEVC.-.YSTEAM
+ Test
+ 4138858110
+ http://nginx/custom/sonarr_bad_nested_top.torrent
+
+ 174674a88c8947f6f9057ac3f82efde384ed216cade43564ec450f2cb4677554
+
+ Sat, 24 Sep 2022 22:02:13 -0300
+
+
+
\ No newline at end of file
diff --git a/code/test/data/nginx/sonarr_bad_nested.xml b/code/test/data/nginx/sonarr_bad_nested.xml
deleted file mode 100644
index 4d8a2b95..00000000
--- a/code/test/data/nginx/sonarr_bad_nested.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-
-
- Test feed
- http://nginx/custom/sonarr_bad_nested.xml
-
- Test
-
- en-CA
- Test
- Tue, 5 Nov 2024 22:02:13 -0400
- Tue, 5 Nov 2024 22:02:13 -0400
- https://validator.w3.org/feed/docs/rss2.html
- 30
- -
- Agatha.All.Along.S01E01.Seekest.Thou.the.Road.2160p.APPS.WEB-DL.DDP5.1.Atmos.H.265-VARYG
- Test
- 4138858110
- http://nginx/custom/sonarr_bad_nested.torrent
-
- 174674a88c8947f6f9057ac3f81efde384ed216cade43564ec450f2cb4677554
-
- Sat, 24 Sep 2022 22:02:13 -0300
-
-
-
\ No newline at end of file
diff --git a/code/test/data/nginx/sonarr_bad_nested_top.torrent b/code/test/data/nginx/sonarr_bad_nested_top.torrent
new file mode 100644
index 00000000..d7f5a45d
--- /dev/null
+++ b/code/test/data/nginx/sonarr_bad_nested_top.torrent
@@ -0,0 +1 @@
+d8:announce28:http://tracker:6969/announce10:created by26:Enhanced-CTorrent/dnh3.3.213:creation datei1732896923e4:infod5:filesld6:lengthi2604e4:pathl4:Dir15:Dir1111:test11.zipxeed6:lengthi2604e4:pathl4:Dir110:sample.txteed6:lengthi2604e4:pathl4:Dir210:test2.zipxeed6:lengthi2604e4:pathl9:test.zipxeed6:lengthi2604e4:pathl49:Top.Gear.S23E02.720p.x265.HDTV.HEVC.-.YSTEAM.zipxeee4:name44:Top.Gear.S23E02.720p.x265.HDTV.HEVC.-.YSTEAM12:piece lengthi262144e6:pieces20:w¤ŸÌ³RÇþ'6Fíoð}ä°ee
\ No newline at end of file
diff --git a/code/test/data/nginx/sonarr_bad_single.xml b/code/test/data/nginx/sonarr_bad_single.xml
deleted file mode 100644
index f2fc59ff..00000000
--- a/code/test/data/nginx/sonarr_bad_single.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-
-
- Test feed
- http://nginx/custom/sonarr_bad_single.xml
-
- Test
-
- en-CA
- Test
- Tue, 5 Nov 2024 22:02:13 -0400
- Tue, 5 Nov 2024 22:02:13 -0400
- https://validator.w3.org/feed/docs/rss2.html
- 30
- -
- Agatha.All.Along.S01E02.Circle.Sewn.With.Fate.Unlock.Thy.Hidden.Gate.2160p.DSNP.WEB-DL.DDP5.1.Atmos.DV.HDR.H.265-FLUX
- Test
- 4138858110
- http://nginx/custom/sonarr_bad_single.torrent
-
- 174674a88c8947f6f9057ac3f81efde384ed216cade43564ec450f2cb4677554
-
- Sat, 24 Sep 2022 22:02:13 -0300
-
-
-
\ No newline at end of file
diff --git a/code/test/data/nginx/sonarr_bad_stuck_metadata.xml b/code/test/data/nginx/sonarr_bad_stuck_metadata.xml
deleted file mode 100644
index 844991b1..00000000
--- a/code/test/data/nginx/sonarr_bad_stuck_metadata.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-
-
- Test feed
- http://nginx/custom/sonarr_bad_stuck_metadata.xml
-
- Test
-
- en-CA
- Test
- Tue, 5 Nov 2024 22:02:13 -0400
- Tue, 5 Nov 2024 22:02:13 -0400
- https://validator.w3.org/feed/docs/rss2.html
- 30
- -
- Top.Gear.S23E01.720p.x265.HDTV.HEVC.-.YSTEAM
- Test
- 4138858110
- magnet:?xt=urn:btih:cf82cf859b110af0ad3d94b846e006828417b193&dn=TPG.2301.720p.x265.yourserie.com.mkv
-
- 174674a88c8947f6f9057ac3f81efde384ed216cade43564ec450f2cb4677554
-
- Sat, 24 Sep 2022 22:02:13 -0300
-
-
-
\ No newline at end of file
diff --git a/code/test/data/nginx/sonarr_bad_stuck_stalled.xml b/code/test/data/nginx/sonarr_bad_stuck_stalled.xml
deleted file mode 100644
index beaf53bc..00000000
--- a/code/test/data/nginx/sonarr_bad_stuck_stalled.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-
-
- Test feed
- http://nginx/custom/sonarr_bad_stuck_metadata.xml
-
- Test
-
- en-CA
- Test
- Tue, 5 Nov 2024 22:02:13 -0400
- Tue, 5 Nov 2024 22:02:13 -0400
- https://validator.w3.org/feed/docs/rss2.html
- 30
- -
- Top.Gear.S23E01.720p.x265.HDTV.HEVC.-.YSTEAM
- Test
- 4138858110
- http://nginx/custom/sonarr_bad_stuck_stalled.torrent
-
- 174674a88c8947f6f9057ac3f81efde384ed216cade43564ec450f2cb4677554
-
- Sat, 24 Sep 2022 22:02:13 -0300
-
-
-
\ No newline at end of file
diff --git a/code/test/data/qbittorrent-bad/config/qBittorrent/BT_backup/queue b/code/test/data/qbittorrent-bad/config/qBittorrent/BT_backup/queue
index 62a4727a..a528236f 100644
--- a/code/test/data/qbittorrent-bad/config/qBittorrent/BT_backup/queue
+++ b/code/test/data/qbittorrent-bad/config/qBittorrent/BT_backup/queue
@@ -1,4 +1,5 @@
-b72541215214be2a1d96ef6b29ca1305f5e5e1f6
-a4a1d1dd1db25763caa8f5e4d25ad72ef304094b
2b2ec156461d77bc48b8fe4d62cede50dcdff8e0
+a4a1d1dd1db25763caa8f5e4d25ad72ef304094b
+b72541215214be2a1d96ef6b29ca1305f5e5e1f6
59ab2bc053430fe53e06a93e2eadb7acb6a6bf2c
+11cece7f8721c484126b66f609d52738ff1bbf1e
diff --git a/code/test/data/qbittorrent-bad/config/qBittorrent/qBittorrent-data.conf b/code/test/data/qbittorrent-bad/config/qBittorrent/qBittorrent-data.conf
index 2cd31648..66611c87 100644
--- a/code/test/data/qbittorrent-bad/config/qBittorrent/qBittorrent-data.conf
+++ b/code/test/data/qbittorrent-bad/config/qBittorrent/qBittorrent-data.conf
@@ -1,2 +1,2 @@
[Stats]
-AllStats=@Variant(\0\0\0\x1c\0\0\0\x2\0\0\0\x12\0\x41\0l\0l\0t\0i\0m\0\x65\0\x44\0L\0\0\0\x4\0\0\0\0\0\x61La\0\0\0\x12\0\x41\0l\0l\0t\0i\0m\0\x65\0U\0L\0\0\0\x4\0\0\0\0\0\x9bGV)
+AllStats=@Variant(\0\0\0\x1c\0\0\0\x2\0\0\0\x12\0\x41\0l\0l\0t\0i\0m\0\x65\0\x44\0L\0\0\0\x4\0\0\0\0\0\x61\xc0\xdf\0\0\0\x12\0\x41\0l\0l\0t\0i\0m\0\x65\0U\0L\0\0\0\x4\0\0\0\0\0\x9b\xf9\x8a)
diff --git a/code/test/data/qbittorrent-bad/downloads/Top.Gear.S23E02.720p.x265.HDTV.HEVC.-.YSTEAM/Dir1/Dir11/test11.zipx b/code/test/data/qbittorrent-bad/downloads/Top.Gear.S23E02.720p.x265.HDTV.HEVC.-.YSTEAM/Dir1/Dir11/test11.zipx
new file mode 100644
index 00000000..69aeb573
--- /dev/null
+++ b/code/test/data/qbittorrent-bad/downloads/Top.Gear.S23E02.720p.x265.HDTV.HEVC.-.YSTEAM/Dir1/Dir11/test11.zipx
@@ -0,0 +1 @@
+testtesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttest
\ No newline at end of file
diff --git a/code/test/data/qbittorrent-bad/downloads/Top.Gear.S23E02.720p.x265.HDTV.HEVC.-.YSTEAM/Dir1/sample.txt b/code/test/data/qbittorrent-bad/downloads/Top.Gear.S23E02.720p.x265.HDTV.HEVC.-.YSTEAM/Dir1/sample.txt
new file mode 100644
index 00000000..69aeb573
--- /dev/null
+++ b/code/test/data/qbittorrent-bad/downloads/Top.Gear.S23E02.720p.x265.HDTV.HEVC.-.YSTEAM/Dir1/sample.txt
@@ -0,0 +1 @@
+testtesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttest
\ No newline at end of file
diff --git a/code/test/data/qbittorrent-bad/downloads/Top.Gear.S23E02.720p.x265.HDTV.HEVC.-.YSTEAM/Dir2/test2.zipx b/code/test/data/qbittorrent-bad/downloads/Top.Gear.S23E02.720p.x265.HDTV.HEVC.-.YSTEAM/Dir2/test2.zipx
new file mode 100644
index 00000000..69aeb573
--- /dev/null
+++ b/code/test/data/qbittorrent-bad/downloads/Top.Gear.S23E02.720p.x265.HDTV.HEVC.-.YSTEAM/Dir2/test2.zipx
@@ -0,0 +1 @@
+testtesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttest
\ No newline at end of file
diff --git a/code/test/data/qbittorrent-bad/downloads/Top.Gear.S23E02.720p.x265.HDTV.HEVC.-.YSTEAM/Top.Gear.S23E02.720p.x265.HDTV.HEVC.-.YSTEAM.zipx b/code/test/data/qbittorrent-bad/downloads/Top.Gear.S23E02.720p.x265.HDTV.HEVC.-.YSTEAM/Top.Gear.S23E02.720p.x265.HDTV.HEVC.-.YSTEAM.zipx
new file mode 100644
index 00000000..69aeb573
--- /dev/null
+++ b/code/test/data/qbittorrent-bad/downloads/Top.Gear.S23E02.720p.x265.HDTV.HEVC.-.YSTEAM/Top.Gear.S23E02.720p.x265.HDTV.HEVC.-.YSTEAM.zipx
@@ -0,0 +1 @@
+testtesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttest
\ No newline at end of file
diff --git a/code/test/data/qbittorrent-bad/downloads/Top.Gear.S23E02.720p.x265.HDTV.HEVC.-.YSTEAM/test.zipx b/code/test/data/qbittorrent-bad/downloads/Top.Gear.S23E02.720p.x265.HDTV.HEVC.-.YSTEAM/test.zipx
new file mode 100644
index 00000000..69aeb573
--- /dev/null
+++ b/code/test/data/qbittorrent-bad/downloads/Top.Gear.S23E02.720p.x265.HDTV.HEVC.-.YSTEAM/test.zipx
@@ -0,0 +1 @@
+testtesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttest
\ No newline at end of file
diff --git a/code/test/data/qbittorrent-bad/downloads/sonarr_bad_nested_top.torrent b/code/test/data/qbittorrent-bad/downloads/sonarr_bad_nested_top.torrent
new file mode 100644
index 00000000..d7f5a45d
--- /dev/null
+++ b/code/test/data/qbittorrent-bad/downloads/sonarr_bad_nested_top.torrent
@@ -0,0 +1 @@
+d8:announce28:http://tracker:6969/announce10:created by26:Enhanced-CTorrent/dnh3.3.213:creation datei1732896923e4:infod5:filesld6:lengthi2604e4:pathl4:Dir15:Dir1111:test11.zipxeed6:lengthi2604e4:pathl4:Dir110:sample.txteed6:lengthi2604e4:pathl4:Dir210:test2.zipxeed6:lengthi2604e4:pathl9:test.zipxeed6:lengthi2604e4:pathl49:Top.Gear.S23E02.720p.x265.HDTV.HEVC.-.YSTEAM.zipxeee4:name44:Top.Gear.S23E02.720p.x265.HDTV.HEVC.-.YSTEAM12:piece lengthi262144e6:pieces20:w¤ŸÌ³RÇþ'6Fíoð}ä°ee
\ No newline at end of file
diff --git a/code/test/data/radarr/config/Sentry/E052B02F117E6BB423BE301CDA607148F4B3F8F6/.session b/code/test/data/radarr/config/Sentry/E052B02F117E6BB423BE301CDA607148F4B3F8F6/.session
index b41d6d29..4a19a599 100644
--- a/code/test/data/radarr/config/Sentry/E052B02F117E6BB423BE301CDA607148F4B3F8F6/.session
+++ b/code/test/data/radarr/config/Sentry/E052B02F117E6BB423BE301CDA607148F4B3F8F6/.session
@@ -1 +1 @@
-{"update":{"sid":"87056ff6106c4bcf8fc90506d02be642","did":"92eba3c5-a8d0-44d5-836d-25bc4aa81a85","init":true,"started":"2024-11-20T08:51:02.9022577+00:00","timestamp":"2024-11-20T08:51:02.902865+00:00","seq":0,"duration":0,"errors":0,"attrs":{"release":"Radarr@5.14.0.9383-master","environment":"master"}}}
\ No newline at end of file
+{"update":{"sid":"743459ae24ef4f4c8a85171b21fd99a8","did":"92eba3c5-a8d0-44d5-836d-25bc4aa81a85","init":true,"started":"2024-11-29T15:46:38.3721409+00:00","timestamp":"2024-11-29T15:46:38.3728803+00:00","seq":0,"duration":0,"errors":0,"attrs":{"release":"Radarr@5.14.0.9383-master","environment":"master"}}}
\ No newline at end of file
diff --git a/code/test/data/radarr/config/logs.db b/code/test/data/radarr/config/logs.db
index f54141c6..c9c10305 100644
Binary files a/code/test/data/radarr/config/logs.db and b/code/test/data/radarr/config/logs.db differ
diff --git a/code/test/data/radarr/config/logs.db-shm b/code/test/data/radarr/config/logs.db-shm
index e68b0f22..d8cff9df 100644
Binary files a/code/test/data/radarr/config/logs.db-shm and b/code/test/data/radarr/config/logs.db-shm differ
diff --git a/code/test/data/radarr/config/logs.db-wal b/code/test/data/radarr/config/logs.db-wal
index fa1975fb..9db9795a 100644
Binary files a/code/test/data/radarr/config/logs.db-wal and b/code/test/data/radarr/config/logs.db-wal differ
diff --git a/code/test/data/radarr/config/radarr.db b/code/test/data/radarr/config/radarr.db
index f1d6a6f4..6a160d1c 100644
Binary files a/code/test/data/radarr/config/radarr.db and b/code/test/data/radarr/config/radarr.db differ
diff --git a/code/test/data/radarr/config/radarr.pid b/code/test/data/radarr/config/radarr.pid
index aca544d0..70e1a64c 100644
--- a/code/test/data/radarr/config/radarr.pid
+++ b/code/test/data/radarr/config/radarr.pid
@@ -1 +1 @@
-145
\ No newline at end of file
+144
\ No newline at end of file
diff --git a/code/test/data/sonarr/config/Sentry/07ADDC43B5669C4F6DB64F2EF2B23B3FEEDFE865/.session b/code/test/data/sonarr/config/Sentry/07ADDC43B5669C4F6DB64F2EF2B23B3FEEDFE865/.session
deleted file mode 100644
index 2a08410f..00000000
--- a/code/test/data/sonarr/config/Sentry/07ADDC43B5669C4F6DB64F2EF2B23B3FEEDFE865/.session
+++ /dev/null
@@ -1 +0,0 @@
-{"update":{"sid":"726ab1cef3114e11a386851d89cb6de4","did":"1df9f2cc-17dc-4130-9753-9b694f82f1b5","init":true,"started":"2024-11-20T08:51:02.5386604+00:00","timestamp":"2024-11-20T08:51:02.5393706+00:00","seq":0,"duration":0,"errors":0,"attrs":{"release":"4.0.10.2544-main","environment":"main"}}}
\ No newline at end of file
diff --git a/code/test/data/sonarr/config/logs.db b/code/test/data/sonarr/config/logs.db
index 79e73451..6999d2eb 100644
Binary files a/code/test/data/sonarr/config/logs.db and b/code/test/data/sonarr/config/logs.db differ
diff --git a/code/test/data/sonarr/config/logs.db-shm b/code/test/data/sonarr/config/logs.db-shm
index 0a956093..9617b44b 100644
Binary files a/code/test/data/sonarr/config/logs.db-shm and b/code/test/data/sonarr/config/logs.db-shm differ
diff --git a/code/test/data/sonarr/config/logs.db-wal b/code/test/data/sonarr/config/logs.db-wal
index 1aadb493..25ae7297 100644
Binary files a/code/test/data/sonarr/config/logs.db-wal and b/code/test/data/sonarr/config/logs.db-wal differ
diff --git a/code/test/data/sonarr/config/sonarr.db b/code/test/data/sonarr/config/sonarr.db
index 50232a60..5db88d2c 100644
Binary files a/code/test/data/sonarr/config/sonarr.db and b/code/test/data/sonarr/config/sonarr.db differ
diff --git a/code/test/data/sonarr/config/sonarr.db-shm b/code/test/data/sonarr/config/sonarr.db-shm
index bf739ed6..be74b3a2 100644
Binary files a/code/test/data/sonarr/config/sonarr.db-shm and b/code/test/data/sonarr/config/sonarr.db-shm differ
diff --git a/code/test/data/sonarr/config/sonarr.db-wal b/code/test/data/sonarr/config/sonarr.db-wal
index 7b46287a..475ce064 100644
Binary files a/code/test/data/sonarr/config/sonarr.db-wal and b/code/test/data/sonarr/config/sonarr.db-wal differ
diff --git a/code/test/data/sonarr/config/sonarr.pid b/code/test/data/sonarr/config/sonarr.pid
index aca544d0..bc768da7 100644
--- a/code/test/data/sonarr/config/sonarr.pid
+++ b/code/test/data/sonarr/config/sonarr.pid
@@ -1 +1 @@
-145
\ No newline at end of file
+146
\ No newline at end of file
diff --git a/code/test/docker-compose.yml b/code/test/docker-compose.yml
index 002520a4..834b3df6 100644
--- a/code/test/docker-compose.yml
+++ b/code/test/docker-compose.yml
@@ -168,12 +168,13 @@ services:
restart: unless-stopped
cleanuperr:
- image: flaminel/cleanuperr:latest
+ image: ghcr.io/flmorg/cleanuperr:latest
container_name: cleanuperr
environment:
- LOGGING__LOGLEVEL=Debug
- LOGGING__FILE__ENABLED=false
- LOGGING__FILE__PATH=/var/logs
+ - LOGGING__ENHANCED=true
- TRIGGERS__QUEUECLEANER=0/30 * * * * ?
- TRIGGERS__CONTENTBLOCKER=0/30 * * * * ?
@@ -203,6 +204,7 @@ services:
# - TRANSMISSION__PASSWORD=testing
- SONARR__ENABLED=true
+ - SONARR__SEARCHTYPE=Episode
- SONARR__INSTANCES__0__URL=http://sonarr:8989
- SONARR__INSTANCES__0__APIKEY=96736c3eb3144936b8f1d62d27be8cee
diff --git a/variables.md b/variables.md
new file mode 100644
index 00000000..653b7904
--- /dev/null
+++ b/variables.md
@@ -0,0 +1,11 @@
+## LOGGING__ENHANCED
+
+Some logs may contain information that is hard to read. Enhancing these logs usually comes with the cost of additional calls to the APIs.
+
+If enabled, logs like this
+
+```movie search triggered | http://localhost:7878/ | movie ids: 1, 2```
+
+will transform into
+
+```movie search triggered | http://localhost:7878/ | [Speak No Evil][The Wild Robot]```
\ No newline at end of file