92 lines
3.3 KiB
TypeScript
92 lines
3.3 KiB
TypeScript
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<boolean> {
|
|
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<SearchResult[]> {
|
|
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<SearchResult[]> {
|
|
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<SearchResult[]> {
|
|
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<ContentLinks> {
|
|
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<SelectionData> {
|
|
const content = await this.getContentLinks(identifier);
|
|
|
|
return {
|
|
links: content.links,
|
|
seasons: [],
|
|
isSeries: type === 'series'
|
|
};
|
|
}
|
|
}
|
|
|
|
// ── Auto-registration ──
|
|
sourceRegistry.register(new FS24Source());
|