|
|
@ -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; |
|
|
|
} |
|
|
|
} |
|
|
|