Logging Enhancements (#1521)

* Recreated Kavita Logging with Serilog instead of Default. This needs to be move out of the appsettings now, to allow auto updater to patch.

* Refactored the code to be completely configured via Code rather than appsettings.json. This is a required step for Auto Updating.

* Added in the ability to send logs directly to the UI only for users on the log route. Stopping implementation as Alerts page will handle the rest of the implementation.

* Fixed up the backup service to not rely on Config from appsettings.json

* Tweaked the Logging levels available

* Moved everything over to File-scoped namespaces

* Moved everything over to File-scoped namespaces

* Code cleanup, removed an old migration and changed so debug logging doesn't print sensitive db data

* Removed dead code
This commit is contained in:
Joseph Milazzo 2022-09-12 19:25:48 -05:00 committed by GitHub
parent 9f715cc35f
commit d1a14f7e68
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
212 changed files with 16599 additions and 16834 deletions

View File

@ -1,8 +1,7 @@
namespace API.Benchmark namespace API.Benchmark;
public class ArchiveSerivceBenchmark
{ {
public class ArchiveSerivceBenchmark
{
// Benchmark to test default GetNumberOfPages from archive // Benchmark to test default GetNumberOfPages from archive
// vs a new method where I try to open the archive and return said stream // vs a new method where I try to open the archive and return said stream
}
} }

View File

@ -5,13 +5,13 @@ using System.Text.RegularExpressions;
using BenchmarkDotNet.Attributes; using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Order; using BenchmarkDotNet.Order;
namespace API.Benchmark namespace API.Benchmark;
[MemoryDiagnoser]
[Orderer(SummaryOrderPolicy.FastestToSlowest)]
[RankColumn]
public class ParserBenchmarks
{ {
[MemoryDiagnoser]
[Orderer(SummaryOrderPolicy.FastestToSlowest)]
[RankColumn]
public class ParserBenchmarks
{
private readonly IList<string> _names; private readonly IList<string> _names;
private static readonly Regex NormalizeRegex = new Regex(@"[^a-zA-Z0-9]", private static readonly Regex NormalizeRegex = new Regex(@"[^a-zA-Z0-9]",
@ -75,5 +75,4 @@ namespace API.Benchmark
} }
}
} }

View File

@ -1,15 +1,15 @@
using BenchmarkDotNet.Running; using BenchmarkDotNet.Running;
namespace API.Benchmark namespace API.Benchmark;
/// <summary>
/// To build this, cd into API.Benchmark directory and run
/// dotnet build -c Release
/// then copy the outputted dll
/// dotnet copied_string\API.Benchmark.dll
/// </summary>
public static class Program
{ {
/// <summary>
/// To build this, cd into API.Benchmark directory and run
/// dotnet build -c Release
/// then copy the outputted dll
/// dotnet copied_string\API.Benchmark.dll
/// </summary>
public static class Program
{
private static void Main(string[] args) private static void Main(string[] args)
{ {
//BenchmarkRunner.Run<ParseScannedFilesBenchmarks>(); //BenchmarkRunner.Run<ParseScannedFilesBenchmarks>();
@ -18,5 +18,4 @@ namespace API.Benchmark
BenchmarkRunner.Run<EpubBenchmark>(); BenchmarkRunner.Run<EpubBenchmark>();
} }
}
} }

View File

@ -6,16 +6,16 @@ using API.Extensions;
using BenchmarkDotNet.Attributes; using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Order; using BenchmarkDotNet.Order;
namespace API.Benchmark namespace API.Benchmark;
/// <summary>
/// This is used as a scratchpad for testing
/// </summary>
[MemoryDiagnoser]
[Orderer(SummaryOrderPolicy.FastestToSlowest)]
[RankColumn]
public class TestBenchmark
{ {
/// <summary>
/// This is used as a scratchpad for testing
/// </summary>
[MemoryDiagnoser]
[Orderer(SummaryOrderPolicy.FastestToSlowest)]
[RankColumn]
public class TestBenchmark
{
private static IEnumerable<VolumeDto> GenerateVolumes(int max) private static IEnumerable<VolumeDto> GenerateVolumes(int max)
{ {
var random = new Random(); var random = new Random();
@ -62,5 +62,4 @@ namespace API.Benchmark
SortSpecialChapters(volumes); SortSpecialChapters(volumes);
} }
}
} }

View File

@ -2,10 +2,10 @@
using API.Comparators; using API.Comparators;
using Xunit; using Xunit;
namespace API.Tests.Comparers namespace API.Tests.Comparers;
public class ChapterSortComparerTest
{ {
public class ChapterSortComparerTest
{
[Theory] [Theory]
[InlineData(new[] {1, 2, 0}, new[] {1, 2, 0})] [InlineData(new[] {1, 2, 0}, new[] {1, 2, 0})]
[InlineData(new[] {3, 1, 2}, new[] {1, 2, 3})] [InlineData(new[] {3, 1, 2}, new[] {1, 2, 3})]
@ -15,5 +15,4 @@ namespace API.Tests.Comparers
Assert.Equal(expected, input.OrderBy(f => f, new ChapterSortComparer()).ToArray()); Assert.Equal(expected, input.OrderBy(f => f, new ChapterSortComparer()).ToArray());
} }
}
} }

View File

@ -2,10 +2,10 @@
using API.Comparators; using API.Comparators;
using Xunit; using Xunit;
namespace API.Tests.Comparers namespace API.Tests.Comparers;
public class StringLogicalComparerTest
{ {
public class StringLogicalComparerTest
{
[Theory] [Theory]
[InlineData( [InlineData(
new[] {"x1.jpg", "x10.jpg", "x3.jpg", "x4.jpg", "x11.jpg"}, new[] {"x1.jpg", "x10.jpg", "x3.jpg", "x4.jpg", "x11.jpg"},
@ -30,5 +30,4 @@ namespace API.Tests.Comparers
i++; i++;
} }
} }
}
} }

View File

@ -1,10 +1,10 @@
using API.Helpers.Converters; using API.Helpers.Converters;
using Xunit; using Xunit;
namespace API.Tests.Converters namespace API.Tests.Converters;
public class CronConverterTests
{ {
public class CronConverterTests
{
[Theory] [Theory]
[InlineData("daily", "0 0 * * *")] [InlineData("daily", "0 0 * * *")]
[InlineData("disabled", "0 0 31 2 *")] [InlineData("disabled", "0 0 31 2 *")]
@ -15,5 +15,4 @@ namespace API.Tests.Converters
{ {
Assert.Equal(expected, CronConverter.ConvertToCronNotation(input)); Assert.Equal(expected, CronConverter.ConvertToCronNotation(input));
} }
}
} }

View File

@ -1,13 +1,13 @@
using API.Data; using API.Data;
using Xunit; using Xunit;
namespace API.Tests.Entities namespace API.Tests.Entities;
/// <summary>
/// Tests for <see cref="API.Entities.Series"/>
/// </summary>
public class SeriesTest
{ {
/// <summary>
/// Tests for <see cref="API.Entities.Series"/>
/// </summary>
public class SeriesTest
{
[Theory] [Theory]
[InlineData("Darker than Black")] [InlineData("Darker than Black")]
public void CreateSeries(string name) public void CreateSeries(string name)
@ -23,5 +23,4 @@ namespace API.Tests.Entities
Assert.Equal(name, series.OriginalName); Assert.Equal(name, series.OriginalName);
Assert.Equal(key, series.NormalizedName); Assert.Equal(key, series.NormalizedName);
} }
}
} }

View File

@ -6,10 +6,10 @@ using API.Extensions;
using API.Parser; using API.Parser;
using Xunit; using Xunit;
namespace API.Tests.Extensions namespace API.Tests.Extensions;
public class ChapterListExtensionsTests
{ {
public class ChapterListExtensionsTests
{
private static Chapter CreateChapter(string range, string number, MangaFile file, bool isSpecial) private static Chapter CreateChapter(string range, string number, MangaFile file, bool isSpecial)
{ {
return new Chapter() return new Chapter()
@ -141,5 +141,4 @@ namespace API.Tests.Extensions
#endregion #endregion
}
} }

View File

@ -4,10 +4,10 @@ using System.IO;
using API.Extensions; using API.Extensions;
using Xunit; using Xunit;
namespace API.Tests.Extensions namespace API.Tests.Extensions;
public class FileInfoExtensionsTests
{ {
public class FileInfoExtensionsTests
{
private static readonly string TestDirectory = Path.Join(Directory.GetCurrentDirectory(), "../../../Extensions/Test Data/"); private static readonly string TestDirectory = Path.Join(Directory.GetCurrentDirectory(), "../../../Extensions/Test Data/");
[Fact] [Fact]
@ -29,5 +29,4 @@ namespace API.Tests.Extensions
File.AppendAllLines(filepath, new[] { DateTime.Now.ToString(CultureInfo.InvariantCulture) }); File.AppendAllLines(filepath, new[] { DateTime.Now.ToString(CultureInfo.InvariantCulture) });
Assert.True(new FileInfo(filepath).HasFileBeenModifiedSince(date)); Assert.True(new FileInfo(filepath).HasFileBeenModifiedSince(date));
} }
}
} }

View File

@ -10,10 +10,10 @@ using Microsoft.Extensions.Logging;
using NSubstitute; using NSubstitute;
using Xunit; using Xunit;
namespace API.Tests.Extensions namespace API.Tests.Extensions;
public class ParserInfoListExtensions
{ {
public class ParserInfoListExtensions
{
private readonly IDefaultParser _defaultParser; private readonly IDefaultParser _defaultParser;
public ParserInfoListExtensions() public ParserInfoListExtensions()
{ {
@ -49,5 +49,4 @@ namespace API.Tests.Extensions
Assert.Equal(expectedHasInfo, infos.HasInfo(chapter)); Assert.Equal(expectedHasInfo, infos.HasInfo(chapter));
} }
}
} }

View File

