Scanner Bugfixes (#2818)

This commit is contained in:
Joe Milazzo 2024-03-25 16:28:10 -05:00 committed by GitHub
parent 829a610579
commit 93a8883fe4
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
24 changed files with 180 additions and 99 deletions

View File

@ -10,12 +10,12 @@ jobs:
runs-on: windows-latest
steps:
- name: Checkout Repo
uses: actions/checkout@v3
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Setup .NET Core
uses: actions/setup-dotnet@v3
uses: actions/setup-dotnet@v4
with:
dotnet-version: 8.0.x
@ -26,7 +26,7 @@ jobs:
- name: Install dependencies
run: dotnet restore
- uses: actions/upload-artifact@v3
- uses: actions/upload-artifact@v4
with:
name: csproj
path: Kavita.Common/Kavita.Common.csproj

View File

@ -12,11 +12,11 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout Repo
uses: actions/checkout@v3
uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: actions/upload-artifact@v3
- uses: actions/upload-artifact@v4
with:
name: csproj
path: Kavita.Common/Kavita.Common.csproj
@ -26,12 +26,12 @@ jobs:
needs: [ build ]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Setup .NET Core
uses: actions/setup-dotnet@v3
uses: actions/setup-dotnet@v4
with:
dotnet-version: 8.0.x
@ -59,14 +59,14 @@ jobs:
github-token: ${{ secrets.GITHUB_TOKEN }}
- name: Check Out Repo
uses: actions/checkout@v3
uses: actions/checkout@v4
with:
ref: canary
- name: NodeJS to Compile WebUI
uses: actions/setup-node@v3
uses: actions/setup-node@v4
with:
node-version: '18.13.x'
node-version: 20
- run: |
cd UI/Web || exit
echo 'Installing web dependencies'
@ -81,7 +81,7 @@ jobs:
cd ../ || exit
- name: Get csproj Version
uses: kzrnm/get-net-sdk-project-versions-action@v1
uses: kzrnm/get-net-sdk-project-versions-action@v2
id: get-version
with:
proj-path: Kavita.Common/Kavita.Common.csproj
@ -96,7 +96,7 @@ jobs:
run: echo "${{steps.get-version.outputs.assembly-version}}"
- name: Compile dotnet app
uses: actions/setup-dotnet@v3
uses: actions/setup-dotnet@v4
with:
dotnet-version: 8.0.x
@ -106,28 +106,28 @@ jobs:
- run: ./monorepo-build.sh
- name: Login to Docker Hub
uses: docker/login-action@v2
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKER_HUB_USERNAME }}
password: ${{ secrets.DOCKER_HUB_ACCESS_TOKEN }}
- name: Login to GitHub Container Registry
uses: docker/login-action@v2
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Set up QEMU
uses: docker/setup-qemu-action@v2
uses: docker/setup-qemu-action@v3
- name: Set up Docker Buildx
id: buildx
uses: docker/setup-buildx-action@v2
uses: docker/setup-buildx-action@v3
- name: Build and push
id: docker_build
uses: docker/build-push-action@v4
uses: docker/build-push-action@v5
with:
context: .
platforms: linux/amd64,linux/arm/v7,linux/arm64

View File

@ -46,7 +46,7 @@ jobs:
steps:
- name: Checkout repository
uses: actions/checkout@v3
uses: actions/checkout@v4
- name: Install Swashbuckle CLI
shell: bash

View File

