makes most classes internal and adds a download command to download original images from piwigo to the local folder (can be used for backup of a gallery)
All checks were successful
PiwigoDirectorySync/pipeline/head This commit looks good
All checks were successful
PiwigoDirectorySync/pipeline/head This commit looks good
This commit is contained in:
parent
303d69efe6
commit
96bce7c83a
@ -2,7 +2,7 @@ using Microsoft.Extensions.Configuration;
|
||||
|
||||
namespace PiwigoDirectorySync;
|
||||
|
||||
public static class AppSettings
|
||||
internal static class AppSettings
|
||||
{
|
||||
public static readonly IReadOnlySet<string> SupportedExtensions = new HashSet<string> { "jpg", "jpeg", "png" };
|
||||
|
||||
|
@ -6,7 +6,7 @@ using Spectre.Console.Cli;
|
||||
namespace PiwigoDirectorySync.Commands;
|
||||
|
||||
[SuppressMessage("ReSharper", "UnusedAutoPropertyAccessor.Global", Justification = "Done by parser")]
|
||||
public class CommonCommandSettings : CommandSettings
|
||||
internal class CommonCommandSettings : CommandSettings
|
||||
{
|
||||
[CommandArgument(0, "[PiwigoServerId]")]
|
||||
[DefaultValue(1)]
|
||||
|
33
PiwigoDirectorySync/Commands/DownloadImagesCommand.cs
Normal file
33
PiwigoDirectorySync/Commands/DownloadImagesCommand.cs
Normal file
@ -0,0 +1,33 @@
|
||||
using System.Diagnostics;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using PiwigoDirectorySync.Services;
|
||||
using Spectre.Console.Cli;
|
||||
|
||||
namespace PiwigoDirectorySync.Commands;
|
||||
|
||||
internal class DownloadImagesCommand : AsyncCommand<DownloadImagesSettings>
|
||||
{
|
||||
private readonly IImageSynchronizer _imageSynchronizer;
|
||||
private readonly ILogger<DownloadImagesCommand> _logger;
|
||||
|
||||
public DownloadImagesCommand(IImageSynchronizer imageSynchronizer, ILogger<DownloadImagesCommand> logger)
|
||||
{
|
||||
_imageSynchronizer = imageSynchronizer;
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
public override async Task<int> ExecuteAsync(CommandContext context, DownloadImagesSettings settings)
|
||||
{
|
||||
_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);
|
||||
|
||||
stopWatch.Stop();
|
||||
_logger.LogInformation("Synchronized all images with piwigo server {SettingsPiwigoServerId} in {ElapsedTotalSeconds} seconds", settings.PiwigoServerId,
|
||||
stopWatch.Elapsed.TotalSeconds);
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
5
PiwigoDirectorySync/Commands/DownloadImagesSettings.cs
Normal file
5
PiwigoDirectorySync/Commands/DownloadImagesSettings.cs
Normal file
@ -0,0 +1,5 @@
|
||||
namespace PiwigoDirectorySync.Commands;
|
||||
|
||||
internal class DownloadImagesSettings : CommonCommandSettings
|
||||
{
|
||||
}
|
@ -6,7 +6,7 @@ using Spectre.Console.Cli;
|
||||
|
||||
namespace PiwigoDirectorySync.Commands;
|
||||
|
||||
public class ScanCommand : AsyncCommand<ScanSettings>
|
||||
internal class ScanCommand : AsyncCommand<ScanSettings>
|
||||
{
|
||||
private readonly IFileIndexer _fileIndexer;
|
||||
private readonly IFileSystemScanner _fileSystemScanner;
|
||||
|
@ -5,7 +5,7 @@ using Spectre.Console.Cli;
|
||||
namespace PiwigoDirectorySync.Commands;
|
||||
|
||||
[SuppressMessage("ReSharper", "UnusedAutoPropertyAccessor.Global")]
|
||||
public class ScanSettings : CommonCommandSettings
|
||||
internal class ScanSettings : CommonCommandSettings
|
||||
{
|
||||
[CommandOption("-d|--mark-for-delete")]
|
||||
[DefaultValue(false)]
|
||||
|
@ -5,7 +5,7 @@ using Spectre.Console.Cli;
|
||||
|
||||
namespace PiwigoDirectorySync.Commands;
|
||||
|
||||
public class SyncAlbumsCommand : AsyncCommand<SyncAlbumsSettings>
|
||||
internal class SyncAlbumsCommand : AsyncCommand<SyncAlbumsSettings>
|
||||
{
|
||||
private readonly IAlbumSynchronizer _albumSynchronizer;
|
||||
private readonly ILogger<SyncAlbumsCommand> _logger;
|
||||
@ -18,7 +18,8 @@ public class SyncAlbumsCommand : AsyncCommand<SyncAlbumsSettings>
|
||||
|
||||
public override async Task<int> ExecuteAsync(CommandContext context, SyncAlbumsSettings settings)
|
||||
{
|
||||
_logger.LogInformation("Starting album synchronization");
|
||||
_logger.LogInformation("Starting album synchronization for piwigo server {SettingsPiwigoServerId}", settings.PiwigoServerId);
|
||||
|
||||
var stopWatch = Stopwatch.StartNew();
|
||||
|
||||
var cancellationTokenSource = new CancellationTokenSource();
|
||||
|
@ -3,6 +3,6 @@ using System.Diagnostics.CodeAnalysis;
|
||||
namespace PiwigoDirectorySync.Commands;
|
||||
|
||||
[SuppressMessage("ReSharper", "UnusedAutoPropertyAccessor.Global")]
|
||||
public class SyncAlbumsSettings : CommonCommandSettings
|
||||
internal class SyncAlbumsSettings : CommonCommandSettings
|
||||
{
|
||||
}
|
@ -5,7 +5,7 @@ using Spectre.Console.Cli;
|
||||
|
||||
namespace PiwigoDirectorySync.Commands;
|
||||
|
||||
public class SyncFullCommand : AsyncCommand<SyncFullSettings>
|
||||
internal class SyncFullCommand : AsyncCommand<SyncFullSettings>
|
||||
{
|
||||
private readonly IAlbumSynchronizer _albumSynchronizer;
|
||||
private readonly IFileIndexer _fileIndexer;
|
||||
@ -37,7 +37,7 @@ public class SyncFullCommand : AsyncCommand<SyncFullSettings>
|
||||
await _albumSynchronizer.SynchronizeAlbums(settings.PiwigoServerId, cancellationTokenSource.Token);
|
||||
|
||||
_logger.LogInformation("running image synchronization");
|
||||
await _imageSynchronizer.SynchronizeImages(settings.PiwigoServerId, cancellationTokenSource.Token);
|
||||
await _imageSynchronizer.SynchronizeImagesAsync(settings.PiwigoServerId, cancellationTokenSource.Token);
|
||||
|
||||
stopWatch.Stop();
|
||||
_logger.LogInformation("Full synchronization for piwigo server {SettingsPiwigoServerId} finished in {ElapsedTotalSeconds} seconds", settings.PiwigoServerId,
|
||||
|
@ -1,3 +1,3 @@
|
||||
namespace PiwigoDirectorySync.Commands;
|
||||
|
||||
public class SyncFullSettings : CommonCommandSettings {}
|
||||
internal class SyncFullSettings : CommonCommandSettings {}
|
@ -5,7 +5,7 @@ using Spectre.Console.Cli;
|
||||
|
||||
namespace PiwigoDirectorySync.Commands;
|
||||
|
||||
public class SyncImagesCommand : AsyncCommand<SyncImagesSettings>
|
||||
internal class SyncImagesCommand : AsyncCommand<SyncImagesSettings>
|
||||
{
|
||||
private readonly IImageSynchronizer _imageSynchronizer;
|
||||
private readonly ILogger<SyncImagesCommand> _logger;
|
||||
@ -18,11 +18,11 @@ public class SyncImagesCommand : AsyncCommand<SyncImagesSettings>
|
||||
|
||||
public override async Task<int> ExecuteAsync(CommandContext context, SyncImagesSettings settings)
|
||||
{
|
||||
_logger.LogInformation("Starting image synchronization");
|
||||
_logger.LogInformation("Starting image synchronization of piwigo server {SettingsPiwigoServerId}", settings.PiwigoServerId);
|
||||
var stopWatch = Stopwatch.StartNew();
|
||||
|
||||
var cancellationTokenSource = new CancellationTokenSource();
|
||||
await _imageSynchronizer.SynchronizeImages(settings.PiwigoServerId, cancellationTokenSource.Token);
|
||||
await _imageSynchronizer.SynchronizeImagesAsync(settings.PiwigoServerId, cancellationTokenSource.Token);
|
||||
|
||||
stopWatch.Stop();
|
||||
_logger.LogInformation("Synchronized all images with piwigo server {SettingsPiwigoServerId} in {ElapsedTotalSeconds} seconds", settings.PiwigoServerId,
|
||||
|
@ -1,5 +1,5 @@
|
||||
namespace PiwigoDirectorySync.Commands;
|
||||
|
||||
public class SyncImagesSettings : CommonCommandSettings
|
||||
internal class SyncImagesSettings : CommonCommandSettings
|
||||
{
|
||||
}
|
@ -3,7 +3,7 @@ using Spectre.Console.Cli;
|
||||
|
||||
namespace PiwigoDirectorySync.Infrastructure;
|
||||
|
||||
public sealed class DependencyInjectionTypeRegistrar : ITypeRegistrar
|
||||
internal sealed class DependencyInjectionTypeRegistrar : ITypeRegistrar
|
||||
{
|
||||
private readonly IServiceCollection _builder;
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
namespace PiwigoDirectorySync.Infrastructure;
|
||||
|
||||
public sealed class DependencyTypeResolver : ITypeResolver, IDisposable
|
||||
internal sealed class DependencyTypeResolver : ITypeResolver, IDisposable
|
||||
{
|
||||
private readonly IServiceProvider _provider;
|
||||
|
||||
|
14
PiwigoDirectorySync/Infrastructure/FilesystemHelpers.cs
Normal file
14
PiwigoDirectorySync/Infrastructure/FilesystemHelpers.cs
Normal file
@ -0,0 +1,14 @@
|
||||
using System.Security.Cryptography;
|
||||
|
||||
namespace PiwigoDirectorySync.Infrastructure;
|
||||
|
||||
internal static class FilesystemHelpers
|
||||
{
|
||||
public static async Task<string> CalculateMd5SumAsync(string imageFileFullPath, CancellationToken stoppingToken)
|
||||
{
|
||||
using var md5 = MD5.Create();
|
||||
await using var stream = File.OpenRead(imageFileFullPath);
|
||||
var hash = await md5.ComputeHashAsync(stream, stoppingToken);
|
||||
return BitConverter.ToString(hash).Replace("-", string.Empty).ToLowerInvariant();
|
||||
}
|
||||
}
|
@ -3,7 +3,7 @@ using PiwigoDirectorySync.Persistence;
|
||||
|
||||
namespace PiwigoDirectorySync.Infrastructure;
|
||||
|
||||
public interface IPiwigoClientFactory
|
||||
internal interface IPiwigoClientFactory
|
||||
{
|
||||
Task<IPiwigoClient> GetPiwigoClientAsync(ServerEntity piwigoServer, CancellationToken ct);
|
||||
}
|
@ -4,7 +4,7 @@ using PiwigoDirectorySync.Persistence;
|
||||
|
||||
namespace PiwigoDirectorySync.Infrastructure;
|
||||
|
||||
public class PiwigoClientFactory : IPiwigoClientFactory
|
||||
internal class PiwigoClientFactory : IPiwigoClientFactory
|
||||
{
|
||||
private readonly ILoggerFactory _loggerFactory;
|
||||
|
||||
|
@ -12,6 +12,7 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Flurl.Http" Version="3.2.4" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="7.0.10">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
|
@ -45,11 +45,12 @@ app.Configure(config =>
|
||||
#endif
|
||||
|
||||
config.AddCommand<ScanCommand>("scan");
|
||||
config.AddCommand<DownloadImagesCommand>("download");
|
||||
config.AddBranch("sync", c =>
|
||||
{
|
||||
c.AddCommand<SyncFullCommand>("full");
|
||||
c.AddCommand<SyncAlbumsCommand>("albums");
|
||||
c.AddCommand<SyncImagesCommand>("images");
|
||||
c.AddCommand<SyncFullCommand>("full");
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -30,6 +30,12 @@
|
||||
"commandLineArgs": "sync full",
|
||||
"environmentVariables": {
|
||||
}
|
||||
},
|
||||
"Download": {
|
||||
"commandName": "Project",
|
||||
"commandLineArgs": "download",
|
||||
"environmentVariables": {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -7,7 +7,7 @@ using PiwigoDirectorySync.Persistence;
|
||||
|
||||
namespace PiwigoDirectorySync.Services;
|
||||
|
||||
public class AlbumSynchronizer : IAlbumSynchronizer
|
||||
internal class AlbumSynchronizer : IAlbumSynchronizer
|
||||
{
|
||||
private readonly ILogger<AlbumSynchronizer> _logger;
|
||||
private readonly PersistenceContext _persistenceContext;
|
||||
|
@ -1,12 +1,12 @@
|
||||
using System.Security.Cryptography;
|
||||
using System.Threading.Channels;
|
||||
using System.Threading.Channels;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using PiwigoDirectorySync.Infrastructure;
|
||||
using PiwigoDirectorySync.Persistence;
|
||||
|
||||
namespace PiwigoDirectorySync.Services;
|
||||
|
||||
public class FileIndexer : IFileIndexer
|
||||
internal class FileIndexer : IFileIndexer
|
||||
{
|
||||
private readonly IList<string> _failedFiles = new List<string>();
|
||||
private readonly ILogger<FileIndexer> _logger;
|
||||
@ -54,7 +54,7 @@ public class FileIndexer : IFileIndexer
|
||||
if (image.LastChange != fileInfo.LastWriteTimeUtc)
|
||||
{
|
||||
image.UploadRequired = true;
|
||||
image.Md5Sum = await CalculateMd5SumAsync(fullFilePath, ct);
|
||||
image.Md5Sum = await FilesystemHelpers.CalculateMd5SumAsync(fullFilePath, ct);
|
||||
}
|
||||
|
||||
image.DeleteRequired = false;
|
||||
@ -125,12 +125,4 @@ public class FileIndexer : IFileIndexer
|
||||
|
||||
return album;
|
||||
}
|
||||
|
||||
private static async Task<string> CalculateMd5SumAsync(string imageFileFullPath, CancellationToken stoppingToken)
|
||||
{
|
||||
using var md5 = MD5.Create();
|
||||
await using var stream = File.OpenRead(imageFileFullPath);
|
||||
var hash = await md5.ComputeHashAsync(stream, stoppingToken);
|
||||
return BitConverter.ToString(hash).Replace("-", string.Empty).ToLowerInvariant();
|
||||
}
|
||||
}
|
@ -4,7 +4,7 @@ using PiwigoDirectorySync.Persistence;
|
||||
|
||||
namespace PiwigoDirectorySync.Services;
|
||||
|
||||
public class FileSystemScanner : IFileSystemScanner
|
||||
internal class FileSystemScanner : IFileSystemScanner
|
||||
{
|
||||
private readonly ILogger<FileSystemScanner> _logger;
|
||||
private readonly PersistenceContext _persistenceContext;
|
||||
|
@ -1,6 +1,6 @@
|
||||
namespace PiwigoDirectorySync.Services;
|
||||
|
||||
public interface IAlbumSynchronizer
|
||||
internal interface IAlbumSynchronizer
|
||||
{
|
||||
Task SynchronizeAlbums(int piwigoServerId, CancellationToken ct);
|
||||
}
|
@ -2,7 +2,7 @@ using System.Threading.Channels;
|
||||
|
||||
namespace PiwigoDirectorySync.Services;
|
||||
|
||||
public interface IFileIndexer
|
||||
internal interface IFileIndexer
|
||||
{
|
||||
int TotalFilesScanned { get; }
|
||||
IReadOnlyCollection<string> FailedFiles { get; }
|
||||
|
@ -2,7 +2,7 @@ using System.Threading.Channels;
|
||||
|
||||
namespace PiwigoDirectorySync.Services;
|
||||
|
||||
public interface IFileSystemScanner
|
||||
internal interface IFileSystemScanner
|
||||
{
|
||||
Task ScanAsync(Channel<string> fileQueue, int piwigoServerId, CancellationToken ct);
|
||||
}
|
@ -1,6 +1,7 @@
|
||||
namespace PiwigoDirectorySync.Services;
|
||||
|
||||
public interface IImageSynchronizer
|
||||
internal interface IImageSynchronizer
|
||||
{
|
||||
Task SynchronizeImages(int piwigoServerId, CancellationToken ct);
|
||||
Task SynchronizeImagesAsync(int piwigoServerId, CancellationToken ct);
|
||||
Task DownloadImagesAsync(int piwigoServerId, CancellationToken ct);
|
||||
}
|
@ -1,13 +1,15 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Flurl.Http;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Piwigo.Client;
|
||||
using Piwigo.Client.Albums;
|
||||
using Piwigo.Client.Images;
|
||||
using PiwigoDirectorySync.Infrastructure;
|
||||
using PiwigoDirectorySync.Persistence;
|
||||
|
||||
namespace PiwigoDirectorySync.Services;
|
||||
|
||||
public class ImageSynchronizer : IImageSynchronizer
|
||||
internal class ImageSynchronizer : IImageSynchronizer
|
||||
{
|
||||
private readonly ILogger<ImageSynchronizer> _logger;
|
||||
private readonly PersistenceContext _persistenceContext;
|
||||
@ -20,7 +22,34 @@ public class ImageSynchronizer : IImageSynchronizer
|
||||
_persistenceContext = persistenceContext;
|
||||
}
|
||||
|
||||
public async Task SynchronizeImages(int piwigoServerId, CancellationToken ct)
|
||||
public async Task DownloadImagesAsync(int piwigoServerId, CancellationToken ct)
|
||||
{
|
||||
var piwigoServer = await _persistenceContext.PiwigoServers.FindAsync(new object?[] { piwigoServerId }, ct);
|
||||
if (piwigoServer is null)
|
||||
{
|
||||
_logger.LogError("Could not sync images with piwigo server {PiwigoServerId}", piwigoServerId);
|
||||
return;
|
||||
}
|
||||
|
||||
_logger.LogInformation("Downloading missing images of piwigo server {PiwigoServerName} using base path {PiwigoServerRootDirectory}", piwigoServer.Name,
|
||||
piwigoServer.RootDirectory);
|
||||
|
||||
var piwigoClient = await _piwigoClientFactory.GetPiwigoClientAsync(piwigoServer, ct);
|
||||
|
||||
var albumIdsToDownload = await _persistenceContext.PiwigoAlbums.Where(a => a.ServerAlbumId.HasValue).Select(a => a.ServerAlbumId!.Value).Distinct().ToListAsync(ct);
|
||||
|
||||
foreach (var albumId in albumIdsToDownload)
|
||||
{
|
||||
var albumInfos = await piwigoClient.Album.GetListAsync(albumId, false, false, ThumbnailSize.Thumb, ct);
|
||||
var albumInfo = albumInfos.First();
|
||||
|
||||
_logger.LogInformation("Starting downloads for album {AlbumInfoName}", albumInfo.Name);
|
||||
|
||||
await DownloadImagesForAlbumAsync(piwigoClient, piwigoServer, albumId, albumInfo, ct);
|
||||
}
|
||||
}
|
||||
|
||||
public async Task SynchronizeImagesAsync(int piwigoServerId, CancellationToken ct)
|
||||
{
|
||||
var piwigoServer = await _persistenceContext.PiwigoServers.FindAsync(new object?[] { piwigoServerId }, ct);
|
||||
if (piwigoServer is null)
|
||||
@ -39,6 +68,75 @@ public class ImageSynchronizer : IImageSynchronizer
|
||||
await UploadChangedImagesToServerAsync(piwigoClient, piwigoServer, ct);
|
||||
}
|
||||
|
||||
private async Task DownloadImagesForAlbumAsync(IPiwigoClient piwigoClient, ServerEntity piwigoServer, int albumId, Album albumInfo, CancellationToken ct)
|
||||
{
|
||||
if (albumInfo.NbImages is null or <= 0)
|
||||
{
|
||||
_logger.LogInformation("No images to download for empty album {AlbumId} / {AlbumInfoName}", albumId, albumInfo.Name);
|
||||
return;
|
||||
}
|
||||
|
||||
const int pageSize = 100;
|
||||
var numberOfPages = albumInfo.NbImages.Value / pageSize + 1;
|
||||
var currentPage = 0;
|
||||
|
||||
while (currentPage < numberOfPages)
|
||||
{
|
||||
var imagePagingInfo = new ImagePagingInfo(currentPage, pageSize, albumInfo.NbImages.Value);
|
||||
var images = await piwigoClient.Image.GetImagesAsync(albumId, false, imagePagingInfo, ImageFilter.Empty, ImageOrder.Name, ct);
|
||||
|
||||
foreach (var image in images.Images)
|
||||
{
|
||||
await DownloadImageAsync(piwigoServer, albumInfo, image, ct);
|
||||
}
|
||||
|
||||
currentPage++;
|
||||
}
|
||||
}
|
||||
|
||||
private async Task DownloadImageAsync(ServerEntity piwigoServer, Album albumInfo, Image image, CancellationToken ct)
|
||||
{
|
||||
var localAlbum = await _persistenceContext.PiwigoAlbums.FindByServerIdAsync(piwigoServer.Id, albumInfo.Id, ct);
|
||||
if (localAlbum is null)
|
||||
{
|
||||
_logger.LogWarning("Could not add image {ImageId} / {ImageFile}: album with server id {AlbumInfoId} / {AlbumInfoName} not found", image.Id, image.File, albumInfo.Id,
|
||||
albumInfo.Name);
|
||||
return;
|
||||
}
|
||||
|
||||
var localImage = await GetOrAddImageFromServerAsync(localAlbum, image, ct);
|
||||
|
||||
var fileInfo = new FileInfo(Path.Combine(piwigoServer.RootDirectory, localImage.FilePath));
|
||||
if (fileInfo.Exists)
|
||||
{
|
||||
_logger.LogWarning("Tried to download image {ImageFile} but it already exists", image.File);
|
||||
return;
|
||||
}
|
||||
|
||||
await image.ElementUrl.DownloadFileAsync(fileInfo.Directory!.FullName, fileInfo.Name, cancellationToken: ct);
|
||||
localImage.Md5Sum = await FilesystemHelpers.CalculateMd5SumAsync(fileInfo.FullName, ct);
|
||||
await _persistenceContext.SaveChangesAsync(ct);
|
||||
}
|
||||
|
||||
private async Task<ImageEntity> GetOrAddImageFromServerAsync(AlbumEntity album, Image image, CancellationToken ct)
|
||||
{
|
||||
var imageEntity = await _persistenceContext.PiwigoImages.Where(i => i.AlbumId == album.Id && i.ServerImageId == image.Id).FirstOrDefaultAsync(ct);
|
||||
if (imageEntity is null)
|
||||
{
|
||||
imageEntity = new ImageEntity
|
||||
{
|
||||
AlbumId = album.Id,
|
||||
Album = album,
|
||||
FilePath = Path.Combine(album.Path, image.File!),
|
||||
UploadRequired = false,
|
||||
DeleteRequired = false
|
||||
};
|
||||
_persistenceContext.PiwigoImages.Add(imageEntity);
|
||||
}
|
||||
|
||||
return imageEntity;
|
||||
}
|
||||
|
||||
private async Task UploadChangedImagesToServerAsync(IPiwigoClient piwigoClient, ServerEntity piwigoServer, CancellationToken ct)
|
||||
{
|
||||
var imagesToUpload = await _persistenceContext.PiwigoImages.Include(i => i.Album)
|
||||
|
@ -1,6 +1,6 @@
|
||||
namespace PiwigoDirectorySync;
|
||||
|
||||
public class Settings
|
||||
internal class Settings
|
||||
{
|
||||
public string DbProvider { get; set; } = null!;
|
||||
public string ImageRootDirectory { get; set; } = null!;
|
||||
|
Loading…
Reference in New Issue
Block a user