Update fedapi.ts

This commit is contained in:
XSWY 2026-06-07 15:45:34 +03:00 committed by GitHub
parent 501baf493a
commit 7743618c33
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -1,12 +1,11 @@
import { flags } from '@/entrypoint/utils/targets';
import { SourcererOutput, makeSourcerer } from '@/providers/base';
import { MovieScrapeContext, ShowScrapeContext } from '@/utils/context';
import { NotFoundError } from '@/utils/errors';
import { Caption, labelToLanguageCode } from '../../captions';
import { labelToLanguageCode } from '../../captions';
const BASE_URL = 'https://fedapi.asteral-ss2.workers.dev';
const getUserToken = (): string | null => {
const getUserToken = () => {
try {
if (typeof window === 'undefined') return null;
@ -14,26 +13,29 @@ const getUserToken = (): string | null => {
if (!prefData) return null;
const parsed = JSON.parse(prefData);
return parsed?.state?.febboxKey ?? null;
return parsed?.state?.febboxKey || null;
} catch {
return null;
}
};
const getRegion = (): string | null => {
const getRegion = () => {
try {
if (typeof window === 'undefined') return null;
const regionData = window.localStorage.getItem('__MW::region');
if (!regionData) return null;
const parsed = JSON.parse(regionData);
return parsed?.state?.region ?? null;
} catch (e) {
return parsed?.state?.region || null;
} catch {
return null;
}
};
function selectSubdomainByRegion(input: string | null): string | null {
function selectSubdomainByRegion(input) {
const region = (input || '').toLowerCase();
const match = region.match(/(usa5|usa6|usa7|uk1|de2|hk1|ca1|au1|sg1|in1)/);
if (match) return match[1];
@ -41,37 +43,44 @@ function selectSubdomainByRegion(input: string | null): string | null {
if (region.includes('portland')) return 'usa6';
if (region.includes('new-york')) return 'usa7';
if (region.includes('paris')) return Math.random() < 0.5 ? 'uk1' : 'de2';
return null;
return null;
}
function rewriteSheguSubdomain(originalUrl: string, subdomain: string): string {
function rewriteSheguSubdomain(url, subdomain) {
try {
const parsed = new URL(originalUrl);
const parsed = new URL(url);
if (parsed.hostname.endsWith('.shegu.net')) {
parsed.hostname = `${subdomain}.shegu.net`;
return parsed.toString();
}
return originalUrl;
return url;
} catch {
return originalUrl;
return url;
}
}
async function FedScraper(ctx: MovieScrapeContext | ShowScrapeContext): Promise<SourcererOutput> {
async function FedScraper(ctx) {
const token = getUserToken();
if (!token) throw new NotFoundError('Missing user token');
const tmdbId = ctx.media.tmdbId;
if (!tmdbId) throw new NotFoundError('Missing TMDB ID');
const region = getRegion();
ctx.progress(30);
const url = ctx.media.type === 'movie'
? `${BASE_URL}/movie/${tmdbId}`
: `${BASE_URL}/tv/${tmdbId}/${ctx.media.season.number}/${ctx.media.episode.number}`;
const url =
ctx.media.type === 'movie'
? `${BASE_URL}/movie/${tmdbId}`
: `${BASE_URL}/tv/${tmdbId}/${ctx.media.season.number}/${ctx.media.episode.number}`;
const data = await ctx.fetcher<any>(url);
const data = await ctx.fetcher(url);
if (!data || !data.success || !data.stream) {
throw new NotFoundError('No stream found in Thunderleaf');
throw new NotFoundError('No stream found');
}
let finalStreamUrl = data.stream;
@ -83,12 +92,15 @@ async function FedScraper(ctx: MovieScrapeContext | ShowScrapeContext): Promise<
ctx.progress(80);
const captions: Caption[] = [];
const captions = [];
if (data.subtitles) {
Object.entries(data.subtitles).forEach(([langKey, sub]: [string, any]) => {
Object.entries(data.subtitles).forEach(([langKey, sub]) => {
const languageName = langKey.split('_')[0];
const languageCode = labelToLanguageCode(languageName)?.toLowerCase() ?? 'unknown';
if (sub.url) {
const languageCode =
labelToLanguageCode(languageName)?.toLowerCase() || 'unknown';
if (sub?.url) {
captions.push({
type: sub.url.endsWith('.vtt') ? 'vtt' : 'srt',
id: sub.url,
@ -100,24 +112,24 @@ async function FedScraper(ctx: MovieScrapeContext | ShowScrapeContext): Promise<
});
}
const stream =
token
? [
{
return {
embeds: [],
stream: [
{
id: 'primary',
type: 'file',
flags: [],
flags: [],
captions,
qualities: {
unknown: {
type: 'mp4',
url: finalStreamUrl,
qualities: {
unknown: {
type: 'mp4',
url: finalStreamUrl,
},
},
headers: {},
} as const,
],
return { embeds: [], stream };
},
],
};
}
export const FedApiScraper = makeSourcerer({