@ -21,11 +21,11 @@ jobs:
if: github.ref == 'refs/heads/develop'
steps:
- name: Checkout Repo
uses: actions/checkout@v3
uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: actions/upload-artifact@v3
- uses: actions/upload-artifact@v4
with:
name: csproj
path: Kavita.Common/Kavita.Common.csproj
@ -36,12 +36,12 @@ jobs:
runs-on: ubuntu-latest
if: github.ref == 'refs/heads/develop'
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Setup .NET Core
uses: actions/setup-dotnet@v3
uses: actions/setup-dotnet@v4
with:
dotnet-version: 8.0.x
@ -89,14 +89,14 @@ jobs:
echo "BODY=$body" >> $GITHUB_OUTPUT
- name: Check Out Repo
uses: actions/checkout@v3
uses: actions/checkout@v4
with:
ref: develop
- name: NodeJS to Compile WebUI
uses: actions/setup-node@v3
uses: actions/setup-node@v4
with:
node-version: '18.13.x'
node-version: 20
- run: |
cd UI/Web || exit
echo 'Installing web dependencies'
@ -111,7 +111,7 @@ jobs:
cd ../ || exit
- name: Get csproj Version
uses: kzrnm/get-net-sdk-project-versions-action@v1
uses: kzrnm/get-net-sdk-project-versions-action@v2
id: get-version
with:
proj-path: Kavita.Common/Kavita.Common.csproj
@ -126,7 +126,7 @@ jobs:
run: echo "${{steps.get-version.outputs.assembly-version}}"
- name: Compile dotnet app
uses: actions/setup-dotnet@v3
uses: actions/setup-dotnet@v4
with:
dotnet-version: 8.0.x
@ -136,28 +136,28 @@ jobs:
- run: ./monorepo-build.sh
- name: Login to Docker Hub
uses: docker/login-action@v2
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKER_HUB_USERNAME }}
password: ${{ secrets.DOCKER_HUB_ACCESS_TOKEN }}
- name: Login to GitHub Container Registry
uses: docker/login-action@v2
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Set up QEMU
uses: docker/setup-qemu-action@v2
uses: docker/setup-qemu-action@v3
- name: Set up Docker Buildx
id: buildx
uses: docker/setup-buildx-action@v2
uses: docker/setup-buildx-action@v3
- name: Build and push
id: docker_build
uses: docker/build-push-action@v4
uses: docker/build-push-action@v5
with:
context: .
platforms: linux/amd64,linux/arm/v7,linux/arm64

View File

@ -30,11 +30,11 @@ jobs:
if: github.event.pull_request.merged == true && contains(github.head_ref, 'release')
steps:
- name: Checkout Repo
uses: actions/checkout@v3
uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: actions/upload-artifact@v3
- uses: actions/upload-artifact@v4
with:
name: csproj
path: Kavita.Common/Kavita.Common.csproj
@ -77,14 +77,14 @@ jobs:
echo "BODY=$body" >> $GITHUB_OUTPUT
- name: Check Out Repo
uses: actions/checkout@v3
uses: actions/checkout@v4
with:
ref: develop
- name: NodeJS to Compile WebUI
uses: actions/setup-node@v3
uses: actions/setup-node@v4
with:
node-version: '18.13.x'
node-version: 20
- run: |
cd UI/Web || exit
@ -100,7 +100,7 @@ jobs:
cd ../ || exit
- name: Get csproj Version
uses: kzrnm/get-net-sdk-project-versions-action@v1
uses: kzrnm/get-net-sdk-project-versions-action@v2
id: get-version
with:
proj-path: Kavita.Common/Kavita.Common.csproj
@ -117,7 +117,7 @@ jobs:
id: parse-version
- name: Compile dotnet app
uses: actions/setup-dotnet@v3
uses: actions/setup-dotnet@v4
with:
dotnet-version: 8.0.x
- name: Install Swashbuckle CLI
@ -126,28 +126,28 @@ jobs:
- run: ./monorepo-build.sh
- name: Login to Docker Hub
uses: docker/login-action@v2
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKER_HUB_USERNAME }}
password: ${{ secrets.DOCKER_HUB_ACCESS_TOKEN }}
- name: Login to GitHub Container Registry
uses: docker/login-action@v2
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Set up QEMU
uses: docker/setup-qemu-action@v2
uses: docker/setup-qemu-action@v3
- name: Set up Docker Buildx
id: buildx
uses: docker/setup-buildx-action@v2
uses: docker/setup-buildx-action@v3
- name: Build and push stable
id: docker_build_stable
uses: docker/build-push-action@v4
uses: docker/build-push-action@v5
with:
context: .
platforms: linux/amd64,linux/arm/v7,linux/arm64
@ -156,7 +156,7 @@ jobs:
- name: Build and push nightly
id: docker_build_nightly
uses: docker/build-push-action@v4
uses: docker/build-push-action@v5
with:
context: .
platforms: linux/amd64,linux/arm/v7,linux/arm64

View File

