feat: add JavDB (#5739)

Co-authored-by: Henry Wang <hi@henry.wang>
This commit is contained in:
Ethan Shen 2020-09-26 22:26:00 +08:00 committed by GitHub
parent 8ac38d18ea
commit aeeaf1c279
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 332 additions and 0 deletions

View File

@ -131,6 +131,116 @@ pageClass: routes
<Route author="MegrezZhu CoderTonyChan Felix2yu" example="/javbus/western/series/20" path="/javbus/western/series/:seriesid" :paramsDesc="['系列id详见作品中系列的链接']" />
## JavDB
### 主页
<Route author="nczitzk" example="/javdb/home" path="/javdb/home/:caty?/:sort?/:filter?" :paramsDesc="['分类,见下表,默认为 `有碼`', '排序,见下表,默认为 `磁鏈更新排序`', '过滤,见下表,默认为 `可下载`']">
分类
| 有碼 | 無碼 | 歐美 | FC2 |
| -------- | ---------- | ------- | --- |
| censored | uncensored | western | fc2 |
排序
| 发布日期排序 | 磁鏈更新排序 |
| ------------ | ------------ |
| 1 | 2 |
过滤
| 全部 | 可下载 | 含字幕 | 含短評 |
| ---- | ------ | ------ | ------ |
| 0 | 1 | 2 | 3 |
</Route>
### 分類
<Route author="nczitzk" example="/javdb/tags/c2=5&c10=1" path="/javdb/tags/:query?/:caty?" :paramsDesc="['筛选,默认为 `c10=1`', '分类,见下表,默认为 `有碼`']">
::: tip 提示
在 [分類](https://javdb.com/tags) 中选定分类后URL 中 `tags?` 后的字段即为筛选参数。
<https://javdb.com/tags?c2=5&c10=1>`c2=5&c10=1` 为筛选参数。
:::
分类
| 有碼 | 無碼 | 歐美 | FC2 |
| -------- | ---------- | ------- | --- |
| censored | uncensored | western | fc2 |
</Route>
### 排行榜
<Route author="nczitzk" example="/javdb/rankings" path="/javdb/rankings/:caty?/:time?" :paramsDesc="['分类,见下表,默认为 `有碼`', '时间,见下表,默认为 `日榜`']">
分类
| 有碼 | 無碼 | 歐美 | FC2 |
| -------- | ---------- | ------- | --- |
| censored | uncensored | western | fc2 |
时间
| 日榜 | 週榜 | 月榜 |
| ----- | ------ | ------- |
| daily | weekly | monthly |
</Route>
### 搜索
<Route author="nczitzk" example="/javdb/search/巨乳" path="/javdb/search/:keyword?/:filter?" :paramsDesc="['关键字,默认为空', '过滤,见下表,默认为 `可播放`']">
| 全部 | 可播放 | 單體作品 | 演員 | 片商 | 導演 | 系列 | 番號 | 可下載 | 字幕 | 預覽圖 |
| ---- | -------- | -------- | ----- | ----- | -------- | ------ | ---- | -------- | ----- | ------- |
| | playable | single | actor | maker | director | series | code | download | cnsub | preview |
</Route>
### 演員
<Route author="nczitzk" example="/javdb/actors/R2Vg" path="/javdb/actors/:id/:filter?" :paramsDesc="['编号,可在演员页 URL 中找到', '过滤,见下表,默认为 `全部`']">
| 全部 | 可播放 | 單體作品 | 可下載 | 含字幕 |
| ---- | ------ | -------- | ------ | ------ |
| | p | s | d | c |
所有演员编号参见 [演員庫](https://javdb.com/actors)
</Route>
### 系列
<Route author="nczitzk" example="/javdb/series/1NW" path="/javdb/series/:id/:filter?" :paramsDesc="['编号,可在系列页 URL 中找到', '过滤,见下表,默认为 `全部`']">
| 全部 | 可播放 | 單體作品 | 可下載 | 字幕 | 預覽圖 |
| ---- | -------- | -------- | -------- | ----- | ------- |
| | playable | single | download | cnsub | preview |
所有系列编号参见 [系列庫](https://javdb.com/series)
</Route>
### 片商
<Route author="nczitzk" example="/javdb/makers/7R" path="/javdb/makers/:id/:filter?" :paramsDesc="['编号,可在片商页 URL 中找到', '过滤,见下表,默认为 `全部`']">
| 全部 | 可播放 | 單體作品 | 可下載 | 字幕 | 預覽圖 |
| ---- | -------- | -------- | -------- | ----- | ------- |
| | playable | single | download | cnsub | preview |
所有片商编号参见 [片商庫](https://javdb.com/makers)
</Route>
## JavLibrary
### 影片

View File

@ -3241,6 +3241,15 @@ router.get('/appsales/:caty?/:time?', require('./routes/appsales/index'));
// CGTN
router.get('/cgtn/top', require('./routes/cgtn/top'));
// JavDB
router.get('/javdb/home/:caty?/:sort?/:filter?', require('./routes/javdb/home'));
router.get('/javdb/search/:keyword?/:filter?', require('./routes/javdb/search'));
router.get('/javdb/tags/:query?/:caty?', require('./routes/javdb/tags'));
router.get('/javdb/actors/:id/:filter?', require('./routes/javdb/actors'));
router.get('/javdb/makers/:id/:filter?', require('./routes/javdb/makers'));
router.get('/javdb/series/:id/:filter?', require('./routes/javdb/series'));
router.get('/javdb/rankings/:caty?/:time?', require('./routes/javdb/rankings'));
// World Economic Forum
router.get('/weforum/report/:lang?/:year?/:platform?', require('./routes/weforum/report'));

View File

@ -0,0 +1,19 @@
const utils = require('./utils');
module.exports = async (ctx) => {
ctx.params.filter = ctx.params.filter || '';
const currentUrl = `${utils.rootUrl}/actors/${ctx.params.id}?t=${ctx.params.filter}`;
const filter = {
'': '',
p: '可播放',
s: '單體作品',
d: '可下載',
c: '含字幕',
};
const title = `JavDB${filter[ctx.params.filter] === '' ? '' : ` - ${filter[ctx.params.filter]}`} `;
ctx.state.data = await utils.ProcessItems(ctx, currentUrl, title);
};

32
lib/routes/javdb/home.js Normal file
View File

@ -0,0 +1,32 @@
const utils = require('./utils');
module.exports = async (ctx) => {
ctx.params.caty = ctx.params.caty || 'censored';
ctx.params.sort = ctx.params.sort || '2';
ctx.params.filter = ctx.params.filter || '1';
const currentUrl = `${utils.rootUrl}/${ctx.params.caty === 'censored' ? '' : ctx.params.caty}?vft=${ctx.params.filter}&vst=${ctx.params.sort}`;
const category = {
censored: '有碼',
uncensored: '無碼',
western: '歐美',
fc2: 'FC2',
};
const filter = {
0: '',
1: '可下载',
2: '含字幕',
3: '含短評',
};
const sort = {
1: '发布日期排序',
2: '磁鏈更新排序',
};
const title = `${category[ctx.params.caty]} - JavDB - ${filter[ctx.params.filter] === '' ? '|' : `${filter[ctx.params.filter]} | `}${sort[ctx.params.sort]}`;
ctx.state.data = await utils.ProcessItems(ctx, currentUrl, title);
};

View File

@ -0,0 +1,20 @@
const utils = require('./utils');
module.exports = async (ctx) => {
ctx.params.filter = ctx.params.filter || '';
const currentUrl = `${utils.rootUrl}/makers/${ctx.params.id}?f=${ctx.params.filter}`;
const filter = {
'': '',
playable: '可播放',
single: '單體作品',
download: '可下載',
cnsub: '字幕',
preview: '預覽圖',
};
const title = `JavDB${filter[ctx.params.filter] === '' ? '' : ` - ${filter[ctx.params.filter]}`} `;
ctx.state.data = await utils.ProcessItems(ctx, currentUrl, title);
};

View File

@ -0,0 +1,12 @@
const utils = require('./utils');
module.exports = async (ctx) => {
ctx.params.caty = ctx.params.caty || 'censored';
ctx.params.time = ctx.params.time || 'daily';
const currentUrl = `${utils.rootUrl}/rankings/video_${ctx.params.caty}?period=${ctx.params.time}`;
const title = 'JavDB';
ctx.state.data = await utils.ProcessItems(ctx, currentUrl, title);
};

View File

@ -0,0 +1,26 @@
const utils = require('./utils');
module.exports = async (ctx) => {
ctx.params.filter = ctx.params.filter || '';
ctx.params.keyword = ctx.params.keyword || '';
const currentUrl = `${utils.rootUrl}/search?q=${ctx.params.keyword}&f=${ctx.params.filter}`;
const filter = {
'': '',
playable: '可播放',
single: '單體作品',
actor: '演員',
maker: '片商',
director: '導演',
series: '系列',
code: '番號',
download: '可下載',
cnsub: '字幕',
preview: '預覽圖',
};
const title = `關鍵字 ${ctx.params.keyword} ${filter[ctx.params.filter] === '' ? '' : `+ ${filter[ctx.params.filter]}`} 搜索結果 - JavDB `;
ctx.state.data = await utils.ProcessItems(ctx, currentUrl, title);
};

View File

@ -0,0 +1,20 @@
const utils = require('./utils');
module.exports = async (ctx) => {
ctx.params.filter = ctx.params.filter || '';
const currentUrl = `${utils.rootUrl}/series/${ctx.params.id}?f=${ctx.params.filter}`;
const filter = {
'': '',
playable: '可播放',
single: '單體作品',
download: '可下載',
cnsub: '字幕',
preview: '預覽圖',
};
const title = `JavDB${filter[ctx.params.filter] === '' ? '' : ` - ${filter[ctx.params.filter]}`} `;
ctx.state.data = await utils.ProcessItems(ctx, currentUrl, title);
};

12
lib/routes/javdb/tags.js Normal file
View File

@ -0,0 +1,12 @@
const utils = require('./utils');
module.exports = async (ctx) => {
ctx.params.caty = ctx.params.caty || 'censored';
ctx.params.query = ctx.params.query || '';
const currentUrl = `${utils.rootUrl}/tags${ctx.params.caty === 'censored' ? '' : `/${ctx.params.caty}`}?${ctx.params.query}`;
const title = `JavDB${ctx.params.query === '' ? '' : ` - ${ctx.params.query}`} `;
ctx.state.data = await utils.ProcessItems(ctx, currentUrl, title);
};

72
lib/routes/javdb/utils.js Normal file
View File

@ -0,0 +1,72 @@
const got = require('@/utils/got');
const cheerio = require('cheerio');
const rootUrl = 'https://javdb.com';
module.exports = {
rootUrl: rootUrl,
ProcessItems: async (ctx, currentUrl, title) => {
const response = await got({
method: 'get',
url: currentUrl,
});
const $ = cheerio.load(response.data);
$('.tags').remove();
const list = $('.grid-item a')
.slice(0, 5)
.map((_, item) => {
item = $(item);
return {
title: item.text(),
link: `${rootUrl}${item.attr('href')}`,
pubDate: new Date(item.find('.meta').text()).toUTCString(),
};
})
.get();
const items = await Promise.all(
list.map(
async (item) =>
await ctx.cache.tryGet(item.link, async () => {
const detailResponse = await got({
method: 'get',
url: item.link,
});
const content = cheerio.load(detailResponse.data);
item.enclosure_url = content('#magnets-content button[data-clipboard-text]').eq(0).attr('data-clipboard-text');
item.enclosure_type = 'application/x-bittorrent';
content('icon, .review-buttons, .copy-to-clipboard').remove();
content('#modal-review-watched, #modal-save-list').remove();
content('.video-cover').eq(1).remove();
content('img.video-cover').attr('src', content(this).parent().attr('href'));
content('.preview-images img').each(function () {
content(this).removeAttr('data-src');
content(this).attr('src', content(this).parent().attr('href'));
});
content('#preview-video').css('display', 'block');
item.description = content('.movie-info-panel .columns').html() + content('#magnets-content').html() + content('.preview-images').html();
return item;
})
)
);
const htmlTitle = $('title').text();
const subject = htmlTitle.indexOf('|') === -1 ? '' : htmlTitle.split('|')[0];
return {
title: subject === '' ? title : `${subject} - ${title}`,
link: currentUrl,
item: items,
};
},
};