@ -7,10 +7,10 @@ using API.Parser;
using API.Services.Tasks.Scanner; using API.Services.Tasks.Scanner;
using Xunit; using Xunit;
namespace API.Tests.Extensions namespace API.Tests.Extensions;
public class SeriesExtensionsTests
{ {
public class SeriesExtensionsTests
{
[Theory] [Theory]
[InlineData(new [] {"Darker than Black", "Darker Than Black", "Darker than Black"}, new [] {"Darker than Black"}, true)] [InlineData(new [] {"Darker than Black", "Darker Than Black", "Darker than Black"}, new [] {"Darker than Black"}, true)]
[InlineData(new [] {"Darker than Black", "Darker Than Black", "Darker than Black"}, new [] {"Darker_than_Black"}, true)] [InlineData(new [] {"Darker than Black", "Darker Than Black", "Darker than Black"}, new [] {"Darker_than_Black"}, true)]
@ -88,5 +88,4 @@ namespace API.Tests.Extensions
} }
}
} }

View File

@ -4,13 +4,13 @@ using API.Entities;
using API.Entities.Enums; using API.Entities.Enums;
using API.Entities.Metadata; using API.Entities.Metadata;
namespace API.Tests.Helpers namespace API.Tests.Helpers;
/// <summary>
/// Used to help quickly create DB entities for Unit Testing
/// </summary>
public static class EntityFactory
{ {
/// <summary>
/// Used to help quickly create DB entities for Unit Testing
/// </summary>
public static class EntityFactory
{
public static Series CreateSeries(string name) public static Series CreateSeries(string name)
{ {
return new Series() return new Series()
@ -79,5 +79,4 @@ namespace API.Tests.Helpers
Promoted = promoted Promoted = promoted
}; };
} }
}
} }

View File

@ -6,10 +6,10 @@ using API.Entities.Enums;
using API.Parser; using API.Parser;
using API.Services.Tasks.Scanner; using API.Services.Tasks.Scanner;
namespace API.Tests.Helpers namespace API.Tests.Helpers;
public static class ParserInfoFactory
{ {
public static class ParserInfoFactory
{
public static ParserInfo CreateParsedInfo(string series, string volumes, string chapters, string filename, bool isSpecial) public static ParserInfo CreateParsedInfo(string series, string volumes, string chapters, string filename, bool isSpecial)
{ {
return new ParserInfo() return new ParserInfo()
@ -69,5 +69,4 @@ namespace API.Tests.Helpers
} }
} }
}
} }

View File

@ -1,13 +1,13 @@
using System.IO; using System.IO;
namespace API.Tests.Helpers namespace API.Tests.Helpers;
/// <summary>
/// Given a -testcase.txt file, will generate a folder with fake archive or book files. These files are just renamed txt files.
/// <remarks>This currently is broken - you cannot create files from a unit test it seems</remarks>
/// </summary>
public static class TestCaseGenerator
{ {
/// <summary>
/// Given a -testcase.txt file, will generate a folder with fake archive or book files. These files are just renamed txt files.
/// <remarks>This currently is broken - you cannot create files from a unit test it seems</remarks>
/// </summary>
public static class TestCaseGenerator
{
public static string GenerateFiles(string directory, string fileToExpand) public static string GenerateFiles(string directory, string fileToExpand)
{ {
//var files = Directory.GetFiles(directory, fileToExpand); //var files = Directory.GetFiles(directory, fileToExpand);
@ -49,5 +49,4 @@ namespace API.Tests.Helpers
return newDirectory; return newDirectory;
} }
}
} }

View File

@ -1,9 +1,9 @@
using Xunit; using Xunit;
namespace API.Tests.Parser namespace API.Tests.Parser;
public class BookParserTests
{ {
public class BookParserTests
{
[Theory] [Theory]
[InlineData("Gifting The Wonderful World With Blessings! - 3 Side Stories [yuNS][Unknown]", "Gifting The Wonderful World With Blessings!")] [InlineData("Gifting The Wonderful World With Blessings! - 3 Side Stories [yuNS][Unknown]", "Gifting The Wonderful World With Blessings!")]
[InlineData("BBC Focus 00 The Science of Happiness 2nd Edition (2018)", "BBC Focus 00 The Science of Happiness 2nd Edition")] [InlineData("BBC Focus 00 The Science of Happiness 2nd Edition (2018)", "BBC Focus 00 The Science of Happiness 2nd Edition")]
@ -39,5 +39,4 @@ namespace API.Tests.Parser
// var actual = API.Parser.Parser.CssImportUrlRegex.Replace(input, "$1" + apiBase + "$2" + "$3"); // var actual = API.Parser.Parser.CssImportUrlRegex.Replace(input, "$1" + apiBase + "$2" + "$3");
// Assert.Equal(expected, actual); // Assert.Equal(expected, actual);
// } // }
}
} }

View File

@ -6,10 +6,10 @@ using NSubstitute;
using Xunit; using Xunit;
using Xunit.Abstractions; using Xunit.Abstractions;
namespace API.Tests.Parser namespace API.Tests.Parser;
public class ComicParserTests
{ {
public class ComicParserTests
{
private readonly ITestOutputHelper _testOutputHelper; private readonly ITestOutputHelper _testOutputHelper;
private readonly DefaultParser _defaultParser; private readonly DefaultParser _defaultParser;
@ -192,5 +192,4 @@ namespace API.Tests.Parser
{ {
Assert.Equal(expected, !string.IsNullOrEmpty(API.Services.Tasks.Scanner.Parser.Parser.ParseComicSpecial(input))); Assert.Equal(expected, !string.IsNullOrEmpty(API.Services.Tasks.Scanner.Parser.Parser.ParseComicSpecial(input)));
} }
}
} }

View File

@ -2,10 +2,10 @@ using API.Entities.Enums;
using Xunit; using Xunit;
using Xunit.Abstractions; using Xunit.Abstractions;
namespace API.Tests.Parser namespace API.Tests.Parser;
public class MangaParserTests
{ {
public class MangaParserTests
{
private readonly ITestOutputHelper _testOutputHelper; private readonly ITestOutputHelper _testOutputHelper;
public MangaParserTests(ITestOutputHelper testOutputHelper) public MangaParserTests(ITestOutputHelper testOutputHelper)
@ -317,5 +317,4 @@ namespace API.Tests.Parser
}
} }

View File

@ -2,10 +2,10 @@
using API.Parser; using API.Parser;
using Xunit; using Xunit;
namespace API.Tests.Parser namespace API.Tests.Parser;
public class ParserInfoTests
{ {
public class ParserInfoTests
{
[Fact] [Fact]
public void MergeFromTest() public void MergeFromTest()
{ {
@ -106,5 +106,4 @@ namespace API.Tests.Parser
Assert.Equal(expected.IsSpecial, actual.IsSpecial); Assert.Equal(expected.IsSpecial, actual.IsSpecial);
Assert.Equal(expected.FullFilePath, actual.FullFilePath); Assert.Equal(expected.FullFilePath, actual.FullFilePath);
} }
}
} }

View File

@ -2,10 +2,10 @@ using System.Linq;
using Xunit; using Xunit;
using static API.Services.Tasks.Scanner.Parser.Parser; using static API.Services.Tasks.Scanner.Parser.Parser;
namespace API.Tests.Parser namespace API.Tests.Parser;
public class ParserTests
{ {
public class ParserTests
{
[Theory] [Theory]
[InlineData("Joe Shmo, Green Blue", "Joe Shmo, Green Blue")] [InlineData("Joe Shmo, Green Blue", "Joe Shmo, Green Blue")]
[InlineData("Shmo, Joe", "Shmo, Joe")] [InlineData("Shmo, Joe", "Shmo, Joe")]
@ -230,5 +230,4 @@ namespace API.Tests.Parser
{ {
Assert.Equal(expected, NormalizePath(inputPath)); Assert.Equal(expected, NormalizePath(inputPath));
} }
}
} }

View File

@ -14,10 +14,10 @@ using NSubstitute.Extensions;
using Xunit; using Xunit;
using Xunit.Abstractions; using Xunit.Abstractions;
namespace API.Tests.Services namespace API.Tests.Services;
public class ArchiveServiceTests
{ {
public class ArchiveServiceTests
{
private readonly ITestOutputHelper _testOutputHelper; private readonly ITestOutputHelper _testOutputHelper;
private readonly ArchiveService _archiveService; private readonly ArchiveService _archiveService;
private readonly ILogger<ArchiveService> _logger = Substitute.For<ILogger<ArchiveService>>(); private readonly ILogger<ArchiveService> _logger = Substitute.For<ILogger<ArchiveService>>();
@ -326,5 +326,4 @@ namespace API.Tests.Services
} }
#endregion #endregion
}
} }

View File

