fix(route): fix pianyuan, add pianyuan/search (#9721)

* fix route pianyuan, add route pianyuan/search

* update doc

* changes for reviews

* Update lib/routes/pianyuan/utils.js

Co-authored-by: Rongrong <Rongronggg9@outlook.com>

* changes for reviews

* refactor: migrate to v2

Co-authored-by: Rongrong <Rongronggg9@outlook.com>
This commit is contained in:
jerry1119
2022-05-09 01:00:29 +08:00
committed by GitHub
parent 145ad517b6
commit 0c3ca1bb11
13 changed files with 209 additions and 63 deletions
-1
View File
@@ -220,7 +220,6 @@
'tw.manhuagui.com': { _name: '漫画柜台湾', www: [{ title: '漫画更新', docs: 'https://docs.rsshub.app/anime.html#kan-man-hua-tai-wan', source: '/comic/:id/', target: '/twmanhuagui/comic/:id' }] },
'copymanga.com': { _name: '拷贝漫画', www: [{ title: '漫画更新', docs: 'https://docs.rsshub.app/anime.html#kao-bei-man-hua', source: '/comic/:id/', target: '/manhuagui/comic/:id/5' }] },
'pgyer.com': { _name: '蒲公英应用分发', www: [{ title: 'app更新', docs: 'https://docs.rsshub.app/program-update.html#pu-gong-ying-ying-yong-fen-fa', source: '/:app', target: '/pgyer/:app' }] },
'pianyuan.la': { _name: '片源网', '.': [{ title: '电影和剧集', docs: 'https://docs.rsshub.app/multimedia.html#pian-yuan', source: '/' }] },
'baidu.com': {
_name: '贴吧',
tieba: [
+4
View File
@@ -664,6 +664,10 @@ RSSHub 支持使用访问密钥 / 码,白名单和黑名单三种方式进行
- `NHENTAI_USERNAME`: nhentai 用户名或邮箱
- `NHENTAI_PASSWORD`: nhentai 密码
- pianyuan 全部路由: [注册地址](https://pianyuan.org)
- `PIANYUAN_COOKIE`: 对应 cookie 中的 `py_loginauth`, 例: PIANYUAN_COOKIE='py_loginauth=xxxxxxxxxx'
- pixiv 全部路由:[注册地址](https://accounts.pixiv.net/signup)
- `PIXIV_REFRESHTOKEN`: Pixiv Refresh Token, 请参考 [此文](https://gist.github.com/ZipFile/c9ebedb224406f4f11845ab700124362) 获取,或自行对客户端抓包获取
+11 -1
View File
@@ -1262,7 +1262,17 @@ JavDB 有多个备用域名,本路由默认使用永久域名 <https://javdb.c
### 最新资源
<Route author="greatcodeeer" example="/pianyuan" path="/pianyuan" radar="1" rssbud="1"/>
<Route author="greatcodeeer jerry1119" example="/pianyuan/index" path="/pianyuan/index/:media?" :paramsDesc="['类别,见下表,默认为首页']" radar="1" rssbud="1" selfhost="1"/>
| 电影 | 剧集 |
| -- | -- |
| mv | tv |
### 搜索
<Route author="jerry1119" example="/pianyuan/indexers/pianyuan/results/search/api?t=test&q=长津湖" path="/pianyuan/indexers/pianyuan/results/search/" selfhost="1"/>
搜索路由模仿 jackett 的搜索 api, 以提供给 nastools 使用,填写在 nastools 配置 indexer 中
## 飘花电影网
+3
View File
@@ -198,6 +198,9 @@ const calculateValue = () => {
username: envs.NHENTAI_USERNAME,
password: envs.NHENTAI_PASSWORD,
},
pianyuan: {
cookie: envs.PIANYUAN_COOKIE,
},
pixiv: {
refreshToken: envs.PIXIV_REFRESHTOKEN,
bypassCdn: envs.PIXIV_BYPASS_CDN !== '0' && envs.PIXIV_BYPASS_CDN !== 'false',
-10
View File
@@ -466,16 +466,6 @@ module.exports = {
},
],
},
'pianyuan.la': {
_name: '片源网',
'.': [
{
title: '电影和剧集',
docs: 'https://docs.rsshub.app/multimedia.html#pian-yuan',
source: '/',
},
],
},
'baidu.com': {
_name: '贴吧',
tieba: [
+3 -2
View File
@@ -2271,8 +2271,9 @@ router.get('/chocolatey/software/:name?', lazyloadRouteHandler('./routes/chocola
// Nyaa
router.get('/nyaa/search/:query?', lazyloadRouteHandler('./routes/nyaa/search'));
// 片源网
router.get('/pianyuan/:media?', lazyloadRouteHandler('./routes/pianyuan/app'));
// 片源网 migrated to v2
// router.get('/pianyuan/index/:media?', lazyloadRouteHandler('./routes/pianyuan/app'));
// router.get('/pianyuan/indexers/pianyuan/results/search/api', lazyloadRouteHandler('./routes/pianyuan/search'));
// 巴哈姆特
router.get('/bahamut/creation/:author/:category?', lazyloadRouteHandler('./routes/bahamut/creation'));
-49
View File
@@ -1,49 +0,0 @@
const got = require('@/utils/got');
const cheerio = require('cheerio');
module.exports = async (ctx) => {
const media = ctx.params.media || -1;
const link_base = 'http://pianyuan.tv/';
let description = '电影和剧集';
let link = link_base;
if (media !== -1) {
link = link_base + `?cat=${media}`;
if (media === 'mv') {
description = '电影';
} else if (media === 'tv') {
description = '剧集';
} else {
link = link_base;
}
}
const response = await got.get(link);
const data = response.data;
const $ = cheerio.load(data);
const items = [];
$('#main-container > div > div.col-md-10 > table > tbody > tr').each((i, item) => {
const link = $(item).find('td.dt.prel.nobr > a').attr('href');
const text = $(item).find('td.dt.prel.nobr > a').text();
const description = $(item)
.find('td.dt.prel.nobr')
.text()
.replace(/^\s+|\s+$/g, '');
const size = $(item).find('td:nth-child(2)').text();
const description_simple = description.substr(0, description.indexOf('主演')).replace(text, '');
items.push({
title: `[${size}] ${description_simple}`,
description,
link: link_base + link,
});
});
ctx.state.data = {
title: `片源网`,
description,
link: link_base,
item: items,
};
};
+34
View File
@@ -0,0 +1,34 @@
const cheerio = require('cheerio');
const utils = require('./utils');
module.exports = async (ctx) => {
const media = ctx.params.media ?? -1;
const link_base = 'https://pianyuan.org/';
let description = '电影和剧集';
let link = link_base;
if (media !== -1) {
link = link_base + `?cat=${media}`;
if (media === 'mv') {
description = '电影';
} else if (media === 'tv') {
description = '剧集';
} else {
link = link_base;
}
}
const response = await utils.request(link, ctx.cache);
const $ = cheerio.load(response.data);
const detailLinks = $('#main-container > div > div.col-md-10 > table > tbody > tr')
.get()
.map((tr) => $(tr).find('td.dt.prel.nobr > a').attr('href'));
detailLinks.shift();
const items = await utils.ProcessFeed(detailLinks, ctx.cache);
ctx.state.data = {
title: '片源网',
description,
link: link_base,
item: items,
};
};
+4
View File
@@ -0,0 +1,4 @@
module.exports = {
'/index/:media?': ['greatcodeeer', 'jerry1119'],
'/indexers/pianyuan/results/search/api': ['jerry1119'],
};
+13
View File
@@ -0,0 +1,13 @@
module.exports = {
'pianyuan.org': {
_name: '片源网',
'.': [
{
title: '电影和剧集',
docs: 'https://docs.rsshub.app/multimedia.html#pian-yuan',
source: '/',
target: '/pianyuan/index',
},
],
},
};
+4
View File
@@ -0,0 +1,4 @@
module.exports = (router) => {
router.get('/index/:media?', require('./app'));
router.get('/indexers/pianyuan/results/search/api', require('./search'));
};
+45
View File
@@ -0,0 +1,45 @@
const cheerio = require('cheerio');
const utils = require('./utils');
module.exports = async (ctx) => {
const link_base = 'https://pianyuan.org/';
const description = '搜索';
// 适配jackett 搜索api, eg: https://rsshub.app/pianyuan/indexers/pianyuan/results/search/api?t=test&q=halo
const searchKey = ctx.originalUrl.split('&q=')[1];
const link = link_base + `search?q=${searchKey}`;
const response = await utils.request(link, ctx.cache);
const $ = cheerio.load(response.data);
// 只获取第一页的搜索结果
const searchLinks = $('.nomt > a')
.get()
.map((a) => $(a).attr('href'));
if (searchLinks.length === 0) {
throw 'pianyuan 搜索失败';
}
const detailLinks = [];
await Promise.all(
searchLinks.map(async (e) => {
const link = new URL(e, link_base);
const single = await ctx.cache.tryGet(link, async () => {
const res = await utils.request(link, ctx.cache);
const content = cheerio.load(res.data);
content('.ico.ico_bt')
.get()
.map((a) => detailLinks.push($(a).attr('href')));
});
return single;
})
);
const items = await utils.ProcessFeed(detailLinks, ctx.cache);
ctx.state.data = {
title: '片源网',
description,
link: link_base,
item: items,
};
};
+88
View File
@@ -0,0 +1,88 @@
const cheerio = require('cheerio');
const got = require('@/utils/got');
const config = require('@/config').value;
const security_key = 'pianyuan-security_session_verify';
const PHPSESSID_key = 'pianyuan-PHPSESSID';
const loginauth_key = 'pianyuan-py_loginauth';
const ProcessFeed = async (list, cache) => {
const link_base = 'https://pianyuan.org';
const items = await Promise.all(
list.map(async (e) => {
const link = new URL(e, link_base);
const single = await cache.tryGet(link, async () => {
const response = await request(link, cache);
const content = cheerio.load(response.data);
const magnet = content('.btn-primary').attr('href');
const torrent_name = content('body > div.jumbotron.masthead > div > div > div.col-sm-10.col-md-10.col-lg-10.text-left > h1').text();
const name = content('body > div.jumbotron.masthead > div > div > div.col-sm-10.col-md-10.col-lg-10.text-left > h2 > a').text();
const size = content('#main-container > div > div.col-sm-10.col-md-8.col-lg-8 > div > ul > li:nth-child(2)').text();
let length;
if (size.includes('MB')) {
length = size.replace('MB', '') * 1024;
} else if (size.includes('GB')) {
length = size.replace('GB', '') * 1024 * 1024;
}
// const description ='';
return {
title: `${torrent_name} [${name}] [${size}]`,
size: length,
enclosure_url: magnet,
enclosure_type: 'application/x-bittorrent',
enclosure_length: length,
};
});
return single;
})
);
return items;
};
async function getCookie(cache) {
const security_session_verify = await cache.get(security_key);
const PHPSESSID = await cache.get(PHPSESSID_key);
let py_loginauth = await cache.get(loginauth_key);
if (!py_loginauth) {
if (!config.pianyuan || !config.pianyuan.cookie) {
throw 'pianyuan is disabled due to the lack of <a href="https://docs.rsshub.app/install/#pei-zhi-bu-fen-rss-mo-kuai-pei-zhi">relevant config</a>';
}
py_loginauth = config.pianyuan.cookie;
}
return `${py_loginauth};${security_session_verify};${PHPSESSID};`;
}
async function request(link, cache) {
const cookie = await getCookie(cache);
const response = await got({
method: 'get',
url: link,
headers: {
Cookie: cookie,
},
});
// set cookie
const set_cookie = response.headers['set-cookie'];
if (set_cookie) {
for (const e of set_cookie) {
if (e.indexOf('security_session_verify') === 0) {
cache.set(security_key, e.split(';')[0]);
} else if (e.indexOf('PHPSESSID') === 0) {
cache.set(PHPSESSID_key, e.split(';')[0]);
} else if (e.indexOf('py_loginauth') === 0) {
cache.set(loginauth_key, e.split(';')[0]);
}
}
}
if (response.data.includes('会员登录后才能访问')) {
throw 'pianyuan Cookie已失效';
}
return response;
}
module.exports = {
ProcessFeed,
request,
};