增加:nhentai (#983)

This commit is contained in:
Zhu Chu
2018-10-28 02:02:38 +08:00
committed by DIYgod
parent eaf11f6e41
commit bd30043b01
5 changed files with 112 additions and 0 deletions

View File

@@ -2079,3 +2079,8 @@ IATA 国际航空运输协会机场代码, 参见[维基百科 国际航空运
### 油价 ### 油价
<route name="今日油价" author="xyqfer" example="/oilprice/shanghai" path="/oilprice/:area" :paramsDesc="['地区拼音,详见[成品油价格网](http://oil.usd-cny.com/)']"/> <route name="今日油价" author="xyqfer" example="/oilprice/shanghai" path="/oilprice/:area" :paramsDesc="['地区拼音,详见[成品油价格网](http://oil.usd-cny.com/)']"/>
### nHentai
<route name="分类筛选" author="MegrezZhu" example="/nhentai/language/chinese" path="/nhentai/:key/:keyword" :paramsDesc="['筛选条件,可选: parody, character, tag, artist, group, language, category','筛选值']" />
<route name="高级搜索" author="MegrezZhu" example="/nhentai/search/translated" path="/nhentai/search/:keyword" :paramsDesc="['用于搜索的关键词,用法详见[官网](https://nhentai.net/info/)']" />

View File

@@ -706,4 +706,8 @@ router.get('/youku/channel/:channelId/:embed?', require('./routes/youku/channel'
// 油价 // 油价
router.get('/oilprice/:area', require('./routes/oilprice')); router.get('/oilprice/:area', require('./routes/oilprice'));
// nHentai
router.get('/nhentai/search/:keyword', require('./routes/nhentai/search'));
router.get('/nhentai/:key/:keyword', require('./routes/nhentai/other'));
module.exports = router; module.exports = router;

23
routes/nhentai/other.js Normal file
View File

@@ -0,0 +1,23 @@
const { getList, getDetailWithCache } = require('./util');
const supportedKeys = ['parody', 'character', 'tag', 'artist', 'group', 'language', 'category'];
module.exports = async (ctx) => {
const { keyword, key } = ctx.params;
if (supportedKeys.indexOf(key) === -1) {
ctx.state.data = {
title: 'nHentai - unsupported',
};
return;
}
const list = await getList(`https://nhentai.net/${key}/${keyword.toLowerCase().replace(' ', '-')}`);
const details = await Promise.all(list.map(getDetailWithCache.bind(null, ctx.cache)));
ctx.state.data = {
title: `nHentai - ${key} - ${keyword}`,
link: 'https://nhentai.net',
description: 'hentai',
item: details,
};
};

14
routes/nhentai/search.js Normal file
View File

@@ -0,0 +1,14 @@
const { getList, getDetailWithCache } = require('./util');
module.exports = async (ctx) => {
const { keyword } = ctx.params;
const list = await getList(`https://nhentai.net/search/?q=${keyword}`);
const details = await Promise.all(list.map(getDetailWithCache.bind(null, ctx.cache)));
ctx.state.data = {
title: `nHentai - search - ${keyword}`,
link: 'https://nhentai.net',
description: 'hentai',
item: details,
};
};

66
routes/nhentai/util.js Normal file
View File

@@ -0,0 +1,66 @@
const { resolve } = require('url');
const cheerio = require('cheerio');
const axios = require('../../utils/axios');
exports.getList = async (url) => {
const { data } = await axios.get(url);
const $ = cheerio.load(data);
return $('.gallery a.cover')
.map((_, ele) => createResult($, ele))
.get();
};
exports.getDetail = async (url) => {
const { data } = await axios.get(url);
const $ = cheerio.load(data);
// thumb to high-quality
let galleryThumbs = $('.gallerythumb img')
.map((_, ele) => resolve('https://nhentai.net', $(ele).attr('data-src')))
.get();
galleryThumbs = galleryThumbs.map((src) => src.replace(/(.+)(\d+)t\.(.+)/, (_, p1, p2, p3) => `${p1}${p2}.${p3}`));
galleryThumbs = galleryThumbs.map((src) => src.replace('t.nhentai.net', 'i.nhentai.net'));
const renderImg = (src) => `<img referrerpolicy="no-referrer" src="${src}" />`;
return {
pubDate: new Date($('time').attr('datetime')).toUTCString(),
guid: `full:${url}`,
description: `
<h1>${galleryThumbs.length} pages</h1>
${galleryThumbs.map(renderImg).join('')}
`.trim(),
};
};
exports.getDetailWithCache = async (cache, info) => {
const cached = await cache.get(`full:${info.link}`);
if (cached) {
return {
...info,
...cached,
};
} else {
const detail = await exports.getDetail(info.link);
cache.set(`full:${info.link}`, detail);
return {
...info,
...detail,
};
}
};
function createResult($, ele) {
const link = resolve('https://nhentai.net', $(ele).attr('href'));
const thumbImg = $(ele).children('img');
const thumbSrc = thumbImg.attr('data-src') || thumbImg.attr('src');
return {
title: $(ele)
.children('.caption')
.text(),
link,
guid: link,
pubDate: new Date().toUTCString(), // 要获得准确时间需要对每个本子都请求一遍,很麻烦
description: `<img referrerpolicy="no-referrer" src="${thumbSrc.replace('thumb', 'cover')}" />`,
};
}