running sources/embeds + media input

This commit is contained in:
mrjvs
2023-08-25 22:29:50 +02:00
parent ffe5cf5369
commit 59b2aa22f7
8 changed files with 119 additions and 14 deletions

View File

@@ -15,3 +15,15 @@ features:
> TODO documentation: how to use + usecases
> TODO documentation: examples on how to make a custom fetcher
> TODO functionality: running individual scrapers
> TODO functionality: running all scrapers
> TODO functionality: choose environment (for browser, for native)
> TODO functionality: show which types are supported for scraper in meta
> TODO content: add all scrapers/providers
> TODO tests: add tests

19
docs/basic.js Normal file
View File

@@ -0,0 +1,19 @@
async function example() {
const providers = makeProviders({
fetcher: makeStandardFetcher(fetch),
});
const source = await providers.runAll({
media: {
title: 'Spider-Man: Across the Spider-Verse',
releaseYear: 2023,
imbdId: 'tt9362722',
tmdbId: '569094',
type: 'movie',
},
});
if (!source) throw new Error("Couldn't find a stream");
if (source.stream.type === 'file') return source.stream.qualities['1080']?.url;
if (source.stream.type === 'hls') return source.stream.playlist;
}

View File

@@ -1 +1,2 @@
export { makeStandardFetcher } from '@/fetchers/standardFetch';
export { ProviderBuilderOptions, ProviderControls, makeProviders } from '@/main/builder';

View File

@@ -1,12 +1,10 @@
import { Fetcher } from '@/fetchers/types';
import { FullScraperEvents, SingleScraperEvents } from '@/main/events';
import { FullScraperEvents } from '@/main/events';
import { ScrapeMedia } from '@/main/media';
import { MetaOutput, getAllEmbedMetaSorted, getAllSourceMetaSorted, getSpecificId } from '@/main/meta';
import { ProviderRunnerOptions, RunOutput, SourceRunOutput, runAllProviders } from '@/main/runner';
import { RunOutput, runAllProviders } from '@/main/runner';
import { getProviders } from '@/providers/all';
// TODO meta data input (tmdb id, imdb id, title, release year)
// TODO actually running scrapers
export interface ProviderBuilderOptions {
// fetcher, every web request gets called through here
fetcher: Fetcher;
@@ -16,13 +14,24 @@ export interface ProviderBuilderOptions {
proxiedFetcher?: Fetcher;
}
export interface RunnerOptions {
// overwrite the order of sources to run. list of ids
sourceOrder?: string[];
// overwrite the order of embeds to run. list of ids
embedOrder?: string[];
// object of event functions
events?: FullScraperEvents;
// the media you want to see sources from
media: ScrapeMedia;
}
export interface ProviderControls {
// Run all providers one by one. in order of rank (highest first)
// returns the stream, or null if none found
runAll(cbs: FullScraperEvents): Promise<RunOutput | null>;
// Run a source provider
runSource(id: string, cbs: SingleScraperEvents): Promise<SourceRunOutput>;
runAll(runnerOps: RunnerOptions): Promise<RunOutput | null>;
// get meta data about a source or embed.
getMetadata(id: string): MetaOutput | null;
@@ -36,14 +45,17 @@ export interface ProviderControls {
export function makeProviders(ops: ProviderBuilderOptions): ProviderControls {
const list = getProviders();
const providerRunnerOps: ProviderRunnerOptions = {
const providerRunnerOps = {
fetcher: ops.fetcher,
proxiedFetcher: ops.proxiedFetcher ?? ops.fetcher,
};
return {
runAll(cbs) {
return runAllProviders(providerRunnerOps, cbs);
runAll(runnerOps: RunnerOptions) {
return runAllProviders({
...providerRunnerOps,
...runnerOps,
});
},
getMetadata(id) {
return getSpecificId(list, id);

26
src/main/media.ts Normal file
View File

@@ -0,0 +1,26 @@
export type CommonMedia = {
title: string;
releaseYear: number;
imbdId: string;
tmdbId: string;
};
export type MediaTypes = 'show' | 'movie';
export type ShowMedia = CommonMedia & {
type: 'show';
episode: {
number: number;
tmdbId: string;
};
season: {
number: number;
tmdbId: string;
};
};
export type MovieMedia = CommonMedia & {
type: 'movie';
};
export type ScrapeMedia = ShowMedia | MovieMedia;

View File

@@ -1,5 +1,6 @@
import { Fetcher } from '@/fetchers/types';
import { FullScraperEvents } from '@/main/events';
import { ScrapeMedia } from '@/main/media';
import { Stream } from '@/providers/streams';
export type RunOutput = {
@@ -22,9 +23,13 @@ export type EmbedRunOutput = {
export type ProviderRunnerOptions = {
fetcher: Fetcher;
proxiedFetcher: Fetcher;
sourceOrder?: string[];
embedOrder?: string[];
events?: FullScraperEvents;
media: ScrapeMedia;
};
export async function runAllProviders(_ops: ProviderRunnerOptions, _cbs: FullScraperEvents): Promise<RunOutput | null> {
export async function runAllProviders(_ops: ProviderRunnerOptions): Promise<RunOutput | null> {
return {
sourceId: '123',
stream: {

View File

@@ -1,3 +1,4 @@
import { MovieMedia, ShowMedia } from '@/main/media';
import { Stream } from '@/providers/streams';
import { EmbedScrapeContext, ScrapeContext } from '@/utils/context';
@@ -14,7 +15,8 @@ export type Sourcerer = {
name: string; // displayed in the UI
rank: number; // the higher the number, the earlier it gets put on the queue
disabled?: boolean;
scrape: (input: ScrapeContext) => Promise<SourcererOutput>;
scrapeMovie?: (input: ScrapeContext & { media: MovieMedia }) => Promise<SourcererOutput>;
scrapeShow: (input: ScrapeContext & { media: ShowMedia }) => Promise<SourcererOutput>;
};
export function makeSourcerer(state: Sourcerer): Sourcerer | null {

View File

@@ -0,0 +1,28 @@
import { makeSourcerer } from '@/providers/base';
export const flixHq = makeSourcerer({
id: 'flixhq',
name: 'FlixHQ',
rank: 500,
async scrapeShow(_input) {
return {
embeds: [],
stream: {
type: 'file',
qualities: {
'360': {
type: 'mp4',
url: 'blabal.mp4',
},
},
},
};
},
async scrapeMovie(_input) {
return {
embeds: [],
};
},
});