feat: CLI command to list media naming formats

spectre-console-remove-di-hacks
Robert Dailey 8 months ago
parent 5a60747a66
commit acd9b3ec75

@ -16,6 +16,7 @@ changes you may need to make.
### Added
- Added Naming Sync (Media Management) for Sonarr v3, Sonarr v4, and Radarr (#179).
- A `list naming` command to show Sonarr and Radarr naming formats available from the guide.
### Changed

@ -20,6 +20,7 @@ public static class CliSetup
list.AddCommand<ListCustomFormatsCommand>("custom-formats");
list.AddCommand<ListReleaseProfilesCommand>("release-profiles");
list.AddCommand<ListQualitiesCommand>("qualities");
list.AddCommand<ListMediaNamingCommand>("naming");
});
cli.AddBranch("config", config =>

@ -0,0 +1,41 @@
using System.ComponentModel;
using System.Diagnostics.CodeAnalysis;
using JetBrains.Annotations;
using Recyclarr.Cli.Console.Helpers;
using Recyclarr.Cli.Pipelines.MediaNaming;
using Recyclarr.Common;
using Recyclarr.Repo;
using Spectre.Console.Cli;
namespace Recyclarr.Cli.Console.Commands;
[UsedImplicitly]
[Description("List media naming formats in the guide for a particular service.")]
public class ListMediaNamingCommand : AsyncCommand<ListMediaNamingCommand.CliSettings>
{
private readonly MediaNamingDataLister _lister;
private readonly IMultiRepoUpdater _repoUpdater;
[UsedImplicitly]
[SuppressMessage("Design", "CA1034:Nested types should not be visible")]
public class CliSettings : BaseCommandSettings
{
[CommandArgument(0, "<service_type>")]
[EnumDescription<SupportedServices>("The service type to obtain information about.")]
[UsedImplicitly(ImplicitUseKindFlags.Assign)]
public SupportedServices Service { get; init; }
}
public ListMediaNamingCommand(MediaNamingDataLister lister, IMultiRepoUpdater repoUpdater)
{
_lister = lister;
_repoUpdater = repoUpdater;
}
public override async Task<int> ExecuteAsync(CommandContext context, CliSettings settings)
{
await _repoUpdater.UpdateAllRepositories(settings.CancellationToken);
_lister.ListNaming(settings.Service);
return 0;
}
}

@ -9,6 +9,7 @@ public class MediaNamingAutofacModule : Module
protected override void Load(ContainerBuilder builder)
{
base.Load(builder);
builder.RegisterType<MediaNamingDataLister>();
builder.RegisterAggregateService<IMediaNamingPipelinePhases>();
builder.RegisterType<MediaNamingConfigPhase>();

@ -0,0 +1,96 @@
using System.Diagnostics.CodeAnalysis;
using Recyclarr.Common;
using Recyclarr.TrashGuide.MediaNaming;
using Spectre.Console;
using Spectre.Console.Rendering;
namespace Recyclarr.Cli.Pipelines.MediaNaming;
public class MediaNamingDataLister
{
private readonly IAnsiConsole _console;
private readonly IMediaNamingGuideService _guide;
public MediaNamingDataLister(
IAnsiConsole console,
IMediaNamingGuideService guide)
{
_console = console;
_guide = guide;
}
public void ListNaming(SupportedServices serviceType)
{
switch (serviceType)
{
case SupportedServices.Radarr:
ListRadarrNaming(_guide.GetRadarrNamingData());
break;
case SupportedServices.Sonarr:
ListSonarrNaming(_guide.GetSonarrNamingData());
break;
default:
throw new ArgumentOutOfRangeException(nameof(serviceType), serviceType, null);
}
}
private void ListRadarrNaming(RadarrMediaNamingData guideData)
{
_console.MarkupLine("Media Naming Formats [red](Preview)[/]");
_console.WriteLine();
_console.Write(DictionaryToTable("Movie Folder Format", guideData.Folder));
_console.WriteLine();
_console.Write(DictionaryToTable("Standard Movie Format", guideData.File));
}
private void ListSonarrNaming(SonarrMediaNamingData guideData)
{
_console.MarkupLine("Media Naming Formats [red](Preview)[/]");
_console.WriteLine();
_console.Write(DictionaryToTable("Season Folder Format", guideData.Season));
_console.WriteLine();
_console.Write(DictionaryToTable("Series Folder Format", guideData.Series));
_console.WriteLine();
_console.Write(DictionaryToTable("Standard Episode Format", guideData.Episodes.Standard));
_console.WriteLine();
_console.Write(DictionaryToTable("Daily Episode Format", guideData.Episodes.Daily));
_console.WriteLine();
_console.Write(DictionaryToTable("Anime Episode Format", guideData.Episodes.Anime));
}
private static IRenderable DictionaryToTable(string title, IReadOnlyDictionary<string, string> formats)
{
var table = new Table()
.AddColumns("Key", "Format");
var alternatingColors = new[] {"white", "paleturquoise4"};
var colorIndex = 0;
foreach (var (key, value) in formats)
{
var color = alternatingColors[colorIndex];
table.AddRow(
$"[{color}]{Markup.Escape(TransformKey(key))}[/]",
$"[{color}]{Markup.Escape(value)}[/]");
colorIndex = 1 - colorIndex;
}
return new Rows(Markup.FromInterpolated($"[orange3]{title}[/]"), table);
}
[SuppressMessage("ReSharper", "ConvertIfStatementToReturnStatement")]
private static string TransformKey(string key)
{
var split = key.Split(':');
if (split.Length > 1)
{
return $"{split[0]} (v{split[1]})";
}
return key;
}
}
Loading…
Cancel
Save