Skip to content

Commit

Permalink
Merge conflicts
Browse files Browse the repository at this point in the history
  • Loading branch information
majora2007 committed Nov 27, 2024
2 parents bdafd00 + fc7c49f commit 6e0ae8b
Show file tree
Hide file tree
Showing 25 changed files with 301 additions and 129 deletions.
11 changes: 11 additions & 0 deletions API.Tests/Parsing/ParsingTests.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System.Globalization;
using System.Linq;
using System.Runtime.InteropServices;
using Xunit;
using static API.Services.Tasks.Scanner.Parser.Parser;

Expand All @@ -15,6 +16,16 @@ public void ShouldWork()
Assert.Equal(6.5f, a);
}

// [Theory]
// [InlineData("de-DE")]
// [InlineData("en-US")]
// public void ShouldParse(string culture)
// {
// var s = 6.5f + "";
// var a = float.Parse(s, CultureInfo.CreateSpecificCulture(culture));
// Assert.Equal(6.5f, a);
// }

[Theory]
[InlineData("Joe Shmo, Green Blue", "Joe Shmo, Green Blue")]
[InlineData("Shmo, Joe", "Shmo, Joe")]
Expand Down
2 changes: 1 addition & 1 deletion API/API.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@
<PackageReference Include="Serilog.Sinks.SignalR.Core" Version="0.1.2" />
<PackageReference Include="SharpCompress" Version="0.38.0" />
<PackageReference Include="SixLabors.ImageSharp" Version="3.1.5" />
<PackageReference Include="SonarAnalyzer.CSharp" Version="9.32.0.97167">
<PackageReference Include="SonarAnalyzer.CSharp" Version="10.3.0.106239">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
Expand Down
66 changes: 58 additions & 8 deletions API/Controllers/LibraryController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
using AutoMapper;
using EasyCaching.Core;
using Hangfire;
using Kavita.Common;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
Expand Down Expand Up @@ -447,12 +448,58 @@ public async Task<ActionResult> ScanFolder(ScanFolderDto dto)
return Ok();
}

/// <summary>
/// Deletes the library and all series within it.
/// </summary>
/// <remarks>This does not touch any files</remarks>
/// <param name="libraryId"></param>
/// <returns></returns>
[Authorize(Policy = "RequireAdminRole")]
[HttpDelete("delete")]
public async Task<ActionResult<bool>> DeleteLibrary(int libraryId)
{
_logger.LogInformation("Library {LibraryId} is being deleted by {UserName}", libraryId, User.GetUsername());

try
{
return Ok(await DeleteLibrary(libraryId, User.GetUserId()));
}
catch (Exception ex)
{
return BadRequest(ex.Message);
}
}

/// <summary>
/// Deletes multiple libraries and all series within it.
/// </summary>
/// <remarks>This does not touch any files</remarks>
/// <param name="libraryIds"></param>
/// <returns></returns>
[Authorize(Policy = "RequireAdminRole")]
[HttpDelete("delete-multiple")]
public async Task<ActionResult<bool>> DeleteMultipleLibraries([FromQuery] List<int> libraryIds)
{
var username = User.GetUsername();
_logger.LogInformation("Library {LibraryId} is being deleted by {UserName}", libraryId, username);
_logger.LogInformation("Libraries {LibraryIds} are being deleted by {UserName}", libraryIds, username);

foreach (var libraryId in libraryIds)
{
try
{
await DeleteLibrary(libraryId, User.GetUserId());
}
catch (Exception ex)
{
return BadRequest(ex.Message);
}
}

return Ok();
}

