fixes id of image on download and adds cancellation support for spectre commands
PiwigoDirectorySync/pipeline/head This commit looks good Details

This commit is contained in:
Philipp Häfelfinger 2023-09-04 23:12:18 +02:00
parent 96bce7c83a
commit d43235bca1
9 changed files with 75 additions and 25 deletions

View File

@ -1,11 +1,12 @@
using System.Diagnostics;
using Microsoft.Extensions.Logging;
using PiwigoDirectorySync.Infrastructure;
using PiwigoDirectorySync.Services;
using Spectre.Console.Cli;
namespace PiwigoDirectorySync.Commands;
internal class DownloadImagesCommand : AsyncCommand<DownloadImagesSettings>
internal class DownloadImagesCommand : CancellableAsyncCommand<DownloadImagesSettings>
{
private readonly IImageSynchronizer _imageSynchronizer;
private readonly ILogger<DownloadImagesCommand> _logger;
@ -16,13 +17,12 @@ internal class DownloadImagesCommand : AsyncCommand<DownloadImagesSettings>
_logger = logger;
}
public override async Task<int> ExecuteAsync(CommandContext context, DownloadImagesSettings settings)
protected override async Task<int> ExecuteAsync(CommandContext context, DownloadImagesSettings settings, CancellationToken cancellationToken)
{
_logger.LogInformation("Starting image download for piwigo server {SettingsPiwigoServerId}", settings.PiwigoServerId);
var stopWatch = Stopwatch.StartNew();
var cancellationTokenSource = new CancellationTokenSource();
await _imageSynchronizer.DownloadImagesAsync(settings.PiwigoServerId, cancellationTokenSource.Token);
await _imageSynchronizer.DownloadImagesAsync(settings.PiwigoServerId, cancellationToken);
stopWatch.Stop();
_logger.LogInformation("Synchronized all images with piwigo server {SettingsPiwigoServerId} in {ElapsedTotalSeconds} seconds", settings.PiwigoServerId,

View File

@ -1,12 +1,13 @@
using System.Diagnostics;
using System.Threading.Channels;
using Microsoft.Extensions.Logging;
using PiwigoDirectorySync.Infrastructure;
using PiwigoDirectorySync.Services;
using Spectre.Console.Cli;
namespace PiwigoDirectorySync.Commands;
internal class ScanCommand : AsyncCommand<ScanSettings>
internal class ScanCommand : CancellableAsyncCommand<ScanSettings>
{
private readonly IFileIndexer _fileIndexer;
private readonly IFileSystemScanner _fileSystemScanner;
@ -19,11 +20,9 @@ internal class ScanCommand : AsyncCommand<ScanSettings>
_fileSystemScanner = fileSystemScanner;
}
public override async Task<int> ExecuteAsync(CommandContext context, ScanSettings settings)
protected override async Task<int> ExecuteAsync(CommandContext context, ScanSettings settings, CancellationToken cancellationToken)
{
var cancellationTokenSource = new CancellationTokenSource();
await ScanDirectory(_logger, _fileIndexer, _fileSystemScanner, settings.PiwigoServerId, cancellationTokenSource.Token);
await ScanDirectory(_logger, _fileIndexer, _fileSystemScanner, settings.PiwigoServerId, cancellationToken);
return 0;
}

View File

@ -1,11 +1,12 @@
using System.Diagnostics;
using Microsoft.Extensions.Logging;
using PiwigoDirectorySync.Infrastructure;
using PiwigoDirectorySync.Services;
using Spectre.Console.Cli;
namespace PiwigoDirectorySync.Commands;
internal class SyncAlbumsCommand : AsyncCommand<SyncAlbumsSettings>
internal class SyncAlbumsCommand : CancellableAsyncCommand<SyncAlbumsSettings>
{
private readonly IAlbumSynchronizer _albumSynchronizer;
private readonly ILogger<SyncAlbumsCommand> _logger;
@ -16,14 +17,13 @@ internal class SyncAlbumsCommand : AsyncCommand<SyncAlbumsSettings>
_albumSynchronizer = albumSynchronizer;
}
public override async Task<int> ExecuteAsync(CommandContext context, SyncAlbumsSettings settings)
protected override async Task<int> ExecuteAsync(CommandContext context, SyncAlbumsSettings settings, CancellationToken cancellationToken)
{
_logger.LogInformation("Starting album synchronization for piwigo server {SettingsPiwigoServerId}", settings.PiwigoServerId);
var stopWatch = Stopwatch.StartNew();
var cancellationTokenSource = new CancellationTokenSource();
await _albumSynchronizer.SynchronizeAlbums(settings.PiwigoServerId, cancellationTokenSource.Token);
await _albumSynchronizer.SynchronizeAlbums(settings.PiwigoServerId, cancellationToken);
stopWatch.Stop();
_logger.LogInformation("Synchronized all albums with piwigo server {SettingsPiwigoServerId} in {ElapsedTotalSeconds} seconds", settings.PiwigoServerId,

View File

@ -1,11 +1,12 @@
using System.Diagnostics;
using Microsoft.Extensions.Logging;
using PiwigoDirectorySync.Infrastructure;
using PiwigoDirectorySync.Services;
using Spectre.Console.Cli;
namespace PiwigoDirectorySync.Commands;
internal class SyncFullCommand : AsyncCommand<SyncFullSettings>
internal class SyncFullCommand : CancellableAsyncCommand<SyncFullSettings>
{
private readonly IAlbumSynchronizer _albumSynchronizer;
private readonly IFileIndexer _fileIndexer;
@ -23,21 +24,19 @@ internal class SyncFullCommand : AsyncCommand<SyncFullSettings>
_logger = logger;
}
public override async Task<int> ExecuteAsync(CommandContext context, SyncFullSettings settings)
protected override async Task<int> ExecuteAsync(CommandContext context, SyncFullSettings settings, CancellationToken cancellationToken)
{
_logger.LogInformation("Starting full synchronization for piwigo server {SettingsPiwigoServerId}", settings.PiwigoServerId);
var stopWatch = Stopwatch.StartNew();
var cancellationTokenSource = new CancellationTokenSource();
_logger.LogInformation("running file system scan");
await ScanCommand.ScanDirectory(_logger, _fileIndexer, _fileSystemScanner, settings.PiwigoServerId, cancellationTokenSource.Token);
await ScanCommand.ScanDirectory(_logger, _fileIndexer, _fileSystemScanner, settings.PiwigoServerId, cancellationToken);
_logger.LogInformation("running album synchronization");
await _albumSynchronizer.SynchronizeAlbums(settings.PiwigoServerId, cancellationTokenSource.Token);
await _albumSynchronizer.SynchronizeAlbums(settings.PiwigoServerId, cancellationToken);
_logger.LogInformation("running image synchronization");
await _imageSynchronizer.SynchronizeImagesAsync(settings.PiwigoServerId, cancellationTokenSource.Token);
await _imageSynchronizer.SynchronizeImagesAsync(settings.PiwigoServerId, cancellationToken);
stopWatch.Stop();
_logger.LogInformation("Full synchronization for piwigo server {SettingsPiwigoServerId} finished in {ElapsedTotalSeconds} seconds", settings.PiwigoServerId,

View File

@ -1,11 +1,12 @@
using System.Diagnostics;
using Microsoft.Extensions.Logging;
using PiwigoDirectorySync.Infrastructure;
using PiwigoDirectorySync.Services;
using Spectre.Console.Cli;
namespace PiwigoDirectorySync.Commands;
internal class SyncImagesCommand : AsyncCommand<SyncImagesSettings>
internal class SyncImagesCommand : CancellableAsyncCommand<SyncImagesSettings>
{
private readonly IImageSynchronizer _imageSynchronizer;
private readonly ILogger<SyncImagesCommand> _logger;
@ -16,13 +17,12 @@ internal class SyncImagesCommand : AsyncCommand<SyncImagesSettings>
_imageSynchronizer = imageSynchronizer;
}
public override async Task<int> ExecuteAsync(CommandContext context, SyncImagesSettings settings)
protected override async Task<int> ExecuteAsync(CommandContext context, SyncImagesSettings settings, CancellationToken cancellationToken)
{
_logger.LogInformation("Starting image synchronization of piwigo server {SettingsPiwigoServerId}", settings.PiwigoServerId);
var stopWatch = Stopwatch.StartNew();
var cancellationTokenSource = new CancellationTokenSource();
await _imageSynchronizer.SynchronizeImagesAsync(settings.PiwigoServerId, cancellationTokenSource.Token);
await _imageSynchronizer.SynchronizeImagesAsync(settings.PiwigoServerId, cancellationToken);
stopWatch.Stop();
_logger.LogInformation("Synchronized all images with piwigo server {SettingsPiwigoServerId} in {ElapsedTotalSeconds} seconds", settings.PiwigoServerId,

View File

@ -0,0 +1,12 @@
using Spectre.Console.Cli;
namespace PiwigoDirectorySync.Infrastructure;
public abstract class CancellableAsyncCommand<TSettings> : AsyncCommand<TSettings> where TSettings : CommandSettings
{
private readonly ConsoleAppCancellationTokenSource _cancellationTokenSource = new();
protected abstract Task<int> ExecuteAsync(CommandContext context, TSettings settings, CancellationToken cancellation);
public sealed override async Task<int> ExecuteAsync(CommandContext context, TSettings settings) => await ExecuteAsync(context, settings, _cancellationTokenSource.Token);
}

View File

@ -0,0 +1,39 @@
namespace PiwigoDirectorySync.Infrastructure;
internal sealed class ConsoleAppCancellationTokenSource
{
private readonly CancellationTokenSource _cts = new();
public ConsoleAppCancellationTokenSource()
{
Console.CancelKeyPress += OnCancelKeyPress;
AppDomain.CurrentDomain.ProcessExit += OnProcessExit;
using var _ = _cts.Token.Register(() =>
{
AppDomain.CurrentDomain.ProcessExit -= OnProcessExit;
Console.CancelKeyPress -= OnCancelKeyPress;
});
}
public CancellationToken Token => _cts.Token;
private void OnCancelKeyPress(object? sender, ConsoleCancelEventArgs e)
{
// NOTE: cancel event, don't terminate the process
e.Cancel = true;
_cts.Cancel();
}
private void OnProcessExit(object? sender, EventArgs e)
{
if (_cts.IsCancellationRequested)
{
// NOTE: SIGINT (cancel key was pressed, this shouldn't ever actually hit however,
// as we remove the event handler upon cancellation of the `cancellationSource`)
return;
}
_cts.Cancel();
}
}

View File

@ -54,4 +54,4 @@ app.Configure(config =>
});
});
return app.Run(args);
return await app.RunAsync(args);

View File

@ -127,6 +127,7 @@ internal class ImageSynchronizer : IImageSynchronizer
{
AlbumId = album.Id,
Album = album,
ServerImageId = image.Id,
FilePath = Path.Combine(album.Path, image.File!),
UploadRequired = false,
DeleteRequired = false