Files
ripster/backend/src/services/omdbService.js
T

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();