using Recyclarr.Cli.Pipelines.CustomFormat.Cache; using Recyclarr.Cli.Pipelines.CustomFormat.Models; using Recyclarr.Cli.Pipelines.Generic; using Recyclarr.Common.Extensions; using Recyclarr.Config.Models; using Recyclarr.TrashGuide.CustomFormat; namespace Recyclarr.Cli.Pipelines.CustomFormat.PipelinePhases; public class CustomFormatConfigPhase( ICustomFormatGuideService guide, ProcessedCustomFormatCache cache, ICustomFormatCachePersister cachePersister) : IConfigPipelinePhase { public Task Execute(CustomFormatPipelineContext context, IServiceConfiguration config) { // Match custom formats in the YAML config to those in the guide, by Trash ID // // This solution is conservative: CustomFormatData is only created for CFs in the guide that are // specified in the config. // // The ToLookup() at the end finds TrashIDs provided in the config that do not match anything in the guide. // These will yield a warning in the logs. var processedCfs = config.CustomFormats .SelectMany(x => x.TrashIds) .Distinct(StringComparer.InvariantCultureIgnoreCase) .GroupJoin(guide.GetCustomFormatData(config.ServiceType), x => x, x => x.TrashId, (id, cf) => (Id: id, CustomFormats: cf)) .ToLookup(x => x.Item2.Any()); context.InvalidFormats = processedCfs[false].Select(x => x.Id).ToList(); context.ConfigOutput.AddRange(processedCfs[true].SelectMany(x => x.CustomFormats)); context.Cache = cachePersister.Load(config); cache.AddCustomFormats(context.ConfigOutput); return Task.CompletedTask; } }