mirror of
https://github.com/Kareadita/Kavita.git
synced 2025-07-09 03:04:19 -04:00
Small set of Fixes (#3776)
This commit is contained in:
parent
5c06e14a73
commit
7b3198ed9c
@ -80,7 +80,6 @@
|
|||||||
<PackageReference Include="Nager.ArticleNumber" Version="1.0.7" />
|
<PackageReference Include="Nager.ArticleNumber" Version="1.0.7" />
|
||||||
<PackageReference Include="NetVips" Version="3.0.0" />
|
<PackageReference Include="NetVips" Version="3.0.0" />
|
||||||
<PackageReference Include="NetVips.Native" Version="8.16.1" />
|
<PackageReference Include="NetVips.Native" Version="8.16.1" />
|
||||||
<PackageReference Include="NReco.Logging.File" Version="1.2.2" />
|
|
||||||
<PackageReference Include="Serilog" Version="4.2.0" />
|
<PackageReference Include="Serilog" Version="4.2.0" />
|
||||||
<PackageReference Include="Serilog.AspNetCore" Version="9.0.0" />
|
<PackageReference Include="Serilog.AspNetCore" Version="9.0.0" />
|
||||||
<PackageReference Include="Serilog.Enrichers.Thread" Version="4.0.0" />
|
<PackageReference Include="Serilog.Enrichers.Thread" Version="4.0.0" />
|
||||||
|
@ -80,7 +80,6 @@ public static class PersonHelper
|
|||||||
// If not, create a new Person entity using the real name
|
// If not, create a new Person entity using the real name
|
||||||
dbPerson = new PersonBuilder(personName).Build();
|
dbPerson = new PersonBuilder(personName).Build();
|
||||||
peopleToAttach.Add(dbPerson); // Add new person to the list to be attached
|
peopleToAttach.Add(dbPerson); // Add new person to the list to be attached
|
||||||
modification = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add the person to the SeriesMetadataPeople collection
|
// Add the person to the SeriesMetadataPeople collection
|
||||||
|
@ -399,11 +399,14 @@ public class BookService : IBookService
|
|||||||
{
|
{
|
||||||
// Check if any classes on the html node (some r2l books do this) and move them to body tag for scoping
|
// Check if any classes on the html node (some r2l books do this) and move them to body tag for scoping
|
||||||
var htmlNode = doc.DocumentNode.SelectSingleNode("//html");
|
var htmlNode = doc.DocumentNode.SelectSingleNode("//html");
|
||||||
if (htmlNode == null || !htmlNode.Attributes.Contains("class")) return body.InnerHtml;
|
if (htmlNode == null) return body.InnerHtml;
|
||||||
|
|
||||||
var bodyClasses = body.Attributes.Contains("class") ? body.Attributes["class"].Value : string.Empty;
|
var bodyClasses = body.Attributes.Contains("class") ? body.Attributes["class"].Value : string.Empty;
|
||||||
var classes = htmlNode.Attributes["class"].Value + " " + bodyClasses;
|
var htmlClasses = htmlNode.Attributes.Contains("class") ? htmlNode.Attributes["class"].Value : string.Empty;
|
||||||
body.Attributes.Add("class", $"{classes}");
|
|
||||||
|
body.Attributes.Add("class", $"{htmlClasses} {bodyClasses}");
|
||||||
|
|
||||||
|
|
||||||
// I actually need the body tag itself for the classes, so i will create a div and put the body stuff there.
|
// I actually need the body tag itself for the classes, so i will create a div and put the body stuff there.
|
||||||
return $"<div class=\"{body.Attributes["class"].Value}\">{body.InnerHtml}</div>";
|
return $"<div class=\"{body.Attributes["class"].Value}\">{body.InnerHtml}</div>";
|
||||||
}
|
}
|
||||||
|
@ -80,7 +80,6 @@ public class CacheService : ICacheService
|
|||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public IEnumerable<FileDimensionDto> GetCachedFileDimensions(string cachePath)
|
public IEnumerable<FileDimensionDto> GetCachedFileDimensions(string cachePath)
|
||||||
{
|
{
|
||||||
var sw = Stopwatch.StartNew();
|
|
||||||
var files = _directoryService.GetFilesWithExtension(cachePath, Tasks.Scanner.Parser.Parser.ImageFileExtensions)
|
var files = _directoryService.GetFilesWithExtension(cachePath, Tasks.Scanner.Parser.Parser.ImageFileExtensions)
|
||||||
.OrderByNatural(Path.GetFileNameWithoutExtension)
|
.OrderByNatural(Path.GetFileNameWithoutExtension)
|
||||||
.ToArray();
|
.ToArray();
|
||||||
@ -186,8 +185,15 @@ public class CacheService : ICacheService
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Potential BUG: If the folder is left here and there are no files within, this could theoretically return without proper cache
|
// Do an explicit check for files since rarely a "permission denied" error on deleting
|
||||||
return chapter;
|
// the file can occur, thus leaving an empty folder and we would never re-cache the files.
|
||||||
|
if (_directoryService.GetFiles(extractPath).Any())
|
||||||
|
{
|
||||||
|
return chapter;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Delete the extractPath as ExtractArchive will return if the directory already exists
|
||||||
|
_directoryService.ClearAndDeleteDirectory(extractPath);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -210,13 +216,13 @@ public class CacheService : ICacheService
|
|||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public void ExtractChapterFiles(string extractPath, IReadOnlyList<MangaFile>? files, bool extractPdfImages = false)
|
public void ExtractChapterFiles(string extractPath, IReadOnlyList<MangaFile>? files, bool extractPdfImages = false)
|
||||||
{
|
{
|
||||||
if (files == null) return;
|
if (files == null || files.Count == 0) return;
|
||||||
var removeNonImages = true;
|
var removeNonImages = true;
|
||||||
var fileCount = files.Count;
|
var fileCount = files.Count;
|
||||||
var extraPath = string.Empty;
|
var extraPath = string.Empty;
|
||||||
var extractDi = _directoryService.FileSystem.DirectoryInfo.New(extractPath);
|
var extractDi = _directoryService.FileSystem.DirectoryInfo.New(extractPath);
|
||||||
|
|
||||||
if (files.Count > 0 && files[0].Format == MangaFormat.Image)
|
if (files[0].Format == MangaFormat.Image)
|
||||||
{
|
{
|
||||||
// Check if all the files are Images. If so, do a directory copy, else do the normal copy
|
// Check if all the files are Images. If so, do a directory copy, else do the normal copy
|
||||||
if (files.All(f => f.Format == MangaFormat.Image))
|
if (files.All(f => f.Format == MangaFormat.Image))
|
||||||
|
@ -113,7 +113,7 @@ public class ExternalMetadataService : IExternalMetadataService
|
|||||||
public async Task FetchExternalDataTask()
|
public async Task FetchExternalDataTask()
|
||||||
{
|
{
|
||||||
// Find all Series that are eligible and limit
|
// Find all Series that are eligible and limit
|
||||||
var ids = await _unitOfWork.ExternalSeriesMetadataRepository.GetSeriesThatNeedExternalMetadata(25, false);
|
var ids = await _unitOfWork.ExternalSeriesMetadataRepository.GetSeriesThatNeedExternalMetadata(25);
|
||||||
if (ids.Count == 0) return;
|
if (ids.Count == 0) return;
|
||||||
ids = await _unitOfWork.ExternalSeriesMetadataRepository.GetSeriesThatNeedExternalMetadata(25, true);
|
ids = await _unitOfWork.ExternalSeriesMetadataRepository.GetSeriesThatNeedExternalMetadata(25, true);
|
||||||
|
|
||||||
@ -444,7 +444,7 @@ public class ExternalMetadataService : IExternalMetadataService
|
|||||||
{
|
{
|
||||||
if (errorMessage.Contains("Too many Requests"))
|
if (errorMessage.Contains("Too many Requests"))
|
||||||
{
|
{
|
||||||
_logger.LogInformation("Hit rate limit, will retry in 3 seconds");
|
_logger.LogDebug("Hit rate limit, will retry in 3 seconds");
|
||||||
await Task.Delay(3000);
|
await Task.Delay(3000);
|
||||||
|
|
||||||
result = await (Configuration.KavitaPlusApiUrl + "/api/metadata/v2/series-detail")
|
result = await (Configuration.KavitaPlusApiUrl + "/api/metadata/v2/series-detail")
|
||||||
@ -673,7 +673,7 @@ public class ExternalMetadataService : IExternalMetadataService
|
|||||||
|
|
||||||
foreach (var relation in externalMetadataRelations.Where(r => r.Relation != RelationKind.Parent))
|
foreach (var relation in externalMetadataRelations.Where(r => r.Relation != RelationKind.Parent))
|
||||||
{
|
{
|
||||||
var names = new [] {relation.SeriesName.PreferredTitle, relation.SeriesName.RomajiTitle, relation.SeriesName.EnglishTitle, relation.SeriesName.NativeTitle};
|
List<string> names = new [] {relation.SeriesName.PreferredTitle, relation.SeriesName.RomajiTitle, relation.SeriesName.EnglishTitle, relation.SeriesName.NativeTitle}.Where(s => !string.IsNullOrEmpty(s)).ToList()!;
|
||||||
var relatedSeries = await _unitOfWork.SeriesRepository.GetSeriesByAnyName(
|
var relatedSeries = await _unitOfWork.SeriesRepository.GetSeriesByAnyName(
|
||||||
names,
|
names,
|
||||||
relation.PlusMediaFormat.GetMangaFormats(),
|
relation.PlusMediaFormat.GetMangaFormats(),
|
||||||
@ -1171,6 +1171,14 @@ public class ExternalMetadataService : IExternalMetadataService
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Some publishers (CBR) can be represented as Boom! Studios/Boom! Town imprint, so let's handle that appropriately
|
||||||
|
if (publisher.Contains('/') || publisher.Contains("imprint", StringComparison.InvariantCultureIgnoreCase))
|
||||||
|
{
|
||||||
|
var imprint = publisher.Split('/')[1].Replace("imprint", string.Empty);
|
||||||
|
return await UpdateChapterPeople(chapter, settings, PersonRole.Publisher, [publisher]) ||
|
||||||
|
await UpdateChapterPeople(chapter, settings, PersonRole.Imprint, [imprint]);
|
||||||
|
}
|
||||||
|
|
||||||
return await UpdateChapterPeople(chapter, settings, PersonRole.Publisher, [publisher]);
|
return await UpdateChapterPeople(chapter, settings, PersonRole.Publisher, [publisher]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1224,7 +1232,7 @@ public class ExternalMetadataService : IExternalMetadataService
|
|||||||
.DistinctBy(p => Parser.Normalize(p.Name))
|
.DistinctBy(p => Parser.Normalize(p.Name))
|
||||||
.ToList();
|
.ToList();
|
||||||
|
|
||||||
await PersonHelper.UpdateChapterPeopleAsync(chapter, staff, role, _unitOfWork);
|
await PersonHelper.UpdateChapterPeopleAsync(chapter, staff ?? [], role, _unitOfWork);
|
||||||
|
|
||||||
foreach (var person in chapter.People.Where(p => p.Role == role))
|
foreach (var person in chapter.People.Where(p => p.Role == role))
|
||||||
{
|
{
|
||||||
|
@ -7,7 +7,12 @@
|
|||||||
<app-card-actionables [actions]="actionables" (actionHandler)="performAction($event)"></app-card-actionables>
|
<app-card-actionables [actions]="actionables" (actionHandler)="performAction($event)"></app-card-actionables>
|
||||||
}
|
}
|
||||||
<h4 class="header" (click)="sectionClicked($event)" [ngClass]="{'non-selectable': !clickableTitle}">
|
<h4 class="header" (click)="sectionClicked($event)" [ngClass]="{'non-selectable': !clickableTitle}">
|
||||||
<a [href]="titleLink !== '' ? titleLink : 'javascript:void(0)'" class="section-title">{{title}}</a>
|
@if (titleLink !== '') {
|
||||||
|
<a [href]="titleLink | safeUrl" class="section-title">{{title}}</a>
|
||||||
|
} @else {
|
||||||
|
<a href="javascript:void(0)" class="section-title">{{title}}</a>
|
||||||
|
}
|
||||||
|
|
||||||
@if (iconClasses !== '') {
|
@if (iconClasses !== '') {
|
||||||
<i class="{{iconClasses}} title-icon ms-1" aria-hidden="true"></i>
|
<i class="{{iconClasses}} title-icon ms-1" aria-hidden="true"></i>
|
||||||
}
|
}
|
||||||
|
@ -15,13 +15,14 @@ import {NgClass, NgTemplateOutlet} from '@angular/common';
|
|||||||
import {TranslocoDirective} from "@jsverse/transloco";
|
import {TranslocoDirective} from "@jsverse/transloco";
|
||||||
import {CardActionablesComponent} from "../../../_single-module/card-actionables/card-actionables.component";
|
import {CardActionablesComponent} from "../../../_single-module/card-actionables/card-actionables.component";
|
||||||
import {ActionItem} from "../../../_services/action-factory.service";
|
import {ActionItem} from "../../../_services/action-factory.service";
|
||||||
|
import {SafeUrlPipe} from "../../../_pipes/safe-url.pipe";
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-carousel-reel',
|
selector: 'app-carousel-reel',
|
||||||
templateUrl: './carousel-reel.component.html',
|
templateUrl: './carousel-reel.component.html',
|
||||||
styleUrls: ['./carousel-reel.component.scss'],
|
styleUrls: ['./carousel-reel.component.scss'],
|
||||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||||
imports: [NgClass, SwiperModule, NgTemplateOutlet, TranslocoDirective, CardActionablesComponent]
|
imports: [NgClass, SwiperModule, NgTemplateOutlet, TranslocoDirective, CardActionablesComponent, SafeUrlPipe]
|
||||||
})
|
})
|
||||||
export class CarouselReelComponent {
|
export class CarouselReelComponent {
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user