import { ISource, SearchResult, ContentLinks, MediaType, SelectionData } from '../../src/types/source.js'; import { sourceRegistry } from '../../src/core/registry.js'; import { FS24API } from './api.js'; import { FS24Auth } from './auth.js'; import { parseListingHTML, extractNewsId, parseReleasesJSON } from './parser.js'; export class FS24Source implements ISource { public readonly name = 'fs24'; public readonly displayName = 'FS24'; public async healthCheck(): Promise { try { await FS24Auth.getCookie(true); return true; } catch (e: any) { console.error(`[FS24] HealthCheck échoué: ${e.message}`); return false; } } public async search(query: string, mediaType?: MediaType): Promise { if (!query || query.length < 3) return []; try { const html = await FS24API.fetchSearch(query); const results = parseListingHTML(html, mediaType || 'movie'); return results; } catch (e: any) { console.error(`[FS24] Erreur search: ${e.message}`); return []; } } public async getTrending(mediaType: MediaType): Promise { try { const html = await FS24API.fetchTrending(mediaType === 'series' ? 'series' : 'movie'); const results = parseListingHTML(html, mediaType); return results.slice(0, 20); // Keep top 20 } catch (e: any) { console.error(`[FS24] Erreur trending: ${e.message}`); return []; } } public async getRecent(): Promise { try { const html = await FS24API.fetchRecent(); const results = parseListingHTML(html, 'movie'); // Default to movie for recents, TMDB will fix it if needed return results.slice(0, 20); } catch (e: any) { console.error(`[FS24] Erreur recent: ${e.message}`); return []; } } public async getContentLinks(identifier: string, season?: number): Promise { try { // Step 1: Fetch the page HTML to extract the news_id const html = await FS24API.fetchPage(identifier); const newsId = extractNewsId(html); if (!newsId) { console.warn(`[FS24] Impossible d'extraire le news_id depuis: ${identifier}`); return { links: [] }; } // Step 2: Call the release JSON API to get the actual download links const releaseData = await FS24API.fetchReleases(newsId); const links = parseReleasesJSON(releaseData); console.log(`[FS24] ${links.length} lien(s) trouvé(s) pour post_id=${newsId}`); return { links }; } catch (e: any) { console.error(`[FS24] Erreur getContentLinks: ${e.message}`); return { links: [] }; } } public async getSelection(identifier: string, type?: string, seasonValue?: string | number): Promise { const content = await this.getContentLinks(identifier); return { links: content.links, seasons: [], isSeries: type === 'series' }; } } // ── Auto-registration ── sourceRegistry.register(new FS24Source());