diff --git a/README.md b/README.md index edb1eae..d761118 100644 --- a/README.md +++ b/README.md @@ -20,10 +20,10 @@ Miru extensions repository | [Miru App Download](https://github.com/miru-project | Flixhq | flixhq.to | v0.0.1 | OshekharO | all | bangumi | [Source Code](https://github.com/miru-project/repo/blob/main/repo/flixhq.to.js) | | GoGoAnime | gogo.anime | v0.0.2 | OshekharO | en | bangumi | [Source Code](https://github.com/miru-project/repo/blob/main/repo/gogo.anime.js) | | Invidious | invidious.io | v0.0.1 | OshekharO | all | bangumi | [Source Code](https://github.com/miru-project/repo/blob/main/repo/invidious.io.js) | -| IsekaiScan | isekaiscan.to | v0.0.2 | bethro | en | manga | [Source Code](https://github.com/miru-project/repo/blob/main/repo/isekaiscan.to.js) | +| IsekaiScan | isekaiscan.to | v0.0.3 | bethro | en | manga | [Source Code](https://github.com/miru-project/repo/blob/main/repo/isekaiscan.to.js) | | KimCartoon | kimcartoon.li | v0.0.1 | OshekharO | en | bangumi | [Source Code](https://github.com/miru-project/repo/blob/main/repo/kimcartoon.li.js) | | Kissasian | kissasian.fm | v0.0.1 | OshekharO | en | bangumi | [Source Code](https://github.com/miru-project/repo/blob/main/repo/kissasian.fm.js) | -| Kisskh | kisskh.co | v0.0.1 | OshekharO | all | bangumi | [Source Code](https://github.com/miru-project/repo/blob/main/repo/kisskh.co.js) | +| Kisskh | kisskh.co | v0.0.2 | OshekharO | all | bangumi | [Source Code](https://github.com/miru-project/repo/blob/main/repo/kisskh.co.js) | | 拷贝漫画 | mangacopy.comic | v0.0.1 | Monster | zh-cn | manga | [Source Code](https://github.com/miru-project/repo/blob/main/repo/mangacopy.comic.js) | | マンガクロス | mangacross.jp | v0.0.1 | OshekharO | jp | manga | [Source Code](https://github.com/miru-project/repo/blob/main/repo/mangacross.jp.js) | | MangaDex | mangadex.org | v0.0.1 | bethro | all | manga | [Source Code](https://github.com/miru-project/repo/blob/main/repo/mangadex.org.js) | @@ -35,7 +35,7 @@ Miru extensions repository | [Miru App Download](https://github.com/miru-project | ReadLN | readlightnovels | v0.0.1 | OshekharO | en | fikushon | [Source Code](https://github.com/miru-project/repo/blob/main/repo/readlightnovels.js) | | ACG.RIP | rip.acg | v0.0.1 | MiaoMint | zh-cn | bangumi | [Source Code](https://github.com/miru-project/repo/blob/main/repo/rip.acg.js) | | 樱花动漫 | sakura | v0.0.1 | Monster | zh-cn | bangumi | [Source Code](https://github.com/miru-project/repo/blob/main/repo/sakura.js) | -| NetTruyen | truyen.net | v0.0.2 | OshekharO | vi | manga | [Source Code](https://github.com/miru-project/repo/blob/main/repo/truyen.net.js) | +| NetTruyen | truyen.net | v0.0.3 | OshekharO | vi | manga | [Source Code](https://github.com/miru-project/repo/blob/main/repo/truyen.net.js) | | Turkish123 | turkish123 | v0.0.2 | OshekharO | tr | bangumi | [Source Code](https://github.com/miru-project/repo/blob/main/repo/turkish123.js) | | Unimay | unimay.media | v0.0.1 | CakesTwix | uk | bangumi | [Source Code](https://github.com/miru-project/repo/blob/main/repo/unimay.media.js) | | viện | vn.tangthuvien | v0.0.1 | Moleys | vi | fikushon | [Source Code](https://github.com/miru-project/repo/blob/main/repo/vn.tangthuvien.js) | @@ -44,4 +44,5 @@ Miru extensions repository | [Miru App Download](https://github.com/miru-project | 风车动漫 | windmill | v0.0.1 | Monster | zh-cn | bangumi | [Source Code](https://github.com/miru-project/repo/blob/main/repo/windmill.js) | | Wnmtl | wnmtl.org | v0.0.1 | OshekharO | en | fikushon | [Source Code](https://github.com/miru-project/repo/blob/main/repo/wnmtl.org.js) | | WTR-LAB | wtr-lab.com | v0.0.1 | OshekharO | en | fikushon | [Source Code](https://github.com/miru-project/repo/blob/main/repo/wtr-lab.com.js) | +| YuriNeko | yurineko.net | v0.0.1 | OshekharO | vi | manga | [Source Code](https://github.com/miru-project/repo/blob/main/repo/yurineko.net.js) | | ZeroScans | zeroscans.com | v0.0.1 | OshekharO | en | manga | [Source Code](https://github.com/miru-project/repo/blob/main/repo/zeroscans.com.js) | diff --git a/index.json b/index.json index 90e04da..de4c051 100644 --- a/index.json +++ b/index.json @@ -205,9 +205,22 @@ "package": "isekaiscan.to", "type": "manga", "url": "isekaiscan.to.js", - "version": "v0.0.2", + "version": "v0.0.3", "webSite": "https://m.isekaiscan.to" }, + { + "author": "OshekharO", + "icon": "https://javhd.today/android-icon-192x192.png", + "lang": "jp", + "license": "MIT", + "name": "JavHD", + "nsfw": "true", + "package": "javhd.today", + "type": "bangumi", + "url": "javhd.today.js", + "version": "v0.0.1", + "webSite": "https://javhd.today" + }, { "author": "OshekharO", "icon": "https://kimcartoon.li/Content/images/favicon.ico", @@ -242,7 +255,7 @@ "package": "kisskh.co", "type": "bangumi", "url": "kisskh.co.js", - "version": "v0.0.1", + "version": "v0.0.2", "webSite": "https://kisskh.co" }, { @@ -454,7 +467,7 @@ "package": "truyen.net", "type": "manga", "url": "truyen.net.js", - "version": "v0.0.2", + "version": "v0.0.3", "webSite": "https://comics-api.vercel.app" }, { @@ -580,6 +593,19 @@ "version": "v0.0.1", "webSite": "https://xdtv2.xyz/" }, + { + "author": "OshekharO", + "icon": "https://yurineko.net/img/logo-footer.png", + "lang": "vi", + "license": "MIT", + "name": "YuriNeko", + "nsfw": "false", + "package": "yurineko.net", + "type": "manga", + "url": "yurineko.net.js", + "version": "v0.0.1", + "webSite": "https://api.yurineko.net" + }, { "author": "OshekharO", "icon": "https://zeroscans.com/favicon.ico", diff --git a/repo/isekaiscan.to.js b/repo/isekaiscan.to.js index f14dbef..fe85958 100644 --- a/repo/isekaiscan.to.js +++ b/repo/isekaiscan.to.js @@ -1,6 +1,6 @@ // ==MiruExtension== // @name IsekaiScan -// @version v0.0.2 +// @version v0.0.3 // @author bethro // @lang en // @license MIT @@ -33,7 +33,7 @@ export default class extends Extension { key: "reverseChaptersOrder", type: "toggle", description: "Reverse the order of chapters in ascending order", - defaultValue: "false", + defaultValue: "true", }); // for latest & search page diff --git a/repo/javhd.today.js b/repo/javhd.today.js new file mode 100644 index 0000000..e22abe9 --- /dev/null +++ b/repo/javhd.today.js @@ -0,0 +1,151 @@ +// ==MiruExtension== +// @name JavHD +// @version v0.0.1 +// @author OshekharO +// @lang jp +// @license MIT +// @package javhd.today +// @type bangumi +// @icon https://javhd.today/android-icon-192x192.png +// @webSite https://javhd.today +// @nsfw true +// ==/MiruExtension== + +export default class extends Extension { + async latest() { + const res = await this.request("/releaseday/"); + const bsxList = await this.querySelectorAll(res, "div.video"); + const novel = []; + for (const element of bsxList) { + const html = await element.content; + const url = await this.getAttributeText(html, "a.thumbnail", "href"); + const title = await this.querySelector(html, "span.video-title").text; + const cover = await this.querySelector(html, "img").getAttributeText("src"); + //console.log(title+cover+url) + novel.push({ + title, + url: 'https://javhd.today' + url, + cover, + }); + } + return novel; + } + + async search(kw) { + const res = await this.request(`/search/video/?s=${kw}`); + const bsxList = await this.querySelectorAll(res, "div.video"); + const novel = []; + + for (const element of bsxList) { + const html = await element.content; + const url = await this.getAttributeText(html, "a.thumbnail", "href"); + const title = await this.querySelector(html, "span.video-title").text; + const cover = await this.querySelector(html, "img").getAttributeText("src"); + novel.push({ + title, + url: 'https://javhd.today' + url, + cover, + }); + } + return novel; + } + + async detail(url) { + const res = await this.request("", { + headers: { + "Miru-Url": url, + }, + }); + + const title = await this.querySelector(res, "meta[property='og:title']").getAttributeText("content"); + const cover = await this.querySelector(res, "meta[property='og:image']").getAttributeText("content"); + const desc = await this.querySelector(res, "p.description").text; + + const urlPatterns = [ + /https:\/\/minoplres\.[^\s'"]+/, + /https:\/\/vidcloud\.[^\s'"]+/, + /https:\/\/emturbovid\.[^\s'"]+/, + ]; + + let episodeUrl = ""; + + for (const pattern of urlPatterns) { + const match = res.match(pattern); + if (match) { + episodeUrl = match[0]; + break; + } + } + + function limitWords(text, maxWords) { + const words = text.split(/\s+/); + if (words.length > maxWords) { + return words.slice(0, maxWords).join(" ") + " ..."; + } + return text; + } + + return { + title: limitWords(title.trim(), 10), + cover, + desc, + episodes: [ + { + title: "Directory", + urls: [ + { + name: limitWords(title.trim(), 10), + url: episodeUrl, + }, + ], + }, + ], + }; +} + + async watch(url) { + const res = await this.request("", { + headers: { + "Miru-Url": url, + }, + }); + + let directUrl = ""; + + if (url.startsWith("https://minoplres")) { + const dwishLink = res.match(/https:\/\/tukipasti\.[^\s'"]+/); + + const dwishLinkRes = await this.request("", { + headers: { + "Miru-Url": dwishLink, + }, + }); + + const directUrlMatch = dwishLinkRes.match(/(https:\/\/[^\s'"]*\.m3u8[^\s'"]*)/); + directUrl = directUrlMatch ? directUrlMatch[0] : ""; + + } else if (url.startsWith("https://vidcloud")) { + + const directUrlMatch = res.match(/(https:\/\/[^\s'"]*\.m3u8[^\s'"]*)/); + directUrl = directUrlMatch ? directUrlMatch[0] : ""; + } else if (url.startsWith("https://emturbovid.com")) { + + const emturbovidRes = await this.request("", { + headers: { + "Miru-Url": url, + "referer": "https://emturbovid.com/", + "origin": "https://emturbovid.com", + }, + method: "Get", + }); + + const directUrlMatch = emturbovidRes.match(/(https:\/\/[^\s'"]*\.m3u8[^\s'"]*)/); + directUrl = directUrlMatch ? directUrlMatch[0] : ""; + } + + return { + type: "hls", + url: directUrl || "", + }; +} +} diff --git a/repo/kisskh.co.js b/repo/kisskh.co.js index 2daf9f5..31f1f8d 100644 --- a/repo/kisskh.co.js +++ b/repo/kisskh.co.js @@ -1,6 +1,6 @@ // ==MiruExtension== // @name Kisskh -// @version v0.0.1 +// @version v0.0.2 // @author OshekharO // @lang all // @license MIT @@ -40,7 +40,7 @@ export default class extends Extension { episodes: [ { title: "Directory", - urls: res.episodes.map((item) => ({ + urls: res.episodes.reverse().map((item) => ({ name: `Episode ${item.number}`, url: item.id.toString(), })), @@ -65,4 +65,4 @@ export default class extends Extension { }; } } - \ No newline at end of file + diff --git a/repo/truyen.net.js b/repo/truyen.net.js index 72d8839..acbcf08 100644 --- a/repo/truyen.net.js +++ b/repo/truyen.net.js @@ -1,6 +1,6 @@ // ==MiruExtension== // @name NetTruyen -// @version v0.0.2 +// @version v0.0.3 // @author OshekharO // @lang vi // @license MIT @@ -74,7 +74,7 @@ export default class extends Extension { const [id, chapter] = url.split("|"); const res = await this.request(`/comics/${id}/chapters/${chapter}`); return { - urls: res.images.map((item) => item.src), + urls: res.images.map((item) => item.backup_src), }; } } diff --git a/repo/yurineko.net.js b/repo/yurineko.net.js new file mode 100644 index 0000000..3bca9bd --- /dev/null +++ b/repo/yurineko.net.js @@ -0,0 +1,87 @@ +// ==MiruExtension== +// @name YuriNeko +// @version v0.0.1 +// @author OshekharO +// @lang vi +// @license MIT +// @icon https://yurineko.net/img/logo-footer.png +// @package yurineko.net +// @type manga +// @webSite https://api.yurineko.net +// @nsfw false +// ==/MiruExtension== + +export default class extends Extension { + async req(url) { + return this.request(url, { + headers: { + "Miru-Url": await this.getSetting("yurineko"), + }, + }); + } + + async load() { + this.registerSetting({ + title: "YURINEKO API", + key: "yurineko", + type: "input", + description: "YURINEKO API URL", + defaultValue: "https://api.yurineko.net", + }); + } + + async latest(page) { + const res = await this.req(`/lastest2?page=${page}`); + return res.result.map((item) => ({ + url: "https://yurineko.net/manga/" + item.id, + title: item.originalName, + cover: item.thumbnail, + })); + } + + async detail(url) { + const mangaId = url.match(/(\d+)/)[1]; + const res = await this.req(`/manga/${mangaId}`); + + return { + title: res.originalName, + cover: res.thumbnail, + desc: res.description, + episodes: [ + { + title: "Chapters", + urls: res.chapters.reverse().map((item) => ({ + name: `${item.name}`, + url: `${item.id}|${item.mangaID}`, + })), + }, + ], + }; + } + + async search(kw) { + const res = await this.req(`/search?query=${kw}`); + return res.result.map((item) => ({ + title: item.originalName, + url: "https://yurineko.net/manga/" + item.id, + cover: item.thumbnail, + })); + } + + async watch(url) { + const [chap, manga] = url.split("|"); + const res = await this.request(`/${manga}/${chap}`, { + headers: { + "Miru-Url": "https://yurineko.net/read", + }, + }); + + const jsonData = res.match(/