From 202b4cfb3a2df10351ffb874a2bc2ef3a32c4080 Mon Sep 17 00:00:00 2001 From: ImoutoChan <kirirrin@gmail.com> Date: Sun, 31 Mar 2024 13:39:40 +0500 Subject: [PATCH] Add in-memory settings to enable/disable imouto pics upload --- CHANGELOG.md | 5 + .../IImoutoPicsUploaderStateService.cs | 10 + .../ImoutoPicsUploaderStateService.cs | 20 + .../Services/ServiceLocator.cs | 2 +- .../View/Flyouts/SettingsView.xaml | 9 + .../ViewModel/MainWindowVM.cs | 1 + .../ViewModel/SettingsVM.cs | 34 ++ .../EnableImoutoPicsUploaderCommand.cs | 34 ++ .../IsImoutoPicsUploaderEnabledQuery.cs | 21 + .../Cqrs/OverseeCollectionCommand.cs | 7 +- .../ServiceCollectionExtensions.cs | 3 + .../Services/IImoutoPicsUploaderRepository.cs | 18 + .../ImoutoPicsUploaderState.cs | 10 + .../CollectionFileSystemTests.cs | 53 +++ .../Fixtures/TestWebApplicationFactory.cs | 8 + .../ImoutoPicsUploaderEnabledTests.cs | 43 ++ ...ImoutoRebirth.Room.IntegrationTests.csproj | 1 + .../WebApi/EndpointsMappings.cs | 18 + .../WebApi/WebApiStartup.cs | 1 + .../Clients.cs | 407 +++++++++++++++++- 20 files changed, 683 insertions(+), 22 deletions(-) create mode 100644 Source/ImoutoRebirth.Navigator/ImoutoRebirth.Navigator/Services/Collections/IImoutoPicsUploaderStateService.cs create mode 100644 Source/ImoutoRebirth.Navigator/ImoutoRebirth.Navigator/Services/Collections/ImoutoPicsUploaderStateService.cs create mode 100644 Source/ImoutoRebirth.Room/ImoutoRebirth.Room.Application/Cqrs/ImoutoPicsUploadStateSlice/EnableImoutoPicsUploaderCommand.cs create mode 100644 Source/ImoutoRebirth.Room/ImoutoRebirth.Room.Application/Cqrs/ImoutoPicsUploadStateSlice/IsImoutoPicsUploaderEnabledQuery.cs create mode 100644 Source/ImoutoRebirth.Room/ImoutoRebirth.Room.Application/Services/IImoutoPicsUploaderRepository.cs create mode 100644 Source/ImoutoRebirth.Room/ImoutoRebirth.Room.Domain/ImoutoPicsUploaderState.cs create mode 100644 Source/ImoutoRebirth.Room/ImoutoRebirth.Room.IntegrationTests/ImoutoPicsUploaderEnabledTests.cs diff --git a/CHANGELOG.md b/CHANGELOG.md index 75cab577..8948485b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,10 +5,15 @@ ### Navigator * Fix webp previews in the list view +* Add button to enable/disable imouto pics upload in Room ### Viewer * Add jfif to the list of supported image formats +### Room +* Add in-memory settings to enable/disable imouto pics upload and api for it +* Add tests for the imouto pics upload settings + # 4.24.0 ### Navigator diff --git a/Source/ImoutoRebirth.Navigator/ImoutoRebirth.Navigator/Services/Collections/IImoutoPicsUploaderStateService.cs b/Source/ImoutoRebirth.Navigator/ImoutoRebirth.Navigator/Services/Collections/IImoutoPicsUploaderStateService.cs new file mode 100644 index 00000000..17115500 --- /dev/null +++ b/Source/ImoutoRebirth.Navigator/ImoutoRebirth.Navigator/Services/Collections/IImoutoPicsUploaderStateService.cs @@ -0,0 +1,10 @@ +namespace ImoutoRebirth.Navigator.Services.Collections; + +public interface IImoutoPicsUploaderStateService +{ + Task EnableAsync(); + + Task DisableAsync(); + + Task<bool> IsEnabledAsync(); +} diff --git a/Source/ImoutoRebirth.Navigator/ImoutoRebirth.Navigator/Services/Collections/ImoutoPicsUploaderStateService.cs b/Source/ImoutoRebirth.Navigator/ImoutoRebirth.Navigator/Services/Collections/ImoutoPicsUploaderStateService.cs new file mode 100644 index 00000000..8c7eafab --- /dev/null +++ b/Source/ImoutoRebirth.Navigator/ImoutoRebirth.Navigator/Services/Collections/ImoutoPicsUploaderStateService.cs @@ -0,0 +1,20 @@ +using ImoutoRebirth.Room.WebApi.Client; + +namespace ImoutoRebirth.Navigator.Services.Collections; + +internal class ImoutoPicsUploaderStateService : IImoutoPicsUploaderStateService +{ + private readonly ImoutoPicsUploaderEnabledClient _imoutoPicsUploaderEnabledClient; + + public ImoutoPicsUploaderStateService(ImoutoPicsUploaderEnabledClient imoutoPicsUploaderEnabledClient) + => _imoutoPicsUploaderEnabledClient = imoutoPicsUploaderEnabledClient; + + public async Task EnableAsync() + => await _imoutoPicsUploaderEnabledClient.EnableImoutoPicsUploaderAsync(); + + public async Task DisableAsync() + => await _imoutoPicsUploaderEnabledClient.DisableImoutoPicsUploaderAsync(); + + public async Task<bool> IsEnabledAsync() + => await _imoutoPicsUploaderEnabledClient.IsImoutoPicsUploaderEnabledAsync(); +} diff --git a/Source/ImoutoRebirth.Navigator/ImoutoRebirth.Navigator/Services/ServiceLocator.cs b/Source/ImoutoRebirth.Navigator/ImoutoRebirth.Navigator/Services/ServiceLocator.cs index 7f4a8587..0c238513 100644 --- a/Source/ImoutoRebirth.Navigator/ImoutoRebirth.Navigator/Services/ServiceLocator.cs +++ b/Source/ImoutoRebirth.Navigator/ImoutoRebirth.Navigator/Services/ServiceLocator.cs @@ -23,7 +23,7 @@ static ServiceLocator() sc.AddTransient<ICollectionService, CollectionService>(); sc.AddTransient<IDestinationFolderService, DestinationFolderService>(); sc.AddTransient<ISourceFolderService, SourceFolderService>(); - + sc.AddTransient<IImoutoPicsUploaderStateService, ImoutoPicsUploaderStateService>(); sc.AddTransient<IFileService, FileService>(); sc.AddTransient<IFileTagService, FileTagService>(); diff --git a/Source/ImoutoRebirth.Navigator/ImoutoRebirth.Navigator/View/Flyouts/SettingsView.xaml b/Source/ImoutoRebirth.Navigator/ImoutoRebirth.Navigator/View/Flyouts/SettingsView.xaml index 2bd38bcd..1188562d 100644 --- a/Source/ImoutoRebirth.Navigator/ImoutoRebirth.Navigator/View/Flyouts/SettingsView.xaml +++ b/Source/ImoutoRebirth.Navigator/ImoutoRebirth.Navigator/View/Flyouts/SettingsView.xaml @@ -123,6 +123,15 @@ Header="Auto shuffle on every load" IsOn="{Binding AutoShuffle}" /> + <controls:ToggleSwitch Margin="0,25,0,0" + Header="Is ImoutoPics integration active" + IsOn="{Binding IsImoutoPicsUploaderEnabled}" + IsEnabled="False" /> + + <Button Content="Toggle ImoutoPics" + Command="{Binding ToggleImoutoPicsCommand}" + Margin="0,25,0,0" /> + <TextBlock Margin="0,25,0,0" Text="Path Overrides" /> diff --git a/Source/ImoutoRebirth.Navigator/ImoutoRebirth.Navigator/ViewModel/MainWindowVM.cs b/Source/ImoutoRebirth.Navigator/ImoutoRebirth.Navigator/ViewModel/MainWindowVM.cs index 5bc35e50..f659f61b 100644 --- a/Source/ImoutoRebirth.Navigator/ImoutoRebirth.Navigator/ViewModel/MainWindowVM.cs +++ b/Source/ImoutoRebirth.Navigator/ImoutoRebirth.Navigator/ViewModel/MainWindowVM.cs @@ -133,6 +133,7 @@ private async Task InitializeAsync() { var topTagsUpdateTask = TagsEdit.UpdateUsersTopTags(); await CollectionManager.ReloadCollectionsAsync(); + await Settings.InitializeAsync(); TagSearchVM.AddCollections(CollectionManager.Collections); await topTagsUpdateTask; } diff --git a/Source/ImoutoRebirth.Navigator/ImoutoRebirth.Navigator/ViewModel/SettingsVM.cs b/Source/ImoutoRebirth.Navigator/ImoutoRebirth.Navigator/ViewModel/SettingsVM.cs index 01d5bee9..39f45136 100644 --- a/Source/ImoutoRebirth.Navigator/ImoutoRebirth.Navigator/ViewModel/SettingsVM.cs +++ b/Source/ImoutoRebirth.Navigator/ImoutoRebirth.Navigator/ViewModel/SettingsVM.cs @@ -6,6 +6,8 @@ using ImoutoRebirth.Common; using ImoutoRebirth.Common.WPF; using ImoutoRebirth.Common.WPF.Commands; +using ImoutoRebirth.Navigator.Services; +using ImoutoRebirth.Navigator.Services.Collections; using MahApps.Metro.Theming; namespace ImoutoRebirth.Navigator.ViewModel; @@ -15,7 +17,10 @@ internal class SettingsVM : VMBase private AccentColorMenuData _selectedAccentColor; private int _selectedTheme; private ICommand? _saveCommand; + private ICommand? _toggleImoutoPicsCommand; private string _pathOverrides; + private readonly IImoutoPicsUploaderStateService _imoutoPicsUploaderStateService; + private bool _isImoutoPicsUploaderEnabled; public SettingsVM() { @@ -32,6 +37,8 @@ public SettingsVM() ShowPreviewOnSelect = Settings.Default.ActivatePreviewOnSelect; PathOverrides = Settings.Default.PathOverrides; + + _imoutoPicsUploaderStateService = ServiceLocator.GetService<IImoutoPicsUploaderStateService>(); } public bool ShowPreviewOnSelect @@ -138,6 +145,12 @@ public string LilinHost set => Settings.Default.LilinHost = value; } + public bool IsImoutoPicsUploaderEnabled + { + get => _isImoutoPicsUploaderEnabled; + set => OnPropertyChanged(ref _isImoutoPicsUploaderEnabled, value, () => IsImoutoPicsUploaderEnabled); + } + public string RoomHost { get => Settings.Default.RoomHost; @@ -146,6 +159,8 @@ public string RoomHost public ICommand SaveCommand => _saveCommand ??= new RelayCommand(_ => Save()); + public ICommand ToggleImoutoPicsCommand => _toggleImoutoPicsCommand ??= new AsyncCommand(() => ToggleImoutoPics()); + private static void Save() => Settings.Default.Save(); public event EventHandler? ShowPreviewOnSelectChanged; @@ -155,6 +170,25 @@ private void OnShowPreviewOnSelectChanged() var handler = ShowPreviewOnSelectChanged; handler?.Invoke(this, EventArgs.Empty); } + + public async Task InitializeAsync() + { + IsImoutoPicsUploaderEnabled = await _imoutoPicsUploaderStateService.IsEnabledAsync(); + } + + private async Task ToggleImoutoPics() + { + if (IsImoutoPicsUploaderEnabled) + { + await _imoutoPicsUploaderStateService.DisableAsync(); + } + else + { + await _imoutoPicsUploaderStateService.EnableAsync(); + } + + IsImoutoPicsUploaderEnabled = await _imoutoPicsUploaderStateService.IsEnabledAsync(); + } } public class AccentColorMenuData diff --git a/Source/ImoutoRebirth.Room/ImoutoRebirth.Room.Application/Cqrs/ImoutoPicsUploadStateSlice/EnableImoutoPicsUploaderCommand.cs b/Source/ImoutoRebirth.Room/ImoutoRebirth.Room.Application/Cqrs/ImoutoPicsUploadStateSlice/EnableImoutoPicsUploaderCommand.cs new file mode 100644 index 00000000..a5a2c1db --- /dev/null +++ b/Source/ImoutoRebirth.Room/ImoutoRebirth.Room.Application/Cqrs/ImoutoPicsUploadStateSlice/EnableImoutoPicsUploaderCommand.cs @@ -0,0 +1,34 @@ +using ImoutoRebirth.Common.Cqrs.Abstract; +using ImoutoRebirth.Room.Application.Services; + +namespace ImoutoRebirth.Room.Application.Cqrs.ImoutoPicsUploadStateSlice; + +public record EnableImoutoPicsUploaderCommand : ICommand; + +public record DisableImoutoPicsUploaderCommand : ICommand; + +internal class EnableImoutoPicsUploaderCommandHandler + : ICommandHandler<EnableImoutoPicsUploaderCommand> + , ICommandHandler<DisableImoutoPicsUploaderCommand> +{ + private readonly IImoutoPicsUploaderRepository _imoutoPicsUploaderRepository; + + public EnableImoutoPicsUploaderCommandHandler(IImoutoPicsUploaderRepository imoutoPicsUploaderRepository) + => _imoutoPicsUploaderRepository = imoutoPicsUploaderRepository; + + public Task Handle(EnableImoutoPicsUploaderCommand _, CancellationToken ct) + { + var state = _imoutoPicsUploaderRepository.Get(); + state.Enable(); + + return Task.CompletedTask; + } + + public Task Handle(DisableImoutoPicsUploaderCommand _, CancellationToken ct) + { + var state = _imoutoPicsUploaderRepository.Get(); + state.Disable(); + + return Task.CompletedTask; + } +} diff --git a/Source/ImoutoRebirth.Room/ImoutoRebirth.Room.Application/Cqrs/ImoutoPicsUploadStateSlice/IsImoutoPicsUploaderEnabledQuery.cs b/Source/ImoutoRebirth.Room/ImoutoRebirth.Room.Application/Cqrs/ImoutoPicsUploadStateSlice/IsImoutoPicsUploaderEnabledQuery.cs new file mode 100644 index 00000000..8c013a40 --- /dev/null +++ b/Source/ImoutoRebirth.Room/ImoutoRebirth.Room.Application/Cqrs/ImoutoPicsUploadStateSlice/IsImoutoPicsUploaderEnabledQuery.cs @@ -0,0 +1,21 @@ +using ImoutoRebirth.Common.Cqrs.Abstract; +using ImoutoRebirth.Room.Application.Services; + +namespace ImoutoRebirth.Room.Application.Cqrs.ImoutoPicsUploadStateSlice; + +public record IsImoutoPicsUploaderEnabledQuery : IQuery<bool>; + +internal class IsImoutoPicsUploaderEnabledQueryHandler + : IQueryHandler<IsImoutoPicsUploaderEnabledQuery, bool> +{ + private readonly IImoutoPicsUploaderRepository _imoutoPicsUploaderRepository; + + public IsImoutoPicsUploaderEnabledQueryHandler(IImoutoPicsUploaderRepository imoutoPicsUploaderRepository) + => _imoutoPicsUploaderRepository = imoutoPicsUploaderRepository; + + public Task<bool> Handle(IsImoutoPicsUploaderEnabledQuery _, CancellationToken ct) + { + var state = _imoutoPicsUploaderRepository.Get(); + return Task.FromResult(state.IsEnabled); + } +} diff --git a/Source/ImoutoRebirth.Room/ImoutoRebirth.Room.Application/Cqrs/OverseeCollectionCommand.cs b/Source/ImoutoRebirth.Room/ImoutoRebirth.Room.Application/Cqrs/OverseeCollectionCommand.cs index ab60228a..2b496ed3 100644 --- a/Source/ImoutoRebirth.Room/ImoutoRebirth.Room.Application/Cqrs/OverseeCollectionCommand.cs +++ b/Source/ImoutoRebirth.Room/ImoutoRebirth.Room.Application/Cqrs/OverseeCollectionCommand.cs @@ -1,6 +1,7 @@ using System.Runtime.CompilerServices; using ImoutoRebirth.Common.Cqrs.Abstract; using ImoutoRebirth.Common.Domain; +using ImoutoRebirth.Room.Application.Cqrs.ImoutoPicsUploadStateSlice; using ImoutoRebirth.Room.Application.Services; using ImoutoRebirth.Room.Domain; using ImoutoRebirth.Room.Domain.CollectionAggregate; @@ -73,7 +74,11 @@ private async Task SaveAndReport(Guid collectionId, SystemFileMoved moved) await _remoteCommandService.SaveTags(newId, moved.SourceTags); await _remoteCommandService.UpdateMetadataRequest(newId, moved.SystemFile.Md5); - await _imoutoPicsUploader.UploadFile(moved.MovedFileInfo.FullName); + + var isUploadEnabled = await _mediator.Send(new IsImoutoPicsUploaderEnabledQuery()); + + if (isUploadEnabled) + await _imoutoPicsUploader.UploadFile(moved.MovedFileInfo.FullName); } private SystemFileMoved MoveFile(Collection collection, SystemFilePreparedToMove preparedToMove) diff --git a/Source/ImoutoRebirth.Room/ImoutoRebirth.Room.Application/ServiceCollectionExtensions.cs b/Source/ImoutoRebirth.Room/ImoutoRebirth.Room.Application/ServiceCollectionExtensions.cs index 91a85c1e..79a78090 100644 --- a/Source/ImoutoRebirth.Room/ImoutoRebirth.Room.Application/ServiceCollectionExtensions.cs +++ b/Source/ImoutoRebirth.Room/ImoutoRebirth.Room.Application/ServiceCollectionExtensions.cs @@ -1,6 +1,7 @@ using System.Reflection; using ImoutoRebirth.Common.Cqrs; using ImoutoRebirth.Room.Application.Cqrs; +using ImoutoRebirth.Room.Application.Services; using Microsoft.Extensions.DependencyInjection; namespace ImoutoRebirth.Room.Application; @@ -18,6 +19,8 @@ public static IServiceCollection AddRoomApplication( }); services.AddLoggingBehavior(); services.AddTransactionBehavior(); + + services.AddSingleton<IImoutoPicsUploaderRepository, ImoutoPicsUploaderRepository>(); return services; } diff --git a/Source/ImoutoRebirth.Room/ImoutoRebirth.Room.Application/Services/IImoutoPicsUploaderRepository.cs b/Source/ImoutoRebirth.Room/ImoutoRebirth.Room.Application/Services/IImoutoPicsUploaderRepository.cs new file mode 100644 index 00000000..56f46549 --- /dev/null +++ b/Source/ImoutoRebirth.Room/ImoutoRebirth.Room.Application/Services/IImoutoPicsUploaderRepository.cs @@ -0,0 +1,18 @@ +using ImoutoRebirth.Room.Domain; + +namespace ImoutoRebirth.Room.Application.Services; + +public interface IImoutoPicsUploaderRepository +{ + ImoutoPicsUploaderState Get(); +} + +/// <summary> +/// Should be registered as a singleton. +/// </summary> +public class ImoutoPicsUploaderRepository : IImoutoPicsUploaderRepository +{ + private readonly ImoutoPicsUploaderState _state = new(); + + public ImoutoPicsUploaderState Get() => _state; +} diff --git a/Source/ImoutoRebirth.Room/ImoutoRebirth.Room.Domain/ImoutoPicsUploaderState.cs b/Source/ImoutoRebirth.Room/ImoutoRebirth.Room.Domain/ImoutoPicsUploaderState.cs new file mode 100644 index 00000000..d7e30ccb --- /dev/null +++ b/Source/ImoutoRebirth.Room/ImoutoRebirth.Room.Domain/ImoutoPicsUploaderState.cs @@ -0,0 +1,10 @@ +namespace ImoutoRebirth.Room.Domain; + +public class ImoutoPicsUploaderState +{ + public bool IsEnabled { get; private set; } = true; + + public void Enable() => IsEnabled = true; + + public void Disable() => IsEnabled = false; +} diff --git a/Source/ImoutoRebirth.Room/ImoutoRebirth.Room.IntegrationTests/CollectionFileSystemTests.cs b/Source/ImoutoRebirth.Room/ImoutoRebirth.Room.IntegrationTests/CollectionFileSystemTests.cs index 5b508f54..3a111495 100644 --- a/Source/ImoutoRebirth.Room/ImoutoRebirth.Room.IntegrationTests/CollectionFileSystemTests.cs +++ b/Source/ImoutoRebirth.Room/ImoutoRebirth.Room.IntegrationTests/CollectionFileSystemTests.cs @@ -11,6 +11,7 @@ using MediatR; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.DependencyInjection; +using Moq; using Xunit; namespace ImoutoRebirth.Room.IntegrationTests; @@ -807,6 +808,58 @@ public async Task MultipleFileIsMovedToDestinationWithSameName() .Should().Be(Path.Combine(destFolderPath, "file1-5f30f9953332c230d11e3f26db5ae9a0.jpg")); } + [Fact] + public async Task ImoutoPicsUploadCalledWhenImoutoPicsUploaderEnabled() + { + // arrange + var (_, sourceFolderPath, destFolderPath) = await CreateDefaultCollection( + sourceShouldCheckFormat: false, + sourceShouldCheckHashFromName: false , + sourceShouldCreateTagsFromSubfolders: false, + sourceShouldAddTagFromFilename: false, + sourceSupportedExtensions: new []{ "jpg" }, + destShouldCreateSubfoldersByHash: false, + destShouldRenameByHash: false); + + var testFile = new FileInfo(Path.Combine(_webApp.TestsLocation, "Resources", "file1-5f30f9953332c230d11e3f26db5ae9a0.jpg")); + + await _webApp.Client.PostAsync("/imouto-pics-uploader-enabled", null); + + // act + testFile.CopyTo(Path.Combine(sourceFolderPath, testFile.Name)); + await _mediator.Send(new OverseeCommand()); + + // assert + var file = Path.Combine(destFolderPath, "file1-5f30f9953332c230d11e3f26db5ae9a0.jpg"); + _webApp.ImoutoPicsUploaderMock.Verify(x => x.UploadFile(file), Times.Once); + } + + [Fact()] + public async Task ImoutoPicsUploadShouldNotBeCalledWhenImoutoPicsUploaderDisabled() + { + // arrange + var (_, sourceFolderPath, destFolderPath) = await CreateDefaultCollection( + sourceShouldCheckFormat: false, + sourceShouldCheckHashFromName: false , + sourceShouldCreateTagsFromSubfolders: false, + sourceShouldAddTagFromFilename: false, + sourceSupportedExtensions: new []{ "jpg" }, + destShouldCreateSubfoldersByHash: false, + destShouldRenameByHash: false); + + var testFile = new FileInfo(Path.Combine(_webApp.TestsLocation, "Resources", "file1-5f30f9953332c230d11e3f26db5ae9a0.jpg")); + + await _webApp.Client.DeleteAsync("/imouto-pics-uploader-enabled"); + + // act + testFile.CopyTo(Path.Combine(sourceFolderPath, testFile.Name)); + await _mediator.Send(new OverseeCommand()); + + // assert + var file = Path.Combine(destFolderPath, "file1-5f30f9953332c230d11e3f26db5ae9a0.jpg"); + _webApp.ImoutoPicsUploaderMock.Verify(x => x.UploadFile(file), Times.Never); + } + private async Task<CreatedCollection> CreateDefaultCollection( bool sourceShouldCheckFormat = false, bool sourceShouldCheckHashFromName = false, diff --git a/Source/ImoutoRebirth.Room/ImoutoRebirth.Room.IntegrationTests/Fixtures/TestWebApplicationFactory.cs b/Source/ImoutoRebirth.Room/ImoutoRebirth.Room.IntegrationTests/Fixtures/TestWebApplicationFactory.cs index d369ba97..93278f81 100644 --- a/Source/ImoutoRebirth.Room/ImoutoRebirth.Room.IntegrationTests/Fixtures/TestWebApplicationFactory.cs +++ b/Source/ImoutoRebirth.Room/ImoutoRebirth.Room.IntegrationTests/Fixtures/TestWebApplicationFactory.cs @@ -1,11 +1,13 @@ using System.Reflection; using ImoutoRebirth.Common.MassTransit; +using ImoutoRebirth.Room.Application.Services; using ImoutoRebirth.Room.Database; using ImoutoRebirth.Room.Infrastructure; using Microsoft.AspNetCore.Mvc.Testing; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; +using Moq; using Npgsql; using Xunit; @@ -33,6 +35,8 @@ public string TestsTempLocation public string TestsLocation => new FileInfo(Assembly.GetExecutingAssembly().Location).Directory!.FullName; + public Mock<IImoutoPicsUploader> ImoutoPicsUploaderMock { get; } = new(); + protected override IHost CreateHost(IHostBuilder builder) { builder.ConfigureServices(services => @@ -47,6 +51,9 @@ protected override IHost CreateHost(IHostBuilder builder) .Union(services.Where( d => d.ServiceType == typeof(IHostedService) && d.ImplementationType?.Name == "QuartzHostedService")) + + // replace IImoutoPicsUploader with mock + .Union(services.Where(x => x.ServiceType == typeof(IImoutoPicsUploader))) .ToList(); foreach (var descriptor in descriptors) @@ -54,6 +61,7 @@ protected override IHost CreateHost(IHostBuilder builder) services.AddDbContext<RoomDbContext>(x => x.UseNpgsql(ConnectionString, y => y.UseNodaTime())); services.AddMassTransitTestHarness(с => с.AddRoomMassTransitSetup()); + services.AddTransient<IImoutoPicsUploader>(x => ImoutoPicsUploaderMock.Object); }); var host = base.CreateHost(builder); diff --git a/Source/ImoutoRebirth.Room/ImoutoRebirth.Room.IntegrationTests/ImoutoPicsUploaderEnabledTests.cs b/Source/ImoutoRebirth.Room/ImoutoRebirth.Room.IntegrationTests/ImoutoPicsUploaderEnabledTests.cs new file mode 100644 index 00000000..00b17dbd --- /dev/null +++ b/Source/ImoutoRebirth.Room/ImoutoRebirth.Room.IntegrationTests/ImoutoPicsUploaderEnabledTests.cs @@ -0,0 +1,43 @@ +using Xunit; +using System.Net.Http.Json; +using ImoutoRebirth.Room.IntegrationTests.Fixtures; + +namespace ImoutoRebirth.Room.IntegrationTests +{ + [Collection("WebApplication")] + public class ImoutoPicsUploaderEnabledTests + { + private readonly TestWebApplicationFactory<Program> _webApp; + + public ImoutoPicsUploaderEnabledTests(TestWebApplicationFactory<Program> webApp) => _webApp = webApp; + + [Fact] + public async Task ImoutoPicsUploaderEnabledByDefault() + { + var response = await _webApp.Client.GetFromJsonAsync<bool>("/imouto-pics-uploader-enabled"); + Assert.True(response); + } + + [Fact] + public async Task DisableImoutoPicsUploader() + { + var response = await _webApp.Client.DeleteAsync("/imouto-pics-uploader-enabled"); + response.EnsureSuccessStatusCode(); + + var isEnabled = await _webApp.Client.GetFromJsonAsync<bool>("/imouto-pics-uploader-enabled"); + Assert.False(isEnabled); + } + + [Fact] + public async Task EnableImoutoPicsUploader() + { + await _webApp.Client.PostAsync("/imouto-pics-uploader-enabled/disable", null); + + var response = await _webApp.Client.PostAsync("/imouto-pics-uploader-enabled", null); + response.EnsureSuccessStatusCode(); + + var isEnabled = await _webApp.Client.GetFromJsonAsync<bool>("/imouto-pics-uploader-enabled"); + Assert.True(isEnabled); + } + } +} diff --git a/Source/ImoutoRebirth.Room/ImoutoRebirth.Room.IntegrationTests/ImoutoRebirth.Room.IntegrationTests.csproj b/Source/ImoutoRebirth.Room/ImoutoRebirth.Room.IntegrationTests/ImoutoRebirth.Room.IntegrationTests.csproj index 8ad62111..7c55a7d9 100644 --- a/Source/ImoutoRebirth.Room/ImoutoRebirth.Room.IntegrationTests/ImoutoRebirth.Room.IntegrationTests.csproj +++ b/Source/ImoutoRebirth.Room/ImoutoRebirth.Room.IntegrationTests/ImoutoRebirth.Room.IntegrationTests.csproj @@ -18,6 +18,7 @@ <PackageReference Include="FluentAssertions" Version="6.12.0" /> <PackageReference Include="Microsoft.AspNetCore.Mvc.Testing" Version="8.0.3" /> <PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.9.0" /> + <PackageReference Include="Moq" Version="4.20.70" /> <PackageReference Include="xunit" Version="2.7.0" /> <PackageReference Include="xunit.runner.visualstudio" Version="2.5.7"> <PrivateAssets>all</PrivateAssets> diff --git a/Source/ImoutoRebirth.Room/ImoutoRebirth.Room.UI/WebApi/EndpointsMappings.cs b/Source/ImoutoRebirth.Room/ImoutoRebirth.Room.UI/WebApi/EndpointsMappings.cs index efd54f17..dc3e674e 100644 --- a/Source/ImoutoRebirth.Room/ImoutoRebirth.Room.UI/WebApi/EndpointsMappings.cs +++ b/Source/ImoutoRebirth.Room/ImoutoRebirth.Room.UI/WebApi/EndpointsMappings.cs @@ -3,6 +3,7 @@ using ImoutoRebirth.Room.Application.Cqrs.CollectionFileSlice; using ImoutoRebirth.Room.Application.Cqrs.CollectionSlice; using ImoutoRebirth.Room.Application.Cqrs.FoldersSlice; +using ImoutoRebirth.Room.Application.Cqrs.ImoutoPicsUploadStateSlice; using MediatR; using Microsoft.AspNetCore.Builder; @@ -103,4 +104,21 @@ public static void MapSourceFoldersEndpoints(this WebApplication app) => mediator.Send(new DeleteSourceFolderCommand(collectionId, sourceFolderId), ct)) .WithName("DeleteSourceFolder"); } + + public static void MapImoutoPicsUploaderEnabled(this WebApplication app) + { + var sourceFolders = app.MapGroup("/imouto-pics-uploader-enabled"); + + sourceFolders.MapGet("", (IMediator mediator, CancellationToken ct) + => mediator.Send(new IsImoutoPicsUploaderEnabledQuery(), ct)) + .WithName("IsImoutoPicsUploaderEnabled"); + + sourceFolders.MapPost("", (IMediator mediator, CancellationToken ct) + => mediator.Send(new EnableImoutoPicsUploaderCommand(), ct)) + .WithName("EnableImoutoPicsUploader"); + + sourceFolders.MapDelete("", (IMediator mediator, CancellationToken ct) + => mediator.Send(new DisableImoutoPicsUploaderCommand(), ct)) + .WithName("DisableImoutoPicsUploader"); + } } diff --git a/Source/ImoutoRebirth.Room/ImoutoRebirth.Room.UI/WebApi/WebApiStartup.cs b/Source/ImoutoRebirth.Room/ImoutoRebirth.Room.UI/WebApi/WebApiStartup.cs index 913c79c5..f950f16c 100644 --- a/Source/ImoutoRebirth.Room/ImoutoRebirth.Room.UI/WebApi/WebApiStartup.cs +++ b/Source/ImoutoRebirth.Room/ImoutoRebirth.Room.UI/WebApi/WebApiStartup.cs @@ -46,6 +46,7 @@ public static WebApplication MapWebEndpoints(this WebApplication app) app.MapCollectionFilesEndpoints(); app.MapDestinationFoldersEndpoints(); app.MapSourceFoldersEndpoints(); + app.MapImoutoPicsUploaderEnabled(); return app; } diff --git a/Source/ImoutoRebirth.Room/ImoutoRebirth.Room.WebApi.Client/Clients.cs b/Source/ImoutoRebirth.Room/ImoutoRebirth.Room.WebApi.Client/Clients.cs index 94a6586c..e4648fdd 100644 --- a/Source/ImoutoRebirth.Room/ImoutoRebirth.Room.WebApi.Client/Clients.cs +++ b/Source/ImoutoRebirth.Room/ImoutoRebirth.Room.WebApi.Client/Clients.cs @@ -1,6 +1,6 @@ //---------------------- // <auto-generated> -// Generated using the NSwag toolchain v14.0.0.0 (NJsonSchema v11.0.0.0 (Newtonsoft.Json v13.0.0.0)) (http://NSwag.org) +// Generated using the NSwag toolchain v14.0.7.0 (NJsonSchema v11.0.0.0 (Newtonsoft.Json v13.0.0.0)) (http://NSwag.org) // </auto-generated> //---------------------- @@ -16,18 +16,22 @@ #pragma warning disable 3016 // Disable "CS3016 Arrays as attribute arguments is not CLS-compliant" #pragma warning disable 8603 // Disable "CS8603 Possible null reference return" #pragma warning disable 8604 // Disable "CS8604 Possible null reference argument for parameter" +#pragma warning disable 8625 // Disable "CS8625 Cannot convert null literal to non-nullable reference type" +#pragma warning disable CS8765 // Nullability of type of parameter doesn't match overridden member (possibly because of nullability attributes). namespace ImoutoRebirth.Room.WebApi.Client { using System = global::System; - [System.CodeDom.Compiler.GeneratedCode("NSwag", "14.0.0.0 (NJsonSchema v11.0.0.0 (Newtonsoft.Json v13.0.0.0))")] + [System.CodeDom.Compiler.GeneratedCode("NSwag", "14.0.7.0 (NJsonSchema v11.0.0.0 (Newtonsoft.Json v13.0.0.0))")] public partial class CollectionFilesClient { private System.Net.Http.HttpClient _httpClient; private static System.Lazy<System.Text.Json.JsonSerializerOptions> _settings = new System.Lazy<System.Text.Json.JsonSerializerOptions>(CreateSerializerSettings, true); + #pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. public CollectionFilesClient(System.Net.Http.HttpClient httpClient) + #pragma warning restore CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. { _httpClient = httpClient; } @@ -645,13 +649,15 @@ private string ConvertToString(object? value, System.Globalization.CultureInfo c } } - [System.CodeDom.Compiler.GeneratedCode("NSwag", "14.0.0.0 (NJsonSchema v11.0.0.0 (Newtonsoft.Json v13.0.0.0))")] + [System.CodeDom.Compiler.GeneratedCode("NSwag", "14.0.7.0 (NJsonSchema v11.0.0.0 (Newtonsoft.Json v13.0.0.0))")] public partial class CollectionsClient { private System.Net.Http.HttpClient _httpClient; private static System.Lazy<System.Text.Json.JsonSerializerOptions> _settings = new System.Lazy<System.Text.Json.JsonSerializerOptions>(CreateSerializerSettings, true); + #pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. public CollectionsClient(System.Net.Http.HttpClient httpClient) + #pragma warning restore CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. { _httpClient = httpClient; } @@ -866,9 +872,9 @@ public virtual async System.Threading.Tasks.Task RenameCollectionAsync(System.Gu // Operation Path: "collections/{collectionId}" urlBuilder_.Append("collections/"); urlBuilder_.Append(System.Uri.EscapeDataString(ConvertToString(collectionId, System.Globalization.CultureInfo.InvariantCulture))); - urlBuilder_.Append('?'); - urlBuilder_.Append(System.Uri.EscapeDataString("newName")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(newName, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); - urlBuilder_.Length--; + urlBuilder_.Append('?'); + urlBuilder_.Append(System.Uri.EscapeDataString("newName")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(newName, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); + urlBuilder_.Length--; PrepareRequest(client_, request_, urlBuilder_); @@ -1675,7 +1681,367 @@ private string ConvertToString(object? value, System.Globalization.CultureInfo c } } - [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "14.0.0.0 (NJsonSchema v11.0.0.0 (Newtonsoft.Json v13.0.0.0))")] + [System.CodeDom.Compiler.GeneratedCode("NSwag", "14.0.7.0 (NJsonSchema v11.0.0.0 (Newtonsoft.Json v13.0.0.0))")] + public partial class ImoutoPicsUploaderEnabledClient + { + private System.Net.Http.HttpClient _httpClient; + private static System.Lazy<System.Text.Json.JsonSerializerOptions> _settings = new System.Lazy<System.Text.Json.JsonSerializerOptions>(CreateSerializerSettings, true); + + #pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. + public ImoutoPicsUploaderEnabledClient(System.Net.Http.HttpClient httpClient) + #pragma warning restore CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. + { + _httpClient = httpClient; + } + + private static System.Text.Json.JsonSerializerOptions CreateSerializerSettings() + { + var settings = new System.Text.Json.JsonSerializerOptions(); + UpdateJsonSerializerSettings(settings); + return settings; + } + + protected System.Text.Json.JsonSerializerOptions JsonSerializerSettings { get { return _settings.Value; } } + + static partial void UpdateJsonSerializerSettings(System.Text.Json.JsonSerializerOptions settings); + + partial void PrepareRequest(System.Net.Http.HttpClient client, System.Net.Http.HttpRequestMessage request, string url); + partial void PrepareRequest(System.Net.Http.HttpClient client, System.Net.Http.HttpRequestMessage request, System.Text.StringBuilder urlBuilder); + partial void ProcessResponse(System.Net.Http.HttpClient client, System.Net.Http.HttpResponseMessage response); + + /// <returns>Success</returns> + /// <exception cref="WebApiException">A server side error occurred.</exception> + public virtual System.Threading.Tasks.Task<bool> IsImoutoPicsUploaderEnabledAsync() + { + return IsImoutoPicsUploaderEnabledAsync(System.Threading.CancellationToken.None); + } + + /// <param name="cancellationToken">A cancellation token that can be used by other objects or threads to receive notice of cancellation.</param> + /// <returns>Success</returns> + /// <exception cref="WebApiException">A server side error occurred.</exception> + public virtual async System.Threading.Tasks.Task<bool> IsImoutoPicsUploaderEnabledAsync(System.Threading.CancellationToken cancellationToken) + { + var client_ = _httpClient; + var disposeClient_ = false; + try + { + using (var request_ = new System.Net.Http.HttpRequestMessage()) + { + request_.Method = new System.Net.Http.HttpMethod("GET"); + request_.Headers.Accept.Add(System.Net.Http.Headers.MediaTypeWithQualityHeaderValue.Parse("application/json")); + + var urlBuilder_ = new System.Text.StringBuilder(); + + // Operation Path: "imouto-pics-uploader-enabled" + urlBuilder_.Append("imouto-pics-uploader-enabled"); + + PrepareRequest(client_, request_, urlBuilder_); + + var url_ = urlBuilder_.ToString(); + request_.RequestUri = new System.Uri(url_, System.UriKind.RelativeOrAbsolute); + + PrepareRequest(client_, request_, url_); + + var response_ = await client_.SendAsync(request_, System.Net.Http.HttpCompletionOption.ResponseHeadersRead, cancellationToken).ConfigureAwait(false); + var disposeResponse_ = true; + try + { + var headers_ = new System.Collections.Generic.Dictionary<string, System.Collections.Generic.IEnumerable<string>>(); + foreach (var item_ in response_.Headers) + headers_[item_.Key] = item_.Value; + if (response_.Content != null && response_.Content.Headers != null) + { + foreach (var item_ in response_.Content.Headers) + headers_[item_.Key] = item_.Value; + } + + ProcessResponse(client_, response_); + + var status_ = (int)response_.StatusCode; + if (status_ == 200) + { + var objectResponse_ = await ReadObjectResponseAsync<bool>(response_, headers_, cancellationToken).ConfigureAwait(false); + if (objectResponse_.Object == null) + { + throw new WebApiException("Response was null which was not expected.", status_, objectResponse_.Text, headers_, null); + } + return objectResponse_.Object; + } + else + { + var responseData_ = response_.Content == null ? null : await response_.Content.ReadAsStringAsync().ConfigureAwait(false); + throw new WebApiException("The HTTP status code of the response was not expected (" + status_ + ").", status_, responseData_, headers_, null); + } + } + finally + { + if (disposeResponse_) + response_.Dispose(); + } + } + } + finally + { + if (disposeClient_) + client_.Dispose(); + } + } + + /// <returns>Success</returns> + /// <exception cref="WebApiException">A server side error occurred.</exception> + public virtual System.Threading.Tasks.Task EnableImoutoPicsUploaderAsync() + { + return EnableImoutoPicsUploaderAsync(System.Threading.CancellationToken.None); + } + + /// <param name="cancellationToken">A cancellation token that can be used by other objects or threads to receive notice of cancellation.</param> + /// <returns>Success</returns> + /// <exception cref="WebApiException">A server side error occurred.</exception> + public virtual async System.Threading.Tasks.Task EnableImoutoPicsUploaderAsync(System.Threading.CancellationToken cancellationToken) + { + var client_ = _httpClient; + var disposeClient_ = false; + try + { + using (var request_ = new System.Net.Http.HttpRequestMessage()) + { + request_.Content = new System.Net.Http.StringContent(string.Empty, System.Text.Encoding.UTF8, "application/json"); + request_.Method = new System.Net.Http.HttpMethod("POST"); + + var urlBuilder_ = new System.Text.StringBuilder(); + + // Operation Path: "imouto-pics-uploader-enabled" + urlBuilder_.Append("imouto-pics-uploader-enabled"); + + PrepareRequest(client_, request_, urlBuilder_); + + var url_ = urlBuilder_.ToString(); + request_.RequestUri = new System.Uri(url_, System.UriKind.RelativeOrAbsolute); + + PrepareRequest(client_, request_, url_); + + var response_ = await client_.SendAsync(request_, System.Net.Http.HttpCompletionOption.ResponseHeadersRead, cancellationToken).ConfigureAwait(false); + var disposeResponse_ = true; + try + { + var headers_ = new System.Collections.Generic.Dictionary<string, System.Collections.Generic.IEnumerable<string>>(); + foreach (var item_ in response_.Headers) + headers_[item_.Key] = item_.Value; + if (response_.Content != null && response_.Content.Headers != null) + { + foreach (var item_ in response_.Content.Headers) + headers_[item_.Key] = item_.Value; + } + + ProcessResponse(client_, response_); + + var status_ = (int)response_.StatusCode; + if (status_ == 200) + { + return; + } + else + { + var responseData_ = response_.Content == null ? null : await response_.Content.ReadAsStringAsync().ConfigureAwait(false); + throw new WebApiException("The HTTP status code of the response was not expected (" + status_ + ").", status_, responseData_, headers_, null); + } + } + finally + { + if (disposeResponse_) + response_.Dispose(); + } + } + } + finally + { + if (disposeClient_) + client_.Dispose(); + } + } + + /// <returns>Success</returns> + /// <exception cref="WebApiException">A server side error occurred.</exception> + public virtual System.Threading.Tasks.Task DisableImoutoPicsUploaderAsync() + { + return DisableImoutoPicsUploaderAsync(System.Threading.CancellationToken.None); + } + + /// <param name="cancellationToken">A cancellation token that can be used by other objects or threads to receive notice of cancellation.</param> + /// <returns>Success</returns> + /// <exception cref="WebApiException">A server side error occurred.</exception> + public virtual async System.Threading.Tasks.Task DisableImoutoPicsUploaderAsync(System.Threading.CancellationToken cancellationToken) + { + var client_ = _httpClient; + var disposeClient_ = false; + try + { + using (var request_ = new System.Net.Http.HttpRequestMessage()) + { + request_.Method = new System.Net.Http.HttpMethod("DELETE"); + + var urlBuilder_ = new System.Text.StringBuilder(); + + // Operation Path: "imouto-pics-uploader-enabled" + urlBuilder_.Append("imouto-pics-uploader-enabled"); + + PrepareRequest(client_, request_, urlBuilder_); + + var url_ = urlBuilder_.ToString(); + request_.RequestUri = new System.Uri(url_, System.UriKind.RelativeOrAbsolute); + + PrepareRequest(client_, request_, url_); + + var response_ = await client_.SendAsync(request_, System.Net.Http.HttpCompletionOption.ResponseHeadersRead, cancellationToken).ConfigureAwait(false); + var disposeResponse_ = true; + try + { + var headers_ = new System.Collections.Generic.Dictionary<string, System.Collections.Generic.IEnumerable<string>>(); + foreach (var item_ in response_.Headers) + headers_[item_.Key] = item_.Value; + if (response_.Content != null && response_.Content.Headers != null) + { + foreach (var item_ in response_.Content.Headers) + headers_[item_.Key] = item_.Value; + } + + ProcessResponse(client_, response_); + + var status_ = (int)response_.StatusCode; + if (status_ == 200) + { + return; + } + else + { + var responseData_ = response_.Content == null ? null : await response_.Content.ReadAsStringAsync().ConfigureAwait(false); + throw new WebApiException("The HTTP status code of the response was not expected (" + status_ + ").", status_, responseData_, headers_, null); + } + } + finally + { + if (disposeResponse_) + response_.Dispose(); + } + } + } + finally + { + if (disposeClient_) + client_.Dispose(); + } + } + + protected struct ObjectResponseResult<T> + { + public ObjectResponseResult(T responseObject, string responseText) + { + this.Object = responseObject; + this.Text = responseText; + } + + public T Object { get; } + + public string Text { get; } + } + + public bool ReadResponseAsString { get; set; } + + protected virtual async System.Threading.Tasks.Task<ObjectResponseResult<T>> ReadObjectResponseAsync<T>(System.Net.Http.HttpResponseMessage response, System.Collections.Generic.IReadOnlyDictionary<string, System.Collections.Generic.IEnumerable<string>> headers, System.Threading.CancellationToken cancellationToken) + { + if (response == null || response.Content == null) + { + return new ObjectResponseResult<T>(default(T)!, string.Empty); + } + + if (ReadResponseAsString) + { + var responseText = await response.Content.ReadAsStringAsync().ConfigureAwait(false); + try + { + var typedBody = System.Text.Json.JsonSerializer.Deserialize<T>(responseText, JsonSerializerSettings); + return new ObjectResponseResult<T>(typedBody!, responseText); + } + catch (System.Text.Json.JsonException exception) + { + var message = "Could not deserialize the response body string as " + typeof(T).FullName + "."; + throw new WebApiException(message, (int)response.StatusCode, responseText, headers, exception); + } + } + else + { + try + { + using (var responseStream = await response.Content.ReadAsStreamAsync().ConfigureAwait(false)) + { + var typedBody = await System.Text.Json.JsonSerializer.DeserializeAsync<T>(responseStream, JsonSerializerSettings, cancellationToken).ConfigureAwait(false); + return new ObjectResponseResult<T>(typedBody!, string.Empty); + } + } + catch (System.Text.Json.JsonException exception) + { + var message = "Could not deserialize the response body stream as " + typeof(T).FullName + "."; + throw new WebApiException(message, (int)response.StatusCode, string.Empty, headers, exception); + } + } + } + + private string ConvertToString(object? value, System.Globalization.CultureInfo cultureInfo) + { + if (value == null) + { + return ""; + } + + if (value is System.Enum) + { + var name = System.Enum.GetName(value.GetType(), value); + if (name != null) + { + var field = System.Reflection.IntrospectionExtensions.GetTypeInfo(value.GetType()).GetDeclaredField(name); + if (field != null) + { + var attribute = System.Reflection.CustomAttributeExtensions.GetCustomAttribute(field, typeof(System.Runtime.Serialization.EnumMemberAttribute)) + as System.Runtime.Serialization.EnumMemberAttribute; + if (attribute != null) + { + return attribute.Value != null ? attribute.Value : name; + } + } + + var converted = System.Convert.ToString(System.Convert.ChangeType(value, System.Enum.GetUnderlyingType(value.GetType()), cultureInfo)); + return converted == null ? string.Empty : converted; + } + } + else if (value is bool) + { + return System.Convert.ToString((bool)value, cultureInfo).ToLowerInvariant(); + } + else if (value is byte[]) + { + return System.Convert.ToBase64String((byte[]) value); + } + else if (value is string[]) + { + return string.Join(",", (string[])value); + } + else if (value.GetType().IsArray) + { + var valueArray = (System.Array)value; + var valueTextArray = new string[valueArray.Length]; + for (var i = 0; i < valueArray.Length; i++) + { + valueTextArray[i] = ConvertToString(valueArray.GetValue(i), cultureInfo); + } + return string.Join(",", valueTextArray); + } + + var result = System.Convert.ToString(value, cultureInfo); + return result == null ? "" : result; + } + } + + [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "14.0.7.0 (NJsonSchema v11.0.0.0 (Newtonsoft.Json v13.0.0.0))")] public partial class AddSourceFolderCommand { [System.Text.Json.Serialization.JsonConstructor] @@ -1722,7 +2088,7 @@ public AddSourceFolderCommand(System.Guid @collectionId, string? @path, bool @sh } - [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "14.0.0.0 (NJsonSchema v11.0.0.0 (Newtonsoft.Json v13.0.0.0))")] + [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "14.0.7.0 (NJsonSchema v11.0.0.0 (Newtonsoft.Json v13.0.0.0))")] public partial class CollectionFile { [System.Text.Json.Serialization.JsonConstructor] @@ -1764,7 +2130,7 @@ public CollectionFile(System.Guid @collectionId, System.Guid @id, string? @md5, } - [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "14.0.0.0 (NJsonSchema v11.0.0.0 (Newtonsoft.Json v13.0.0.0))")] + [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "14.0.7.0 (NJsonSchema v11.0.0.0 (Newtonsoft.Json v13.0.0.0))")] public partial class CollectionFilesQuery { [System.Text.Json.Serialization.JsonConstructor] @@ -1806,7 +2172,7 @@ public CollectionFilesQuery(System.Collections.Generic.IReadOnlyCollection<Syste } - [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "14.0.0.0 (NJsonSchema v11.0.0.0 (Newtonsoft.Json v13.0.0.0))")] + [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "14.0.7.0 (NJsonSchema v11.0.0.0 (Newtonsoft.Json v13.0.0.0))")] public partial class CollectionResponse { [System.Text.Json.Serialization.JsonConstructor] @@ -1828,7 +2194,7 @@ public CollectionResponse(System.Guid @id, string? @name) } - [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "14.0.0.0 (NJsonSchema v11.0.0.0 (Newtonsoft.Json v13.0.0.0))")] + [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "14.0.7.0 (NJsonSchema v11.0.0.0 (Newtonsoft.Json v13.0.0.0))")] public partial class CreateCollectionCommand { [System.Text.Json.Serialization.JsonConstructor] @@ -1845,7 +2211,7 @@ public CreateCollectionCommand(string? @name) } - [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "14.0.0.0 (NJsonSchema v11.0.0.0 (Newtonsoft.Json v13.0.0.0))")] + [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "14.0.7.0 (NJsonSchema v11.0.0.0 (Newtonsoft.Json v13.0.0.0))")] public partial class DestinationFolderInfo { [System.Text.Json.Serialization.JsonConstructor] @@ -1897,7 +2263,7 @@ public DestinationFolderInfo(System.Guid @collectionId, string? @formatErrorSubf } - [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "14.0.0.0 (NJsonSchema v11.0.0.0 (Newtonsoft.Json v13.0.0.0))")] + [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "14.0.7.0 (NJsonSchema v11.0.0.0 (Newtonsoft.Json v13.0.0.0))")] public partial class DestinationFolderInfoOptionalResponse { [System.Text.Json.Serialization.JsonConstructor] @@ -1919,7 +2285,7 @@ public DestinationFolderInfoOptionalResponse(bool @hasValue, DestinationFolderIn } - [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "14.0.0.0 (NJsonSchema v11.0.0.0 (Newtonsoft.Json v13.0.0.0))")] + [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "14.0.7.0 (NJsonSchema v11.0.0.0 (Newtonsoft.Json v13.0.0.0))")] public partial class FilterCollectionFileHashesQuery { [System.Text.Json.Serialization.JsonConstructor] @@ -1936,7 +2302,7 @@ public FilterCollectionFileHashesQuery(System.Collections.Generic.IReadOnlyColle } - [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "14.0.0.0 (NJsonSchema v11.0.0.0 (Newtonsoft.Json v13.0.0.0))")] + [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "14.0.7.0 (NJsonSchema v11.0.0.0 (Newtonsoft.Json v13.0.0.0))")] public partial class SetDestinationFolderCommand { [System.Text.Json.Serialization.JsonConstructor] @@ -1983,7 +2349,7 @@ public SetDestinationFolderCommand(System.Guid @collectionId, string? @formatErr } - [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "14.0.0.0 (NJsonSchema v11.0.0.0 (Newtonsoft.Json v13.0.0.0))")] + [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "14.0.7.0 (NJsonSchema v11.0.0.0 (Newtonsoft.Json v13.0.0.0))")] public partial class SourceFolderInfo { [System.Text.Json.Serialization.JsonConstructor] @@ -2035,7 +2401,7 @@ public SourceFolderInfo(System.Guid @collectionId, System.Guid @id, string? @pat } - [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "14.0.0.0 (NJsonSchema v11.0.0.0 (Newtonsoft.Json v13.0.0.0))")] + [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "14.0.7.0 (NJsonSchema v11.0.0.0 (Newtonsoft.Json v13.0.0.0))")] public partial class UpdateSourceFolderCommand { [System.Text.Json.Serialization.JsonConstructor] @@ -2089,7 +2455,7 @@ public UpdateSourceFolderCommand(System.Guid @collectionId, string? @path, bool - [System.CodeDom.Compiler.GeneratedCode("NSwag", "14.0.0.0 (NJsonSchema v11.0.0.0 (Newtonsoft.Json v13.0.0.0))")] + [System.CodeDom.Compiler.GeneratedCode("NSwag", "14.0.7.0 (NJsonSchema v11.0.0.0 (Newtonsoft.Json v13.0.0.0))")] public partial class WebApiException : System.Exception { public int StatusCode { get; private set; } @@ -2112,7 +2478,7 @@ public override string ToString() } } - [System.CodeDom.Compiler.GeneratedCode("NSwag", "14.0.0.0 (NJsonSchema v11.0.0.0 (Newtonsoft.Json v13.0.0.0))")] + [System.CodeDom.Compiler.GeneratedCode("NSwag", "14.0.7.0 (NJsonSchema v11.0.0.0 (Newtonsoft.Json v13.0.0.0))")] public partial class WebApiException<TResult> : WebApiException { public TResult Result { get; private set; } @@ -2135,4 +2501,5 @@ public WebApiException(string message, int statusCode, string? response, System. #pragma warning restore 8073 #pragma warning restore 3016 #pragma warning restore 8603 -#pragma warning restore 8604 \ No newline at end of file +#pragma warning restore 8604 +#pragma warning restore 8625 \ No newline at end of file