tvbox_config/open/manhuagui_open.js
liushiquan 36ab603d34 init
2024-06-01 22:41:46 +08:00

284 lines
11 KiB
JavaScript

import { Crypto, _, load } from './lib/cat.js';
import { LZString } from './lib/lz_string.js';
let key = 'manhuagui';
let HOST = 'https://www.manhuagui.com';
let siteKey = '';
let siteType = 0;
let prefixMap = {};
const VOLUME_KEY_TELECOM = 'tel';
const VOLUME_KEY_TELECOM1 = 'tel2';
const VOLUME_KEY_UNICOM = 'uni';
const VOLUME_KEY_UNICOM1 = 'uni1';
const VOLUME_KEY_UNICOM2 = 'uni2';
const VOLUME_KEY_UNICOM3 = 'uni3';
const PC_UA = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.54 Safari/537.36';
async function request(reqUrl) {
let resp = await req(reqUrl, {
headers: {
'User-Agent': PC_UA,
},
});
return resp.content;
}
// cfg = {skey: siteKey, ext: extend}
async function init(cfg) {
siteKey = cfg.skey;
siteType = cfg.stype;
initKeys();
String.prototype.splic = function(f) {
const data = LZString.decompressFromBase64(this);
return data.split(f);
}
}
function initKeys() {
prefixMap[VOLUME_KEY_TELECOM] = {
key: 'eu',
name: '电信',
};
prefixMap[VOLUME_KEY_TELECOM1] = {
key: 'eu1',
name: '电信1',
};
prefixMap[VOLUME_KEY_UNICOM] = {
key: 'us',
name: '联通',
};
prefixMap[VOLUME_KEY_UNICOM1] = {
key: 'us1',
name: '联通1',
};
prefixMap[VOLUME_KEY_UNICOM2] = {
key: 'us2',
name: '联通2',
};
prefixMap[VOLUME_KEY_UNICOM3] = {
key: 'us3',
name: '联通3',
};
}
async function home(filter) {
const classes = [{'type_id':'all','type_name':'漫画大全'}];
const filterObj = {
'all':[{'key':'area','name':'地区','init':'','value':[{'n':'全部','v':''},{'n':'日本','v':'japan'},{'n':'港台','v':'hongkon'},{'n':'其它','v':'other'},{'n':'欧美','v':'europe'},{'n':'内地','v':'china'},{'n':'韩国','v':'korea'}]},{'key':'genre','name':'剧情','init':'','value':[{'n':'全部','v':''},{'n':'热血','v':'rexue'},{'n':'冒险','v':'maoxian'},{'n':'魔幻','v':'mohuan'},{'n':'神鬼','v':'shengui'},{'n':'搞笑','v':'gaoxiao'},{'n':'萌系','v':'mengxi'},{'n':'爱情','v':'aiqing'},{'n':'科幻','v':'kehuan'},{'n':'魔法','v':'mofa'},{'n':'格斗','v':'gedou'},{'n':'武侠','v':'wuxia'},{'n':'机战','v':'jizhan'},{'n':'战争','v':'zhanzheng'},{'n':'竞技','v':'jingji'},{'n':'体育','v':'tiyu'},{'n':'校园','v':'xiaoyuan'},{'n':'生活','v':'shenghuo'},{'n':'励志','v':'lizhi'},{'n':'历史','v':'lishi'},{'n':'伪娘','v':'weiniang'},{'n':'宅男','v':'zhainan'},{'n':'腐女','v':'funv'},{'n':'耽美','v':'danmei'},{'n':'百合','v':'baihe'},{'n':'后宫','v':'hougong'},{'n':'治愈','v':'zhiyu'},{'n':'美食','v':'meishi'},{'n':'推理','v':'tuili'},{'n':'悬疑','v':'xuanyi'},{'n':'恐怖','v':'kongbu'},{'n':'四格','v':'sige'},{'n':'职场','v':'zhichan'},{'n':'侦探','v':'zhentan'},{'n':'社会','v':'shehui'},{'n':'音乐','v':'yinyue'},{'n':'舞蹈','v':'wudao'},{'n':'杂志','v':'zazhi'},{'n':'黑道','v':'heidao'}]},{'key':'age','name':'受众','init':'','value':[{'n':'全部','v':''},{'n':'少女','v':'shaonv'},{'n':'少年','v':'shaonian'},{'n':'青年','v':'qingnian'},{'n':'儿童','v':'ertong'},{'n':'通用','v':'tongyong'}]},{'key':'year','name':'年份','init':'','value':[{'n':'全部','v':''},{'n':'2024年','v':'2024'},{'n':'2023年','v':'2023'},{'n':'2022年','v':'2022'},{'n':'2021年','v':'2021'},{'n':'2020年','v':'2020'},{'n':'2019年','v':'2019'},{'n':'2018年','v':'2018'},{'n':'2017年','v':'2017'},{'n':'2016年','v':'2016'},{'n':'2015年','v':'2015'},{'n':'2014年','v':'2014'},{'n':'2013年','v':'2013'},{'n':'2012年','v':'2012'},{'n':'2011年','v':'2011'},{'n':'2010年','v':'2010'},{'n':'00年代','v':'200x'},{'n':'90年代','v':'199x'},{'n':'80年代','v':'198x'},{'n':'更早','v':'197x'}]},{'key':'letter','name':'字母','init':'','value':[{'n':'全部','v':''},{'n':'A','v':'A'},{'n':'B','v':'B'},{'n':'C','v':'C'},{'n':'D','v':'D'},{'n':'E','v':'E'},{'n':'F','v':'F'},{'n':'G','v':'G'},{'n':'H','v':'H'},{'n':'I','v':'I'},{'n':'J','v':'J'},{'n':'K','v':'K'},{'n':'L','v':'L'},{'n':'M','v':'M'},{'n':'N','v':'N'},{'n':'O','v':'O'},{'n':'P','v':'P'},{'n':'Q','v':'Q'},{'n':'R','v':'R'},{'n':'S','v':'S'},{'n':'T','v':'T'},{'n':'U','v':'U'},{'n':'V','v':'V'},{'n':'W','v':'W'},{'n':'X','v':'X'},{'n':'Y','v':'Y'},{'n':'Z','v':'Z'},{'n':'0-9','v':'0-9'}]},{'key':'status','name':'进度','init':'','value':[{'n':'全部','v':''},{'n':'连载','v':'lianzai'},{'n':'完结','v':'wanjie'}]},{'key':'sort','name':'排序','init':'index','value':[{'n':'最新发布','v':'index'},{'n':'最新更新','v':'update'},{'n':'热气最旺','v':'view'},{'n':'评分最高','v':'rate'}]}],
};
return JSON.stringify({
class: classes,
filters: filterObj,
});
}
async function category(tid, pg, filter, extend) {
if (pg == 0) pg = 1;
const area = getFilterUrlPart(extend, 'area');
const genre = getFilterUrlPart(extend, 'genre');
const age = getFilterUrlPart(extend, 'age');
const year = getFilterUrlPart(extend, 'year');
const letter = getFilterUrlPart(extend, 'letter');
const status = getFilterUrlPart(extend, 'status');
let path1 = `${area}${genre}${age}${year}${letter}${status}`;
path1 = path1.replace(/_$/, '');
const sort = getFilterUrlPart(extend, 'sort');
let path2 = sort;
if (pg > 1) {
path2 += `p${pg}`;
}
path2 = path2.replace(/_$/, '');
let path = '';
if (!_.isEmpty(path1)) {
path += `/${path1}`;
}
if (!_.isEmpty(path2)) {
path += `/${path2}.html`;
}
if (_.isEmpty(path)) {
path = '/';
}
const link = HOST + `/list${path}`;
const html = await request(link);
const $ = load(html);
const list = $('.book-list > #contList > li');
const books = _.map(list, (item) => {
const $item = $(item);
const $cover = $item.find('.bcover');
const $img = $cover.find('img:first');
const $remark = $item.find('.updateon em:first');
let src = $img.attr('src');
if (_.isEmpty(src)) {
src = $img.attr('data-src');
}
return {
book_id: $cover.attr('href').replace(/\/comic\/(.*)\//, '$1'),
book_name: $cover.attr('title'),
book_pic: 'https:' + src,
book_remarks: $remark.text(),
};
});
const hasMore = $('.pager-cont a:contains(下一页)').length > 0;
return {
page: pg,
pagecount: hasMore ? pg + 1 : pg,
list: books,
};
}
function getFilterUrlPart(extend, part) {
let result = '';
if (extend[part]) {
result = extend[part] + '_';
}
return result;
}
async function detail(id) {
const html = await request(HOST + `/comic/${id}/`);
const $ = load(html);
const book = {
book_name: $('.book-title').text().trim(),
book_year: $('.detail-list span:contains(出品年代) a').text().trim(),
book_area: $('.detail-list span:contains(漫画地区) a').text().trim(),
book_director: $('.detail-list span:contains(漫画作者) a').text().trim(),
book_content: $('#intro-all').text().trim(),
};
const list = $('.chapter-list a');
const keys = _.keys(prefixMap);
const urls = _.map(keys, (key) => {
const volume = prefixMap[key].key;
return _.map(list, (item) => {
const $item = $(item);
const title = $item.attr('title');
const href = $item.attr('href');
return title + '$' + href + '|' + volume;
}).join('#');
}).join('$$$');
const volumes = _.map(keys, (key) => {
return prefixMap[key].name;
}).join('$$$');
book.volumes = volumes;
book.urls = urls;
return {
list: [book],
};
}
async function play(flag, id, flags) {
try {
const info = id.split('|');
const path = info[0];
const volumeKey = info[1];
const html = await request(HOST + path);
const matches = html.match(/\[\"\\x65\\x76\\x61\\x6c\"\]\((.*)\)/);
const js = 'var result =' + matches[1] + ';result';
const data = eval(js);
const configs = data.match(/SMH\.imgData\((.*?)\)/);
const json = JSON.parse(configs[1]);
const jsBase = await js2Proxy(true, siteType, siteKey, 'img/', {});
const content = _.map(json.files, (file) => {
const playUrl = `https://${volumeKey}.hamreus.com${json.path}${file}?e=${json.sl.e}&m=${json.sl.m}`;
return jsBase + base64Encode(playUrl);
});
return {
content: content,
};
} catch (e) {
console.debug('error: ' + e);
return {
content: '',
};
}
}
function base64Encode(text) {
return Crypto.enc.Base64.stringify(Crypto.enc.Utf8.parse(text));
}
function base64Decode(text) {
return Crypto.enc.Utf8.stringify(Crypto.enc.Base64.parse(text));
}
async function proxy(segments, headers) {
const what = segments[0];
const url = base64Decode(segments[1]);
if (what == 'img') {
const resp = await req(url, {
buffer: 1,
shared: 1,
headers: {
'User-Agent': PC_UA,
Referer: HOST,
},
});
delete resp.headers['transfer-encoding'];
if (resp.headers['content-encoding'] == 'gzip') {
delete resp.headers['content-encoding'];
}
return {
code: resp.code,
buffer: 3,
content: resp.content,
headers: resp.headers,
};
}
return {
code: 500,
content: '',
};
}
async function search(wd, quick, pg) {
if (pg == 0) pg = 1;
let page = '';
if (pg > 1) {
page = `_p${pg}`;
}
const link = HOST + `/s/${encodeURIComponent(wd)}${page}.html`;
const html = await request(link);
const $ = load(html);
const list = $('.book-result li.cf');
const books = _.map(list, (item) => {
const $item = $(item);
const $cover = $item.find('.book-cover');
const $a = $cover.find('a:first');
const $img = $cover.find('img:first');
const $remark = $item.find('.book-score .score-avg strong:first');
let src = $img.attr('src');
if (_.isEmpty(src)) {
src = $img.attr('data-src');
}
return {
book_id: $a.attr('href').replace(/\/comic\/(.*)\//, '$1'),
book_name: $a.attr('title'),
book_pic: 'https:' + src,
book_remarks: $remark.text(),
};
});
const hasMore = $('.pager-cont a:contains(下一页)').length > 0;
return {
page: pg,
pagecount: hasMore ? pg + 1 : pg,
list: books,
};
}
export function __jsEvalReturn() {
return {
init: init,
home: home,
category: category,
detail: detail,
play: play,
proxy: proxy,
search: search,
};
}