Skip to content

Commit

Permalink
feat(route): add 18comic (DIYgod#8588)
Browse files Browse the repository at this point in the history
  • Loading branch information
Ethan Shen authored Nov 27, 2021
1 parent 02fda1c commit 4ba85ef
Show file tree
Hide file tree
Showing 9 changed files with 342 additions and 0 deletions.
67 changes: 67 additions & 0 deletions docs/anime.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,73 @@ pageClass: routes

<Route author="junfengP" example="/005tv/zx/latest" path="/005tv/zx/latest"/>

## 18comic 禁漫天堂

### 成人 A 漫

<Route author="nczitzk" example="/18comic" path="/18comic/:category?/:time?/:order?/:keyword?" :paramsDesc="['分类,见下表,默认为 `all` 即全部', '时间范围,见下表,默认为 `a` 即全部', '排列顺序,见下表,默认为 `mr` 即最新', '关键字,见下表,默认为空']">

分类

| 全部 | 其他漫畫 | 同人 | 韓漫 | 美漫 | 短篇 | 單本 |
| ---- | -------- | ------ | ------ | ------ | ----- | ------ |
| all | another | doujin | hanman | meiman | short | single |

时间范围

| 全部 | 今天 | 这周 | 本月 |
| ---- | ---- | ---- | ---- |
| a | t | w | m |

排列顺序

| 最新 | 最多点阅 | 最多图片 | 最爱 |
| ---- | -------- | -------- | ---- |
| mr | mv | mp | tf |

关键字(供参考)

| YAOI | 女性向 | NTR | 非 H | 3D | 獵奇 |
| ---- | ------ | --- | ---- | -- | ---- |

</Route>

### 搜索

<Route author="nczitzk" example="/18comic/search/photos/all/NTR" path="/18comic/search/:option?/:category?:keyword?/:time?/:order?" :paramsDesc="['选项,可选 `video` 和 `photos`,默认为 `photos`', '分类,同上表,默认为 `all` 即全部', '关键字,同上表,默认为空', '时间范围,同上表,默认为 `a` 即全部', '排列顺序,同上表,默认为 `mr` 即最新']">

::: tip 提示

关键字必须超过两个字,这是来自网站的限制。

:::

</Route>

### 专辑

<Route author="nczitzk" example="/18comic/album/292282" path="/18comic/album/:id" :paramsDesc="['专辑 id,可在专辑页 URL 中找到']">

::: tip 提示

专辑 id 不包括 URL 中标题的部分。

:::

</Route>

### 文庫

<Route author="nczitzk" example="/18comic/blogs" path="/18comic/blogs/:category?" :paramsDesc="['分类,见下表,默认为空即全部']">

分类

| 全部 | 紳夜食堂 | 遊戲文庫 | JG GAMES | 模型山下 |
| ---- | -------- | -------- | -------- | -------- |
| | dinner | raiders | jg | figure |

</Route>

## 1draw #深夜の真剣お絵描き 60 分一本勝負

### 投稿一览
Expand Down
75 changes: 75 additions & 0 deletions lib/v2/18comic/album.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
const got = require('@/utils/got');
const cheerio = require('cheerio');
const { parseDate } = require('@/utils/parse-date');

const { rootUrl } = require('./utils');

module.exports = async (ctx) => {
const id = ctx.params.id;

const currentUrl = `${rootUrl}/album/${id}`;

const response = await got({
method: 'get',
url: currentUrl,
});

const $ = cheerio.load(response.data);

const category = $('span[data-type="tags"]')
.first()
.find('a')
.toArray()
.map((c) => $(c).text());
const author = $('span[data-type="author"]')
.first()
.find('a')
.toArray()
.map((a) => $(a).text())
.join(', ');

let items = $('.btn-toolbar')
.first()
.find('a')
.toArray()
.map((item) => {
item = $(item);

return {
title: item.text(),
link: `${rootUrl}${item.attr('href')}`,
pubDate: parseDate(item.find('.hidden-xs').text()),
};
});

items = await Promise.all(
items.map((item) =>
ctx.cache.tryGet(item.link, async () => {
const detailResponse = await got({
method: 'get',
url: item.link,
});

const content = cheerio.load(detailResponse.data);

content('.tab-content').remove();

item.author = author;
item.category = category;
item.description = `<img src="${content('.thumb-overlay-albums img[data-original]')
.toArray()
.map((image) => content(image).attr('data-original'))
.join('"><img src="')}">`;

return item;
})
)
);

ctx.state.data = {
title: $('title').text(),
link: currentUrl,
item: items,
description: $('meta[property="og:description"]').attr('content'),
};
};
61 changes: 61 additions & 0 deletions lib/v2/18comic/blogs.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
const got = require('@/utils/got');
const cheerio = require('cheerio');
const { parseDate } = require('@/utils/parse-date');

const { rootUrl } = require('./utils');

module.exports = async (ctx) => {
const category = ctx.params.category ?? '';

const currentUrl = `${rootUrl}/blogs${category ? `/${category}` : ''}`;

const response = await got({
method: 'get',
url: currentUrl,
});

const $ = cheerio.load(response.data);

let items = $('.title')
.toArray()
.map((item) => {
item = $(item);

return {
title: item.text(),
link: `${rootUrl}${item.parent().attr('href')}`,
};
});

items = await Promise.all(
items.map((item) =>
ctx.cache.tryGet(item.link, async () => {
const detailResponse = await got({
method: 'get',
url: item.link,
});

const content = cheerio.load(detailResponse.data);

item.pubDate = parseDate(content('.date').first().text());

content('.d-flex').remove();

item.author = content('.blog_name_id').first().text();
item.description = content('.blog_content').html();
item.category = content('.panel-heading dropdown-toggle')
.toArray()
.map((c) => $(c).text());

return item;
})
)
);

ctx.state.data = {
title: $('title').text().replace(/最新的/, $('.article-nav .active').text()),
link: currentUrl,
item: items,
description: $('meta[property="og:description"]').attr('content'),
};
};
12 changes: 12 additions & 0 deletions lib/v2/18comic/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
const { rootUrl, ProcessItems } = require('./utils');

module.exports = async (ctx) => {
const category = ctx.params.category ?? 'all';
const keyword = ctx.params.keyword ?? '';
const time = ctx.params.time ?? 'a';
const order = ctx.params.order ?? 'mr';

const currentUrl = `${rootUrl}/albums${category !== 'all' ? `/${category}` : ''}${keyword ? `?screen=${keyword}` : '?'}${time !== 'a' ? `&t=${time}` : ''}${order !== 'mr' ? `&o=${order}` : ''}`;

ctx.state.data = await ProcessItems(ctx, currentUrl);
};
6 changes: 6 additions & 0 deletions lib/v2/18comic/maintainer.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
module.exports = {
'/album/:id': ['nczitzk'],
'/blogs/:category?': ['nczitzk'],
'/search/:option?/:category?/:time?/:order?/:keyword?': ['nczitzk'],
'/:category?/:time?/:order?/:keyword?': ['nczitzk'],
};
31 changes: 31 additions & 0 deletions lib/v2/18comic/radar.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
module.exports = {
'18comic.org': {
_name: '18comic 禁漫天堂',
'.': [
{
title: '成人 A 漫',
docs: 'https://docs.rsshub.app/anime.html#18comic-jin-man-tian-tang-cheng-ren-a-man',
source: ['/'],
target: '/18comic/:category?/:time?/:order?/:keyword?',
},
{
title: '搜索',
docs: 'https://docs.rsshub.app/anime.html#18comic-jin-man-tian-tang-sou-suo',
source: ['/'],
target: '/18comic/search/:option?/:category?:keyword?/:time?/:order?',
},
{
title: '专辑',
docs: 'https://docs.rsshub.app/anime.html#18comic-jin-man-tian-tang-zhuan-ji',
source: ['/'],
target: '/18comic/album/:id',
},
{
title: '文庫',
docs: 'https://docs.rsshub.app/anime.html#18comic-jin-man-tian-tang-wen-ku',
source: ['/'],
target: '/18comic/blogs/:category?',
},
],
},
};
6 changes: 6 additions & 0 deletions lib/v2/18comic/router.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
module.exports = function (router) {
router.get('/album/:id', require('./album'));
router.get('/blogs/:category?', require('./blogs'));
router.get('/search/:option?/:category?/:keyword?/:time?/:order?', require('./search'));
router.get('/:category?/:time?/:order?/:keyword?', require('./index'));
};
13 changes: 13 additions & 0 deletions lib/v2/18comic/search.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
const { rootUrl, ProcessItems } = require('./utils');

module.exports = async (ctx) => {
const option = ctx.params.option ?? 'photos';
const category = ctx.params.category ?? 'all';
const keyword = ctx.params.keyword ?? '';
const time = ctx.params.time ?? 'a';
const order = ctx.params.order ?? 'mr';

const currentUrl = `${rootUrl}/search/${option}${category !== 'all' ? `/${category}` : ''}${keyword ? `?search_query=${keyword}` : '?'}${time !== 'a' ? `&t=${time}` : ''}${order !== 'mr' ? `&o=${order}` : ''}`;

ctx.state.data = await ProcessItems(ctx, currentUrl);
};
71 changes: 71 additions & 0 deletions lib/v2/18comic/utils.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
const got = require('@/utils/got');
const cheerio = require('cheerio');
const { parseDate } = require('@/utils/parse-date');

const rootUrl = 'https://18comic.org';

module.exports = {
rootUrl,
ProcessItems: async (ctx, currentUrl) => {
currentUrl = currentUrl.replace(/\?$/, '');

const response = await got({
method: 'get',
url: currentUrl,
});

const $ = cheerio.load(response.data);

let items = $('.video-title')
.slice(0, ctx.query.limit ? parseInt(ctx.query.limit) : 20)
.toArray()
.map((item) => {
item = $(item);

return {
title: item.text().trim(),
link: `${rootUrl}${item.prev().prev().attr('href')}`,
};
});

items = await Promise.all(
items.map((item) =>
ctx.cache.tryGet(item.link, async () => {
const detailResponse = await got({
method: 'get',
url: item.link,
});

const content = cheerio.load(detailResponse.data);

item.pubDate = parseDate(content('div[itemprop="datePublished"]').first().attr('content'));
item.category = content('span[data-type="tags"]')
.first()
.find('a')
.toArray()
.map((c) => $(c).text());
item.author = content('span[data-type="author"]')
.first()
.find('a')
.toArray()
.map((a) => $(a).text())
.join(', ');
item.description = `<p>${content('#intro-block .p-t-5').text()}</p><img src="${content('.img_zoom_img img')
.toArray()
.map((image) => content(image).attr('src'))
.join('"><img src="')}">`;

return item;
})
)
);

return {
title: $('title').text(),
link: currentUrl,
item: items,
description: $('meta[property="og:description"]').attr('content'),
allowEmpty: true,
};
},
};

0 comments on commit 4ba85ef

Please sign in to comment.