123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234 |
- import {Spider} from "./spider.js";
- import {BookDetail, BookShort} from "../lib/book.js";
- import {Crypto} from "../lib/cat.js";
- class CopyManhuaSpider extends Spider {
- constructor() {
- super();
- this.siteUrl = 'https://www.copymanga.tv';
- }
- getName() {
- return "🧑🎨|拷贝漫画|🧑🎨"
- }
- getAppName() {
- return "拷贝漫画"
- }
- getJSName() {
- return "copymanga"
- }
- getType() {
- return 20
- }
- async setClasses() {
- this.classes.push(this.getTypeDic("全部", "c1"))
- }
- async getFilter($) {
- let region = {
- key: 'region', name: '地區', init: '',
- };
- let regionValues = [];
- regionValues.push({n: '全部', v: ''});
- regionValues.push({n: '日漫', v: '0'});
- regionValues.push({n: '韓漫', v: '1'});
- regionValues.push({n: '美漫', v: '2'});
- region['value'] = regionValues;
- let ordering = {
- key: 'ordering', name: '排序', init: '-datetime_updated',
- };
- let orderingValues = [];
- orderingValues.push({n: '更新時間↓', v: '-datetime_updated'});
- orderingValues.push({n: '更新時間↑', v: 'datetime_updated'});
- orderingValues.push({n: '熱門↓', v: '-popular'});
- orderingValues.push({n: '熱門↑', v: 'popular'});
- ordering['value'] = orderingValues;
- let status = {
- key: 'sort', name: '狀態', init: '',
- };
- let statusValues = [];
- statusValues.push({n: '全部', v: ''});
- statusValues.push({n: '連載中', v: '0'});
- statusValues.push({n: '已完結', v: '1'});
- statusValues.push({n: '短篇', v: '2'});
- status['value'] = statusValues;
- let extend_list = []
- let themeValues = [{n: '全部', v: ''}];
- for (const a of $('div.classify-right>a[href*="theme="]')) {
- themeValues.push({
- n: $(a).text().trim(), v: a.attribs.href.match(/.*?theme=(.*)&/)[1],
- });
- }
- extend_list.push({
- key: 'theme', name: '', init: '', wrap: 1, value: themeValues,
- });
- extend_list.push(region);
- extend_list.push(status);
- extend_list.push(ordering);
- return extend_list
- }
- async setFilterObj() {
- let $ = await this.getHtml(this.siteUrl + '/comics');
- this.filterObj['c1'] = await this.getFilter($);
- }
- parseVodShortFromJson(obj) {
- let bookShort = new BookShort()
- bookShort.book_id = obj["path_word"]
- bookShort.book_name = obj["name"]
- bookShort.book_pic = obj["cover"]
- bookShort.book_remarks = obj.author ? obj.author[0].name : '';
- return bookShort
- }
- async parseVodShortListFromDocByCategory($) {
- const list = eval($('div[class="row exemptComic-box"]')[0].attribs.list);
- let books = [];
- for (const book of list) {
- let bookShort = this.parseVodShortFromJson(book)
- books.push(bookShort)
- }
- return books
- }
- async parseVodShortListFromDoc($) {
- let vodElements = $("[class=\"container edit\"]").find("[class=\"col-auto\"]")
- let books = []
- for (const vodElement of vodElements) {
- let bookShort = new BookShort()
- bookShort.book_id = $(vodElement).find("a")[0].attribs.href.split("/comic/")[1]
- bookShort.book_pic = $(vodElement).find("img")[0].attribs["data-src"]
- bookShort.book_name = $($(vodElement).find("p")).text()
- books.push(bookShort)
- }
- return books
- }
- async parseVodDetailFromDoc($, id) {
- let bookDetail = new BookDetail()
- bookDetail.book_pic = $("[class=\"comicParticulars-left-img loadingIcon\"]").find("img")[0].attribs["data-src"]
- bookDetail.book_name = $('h6').text().trim()
- bookDetail.book_director = $('span.comicParticulars-right-txt>a[href*="/author/"]')
- .map((_, a) => $(a).text().trim())
- .get()
- .join('/')
- bookDetail.book_content = $('p.intro').text().trim()
- let data = JSON.parse(await this.fetch(this.siteUrl + `/comicdetail/${id}/chapters`, null, this.getHeader()))["results"]
- let key = Crypto.enc.Utf8.parse('xxxmanga.woo.key');
- let iv = Crypto.enc.Utf8.parse(data.substr(0, 16));
- let src = Crypto.enc.Hex.parse(data.substr(16));
- let dst = Crypto.AES.decrypt({ciphertext: src}, key, {iv: iv, padding: Crypto.pad.Pkcs7});
- dst = Crypto.enc.Utf8.stringify(dst);
- const groups = JSON.parse(dst).groups;
- let urls = groups.default["chapters"]
- .map((c) => {
- return c.name + '$' + id + '|' + c.id;
- })
- .join('#');
- bookDetail.volumes = '默認';
- bookDetail.urls = urls;
- bookDetail.book_id = id
- return bookDetail
- }
- async parseVodShortListFromJson(obj) {
- const books = [];
- for (const book of obj) {
- books.push(this.parseVodShortFromJson(book))
- }
- return books
- }
- async setHomeVod() {
- let $ = await this.getHtml(this.siteUrl)
- this.homeVodList = await this.parseVodShortListFromDoc($)
- }
- async setCategory(tid, pg, filter, extend) {
- let page = pg || 1;
- if (page === 0) page = 1;
- let link = this.siteUrl + `/comics?theme=${extend.theme || ''}®ion=${extend.region || ''}&status=${extend.status || ''}&ordering=${extend.ordering || '-datetime_updated'}`;
- if (page > 1) {
- link += '&offset=' + (page - 1) * 50 + '&limit=50';
- }
- let $ = await this.getHtml(link)
- this.vodList = await this.parseVodShortListFromDocByCategory($)
- }
- async setDetail(id) {
- let $ = await this.getHtml(this.siteUrl + `/comic/${id}`)
- this.vodDetail = await this.parseVodDetailFromDoc($, id)
- }
- async setPlay(flag, id, flags) {
- let info = id.split('|');
- let $ = await this.getHtml(this.siteUrl + `/comic/${info[0]}/chapter/${info[1]}`);
- const data = $('div.imageData')[0].attribs["contentkey"];
- let key = Crypto.enc.Utf8.parse('xxxmanga.woo.key');
- let iv = Crypto.enc.Utf8.parse(data.substr(0, 16));
- let src = Crypto.enc.Hex.parse(data.substr(16));
- let dst = Crypto.AES.decrypt({ciphertext: src}, key, {iv: iv, padding: Crypto.pad.Pkcs7});
- dst = Crypto.enc.Utf8.stringify(dst);
- const list = JSON.parse(dst);
- let content = [];
- for (let index = 0; index < list.length; index++) {
- const element = list[index];
- content[index] = element.url;
- }
- this.playUrl = {
- "content": content,
- }
- }
- async setSearch(wd, quick) {
- let page = 1
- const link = `${this.siteUrl}/api/kb/web/searcha/comics?offset=${page > 1 ? ((page - 1) * 12).toString() : ''}&platform=2&limit=12&q=${wd}&q_type=`;
- let list = JSON.parse(await this.fetch(link, null, this.getHeader()))["results"]["list"]
- this.vodList = await this.parseVodShortListFromJson(list)
- }
- }
- let spider = new CopyManhuaSpider()
- async function init(cfg) {
- await spider.init(cfg)
- }
- async function home(filter) {
- return await spider.home(filter)
- }
- async function homeVod() {
- return await spider.homeVod()
- }
- async function category(tid, pg, filter, extend) {
- return await spider.category(tid, pg, filter, extend)
- }
- async function detail(id) {
- return await spider.detail(id)
- }
- async function play(flag, id, flags) {
- return await spider.play(flag, id, flags)
- }
- async function search(wd, quick) {
- return await spider.search(wd, quick)
- }
- export function __jsEvalReturn() {
- return {
- init: init, home: home, homeVod: homeVod, category: category, detail: detail, play: play, search: search,
- };
- }
- export {spider}
|