fix(v5): Laufzeit-Pfade plattformneutral — pipeline/struktur auf node:path
Ampel / ampel (push) Successful in 1m21s
Ampel / ampel (push) Successful in 1m21s
Der NFO-Ablage-Test brach in der Linux-CI: pipeline/struktur bauten mit path.win32 auf POSIX-Testordnern (mkdir legte 'x\Filme' als EINEN Namen an, readdir fand nichts). Regel jetzt dokumentiert: Module ueber LAUFZEIT-Wurzeln (Ablage) nutzen plattform-path — zur echten Laufzeit immer Windows, in der CI physisch korrekt auf POSIX; Module mit FESTER Windows-Semantik (katalog, dateiDaneben) bleiben bei path.win32. Testerwartungen entsprechend ueber join() statt Literale. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Fable 5
parent
3dc296f071
commit
e840b7f327
@@ -0,0 +1,59 @@
|
||||
// OMDb-Client — eigene Datenbasis, findet oft, was TMDb nicht exakt
|
||||
// trifft. Nur Englisch; der deutsche Datensatz wird danach über
|
||||
// TMDb /find (IMDb-ID) nachgeladen (zuordnung.ts). Ohne Key überspringt
|
||||
// er sich selbst — kein Fehler, keine Behauptung.
|
||||
|
||||
export interface OmdbTreffer {
|
||||
type: 'movie' | 'tv'
|
||||
id: string
|
||||
title: string
|
||||
year: number | null
|
||||
overview: string
|
||||
poster_path: string
|
||||
runtime: number
|
||||
genres: string[]
|
||||
source: 'omdb'
|
||||
}
|
||||
|
||||
export class OmdbClient {
|
||||
constructor(
|
||||
private readonly apiKey: string,
|
||||
private readonly holen: typeof fetch = fetch,
|
||||
) {}
|
||||
|
||||
get verfuegbar(): boolean {
|
||||
return this.apiKey.length > 0
|
||||
}
|
||||
|
||||
async lookup(titel: string): Promise<OmdbTreffer | null> {
|
||||
if (!this.verfuegbar) return null
|
||||
try {
|
||||
const url = new URL('https://www.omdbapi.com/')
|
||||
url.searchParams.set('apikey', this.apiKey)
|
||||
url.searchParams.set('t', titel)
|
||||
url.searchParams.set('r', 'json')
|
||||
const antwort = await this.holen(url.toString(), { signal: AbortSignal.timeout(15_000) })
|
||||
if (antwort.status >= 300) return null
|
||||
const daten = (await antwort.json()) as Record<string, string>
|
||||
if (daten['Response'] !== 'True') return null
|
||||
const jahr = /(\d{4})/.exec(daten['Year'] ?? '')
|
||||
const laufzeit = /(\d+)/.exec(daten['Runtime'] ?? '')
|
||||
return {
|
||||
type: daten['Type'] === 'series' ? 'tv' : 'movie',
|
||||
id: daten['imdbID'] ?? '',
|
||||
title: daten['Title'] ?? titel,
|
||||
year: jahr === null ? null : Number(jahr[1]),
|
||||
overview: daten['Plot'] ?? '',
|
||||
poster_path: daten['Poster'] !== 'N/A' ? (daten['Poster'] ?? '') : '',
|
||||
runtime: laufzeit === null ? 0 : Number(laufzeit[1]),
|
||||
genres: (daten['Genre'] ?? '')
|
||||
.split(',')
|
||||
.map((g) => g.trim())
|
||||
.filter((g) => g.length > 0),
|
||||
source: 'omdb',
|
||||
}
|
||||
} catch {
|
||||
return null
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user