mirror of
https://github.com/movie-web/providers.git
synced 2025-09-13 13:33:25 +00:00
running sources/embeds + media input
This commit is contained in:
12
README.md
12
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
|
||||
|
19
docs/basic.js
Normal file
19
docs/basic.js
Normal 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;
|
||||
}
|
@@ -1 +1,2 @@
|
||||
export { makeStandardFetcher } from '@/fetchers/standardFetch';
|
||||
export { ProviderBuilderOptions, ProviderControls, makeProviders } from '@/main/builder';
|
||||
|
@@ -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
26
src/main/media.ts
Normal 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;
|
@@ -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: {
|
||||
|
@@ -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 {
|
||||
|
28
src/providers/sources/flixhq.ts
Normal file
28
src/providers/sources/flixhq.ts
Normal 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: [],
|
||||
};
|
||||
},
|
||||
});
|
Reference in New Issue
Block a user