@ -206,6 +206,7 @@ public class MangaParsingTests
[InlineData("test 2 years 1권", "test 2 years")]
[InlineData("test 2 years 1화", "test 2 years")]
[InlineData("Nagasarete Airantou - Vol. 30 Ch. 187.5 - Vol.30 Omake", "Nagasarete Airantou")]
[InlineData("Cynthia The Mission - c000 - c006 (v06)", "Cynthia The Mission")]
public void ParseSeriesTest(string filename, string expected)
{
Assert.Equal(expected, API.Services.Tasks.Scanner.Parser.Parser.ParseSeries(filename));

View File

@ -66,7 +66,7 @@
<PackageReference Include="Flurl" Version="3.0.7" />
<PackageReference Include="Flurl.Http" Version="3.2.4" />
<PackageReference Include="Hangfire" Version="1.8.11" />
<PackageReference Include="Hangfire.InMemory" Version="0.8.0" />
<PackageReference Include="Hangfire.InMemory" Version="0.8.1" />
<PackageReference Include="Hangfire.MaximumConcurrentExecutions" Version="1.1.0" />
<PackageReference Include="Hangfire.Storage.SQLite" Version="0.4.1" />
<PackageReference Include="HtmlAgilityPack" Version="1.11.59" />

View File

@ -113,7 +113,35 @@ public static class MigrateLooseLeafChapters
//UpdateCoverImage(directoryService, logger, chapter, extension, newVolume);
}
// Update the progress table with the new VolumeId
var oldVolumeBookmarks = await dataContext.AppUserBookmark
.Where(p => p.VolumeId == distinctVolume.Volume.Id).ToListAsync();
logger.LogInformation("Moving {Count} existing Bookmarks from Volume Id {OldVolumeId} to New Volume {NewVolumeId}",
oldVolumeBookmarks.Count, distinctVolume.Volume.Id, newVolume.Id);
foreach (var bookmark in oldVolumeBookmarks)
{
bookmark.VolumeId = newVolume.Id;
}
var oldVolumePersonalToC = await dataContext.AppUserTableOfContent
.Where(p => p.VolumeId == distinctVolume.Volume.Id).ToListAsync();
logger.LogInformation("Moving {Count} existing Personal ToC from Volume Id {OldVolumeId} to New Volume {NewVolumeId}",
oldVolumePersonalToC.Count, distinctVolume.Volume.Id, newVolume.Id);
foreach (var pToc in oldVolumePersonalToC)
{
pToc.VolumeId = newVolume.Id;
}
var oldVolumeReadingListItems = await dataContext.ReadingListItem
.Where(p => p.VolumeId == distinctVolume.Volume.Id).ToListAsync();
logger.LogInformation("Moving {Count} existing Personal ToC from Volume Id {OldVolumeId} to New Volume {NewVolumeId}",
oldVolumeReadingListItems.Count, distinctVolume.Volume.Id, newVolume.Id);
foreach (var readingListItem in oldVolumeReadingListItems)
{
readingListItem.VolumeId = newVolume.Id;
}
await dataContext.SaveChangesAsync();
}

View File

@ -129,6 +129,35 @@ public static class MigrateMixedSpecials
//UpdateCoverImage(directoryService, logger, specialChapter, extension, newVolume);
}
var oldVolumeBookmarks = await dataContext.AppUserBookmark
.Where(p => p.VolumeId == distinctVolume.Volume.Id).ToListAsync();
logger.LogInformation("Moving {Count} existing Bookmarks from Volume Id {OldVolumeId} to New Volume {NewVolumeId}",
oldVolumeBookmarks.Count, distinctVolume.Volume.Id, newVolume.Id);
foreach (var bookmark in oldVolumeBookmarks)
{
bookmark.VolumeId = newVolume.Id;
}
var oldVolumePersonalToC = await dataContext.AppUserTableOfContent
.Where(p => p.VolumeId == distinctVolume.Volume.Id).ToListAsync();
logger.LogInformation("Moving {Count} existing Personal ToC from Volume Id {OldVolumeId} to New Volume {NewVolumeId}",
oldVolumePersonalToC.Count, distinctVolume.Volume.Id, newVolume.Id);
foreach (var pToc in oldVolumePersonalToC)
{
pToc.VolumeId = newVolume.Id;
}
var oldVolumeReadingListItems = await dataContext.ReadingListItem
.Where(p => p.VolumeId == distinctVolume.Volume.Id).ToListAsync();
logger.LogInformation("Moving {Count} existing Personal ToC from Volume Id {OldVolumeId} to New Volume {NewVolumeId}",
oldVolumeReadingListItems.Count, distinctVolume.Volume.Id, newVolume.Id);
foreach (var readingListItem in oldVolumeReadingListItems)
{
readingListItem.VolumeId = newVolume.Id;
}
await dataContext.SaveChangesAsync();
}

View File

