Initial commit (v1.5.9)
This commit is contained in:
@@ -0,0 +1,112 @@
|
||||
import { SearchResult, VideoLink, SeasonOption, SelectionData, ContentLinks } from '../../src/types/source.js';
|
||||
import { FlixArtAuth } from './auth.js';
|
||||
import { FlixArtParser } from './parser.js';
|
||||
import { CONFIG } from '../../src/utils/config.js';
|
||||
|
||||
export class FlixArtAPI {
|
||||
private static get baseUrl() { return CONFIG.FLIXART_URL || ''; }
|
||||
private static get ajaxUrl() { return `${this.baseUrl}/wp-admin/admin-ajax.php`; }
|
||||
private static userAgent = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64)';
|
||||
|
||||
// Cache the film page data temporarily for resolveLink
|
||||
private static contextCache: { [url: string]: { postId: string, nonce: string, type: string } } = {};
|
||||
|
||||
private static async fetchWithAuth(url: string, options: RequestInit = {}, retries = 1): Promise<Response> {
|
||||
try {
|
||||
const cookie = await FlixArtAuth.getCookie();
|
||||
|
||||
const headers = new Headers(options.headers || {});
|
||||
headers.set('User-Agent', this.userAgent);
|
||||
headers.set('Cookie', cookie);
|
||||
headers.set('Origin', this.baseUrl);
|
||||
headers.set('Referer', this.baseUrl);
|
||||
|
||||
const response = await fetch(url, { ...options, headers });
|
||||
|
||||
// If FlixArt returns 403 or redirects to login, refresh cookie and retry
|
||||
if (response.status === 403 && retries > 0) {
|
||||
console.log('[FlixArt] Session expirée, renouvellement du cookie...');
|
||||
await FlixArtAuth.getCookie(true);
|
||||
return this.fetchWithAuth(url, options, retries - 1);
|
||||
}
|
||||
|
||||
return response;
|
||||
} catch (error) {
|
||||
if (retries > 0) {
|
||||
await FlixArtAuth.getCookie(true);
|
||||
return this.fetchWithAuth(url, options, retries - 1);
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
public static async search(query: string, mediaType?: string): Promise<SearchResult[]> {
|
||||
const body = new URLSearchParams({
|
||||
action: 'flixart_header_search',
|
||||
s: query,
|
||||
search: query,
|
||||
type_query: 'all',
|
||||
post_type: mediaType === 'series' ? 'tv_shows' : 'movies'
|
||||
});
|
||||
|
||||
// Search works without auth, but we use fetchWithAuth just in case
|
||||
const res = await this.fetchWithAuth(this.ajaxUrl, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/x-www-form-urlencoded',
|
||||
'X-Requested-With': 'XMLHttpRequest'
|
||||
},
|
||||
body: body.toString()
|
||||
});
|
||||
|
||||
const data = await res.json();
|
||||
if (data.success && data.data && data.data.results) {
|
||||
return FlixArtParser.parseSearchAjax(data.data.results);
|
||||
}
|
||||
return [];
|
||||
}
|
||||
|
||||
public static async getTrending(mediaType: 'movie' | 'series'): Promise<SearchResult[]> {
|
||||
const res = await this.fetchWithAuth(this.baseUrl, { method: 'GET' });
|
||||
const html = await res.text();
|
||||
return FlixArtParser.parseTrending(html, mediaType === 'series');
|
||||
}
|
||||
|
||||
public static async getSelection(url: string): Promise<SelectionData> {
|
||||
const res = await this.fetchWithAuth(url, { method: 'GET' });
|
||||
const html = await res.text();
|
||||
|
||||
const parsed = FlixArtParser.parseSelection(html);
|
||||
|
||||
// Cache post data for resolveLink
|
||||
if (parsed.postId && parsed.nonce) {
|
||||
this.contextCache[url] = {
|
||||
postId: parsed.postId,
|
||||
nonce: parsed.nonce,
|
||||
type: parsed.isSeries ? 'tv_shows' : 'movies' // Note: actually parser returns isSeries. Captcha needs 'movies' or 'tv_shows'
|
||||
};
|
||||
}
|
||||
|
||||
// Prefix ID with url to pass state to resolveLink
|
||||
parsed.links.forEach((link: any) => {
|
||||
link.id = `${url}|${link.id}`;
|
||||
});
|
||||
|
||||
return {
|
||||
links: parsed.links,
|
||||
seasons: parsed.seasons,
|
||||
isSeries: parsed.isSeries
|
||||
};
|
||||
}
|
||||
|
||||
public static async getContentLinks(url: string, season?: number): Promise<ContentLinks> {
|
||||
// Not used heavily if getSelection is prioritized, but we need to fetch the season HTML via ajax
|
||||
// For simplicity, if season is passed, we fetch season content via AJAX.
|
||||
// Actually, FlixArt loads all episodes HTML when you click a season tab.
|
||||
// For now, getSelection is sufficient.
|
||||
const selection = await this.getSelection(url);
|
||||
return { links: selection.links };
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user