new config system

This commit is contained in:
Jelle van Snik 2022-12-27 16:44:36 +01:00
parent 2e8025a241
commit 388827b56f
20 changed files with 168 additions and 69 deletions

View File

@ -1,26 +1,32 @@
const a11yOff = Object.keys(require('eslint-plugin-jsx-a11y').rules) const a11yOff = Object.keys(require("eslint-plugin-jsx-a11y").rules).reduce(
.reduce((acc, rule) => { acc[`jsx-a11y/${rule}`] = 'off'; return acc }, {}) (acc, rule) => {
acc[`jsx-a11y/${rule}`] = "off";
return acc;
},
{}
);
module.exports = { module.exports = {
extends: [ extends: [
"airbnb", "airbnb",
"airbnb/hooks", "airbnb/hooks",
"plugin:@typescript-eslint/recommended", "plugin:@typescript-eslint/recommended",
"prettier", "prettier"
], ],
settings: { settings: {
"import/resolver": { "import/resolver": {
typescript: {}, typescript: {}
}, }
}, },
ignorePatterns: ["public/*", "/*.js", "/*.ts"],
parser: "@typescript-eslint/parser", parser: "@typescript-eslint/parser",
parserOptions: { parserOptions: {
project: "./tsconfig.json", project: "./tsconfig.json",
tsconfigRootDir: "./", tsconfigRootDir: "./"
}, },
plugins: ["@typescript-eslint", "import"], plugins: ["@typescript-eslint", "import"],
env: { env: {
browser: true, browser: true
}, },
rules: { rules: {
"react/jsx-uses-react": "off", "react/jsx-uses-react": "off",
@ -43,16 +49,16 @@ module.exports = {
"no-await-in-loop": "off", "no-await-in-loop": "off",
"react/jsx-filename-extension": [ "react/jsx-filename-extension": [
"error", "error",
{ extensions: [".js", ".tsx", ".jsx"] }, { extensions: [".js", ".tsx", ".jsx"] }
], ],
"import/extensions": [ "import/extensions": [
"error", "error",
"ignorePackages", "ignorePackages",
{ {
ts: "never", ts: "never",
tsx: "never", tsx: "never"
}, }
], ],
...a11yOff ...a11yOff
}, }
}; };

3
.gitignore vendored
View File

@ -23,3 +23,6 @@ yarn-debug.log*
yarn-error.log* yarn-error.log*
package-lock.json package-lock.json
# config
.env

View File

@ -45,7 +45,7 @@ yarn start
To build production files, simply run `yarn build`. To build production files, simply run `yarn build`.
You'll need to deploy a cloudflare service worker as well. Check the [selfhosting guide](https://github.com/movie-web/movie-web/blob/dev/SELFHOSTING.md) on how to run the service worker. Afterwards update the proxy URL constant in `/src/mw-constants.ts` with your service worker. You'll need to deploy a cloudflare service worker as well. Check the [selfhosting guide](https://github.com/movie-web/movie-web/blob/dev/SELFHOSTING.md) on how to run the service worker. Afterwards you can make a `.env` file and put in the URL. (see `example.env` for an example)
<h2>Contributing - <a href="https://github.com/JamesHawkinss/movie-web/issues"><img alt="GitHub issues" src="https://img.shields.io/github/issues/JamesHawkinss/movie-web?style=flat-square"></a> <h2>Contributing - <a href="https://github.com/JamesHawkinss/movie-web/issues"><img alt="GitHub issues" src="https://img.shields.io/github/issues/JamesHawkinss/movie-web?style=flat-square"></a>
<a href="https://github.com/JamesHawkinss/movie-web/pulls"><img alt="GitHub pull requests" src="https://img.shields.io/github/issues-pr/JamesHawkinss/movie-web?style=flat-square"></a></h2> <a href="https://github.com/JamesHawkinss/movie-web/pulls"><img alt="GitHub pull requests" src="https://img.shields.io/github/issues-pr/JamesHawkinss/movie-web?style=flat-square"></a></h2>

View File

@ -28,6 +28,11 @@ Your proxy is now hosted on cloudflare. Note the url of your worker. you will ne
1. Download the file `movie-web.zip` from the latest release: [https://github.com/movie-web/movie-web/releases/latest](https://github.com/movie-web/movie-web/releases/latest) 1. Download the file `movie-web.zip` from the latest release: [https://github.com/movie-web/movie-web/releases/latest](https://github.com/movie-web/movie-web/releases/latest)
2. Extract the zip file so you can edit the files. 2. Extract the zip file so you can edit the files.
3. Open `config.js` in notepad, VScode or similar.
4. Put your cloudflare proxy URL inbetween the double qoutes of `VITE_CORS_PROXY_URL: "",`.
> Whoops, the rest of this guide hasn't been written yet. Example (THIS IS MINE, IT WONT WORK FOR YOU): `VITE_CORS_PROXY_URL: "https://test-proxy.test.workers.dev/",`
Check back soon. 5. Save the file
Your client has been prepared, you can now host it on any webhost.
It doesn't require php, its just a standard static page.

6
example.env Normal file
View File

@ -0,0 +1,6 @@
# make sure the cors proxy url does NOT have a slash at the end
VITE_CORS_PROXY_URL=...
# the keys below are optional - defaults are provided
VITE_TMDB_API_KEY=...
VITE_OMDB_API_KEY=...

View File

@ -39,6 +39,7 @@
rel="stylesheet" rel="stylesheet"
/> />
<script src="config.js"></script>
<title>movie-web</title> <title>movie-web</title>
</head> </head>
<body> <body>

5
public/config.js Normal file
View File

@ -0,0 +1,5 @@
window.__CONFIG__ = {
VITE_CORS_PROXY_URL: "",
VITE_TMDB_API_KEY: "b030404650f279792a8d3287232358e3",
VITE_OMDB_API_KEY: "aa0937c0"
};

View File

@ -3,7 +3,7 @@ import { IconPatch } from "@/components/buttons/IconPatch";
import { Icons } from "@/components/Icon"; import { Icons } from "@/components/Icon";
import { Link } from "@/components/text/Link"; import { Link } from "@/components/text/Link";
import { Title } from "@/components/text/Title"; import { Title } from "@/components/text/Title";
import { DISCORD_LINK, GITHUB_LINK } from "@/mw_constants"; import { conf } from "@/config";
interface ErrorBoundaryState { interface ErrorBoundaryState {
hasError: boolean; hasError: boolean;
@ -58,11 +58,11 @@ export class ErrorBoundary extends Component<
<p className="my-6 max-w-lg"> <p className="my-6 max-w-lg">
The app encountered an error and wasn&apos;t able to recover, please The app encountered an error and wasn&apos;t able to recover, please
report it to the{" "} report it to the{" "}
<Link url={DISCORD_LINK} newTab> <Link url={conf().DISCORD_LINK} newTab>
Discord server Discord server
</Link>{" "} </Link>{" "}
or on{" "} or on{" "}
<Link url={GITHUB_LINK} newTab> <Link url={conf().GITHUB_LINK} newTab>
GitHub GitHub
</Link> </Link>
. .

View File

@ -2,7 +2,7 @@ import { ReactNode } from "react";
import { Link } from "react-router-dom"; import { Link } from "react-router-dom";
import { IconPatch } from "@/components/buttons/IconPatch"; import { IconPatch } from "@/components/buttons/IconPatch";
import { Icons } from "@/components/Icon"; import { Icons } from "@/components/Icon";
import { DISCORD_LINK, GITHUB_LINK } from "@/mw_constants"; import { conf } from "@/config";
import { BrandPill } from "./BrandPill"; import { BrandPill } from "./BrandPill";
export interface NavigationProps { export interface NavigationProps {
@ -26,7 +26,7 @@ export function Navigation(props: NavigationProps) {
} flex-row gap-4`} } flex-row gap-4`}
> >
<a <a
href={DISCORD_LINK} href={conf().DISCORD_LINK}
target="_blank" target="_blank"
rel="noreferrer" rel="noreferrer"
className="text-2xl text-white" className="text-2xl text-white"
@ -34,7 +34,7 @@ export function Navigation(props: NavigationProps) {
<IconPatch icon={Icons.DISCORD} clickable /> <IconPatch icon={Icons.DISCORD} clickable />
</a> </a>
<a <a
href={GITHUB_LINK} href={conf().GITHUB_LINK}
target="_blank" target="_blank"
rel="noreferrer" rel="noreferrer"
className="text-2xl text-white" className="text-2xl text-white"

50
src/config.ts Normal file
View File

@ -0,0 +1,50 @@
import { APP_VERSION, GITHUB_LINK, DISCORD_LINK } from "@/constants";
export interface Config {
APP_VERSION: string;
GITHUB_LINK: string;
DISCORD_LINK: string;
OMDB_API_KEY: string;
TMDB_API_KEY: string;
CORS_PROXY_URL: string;
}
const env: Record<keyof Config, undefined | string> = {
OMDB_API_KEY: import.meta.env.VITE_OMDB_API_KEY,
TMDB_API_KEY: import.meta.env.VITE_TMDB_API_KEY,
APP_VERSION: undefined,
GITHUB_LINK: undefined,
DISCORD_LINK: undefined,
CORS_PROXY_URL: import.meta.env.VITE_CORS_PROXY_URL,
};
const alerts = [] as string[];
// loads from different locations, in order: environment (VITE_{KEY}), window (public/config.js)
function getKey(key: keyof Config): string {
let windowValue = (window as any)?.__CONFIG__?.[`VITE_${key}`];
if (windowValue !== undefined && windowValue.length === 0)
windowValue = undefined;
const value = env[key] ?? windowValue ?? undefined;
if (value === undefined) {
if (!alerts.includes(key)) {
// eslint-disable-next-line no-alert
window.alert(`Misconfigured instance, missing key: ${key}`);
alerts.push(key);
}
return "";
}
return value;
}
export function conf(): Config {
return {
APP_VERSION,
GITHUB_LINK,
DISCORD_LINK,
OMDB_API_KEY: getKey("OMDB_API_KEY"),
TMDB_API_KEY: getKey("TMDB_API_KEY"),
CORS_PROXY_URL: `${getKey("CORS_PROXY_URL")}/?destination=`,
};
}

3
src/constants.ts Normal file
View File

@ -0,0 +1,3 @@
export const DISCORD_LINK = "https://discord.gg/Jhqt4Xzpfb";
export const GITHUB_LINK = "https://github.com/JamesHawkinss/movie-web";
export const APP_VERSION = "2.1.0";

View File

@ -1,7 +0,0 @@
export const CORS_PROXY_URL =
"https://cors.squeezebox.dev/?destination=";
export const TMDB_API_KEY = "b030404650f279792a8d3287232358e3";
export const OMDB_API_KEY = "aa0937c0";
export const DISCORD_LINK = "https://discord.gg/Jhqt4Xzpfb";
export const GITHUB_LINK = "https://github.com/JamesHawkinss/movie-web";
export const APP_VERSION = "2.1.0";

View File

@ -7,7 +7,7 @@ import {
MWProviderMediaResult, MWProviderMediaResult,
} from "@/providers/types"; } from "@/providers/types";
import { CORS_PROXY_URL } from "@/mw_constants"; import { conf } from "@/config";
export const flixhqProvider: MWMediaProvider = { export const flixhqProvider: MWMediaProvider = {
id: "flixhq", id: "flixhq",
@ -19,7 +19,9 @@ export const flixhqProvider: MWMediaProvider = {
media: MWPortableMedia media: MWPortableMedia
): Promise<MWProviderMediaResult> { ): Promise<MWProviderMediaResult> {
const searchRes = await fetch( const searchRes = await fetch(
`${CORS_PROXY_URL}https://api.consumet.org/movies/flixhq/info?id=${encodeURIComponent( `${
conf().CORS_PROXY_URL
}https://api.consumet.org/movies/flixhq/info?id=${encodeURIComponent(
media.mediaId media.mediaId
)}` )}`
).then((d) => d.json()); ).then((d) => d.json());
@ -33,7 +35,9 @@ export const flixhqProvider: MWMediaProvider = {
async searchForMedia(query: MWQuery): Promise<MWProviderMediaResult[]> { async searchForMedia(query: MWQuery): Promise<MWProviderMediaResult[]> {
const searchRes = await fetch( const searchRes = await fetch(
`${CORS_PROXY_URL}https://api.consumet.org/movies/flixhq/${encodeURIComponent( `${
conf().CORS_PROXY_URL
}https://api.consumet.org/movies/flixhq/${encodeURIComponent(
query.searchQuery query.searchQuery
)}` )}`
).then((d) => d.json()); ).then((d) => d.json());
@ -52,7 +56,9 @@ export const flixhqProvider: MWMediaProvider = {
async getStream(media: MWPortableMedia): Promise<MWMediaStream> { async getStream(media: MWPortableMedia): Promise<MWMediaStream> {
const searchRes = await fetch( const searchRes = await fetch(
`${CORS_PROXY_URL}https://api.consumet.org/movies/flixhq/info?id=${encodeURIComponent( `${
conf().CORS_PROXY_URL
}https://api.consumet.org/movies/flixhq/info?id=${encodeURIComponent(
media.mediaId media.mediaId
)}` )}`
).then((d) => d.json()); ).then((d) => d.json());
@ -63,7 +69,9 @@ export const flixhqProvider: MWMediaProvider = {
}); });
const watchRes = await fetch( const watchRes = await fetch(
`${CORS_PROXY_URL}https://api.consumet.org/movies/flixhq/watch?${encodeURIComponent( `${
conf().CORS_PROXY_URL
}https://api.consumet.org/movies/flixhq/watch?${encodeURIComponent(
params.toString() params.toString()
)}` )}`
).then((d) => d.json()); ).then((d) => d.json());

View File

@ -9,7 +9,7 @@ import {
MWProviderMediaResult, MWProviderMediaResult,
} from "@/providers/types"; } from "@/providers/types";
import { CORS_PROXY_URL } from "@/mw_constants"; import { conf } from "@/config";
const format = { const format = {
stringify: (cipher: any) => { stringify: (cipher: any) => {
@ -47,7 +47,9 @@ export const gDrivePlayerScraper: MWMediaProvider = {
media: MWPortableMedia media: MWPortableMedia
): Promise<MWProviderMediaResult> { ): Promise<MWProviderMediaResult> {
const res = await fetch( const res = await fetch(
`${CORS_PROXY_URL}https://api.gdriveplayer.us/v1/imdb/${media.mediaId}` `${conf().CORS_PROXY_URL}https://api.gdriveplayer.us/v1/imdb/${
media.mediaId
}`
).then((d) => d.json()); ).then((d) => d.json());
return { return {
@ -59,7 +61,9 @@ export const gDrivePlayerScraper: MWMediaProvider = {
async searchForMedia(query: MWQuery): Promise<MWProviderMediaResult[]> { async searchForMedia(query: MWQuery): Promise<MWProviderMediaResult[]> {
const searchRes = await fetch( const searchRes = await fetch(
`${CORS_PROXY_URL}https://api.gdriveplayer.us/v1/movie/search?title=${query.searchQuery}` `${
conf().CORS_PROXY_URL
}https://api.gdriveplayer.us/v1/movie/search?title=${query.searchQuery}`
).then((d) => d.json()); ).then((d) => d.json());
const results: MWProviderMediaResult[] = (searchRes || []).map( const results: MWProviderMediaResult[] = (searchRes || []).map(
@ -75,7 +79,9 @@ export const gDrivePlayerScraper: MWMediaProvider = {
async getStream(media: MWPortableMedia): Promise<MWMediaStream> { async getStream(media: MWPortableMedia): Promise<MWMediaStream> {
const streamRes = await fetch( const streamRes = await fetch(
`${CORS_PROXY_URL}https://database.gdriveplayer.us/player.php?imdb=${media.mediaId}` `${
conf().CORS_PROXY_URL
}https://database.gdriveplayer.us/player.php?imdb=${media.mediaId}`
).then((d) => d.text()); ).then((d) => d.text());
const page = new DOMParser().parseFromString(streamRes, "text/html"); const page = new DOMParser().parseFromString(streamRes, "text/html");

View File

@ -9,7 +9,7 @@ import {
MWProviderMediaResult, MWProviderMediaResult,
} from "@/providers/types"; } from "@/providers/types";
import { CORS_PROXY_URL, OMDB_API_KEY } from "@/mw_constants"; import { conf } from "@/config";
export const gomostreamScraper: MWMediaProvider = { export const gomostreamScraper: MWMediaProvider = {
id: "gomostream", id: "gomostream",
@ -21,13 +21,13 @@ export const gomostreamScraper: MWMediaProvider = {
media: MWPortableMedia media: MWPortableMedia
): Promise<MWProviderMediaResult> { ): Promise<MWProviderMediaResult> {
const params = new URLSearchParams({ const params = new URLSearchParams({
apikey: OMDB_API_KEY, apikey: conf().OMDB_API_KEY,
i: media.mediaId, i: media.mediaId,
type: media.mediaType, type: media.mediaType,
}); });
const res = await fetch( const res = await fetch(
`${CORS_PROXY_URL}http://www.omdbapi.com/?${encodeURIComponent( `${conf().CORS_PROXY_URL}http://www.omdbapi.com/?${encodeURIComponent(
params.toString() params.toString()
)}` )}`
).then((d) => d.json()); ).then((d) => d.json());
@ -43,12 +43,12 @@ export const gomostreamScraper: MWMediaProvider = {
const term = query.searchQuery.toLowerCase(); const term = query.searchQuery.toLowerCase();
const params = new URLSearchParams({ const params = new URLSearchParams({
apikey: OMDB_API_KEY, apikey: conf().OMDB_API_KEY,
s: term, s: term,
type: query.type, type: query.type,
}); });
const searchRes = await fetch( const searchRes = await fetch(
`${CORS_PROXY_URL}http://www.omdbapi.com/?${encodeURIComponent( `${conf().CORS_PROXY_URL}http://www.omdbapi.com/?${encodeURIComponent(
params.toString() params.toString()
)}` )}`
).then((d) => d.json()); ).then((d) => d.json());
@ -69,7 +69,7 @@ export const gomostreamScraper: MWMediaProvider = {
const type = const type =
media.mediaType === MWMediaType.SERIES ? "show" : media.mediaType; media.mediaType === MWMediaType.SERIES ? "show" : media.mediaType;
const res1 = await fetch( const res1 = await fetch(
`${CORS_PROXY_URL}https://gomo.to/${type}/${media.mediaId}` `${conf().CORS_PROXY_URL}https://gomo.to/${type}/${media.mediaId}`
).then((d) => d.text()); ).then((d) => d.text());
if (res1 === "Movie not available." || res1 === "Episode not available.") if (res1 === "Movie not available." || res1 === "Episode not available.")
throw new Error(res1); throw new Error(res1);
@ -82,7 +82,7 @@ export const gomostreamScraper: MWMediaProvider = {
fd.append("_token", _token); fd.append("_token", _token);
const src = await fetch( const src = await fetch(
`${CORS_PROXY_URL}https://gomo.to/decoding_v3.php`, `${conf().CORS_PROXY_URL}https://gomo.to/decoding_v3.php`,
{ {
method: "POST", method: "POST",
body: fd, body: fd,
@ -95,7 +95,7 @@ export const gomostreamScraper: MWMediaProvider = {
// maybe try all embeds in the future // maybe try all embeds in the future
const embedUrl = embeds[1]; const embedUrl = embeds[1];
const res2 = await fetch(`${CORS_PROXY_URL}${embedUrl}`).then((d) => const res2 = await fetch(`${conf().CORS_PROXY_URL}${embedUrl}`).then((d) =>
d.text() d.text()
); );

View File

@ -4,7 +4,7 @@
import { customAlphabet } from "nanoid"; import { customAlphabet } from "nanoid";
import toWebVTT from "srt-webvtt"; import toWebVTT from "srt-webvtt";
import CryptoJS from "crypto-js"; import CryptoJS from "crypto-js";
import { CORS_PROXY_URL, TMDB_API_KEY } from "@/mw_constants"; import { conf } from "@/config";
import { import {
MWMediaProvider, MWMediaProvider,
MWMediaType, MWMediaType,
@ -85,7 +85,7 @@ const get = (data: object, altApi = false) => {
formatted.append("medium", "Website"); formatted.append("medium", "Website");
const requestUrl = altApi ? apiUrls[1] : apiUrls[0]; const requestUrl = altApi ? apiUrls[1] : apiUrls[0];
return fetch(`${CORS_PROXY_URL}${requestUrl}`, { return fetch(`${conf().CORS_PROXY_URL}${requestUrl}`, {
method: "POST", method: "POST",
headers: { headers: {
Platform: "android", Platform: "android",
@ -200,7 +200,7 @@ export const superStreamScraper: MWMediaProvider = {
const mappedCaptions = await Promise.all( const mappedCaptions = await Promise.all(
subtitleRes.list.map(async (subtitle: any) => { subtitleRes.list.map(async (subtitle: any) => {
const captionBlob = await fetch( const captionBlob = await fetch(
`${CORS_PROXY_URL}${subtitle.subtitles[0].file_path}` `${conf().CORS_PROXY_URL}${subtitle.subtitles[0].file_path}`
).then((captionRes) => captionRes.blob()); // cross-origin bypass ).then((captionRes) => captionRes.blob()); // cross-origin bypass
const captionUrl = await toWebVTT(captionBlob); // convert to vtt so it's playable const captionUrl = await toWebVTT(captionBlob); // convert to vtt so it's playable
return { return {
@ -253,7 +253,7 @@ export const superStreamScraper: MWMediaProvider = {
const mappedCaptions = await Promise.all( const mappedCaptions = await Promise.all(
subtitleRes.list.map(async (subtitle: any) => { subtitleRes.list.map(async (subtitle: any) => {
const captionBlob = await fetch( const captionBlob = await fetch(
`${CORS_PROXY_URL}${subtitle.subtitles[0].file_path}` `${conf().CORS_PROXY_URL}${subtitle.subtitles[0].file_path}`
).then((captionRes) => captionRes.blob()); // cross-origin bypass ).then((captionRes) => captionRes.blob()); // cross-origin bypass
const captionUrl = await toWebVTT(captionBlob); // convert to vtt so it's playable const captionUrl = await toWebVTT(captionBlob); // convert to vtt so it's playable
return { return {
@ -277,11 +277,15 @@ export const superStreamScraper: MWMediaProvider = {
const detailRes = (await get(apiQuery, true).then((r) => r.json())).data; const detailRes = (await get(apiQuery, true).then((r) => r.json())).data;
const firstSearchResult = ( const firstSearchResult = (
await fetch( await fetch(
`https://api.themoviedb.org/3/search/tv?api_key=${TMDB_API_KEY}&language=en-US&page=1&query=${detailRes.title}&include_adult=false` `https://api.themoviedb.org/3/search/tv?api_key=${
conf().TMDB_API_KEY
}&language=en-US&page=1&query=${detailRes.title}&include_adult=false`
).then((r) => r.json()) ).then((r) => r.json())
).results[0]; ).results[0];
const showDetails = await fetch( const showDetails = await fetch(
`https://api.themoviedb.org/3/tv/${firstSearchResult.id}?api_key=${TMDB_API_KEY}` `https://api.themoviedb.org/3/tv/${firstSearchResult.id}?api_key=${
conf().TMDB_API_KEY
}`
).then((r) => r.json()); ).then((r) => r.json());
return { return {

View File

@ -15,7 +15,7 @@ import {
} from "@/providers/list/theflix/search"; } from "@/providers/list/theflix/search";
import { getDataFromPortableSearch } from "@/providers/list/theflix/portableToMedia"; import { getDataFromPortableSearch } from "@/providers/list/theflix/portableToMedia";
import { CORS_PROXY_URL } from "@/mw_constants"; import { conf } from "@/config";
export const theFlixScraper: MWMediaProvider = { export const theFlixScraper: MWMediaProvider = {
id: "theflix", id: "theflix",
@ -51,9 +51,13 @@ export const theFlixScraper: MWMediaProvider = {
let url = ""; let url = "";
if (media.mediaType === MWMediaType.MOVIE) { if (media.mediaType === MWMediaType.MOVIE) {
url = `${CORS_PROXY_URL}https://theflix.to/movie/${media.mediaId}?movieInfo=${media.mediaId}`; url = `${conf().CORS_PROXY_URL}https://theflix.to/movie/${
media.mediaId
}?movieInfo=${media.mediaId}`;
} else if (media.mediaType === MWMediaType.SERIES) { } else if (media.mediaType === MWMediaType.SERIES) {
url = `${CORS_PROXY_URL}https://theflix.to/tv-show/${media.mediaId}/season-${media.seasonId}/episode-${media.episodeId}`; url = `${conf().CORS_PROXY_URL}https://theflix.to/tv-show/${
media.mediaId
}/season-${media.seasonId}/episode-${media.episodeId}`;
} }
const res = await fetch(url).then((d) => d.text()); const res = await fetch(url).then((d) => d.text());
@ -76,7 +80,9 @@ export const theFlixScraper: MWMediaProvider = {
async getSeasonDataFromMedia( async getSeasonDataFromMedia(
media: MWPortableMedia media: MWPortableMedia
): Promise<MWMediaSeasons> { ): Promise<MWMediaSeasons> {
const url = `${CORS_PROXY_URL}https://theflix.to/tv-show/${media.mediaId}/season-${media.seasonId}/episode-${media.episodeId}`; const url = `${conf().CORS_PROXY_URL}https://theflix.to/tv-show/${
media.mediaId
}/season-${media.seasonId}/episode-${media.episodeId}`;
const res = await fetch(url).then((d) => d.text()); const res = await fetch(url).then((d) => d.text());
const node: Element = Array.from( const node: Element = Array.from(

View File

@ -1,4 +1,4 @@
import { CORS_PROXY_URL } from "@/mw_constants"; import { conf } from "@/config";
import { MWMediaType, MWPortableMedia } from "@/providers/types"; import { MWMediaType, MWPortableMedia } from "@/providers/types";
const getTheFlixUrl = (media: MWPortableMedia, params?: URLSearchParams) => { const getTheFlixUrl = (media: MWPortableMedia, params?: URLSearchParams) => {
@ -18,9 +18,9 @@ export async function getDataFromPortableSearch(
const params = new URLSearchParams(); const params = new URLSearchParams();
params.append("movieInfo", media.mediaId); params.append("movieInfo", media.mediaId);
const res = await fetch(CORS_PROXY_URL + getTheFlixUrl(media, params)).then( const res = await fetch(
(d) => d.text() conf().CORS_PROXY_URL + getTheFlixUrl(media, params)
); ).then((d) => d.text());
const node: Element = Array.from( const node: Element = Array.from(
new DOMParser() new DOMParser()

View File

@ -1,4 +1,4 @@
import { CORS_PROXY_URL } from "@/mw_constants"; import { conf } from "@/config";
import { MWMediaType, MWProviderMediaResult, MWQuery } from "@/providers"; import { MWMediaType, MWProviderMediaResult, MWQuery } from "@/providers";
const getTheFlixUrl = (type: "tv-shows" | "movies", params: URLSearchParams) => const getTheFlixUrl = (type: "tv-shows" | "movies", params: URLSearchParams) =>
@ -8,7 +8,7 @@ export function searchTheFlix(query: MWQuery): Promise<string> {
const params = new URLSearchParams(); const params = new URLSearchParams();
params.append("search", query.searchQuery); params.append("search", query.searchQuery);
return fetch( return fetch(
CORS_PROXY_URL + conf().CORS_PROXY_URL +
getTheFlixUrl( getTheFlixUrl(
query.type === MWMediaType.MOVIE ? "movies" : "tv-shows", query.type === MWMediaType.MOVIE ? "movies" : "tv-shows",
params params

View File

@ -8,7 +8,7 @@ import {
MWMediaCaption, MWMediaCaption,
} from "@/providers/types"; } from "@/providers/types";
import { CORS_PROXY_URL } from "@/mw_constants"; import { conf } from "@/config";
export const xemovieScraper: MWMediaProvider = { export const xemovieScraper: MWMediaProvider = {
id: "xemovie", id: "xemovie",
@ -20,7 +20,7 @@ export const xemovieScraper: MWMediaProvider = {
media: MWPortableMedia media: MWPortableMedia
): Promise<MWProviderMediaResult> { ): Promise<MWProviderMediaResult> {
const res = await fetch( const res = await fetch(
`${CORS_PROXY_URL}https://xemovie.co/movies/${media.mediaId}/watch` `${conf().CORS_PROXY_URL}https://xemovie.co/movies/${media.mediaId}/watch`
).then((d) => d.text()); ).then((d) => d.text());
const DOM = new DOMParser().parseFromString(res, "text/html"); const DOM = new DOMParser().parseFromString(res, "text/html");
@ -42,9 +42,9 @@ export const xemovieScraper: MWMediaProvider = {
async searchForMedia(query: MWQuery): Promise<MWProviderMediaResult[]> { async searchForMedia(query: MWQuery): Promise<MWProviderMediaResult[]> {
const term = query.searchQuery.toLowerCase(); const term = query.searchQuery.toLowerCase();
const searchUrl = `${CORS_PROXY_URL}https://xemovie.co/search?q=${encodeURIComponent( const searchUrl = `${
term conf().CORS_PROXY_URL
)}`; }https://xemovie.co/search?q=${encodeURIComponent(term)}`;
const searchRes = await fetch(searchUrl).then((d) => d.text()); const searchRes = await fetch(searchUrl).then((d) => d.text());
const parser = new DOMParser(); const parser = new DOMParser();
@ -81,7 +81,9 @@ export const xemovieScraper: MWMediaProvider = {
if (media.mediaType !== MWMediaType.MOVIE) if (media.mediaType !== MWMediaType.MOVIE)
throw new Error("Incorrect type"); throw new Error("Incorrect type");
const url = `${CORS_PROXY_URL}https://xemovie.co/movies/${media.mediaId}/watch`; const url = `${conf().CORS_PROXY_URL}https://xemovie.co/movies/${
media.mediaId
}/watch`;
let streamUrl = ""; let streamUrl = "";
const subtitles: MWMediaCaption[] = []; const subtitles: MWMediaCaption[] = [];
@ -100,7 +102,8 @@ export const xemovieScraper: MWMediaProvider = {
const data = JSON.parse( const data = JSON.parse(
JSON.stringify( JSON.stringify(
eval( eval(
`(${script.textContent.replace("const data = ", "").split("};")[0] `(${
script.textContent.replace("const data = ", "").split("};")[0]
}})` }})`
) )
) )
@ -112,7 +115,7 @@ export const xemovieScraper: MWMediaProvider = {
subtitleTrack, subtitleTrack,
] of data.playlist[0].tracks.entries()) { ] of data.playlist[0].tracks.entries()) {
const subtitleBlob = URL.createObjectURL( const subtitleBlob = URL.createObjectURL(
await fetch(`${CORS_PROXY_URL}${subtitleTrack.file}`).then( await fetch(`${conf().CORS_PROXY_URL}${subtitleTrack.file}`).then(
(captionRes) => captionRes.blob() (captionRes) => captionRes.blob()
) )
); // do this so no need for CORS errors ); // do this so no need for CORS errors