Add MoviezWap provider and update manifest (#1)

Co-authored-by: shaker <your_github_username@users.noreply.github.com>
Co-authored-by: himanshu8443 <sangwanhimanshu8443@gmail.com>
This commit is contained in:
Shaker
2025-06-30 12:04:26 +05:30
committed by GitHub
parent 6b0a4b7484
commit 305e3d2552
6 changed files with 281 additions and 0 deletions

View File

@@ -143,6 +143,14 @@
"type": "english",
"disabled": true
},
{
"display_name": "MoviezWap",
"value": "Moviezwap",
"version": "1.0",
"icon": "",
"type": "india",
"disabled": false
},
{
"display_name": "ShowBox",
"value": "showbox",

View File

@@ -0,0 +1,21 @@
export const catalog = [
{
title: "Telugu Movies",
filter: "/category/Telugu-(2025)-Movies.html",
},
{
title: "Tamil Movies",
filter: "/category/Tamil-(2025)-Movies.html",
},
{
title: "Hollywood Telugu Dubbed",
filter: "/category/Telugu-Dubbed-Hollywood-Movies-Complete-Set.html",
},
{
title: "Web Series",
filter: "/category/Telugu-Web-Series.html",
},
];
export const genres = [];

View File

@@ -0,0 +1,43 @@
import { EpisodeLink, ProviderContext } from "../types";
export const getEpisodes = async function ({
url,
providerContext,
}: {
url: string;
providerContext: ProviderContext;
}): Promise<EpisodeLink[]> {
const { axios, cheerio, getBaseUrl } = providerContext;
try {
const res = await axios.get(url);
const baseUrl = await getBaseUrl("moviezwap");
const html = res.data;
const $ = cheerio.load(html);
const episodeLinks: EpisodeLink[] = [];
$('a[href*="download.php?file="], a[href*="dwload.php?file="]').each(
(i, el) => {
const downloadPage =
$(el).attr("href")?.replace("dwload.php", "download.php") || "";
let text = $(el).text().trim();
if (text.includes("Download page")) {
// Remove "Download" from the text
text = "Play";
}
if (downloadPage && text) {
// Only add links with quality in text
episodeLinks.push({
title: text,
link: baseUrl + downloadPage,
});
}
}
);
return episodeLinks;
} catch (err) {
console.error(err);
return [];
}
};

105
providers/moviezwap/meta.ts Normal file
View File

@@ -0,0 +1,105 @@
import { Info, Link, ProviderContext } from "../types";
export const getMeta = async function ({
link,
providerContext,
}: {
link: string;
providerContext: ProviderContext;
}): Promise<Info> {
try {
const { axios, cheerio, getBaseUrl } = providerContext;
const baseUrl = await getBaseUrl("moviezwap");
const url = link.startsWith("http") ? link : `${baseUrl}${link}`;
const res = await axios.get(url);
const data = res.data;
const $ = cheerio.load(data);
// 1. Poster image find image with width 260
let image = $('img[width="260"]').attr("src") || "";
if (image && !image.startsWith("http")) {
image = baseUrl + image;
}
const tags = $("font[color='steelblue']")
.map((i, el) => $(el).text().trim())
.get()
.slice(0, 2);
// 2. Title
const title = $("title").text().replace(" - MoviezWap", "").trim() || "";
// 3. Info table
let synopsis = "";
let imdbId = "";
let type = "movie";
let infoRows: string[] = [];
$("td:contains('Movie Information')")
.parent()
.nextAll("tr")
.each((i, el) => {
const tds = $(el).find("td");
if (tds.length === 2) {
const key = tds.eq(0).text().trim();
const value = tds.eq(1).text().trim();
infoRows.push(`${key}: ${value}`);
if (key.toLowerCase().includes("plot")) synopsis = value;
if (key.toLowerCase().includes("imdb")) imdbId = value;
}
});
if (!synopsis) {
// fallback: try to find a <p> with plot
synopsis = $("p:contains('plot')").text().trim();
}
// 4. Download links (multiple qualities)
const links: Link[] = [];
$('a[href*="download.php?file="], a[href*="dwload.php?file="]').each(
(i, el) => {
const downloadPage =
$(el).attr("href")?.replace("dwload.php", "download.php") || "";
const text = $(el).text().trim();
if (downloadPage && /\d+p/i.test(text)) {
// Only add links with quality in text
links.push({
title: text,
directLinks: [{ title: "Movie", link: baseUrl + downloadPage }],
});
}
}
);
$("img[src*='/images/play.png']").each((i, el) => {
const downloadPage = $(el).siblings("a").attr("href");
const text = $(el).siblings("a").text().trim();
console.log("Found link:🔥🔥", text, downloadPage);
if (downloadPage && text) {
links.push({
title: text,
episodesLink: baseUrl + downloadPage,
});
}
});
return {
title,
synopsis,
image,
imdbId,
tags,
type,
linkList: links,
//info: infoRows.join("\n"),
};
} catch (err) {
console.error(err);
return {
title: "",
synopsis: "",
image: "",
imdbId: "",
type: "movie",
linkList: [],
};
}
};

View File

@@ -0,0 +1,70 @@
import { Post, ProviderContext } from "../types";
export const getPosts = async function ({
filter,
page,
signal,
providerContext,
}: {
filter: string;
page: number;
providerValue: string;
signal: AbortSignal;
providerContext: ProviderContext;
}): Promise<Post[]> {
const { getBaseUrl, cheerio } = providerContext;
const baseUrl = await getBaseUrl("moviezwap");
const url = `${baseUrl}${filter}`;
return posts({ url, signal, cheerio });
};
export const getSearchPosts = async function ({
searchQuery,
page,
signal,
providerContext,
}: {
searchQuery: string;
page: number;
providerValue: string;
signal: AbortSignal;
providerContext: ProviderContext;
}): Promise<Post[]> {
const { getBaseUrl, cheerio } = providerContext;
const baseUrl = await getBaseUrl("moviezwap");
const url = `${baseUrl}/search.php?q=${encodeURIComponent(searchQuery)}`;
return posts({ url, signal, cheerio });
};
async function posts({
url,
signal,
cheerio,
}: {
url: string;
signal: AbortSignal;
cheerio: ProviderContext["cheerio"];
}): Promise<Post[]> {
try {
const res = await fetch(url, { signal });
const data = await res.text();
const $ = cheerio.load(data);
const catalog: Post[] = [];
$('a[href^="/movie/"]').each((i, el) => {
const title = $(el).text().trim();
const link = $(el).attr("href");
const image = "";
if (title && link) {
catalog.push({
title: title,
link: link,
image: image,
});
}
});
return catalog;
} catch (err) {
console.error("moviezwapGetPosts error ", err);
return [];
}
}

View File

@@ -0,0 +1,34 @@
import { ProviderContext, Stream } from "../types";
export async function getStream({
link,
signal,
providerContext,
}: {
link: string;
type: string;
signal: AbortSignal;
providerContext: ProviderContext;
}) {
const { axios, cheerio, commonHeaders: headers } = providerContext;
const res = await axios.get(link, { headers, signal });
const html = res.data;
const $ = cheerio.load(html);
const Streams: Stream[] = [];
// Find the actual .mp4 download link
let downloadLink = null;
$('a:contains("Fast Download Server")').each((i, el) => {
const href = $(el).attr("href");
if (href && href.toLocaleLowerCase().includes(".mp4")) {
Streams.push({
link: href,
type: "mp4",
server: "Fast Download",
headers: headers,
});
}
});
return Streams;
}