From c41375aeb5dc8c6d59969f797d5cbd1fdb60754d Mon Sep 17 00:00:00 2001
From: ueiu <39592269+ueiu@users.noreply.github.com>
Date: Fri, 15 Dec 2023 21:21:19 +0800
Subject: [PATCH 1/5] =?UTF-8?q?feat(route):=20add=20=E5=A4=A7=E8=BF=9E?=
=?UTF-8?q?=E7=90=86=E5=B7=A5=E5=A4=A7=E5=AD=A6=E5=85=AC=E5=85=B1=E5=9F=BA?=
=?UTF-8?q?=E7=A1=80=E5=AD=A6=E9=99=A2=20RSS=20(#13982)=20(#14007)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
* Update index.js
* fix(route): 中国政府网没有正确拼接相对地址路径 && 替换滚动新闻地址
* feat(route): add 大连理工大学公共基础学院 RSS (#13982)
* 移除 pubDate 使用 new Date
* 增加默认路由设置
* 完善 公共基础学院 说明文档
* 根据修改建议修改代码
* fix: sort maintainer
---------
---
lib/v2/dut/defaults.js | 4 ++
lib/v2/dut/index.js | 30 ++++++++++----
lib/v2/dut/maintainer.js | 15 +++----
lib/v2/dut/radar.js | 66 +++++++++++++++++-------------
lib/v2/dut/shortcuts.js | 5 +++
website/docs/routes/university.mdx | 16 ++++++++
6 files changed, 91 insertions(+), 45 deletions(-)
diff --git a/lib/v2/dut/defaults.js b/lib/v2/dut/defaults.js
index e64da872460f41..30c00a314394de 100644
--- a/lib/v2/dut/defaults.js
+++ b/lib/v2/dut/defaults.js
@@ -50,4 +50,8 @@ module.exports = {
// 体育场馆中心:http://tycgzx.dlut.edu.cn
// 默认 -> 通知公告 http://tycgzx.dlut.edu.cn/tzgg/tzgg.htm
tycgzx: 'tzgg/tzgg',
+
+ // 公共基础学院:http://fldpj.dlut.edu.cn/index.htm
+ // 默认 -> 重要通知 http://fldpj.dlut.edu.cn/index/zytz.htm
+ fldpj: 'index/zytz',
};
diff --git a/lib/v2/dut/index.js b/lib/v2/dut/index.js
index 6efb5a4e2cc28b..9ff5ff06a58b5e 100644
--- a/lib/v2/dut/index.js
+++ b/lib/v2/dut/index.js
@@ -27,6 +27,8 @@ module.exports = async (ctx) => {
if (site === 'panjin') {
items = $('a.news').slice(0, -4);
+ } else if (site === 'fldpj') {
+ items = $('li[id^="line_u9"]').find('a');
} else {
$('.Next, .rjxw_left, .pb_sys_common').remove();
items = $('.txt, .itemlist, .wall, .list, .list01, .ny_list, .rjxw_right, .rj_yjs_con, .c_hzjl_list1, .winstyle67894, .winstyle80936, .winstyle50738, #lili').find('a');
@@ -38,18 +40,28 @@ module.exports = async (ctx) => {
.map((item) => {
item = $(item);
- const dateRegex = /(\d{4}[-/年]\d{2}[-/月]\d{2})/;
+ const result = {
+ link: item.attr('href').startsWith('http') ? item.attr('href') : `${rootUrl}/${item.attr('href').replace(/^[./]+/, '')}`,
+ };
+
+ if (site === 'fldpj') {
+ result.title = item.find('em').text();
+ result.pubDate = parseDate(item.find('span').text());
+ } else {
+ const dateRegex = /(\d{4}[-/年]\d{2}[-/月]\d{2})/;
+
+ let dateMatch = item.parent().text().match(dateRegex);
+ if (!dateMatch) {
+ dateMatch = item.parent().parent().text().match(dateRegex);
+ }
- let dateMatch = item.parent().text().match(dateRegex);
- if (!dateMatch) {
- dateMatch = item.parent().parent().text().match(dateRegex);
+ result.title = item.text().trim() === '' ? item.next().text() : item.text();
+ if (dateMatch) {
+ result.pubDate = parseDate(dateMatch[1].replace(/年|月/g, '-'));
+ }
}
- 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()),
- };
+ return result;
});
items = await Promise.all(
diff --git a/lib/v2/dut/maintainer.js b/lib/v2/dut/maintainer.js
index 25e6d8292b7c36..8dbc087da2bd31 100644
--- a/lib/v2/dut/maintainer.js
+++ b/lib/v2/dut/maintainer.js
@@ -1,14 +1,15 @@
module.exports = {
- '/news/:category?': ['nczitzk'],
- '/perdep/:category?': ['nczitzk'],
- '/teach/:category?': ['beautyyuyanli', 'nczitzk'],
- '/gs/:category?': ['nczitzk'],
- '/ssdut/:category?': ['nczitzk'],
+ '/dutdice/:category?': ['beautyyuyanli', 'nczitzk'],
'/eda/:category?': ['nczitzk'],
+ '/fldpj/:category?': ['ueiu'],
+ '/gs/:category?': ['nczitzk'],
+ '/news/:category?': ['nczitzk'],
'/panjin/:category?': ['nczitzk'],
- '/xsgzb/:category?': ['nczitzk'],
+ '/perdep/:category?': ['nczitzk'],
'/pjteach/:category?': ['nczitzk'],
'/pjxqzwb/:category?': ['nczitzk'],
- '/dutdice/:category?': ['beautyyuyanli', 'nczitzk'],
+ '/ssdut/:category?': ['nczitzk'],
+ '/teach/:category?': ['beautyyuyanli', 'nczitzk'],
'/tycgzx/:category?': ['beatyyuyanli', 'nczitzk'],
+ '/xsgzb/:category?': ['nczitzk'],
};
diff --git a/lib/v2/dut/radar.js b/lib/v2/dut/radar.js
index 3558a1687d444c..1bd81bedada4fe 100644
--- a/lib/v2/dut/radar.js
+++ b/lib/v2/dut/radar.js
@@ -1,26 +1,26 @@
module.exports = {
'dlut.edu.cn': {
_name: '大连理工大学',
- news: [
+ dutdice: [
{
- title: '新闻网',
- docs: 'https://docs.rsshub.app/routes/university#da-lian-li-gong-da-xue-xin-wen-wang',
+ title: '国际合作与交流处(港澳台办)',
+ docs: 'https://docs.rsshub.app/routes/university#da-lian-li-gong-da-xue-guo-ji-he-zuo-yu-jiao-liu-chu-gang-ao-tai-ban',
source: ['/'],
target: (params, url) => `/dut/${url.match(/:\/\/[\w\d]+\./)[1]}/${url.match(/\.cn\/(.*)\.htm/)[1]}`,
},
],
- perdep: [
+ eda: [
{
- title: '人事处',
- docs: 'https://docs.rsshub.app/routes/university#da-lian-li-gong-da-xue-ren-shi-chu',
+ title: '开发区校区',
+ docs: 'https://docs.rsshub.app/routes/university#da-lian-li-gong-da-xue-kai-fa-qu-xiao-qu',
source: ['/'],
target: (params, url) => `/dut/${url.match(/:\/\/[\w\d]+\./)[1]}/${url.match(/\.cn\/(.*)\.htm/)[1]}`,
},
],
- teach: [
+ fldpj: [
{
- title: '教务处',
- docs: 'https://docs.rsshub.app/routes/university#da-lian-li-gong-da-xue-jiao-wu-chu',
+ title: '公共基础学院',
+ docs: 'https://docs.rsshub.app/routes/university#da-lian-li-gong-da-xue-gong-gong-ji-chu-xue-yuan',
source: ['/'],
target: (params, url) => `/dut/${url.match(/:\/\/[\w\d]+\./)[1]}/${url.match(/\.cn\/(.*)\.htm/)[1]}`,
},
@@ -33,18 +33,10 @@ module.exports = {
target: (params, url) => `/dut/${url.match(/:\/\/[\w\d]+\./)[1]}/${url.match(/\.cn\/(.*)\.htm/)[1]}`,
},
],
- ssdut: [
- {
- title: '软件学院',
- docs: 'https://docs.rsshub.app/routes/university#da-lian-li-gong-da-xue-ruan-jian-xue-yuan',
- source: ['/'],
- target: (params, url) => `/dut/${url.match(/:\/\/[\w\d]+\./)[1]}/${url.match(/\.cn\/(.*)\.htm/)[1]}`,
- },
- ],
- eda: [
+ news: [
{
- title: '开发区校区',
- docs: 'https://docs.rsshub.app/routes/university#da-lian-li-gong-da-xue-kai-fa-qu-xiao-qu',
+ title: '新闻网',
+ docs: 'https://docs.rsshub.app/routes/university#da-lian-li-gong-da-xue-xin-wen-wang',
source: ['/'],
target: (params, url) => `/dut/${url.match(/:\/\/[\w\d]+\./)[1]}/${url.match(/\.cn\/(.*)\.htm/)[1]}`,
},
@@ -57,10 +49,10 @@ module.exports = {
target: (params, url) => `/dut/${url.match(/:\/\/[\w\d]+\./)[1]}/${url.match(/\.cn\/(.*)\.htm/)[1]}`,
},
],
- xsgzb: [
+ perdep: [
{
- title: '盘锦校区学生事务办公室',
- docs: 'https://docs.rsshub.app/routes/university#da-lian-li-gong-da-xue-pan-jin-xiao-qu-xue-sheng-shi-wu-ban-gong-shi',
+ title: '人事处',
+ docs: 'https://docs.rsshub.app/routes/university#da-lian-li-gong-da-xue-ren-shi-chu',
source: ['/'],
target: (params, url) => `/dut/${url.match(/:\/\/[\w\d]+\./)[1]}/${url.match(/\.cn\/(.*)\.htm/)[1]}`,
},
@@ -81,18 +73,26 @@ module.exports = {
target: (params, url) => `/dut/${url.match(/:\/\/[\w\d]+\./)[1]}/${url.match(/\.cn\/(.*)\.htm/)[1]}`,
},
],
- tjpj: [
+ ssdut: [
{
- title: '体育与健康学院盘锦分院',
- docs: 'https://docs.rsshub.app/routes/university#da-lian-li-gong-da-xue-ti-yu-jian-kang-xue-yuan-pan-jin-fen-yuan',
+ title: '软件学院',
+ docs: 'https://docs.rsshub.app/routes/university#da-lian-li-gong-da-xue-ruan-jian-xue-yuan',
source: ['/'],
target: (params, url) => `/dut/${url.match(/:\/\/[\w\d]+\./)[1]}/${url.match(/\.cn\/(.*)\.htm/)[1]}`,
},
],
- dutdice: [
+ teach: [
{
- title: '国际合作与交流处(港澳台办)',
- docs: 'https://docs.rsshub.app/routes/university#da-lian-li-gong-da-xue-guo-ji-he-zuo-yu-jiao-liu-chu-gang-ao-tai-ban',
+ title: '教务处',
+ docs: 'https://docs.rsshub.app/routes/university#da-lian-li-gong-da-xue-jiao-wu-chu',
+ source: ['/'],
+ target: (params, url) => `/dut/${url.match(/:\/\/[\w\d]+\./)[1]}/${url.match(/\.cn\/(.*)\.htm/)[1]}`,
+ },
+ ],
+ tjpj: [
+ {
+ title: '体育与健康学院盘锦分院',
+ docs: 'https://docs.rsshub.app/routes/university#da-lian-li-gong-da-xue-ti-yu-jian-kang-xue-yuan-pan-jin-fen-yuan',
source: ['/'],
target: (params, url) => `/dut/${url.match(/:\/\/[\w\d]+\./)[1]}/${url.match(/\.cn\/(.*)\.htm/)[1]}`,
},
@@ -105,5 +105,13 @@ module.exports = {
target: (params, url) => `/dut/${url.match(/:\/\/[\w\d]+\./)[1]}/${url.match(/\.cn\/(.*)\.htm/)[1]}`,
},
],
+ xsgzb: [
+ {
+ title: '盘锦校区学生事务办公室',
+ docs: 'https://docs.rsshub.app/routes/university#da-lian-li-gong-da-xue-pan-jin-xiao-qu-xue-sheng-shi-wu-ban-gong-shi',
+ source: ['/'],
+ target: (params, url) => `/dut/${url.match(/:\/\/[\w\d]+\./)[1]}/${url.match(/\.cn\/(.*)\.htm/)[1]}`,
+ },
+ ],
},
};
diff --git a/lib/v2/dut/shortcuts.js b/lib/v2/dut/shortcuts.js
index 9dd64655e7e880..70e6ab507c35f2 100644
--- a/lib/v2/dut/shortcuts.js
+++ b/lib/v2/dut/shortcuts.js
@@ -74,4 +74,9 @@ module.exports = {
xwdt: 'xwdt/xwdt',
jkzs: 'jkzs/jkzs1',
},
+ fldpj: {
+ xsdt: 'kxyj/xsdt',
+ zytz: 'index/zytz',
+ ywgk: 'index/ywgk',
+ },
};
diff --git a/website/docs/routes/university.mdx b/website/docs/routes/university.mdx
index 0454a67efa206b..282cfa3ad09209 100644
--- a/website/docs/routes/university.mdx
+++ b/website/docs/routes/university.mdx
@@ -875,6 +875,22 @@ Note:[Source website](https://ece.umass.edu/seminar) may be empty when there's
:::
+### 公共基础学院 {#da-lian-li-gong-da-xue-gong-gong-ji-chu-xue-yuan}
+
+
+
+| 重要通知 | 学术动态 | 院务公开 |
+| -------- | -------- | -------- |
+| zytz | xsdt | ywgk |
+
+:::tip
+
+表格仅呈现了部分分类栏目,更多分类栏目参见 [大连理工大学公共基础学院](http://fldpj.dlut.edu.cn/index.htm),并按照上方 [**通用**](#da-lian-li-gong-da-xue-tong-yong) 规则订阅。
+
+:::
+
+
+
## 电子科技大学 {#dian-zi-ke-ji-da-xue}
### 研究生院 {#dian-zi-ke-ji-da-xue-yan-jiu-sheng-yuan}
From c7518e4619d73d416498c42aa3327dc4fbbdeeeb Mon Sep 17 00:00:00 2001
From: "github-actions[bot]"
<41898282+github-actions[bot]@users.noreply.github.com>
Date: Fri, 15 Dec 2023 13:22:59 +0000
Subject: [PATCH 2/5] style: auto format
---
website/docs/routes/university.mdx | 16 ++++++----------
1 file changed, 6 insertions(+), 10 deletions(-)
diff --git a/website/docs/routes/university.mdx b/website/docs/routes/university.mdx
index 282cfa3ad09209..0accaaa82ffa76 100644
--- a/website/docs/routes/university.mdx
+++ b/website/docs/routes/university.mdx
@@ -878,17 +878,13 @@ Note:[Source website](https://ece.umass.edu/seminar) may be empty when there's
### 公共基础学院 {#da-lian-li-gong-da-xue-gong-gong-ji-chu-xue-yuan}
+ | 重要通知 | 学术动态 | 院务公开 |
+ | -------- | -------- | -------- |
+ | zytz | xsdt | ywgk |
-| 重要通知 | 学术动态 | 院务公开 |
-| -------- | -------- | -------- |
-| zytz | xsdt | ywgk |
-
-:::tip
-
-表格仅呈现了部分分类栏目,更多分类栏目参见 [大连理工大学公共基础学院](http://fldpj.dlut.edu.cn/index.htm),并按照上方 [**通用**](#da-lian-li-gong-da-xue-tong-yong) 规则订阅。
-
-:::
-
+ :::tip
+ 表格仅呈现了部分分类栏目,更多分类栏目参见 [大连理工大学公共基础学院](http://fldpj.dlut.edu.cn/index.htm),并按照上方 [**通用**](#da-lian-li-gong-da-xue-tong-yong) 规则订阅。
+ :::
## 电子科技大学 {#dian-zi-ke-ji-da-xue}
From fac29ed93b6fd1c4cfe378b7fb5169778d93e922 Mon Sep 17 00:00:00 2001
From: Jack Bryant
Date: Fri, 15 Dec 2023 22:00:03 +0800
Subject: [PATCH 3/5] feat(route): add fxiaoke.com blog (#14046)
* feat(route): add fxiaoke.com blog
* Update lib/v2/fxiaoke/radar.js
* Update lib/v2/fxiaoke/radar.js
* Update lib/v2/fxiaoke/radar.js
* Update lib/v2/fxiaoke/radar.js
* Update lib/v2/fxiaoke/radar.js
* Update lib/v2/fxiaoke/radar.js
* Update lib/v2/fxiaoke/crm.js
* gen exact pubdate
---------
---
lib/v2/fxiaoke/crm.js | 63 ++++++++++++++++++++++++++++++++++++
lib/v2/fxiaoke/maintainer.js | 3 ++
lib/v2/fxiaoke/radar.js | 37 +++++++++++++++++++++
lib/v2/fxiaoke/router.js | 3 ++
website/docs/routes/blog.mdx | 10 ++++++
5 files changed, 116 insertions(+)
create mode 100644 lib/v2/fxiaoke/crm.js
create mode 100644 lib/v2/fxiaoke/maintainer.js
create mode 100644 lib/v2/fxiaoke/radar.js
create mode 100644 lib/v2/fxiaoke/router.js
diff --git a/lib/v2/fxiaoke/crm.js b/lib/v2/fxiaoke/crm.js
new file mode 100644
index 00000000000000..c62ce673e6202a
--- /dev/null
+++ b/lib/v2/fxiaoke/crm.js
@@ -0,0 +1,63 @@
+const got = require('@/utils/got');
+const cheerio = require('cheerio');
+const { parseDate } = require('@/utils/parse-date');
+const baseUrl = 'https://www.fxiaoke.com/crm';
+const baseTitle = '纷享销客 CRM';
+const titleMap = new Map([
+ ['news', `全部文章 - ${baseTitle}`],
+ ['blog', `文章干货 - ${baseTitle}`],
+ ['articles', `CRM 知识 - ${baseTitle}`],
+ ['about-influence', `纷享动态 - ${baseTitle}`],
+ ['customers', `签约喜报 - ${baseTitle}`],
+]);
+
+module.exports = async (ctx) => {
+ const t = ctx.params.type;
+ const title = titleMap.get(t);
+ const url = `${baseUrl}/${t}/`;
+ const resp = await got(url);
+ const $ = cheerio.load(resp.data);
+ const desc = $('.meeting').text().trim();
+ let items = $('.content-item')
+ .toArray()
+ .map((item) => {
+ item = $(item);
+ const c1 = item.find('.baike-content-t1');
+ const c3 = item.find('.baike-content-t3').find('span');
+ return {
+ title: c1.text().trim(),
+ // pubDate: parseDate(c3.first().text().trim()),
+ link: item.find('a').attr('href'),
+ author: c3.last().text().trim(),
+ };
+ });
+ items = await Promise.all(
+ items.map((item) =>
+ ctx.cache.tryGet(item.link, async () => {
+ const resp = await got(item.link);
+ const $ = cheerio.load(resp.data);
+ const firstViewBox = $('.body-wrapper-article').first();
+
+ firstViewBox.find('img').each((_, img) => {
+ img = $(img);
+ if (img.attr('zoomfile')) {
+ img.attr('src', img.attr('zoomfile'));
+ img.removeAttr('zoomfile');
+ img.removeAttr('file');
+ }
+ img.removeAttr('onmouseover');
+ });
+
+ item.description = firstViewBox.html();
+ item.pubDate = parseDate($('.month-day').first().text().trim());
+ return item;
+ })
+ )
+ );
+ ctx.state.data = {
+ title,
+ link: url,
+ description: desc,
+ item: items,
+ };
+};
diff --git a/lib/v2/fxiaoke/maintainer.js b/lib/v2/fxiaoke/maintainer.js
new file mode 100644
index 00000000000000..ded6b214b0c54a
--- /dev/null
+++ b/lib/v2/fxiaoke/maintainer.js
@@ -0,0 +1,3 @@
+module.exports = {
+ '/crm/:type': ['akynazh'],
+};
diff --git a/lib/v2/fxiaoke/radar.js b/lib/v2/fxiaoke/radar.js
new file mode 100644
index 00000000000000..067c8506854e1a
--- /dev/null
+++ b/lib/v2/fxiaoke/radar.js
@@ -0,0 +1,37 @@
+module.exports = {
+ 'fxiaoke.com': {
+ _name: '纷享销客 CRM',
+ '.': [
+ {
+ title: '全部文章',
+ docs: 'https://docs.rsshub.app/routes/blog#fen-xiang-xiao-ke-crm',
+ source: ['/*'],
+ target: '/fxiaoke/crm/news',
+ },
+ {
+ title: '文章干货',
+ docs: 'https://docs.rsshub.app/routes/blog#fen-xiang-xiao-ke-crm',
+ source: ['/*'],
+ target: '/fxiaoke/crm/blog',
+ },
+ {
+ title: 'CRM 知识',
+ docs: 'https://docs.rsshub.app/routes/blog#fen-xiang-xiao-ke-crm',
+ source: ['/*'],
+ target: '/fxiaoke/crm/articles',
+ },
+ {
+ title: '纷享动态',
+ docs: 'https://docs.rsshub.app/routes/blog#fen-xiang-xiao-ke-crm',
+ source: ['/*'],
+ target: '/fxiaoke/crm/about-influence',
+ },
+ {
+ title: '签约喜报',
+ docs: 'https://docs.rsshub.app/routes/blog#fen-xiang-xiao-ke-crm',
+ source: ['/*'],
+ target: '/fxiaoke/crm/customers',
+ },
+ ],
+ },
+};
diff --git a/lib/v2/fxiaoke/router.js b/lib/v2/fxiaoke/router.js
new file mode 100644
index 00000000000000..bd6557d1a5c8b5
--- /dev/null
+++ b/lib/v2/fxiaoke/router.js
@@ -0,0 +1,3 @@
+module.exports = function (router) {
+ router.get('/crm/:type', require('./crm'));
+};
diff --git a/website/docs/routes/blog.mdx b/website/docs/routes/blog.mdx
index 635a8ab95fc79a..45ff162740e73a 100644
--- a/website/docs/routes/blog.mdx
+++ b/website/docs/routes/blog.mdx
@@ -375,6 +375,16 @@ Limit the number of entries to be retrieved by adding `?limit=x` to the end of t
| windows | android | tutorial | other |
+## 纷享销客 CRM {#fen-xiang-xiao-ke-crm}
+
+### 文章 {#fen-xiang-xiao-ke-crm-wen-zhang}
+
+
+ | 全部文章 | 文章干货 | CRM 知识 | 纷享动态 | 签约喜报 |
+ | -------- | -------- | -------- | --------------- | --------- |
+ | news | blog | articles | about-influence | customers |
+
+
## 虎皮椒 {#hu-pi-jiao}
### 文章 {#hu-pi-jiao-wen-zhang}
From a1644ac4cafb8a4ba76745208a86924d92ef9eb5 Mon Sep 17 00:00:00 2001
From: Tony
Date: Fri, 15 Dec 2023 14:37:12 +0000
Subject: [PATCH 4/5] feat: title case following The Chicago Manual of Style
(#14048)
---
lib/utils/common-utils.js | 8 +--
package.json | 1 +
pnpm-lock.yaml | 141 ++++++++++++++++++++++++++++++++++++-
test/utils/common-utils.js | 2 +-
4 files changed, 142 insertions(+), 10 deletions(-)
diff --git a/lib/utils/common-utils.js b/lib/utils/common-utils.js
index 4e29e5086046ab..661b343c527a21 100644
--- a/lib/utils/common-utils.js
+++ b/lib/utils/common-utils.js
@@ -1,12 +1,8 @@
const { parseDate } = require('@/utils/parse-date');
+const title = require('title');
// convert a string into title case
-const toTitleCase = (str) =>
- str
- .toLowerCase()
- .split(' ')
- .map((word) => word.replace(word[0], word[0].toUpperCase()))
- .join(' ');
+const toTitleCase = (str) => title(str);
const rWhiteSpace = /\s+/;
const rAllWhiteSpace = /\s+/g;
diff --git a/package.json b/package.json
index 90348ce6a42233..e01ea5af410fa4 100644
--- a/package.json
+++ b/package.json
@@ -144,6 +144,7 @@
"socks-proxy-agent": "8.0.2",
"source-map": "0.7.4",
"tiny-async-pool": "2.1.0",
+ "title": "3.5.3",
"tough-cookie": "4.1.3",
"twitter-api-v2": "1.15.2",
"winston": "3.11.0",
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 90bb01945dbb32..a843cb748848af 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -188,6 +188,9 @@ dependencies:
tiny-async-pool:
specifier: 2.1.0
version: 2.1.0
+ title:
+ specifier: 3.5.3
+ version: 3.5.3
tough-cookie:
specifier: 4.1.3
version: 4.1.3
@@ -1692,7 +1695,7 @@ packages:
/@types/mdast@4.0.3:
resolution: {integrity: sha512-LsjtqsyF+d2/yFOYaN22dHZI1Cpwkrj+g06G8+qtUKlhovPW89YhqSnfKtMbkgmEtYpH2gydRNULd6y8mciAFg==}
dependencies:
- '@types/unist': 2.0.7
+ '@types/unist': 3.0.2
dev: true
/@types/mdurl@1.0.2:
@@ -2013,6 +2016,10 @@ packages:
resolution: {integrity: sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==}
dev: true
+ /arch@2.2.0:
+ resolution: {integrity: sha512-Of/R0wqp83cgHozfIYLbBMnej79U/SVGOOyuB3VVFv1NRM/PSFMK12x9KVtiYzJqmnU5WR2qp0Z5rHb7sWGnFQ==}
+ dev: false
+
/are-we-there-yet@2.0.0:
resolution: {integrity: sha512-Ci/qENmwHnsYo9xKIcUJN5LeDKdJ6R1Z1j9V/J5wyq8nh/mYPEpIKJbBZXtZjG04HiK7zV/p6Vs9952MrMeUIw==}
engines: {node: '>=10'}
@@ -2021,6 +2028,10 @@ packages:
readable-stream: 3.6.2
dev: true
+ /arg@1.0.0:
+ resolution: {integrity: sha512-Wk7TEzl1KqvTGs/uyhmHO/3XLd3t1UeU4IstvPXVzGPM522cTjqjNZ99esCkcL52sjqjo8e8CTBcWhkxvGzoAw==}
+ dev: false
+
/argparse@1.0.10:
resolution: {integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==}
dependencies:
@@ -2393,6 +2404,15 @@ packages:
resolution: {integrity: sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==}
dev: true
+ /chalk@2.3.0:
+ resolution: {integrity: sha512-Az5zJR2CBujap2rqXGaJKaPHyJ0IrUimvYNX+ncCy8PJP4ltOGTrHUIo097ZaL2zMeKYpiCdqDvS6zdrTFok3Q==}
+ engines: {node: '>=4'}
+ dependencies:
+ ansi-styles: 3.2.1
+ escape-string-regexp: 1.0.5
+ supports-color: 4.5.0
+ dev: false
+
/chalk@2.4.2:
resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==}
engines: {node: '>=4'}
@@ -2575,6 +2595,14 @@ packages:
string-width: 7.0.0
dev: true
+ /clipboardy@1.2.2:
+ resolution: {integrity: sha512-16KrBOV7bHmHdxcQiCvfUFYVFyEah4FI8vYT1Fr7CGSA4G+xBWMEfUEQJS1hxeHGtI9ju1Bzs9uXSbj5HZKArw==}
+ engines: {node: '>=4'}
+ dependencies:
+ arch: 2.2.0
+ execa: 0.8.0
+ dev: false
+
/cliui@8.0.1:
resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==}
engines: {node: '>=12'}
@@ -2781,6 +2809,14 @@ packages:
- encoding
dev: false
+ /cross-spawn@5.1.0:
+ resolution: {integrity: sha512-pTgQJ5KC0d2hcY8eyL1IzlBPYjTkyH72XRZPnLyKus2mBfNjQs3klqbJU2VILqZryAZUt9JOb3h/mWMy23/f5A==}
+ dependencies:
+ lru-cache: 4.1.5
+ shebang-command: 1.2.0
+ which: 1.3.1
+ dev: false
+
/cross-spawn@7.0.3:
resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==}
engines: {node: '>= 8'}
@@ -3469,6 +3505,19 @@ packages:
engines: {node: '>=0.8.x'}
dev: false
+ /execa@0.8.0:
+ resolution: {integrity: sha512-zDWS+Rb1E8BlqqhALSt9kUhss8Qq4nN3iof3gsOdyINksElaPyNBtKUMTR62qhvgVWR0CqCX7sdnKe4MnUbFEA==}
+ engines: {node: '>=4'}
+ dependencies:
+ cross-spawn: 5.1.0
+ get-stream: 3.0.0
+ is-stream: 1.1.0
+ npm-run-path: 2.0.2
+ p-finally: 1.0.0
+ signal-exit: 3.0.7
+ strip-eof: 1.0.0
+ dev: false
+
/execa@5.1.1:
resolution: {integrity: sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==}
engines: {node: '>=10'}
@@ -3870,6 +3919,11 @@ packages:
engines: {node: '>=8.0.0'}
dev: true
+ /get-stream@3.0.0:
+ resolution: {integrity: sha512-GlhdIUuVakc8SJ6kK0zAFbiGzRFzNnY4jUuEbV9UROo4Y+0Ny4fjvcZFVTeDA4odpFyOQzaw6hXukJSq/f28sQ==}
+ engines: {node: '>=4'}
+ dev: false
+
/get-stream@5.2.0:
resolution: {integrity: sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==}
engines: {node: '>=8'}
@@ -4070,6 +4124,11 @@ packages:
ajv: 6.12.6
har-schema: 2.0.0
+ /has-flag@2.0.0:
+ resolution: {integrity: sha512-P+1n3MnwjR/Epg9BBo1KT8qbye2g2Ou4sFumihwt6I4tsUX7jnLcX4BTOSKg/B1ZrIYMN9FcEnG4x5a7NB8Eng==}
+ engines: {node: '>=0.10.0'}
+ dev: false
+
/has-flag@3.0.0:
resolution: {integrity: sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==}
engines: {node: '>=4'}
@@ -4625,6 +4684,11 @@ packages:
resolution: {integrity: sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==}
dev: false
+ /is-stream@1.1.0:
+ resolution: {integrity: sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ==}
+ engines: {node: '>=0.10.0'}
+ dev: false
+
/is-stream@2.0.1:
resolution: {integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==}
engines: {node: '>=8'}
@@ -4646,7 +4710,6 @@ packages:
/isexe@2.0.0:
resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==}
- dev: true
/isobject@3.0.1:
resolution: {integrity: sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==}
@@ -5634,6 +5697,13 @@ packages:
engines: {node: 14 || >=16.14}
dev: false
+ /lru-cache@4.1.5:
+ resolution: {integrity: sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==}
+ dependencies:
+ pseudomap: 1.0.2
+ yallist: 2.1.2
+ dev: false
+
/lru-cache@5.1.1:
resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==}
dependencies:
@@ -6813,6 +6883,13 @@ packages:
- encoding
dev: false
+ /npm-run-path@2.0.2:
+ resolution: {integrity: sha512-lJxZYlT4DW/bRUtFh1MQIWqmLwQfAxnqWG4HhEdjMlkrJYnJn0Jrr2u3mgxqaWsdiBc76TYkTG/mhrnYTuzfHw==}
+ engines: {node: '>=4'}
+ dependencies:
+ path-key: 2.0.1
+ dev: false
+
/npm-run-path@4.0.1:
resolution: {integrity: sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==}
engines: {node: '>=8'}
@@ -7105,6 +7182,11 @@ packages:
resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==}
engines: {node: '>=0.10.0'}
+ /path-key@2.0.1:
+ resolution: {integrity: sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==}
+ engines: {node: '>=4'}
+ dev: false
+
/path-key@3.1.1:
resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==}
engines: {node: '>=8'}
@@ -7316,6 +7398,10 @@ packages:
resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==}
dev: false
+ /pseudomap@1.0.2:
+ resolution: {integrity: sha512-b/YwNhb8lk1Zz2+bXXpS/LK9OisiZZ1SNsSLxN1x2OXVEhW2Ckr/7mWE5vrC1ZTiJlD9g19jWszTmJsB+oEpFQ==}
+ dev: false
+
/psl@1.9.0:
resolution: {integrity: sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==}
@@ -7974,6 +8060,13 @@ packages:
mixin-object: 2.0.1
dev: false
+ /shebang-command@1.2.0:
+ resolution: {integrity: sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==}
+ engines: {node: '>=0.10.0'}
+ dependencies:
+ shebang-regex: 1.0.0
+ dev: false
+
/shebang-command@2.0.0:
resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==}
engines: {node: '>=8'}
@@ -7981,6 +8074,11 @@ packages:
shebang-regex: 3.0.0
dev: true
+ /shebang-regex@1.0.0:
+ resolution: {integrity: sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==}
+ engines: {node: '>=0.10.0'}
+ dev: false
+
/shebang-regex@3.0.0:
resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==}
engines: {node: '>=8'}
@@ -8005,7 +8103,6 @@ packages:
/signal-exit@3.0.7:
resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==}
- dev: true
/signal-exit@4.1.0:
resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==}
@@ -8258,6 +8355,11 @@ packages:
engines: {node: '>=8'}
dev: true
+ /strip-eof@1.0.0:
+ resolution: {integrity: sha512-7FCwGGmx8mD5xQd3RPUvnSpUXHM3BWuzjtpD4TXsfcZ9EL4azvVVUscFYwD9nx8Kh+uCBC00XBtAykoMHwTh8Q==}
+ engines: {node: '>=0.10.0'}
+ dev: false
+
/strip-final-newline@2.0.0:
resolution: {integrity: sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==}
engines: {node: '>=6'}
@@ -8301,6 +8403,13 @@ packages:
- supports-color
dev: true
+ /supports-color@4.5.0:
+ resolution: {integrity: sha512-ycQR/UbvI9xIlEdQT1TQqwoXtEldExbCEAJgRo5YXlmSKjv6ThHnP9/vwGa1gr19Gfw+LkFd7KqYMhzrRC5JYw==}
+ engines: {node: '>=4'}
+ dependencies:
+ has-flag: 2.0.0
+ dev: false
+
/supports-color@5.5.0:
resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==}
engines: {node: '>=4'}
@@ -8409,6 +8518,21 @@ packages:
resolution: {integrity: sha512-ltAHPh/9k0STRQqaoUX52NH4ZQYAJz24ZAEwf1Zm+HYg3l9OXTWeqWKyYsHu40wF/F0rxd2N2bk5sLvX2qlSvg==}
dev: false
+ /title@3.5.3:
+ resolution: {integrity: sha512-20JyowYglSEeCvZv3EZ0nZ046vLarO37prvV0mbtQV7C8DJPGgN967r8SJkqd3XK3K3lD3/Iyfp3avjfil8Q2Q==}
+ hasBin: true
+ dependencies:
+ arg: 1.0.0
+ chalk: 2.3.0
+ clipboardy: 1.2.2
+ titleize: 1.0.0
+ dev: false
+
+ /titleize@1.0.0:
+ resolution: {integrity: sha512-TARUb7z1pGvlLxgPk++7wJ6aycXF3GJ0sNSBTAsTuJrQG5QuZlkUQP+zl+nbjAh4gMX9yDw9ZYklMd7vAfJKEw==}
+ engines: {node: '>=0.10.0'}
+ dev: false
+
/titleize@3.0.0:
resolution: {integrity: sha512-KxVu8EYHDPBdUYdKZdKtU2aj2XfEx9AfjXxE/Aj0vT06w2icA09Vus1rh6eSu1y01akYg6BjIK/hxyLJINoMLQ==}
engines: {node: '>=12'}
@@ -8991,6 +9115,13 @@ packages:
tr46: 0.0.3
webidl-conversions: 3.0.1
+ /which@1.3.1:
+ resolution: {integrity: sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==}
+ hasBin: true
+ dependencies:
+ isexe: 2.0.0
+ dev: false
+
/which@2.0.2:
resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==}
engines: {node: '>= 8'}
@@ -9134,6 +9265,10 @@ packages:
resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==}
engines: {node: '>=10'}
+ /yallist@2.1.2:
+ resolution: {integrity: sha512-ncTzHV7NvsQZkYe1DW7cbDLm0YpzHmZF5r/iyP3ZnQtMiJ+pjzisCiMNI+Sj+xQF5pXhSHxSB3uDbsBTzY/c2A==}
+ dev: false
+
/yallist@3.1.1:
resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==}
dev: true
diff --git a/test/utils/common-utils.js b/test/utils/common-utils.js
index e895a485653325..37c355580de9ef 100644
--- a/test/utils/common-utils.js
+++ b/test/utils/common-utils.js
@@ -2,7 +2,7 @@ const utils = require('../../lib/utils/common-utils');
describe('common-utils', () => {
it('toTitleCase', () => {
- expect(utils.toTitleCase('RSSHub IS AS aweSOme aS henry')).toBe('Rsshub Is As Awesome As Henry');
+ expect(utils.toTitleCase('RSSHub IS AS aweSOme aS henry')).toBe('Rsshub Is as Awesome as Henry');
});
it('convertDateToISO8601', () => {
From f7f8b7a8e71c15879d401f146a305f833db9c875 Mon Sep 17 00:00:00 2001
From: Tony
Date: Fri, 15 Dec 2023 17:23:01 +0000
Subject: [PATCH 5/5] feat(route): sspu (#14050)
---
lib/v2/sspu/jwc.js | 44 ++++++++++++++++++++++++++++++
lib/v2/sspu/maintainer.js | 3 ++
lib/v2/sspu/radar.js | 13 +++++++++
lib/v2/sspu/router.js | 3 ++
website/docs/routes/university.mdx | 10 +++++++
5 files changed, 73 insertions(+)
create mode 100644 lib/v2/sspu/jwc.js
create mode 100644 lib/v2/sspu/maintainer.js
create mode 100644 lib/v2/sspu/radar.js
create mode 100644 lib/v2/sspu/router.js
diff --git a/lib/v2/sspu/jwc.js b/lib/v2/sspu/jwc.js
new file mode 100644
index 00000000000000..209cd2435f0016
--- /dev/null
+++ b/lib/v2/sspu/jwc.js
@@ -0,0 +1,44 @@
+const got = require('@/utils/got');
+const cheerio = require('cheerio');
+const { parseDate } = require('@/utils/parse-date');
+const timezone = require('@/utils/timezone');
+
+module.exports = async (ctx) => {
+ const { listId } = ctx.params;
+ const baseUrl = 'https://jwc.sspu.edu.cn';
+
+ const { data: response, url: link } = await got(`${baseUrl}/${listId}/list.htm`);
+ const $ = cheerio.load(response);
+
+ const list = $('.news_list .news')
+ .slice(0, ctx.query.limit ? parseInt(ctx.query.limit) : 15)
+ .toArray()
+ .map((item) => {
+ item = $(item);
+ const title = item.find('.news_title a');
+ return {
+ title: title.attr('title'),
+ link: `${baseUrl}${title.attr('href')}`,
+ };
+ });
+
+ const items = await Promise.all(
+ list.map((item) =>
+ ctx.cache.tryGet(item.link, async () => {
+ const { data: response } = await got(item.link);
+ const $ = cheerio.load(response);
+
+ item.description = $('.wp_articlecontent').html();
+ item.pubDate = timezone(parseDate($('.arti_update').text(), 'YYYY-MM-DD HH:mm:ss'), +8);
+
+ return item;
+ })
+ )
+ );
+
+ ctx.state.data = {
+ title: $('head title').text(),
+ link,
+ item: items,
+ };
+};
diff --git a/lib/v2/sspu/maintainer.js b/lib/v2/sspu/maintainer.js
new file mode 100644
index 00000000000000..7ddb6347a5d476
--- /dev/null
+++ b/lib/v2/sspu/maintainer.js
@@ -0,0 +1,3 @@
+module.exports = {
+ '/jwc/:listId': ['TonyRL'],
+};
diff --git a/lib/v2/sspu/radar.js b/lib/v2/sspu/radar.js
new file mode 100644
index 00000000000000..b0c3b76645b893
--- /dev/null
+++ b/lib/v2/sspu/radar.js
@@ -0,0 +1,13 @@
+module.exports = {
+ 'sspu.edu.cn': {
+ _name: '上海第二工业大学',
+ jwc: [
+ {
+ title: '教务处',
+ docs: 'https://docs.rsshub.app/university#shang-hai-di-er-gong-ye-da-xue',
+ source: ['/jwc/:listId/list.htm'],
+ target: '/sspu/jwc/:listId',
+ },
+ ],
+ },
+};
diff --git a/lib/v2/sspu/router.js b/lib/v2/sspu/router.js
new file mode 100644
index 00000000000000..fa4184a46a1eb6
--- /dev/null
+++ b/lib/v2/sspu/router.js
@@ -0,0 +1,3 @@
+module.exports = (router) => {
+ router.get('/jwc/:listId', require('./jwc'));
+};
diff --git a/website/docs/routes/university.mdx b/website/docs/routes/university.mdx
index 0accaaa82ffa76..cf1928b10ab654 100644
--- a/website/docs/routes/university.mdx
+++ b/website/docs/routes/university.mdx
@@ -2335,6 +2335,16 @@ jsjxy.hbut.edu.cn 证书链不全,自建 RSSHub 可设置环境变量 NODE\_TL
| notice | news | policy |
+## 上海第二工业大学 {#shang-hai-di-er-gong-ye-da-xue}
+
+### 教务处 {#shang-hai-di-er-gong-ye-da-xue-jiao-wu-chu}
+
+
+ | 学生专栏 | 教师专栏 |
+ | -------- | -------- |
+ | 897 | 898 |
+
+
## 上海电力大学 {#shang-hai-dian-li-da-xue}
### 新闻网与学院通知 {#shang-hai-dian-li-da-xue-xin-wen-wang-yu-xue-yuan-tong-zhi}