mirror of
https://github.com/movie-web/providers.git
synced 2025-09-13 18:13:25 +00:00
4385
package-lock.json
generated
4385
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@movie-web/providers",
|
"name": "@movie-web/providers",
|
||||||
"version": "1.1.4",
|
"version": "1.1.5",
|
||||||
"description": "Package that contains all the providers of movie-web",
|
"description": "Package that contains all the providers of movie-web",
|
||||||
"main": "./lib/index.umd.js",
|
"main": "./lib/index.umd.js",
|
||||||
"types": "./lib/index.d.ts",
|
"types": "./lib/index.d.ts",
|
||||||
|
@@ -1,5 +1,6 @@
|
|||||||
export const flags = {
|
export const flags = {
|
||||||
NO_CORS: 'no-cors',
|
NO_CORS: 'no-cors',
|
||||||
|
IP_LOCKED: 'ip-locked',
|
||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
export type Flags = (typeof flags)[keyof typeof flags];
|
export type Flags = (typeof flags)[keyof typeof flags];
|
||||||
|
@@ -8,6 +8,7 @@ import { upstreamScraper } from '@/providers/embeds/upstream';
|
|||||||
import { flixhqScraper } from '@/providers/sources/flixhq/index';
|
import { flixhqScraper } from '@/providers/sources/flixhq/index';
|
||||||
import { goMoviesScraper } from '@/providers/sources/gomovies/index';
|
import { goMoviesScraper } from '@/providers/sources/gomovies/index';
|
||||||
import { kissAsianScraper } from '@/providers/sources/kissasian/index';
|
import { kissAsianScraper } from '@/providers/sources/kissasian/index';
|
||||||
|
import { lookmovieScraper } from '@/providers/sources/lookmovie';
|
||||||
import { remotestreamScraper } from '@/providers/sources/remotestream';
|
import { remotestreamScraper } from '@/providers/sources/remotestream';
|
||||||
import { superStreamScraper } from '@/providers/sources/superstream/index';
|
import { superStreamScraper } from '@/providers/sources/superstream/index';
|
||||||
import { zoechipScraper } from '@/providers/sources/zoechip';
|
import { zoechipScraper } from '@/providers/sources/zoechip';
|
||||||
@@ -23,6 +24,7 @@ export function gatherAllSources(): Array<Sourcerer> {
|
|||||||
superStreamScraper,
|
superStreamScraper,
|
||||||
goMoviesScraper,
|
goMoviesScraper,
|
||||||
zoechipScraper,
|
zoechipScraper,
|
||||||
|
lookmovieScraper,
|
||||||
showBoxScraper,
|
showBoxScraper,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
@@ -12,7 +12,7 @@ export const gomoviesBase = `https://gomovies.sx`;
|
|||||||
export const goMoviesScraper = makeSourcerer({
|
export const goMoviesScraper = makeSourcerer({
|
||||||
id: 'gomovies',
|
id: 'gomovies',
|
||||||
name: 'GOmovies',
|
name: 'GOmovies',
|
||||||
rank: 200,
|
rank: 110,
|
||||||
flags: [flags.NO_CORS],
|
flags: [flags.NO_CORS],
|
||||||
async scrapeShow(ctx) {
|
async scrapeShow(ctx) {
|
||||||
const search = await ctx.proxiedFetcher<string>(`/ajax/search`, {
|
const search = await ctx.proxiedFetcher<string>(`/ajax/search`, {
|
||||||
|
36
src/providers/sources/lookmovie/index.ts
Normal file
36
src/providers/sources/lookmovie/index.ts
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
import { flags } from '@/main/targets';
|
||||||
|
import { SourcererOutput, makeSourcerer } from '@/providers/base';
|
||||||
|
import { NotFoundError } from '@/utils/errors';
|
||||||
|
|
||||||
|
import { scrape, searchAndFindMedia } from './util';
|
||||||
|
import { MovieContext, ShowContext } from '../zoechip/common';
|
||||||
|
|
||||||
|
async function universalScraper(ctx: ShowContext | MovieContext): Promise<SourcererOutput> {
|
||||||
|
const lookmovieData = await searchAndFindMedia(ctx, ctx.media);
|
||||||
|
if (!lookmovieData) throw new NotFoundError('Media not found');
|
||||||
|
|
||||||
|
ctx.progress(30);
|
||||||
|
const videoUrl = await scrape(ctx, ctx.media, lookmovieData);
|
||||||
|
if (!videoUrl) throw new NotFoundError('No video found');
|
||||||
|
|
||||||
|
ctx.progress(60);
|
||||||
|
|
||||||
|
return {
|
||||||
|
embeds: [],
|
||||||
|
stream: {
|
||||||
|
playlist: videoUrl,
|
||||||
|
type: 'hls',
|
||||||
|
flags: [flags.IP_LOCKED],
|
||||||
|
captions: [],
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export const lookmovieScraper = makeSourcerer({
|
||||||
|
id: 'lookmovie',
|
||||||
|
name: 'LookMovie',
|
||||||
|
rank: 1,
|
||||||
|
flags: [flags.IP_LOCKED],
|
||||||
|
scrapeShow: universalScraper,
|
||||||
|
scrapeMovie: universalScraper,
|
||||||
|
});
|
60
src/providers/sources/lookmovie/type.ts
Normal file
60
src/providers/sources/lookmovie/type.ts
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
import { MovieMedia } from '@/main/media';
|
||||||
|
|
||||||
|
// ! Types
|
||||||
|
interface BaseConfig {
|
||||||
|
/** The website's slug. Formatted as `1839578-person-of-interest-2011` */
|
||||||
|
slug: string;
|
||||||
|
/** Type of request */
|
||||||
|
type: 'show' | 'movie';
|
||||||
|
/** Hash */
|
||||||
|
hash: string;
|
||||||
|
/** Hash expiry */
|
||||||
|
expires: number;
|
||||||
|
}
|
||||||
|
interface TvConfig extends BaseConfig {
|
||||||
|
/** Type of request */
|
||||||
|
type: 'show';
|
||||||
|
/** The episode ID for a TV show. Given in search and URL */
|
||||||
|
episodeId: string;
|
||||||
|
}
|
||||||
|
interface MovieConfig extends BaseConfig {
|
||||||
|
/** Type of request */
|
||||||
|
type: 'movie';
|
||||||
|
/** Movie's id */
|
||||||
|
id_movie: string;
|
||||||
|
}
|
||||||
|
export type Config = MovieConfig | TvConfig;
|
||||||
|
|
||||||
|
export interface episodeObj {
|
||||||
|
season: string;
|
||||||
|
episode: string;
|
||||||
|
id: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ShowDataResult {
|
||||||
|
episodes: episodeObj[];
|
||||||
|
}
|
||||||
|
|
||||||
|
interface VideoSources {
|
||||||
|
[key: string]: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface StreamsDataResult {
|
||||||
|
streams: VideoSources;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ResultItem {
|
||||||
|
title: string;
|
||||||
|
slug: string;
|
||||||
|
year: string;
|
||||||
|
id_movie: string;
|
||||||
|
id_show: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface Result {
|
||||||
|
title(media: MovieMedia, title: any, arg2: number): boolean;
|
||||||
|
year(year: any): number | undefined;
|
||||||
|
id_movie: any;
|
||||||
|
id_show: string;
|
||||||
|
items: ResultItem[];
|
||||||
|
}
|
59
src/providers/sources/lookmovie/util.ts
Normal file
59
src/providers/sources/lookmovie/util.ts
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
import { MovieMedia, ShowMedia } from '@/main/media';
|
||||||
|
import { compareMedia } from '@/utils/compare';
|
||||||
|
import { ScrapeContext } from '@/utils/context';
|
||||||
|
import { NotFoundError } from '@/utils/errors';
|
||||||
|
|
||||||
|
import { Result, ResultItem, ShowDataResult, episodeObj } from './type';
|
||||||
|
import { getVideoUrl } from './video';
|
||||||
|
|
||||||
|
export async function searchAndFindMedia(
|
||||||
|
ctx: ScrapeContext,
|
||||||
|
media: MovieMedia | ShowMedia,
|
||||||
|
): Promise<ResultItem | undefined> {
|
||||||
|
if (media.type === 'show') {
|
||||||
|
const searchRes = await ctx.fetcher<Result>(`/v1/shows`, {
|
||||||
|
baseUrl: 'https://lmscript.xyz',
|
||||||
|
query: { 'filters[q]': media.title },
|
||||||
|
});
|
||||||
|
|
||||||
|
const results = searchRes.items;
|
||||||
|
|
||||||
|
const result = results.find((res: ResultItem) => compareMedia(media, res.title, Number(res.year)));
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
if (media.type === 'movie') {
|
||||||
|
const searchRes = await ctx.fetcher<Result>(`/v1/movies`, {
|
||||||
|
baseUrl: 'https://lmscript.xyz',
|
||||||
|
query: { 'filters[q]': media.title },
|
||||||
|
});
|
||||||
|
|
||||||
|
const results = searchRes.items;
|
||||||
|
const result = results.find((res: ResultItem) => compareMedia(media, res.title, Number(res.year)));
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function scrape(ctx: ScrapeContext, media: MovieMedia | ShowMedia, result: ResultItem) {
|
||||||
|
// Find the relevant id
|
||||||
|
let id = null;
|
||||||
|
if (media.type === 'movie') {
|
||||||
|
id = result.id_movie;
|
||||||
|
} else if (media.type === 'show') {
|
||||||
|
const data = await ctx.fetcher<ShowDataResult>(`/v1/shows`, {
|
||||||
|
baseUrl: 'https://lmscript.xyz',
|
||||||
|
query: { expand: 'episodes', id: result.id_show },
|
||||||
|
});
|
||||||
|
|
||||||
|
const episode = data.episodes?.find((v: episodeObj) => {
|
||||||
|
return Number(v.season) === Number(media.season.number) && Number(v.episode) === Number(media.episode.number);
|
||||||
|
});
|
||||||
|
|
||||||
|
if (episode) id = episode.id;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check ID
|
||||||
|
if (id === null) throw new NotFoundError('Not found');
|
||||||
|
|
||||||
|
const videoUrl = await getVideoUrl(ctx, id, media);
|
||||||
|
return videoUrl;
|
||||||
|
}
|
46
src/providers/sources/lookmovie/video.ts
Normal file
46
src/providers/sources/lookmovie/video.ts
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
import { MovieMedia, ShowMedia } from '@/main/media';
|
||||||
|
import { ScrapeContext } from '@/utils/context';
|
||||||
|
|
||||||
|
import { StreamsDataResult } from './type';
|
||||||
|
|
||||||
|
export async function getVideoSources(
|
||||||
|
ctx: ScrapeContext,
|
||||||
|
id: string,
|
||||||
|
media: MovieMedia | ShowMedia,
|
||||||
|
): Promise<StreamsDataResult> {
|
||||||
|
// Fetch video sources
|
||||||
|
|
||||||
|
let path = '';
|
||||||
|
if (media.type === 'show') {
|
||||||
|
path = `/v1/episodes/view`;
|
||||||
|
} else if (media.type === 'movie') {
|
||||||
|
path = `/v1/movies/view`;
|
||||||
|
}
|
||||||
|
const data = await ctx.fetcher<StreamsDataResult>(path, {
|
||||||
|
baseUrl: 'https://lmscript.xyz',
|
||||||
|
query: { expand: 'streams', id },
|
||||||
|
});
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function getVideoUrl(
|
||||||
|
ctx: ScrapeContext,
|
||||||
|
id: string,
|
||||||
|
media: MovieMedia | ShowMedia,
|
||||||
|
): Promise<string | null> {
|
||||||
|
// Get sources
|
||||||
|
const data = await getVideoSources(ctx, id, media);
|
||||||
|
const videoSources = data.streams;
|
||||||
|
|
||||||
|
// Find video URL and return it
|
||||||
|
const opts = ['auto', '1080p', '1080', '720p', '720', '480p', '480', '240p', '240', '360p', '360', '144', '144p'];
|
||||||
|
|
||||||
|
let videoUrl: string | null = null;
|
||||||
|
for (const res of opts) {
|
||||||
|
if (videoSources[res] && !videoUrl) {
|
||||||
|
videoUrl = videoSources[res];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return videoUrl;
|
||||||
|
}
|
@@ -12,6 +12,7 @@ export const showBoxScraper = makeSourcerer({
|
|||||||
id: 'show_box',
|
id: 'show_box',
|
||||||
name: 'ShowBox',
|
name: 'ShowBox',
|
||||||
rank: 20,
|
rank: 20,
|
||||||
|
disabled: true,
|
||||||
flags: [flags.NO_CORS],
|
flags: [flags.NO_CORS],
|
||||||
async scrapeMovie(ctx) {
|
async scrapeMovie(ctx) {
|
||||||
const search = await ctx.proxiedFetcher<string>('/search', {
|
const search = await ctx.proxiedFetcher<string>('/search', {
|
||||||
|
@@ -6,7 +6,7 @@ import { scrapeShow } from '@/providers/sources/zoechip/scrape-show';
|
|||||||
export const zoechipScraper = makeSourcerer({
|
export const zoechipScraper = makeSourcerer({
|
||||||
id: 'zoechip',
|
id: 'zoechip',
|
||||||
name: 'ZoeChip',
|
name: 'ZoeChip',
|
||||||
rank: 110,
|
rank: 200,
|
||||||
flags: [flags.NO_CORS],
|
flags: [flags.NO_CORS],
|
||||||
scrapeMovie,
|
scrapeMovie,
|
||||||
scrapeShow,
|
scrapeShow,
|
||||||
|
Reference in New Issue
Block a user