fix(api): robustesse des providers de métadonnées

Recherche ISBN directe sur Open Library avec repli titre/auteur,
normalisation des réponses, timeouts et User-Agent explicites sur les
trois providers distants, abandon de l'extraction de jaquette CBR en
échec silencieux (fallback métadonnées seules), tests des providers et
garde du test de migration si better-sqlite3 est indisponible.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Git Agent
2026-08-23 16:23:57 +02:00
parent 7b72cc0d83
commit 2f98c48259
6 changed files with 240 additions and 33 deletions

View File

@ -3,7 +3,7 @@ import { mkdirSync, readFileSync, writeFileSync } from "node:fs";
import { basename, dirname, extname, join } from "node:path";
import AdmZip from "adm-zip";
import { XMLParser } from "fast-xml-parser";
import { listCbrImageEntries, readCbrPage } from "../common/cbr.js";
import { listCbrImageEntries } from "../common/cbr.js";
import { listCbzImageEntries } from "../common/cbz.js";
export type BookMetadata = {
@ -97,16 +97,10 @@ function extractCbzMetadata(filePath: string, storageDir: string): BookMetadata
}
async function extractCbrMetadata(filePath: string, storageDir: string): Promise<BookMetadata> {
const firstPage = (await listCbrImageEntries(filePath))[0];
const page = await readCbrPage(filePath, 1, storageDir);
const extension = extname(firstPage.entryName) || ".jpg";
const hash = createHash("sha256").update(filePath).digest("hex").slice(0, 24);
const target = join(storageDir, "covers", `${hash}${extension}`);
mkdirSync(dirname(target), { recursive: true });
writeFileSync(target, page.data);
await listCbrImageEntries(filePath);
return {
...fallbackMetadata(filePath),
coverPath: target
coverPath: null
};
}