@ -135,17 +135,9 @@ public class BackupServiceTests
filesystem.AddFile($"{LogDirectory}kavita1.log", new MockFileData("")); filesystem.AddFile($"{LogDirectory}kavita1.log", new MockFileData(""));
var ds = new DirectoryService(Substitute.For<ILogger<DirectoryService>>(), filesystem); var ds = new DirectoryService(Substitute.For<ILogger<DirectoryService>>(), filesystem);
var inMemorySettings = new Dictionary<string, string> { var backupService = new BackupService(_logger, _unitOfWork, ds, _messageHub);
{"Logging:File:Path", "config/logs/kavita.log"},
{"Logging:File:MaxRollingFiles", "0"},
};
IConfiguration configuration = new ConfigurationBuilder()
.AddInMemoryCollection(inMemorySettings)
.Build();
var backupService = new BackupService(_logger, _unitOfWork, ds, configuration, _messageHub); var backupLogFiles = backupService.GetLogFiles(false).ToList();
var backupLogFiles = backupService.GetLogFiles(0, LogDirectory).ToList();
Assert.Single(backupLogFiles); Assert.Single(backupLogFiles);
Assert.Equal(API.Services.Tasks.Scanner.Parser.Parser.NormalizePath($"{LogDirectory}kavita.log"), API.Services.Tasks.Scanner.Parser.Parser.NormalizePath(backupLogFiles.First())); Assert.Equal(API.Services.Tasks.Scanner.Parser.Parser.NormalizePath($"{LogDirectory}kavita.log"), API.Services.Tasks.Scanner.Parser.Parser.NormalizePath(backupLogFiles.First()));
} }
@ -155,20 +147,12 @@ public class BackupServiceTests
{ {
var filesystem = CreateFileSystem(); var filesystem = CreateFileSystem();
filesystem.AddFile($"{LogDirectory}kavita.log", new MockFileData("")); filesystem.AddFile($"{LogDirectory}kavita.log", new MockFileData(""));
filesystem.AddFile($"{LogDirectory}kavita1.log", new MockFileData("")); filesystem.AddFile($"{LogDirectory}kavita20200213.log", new MockFileData(""));
var ds = new DirectoryService(Substitute.For<ILogger<DirectoryService>>(), filesystem); var ds = new DirectoryService(Substitute.For<ILogger<DirectoryService>>(), filesystem);
var inMemorySettings = new Dictionary<string, string> { var backupService = new BackupService(_logger, _unitOfWork, ds, _messageHub);
{"Logging:File:Path", "config/logs/kavita.log"},
{"Logging:File:MaxRollingFiles", "1"},
};
IConfiguration configuration = new ConfigurationBuilder()
.AddInMemoryCollection(inMemorySettings)
.Build();
var backupService = new BackupService(_logger, _unitOfWork, ds, configuration, _messageHub); var backupLogFiles = backupService.GetLogFiles().Select(API.Services.Tasks.Scanner.Parser.Parser.NormalizePath).ToList();
var backupLogFiles = backupService.GetLogFiles(1, LogDirectory).Select(API.Services.Tasks.Scanner.Parser.Parser.NormalizePath).ToList();
Assert.NotEmpty(backupLogFiles.Where(file => file.Equals(API.Services.Tasks.Scanner.Parser.Parser.NormalizePath($"{LogDirectory}kavita.log")) || file.Equals(API.Services.Tasks.Scanner.Parser.Parser.NormalizePath($"{LogDirectory}kavita1.log")))); Assert.NotEmpty(backupLogFiles.Where(file => file.Equals(API.Services.Tasks.Scanner.Parser.Parser.NormalizePath($"{LogDirectory}kavita.log")) || file.Equals(API.Services.Tasks.Scanner.Parser.Parser.NormalizePath($"{LogDirectory}kavita1.log"))));
} }

View File

@ -5,10 +5,10 @@ using Microsoft.Extensions.Logging;
using NSubstitute; using NSubstitute;
using Xunit; using Xunit;
namespace API.Tests.Services namespace API.Tests.Services;
public class BookServiceTests
{ {
public class BookServiceTests
{
private readonly IBookService _bookService; private readonly IBookService _bookService;
private readonly ILogger<BookService> _logger = Substitute.For<ILogger<BookService>>(); private readonly ILogger<BookService> _logger = Substitute.For<ILogger<BookService>>();
@ -54,5 +54,4 @@ namespace API.Tests.Services
Assert.Equal("Roger Starbuck,Junya Inoue", comicInfo.Writer); Assert.Equal("Roger Starbuck,Junya Inoue", comicInfo.Writer);
} }
}
} }

View File

@ -20,10 +20,10 @@ using Microsoft.Extensions.Logging;
using NSubstitute; using NSubstitute;
using Xunit; using Xunit;
namespace API.Tests.Services namespace API.Tests.Services;
internal class MockReadingItemServiceForCacheService : IReadingItemService
{ {
internal class MockReadingItemServiceForCacheService : IReadingItemService
{
private readonly DirectoryService _directoryService; private readonly DirectoryService _directoryService;
public MockReadingItemServiceForCacheService(DirectoryService directoryService) public MockReadingItemServiceForCacheService(DirectoryService directoryService)
@ -60,9 +60,9 @@ namespace API.Tests.Services
{ {
throw new System.NotImplementedException(); throw new System.NotImplementedException();
} }
} }
public class CacheServiceTests public class CacheServiceTests
{ {
private readonly ILogger<CacheService> _logger = Substitute.For<ILogger<CacheService>>(); private readonly ILogger<CacheService> _logger = Substitute.For<ILogger<CacheService>>();
private readonly IUnitOfWork _unitOfWork; private readonly IUnitOfWork _unitOfWork;
private readonly IHubContext<MessageHub> _messageHub = Substitute.For<IHubContext<MessageHub>>(); private readonly IHubContext<MessageHub> _messageHub = Substitute.For<IHubContext<MessageHub>>();
@ -516,5 +516,4 @@ namespace API.Tests.Services
// } // }
#endregion #endregion
}
} }

View File

@ -10,11 +10,10 @@ using Microsoft.Extensions.Logging;
using NSubstitute; using NSubstitute;
using Xunit; using Xunit;
namespace API.Tests.Services namespace API.Tests.Services;
{
public class DirectoryServiceTests public class DirectoryServiceTests
{ {
private readonly ILogger<DirectoryService> _logger = Substitute.For<ILogger<DirectoryService>>(); private readonly ILogger<DirectoryService> _logger = Substitute.For<ILogger<DirectoryService>>();
@ -996,5 +995,4 @@ namespace API.Tests.Services
} }
#endregion #endregion
}
} }

View File

@ -5,10 +5,10 @@ using System.IO.Abstractions.TestingHelpers;
using API.Helpers; using API.Helpers;
using API.Services; using API.Services;
namespace API.Tests.Services namespace API.Tests.Services;
public class MetadataServiceTests
{ {
public class MetadataServiceTests
{
private readonly string _testDirectory = Path.Join(Directory.GetCurrentDirectory(), "../../../Services/Test Data/ArchiveService/Archives"); private readonly string _testDirectory = Path.Join(Directory.GetCurrentDirectory(), "../../../Services/Test Data/ArchiveService/Archives");
private const string TestCoverImageFile = "thumbnail.jpg"; private const string TestCoverImageFile = "thumbnail.jpg";
private const string TestCoverArchive = @"c:\file in folder.zip"; private const string TestCoverArchive = @"c:\file in folder.zip";
@ -38,5 +38,4 @@ namespace API.Tests.Services
var fileService = new FileService(fileSystem); var fileService = new FileService(fileSystem);
_cacheHelper = new CacheHelper(fileService); _cacheHelper = new CacheHelper(fileService);
} }
}
} }

View File

@ -9,10 +9,10 @@ using API.Services.Tasks.Scanner;
using API.Tests.Helpers; using API.Tests.Helpers;
using Xunit; using Xunit;
namespace API.Tests.Services namespace API.Tests.Services;
public class ScannerServiceTests
{ {
public class ScannerServiceTests
{
[Fact] [Fact]
public void FindSeriesNotOnDisk_Should_Remove1() public void FindSeriesNotOnDisk_Should_Remove1()
{ {
@ -128,5 +128,4 @@ namespace API.Tests.Services
// TODO: I want a test for UpdateSeries where if I have chapter 10 and now it's mapping into Vol 2 Chapter 10, // TODO: I want a test for UpdateSeries where if I have chapter 10 and now it's mapping into Vol 2 Chapter 10,
// if I can do it without deleting the underlying chapter (aka id change) // if I can do it without deleting the underlying chapter (aka id change)
}
} }

View File

@ -73,6 +73,14 @@
<PackageReference Include="NetVips" Version="2.2.0" /> <PackageReference Include="NetVips" Version="2.2.0" />
<PackageReference Include="NetVips.Native" Version="8.13.0" /> <PackageReference Include="NetVips.Native" Version="8.13.0" />
<PackageReference Include="NReco.Logging.File" Version="1.1.5" /> <PackageReference Include="NReco.Logging.File" Version="1.1.5" />
<PackageReference Include="Serilog" Version="2.11.0" />
<PackageReference Include="Serilog.AspNetCore" Version="6.0.1" />
<PackageReference Include="Serilog.Extensions.Hosting" Version="5.0.1" />
<PackageReference Include="Serilog.Settings.Configuration" Version="3.3.0" />
<PackageReference Include="Serilog.Sinks.AspNetCore.SignalR" Version="0.4.0" />
<PackageReference Include="Serilog.Sinks.Console" Version="4.0.1" />
<PackageReference Include="Serilog.Sinks.File" Version="5.0.0" />
<PackageReference Include="Serilog.Sinks.SignalR.Core" Version="0.1.2" />
<PackageReference Include="SharpCompress" Version="0.32.2" /> <PackageReference Include="SharpCompress" Version="0.32.2" />
<PackageReference Include="SixLabors.ImageSharp" Version="2.1.3" /> <PackageReference Include="SixLabors.ImageSharp" Version="2.1.3" />
<PackageReference Include="SonarAnalyzer.CSharp" Version="8.43.0.51858"> <PackageReference Include="SonarAnalyzer.CSharp" Version="8.43.0.51858">

View File

@ -1,10 +1,10 @@
namespace API.Archive namespace API.Archive;
/// <summary>
/// Represents which library should handle opening this library
/// </summary>
public enum ArchiveLibrary
{ {
/// <summary>
/// Represents which library should handle opening this library
/// </summary>
public enum ArchiveLibrary
{
/// <summary> /// <summary>
/// The underlying archive cannot be opened /// The underlying archive cannot be opened
/// </summary> /// </summary>
@ -17,5 +17,4 @@
/// The underlying archive can be opened by default .NET /// The underlying archive can be opened by default .NET
/// </summary> /// </summary>
Default = 2 Default = 2
}
} }

View File

@ -1,12 +1,12 @@
using System.Collections.Generic; using System.Collections.Generic;
namespace API.Comparators namespace API.Comparators;
/// <summary>
/// Sorts chapters based on their Number. Uses natural ordering of doubles.
/// </summary>
public class ChapterSortComparer : IComparer<double>
{ {
/// <summary>
/// Sorts chapters based on their Number. Uses natural ordering of doubles.
/// </summary>
public class ChapterSortComparer : IComparer<double>
{
/// <summary> /// <summary>
/// Normal sort for 2 doubles. 0 always comes last /// Normal sort for 2 doubles. 0 always comes last
/// </summary> /// </summary>
@ -25,17 +25,17 @@ namespace API.Comparators
} }
public static readonly ChapterSortComparer Default = new ChapterSortComparer(); public static readonly ChapterSortComparer Default = new ChapterSortComparer();
} }
/// <summary> /// <summary>
/// This is a special case comparer used exclusively for sorting chapters within a single Volume for reading order. /// This is a special case comparer used exclusively for sorting chapters within a single Volume for reading order.
/// <example> /// <example>
/// Volume 10 has "Series - Vol 10" and "Series - Vol 10 Chapter 81". In this case, for reading order, the order is Vol 10, Vol 10 Chapter 81. /// Volume 10 has "Series - Vol 10" and "Series - Vol 10 Chapter 81". In this case, for reading order, the order is Vol 10, Vol 10 Chapter 81.
/// This is represented by Chapter 0, Chapter 81. /// This is represented by Chapter 0, Chapter 81.
/// </example> /// </example>
/// </summary> /// </summary>
public class ChapterSortComparerZeroFirst : IComparer<double> public class ChapterSortComparerZeroFirst : IComparer<double>
{ {
public int Compare(double x, double y) public int Compare(double x, double y)
{ {
if (x == 0.0 && y == 0.0) return 0; if (x == 0.0 && y == 0.0) return 0;
@ -48,10 +48,10 @@ namespace API.Comparators
} }
public static readonly ChapterSortComparerZeroFirst Default = new ChapterSortComparerZeroFirst(); public static readonly ChapterSortComparerZeroFirst Default = new ChapterSortComparerZeroFirst();
} }
public class SortComparerZeroLast : IComparer<double> public class SortComparerZeroLast : IComparer<double>
{ {
public int Compare(double x, double y) public int Compare(double x, double y)
{ {
if (x == 0.0 && y == 0.0) return 0; if (x == 0.0 && y == 0.0) return 0;
@ -62,5 +62,4 @@ namespace API.Comparators
return x.CompareTo(y); return x.CompareTo(y);
} }
}
} }

