diff --git a/lib/routes/hfut/hf/notice.ts b/lib/routes/hfut/hf/notice.ts new file mode 100644 index 00000000000000..cff0e9492b2954 --- /dev/null +++ b/lib/routes/hfut/hf/notice.ts @@ -0,0 +1,43 @@ +import { Route } from '@/types'; +import parseList from './utils'; + +export const route: Route = { + path: '/hf/notice/:type?', + categories: ['university'], + example: '/hfut/hf/notice/tzgg', + parameters: { type: '分类,见下表(默认为 `tzgg`)' }, + features: { + requireConfig: false, + requirePuppeteer: false, + antiCrawler: false, + supportBT: false, + supportPodcast: false, + supportRadar: true, + supportScihub: false, + }, + radar: [ + { + source: ['news.hfut.edu.cn'], + }, + ], + name: '合肥校区通知', + maintainers: ['batemax'], + handler, + description: `| 通知公告(https://news.hfut.edu.cn/tzgg2.htm) | 教学科研(https://news.hfut.edu.cn/tzgg2/jxky.htm) | 其他通知(https://news.hfut.edu.cn/tzgg2/qttz.htm) | + | ------------ | -------------- | ------------------ | + | tzgg | jxky | qttz |`, +}; + +async function handler(ctx) { + // set default router type + const type = ctx.req.param('type') ?? 'tzgg'; + + const { link, title, resultList } = await parseList(ctx, type); + + return { + title, + link, + description: '合肥工业大学 - 通知公告', + item: resultList, + }; +} diff --git a/lib/routes/hfut/hf/utils.ts b/lib/routes/hfut/hf/utils.ts new file mode 100644 index 00000000000000..874121db6bdd39 --- /dev/null +++ b/lib/routes/hfut/hf/utils.ts @@ -0,0 +1,80 @@ +import cache from '@/utils/cache'; +import got from '@/utils/got'; +import { load } from 'cheerio'; +import { parseDate } from '@/utils/parse-date'; + +const typeMap = { + tzgg: { name: 'tzgg', url: 'https://news.hfut.edu.cn/tzgg2.htm', root: 'https://news.hfut.edu.cn', title: '合肥工业大学 - 通知公告' }, + jxky: { name: 'jxky', url: 'https://news.hfut.edu.cn/tzgg2.htm', root: 'https://news.hfut.edu.cn', title: '合肥工业大学 - 通知公告 - 教学科研' }, + qttz: { name: 'qttz', url: 'https://news.hfut.edu.cn/tzgg2.htm', root: 'https://news.hfut.edu.cn', title: '合肥工业大学 - 通知公告 - 其它通知' }, +}; + +const commLink = 'https://news.hfut.edu.cn/'; + +const parseList = async (ctx, type) => { + const link = typeMap[type].url; + const title = typeMap[type].title; + + const response = await got(link); + const $ = load(response.data); + + const resultList = await parseArticle(typeMap[type].name, $); + + return { + title, + link, + resultList, + }; +}; + +async function parseArticle(type, $) { + let data = $('#tzz').find('li').toArray(); + + if (type === 'jxky') { + data = $('#c01').find('li').toArray(); + } else if (type === 'qttz') { + data = $('#c02').find('li').toArray(); + } + + const items = data.map((item) => { + item = $(item); + const oriLink = item.find('a').attr('href'); + let linkRes = oriLink; + if (!oriLink.startsWith('http')) { + linkRes = commLink + item.find('a').attr('href'); + } + const pubDate = parseDate(item.find('i').text(), 'YYYY-MM-DD'); + + return { + title: item.find('p').text(), + pubDate, + link: linkRes, + }; + }); + + const resultItems = await Promise.all( + items.map((item) => + cache.tryGet(item.link, async () => { + let description; + try { + const response = await got(item.link); + const $ = load(response.data); + description = $('.wp_articlecontent').html() ?? $('.v_news_content').html() ?? item.link; + } catch { + description = item.link; + } + + return { + title: item.title, + link: item.link, + description, + pubDate: item.pubDate, + }; + }) + ) + ); + + return resultItems; +} + +export default parseList; diff --git a/lib/routes/hfut/namespace.ts b/lib/routes/hfut/namespace.ts new file mode 100644 index 00000000000000..723f877f1de21d --- /dev/null +++ b/lib/routes/hfut/namespace.ts @@ -0,0 +1,6 @@ +import type { Namespace } from '@/types'; + +export const namespace: Namespace = { + name: '合肥工业大学', + url: 'hfut.edu.cn', +}; diff --git a/lib/routes/hfut/xc/notice.ts b/lib/routes/hfut/xc/notice.ts new file mode 100644 index 00000000000000..1dc36c663c7162 --- /dev/null +++ b/lib/routes/hfut/xc/notice.ts @@ -0,0 +1,43 @@ +import { Route } from '@/types'; +import parseList from './utils'; + +export const route: Route = { + path: '/xc/notice/:type?', + categories: ['university'], + example: '/hfut/xc/notice/tzgg', + parameters: { type: '分类,见下表(默认为 `tzgg`)' }, + features: { + requireConfig: false, + requirePuppeteer: false, + antiCrawler: false, + supportBT: false, + supportPodcast: false, + supportRadar: true, + supportScihub: false, + }, + radar: [ + { + source: ['xc.hfut.edu.cn'], + }, + ], + name: '宣城校区通知', + maintainers: ['batemax'], + handler, + description: `| 通知公告(https://xc.hfut.edu.cn/1955/list.htm) | 院系动态-工作通知(https://xc.hfut.edu.cn/gztz/list.htm) | + | ------------ | -------------- | + | tzgg | gztz |`, +}; + +async function handler(ctx) { + // set default router type + const type = ctx.req.param('type') ?? 'tzgg'; + + const { link, title, resultList } = await parseList(ctx, type); + + return { + title, + link, + description: '合肥工业大学宣城校区 - 通知公告', + item: resultList, + }; +} diff --git a/lib/routes/hfut/xc/utils.ts b/lib/routes/hfut/xc/utils.ts new file mode 100644 index 00000000000000..3e2c998fed6813 --- /dev/null +++ b/lib/routes/hfut/xc/utils.ts @@ -0,0 +1,73 @@ +import cache from '@/utils/cache'; +import got from '@/utils/got'; +import { load } from 'cheerio'; +import { parseDate } from '@/utils/parse-date'; + +const typeMap = { + tzgg: { name: 'tzgg', url: 'https://xc.hfut.edu.cn/1955/list.htm', root: 'https://xc.hfut.edu.cn', title: '合肥工业大学宣城校区 - 通知公告' }, + gztz: { name: 'gztz', url: 'https://xc.hfut.edu.cn/gztz/list.htm', root: 'https://xc.hfut.edu.cn', title: '合肥工业大学宣城校区 - 院系动态 - 工作通知' }, +}; + +const commLink = 'https://xc.hfut.edu.cn/'; + +const parseList = async (ctx, type) => { + const link = typeMap[type].url; + const title = typeMap[type].title; + + const response = await got(link); + const $ = load(response.data); + + const resultList = await parseArticle($); + + return { + title, + link, + resultList, + }; +}; + +async function parseArticle($) { + const data = $('#wp_news_w6').find('li').toArray(); + + const items = data.map((item) => { + item = $(item); + const oriLink = item.find('a').attr('href'); + let linkRes = oriLink; + if (!oriLink.startsWith('http')) { + linkRes = commLink + item.find('a').attr('href'); + } + const pubDate = parseDate(item.find('.news_meta').text(), 'YYYY-MM-DD'); + + return { + title: item.find('a').attr('title'), + pubDate, + link: linkRes, + }; + }); + + const resultItems = await Promise.all( + items.map((item) => + cache.tryGet(item.link, async () => { + let description; + try { + const response = await got(item.link); + const $ = load(response.data); + description = $('.wp_articlecontent').html() ?? $('.v_news_content').html() ?? item.link; + } catch { + description = item.link; + } + + return { + title: item.title, + link: item.link, + description, + pubDate: item.pubDate, + }; + }) + ) + ); + + return resultItems; +} + +export default parseList;