feat(route): add domp4 影视 (#9966)

* feat: domp4 最近更新+详情订阅

* fix: docs && radar

* docs: add radar support

* fix: detail remove puppeteer use

* fix: domp4 add meta info

* fix: feed link

Co-authored-by: jasehuang <jasehuang@tencent.com>
This commit is contained in:
savokiss 2022-06-17 22:53:01 +08:00 committed by GitHub
parent 1fcb5379df
commit 07c9c80ca5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 217 additions and 0 deletions

View File

@ -404,6 +404,20 @@ BT 之家的域名会变更,本路由以 <https://www.btbtt20.com> 为默认
<Route author="nczitzk" example="/coomer/posts" path="/coomer/posts"/>
## DoMP4 影视
### 最近更新
<Route author="savokiss" example="/domp4/latest/vod" path="/domp4/latest/:type?" :paramsDesc="['`vod` 代表电影,`tv` 代表电视剧,默认 vod']" radar="1"/>
### 剧集订阅
<Route author="savokiss" example="/domp4/detail/LBTANI22222I" path="/domp4/detail/:id" :paramsDesc="['从剧集详情页 URL 处获取,如:`https://www.domp4.cc/html/LBTANI22222I.html`,取 `.html` 前面部分']" radar="1" supportBT="1"/>
:::tip
由于大部分详情页是 `/html/xxx.html`,还有部分是 `/detail/123.html`所以此处做了兼容id 取 `xxx` 或者 `123` 都可以。
:::
## E-Hentai
### 分类

67
lib/v2/domp4/detail.js Normal file
View File

@ -0,0 +1,67 @@
const cheerio = require('cheerio');
const got = require('@/utils/got');
const { decodeCipherText, composeMagnetUrl } = require('./utils');
const baseUrl = 'https://www.domp4.cc';
function getItemList($, detailUrl) {
const encoded = $('.article script[type]')
.text()
.match(/return p}\('(.*)',(\d+),(\d+),'(.*)'.split\(/);
const data = JSON.parse(
decodeCipherText(encoded[1], encoded[2], encoded[3], encoded[4].split('|'), 0, {})
.match(/var down_urls=\\'(.*)\\'/)[1]
.replace(/\\\\"/g, '"')
.replace(/\\\\\\/g, '')
);
const { downurls } = data.Data[0];
return downurls.map((item) => {
const [title, magnet] = item.split('$');
return {
enclosure_url: composeMagnetUrl(magnet),
enclosure_length: '',
enclosure_type: 'application/x-bittorrent',
title,
link: detailUrl,
};
});
}
function getMetaInfo($) {
const title = $('.article-header .text p').first().find('span').text();
const cover = $('.article-header .pic img').attr('src');
const description = $('.article-related.info p').text();
return {
title,
cover,
description,
};
}
module.exports = async (ctx) => {
const { id } = ctx.params;
let pureId = id;
let detailType = 'html';
// compatible for .html suffix in radar
if (id.endsWith('.html')) {
pureId = id.replace('.html', '');
}
// compatible for /detail/123.html && /html/xxx.html
if (/^\d+$/.test(pureId)) {
detailType = 'detail';
}
const detailUrl = `${baseUrl}/${detailType}/${pureId}.html`;
const res = await got(detailUrl);
const $ = cheerio.load(res.data);
const list = getItemList($, detailUrl);
const meta = getMetaInfo($);
ctx.state.data = {
link: detailUrl,
title: meta.title || 'domp4电影 - 详情',
image: meta.cover,
description: meta.description,
item: list,
};
};

31
lib/v2/domp4/latest.js Normal file
View File

@ -0,0 +1,31 @@
const got = require('@/utils/got');
const cheerio = require('cheerio');
const baseUrl = 'https://www.domp4.cc';
const latestUrl = 'https://www.domp4.cc/custom/update.html';
function getItemList($, type) {
const list = $(`#${type} .list-group-item`)
.toArray()
.map((item) => {
item = $(item);
return {
title: item.find('a').text(),
link: `${baseUrl}${item.find('a').attr('href')}`,
};
});
return list;
}
module.exports = async (ctx) => {
const { type = 'vod' } = ctx.params;
const res = await got.get(latestUrl);
const $ = cheerio.load(res.data);
const list = getItemList($, type);
ctx.state.data = {
link: latestUrl,
title: 'domp4电影',
item: list,
};
};

View File

@ -0,0 +1,4 @@
module.exports = {
'/detail/:id': ['savokiss'],
'/latest/:type?': ['savokiss'],
};

25
lib/v2/domp4/radar.js Normal file
View File

@ -0,0 +1,25 @@
module.exports = {
'domp4.cc': {
_name: 'domp4电影',
'.': [
{
title: '最近更新',
docs: 'https://docs.rsshub.app/multimedia.html#domp4-ying-shi',
source: ['/', '/custom/update.html'],
target: '/domp4/latest/:type?',
},
{
title: '剧集订阅',
docs: 'https://docs.rsshub.app/multimedia.html#domp4-ying-shi',
source: '/html/:id',
target: '/domp4/detail/:id',
},
{
title: '剧集订阅',
docs: 'https://docs.rsshub.app/multimedia.html#domp4-ying-shi',
source: '/detail/:id',
target: '/domp4/detail/:id',
},
],
},
};

4
lib/v2/domp4/router.js Normal file
View File

@ -0,0 +1,4 @@
module.exports = function (router) {
router.get('/detail/:id', require('./detail'));
router.get('/latest/:type?', require('./latest'));
};

72
lib/v2/domp4/utils.js Normal file
View File

@ -0,0 +1,72 @@
/**
* trackers from https://www.domp4.cc/Style/2020/js/base.js?v=2
*/
const magnetTrackers = [
'https://tracker.iriseden.fr:443/announce',
'https://tr.highstar.shop:443/announce',
'https://tr.fuckbitcoin.xyz:443/announce',
'https://tr.doogh.club:443/announce',
'https://tr.burnabyhighstar.com:443/announce',
'https://t.btcland.xyz:443/announce',
'http://vps02.net.orel.ru:80/announce',
'https://tracker.kuroy.me:443/announce',
'http://tr.cili001.com:8070/announce',
'http://t.overflow.biz:6969/announce',
'http://t.nyaatracker.com:80/announce',
'http://open.acgnxtracker.com:80/announce',
'http://nyaa.tracker.wf:7777/announce',
'http://home.yxgz.vip:6969/announce',
'http://buny.uk:6969/announce',
'https://tracker.tamersunion.org:443/announce',
'https://tracker.nanoha.org:443/announce',
'https://tracker.loligirl.cn:443/announce',
'udp://bubu.mapfactor.com:6969/announce',
'http://share.camoe.cn:8080/announce',
'udp://movies.zsw.ca:6969/announce',
'udp://ipv4.tracker.harry.lu:80/announce',
'udp://tracker.sylphix.com:6969/announce',
'http://95.216.22.207:9001/announce',
];
/**
* compose magnet url with trackers
*/
function composeMagnetUrl(magnet, trackers = magnetTrackers) {
return `${magnet}&tr=${trackers.join('&tr=')}`;
}
/**
* method for generating magnet url
* from the detail page source
*/
function decodeCipherText(p, a, c, k, e, d) {
e = function (c) {
return (c < a ? '' : e(parseInt(c / a))) + ((c = c % a) > 35 ? String.fromCharCode(c + 29) : c.toString(36));
};
if (!''.replace(/^/, String)) {
while (c--) {
d[e(c)] = k[c] || e(c);
}
k = [
function (e) {
return d[e];
},
];
e = function () {
return '\\w+';
};
c = 1;
}
while (c--) {
if (k[c]) {
p = p.replace(new RegExp('\\b' + e(c) + '\\b', 'g'), k[c]);
}
}
return p;
}
module.exports = {
magnetTrackers,
composeMagnetUrl,
decodeCipherText,
};