feat(api,shared): métadonnées multi-providers et automatisation des scans/enrichissements
Chaîne de résolution metadata (local, Open Library, Google Books, BNF) avec activation/priorité/clé API par provider, colonnes isbn13 et identifiers sur les livres, et intégration au scanner pour compléter métadonnées et jaquettes manquantes. Module automation: réglages persistés, planifications scan/enrichissement et déclenchement manuel, exposés via des endpoints admin. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
33
apps/api/src/metadata/adapters/open-library.provider.ts
Normal file
33
apps/api/src/metadata/adapters/open-library.provider.ts
Normal file
@ -0,0 +1,33 @@
|
||||
import { Injectable } from "@nestjs/common";
|
||||
import { MetadataLookup, MetadataMatch, MetadataProvider, MetadataProviderConfig } from "../metadata.types.js";
|
||||
|
||||
@Injectable()
|
||||
export class OpenLibraryProvider implements MetadataProvider {
|
||||
readonly id = "openlibrary" as const;
|
||||
|
||||
async lookup(lookup: MetadataLookup, _config: MetadataProviderConfig): Promise<MetadataMatch | null> {
|
||||
const query = lookup.identifiers.isbn13
|
||||
? `isbn:${encodeURIComponent(lookup.identifiers.isbn13)}`
|
||||
: `title:${encodeURIComponent(lookup.title)}${lookup.author ? ` author:${encodeURIComponent(lookup.author)}` : ""}`;
|
||||
const response = await fetch(`https://openlibrary.org/search.json?q=${query}&limit=1`, {
|
||||
headers: { "User-Agent": "ReadaBook/0.1 local-library-manager" },
|
||||
signal: AbortSignal.timeout(4000)
|
||||
});
|
||||
if (!response.ok) return null;
|
||||
const data = (await response.json()) as { docs?: Array<Record<string, unknown>> };
|
||||
const doc = data.docs?.[0];
|
||||
if (!doc) return null;
|
||||
return {
|
||||
author: firstArrayValue(doc.author_name),
|
||||
language: firstArrayValue(doc.language),
|
||||
publisher: firstArrayValue(doc.publisher),
|
||||
publishedDate: String(doc.first_publish_year ?? "") || null,
|
||||
isbn: firstArrayValue(doc.isbn)
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
function firstArrayValue(value: unknown): string | null {
|
||||
if (!Array.isArray(value) || !value.length) return null;
|
||||
return String(value[0]);
|
||||
}
|
||||
Reference in New Issue
Block a user