@ -7,7 +7,7 @@ namespace API.Entities;
/// <summary>
/// Represents the progress a single user has on a given Chapter.
/// </summary>
public class AppUserProgress : IEntityDate
public class AppUserProgress
{
/// <summary>
/// Id of Entity
@ -59,4 +59,10 @@ public class AppUserProgress : IEntityDate
/// User this progress belongs to
/// </summary>
public int AppUserId { get; set; }
public void MarkModified()
{
LastModified = DateTime.Now;
LastModifiedUtc = DateTime.UtcNow;
}
}

View File

@ -31,7 +31,7 @@ public static class ChapterListExtensions
{
var normalizedPath = Parser.NormalizePath(info.FullFilePath);
var specialTreatment = info.IsSpecialInfo();
return specialTreatment
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 == info.Chapters);
}

View File

@ -31,7 +31,7 @@ public static class SeriesSort
SortField.TimeToRead => query.DoOrderBy(s => s.AvgHoursToRead, sortOptions),
SortField.ReleaseYear => query.DoOrderBy(s => s.Metadata.ReleaseYear, sortOptions),
SortField.ReadProgress => query.DoOrderBy(s => s.Progress.Where(p => p.SeriesId == s.Id && p.AppUserId == userId)
.Select(p => p.LastModified)
.Select(p => p.LastModified) // TODO: Migrate this to UTC
.Max(), sortOptions),
SortField.AverageRating => query.DoOrderBy(s => s.ExternalSeriesMetadata.ExternalRatings
.Where(p => p.SeriesId == s.Id).Average(p => p.AverageScore), sortOptions),

View File