View File

@ -1,9 +1,9 @@
using System.Collections; using System.Collections;
namespace API.Comparators namespace API.Comparators;
public class NumericComparer : IComparer
{ {
public class NumericComparer : IComparer
{
public int Compare(object x, object y) public int Compare(object x, object y)
{ {
@ -13,5 +13,4 @@ namespace API.Comparators
} }
return -1; return -1;
} }
}
} }

View File

@ -4,10 +4,10 @@
using static System.Char; using static System.Char;
namespace API.Comparators namespace API.Comparators;
public static class StringLogicalComparer
{ {
public static class StringLogicalComparer
{
public static int Compare(string s1, string s2) public static int Compare(string s1, string s2)
{ {
//get rid of special cases //get rid of special cases
@ -126,5 +126,4 @@ namespace API.Comparators
if(end >= s.Length) break; if(end >= s.Length) break;
} }
} }
}
} }

View File

@ -1,12 +1,12 @@
using System.Collections.Immutable; using System.Collections.Immutable;
namespace API.Constants namespace API.Constants;
/// <summary>
/// Role-based Security
/// </summary>
public static class PolicyConstants
{ {
/// <summary>
/// Role-based Security
/// </summary>
public static class PolicyConstants
{
/// <summary> /// <summary>
/// Admin User. Has all privileges /// Admin User. Has all privileges
/// </summary> /// </summary>
@ -30,5 +30,4 @@ namespace API.Constants
public static readonly ImmutableArray<string> ValidRoles = public static readonly ImmutableArray<string> ValidRoles =
ImmutableArray.Create(AdminRole, PlebRole, DownloadRole, ChangePasswordRole, BookmarkRole); ImmutableArray.Create(AdminRole, PlebRole, DownloadRole, ChangePasswordRole, BookmarkRole);
}
} }

View File

@ -26,13 +26,13 @@ using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
namespace API.Controllers namespace API.Controllers;
/// <summary>
/// All Account matters
/// </summary>
public class AccountController : BaseApiController
{ {
/// <summary>
/// All Account matters
/// </summary>
public class AccountController : BaseApiController
{
private readonly UserManager<AppUser> _userManager; private readonly UserManager<AppUser> _userManager;
private readonly SignInManager<AppUser> _signInManager; private readonly SignInManager<AppUser> _signInManager;
private readonly ITokenService _tokenService; private readonly ITokenService _tokenService;
@ -773,5 +773,4 @@ namespace API.Controllers
return false; return false;
} }
}
} }

View File

@ -4,10 +4,10 @@ using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Identity; using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
namespace API.Controllers namespace API.Controllers;
public class AdminController : BaseApiController
{ {
public class AdminController : BaseApiController
{
private readonly UserManager<AppUser> _userManager; private readonly UserManager<AppUser> _userManager;
public AdminController(UserManager<AppUser> userManager) public AdminController(UserManager<AppUser> userManager)
@ -26,5 +26,4 @@ namespace API.Controllers
var users = await _userManager.GetUsersInRoleAsync("Admin"); var users = await _userManager.GetUsersInRoleAsync("Admin");
return users.Count > 0; return users.Count > 0;
} }
}
} }

View File

@ -1,12 +1,11 @@
using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
namespace API.Controllers namespace API.Controllers;
[ApiController]
[Route("api/[controller]")]
[Authorize]
public class BaseApiController : ControllerBase
{ {
[ApiController]
[Route("api/[controller]")]
[Authorize]
public class BaseApiController : ControllerBase
{
}
} }

View File

@ -13,10 +13,10 @@ using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using VersOne.Epub; using VersOne.Epub;
namespace API.Controllers namespace API.Controllers;
public class BookController : BaseApiController
{ {
public class BookController : BaseApiController
{
private readonly IBookService _bookService; private readonly IBookService _bookService;
private readonly IUnitOfWork _unitOfWork; private readonly IUnitOfWork _unitOfWork;
private readonly ICacheService _cacheService; private readonly ICacheService _cacheService;
@ -159,5 +159,4 @@ namespace API.Controllers
} }
} }
}
} }

View File

@ -11,13 +11,13 @@ using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.SignalR; using Microsoft.AspNetCore.SignalR;
namespace API.Controllers namespace API.Controllers;
/// <summary>
/// APIs for Collections
/// </summary>
public class CollectionController : BaseApiController
{ {
/// <summary>
/// APIs for Collections
/// </summary>
public class CollectionController : BaseApiController
{
private readonly IUnitOfWork _unitOfWork; private readonly IUnitOfWork _unitOfWork;
private readonly IEventHub _eventHub; private readonly IEventHub _eventHub;
@ -188,5 +188,4 @@ namespace API.Controllers
return BadRequest("Something went wrong. Please try again."); return BadRequest("Something went wrong. Please try again.");
} }
}
} }

View File

@ -16,14 +16,14 @@ using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
namespace API.Controllers namespace API.Controllers;
/// <summary>
/// All APIs related to downloading entities from the system. Requires Download Role or Admin Role.
/// </summary>
[Authorize(Policy="RequireDownloadRole")]
public class DownloadController : BaseApiController
{ {
/// <summary>
/// All APIs related to downloading entities from the system. Requires Download Role or Admin Role.
/// </summary>
[Authorize(Policy="RequireDownloadRole")]
public class DownloadController : BaseApiController
{
private readonly IUnitOfWork _unitOfWork; private readonly IUnitOfWork _unitOfWork;
private readonly IArchiveService _archiveService; private readonly IArchiveService _archiveService;
private readonly IDirectoryService _directoryService; private readonly IDirectoryService _directoryService;
@ -221,5 +221,4 @@ namespace API.Controllers
return PhysicalFile(filePath, DefaultContentType, filename, true); return PhysicalFile(filePath, DefaultContentType, filename, true);
} }
}
} }

View File

@ -7,14 +7,14 @@ using API.Services;
using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
namespace API.Controllers namespace API.Controllers;
/// <summary>
/// Responsible for servicing up images stored in Kavita for entities
/// </summary>
[AllowAnonymous]
public class ImageController : BaseApiController
{ {
/// <summary>
/// Responsible for servicing up images stored in Kavita for entities
/// </summary>
[AllowAnonymous]
public class ImageController : BaseApiController
{
private readonly IUnitOfWork _unitOfWork; private readonly IUnitOfWork _unitOfWork;
private readonly IDirectoryService _directoryService; private readonly IDirectoryService _directoryService;
@ -149,5 +149,4 @@ namespace API.Controllers
return PhysicalFile(path, "image/" + format, _directoryService.FileSystem.Path.GetFileName(path)); return PhysicalFile(path, "image/" + format, _directoryService.FileSystem.Path.GetFileName(path));
} }
}
} }

View File

@ -22,11 +22,11 @@ using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using TaskScheduler = API.Services.TaskScheduler; using TaskScheduler = API.Services.TaskScheduler;
namespace API.Controllers namespace API.Controllers;
[Authorize]
public class LibraryController : BaseApiController
{ {
[Authorize]
public class LibraryController : BaseApiController
{
private readonly IDirectoryService _directoryService; private readonly IDirectoryService _directoryService;
private readonly ILogger<LibraryController> _logger; private readonly ILogger<LibraryController> _logger;
private readonly IMapper _mapper; private readonly IMapper _mapper;
@ -340,5 +340,4 @@ namespace API.Controllers
{ {
return Ok(await _unitOfWork.LibraryRepository.GetLibraryTypeAsync(libraryId)); return Ok(await _unitOfWork.LibraryRepository.GetLibraryTypeAsync(libraryId));
} }
}
} }

View File

@ -7,10 +7,10 @@ using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
namespace API.Controllers namespace API.Controllers;
public class PluginController : BaseApiController
{ {
public class PluginController : BaseApiController
{
private readonly IUnitOfWork _unitOfWork; private readonly IUnitOfWork _unitOfWork;
private readonly ITokenService _tokenService; private readonly ITokenService _tokenService;
private readonly ILogger<PluginController> _logger; private readonly ILogger<PluginController> _logger;
@ -46,5 +46,4 @@ namespace API.Controllers
ApiKey = user.ApiKey, ApiKey = user.ApiKey,
}; };
} }
}
} }

