93 lines
2.9 KiB
JavaScript
93 lines
2.9 KiB
JavaScript
const settingsService = require('./settingsService');
|
|
const logger = require('./logger').child('OMDB');
|
|
|
|
class OmdbService {
|
|
async search(query) {
|
|
if (!query || query.trim().length === 0) {
|
|
return [];
|
|
}
|
|
logger.info('search:start', { query });
|
|
|
|
const settings = await settingsService.getSettingsMap();
|
|
const apiKey = settings.omdb_api_key;
|
|
if (!apiKey) {
|
|
return [];
|
|
}
|
|
|
|
const type = settings.omdb_default_type || 'movie';
|
|
const url = new URL('https://www.omdbapi.com/');
|
|
url.searchParams.set('apikey', apiKey);
|
|
url.searchParams.set('s', query.trim());
|
|
url.searchParams.set('type', type);
|
|
|
|
const response = await fetch(url);
|
|
if (!response.ok) {
|
|
logger.error('search:http-failed', { query, status: response.status });
|
|
throw new Error(`OMDb Anfrage fehlgeschlagen (${response.status})`);
|
|
}
|
|
|
|
const data = await response.json();
|
|
if (data.Response === 'False' || !Array.isArray(data.Search)) {
|
|
logger.warn('search:no-results', { query, response: data.Response, error: data.Error });
|
|
return [];
|
|
}
|
|
const results = data.Search.map((item) => ({
|
|
title: item.Title,
|
|
year: item.Year,
|
|
imdbId: item.imdbID,
|
|
type: item.Type,
|
|
poster: item.Poster
|
|
}));
|
|
logger.info('search:done', { query, count: results.length });
|
|
return results;
|
|
}
|
|
|
|
async fetchByImdbId(imdbId) {
|
|
const normalizedId = String(imdbId || '').trim().toLowerCase();
|
|
if (!/^tt\d{6,12}$/.test(normalizedId)) {
|
|
return null;
|
|
}
|
|
|
|
logger.info('fetchByImdbId:start', { imdbId: normalizedId });
|
|
const settings = await settingsService.getSettingsMap();
|
|
const apiKey = settings.omdb_api_key;
|
|
if (!apiKey) {
|
|
return null;
|
|
}
|
|
|
|
const url = new URL('https://www.omdbapi.com/');
|
|
url.searchParams.set('apikey', apiKey);
|
|
url.searchParams.set('i', normalizedId);
|
|
url.searchParams.set('plot', 'full');
|
|
|
|
const response = await fetch(url);
|
|
if (!response.ok) {
|
|
logger.error('fetchByImdbId:http-failed', { imdbId: normalizedId, status: response.status });
|
|
throw new Error(`OMDb Anfrage fehlgeschlagen (${response.status})`);
|
|
}
|
|
|
|
const data = await response.json();
|
|
if (data.Response === 'False') {
|
|
logger.warn('fetchByImdbId:not-found', { imdbId: normalizedId, error: data.Error });
|
|
return null;
|
|
}
|
|
|
|
const yearMatch = String(data.Year || '').match(/\b(19|20)\d{2}\b/);
|
|
const year = yearMatch ? Number(yearMatch[0]) : null;
|
|
const poster = data.Poster && data.Poster !== 'N/A' ? data.Poster : null;
|
|
|
|
const result = {
|
|
title: data.Title || null,
|
|
year: Number.isFinite(year) ? year : null,
|
|
imdbId: String(data.imdbID || normalizedId),
|
|
type: data.Type || null,
|
|
poster,
|
|
raw: data
|
|
};
|
|
logger.info('fetchByImdbId:done', { imdbId: result.imdbId, title: result.title });
|
|
return result;
|
|
}
|
|
}
|
|
|
|
module.exports = new OmdbService();
|