From dcad7db29c272dcb35504cc38d365a929906bf9c Mon Sep 17 00:00:00 2001 From: WebStreamr <210764791+webstreamr@users.noreply.github.com> Date: Fri, 9 Jan 2026 15:33:50 +0000 Subject: [PATCH] feat: add RgShows --- src/extractor/RgShows.test.ts | 20 +++++++++ src/extractor/RgShows.ts | 45 +++++++++++++++++++ .../https:api.rgshows.rumainmovie1054867 | 1 + .../RgShows/https:api.rgshows.rumaintv6673251 | 1 + ...99key.com-0d4475035df5f2c4950ddec91c1c5007 | 9 ++++ ...99key.com-ea06cca9877e47ce5f9c274b5c99b941 | 9 ++++ .../__snapshots__/RgShows.test.ts.snap | 43 ++++++++++++++++++ src/extractor/index.ts | 2 + src/source/RgShows.test.ts | 23 ++++++++++ src/source/RgShows.ts | 42 +++++++++++++++++ .../https:api.themoviedb.org3movie1054867 | 1 + .../RgShows/https:api.themoviedb.org3tv66732 | 1 + src/source/__snapshots__/RgShows.test.ts.snap | 29 ++++++++++++ src/source/index.ts | 2 + src/utils/Fetcher.ts | 3 +- src/utils/__snapshots__/manifest.test.ts.snap | 9 +++- 16 files changed, 237 insertions(+), 3 deletions(-) create mode 100644 src/extractor/RgShows.test.ts create mode 100644 src/extractor/RgShows.ts create mode 100644 src/extractor/__fixtures__/RgShows/https:api.rgshows.rumainmovie1054867 create mode 100644 src/extractor/__fixtures__/RgShows/https:api.rgshows.rumaintv6673251 create mode 100644 src/extractor/__fixtures__/RgShows/https:i-arch-400.lethe399key.com-0d4475035df5f2c4950ddec91c1c5007 create mode 100644 src/extractor/__fixtures__/RgShows/https:i-cdn-0.lethe399key.com-ea06cca9877e47ce5f9c274b5c99b941 create mode 100644 src/extractor/__snapshots__/RgShows.test.ts.snap create mode 100644 src/source/RgShows.test.ts create mode 100644 src/source/RgShows.ts create mode 100644 src/source/__fixtures__/RgShows/https:api.themoviedb.org3movie1054867 create mode 100644 src/source/__fixtures__/RgShows/https:api.themoviedb.org3tv66732 create mode 100644 src/source/__snapshots__/RgShows.test.ts.snap diff --git a/src/extractor/RgShows.test.ts b/src/extractor/RgShows.test.ts new file mode 100644 index 0000000..689811b --- /dev/null +++ b/src/extractor/RgShows.test.ts @@ -0,0 +1,20 @@ +import winston from 'winston'; +import { createTestContext } from '../test'; +import { FetcherMock } from '../utils'; +import { ExtractorRegistry } from './ExtractorRegistry'; +import { RgShows } from './RgShows'; + +const logger = winston.createLogger({ transports: [new winston.transports.Console({ level: 'nope' })] }); +const extractorRegistry = new ExtractorRegistry(logger, [new RgShows(new FetcherMock(`${__dirname}/__fixtures__/RgShows`))]); + +const ctx = createTestContext(); + +describe('RgShows', () => { + test('handle one battle after another', async () => { + expect(await extractorRegistry.handle(ctx, new URL('https://api.rgshows.ru/main/movie/1054867'))).toMatchSnapshot(); + }); + + test('handle stranger things s05e01', async () => { + expect(await extractorRegistry.handle(ctx, new URL('https://api.rgshows.ru/main/tv/66732/5/1'))).toMatchSnapshot(); + }); +}); diff --git a/src/extractor/RgShows.ts b/src/extractor/RgShows.ts new file mode 100644 index 0000000..d349a92 --- /dev/null +++ b/src/extractor/RgShows.ts @@ -0,0 +1,45 @@ +import { Context, Format, Meta, UrlResult } from '../types'; +import { guessHeightFromPlaylist } from '../utils'; +import { Extractor } from './Extractor'; + +interface RgShowsApiData { + stream: { + url: string; + }; +} + +export class RgShows extends Extractor { + public readonly id = 'rgshows'; + + public readonly label = 'RgShows'; + + public override readonly ttl: number = 10800000; // 3h + + public supports(_ctx: Context, url: URL): boolean { + return null !== url.host.match(/rgshows/); + } + + protected async extractInternal(ctx: Context, url: URL, meta: Meta): Promise { + const nonSubDomainUrl = new URL(url); + nonSubDomainUrl.hostname = nonSubDomainUrl.hostname.split('.').slice(-2).join('.'); + const headers = { 'Referer': `${nonSubDomainUrl.origin}/`, 'Origin': nonSubDomainUrl.origin, 'User-Agent': 'Mozilla' }; + + const data = await this.fetcher.json(ctx, url, { headers, noProxy: true }) as RgShowsApiData; + + const playlistUrl = new URL(data.stream.url); + + return [ + { + url: playlistUrl, + format: Format.hls, + label: this.label, + ttl: this.ttl, + meta: { + ...meta, + height: await guessHeightFromPlaylist(ctx, this.fetcher, playlistUrl, url, { headers, noProxy: true }), + }, + requestHeaders: headers, + }, + ]; + }; +} diff --git a/src/extractor/__fixtures__/RgShows/https:api.rgshows.rumainmovie1054867 b/src/extractor/__fixtures__/RgShows/https:api.rgshows.rumainmovie1054867 new file mode 100644 index 0000000..4f558d5 --- /dev/null +++ b/src/extractor/__fixtures__/RgShows/https:api.rgshows.rumainmovie1054867 @@ -0,0 +1 @@ +{"stream":{"url":"https://i-arch-400.lethe399key.com/stream2/i-arch-400/01df0d24fc785e08a44241ed17dc9aef/MJTMsp1RshGTygnMNRUR2N2MSlnWXZEdMNDZzQWe5MDZzMmdZJTO1R2RWVHZDljekhkSsl1VwYnWtx2cihVT2pFVNlnT6FVNPR1a04kMJlnTUJkaO1WWzklaNFTTHV1daRUW04ERFhnWUFVP:1767971011:193.233.230.8:338a99d2e898667664ed62657ac0b65a05ed7308fe98419b3a65225ee36a7ae1/index.m3u8"}} \ No newline at end of file diff --git a/src/extractor/__fixtures__/RgShows/https:api.rgshows.rumaintv6673251 b/src/extractor/__fixtures__/RgShows/https:api.rgshows.rumaintv6673251 new file mode 100644 index 0000000..57f42e3 --- /dev/null +++ b/src/extractor/__fixtures__/RgShows/https:api.rgshows.rumaintv6673251 @@ -0,0 +1 @@ +{"stream":{"url":"https://i-cdn-0.lethe399key.com/stream2/i-cdn-0/01df0d24fc785e08a44241ed17dc9aef/MJTMsp1RshGTygnMNRUR2N2MSlnWXZEdMNDZzQWe5MDZzMmdZJTO1R2RWVHZDljekhkSsl1VwYnWtx2cihVT290VZBjTH1kMORVR390RFRTT6lFMPRUS18EVNhnWUtWMapWQ5l1VRJjTHlUP:1767971582:193.233.230.8:3e079e35a7d560d1b37aa2a38f4b3e6cf2d6449ab480651c4c3557eda220addd/index.m3u8"}} \ No newline at end of file diff --git a/src/extractor/__fixtures__/RgShows/https:i-arch-400.lethe399key.com-0d4475035df5f2c4950ddec91c1c5007 b/src/extractor/__fixtures__/RgShows/https:i-arch-400.lethe399key.com-0d4475035df5f2c4950ddec91c1c5007 new file mode 100644 index 0000000..5f1d166 --- /dev/null +++ b/src/extractor/__fixtures__/RgShows/https:i-arch-400.lethe399key.com-0d4475035df5f2c4950ddec91c1c5007 @@ -0,0 +1,9 @@ +#EXTM3U +#EXT-X-STREAM-INF:BANDWIDTH=400000,RESOLUTION=640x358 +./360/index.m3u8 +#EXT-X-STREAM-INF:BANDWIDTH=800000,RESOLUTION=858x482 +./480/index.m3u8 +#EXT-X-STREAM-INF:BANDWIDTH=2000000,RESOLUTION=1280x720 +./720/index.m3u8 +#EXT-X-STREAM-INF:BANDWIDTH=3000000,RESOLUTION=1920x1080 +./1080/index.m3u8 diff --git a/src/extractor/__fixtures__/RgShows/https:i-cdn-0.lethe399key.com-ea06cca9877e47ce5f9c274b5c99b941 b/src/extractor/__fixtures__/RgShows/https:i-cdn-0.lethe399key.com-ea06cca9877e47ce5f9c274b5c99b941 new file mode 100644 index 0000000..5f1d166 --- /dev/null +++ b/src/extractor/__fixtures__/RgShows/https:i-cdn-0.lethe399key.com-ea06cca9877e47ce5f9c274b5c99b941 @@ -0,0 +1,9 @@ +#EXTM3U +#EXT-X-STREAM-INF:BANDWIDTH=400000,RESOLUTION=640x358 +./360/index.m3u8 +#EXT-X-STREAM-INF:BANDWIDTH=800000,RESOLUTION=858x482 +./480/index.m3u8 +#EXT-X-STREAM-INF:BANDWIDTH=2000000,RESOLUTION=1280x720 +./720/index.m3u8 +#EXT-X-STREAM-INF:BANDWIDTH=3000000,RESOLUTION=1920x1080 +./1080/index.m3u8 diff --git a/src/extractor/__snapshots__/RgShows.test.ts.snap b/src/extractor/__snapshots__/RgShows.test.ts.snap new file mode 100644 index 0000000..a991142 --- /dev/null +++ b/src/extractor/__snapshots__/RgShows.test.ts.snap @@ -0,0 +1,43 @@ +// Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing + +exports[`RgShows handle one battle after another 1`] = ` +[ + { + "format": "hls", + "label": "RgShows", + "meta": { + "countryCodes": [], + "extractorId": "rgshows", + "height": 1080, + }, + "requestHeaders": { + "Origin": "https://rgshows.ru", + "Referer": "https://rgshows.ru/", + "User-Agent": "Mozilla", + }, + "ttl": 10800000, + "url": "https://i-arch-400.lethe399key.com/stream2/i-arch-400/01df0d24fc785e08a44241ed17dc9aef/MJTMsp1RshGTygnMNRUR2N2MSlnWXZEdMNDZzQWe5MDZzMmdZJTO1R2RWVHZDljekhkSsl1VwYnWtx2cihVT2pFVNlnT6FVNPR1a04kMJlnTUJkaO1WWzklaNFTTHV1daRUW04ERFhnWUFVP:1767971011:193.233.230.8:338a99d2e898667664ed62657ac0b65a05ed7308fe98419b3a65225ee36a7ae1/index.m3u8", + }, +] +`; + +exports[`RgShows handle stranger things s05e01 1`] = ` +[ + { + "format": "hls", + "label": "RgShows", + "meta": { + "countryCodes": [], + "extractorId": "rgshows", + "height": 1080, + }, + "requestHeaders": { + "Origin": "https://rgshows.ru", + "Referer": "https://rgshows.ru/", + "User-Agent": "Mozilla", + }, + "ttl": 10800000, + "url": "https://i-cdn-0.lethe399key.com/stream2/i-cdn-0/01df0d24fc785e08a44241ed17dc9aef/MJTMsp1RshGTygnMNRUR2N2MSlnWXZEdMNDZzQWe5MDZzMmdZJTO1R2RWVHZDljekhkSsl1VwYnWtx2cihVT290VZBjTH1kMORVR390RFRTT6lFMPRUS18EVNhnWUtWMapWQ5l1VRJjTHlUP:1767971582:193.233.230.8:3e079e35a7d560d1b37aa2a38f4b3e6cf2d6449ab480651c4c3557eda220addd/index.m3u8", + }, +] +`; diff --git a/src/extractor/index.ts b/src/extractor/index.ts index 738f415..19536ba 100644 --- a/src/extractor/index.ts +++ b/src/extractor/index.ts @@ -11,6 +11,7 @@ import { HubCloud } from './HubCloud'; import { KinoGer } from './KinoGer'; import { LuluStream } from './LuluStream'; import { Mixdrop } from './Mixdrop'; +import { RgShows } from './RgShows'; import { SaveFiles } from './SaveFiles'; import { StreamEmbed } from './StreamEmbed'; import { Streamtape } from './Streamtape'; @@ -38,6 +39,7 @@ export const createExtractors = (fetcher: Fetcher): Extractor[] => { new KinoGer(fetcher), new LuluStream(fetcher), new Mixdrop(fetcher), + new RgShows(fetcher), new SaveFiles(fetcher), new StreamEmbed(fetcher), new Streamtape(fetcher), diff --git a/src/source/RgShows.test.ts b/src/source/RgShows.test.ts new file mode 100644 index 0000000..bbe41d5 --- /dev/null +++ b/src/source/RgShows.test.ts @@ -0,0 +1,23 @@ +import { createTestContext } from '../test'; +import { FetcherMock, TmdbId } from '../utils'; +import { RgShows } from './RgShows'; + +const ctx = createTestContext(); + +describe('RgShows', () => { + let source: RgShows; + + beforeEach(() => { + source = new RgShows(new FetcherMock(`${__dirname}/__fixtures__/RgShows`)); + }); + + test('handle stranger things s05e01', async () => { + const streams = await source.handle(ctx, 'series', new TmdbId(66732, 5, 1)); + expect(streams).toMatchSnapshot(); + }); + + test('handle one battle after another', async () => { + const streams = await source.handle(ctx, 'movie', new TmdbId(1054867, undefined, undefined)); + expect(streams).toMatchSnapshot(); + }); +}); diff --git a/src/source/RgShows.ts b/src/source/RgShows.ts new file mode 100644 index 0000000..c768e4c --- /dev/null +++ b/src/source/RgShows.ts @@ -0,0 +1,42 @@ +import { ContentType } from 'stremio-addon-sdk'; +import { Context, CountryCode } from '../types'; +import { Fetcher, getTmdbId, getTmdbNameAndYear, Id } from '../utils'; +import { Source, SourceResult } from './Source'; + +export class RgShows extends Source { + public readonly id = 'rgshows'; + + public readonly label = 'RgShows'; + + public readonly contentTypes: ContentType[] = ['movie', 'series']; + + public readonly countryCodes: CountryCode[] = [CountryCode.en]; + + public readonly baseUrl = 'https://rgshows.ru'; + + private readonly fetcher: Fetcher; + + public constructor(fetcher: Fetcher) { + super(); + + this.fetcher = fetcher; + } + + public async handleInternal(ctx: Context, _type: string, id: Id): Promise { + const tmdbId = await getTmdbId(ctx, this.fetcher, id); + const [name, year] = await getTmdbNameAndYear(ctx, this.fetcher, tmdbId); + + let title: string = name; + if (tmdbId.season) { + title += ` ${tmdbId.formatSeasonAndEpisode()}`; + } else { + title += ` (${year})`; + } + + const url = tmdbId.season + ? new URL(`https://api.rgshows.ru/main/tv/${tmdbId.id}/${tmdbId.season}/${tmdbId.episode}`, this.baseUrl) + : new URL(`https://api.rgshows.ru/main/movie/${tmdbId.id}`, this.baseUrl); + + return [{ url, meta: { countryCodes: [CountryCode.multi], title } }]; + }; +} diff --git a/src/source/__fixtures__/RgShows/https:api.themoviedb.org3movie1054867 b/src/source/__fixtures__/RgShows/https:api.themoviedb.org3movie1054867 new file mode 100644 index 0000000..cdc38f2 --- /dev/null +++ b/src/source/__fixtures__/RgShows/https:api.themoviedb.org3movie1054867 @@ -0,0 +1 @@ +{"adult":false,"backdrop_path":"/zpEWFNqoN8Qg1SzMMHmaGyOBTdW.jpg","belongs_to_collection":null,"budget":175000000,"genres":[{"id":53,"name":"Thriller"},{"id":80,"name":"Crime"},{"id":28,"name":"Action"}],"homepage":"https://www.onebattleafteranothermovie.com","id":1054867,"imdb_id":"tt30144839","origin_country":["US"],"original_language":"en","original_title":"One Battle After Another","overview":"Washed-up revolutionary Bob exists in a state of stoned paranoia, surviving off-grid with his spirited, self-reliant daughter, Willa. When his evil nemesis resurfaces after 16 years and she goes missing, the former radical scrambles to find her, father and daughter both battling the consequences of his past.","popularity":88.9734,"poster_path":"/r4uXvqCeco0KmO0CjlhXuTEFuSE.jpg","production_companies":[{"id":174,"logo_path":"/ingPVoHnINIrFR7WHmYux1f5pES.png","name":"Warner Bros. Pictures","origin_country":"US"},{"id":178,"logo_path":null,"name":"Ghoulardi Film Company","origin_country":"US"},{"id":216687,"logo_path":"/kKVYqekveOvLK1IgqdJojLjQvtu.png","name":"Domain Entertainment","origin_country":"US"}],"production_countries":[{"iso_3166_1":"US","name":"United States of America"}],"release_date":"2025-09-23","revenue":205168736,"runtime":162,"spoken_languages":[{"english_name":"English","iso_639_1":"en","name":"English"},{"english_name":"French","iso_639_1":"fr","name":"Français"},{"english_name":"Spanish","iso_639_1":"es","name":"Español"},{"english_name":"Telugu","iso_639_1":"te","name":"తెలుగు"}],"status":"Released","tagline":"Some search for battle, others are born into it...","title":"One Battle After Another","video":false,"vote_average":7.462,"vote_count":2171} \ No newline at end of file diff --git a/src/source/__fixtures__/RgShows/https:api.themoviedb.org3tv66732 b/src/source/__fixtures__/RgShows/https:api.themoviedb.org3tv66732 new file mode 100644 index 0000000..470136e --- /dev/null +++ b/src/source/__fixtures__/RgShows/https:api.themoviedb.org3tv66732 @@ -0,0 +1 @@ +{"adult":false,"backdrop_path":"/8zbAoryWbtH0DKdev8abFAjdufy.jpg","created_by":[{"id":1179422,"credit_id":"57599b039251410a99001cce","name":"Ross Duffer","original_name":"Ross Duffer","gender":2,"profile_path":"/kN1HdFViQkcJOQlNcvvFJIx9Uju.jpg"},{"id":1179419,"credit_id":"57599b0e925141378a002c87","name":"Matt Duffer","original_name":"Matt Duffer","gender":2,"profile_path":"/kXO5CnSxC0znMAICGxnPeuGP73U.jpg"}],"episode_run_time":[],"first_air_date":"2016-07-15","genres":[{"id":10765,"name":"Sci-Fi & Fantasy"},{"id":9648,"name":"Mystery"},{"id":10759,"name":"Action & Adventure"}],"homepage":"https://www.netflix.com/title/80057281","id":66732,"in_production":false,"languages":["en"],"last_air_date":"2025-12-31","last_episode_to_air":{"id":5607051,"name":"Chapter Eight: The Rightside Up","overview":"As Vecna prepares to destroy the world as we know it, the party must put everything on the line to defeat him once and for all.","vote_average":7.113,"vote_count":80,"air_date":"2025-12-31","episode_number":8,"episode_type":"finale","production_code":"","runtime":129,"season_number":5,"show_id":66732,"still_path":"/kP23RWbUWM6vGhT9PxFyP5VT3y4.jpg"},"name":"Stranger Things","next_episode_to_air":null,"networks":[{"id":213,"logo_path":"/wwemzKWzjKYJFfCeiB57q3r4Bcm.png","name":"Netflix","origin_country":""}],"number_of_episodes":42,"number_of_seasons":5,"origin_country":["US"],"original_language":"en","original_name":"Stranger Things","overview":"When a young boy vanishes, a small town uncovers a mystery involving secret experiments, terrifying supernatural forces, and one strange little girl.","popularity":1622.2589,"poster_path":"/uOOtwVbSr4QDjAGIifLDwpb2Pdl.jpg","production_companies":[{"id":2575,"logo_path":"/9YJrHYlcfHtwtulkFMAies3aFEl.png","name":"21 Laps Entertainment","origin_country":"US"},{"id":170090,"logo_path":null,"name":"Monkey Massacre Productions","origin_country":"US"},{"id":184664,"logo_path":"/4qv40ryAKUzvwptbv13eXUAl1Wm.png","name":"Upside Down Pictures","origin_country":"US"}],"production_countries":[{"iso_3166_1":"US","name":"United States of America"}],"seasons":[{"air_date":"2016-07-15","episode_count":8,"id":77680,"name":"Season 1","overview":"Strange things are afoot in Hawkins, Indiana, where a young boy's sudden disappearance unearths a young girl with otherworldly powers.","poster_path":"/hb4KmdA4F1XMnf0vVjevPKKBEjV.jpg","season_number":1,"vote_average":8.4},{"air_date":"2017-10-27","episode_count":9,"id":83248,"name":"Stranger Things 2","overview":"It's been nearly a year since Will's strange disappearance. But life's hardly back to normal in Hawkins. Not even close.","poster_path":"/74nFJmiapxKuUBXRbSu6VqGGcuo.jpg","season_number":2,"vote_average":8.2},{"air_date":"2019-07-04","episode_count":8,"id":115216,"name":"Stranger Things 3","overview":"Budding romance. A brand-new mall. And rabid rats running toward danger. It's the summer of 1985 in Hawkins ... and one summer can change everything.","poster_path":"/sDms9g40ZBhjMIfX9YqqaqId8sK.jpg","season_number":3,"vote_average":8.1},{"air_date":"2022-05-27","episode_count":9,"id":163313,"name":"Stranger Things 4","overview":"Darkness returns to Hawkins just in time for spring break, igniting fresh terror, disturbing memories — and an ominous new threat.","poster_path":"/zvGTZYDCoMSMIBkXExxRxLYimqN.jpg","season_number":4,"vote_average":8.5},{"air_date":"2025-11-26","episode_count":8,"id":402292,"name":"Stranger Things 5","overview":"The fall of 1987. Hawkins is scarred by rifts. Vecna has vanished and the government has placed the town under military quarantine, forcing Eleven back into hiding. To end this nightmare, they'll need everyone together, one last time.","poster_path":"/AaLrOh33YLkK1WLEB8Uml7FL8fm.jpg","season_number":5,"vote_average":7.5}],"spoken_languages":[{"english_name":"English","iso_639_1":"en","name":"English"}],"status":"Ended","tagline":"One last adventure.","type":"Scripted","vote_average":8.591,"vote_count":19952} \ No newline at end of file diff --git a/src/source/__snapshots__/RgShows.test.ts.snap b/src/source/__snapshots__/RgShows.test.ts.snap new file mode 100644 index 0000000..aef18b1 --- /dev/null +++ b/src/source/__snapshots__/RgShows.test.ts.snap @@ -0,0 +1,29 @@ +// Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing + +exports[`RgShows handle one battle after another 1`] = ` +[ + { + "meta": { + "countryCodes": [ + "multi", + ], + "title": "One Battle After Another (2025)", + }, + "url": "https://api.rgshows.ru/main/movie/1054867", + }, +] +`; + +exports[`RgShows handle stranger things s05e01 1`] = ` +[ + { + "meta": { + "countryCodes": [ + "multi", + ], + "title": "Stranger Things S05E01", + }, + "url": "https://api.rgshows.ru/main/tv/66732/5/1", + }, +] +`; diff --git a/src/source/index.ts b/src/source/index.ts index b21b6a3..5d4402f 100644 --- a/src/source/index.ts +++ b/src/source/index.ts @@ -13,6 +13,7 @@ import { MegaKino } from './MegaKino'; import { MeineCloud } from './MeineCloud'; import { MostraGuarda } from './MostraGuarda'; import { Movix } from './Movix'; +import { RgShows } from './RgShows'; import { Source } from './Source'; import { StreamKiste } from './StreamKiste'; import { VerHdLink } from './VerHdLink'; @@ -26,6 +27,7 @@ export const createSources = (fetcher: Fetcher): Source[] => { return [ // multi new FourKHDHub(fetcher), + new RgShows(fetcher), new VixSrc(fetcher), // AL new Kokoshka(fetcher), diff --git a/src/utils/Fetcher.ts b/src/utils/Fetcher.ts index 485cba2..774aba4 100644 --- a/src/utils/Fetcher.ts +++ b/src/utils/Fetcher.ts @@ -42,6 +42,7 @@ type ProxyConfig = Pick { - const proxyUrl = this.getProxyForUrl(ctx, url); + const proxyUrl = requestConfig?.noProxy ? null : this.getProxyForUrl(ctx, url); let message = `Fetch ${requestConfig?.method ?? 'GET'} ${url}`; /* istanbul ignore if */ diff --git a/src/utils/__snapshots__/manifest.test.ts.snap b/src/utils/__snapshots__/manifest.test.ts.snap index cbb7228..5fccbd7 100644 --- a/src/utils/__snapshots__/manifest.test.ts.snap +++ b/src/utils/__snapshots__/manifest.test.ts.snap @@ -24,6 +24,11 @@ exports[`buildManifest default manifest 1`] = ` "title": "German 🇩🇪 (Einschalten, KinoGer, MegaKino, MeineCloud, StreamKiste)", "type": "checkbox", }, + { + "key": "en", + "title": "English 🇺🇸 (RgShows)", + "type": "checkbox", + }, { "key": "es", "title": "Castilian Spanish 🇪🇸 (CineHDPlus, Cuevana, HomeCine, VerHdLink)", @@ -74,9 +79,9 @@ exports[`buildManifest default manifest 1`] = ` ], "description": "Provides HTTP URLs from streaming websites. Configure add-on for additional languages. Add MediaFlow proxy for more URLs. -Supported languages: Albanian, German, Castilian Spanish, French, Hindi, Italian, Latin American Spanish +Supported languages: Albanian, German, English, Castilian Spanish, French, Hindi, Italian, Latin American Spanish -Supported sources: 4KHDHub, VixSrc, Kokoshka, CineHDPlus, Cuevana, HomeCine, VerHdLink, Einschalten, KinoGer, MegaKino, MeineCloud, StreamKiste, Frembed, FrenchCloud, Movix, Eurostreaming, MostraGuarda +Supported sources: 4KHDHub, RgShows, VixSrc, Kokoshka, CineHDPlus, Cuevana, HomeCine, VerHdLink, Einschalten, KinoGer, MegaKino, MeineCloud, StreamKiste, Frembed, FrenchCloud, Movix, Eurostreaming, MostraGuarda Supported extractors: ", "id": "webstreamr",