Merge pull request #14 from ztpn/fsharetv

Add fsharetv source
This commit is contained in:
TPN 2024-07-17 18:27:39 +05:30 committed by GitHub
commit ee539bc0ed
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 92 additions and 0 deletions

View File

@ -18,6 +18,7 @@ import { autoembedScraper } from '@/providers/sources/autoembed';
import { catflixScraper } from '@/providers/sources/catflix';
import { ee3Scraper } from '@/providers/sources/ee3';
import { flixhqScraper } from '@/providers/sources/flixhq/index';
import { fsharetvScraper } from '@/providers/sources/fsharetv';
import { goMoviesScraper } from '@/providers/sources/gomovies/index';
import { insertunitScraper } from '@/providers/sources/insertunit';
import { kissAsianScraper } from '@/providers/sources/kissasian/index';
@ -96,6 +97,7 @@ export function gatherAllSources(): Array<Sourcerer> {
tugaflixScraper,
ee3Scraper,
whvxScraper,
fsharetvScraper,
];
}

View File

@ -0,0 +1,90 @@
import { load } from 'cheerio';
import { SourcererOutput, makeSourcerer } from '@/providers/base';
import { FileBasedStream } from '@/providers/streams';
import { compareMedia } from '@/utils/compare';
import { MovieScrapeContext, ShowScrapeContext } from '@/utils/context';
import { NotFoundError } from '@/utils/errors';
import { getValidQualityFromString } from '@/utils/quality';
const baseUrl = 'https://fsharetv.co';
async function comboScraper(ctx: ShowScrapeContext | MovieScrapeContext): Promise<SourcererOutput> {
const searchPage = await ctx.proxiedFetcher('/search', {
baseUrl,
query: {
q: ctx.media.title,
},
});
const search$ = load(searchPage);
const searchResults: { title: string; year?: number; url: string }[] = [];
search$('.movie-item').each((_, element) => {
const [, title, year] =
search$(element)
.find('b')
.text()
?.match(/^(.*?)\s*(?:\(?\s*(\d{4})(?:\s*-\s*\d{0,4})?\s*\)?)?\s*$/) || [];
const url = search$(element).find('a').attr('href');
if (!title || !url) return;
searchResults.push({ title, year: Number(year) ?? undefined, url });
});
const watchPageUrl = searchResults.find((x) => x && compareMedia(ctx.media, x.title, x.year))?.url;
if (!watchPageUrl) throw new NotFoundError('No watchable item found');
const watchPage = await ctx.proxiedFetcher(watchPageUrl.replace('/movie', '/w'), { baseUrl });
const fileId = watchPage.match(/Movie\.setSource\('([^']*)'/)?.[1];
if (!fileId) throw new Error('File ID not found');
const apiRes: { data: { file: { sources: { src: string; quality: string | number }[] } } } = await ctx.proxiedFetcher(
`/api/file/${fileId}/source`,
{
baseUrl,
query: {
type: 'watch',
},
},
);
if (!apiRes.data.file.sources.length) throw new Error('No sources found');
const qualities = apiRes.data.file.sources.reduce(
(acc, source) => {
const quality = typeof source.quality === 'number' ? source.quality.toString() : source.quality;
const validQuality = getValidQualityFromString(quality);
acc[validQuality] = {
type: 'mp4',
url: `${baseUrl}${source.src}`,
};
return acc;
},
{} as FileBasedStream['qualities'],
);
return {
embeds: [],
stream: [
{
id: 'primary',
type: 'file',
flags: [],
headers: {
referer: 'https://fsharetv.co',
},
qualities,
captions: [],
},
],
};
}
export const fsharetvScraper = makeSourcerer({
id: 'fsharetv',
name: 'FshareTV',
rank: 93,
flags: [],
scrapeMovie: comboScraper,
});