diff --git a/docs/anime.md b/docs/anime.md
index ce8443c73..74714e06e 100644
--- a/docs/anime.md
+++ b/docs/anime.md
@@ -363,7 +363,22 @@ Sources
### Love Live 官网最新 News
-
+
+
+### Love Live 官网分类 Topics
+
+
+
+| 子企划名(非全称) | Lovelive! | Lovelive! Sunshine!! | Lovelive! Nijigasaki High School Idol Club | Lovelive! Superstar!! |
+| ------------------ | ----------- | -------------------- | ------------------------------------------ | --------------------- |
+| `abbr`参数 | otonokizaka | uranohoshi | nijigasaki | yuigaoka |
+
+
+| 分类名 | 全てのニュース | 音楽商品 | アニメ映像商品 | キャスト映像商品 | 劇場 | アニメ放送/配信 | キャスト配信/ラジオ | ライブ/イベント | ブック | グッズ | ゲーム | メディア | ご当地情報 | その他 | キャンペーン |
+| -------------- | --------------- | -------- | -------------- | ---------------- | ------- | --------------- | ------------------- | --------------- | ------ | ------ | ------ | -------- | ---------- | ------ | ------------ |
+| `category`参数 | *无参数* | music | anime_movie | cast_movie | theater | onair | radio | event | books | goods | game | media | local | other | campaign |
+
+
## Mox.moe
diff --git a/docs/en/anime.md b/docs/en/anime.md
index 1e5c6d795..57d57ef40 100644
--- a/docs/en/anime.md
+++ b/docs/en/anime.md
@@ -72,7 +72,22 @@ When `posts` is selected as the value of the parameter **source**, the parameter
### Love Live! Official Website Latest NEWS
-
+
+
+### Love Live Official Website Categories Topics
+
+
+
+| 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 | *No parameter* | music | anime_movie | cast_movie | theater | onair | radio | event | books | goods | game | media | local | other | campaign |
+
+
## Touhougarakuta
diff --git a/lib/v2/lovelive-anime/maintainer.js b/lib/v2/lovelive-anime/maintainer.js
index 4dc741ff7..1f883a6c9 100644
--- a/lib/v2/lovelive-anime/maintainer.js
+++ b/lib/v2/lovelive-anime/maintainer.js
@@ -1,3 +1,4 @@
module.exports = {
'/news/:option?': ['axojhf'],
+ '/topics/:abbr/:category?': ['axojhf'],
};
diff --git a/lib/v2/lovelive-anime/radar.js b/lib/v2/lovelive-anime/radar.js
index fa57df0d3..e64c19483 100644
--- a/lib/v2/lovelive-anime/radar.js
+++ b/lib/v2/lovelive-anime/radar.js
@@ -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] : ''}`;
+ },
+ },
],
},
};
diff --git a/lib/v2/lovelive-anime/router.js b/lib/v2/lovelive-anime/router.js
index c7bbc2e16..0734739f7 100644
--- a/lib/v2/lovelive-anime/router.js
+++ b/lib/v2/lovelive-anime/router.js
@@ -1,3 +1,4 @@
module.exports = (router) => {
router.get('/news/:option?', require('./news'));
+ router.get('/topics/:abbr/:category?/:option?', require('./topics'));
};
diff --git a/lib/v2/lovelive-anime/topics.js b/lib/v2/lovelive-anime/topics.js
new file mode 100644
index 000000000..01a65f940
--- /dev/null
+++ b/lib/v2/lovelive-anime/topics.js
@@ -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,
+ };
+};