feat(route): add 大连理工大学 (#8580)

* feat(route): add 大连理工大学

* add radar

* fix: add maintainer

* fix typo

* docs: fix url

* fix: incomplete multi-character sanitization
This commit is contained in:
Ethan Shen
2022-04-10 23:39:24 +08:00
committed by GitHub
parent c5741650d2
commit 0c3888787a
10 changed files with 383 additions and 127 deletions
+144 -16
View File
@@ -535,33 +535,161 @@ pageClass: routes
## 大连理工大学
### 通用
<Route author="nczitzk" example="/dut" path="/dut/:site?/:category?" :paramsDesc="['站点,可在 URL 中找到,默认为 **新闻网**', '分类,可在 URL 中找到,默认为各站点默认分类栏目,如 **新闻网** 即为 **头条关注**']">
订阅 **单级** 栏目如 [大连理工大学新闻网](https://news.dlut.edu.cn) 的 [头条关注](https://news.dlut.edu.cn/ttgz.htm) 分类栏目,分为 3 步:
1. 将 URL <https://news.dlut.edu.cn/ttgz.htm> 中 `https://` 与 `.dlut.edu.cn/` 中间的 `news` 作为 `site` 参数填入;
2. 将 `https://news.dlut.edu.cn/` 与 `.htm` 间的 `ttgz` 作为 `category` 参数填入;
3. 最终可获得 [`/dut/news/ttgz`](https://rsshub.app/dut/news/tzgg)。
订阅 **多级** 栏目如 [大连理工大学新闻网](https://news.dlut.edu.cn) 的 [人才培养](https://news.dlut.edu.cn/xwjj01/rcpy.htm) 分类栏目,同样分为 3 步:
1. 将 URL <https://news.dlut.edu.cn/xwjj01/rcpy.htm> 中 `https://` 与 `.dlut.edu.cn/` 中间的 `news` 作为 `site` 参数填入;
2. 把 `https://news.dlut.edu.cn/` 与 `.htm` 间 `xwjj01/rcpy` 作为 `category` 参数填入;
3. 最终可获得 [`/dut/news/xwjj01/rcpy`](https://rsshub.app/dut/news/xwjj01/rcpy)。
::: tip 小提示
大连理工大学大部分站点支持上述通用规则进行订阅。下方的大连理工大学相关路由基本适用于该规则,在其对应的表格中没有提及的分类栏目,可以使用上方的方法自行扩展。
:::
::: tip 小小提示
你会发现 [大连理工大学新闻网](https://news.dlut.edu.cn) 的 [人才培养](https://news.dlut.edu.cn/xwjj01/rcpy.htm) 分类栏目在下方 [**新闻网**](#da-lian-li-gong-da-xue-xin-wen-wang) 参数表格中 `category` 参数为 `rcpy`,并非上面例子中给出的 `xwjj01/rcpy`。这意味着开发者对路由 `/dut/news/xwjj01/rcpy` 指定了快捷方式 `/dut/news/rcpy`。两者的效果是一致的。
:::
</Route>
### 新闻网
<Route author="nczitzk" example="/dut/news" path="/dut/news/:category?" :paramsDesc="['分类,见下表,默认为 [**头条关注**](https://news.dlut.edu.cn/ttgz.htm)']">
| 头条关注 | 新闻聚焦 | 人才培养 | 科学研究 | 交流合作 |
| ---- | ---- | ---- | ---- | ---- |
| ttgz | xwjj | rcpy | kxyj | jlhz |
| 一线风采 | 大工人物 | 图说大工 | 影像大工 | 媒体大工 |
| ---- | ---- | ---- | ---- | ---- |
| yxfc | dgrw | tsdg | yxdg | mtdg |
</Route>
### 人事处
<Route author="nczitzk" example="/dut/perdep" path="/dut/perdep/:category?" :paramsDesc="['分类,见下表,默认为 [**通知公告**](http://perdep.dlut.edu.cn/tzgg/tzgg.htm)']">
| 通知公告 | 工作动态 | 政策法规 |
| ---- | ---- | ---- |
| tzgg | gzdt | zcfg |
::: tip 提示
表格仅呈现了部分分类栏目,更多分类栏目参见 [大连理工大学人事处](http://perdep.dlut.edu.cn),并按照上方 [**通用**](#da-lian-li-gong-da-xue-tong-yong) 规则订阅。
:::
</Route>
### 教务处
<Route author="beautyyuyanli" example="/dut/teach/zytg" path="/dut/teach/:type" :paramsDesc="['通知类型']">
<Route author="beautyyuyanli nczitzk" example="/dut/teach" path="/dut/teach/:category?" :paramsDesc="['分类,见下表,默认为 [**新闻快递**](http://teach.dlut.edu.cn/xwkd/xwkd.htm)']">
| 重要通告 | 新闻快递 | 教学文件 | 其他文件 |
| ---- | ---- | -------------- | ----------- |
| zytg | xwkd | jiaoxuewenjian | qitawenjian |
| 新闻快递 | 重要通告 | 办会公示 |
| ---- | ---- | ---- |
| xwkd | zytg | bhgs |
::: tip 提示
表格仅呈现了部分分类栏目,更多分类栏目参见 [大连理工大学教务处](http://teach.dlut.edu.cn),并按照上方 [**通用**](#da-lian-li-gong-da-xue-tong-yong) 规则订阅。
:::
</Route>
### 研究生院
<Route author="nczitzk" example="/dut/gs" path="/dut/gs/:category?" :paramsDesc="['分类,见下表,默认为 [**重要通知**](http://gs.dlut.edu.cn/zytz.htm)']">
| 重要通知 | 工作动态 | 政策法规 |
| ---- | ---- | ---- |
| zytz | gzdt | zcfg |
| 研究生招生 - 政策文件 | 研究生招生 - 工作动态 | 研究生招生 - 资料下载 |
| ------------ | --------------- | --------------- |
| yjszs/zcwj1 | yjszs/gzdt/gzdt | yjszs/zlxz/zlxz |
::: tip 提示
表格仅呈现了部分分类栏目,更多分类栏目参见 [大连理工大学研究生院](http://gs.dlut.edu.cn),并按照上方 [**通用**](#da-lian-li-gong-da-xue-tong-yong) 规则订阅。
:::
### 软件学院
<Route author="nczitzk" example="/dut/ssdut" path="/dut/ssdut/:category?" :paramsDesc="['分类,见下表,默认为 [**焦点新闻**](http://ssdut.dlut.edu.cn/ywgg/xueyuanxinwen/jdxw.htm)']">
| 焦点新闻 | 综合新闻 | 学院通知 | 学术动态 | 本科生通知 | 研究生通知 |
| ---- | ---- | ---- | ---- | ----- | ----- |
| jdxw | zhxw | xytz | xsdt | bkstz | yjstz |
::: tip 提示
表格仅呈现了部分分类栏目,更多分类栏目参见 [大连理工大学软件学院](http://ssdut.dlut.edu.cn),并按照上方 [**通用**](#da-lian-li-gong-da-xue-tong-yong) 规则订阅。
:::
</Route>
### 开发区校区
<Route author="nczitzk" example="/dut/eda" path="/dut/eda/:category?" :paramsDesc="['分类,见下表,默认为 [**通知公告**](http://eda.dlut.edu.cn/tzgg/tzgg.htm)']">
| 通知公告 | 校区新闻 |
| ---- | ---- |
| tzgg | xqxw |
::: tip 提示
表格仅呈现了部分分类栏目,更多分类栏目参见 [大连理工大学开发区校区](http://eda.dlut.edu.cn),并按照上方 [**通用**](#da-lian-li-gong-da-xue-tong-yong) 规则订阅。
:::
</Route>
### 国际合作与交流处(港澳台办)
<Route author="beautyyuyanli nczitzk" example="/dut/dutdice" path="/dut/dutdice/:category?" :paramsDesc="['分类,见下表,默认为 [**新闻速递**](http://dutdice.dlut.edu.cn/xwsd/xxxw.htm)']">
| 教师通知 | 学生通知 | 新闻速递 |
| ---- | ---------- | ---- |
| jstz | xstong_zhi | xwsd |
::: tip 提示
表格仅呈现了部分分类栏目,更多分类栏目参见 [大连理工大学国际合作与交流处(港澳台办)](http://dutdice.dlut.edu.cn),并按照上方 [**通用**](#da-lian-li-gong-da-xue-tong-yong) 规则订阅。
:::
</Route>
### 体育场馆中心
<Route author="beautyyuyanli" example="/dut/tycgzx/hdrc" path="/dut/tycgzx/:type" :paramsDesc="['通知类型']">
<Route author="beautyyuyanli nczitzk" example="/dut/tycgzx" path="/dut/tycgzx/:category?" :paramsDesc="['分类,见下表,默认为 [**通知公告**](http://tycgzx.dlut.edu.cn/tzgg/tzgg.htm)']">
| 通知公告 | 活动日程 | 新闻动态 |
| ---- | ---- | ---- |
| tzgg | hdrc | xwdt |
| 通知公告 | 活动日程 | 新闻动态 | 健康知识 |
| ---- | ---- | ---- | ---- |
| tzgg | hdrc | xwdt | jkzs |
</Route>
::: tip 提示
### 国际处及港澳台办
表格仅呈现了部分分类栏目,更多分类栏目参见 [大连理工大学体育场馆中心](http://tycgzx.dlut.edu.cn),并按照上方 [**通用**](#da-lian-li-gong-da-xue-tong-yong) 规则订阅。
<Route author="beautyyuyanli" example="/dut/dutdice/xwsd" path="/dut/dutdice/:type" :paramsDesc="['通知类型']">
| 学生通知 | 教师通知 | 新闻速递 |
| ---------- | ---- | ---- |
| xstong_zhi | jstz | xwsd |
:::
</Route>
@@ -1595,7 +1723,7 @@ type 列表:
将其替换到 RSS 路由地址中即可:
<https://rsshub&#46;app/**nuist**/`bulletin`> 或 <https://rsshub&#46;app/**nuist**/`bulletin`/`791`>
[https://rsshub.app/**nuist**/`bulletin`](https://rsshub.app/nuist/bulletin) 或 [https://rsshub.app/**nuist**/`bulletin`/`791`](https://rsshub.app/nuist/bulletin)
:::
+1 -1
View File
@@ -510,7 +510,7 @@ router.get('/dpu/jiaowu/news/:type?', lazyloadRouteHandler('./routes/universitie
router.get('/dpu/wlfw/news/:type?', lazyloadRouteHandler('./routes/universities/dpu/wlfw/news'));
// 大连理工大学
router.get('/dut/:subsite/:type', lazyloadRouteHandler('./routes/universities/dut/index'));
// router.get('/dut/:subsite/:type', lazyloadRouteHandler('./routes/universities/dut/index'));
// 东南大学
router.get('/seu/radio/academic', lazyloadRouteHandler('./routes/universities/seu/radio/academic'));
-60
View File
@@ -1,60 +0,0 @@
const got = require('@/utils/got');
const cheerio = require('cheerio');
const { parseDate } = require('@/utils/parse-date');
const timezone = require('@/utils/timezone');
const subsiteDic = require('./subsite.js');
module.exports = async (ctx) => {
const subsiteMap = subsiteDic[ctx.params.subsite];
const typeMap = subsiteMap.typeMap[ctx.params.type];
const frontUrl = typeMap.url;
const basePath = typeMap.basePath;
const response = await got({
method: 'get',
url: frontUrl,
});
const data = response.data;
const $ = cheerio.load(data);
const list = $(subsiteMap.listSelector)
.map((index, item) => {
item = $(item);
return {
title: subsiteMap.titleMethod(item),
// description,
link: subsiteMap.linkMethod(item),
pubDate: timezone(parseDate(subsiteMap.pubDateMethod(item), 'YYYY/MM/DD'), +8),
};
})
.get();
const entries = await Promise.all(
list.map(async (item) => {
const { title, link, pubDate } = item;
const entryUrl = basePath + link;
const cache = await ctx.cache.tryGet(entryUrl, async () => {
const response = await got({
method: 'get',
url: entryUrl,
});
const $ = cheerio.load(response.data);
const description = subsiteMap.descriptionMethod($);
const entry = {
title,
link,
pubDate,
description,
};
return JSON.stringify(entry);
});
return Promise.resolve(JSON.parse(cache));
})
);
ctx.state.data = {
title: typeMap.title,
link: frontUrl,
item: entries,
};
};
-50
View File
@@ -1,50 +0,0 @@
const titleMethod1 = (item) => item.find('a').text();
const linkMethod1 = (item) => item.find('a').attr().href;
const pubDateMethod1 = (item) => item.find('span').text();
const descriptionMethod1 = ($) => {
const main = $('.v_news_content').html();
let attachment = $('form ul').html();
// attachment = (attachment ? attachment : '').replace(/<li>/g, '<li><p>').replace(/<\/li>/g, '</p></li>');
attachment = (attachment ? attachment : '').replace(/<li>/g, '<br><li>');
return main + '<br>' + attachment;
};
const subsiteDic = {
teach: {
listSelector: '.list > ul > li',
titleMethod: titleMethod1,
linkMethod: linkMethod1,
pubDateMethod: pubDateMethod1,
descriptionMethod: descriptionMethod1,
typeMap: {
zytg: { title: '大连理工大学教务处-重要通告', url: 'https://teach.dlut.edu.cn/zytg/zytg.htm', basePath: 'https://teach.dlut.edu.cn/zytg/' },
xwkd: { title: '大连理工大学教务处-新闻快递', url: 'https://teach.dlut.edu.cn/xwkd/xwkd.htm', basePath: 'https://teach.dlut.edu.cn/xwkd/' },
qitawenjian: { title: '大连理工大学教务处-其他文件', url: 'https://teach.dlut.edu.cn/qitawenjian/list.jsp?urltype=tree.TreeTempUrl&wbtreeid=1081', basePath: 'https://teach.dlut.edu.cn/qitawenjian/' },
jiaoxuewenjian: { title: '大连理工大学教务处-教学文件', url: 'https://teach.dlut.edu.cn/jiaoxuewenjian/list.jsp?urltype=tree.TreeTempUrl&wbtreeid=1082', basePath: 'https://teach.dlut.edu.cn/jiaoxuewenjian/' },
},
},
dutdice: {
listSelector: '.list01 li',
titleMethod: titleMethod1,
linkMethod: linkMethod1,
pubDateMethod: pubDateMethod1,
descriptionMethod: descriptionMethod1,
typeMap: {
xstong_zhi: { title: '大连理工大学国际处及港澳台办-学生通知', url: 'http://dutdice.dlut.edu.cn/tzgg/xstong_zhi.htm', basePath: 'http://dutdice.dlut.edu.cn/tzgg/' },
jstz: { title: '大连理工大学国际处及港澳台办-教师通知', url: 'http://dutdice.dlut.edu.cn/tzgg/jstz.htm', basePath: 'http://dutdice.dlut.edu.cn/tzgg/' },
xwsd: { title: '大连理工大学国际处及港澳台办-新闻速递', url: 'http://dutdice.dlut.edu.cn/xwsd/xxxw.htm', basePath: 'http://dutdice.dlut.edu.cn/xwsd/' },
},
},
tycgzx: {
listSelector: '.list li',
titleMethod: titleMethod1,
linkMethod: linkMethod1,
pubDateMethod: pubDateMethod1,
descriptionMethod: descriptionMethod1,
typeMap: {
tzgg: { title: '大连理工大学体育场馆中心-通知公告', url: 'http://tycgzx.dlut.edu.cn/tzgg/tzgg.htm', basePath: 'http://tycgzx.dlut.edu.cn/tzgg/' },
hdrc: { title: '大连理工大学体育场馆中心-活动日程', url: 'http://tycgzx.dlut.edu.cn/hdrc/hdrc.htm', basePath: 'http://tycgzx.dlut.edu.cn/hdrc/' },
xwdt: { title: '大连理工大学体育场馆中心-新闻动态', url: 'http://tycgzx.dlut.edu.cn/xwdt/xwdt.htm', basePath: 'http://tycgzx.dlut.edu.cn/xwdt/' },
},
},
};
module.exports = subsiteDic;
+33
View File
@@ -0,0 +1,33 @@
module.exports = {
// 新闻网:https://news.dlut.edu.cn
// 默认 -> 头条关注 https://news.dlut.edu.cn/ttgz.htm
news: 'ttgz',
// 教务处:http://teach.dlut.edu.cn
// 默认 -> 新闻快递 http://teach.dlut.edu.cn/xwkd/xwkd.htm
teach: 'xwkd/xwkd',
// 人事处:http://perdep.dlut.edu.cn
// 默认 -> 通知公告 http://perdep.dlut.edu.cn/tzgg/tzgg.htm
perdep: 'tzgg/tzgg',
// 研究生院:http://gs.dlut.edu.cn
// 默认 -> 重要通知 http://gs.dlut.edu.cn/zytz.htm
gs: 'zytz',
// 软件学院:http://ssdut.dlut.edu.cn
// 默认 -> 焦点新闻 http://ssdut.dlut.edu.cn/ywgg/xueyuanxinwen/jdxw.htm
ssdut: 'ywgg/xueyuanxinwen/jdxw',
// 开发区校区:http://eda.dlut.edu.cn
// 默认 -> 通知公告 http://eda.dlut.edu.cn/tzgg/tzgg.htm
eda: 'tzgg/tzgg',
// 国际合作与交流处(港澳台办):http://dutdice.dlut.edu.cn
// 默认 -> 新闻速递 http://dutdice.dlut.edu.cn/xwsd/xxxw.htm
dutdice: 'xwsd/xxxw',
// 体育场馆中心:http://tycgzx.dlut.edu.cn
// 默认 -> 通知公告 http://tycgzx.dlut.edu.cn/tzgg/tzgg.htm
tycgzx: 'tzgg/tzgg',
};
+73
View File
@@ -0,0 +1,73 @@
const got = require('@/utils/got');
const cheerio = require('cheerio');
const { parseDate } = require('@/utils/parse-date');
const defaults = require('./defaults');
const shortcuts = require('./shortcuts');
module.exports = async (ctx) => {
const site = ctx.params[0] ?? 'news';
let category = ctx.params[1] ?? (defaults.hasOwnProperty(site) ? defaults[site] : '');
category = shortcuts.hasOwnProperty(site) ? (shortcuts[site].hasOwnProperty(category) ? shortcuts[site][category] : category) : category;
const rootUrl = `https://${site}.dlut.edu.cn`;
const currentUrl = `${rootUrl}/${category}.htm`;
const response = await got({
method: 'get',
url: currentUrl,
});
const $ = cheerio.load(response.data);
$('.Next, .rjxw_left, .pb_sys_common').remove();
let items = $('.txt, .itemlist, .wall, .list, .list01, .ny_list, .rjxw_right, .rj_yjs_con, .c_hzjl_list1')
.find('a')
.slice(0, ctx.query.limit ? parseInt(ctx.query.limit) : 50)
.toArray()
.map((item) => {
item = $(item);
const dateRegex = /(\d{4}[-/年]\d{2}[-/月]\d{2})/;
let dateMatch = item.parent().text().match(dateRegex);
if (!dateMatch) {
dateMatch = item.parent().parent().text().match(dateRegex);
}
return {
title: item.text() === '' ? item.next().text() : item.text(),
link: /^http/.test(item.attr('href')) ? item.attr('href') : `${rootUrl}/${item.attr('href').replace(/^[./]+/, '')}`,
pubDate: parseDate(dateMatch ? dateMatch[1].replace(/年|月/g, '-') : new Date().toString()),
};
});
items = await Promise.all(
items.map((item) =>
ctx.cache.tryGet(item.link, async () => {
try {
const detailResponse = await got({
method: 'get',
url: item.link,
});
const content = cheerio.load(detailResponse.data);
item.description = content('.v_news_content, .conbox').html();
} catch (err) {
// Fo example: http://dutdice.dlut.edu.cn/nry.jsp?urltype=news.NewsContentUrl&wbtreeid=1006&wbnewsid=9820
// do nothing to the cases which require fetching resources from the Intranet :P
}
return item;
})
)
);
ctx.state.data = {
title: $('title').text(),
link: currentUrl,
item: items,
allowEmpty: true,
};
};
+10
View File
@@ -0,0 +1,10 @@
module.exports = {
'/news/:category?': ['nczitzk'],
'/perdep/:category?': ['nczitzk'],
'/teach/:category?': ['beautyyuyanli', 'nczitzk'],
'/gs/:category?': ['nczitzk'],
'/ssdut/:category?': ['nczitzk'],
'/eda/:category?': ['nczitzk'],
'/dutdice/:category?': ['beautyyuyanli', 'nczitzk'],
'/tycgzx/:category?': ['beatyyuyanli', 'nczitzk'],
};
+69
View File
@@ -0,0 +1,69 @@
module.exports = {
'dlut.edu.cn': {
_name: '大连理工大学',
news: [
{
title: '新闻网',
docs: 'https://docs.rsshub.app/university.html#da-lian-li-gong-da-xue-xin-wen-wang',
source: ['/'],
target: '/dut/news/:category?',
},
],
perdep: [
{
title: '人事处',
docs: 'https://docs.rsshub.app/university.html#da-lian-li-gong-da-xue-ren-shi-chu',
source: ['/'],
target: '/dut/perdep/:category?',
},
],
teach: [
{
title: '教务处',
docs: 'https://docs.rsshub.app/university.html#da-lian-li-gong-da-xue-jiao-wu-chu',
source: ['/'],
target: '/dut/teach/:category?',
},
],
gs: [
{
title: '研究生院',
docs: 'https://docs.rsshub.app/university.html#da-lian-li-gong-da-xue-yan-jiu-sheng-yuan',
source: ['/'],
target: '/dut/gs/:category?',
},
],
ssdut: [
{
title: '软件学院',
docs: 'https://docs.rsshub.app/university.html#da-lian-li-gong-da-xue-ruan-jian-xue-yuan',
source: ['/'],
target: '/dut/ssdut/:category?',
},
],
eda: [
{
title: '开发区校区',
docs: 'https://docs.rsshub.app/university.html#da-lian-li-gong-da-xue-kai-fa-qu-xiao-qu',
source: ['/'],
target: '/dut/eda/:category?',
},
],
dutdice: [
{
title: '国际合作与交流处(港澳台办)',
docs: 'https://docs.rsshub.app/university.html#da-lian-li-gong-da-xue-guo-ji-he-zuo-yu-jiao-liu-chu-gang-ao-tai-ban',
source: ['/'],
target: '/dut/dutdice/:category?',
},
],
tycgzx: [
{
title: '体育场馆中心',
docs: 'https://docs.rsshub.app/university.html#da-lian-li-gong-da-xue-ti-yu-chang-guan-zhong-xin',
source: ['/'],
target: '/dut/tycgzx/:category?',
},
],
},
};
+4
View File
@@ -0,0 +1,4 @@
module.exports = function (router) {
router.get(/([\w\d]+)\/([\w\d/]+)?/, require('./index'));
router.get('/:0?', require('./index'));
};
+49
View File
@@ -0,0 +1,49 @@
module.exports = {
news: {
xwjj: 'xwjj01',
rcpy: 'xwjj01/rcpy',
kxyj: 'xwjj01/kxyj',
jlhz: 'xwjj01-kxyj',
yxfc: 'yxfc1',
dgrw: 'dgrw/dgrw1',
yxdg: 'yxdg1',
mtdg: 'mtdg/mtdg',
},
teach: {
xwkd: 'xwkd/xwkd',
zytg: 'zytg/zytg',
bhgs: 'zytg/bhgs',
},
perdep: {
tzgg: 'tzgg/tzgg',
gzdt: 'gzdt/gzdt1',
zcfg: 'zcfg/zcfg',
},
gs: {
gzdt: 'gzdt1',
zcfg: 'zcfg/zcfg',
},
ssdut: {
jdxw: 'ywgg/xueyuanxinwen/jdxw',
zhxw: 'ywgg/xueyuanxinwen',
xytz: 'index/xytz',
xsdt: 'index/xsdt',
bkstz: 'index/bkstz',
yjstz: 'yjspy/yjspy/yjstz',
},
eda: {
tzgg: 'tzgg/tzgg',
xqxw: 'xqxw/xqxw',
},
dutdice: {
jstz: 'tzgg/jstz',
xstong_zhi: 'tzgg/xstong_zhi',
xwsd: 'xwsd/xxxw',
},
tycgzx: {
tzgg: 'tzgg/tzgg',
hdrc: 'hdrc/hdrc',
xwdt: 'xwdt/xwdt',
jkzs: 'jkzs/jkzs1',
},
};