Browse Source

update dependencies that require api migrations (#2063)

* migrate system.commandline to 2.0.0-beta5 api

* bump sixlabors.imagesharp

* migrate skiasharp to 3.x api
pull/1898/merge
Jason Dove 17 hours ago committed by GitHub
parent
commit
3805b9e48c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 4
      ErsatzTV.Core/ErsatzTV.Core.csproj
  2. 22
      ErsatzTV.Core/Images/ChannelLogoGenerator.cs
  3. 2
      ErsatzTV.Infrastructure/ErsatzTV.Infrastructure.csproj
  4. 2
      ErsatzTV.Scanner/ErsatzTV.Scanner.csproj
  5. 155
      ErsatzTV.Scanner/Worker.cs
  6. 10
      ErsatzTV/Shared/MainLayout.razor

4
ErsatzTV.Core/ErsatzTV.Core.csproj

@ -27,8 +27,8 @@
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" /> <PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
<PackageReference Include="Serilog" Version="4.3.0" /> <PackageReference Include="Serilog" Version="4.3.0" />
<PackageReference Include="Serilog.Sinks.Console" Version="6.0.0" /> <PackageReference Include="Serilog.Sinks.Console" Version="6.0.0" />
<PackageReference Include="SkiaSharp" Version="2.88.9" /> <PackageReference Include="SkiaSharp" Version="3.119.0" />
<PackageReference Include="SkiaSharp.NativeAssets.Linux.NoDependencies" Version="2.88.9" /> <PackageReference Include="SkiaSharp.NativeAssets.Linux.NoDependencies" Version="3.119.0" />
<PackageReference Include="TimeSpanParserUtil" Version="1.2.0" /> <PackageReference Include="TimeSpanParserUtil" Version="1.2.0" />
<PackageReference Include="YamlDotNet" Version="16.3.0" /> <PackageReference Include="YamlDotNet" Version="16.3.0" />
</ItemGroup> </ItemGroup>

22
ErsatzTV.Core/Images/ChannelLogoGenerator.cs

@ -41,32 +41,34 @@ public class ChannelLogoGenerator : IChannelLogoGenerator
//Custom Font //Custom Font
string fontPath = Path.Combine(FileSystemLayout.ResourcesCacheFolder, "Sen.ttf"); string fontPath = Path.Combine(FileSystemLayout.ResourcesCacheFolder, "Sen.ttf");
using SKTypeface fontTypeface = SKTypeface.FromFile(fontPath); using SKTypeface fontTypeface = SKTypeface.FromFile(fontPath);
int fontSize = 30; var fontSize = 30;
SKPaint paint = new SKPaint var font = new SKFont
{ {
Typeface = fontTypeface, Typeface = fontTypeface,
TextSize = fontSize, Size = fontSize
};
var paint = new SKPaint
{
IsAntialias = true, IsAntialias = true,
Color = SKColors.White, Color = SKColors.White,
Style = SKPaintStyle.Fill, Style = SKPaintStyle.Fill
TextAlign = SKTextAlign.Center
}; };
SKRect textBounds = new SKRect(); font.MeasureText(text, out SKRect textBounds, paint);
paint.MeasureText(text, ref textBounds);
// Ajuster la taille de la police si nécessaire // Ajuster la taille de la police si nécessaire
while (textBounds.Width > logoWidth - 10 && fontSize > 16) while (textBounds.Width > logoWidth - 10 && fontSize > 16)
{ {
fontSize -= 2; fontSize -= 2;
paint.TextSize = fontSize; font.Size = fontSize;
paint.MeasureText(text, ref textBounds); font.MeasureText(text, out textBounds, paint);
} }
// Dessiner le texte // Dessiner le texte
float x = logoWidth / 2f; float x = logoWidth / 2f;
float y = logoHeight / 2f - textBounds.MidY; float y = logoHeight / 2f - textBounds.MidY;
canvas.DrawText(text, x, y, paint); canvas.DrawText(text, x, y, SKTextAlign.Center, font, paint);
using SKImage image = surface.Snapshot(); using SKImage image = surface.Snapshot();
using MemoryStream ms = new MemoryStream(); using MemoryStream ms = new MemoryStream();

2
ErsatzTV.Infrastructure/ErsatzTV.Infrastructure.csproj

@ -36,7 +36,7 @@
<!-- transitive; upgrading for vuln --> <!-- transitive; upgrading for vuln -->
<PackageReference Include="SixLabors.ImageSharp" Version="3.1.7" /> <PackageReference Include="SixLabors.ImageSharp" Version="3.1.10" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>

2
ErsatzTV.Scanner/ErsatzTV.Scanner.csproj

@ -33,7 +33,7 @@
<PackageReference Include="Serilog.Formatting.Compact" Version="3.0.0" /> <PackageReference Include="Serilog.Formatting.Compact" Version="3.0.0" />
<PackageReference Include="Serilog.Sinks.Console" Version="6.0.0" /> <PackageReference Include="Serilog.Sinks.Console" Version="6.0.0" />
<PackageReference Include="Serilog.Sinks.File" Version="7.0.0" /> <PackageReference Include="Serilog.Sinks.File" Version="7.0.0" />
<PackageReference Include="System.CommandLine" Version="2.0.0-beta4.22272.1" /> <PackageReference Include="System.CommandLine" Version="2.0.0-beta5.25306.1" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>

155
ErsatzTV.Scanner/Worker.cs

@ -33,202 +33,207 @@ public class Worker : BackgroundService
// need to strip program name (head) from command line args // need to strip program name (head) from command line args
string[] arguments = Environment.GetCommandLineArgs().Skip(1).ToArray(); string[] arguments = Environment.GetCommandLineArgs().Skip(1).ToArray();
await rootCommand.InvokeAsync(arguments); ParseResult parseResult = rootCommand.Parse(arguments);
await parseResult.InvokeAsync(stoppingToken);
_appLifetime.StopApplication(); _appLifetime.StopApplication();
} }
private RootCommand ConfigureCommandLine() private RootCommand ConfigureCommandLine()
{ {
var forceOption = new System.CommandLine.Option<bool>( var forceOption = new System.CommandLine.Option<bool>("--force")
"--force",
description: "Force scanning",
parseArgument: _ => true)
{ {
AllowMultipleArgumentsPerToken = true, AllowMultipleArgumentsPerToken = true,
Arity = ArgumentArity.Zero Arity = ArgumentArity.Zero,
Description = "Force scanning",
DefaultValueFactory = _ => false
}; };
var deepOption = new System.CommandLine.Option<bool>( var deepOption = new System.CommandLine.Option<bool>("--deep")
"--deep",
description: "Deep scan",
parseArgument: _ => true)
{ {
AllowMultipleArgumentsPerToken = true, AllowMultipleArgumentsPerToken = true,
Arity = ArgumentArity.Zero Arity = ArgumentArity.Zero,
Description = "Deep scan",
DefaultValueFactory = _ => false
}; };
var libraryIdArgument = new Argument<int>("library-id", "The library id to scan"); var libraryIdArgument = new Argument<int>("library-id")
var mediaSourceIdArgument = new Argument<int>("media-source-id", "The media source id to scan"); {
Description = "The library id to scan"
};
var mediaSourceIdArgument = new Argument<int>("media-source-id")
{
Description = "The media source id to scan"
};
var scanLocalCommand = new Command("scan-local", "Scan a local library"); var scanLocalCommand = new Command("scan-local", "Scan a local library");
scanLocalCommand.AddArgument(libraryIdArgument); scanLocalCommand.Arguments.Add(libraryIdArgument);
scanLocalCommand.AddOption(forceOption); scanLocalCommand.Options.Add(forceOption);
var scanPlexCommand = new Command("scan-plex", "Scan a Plex library"); var scanPlexCommand = new Command("scan-plex", "Scan a Plex library");
scanPlexCommand.AddArgument(libraryIdArgument); scanPlexCommand.Arguments.Add(libraryIdArgument);
scanPlexCommand.AddOption(forceOption); scanPlexCommand.Options.Add(forceOption);
scanPlexCommand.AddOption(deepOption); scanPlexCommand.Options.Add(deepOption);
var scanPlexCollectionsCommand = new Command("scan-plex-collections", "Scan Plex collections"); var scanPlexCollectionsCommand = new Command("scan-plex-collections", "Scan Plex collections");
scanPlexCollectionsCommand.AddArgument(mediaSourceIdArgument); scanPlexCollectionsCommand.Arguments.Add(mediaSourceIdArgument);
scanPlexCollectionsCommand.AddOption(forceOption); scanPlexCollectionsCommand.Options.Add(forceOption);
var scanEmbyCommand = new Command("scan-emby", "Scan an Emby library"); var scanEmbyCommand = new Command("scan-emby", "Scan an Emby library");
scanEmbyCommand.AddArgument(libraryIdArgument); scanEmbyCommand.Arguments.Add(libraryIdArgument);
scanEmbyCommand.AddOption(forceOption); scanEmbyCommand.Options.Add(forceOption);
scanEmbyCommand.AddOption(deepOption); scanEmbyCommand.Options.Add(deepOption);
var scanEmbyCollectionsCommand = new Command("scan-emby-collections", "Scan Emby collections"); var scanEmbyCollectionsCommand = new Command("scan-emby-collections", "Scan Emby collections");
scanEmbyCollectionsCommand.AddArgument(mediaSourceIdArgument); scanEmbyCollectionsCommand.Arguments.Add(mediaSourceIdArgument);
scanEmbyCollectionsCommand.AddOption(forceOption); scanEmbyCollectionsCommand.Options.Add(forceOption);
var scanJellyfinCommand = new Command("scan-jellyfin", "Scan a Jellyfin library"); var scanJellyfinCommand = new Command("scan-jellyfin", "Scan a Jellyfin library");
scanJellyfinCommand.AddArgument(libraryIdArgument); scanJellyfinCommand.Arguments.Add(libraryIdArgument);
scanJellyfinCommand.AddOption(forceOption); scanJellyfinCommand.Options.Add(forceOption);
scanJellyfinCommand.AddOption(deepOption); scanJellyfinCommand.Options.Add(deepOption);
var scanJellyfinCollectionsCommand = new Command("scan-jellyfin-collections", "Scan Jellyfin collections"); var scanJellyfinCollectionsCommand = new Command("scan-jellyfin-collections", "Scan Jellyfin collections");
scanJellyfinCollectionsCommand.AddArgument(mediaSourceIdArgument); scanJellyfinCollectionsCommand.Arguments.Add(mediaSourceIdArgument);
scanJellyfinCollectionsCommand.AddOption(forceOption); scanJellyfinCollectionsCommand.Options.Add(forceOption);
scanLocalCommand.SetHandler( scanLocalCommand.SetAction(
async context => async (parseResult, token) =>
{ {
if (IsScanningEnabled()) if (IsScanningEnabled())
{ {
bool force = context.ParseResult.GetValueForOption(forceOption); bool force = parseResult.GetValue(forceOption);
SetProcessPriority(force); SetProcessPriority(force);
int libraryId = context.ParseResult.GetValueForArgument(libraryIdArgument); int libraryId = parseResult.GetValue(libraryIdArgument);
using IServiceScope scope = _serviceScopeFactory.CreateScope(); using IServiceScope scope = _serviceScopeFactory.CreateScope();
IMediator mediator = scope.ServiceProvider.GetRequiredService<IMediator>(); IMediator mediator = scope.ServiceProvider.GetRequiredService<IMediator>();
var scan = new ScanLocalLibrary(libraryId, force); var scan = new ScanLocalLibrary(libraryId, force);
await mediator.Send(scan, context.GetCancellationToken()); await mediator.Send(scan, token);
} }
}); });
scanPlexCommand.SetHandler( scanPlexCommand.SetAction(
async context => async (parseResult, token) =>
{ {
if (IsScanningEnabled()) if (IsScanningEnabled())
{ {
bool force = context.ParseResult.GetValueForOption(forceOption); bool force = parseResult.GetValue(forceOption);
SetProcessPriority(force); SetProcessPriority(force);
bool deep = context.ParseResult.GetValueForOption(deepOption); bool deep = parseResult.GetValue(deepOption);
int libraryId = context.ParseResult.GetValueForArgument(libraryIdArgument); int libraryId = parseResult.GetValue(libraryIdArgument);
using IServiceScope scope = _serviceScopeFactory.CreateScope(); using IServiceScope scope = _serviceScopeFactory.CreateScope();
IMediator mediator = scope.ServiceProvider.GetRequiredService<IMediator>(); IMediator mediator = scope.ServiceProvider.GetRequiredService<IMediator>();
var scan = new SynchronizePlexLibraryById(libraryId, force, deep); var scan = new SynchronizePlexLibraryById(libraryId, force, deep);
await mediator.Send(scan, context.GetCancellationToken()); await mediator.Send(scan, token);
} }
}); });
scanPlexCollectionsCommand.SetHandler( scanPlexCollectionsCommand.SetAction(
async context => async (parseResult, token) =>
{ {
if (IsScanningEnabled()) if (IsScanningEnabled())
{ {
bool force = context.ParseResult.GetValueForOption(forceOption); bool force = parseResult.GetValue(forceOption);
SetProcessPriority(force); SetProcessPriority(force);
int mediaSourceId = context.ParseResult.GetValueForArgument(mediaSourceIdArgument); int mediaSourceId = parseResult.GetValue(mediaSourceIdArgument);
using IServiceScope scope = _serviceScopeFactory.CreateScope(); using IServiceScope scope = _serviceScopeFactory.CreateScope();
IMediator mediator = scope.ServiceProvider.GetRequiredService<IMediator>(); IMediator mediator = scope.ServiceProvider.GetRequiredService<IMediator>();
var scan = new SynchronizePlexCollections(mediaSourceId, force); var scan = new SynchronizePlexCollections(mediaSourceId, force);
await mediator.Send(scan, context.GetCancellationToken()); await mediator.Send(scan, token);
} }
}); });
scanEmbyCommand.SetHandler( scanEmbyCommand.SetAction(
async context => async (parseResult, token) =>
{ {
if (IsScanningEnabled()) if (IsScanningEnabled())
{ {
bool force = context.ParseResult.GetValueForOption(forceOption); bool force = parseResult.GetValue(forceOption);
SetProcessPriority(force); SetProcessPriority(force);
bool deep = context.ParseResult.GetValueForOption(deepOption); bool deep = parseResult.GetValue(deepOption);
int libraryId = context.ParseResult.GetValueForArgument(libraryIdArgument); int libraryId = parseResult.GetValue(libraryIdArgument);
using IServiceScope scope = _serviceScopeFactory.CreateScope(); using IServiceScope scope = _serviceScopeFactory.CreateScope();
IMediator mediator = scope.ServiceProvider.GetRequiredService<IMediator>(); IMediator mediator = scope.ServiceProvider.GetRequiredService<IMediator>();
var scan = new SynchronizeEmbyLibraryById(libraryId, force, deep); var scan = new SynchronizeEmbyLibraryById(libraryId, force, deep);
await mediator.Send(scan, context.GetCancellationToken()); await mediator.Send(scan, token);
} }
}); });
scanEmbyCollectionsCommand.SetHandler( scanEmbyCollectionsCommand.SetAction(
async context => async (parseResult, token) =>
{ {
if (IsScanningEnabled()) if (IsScanningEnabled())
{ {
bool force = context.ParseResult.GetValueForOption(forceOption); bool force = parseResult.GetValue(forceOption);
SetProcessPriority(force); SetProcessPriority(force);
int mediaSourceId = context.ParseResult.GetValueForArgument(mediaSourceIdArgument); int mediaSourceId = parseResult.GetValue(mediaSourceIdArgument);
using IServiceScope scope = _serviceScopeFactory.CreateScope(); using IServiceScope scope = _serviceScopeFactory.CreateScope();
IMediator mediator = scope.ServiceProvider.GetRequiredService<IMediator>(); IMediator mediator = scope.ServiceProvider.GetRequiredService<IMediator>();
var scan = new SynchronizeEmbyCollections(mediaSourceId, force); var scan = new SynchronizeEmbyCollections(mediaSourceId, force);
await mediator.Send(scan, context.GetCancellationToken()); await mediator.Send(scan, token);
} }
}); });
scanJellyfinCommand.SetHandler( scanJellyfinCommand.SetAction(
async context => async (parseResult, token) =>
{ {
if (IsScanningEnabled()) if (IsScanningEnabled())
{ {
bool force = context.ParseResult.GetValueForOption(forceOption); bool force = parseResult.GetValue(forceOption);
SetProcessPriority(force); SetProcessPriority(force);
bool deep = context.ParseResult.GetValueForOption(deepOption); bool deep = parseResult.GetValue(deepOption);
int libraryId = context.ParseResult.GetValueForArgument(libraryIdArgument); int libraryId = parseResult.GetValue(libraryIdArgument);
using IServiceScope scope = _serviceScopeFactory.CreateScope(); using IServiceScope scope = _serviceScopeFactory.CreateScope();
IMediator mediator = scope.ServiceProvider.GetRequiredService<IMediator>(); IMediator mediator = scope.ServiceProvider.GetRequiredService<IMediator>();
var scan = new SynchronizeJellyfinLibraryById(libraryId, force, deep); var scan = new SynchronizeJellyfinLibraryById(libraryId, force, deep);
await mediator.Send(scan, context.GetCancellationToken()); await mediator.Send(scan, token);
} }
}); });
scanJellyfinCollectionsCommand.SetHandler( scanJellyfinCollectionsCommand.SetAction(
async context => async (parseResult, token) =>
{ {
if (IsScanningEnabled()) if (IsScanningEnabled())
{ {
bool force = context.ParseResult.GetValueForOption(forceOption); bool force = parseResult.GetValue(forceOption);
SetProcessPriority(force); SetProcessPriority(force);
int mediaSourceId = context.ParseResult.GetValueForArgument(mediaSourceIdArgument); int mediaSourceId = parseResult.GetValue(mediaSourceIdArgument);
using IServiceScope scope = _serviceScopeFactory.CreateScope(); using IServiceScope scope = _serviceScopeFactory.CreateScope();
IMediator mediator = scope.ServiceProvider.GetRequiredService<IMediator>(); IMediator mediator = scope.ServiceProvider.GetRequiredService<IMediator>();
var scan = new SynchronizeJellyfinCollections(mediaSourceId, force); var scan = new SynchronizeJellyfinCollections(mediaSourceId, force);
await mediator.Send(scan, context.GetCancellationToken()); await mediator.Send(scan, token);
} }
}); });
var rootCommand = new RootCommand(); var rootCommand = new RootCommand();
rootCommand.AddCommand(scanLocalCommand); rootCommand.Subcommands.Add(scanLocalCommand);
rootCommand.AddCommand(scanPlexCommand); rootCommand.Subcommands.Add(scanPlexCommand);
rootCommand.AddCommand(scanPlexCollectionsCommand); rootCommand.Subcommands.Add(scanPlexCollectionsCommand);
rootCommand.AddCommand(scanEmbyCommand); rootCommand.Subcommands.Add(scanEmbyCommand);
rootCommand.AddCommand(scanEmbyCollectionsCommand); rootCommand.Subcommands.Add(scanEmbyCollectionsCommand);
rootCommand.AddCommand(scanJellyfinCommand); rootCommand.Subcommands.Add(scanJellyfinCommand);
rootCommand.AddCommand(scanJellyfinCollectionsCommand); rootCommand.Subcommands.Add(scanJellyfinCollectionsCommand);
return rootCommand; return rootCommand;
} }

