feat(route): Add Love Live Topics Route (#10645)

* Add Love Live Topics Route

* fix radar issue
This commit is contained in:
Axojhf 2022-08-30 01:52:01 +08:00 committed by GitHub
parent c233b1787f
commit 896b450cc8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 130 additions and 5 deletions

View File

@ -363,7 +363,22 @@ Sources
### Love Live 官网最新 News
<Route author="axojhf" example="/lovelive-anime/news" path="/lovelive-anime/news/:option?" :paramsDesc="['`option` 为 `detail` 时抓取全文']" />
<Route author="axojhf" example="/lovelive-anime/news" path="/lovelive-anime/news/:option?" :paramsDesc="['`option` 为 `detail` 时抓取全文']" radar="1"/>
### Love Live 官网分类 Topics
<Route author="axojhf" example="/lovelive-anime/topics/otonokizaka" path="/lovelive-anime/topics/:abbr/:category?/:option?" :paramsDesc="['Love Live系列子企划在官网的路径详见下表', '官网列出的Topics分类`category` 为 `detail` 时抓取全文,其他分类详见下表', '`option` 为 `detail` 时抓取全文']" radar="1">
| 子企划名(非全称) | Lovelive! | Lovelive! Sunshine!! | Lovelive! Nijigasaki High School Idol Club | Lovelive! Superstar!! |
| ------------------ | ----------- | -------------------- | ------------------------------------------ | --------------------- |
| `abbr`参数 | otonokizaka | uranohoshi | nijigasaki | yuigaoka |
| 分类名 | 全てのニュース | 音楽商品 | アニメ映像商品 | キャスト映像商品 | 劇場 | アニメ放送/配信 | キャスト配信/ラジオ | ライブ/イベント | ブック | グッズ | ゲーム | メディア | ご当地情報 | その他 | キャンペーン |
| -------------- | --------------- | -------- | -------------- | ---------------- | ------- | --------------- | ------------------- | --------------- | ------ | ------ | ------ | -------- | ---------- | ------ | ------------ |
| `category`参数 | <u>*无参数*</u> | music | anime_movie | cast_movie | theater | onair | radio | event | books | goods | game | media | local | other | campaign |
</Route>
## Mox.moe

View File

@ -72,7 +72,22 @@ When `posts` is selected as the value of the parameter **source**, the parameter
### Love Live! Official Website Latest NEWS
<RouteEn author="axojhf" example="/lovelive-anime/news" path="/lovelive-anime/news/:option?" :paramsDesc="['Crawl full text when `option` is `detail`.']" />
<RouteEn author="axojhf" example="/lovelive-anime/news" path="/lovelive-anime/news/:option?" :paramsDesc="['Crawl full text when `option` is `detail`.']" radar="1"/>
### Love Live Official Website Categories Topics
<RouteEn author="axojhf" example="/lovelive-anime/topics/otonokizaka" path="/lovelive-anime/topics/:abbr/:category?/:option?" :paramsDesc="['The path to the Love Live series of sub-projects on the official website is detailed in the table below', 'The official website lists the Topics category, `category` is `detail` when crawling the full text, other categories see the following table for details', 'Crawl full text when `option` is `detail`.']" radar="1">
| Sub-project name (not full name) | Lovelive! | Lovelive! Sunshine!! | Lovelive! Nijigasaki High School Idol Club | Lovelive! Superstar!! |
| -------------------------------- | ----------- | -------------------- | ------------------------------------------ | --------------------- |
| `abbr`parameter | otonokizaka | uranohoshi | nijigasaki | yuigaoka |
| category name | 全てのニュース | 音楽商品 | アニメ映像商品 | キャスト映像商品 | 劇場 | アニメ放送/配信 | キャスト配信/ラジオ | ライブ/イベント | ブック | グッズ | ゲーム | メディア | ご当地情報 | その他 | キャンペーン |
| -------------- | --------------- | -------- | -------------- | ---------------- | ------- | --------------- | ------------------- | --------------- | ------ | ------ | ------ | -------- | ---------- | ------ | ------------ |
| `category`parameter | <u>*No parameter*</u> | music | anime_movie | cast_movie | theater | onair | radio | event | books | goods | game | media | local | other | campaign |
</RouteEn>
## Touhougarakuta

View File

@ -1,3 +1,4 @@
module.exports = {
'/news/:option?': ['axojhf'],
'/topics/:abbr/:category?': ['axojhf'],
};

View File

@ -3,11 +3,20 @@ module.exports = {
_name: 'Love Live 官网',
www: [
{
title: '最新NEWS',
docs: 'https://docs.rsshub.app/anime.html#lovelive-anime',
source: ['/'],
title: '最新 NEWS',
docs: 'https://docs.rsshub.app/anime.html#lovelive-anime-love-live-guan-wang-zui-xin-news',
source: ['/', '/news'],
target: '/lovelive-anime/news',
},
{
title: '分类 Topics',
docs: 'https://docs.rsshub.app/anime.html#lovelive-anime-love-live-guan-wang-fen-lei-topics',
source: ['/:abbr/topics/', '/:abbr/topics.php'],
target: (params, url) => {
const cat = url.match(/\?cat=(.*)/);
return `/lovelive-anime/topics/${params.abbr}/${null !== cat && cat.length === 2 ? cat[1] : ''}`;
},
},
],
},
};

