uni_scrapper
Version:
A Collection of Movies, Series, Animes Scrapper.
233 lines • 9.37 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.SourceHandler = exports.Source = void 0;
const axios_1 = __importDefault(require("axios"));
const index_1 = require("../index");
const vidsrc_scrapper_1 = __importDefault(require("../scrappers/vidsrc.scrapper"));
var Source;
(function (Source) {
Source["XPRIME"] = "xprime";
Source["AUTOEMBED"] = "autoembed";
Source["VIDSRC"] = "vidsrc";
})(Source || (exports.Source = Source = {}));
class SourceHandler {
constructor({ tmdbKey }) {
this.sources = new Map();
this.initializeSources();
this.apiKey = tmdbKey;
}
request(url) {
return axios_1.default.get(url, {
headers: {
Authorization: `Bearer ${this.apiKey}`,
},
});
}
initializeSources() {
this.sources.set(Source.XPRIME, new index_1.Xprime());
this.sources.set(Source.AUTOEMBED, new index_1.AutoEmbedSource());
this.sources.set(Source.VIDSRC, new vidsrc_scrapper_1.default());
}
getAllSources() {
return Array.from(this.sources.values());
}
getSource(source) {
const sourceInstance = this.sources.get(source);
if (!sourceInstance) {
throw new Error(`Source ${source} not found`);
}
return sourceInstance;
}
async search(query) {
try {
const cleanedQuery = query.replace(/\bseasons?\b/gi, "").trim();
const movieUrl = `https://api.themoviedb.org/3/search/movie?query=${encodeURIComponent(cleanedQuery)}&page=1&include_adult=false`;
const tvUrl = `https://api.themoviedb.org/3/search/tv?query=${encodeURIComponent(cleanedQuery)}&page=1&include_adult=false`;
const [movieRes, tvRes] = await Promise.all([
this.request(movieUrl),
this.request(tvUrl),
]);
if (movieRes.status !== 200) {
throw new Error(`Failed to load movie data: ${movieRes.status}`);
}
if (tvRes.status !== 200) {
throw new Error(`Failed to load TV data: ${tvRes.status}`);
}
const movies = (movieRes.data.results || []).map((e) => ({
id: `https://api.themoviedb.org/3/movie/${e.id}?append_to_response=external_ids`,
title: e.title || e.name,
poster: `https://image.tmdb.org/t/p/w500${e.poster_path || e.backdrop_path || ""}`,
}));
const series = (tvRes.data.results || []).map((e) => ({
id: `https://api.themoviedb.org/3/tv/${e.id}?append_to_response=external_ids`,
title: e.title || e.name,
poster: `https://image.tmdb.org/t/p/w500${e.poster_path || e.backdrop_path || ""}`,
}));
const mixedResults = [];
const maxLength = Math.max(movies.length, series.length);
for (let i = 0; i < maxLength; i++) {
if (i < series.length)
mixedResults.push(series[i]);
if (i < movies.length)
mixedResults.push(movies[i]);
}
return mixedResults;
}
catch (error) {
console.log("Search error:", error);
throw error;
}
}
async getDetails(id) {
try {
const response = await this.request(id);
const parsedData = response.data;
const isMovie = id.includes("/movie");
const name = parsedData.name || parsedData.title;
const seasons = [];
let content = null;
const idMatch = id.match(/(?:movie|tv)\/(\d+)/);
const tmdbId = idMatch?.[1];
let imdbId = parsedData?.external_ids?.imdb_id;
if (!imdbId) {
try {
const data = await this.request(`https://api.themoviedb.org/3/${isMovie ? "movie" : "tv"}/${tmdbId}/external_ids`);
imdbId = data.imdb_id;
}
catch (e) {
console.log(e);
}
}
if (!tmdbId)
throw new Error("Invalid TMDB ID in URL");
if (isMovie) {
const releaseDate = parsedData.release_date || "";
const year = releaseDate ? releaseDate.split("-")[0] : "";
content = {
title: "Movie",
id: JSON.stringify({
id: tmdbId,
imdbId,
year,
name,
}),
};
}
else {
const seasonList = parsedData.seasons || [];
for (const season of seasonList) {
if (season.season_number === 0)
continue;
const currentSeason = {
title: `Season ${season.season_number}`,
poster: `https://image.tmdb.org/t/p/w500${season.poster_path || season.backdrop_path || ""}`,
episodes: [],
};
const episodeCount = season.episode_count || 0;
const airDate = season.air_date || "";
const year = airDate ? airDate.split("-")[0] : "";
for (let ep = 1; ep <= episodeCount; ep++) {
currentSeason.episodes.push({
title: `Episode ${ep}`,
id: JSON.stringify({
id: tmdbId,
imdbId,
season: season.season_number,
name,
episode: ep,
year,
}),
});
}
seasons.push(currentSeason);
}
}
if (isMovie) {
return {
id: id,
title: name,
poster: `https://image.tmdb.org/t/p/w500${parsedData.poster_path}`,
type: "movie",
seasons: [
{
title: "Movie",
poster: "",
episodes: [content],
},
],
};
}
return {
id: id,
title: name,
poster: `https://image.tmdb.org/t/p/w500${parsedData.poster_path}`,
seasons: seasons,
type: "tv",
};
}
catch (error) {
console.error("getDetails error:", error);
throw error;
}
}
async getStreams(id, source = Source.VIDSRC) {
const allSources = Object.values(Source);
const sourcesToTry = [
source,
...allSources.filter((s) => s !== source && s !== Source.AUTOEMBED),
Source.AUTOEMBED,
];
const errors = [];
for (const src of sourcesToTry) {
try {
const instance = this.getSource(src);
const streams = await instance.getStreams(id);
if (streams && streams.length) {
console.log(`Successfully fetched ${streams.length} streams from ${src}`);
console.log(errors);
return streams;
}
}
catch (err) {
errors.push({ source: src, error: err });
}
}
throw new Error(`All sources failed:\n` +
errors
.map((e) => `- ${e.source}: ${e.error?.message ?? e.error}`)
.join("\n"));
}
async getStreamsFromAllSources(id, except) {
const sourceList = Object.values(Source).filter((e) => e != except);
const allStreams = await Promise.all(sourceList.map((e) => this.getSource(e).getStreams(id)));
return allStreams.flat();
}
async getPopular() {
try {
const url = "https://api.themoviedb.org/3/trending/all/week?page=1";
const data = await this.request(url);
if (data.status !== 200) {
throw new Error(`Failed to load movie data: ${data.status}`);
}
const result = (data.data.results || []).map((e) => {
const type = e.media_type === "movie" ? "movie" : "tv";
return {
id: `https://api.themoviedb.org/3/${type}/${e.id}?append_to_response=external_ids`,
title: e.title || e.name,
poster: `https://image.tmdb.org/t/p/w500${e.poster_path || e.backdrop_path || ""}`,
};
});
return result;
}
catch (error) {
console.log("Search error:", error);
throw error;
}
}
}
exports.SourceHandler = SourceHandler;
exports.default = SourceHandler;
//# sourceMappingURL=sources.handler.js.map