diff --git a/src/Recyclarr.Cli/CompositionRoot.cs b/src/Recyclarr.Cli/CompositionRoot.cs index 10fae7e2..268bc580 100644 --- a/src/Recyclarr.Cli/CompositionRoot.cs +++ b/src/Recyclarr.Cli/CompositionRoot.cs @@ -14,10 +14,11 @@ using Recyclarr.TrashLib.Config; using Recyclarr.TrashLib.Http; using Recyclarr.TrashLib.Repo; using Recyclarr.TrashLib.Repo.VersionControl; -using Recyclarr.TrashLib.Services.Common; using Recyclarr.TrashLib.Services.CustomFormat; using Recyclarr.TrashLib.Services.Processors; +using Recyclarr.TrashLib.Services.QualitySize; using Recyclarr.TrashLib.Services.Radarr; +using Recyclarr.TrashLib.Services.ReleaseProfile; using Recyclarr.TrashLib.Services.Sonarr; using Recyclarr.TrashLib.Services.System; using Recyclarr.TrashLib.Startup; @@ -38,11 +39,12 @@ public static class CompositionRoot builder.RegisterModule(); builder.RegisterModule(); + builder.RegisterModule(); + builder.RegisterModule(); + builder.RegisterModule(); builder.RegisterModule(); builder.RegisterModule(); builder.RegisterModule(); - builder.RegisterModule(); - builder.RegisterModule(); builder.RegisterModule(); builder.RegisterModule(new ConfigAutofacModule(assemblies)); builder.RegisterModule(); diff --git a/src/Recyclarr.Cli/Console/Commands/ListCustomFormatsCommand.cs b/src/Recyclarr.Cli/Console/Commands/ListCustomFormatsCommand.cs index 5ff2348a..ef8ab4fc 100644 --- a/src/Recyclarr.Cli/Console/Commands/ListCustomFormatsCommand.cs +++ b/src/Recyclarr.Cli/Console/Commands/ListCustomFormatsCommand.cs @@ -1,11 +1,10 @@ using System.ComponentModel; using System.Diagnostics.CodeAnalysis; -using Autofac.Features.Indexed; using JetBrains.Annotations; using Recyclarr.Cli.Console.Helpers; using Recyclarr.TrashLib.Config; using Recyclarr.TrashLib.Repo; -using Recyclarr.TrashLib.Services.Common; +using Recyclarr.TrashLib.Services.CustomFormat.Guide; using Spectre.Console.Cli; #pragma warning disable CS8765 @@ -16,8 +15,7 @@ namespace Recyclarr.Cli.Console.Commands; [Description("List custom formats in the guide for a particular service.")] internal class ListCustomFormatsCommand : AsyncCommand { - private readonly IGuideDataLister _lister; - private readonly IIndex _guideService; + private readonly CustomFormatDataLister _lister; private readonly IRepoUpdater _repoUpdater; [UsedImplicitly] @@ -31,20 +29,17 @@ internal class ListCustomFormatsCommand : AsyncCommand guideService, + CustomFormatDataLister lister, IRepoUpdater repoUpdater) { _lister = lister; - _guideService = guideService; _repoUpdater = repoUpdater; } public override async Task ExecuteAsync(CommandContext context, CliSettings settings) { await _repoUpdater.UpdateRepo(); - var guideService = _guideService[settings.Service]; - _lister.ListCustomFormats(guideService.GetCustomFormatData()); + _lister.ListCustomFormats(settings.Service); return 0; } } diff --git a/src/Recyclarr.Cli/Console/Commands/ListQualitiesCommand.cs b/src/Recyclarr.Cli/Console/Commands/ListQualitiesCommand.cs index 6a6c256e..5738ee70 100644 --- a/src/Recyclarr.Cli/Console/Commands/ListQualitiesCommand.cs +++ b/src/Recyclarr.Cli/Console/Commands/ListQualitiesCommand.cs @@ -1,11 +1,10 @@ using System.ComponentModel; using System.Diagnostics.CodeAnalysis; -using Autofac.Features.Indexed; using JetBrains.Annotations; using Recyclarr.Cli.Console.Helpers; using Recyclarr.TrashLib.Config; using Recyclarr.TrashLib.Repo; -using Recyclarr.TrashLib.Services.Common; +using Recyclarr.TrashLib.Services.QualitySize.Guide; using Spectre.Console.Cli; namespace Recyclarr.Cli.Console.Commands; @@ -15,8 +14,7 @@ namespace Recyclarr.Cli.Console.Commands; [Description("List quality definitions in the guide for a particular service.")] internal class ListQualitiesCommand : AsyncCommand { - private readonly IGuideDataLister _lister; - private readonly IIndex _guideService; + private readonly QualitySizeDataLister _lister; private readonly IRepoUpdater _repoUpdater; [UsedImplicitly] @@ -29,21 +27,16 @@ internal class ListQualitiesCommand : AsyncCommand guideService, - IRepoUpdater repoUpdater) + public ListQualitiesCommand(QualitySizeDataLister lister, IRepoUpdater repoUpdater) { _lister = lister; - _guideService = guideService; _repoUpdater = repoUpdater; } public override async Task ExecuteAsync(CommandContext context, CliSettings settings) { await _repoUpdater.UpdateRepo(); - var guideService = _guideService[settings.Service]; - _lister.ListQualities(guideService.GetQualities()); + _lister.ListQualities(settings.Service); return 0; } } diff --git a/src/Recyclarr.Cli/Console/Commands/ListReleaseProfilesCommand.cs b/src/Recyclarr.Cli/Console/Commands/ListReleaseProfilesCommand.cs index e6745175..eaed91d0 100644 --- a/src/Recyclarr.Cli/Console/Commands/ListReleaseProfilesCommand.cs +++ b/src/Recyclarr.Cli/Console/Commands/ListReleaseProfilesCommand.cs @@ -2,7 +2,7 @@ using System.ComponentModel; using System.Diagnostics.CodeAnalysis; using JetBrains.Annotations; using Recyclarr.TrashLib.Repo; -using Recyclarr.TrashLib.Services.Sonarr; +using Recyclarr.TrashLib.Services.ReleaseProfile.Guide; using Spectre.Console.Cli; #pragma warning disable CS8765 @@ -14,7 +14,7 @@ namespace Recyclarr.Cli.Console.Commands; internal class ListReleaseProfilesCommand : AsyncCommand { private readonly ILogger _log; - private readonly ISonarrGuideDataLister _lister; + private readonly ReleaseProfileDataLister _lister; private readonly IRepoUpdater _repoUpdater; [UsedImplicitly] @@ -31,7 +31,7 @@ internal class ListReleaseProfilesCommand : AsyncCommand { private readonly ILogger _log; - private readonly IRadarrGuideDataLister _lister; + private readonly CustomFormatDataLister _cfLister; + private readonly QualitySizeDataLister _qualityLister; private readonly IMigrationExecutor _migration; private readonly IRepoUpdater _repoUpdater; private readonly ISyncProcessor _syncProcessor; @@ -56,13 +58,15 @@ internal class RadarrCommand : AsyncCommand public RadarrCommand( ILogger log, - IRadarrGuideDataLister lister, + CustomFormatDataLister cfLister, + QualitySizeDataLister qualityLister, IMigrationExecutor migration, IRepoUpdater repoUpdater, ISyncProcessor syncProcessor) { _log = log; - _lister = lister; + _cfLister = cfLister; + _qualityLister = qualityLister; _migration = migration; _repoUpdater = repoUpdater; _syncProcessor = syncProcessor; @@ -77,14 +81,14 @@ internal class RadarrCommand : AsyncCommand if (settings.ListCustomFormats) { _log.Warning("The `radarr` subcommand is DEPRECATED -- Use `list custom-formats radarr` instead!"); - _lister.ListCustomFormats(); + _cfLister.ListCustomFormats(SupportedServices.Radarr); return 0; } if (settings.ListQualities) { _log.Warning("The `radarr` subcommand is DEPRECATED -- Use `list qualities radarr` instead!"); - _lister.ListQualities(); + _qualityLister.ListQualities(SupportedServices.Radarr); return 0; } diff --git a/src/Recyclarr.Cli/Console/Commands/SonarrCommand.cs b/src/Recyclarr.Cli/Console/Commands/SonarrCommand.cs index 89bbbf2a..8acf86b7 100644 --- a/src/Recyclarr.Cli/Console/Commands/SonarrCommand.cs +++ b/src/Recyclarr.Cli/Console/Commands/SonarrCommand.cs @@ -6,8 +6,10 @@ using Recyclarr.Cli.Console.Helpers; using Recyclarr.Cli.Migration; using Recyclarr.TrashLib.Config; using Recyclarr.TrashLib.Repo; +using Recyclarr.TrashLib.Services.CustomFormat.Guide; using Recyclarr.TrashLib.Services.Processors; -using Recyclarr.TrashLib.Services.Sonarr; +using Recyclarr.TrashLib.Services.QualitySize.Guide; +using Recyclarr.TrashLib.Services.ReleaseProfile.Guide; using Spectre.Console.Cli; namespace Recyclarr.Cli.Console.Commands; @@ -17,7 +19,9 @@ namespace Recyclarr.Cli.Console.Commands; internal class SonarrCommand : AsyncCommand { private readonly ILogger _log; - private readonly ISonarrGuideDataLister _lister; + private readonly CustomFormatDataLister _cfLister; + private readonly QualitySizeDataLister _qualityLister; + private readonly ReleaseProfileDataLister _rpLister; private readonly IMigrationExecutor _migration; private readonly IRepoUpdater _repoUpdater; private readonly ISyncProcessor _syncProcessor; @@ -70,13 +74,17 @@ internal class SonarrCommand : AsyncCommand public SonarrCommand( ILogger log, - ISonarrGuideDataLister lister, + CustomFormatDataLister cfLister, + QualitySizeDataLister qualityLister, + ReleaseProfileDataLister rpLister, IMigrationExecutor migration, IRepoUpdater repoUpdater, ISyncProcessor syncProcessor) { _log = log; - _lister = lister; + _cfLister = cfLister; + _qualityLister = qualityLister; + _rpLister = rpLister; _migration = migration; _repoUpdater = repoUpdater; _syncProcessor = syncProcessor; @@ -91,27 +99,27 @@ internal class SonarrCommand : AsyncCommand if (settings.ListCustomFormats) { _log.Warning("The `sonarr` subcommand is DEPRECATED -- Use `list custom-formats sonarr` instead!"); - _lister.ListCustomFormats(); + _cfLister.ListCustomFormats(SupportedServices.Sonarr); return 0; } if (settings.ListQualities) { _log.Warning("The `sonarr` subcommand is DEPRECATED -- Use `list qualities sonarr` instead!"); - _lister.ListQualities(); + _qualityLister.ListQualities(SupportedServices.Sonarr); return 0; } if (settings.ListReleaseProfiles) { _log.Warning("The `sonarr` subcommand is DEPRECATED -- Use `list release-profiles` instead!"); - _lister.ListReleaseProfiles(); + _rpLister.ListReleaseProfiles(); return 0; } if (settings.ListTerms is not null) { - _lister.ListTerms(settings.ListTerms); + _rpLister.ListTerms(settings.ListTerms); return 0; } diff --git a/src/Recyclarr.TrashLib.Tests/CustomFormat/GuideDataListerTest.cs b/src/Recyclarr.TrashLib.Tests/CustomFormat/GuideDataListerTest.cs index ac2dd82b..40592978 100644 --- a/src/Recyclarr.TrashLib.Tests/CustomFormat/GuideDataListerTest.cs +++ b/src/Recyclarr.TrashLib.Tests/CustomFormat/GuideDataListerTest.cs @@ -1,8 +1,9 @@ using AutoFixture.NUnit3; using FluentAssertions; +using NSubstitute; using NUnit.Framework; using Recyclarr.TestLibrary.AutoFixture; -using Recyclarr.TrashLib.Services.Common; +using Recyclarr.TrashLib.Services.CustomFormat.Guide; using Recyclarr.TrashLib.TestLibrary; using Spectre.Console.Testing; @@ -15,7 +16,8 @@ public class GuideDataListerTest [Test, AutoMockData] public void Custom_formats_appear_in_console_output( [Frozen(Matching.ImplementedInterfaces)] TestConsole console, - GuideDataLister sut) + [Frozen] ICustomFormatGuideService guide, + CustomFormatDataLister sut) { var testData = new[] { @@ -23,7 +25,9 @@ public class GuideDataListerTest NewCf.Data("Second", "456") }; - sut.ListCustomFormats(testData); + guide.GetCustomFormatData(default!).ReturnsForAnyArgs(testData); + + sut.ListCustomFormats(default!); console.Output.Should().ContainAll( testData.SelectMany(x => new[] {x.Name, x.TrashId})); diff --git a/src/Recyclarr.TrashLib.Tests/CustomFormat/Processors/GuideProcessorTest.cs b/src/Recyclarr.TrashLib.Tests/CustomFormat/Processors/GuideProcessorTest.cs index a0b99f63..bbdc206a 100644 --- a/src/Recyclarr.TrashLib.Tests/CustomFormat/Processors/GuideProcessorTest.cs +++ b/src/Recyclarr.TrashLib.Tests/CustomFormat/Processors/GuideProcessorTest.cs @@ -10,7 +10,6 @@ using Recyclarr.TrashLib.Services.CustomFormat.Guide; using Recyclarr.TrashLib.Services.CustomFormat.Models; using Recyclarr.TrashLib.Services.CustomFormat.Processors; using Recyclarr.TrashLib.Services.CustomFormat.Processors.GuideSteps; -using Recyclarr.TrashLib.Services.Radarr; using Recyclarr.TrashLib.TestLibrary; namespace Recyclarr.TrashLib.Tests.CustomFormat.Processors; @@ -57,11 +56,11 @@ public class GuideProcessorTest public async Task Guide_processor_behaves_as_expected_with_normal_guide_data() { var ctx = new Context(); - var guideService = Substitute.For(); - var guideProcessor = new GuideProcessor(new TestGuideProcessorSteps()); + var guideService = Substitute.For(); + var guideProcessor = new GuideProcessor(new TestGuideProcessorSteps(), guideService); // simulate guide data - guideService.GetCustomFormatData().Returns(new[] + guideService.GetCustomFormatData(default!).ReturnsForAnyArgs(new[] { ctx.ReadCustomFormat("ImportableCustomFormat1.json"), ctx.ReadCustomFormat("ImportableCustomFormat2.json"), @@ -102,7 +101,7 @@ public class GuideProcessorTest } }; - await guideProcessor.BuildGuideDataAsync(config, null, guideService); + await guideProcessor.BuildGuideDataAsync(config, null, default!); var expectedProcessedCustomFormatData = new List { diff --git a/src/Recyclarr.TrashLib.Tests/Sonarr/ReleaseProfile/Guide/LocalRepoSonarrGuideServiceTest.cs b/src/Recyclarr.TrashLib.Tests/Services/GuideServiceTest.cs similarity index 79% rename from src/Recyclarr.TrashLib.Tests/Sonarr/ReleaseProfile/Guide/LocalRepoSonarrGuideServiceTest.cs rename to src/Recyclarr.TrashLib.Tests/Services/GuideServiceTest.cs index 0da7de0c..3c8966ad 100644 --- a/src/Recyclarr.TrashLib.Tests/Sonarr/ReleaseProfile/Guide/LocalRepoSonarrGuideServiceTest.cs +++ b/src/Recyclarr.TrashLib.Tests/Services/GuideServiceTest.cs @@ -9,20 +9,20 @@ using NUnit.Framework; using Recyclarr.TestLibrary; using Recyclarr.TestLibrary.AutoFixture; using Recyclarr.TrashLib.Repo; -using Recyclarr.TrashLib.Services.Sonarr; -using Recyclarr.TrashLib.Services.Sonarr.ReleaseProfile; +using Recyclarr.TrashLib.Services.ReleaseProfile; +using Recyclarr.TrashLib.Services.ReleaseProfile.Guide; -namespace Recyclarr.TrashLib.Tests.Sonarr.ReleaseProfile.Guide; +namespace Recyclarr.TrashLib.Tests.Services; [TestFixture] [Parallelizable(ParallelScope.All)] -public class LocalRepoSonarrGuideServiceTest +public class GuideServiceTest { [Test, AutoMockData] - public void Get_custom_format_json_works( + public void Get_release_profile_json_works( [Frozen(Matching.ImplementedInterfaces)] MockFileSystem fs, - [Frozen] IRepoPaths repoPaths, - LocalRepoSonarrGuideService sut) + [Frozen] IRepoMetadataBuilder metadataBuilder, + ReleaseProfileGuideService sut) { static ReleaseProfileData MakeMockObject(string term) { @@ -50,7 +50,7 @@ public class LocalRepoSonarrGuideServiceTest fs.AddFile(baseDir.File("first.json").FullName, MockFileData(mockData1)); fs.AddFile(baseDir.File("second.json").FullName, MockFileData(mockData2)); - repoPaths.SonarrReleaseProfilePaths.Returns(new[] {baseDir}); + metadataBuilder.ToDirectoryInfoList(default!).ReturnsForAnyArgs(new[] {baseDir}); var results = sut.GetReleaseProfileData(); @@ -64,8 +64,8 @@ public class LocalRepoSonarrGuideServiceTest [Test, AutoMockData] public void Json_exceptions_do_not_interrupt_parsing_other_files( [Frozen(Matching.ImplementedInterfaces)] MockFileSystem fs, - [Frozen] IRepoPaths repoPaths, - LocalRepoSonarrGuideService sut) + [Frozen] IRepoMetadataBuilder metadataBuilder, + ReleaseProfileGuideService sut) { var rootPath = fs.CurrentDirectory().SubDirectory("files"); rootPath.Create(); @@ -84,7 +84,7 @@ public class LocalRepoSonarrGuideServiceTest fs.AddFile(rootPath.File("0_bad_data.json").FullName, MockData.FromString(badData)); fs.AddFile(rootPath.File("1_good_data.json").FullName, MockData.FromJson(goodData)); - repoPaths.SonarrReleaseProfilePaths.Returns(new[] {rootPath}); + metadataBuilder.ToDirectoryInfoList(default!).ReturnsForAnyArgs(new[] {rootPath}); var results = sut.GetReleaseProfileData(); diff --git a/src/Recyclarr.TrashLib.Tests/Sonarr/SonarrGuideDataListerTest.cs b/src/Recyclarr.TrashLib.Tests/Services/ReleaseProfileDataListerTest.cs similarity index 72% rename from src/Recyclarr.TrashLib.Tests/Sonarr/SonarrGuideDataListerTest.cs rename to src/Recyclarr.TrashLib.Tests/Services/ReleaseProfileDataListerTest.cs index 3fd9d0c8..3ff18aa0 100644 --- a/src/Recyclarr.TrashLib.Tests/Sonarr/SonarrGuideDataListerTest.cs +++ b/src/Recyclarr.TrashLib.Tests/Services/ReleaseProfileDataListerTest.cs @@ -3,21 +3,21 @@ using FluentAssertions; using NSubstitute; using NUnit.Framework; using Recyclarr.TestLibrary.AutoFixture; -using Recyclarr.TrashLib.Services.Sonarr; -using Recyclarr.TrashLib.Services.Sonarr.ReleaseProfile; +using Recyclarr.TrashLib.Services.ReleaseProfile; +using Recyclarr.TrashLib.Services.ReleaseProfile.Guide; using Spectre.Console.Testing; -namespace Recyclarr.TrashLib.Tests.Sonarr; +namespace Recyclarr.TrashLib.Tests.Services; [TestFixture] [Parallelizable(ParallelScope.All)] -public class SonarrGuideDataListerTest +public class ReleaseProfileDataListerTest { [Test, AutoMockData] public void Release_profiles_appear_in_console_output( - [Frozen] SonarrGuideService guide, [Frozen(Matching.ImplementedInterfaces)] TestConsole console, - SonarrGuideDataLister sut) + [Frozen] IReleaseProfileGuideService guide, + ReleaseProfileDataLister sut) { var testData = new[] { @@ -35,9 +35,9 @@ public class SonarrGuideDataListerTest [Test, AutoMockData] public void Terms_appear_in_console_output( - [Frozen] SonarrGuideService guide, + [Frozen] IReleaseProfileGuideService guide, [Frozen(Matching.ImplementedInterfaces)] TestConsole console, - SonarrGuideDataLister sut) + ReleaseProfileDataLister sut) { var requiredData = new[] { @@ -57,15 +57,18 @@ public class SonarrGuideDataListerTest new TermData {Name = "Sixth", TrashId = "666", Term = "term6"} }; - guide.GetUnfilteredProfileById(default!).ReturnsForAnyArgs(new ReleaseProfileData + guide.GetReleaseProfileData().Returns(new[] { - Name = "Release Profile", - TrashId = "098", - Required = requiredData, - Ignored = ignoredData, - Preferred = new PreferredTermData[] + new ReleaseProfileData { - new() {Score = 100, Terms = preferredData} + Name = "Release Profile", + TrashId = "098", + Required = requiredData, + Ignored = ignoredData, + Preferred = new PreferredTermData[] + { + new() {Score = 100, Terms = preferredData} + } } }); @@ -78,7 +81,6 @@ public class SonarrGuideDataListerTest preferredData.SelectMany(x => new[] {x.Name, x.TrashId}) }; - guide.Received().GetUnfilteredProfileById("098"); console.Output.Should().ContainAll(expectedOutput.SelectMany(x => x)); } } diff --git a/src/Recyclarr.TrashLib.Tests/Sonarr/ReleaseProfile/Filters/ReleaseProfileDataFiltererTest.cs b/src/Recyclarr.TrashLib.Tests/Sonarr/ReleaseProfile/Filters/ReleaseProfileDataFiltererTest.cs index 203496ba..8d05a28b 100644 --- a/src/Recyclarr.TrashLib.Tests/Sonarr/ReleaseProfile/Filters/ReleaseProfileDataFiltererTest.cs +++ b/src/Recyclarr.TrashLib.Tests/Sonarr/ReleaseProfile/Filters/ReleaseProfileDataFiltererTest.cs @@ -1,9 +1,9 @@ using FluentAssertions; using NUnit.Framework; using Recyclarr.TestLibrary.AutoFixture; +using Recyclarr.TrashLib.Services.ReleaseProfile; +using Recyclarr.TrashLib.Services.ReleaseProfile.Filters; using Recyclarr.TrashLib.Services.Sonarr.Config; -using Recyclarr.TrashLib.Services.Sonarr.ReleaseProfile; -using Recyclarr.TrashLib.Services.Sonarr.ReleaseProfile.Filters; namespace Recyclarr.TrashLib.Tests.Sonarr.ReleaseProfile.Filters; diff --git a/src/Recyclarr.TrashLib.Tests/Sonarr/ReleaseProfile/Filters/ReleaseProfileDataValidationFiltererTest.cs b/src/Recyclarr.TrashLib.Tests/Sonarr/ReleaseProfile/Filters/ReleaseProfileDataValidationFiltererTest.cs index abf520f7..967e3790 100644 --- a/src/Recyclarr.TrashLib.Tests/Sonarr/ReleaseProfile/Filters/ReleaseProfileDataValidationFiltererTest.cs +++ b/src/Recyclarr.TrashLib.Tests/Sonarr/ReleaseProfile/Filters/ReleaseProfileDataValidationFiltererTest.cs @@ -1,8 +1,8 @@ using FluentAssertions; using NUnit.Framework; using Recyclarr.TestLibrary.AutoFixture; -using Recyclarr.TrashLib.Services.Sonarr.ReleaseProfile; -using Recyclarr.TrashLib.Services.Sonarr.ReleaseProfile.Filters; +using Recyclarr.TrashLib.Services.ReleaseProfile; +using Recyclarr.TrashLib.Services.ReleaseProfile.Filters; namespace Recyclarr.TrashLib.Tests.Sonarr.ReleaseProfile.Filters; diff --git a/src/Recyclarr.TrashLib.Tests/Sonarr/ReleaseProfile/Filters/StrictNegativeScoresFilterTest.cs b/src/Recyclarr.TrashLib.Tests/Sonarr/ReleaseProfile/Filters/StrictNegativeScoresFilterTest.cs index ef0ae845..83a4e21b 100644 --- a/src/Recyclarr.TrashLib.Tests/Sonarr/ReleaseProfile/Filters/StrictNegativeScoresFilterTest.cs +++ b/src/Recyclarr.TrashLib.Tests/Sonarr/ReleaseProfile/Filters/StrictNegativeScoresFilterTest.cs @@ -1,9 +1,9 @@ using FluentAssertions; using NUnit.Framework; using Recyclarr.TestLibrary.AutoFixture; +using Recyclarr.TrashLib.Services.ReleaseProfile; +using Recyclarr.TrashLib.Services.ReleaseProfile.Filters; using Recyclarr.TrashLib.Services.Sonarr.Config; -using Recyclarr.TrashLib.Services.Sonarr.ReleaseProfile; -using Recyclarr.TrashLib.Services.Sonarr.ReleaseProfile.Filters; namespace Recyclarr.TrashLib.Tests.Sonarr.ReleaseProfile.Filters; diff --git a/src/Recyclarr.TrashLib.Tests/Sonarr/ReleaseProfile/ReleaseProfileDataValidatorTest.cs b/src/Recyclarr.TrashLib.Tests/Sonarr/ReleaseProfile/ReleaseProfileDataValidatorTest.cs index 015cacb6..57033eec 100644 --- a/src/Recyclarr.TrashLib.Tests/Sonarr/ReleaseProfile/ReleaseProfileDataValidatorTest.cs +++ b/src/Recyclarr.TrashLib.Tests/Sonarr/ReleaseProfile/ReleaseProfileDataValidatorTest.cs @@ -1,7 +1,7 @@ using FluentAssertions; using FluentValidation.TestHelper; using NUnit.Framework; -using Recyclarr.TrashLib.Services.Sonarr.ReleaseProfile; +using Recyclarr.TrashLib.Services.ReleaseProfile; namespace Recyclarr.TrashLib.Tests.Sonarr.ReleaseProfile; diff --git a/src/Recyclarr.TrashLib.Tests/Sonarr/ReleaseProfile/ScopedStateTest.cs b/src/Recyclarr.TrashLib.Tests/Sonarr/ReleaseProfile/ScopedStateTest.cs index f13bdd20..4ea0446f 100644 --- a/src/Recyclarr.TrashLib.Tests/Sonarr/ReleaseProfile/ScopedStateTest.cs +++ b/src/Recyclarr.TrashLib.Tests/Sonarr/ReleaseProfile/ScopedStateTest.cs @@ -1,6 +1,6 @@ using FluentAssertions; using NUnit.Framework; -using Recyclarr.TrashLib.Services.Sonarr.ReleaseProfile; +using Recyclarr.TrashLib.Services.ReleaseProfile; namespace Recyclarr.TrashLib.Tests.Sonarr.ReleaseProfile; diff --git a/src/Recyclarr.TrashLib.Tests/Sonarr/SonarrCompatibilityTest.cs b/src/Recyclarr.TrashLib.Tests/Sonarr/SonarrCompatibilityTest.cs index b4769be8..91b826f0 100644 --- a/src/Recyclarr.TrashLib.Tests/Sonarr/SonarrCompatibilityTest.cs +++ b/src/Recyclarr.TrashLib.Tests/Sonarr/SonarrCompatibilityTest.cs @@ -7,8 +7,8 @@ using NSubstitute; using NUnit.Framework; using Recyclarr.Cli.TestLibrary; using Recyclarr.TestLibrary; -using Recyclarr.TrashLib.Services.Sonarr.Api; -using Recyclarr.TrashLib.Services.Sonarr.Api.Objects; +using Recyclarr.TrashLib.Services.ReleaseProfile.Api; +using Recyclarr.TrashLib.Services.ReleaseProfile.Api.Objects; using Recyclarr.TrashLib.Services.Sonarr.Capabilities; namespace Recyclarr.TrashLib.Tests.Sonarr; diff --git a/src/Recyclarr.TrashLib/Repo/IRepoMetadataBuilder.cs b/src/Recyclarr.TrashLib/Repo/IRepoMetadataBuilder.cs new file mode 100644 index 00000000..147aa69c --- /dev/null +++ b/src/Recyclarr.TrashLib/Repo/IRepoMetadataBuilder.cs @@ -0,0 +1,10 @@ +using System.IO.Abstractions; + +namespace Recyclarr.TrashLib.Repo; + +public interface IRepoMetadataBuilder +{ + RepoMetadata GetMetadata(); + IReadOnlyList ToDirectoryInfoList(IEnumerable listOfDirectories); + IDirectoryInfo DocsDirectory { get; } +} diff --git a/src/Recyclarr.TrashLib/Repo/IRepoPaths.cs b/src/Recyclarr.TrashLib/Repo/IRepoPaths.cs deleted file mode 100644 index 217a2516..00000000 --- a/src/Recyclarr.TrashLib/Repo/IRepoPaths.cs +++ /dev/null @@ -1,14 +0,0 @@ -using System.IO.Abstractions; - -namespace Recyclarr.TrashLib.Repo; - -public interface IRepoPaths -{ - IReadOnlyCollection RadarrCustomFormatPaths { get; } - IReadOnlyCollection SonarrReleaseProfilePaths { get; } - IReadOnlyCollection SonarrQualityPaths { get; } - IReadOnlyCollection RadarrQualityPaths { get; } - IReadOnlyCollection SonarrCustomFormatPaths { get; } - IFileInfo RadarrCollectionOfCustomFormats { get; } - IFileInfo SonarrCollectionOfCustomFormats { get; } -} diff --git a/src/Recyclarr.TrashLib/Repo/IRepoPathsFactory.cs b/src/Recyclarr.TrashLib/Repo/IRepoPathsFactory.cs deleted file mode 100644 index c2560523..00000000 --- a/src/Recyclarr.TrashLib/Repo/IRepoPathsFactory.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Recyclarr.TrashLib.Repo; - -public interface IRepoPathsFactory -{ - IRepoPaths Create(); - RepoMetadata Metadata { get; } -} diff --git a/src/Recyclarr.TrashLib/Repo/RepoAutofacModule.cs b/src/Recyclarr.TrashLib/Repo/RepoAutofacModule.cs index 1e891905..b2ae5156 100644 --- a/src/Recyclarr.TrashLib/Repo/RepoAutofacModule.cs +++ b/src/Recyclarr.TrashLib/Repo/RepoAutofacModule.cs @@ -9,6 +9,6 @@ public class RepoAutofacModule : Module base.Load(builder); builder.RegisterType().As(); builder.RegisterType().As(); - builder.RegisterType().As().InstancePerLifetimeScope(); + builder.RegisterType().As().InstancePerLifetimeScope(); } } diff --git a/src/Recyclarr.TrashLib/Repo/RepoMetadata.cs b/src/Recyclarr.TrashLib/Repo/RepoMetadata.cs index 8b1f275b..f44e23ac 100644 --- a/src/Recyclarr.TrashLib/Repo/RepoMetadata.cs +++ b/src/Recyclarr.TrashLib/Repo/RepoMetadata.cs @@ -1,21 +1,25 @@ namespace Recyclarr.TrashLib.Repo; -public record RadarrMetadata( - IReadOnlyCollection CustomFormats, - IReadOnlyCollection Qualities -); +public record RadarrMetadata +{ + public IReadOnlyCollection CustomFormats { get; init; } = Array.Empty(); + public IReadOnlyCollection Qualities { get; init; } = Array.Empty(); +} -public record SonarrMetadata( - IReadOnlyCollection ReleaseProfiles, - IReadOnlyCollection Qualities, - IReadOnlyCollection CustomFormats -); +public record SonarrMetadata +{ + public IReadOnlyCollection ReleaseProfiles { get; init; } = Array.Empty(); + public IReadOnlyCollection Qualities { get; init; } = Array.Empty(); + public IReadOnlyCollection CustomFormats { get; init; } = Array.Empty(); +} -public record JsonPaths( - RadarrMetadata Radarr, - SonarrMetadata Sonarr -); +public record JsonPaths +{ + public RadarrMetadata Radarr { get; init; } = new(); + public SonarrMetadata Sonarr { get; init; } = new(); +} -public record RepoMetadata( - JsonPaths JsonPaths -); +public record RepoMetadata +{ + public JsonPaths JsonPaths { get; init; } = new(); +} diff --git a/src/Recyclarr.TrashLib/Repo/RepoMetadataBuilder.cs b/src/Recyclarr.TrashLib/Repo/RepoMetadataBuilder.cs new file mode 100644 index 00000000..3c6c48bc --- /dev/null +++ b/src/Recyclarr.TrashLib/Repo/RepoMetadataBuilder.cs @@ -0,0 +1,30 @@ +using System.IO.Abstractions; +using Recyclarr.TrashLib.Startup; + +namespace Recyclarr.TrashLib.Repo; + +public class RepoMetadataBuilder : IRepoMetadataBuilder +{ + private readonly IAppPaths _paths; + private readonly Lazy _metadata; + + public RepoMetadataBuilder( + IRepoMetadataParser parser, + IAppPaths paths) + { + _paths = paths; + _metadata = new Lazy(parser.Deserialize); + } + + public IReadOnlyList ToDirectoryInfoList(IEnumerable listOfDirectories) + { + return listOfDirectories.Select(x => _paths.RepoDirectory.SubDirectory(x)).ToList(); + } + + public IDirectoryInfo DocsDirectory => _paths.RepoDirectory.SubDirectory("docs"); + + public RepoMetadata GetMetadata() + { + return _metadata.Value; + } +} diff --git a/src/Recyclarr.TrashLib/Repo/RepoPaths.cs b/src/Recyclarr.TrashLib/Repo/RepoPaths.cs deleted file mode 100644 index ee6909b5..00000000 --- a/src/Recyclarr.TrashLib/Repo/RepoPaths.cs +++ /dev/null @@ -1,13 +0,0 @@ -using System.IO.Abstractions; - -namespace Recyclarr.TrashLib.Repo; - -public record RepoPaths( - IReadOnlyCollection RadarrCustomFormatPaths, - IReadOnlyCollection SonarrReleaseProfilePaths, - IReadOnlyCollection RadarrQualityPaths, - IReadOnlyCollection SonarrQualityPaths, - IReadOnlyCollection SonarrCustomFormatPaths, - IFileInfo RadarrCollectionOfCustomFormats, - IFileInfo SonarrCollectionOfCustomFormats -) : IRepoPaths; diff --git a/src/Recyclarr.TrashLib/Repo/RepoPathsFactory.cs b/src/Recyclarr.TrashLib/Repo/RepoPathsFactory.cs deleted file mode 100644 index 27e783a8..00000000 --- a/src/Recyclarr.TrashLib/Repo/RepoPathsFactory.cs +++ /dev/null @@ -1,40 +0,0 @@ -using System.IO.Abstractions; -using Recyclarr.TrashLib.Startup; - -namespace Recyclarr.TrashLib.Repo; - -public class RepoPathsFactory : IRepoPathsFactory -{ - private readonly IAppPaths _paths; - private readonly Lazy _metadata; - - public RepoMetadata Metadata => _metadata.Value; - - public RepoPathsFactory(IRepoMetadataParser parser, IAppPaths paths) - { - _paths = paths; - _metadata = new Lazy(parser.Deserialize); - } - - private List ToDirectoryInfoList(IEnumerable listOfDirectories) - { - return listOfDirectories - .Select(x => _paths.RepoDirectory.SubDirectory(x)) - .ToList(); - } - - public IRepoPaths Create() - { - var docs = _paths.RepoDirectory.SubDirectory("docs"); - var metadata = _metadata.Value; - return new RepoPaths( - ToDirectoryInfoList(metadata.JsonPaths.Radarr.CustomFormats), - ToDirectoryInfoList(metadata.JsonPaths.Sonarr.ReleaseProfiles), - ToDirectoryInfoList(metadata.JsonPaths.Radarr.Qualities), - ToDirectoryInfoList(metadata.JsonPaths.Sonarr.Qualities), - ToDirectoryInfoList(metadata.JsonPaths.Sonarr.CustomFormats), - docs.SubDirectory("Radarr").File("Radarr-collection-of-custom-formats.md"), - docs.SubDirectory("Sonarr").File("sonarr-collection-of-custom-formats.md") - ); - } -} diff --git a/src/Recyclarr.TrashLib/Services/Common/GuideDataLister.cs b/src/Recyclarr.TrashLib/Services/Common/GuideDataLister.cs deleted file mode 100644 index bede1a1f..00000000 --- a/src/Recyclarr.TrashLib/Services/Common/GuideDataLister.cs +++ /dev/null @@ -1,54 +0,0 @@ -using MoreLinq; -using Recyclarr.TrashLib.Services.CustomFormat.Models; -using Recyclarr.TrashLib.Services.QualitySize; -using Spectre.Console; - -namespace Recyclarr.TrashLib.Services.Common; - -public class GuideDataLister : IGuideDataLister -{ - private readonly IAnsiConsole _console; - - public GuideDataLister(IAnsiConsole console) - { - _console = console; - } - - public void ListCustomFormats(IEnumerable customFormats) - { - _console.WriteLine("\nList of Custom Formats in the TRaSH Guides:"); - - var categories = customFormats - .OrderBy(x => x.Name) - .ToLookup(x => x.Category) - .OrderBy(x => x.Key); - - foreach (var cat in categories) - { - var title = cat.Key is not null ? $"{cat.Key}" : "[No Category]"; - _console.WriteLine($"\n # {title}"); - - foreach (var cf in cat) - { - _console.WriteLine($" - {cf.TrashId} # {cf.Name}"); - } - } - - _console.WriteLine( - "\nThe above Custom Formats are in YAML format and ready to be copied & pasted " + - "under the `trash_ids:` property."); - } - - public void ListQualities(IEnumerable qualityData) - { - _console.WriteLine("\nList of Quality Definition types in the TRaSH Guides:\n"); - - qualityData - .Select(x => x.Type) - .ForEach(x => _console.WriteLine($" - {x}")); - - _console.WriteLine( - "\nThe above quality definition types can be used with the `quality_definition:` property in your " + - "recyclarr.yml file."); - } -} diff --git a/src/Recyclarr.TrashLib/Services/Common/GuideServicesAutofacModule.cs b/src/Recyclarr.TrashLib/Services/Common/GuideServicesAutofacModule.cs deleted file mode 100644 index ec863597..00000000 --- a/src/Recyclarr.TrashLib/Services/Common/GuideServicesAutofacModule.cs +++ /dev/null @@ -1,12 +0,0 @@ -using Autofac; - -namespace Recyclarr.TrashLib.Services.Common; - -public class GuideServicesAutofacModule : Module -{ - protected override void Load(ContainerBuilder builder) - { - base.Load(builder); - builder.RegisterType().As(); - } -} diff --git a/src/Recyclarr.TrashLib/Services/Common/IGuideDataLister.cs b/src/Recyclarr.TrashLib/Services/Common/IGuideDataLister.cs deleted file mode 100644 index aee73df0..00000000 --- a/src/Recyclarr.TrashLib/Services/Common/IGuideDataLister.cs +++ /dev/null @@ -1,10 +0,0 @@ -using Recyclarr.TrashLib.Services.CustomFormat.Models; -using Recyclarr.TrashLib.Services.QualitySize; - -namespace Recyclarr.TrashLib.Services.Common; - -public interface IGuideDataLister -{ - void ListCustomFormats(IEnumerable customFormats); - void ListQualities(IEnumerable qualityData); -} diff --git a/src/Recyclarr.TrashLib/Services/Common/IGuideService.cs b/src/Recyclarr.TrashLib/Services/Common/IGuideService.cs deleted file mode 100644 index 4d6acbbe..00000000 --- a/src/Recyclarr.TrashLib/Services/Common/IGuideService.cs +++ /dev/null @@ -1,10 +0,0 @@ -using Recyclarr.TrashLib.Services.CustomFormat.Models; -using Recyclarr.TrashLib.Services.QualitySize; - -namespace Recyclarr.TrashLib.Services.Common; - -public interface IGuideService -{ - ICollection GetCustomFormatData(); - ICollection GetQualities(); -} diff --git a/src/Recyclarr.TrashLib/Services/CustomFormat/CustomFormatAutofacModule.cs b/src/Recyclarr.TrashLib/Services/CustomFormat/CustomFormatAutofacModule.cs index e4135367..19968a9c 100644 --- a/src/Recyclarr.TrashLib/Services/CustomFormat/CustomFormatAutofacModule.cs +++ b/src/Recyclarr.TrashLib/Services/CustomFormat/CustomFormatAutofacModule.cs @@ -15,6 +15,7 @@ public class CustomFormatAutofacModule : Module builder.RegisterType().As(); builder.RegisterType().As(); builder.RegisterType().As(); + builder.RegisterType().As(); builder.RegisterType().As(); builder.RegisterType().As(); builder.RegisterType().As(); diff --git a/src/Recyclarr.TrashLib/Services/CustomFormat/CustomFormatUpdater.cs b/src/Recyclarr.TrashLib/Services/CustomFormat/CustomFormatUpdater.cs index 59c529c5..15f3b3d1 100644 --- a/src/Recyclarr.TrashLib/Services/CustomFormat/CustomFormatUpdater.cs +++ b/src/Recyclarr.TrashLib/Services/CustomFormat/CustomFormatUpdater.cs @@ -1,6 +1,6 @@ using Recyclarr.Common.Extensions; +using Recyclarr.TrashLib.Config; using Recyclarr.TrashLib.Config.Services; -using Recyclarr.TrashLib.Services.Common; using Recyclarr.TrashLib.Services.CustomFormat.Processors; using Recyclarr.TrashLib.Services.CustomFormat.Processors.PersistenceSteps; using Spectre.Console; @@ -29,11 +29,11 @@ internal class CustomFormatUpdater : ICustomFormatUpdater _console = console; } - public async Task Process(bool isPreview, IEnumerable configs, IGuideService guideService) + public async Task Process(bool isPreview, IEnumerable configs, SupportedServices serviceType) { _cache.Load(); - await _guideProcessor.BuildGuideDataAsync(configs, _cache.CfCache, guideService); + await _guideProcessor.BuildGuideDataAsync(configs, _cache.CfCache, serviceType); if (!ValidateGuideDataAndCheckShouldProceed()) { diff --git a/src/Recyclarr.TrashLib/Services/CustomFormat/Guide/CustomFormatDataLister.cs b/src/Recyclarr.TrashLib/Services/CustomFormat/Guide/CustomFormatDataLister.cs new file mode 100644 index 00000000..f62799e7 --- /dev/null +++ b/src/Recyclarr.TrashLib/Services/CustomFormat/Guide/CustomFormatDataLister.cs @@ -0,0 +1,41 @@ +using Recyclarr.TrashLib.Config; +using Spectre.Console; + +namespace Recyclarr.TrashLib.Services.CustomFormat.Guide; + +public class CustomFormatDataLister +{ + private readonly IAnsiConsole _console; + private readonly ICustomFormatGuideService _guide; + + public CustomFormatDataLister(IAnsiConsole console, ICustomFormatGuideService guide) + { + _console = console; + _guide = guide; + } + + public void ListCustomFormats(SupportedServices serviceType) + { + _console.WriteLine("\nList of Custom Formats in the TRaSH Guides:"); + + var categories = _guide.GetCustomFormatData(serviceType) + .OrderBy(x => x.Name) + .ToLookup(x => x.Category) + .OrderBy(x => x.Key); + + foreach (var cat in categories) + { + var title = cat.Key is not null ? $"{cat.Key}" : "[No Category]"; + _console.WriteLine($"\n # {title}"); + + foreach (var cf in cat) + { + _console.WriteLine($" - {cf.TrashId} # {cf.Name}"); + } + } + + _console.WriteLine( + "\nThe above Custom Formats are in YAML format and ready to be copied & pasted " + + "under the `trash_ids:` property."); + } +} diff --git a/src/Recyclarr.TrashLib/Services/CustomFormat/Guide/CustomFormatGuideService.cs b/src/Recyclarr.TrashLib/Services/CustomFormat/Guide/CustomFormatGuideService.cs new file mode 100644 index 00000000..e0579815 --- /dev/null +++ b/src/Recyclarr.TrashLib/Services/CustomFormat/Guide/CustomFormatGuideService.cs @@ -0,0 +1,46 @@ +using System.IO.Abstractions; +using Recyclarr.TrashLib.Config; +using Recyclarr.TrashLib.Repo; +using Recyclarr.TrashLib.Services.CustomFormat.Models; + +namespace Recyclarr.TrashLib.Services.CustomFormat.Guide; + +public class CustomFormatGuideService : ICustomFormatGuideService +{ + private readonly IRepoMetadataBuilder _metadataBuilder; + private readonly ICustomFormatLoader _cfLoader; + + public CustomFormatGuideService( + IRepoMetadataBuilder metadataBuilder, + ICustomFormatLoader cfLoader) + { + _metadataBuilder = metadataBuilder; + _cfLoader = cfLoader; + } + + private CustomFormatPaths CreatePaths(SupportedServices serviceType) + { + var metadata = _metadataBuilder.GetMetadata(); + return serviceType switch + { + SupportedServices.Radarr => new CustomFormatPaths( + _metadataBuilder.ToDirectoryInfoList(metadata.JsonPaths.Radarr.CustomFormats), + _metadataBuilder.DocsDirectory.SubDirectory("Radarr").File("Radarr-collection-of-custom-formats.md") + ), + SupportedServices.Sonarr => new CustomFormatPaths( + _metadataBuilder.ToDirectoryInfoList(metadata.JsonPaths.Sonarr.CustomFormats), + _metadataBuilder.DocsDirectory.SubDirectory("Sonarr").File("sonarr-collection-of-custom-formats.md") + ), + _ => throw new ArgumentOutOfRangeException(nameof(serviceType), serviceType, null) + }; + } + + public ICollection GetCustomFormatData(SupportedServices serviceType) + { + var paths = CreatePaths(serviceType); + + return _cfLoader.LoadAllCustomFormatsAtPaths( + paths.CustomFormatDirectories, + paths.CollectionOfCustomFormatsMarkdown); + } +} diff --git a/src/Recyclarr.TrashLib/Services/CustomFormat/Guide/CustomFormatPaths.cs b/src/Recyclarr.TrashLib/Services/CustomFormat/Guide/CustomFormatPaths.cs new file mode 100644 index 00000000..5cae8114 --- /dev/null +++ b/src/Recyclarr.TrashLib/Services/CustomFormat/Guide/CustomFormatPaths.cs @@ -0,0 +1,8 @@ +using System.IO.Abstractions; + +namespace Recyclarr.TrashLib.Services.CustomFormat.Guide; + +internal record CustomFormatPaths( + IReadOnlyList CustomFormatDirectories, + IFileInfo CollectionOfCustomFormatsMarkdown +); diff --git a/src/Recyclarr.TrashLib/Services/CustomFormat/Guide/ICustomFormatGuideService.cs b/src/Recyclarr.TrashLib/Services/CustomFormat/Guide/ICustomFormatGuideService.cs new file mode 100644 index 00000000..9b993d80 --- /dev/null +++ b/src/Recyclarr.TrashLib/Services/CustomFormat/Guide/ICustomFormatGuideService.cs @@ -0,0 +1,9 @@ +using Recyclarr.TrashLib.Config; +using Recyclarr.TrashLib.Services.CustomFormat.Models; + +namespace Recyclarr.TrashLib.Services.CustomFormat.Guide; + +public interface ICustomFormatGuideService +{ + ICollection GetCustomFormatData(SupportedServices serviceType); +} diff --git a/src/Recyclarr.TrashLib/Services/CustomFormat/ICustomFormatUpdater.cs b/src/Recyclarr.TrashLib/Services/CustomFormat/ICustomFormatUpdater.cs index bcae28da..eaad2498 100644 --- a/src/Recyclarr.TrashLib/Services/CustomFormat/ICustomFormatUpdater.cs +++ b/src/Recyclarr.TrashLib/Services/CustomFormat/ICustomFormatUpdater.cs @@ -1,9 +1,9 @@ +using Recyclarr.TrashLib.Config; using Recyclarr.TrashLib.Config.Services; -using Recyclarr.TrashLib.Services.Common; namespace Recyclarr.TrashLib.Services.CustomFormat; public interface ICustomFormatUpdater { - Task Process(bool isPreview, IEnumerable configs, IGuideService guideService); + Task Process(bool isPreview, IEnumerable configs, SupportedServices serviceType); } diff --git a/src/Recyclarr.TrashLib/Services/CustomFormat/Processors/GuideProcessor.cs b/src/Recyclarr.TrashLib/Services/CustomFormat/Processors/GuideProcessor.cs index 96efce82..c53eea98 100644 --- a/src/Recyclarr.TrashLib/Services/CustomFormat/Processors/GuideProcessor.cs +++ b/src/Recyclarr.TrashLib/Services/CustomFormat/Processors/GuideProcessor.cs @@ -1,5 +1,6 @@ +using Recyclarr.TrashLib.Config; using Recyclarr.TrashLib.Config.Services; -using Recyclarr.TrashLib.Services.Common; +using Recyclarr.TrashLib.Services.CustomFormat.Guide; using Recyclarr.TrashLib.Services.CustomFormat.Models; using Recyclarr.TrashLib.Services.CustomFormat.Models.Cache; using Recyclarr.TrashLib.Services.CustomFormat.Processors.GuideSteps; @@ -17,10 +18,14 @@ internal class GuideProcessor : IGuideProcessor { private IList? _guideCustomFormatJson; private readonly IGuideProcessorSteps _steps; + private readonly ICustomFormatGuideService _guide; - public GuideProcessor(IGuideProcessorSteps steps) + public GuideProcessor( + IGuideProcessorSteps steps, + ICustomFormatGuideService guide) { _steps = steps; + _guide = guide; } public IReadOnlyCollection ProcessedCustomFormats @@ -44,10 +49,12 @@ internal class GuideProcessor : IGuideProcessor public IReadOnlyCollection DeletedCustomFormatsInCache => _steps.CustomFormat.DeletedCustomFormatsInCache; - public Task BuildGuideDataAsync(IEnumerable config, CustomFormatCache? cache, - IGuideService guideService) + public Task BuildGuideDataAsync( + IEnumerable config, + CustomFormatCache? cache, + SupportedServices serviceType) { - _guideCustomFormatJson ??= guideService.GetCustomFormatData().ToList(); + _guideCustomFormatJson ??= _guide.GetCustomFormatData(serviceType).ToList(); var listOfConfigs = config.ToList(); diff --git a/src/Recyclarr.TrashLib/Services/CustomFormat/Processors/IGuideProcessor.cs b/src/Recyclarr.TrashLib/Services/CustomFormat/Processors/IGuideProcessor.cs index 6e5926f4..24e52028 100644 --- a/src/Recyclarr.TrashLib/Services/CustomFormat/Processors/IGuideProcessor.cs +++ b/src/Recyclarr.TrashLib/Services/CustomFormat/Processors/IGuideProcessor.cs @@ -1,5 +1,5 @@ +using Recyclarr.TrashLib.Config; using Recyclarr.TrashLib.Config.Services; -using Recyclarr.TrashLib.Services.Common; using Recyclarr.TrashLib.Services.CustomFormat.Models; using Recyclarr.TrashLib.Services.CustomFormat.Models.Cache; @@ -15,6 +15,8 @@ internal interface IGuideProcessor IReadOnlyCollection DeletedCustomFormatsInCache { get; } IReadOnlyDictionary>> DuplicateScores { get; } - Task BuildGuideDataAsync(IEnumerable config, CustomFormatCache? cache, - IGuideService guideService); + Task BuildGuideDataAsync( + IEnumerable config, + CustomFormatCache? cache, + SupportedServices serviceType); } diff --git a/src/Recyclarr.TrashLib/Services/Processors/RadarrProcessor.cs b/src/Recyclarr.TrashLib/Services/Processors/RadarrProcessor.cs index 5952c97d..fcf3dad3 100644 --- a/src/Recyclarr.TrashLib/Services/Processors/RadarrProcessor.cs +++ b/src/Recyclarr.TrashLib/Services/Processors/RadarrProcessor.cs @@ -1,6 +1,6 @@ +using Recyclarr.TrashLib.Config; using Recyclarr.TrashLib.Services.CustomFormat; using Recyclarr.TrashLib.Services.QualitySize; -using Recyclarr.TrashLib.Services.Radarr; using Recyclarr.TrashLib.Services.Radarr.Config; namespace Recyclarr.TrashLib.Services.Processors; @@ -10,20 +10,17 @@ public class RadarrProcessor : IServiceProcessor private readonly ILogger _log; private readonly ICustomFormatUpdater _cfUpdater; private readonly IQualitySizeUpdater _qualityUpdater; - private readonly RadarrGuideService _guideService; private readonly RadarrConfiguration _config; public RadarrProcessor( ILogger log, ICustomFormatUpdater cfUpdater, IQualitySizeUpdater qualityUpdater, - RadarrGuideService guideService, RadarrConfiguration config) { _log = log; _cfUpdater = cfUpdater; _qualityUpdater = qualityUpdater; - _guideService = guideService; _config = config; } @@ -33,13 +30,13 @@ public class RadarrProcessor : IServiceProcessor if (_config.QualityDefinition != null) { - await _qualityUpdater.Process(settings.Preview, _config.QualityDefinition, _guideService); + await _qualityUpdater.Process(settings.Preview, _config.QualityDefinition, SupportedServices.Radarr); didWork = true; } if (_config.CustomFormats.Count > 0) { - await _cfUpdater.Process(settings.Preview, _config.CustomFormats, _guideService); + await _cfUpdater.Process(settings.Preview, _config.CustomFormats, SupportedServices.Radarr); didWork = true; } diff --git a/src/Recyclarr.TrashLib/Services/Processors/SonarrProcessor.cs b/src/Recyclarr.TrashLib/Services/Processors/SonarrProcessor.cs index f7ae9867..d81b2cc9 100644 --- a/src/Recyclarr.TrashLib/Services/Processors/SonarrProcessor.cs +++ b/src/Recyclarr.TrashLib/Services/Processors/SonarrProcessor.cs @@ -1,9 +1,9 @@ +using Recyclarr.TrashLib.Config; using Recyclarr.TrashLib.Services.CustomFormat; using Recyclarr.TrashLib.Services.QualitySize; -using Recyclarr.TrashLib.Services.Sonarr; +using Recyclarr.TrashLib.Services.ReleaseProfile; using Recyclarr.TrashLib.Services.Sonarr.Capabilities; using Recyclarr.TrashLib.Services.Sonarr.Config; -using Recyclarr.TrashLib.Services.Sonarr.ReleaseProfile; namespace Recyclarr.TrashLib.Services.Processors; @@ -12,7 +12,6 @@ public class SonarrProcessor : IServiceProcessor private readonly ILogger _log; private readonly ICustomFormatUpdater _cfUpdater; private readonly IQualitySizeUpdater _qualityUpdater; - private readonly SonarrGuideService _guideService; private readonly IReleaseProfileUpdater _profileUpdater; private readonly SonarrCapabilityEnforcer _compatibilityEnforcer; private readonly SonarrConfiguration _config; @@ -21,7 +20,6 @@ public class SonarrProcessor : IServiceProcessor ILogger log, ICustomFormatUpdater cfUpdater, IQualitySizeUpdater qualityUpdater, - SonarrGuideService guideService, IReleaseProfileUpdater profileUpdater, SonarrCapabilityEnforcer compatibilityEnforcer, SonarrConfiguration config) @@ -29,7 +27,6 @@ public class SonarrProcessor : IServiceProcessor _log = log; _cfUpdater = cfUpdater; _qualityUpdater = qualityUpdater; - _guideService = guideService; _profileUpdater = profileUpdater; _compatibilityEnforcer = compatibilityEnforcer; _config = config; @@ -50,13 +47,13 @@ public class SonarrProcessor : IServiceProcessor if (_config.QualityDefinition != null) { - await _qualityUpdater.Process(settings.Preview, _config.QualityDefinition, _guideService); + await _qualityUpdater.Process(settings.Preview, _config.QualityDefinition, SupportedServices.Sonarr); didWork = true; } if (_config.CustomFormats.Count > 0) { - await _cfUpdater.Process(settings.Preview, _config.CustomFormats, _guideService); + await _cfUpdater.Process(settings.Preview, _config.CustomFormats, SupportedServices.Sonarr); didWork = true; } diff --git a/src/Recyclarr.TrashLib/Services/QualitySize/Guide/IQualityGuideService.cs b/src/Recyclarr.TrashLib/Services/QualitySize/Guide/IQualityGuideService.cs new file mode 100644 index 00000000..5ee46d43 --- /dev/null +++ b/src/Recyclarr.TrashLib/Services/QualitySize/Guide/IQualityGuideService.cs @@ -0,0 +1,8 @@ +using Recyclarr.TrashLib.Config; + +namespace Recyclarr.TrashLib.Services.QualitySize.Guide; + +public interface IQualityGuideService +{ + IReadOnlyList GetQualitySizeData(SupportedServices serviceType); +} diff --git a/src/Recyclarr.TrashLib/Services/QualitySize/Guide/QualityGuideService.cs b/src/Recyclarr.TrashLib/Services/QualitySize/Guide/QualityGuideService.cs new file mode 100644 index 00000000..46eaa464 --- /dev/null +++ b/src/Recyclarr.TrashLib/Services/QualitySize/Guide/QualityGuideService.cs @@ -0,0 +1,39 @@ +using Recyclarr.TrashLib.Config; +using Recyclarr.TrashLib.Repo; + +namespace Recyclarr.TrashLib.Services.QualitySize.Guide; + +public class QualityGuideService : IQualityGuideService +{ + private readonly IRepoMetadataBuilder _metadataBuilder; + private readonly QualitySizeGuideParser _parser; + + public QualityGuideService( + IRepoMetadataBuilder metadataBuilder, + QualitySizeGuideParser parser) + { + _metadataBuilder = metadataBuilder; + _parser = parser; + } + + private QualitySizePaths CreatePaths(SupportedServices serviceType) + { + var metadata = _metadataBuilder.GetMetadata(); + return serviceType switch + { + SupportedServices.Radarr => new QualitySizePaths( + _metadataBuilder.ToDirectoryInfoList(metadata.JsonPaths.Radarr.Qualities) + ), + SupportedServices.Sonarr => new QualitySizePaths( + _metadataBuilder.ToDirectoryInfoList(metadata.JsonPaths.Sonarr.Qualities) + ), + _ => throw new ArgumentOutOfRangeException(nameof(serviceType), serviceType, null) + }; + } + + public IReadOnlyList GetQualitySizeData(SupportedServices serviceType) + { + var paths = CreatePaths(serviceType); + return _parser.GetQualities(paths.QualitySizeDirectories); + } +} diff --git a/src/Recyclarr.TrashLib/Services/QualitySize/Guide/QualitySizeDataLister.cs b/src/Recyclarr.TrashLib/Services/QualitySize/Guide/QualitySizeDataLister.cs new file mode 100644 index 00000000..842ba0d1 --- /dev/null +++ b/src/Recyclarr.TrashLib/Services/QualitySize/Guide/QualitySizeDataLister.cs @@ -0,0 +1,32 @@ +using MoreLinq; +using Recyclarr.TrashLib.Config; +using Spectre.Console; + +namespace Recyclarr.TrashLib.Services.QualitySize.Guide; + +public class QualitySizeDataLister +{ + private readonly IAnsiConsole _console; + private readonly IQualityGuideService _guide; + + public QualitySizeDataLister( + IAnsiConsole console, + IQualityGuideService guide) + { + _console = console; + _guide = guide; + } + + public void ListQualities(SupportedServices serviceType) + { + _console.WriteLine("\nList of Quality Definition types in the TRaSH Guides:\n"); + + _guide.GetQualitySizeData(serviceType) + .Select(x => x.Type) + .ForEach(x => _console.WriteLine($" - {x}")); + + _console.WriteLine( + "\nThe above quality definition types can be used with the `quality_definition:` property in your " + + "recyclarr.yml file."); + } +} diff --git a/src/Recyclarr.TrashLib/Services/QualitySize/Guide/QualitySizeGuideParser.cs b/src/Recyclarr.TrashLib/Services/QualitySize/Guide/QualitySizeGuideParser.cs index 58dc540d..1941c1dd 100644 --- a/src/Recyclarr.TrashLib/Services/QualitySize/Guide/QualitySizeGuideParser.cs +++ b/src/Recyclarr.TrashLib/Services/QualitySize/Guide/QualitySizeGuideParser.cs @@ -6,7 +6,7 @@ using Recyclarr.Common.Extensions; namespace Recyclarr.TrashLib.Services.QualitySize.Guide; -internal class QualitySizeGuideParser where T : class +public class QualitySizeGuideParser { private readonly ILogger _log; @@ -15,7 +15,7 @@ internal class QualitySizeGuideParser where T : class _log = log; } - public ICollection GetQualities(IEnumerable jsonDirectories) + public IReadOnlyList GetQualities(IEnumerable jsonDirectories) { return JsonUtils.GetJsonFilesInDirectories(jsonDirectories, _log) .Select(ParseQuality) @@ -23,7 +23,7 @@ internal class QualitySizeGuideParser where T : class .ToList(); } - private T? ParseQuality(IFileInfo jsonFile) + private QualitySizeData? ParseQuality(IFileInfo jsonFile) { var serializer = JsonSerializer.Create(new JsonSerializerSettings { @@ -34,7 +34,7 @@ internal class QualitySizeGuideParser where T : class }); using var json = new JsonTextReader(jsonFile.OpenText()); - var quality = serializer.Deserialize(json); + var quality = serializer.Deserialize(json); if (quality is null) { _log.Debug("Failed to parse quality definition JSON file: {Filename}", jsonFile.FullName); diff --git a/src/Recyclarr.TrashLib/Services/QualitySize/Guide/QualitySizePaths.cs b/src/Recyclarr.TrashLib/Services/QualitySize/Guide/QualitySizePaths.cs new file mode 100644 index 00000000..b90cd1ff --- /dev/null +++ b/src/Recyclarr.TrashLib/Services/QualitySize/Guide/QualitySizePaths.cs @@ -0,0 +1,7 @@ +using System.IO.Abstractions; + +namespace Recyclarr.TrashLib.Services.QualitySize.Guide; + +internal record QualitySizePaths( + IReadOnlyCollection QualitySizeDirectories +); diff --git a/src/Recyclarr.TrashLib/Services/QualitySize/IQualitySizeUpdater.cs b/src/Recyclarr.TrashLib/Services/QualitySize/IQualitySizeUpdater.cs index ff14273c..b13b7e9a 100644 --- a/src/Recyclarr.TrashLib/Services/QualitySize/IQualitySizeUpdater.cs +++ b/src/Recyclarr.TrashLib/Services/QualitySize/IQualitySizeUpdater.cs @@ -1,9 +1,9 @@ +using Recyclarr.TrashLib.Config; using Recyclarr.TrashLib.Config.Services; -using Recyclarr.TrashLib.Services.Common; namespace Recyclarr.TrashLib.Services.QualitySize; public interface IQualitySizeUpdater { - Task Process(bool isPreview, QualityDefinitionConfig config, IGuideService guideService); + Task Process(bool isPreview, QualityDefinitionConfig config, SupportedServices serviceType); } diff --git a/src/Recyclarr.TrashLib/Services/QualitySize/QualitySizeAutofacModule.cs b/src/Recyclarr.TrashLib/Services/QualitySize/QualitySizeAutofacModule.cs new file mode 100644 index 00000000..19e7b057 --- /dev/null +++ b/src/Recyclarr.TrashLib/Services/QualitySize/QualitySizeAutofacModule.cs @@ -0,0 +1,16 @@ +using Autofac; +using Recyclarr.TrashLib.Services.QualitySize.Api; +using Recyclarr.TrashLib.Services.QualitySize.Guide; + +namespace Recyclarr.TrashLib.Services.QualitySize; + +public class QualitySizeAutofacModule : Module +{ + protected override void Load(ContainerBuilder builder) + { + builder.RegisterType().As(); + builder.RegisterType().As(); + builder.RegisterType().As(); + builder.RegisterType(); + } +} diff --git a/src/Recyclarr.TrashLib/Services/QualitySize/QualitySizeUpdater.cs b/src/Recyclarr.TrashLib/Services/QualitySize/QualitySizeUpdater.cs index 1be14090..2fddac2e 100644 --- a/src/Recyclarr.TrashLib/Services/QualitySize/QualitySizeUpdater.cs +++ b/src/Recyclarr.TrashLib/Services/QualitySize/QualitySizeUpdater.cs @@ -1,7 +1,8 @@ using Recyclarr.Common.Extensions; +using Recyclarr.TrashLib.Config; using Recyclarr.TrashLib.Config.Services; -using Recyclarr.TrashLib.Services.Common; using Recyclarr.TrashLib.Services.QualitySize.Api; +using Recyclarr.TrashLib.Services.QualitySize.Guide; using Spectre.Console; namespace Recyclarr.TrashLib.Services.QualitySize; @@ -11,21 +12,24 @@ internal class QualitySizeUpdater : IQualitySizeUpdater private readonly ILogger _log; private readonly IQualityDefinitionService _api; private readonly IAnsiConsole _console; + private readonly IQualityGuideService _guide; public QualitySizeUpdater( ILogger logger, IQualityDefinitionService api, - IAnsiConsole console) + IAnsiConsole console, + IQualityGuideService guide) { _log = logger; _api = api; _console = console; + _guide = guide; } - public async Task Process(bool isPreview, QualityDefinitionConfig config, IGuideService guideService) + public async Task Process(bool isPreview, QualityDefinitionConfig config, SupportedServices serviceType) { _log.Information("Processing Quality Definition: {QualityDefinition}", config.Type); - var qualityDefinitions = guideService.GetQualities(); + var qualityDefinitions = _guide.GetQualitySizeData(serviceType); var qualityTypeInConfig = config.Type; var selectedQuality = qualityDefinitions diff --git a/src/Recyclarr.TrashLib/Services/Radarr/IRadarrGuideDataLister.cs b/src/Recyclarr.TrashLib/Services/Radarr/IRadarrGuideDataLister.cs deleted file mode 100644 index 3d1c02ff..00000000 --- a/src/Recyclarr.TrashLib/Services/Radarr/IRadarrGuideDataLister.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Recyclarr.TrashLib.Services.Radarr; - -public interface IRadarrGuideDataLister -{ - void ListCustomFormats(); - void ListQualities(); -} diff --git a/src/Recyclarr.TrashLib/Services/Radarr/LocalRepoRadarrGuideService.cs b/src/Recyclarr.TrashLib/Services/Radarr/LocalRepoRadarrGuideService.cs deleted file mode 100644 index 606b53f5..00000000 --- a/src/Recyclarr.TrashLib/Services/Radarr/LocalRepoRadarrGuideService.cs +++ /dev/null @@ -1,34 +0,0 @@ -using Recyclarr.TrashLib.Repo; -using Recyclarr.TrashLib.Services.CustomFormat.Guide; -using Recyclarr.TrashLib.Services.CustomFormat.Models; -using Recyclarr.TrashLib.Services.QualitySize; -using Recyclarr.TrashLib.Services.QualitySize.Guide; - -namespace Recyclarr.TrashLib.Services.Radarr; - -public class LocalRepoRadarrGuideService : RadarrGuideService -{ - private readonly IRepoPathsFactory _pathsFactory; - private readonly ICustomFormatLoader _cfLoader; - private readonly QualitySizeGuideParser _parser; - - public LocalRepoRadarrGuideService(IRepoPathsFactory pathsFactory, ILogger log, ICustomFormatLoader cfLoader) - { - _pathsFactory = pathsFactory; - _cfLoader = cfLoader; - _parser = new QualitySizeGuideParser(log); - } - - public override ICollection GetQualities() - { - return _parser.GetQualities(_pathsFactory.Create().RadarrQualityPaths); - } - - public override ICollection GetCustomFormatData() - { - var paths = _pathsFactory.Create(); - return _cfLoader.LoadAllCustomFormatsAtPaths( - paths.RadarrCustomFormatPaths, - paths.RadarrCollectionOfCustomFormats); - } -} diff --git a/src/Recyclarr.TrashLib/Services/Radarr/RadarrAutofacModule.cs b/src/Recyclarr.TrashLib/Services/Radarr/RadarrAutofacModule.cs index 09c35af4..286c3748 100644 --- a/src/Recyclarr.TrashLib/Services/Radarr/RadarrAutofacModule.cs +++ b/src/Recyclarr.TrashLib/Services/Radarr/RadarrAutofacModule.cs @@ -1,8 +1,4 @@ using Autofac; -using Recyclarr.TrashLib.Config; -using Recyclarr.TrashLib.Services.Common; -using Recyclarr.TrashLib.Services.QualitySize; -using Recyclarr.TrashLib.Services.QualitySize.Api; namespace Recyclarr.TrashLib.Services.Radarr; @@ -10,14 +6,6 @@ public class RadarrAutofacModule : Module { protected override void Load(ContainerBuilder builder) { - builder.RegisterType().As(); - builder.RegisterType().As(); - builder.RegisterType().As(); - - builder.RegisterType() - .As() - .Keyed(SupportedServices.Radarr); - builder.RegisterType().As() .InstancePerLifetimeScope(); } diff --git a/src/Recyclarr.TrashLib/Services/Radarr/RadarrGuideDataLister.cs b/src/Recyclarr.TrashLib/Services/Radarr/RadarrGuideDataLister.cs deleted file mode 100644 index 5a635996..00000000 --- a/src/Recyclarr.TrashLib/Services/Radarr/RadarrGuideDataLister.cs +++ /dev/null @@ -1,29 +0,0 @@ -using JetBrains.Annotations; -using Recyclarr.TrashLib.Services.Common; - -namespace Recyclarr.TrashLib.Services.Radarr; - -[UsedImplicitly] -public class RadarrGuideDataLister : IRadarrGuideDataLister -{ - private readonly RadarrGuideService _guide; - private readonly IGuideDataLister _guideLister; - - public RadarrGuideDataLister( - RadarrGuideService guide, - IGuideDataLister guideLister) - { - _guide = guide; - _guideLister = guideLister; - } - - public void ListCustomFormats() - { - _guideLister.ListCustomFormats(_guide.GetCustomFormatData()); - } - - public void ListQualities() - { - _guideLister.ListQualities(_guide.GetQualities()); - } -} diff --git a/src/Recyclarr.TrashLib/Services/Radarr/RadarrGuideService.cs b/src/Recyclarr.TrashLib/Services/Radarr/RadarrGuideService.cs deleted file mode 100644 index 2fa96086..00000000 --- a/src/Recyclarr.TrashLib/Services/Radarr/RadarrGuideService.cs +++ /dev/null @@ -1,11 +0,0 @@ -using Recyclarr.TrashLib.Services.Common; -using Recyclarr.TrashLib.Services.CustomFormat.Models; -using Recyclarr.TrashLib.Services.QualitySize; - -namespace Recyclarr.TrashLib.Services.Radarr; - -public abstract class RadarrGuideService : IGuideService -{ - public abstract ICollection GetCustomFormatData(); - public abstract ICollection GetQualities(); -} diff --git a/src/Recyclarr.TrashLib/Services/Sonarr/Api/IReleaseProfileApiService.cs b/src/Recyclarr.TrashLib/Services/ReleaseProfile/Api/IReleaseProfileApiService.cs similarity index 71% rename from src/Recyclarr.TrashLib/Services/Sonarr/Api/IReleaseProfileApiService.cs rename to src/Recyclarr.TrashLib/Services/ReleaseProfile/Api/IReleaseProfileApiService.cs index e0a81bee..f14cdffa 100644 --- a/src/Recyclarr.TrashLib/Services/Sonarr/Api/IReleaseProfileApiService.cs +++ b/src/Recyclarr.TrashLib/Services/ReleaseProfile/Api/IReleaseProfileApiService.cs @@ -1,6 +1,6 @@ -using Recyclarr.TrashLib.Services.Sonarr.Api.Objects; +using Recyclarr.TrashLib.Services.ReleaseProfile.Api.Objects; -namespace Recyclarr.TrashLib.Services.Sonarr.Api; +namespace Recyclarr.TrashLib.Services.ReleaseProfile.Api; public interface IReleaseProfileApiService { diff --git a/src/Recyclarr.TrashLib/Services/Sonarr/Api/ISonarrReleaseProfileCompatibilityHandler.cs b/src/Recyclarr.TrashLib/Services/ReleaseProfile/Api/ISonarrReleaseProfileCompatibilityHandler.cs similarity index 67% rename from src/Recyclarr.TrashLib/Services/Sonarr/Api/ISonarrReleaseProfileCompatibilityHandler.cs rename to src/Recyclarr.TrashLib/Services/ReleaseProfile/Api/ISonarrReleaseProfileCompatibilityHandler.cs index 4332c49b..d1a9da94 100644 --- a/src/Recyclarr.TrashLib/Services/Sonarr/Api/ISonarrReleaseProfileCompatibilityHandler.cs +++ b/src/Recyclarr.TrashLib/Services/ReleaseProfile/Api/ISonarrReleaseProfileCompatibilityHandler.cs @@ -1,7 +1,7 @@ using Newtonsoft.Json.Linq; -using Recyclarr.TrashLib.Services.Sonarr.Api.Objects; +using Recyclarr.TrashLib.Services.ReleaseProfile.Api.Objects; -namespace Recyclarr.TrashLib.Services.Sonarr.Api; +namespace Recyclarr.TrashLib.Services.ReleaseProfile.Api; public interface ISonarrReleaseProfileCompatibilityHandler { diff --git a/src/Recyclarr.TrashLib/Services/Sonarr/Api/Mappings/SonarrApiObjectMappingProfile.cs b/src/Recyclarr.TrashLib/Services/ReleaseProfile/Api/Mappings/SonarrApiObjectMappingProfile.cs similarity index 86% rename from src/Recyclarr.TrashLib/Services/Sonarr/Api/Mappings/SonarrApiObjectMappingProfile.cs rename to src/Recyclarr.TrashLib/Services/ReleaseProfile/Api/Mappings/SonarrApiObjectMappingProfile.cs index 51bac83e..0f6692ae 100644 --- a/src/Recyclarr.TrashLib/Services/Sonarr/Api/Mappings/SonarrApiObjectMappingProfile.cs +++ b/src/Recyclarr.TrashLib/Services/ReleaseProfile/Api/Mappings/SonarrApiObjectMappingProfile.cs @@ -1,8 +1,8 @@ using AutoMapper; using JetBrains.Annotations; -using Recyclarr.TrashLib.Services.Sonarr.Api.Objects; +using Recyclarr.TrashLib.Services.ReleaseProfile.Api.Objects; -namespace Recyclarr.TrashLib.Services.Sonarr.Api.Mappings; +namespace Recyclarr.TrashLib.Services.ReleaseProfile.Api.Mappings; [UsedImplicitly] public class SonarrApiObjectMappingProfile : Profile diff --git a/src/Recyclarr.TrashLib/Services/Sonarr/Api/Objects/SonarrReleaseProfile.cs b/src/Recyclarr.TrashLib/Services/ReleaseProfile/Api/Objects/SonarrReleaseProfile.cs similarity index 96% rename from src/Recyclarr.TrashLib/Services/Sonarr/Api/Objects/SonarrReleaseProfile.cs rename to src/Recyclarr.TrashLib/Services/ReleaseProfile/Api/Objects/SonarrReleaseProfile.cs index 668c122d..419c33c9 100644 --- a/src/Recyclarr.TrashLib/Services/Sonarr/Api/Objects/SonarrReleaseProfile.cs +++ b/src/Recyclarr.TrashLib/Services/ReleaseProfile/Api/Objects/SonarrReleaseProfile.cs @@ -1,7 +1,7 @@ using JetBrains.Annotations; using Newtonsoft.Json; -namespace Recyclarr.TrashLib.Services.Sonarr.Api.Objects; +namespace Recyclarr.TrashLib.Services.ReleaseProfile.Api.Objects; [UsedImplicitly(ImplicitUseKindFlags.Assign, ImplicitUseTargetFlags.Members)] public class SonarrPreferredTerm diff --git a/src/Recyclarr.TrashLib/Services/Sonarr/Api/ReleaseProfileApiService.cs b/src/Recyclarr.TrashLib/Services/ReleaseProfile/Api/ReleaseProfileApiService.cs similarity index 93% rename from src/Recyclarr.TrashLib/Services/Sonarr/Api/ReleaseProfileApiService.cs rename to src/Recyclarr.TrashLib/Services/ReleaseProfile/Api/ReleaseProfileApiService.cs index ba18a483..13ad1552 100644 --- a/src/Recyclarr.TrashLib/Services/Sonarr/Api/ReleaseProfileApiService.cs +++ b/src/Recyclarr.TrashLib/Services/ReleaseProfile/Api/ReleaseProfileApiService.cs @@ -1,9 +1,9 @@ using Flurl.Http; using Newtonsoft.Json.Linq; using Recyclarr.TrashLib.Http; -using Recyclarr.TrashLib.Services.Sonarr.Api.Objects; +using Recyclarr.TrashLib.Services.ReleaseProfile.Api.Objects; -namespace Recyclarr.TrashLib.Services.Sonarr.Api; +namespace Recyclarr.TrashLib.Services.ReleaseProfile.Api; public class ReleaseProfileApiService : IReleaseProfileApiService { diff --git a/src/Recyclarr.TrashLib/Services/Sonarr/Api/Schemas/SonarrReleaseProfileSchema.cs b/src/Recyclarr.TrashLib/Services/ReleaseProfile/Api/Schemas/SonarrReleaseProfileSchema.cs similarity index 97% rename from src/Recyclarr.TrashLib/Services/Sonarr/Api/Schemas/SonarrReleaseProfileSchema.cs rename to src/Recyclarr.TrashLib/Services/ReleaseProfile/Api/Schemas/SonarrReleaseProfileSchema.cs index ae72c7b8..822da445 100644 --- a/src/Recyclarr.TrashLib/Services/Sonarr/Api/Schemas/SonarrReleaseProfileSchema.cs +++ b/src/Recyclarr.TrashLib/Services/ReleaseProfile/Api/Schemas/SonarrReleaseProfileSchema.cs @@ -1,4 +1,4 @@ -namespace Recyclarr.TrashLib.Services.Sonarr.Api.Schemas; +namespace Recyclarr.TrashLib.Services.ReleaseProfile.Api.Schemas; public static class SonarrReleaseProfileSchema { diff --git a/src/Recyclarr.TrashLib/Services/Sonarr/Api/SonarrReleaseProfileCompatibilityHandler.cs b/src/Recyclarr.TrashLib/Services/ReleaseProfile/Api/SonarrReleaseProfileCompatibilityHandler.cs similarity index 92% rename from src/Recyclarr.TrashLib/Services/Sonarr/Api/SonarrReleaseProfileCompatibilityHandler.cs rename to src/Recyclarr.TrashLib/Services/ReleaseProfile/Api/SonarrReleaseProfileCompatibilityHandler.cs index 800685cd..d00afbcf 100644 --- a/src/Recyclarr.TrashLib/Services/Sonarr/Api/SonarrReleaseProfileCompatibilityHandler.cs +++ b/src/Recyclarr.TrashLib/Services/ReleaseProfile/Api/SonarrReleaseProfileCompatibilityHandler.cs @@ -2,11 +2,11 @@ using AutoMapper; using Newtonsoft.Json.Linq; using Newtonsoft.Json.Schema; using Recyclarr.TrashLib.ExceptionTypes; -using Recyclarr.TrashLib.Services.Sonarr.Api.Objects; -using Recyclarr.TrashLib.Services.Sonarr.Api.Schemas; +using Recyclarr.TrashLib.Services.ReleaseProfile.Api.Objects; +using Recyclarr.TrashLib.Services.ReleaseProfile.Api.Schemas; using Recyclarr.TrashLib.Services.Sonarr.Capabilities; -namespace Recyclarr.TrashLib.Services.Sonarr.Api; +namespace Recyclarr.TrashLib.Services.ReleaseProfile.Api; public class SonarrReleaseProfileCompatibilityHandler : ISonarrReleaseProfileCompatibilityHandler { diff --git a/src/Recyclarr.TrashLib/Services/Sonarr/ReleaseProfile/Filters/IReleaseProfileFilter.cs b/src/Recyclarr.TrashLib/Services/ReleaseProfile/Filters/IReleaseProfileFilter.cs similarity index 72% rename from src/Recyclarr.TrashLib/Services/Sonarr/ReleaseProfile/Filters/IReleaseProfileFilter.cs rename to src/Recyclarr.TrashLib/Services/ReleaseProfile/Filters/IReleaseProfileFilter.cs index 9afcfc05..1e0a2f6e 100644 --- a/src/Recyclarr.TrashLib/Services/Sonarr/ReleaseProfile/Filters/IReleaseProfileFilter.cs +++ b/src/Recyclarr.TrashLib/Services/ReleaseProfile/Filters/IReleaseProfileFilter.cs @@ -1,6 +1,6 @@ using Recyclarr.TrashLib.Services.Sonarr.Config; -namespace Recyclarr.TrashLib.Services.Sonarr.ReleaseProfile.Filters; +namespace Recyclarr.TrashLib.Services.ReleaseProfile.Filters; public interface IReleaseProfileFilter { diff --git a/src/Recyclarr.TrashLib/Services/Sonarr/ReleaseProfile/Filters/IReleaseProfileFilterPipeline.cs b/src/Recyclarr.TrashLib/Services/ReleaseProfile/Filters/IReleaseProfileFilterPipeline.cs similarity index 73% rename from src/Recyclarr.TrashLib/Services/Sonarr/ReleaseProfile/Filters/IReleaseProfileFilterPipeline.cs rename to src/Recyclarr.TrashLib/Services/ReleaseProfile/Filters/IReleaseProfileFilterPipeline.cs index 9fcb1810..735b5bcc 100644 --- a/src/Recyclarr.TrashLib/Services/Sonarr/ReleaseProfile/Filters/IReleaseProfileFilterPipeline.cs +++ b/src/Recyclarr.TrashLib/Services/ReleaseProfile/Filters/IReleaseProfileFilterPipeline.cs @@ -1,6 +1,6 @@ using Recyclarr.TrashLib.Services.Sonarr.Config; -namespace Recyclarr.TrashLib.Services.Sonarr.ReleaseProfile.Filters; +namespace Recyclarr.TrashLib.Services.ReleaseProfile.Filters; public interface IReleaseProfileFilterPipeline { diff --git a/src/Recyclarr.TrashLib/Services/Sonarr/ReleaseProfile/Filters/IncludeExcludeFilter.cs b/src/Recyclarr.TrashLib/Services/ReleaseProfile/Filters/IncludeExcludeFilter.cs similarity index 91% rename from src/Recyclarr.TrashLib/Services/Sonarr/ReleaseProfile/Filters/IncludeExcludeFilter.cs rename to src/Recyclarr.TrashLib/Services/ReleaseProfile/Filters/IncludeExcludeFilter.cs index 05e19f66..46529829 100644 --- a/src/Recyclarr.TrashLib/Services/Sonarr/ReleaseProfile/Filters/IncludeExcludeFilter.cs +++ b/src/Recyclarr.TrashLib/Services/ReleaseProfile/Filters/IncludeExcludeFilter.cs @@ -1,6 +1,6 @@ using Recyclarr.TrashLib.Services.Sonarr.Config; -namespace Recyclarr.TrashLib.Services.Sonarr.ReleaseProfile.Filters; +namespace Recyclarr.TrashLib.Services.ReleaseProfile.Filters; public class IncludeExcludeFilter : IReleaseProfileFilter { diff --git a/src/Recyclarr.TrashLib/Services/Sonarr/ReleaseProfile/Filters/ReleaseProfileDataFilterer.cs b/src/Recyclarr.TrashLib/Services/ReleaseProfile/Filters/ReleaseProfileDataFilterer.cs similarity index 97% rename from src/Recyclarr.TrashLib/Services/Sonarr/ReleaseProfile/Filters/ReleaseProfileDataFilterer.cs rename to src/Recyclarr.TrashLib/Services/ReleaseProfile/Filters/ReleaseProfileDataFilterer.cs index d76c48f6..a83e6224 100644 --- a/src/Recyclarr.TrashLib/Services/Sonarr/ReleaseProfile/Filters/ReleaseProfileDataFilterer.cs +++ b/src/Recyclarr.TrashLib/Services/ReleaseProfile/Filters/ReleaseProfileDataFilterer.cs @@ -1,7 +1,7 @@ using System.Collections.ObjectModel; using Recyclarr.TrashLib.Services.Sonarr.Config; -namespace Recyclarr.TrashLib.Services.Sonarr.ReleaseProfile.Filters; +namespace Recyclarr.TrashLib.Services.ReleaseProfile.Filters; public class ReleaseProfileDataFilterer { diff --git a/src/Recyclarr.TrashLib/Services/Sonarr/ReleaseProfile/Filters/ReleaseProfileDataValidationFilterer.cs b/src/Recyclarr.TrashLib/Services/ReleaseProfile/Filters/ReleaseProfileDataValidationFilterer.cs similarity index 95% rename from src/Recyclarr.TrashLib/Services/Sonarr/ReleaseProfile/Filters/ReleaseProfileDataValidationFilterer.cs rename to src/Recyclarr.TrashLib/Services/ReleaseProfile/Filters/ReleaseProfileDataValidationFilterer.cs index 239e52ca..2873a348 100644 --- a/src/Recyclarr.TrashLib/Services/Sonarr/ReleaseProfile/Filters/ReleaseProfileDataValidationFilterer.cs +++ b/src/Recyclarr.TrashLib/Services/ReleaseProfile/Filters/ReleaseProfileDataValidationFilterer.cs @@ -1,7 +1,7 @@ using FluentValidation.Results; using Recyclarr.Common.FluentValidation; -namespace Recyclarr.TrashLib.Services.Sonarr.ReleaseProfile.Filters; +namespace Recyclarr.TrashLib.Services.ReleaseProfile.Filters; public class ReleaseProfileDataValidationFilterer { diff --git a/src/Recyclarr.TrashLib/Services/Sonarr/ReleaseProfile/Filters/ReleaseProfileFilterPipeline.cs b/src/Recyclarr.TrashLib/Services/ReleaseProfile/Filters/ReleaseProfileFilterPipeline.cs similarity index 88% rename from src/Recyclarr.TrashLib/Services/Sonarr/ReleaseProfile/Filters/ReleaseProfileFilterPipeline.cs rename to src/Recyclarr.TrashLib/Services/ReleaseProfile/Filters/ReleaseProfileFilterPipeline.cs index 4c6b94a6..196737a4 100644 --- a/src/Recyclarr.TrashLib/Services/Sonarr/ReleaseProfile/Filters/ReleaseProfileFilterPipeline.cs +++ b/src/Recyclarr.TrashLib/Services/ReleaseProfile/Filters/ReleaseProfileFilterPipeline.cs @@ -1,6 +1,6 @@ using Recyclarr.TrashLib.Services.Sonarr.Config; -namespace Recyclarr.TrashLib.Services.Sonarr.ReleaseProfile.Filters; +namespace Recyclarr.TrashLib.Services.ReleaseProfile.Filters; public class ReleaseProfileFilterPipeline : IReleaseProfileFilterPipeline { diff --git a/src/Recyclarr.TrashLib/Services/Sonarr/ReleaseProfile/Filters/StrictNegativeScoresFilter.cs b/src/Recyclarr.TrashLib/Services/ReleaseProfile/Filters/StrictNegativeScoresFilter.cs similarity index 91% rename from src/Recyclarr.TrashLib/Services/Sonarr/ReleaseProfile/Filters/StrictNegativeScoresFilter.cs rename to src/Recyclarr.TrashLib/Services/ReleaseProfile/Filters/StrictNegativeScoresFilter.cs index b02987c3..fbf2b390 100644 --- a/src/Recyclarr.TrashLib/Services/Sonarr/ReleaseProfile/Filters/StrictNegativeScoresFilter.cs +++ b/src/Recyclarr.TrashLib/Services/ReleaseProfile/Filters/StrictNegativeScoresFilter.cs @@ -1,6 +1,6 @@ using Recyclarr.TrashLib.Services.Sonarr.Config; -namespace Recyclarr.TrashLib.Services.Sonarr.ReleaseProfile.Filters; +namespace Recyclarr.TrashLib.Services.ReleaseProfile.Filters; public class StrictNegativeScoresFilter : IReleaseProfileFilter { diff --git a/src/Recyclarr.TrashLib/Services/ReleaseProfile/Guide/IReleaseProfileGuideService.cs b/src/Recyclarr.TrashLib/Services/ReleaseProfile/Guide/IReleaseProfileGuideService.cs new file mode 100644 index 00000000..6decef66 --- /dev/null +++ b/src/Recyclarr.TrashLib/Services/ReleaseProfile/Guide/IReleaseProfileGuideService.cs @@ -0,0 +1,6 @@ +namespace Recyclarr.TrashLib.Services.ReleaseProfile.Guide; + +public interface IReleaseProfileGuideService +{ + IReadOnlyList GetReleaseProfileData(); +} diff --git a/src/Recyclarr.TrashLib/Services/Sonarr/SonarrGuideDataLister.cs b/src/Recyclarr.TrashLib/Services/ReleaseProfile/Guide/ReleaseProfileDataLister.cs similarity index 76% rename from src/Recyclarr.TrashLib/Services/Sonarr/SonarrGuideDataLister.cs rename to src/Recyclarr.TrashLib/Services/ReleaseProfile/Guide/ReleaseProfileDataLister.cs index 6499175a..35e7a260 100644 --- a/src/Recyclarr.TrashLib/Services/Sonarr/SonarrGuideDataLister.cs +++ b/src/Recyclarr.TrashLib/Services/ReleaseProfile/Guide/ReleaseProfileDataLister.cs @@ -1,36 +1,18 @@ using System.Text; -using JetBrains.Annotations; -using Recyclarr.TrashLib.Services.Common; -using Recyclarr.TrashLib.Services.Sonarr.ReleaseProfile; +using Recyclarr.Common.Extensions; using Spectre.Console; -namespace Recyclarr.TrashLib.Services.Sonarr; +namespace Recyclarr.TrashLib.Services.ReleaseProfile.Guide; -[UsedImplicitly] -public class SonarrGuideDataLister : ISonarrGuideDataLister +public class ReleaseProfileDataLister { private readonly IAnsiConsole _console; - private readonly SonarrGuideService _guide; - private readonly IGuideDataLister _guideLister; + private readonly IReleaseProfileGuideService _guide; - public SonarrGuideDataLister( - IAnsiConsole console, - SonarrGuideService guide, - IGuideDataLister guideLister) + public ReleaseProfileDataLister(IAnsiConsole console, IReleaseProfileGuideService guide) { _console = console; _guide = guide; - _guideLister = guideLister; - } - - public void ListCustomFormats() - { - _guideLister.ListCustomFormats(_guide.GetCustomFormatData()); - } - - public void ListQualities() - { - _guideLister.ListQualities(_guide.GetQualities()); } public void ListReleaseProfiles() @@ -62,7 +44,9 @@ public class SonarrGuideDataLister : ISonarrGuideDataLister public void ListTerms(string releaseProfileId) { - var profile = _guide.GetUnfilteredProfileById(releaseProfileId); + var profile = _guide.GetReleaseProfileData() + .FirstOrDefault(x => x.TrashId.EqualsIgnoreCase(releaseProfileId)); + if (profile is null) { throw new ArgumentException("No release profile found with that Trash ID"); diff --git a/src/Recyclarr.TrashLib/Services/ReleaseProfile/Guide/ReleaseProfileGuideParser.cs b/src/Recyclarr.TrashLib/Services/ReleaseProfile/Guide/ReleaseProfileGuideParser.cs new file mode 100644 index 00000000..4daee561 --- /dev/null +++ b/src/Recyclarr.TrashLib/Services/ReleaseProfile/Guide/ReleaseProfileGuideParser.cs @@ -0,0 +1,59 @@ +using System.IO.Abstractions; +using MoreLinq; +using Newtonsoft.Json; +using Recyclarr.Common; +using Recyclarr.TrashLib.Services.ReleaseProfile.Filters; +using Serilog; + +namespace Recyclarr.TrashLib.Services.ReleaseProfile.Guide; + +public class ReleaseProfileGuideParser +{ + private readonly ILogger _log; + + public ReleaseProfileGuideParser(ILogger log) + { + _log = log; + } + + private async Task LoadAndParseFile(IFileInfo file, params JsonConverter[] converters) + { + try + { + using var stream = file.OpenText(); + var json = await stream.ReadToEndAsync(); + return JsonConvert.DeserializeObject(json, converters); + } + catch (JsonException e) + { + HandleJsonException(e, file); + } + catch (AggregateException ae) when (ae.InnerException is JsonException e) + { + HandleJsonException(e, file); + } + + return null; + } + + private void HandleJsonException(JsonException exception, IFileInfo file) + { + _log.Warning(exception, + "Failed to parse Sonarr JSON file (This likely indicates a bug that should be " + + "reported in the TRaSH repo): {File}", file.Name); + } + + public IEnumerable GetReleaseProfileData(IEnumerable paths) + { + var converter = new TermDataConverter(); + var tasks = JsonUtils.GetJsonFilesInDirectories(paths, _log) + .Select(x => LoadAndParseFile(x, converter)); + + var data = Task.WhenAll(tasks).Result + // Make non-nullable type and filter out null values + .Choose(x => x is not null ? (true, x) : default); + + var validator = new ReleaseProfileDataValidationFilterer(_log); + return validator.FilterProfiles(data); + } +} diff --git a/src/Recyclarr.TrashLib/Services/ReleaseProfile/Guide/ReleaseProfileGuideService.cs b/src/Recyclarr.TrashLib/Services/ReleaseProfile/Guide/ReleaseProfileGuideService.cs new file mode 100644 index 00000000..f7dbd201 --- /dev/null +++ b/src/Recyclarr.TrashLib/Services/ReleaseProfile/Guide/ReleaseProfileGuideService.cs @@ -0,0 +1,31 @@ +using Recyclarr.TrashLib.Repo; + +namespace Recyclarr.TrashLib.Services.ReleaseProfile.Guide; + +public class ReleaseProfileGuideService : IReleaseProfileGuideService +{ + private readonly IRepoMetadataBuilder _metadataBuilder; + private readonly ReleaseProfileGuideParser _parser; + + public ReleaseProfileGuideService( + IRepoMetadataBuilder metadataBuilder, + ReleaseProfileGuideParser parser) + { + _metadataBuilder = metadataBuilder; + _parser = parser; + } + + private ReleaseProfilePaths GetPaths() + { + var metadata = _metadataBuilder.GetMetadata(); + return new ReleaseProfilePaths( + _metadataBuilder.ToDirectoryInfoList(metadata.JsonPaths.Sonarr.ReleaseProfiles) + ); + } + + public IReadOnlyList GetReleaseProfileData() + { + var paths = GetPaths(); + return _parser.GetReleaseProfileData(paths.ReleaseProfileDirectories).ToList(); + } +} diff --git a/src/Recyclarr.TrashLib/Services/ReleaseProfile/Guide/ReleaseProfilePaths.cs b/src/Recyclarr.TrashLib/Services/ReleaseProfile/Guide/ReleaseProfilePaths.cs new file mode 100644 index 00000000..e6607485 --- /dev/null +++ b/src/Recyclarr.TrashLib/Services/ReleaseProfile/Guide/ReleaseProfilePaths.cs @@ -0,0 +1,7 @@ +using System.IO.Abstractions; + +namespace Recyclarr.TrashLib.Services.ReleaseProfile.Guide; + +public record ReleaseProfilePaths( + IReadOnlyList ReleaseProfileDirectories +); diff --git a/src/Recyclarr.TrashLib/Services/Sonarr/ReleaseProfile/IReleaseProfileUpdater.cs b/src/Recyclarr.TrashLib/Services/ReleaseProfile/IReleaseProfileUpdater.cs similarity index 72% rename from src/Recyclarr.TrashLib/Services/Sonarr/ReleaseProfile/IReleaseProfileUpdater.cs rename to src/Recyclarr.TrashLib/Services/ReleaseProfile/IReleaseProfileUpdater.cs index 7015cce6..81f26110 100644 --- a/src/Recyclarr.TrashLib/Services/Sonarr/ReleaseProfile/IReleaseProfileUpdater.cs +++ b/src/Recyclarr.TrashLib/Services/ReleaseProfile/IReleaseProfileUpdater.cs @@ -1,6 +1,6 @@ using Recyclarr.TrashLib.Services.Sonarr.Config; -namespace Recyclarr.TrashLib.Services.Sonarr.ReleaseProfile; +namespace Recyclarr.TrashLib.Services.ReleaseProfile; public interface IReleaseProfileUpdater { diff --git a/src/Recyclarr.TrashLib/Services/ReleaseProfile/ReleaseProfileAutofacModule.cs b/src/Recyclarr.TrashLib/Services/ReleaseProfile/ReleaseProfileAutofacModule.cs new file mode 100644 index 00000000..aeeb4ec4 --- /dev/null +++ b/src/Recyclarr.TrashLib/Services/ReleaseProfile/ReleaseProfileAutofacModule.cs @@ -0,0 +1,31 @@ +using Autofac; +using Autofac.Extras.Ordering; +using Recyclarr.TrashLib.Services.ReleaseProfile.Api; +using Recyclarr.TrashLib.Services.ReleaseProfile.Filters; +using Recyclarr.TrashLib.Services.ReleaseProfile.Guide; + +namespace Recyclarr.TrashLib.Services.ReleaseProfile; + +public class ReleaseProfileAutofacModule : Module +{ + protected override void Load(ContainerBuilder builder) + { + base.Load(builder); + + builder.RegisterType().As(); + + builder.RegisterType().As(); + builder.RegisterType() + .As(); + builder.RegisterType().As(); + builder.RegisterType(); + builder.RegisterType().As(); + + // Release Profile Filters (ORDER MATTERS!) + builder.RegisterTypes( + typeof(IncludeExcludeFilter), + typeof(StrictNegativeScoresFilter)) + .As() + .OrderByRegistration(); + } +} diff --git a/src/Recyclarr.TrashLib/Services/Sonarr/ReleaseProfile/ReleaseProfileData.cs b/src/Recyclarr.TrashLib/Services/ReleaseProfile/ReleaseProfileData.cs similarity index 67% rename from src/Recyclarr.TrashLib/Services/Sonarr/ReleaseProfile/ReleaseProfileData.cs rename to src/Recyclarr.TrashLib/Services/ReleaseProfile/ReleaseProfileData.cs index 1a8c3981..6f3c13c8 100644 --- a/src/Recyclarr.TrashLib/Services/Sonarr/ReleaseProfile/ReleaseProfileData.cs +++ b/src/Recyclarr.TrashLib/Services/ReleaseProfile/ReleaseProfileData.cs @@ -1,7 +1,7 @@ using JetBrains.Annotations; using Newtonsoft.Json; -namespace Recyclarr.TrashLib.Services.Sonarr.ReleaseProfile; +namespace Recyclarr.TrashLib.Services.ReleaseProfile; [UsedImplicitly(ImplicitUseTargetFlags.WithMembers)] public record TermData @@ -11,11 +11,6 @@ public record TermData public string Name { get; init; } = string.Empty; public string Term { get; init; } = string.Empty; - - public override string ToString() - { - return $"[TrashId: {TrashId}] [Name: {Name}] [Term: {Term}]"; - } } [UsedImplicitly(ImplicitUseTargetFlags.WithMembers)] @@ -29,11 +24,6 @@ public record PreferredTermData score = Score; terms = Terms; } - - public override string ToString() - { - return $"[Score: {Score}] [Terms: {Terms.Count}]"; - } } [UsedImplicitly(ImplicitUseTargetFlags.WithMembers)] @@ -47,14 +37,4 @@ public record ReleaseProfileData public IReadOnlyCollection Required { get; init; } = Array.Empty(); public IReadOnlyCollection Ignored { get; init; } = Array.Empty(); public IReadOnlyCollection Preferred { get; init; } = Array.Empty(); - - public override string ToString() - { - return $"[TrashId: {TrashId}] " + - $"[Name: {Name}] " + - $"[IncludePreferred: {IncludePreferredWhenRenaming}] " + - $"[Required: {Required.Count}] " + - $"[Ignored: {Ignored.Count}] " + - $"[Preferred: {Preferred.Count}]"; - } } diff --git a/src/Recyclarr.TrashLib/Services/Sonarr/ReleaseProfile/ReleaseProfileDataValidator.cs b/src/Recyclarr.TrashLib/Services/ReleaseProfile/ReleaseProfileDataValidator.cs similarity index 93% rename from src/Recyclarr.TrashLib/Services/Sonarr/ReleaseProfile/ReleaseProfileDataValidator.cs rename to src/Recyclarr.TrashLib/Services/ReleaseProfile/ReleaseProfileDataValidator.cs index c1308d21..3b05d9c8 100644 --- a/src/Recyclarr.TrashLib/Services/Sonarr/ReleaseProfile/ReleaseProfileDataValidator.cs +++ b/src/Recyclarr.TrashLib/Services/ReleaseProfile/ReleaseProfileDataValidator.cs @@ -1,6 +1,6 @@ using FluentValidation; -namespace Recyclarr.TrashLib.Services.Sonarr.ReleaseProfile; +namespace Recyclarr.TrashLib.Services.ReleaseProfile; internal class TermDataValidator : AbstractValidator { diff --git a/src/Recyclarr.TrashLib/Services/Sonarr/ReleaseProfile/ReleaseProfileUpdater.cs b/src/Recyclarr.TrashLib/Services/ReleaseProfile/ReleaseProfileUpdater.cs similarity index 93% rename from src/Recyclarr.TrashLib/Services/Sonarr/ReleaseProfile/ReleaseProfileUpdater.cs rename to src/Recyclarr.TrashLib/Services/ReleaseProfile/ReleaseProfileUpdater.cs index 7f850d18..9f461335 100644 --- a/src/Recyclarr.TrashLib/Services/Sonarr/ReleaseProfile/ReleaseProfileUpdater.cs +++ b/src/Recyclarr.TrashLib/Services/ReleaseProfile/ReleaseProfileUpdater.cs @@ -1,32 +1,35 @@ using Recyclarr.Common.Extensions; +using Recyclarr.TrashLib.Services.ReleaseProfile.Api; +using Recyclarr.TrashLib.Services.ReleaseProfile.Api.Objects; +using Recyclarr.TrashLib.Services.ReleaseProfile.Filters; +using Recyclarr.TrashLib.Services.ReleaseProfile.Guide; using Recyclarr.TrashLib.Services.Sonarr.Api; using Recyclarr.TrashLib.Services.Sonarr.Api.Objects; using Recyclarr.TrashLib.Services.Sonarr.Config; -using Recyclarr.TrashLib.Services.Sonarr.ReleaseProfile.Filters; using Spectre.Console; -namespace Recyclarr.TrashLib.Services.Sonarr.ReleaseProfile; +namespace Recyclarr.TrashLib.Services.ReleaseProfile; public class ReleaseProfileUpdater : IReleaseProfileUpdater { private readonly IReleaseProfileApiService _releaseProfileApi; private readonly IReleaseProfileFilterPipeline _pipeline; private readonly IAnsiConsole _console; - private readonly SonarrGuideService _guide; - private readonly ISonarrApi _api; + private readonly IReleaseProfileGuideService _guide; + private readonly ISonarrTagApiService _tagApiService; private readonly ILogger _log; public ReleaseProfileUpdater( ILogger logger, - SonarrGuideService guide, - ISonarrApi api, + IReleaseProfileGuideService guide, + ISonarrTagApiService tagApiService, IReleaseProfileApiService releaseProfileApi, IReleaseProfileFilterPipeline pipeline, IAnsiConsole console) { _log = logger; _guide = guide; - _api = api; + _tagApiService = tagApiService; _releaseProfileApi = releaseProfileApi; _pipeline = pipeline; _console = console; @@ -195,7 +198,7 @@ public class ReleaseProfileUpdater : IReleaseProfileUpdater return Array.Empty(); } - var sonarrTags = await _api.GetTags(); + var sonarrTags = await _tagApiService.GetTags(); await CreateMissingTags(sonarrTags, tags); return sonarrTags .Where(t => tags.Any(ct => ct.EqualsIgnoreCase(t.Label))) @@ -209,7 +212,7 @@ public class ReleaseProfileUpdater : IReleaseProfileUpdater foreach (var tag in missingTags) { _log.Debug("Creating Tag: {Tag}", tag); - var newTag = await _api.CreateTag(tag); + var newTag = await _tagApiService.CreateTag(tag); sonarrTags.Add(newTag); } } diff --git a/src/Recyclarr.TrashLib/Services/Sonarr/ReleaseProfile/ScopedState.cs b/src/Recyclarr.TrashLib/Services/ReleaseProfile/ScopedState.cs similarity index 95% rename from src/Recyclarr.TrashLib/Services/Sonarr/ReleaseProfile/ScopedState.cs rename to src/Recyclarr.TrashLib/Services/ReleaseProfile/ScopedState.cs index 1d153073..dbd39b64 100644 --- a/src/Recyclarr.TrashLib/Services/Sonarr/ReleaseProfile/ScopedState.cs +++ b/src/Recyclarr.TrashLib/Services/ReleaseProfile/ScopedState.cs @@ -1,4 +1,4 @@ -namespace Recyclarr.TrashLib.Services.Sonarr.ReleaseProfile; +namespace Recyclarr.TrashLib.Services.ReleaseProfile; public class ScopedState { diff --git a/src/Recyclarr.TrashLib/Services/Sonarr/ReleaseProfile/TermDataConverter.cs b/src/Recyclarr.TrashLib/Services/ReleaseProfile/TermDataConverter.cs similarity index 92% rename from src/Recyclarr.TrashLib/Services/Sonarr/ReleaseProfile/TermDataConverter.cs rename to src/Recyclarr.TrashLib/Services/ReleaseProfile/TermDataConverter.cs index 478fb7c0..441f6c43 100644 --- a/src/Recyclarr.TrashLib/Services/Sonarr/ReleaseProfile/TermDataConverter.cs +++ b/src/Recyclarr.TrashLib/Services/ReleaseProfile/TermDataConverter.cs @@ -1,7 +1,7 @@ using Newtonsoft.Json; using Newtonsoft.Json.Linq; -namespace Recyclarr.TrashLib.Services.Sonarr.ReleaseProfile; +namespace Recyclarr.TrashLib.Services.ReleaseProfile; internal class TermDataConverter : JsonConverter { diff --git a/src/Recyclarr.TrashLib/Services/Sonarr/Api/ISonarrApi.cs b/src/Recyclarr.TrashLib/Services/Sonarr/Api/ISonarrApi.cs deleted file mode 100644 index 28cfc375..00000000 --- a/src/Recyclarr.TrashLib/Services/Sonarr/Api/ISonarrApi.cs +++ /dev/null @@ -1,13 +0,0 @@ -using Recyclarr.TrashLib.Services.Sonarr.Api.Objects; - -namespace Recyclarr.TrashLib.Services.Sonarr.Api; - -public interface ISonarrApi -{ - Task> GetTags(); - Task CreateTag(string tag); - Task> GetQualityDefinition(); - - Task> UpdateQualityDefinition( - IReadOnlyCollection newQuality); -} diff --git a/src/Recyclarr.TrashLib/Services/Sonarr/Api/ISonarrTagApiService.cs b/src/Recyclarr.TrashLib/Services/Sonarr/Api/ISonarrTagApiService.cs new file mode 100644 index 00000000..e815e335 --- /dev/null +++ b/src/Recyclarr.TrashLib/Services/Sonarr/Api/ISonarrTagApiService.cs @@ -0,0 +1,9 @@ +using Recyclarr.TrashLib.Services.Sonarr.Api.Objects; + +namespace Recyclarr.TrashLib.Services.Sonarr.Api; + +public interface ISonarrTagApiService +{ + Task> GetTags(); + Task CreateTag(string tag); +} diff --git a/src/Recyclarr.TrashLib/Services/Sonarr/Api/Objects/SonarrQualityDefinitionItem.cs b/src/Recyclarr.TrashLib/Services/Sonarr/Api/Objects/SonarrQualityDefinitionItem.cs deleted file mode 100644 index 50ac9a0f..00000000 --- a/src/Recyclarr.TrashLib/Services/Sonarr/Api/Objects/SonarrQualityDefinitionItem.cs +++ /dev/null @@ -1,23 +0,0 @@ -using JetBrains.Annotations; - -namespace Recyclarr.TrashLib.Services.Sonarr.Api.Objects; - -[UsedImplicitly(ImplicitUseTargetFlags.WithMembers)] -public class SonarrQualityItem -{ - public int Id { get; set; } - public string Name { get; set; } = ""; - public string Source { get; set; } = ""; - public int Resolution { get; set; } -} - -[UsedImplicitly(ImplicitUseTargetFlags.WithMembers)] -public class SonarrQualityDefinitionItem -{ - public int Id { get; set; } - public SonarrQualityItem? Quality { get; set; } - public string Title { get; set; } = ""; - public int Weight { get; set; } - public decimal MinSize { get; set; } - public decimal? MaxSize { get; set; } -} diff --git a/src/Recyclarr.TrashLib/Services/Sonarr/Api/SonarrApi.cs b/src/Recyclarr.TrashLib/Services/Sonarr/Api/SonarrApi.cs deleted file mode 100644 index e429e0ae..00000000 --- a/src/Recyclarr.TrashLib/Services/Sonarr/Api/SonarrApi.cs +++ /dev/null @@ -1,42 +0,0 @@ -using Flurl.Http; -using Recyclarr.TrashLib.Http; -using Recyclarr.TrashLib.Services.Sonarr.Api.Objects; - -namespace Recyclarr.TrashLib.Services.Sonarr.Api; - -public class SonarrApi : ISonarrApi -{ - private readonly IServiceRequestBuilder _service; - - public SonarrApi(IServiceRequestBuilder service) - { - _service = service; - } - - public async Task> GetTags() - { - return await _service.Request("tag") - .GetJsonAsync>(); - } - - public async Task CreateTag(string tag) - { - return await _service.Request("tag") - .PostJsonAsync(new {label = tag}) - .ReceiveJson(); - } - - public async Task> GetQualityDefinition() - { - return await _service.Request("qualitydefinition") - .GetJsonAsync>(); - } - - public async Task> UpdateQualityDefinition( - IReadOnlyCollection newQuality) - { - return await _service.Request("qualityDefinition", "update") - .PutJsonAsync(newQuality) - .ReceiveJson>(); - } -} diff --git a/src/Recyclarr.TrashLib/Services/Sonarr/Api/SonarrTagApiService.cs b/src/Recyclarr.TrashLib/Services/Sonarr/Api/SonarrTagApiService.cs new file mode 100644 index 00000000..142f2618 --- /dev/null +++ b/src/Recyclarr.TrashLib/Services/Sonarr/Api/SonarrTagApiService.cs @@ -0,0 +1,28 @@ +using Flurl.Http; +using Recyclarr.TrashLib.Http; +using Recyclarr.TrashLib.Services.Sonarr.Api.Objects; + +namespace Recyclarr.TrashLib.Services.Sonarr.Api; + +public class SonarrTagApiService : ISonarrTagApiService +{ + private readonly IServiceRequestBuilder _service; + + public SonarrTagApiService(IServiceRequestBuilder service) + { + _service = service; + } + + public async Task> GetTags() + { + return await _service.Request("tag") + .GetJsonAsync>(); + } + + public async Task CreateTag(string tag) + { + return await _service.Request("tag") + .PostJsonAsync(new {label = tag}) + .ReceiveJson(); + } +} diff --git a/src/Recyclarr.TrashLib/Services/Sonarr/ISonarrGuideDataLister.cs b/src/Recyclarr.TrashLib/Services/Sonarr/ISonarrGuideDataLister.cs deleted file mode 100644 index 2bcf67a1..00000000 --- a/src/Recyclarr.TrashLib/Services/Sonarr/ISonarrGuideDataLister.cs +++ /dev/null @@ -1,9 +0,0 @@ -namespace Recyclarr.TrashLib.Services.Sonarr; - -public interface ISonarrGuideDataLister -{ - void ListReleaseProfiles(); - void ListTerms(string releaseProfileId); - void ListQualities(); - void ListCustomFormats(); -} diff --git a/src/Recyclarr.TrashLib/Services/Sonarr/LocalRepoSonarrGuideService.cs b/src/Recyclarr.TrashLib/Services/Sonarr/LocalRepoSonarrGuideService.cs deleted file mode 100644 index 9db4423d..00000000 --- a/src/Recyclarr.TrashLib/Services/Sonarr/LocalRepoSonarrGuideService.cs +++ /dev/null @@ -1,100 +0,0 @@ -using System.IO.Abstractions; -using MoreLinq; -using Newtonsoft.Json; -using Recyclarr.Common; -using Recyclarr.Common.Extensions; -using Recyclarr.TrashLib.Repo; -using Recyclarr.TrashLib.Services.CustomFormat.Guide; -using Recyclarr.TrashLib.Services.CustomFormat.Models; -using Recyclarr.TrashLib.Services.QualitySize; -using Recyclarr.TrashLib.Services.QualitySize.Guide; -using Recyclarr.TrashLib.Services.Sonarr.ReleaseProfile; -using Recyclarr.TrashLib.Services.Sonarr.ReleaseProfile.Filters; - -namespace Recyclarr.TrashLib.Services.Sonarr; - -public class LocalRepoSonarrGuideService : SonarrGuideService -{ - private readonly IRepoPathsFactory _pathsFactory; - private readonly ILogger _log; - private readonly ICustomFormatLoader _cfLoader; - private readonly Lazy> _data; - private readonly QualitySizeGuideParser _parser; - - public LocalRepoSonarrGuideService( - IRepoPathsFactory pathsFactory, - ILogger log, - ICustomFormatLoader cfLoader) - { - _pathsFactory = pathsFactory; - _log = log; - _cfLoader = cfLoader; - _data = new Lazy>(GetReleaseProfileDataImpl); - _parser = new QualitySizeGuideParser(log); - } - - public override ICollection GetQualities() - { - return _parser.GetQualities(_pathsFactory.Create().SonarrQualityPaths); - } - - public override ICollection GetCustomFormatData() - { - var paths = _pathsFactory.Create(); - return _cfLoader.LoadAllCustomFormatsAtPaths( - paths.SonarrCustomFormatPaths, - paths.SonarrCollectionOfCustomFormats); - } - - private IEnumerable GetReleaseProfileDataImpl() - { - var converter = new TermDataConverter(); - var paths = _pathsFactory.Create(); - var tasks = JsonUtils.GetJsonFilesInDirectories(paths.SonarrReleaseProfilePaths, _log) - .Select(x => LoadAndParseFile(x, converter)); - - var data = Task.WhenAll(tasks).Result - // Make non-nullable type and filter out null values - .Choose(x => x is not null ? (true, x) : default); - - var validator = new ReleaseProfileDataValidationFilterer(_log); - return validator.FilterProfiles(data); - } - - private async Task LoadAndParseFile(IFileInfo file, params JsonConverter[] converters) - { - try - { - using var stream = file.OpenText(); - var json = await stream.ReadToEndAsync(); - return JsonConvert.DeserializeObject(json, converters); - } - catch (JsonException e) - { - HandleJsonException(e, file); - } - catch (AggregateException ae) when (ae.InnerException is JsonException e) - { - HandleJsonException(e, file); - } - - return null; - } - - private void HandleJsonException(JsonException exception, IFileInfo file) - { - _log.Warning(exception, - "Failed to parse Sonarr JSON file (This likely indicates a bug that should be " + - "reported in the TRaSH repo): {File}", file.Name); - } - - public override ReleaseProfileData? GetUnfilteredProfileById(string trashId) - { - return _data.Value.FirstOrDefault(x => x.TrashId.EqualsIgnoreCase(trashId)); - } - - public override IReadOnlyCollection GetReleaseProfileData() - { - return _data.Value.ToList(); - } -} diff --git a/src/Recyclarr.TrashLib/Services/Sonarr/SonarrAutofacModule.cs b/src/Recyclarr.TrashLib/Services/Sonarr/SonarrAutofacModule.cs index 52757b44..e7c4add5 100644 --- a/src/Recyclarr.TrashLib/Services/Sonarr/SonarrAutofacModule.cs +++ b/src/Recyclarr.TrashLib/Services/Sonarr/SonarrAutofacModule.cs @@ -1,11 +1,6 @@ using Autofac; -using Autofac.Extras.Ordering; -using Recyclarr.TrashLib.Config; -using Recyclarr.TrashLib.Services.Common; using Recyclarr.TrashLib.Services.Sonarr.Api; using Recyclarr.TrashLib.Services.Sonarr.Capabilities; -using Recyclarr.TrashLib.Services.Sonarr.ReleaseProfile; -using Recyclarr.TrashLib.Services.Sonarr.ReleaseProfile.Filters; namespace Recyclarr.TrashLib.Services.Sonarr; @@ -13,29 +8,9 @@ public class SonarrAutofacModule : Module { protected override void Load(ContainerBuilder builder) { - builder.RegisterType().As(); - builder.RegisterType().As(); - + builder.RegisterType().As(); builder.RegisterType(); builder.RegisterType().As() .InstancePerLifetimeScope(); - - builder.RegisterType().As(); - builder.RegisterType() - .As() - .Keyed(SupportedServices.Sonarr); - - // Release Profile Support - builder.RegisterType().As(); - builder.RegisterType() - .As(); - builder.RegisterType().As(); - - // Release Profile Filters (ORDER MATTERS!) - builder.RegisterTypes( - typeof(IncludeExcludeFilter), - typeof(StrictNegativeScoresFilter)) - .As() - .OrderByRegistration(); } } diff --git a/src/Recyclarr.TrashLib/Services/Sonarr/SonarrGuideService.cs b/src/Recyclarr.TrashLib/Services/Sonarr/SonarrGuideService.cs deleted file mode 100644 index 448dd9bc..00000000 --- a/src/Recyclarr.TrashLib/Services/Sonarr/SonarrGuideService.cs +++ /dev/null @@ -1,14 +0,0 @@ -using Recyclarr.TrashLib.Services.Common; -using Recyclarr.TrashLib.Services.CustomFormat.Models; -using Recyclarr.TrashLib.Services.QualitySize; -using Recyclarr.TrashLib.Services.Sonarr.ReleaseProfile; - -namespace Recyclarr.TrashLib.Services.Sonarr; - -public abstract class SonarrGuideService : IGuideService -{ - public abstract IReadOnlyCollection GetReleaseProfileData(); - public abstract ReleaseProfileData? GetUnfilteredProfileById(string trashId); - public abstract ICollection GetCustomFormatData(); - public abstract ICollection GetQualities(); -}