Skip to content
This repository was archived by the owner on Feb 3, 2025. It is now read-only.

Commit 5713cd6

Browse files
committed
fix: remove leftover chapters when fixing out-of-sync ones
1 parent 6100e6c commit 5713cd6

File tree

4 files changed

+36
-32
lines changed

4 files changed

+36
-32
lines changed

src/server/queue/checkChapters.ts

+17-6
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
import { Prisma } from '@prisma/client';
22
import { Job, Queue, Worker } from 'bullmq';
33
import path from 'path';
4-
import { logger } from '../../utils/logging';
54
import { sanitizer } from '../../utils';
5+
import { logger } from '../../utils/logging';
66
import { prisma } from '../db/client';
77
import { findMissingChapterFiles, getChaptersFromLocal } from '../utils/mangal';
88
import { downloadQueue } from './download';
@@ -13,10 +13,8 @@ const mangaWithLibraryAndMetadata = Prisma.validator<Prisma.MangaArgs>()({
1313

1414
export type MangaWithLibraryAndMetadata = Prisma.MangaGetPayload<typeof mangaWithLibraryAndMetadata>;
1515

16-
const checkChapters = async (manga: MangaWithLibraryAndMetadata) => {
17-
logger.info(`Checking for new chapters: ${manga.title}`);
16+
export const syncDbWithFiles = async (manga: MangaWithLibraryAndMetadata) => {
1817
const mangaDir = path.resolve(manga.library.path, sanitizer(manga.title));
19-
const missingChapterFiles = await findMissingChapterFiles(mangaDir, manga.source, manga.title);
2018

2119
const localChapters = await getChaptersFromLocal(mangaDir);
2220
const dbChapters = await prisma.chapter.findMany({
@@ -26,11 +24,17 @@ const checkChapters = async (manga: MangaWithLibraryAndMetadata) => {
2624
});
2725

2826
const dbOnlyChapters = dbChapters.filter(
29-
(dbChapter) => localChapters.findIndex((localChapter) => localChapter.index === dbChapter.index) < 0,
27+
(dbChapter) =>
28+
localChapters.findIndex(
29+
(localChapter) => localChapter.fileName === dbChapter.fileName && localChapter.index === dbChapter.index,
30+
) < 0,
3031
);
3132

3233
const missingDbChapters = localChapters.filter(
33-
(localChapter) => dbChapters.findIndex((dbChapter) => dbChapter.index === localChapter.index) < 0,
34+
(localChapter) =>
35+
dbChapters.findIndex(
36+
(dbChapter) => dbChapter.fileName === localChapter.fileName && dbChapter.index === localChapter.index,
37+
) < 0,
3438
);
3539

3640
await prisma.$transaction([
@@ -48,6 +52,13 @@ const checkChapters = async (manga: MangaWithLibraryAndMetadata) => {
4852
})),
4953
}),
5054
]);
55+
};
56+
57+
const checkChapters = async (manga: MangaWithLibraryAndMetadata) => {
58+
logger.info(`Checking for new chapters: ${manga.title}`);
59+
const mangaDir = path.resolve(manga.library.path, sanitizer(manga.title));
60+
const missingChapterFiles = await findMissingChapterFiles(mangaDir, manga.source, manga.title);
61+
await syncDbWithFiles(manga);
5162

5263
if (missingChapterFiles.length === 0) {
5364
logger.info(`There are no missing chapter files for ${manga.title}`);

src/server/queue/checkOutOfSyncChapters.ts

+6-4
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import path from 'path';
44
import { sanitizer } from '../../utils';
55
import { prisma } from '../db/client';
66
import { getOutOfSyncChapters } from '../utils/mangal';
7+
import { syncDbWithFiles } from './checkChapters';
78

89
export interface ICheckOutOfSyncChaptersWorkerData {
910
mangaId: number;
@@ -15,17 +16,18 @@ export const checkOutOfSyncChaptersWorker = new Worker(
1516
const { mangaId }: ICheckOutOfSyncChaptersWorkerData = job.data;
1617
try {
1718
const mangaInDb = await prisma.manga.findUniqueOrThrow({
18-
include: { library: true, chapters: true },
19+
include: { library: true, chapters: true, metadata: true },
1920
where: { id: mangaId },
2021
});
22+
await syncDbWithFiles(mangaInDb);
2123
const mangaDir = path.resolve(mangaInDb.library.path, sanitizer(mangaInDb.title));
22-
const outOfSyncChapters = await getOutOfSyncChapters(mangaDir, mangaInDb.source, mangaInDb.title);
24+
const toBeRemovedChapters = await getOutOfSyncChapters(mangaDir, mangaInDb.source, mangaInDb.title);
2325

2426
await prisma.outOfSyncChapter.deleteMany({ where: { mangaId: mangaInDb.id } });
2527
await prisma.outOfSyncChapter.createMany({
26-
data: outOfSyncChapters
28+
data: toBeRemovedChapters
2729
.map((outOfSyncChapterFile) => {
28-
const chapter = mangaInDb.chapters.find((c) => c.fileName === outOfSyncChapterFile);
30+
const chapter = mangaInDb.chapters.find((c) => c.fileName === outOfSyncChapterFile.fileName);
2931
if (!chapter) {
3032
return undefined;
3133
}

src/server/queue/fixOutOfSyncChapters.ts

+5-17
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@ import { Job, Queue, Worker } from 'bullmq';
22
import path from 'path';
33
import { sanitizer } from '../../utils';
44
import { prisma } from '../db/client';
5-
import { downloadChapter, getChapterFromLocal, removeChapter } from '../utils/mangal';
6-
import { integrationQueue } from './integration';
5+
import { removeChapter } from '../utils/mangal';
6+
import { schedule } from './checkChapters';
77

88
export interface IFixOutOfSyncChaptersWorkerData {
99
mangaId: number;
@@ -15,7 +15,7 @@ export const fixOutOfSyncChaptersWorker = new Worker(
1515
const { mangaId }: IFixOutOfSyncChaptersWorkerData = job.data;
1616
try {
1717
const mangaInDb = await prisma.manga.findUniqueOrThrow({
18-
include: { library: true, outOfSyncChapters: true, chapters: true },
18+
include: { library: true, outOfSyncChapters: true, chapters: true, metadata: true },
1919
where: { id: mangaId },
2020
});
2121
const mangaPath = path.resolve(mangaInDb.library.path, sanitizer(mangaInDb.title));
@@ -26,25 +26,13 @@ export const fixOutOfSyncChaptersWorker = new Worker(
2626
if (!chapter) {
2727
return;
2828
}
29-
const filePath = await downloadChapter(
30-
mangaInDb.title,
31-
mangaInDb.source,
32-
chapter.index,
33-
mangaInDb.library.path,
34-
);
3529
await removeChapter(mangaPath, chapter.fileName);
3630
await prisma.outOfSyncChapter.delete({ where: { id: outOfSyncChapter.id } });
3731
await prisma.chapter.delete({ where: { id: outOfSyncChapter.id } });
38-
const newChapter = await getChapterFromLocal(filePath);
39-
await prisma.chapter.create({
40-
data: {
41-
...newChapter,
42-
mangaId,
43-
},
44-
});
4532
}),
4633
);
47-
await integrationQueue.add('run_integrations', null);
34+
35+
await schedule(mangaInDb, true);
4836
await job.updateProgress(100);
4937
} catch (err) {
5038
await job.log(`${err}`);

src/server/utils/mangal.ts

+8-5
Original file line numberDiff line numberDiff line change
@@ -369,11 +369,14 @@ export const removeChapter = async (mangaDir: string, chapterFileName: string) =
369369
};
370370

371371
export const getOutOfSyncChapters = async (mangaDir: string, source: string, title: string) => {
372-
const localChapterNames = (await fs.readdir(mangaDir)).filter(shouldIncludeFile);
372+
const localChapters = await getChaptersFromLocal(mangaDir);
373373
const remoteChapters = await getChaptersFromRemote(source, title);
374-
const remoteChapterNames = remoteChapters.map(
375-
(r) => `[${String(r.index + 1).padStart(4, '0')}]_${sanitizer(r.name)}.cbz`,
376-
);
374+
const remoteChaptersWithIndex = remoteChapters.map((r) => ({
375+
fileName: `[${String(r.index + 1).padStart(4, '0')}]_${sanitizer(r.name)}.cbz`,
376+
index: r.index + 1,
377+
}));
377378

378-
return localChapterNames.filter((l) => !remoteChapterNames.includes(l));
379+
return localChapters.filter(
380+
(l) => !remoteChaptersWithIndex.find((r) => l.index + 1 === r.index && l.fileName === r.fileName),
381+
);
379382
};

0 commit comments

Comments
 (0)