private async Task<bool> DeleteLibrary(int libraryId, int userId)
{
var series = await _unitOfWork.SeriesRepository.GetSeriesForLibraryIdAsync(libraryId);
var seriesIds = series.Select(x => x.Id).ToArray();
var chapterIds =
Expand All @@ -463,16 +510,19 @@ public async Task<ActionResult<bool>> DeleteLibrary(int libraryId)
if (TaskScheduler.HasScanTaskRunningForLibrary(libraryId))
{
_logger.LogInformation("User is attempting to delete a library while a scan is in progress");
return BadRequest(await _localizationService.Translate(User.GetUserId(), "delete-library-while-scan"));
throw new KavitaException(await _localizationService.Translate(userId, "delete-library-while-scan"));
}

var library = await _unitOfWork.LibraryRepository.GetLibraryForIdAsync(libraryId);
if (library == null) return BadRequest(await _localizationService.Translate(User.GetUserId(), "library-doesnt-exist"));
if (library == null)
{
throw new KavitaException(await _localizationService.Translate(userId, "library-doesnt-exist"));
}


// Due to a bad schema that I can't figure out how to fix, we need to erase all RelatedSeries before we delete the library
// Aka SeriesRelation has an invalid foreign key
foreach (var s in await _unitOfWork.SeriesRepository.GetSeriesForLibraryIdAsync(library.Id,
SeriesIncludes.Related))
foreach (var s in await _unitOfWork.SeriesRepository.GetSeriesForLibraryIdAsync(library.Id, SeriesIncludes.Related))
{
s.Relations = new List<SeriesRelation>();
_unitOfWork.SeriesRepository.Update(s);
Expand All @@ -489,7 +539,7 @@ public async Task<ActionResult<bool>> DeleteLibrary(int libraryId)

await _libraryCacheProvider.RemoveByPrefixAsync(CacheKey);
await _eventHub.SendMessageAsync(MessageFactory.SideNavUpdate,
MessageFactory.SideNavUpdateEvent(User.GetUserId()), false);
MessageFactory.SideNavUpdateEvent(userId), false);

if (chapterIds.Any())
{
Expand All @@ -508,13 +558,13 @@ await _eventHub.SendMessageAsync(MessageFactory.SeriesRemoved,

await _eventHub.SendMessageAsync(MessageFactory.LibraryModified,
MessageFactory.LibraryModifiedEvent(libraryId, "delete"), false);
return Ok(true);
return true;
}
catch (Exception ex)
{
_logger.LogError(ex, "There was a critical issue. Please try again");
await _unitOfWork.RollbackAsync();
return Ok(false);
return false;
}
}

Expand Down
2 changes: 2 additions & 0 deletions API/Controllers/ReaderController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -540,6 +540,8 @@ public async Task<ActionResult> MarkMultipleSeriesAsUnread(MarkMultipleSeriesAsR
public async Task<ActionResult<ProgressDto>> GetProgress(int chapterId)
{
var progress = await _unitOfWork.AppUserProgressRepository.GetUserProgressDtoAsync(chapterId, User.GetUserId());
_logger.LogDebug("Get Progress for {ChapterId} is {Pages}", chapterId, progress?.PageNum ?? 0);

if (progress == null) return Ok(new ProgressDto()
{
PageNum = 0,
Expand Down
3 changes: 2 additions & 1 deletion API/Data/ManualMigrations/MigrateChapterRange.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using System.Linq;
using System.Threading.Tasks;
using API.Entities;
using API.Extensions;
using API.Helpers.Builders;
using API.Services.Tasks.Scanner.Parser;
using Kavita.Common.EnvironmentInfo;
Expand All @@ -28,7 +29,7 @@ public static async Task Migrate(DataContext dataContext, IUnitOfWork unitOfWork
var chapters = await dataContext.Chapter.ToListAsync();
foreach (var chapter in chapters)
{
if (Parser.MinNumberFromRange(chapter.Range) == 0.0f)
if (Parser.MinNumberFromRange(chapter.Range).Is(0.0f))
{
chapter.Range = chapter.GetNumberTitle();
}
Expand Down
30 changes: 20 additions & 10 deletions API/Entities/Chapter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -192,22 +192,32 @@ public void UpdateFrom(ParserInfo info)
/// <returns></returns>
public string GetNumberTitle()
{
if (MinNumber.Is(MaxNumber))
// BUG: TODO: On non-english locales, for floats, the range will be 20,5 but the NumberTitle will return 20.5
// Have I fixed this with TryParse CultureInvariant
try
{
if (MinNumber.Is(Parser.DefaultChapterNumber) && IsSpecial)
if (MinNumber.Is(MaxNumber))
{
return Parser.RemoveExtensionIfSupported(Title);
}
if (MinNumber.Is(Parser.DefaultChapterNumber) && IsSpecial)
{
return Parser.RemoveExtensionIfSupported(Title);
}

if (MinNumber.Is(0) && !float.TryParse(Range, CultureInfo.InvariantCulture, out _))
{
return $"{Range}";
}
if (MinNumber.Is(0f) && !float.TryParse(Range, CultureInfo.InvariantCulture, out _))
{
return $"{Range.ToString(CultureInfo.InvariantCulture)}";
}

return $"{MinNumber}";
return $"{MinNumber.ToString(CultureInfo.InvariantCulture)}";

}

return $"{MinNumber.ToString(CultureInfo.InvariantCulture)}-{MaxNumber.ToString(CultureInfo.InvariantCulture)}";
}
catch (Exception)
{
return MinNumber.ToString(CultureInfo.InvariantCulture);
}
return $"{MinNumber}-{MaxNumber}";
}

/// <summary>
Expand Down
8 changes: 5 additions & 3 deletions API/Entities/Volume.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using API.Entities.Interfaces;
using API.Extensions;
using API.Services.Tasks.Scanner.Parser;
Expand Down Expand Up @@ -67,11 +68,12 @@ public class Volume : IEntityDate, IHasReadTimeEstimate, IHasCoverImage
/// <returns></returns>
public string GetNumberTitle()
{
if (MinNumber.Is(MaxNumber))
if (MinNumber.Equals(MaxNumber))
{
return $"{MinNumber}";
return MinNumber.ToString(CultureInfo.InvariantCulture);
}
return $"{MinNumber}-{MaxNumber}";

return $"{MinNumber.ToString(CultureInfo.InvariantCulture)}-{MaxNumber.ToString(CultureInfo.InvariantCulture)}";
}

public void ResetColorScape()
Expand Down
2 changes: 1 addition & 1 deletion API/Extensions/ChapterListExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ public static class ChapterListExtensions
fakeChapter.UpdateFrom(info);
return specialTreatment
? chapters.FirstOrDefault(c => c.Range == Parser.RemoveExtensionIfSupported(info.Filename) || c.Files.Select(f => Parser.NormalizePath(f.FilePath)).Contains(normalizedPath))
: chapters.FirstOrDefault(c => c.Range == fakeChapter.GetNumberTitle()); // BUG: TODO: On non-english locales, for floats, the range will be 20,5 but the NumberTitle will return 20.5
: chapters.FirstOrDefault(c => c.Range == fakeChapter.GetNumberTitle());
}

/// <summary>
Expand Down
2 changes: 1 addition & 1 deletion API/Services/BookService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -885,7 +885,7 @@ public async Task<Dictionary<string, int>> CreateKeyToPageMappingAsync(EpubBookR
}

/// <summary>
/// Extracts a pdf into images to a target directory. Uses multi-threaded implementation since docnet is slow normally.
/// Extracts a pdf into images to a target directory. Uses multithreaded implementation since docnet is slow normally.
/// </summary>
/// <param name="fileFilePath"></param>
/// <param name="targetDirectory"></param>
Expand Down
2 changes: 1 addition & 1 deletion API/Services/DirectoryService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -708,7 +708,7 @@ public IEnumerable<string> GetAllDirectories(string folderPath, GlobMatcher? mat
if (!FileSystem.Directory.Exists(folderPath)) return ImmutableArray<string>.Empty;
var directories = new List<string>();

var foundDirs = GetDirectories(folderPath);
var foundDirs = GetDirectories(folderPath, matcher);
foreach (var foundDir in foundDirs)
{
directories.Add(foundDir);
Expand Down
4 changes: 2 additions & 2 deletions API/Services/Tasks/Scanner/ParseScannedFiles.cs
Original file line number Diff line number Diff line change
Expand Up @@ -818,11 +818,11 @@ private static void UpdateSortOrder(ConcurrentDictionary<ParsedSeries, List<Pars
chapter.IssueOrder = counter;

// Increment for next chapter (unless the next has a similar value, then add 0.1)
if (!string.IsNullOrEmpty(prevIssue) && float.TryParse(prevIssue, CultureInfo.InvariantCulture, out var prevIssueFloat) && parsedChapter.Is(prevIssueFloat))
if (!string.IsNullOrEmpty(prevIssue) && float.TryParse(prevIssue, NumberStyles.Any, CultureInfo.InvariantCulture, out var prevIssueFloat) && parsedChapter.Is(prevIssueFloat))
{
counter += 0.1f; // bump if same value as the previous issue
}
prevIssue = $"{parsedChapter}";
prevIssue = $"{parsedChapter.ToString(CultureInfo.InvariantCulture)}";
}
else
{
Expand Down
15 changes: 10 additions & 5 deletions API/Services/Tasks/Scanner/Parser/Parser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
namespace API.Services.Tasks.Scanner.Parser;
#nullable enable

public static class Parser
public static partial class Parser
{
// NOTE: If you change this, don't forget to change in the UI (see Series Detail)
public const string DefaultChapter = "-100000"; // -2147483648
Expand Down Expand Up @@ -1054,7 +1054,7 @@ public static float MinNumberFromRange(string range)
}

// Check if there is a range or not
if (Regex.IsMatch(range, @"\d-{1}\d"))
if (NumberRangeRegex().IsMatch(range))
{

var tokens = range.Replace("_", string.Empty).Split("-", StringSplitOptions.RemoveEmptyEntries);
Expand All @@ -1081,7 +1081,7 @@ public static float MaxNumberFromRange(string range)
}

// Check if there is a range or not
if (Regex.IsMatch(range, @"\d-{1}\d"))
if (NumberRangeRegex().IsMatch(range))
{

var tokens = range.Replace("_", string.Empty).Split("-", StringSplitOptions.RemoveEmptyEntries);
Expand Down Expand Up @@ -1244,10 +1244,15 @@ public static string ParseYear(string? name)
{
if (string.IsNullOrEmpty(filename)) return filename;

if (Regex.IsMatch(filename, SupportedExtensions))
if (SupportedExtensionsRegex().IsMatch(filename))
{
return Regex.Replace(filename, SupportedExtensions, string.Empty);
return SupportedExtensionsRegex().Replace(filename, string.Empty);
}
return filename;
}

[GeneratedRegex(SupportedExtensions)]
private static partial Regex SupportedExtensionsRegex();
[GeneratedRegex(@"\d-{1}\d")]
private static partial Regex NumberRangeRegex();
}
4 changes: 2 additions & 2 deletions Kavita.Common/Kavita.Common.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<TargetFramework>net8.0</TargetFramework>
<Company>kavitareader.com</Company>
<Product>Kavita</Product>
<AssemblyVersion>0.8.4.1</AssemblyVersion>
<AssemblyVersion>0.8.4.2</AssemblyVersion>
<NeutralLanguage>en</NeutralLanguage>
<TieredPGO>true</TieredPGO>
</PropertyGroup>
Expand All @@ -20,4 +20,4 @@
</PackageReference>
<PackageReference Include="xunit.assert" Version="2.9.2" />
</ItemGroup>
</Project>
</Project>
7 changes: 7 additions & 0 deletions UI/Web/src/app/_services/library.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,13 @@ export class LibraryService {
return this.httpClient.delete(this.baseUrl + 'library/delete?libraryId=' + libraryId, {});
}

deleteMultiple(libraryIds: Array<number>) {
if (libraryIds.length === 0) {
return of();
}
return this.httpClient.delete(this.baseUrl + 'library/delete-multiple?libraryIds=' + libraryIds.join(','), {});
}

update(model: {name: string, folders: string[], id: number}) {
return this.httpClient.post(this.baseUrl + 'library/update', model);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ import {takeUntilDestroyed} from "@angular/core/rxjs-interop";
selector: 'app-actionable-modal',
standalone: true,
imports: [
NgClass,
TranslocoDirective
],
templateUrl: './actionable-modal.component.html',
Expand Down Expand Up @@ -66,7 +65,8 @@ export class ActionableModalComponent implements OnInit {
...item,
children: [], // Required as dynamic list is only one deep
title: di.title,
_extra: di
_extra: di,
action: item.children[0].action // override action to be correct from child
}));
});
} else {
Expand Down
Loading

0 comments on commit 6e0ae8b

Please sign in to comment.