Files
RSSHub/lib/v2/luogu/contest.js
2022-10-12 01:48:50 +08:00

73 lines
2.1 KiB
JavaScript

const got = require('@/utils/got');
const cheerio = require('cheerio');
const md = require('markdown-it')();
const { parseDate } = require('@/utils/parse-date');
const asyncPool = require('tiny-async-pool');
const baseUrl = 'https://www.luogu.com.cn';
const typeMap = {
ruleType: {
1: 'OI',
2: 'ACM',
3: '乐多',
4: 'IOI',
},
visibilityType: {
1: '官方比赛',
2: '团队公开赛',
4: '个人公开赛',
},
// invitationCodeType: {
// 1: '',
// 2: '',
// },
};
module.exports = async (ctx) => {
const link = `${baseUrl}/contest/list`;
const { data: response } = await got(link);
const $ = cheerio.load(response);
const data = JSON.parse(
decodeURIComponent(
$('script')
.text()
.match(/decodeURIComponent\("(.*)"\)/)[1]
)
);
const result = [];
for await (const item of asyncPool(4, data.currentData.contests.result, (item) =>
ctx.cache.tryGet(`${baseUrl}/contest/${item.id}`, async () => {
const { data: response } = await got(`${baseUrl}/contest/${item.id}`);
const $ = cheerio.load(response);
const data = JSON.parse(
decodeURIComponent(
$('script')
.text()
.match(/decodeURIComponent\("(.*)"\)/)[1]
)
);
return {
title: item.name,
description: md.render(data.currentData.contest.description),
link: `${baseUrl}/contest/${item.id}`,
author: item.host.name,
pubDate: parseDate(item.startTime, 'X'),
category: [item.rated ? 'Rated' : null, typeMap.ruleType[item.ruleType], typeMap.visibilityType[item.visibilityType]].filter((i) => i),
};
})
)) {
result.push(item);
}
ctx.state.data = {
title: $('head title').text(),
link,
image: 'https://www.luogu.com.cn/favicon.ico',
item: result,
};
};