mirror of
https://github.com/movie-web/movie-web.git
synced 2024-12-28 08:36:06 +00:00
new config system
This commit is contained in:
parent
2e8025a241
commit
388827b56f
28
.eslintrc.js
28
.eslintrc.js
|
@ -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
|
||||||
},
|
}
|
||||||
};
|
};
|
||||||
|
|
5
.gitignore
vendored
5
.gitignore
vendored
|
@ -22,4 +22,7 @@ npm-debug.log*
|
||||||
yarn-debug.log*
|
yarn-debug.log*
|
||||||
yarn-error.log*
|
yarn-error.log*
|
||||||
|
|
||||||
package-lock.json
|
package-lock.json
|
||||||
|
|
||||||
|
# config
|
||||||
|
.env
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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
6
example.env
Normal 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=...
|
|
@ -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
5
public/config.js
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
window.__CONFIG__ = {
|
||||||
|
VITE_CORS_PROXY_URL: "",
|
||||||
|
VITE_TMDB_API_KEY: "b030404650f279792a8d3287232358e3",
|
||||||
|
VITE_OMDB_API_KEY: "aa0937c0"
|
||||||
|
};
|
|
@ -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't able to recover, please
|
The app encountered an error and wasn'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>
|
||||||
.
|
.
|
||||||
|
|
|
@ -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
50
src/config.ts
Normal 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
3
src/constants.ts
Normal 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";
|
|
@ -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";
|
|
|
@ -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());
|
||||||
|
|
|
@ -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");
|
||||||
|
|
||||||
|
|
|
@ -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()
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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(
|
||||||
|
|
|
@ -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()
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in a new issue