View File

@ -1,3 +1,4 @@
module.exports = (router) => {
router.get('/news/:option?', require('./news'));
router.get('/topics/:abbr/:category?/:option?', require('./topics'));
};

View File

@ -0,0 +1,84 @@
const got = require('@/utils/got');
const cheerio = require('cheerio');
const path = require('path');
const { art } = require('@/utils/render');
const { parseDate } = require('@/utils/parse-date');
const renderDescription = (desc) => art(path.join(__dirname, 'templates/description.art'), desc);
module.exports = async (ctx) => {
const abbr = ctx.params.abbr;
const rootUrl = `https://www.lovelive-anime.jp/${abbr}`;
const topicsUrlPart = 'yuigaoka' === abbr ? 'topics/' : 'topics.php';
const baseUrl = `${rootUrl}/${'yuigaoka' === abbr ? 'topics/' : ''}`;
const abbrDetail = {
otonokizaka: 'ラブライブ!',
uranohoshi: 'サンシャイン!!',
nijigasaki: '虹ヶ咲学園',
yuigaoka: 'スーパースター!!',
};
let url;
if (ctx.params.hasOwnProperty('category') && ctx.params.category !== 'detail') {
url = `${rootUrl}/${topicsUrlPart}?cat=${ctx.params.category}`;
} else {
url = `${rootUrl}/${topicsUrlPart}`;
}
const response = await got(url);
const $ = cheerio.load(response.data);
const categoryName = 'uranohoshi' === abbr ? $('div.llbox > p').text() : $('div.category_title > h2').text();
let items = $('ul.listbox > li')
.map((_, item) => {
item = $(item);
const link = `${baseUrl}${item.find('div > a').attr('href')}`;
const pubDate = parseDate(item.find('a > p.date').text(), 'YYYY/MM/DD');
const title = item.find('a > p.title').text();
const category = item.find('a > p.category').text();
const imglink = `${baseUrl}${
item
.find('a > img')
.attr('style')
.match(/background-image:url\((.*)\)/)[1]
}`;
return {
link,
pubDate,
title,
category,
description: renderDescription({
title,
imglink,
}),
};
})
.get();
if (ctx.params.option === 'detail' || ctx.params.category === 'detail') {
items = await Promise.all(
items.map((item) =>
ctx.cache.tryGet(item.link, async () => {
const detailResp = await got(item.link);
const $ = cheerio.load(detailResp.data);
const content = $('div.p-page__detail.p-article');
for (const v of content.find('img')) {
v.attribs.src = `${baseUrl}${v.attribs.src}`;
}
item.description = content.html();
return item;
})
)
);
}
ctx.state.data = {
title: `${categoryName} - ${abbrDetail[abbr]} - Love Live Official Website Topics`,
link: url,
item: items,
};
};