diff --git a/docs/README.md b/docs/README.md index c49f375f5..0263d8d39 100644 --- a/docs/README.md +++ b/docs/README.md @@ -1560,6 +1560,10 @@ category 列表: +### 中山大学 + + + ## 传统媒体 ### 央视新闻 diff --git a/router.js b/router.js index dc1f969d7..0c7172dac 100644 --- a/router.js +++ b/router.js @@ -853,6 +853,9 @@ router.get('/javbus/western/home', require('./routes/javbus/western/home')); router.get('/javbus/western/genre/:gid', require('./routes/javbus/western/genre')); router.get('/javbus/western/star/:sid', require('./routes/javbus/western/star')); +// 中山大学 +router.get('/sysu/sdcs', require('./routes/universities/sysu/sdcs')); + // 動畫瘋 router.get('/anigamer/new_anime', require('./routes/anigamer/new_anime')); router.get('/anigamer/anime/:sn', require('./routes/anigamer/anime')); diff --git a/routes/universities/sysu/sdcs.js b/routes/universities/sysu/sdcs.js new file mode 100644 index 000000000..a7e721756 --- /dev/null +++ b/routes/universities/sysu/sdcs.js @@ -0,0 +1,55 @@ +const axios = require('../../../utils/axios'); +const { load } = require('cheerio'); +const { resolve } = require('url'); + +const base = 'http://sdcs.sysu.edu.cn/'; + +module.exports = async (ctx) => { + const { data } = await axios.get('http://sdcs.sysu.edu.cn/'); + const $ = load(data); + + const urls = $('.view-content li > a') + .map((_, ele) => $(ele).attr('href')) + .toArray() + .map((path) => path.match(/\/content\/(\d+)/)[1]) // extract article-id + .sort() + .reverse() // sort by article-id (or to say, date), latest first + .map((aid) => resolve(base, `/content/${aid}`)); + + ctx.state.data = { + title: '中山大学 - 数据科学与计算机学院', + link: 'http://sdcs.sysu.edu.cn/', + description: '中山大学 - 数据科学与计算机学院', + item: await getDetails(ctx.cache, urls), + }; +}; + +const getDetails = (cache, urls) => Promise.all(urls.map((url) => cache.tryGet(url, () => getDetail(url), 24 * 60 * 60))); + +const timezone = 8; +const serverOffset = new Date().getTimezoneOffset() / 60; +const shiftTimezone = (date) => new Date(date.getTime() - 60 * 60 * 1000 * (timezone + serverOffset)).toUTCString(); + +const getDetail = async (url) => { + const { data } = await axios.get(url); + const $ = load(data); + + // transforming images + $('.content img').each((_, ele) => { + $(ele).attr('referrerpolicy', 'no-referrer'); + $(ele).attr('src', resolve(base, $(ele).attr('src'))); + }); + + return { + title: $('section > h1').text(), + description: $('.content').html(), + link: url, + pubDate: shiftTimezone( + new Date( + $('.submitted-by') + .text() + .match(/(\d+\/\d+\/\d+)/)[1] + ) + ), + }; +};