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>
39 lines
1.6 KiB
TypeScript
39 lines
1.6 KiB
TypeScript
import { Injectable } from "@nestjs/common";
|
|
import { XMLParser } from "fast-xml-parser";
|
|
import { MetadataLookup, MetadataMatch, MetadataProvider, MetadataProviderConfig } from "../metadata.types.js";
|
|
|
|
const parser = new XMLParser({ ignoreAttributes: false, attributeNamePrefix: "@_" });
|
|
|
|
@Injectable()
|
|
export class BnfProvider implements MetadataProvider {
|
|
readonly id = "bnf" as const;
|
|
|
|
async lookup(lookup: MetadataLookup, _config: MetadataProviderConfig): Promise<MetadataMatch | null> {
|
|
const query = lookup.identifiers.isbn13
|
|
? `bib.isbn all "${lookup.identifiers.isbn13}"`
|
|
: `bib.title all "${lookup.title.replace(/"/g, " ")}"`;
|
|
const url = new URL("https://catalogue.bnf.fr/api/SRU");
|
|
url.searchParams.set("version", "1.2");
|
|
url.searchParams.set("operation", "searchRetrieve");
|
|
url.searchParams.set("query", query);
|
|
url.searchParams.set("maximumRecords", "1");
|
|
|
|
const response = await fetch(url, { signal: AbortSignal.timeout(5000) });
|
|
if (!response.ok) return null;
|
|
const parsed = parser.parse(await response.text());
|
|
const record = parsed?.searchRetrieveResponse?.records?.record?.recordData;
|
|
if (!record) return null;
|
|
const text = JSON.stringify(record);
|
|
return {
|
|
title: match(text, /"titleInfo"[^}]*"title":"([^"]+)"/),
|
|
author: match(text, /"namePart":"([^"]+)"/),
|
|
publisher: match(text, /"publisher":"([^"]+)"/),
|
|
publishedDate: match(text, /"dateIssued":"([^"]+)"/)
|
|
};
|
|
}
|
|
}
|
|
|
|
function match(value: string, pattern: RegExp): string | undefined {
|
|
return value.match(pattern)?.[1];
|
|
}
|