feat(route): add oreno3d.com - 俺の3Dエロ動画 (#10458)

* feat(route): add oreno3d.com - 俺の3Dエロ動画

* Update docs/anime.md

Co-authored-by: Tony <TonyRL@users.noreply.github.com>

* Update docs/anime.md

Co-authored-by: Tony <TonyRL@users.noreply.github.com>

* Update lib/v2/oreno3d/radar.js

Co-authored-by: Tony <TonyRL@users.noreply.github.com>

* Update lib/v2/oreno3d/maintainer.js

Co-authored-by: Tony <TonyRL@users.noreply.github.com>

* Update docs/anime.md

Co-authored-by: Tony <TonyRL@users.noreply.github.com>

* Update lib/v2/oreno3d/authors.js

Co-authored-by: Tony <TonyRL@users.noreply.github.com>

* Update lib/v2/oreno3d/get_sec_page_data.js

Co-authored-by: Tony <TonyRL@users.noreply.github.com>

* Update lib/v2/oreno3d/router.js

Co-authored-by: Tony <TonyRL@users.noreply.github.com>

* Update lib/v2/oreno3d/authors.js

Co-authored-by: Tony <TonyRL@users.noreply.github.com>

* Update lib/v2/oreno3d/authors.js

Co-authored-by: Tony <TonyRL@users.noreply.github.com>

* refactor🎨: sortName and linkable

* refactor🎨:  en docs,category and yarn

* fix🐛:  fix docs bugs

* fix🐛:  fix radar bugs

* docs📝:  addTipsInEnDocs

* docs📝:  fix docs bug

* docs📝:  fix docs bug

* Update lib/v2/oreno3d/characters.js

Co-authored-by: Tony <TonyRL@users.noreply.github.com>

* Update lib/v2/oreno3d/origins.js

Co-authored-by: Tony <TonyRL@users.noreply.github.com>

* Update lib/v2/oreno3d/search.js

Co-authored-by: Tony <TonyRL@users.noreply.github.com>

* Update lib/v2/oreno3d/tags.js

Co-authored-by: Tony <TonyRL@users.noreply.github.com>

* Update docs/en/anime.md

Co-authored-by: Tony <TonyRL@users.noreply.github.com>

* perf👌:  combine to a single file/fix maintainer

* fix🐛:  fix main.js bugs

* fix: docs and radar

* fix: caching
This commit is contained in:
xueli-sherryli
2022-08-15 19:35:27 +08:00
committed by GitHub
co-authored by Tony
parent ef670174ba
commit 0fbec30a0f
8 changed files with 310 additions and 0 deletions
+34
View File
@@ -399,6 +399,40 @@ Sources
<Route author="Ye11" example="/xmanhua" path="/xmanhua/:uid" :paramsDesc="['漫画 id,在浏览器中可见,例如鬼灭之刃对应的 id 为 `73xm`']"/>
## 俺の 3D エロ動画 (oreno3d)
::: tip 提示
可配合其他 RSS 解析库 (如`Python`的`feedparser`库) 实现视频的更新检测以及自动下载
:::
### 关键词搜索
<Route author="xueli-sherryli" example="/oreno3d/search/bronya/latest" path="/oreno3d/search/:keyword/:sort?" :paramsDesc="['关键词', '排序方法,见下表,默认为 `latest`']">
| 高評価 | 急上昇 | 新着 | 人気 |
| --------- | --- | ------ | ---------- |
| favorites | hot | latest | popularity |
</Route>
### 角色搜索
<Route author="xueli-sherryli" example="/oreno3d/characters/283/latest" path="/oreno3d/characters/:characterid/:sort?" :paramsDesc="['角色 id,可在浏览器地址栏找到', '排序方法,见上表,默认为 `latest`']" />
### 作者搜索
<Route author="xueli-sherryli" example="/oreno3d/authors/3189/latest" path="/oreno3d/authors/:authorid/:sort?" :paramsDesc="['作者 id,可在浏览器地址栏找到', '排序方法,见上表,默认为 `latest`']" />
### 标签搜索
<Route author="xueli-sherryli" example="/oreno3d/tags/177/latest" path="/oreno3d/tags/:tagid/:sort?" :paramsDesc="['标签 id,可在浏览器地址栏找到', '排序方法,见上表,默认为 `latest`']" />
### 原作搜索
<Route author="xueli-sherryli" example="/oreno3d/origins/3/latest" path="/oreno3d/origins/:originid/:sort?" :paramsDesc="['原作 id,可在浏览器地址栏找到', '排序方法,见上表,默认为 `latest`']" />
## 包子漫画
#### 订阅漫画
+34
View File
@@ -105,3 +105,37 @@ For example: <https://www.webtoons.com/zh-hant/drama/gongzhuweimian/list?title_n
### [Naver](https://comic.naver.com)
<RouteEn author="zfanta" example="/webtoons/naver/651673" path="/webtoons/naver/:titleId" :paramsDesc="['titleId of naver webtoon']" />
## 俺の3Dエロ動画(oreno3d)
::: tip Tip
You can use some RSS parsing libraries (like `feedpraser` in `Python`) to receive the video update messages and download them automatically
:::
### Keyword Search
<RouteEn author="xueli-sherryli" example="/oreno3d/search/bronya/latest" path="/oreno3d/search/:keyword/:sort?" :paramsDesc="['Search keyword', 'Sort method, see the table below, `latest` by default']" radar="1" rssbud="1">
| favorites | hot | latest | popularity |
| --------- | ------ | ------ | ---------- |
| favorites | hot | latest | popularity |
</RouteEn>
### Character Search
<RouteEn author="xueli-sherryli" example="/oreno3d/characters/283/latest" path="/oreno3d/characters/:characterid/:sort?" :paramsDesc="['Character id, can be found in URL' , 'Sort method, see the table above, `latest` by default']" radar="1" rssbud="1"/>
### Author Search
<RouteEn author="xueli-sherryli" example="/oreno3d/authors/3189/latest" path="/oreno3d/authors/:authorid/:sort?" :paramsDesc="['Author id, can be found in URL' , 'Sort method, see the table above, `latest` by default']" radar="1" rssbud="1"/>
### Tags Search
<RouteEn tag="xueli-sherryli" example="/oreno3d/tags/177/latest" path="/oreno3d/tags/:tagid/:sort?" :paramsDesc="['Tag id, can be found in URL', 'Sort method, see the table above, `latest` by default']" radar="1" rssbud="1"/>
### Origins Search
<RouteEn origin="xueli-sherryli" example="/oreno3d/origins/3/latest" path="/oreno3d/origins/:originid/:sort?" :paramsDesc="['Origin id, can be found in URL' , 'Sort method, see the table above, `latest` by default']" radar="1" rssbud="1"/>
+69
View File
@@ -0,0 +1,69 @@
const got = require('@/utils/got');
const cheerio = require('cheerio');
const rootUrl = 'https://oreno3d.com';
async function sync_detail(link) {
// 主选择器
const sec_page_selector = "article.g-main-video-article";
// 分条选择器
const raw_pic_selector = "header > figure.video-figure > a ";
const video_name_selector = "header > h1.video-h1 ";
const author_selector = "section:nth-child(4) > a > div.video-center";
const origins_selector = "section:nth-child(5) > a > div.video-center";
const characters_selector = "section:nth-child(6) > a > div.video-center";
const tags_selector = "section:nth-child(7) > ul > li > a div.tag-text";// 未修复
const desc_selector = "section blockquote.video-information-comment";
const iwara_link_selector = "header > figure.video-figure > a";
// 下载
const response = await got(link);
const $ = cheerio.load(response.data);
// 创建列表
const tags = [];
const authors = [];
const origins = [];
const characters = [];
// 筛选
const raw_pic_link = rootUrl + $(raw_pic_selector).find('img').attr('src');
const video_name = $(video_name_selector).text();
// 存为列表
$(sec_page_selector).find(author_selector).each(function(i) {
authors[i] = $(this).text();
authors[i].replace(" ", "");// 去空格
authors[i].trim();// 去首尾空格
});
$(sec_page_selector).find(origins_selector).each(function(i) {
origins[i] = $(this).text();
origins[i].replace(" ", "");
origins[i].trim();
});
$(sec_page_selector).find(characters_selector).each(function(i) {
characters[i] = $(this).text();
characters[i].replace(" ", "");
characters[i].trim();
});
$(sec_page_selector).find(tags_selector).each(function(i) {
tags[i] = $(this).text();
tags[i].replace(" ", "");
tags[i].trim();
});
// 筛选
const desc = $(sec_page_selector).find(desc_selector).text();
const iwara_link = $(iwara_link_selector).attr('href');
// 打包
return {
raw_pic_link,
video_name,
authors:authors.join(" "),
origins:origins.join(" "),
characters:characters.join(" "),
tags:tags.join(" "),
desc,
iwara_link,
oreno3d_link:link
};
}
module.exports = sync_detail;
+94
View File
@@ -0,0 +1,94 @@
const got = require('@/utils/got');
const { art } = require('@/utils/render');
const path = require('path');
const cheerio = require('cheerio');
const get_sec_page_data = require('./get_sec_page_data');
const rootUrl = 'https://oreno3d.com';
const sortRename = {
favorites: '高評価',
hot: '急上昇',
latest: '新着',
popularity: '人気',
};
function get_user_url(rootUrl, ctx, sort) {
let userUrl = '';
// 判断userurl获取位置
if (ctx.params.keyword) {
const keyword = ctx.params.keyword;
userUrl = `${rootUrl}/search?sort=${sort}&keyword=${keyword}`;
} else if (ctx.params.characterid) {
const characterid = ctx.params.characterid;
userUrl = `${rootUrl}/characters/${characterid}?sort=${sort}`;
} else if (ctx.params.authorid) {
const authorid = ctx.params.authorid;
userUrl = `${rootUrl}/authors/${authorid}?sort=${sort}`;
} else if (ctx.params.tagid) {
const tagid = ctx.params.tagid;
userUrl = `${rootUrl}/tags/${tagid}?sort=${sort}`;
} else if (ctx.params.originid) {
const originid = ctx.params.originid;
userUrl = `${rootUrl}/origins/${originid}?sort=${sort}`;
}
return userUrl;
}
const selector = 'a.box';
module.exports = async (ctx) => {
// 下载
const sort = ctx.params.sort ?? 'latest';
const userUrl = get_user_url(rootUrl, ctx, sort);
const response = await got(userUrl);
const $ = cheerio.load(response.data);
// 第一页,获取搜索主标题
const title = $('div.g-main-list').find('h1.main-h').text(); // 搜索标题;//第二页跳转链接
const list = $(selector);
const items = await Promise.all(
list
.map((_, item) => {
// 第一页,获取搜各视频地址
const link = $(item).attr('href');
return ctx.cache.tryGet(link, async () => {
// 第二页数据分析
const sec_data = await get_sec_page_data(link);
// 传递
const raw_pic_link = sec_data.raw_pic_link;
const video_name = sec_data.video_name;
const authors = sec_data.authors;
const origins = sec_data.origins;
const characters = sec_data.characters;
const tags = sec_data.tags;
const desc = sec_data.desc;
const iwara_link = sec_data.iwara_link;
const oreno3d_link = sec_data.oreno3d_link;
// 打包
return {
title: `${video_name} - ${authors}`,
author: authors,
link: oreno3d_link,
category: tags.split(' '),
description: art(path.join(__dirname, 'templates/description.art'), {
raw_pic_link,
video_name,
authors,
origins,
characters,
tags,
desc,
iwara_link,
oreno3d_link,
}),
};
});
})
.get()
);
ctx.state.data = {
title: `${title} - ${sortRename[sort]}`,
link: userUrl,
item: items,
};
};
+7
View File
@@ -0,0 +1,7 @@
module.exports = {
'/authors/:authorid/:sort?': ['xueli_sherryli'],
'/characters/:characterid/:sort?': ['xueli_sherryli'],
'/origins/:originid/:sort?': ['xueli_sherryli'],
'/search/:keyword/:sort?': ['xueli_sherryli'],
'/tags/:tagid/:sort?': ['xueli_sherryli'],
};
+52
View File
@@ -0,0 +1,52 @@
module.exports = {
'oreno3d.com': {
_name: '俺の3Dエロ動画',
'.': [
{
title: '关键词搜索',
docs: 'https://docs.rsshub.app/anime.htm#an-の3dエロ-dong-hua-oreno3d-guan-jian-ci-sou-suo',
source: ['/search'],
target: (_params, url) => {
const searchParams = new URL(url).searchParams;
return `/oreno3d/search/${searchParams.get('keyword')}${searchParams.has('sort') ? '/' + searchParams.get('sort') : ''}`;
},
},
{
title: '角色搜索',
docs: 'https://docs.rsshub.app/anime.html#an-の3dエロ-dong-hua-oreno3d-jiao-se-sou-suo',
source: ['/characters/:characterid'],
target: (params, url) => {
const searchParams = new URL(url).searchParams;
return `/oreno3d/characters/${params.characterid}${searchParams.has('sort') ? '/' + searchParams.get('sort') : ''}`;
},
},
{
title: '作者搜索',
docs: 'https://docs.rsshub.app/anime.html#an-の3dエロ-dong-hua-oreno3d-zuo-zhe-sou-suo',
source: ['/authors/:authorid'],
target: (params, url) => {
const searchParams = new URL(url).searchParams;
return `/oreno3d/authors/${params.authorid}${searchParams.has('sort') ? '/' + searchParams.get('sort') : ''}`;
},
},
{
title: '标签搜索',
docs: 'https://docs.rsshub.app/anime.html#an-の3dエロ-dong-hua-oreno3d-biao-qian-sou-suo',
source: ['/tags/:tagid'],
target: (params, url) => {
const searchParams = new URL(url).searchParams;
return `/oreno3d/tags/${params.tagid}${searchParams.has('sort') ? '/' + searchParams.get('sort') : ''}`;
},
},
{
title: '原作搜索',
docs: 'https://docs.rsshub.app/anime.html#an-の3dエロ-dong-hua-oreno3d-yuan-zuo-sou-suo',
source: ['/origins/:originid'],
target: (params, url) => {
const searchParams = new URL(url).searchParams;
return `/oreno3d/origins/${params.originid}${searchParams.has('sort') ? '/' + searchParams.get('sort') : ''}`;
},
},
],
},
};
+7
View File
@@ -0,0 +1,7 @@
module.exports = function (router) {
router.get('/authors/:authorid/:sort?', require('./main'));
router.get('/characters/:characterid/:sort?', require('./main'));
router.get('/origins/:originid/:sort?', require('./main'));
router.get('/search/:keyword/:sort?', require('./main'));
router.get('/tags/:tagid/:sort?', require('./main'));
};
+13
View File
@@ -0,0 +1,13 @@
<img src="{{ raw_pic_link }}">
<p>标题:<b>{{ video_name }}</b></p>
<p>作者:<b>{{ authors }}</b></p>
<p>原作:<b>{{ origins }}</b></p>
<p>角色:<b>{{ characters }}</b></p>
<p>标签:<b>{{ tags }}</b></p>
<p>简介:</p>
<div style = "white-space: pre-line;">
<b>{{ desc }}</b>
</div>
<p>iwara链接:<b><a href="{{ iwara_link }}">{{ iwara_link }}</a></b></p>
<p>Oreno3D链接:<b><a href="{{ oreno3d_link }}">{{ oreno3d_link }}</a></b></p>