View File

@ -17,13 +17,13 @@ using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
namespace API.Controllers namespace API.Controllers;
/// <summary>
/// For all things regarding reading, mainly focusing on non-Book related entities
/// </summary>
public class ReaderController : BaseApiController
{ {
/// <summary>
/// For all things regarding reading, mainly focusing on non-Book related entities
/// </summary>
public class ReaderController : BaseApiController
{
private readonly ICacheService _cacheService; private readonly ICacheService _cacheService;
private readonly IUnitOfWork _unitOfWork; private readonly IUnitOfWork _unitOfWork;
private readonly ILogger<ReaderController> _logger; private readonly ILogger<ReaderController> _logger;
@ -768,5 +768,4 @@ namespace API.Controllers
return _readerService.GetTimeEstimate(0, pagesLeft, false); return _readerService.GetTimeEstimate(0, pagesLeft, false);
} }
}
} }

View File

@ -13,11 +13,11 @@ using API.SignalR;
using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
namespace API.Controllers namespace API.Controllers;
[Authorize]
public class ReadingListController : BaseApiController
{ {
[Authorize]
public class ReadingListController : BaseApiController
{
private readonly IUnitOfWork _unitOfWork; private readonly IUnitOfWork _unitOfWork;
private readonly IEventHub _eventHub; private readonly IEventHub _eventHub;
private readonly IReadingListService _readingListService; private readonly IReadingListService _readingListService;
@ -491,5 +491,4 @@ namespace API.Controllers
return Ok(-1); return Ok(-1);
} }
}
} }

View File

@ -19,10 +19,10 @@ using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
namespace API.Controllers namespace API.Controllers;
public class SeriesController : BaseApiController
{ {
public class SeriesController : BaseApiController
{
private readonly ILogger<SeriesController> _logger; private readonly ILogger<SeriesController> _logger;
private readonly ITaskScheduler _taskScheduler; private readonly ITaskScheduler _taskScheduler;
private readonly IUnitOfWork _unitOfWork; private readonly IUnitOfWork _unitOfWork;
@ -494,5 +494,4 @@ namespace API.Controllers
_unitOfWork.SeriesRepository.Update(series); _unitOfWork.SeriesRepository.Update(series);
} }
} }
}
} }

View File

