diff --git a/docs/university.md b/docs/university.md index 71a9f5b7b..cb0dd2754 100644 --- a/docs/university.md +++ b/docs/university.md @@ -2021,6 +2021,16 @@ type 列表: +### 教务处 + + + +| 规章制度 | 专业建设 | 实践教学 | 支部风采 | 服务指南 | 教务要闻 | 工作通知 | 教务简报 | 常用下载 | +| ---- | ---- | ---- | ---- | ---- | ---- | ---- | ---- | ---- | +| gzzd | zyjs | sjjx | zbfc | fwzn | jwyw | gztz | jwjb | cyxz | + + + ## 上海大学 ### 上海大学官网信息 diff --git a/lib/v2/sdu/data.js b/lib/v2/sdu/data.js index c9c1da953..00b5d6919 100644 --- a/lib/v2/sdu/data.js +++ b/lib/v2/sdu/data.js @@ -3,7 +3,7 @@ module.exports = { news: { name: '山东大学(威海)新闻网', route: '/news', - source: ['/'], + source: ['/*path', '/'], titlePrefix: '(威海)新闻网|', docs: 'https://docs.rsshub.app/university.html#shan-dong-da-xue-wei-hai', getTarget(url) { @@ -57,5 +57,54 @@ module.exports = { }, }, }, + jwc: { + name: '山东大学(威海)教务处', + route: '/jwc', + source: ['/*path', '/'], + titlePrefix: '(威海)教务处|', + docs: 'https://docs.rsshub.app/university.html#shan-dong-da-xue-wei-hai', + getTarget(url) { + return this.route + '/' + url.replace(/\.htm$/, ''); + }, + url: 'https://jwc.wh.sdu.edu.cn/', + columns: { + gzzd: { + name: '规章制度', + url: 'gzzd.htm', + }, + zyjs: { + name: '专业建设', + url: 'zyjs.htm', + }, + sjjx: { + name: '实践教学', + url: 'sjjx.htm', + }, + zbfc: { + name: '支部风采', + url: 'zbfc.htm', + }, + fwzn: { + name: '服务指南', + url: 'fwzn.htm', + }, + jwyw: { + name: '教务要闻', + url: 'jwyw.htm', + }, + gztz: { + name: '工作通知', + url: 'gztz.htm', + }, + jwjb: { + name: '教务简报', + url: 'jwjb.htm', + }, + cyxz: { + name: '常用下载', + url: 'cyxz.htm', + }, + }, + }, }, }; diff --git a/lib/v2/sdu/extractor/index.js b/lib/v2/sdu/extractor/index.js index de1fc1979..97cc11178 100644 --- a/lib/v2/sdu/extractor/index.js +++ b/lib/v2/sdu/extractor/index.js @@ -8,5 +8,8 @@ module.exports = async (link, ctx) => { if (link.startsWith('https://www.sdrj.sdu.edu.cn/')) { return await require('./sdrj')(link, ctx); } + if (link.startsWith('https://jwc.wh.sdu.edu.cn/')) { + return await require('./wh/jwc')(link, ctx); + } return {}; }; diff --git a/lib/v2/sdu/extractor/wh/jwc.js b/lib/v2/sdu/extractor/wh/jwc.js new file mode 100644 index 000000000..18e06ace2 --- /dev/null +++ b/lib/v2/sdu/extractor/wh/jwc.js @@ -0,0 +1,24 @@ +const got = require('@/utils/got'); +const cheerio = require('cheerio'); +const { parseDate } = require('@/utils/parse-date'); +const timezone = require('@/utils/timezone'); + +module.exports = async (link, ctx) => + await ctx.cache.tryGet(link, async () => { + let content, exactDate; + try { + const result = await got(link); + const $ = cheerio.load(result.data); + const form = $("form[name='_newscontent_fromname']"); + form.find('h2').remove(); + const exactDateElement = form.find('#author'); + const exactDateStr = exactDateElement.text(); + exactDateElement.remove(); + content = form.html(); + const exactDateText = exactDateStr.match(/^创建时间:(?\d{4}-\d{2}-\d{2}\s\d{2}:\d{2}:\d{2})/).groups.date; + exactDate = timezone(parseDate(exactDateText, 'YYYY-MM-DD HH:mm:ss'), +8); + return { description: content, exactDate }; + } catch (e) { + return { description: content, exactDate }; + } + }); diff --git a/lib/v2/sdu/maintainer.js b/lib/v2/sdu/maintainer.js index db0b8798d..901e76c75 100644 --- a/lib/v2/sdu/maintainer.js +++ b/lib/v2/sdu/maintainer.js @@ -5,4 +5,5 @@ module.exports = { '/mech/:type?': ['Ji4n1ng'], '/sc/:type?': ['Ji4n1ng'], '/wh/news/:column?': ['kxxt'], + '/wh/jwc/:column?': ['kxxt'], }; diff --git a/lib/v2/sdu/radar.js b/lib/v2/sdu/radar.js index 0056e5ef4..f43ea24c2 100644 --- a/lib/v2/sdu/radar.js +++ b/lib/v2/sdu/radar.js @@ -9,6 +9,12 @@ module.exports = { source: wh.news.source, target: '/sdu/wh' + wh.news.getTarget(value.url), })), + 'jwc.wh': Object.entries(wh.jwc.columns).map(([, value]) => ({ + title: wh.jwc.titlePrefix + value.name, + docs: wh.jwc.docs, + source: wh.jwc.source, + target: '/sdu/wh' + wh.jwc.getTarget(value.url), + })), 'www.cmse': [ { title: '材料科学与工程学院通知', diff --git a/lib/v2/sdu/router.js b/lib/v2/sdu/router.js index 6913d656c..a60440332 100644 --- a/lib/v2/sdu/router.js +++ b/lib/v2/sdu/router.js @@ -5,4 +5,5 @@ module.exports = function (router) { router.get('/mech/:type?', require('./mech')); router.get('/sc/:type?', require('./sc')); router.get('/wh/news/:column?', require('./wh/news')); + router.get('/wh/jwc/:column?', require('./wh/jwc')); }; diff --git a/lib/v2/sdu/wh/jwc.js b/lib/v2/sdu/wh/jwc.js new file mode 100644 index 000000000..be17c0296 --- /dev/null +++ b/lib/v2/sdu/wh/jwc.js @@ -0,0 +1,42 @@ +const got = require('@/utils/got'); +const cheerio = require('cheerio'); +const data = require('../data').wh.jwc; +const extractor = require('../extractor'); +const { parseDate } = require('@/utils/parse-date'); +const timezone = require('@/utils/timezone'); + +module.exports = async (ctx) => { + const column = ctx.params.column ?? 'gztz'; + const baseUrl = data.url; + const response = await got(baseUrl + data.columns[column].url); + const $ = cheerio.load(response.data); + const items = $('.articleul li'); + const out = await Promise.all( + items.map(async (index, item) => { + item = $(item); + const anchor = item.find('a'); + const dateElement = item.find('div:last-of-type'); + const dateText = dateElement.text(); + dateElement.remove(); + const href = anchor.attr('href'); + const link = href.startsWith('http') ? href : baseUrl + href; + const title = item.text(); + const { description, author: exactAuthor, exactDate } = await ctx.cache.tryGet(link, async () => await extractor(link, ctx)); + const author = exactAuthor ?? '教务处'; + const pubDate = exactDate ?? timezone(parseDate(dateText.slice(1, dateText.length - 1), 'YYYY-MM-DD'), +8); + return { + title, + link, + description, + pubDate, + author, + }; + }) + ); + + ctx.state.data = { + title: `${data.name} ${data.columns[column].name}`, + link: baseUrl + data.columns[column].url, + item: out, + }; +};