10
ErsatzTV/Shared/MainLayout.razor

@ -75,8 +75,8 @@
<div style="align-items: center; display: flex;" class="d-none d-md-flex"> <div style="align-items: center; display: flex;" class="d-none d-md-flex">
@if (SystemStartup.IsDatabaseReady && SystemStartup.IsSearchIndexReady) @if (SystemStartup.IsDatabaseReady && SystemStartup.IsSearchIndexReady)
{ {
<MudLink Color="Color.Info" Href="@IptvUrl("channels.m3u")" Target="_blank" Underline="Underline.None">M3U</MudLink> <MudLink Color="Color.Info" Href="iptv/channels.m3u" Target="_blank" Underline="Underline.None">M3U</MudLink>
<MudLink Color="Color.Info" Href="@IptvUrl("xmltv.xml")" Target="_blank" Class="mx-4" Underline="Underline.None">XMLTV</MudLink> <MudLink Color="Color.Info" Href="iptv/xmltv.xml" Target="_blank" Class="mx-4" Underline="Underline.None">XMLTV</MudLink>
} }
@* <MudLink Color="Color.Info" Href="/swagger" Target="_blank" Class="mr-4" Underline="Underline.None">API</MudLink> *@ @* <MudLink Color="Color.Info" Href="/swagger" Target="_blank" Class="mr-4" Underline="Underline.None">API</MudLink> *@
<MudTooltip Text="Documentation"> <MudTooltip Text="Documentation">
@ -291,12 +291,6 @@
_ => null _ => null
}; };
private string IptvUrl(string path)
{
var uri = new Uri(NavigationManager.Uri);
return $"{uri.Scheme}://{uri.Host}:{Settings.StreamingPort}/iptv/{path}";
}
private void ToggleDrawer() private void ToggleDrawer()
{ {
_drawerIsOpen = !_drawerIsOpen; _drawerIsOpen = !_drawerIsOpen;

Loading…
Cancel
Save