diff --git a/src/controller/ConfigureController.ts b/src/controller/ConfigureController.ts index 7c65262..d3f8965 100644 --- a/src/controller/ConfigureController.ts +++ b/src/controller/ConfigureController.ts @@ -1,18 +1,18 @@ import { Request, Response, Router } from 'express'; import { landingTemplate } from '../landingTemplate'; import { buildManifest, getDefaultConfig } from '../utils'; -import { Handler } from '../handler'; +import { Source } from '../source'; import { Config } from '../types'; export class ConfigureController { public readonly router: Router; - private readonly handlers: Handler[]; + private readonly sources: Source[]; - constructor(handlers: Handler[]) { + constructor(sources: Source[]) { this.router = Router(); - this.handlers = handlers; + this.sources = sources; this.router.get('/configure', this.getConfigure.bind(this)); this.router.get('/:config/configure', this.getConfigure.bind(this)); @@ -21,7 +21,7 @@ export class ConfigureController { private readonly getConfigure = (req: Request, res: Response) => { const config: Config = JSON.parse(req.params['config'] || JSON.stringify(getDefaultConfig())); - const manifest = buildManifest(this.handlers, config); + const manifest = buildManifest(this.sources, config); res.setHeader('content-type', 'text/html'); res.send(landingTemplate(manifest)); diff --git a/src/controller/ManifestController.ts b/src/controller/ManifestController.ts index dee40b9..8fd0fa4 100644 --- a/src/controller/ManifestController.ts +++ b/src/controller/ManifestController.ts @@ -1,17 +1,17 @@ import { Request, Response, Router } from 'express'; import { buildManifest, getDefaultConfig } from '../utils'; -import { Handler } from '../handler'; +import { Source } from '../source'; import { Config } from '../types'; export class ManifestController { public readonly router: Router; - private readonly handlers: Handler[]; + private readonly sources: Source[]; - constructor(handlers: Handler[]) { + constructor(sources: Source[]) { this.router = Router(); - this.handlers = handlers; + this.sources = sources; this.router.get('/manifest.json', this.getManifest.bind(this)); this.router.get('/:config/manifest.json', this.getManifest.bind(this)); @@ -20,7 +20,7 @@ export class ManifestController { private readonly getManifest = (req: Request, res: Response) => { const config: Config = JSON.parse(req.params['config'] || JSON.stringify(getDefaultConfig())); - const manifest = buildManifest(this.handlers, config); + const manifest = buildManifest(this.sources, config); res.setHeader('Content-Type', 'application/json'); res.send(manifest); diff --git a/src/controller/StreamController.ts b/src/controller/StreamController.ts index d5009ad..b221f4a 100644 --- a/src/controller/StreamController.ts +++ b/src/controller/StreamController.ts @@ -1,6 +1,6 @@ import { Request, Response, Router } from 'express'; import winston from 'winston'; -import { Handler } from '../handler'; +import { Source } from '../source'; import { Config, Context } from '../types'; import { envIsProd, getDefaultConfig, ImdbId, StreamResolver } from '../utils'; import { ContentType } from 'stremio-addon-sdk'; @@ -9,14 +9,14 @@ export class StreamController { public readonly router: Router; private readonly logger: winston.Logger; - private readonly handlers: Handler[]; + private readonly sources: Source[]; private readonly streamResolver: StreamResolver; - constructor(logger: winston.Logger, handlers: Handler[], streams: StreamResolver) { + constructor(logger: winston.Logger, sources: Source[], streams: StreamResolver) { this.router = Router(); this.logger = logger; - this.handlers = handlers; + this.sources = sources; this.streamResolver = streams; this.router.get('/:config/stream/:type/:id.json', this.getStream.bind(this)); @@ -35,9 +35,9 @@ export class StreamController { this.logger.info(`Search stream for type "${type}" and id "${id}" for ip ${ctx.ip}`, ctx); - const handlers = this.handlers.filter(handler => handler.countryCodes.filter(countryCode => countryCode in ctx.config).length); + const sources = this.sources.filter(handler => handler.countryCodes.filter(countryCode => countryCode in ctx.config).length); - const { streams, ttl } = await this.streamResolver.resolve(ctx, handlers, type, ImdbId.fromString(id)); + const { streams, ttl } = await this.streamResolver.resolve(ctx, sources, type, ImdbId.fromString(id)); if (ttl && envIsProd()) { res.setHeader('Cache-Control', `max-age=${ttl / 1000}, public`); diff --git a/src/index.ts b/src/index.ts index be83ae6..562f237 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,7 +1,7 @@ import express, { NextFunction, Request, Response } from 'express'; import { v4 as uuidv4 } from 'uuid'; import winston from 'winston'; -import { CineHDPlus, Frembed, FrenchCloud, Handler, KinoGer, MeineCloud, MostraGuarda, Soaper, StreamKiste, VerHdLink, VidSrc } from './handler'; +import { CineHDPlus, Frembed, FrenchCloud, Source, KinoGer, MeineCloud, MostraGuarda, Soaper, StreamKiste, VerHdLink, VidSrc } from './source'; import { createExtractors, ExtractorRegistry } from './extractor'; import { ConfigureController, ManifestController, StreamController } from './controller'; import { envGet, envIsProd, Fetcher, StreamResolver, tmdbFetch, TmdbId } from './utils'; @@ -19,7 +19,7 @@ const logger = winston.createLogger({ const fetcher = new Fetcher(logger); -const handlers: Handler[] = [ +const sources: Source[] = [ // EN new Soaper(fetcher), new VidSrc(fetcher), @@ -54,12 +54,12 @@ addon.use((_req: Request, res: Response, next: NextFunction) => { next(); }); -addon.use('/', (new ConfigureController(handlers)).router); -addon.use('/', (new ManifestController(handlers)).router); +addon.use('/', (new ConfigureController(sources)).router); +addon.use('/', (new ManifestController(sources)).router); const extractorRegistry = new ExtractorRegistry(logger, createExtractors(fetcher)); const streamResolver = new StreamResolver(logger, extractorRegistry); -addon.use('/', (new StreamController(logger, handlers, streamResolver)).router); +addon.use('/', (new StreamController(logger, sources, streamResolver)).router); addon.get('/', (_req: Request, res: Response) => { res.redirect('/configure'); @@ -86,7 +86,7 @@ const cacheWarmup = async () => { } }); for (const id of movieIds) { - await streamResolver.resolve(ctx, handlers, 'movie', new TmdbId(id, undefined, undefined)); + await streamResolver.resolve(ctx, sources, 'movie', new TmdbId(id, undefined, undefined)); } logger.info(`warmed up cache with ${movieIds.length} movies`, ctx); @@ -100,7 +100,7 @@ const cacheWarmup = async () => { } }); for (const id of tvShowIds) { - await streamResolver.resolve(ctx, handlers, 'series', new TmdbId(id, 1, 1)); + await streamResolver.resolve(ctx, sources, 'series', new TmdbId(id, 1, 1)); } logger.info(`warmed up cache with ${tvShowIds.length} tv shows`, ctx); diff --git a/src/handler/CineHDPlus.test.ts b/src/source/CineHDPlus.test.ts similarity index 100% rename from src/handler/CineHDPlus.test.ts rename to src/source/CineHDPlus.test.ts diff --git a/src/handler/CineHDPlus.ts b/src/source/CineHDPlus.ts similarity index 94% rename from src/handler/CineHDPlus.ts rename to src/source/CineHDPlus.ts index 20cc89e..0bbc473 100644 --- a/src/handler/CineHDPlus.ts +++ b/src/source/CineHDPlus.ts @@ -1,10 +1,10 @@ import { ContentType } from 'stremio-addon-sdk'; import * as cheerio from 'cheerio'; -import { Handler, HandleResult } from './types'; +import { Source, SourceResult } from './types'; import { Fetcher, getImdbId, Id, ImdbId } from '../utils'; import { Context, CountryCode } from '../types'; -export class CineHDPlus implements Handler { +export class CineHDPlus implements Source { readonly id = 'cinehdplus'; readonly label = 'CineHDPlus'; @@ -19,7 +19,7 @@ export class CineHDPlus implements Handler { this.fetcher = fetcher; } - readonly handle = async (ctx: Context, _type: string, id: Id): Promise => { + readonly handle = async (ctx: Context, _type: string, id: Id): Promise => { const imdbId = await getImdbId(ctx, this.fetcher, id); const seriesPageUrl = await this.fetchSeriesPageUrl(ctx, imdbId); diff --git a/src/handler/Eurostreaming.test.ts b/src/source/Eurostreaming.test.ts similarity index 100% rename from src/handler/Eurostreaming.test.ts rename to src/source/Eurostreaming.test.ts diff --git a/src/handler/Eurostreaming.ts b/src/source/Eurostreaming.ts similarity index 94% rename from src/handler/Eurostreaming.ts rename to src/source/Eurostreaming.ts index 66524b9..a0c7bac 100644 --- a/src/handler/Eurostreaming.ts +++ b/src/source/Eurostreaming.ts @@ -1,10 +1,10 @@ import { ContentType } from 'stremio-addon-sdk'; import * as cheerio from 'cheerio'; -import { Handler, HandleResult } from './types'; +import { Source, SourceResult } from './types'; import { Fetcher, getImdbId, Id, ImdbId } from '../utils'; import { Context, CountryCode } from '../types'; -export class Eurostreaming implements Handler { +export class Eurostreaming implements Source { readonly id = 'eurostreaming'; readonly label = 'Eurostreaming'; @@ -19,7 +19,7 @@ export class Eurostreaming implements Handler { this.fetcher = fetcher; } - readonly handle = async (ctx: Context, _type: string, id: Id): Promise => { + readonly handle = async (ctx: Context, _type: string, id: Id): Promise => { const imdbId = await getImdbId(ctx, this.fetcher, id); const seriesPageUrl = await this.fetchSeriesPageUrl(ctx, imdbId); diff --git a/src/handler/Frembed.test.ts b/src/source/Frembed.test.ts similarity index 100% rename from src/handler/Frembed.test.ts rename to src/source/Frembed.test.ts diff --git a/src/handler/Frembed.ts b/src/source/Frembed.ts similarity index 90% rename from src/handler/Frembed.ts rename to src/source/Frembed.ts index f7d856a..5acee28 100644 --- a/src/handler/Frembed.ts +++ b/src/source/Frembed.ts @@ -1,9 +1,9 @@ import { ContentType } from 'stremio-addon-sdk'; -import { Handler, HandleResult } from './types'; +import { Source, SourceResult } from './types'; import { Fetcher, getTmdbId, Id } from '../utils'; import { Context, CountryCode } from '../types'; -export class Frembed implements Handler { +export class Frembed implements Source { readonly id = 'frembed'; readonly label = 'Frembed'; @@ -18,7 +18,7 @@ export class Frembed implements Handler { this.fetcher = fetcher; } - readonly handle = async (ctx: Context, _type: string, id: Id): Promise => { + readonly handle = async (ctx: Context, _type: string, id: Id): Promise => { const tmdbId = await getTmdbId(ctx, this.fetcher, id); const apiUrl = new URL(`https://frembed.space/api/series?id=${tmdbId.id}&sa=${tmdbId.season}&epi=${tmdbId.episode}&idType=tmdb`); diff --git a/src/handler/FrenchCloud.test.ts b/src/source/FrenchCloud.test.ts similarity index 100% rename from src/handler/FrenchCloud.test.ts rename to src/source/FrenchCloud.test.ts diff --git a/src/handler/FrenchCloud.ts b/src/source/FrenchCloud.ts similarity index 89% rename from src/handler/FrenchCloud.ts rename to src/source/FrenchCloud.ts index 091ce92..ac35d27 100644 --- a/src/handler/FrenchCloud.ts +++ b/src/source/FrenchCloud.ts @@ -1,10 +1,10 @@ import { ContentType } from 'stremio-addon-sdk'; import * as cheerio from 'cheerio'; -import { Handler, HandleResult } from './types'; +import { Source, SourceResult } from './types'; import { Fetcher, getImdbId, Id } from '../utils'; import { Context, CountryCode } from '../types'; -export class FrenchCloud implements Handler { +export class FrenchCloud implements Source { readonly id = 'frenchcloud'; readonly label = 'FrenchCloud'; @@ -19,7 +19,7 @@ export class FrenchCloud implements Handler { this.fetcher = fetcher; } - readonly handle = async (ctx: Context, _type: string, id: Id): Promise => { + readonly handle = async (ctx: Context, _type: string, id: Id): Promise => { const imdbId = await getImdbId(ctx, this.fetcher, id); const pageUrl = new URL(`https://frenchcloud.cam/movie/${imdbId.id}`); diff --git a/src/handler/KinoGer.test.ts b/src/source/KinoGer.test.ts similarity index 100% rename from src/handler/KinoGer.test.ts rename to src/source/KinoGer.test.ts diff --git a/src/handler/KinoGer.ts b/src/source/KinoGer.ts similarity index 96% rename from src/handler/KinoGer.ts rename to src/source/KinoGer.ts index 7467f48..e899c71 100644 --- a/src/handler/KinoGer.ts +++ b/src/source/KinoGer.ts @@ -1,10 +1,10 @@ import { ContentType } from 'stremio-addon-sdk'; import * as cheerio from 'cheerio'; -import { Handler, HandleResult } from './types'; +import { Source, SourceResult } from './types'; import { Fetcher, getTmdbId, getTmdbMovieDetails, getTmdbTvDetails, Id, TmdbId } from '../utils'; import { Context, CountryCode } from '../types'; -export class KinoGer implements Handler { +export class KinoGer implements Source { readonly id = 'kinoger'; readonly label = 'KinoGer'; @@ -21,7 +21,7 @@ export class KinoGer implements Handler { this.fetcher = fetcher; } - readonly handle = async (ctx: Context, _type: string, id: Id): Promise => { + readonly handle = async (ctx: Context, _type: string, id: Id): Promise => { const tmdbId = await getTmdbId(ctx, this.fetcher, id); const [keyword, year] = await this.getKeywordAndYear(ctx, tmdbId); diff --git a/src/handler/MeineCloud.test.ts b/src/source/MeineCloud.test.ts similarity index 100% rename from src/handler/MeineCloud.test.ts rename to src/source/MeineCloud.test.ts diff --git a/src/handler/MeineCloud.ts b/src/source/MeineCloud.ts similarity index 89% rename from src/handler/MeineCloud.ts rename to src/source/MeineCloud.ts index 287a708..b867631 100644 --- a/src/handler/MeineCloud.ts +++ b/src/source/MeineCloud.ts @@ -1,10 +1,10 @@ import { ContentType } from 'stremio-addon-sdk'; import * as cheerio from 'cheerio'; -import { Handler, HandleResult } from './types'; +import { Source, SourceResult } from './types'; import { Fetcher, getImdbId, Id } from '../utils'; import { Context, CountryCode } from '../types'; -export class MeineCloud implements Handler { +export class MeineCloud implements Source { readonly id = 'meinecloud'; readonly label = 'MeineCloud'; @@ -19,7 +19,7 @@ export class MeineCloud implements Handler { this.fetcher = fetcher; } - readonly handle = async (ctx: Context, _type: string, id: Id): Promise => { + readonly handle = async (ctx: Context, _type: string, id: Id): Promise => { const imdbId = await getImdbId(ctx, this.fetcher, id); const pageUrl = new URL(`https://meinecloud.click/movie/${imdbId.id}`); diff --git a/src/handler/MostraGuarda.test.ts b/src/source/MostraGuarda.test.ts similarity index 100% rename from src/handler/MostraGuarda.test.ts rename to src/source/MostraGuarda.test.ts diff --git a/src/handler/MostraGuarda.ts b/src/source/MostraGuarda.ts similarity index 89% rename from src/handler/MostraGuarda.ts rename to src/source/MostraGuarda.ts index 1d0fd42..145ab7c 100644 --- a/src/handler/MostraGuarda.ts +++ b/src/source/MostraGuarda.ts @@ -1,10 +1,10 @@ import { ContentType } from 'stremio-addon-sdk'; import * as cheerio from 'cheerio'; -import { Handler, HandleResult } from './types'; +import { Source, SourceResult } from './types'; import { Fetcher, getImdbId, Id } from '../utils'; import { Context, CountryCode } from '../types'; -export class MostraGuarda implements Handler { +export class MostraGuarda implements Source { readonly id = 'mostraguarda'; readonly label = 'MostraGuarda'; @@ -19,7 +19,7 @@ export class MostraGuarda implements Handler { this.fetcher = fetcher; } - readonly handle = async (ctx: Context, _type: string, id: Id): Promise => { + readonly handle = async (ctx: Context, _type: string, id: Id): Promise => { const imdbId = await getImdbId(ctx, this.fetcher, id); const pageUrl = new URL(`https://mostraguarda.stream/movie/${imdbId.id}`); diff --git a/src/handler/Soaper.test.ts b/src/source/Soaper.test.ts similarity index 100% rename from src/handler/Soaper.test.ts rename to src/source/Soaper.test.ts diff --git a/src/handler/Soaper.ts b/src/source/Soaper.ts similarity index 95% rename from src/handler/Soaper.ts rename to src/source/Soaper.ts index 19d3309..d155c95 100644 --- a/src/handler/Soaper.ts +++ b/src/source/Soaper.ts @@ -1,10 +1,10 @@ import { ContentType } from 'stremio-addon-sdk'; import * as cheerio from 'cheerio'; -import { Handler, HandleResult } from './types'; +import { Source, SourceResult } from './types'; import { Fetcher, getTmdbId, getTmdbMovieDetails, getTmdbTvDetails, Id, TmdbId } from '../utils'; import { Context, CountryCode } from '../types'; -export class Soaper implements Handler { +export class Soaper implements Source { readonly id = 'soaper'; readonly label = 'Soaper'; @@ -21,7 +21,7 @@ export class Soaper implements Handler { this.fetcher = fetcher; } - readonly handle = async (ctx: Context, _type: string, id: Id): Promise => { + readonly handle = async (ctx: Context, _type: string, id: Id): Promise => { const tmdbId = await getTmdbId(ctx, this.fetcher, id); const [keyword, year, hrefPrefix] = await this.getKeywordYearAndHrefPrefix(ctx, tmdbId); diff --git a/src/handler/StreamKiste.test.ts b/src/source/StreamKiste.test.ts similarity index 100% rename from src/handler/StreamKiste.test.ts rename to src/source/StreamKiste.test.ts diff --git a/src/handler/StreamKiste.ts b/src/source/StreamKiste.ts similarity index 93% rename from src/handler/StreamKiste.ts rename to src/source/StreamKiste.ts index fd45629..cca06d4 100644 --- a/src/handler/StreamKiste.ts +++ b/src/source/StreamKiste.ts @@ -1,10 +1,10 @@ import { ContentType } from 'stremio-addon-sdk'; import * as cheerio from 'cheerio'; -import { Handler, HandleResult } from './types'; +import { Source, SourceResult } from './types'; import { ImdbId, Fetcher, getImdbId, Id } from '../utils'; import { Context, CountryCode } from '../types'; -export class StreamKiste implements Handler { +export class StreamKiste implements Source { readonly id = 'streamkiste'; readonly label = 'StreamKiste'; @@ -19,7 +19,7 @@ export class StreamKiste implements Handler { this.fetcher = fetcher; } - readonly handle = async (ctx: Context, _type: string, id: Id): Promise => { + readonly handle = async (ctx: Context, _type: string, id: Id): Promise => { const imdbId = await getImdbId(ctx, this.fetcher, id); const seriesPageUrl = await this.fetchSeriesPageUrl(ctx, imdbId); diff --git a/src/handler/VerHdLink.test.ts b/src/source/VerHdLink.test.ts similarity index 100% rename from src/handler/VerHdLink.test.ts rename to src/source/VerHdLink.test.ts diff --git a/src/handler/VerHdLink.ts b/src/source/VerHdLink.ts similarity index 92% rename from src/handler/VerHdLink.ts rename to src/source/VerHdLink.ts index 265bc49..10dee87 100644 --- a/src/handler/VerHdLink.ts +++ b/src/source/VerHdLink.ts @@ -1,10 +1,10 @@ import { ContentType } from 'stremio-addon-sdk'; import * as cheerio from 'cheerio'; -import { Handler, HandleResult } from './types'; +import { Source, SourceResult } from './types'; import { Fetcher, getImdbId, Id } from '../utils'; import { Context, CountryCode } from '../types'; -export class VerHdLink implements Handler { +export class VerHdLink implements Source { readonly id = 'verhdlink'; readonly label = 'VerHdLink'; @@ -19,7 +19,7 @@ export class VerHdLink implements Handler { this.fetcher = fetcher; } - readonly handle = async (ctx: Context, _type: string, id: Id): Promise => { + readonly handle = async (ctx: Context, _type: string, id: Id): Promise => { const imdbId = await getImdbId(ctx, this.fetcher, id); const pageUrl = new URL(`https://verhdlink.cam/movie/${imdbId.id}`); diff --git a/src/handler/VidSrc.test.ts b/src/source/VidSrc.test.ts similarity index 100% rename from src/handler/VidSrc.test.ts rename to src/source/VidSrc.test.ts diff --git a/src/handler/VidSrc.ts b/src/source/VidSrc.ts similarity index 87% rename from src/handler/VidSrc.ts rename to src/source/VidSrc.ts index 4bd89cd..0d55134 100644 --- a/src/handler/VidSrc.ts +++ b/src/source/VidSrc.ts @@ -1,9 +1,9 @@ import { ContentType } from 'stremio-addon-sdk'; -import { Handler, HandleResult } from './types'; +import { Source, SourceResult } from './types'; import { Fetcher, getImdbId, Id } from '../utils'; import { Context, CountryCode } from '../types'; -export class VidSrc implements Handler { +export class VidSrc implements Source { readonly id = 'vidsrc'; readonly label = 'VidSrc'; @@ -20,7 +20,7 @@ export class VidSrc implements Handler { this.fetcher = fetcher; } - readonly handle = async (ctx: Context, _type: string, id: Id): Promise => { + readonly handle = async (ctx: Context, _type: string, id: Id): Promise => { const imdbId = await getImdbId(ctx, this.fetcher, id); const url = imdbId.season diff --git a/src/handler/__snapshots__/CineHDPlus.test.ts.snap b/src/source/__snapshots__/CineHDPlus.test.ts.snap similarity index 100% rename from src/handler/__snapshots__/CineHDPlus.test.ts.snap rename to src/source/__snapshots__/CineHDPlus.test.ts.snap diff --git a/src/handler/__snapshots__/Eurostreaming.test.ts.snap b/src/source/__snapshots__/Eurostreaming.test.ts.snap similarity index 100% rename from src/handler/__snapshots__/Eurostreaming.test.ts.snap rename to src/source/__snapshots__/Eurostreaming.test.ts.snap diff --git a/src/handler/__snapshots__/Frembed.test.ts.snap b/src/source/__snapshots__/Frembed.test.ts.snap similarity index 100% rename from src/handler/__snapshots__/Frembed.test.ts.snap rename to src/source/__snapshots__/Frembed.test.ts.snap diff --git a/src/handler/__snapshots__/FrenchCloud.test.ts.snap b/src/source/__snapshots__/FrenchCloud.test.ts.snap similarity index 100% rename from src/handler/__snapshots__/FrenchCloud.test.ts.snap rename to src/source/__snapshots__/FrenchCloud.test.ts.snap diff --git a/src/handler/__snapshots__/KinoGer.test.ts.snap b/src/source/__snapshots__/KinoGer.test.ts.snap similarity index 100% rename from src/handler/__snapshots__/KinoGer.test.ts.snap rename to src/source/__snapshots__/KinoGer.test.ts.snap diff --git a/src/handler/__snapshots__/MeineCloud.test.ts.snap b/src/source/__snapshots__/MeineCloud.test.ts.snap similarity index 100% rename from src/handler/__snapshots__/MeineCloud.test.ts.snap rename to src/source/__snapshots__/MeineCloud.test.ts.snap diff --git a/src/handler/__snapshots__/MostraGuarda.test.ts.snap b/src/source/__snapshots__/MostraGuarda.test.ts.snap similarity index 100% rename from src/handler/__snapshots__/MostraGuarda.test.ts.snap rename to src/source/__snapshots__/MostraGuarda.test.ts.snap diff --git a/src/handler/__snapshots__/Soaper.test.ts.snap b/src/source/__snapshots__/Soaper.test.ts.snap similarity index 100% rename from src/handler/__snapshots__/Soaper.test.ts.snap rename to src/source/__snapshots__/Soaper.test.ts.snap diff --git a/src/handler/__snapshots__/StreamKiste.test.ts.snap b/src/source/__snapshots__/StreamKiste.test.ts.snap similarity index 100% rename from src/handler/__snapshots__/StreamKiste.test.ts.snap rename to src/source/__snapshots__/StreamKiste.test.ts.snap diff --git a/src/handler/__snapshots__/VerHdLink.test.ts.snap b/src/source/__snapshots__/VerHdLink.test.ts.snap similarity index 100% rename from src/handler/__snapshots__/VerHdLink.test.ts.snap rename to src/source/__snapshots__/VerHdLink.test.ts.snap diff --git a/src/handler/__snapshots__/VidSrc.test.ts.snap b/src/source/__snapshots__/VidSrc.test.ts.snap similarity index 100% rename from src/handler/__snapshots__/VidSrc.test.ts.snap rename to src/source/__snapshots__/VidSrc.test.ts.snap diff --git a/src/handler/index.ts b/src/source/index.ts similarity index 100% rename from src/handler/index.ts rename to src/source/index.ts diff --git a/src/handler/types.ts b/src/source/types.ts similarity index 82% rename from src/handler/types.ts rename to src/source/types.ts index 6b01873..b93c6af 100644 --- a/src/handler/types.ts +++ b/src/source/types.ts @@ -2,14 +2,14 @@ import { ContentType } from 'stremio-addon-sdk'; import { Context, CountryCode } from '../types'; import { Id } from '../utils'; -export interface HandleResult { +export interface SourceResult { countryCode: CountryCode; referer?: URL; title?: string; url: URL; } -export interface Handler { +export interface Source { readonly id: string; readonly label: string; @@ -18,5 +18,5 @@ export interface Handler { readonly countryCodes: CountryCode[]; - readonly handle: (ctx: Context, type: ContentType, id: Id) => Promise<(HandleResult[])>; + readonly handle: (ctx: Context, type: ContentType, id: Id) => Promise<(SourceResult[])>; } diff --git a/src/utils/StreamResolver.test.ts b/src/utils/StreamResolver.test.ts index d927f0d..2b7c3d3 100644 --- a/src/utils/StreamResolver.test.ts +++ b/src/utils/StreamResolver.test.ts @@ -2,7 +2,7 @@ import { ContentType } from 'stremio-addon-sdk'; import winston from 'winston'; import { createExtractors, Extractor, ExtractorRegistry } from '../extractor'; import { StreamResolver } from './StreamResolver'; -import { Handler, HandleResult, MeineCloud, MostraGuarda } from '../handler'; +import { Source, SourceResult, MeineCloud, MostraGuarda } from '../source'; import { Fetcher } from './Fetcher'; import { BlockedReason, Context, CountryCode, TIMEOUT, UrlResult } from '../types'; import { BlockedError, HttpError, NotFoundError, QueueIsFullError } from '../error'; @@ -19,7 +19,7 @@ const meineCloud = new MeineCloud(fetcher); const mostraGuarda = new MostraGuarda(fetcher); describe('resolve', () => { - test('returns info as stream if no handlers were configured', async () => { + test('returns info as stream if no sources were configured', async () => { const streamResolver = new StreamResolver(logger, new ExtractorRegistry(logger, createExtractors(fetcher))); const streams = await streamResolver.resolve(ctx, [], 'movie', new ImdbId('tt123456789', undefined, undefined)); @@ -27,7 +27,7 @@ describe('resolve', () => { expect(streams).toMatchSnapshot(); }); - test('returns handler errors as stream', async () => { + test('returns source errors as stream', async () => { const fetcherSpy = jest.spyOn(fetcher, 'text').mockRejectedValue('ups, an error occurred.'); const streamResolver = new StreamResolver(logger, new ExtractorRegistry(logger, createExtractors(fetcher))); @@ -38,7 +38,7 @@ describe('resolve', () => { fetcherSpy.mockRestore(); }); - test('returns empty array if no handler found anything', async () => { + test('returns empty array if no source found anything', async () => { const streamResolver = new StreamResolver(logger, new ExtractorRegistry(logger, createExtractors(fetcher))); const streams = await streamResolver.resolve(ctx, [meineCloud, mostraGuarda], 'movie', new ImdbId('tt12345678', undefined, undefined)); @@ -46,7 +46,7 @@ describe('resolve', () => { expect(streams).toMatchSnapshot(); }); - test('returns empty array if no handler supported the type', async () => { + test('returns empty array if no source supported the type', async () => { const streamResolver = new StreamResolver(logger, new ExtractorRegistry(logger, createExtractors(fetcher))); const streams = await streamResolver.resolve(ctx, [meineCloud, mostraGuarda], 'series', new ImdbId('tt12345678', 1, 1)); @@ -63,7 +63,7 @@ describe('resolve', () => { }); test('adds error info', async () => { - class MockHandler implements Handler { + class MockHandler implements Source { readonly id = 'mockhandler'; readonly label = 'MockHandler'; @@ -72,7 +72,7 @@ describe('resolve', () => { readonly countryCodes: CountryCode[] = [CountryCode.de]; - readonly handle = async (): Promise => { + readonly handle = async (): Promise => { return [{ countryCode: CountryCode.de, url: new URL('https://example.com') }]; }; } @@ -163,7 +163,7 @@ describe('resolve', () => { }); test('ignores not found errors', async () => { - const mockHandler: Handler = { + const mockHandler: Source = { id: 'mockhandler', label: 'MockHandler', contentTypes: ['movie'], diff --git a/src/utils/StreamResolver.ts b/src/utils/StreamResolver.ts index c5e2a27..7a0ab5f 100644 --- a/src/utils/StreamResolver.ts +++ b/src/utils/StreamResolver.ts @@ -2,7 +2,7 @@ import { ContentType, Stream } from 'stremio-addon-sdk'; import winston from 'winston'; import bytes from 'bytes'; import { Context, TIMEOUT, UrlResult } from '../types'; -import { Handler } from '../handler'; +import { Source } from '../source'; import { BlockedError, HttpError, NotFoundError, QueueIsFullError } from '../error'; import { flagFromCountryCode, languageFromCountryCode } from './language'; import { envGetAppName } from './env'; @@ -23,13 +23,13 @@ export class StreamResolver { this.extractorRegistry = extractorRegistry; } - readonly resolve = async (ctx: Context, handlers: Handler[], type: ContentType, id: Id): Promise => { - if (handlers.length === 0) { + readonly resolve = async (ctx: Context, sources: Source[], type: ContentType, id: Id): Promise => { + if (sources.length === 0) { return { streams: [ { name: 'WebStreamr', - title: '⚠️ No handlers found. Please re-configure the plugin.', + title: '⚠️ No sources found. Please re-configure the plugin.', ytId: 'E4WlUXrJgy4', }, ], @@ -40,7 +40,7 @@ export class StreamResolver { let handlerErrorOccurred = false; const urlResults: UrlResult[] = []; - const handlerPromises = handlers.map(async (handler) => { + const handlerPromises = sources.map(async (handler) => { if (!handler.contentTypes.includes(type)) { return; } diff --git a/src/utils/__snapshots__/StreamResolver.test.ts.snap b/src/utils/__snapshots__/StreamResolver.test.ts.snap index 86062ec..e45524b 100644 --- a/src/utils/__snapshots__/StreamResolver.test.ts.snap +++ b/src/utils/__snapshots__/StreamResolver.test.ts.snap @@ -1,4 +1,4 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP +// Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing exports[`resolve adds error info 1`] = ` { @@ -117,39 +117,26 @@ exports[`resolve ignores not found errors 1`] = ` } `; -exports[`resolve returns empty array if no handler found anything 1`] = ` +exports[`resolve returns empty array if no source found anything 1`] = ` { "streams": [], "ttl": 900000, } `; -exports[`resolve returns empty array if no handler supported the type 1`] = ` +exports[`resolve returns empty array if no source supported the type 1`] = ` { "streams": [], "ttl": 900000, } `; -exports[`resolve returns handler errors as stream 1`] = ` +exports[`resolve returns info as stream if no sources were configured 1`] = ` { "streams": [ { "name": "WebStreamr", - "title": "🔗 MeineCloud -❌ Request failed. Request-id: id.", - "ytId": "E4WlUXrJgy4", - }, - ], -} -`; - -exports[`resolve returns info as stream if no handlers were configured 1`] = ` -{ - "streams": [ - { - "name": "WebStreamr", - "title": "⚠️ No handlers found. Please re-configure the plugin.", + "title": "⚠️ No sources found. Please re-configure the plugin.", "ytId": "E4WlUXrJgy4", }, ], @@ -263,3 +250,16 @@ exports[`resolve returns sorted results 1`] = ` "ttl": 900000, } `; + +exports[`resolve returns source errors as stream 1`] = ` +{ + "streams": [ + { + "name": "WebStreamr", + "title": "🔗 MeineCloud +❌ Request failed. Request-id: id.", + "ytId": "E4WlUXrJgy4", + }, + ], +} +`; diff --git a/src/utils/__snapshots__/manifest.test.ts.snap b/src/utils/__snapshots__/manifest.test.ts.snap index 09512d1..6fd0fcb 100644 --- a/src/utils/__snapshots__/manifest.test.ts.snap +++ b/src/utils/__snapshots__/manifest.test.ts.snap @@ -1,6 +1,6 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP +// Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing -exports[`buildManifest has checked handler with appropriate config 1`] = ` +exports[`buildManifest has checked source with appropriate config 1`] = ` [ { "default": "checked", @@ -26,7 +26,7 @@ exports[`buildManifest has checked handler with appropriate config 1`] = ` ] `; -exports[`buildManifest has unchecked handler without a config 1`] = ` +exports[`buildManifest has unchecked source without a config 1`] = ` [ { "key": "de", diff --git a/src/utils/manifest.test.ts b/src/utils/manifest.test.ts index 221ecfc..6842ee0 100644 --- a/src/utils/manifest.test.ts +++ b/src/utils/manifest.test.ts @@ -1,5 +1,5 @@ import { buildManifest } from './manifest'; -import { StreamKiste, MeineCloud, VerHdLink } from '../handler'; +import { StreamKiste, MeineCloud, VerHdLink } from '../source'; import { Fetcher } from './Fetcher'; jest.mock('../utils/Fetcher'); @@ -7,25 +7,25 @@ jest.mock('../utils/Fetcher'); const fetcher = new Fetcher(); describe('buildManifest', () => { - test('has unchecked handler without a config', () => { - const handlers = [ + test('has unchecked source without a config', () => { + const sources = [ new VerHdLink(fetcher), new StreamKiste(fetcher), new MeineCloud(fetcher), ]; - const manifest = buildManifest(handlers, {}); + const manifest = buildManifest(sources, {}); expect(manifest.config).toMatchSnapshot(); }); - test('has checked handler with appropriate config', () => { - const handlers = [ + test('has checked source with appropriate config', () => { + const sources = [ new VerHdLink(fetcher), new StreamKiste(fetcher), new MeineCloud(fetcher), ]; - const manifest = buildManifest(handlers, { de: 'on' }); + const manifest = buildManifest(sources, { de: 'on' }); expect(manifest.config).toMatchSnapshot(); }); diff --git a/src/utils/manifest.ts b/src/utils/manifest.ts index 0f65eb5..7e136f5 100644 --- a/src/utils/manifest.ts +++ b/src/utils/manifest.ts @@ -1,11 +1,11 @@ -import { Handler } from '../handler'; +import { Source } from '../source'; import { Config, CountryCode, ManifestWithConfig } from '../types'; import { envGetAppId, envGetAppName } from './env'; import { flagFromCountryCode, languageFromCountryCode } from './language'; const typedEntries = (obj: T): [keyof T, T[keyof T]][] => (Object.entries(obj) as [keyof T, T[keyof T]][]); -export const buildManifest = (handlers: Handler[], config: Config): ManifestWithConfig => { +export const buildManifest = (sources: Source[], config: Config): ManifestWithConfig => { const manifest: ManifestWithConfig = { id: envGetAppId(), version: '0.28.0', // x-release-please-version @@ -33,19 +33,19 @@ export const buildManifest = (handlers: Handler[], config: Config): ManifestWith }, }; - const countryCodeHandlers: Partial> = {}; - handlers.forEach((handler) => { - handler.countryCodes.forEach(countryCode => countryCodeHandlers[countryCode] = [...(countryCodeHandlers[countryCode] ?? []), handler]); + const countryCodeSources: Partial> = {}; + sources.forEach((handler) => { + handler.countryCodes.forEach(countryCode => countryCodeSources[countryCode] = [...(countryCodeSources[countryCode] ?? []), handler]); }); - const sortedLanguageHandlers = typedEntries(countryCodeHandlers) + const sortedLanguageSources = typedEntries(countryCodeSources) .sort(([countryCodeA], [countryCodeB]) => countryCodeA.localeCompare(countryCodeB)); - for (const [countryCode, handlers] of sortedLanguageHandlers) { + for (const [countryCode, sources] of sortedLanguageSources) { manifest.config.push({ key: countryCode, type: 'checkbox', - title: `${languageFromCountryCode(countryCode)} ${flagFromCountryCode(countryCode)} (${(handlers as Handler[]).map(handler => handler.label).join(', ')})`, + title: `${languageFromCountryCode(countryCode)} ${flagFromCountryCode(countryCode)} (${(sources as Source[]).map(handler => handler.label).join(', ')})`, ...(countryCode in config && { default: 'checked' }), }); }