From 8ffc9dc9ae946fc0a9d3edb055ca4bc22da93cb8 Mon Sep 17 00:00:00 2001 From: yxxyun Date: Thu, 27 Mar 2025 14:55:37 +0800 Subject: [PATCH] update zh source --- javascript/anime/src/zh/ffzy.js | 37 +++-- javascript/anime/src/zh/jisuzy.js | 39 +++-- javascript/anime/src/zh/mihdr.js | 211 ++++++++++++++++++++++++++ javascript/anime/src/zh/mucpan.js | 210 +++++++++++++++++++++++++ javascript/anime/src/zh/tiankongzy.js | 37 +++-- javascript/anime/src/zh/wogg.js | 12 +- 6 files changed, 498 insertions(+), 48 deletions(-) create mode 100644 javascript/anime/src/zh/mihdr.js create mode 100644 javascript/anime/src/zh/mucpan.js diff --git a/javascript/anime/src/zh/ffzy.js b/javascript/anime/src/zh/ffzy.js index dbd79752..6c06d519 100644 --- a/javascript/anime/src/zh/ffzy.js +++ b/javascript/anime/src/zh/ffzy.js @@ -7,7 +7,7 @@ const mangayomiSources = [{ "typeSource": "single", "itemType": 1, "isNsfw": false, - "version": "0.0.1", + "version": "0.0.2", "dateFormat": "", "dateFormatLocale": "", "pkgPath": "anime/src/zh/ffzy.js" @@ -95,13 +95,22 @@ class DefaultExtension extends MProvider { const content = this.text(anime.vod_content); desc = desc.length < blurb?.length ? blurb : desc; desc = desc.length < content.length ? content : desc; - const urls = anime.vod_play_url - .split("#") - .filter((e) => e) - .map((e) => { - const s = e.split("$"); - return { name: s[0], url: s[1] }; - }); + + const playLists = anime.vod_play_url.split("$$$"); + const urls = []; + + for (const playList of playLists) { + const episodes = playList.split("#").filter(e => e); + + for (const episode of episodes) { + const parts = episode.split("$"); + const name = parts[0]; + const episodeUrl = parts[1]; + if (episodeUrl.includes("m3u8")) { + urls.push({ name, url: episodeUrl }); + } + } + } return { name: anime.vod_name, imageUrl: anime.vod_pic, @@ -111,11 +120,13 @@ class DefaultExtension extends MProvider { } // For anime episode video list async getVideoList(url) { - return [{ - url: url, - originalUrl: url, - quality: "HLS" - }]; + return [ + { + url: url, + originalUrl: url, + quality: "HLS" + } + ]; } // For manga chapter pages async getPageList() { diff --git a/javascript/anime/src/zh/jisuzy.js b/javascript/anime/src/zh/jisuzy.js index 0c4f0fb8..b41cc5ba 100644 --- a/javascript/anime/src/zh/jisuzy.js +++ b/javascript/anime/src/zh/jisuzy.js @@ -1,13 +1,13 @@ const mangayomiSources = [{ "name": "极速资源", "lang": "zh", - "baseUrl": "https://wwww.jisuzy.com", + "baseUrl": "https://www.jisuzy.com", "apiUrl": "", "iconUrl": "https://www.jisuzy.com/template/default/images/site_logo.png", "typeSource": "single", "itemType": 1, "isNsfw": false, - "version": "0.0.1", + "version": "0.0.2", "dateFormat": "", "dateFormatLocale": "", "pkgPath": "anime/src/zh/jisuzy.js" @@ -95,13 +95,22 @@ class DefaultExtension extends MProvider { const content = this.text(anime.vod_content); desc = desc.length < blurb?.length ? blurb : desc; desc = desc.length < content.length ? content : desc; - const urls = anime.vod_play_url - .split("#") - .filter((e) => e) - .map((e) => { - const s = e.split("$"); - return { name: s[0], url: s[1] }; - }); + + const playLists = anime.vod_play_url.split("$$$"); + const urls = []; + + for (const playList of playLists) { + const episodes = playList.split("#").filter(e => e); + + for (const episode of episodes) { + const parts = episode.split("$"); + const name = parts[0]; + const episodeUrl = parts[1]; + if (episodeUrl.includes("m3u8")) { + urls.push({ name, url: episodeUrl }); + } + } + } return { name: anime.vod_name, imageUrl: anime.vod_pic, @@ -111,11 +120,13 @@ class DefaultExtension extends MProvider { } // For anime episode video list async getVideoList(url) { - return [{ - url: url, - originalUrl: url, - quality: "HLS" - }]; + return [ + { + url: url, + originalUrl: url, + quality: "HLS" + } + ]; } // For manga chapter pages async getPageList() { diff --git a/javascript/anime/src/zh/mihdr.js b/javascript/anime/src/zh/mihdr.js new file mode 100644 index 00000000..cfdb8b44 --- /dev/null +++ b/javascript/anime/src/zh/mihdr.js @@ -0,0 +1,211 @@ +const mangayomiSources = [{ + "name": "至臻视觉", + "lang": "zh", + "baseUrl": "https://mihdr.top", + "apiUrl": "", + "iconUrl": "https://mihdr.top/upload/dycms/20240708-1/9150a85ec594c1e7b14619e6570d7ee4.png", + "typeSource": "single", + "itemType": 1, + "isNsfw": false, + "version": "0.0.25", + "dateFormat": "", + "dateFormatLocale": "", + "pkgPath": "anime/src/zh/mihdr.js" +}]; +class DefaultExtension extends MProvider { + patternQuark = /(https:\/\/pan\.quark\.cn\/s\/[^"]+)/; + patternUc = /(https:\/\/drive\.uc\.cn\/s\/[^"]+)/; + getHeaders(url) { + throw new Error("getHeaders not implemented"); + } + async getPopular(page) { + const baseUrl = new SharedPreferences().get("url"); + const response = await new Client({ 'useDartHttpClient': true }).get(baseUrl, { "Referer": baseUrl }); + const elements = new Document(response.body).select("div.module-item"); + const list = []; + for (const element of elements) { + let oneA = element.selectFirst('.module-item-cover .module-item-pic a'); + const name = oneA.attr("title"); + const imageUrl = element.selectFirst(".module-item-cover .module-item-pic img").attr("data-src"); + const link = oneA.attr("href"); + list.push({ name, imageUrl, link }); + } + return { + list: list, + hasNextPage: false + } + } + async getLatestUpdates(page) { + const baseUrl = new SharedPreferences().get("url"); + const response = await new Client({ 'useDartHttpClient': true }).get(baseUrl + `/index.php/vod/show/id/1/page/${page}.html`, { "Referer": baseUrl }); + const elements = new Document(response.body).select("div.module-item"); + const list = []; + for (const element of elements) { + let oneA = element.selectFirst('.module-item-cover .module-item-pic a'); + const name = oneA.attr("title"); + const imageUrl = element.selectFirst(".module-item-cover .module-item-pic img").attr("data-src"); + const link = oneA.attr("href"); + list.push({ name, imageUrl, link }); + } + return { + list: list, + hasNextPage: true + } + } + async search(query, page, filters) { + const baseUrl = new SharedPreferences().get("url"); + if (query == "") { + var categories; + for (const filter of filters) { + if (filter["type"] == "categories") { + categories = filter["values"][filter["state"]]["value"]; + } + } + const response = await new Client({ 'useDartHttpClient': true }).get(baseUrl + `/index.php/vod/show/id/${categories}/page/${page}.html`, { "Referer": baseUrl }); + const elements = new Document(response.body).select("div.module-item"); + const list = []; + for (const element of elements) { + let oneA = element.selectFirst('.module-item-cover .module-item-pic a'); + const name = oneA.attr("title"); + const imageUrl = element.selectFirst(".module-item-cover .module-item-pic img").attr("data-src"); + const link = oneA.attr("href"); + list.push({ name, imageUrl, link }); + } + return { + list: list, + hasNextPage: true + } + } else { + const response = await new Client({ 'useDartHttpClient': true }).get(baseUrl + `/index.php/vod/search/page/${page}/wd/${query}.html`, { "Referer": baseUrl }); + const elements = new Document(response.body).select(".module-search-item"); + const list = []; + for (const element of elements) { + let oneA = element.selectFirst('.video-info .video-info-header a'); + const name = oneA.attr("title"); + const imageUrl = element.selectFirst(".video-cover .module-item-cover .module-item-pic img").attr("data-src"); + const link = oneA.attr("href"); + list.push({ name, imageUrl, link }); + } + return { + list: list, + hasNextPage: true + } + } + } + async getDetail(url) { + const baseUrl = new SharedPreferences().get("url"); + const response = await new Client({ 'useDartHttpClient': true }).get(baseUrl + url, { "Referer": baseUrl }); + const document = new Document(response.body); + const imageUrl = document.selectFirst("div.video-cover .module-item-cover .module-item-pic img").attr("data-src"); + const name = document.selectFirst("div.video-info .video-info-header h1").text; + const description = document.selectFirst("div.video-info .video-info-content").text.replace("[收起部分]", "").replace("[展开全部]", ""); + const type_name = "电影"; + let quark_share_url_list = [], uc_share_url_list = [] + const share_url_list = document.select("div.module-row-one .module-row-info") + .map(e => { + const url = e.selectFirst(".module-row-title p").text; + const quarkMatches = url.match(this.patternQuark); + + if (quarkMatches && quarkMatches[1]) { + quark_share_url_list.push(quarkMatches[1]); + } + const ucMatches = url.match(this.patternUc); + if (ucMatches && ucMatches[1]) { + uc_share_url_list.push(ucMatches[1]); + } + return null; + }) + .filter(url => url !== null); + let quark_episodes = await quarkFilesExtractor(quark_share_url_list, new SharedPreferences().get("quarkCookie")); + let uc_episodes = await ucFilesExtractor(uc_share_url_list, new SharedPreferences().get("ucCookie")); + let episodes = [...quark_episodes, ...uc_episodes]; + return { + name, imageUrl, description, episodes + }; + } + // For anime episode video list + async getVideoList(url) { + const videos = []; + const parts = url.split('++'); + const type = parts[0].toLowerCase(); + + let vids; + if (type === 'quark') { + let cookie = new SharedPreferences().get("quarkCookie"); + if (cookie == "") { + throw new Error("请先在本扩展设置中填写夸克Cookies, 需要夸克VIP账号 \n Please fill in the Quark Cookies in this extension settings first, you need a Quark VIP account"); + } else { + vids = await quarkVideosExtractor(url, cookie); + } + } else if (type === 'uc') { + let cookie = new SharedPreferences().get("ucCookie"); + if (cookie == "") { + throw new Error("请先在本扩展设置中填写UC云盘Cookies \n Please fill in the UC Cloud Cookies in this extension settings first"); + } else { + vids = await ucVideosExtractor(url, cookie); + } + } else { + throw new Error("不支持的链接类型"); + } + + for (const vid of vids) { + videos.push(vid); + } + return videos; + } + getFilterList() { + return [{ + type: "categories", + name: "影片類型", + type_name: "SelectFilter", + values: [ + { type_name: "SelectOption", value: "1", name: "电影" }, + { type_name: "SelectOption", value: "2", name: "剧集" }, + { type_name: "SelectOption", value: "3", name: "动漫" }, + { type_name: "SelectOption", value: "4", name: "综艺" }, + { type_name: "SelectOption", value: "5", name: "短剧" }, + { type_name: "SelectOption", value: "25", name: "臻彩视觉" } + ] + }]; + } + getSourcePreferences() { + return [ + { + "key": "quarkCookie", + "editTextPreference": { + "title": "夸克Cookies", + "summary": "填写获取到的夸克Cookies", + "value": "", + "dialogTitle": "Cookies", + "dialogMessage": "", + } + }, + { + "key": "ucCookie", + "editTextPreference": { + "title": "UC云盘Cookies", + "summary": "填写获取到的UC云盘Cookies", + "value": "", + "dialogTitle": "Cookies", + "dialogMessage": "", + } + }, + { + "key": "url", + "listPreference": { + "title": "Website Url", + "summary": "", + "valueIndex": 0, + "entries": [ + "mihdr.top", + "mpanso.com", + ], + "entryValues": [ + "https://mihdr.top", + "http://mpanso.com", + ], + } + } + ]; + } +} diff --git a/javascript/anime/src/zh/mucpan.js b/javascript/anime/src/zh/mucpan.js new file mode 100644 index 00000000..68c759da --- /dev/null +++ b/javascript/anime/src/zh/mucpan.js @@ -0,0 +1,210 @@ +const mangayomiSources = [{ + "name": "小米UC资源站", + "lang": "zh", + "baseUrl": "http://www.mucpan.cc", + "apiUrl": "", + "iconUrl": "http://www.mucpan.cc/template/DYXS2/static/picture/index_logo.png", + "typeSource": "single", + "itemType": 1, + "isNsfw": false, + "version": "0.0.25", + "dateFormat": "", + "dateFormatLocale": "", + "pkgPath": "anime/src/zh/mucpan.js" +}]; +class DefaultExtension extends MProvider { + patternQuark = /(https:\/\/pan\.quark\.cn\/s\/[^"]+)/; + patternUc = /(https:\/\/drive\.uc\.cn\/s\/[^"]+)/; + getHeaders(url) { + throw new Error("getHeaders not implemented"); + } + async getPopular(page) { + const baseUrl = new SharedPreferences().get("url"); + const response = await new Client({ 'useDartHttpClient': true }).get(baseUrl, { "Referer": baseUrl }); + const elements = new Document(response.body).select("div.module-item"); + const list = []; + for (const element of elements) { + let oneA = element.selectFirst('.module-item-cover .module-item-pic a'); + const name = oneA.attr("title"); + const imageUrl = element.selectFirst(".module-item-cover .module-item-pic img").attr("data-src"); + const link = oneA.attr("href"); + list.push({ name, imageUrl, link }); + } + return { + list: list, + hasNextPage: false + } + } + async getLatestUpdates(page) { + const baseUrl = new SharedPreferences().get("url"); + const response = await new Client({ 'useDartHttpClient': true }).get(baseUrl + `/index.php/vod/show/id/20/page/${page}.html`, { "Referer": baseUrl }); + const elements = new Document(response.body).select("div.module-item"); + const list = []; + for (const element of elements) { + let oneA = element.selectFirst('.module-item-cover .module-item-pic a'); + const name = oneA.attr("title"); + const imageUrl = element.selectFirst(".module-item-cover .module-item-pic img").attr("data-src"); + const link = oneA.attr("href"); + list.push({ name, imageUrl, link }); + } + return { + list: list, + hasNextPage: true + } + } + async search(query, page, filters) { + const baseUrl = new SharedPreferences().get("url"); + if (query == "") { + var categories; + for (const filter of filters) { + if (filter["type"] == "categories") { + categories = filter["values"][filter["state"]]["value"]; + } + } + const response = await new Client({ 'useDartHttpClient': true }).get(baseUrl + `/index.php/vod/show/id/${categories}/page/${page}.html`, { "Referer": baseUrl }); + const elements = new Document(response.body).select("div.module-item"); + const list = []; + for (const element of elements) { + let oneA = element.selectFirst('.module-item-cover .module-item-pic a'); + const name = oneA.attr("title"); + const imageUrl = element.selectFirst(".module-item-cover .module-item-pic img").attr("data-src"); + const link = oneA.attr("href"); + list.push({ name, imageUrl, link }); + } + return { + list: list, + hasNextPage: true + } + } else { + const response = await new Client({ 'useDartHttpClient': true }).get(baseUrl + `/index.php/vod/search/page/${page}/wd/${query}.html`, { "Referer": baseUrl }); + const elements = new Document(response.body).select(".module-search-item"); + const list = []; + for (const element of elements) { + let oneA = element.selectFirst('.video-info .video-info-header a'); + const name = oneA.attr("title"); + const imageUrl = element.selectFirst(".video-cover .module-item-cover .module-item-pic img").attr("data-src"); + const link = oneA.attr("href"); + list.push({ name, imageUrl, link }); + } + return { + list: list, + hasNextPage: true + } + } + } + async getDetail(url) { + const baseUrl = new SharedPreferences().get("url"); + const response = await new Client({ 'useDartHttpClient': true }).get(baseUrl + url, { "Referer": baseUrl }); + const document = new Document(response.body); + const imageUrl = document.selectFirst("div.video-cover .module-item-cover .module-item-pic img").attr("data-src"); + const name = document.selectFirst("div.video-info .video-info-header h1").text; + const description = document.selectFirst("div.video-info .video-info-content").text.replace("[收起部分]", "").replace("[展开全部]", ""); + const type_name = "电影"; + let quark_share_url_list = [], uc_share_url_list = [] + const share_url_list = document.select("div.module-row-one .module-row-info") + .map(e => { + const url = e.selectFirst(".module-row-title p").text; + const quarkMatches = url.match(this.patternQuark); + + if (quarkMatches && quarkMatches[1]) { + quark_share_url_list.push(quarkMatches[1]); + } + const ucMatches = url.match(this.patternUc); + if (ucMatches && ucMatches[1]) { + uc_share_url_list.push(ucMatches[1]); + } + return null; + }) + .filter(url => url !== null); + let quark_episodes = await quarkFilesExtractor(quark_share_url_list, new SharedPreferences().get("quarkCookie")); + let uc_episodes = await ucFilesExtractor(uc_share_url_list, new SharedPreferences().get("ucCookie")); + let episodes = [...quark_episodes, ...uc_episodes]; + return { + name, imageUrl, description, episodes + }; + } + // For anime episode video list + async getVideoList(url) { + const videos = []; + const parts = url.split('++'); + const type = parts[0].toLowerCase(); + + let vids; + if (type === 'quark') { + let cookie = new SharedPreferences().get("quarkCookie"); + if (cookie == "") { + throw new Error("请先在本扩展设置中填写夸克Cookies, 需要夸克VIP账号 \n Please fill in the Quark Cookies in this extension settings first, you need a Quark VIP account"); + } else { + vids = await quarkVideosExtractor(url, cookie); + } + } else if (type === 'uc') { + let cookie = new SharedPreferences().get("ucCookie"); + if (cookie == "") { + throw new Error("请先在本扩展设置中填写UC云盘Cookies \n Please fill in the UC Cloud Cookies in this extension settings first"); + } else { + vids = await ucVideosExtractor(url, cookie); + } + } else { + throw new Error("不支持的链接类型"); + } + + for (const vid of vids) { + videos.push(vid); + } + return videos; + } + getFilterList() { + return [{ + type: "categories", + name: "影片類型", + type_name: "SelectFilter", + values: [ + { type_name: "SelectOption", value: "20", name: "电影" }, + { type_name: "SelectOption", value: "21", name: "剧集" }, + { type_name: "SelectOption", value: "22", name: "动漫" }, + { type_name: "SelectOption", value: "23", name: "综艺" }, + { type_name: "SelectOption", value: "24", name: "少儿" } + ] + }]; + } + getSourcePreferences() { + return [ + { + "key": "quarkCookie", + "editTextPreference": { + "title": "夸克Cookies", + "summary": "填写获取到的夸克Cookies", + "value": "", + "dialogTitle": "Cookies", + "dialogMessage": "", + } + }, + { + "key": "ucCookie", + "editTextPreference": { + "title": "UC云盘Cookies", + "summary": "填写获取到的UC云盘Cookies", + "value": "", + "dialogTitle": "Cookies", + "dialogMessage": "", + } + }, + { + "key": "url", + "listPreference": { + "title": "Website Url", + "summary": "", + "valueIndex": 0, + "entries": [ + "mucpan.cc", + "54271.fun" + ], + "entryValues": [ + "http://www.mucpan.cc", + "https://54271.fun" + ], + } + } + ]; + } +} diff --git a/javascript/anime/src/zh/tiankongzy.js b/javascript/anime/src/zh/tiankongzy.js index 06d0906d..25543399 100644 --- a/javascript/anime/src/zh/tiankongzy.js +++ b/javascript/anime/src/zh/tiankongzy.js @@ -7,7 +7,7 @@ const mangayomiSources = [{ "typeSource": "single", "itemType": 1, "isNsfw": false, - "version": "0.0.1", + "version": "0.0.2", "dateFormat": "", "dateFormatLocale": "", "pkgPath": "anime/src/zh/tiankongzy.js" @@ -95,13 +95,22 @@ class DefaultExtension extends MProvider { const content = this.text(anime.vod_content); desc = desc.length < blurb?.length ? blurb : desc; desc = desc.length < content.length ? content : desc; - const urls = anime.vod_play_url - .split("#") - .filter((e) => e) - .map((e) => { - const s = e.split("$"); - return { name: s[0], url: s[1] }; - }); + + const playLists = anime.vod_play_url.split("$$$"); + const urls = []; + + for (const playList of playLists) { + const episodes = playList.split("#").filter(e => e); + + for (const episode of episodes) { + const parts = episode.split("$"); + const name = parts[0]; + const episodeUrl = parts[1]; + if (episodeUrl.includes("m3u8")) { + urls.push({ name, url: episodeUrl }); + } + } + } return { name: anime.vod_name, imageUrl: anime.vod_pic, @@ -111,11 +120,13 @@ class DefaultExtension extends MProvider { } // For anime episode video list async getVideoList(url) { - return [{ - url: url, - originalUrl: url, - quality: "HLS" - }]; + return [ + { + url: url, + originalUrl: url, + quality: "HLS" + } + ]; } // For manga chapter pages async getPageList() { diff --git a/javascript/anime/src/zh/wogg.js b/javascript/anime/src/zh/wogg.js index ab606811..1a2b34c4 100644 --- a/javascript/anime/src/zh/wogg.js +++ b/javascript/anime/src/zh/wogg.js @@ -1,13 +1,13 @@ const mangayomiSources = [{ "name": "玩偶哥哥", "lang": "zh", - "baseUrl": "https://www.wogg.net", + "baseUrl": "https://www.wogg.one", "apiUrl": "", "iconUrl": "https://imgsrc.baidu.com/forum/pic/item/4b90f603738da977d5da660af651f8198618e31f.jpg", "typeSource": "single", "itemType": 1, "isNsfw": false, - "version": "0.0.2", + "version": "0.0.25", "dateFormat": "", "dateFormatLocale": "", "pkgPath": "anime/src/zh/wogg.js" @@ -198,17 +198,13 @@ class DefaultExtension extends MProvider { "summary": "", "valueIndex": 0, "entries": [ - "wogg.net", + "wogg.one", "wogg.xxooo.cf", - "wogg.888484.xyz", - "wogg.bf", "wogg.333232.xyz" ], "entryValues": [ - "https://www.wogg.net", + "https://www.wogg.one", "https://wogg.xxooo.cf", - "https://wogg.888484.xyz", - "https://www.wogg.bf", "https://wogg.333232.xyz" ], }