@ -134,7 +134,11 @@ public class ReaderService : IReaderService
VolumeId = chapter.VolumeId,
SeriesId = seriesId,
ChapterId = chapter.Id,
LibraryId = series.LibraryId
LibraryId = series.LibraryId,
Created = DateTime.Now,
CreatedUtc = DateTime.UtcNow,
LastModified = DateTime.Now,
LastModifiedUtc = DateTime.UtcNow
});
}
else
@ -144,6 +148,8 @@ public class ReaderService : IReaderService
userProgress.VolumeId = chapter.VolumeId;
}
userProgress?.MarkModified();
await _eventHub.SendMessageAsync(MessageFactory.UserProgressUpdate,
MessageFactory.UserProgressUpdateEvent(user.Id, user.UserName!, seriesId, chapter.VolumeId, chapter.Id, chapter.Pages));
@ -177,6 +183,7 @@ public class ReaderService : IReaderService
userProgress.PagesRead = 0;
userProgress.SeriesId = seriesId;
userProgress.VolumeId = chapter.VolumeId;
userProgress.MarkModified();
await _eventHub.SendMessageAsync(MessageFactory.UserProgressUpdate,
MessageFactory.UserProgressUpdateEvent(user.Id, user.UserName!, userProgress.SeriesId, userProgress.VolumeId, userProgress.ChapterId, 0));
@ -266,7 +273,11 @@ public class ReaderService : IReaderService
SeriesId = progressDto.SeriesId,
ChapterId = progressDto.ChapterId,
LibraryId = progressDto.LibraryId,
BookScrollId = progressDto.BookScrollId
BookScrollId = progressDto.BookScrollId,
Created = DateTime.Now,
CreatedUtc = DateTime.UtcNow,
LastModified = DateTime.Now,
LastModifiedUtc = DateTime.UtcNow
});
_unitOfWork.UserRepository.Update(userWithProgress);
}
@ -280,6 +291,8 @@ public class ReaderService : IReaderService
_unitOfWork.AppUserProgressRepository.Update(userProgress);
}
userProgress?.MarkModified();
if (!_unitOfWork.HasChanges() || await _unitOfWork.CommitAsync())
{
var user = await _unitOfWork.UserRepository.GetUserByIdAsync(userId);

View File

@ -31,7 +31,7 @@ public class BookParser(IDirectoryService directoryService, IBookService bookSer
{
var info2 = basicParser.Parse(filePath, rootPath, libraryRoot, LibraryType.Book, comicInfo);
info.Merge(info2);
if (type == LibraryType.LightNovel && hasVolumeInSeries && info2 != null && Parser.ParseVolume(info2.Series)
if (hasVolumeInSeries && info2 != null && Parser.ParseVolume(info2.Series)
.Equals(Parser.LooseLeafVolume))
{
// Override the Series name so it groups appropriately

View File

@ -107,11 +107,11 @@ public abstract class DefaultParser(IDirectoryService directoryService) : IDefau
{
info.Volumes = info.ComicInfo.Volume;
}
if (string.IsNullOrEmpty(info.Series) && !string.IsNullOrEmpty(info.ComicInfo.Series))
if (!string.IsNullOrEmpty(info.ComicInfo.Series))
{
info.Series = info.ComicInfo.Series.Trim();
}
if (string.IsNullOrEmpty(info.LocalizedSeries) && !string.IsNullOrEmpty(info.ComicInfo.LocalizedSeries))
if (!string.IsNullOrEmpty(info.ComicInfo.LocalizedSeries))
{
info.LocalizedSeries = info.ComicInfo.LocalizedSeries.Trim();
}

View File

@ -232,7 +232,7 @@ public static class Parser
RegexTimeout),
// Gokukoku no Brynhildr - c001-008 (v01) [TrinityBAKumA], Black Bullet - v4 c17 [batoto]
new Regex(
@"(?<Series>.*)( - )(?:v|vo|c|chapters)\d",
@"(?<Series>.+?)( - )(?:v|vo|c|chapters)\d",
MatchOptions, RegexTimeout),
// Kedouin Makoto - Corpse Party Musume, Chapter 19 [Dametrans].zip
new Regex(

View File

@ -22,6 +22,11 @@ public class PdfParser(IDirectoryService directoryService) : DefaultParser(direc
: Parser.ParseChapter(fileName)
};
if (type == LibraryType.Book)
{
ret.Chapters = Parser.DefaultChapter;
}
ret.Series = type == LibraryType.Comic ? Parser.ParseComicSeries(fileName) : Parser.ParseSeries(fileName);
ret.Volumes = type == LibraryType.Comic ? Parser.ParseComicVolume(fileName) : Parser.ParseVolume(fileName);

View File

@ -14,6 +14,6 @@ export class FilterPipe implements PipeTransform {
const ret = items.filter(item => callback(item));
if (ret.length === items.length) return items; // This will prevent a re-render
return ret;
}
}
}

View File

@ -339,6 +339,9 @@ export class SeriesDetailComponent implements OnInit, AfterContentChecked {
get ShowStorylineTab() {
if (this.libraryType === LibraryType.ComicVine) return false;
// Edge case for bad pdf parse
if (this.libraryType === LibraryType.Book && (this.volumes.length === 0 && this.chapters.length === 0 && this.storyChapters.length > 0)) return true;
return (this.libraryType !== LibraryType.Book && this.libraryType !== LibraryType.LightNovel && this.libraryType !== LibraryType.Comic)
&& (this.volumes.length > 0 || this.chapters.length > 0);
}
@ -727,7 +730,12 @@ export class SeriesDetailComponent implements OnInit, AfterContentChecked {
// Book libraries only have Volumes or Specials enabled
if (this.libraryType === LibraryType.Book || this.libraryType === LibraryType.LightNovel) {
if (this.volumes.length === 0) {
this.activeTabId = TabID.Specials;
if (this.specials.length === 0 && this.storyChapters.length > 0) {
// NOTE: This is an edge case caused by bad parsing of pdf files. Once the new pdf parser is in place, this should be removed
this.activeTabId = TabID.Storyline;
} else {
this.activeTabId = TabID.Specials;
}
} else {
this.activeTabId = TabID.Volumes;
}

View File

@ -258,7 +258,10 @@ export class LibrarySettingsModalComponent implements OnInit {
forceScan() {
this.libraryService.scan(this.library!.id, true)
.subscribe(() => this.toastr.info(translate('toasts.forced-scan-queued', {name: this.library!.name})));
.subscribe(() => {
this.toastr.info(translate('toasts.forced-scan-queued', {name: this.library!.name}));
this.close();
});
}
async save() {

View File

@ -1,37 +1,23 @@
<ng-container *transloco="let t; read: 'kavitaplus-metadata-breakdown-stats'">
<div class="dashboard-card-content">
<h4>{{t('title')}}</h4>
<p>{{t('description')}}</p>
@if(breakdown) {
@if(breakdown.totalSeries === 0 || breakdown.seriesCompleted === 0) {
<div>{{t('no-data')}}</div>
}
@if (percentDone >= 1) {
<p>{{t('complete') }}</p>
} @else {
<p>{{t('total-series-progress-label', {percent: percentDone * 100 | percent}) }}</p>
<div class="day-breakdown-chart">
<table class="charts-css pie show-labels">
<tbody>
<tr>
<th scope="row">{{t('completed-series-label')}}</th>
<td class="completed" style="--start: 0; --end: ' + {{ completedEnd }}">
<span class="data">{{ breakdown.seriesCompleted }}</span>
</td>
</tr>
<tr>
<th scope="row">{{t('errored-series-label')}}</th>
<td class="error" style="--start: ' + {{ errorStart }}; --end: {{ errorEnd }}'">
<span class="data">{{ breakdown.erroredSeries }}</span>
</td>
</tr>
</tbody>
</table>
</div>
<ngb-progressbar-stacked>
<ngb-progressbar type="danger" [value]="errorPercent" [ngbTooltip]="t('errored-series-label') + ' ' + breakdown.erroredSeries"></ngb-progressbar>
<ngb-progressbar type="success" [value]="completedPercent" [ngbTooltip]="t('completed-series-label') + ' ' + breakdown.seriesCompleted"></ngb-progressbar>
</ngb-progressbar-stacked>
@if (breakdown.seriesCompleted >= breakdown.totalSeries) {
<p>{{t('complete') }}
@if (breakdown.erroredSeries > 0) {
{{t('errored-series-label') }} {{breakdown.erroredSeries}}
}
</p>
}
}
}
</div>

View File

@ -3,13 +3,17 @@ import {StatisticsService} from "../../../_services/statistics.service";
import {KavitaPlusMetadataBreakdown} from "../../_models/kavitaplus-metadata-breakdown";
import {TranslocoDirective} from "@ngneat/transloco";
import {PercentPipe} from "@angular/common";
import {NgbProgressbar, NgbProgressbarStacked, NgbTooltip} from "@ng-bootstrap/ng-bootstrap";
@Component({
selector: 'app-kavitaplus-metadata-breakdown-stats',
standalone: true,
imports: [
TranslocoDirective,
PercentPipe
PercentPipe,
NgbProgressbarStacked,
NgbProgressbar,
NgbTooltip
],
templateUrl: './kavitaplus-metadata-breakdown-stats.component.html',
styleUrl: './kavitaplus-metadata-breakdown-stats.component.scss',
@ -20,20 +24,18 @@ export class KavitaplusMetadataBreakdownStatsComponent {
private readonly statsService = inject(StatisticsService);
breakdown: KavitaPlusMetadataBreakdown | undefined;
completedStart!: number;
completedEnd!: number;
errorStart!: number;
errorEnd!: number;
percentDone!: number;
errorPercent!: number;
completedPercent!: number;
constructor() {
this.statsService.getKavitaPlusMetadataBreakdown().subscribe(res => {
this.breakdown = res;
this.completedStart = 0;
this.completedEnd = ((res.seriesCompleted - res.erroredSeries) / res.totalSeries);
this.errorStart = this.completedEnd;
this.errorEnd = Math.max(1, ((res.seriesCompleted) / res.totalSeries));
this.percentDone = res.seriesCompleted / res.totalSeries;
this.errorPercent = (res.erroredSeries / res.totalSeries) * 100;
this.completedPercent = ((res.seriesCompleted - res.erroredSeries) / res.totalSeries) * 100;
this.cdRef.markForCheck();
});
}

View File

@ -579,7 +579,7 @@
"published-label": "Published: ",
"available": "Available",
"description": "If you do not see an {{installed}}",
"description-continued": "tag, you are on a nightly release. Only major versions will show as available."
"description-continued": "tag, you are on a nightly release. Only major versions will show as available. A nightly tag will show when on a nightly from that stable."
},
"invite-user": {
@ -1786,10 +1786,10 @@
"kavitaplus-metadata-breakdown-stats": {
"title": "Kavita+ Metadata Breakdown",
"description": "Kavita fetches metadata (ratings, reviews, recommendations, etc) slowly over time for eligible series.",
"no-data": "No data",
"errored-series-label": "Errored Series",
"completed-series-label": "Completed Series",
"total-series-progress-label": "Series Processed: {{percent}}",
"complete": "All Series have metadata"
},

View File

@ -7,7 +7,7 @@
"name": "GPL-3.0",
"url": "https://github.com/Kareadita/Kavita/blob/develop/LICENSE"
},
"version": "0.7.14.8"
"version": "0.7.14.9"
},
"servers": [
{