diff --git a/README.md b/README.md index 14a1337..f9b5661 100644 --- a/README.md +++ b/README.md @@ -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 diff --git a/docs/basic.js b/docs/basic.js new file mode 100644 index 0000000..7acc249 --- /dev/null +++ b/docs/basic.js @@ -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; +} diff --git a/src/index.ts b/src/index.ts index 97173d5..9025534 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1 +1,2 @@ +export { makeStandardFetcher } from '@/fetchers/standardFetch'; export { ProviderBuilderOptions, ProviderControls, makeProviders } from '@/main/builder'; diff --git a/src/main/builder.ts b/src/main/builder.ts index ee96ba1..bb4d114 100644 --- a/src/main/builder.ts +++ b/src/main/builder.ts @@ -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; - - // Run a source provider - runSource(id: string, cbs: SingleScraperEvents): Promise; + runAll(runnerOps: RunnerOptions): Promise; // 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); diff --git a/src/main/media.ts b/src/main/media.ts new file mode 100644 index 0000000..8acc8e1 --- /dev/null +++ b/src/main/media.ts @@ -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; diff --git a/src/main/runner.ts b/src/main/runner.ts index b2627e0..75203af 100644 --- a/src/main/runner.ts +++ b/src/main/runner.ts @@ -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 { +export async function runAllProviders(_ops: ProviderRunnerOptions): Promise { return { sourceId: '123', stream: { diff --git a/src/providers/base.ts b/src/providers/base.ts index 373989a..df414f2 100644 --- a/src/providers/base.ts +++ b/src/providers/base.ts @@ -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; + scrapeMovie?: (input: ScrapeContext & { media: MovieMedia }) => Promise; + scrapeShow: (input: ScrapeContext & { media: ShowMedia }) => Promise; }; export function makeSourcerer(state: Sourcerer): Sourcerer | null { diff --git a/src/providers/sources/flixhq.ts b/src/providers/sources/flixhq.ts new file mode 100644 index 0000000..eff0750 --- /dev/null +++ b/src/providers/sources/flixhq.ts @@ -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: [], + }; + }, +});