// Bibliotheks-Refresh des Medienservers anstoßen (KONZEPT § 6.10) — // Wege aus medien.py: Jellyfin/Emby per POST /Library/Refresh mit // X-Emby-Token; Kodi per JSON-RPC VideoLibrary.Scan mit Basic-Auth // (api_key = "user:passwort"). Wirft NIE — der Refresh ist Komfort, // nicht Teil des Rips (R4: das Ergebnis wird trotzdem GEMELDET). export type MedienServer = 'jellyfin' | 'emby' | 'kodi' | 'plex' | 'none' export async function bibliothekRefresh( server: string, url: string, apiKey: string, holen: typeof fetch = fetch, ): Promise { if (url.length === 0 || !['jellyfin', 'emby', 'kodi'].includes(server)) return '' try { if ((server === 'jellyfin' || server === 'emby') && apiKey.length > 0) { const antwort = await holen(url.replace(/\/+$/, '') + '/Library/Refresh', { method: 'POST', headers: { 'X-Emby-Token': apiKey }, signal: AbortSignal.timeout(15_000), }) if (antwort.status < 300) { return `${server[0].toUpperCase()}${server.slice(1)}-Bibliothek aktualisiert (${url})` } return `Bibliotheks-Refresh: HTTP ${antwort.status} von ${url}` } if (server === 'kodi') { const kopf: Record = { 'Content-Type': 'application/json' } if (apiKey.includes(':')) { kopf['Authorization'] = 'Basic ' + Buffer.from(apiKey).toString('base64') } const antwort = await holen(url.replace(/\/+$/, '') + '/jsonrpc', { method: 'POST', headers: kopf, body: JSON.stringify({ jsonrpc: '2.0', method: 'VideoLibrary.Scan', id: 1 }), signal: AbortSignal.timeout(15_000), }) if (antwort.status < 300) return `Kodi-Bibliothek aktualisiert (${url})` return `Kodi-Refresh: HTTP ${antwort.status} von ${url}` } } catch (fehler) { return `Bibliotheks-Refresh fehlgeschlagen: ${String(fehler)}` } return '' }