feat(route): Fix and update LoveLive! routes due to official website renewal (#20240)
* Fix lovelive due to website renewal * Update lib/routes/lovelive-anime/news.ts ---------
This commit is contained in:
parent
2c46b2ad1c
commit
51790e38c2
|
|
@ -37,9 +37,9 @@ export const route: Route = {
|
|||
maintainers: ['axojhf', 'zhaoweizhong'],
|
||||
handler,
|
||||
url: 'www.lovelive-anime.jp/',
|
||||
description: `| Sub-project Name | All Projects | Lovelive! | Lovelive! Sunshine!! | Lovelive! Nijigasaki High School Idol Club | Lovelive! Superstar!! | 蓮ノ空女学院 | 幻日のヨハネ | ラブライブ!スクールアイドルミュージカル |
|
||||
| -------------------------------- | -------------- | ----------- | -------------------- | ------------------------------------------ | --------------------- | ------------ | ------------ | ---------------------------------------- |
|
||||
| \`abbr\`parameter | <u>*No parameter*</u> | lovelive | sunshine | nijigasaki | superstar | hasunosora | yohane | musical |
|
||||
description: `| Sub-project Name | All Projects | Lovelive! | Lovelive! Sunshine!! | Lovelive! Nijigasaki High School Idol Club | Lovelive! Superstar!! | 蓮ノ空女学院 | イキヅライブ! | 幻日のヨハネ | ラブライブ!スクールアイドルミュージカル |
|
||||
| -------------------------------- | -------------- | ----------- | -------------------- | ------------------------------------------ | --------------------- | ------------ | ------------ | ------------ | ---------------------------------------- |
|
||||
| \`abbr\`parameter | <u>*No parameter*</u> | lovelive | sunshine | nijigasaki | superstar | hasunosora | ikizulive | yohane | musical |
|
||||
|
||||
| Category Name | 全てのニュース | 音楽商品 | アニメ映像商品 | キャスト映像商品 | 劇場 | アニメ放送 / 配信 | キャスト配信 / ラジオ | ライブ / イベント | ブック | グッズ | ゲーム | メディア | ご当地情報 | キャンペーン | その他 |
|
||||
| ------------------- | --------------------- | -------- | -------------- | ---------------- | ------- | ----------------- | --------------------- | ----------------- | ------ | ------ | ------ | -------- | ---------- | ------ | ------------ |
|
||||
|
|
@ -64,7 +64,7 @@ async function handler(ctx) {
|
|||
|
||||
const limit = 20;
|
||||
|
||||
let url = `https://www.lovelive-anime.jp/common/api/article_list.php?site=jp&ip=lovelive&limit=${limit}&data=`;
|
||||
let url = `https://www.lovelive-anime.jp/common/templates/api/article_list.php?limit=${limit}&data=`;
|
||||
const params: { category: string[]; series?: string[]; subcategory?: string[] } = { category: ['NEWS'] };
|
||||
if (series) {
|
||||
params.series = [series];
|
||||
|
|
|
|||
|
|
@ -1,76 +0,0 @@
|
|||
import { Route } from '@/types';
|
||||
|
||||
import ofetch from '@/utils/ofetch';
|
||||
import path from 'node:path';
|
||||
import { art } from '@/utils/render';
|
||||
const renderDescription = (desc) => art(path.join(__dirname, 'templates/scheduleDesc.art'), desc);
|
||||
import dayjs from 'dayjs';
|
||||
import utc from 'dayjs/plugin/utc.js';
|
||||
import timezone from 'dayjs/plugin/timezone.js';
|
||||
dayjs.extend(utc);
|
||||
dayjs.extend(timezone);
|
||||
|
||||
export const route: Route = {
|
||||
path: '/schedules/:serie?/:category?',
|
||||
parameters: {
|
||||
serie: 'Love Live! Series sub-projects abbreviation, see the following table',
|
||||
category: 'The official website lists the categories, see the following table for details',
|
||||
},
|
||||
name: 'Schedule',
|
||||
example: '/lovelive-anime/schedules',
|
||||
categories: ['anime'],
|
||||
maintainers: ['axojhf'],
|
||||
handler,
|
||||
description: `| Sub-project Name (not full name) | 全シリーズ | Lovelive! | Lovelive! Sunshine!! | Lovelive! Nijigasaki High School Idol Club | Lovelive! Superstar!! | ラブライブ!スクールアイドルミュージカル |
|
||||
| -------------------------------- | ----------------------- | ---------- | -------------------- | ------------------------------------------ | --------------------- | ---------------------------------------- |
|
||||
| \`serie\` parameter | *No parameter* or \`all\` | \`lovelive\` | \`sunshine\` | \`nijigasaki\` | \`superstar\` | \`musical\` |
|
||||
|
||||
| Category Name | 全て | ライブ | イベント | 生配信 |
|
||||
| -------------------- | ----------------------- | ------ | -------- | --------- |
|
||||
| \`category\` parameter | *No parameter* or \`all\` | \`live\` | \`event\` | \`haishin\` |`,
|
||||
};
|
||||
|
||||
async function handler(ctx) {
|
||||
const { serie = 'all', category = 'all' } = ctx.req.param();
|
||||
const rootUrl = 'https://www.lovelive-anime.jp/common/api/calendar_list.php';
|
||||
const nowTime = dayjs();
|
||||
const dataPara = {
|
||||
year: nowTime.year(),
|
||||
month: nowTime.format('MM'),
|
||||
};
|
||||
if (serie && 'all' !== serie) {
|
||||
dataPara.series = [serie];
|
||||
}
|
||||
if (category && 'all' !== category) {
|
||||
dataPara.category = [category];
|
||||
}
|
||||
const response = await ofetch(`${rootUrl}?site=jp&ip=lovelive&data=${encodeURIComponent(JSON.stringify(dataPara))}`);
|
||||
|
||||
const items = response.data.schedule_list.map((item) => {
|
||||
const link = item.url.select_url;
|
||||
const title = item.title;
|
||||
const category = item.categories.name;
|
||||
const eventStartDate = dayjs.unix(item.event_startdate).tz('Asia/Tokyo').format('YYYY-MM-DD HH:mm:ss JST');
|
||||
const eventEndDate = dayjs.unix(item.event_enddate).tz('Asia/Tokyo').format('YYYY-MM-DD HH:mm:ss JST');
|
||||
|
||||
return {
|
||||
link,
|
||||
pubDate: item.start_endflg ? dayjs.unix(item.event_enddate).tz('Asia/Tokyo') : dayjs.unix(item.event_startdate).tz('Asia/Tokyo'),
|
||||
title,
|
||||
category,
|
||||
description: renderDescription({
|
||||
desc: item.event_dspdate,
|
||||
startTime: eventStartDate,
|
||||
endTime: eventEndDate,
|
||||
}),
|
||||
};
|
||||
});
|
||||
|
||||
return {
|
||||
title: `${category} - ${serie} - Love Live Official Website Schedule`,
|
||||
link: 'https://www.lovelive-anime.jp/schedule/',
|
||||
item: items,
|
||||
description:
|
||||
'The schedule date and other information shall be subject to the announcement on the official website. The RSS route has not been strictly tested, and the captured information cannot be guaranteed to be correct.',
|
||||
};
|
||||
}
|
||||
|
|
@ -1,161 +0,0 @@
|
|||
import { Route } from '@/types';
|
||||
|
||||
import cache from '@/utils/cache';
|
||||
import ofetch from '@/utils/ofetch';
|
||||
import { load } from 'cheerio';
|
||||
import path from 'node:path';
|
||||
import { art } from '@/utils/render';
|
||||
import { parseDate } from '@/utils/parse-date';
|
||||
import timezone from '@/utils/timezone';
|
||||
const renderDescription = (desc) => art(path.join(__dirname, 'templates/description.art'), desc);
|
||||
|
||||
export const route: Route = {
|
||||
path: '/topics/:abbr/:category?/:option?',
|
||||
categories: ['anime'],
|
||||
example: '/lovelive-anime/topics/otonokizaka',
|
||||
parameters: {
|
||||
abbr: 'The path to the Love Live series of sub-projects on the official website is detailed in the table below',
|
||||
category: 'The official website lists the Topics category, `category` is `detail` when crawling the full text, other categories see the following table for details',
|
||||
option: 'Crawl full text when `option` is `detail`.',
|
||||
},
|
||||
features: {
|
||||
requireConfig: false,
|
||||
requirePuppeteer: false,
|
||||
antiCrawler: false,
|
||||
supportBT: false,
|
||||
supportPodcast: false,
|
||||
supportScihub: false,
|
||||
},
|
||||
name: 'Categories Topics',
|
||||
maintainers: ['axojhf'],
|
||||
handler,
|
||||
description: `| Sub-project Name (not full name) | Lovelive! | Lovelive! Sunshine!! | Lovelive! Nijigasaki High School Idol Club | Lovelive! Superstar!! | 幻日のヨハネ | ラブライブ!スクールアイドルミュージカル |
|
||||
| -------------------------------- | ----------- | -------------------- | ------------------------------------------ | --------------------- | ------------ | ---------------------------------------- |
|
||||
| \`abbr\`parameter | otonokizaka | uranohoshi | nijigasaki | yuigaoka | yohane | musical |
|
||||
|
||||
| Category Name | 全てのニュース | 音楽商品 | アニメ映像商品 | キャスト映像商品 | 劇場 | アニメ放送 / 配信 | キャスト配信 / ラジオ | ライブ / イベント | ブック | グッズ | ゲーム | メディア | ご当地情報 | その他 | キャンペーン |
|
||||
| ------------------- | --------------------- | -------- | -------------- | ---------------- | ------- | ----------------- | --------------------- | ----------------- | ------ | ------ | ------ | -------- | ---------- | ------ | ------------ |
|
||||
| \`category\`parameter | <u>*No parameter*</u> | music | anime\_movie | cast\_movie | theater | onair | radio | event | books | goods | game | media | local | other | campaign |`,
|
||||
};
|
||||
|
||||
async function handler(ctx) {
|
||||
const { abbr, category = '', option } = ctx.req.param();
|
||||
let rootUrl: string;
|
||||
switch (abbr) {
|
||||
case 'musical':
|
||||
rootUrl = 'https://www.lovelive-anime.jp/special/musical';
|
||||
break;
|
||||
default:
|
||||
rootUrl = `https://www.lovelive-anime.jp/${abbr}`;
|
||||
break;
|
||||
}
|
||||
const topicsTable = {
|
||||
otonokizaka: 'topics.php',
|
||||
uranohoshi: 'topics.php',
|
||||
nijigasaki: 'topics.php',
|
||||
yuigaoka: 'topics/',
|
||||
hasunosora: 'news/',
|
||||
musical: 'topics.php',
|
||||
};
|
||||
const baseUrl = `${rootUrl}/${topicsTable[abbr]}`;
|
||||
const abbrDetail = {
|
||||
otonokizaka: 'ラブライブ!',
|
||||
uranohoshi: 'サンシャイン!!',
|
||||
nijigasaki: '虹ヶ咲学園',
|
||||
yuigaoka: 'スーパースター!!',
|
||||
};
|
||||
|
||||
const url = category !== '' && category !== 'detail' ? `${baseUrl}?cat=${category}` : baseUrl;
|
||||
|
||||
const response = await ofetch(url);
|
||||
|
||||
const $ = load(response);
|
||||
|
||||
const categoryName = 'uranohoshi' === abbr ? $('div.llbox > p').text() : $('div.category_title > h2').text();
|
||||
|
||||
const newsList = 'hasunosora' === abbr ? $('.list__content > ul > li').toArray() : $('ul.listbox > li').toArray();
|
||||
let items;
|
||||
|
||||
switch (abbr) {
|
||||
case 'hasunosora':
|
||||
items = newsList.map((item) => {
|
||||
item = $(item);
|
||||
const link = `${rootUrl}/news/${item.find('a').attr('href')}`;
|
||||
const pubDate = timezone(parseDate(item.find('.list--date').text(), 'YYYY.MM.DD'), +9);
|
||||
const title = item.find('.list--text').text();
|
||||
const category = item.find('.list--category').text();
|
||||
|
||||
return {
|
||||
link,
|
||||
pubDate,
|
||||
title,
|
||||
category,
|
||||
description: title,
|
||||
};
|
||||
});
|
||||
break;
|
||||
default:
|
||||
items = newsList.map((item) => {
|
||||
item = $(item);
|
||||
let link: string;
|
||||
switch (abbr) {
|
||||
case 'yuigaoka':
|
||||
link = `${baseUrl}${item.find('div > a').attr('href')}`;
|
||||
break;
|
||||
default:
|
||||
link = `${rootUrl}/${item.find('div > a').attr('href')}`;
|
||||
break;
|
||||
}
|
||||
const pubDate = timezone(parseDate(item.find('a > p.date').text(), 'YYYY/MM/DD'), +9);
|
||||
const title = item.find('a > p.title').text();
|
||||
const category = item.find('a > p.category').text();
|
||||
const relativeImgLink = item
|
||||
.find('a > img')
|
||||
.attr('style')
|
||||
.match(/background-image:url\((.*)\)/)[1];
|
||||
const imglink = new URL(relativeImgLink, baseUrl).href;
|
||||
|
||||
return {
|
||||
link,
|
||||
pubDate,
|
||||
title,
|
||||
category,
|
||||
description: renderDescription({
|
||||
imglink,
|
||||
}),
|
||||
};
|
||||
});
|
||||
break;
|
||||
}
|
||||
|
||||
if (option === 'detail' || category === 'detail') {
|
||||
items = await Promise.all(
|
||||
items.map((item) =>
|
||||
cache.tryGet(item.link, async () => {
|
||||
const detailResp = await ofetch(item.link);
|
||||
const $ = load(detailResp);
|
||||
let content;
|
||||
switch (abbr) {
|
||||
case 'hasunosora':
|
||||
content = $('div.detail__content');
|
||||
break;
|
||||
default:
|
||||
content = $('div.p-page__detail.p-article');
|
||||
break;
|
||||
}
|
||||
for (const v of content.find('img')) {
|
||||
v.attribs.src = `${baseUrl}${v.attribs.src}`;
|
||||
}
|
||||
item.description = content.html();
|
||||
return item;
|
||||
})
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
return {
|
||||
title: `${categoryName} - ${abbrDetail[abbr]} - Love Live Official Website Topics`,
|
||||
link: url,
|
||||
item: items,
|
||||
};
|
||||
}
|
||||
Loading…
Reference in New Issue