diff --git a/assets/radar-rules.js b/assets/radar-rules.js index d30ce60a2..c0ea5734f 100644 --- a/assets/radar-rules.js +++ b/assets/radar-rules.js @@ -1333,6 +1333,51 @@ }, ], }, + 'ynu.edu.cn': { + _name: '云南大学', + home: [ + { + title: '官网消息通告', + docs: 'https://docs.rsshub.app/university.html#yun-nan-da-xue', + source: '/tzgg.htm', + target: '/ynu/home', + }, + ], + jwc: [ + { + title: '教务处教务科通知', + docs: 'https://docs.rsshub.app/university.html#yun-nan-da-xue', + source: '/*', + target: '/jwc/1', + }, + { + title: '教务处学籍科通知', + docs: 'https://docs.rsshub.app/university.html#yun-nan-da-xue', + source: '/*', + target: '/jwc/2', + }, + { + title: '教务处教学研究科通知', + docs: 'https://docs.rsshub.app/university.html#yun-nan-da-xue', + source: '/*', + target: '/jwc/3', + }, + { + title: '教务处实践科学科通知', + docs: 'https://docs.rsshub.app/university.html#yun-nan-da-xue', + source: '/*', + target: '/jwc/4', + }, + ], + grs: [ + { + title: '研究生院通知', + docs: 'https://docs.rsshub.app/university.html#yun-nan-da-xue', + source: '/*', + target: '', + }, + ], + }, 'zju.edu.cn': { _name: '浙江大学', cst: [ diff --git a/docs/university.md b/docs/university.md index 2ffed1db0..48707a874 100644 --- a/docs/university.md +++ b/docs/university.md @@ -1602,6 +1602,38 @@ type 列表: +## 云南大学 + +### 官网消息通告 + + + + +### 教务处主要通知 + + + +| 教务科 | 学籍科 | 教学研究科 | 实践科学科 | +| ------ | ------ | ---------- | ---------- | +| 1 | 2 | 3 | 4 | + + + +### 研究生院重要通知(置顶消息) + + + + +### 研究生院其他通知 + + + +| 招生工作 | 研究生培养 | 质量管理 | 学位工作 | 综合办公室 | 相关下载 | +| -------- | ---------- | -------- | -------- | ---------- | -------- | +| 1 | 2 | 3 | 4 | 5 | 6 | + + + ## 浙江大学 ### 普通栏目 如学术 / 图片 / 新闻等 diff --git a/lib/router.js b/lib/router.js index a9ae0ff51..bd743f161 100644 --- a/lib/router.js +++ b/lib/router.js @@ -728,6 +728,12 @@ router.get('/uestc/news/:type?', require('./routes/universities/uestc/news')); router.get('/uestc/auto/:type?', require('./routes/universities/uestc/auto')); router.get('/uestc/cs/:type?', require('./routes/universities/uestc/cs')); +// 云南大学 +router.get('/ynu/grs/zytz', require('./routes/universities/ynu/grs/zytz')); +router.get('/ynu/grs/qttz/:category', require('./routes/universities/ynu/grs/qttz')); +router.get('/ynu/jwc/:category', require('./routes/universities/ynu/jwc/zytz')); +router.get('/ynu/home', require('./routes/universities/ynu/home/main')); + // 昆明理工大学 router.get('/kmust/jwc/:type?', require('./routes/universities/kmust/jwc')); router.get('/kmust/job/careers/:type?', require('./routes/universities/kmust/job/careers')); diff --git a/lib/routes/universities/ynu/grs/qttz.js b/lib/routes/universities/ynu/grs/qttz.js new file mode 100644 index 000000000..5f300fa1b --- /dev/null +++ b/lib/routes/universities/ynu/grs/qttz.js @@ -0,0 +1,35 @@ +const got = require('@/utils/got'); +const cheerio = require('cheerio'); +const utils = require('../utils'); + +// 云南大学研究生院其他通知 +module.exports = async (ctx) => { + const host = 'http://www.grs.ynu.edu.cn/'; + const category = ctx.params.category; + const dep = ['招生工作', '研究生培养', '质量管理', '学位工作', '综合办公室', '相关下载']; + + const response = await got({ + method: 'get', + url: 'http://www.grs.ynu.edu.cn/index.htm', + headers: { + Referer: host, + }, + }); + + const $ = cheerio.load(response.data); + const list = $('#con3:nth-of-type(' + category + ') ul li') + .slice(0, 6) + .map((i, e) => ({ + path: $('a', e).attr('href'), + title: $('a', e).attr('title'), + author: dep[category - 1], + })) + .get(); + const out = await utils.processPages({ list: list, caches: ctx.cache, host: host, department: 'grs' }); + ctx.state.data = { + title: '云南大学研究生院' + dep[category - 1] + '通知', + link: host, + description: '云南大学研究生院' + dep[category - 1], + item: out, + }; +}; diff --git a/lib/routes/universities/ynu/grs/zytz.js b/lib/routes/universities/ynu/grs/zytz.js new file mode 100644 index 000000000..06b75baae --- /dev/null +++ b/lib/routes/universities/ynu/grs/zytz.js @@ -0,0 +1,34 @@ +const got = require('@/utils/got'); +const cheerio = require('cheerio'); +const utils = require('../utils'); + +// 云南大学研究生院重要通知 +module.exports = async (ctx) => { + const host = 'http://www.grs.ynu.edu.cn/'; + + const response = await got({ + method: 'get', + url: 'http://www.grs.ynu.edu.cn/index.htm', + headers: { + Referer: host, + }, + }); + + const $ = cheerio.load(response.data); + const list = $('#news table table tbody tr') + .slice(0, 9) + .map((i, e) => ({ + path: $('td a', e).attr('href'), + title: $('td a', e).attr('title'), + author: '研究生院', + })) + .get(); + const out = await utils.processPages({ list: list, caches: ctx.cache, host: host, department: 'grs' }); + + ctx.state.data = { + title: '云南大学研究生院重要通知', + link: host + 'zytz.htm', + description: '云南大学研究生院重要通知', + item: out, + }; +}; diff --git a/lib/routes/universities/ynu/home/main.js b/lib/routes/universities/ynu/home/main.js new file mode 100644 index 000000000..a6ae70bb3 --- /dev/null +++ b/lib/routes/universities/ynu/home/main.js @@ -0,0 +1,34 @@ +const got = require('@/utils/got'); +const cheerio = require('cheerio'); +const utils = require('../utils'); + +// 云南大学主页通知公告 +module.exports = async (ctx) => { + const host = 'http://www.ynu.edu.cn/'; + + const response = await got({ + method: 'get', + url: 'http://www.ynu.edu.cn/tzgg.htm', + headers: { + Referer: host, + }, + }); + + const $ = cheerio.load(response.data); + const list = $('.list_cont_rigB.fl ul li') + .slice(0, 8) + .map((i, e) => ({ + path: $('a', e).attr('href'), + title: $('a', e).attr('title'), + author: '云南大学', + })) + .get(); + + const out = await utils.processPages({ list: list, caches: ctx.cache, host: host, department: 'home' }); + ctx.state.data = { + title: '云南大学主页通知公告', + link: host, + description: '云南大学主页通知公告', + item: out, + }; +}; diff --git a/lib/routes/universities/ynu/jwc/zytz.js b/lib/routes/universities/ynu/jwc/zytz.js new file mode 100644 index 000000000..978024b46 --- /dev/null +++ b/lib/routes/universities/ynu/jwc/zytz.js @@ -0,0 +1,41 @@ +const got = require('@/utils/got'); +const cheerio = require('cheerio'); +const utils = require('../utils'); + +// 云南大学教务处主要通知 +module.exports = async (ctx) => { + const host = 'http://www.jwc.ynu.edu.cn/'; + const category = ctx.params.category; + const dep = ['教务科', '学籍科', '教学研究科', '实践教学科']; + + const response = await got({ + method: 'get', + url: 'http://www.jwc.ynu.edu.cn/', + headers: { + Referer: host, + }, + }); + + const $ = cheerio.load(response.data); + const firstRow = category < 3 ? 0 : 1; + const secondRow = category % 2 === 0 ? 2 : 1; + + const list = $('.index-row3') + .eq(firstRow) + .find('.c' + secondRow + ' .text-list ul li') + .slice(0, 8) + .map((i, e) => ({ + path: $('a', e).attr('href'), + title: $('a', e).attr('title'), + author: dep[category - 1], + })) + .get(); + + const out = await utils.processPages({ list: list, caches: ctx.cache, host: host, department: 'jwc' }); + ctx.state.data = { + title: '云南大学教务处' + dep[category - 1] + '通知', + link: host, + description: '云南大学教务处' + dep[category - 1], + item: out, + }; +}; diff --git a/lib/routes/universities/ynu/utils.js b/lib/routes/universities/ynu/utils.js new file mode 100644 index 000000000..1f05a37c3 --- /dev/null +++ b/lib/routes/universities/ynu/utils.js @@ -0,0 +1,64 @@ +const url = require('url'); +const cheerio = require('cheerio'); +const got = require('@/utils/got'); + +const processPages = async ({ list, caches, host, department }) => + await Promise.all( + list.map(async (item) => { + const { path, title, author } = item; + const link = path.indexOf('http://') === -1 ? host + path : path; + const cache = await caches.get(link); + if (cache) { + return Promise.resolve(JSON.parse(cache)); + } + const response = await got({ + method: 'get', + url: link, + headers: { + Referer: host, + }, + }); + + const $ = cheerio.load(response.data); + let dateString = ''; + switch (department) { + case 'grs': + dateString = $('#times').text().slice(5); + break; + case 'home': + dateString = $('.dateAadDian').text().slice(6, 17).replace(/年/, '-').replace(/月/, '-').replace(/日/, ''); + break; + case 'jwc': + dateString = $('.taitshj').text().slice(5, 15); + } + let description = + $('.v_news_content').html() && + $('.v_news_content') + .html() + .replace(/src="\//g, `src="${url.resolve(host, '.')}`) + .replace(/href="\//g, `href="${url.resolve(host, '.')}`) + .trim(); + if (department === 'jwc' && $('#vsb_content').siblings().has('ul li').length > 0) { + const attachment = $('#vsb_content') + .siblings('ul') + .html() + .replace(/src="\//g, `src="${url.resolve(host, '.')}`) + .replace(/href="\//g, `href="${url.resolve(host, '.')}`) + .trim(); + description = description.concat('\n' + attachment); + } + const single = { + pubDate: new Date(dateString).toUTCString(), + author: author, + link: link, + title: title, + description: description, + }; + caches.set(link, JSON.stringify(single)); + return Promise.resolve(single); + }) + ); + +module.exports = { + processPages, +};