@ -8,6 +8,7 @@ using API.DTOs.Jobs;
using API.DTOs.Stats; using API.DTOs.Stats;
using API.DTOs.Update; using API.DTOs.Update;
using API.Extensions; using API.Extensions;
using API.Logging;
using API.Services; using API.Services;
using API.Services.Tasks; using API.Services.Tasks;
using Hangfire; using Hangfire;
@ -20,14 +21,13 @@ using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using TaskScheduler = System.Threading.Tasks.TaskScheduler; using TaskScheduler = System.Threading.Tasks.TaskScheduler;
namespace API.Controllers namespace API.Controllers;
[Authorize(Policy = "RequireAdminRole")]
public class ServerController : BaseApiController
{ {
[Authorize(Policy = "RequireAdminRole")]
public class ServerController : BaseApiController
{
private readonly IHostApplicationLifetime _applicationLifetime; private readonly IHostApplicationLifetime _applicationLifetime;
private readonly ILogger<ServerController> _logger; private readonly ILogger<ServerController> _logger;
private readonly IConfiguration _config;
private readonly IBackupService _backupService; private readonly IBackupService _backupService;
private readonly IArchiveService _archiveService; private readonly IArchiveService _archiveService;
private readonly IVersionUpdaterService _versionUpdaterService; private readonly IVersionUpdaterService _versionUpdaterService;
@ -36,13 +36,12 @@ namespace API.Controllers
private readonly IEmailService _emailService; private readonly IEmailService _emailService;
private readonly IBookmarkService _bookmarkService; private readonly IBookmarkService _bookmarkService;
public ServerController(IHostApplicationLifetime applicationLifetime, ILogger<ServerController> logger, IConfiguration config, public ServerController(IHostApplicationLifetime applicationLifetime, ILogger<ServerController> logger,
IBackupService backupService, IArchiveService archiveService, IVersionUpdaterService versionUpdaterService, IStatsService statsService, IBackupService backupService, IArchiveService archiveService, IVersionUpdaterService versionUpdaterService, IStatsService statsService,
ICleanupService cleanupService, IEmailService emailService, IBookmarkService bookmarkService) ICleanupService cleanupService, IEmailService emailService, IBookmarkService bookmarkService)
{ {
_applicationLifetime = applicationLifetime; _applicationLifetime = applicationLifetime;
_logger = logger; _logger = logger;
_config = config;
_backupService = backupService; _backupService = backupService;
_archiveService = archiveService; _archiveService = archiveService;
_versionUpdaterService = versionUpdaterService; _versionUpdaterService = versionUpdaterService;
@ -114,7 +113,7 @@ namespace API.Controllers
[HttpGet("logs")] [HttpGet("logs")]
public ActionResult GetLogs() public ActionResult GetLogs()
{ {
var files = _backupService.GetLogFiles(_config.GetMaxRollingFiles(), _config.GetLoggingFileName()); var files = _backupService.GetLogFiles();
try try
{ {
var zipPath = _archiveService.CreateZipForDownload(files, "logs"); var zipPath = _archiveService.CreateZipForDownload(files, "logs");
@ -155,7 +154,7 @@ namespace API.Controllers
[HttpGet("jobs")] [HttpGet("jobs")]
public ActionResult<IEnumerable<JobDto>> GetJobs() public ActionResult<IEnumerable<JobDto>> GetJobs()
{ {
var recurringJobs = Hangfire.JobStorage.Current.GetConnection().GetRecurringJobs().Select( var recurringJobs = JobStorage.Current.GetConnection().GetRecurringJobs().Select(
dto => dto =>
new JobDto() { new JobDto() {
Id = dto.Id, Id = dto.Id,
@ -170,5 +169,4 @@ namespace API.Controllers
return Ok(recurringJobs); return Ok(recurringJobs);
} }
}
} }

View File

@ -9,6 +9,7 @@ using API.DTOs.Settings;
using API.Entities.Enums; using API.Entities.Enums;
using API.Extensions; using API.Extensions;
using API.Helpers.Converters; using API.Helpers.Converters;
using API.Logging;
using API.Services; using API.Services;
using API.Services.Tasks.Scanner; using API.Services.Tasks.Scanner;
using AutoMapper; using AutoMapper;
@ -20,10 +21,10 @@ using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
namespace API.Controllers namespace API.Controllers;
public class SettingsController : BaseApiController
{ {
public class SettingsController : BaseApiController
{
private readonly ILogger<SettingsController> _logger; private readonly ILogger<SettingsController> _logger;
private readonly IUnitOfWork _unitOfWork; private readonly IUnitOfWork _unitOfWork;
private readonly ITaskScheduler _taskScheduler; private readonly ITaskScheduler _taskScheduler;
@ -159,7 +160,7 @@ namespace API.Controllers
if (setting.Key == ServerSettingKey.LoggingLevel && updateSettingsDto.LoggingLevel + string.Empty != setting.Value) if (setting.Key == ServerSettingKey.LoggingLevel && updateSettingsDto.LoggingLevel + string.Empty != setting.Value)
{ {
setting.Value = updateSettingsDto.LoggingLevel + string.Empty; setting.Value = updateSettingsDto.LoggingLevel + string.Empty;
Configuration.LogLevel = updateSettingsDto.LoggingLevel; LogLevelOptions.SwitchLogLevel(updateSettingsDto.LoggingLevel);
_unitOfWork.SettingsRepository.Update(setting); _unitOfWork.SettingsRepository.Update(setting);
} }
@ -300,5 +301,4 @@ namespace API.Controllers
var settingsDto = await _unitOfWork.SettingsRepository.GetSettingsDtoAsync(); var settingsDto = await _unitOfWork.SettingsRepository.GetSettingsDtoAsync();
return Ok(settingsDto.EnableOpds); return Ok(settingsDto.EnableOpds);
} }
}
} }

View File

@ -12,14 +12,14 @@ using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using NetVips; using NetVips;
namespace API.Controllers namespace API.Controllers;
/// <summary>
///
/// </summary>
[Authorize(Policy = "RequireAdminRole")]
public class UploadController : BaseApiController
{ {
/// <summary>
///
/// </summary>
[Authorize(Policy = "RequireAdminRole")]
public class UploadController : BaseApiController
{
private readonly IUnitOfWork _unitOfWork; private readonly IUnitOfWork _unitOfWork;
private readonly IImageService _imageService; private readonly IImageService _imageService;
private readonly ILogger<UploadController> _logger; private readonly ILogger<UploadController> _logger;
@ -305,5 +305,4 @@ namespace API.Controllers
return BadRequest("Unable to resetting cover lock for Chapter"); return BadRequest("Unable to resetting cover lock for Chapter");
} }
}
} }

View File

@ -13,11 +13,11 @@ using AutoMapper;
using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
namespace API.Controllers namespace API.Controllers;
[Authorize]
public class UsersController : BaseApiController
{ {
[Authorize]
public class UsersController : BaseApiController
{
private readonly IUnitOfWork _unitOfWork; private readonly IUnitOfWork _unitOfWork;
private readonly IMapper _mapper; private readonly IMapper _mapper;
private readonly IEventHub _eventHub; private readonly IEventHub _eventHub;
@ -120,5 +120,4 @@ namespace API.Controllers
await _unitOfWork.UserRepository.GetPreferencesAsync(User.GetUsername())); await _unitOfWork.UserRepository.GetPreferencesAsync(User.GetUsername()));
} }
}
} }

View File

@ -1,8 +1,7 @@
namespace API.DTOs.Account namespace API.DTOs.Account;
public class LoginDto
{ {
public class LoginDto
{
public string Username { get; init; } public string Username { get; init; }
public string Password { get; set; } public string Password { get; set; }
}
} }

View File

@ -1,9 +1,9 @@
using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations;
namespace API.DTOs.Account namespace API.DTOs.Account;
public class ResetPasswordDto
{ {
public class ResetPasswordDto
{
/// <summary> /// <summary>
/// The Username of the User /// The Username of the User
/// </summary> /// </summary>
@ -19,5 +19,4 @@ namespace API.DTOs.Account
/// The old, existing password. If an admin is performing the change, this is not required. Otherwise, it is. /// The old, existing password. If an admin is performing the change, this is not required. Otherwise, it is.
/// </summary> /// </summary>
public string OldPassword { get; init; } public string OldPassword { get; init; }
}
} }

View File

@ -5,14 +5,14 @@ using API.DTOs.Reader;
using API.Entities.Enums; using API.Entities.Enums;
using API.Entities.Interfaces; using API.Entities.Interfaces;
namespace API.DTOs namespace API.DTOs;
/// <summary>
/// A Chapter is the lowest grouping of a reading medium. A Chapter contains a set of MangaFiles which represents the underlying
/// file (abstracted from type).
/// </summary>
public class ChapterDto : IHasReadTimeEstimate
{ {
/// <summary>
/// A Chapter is the lowest grouping of a reading medium. A Chapter contains a set of MangaFiles which represents the underlying
/// file (abstracted from type).
/// </summary>
public class ChapterDto : IHasReadTimeEstimate
{
public int Id { get; init; } public int Id { get; init; }
/// <summary> /// <summary>
/// Range of chapters. Chapter 2-4 -> "2-4". Chapter 2 -> "2". /// Range of chapters. Chapter 2-4 -> "2-4". Chapter 2 -> "2".
@ -89,5 +89,4 @@ namespace API.DTOs
public int MaxHoursToRead { get; set; } public int MaxHoursToRead { get; set; }
/// <inheritdoc cref="IHasReadTimeEstimate.AvgHoursToRead"/> /// <inheritdoc cref="IHasReadTimeEstimate.AvgHoursToRead"/>
public int AvgHoursToRead { get; set; } public int AvgHoursToRead { get; set; }
}
} }

View File

@ -1,9 +1,9 @@
using System.Collections.Generic; using System.Collections.Generic;
namespace API.DTOs.CollectionTags namespace API.DTOs.CollectionTags;
public class CollectionTagBulkAddDto
{ {
public class CollectionTagBulkAddDto
{
/// <summary> /// <summary>
/// Collection Tag Id /// Collection Tag Id
/// </summary> /// </summary>
@ -14,5 +14,4 @@ namespace API.DTOs.CollectionTags
/// Series Ids to add onto Collection Tag /// Series Ids to add onto Collection Tag
/// </summary> /// </summary>
public IEnumerable<int> SeriesIds { get; init; } public IEnumerable<int> SeriesIds { get; init; }
}
} }

View File

@ -1,7 +1,7 @@
namespace API.DTOs.CollectionTags namespace API.DTOs.CollectionTags;
public class CollectionTagDto
{ {
public class CollectionTagDto
{
public int Id { get; set; } public int Id { get; set; }
public string Title { get; set; } public string Title { get; set; }
public string Summary { get; set; } public string Summary { get; set; }
@ -11,5 +11,4 @@
/// </summary> /// </summary>
public string CoverImage { get; set; } public string CoverImage { get; set; }
public bool CoverImageLocked { get; set; } public bool CoverImageLocked { get; set; }
}
} }

View File

@ -1,10 +1,9 @@
using System.Collections.Generic; using System.Collections.Generic;
namespace API.DTOs.CollectionTags namespace API.DTOs.CollectionTags;
public class UpdateSeriesForTagDto
{ {
public class UpdateSeriesForTagDto
{
public CollectionTagDto Tag { get; init; } public CollectionTagDto Tag { get; init; }
public IEnumerable<int> SeriesIdsToRemove { get; init; } public IEnumerable<int> SeriesIdsToRemove { get; init; }
}
} }

View File

@ -2,10 +2,10 @@
using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations;
using API.Entities.Enums; using API.Entities.Enums;
namespace API.DTOs namespace API.DTOs;
public class CreateLibraryDto
{ {
public class CreateLibraryDto
{
[Required] [Required]
public string Name { get; init; } public string Name { get; init; }
[Required] [Required]
@ -13,5 +13,4 @@ namespace API.DTOs
[Required] [Required]
[MinLength(1)] [MinLength(1)]
public IEnumerable<string> Folders { get; init; } public IEnumerable<string> Folders { get; init; }
}
} }

View File

@ -1,9 +1,8 @@
using System.Collections.Generic; using System.Collections.Generic;
namespace API.DTOs namespace API.DTOs;
public class DeleteSeriesDto
{ {
public class DeleteSeriesDto
{
public IList<int> SeriesIds { get; set; } public IList<int> SeriesIds { get; set; }
}
} }

View File

@ -2,11 +2,10 @@
using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations;
using API.DTOs.Reader; using API.DTOs.Reader;
namespace API.DTOs.Downloads namespace API.DTOs.Downloads;
public class DownloadBookmarkDto
{ {
public class DownloadBookmarkDto
{
[Required] [Required]
public IEnumerable<BookmarkDto> Bookmarks { get; set; } public IEnumerable<BookmarkDto> Bookmarks { get; set; }
}
} }

View File

@ -3,10 +3,10 @@ using System.Runtime.InteropServices;
using API.Entities; using API.Entities;
using API.Entities.Enums; using API.Entities.Enums;
namespace API.DTOs.Filtering namespace API.DTOs.Filtering;
public class FilterDto
{ {
public class FilterDto
{
/// <summary> /// <summary>
/// The type of Formats you want to be returned. An empty list will return all formats back /// The type of Formats you want to be returned. An empty list will return all formats back
/// </summary> /// </summary>
@ -99,5 +99,4 @@ namespace API.DTOs.Filtering
/// An optional name string to filter by. Empty string will ignore. /// An optional name string to filter by. Empty string will ignore.
/// </summary> /// </summary>
public string SeriesNameQuery { get; init; } = string.Empty; public string SeriesNameQuery { get; init; } = string.Empty;
}
} }

View File

@ -2,10 +2,10 @@
using System.Collections.Generic; using System.Collections.Generic;
using API.Entities.Enums; using API.Entities.Enums;
namespace API.DTOs namespace API.DTOs;
public class LibraryDto
{ {
public class LibraryDto
{
public int Id { get; init; } public int Id { get; init; }
public string Name { get; init; } public string Name { get; init; }
/// <summary> /// <summary>
@ -14,5 +14,4 @@ namespace API.DTOs
public DateTime LastScanned { get; init; } public DateTime LastScanned { get; init; }
public LibraryType Type { get; init; } public LibraryType Type { get; init; }
public ICollection<string> Folders { get; init; } public ICollection<string> Folders { get; init; }
}
} }

View File

@ -1,15 +1,14 @@
using System; using System;
using API.Entities.Enums; using API.Entities.Enums;
namespace API.DTOs namespace API.DTOs;
public class MangaFileDto
{ {
public class MangaFileDto
{
public int Id { get; init; } public int Id { get; init; }
public string FilePath { get; init; } public string FilePath { get; init; }
public int Pages { get; init; } public int Pages { get; init; }
public MangaFormat Format { get; init; } public MangaFormat Format { get; init; }
public DateTime Created { get; init; } public DateTime Created { get; init; }
}
} }

View File

@ -1,13 +1,13 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
namespace API.DTOs namespace API.DTOs;
/// <summary>
/// Represents a member of a Kavita server.
/// </summary>
public class MemberDto
{ {
/// <summary>
/// Represents a member of a Kavita server.
/// </summary>
public class MemberDto
{
public int Id { get; init; } public int Id { get; init; }
public string Username { get; init; } public string Username { get; init; }
public string Email { get; init; } public string Email { get; init; }
@ -15,5 +15,4 @@ namespace API.DTOs
public DateTime LastActive { get; init; } public DateTime LastActive { get; init; }
public IEnumerable<LibraryDto> Libraries { get; init; } public IEnumerable<LibraryDto> Libraries { get; init; }
public IEnumerable<string> Roles { get; init; } public IEnumerable<string> Roles { get; init; }
}
} }

View File

@ -1,13 +1,13 @@
using System.Collections.Generic; using System.Collections.Generic;
using API.Entities.Enums; using API.Entities.Enums;
namespace API.DTOs.Metadata namespace API.DTOs.Metadata;
/// <summary>
/// Exclusively metadata about a given chapter
/// </summary>
public class ChapterMetadataDto
{ {
/// <summary>
/// Exclusively metadata about a given chapter
/// </summary>
public class ChapterMetadataDto
{
public int Id { get; set; } public int Id { get; set; }
public int ChapterId { get; set; } public int ChapterId { get; set; }
public string Title { get; set; } public string Title { get; set; }
@ -52,5 +52,4 @@ namespace API.DTOs.Metadata
/// </summary> /// </summary>
public long WordCount { get; set; } public long WordCount { get; set; }
}
} }

View File

@ -1,8 +1,7 @@
namespace API.DTOs.Metadata namespace API.DTOs.Metadata;
public class GenreTagDto
{ {
public class GenreTagDto
{
public int Id { get; set; } public int Id { get; set; }
public string Title { get; set; } public string Title { get; set; }
}
} }

View File

@ -2,14 +2,14 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Xml.Serialization; using System.Xml.Serialization;
namespace API.DTOs.OPDS namespace API.DTOs.OPDS;
/// <summary>
///
/// </summary>
[XmlRoot("feed", Namespace = "http://www.w3.org/2005/Atom")]
public class Feed
{ {
/// <summary>
///
/// </summary>
[XmlRoot("feed", Namespace = "http://www.w3.org/2005/Atom")]
public class Feed
{
[XmlElement("updated")] [XmlElement("updated")]
public string Updated { get; init; } = DateTime.UtcNow.ToString("s"); public string Updated { get; init; } = DateTime.UtcNow.ToString("s");
@ -58,5 +58,4 @@ namespace API.DTOs.OPDS
{ {
return StartIndex.HasValue; return StartIndex.HasValue;
} }
}
} }

View File

@ -1,12 +1,11 @@
using System.Xml.Serialization; using System.Xml.Serialization;
namespace API.DTOs.OPDS namespace API.DTOs.OPDS;
public class FeedAuthor
{ {
public class FeedAuthor
{
[XmlElement("name")] [XmlElement("name")]
public string Name { get; set; } public string Name { get; set; }
[XmlElement("uri")] [XmlElement("uri")]
public string Uri { get; set; } public string Uri { get; set; }
}
} }

View File

@ -2,10 +2,10 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Xml.Serialization; using System.Xml.Serialization;
namespace API.DTOs.OPDS namespace API.DTOs.OPDS;
public class FeedEntry
{ {
public class FeedEntry
{
[XmlElement("updated")] [XmlElement("updated")]
public string Updated { get; init; } = DateTime.UtcNow.ToString("s"); public string Updated { get; init; } = DateTime.UtcNow.ToString("s");
@ -47,5 +47,4 @@ namespace API.DTOs.OPDS
// [XmlElement("category")] // [XmlElement("category")]
// public List<FeedCategory> Categories = new List<FeedCategory>(); // public List<FeedCategory> Categories = new List<FeedCategory>();
}
} }

View File

@ -1,12 +1,11 @@
using System.Xml.Serialization; using System.Xml.Serialization;
namespace API.DTOs.OPDS namespace API.DTOs.OPDS;
public class FeedEntryContent
{ {
public class FeedEntryContent
{
[XmlAttribute("type")] [XmlAttribute("type")]
public string Type = "text"; public string Type = "text";
[XmlText] [XmlText]
public string Text; public string Text;
}
} }

View File

@ -1,9 +1,9 @@
using System.Xml.Serialization; using System.Xml.Serialization;
namespace API.DTOs.OPDS namespace API.DTOs.OPDS;
public class FeedLink
{ {
public class FeedLink
{
/// <summary> /// <summary>
/// Relation on the Link /// Relation on the Link
/// </summary> /// </summary>
@ -29,5 +29,4 @@ namespace API.DTOs.OPDS
{ {
return TotalPages > 0; return TotalPages > 0;
} }
}
} }

View File

@ -1,7 +1,7 @@
namespace API.DTOs.OPDS namespace API.DTOs.OPDS;
public static class FeedLinkRelation
{ {
public static class FeedLinkRelation
{
public const string Debug = "debug"; public const string Debug = "debug";
public const string Search = "search"; public const string Search = "search";
public const string Self = "self"; public const string Self = "self";
@ -20,5 +20,4 @@
#pragma warning disable S1075 #pragma warning disable S1075
public const string Stream = "http://vaemendis.net/opds-pse/stream"; public const string Stream = "http://vaemendis.net/opds-pse/stream";
#pragma warning restore S1075 #pragma warning restore S1075
}
} }

View File

@ -1,11 +1,10 @@
namespace API.DTOs.OPDS namespace API.DTOs.OPDS;
public static class FeedLinkType
{ {
public static class FeedLinkType
{
public const string Atom = "application/atom+xml"; public const string Atom = "application/atom+xml";
public const string AtomSearch = "application/opensearchdescription+xml"; public const string AtomSearch = "application/opensearchdescription+xml";
public const string AtomNavigation = "application/atom+xml;profile=opds-catalog;kind=navigation"; public const string AtomNavigation = "application/atom+xml;profile=opds-catalog;kind=navigation";
public const string AtomAcquisition = "application/atom+xml;profile=opds-catalog;kind=acquisition"; public const string AtomAcquisition = "application/atom+xml;profile=opds-catalog;kind=acquisition";
public const string Image = "image/jpeg"; public const string Image = "image/jpeg";
}
} }

View File

@ -1,10 +1,10 @@
using System.Xml.Serialization; using System.Xml.Serialization;
namespace API.DTOs.OPDS namespace API.DTOs.OPDS;
[XmlRoot("OpenSearchDescription", Namespace = "http://a9.com/-/spec/opensearch/1.1/")]
public class OpenSearchDescription
{ {
[XmlRoot("OpenSearchDescription", Namespace = "http://a9.com/-/spec/opensearch/1.1/")]
public class OpenSearchDescription
{
/// <summary> /// <summary>
/// Contains a brief human-readable title that identifies this search engine. /// Contains a brief human-readable title that identifies this search engine.
/// </summary> /// </summary>
@ -38,5 +38,4 @@ namespace API.DTOs.OPDS
/// </summary> /// </summary>
public string Developer { get; set; } = "kavitareader.com"; public string Developer { get; set; } = "kavitareader.com";
}
} }

View File

@ -1,9 +1,9 @@
using System.Xml.Serialization; using System.Xml.Serialization;
namespace API.DTOs.OPDS namespace API.DTOs.OPDS;
public class SearchLink
{ {
public class SearchLink
{
[XmlAttribute("type")] [XmlAttribute("type")]
public string Type { get; set; } public string Type { get; set; }
@ -12,5 +12,4 @@ namespace API.DTOs.OPDS
[XmlAttribute("template")] [XmlAttribute("template")]
public string Template { get; set; } public string Template { get; set; }
}
} }

View File

@ -1,11 +1,10 @@
using API.Entities.Enums; using API.Entities.Enums;
namespace API.DTOs namespace API.DTOs;
public class PersonDto
{ {
public class PersonDto
{
public int Id { get; set; } public int Id { get; set; }
public string Name { get; set; } public string Name { get; set; }
public PersonRole Role { get; set; } public PersonRole Role { get; set; }
}
} }

View File

@ -1,9 +1,9 @@
using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations;
namespace API.DTOs namespace API.DTOs;
public class ProgressDto
{ {
public class ProgressDto
{
[Required] [Required]
public int VolumeId { get; set; } public int VolumeId { get; set; }
[Required] [Required]
@ -17,5 +17,4 @@ namespace API.DTOs
/// on pages that combine multiple "chapters". /// on pages that combine multiple "chapters".
/// </summary> /// </summary>
public string BookScrollId { get; set; } public string BookScrollId { get; set; }
}
} }

View File

@ -1,9 +1,9 @@
using System.Collections.Generic; using System.Collections.Generic;
namespace API.DTOs.Reader namespace API.DTOs.Reader;
public class BookChapterItem
{ {
public class BookChapterItem
{
/// <summary> /// <summary>
/// Name of the Chapter /// Name of the Chapter
/// </summary> /// </summary>
@ -17,5 +17,4 @@ namespace API.DTOs.Reader
/// </summary> /// </summary>
public int Page { get; set; } public int Page { get; set; }
public ICollection<BookChapterItem> Children { get; set; } public ICollection<BookChapterItem> Children { get; set; }
}
} }

View File

@ -1,9 +1,9 @@
using API.Entities.Enums; using API.Entities.Enums;
namespace API.DTOs.Reader namespace API.DTOs.Reader;
public class BookInfoDto : IChapterInfoDto
{ {
public class BookInfoDto : IChapterInfoDto
{
public string BookTitle { get; set; } public string BookTitle { get; set; }
public int SeriesId { get; set; } public int SeriesId { get; set; }
public int VolumeId { get; set; } public int VolumeId { get; set; }
@ -15,5 +15,4 @@ namespace API.DTOs.Reader
public int Pages { get; set; } public int Pages { get; set; }
public bool IsSpecial { get; set; } public bool IsSpecial { get; set; }
public string ChapterTitle { get; set; } public string ChapterTitle { get; set; }
}
} }

View File

@ -1,9 +1,9 @@
using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations;
namespace API.DTOs.Reader namespace API.DTOs.Reader;
public class BookmarkDto
{ {
public class BookmarkDto
{
public int Id { get; set; } public int Id { get; set; }
[Required] [Required]
public int Page { get; set; } public int Page { get; set; }
@ -13,5 +13,4 @@ namespace API.DTOs.Reader
public int SeriesId { get; set; } public int SeriesId { get; set; }
[Required] [Required]
public int ChapterId { get; set; } public int ChapterId { get; set; }
}
} }

View File

@ -1,9 +1,8 @@
using System.Collections.Generic; using System.Collections.Generic;
namespace API.DTOs.Reader namespace API.DTOs.Reader;
public class BulkRemoveBookmarkForSeriesDto
{ {
public class BulkRemoveBookmarkForSeriesDto
{
public ICollection<int> SeriesIds { get; init; } public ICollection<int> SeriesIds { get; init; }
}
} }

View File

@ -1,9 +1,9 @@
using API.Entities.Enums; using API.Entities.Enums;
namespace API.DTOs.Reader namespace API.DTOs.Reader;
public interface IChapterInfoDto
{ {
public interface IChapterInfoDto
{
public int SeriesId { get; set; } public int SeriesId { get; set; }
public int VolumeId { get; set; } public int VolumeId { get; set; }
public MangaFormat SeriesFormat { get; set; } public MangaFormat SeriesFormat { get; set; }
@ -15,5 +15,4 @@ namespace API.DTOs.Reader
public bool IsSpecial { get; set; } public bool IsSpecial { get; set; }
public string ChapterTitle { get; set; } public string ChapterTitle { get; set; }
}
} }

View File

@ -1,9 +1,8 @@
using System.Collections.Generic; using System.Collections.Generic;
namespace API.DTOs.Reader namespace API.DTOs.Reader;
public class MarkMultipleSeriesAsReadDto
{ {
public class MarkMultipleSeriesAsReadDto
{
public IReadOnlyList<int> SeriesIds { get; init; } public IReadOnlyList<int> SeriesIds { get; init; }
}
} }

View File

@ -1,7 +1,6 @@
namespace API.DTOs.Reader namespace API.DTOs.Reader;
public class MarkReadDto
{ {
public class MarkReadDto
{
public int SeriesId { get; init; } public int SeriesId { get; init; }
}
} }

View File

@ -1,8 +1,7 @@
namespace API.DTOs.Reader namespace API.DTOs.Reader;
public class MarkVolumeReadDto
{ {
public class MarkVolumeReadDto
{
public int SeriesId { get; init; } public int SeriesId { get; init; }
public int VolumeId { get; init; } public int VolumeId { get; init; }
}
} }

View File

@ -1,12 +1,12 @@
using System.Collections.Generic; using System.Collections.Generic;
namespace API.DTOs.Reader namespace API.DTOs.Reader;
/// <summary>
/// This is used for bulk updating a set of volume and or chapters in one go
/// </summary>
public class MarkVolumesReadDto
{ {
/// <summary>
/// This is used for bulk updating a set of volume and or chapters in one go
/// </summary>
public class MarkVolumesReadDto
{
public int SeriesId { get; set; } public int SeriesId { get; set; }
/// <summary> /// <summary>
/// A list of Volumes to mark read /// A list of Volumes to mark read
@ -16,5 +16,4 @@ namespace API.DTOs.Reader
/// A list of additional Chapters to mark as read /// A list of additional Chapters to mark as read
/// </summary> /// </summary>
public IReadOnlyList<int> ChapterIds { get; set; } public IReadOnlyList<int> ChapterIds { get; set; }
}
} }

View File

@ -1,7 +1,6 @@
namespace API.DTOs.Reader namespace API.DTOs.Reader;
public class RemoveBookmarkForSeriesDto
{ {
public class RemoveBookmarkForSeriesDto
{
public int SeriesId { get; init; } public int SeriesId { get; init; }
}
} }

View File

@ -1,7 +1,6 @@
namespace API.DTOs.ReadingLists namespace API.DTOs.ReadingLists;
public class CreateReadingListDto
{ {
public class CreateReadingListDto
{
public string Title { get; init; } public string Title { get; init; }
}
} }

View File

@ -1,7 +1,7 @@
namespace API.DTOs.ReadingLists namespace API.DTOs.ReadingLists;
public class ReadingListDto
{ {
public class ReadingListDto
{
public int Id { get; init; } public int Id { get; init; }
public string Title { get; set; } public string Title { get; set; }
public string Summary { get; set; } public string Summary { get; set; }
@ -14,5 +14,4 @@
/// This is used to tell the UI if it should request a Cover Image or not. If null or empty, it has not been set. /// This is used to tell the UI if it should request a Cover Image or not. If null or empty, it has not been set.
/// </summary> /// </summary>
public string CoverImage { get; set; } = string.Empty; public string CoverImage { get; set; } = string.Empty;
}
} }

View File

@ -1,9 +1,9 @@
using API.Entities.Enums; using API.Entities.Enums;
namespace API.DTOs.ReadingLists namespace API.DTOs.ReadingLists;
public class ReadingListItemDto
{ {
public class ReadingListItemDto
{
public int Id { get; init; } public int Id { get; init; }
public int Order { get; init; } public int Order { get; init; }
public int ChapterId { get; init; } public int ChapterId { get; init; }
@ -21,5 +21,4 @@ namespace API.DTOs.ReadingLists
/// Used internally only /// Used internally only
/// </summary> /// </summary>
public int ReadingListId { get; set; } public int ReadingListId { get; set; }
}
} }

View File

@ -1,9 +1,8 @@
namespace API.DTOs.ReadingLists namespace API.DTOs.ReadingLists;
public class UpdateReadingListByChapterDto
{ {
public class UpdateReadingListByChapterDto
{
public int ChapterId { get; init; } public int ChapterId { get; init; }
public int SeriesId { get; init; } public int SeriesId { get; init; }
public int ReadingListId { get; init; } public int ReadingListId { get; init; }
}
} }

View File

@ -1,12 +1,11 @@
using System.Collections.Generic; using System.Collections.Generic;
namespace API.DTOs.ReadingLists namespace API.DTOs.ReadingLists;
public class UpdateReadingListByMultipleDto
{ {
public class UpdateReadingListByMultipleDto
{
public int SeriesId { get; init; } public int SeriesId { get; init; }
public int ReadingListId { get; init; } public int ReadingListId { get; init; }
public IReadOnlyList<int> VolumeIds { get; init; } public IReadOnlyList<int> VolumeIds { get; init; }
public IReadOnlyList<int> ChapterIds { get; init; } public IReadOnlyList<int> ChapterIds { get; init; }
}
} }

View File

@ -1,10 +1,9 @@
using System.Collections.Generic; using System.Collections.Generic;
namespace API.DTOs.ReadingLists namespace API.DTOs.ReadingLists;
public class UpdateReadingListByMultipleSeriesDto
{ {
public class UpdateReadingListByMultipleSeriesDto
{
public int ReadingListId { get; init; } public int ReadingListId { get; init; }
public IReadOnlyList<int> SeriesIds { get; init; } public IReadOnlyList<int> SeriesIds { get; init; }
}
} }

View File

@ -1,8 +1,7 @@
namespace API.DTOs.ReadingLists namespace API.DTOs.ReadingLists;
public class UpdateReadingListBySeriesDto
{ {
public class UpdateReadingListBySeriesDto
{
public int SeriesId { get; init; } public int SeriesId { get; init; }
public int ReadingListId { get; init; } public int ReadingListId { get; init; }
}
} }

View File

@ -1,9 +1,8 @@
namespace API.DTOs.ReadingLists namespace API.DTOs.ReadingLists;
public class UpdateReadingListByVolumeDto
{ {
public class UpdateReadingListByVolumeDto
{
public int VolumeId { get; init; } public int VolumeId { get; init; }
public int SeriesId { get; init; } public int SeriesId { get; init; }
public int ReadingListId { get; init; } public int ReadingListId { get; init; }
}
} }

View File

@ -1,11 +1,10 @@
namespace API.DTOs.ReadingLists namespace API.DTOs.ReadingLists;
public class UpdateReadingListDto
{ {
public class UpdateReadingListDto
{
public int ReadingListId { get; set; } public int ReadingListId { get; set; }
public string Title { get; set; } public string Title { get; set; }
public string Summary { get; set; } public string Summary { get; set; }
public bool Promoted { get; set; } public bool Promoted { get; set; }
public bool CoverImageLocked { get; set; } public bool CoverImageLocked { get; set; }
}
} }

View File

@ -1,18 +1,14 @@
using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations;
namespace API.DTOs.ReadingLists namespace API.DTOs.ReadingLists;
/// <summary>
/// DTO for moving a reading list item to another position within the same list
/// </summary>
public class UpdateReadingListPosition
{ {
/// <summary> [Required] public int ReadingListId { get; set; }
/// DTO for moving a reading list item to another position within the same list [Required] public int ReadingListItemId { get; set; }
/// </summary>
public class UpdateReadingListPosition
{
[Required]
public int ReadingListId { get; set; }
[Required]
public int ReadingListItemId { get; set; }
public int FromPosition { get; set; } public int FromPosition { get; set; }
[Required] [Required] public int ToPosition { get; set; }
public int ToPosition { get; set; }
}
} }

View File

@ -1,10 +1,10 @@
namespace API.DTOs namespace API.DTOs;
/// <summary>
/// Used for running some task against a Series.
/// </summary>
public class RefreshSeriesDto
{ {
/// <summary>
/// Used for running some task against a Series.
/// </summary>
public class RefreshSeriesDto
{
/// <summary> /// <summary>
/// Library Id series belongs to /// Library Id series belongs to
/// </summary> /// </summary>
@ -18,5 +18,4 @@
/// </summary> /// </summary>
/// <remarks>This is expensive if true. Defaults to true.</remarks> /// <remarks>This is expensive if true. Defaults to true.</remarks>
public bool ForceUpdate { get; init; } = true; public bool ForceUpdate { get; init; } = true;
}
} }

View File

@ -1,9 +1,9 @@
using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations;
namespace API.DTOs namespace API.DTOs;
public class RegisterDto
{ {
public class RegisterDto
{
[Required] [Required]
public string Username { get; init; } public string Username { get; init; }
[Required] [Required]
@ -11,5 +11,4 @@ namespace API.DTOs
[Required] [Required]
[StringLength(32, MinimumLength = 6)] [StringLength(32, MinimumLength = 6)]
public string Password { get; set; } public string Password { get; set; }
}
} }

View File

@ -1,9 +1,9 @@
using API.Entities.Enums; using API.Entities.Enums;
namespace API.DTOs.Search namespace API.DTOs.Search;
public class SearchResultDto
{ {
public class SearchResultDto
{
public int SeriesId { get; init; } public int SeriesId { get; init; }
public string Name { get; init; } public string Name { get; init; }
public string OriginalName { get; init; } public string OriginalName { get; init; }
@ -14,5 +14,4 @@ namespace API.DTOs.Search
// Grouping information // Grouping information
public string LibraryName { get; set; } public string LibraryName { get; set; }
public int LibraryId { get; set; } public int LibraryId { get; set; }
}
} }

View File

@ -1,7 +1,6 @@
namespace API.DTOs namespace API.DTOs;
public class SeriesByIdsDto
{ {
public class SeriesByIdsDto
{
public int[] SeriesIds { get; init; } public int[] SeriesIds { get; init; }
}
} }

View File

@ -2,10 +2,10 @@
using API.Entities.Enums; using API.Entities.Enums;
using API.Entities.Interfaces; using API.Entities.Interfaces;
namespace API.DTOs namespace API.DTOs;
public class SeriesDto : IHasReadTimeEstimate
{ {
public class SeriesDto : IHasReadTimeEstimate
{
public int Id { get; init; } public int Id { get; init; }
public string Name { get; init; } public string Name { get; init; }
public string OriginalName { get; init; } public string OriginalName { get; init; }
@ -62,5 +62,4 @@ namespace API.DTOs
/// The last time the folder for this series was scanned /// The last time the folder for this series was scanned
/// </summary> /// </summary>
public DateTime LastFolderScanned { get; set; } public DateTime LastFolderScanned { get; set; }
}
} }

Some files were not shown because too many files have changed in this diff Show More