Merge branch 'master' of https://github.com/DIYgod/RSSHub into weibo_home_timeline_refactor

This commit is contained in:
zytomorrow
2021-07-05 23:37:57 +08:00
85 changed files with 5655 additions and 3248 deletions
+2 -1
View File
@@ -37,4 +37,5 @@ jobs:
--platform=linux/amd64,linux/arm/v7,linux/arm64 \
--output "type=image,push=true" \
--file ./Dockerfile . \
--tag $(echo "${DOCKER_USERNAME}" | tr '[:upper:]' '[:lower:]')/rsshub:latest
--tag $(echo "${DOCKER_USERNAME}" | tr '[:upper:]' '[:lower:]')/rsshub:latest \
--tag $(echo "${DOCKER_USERNAME}" | tr '[:upper:]' '[:lower:]')/rsshub:$(date +%Y)-$(date +%m)-$(date +%d)
+1 -1
View File
@@ -8,7 +8,7 @@ on:
jobs:
build:
if: github.repository == "DIYgod/RSSHub"
if: github.repository == 'DIYgod/RSSHub'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
-1
View File
@@ -1 +0,0 @@
--exact true
+1 -1
View File
@@ -32,7 +32,7 @@ RSSHub 是一个开源、简单易用、易于扩展的 RSS 生成器,可以
### Special Sponsors
<div>
<a href="https://sa.net/" target="_blank"><img height="60px" src="https://i.imgur.com/3rM8nWI.png"></a>
<a href="https://rss3.io/" target="_blank"><img height="60px" src="https://i.imgur.com/v7TF0jp.jpg"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="https://sa.net/" target="_blank"><img height="60px" src="https://i.imgur.com/3rM8nWI.png"></a>
</div>
### Sponsors
+35 -14
View File
@@ -140,24 +140,26 @@
{
title: '用户收藏',
docs: 'https://docs.rsshub.app/social-media.html#pixiv',
source: '/bookmark.php',
target: (params, url) => `/pixiv/user/bookmarks/${new URL(url).searchParams.get('id')}`,
source: '/users/:id/bookmarks/artworks',
target: '/pixiv/user/bookmarks/:id',
},
{
title: '用户动态',
docs: 'https://docs.rsshub.app/social-media.html#pixiv',
source: '/member.php',
target: (params, url) => `/pixiv/user/${new URL(url).searchParams.get('id')}`,
source: '/users/:id',
target: '/pixiv/user/:id',
},
{
title: '排行榜',
docs: 'https://docs.rsshub.app/social-media.html#pixiv',
source: '/ranking.php',
target: (params, url) => `/pixiv/ranking/${new URL(url).searchParams.get('mode') || 'daily'}`,
},
{
title: '关键词',
docs: 'https://docs.rsshub.app/social-media.html#pixiv',
source: '/search.php',
source: ['/tags/:keyword', '/tags/:keyword/:type?'],
target: (params, url) => `/pixiv/search/:keyword/${new URL(url).searchParams.get('order')}/${new URL(url).searchParams.get('mode')}`,
},
{
title: '关注的新作品',
@@ -1142,12 +1144,6 @@
source: '/search/',
target: (params, url) => `/steam/search/${new URL(url).searchParams}`,
},
{
title: 'news',
docs: 'https://docs.rsshub.app/game.html#steam',
source: '/news/',
target: (params, url) => `/steam/news/${new URL(url).searchParams.get('appids')}`,
},
],
},
'baijingapp.com': {
@@ -1733,13 +1729,13 @@
'trackings.post': [
{
title: '郵便・荷物の追跡',
docs: 'https://docs.rsshub.app/other.html#ri-ben-you-bian',
docs: 'https://docs.rsshub.app/other.html#ri-ben-you-bian-you-bian-zhui-ji-サービス',
source: '/services/srv/search/direct',
target: (params, url) => {
const reqCode = new URL(url).searchParams.get('reqCodeNo1').toUpperCase();
const locale = new URL(url).searchParams.get('locale').toLowerCase();
if ((reqCode.search(/^(?:\d{12}|[A-Z]{2}\d{9}[A-Z]{2})$/) === 0 && locale === 'ja') || locale === 'en') {
return `/japanpost/${reqCode}/${locale}`;
if ((reqCode.search(/^(?:\d{11,12}|[A-Z]{2}\d{9}[A-Z]{2})$/) === 0 && locale === 'ja') || locale === 'en') {
return `/japanpost/track/${reqCode}/${locale}`;
}
},
},
@@ -2986,4 +2982,29 @@
},
],
},
'iyingdi.com': {
_name: '旅法师营地',
www: [
{
title: '分区',
docs: 'https://docs.rsshub.app/game.html#lv-fa-shi-ying-di',
source: '/tz/tag/:tag',
target: '/lfsyd/tag/:tag',
},
{
title: '用户发帖',
docs: 'https://docs.rsshub.app/game.html#lv-fa-shi-ying-di',
source: ['/tz/people/:id', '/tz/people/:id/*'],
target: '/lfsyd/user/:id',
},
],
mob: [
{
title: '分区',
docs: 'https://docs.rsshub.app/game.html#lv-fa-shi-ying-di',
source: '/fine/:tag',
target: '/lfsyd/tag/:tag',
},
],
},
});
+4
View File
@@ -19,6 +19,10 @@ services:
# See issue 6680
image: browserless/chrome:1.43-chrome-stable
restart: always
ulimits:
core:
hard: 0
soft: 0
redis:
image: redis:alpine
+2 -3
View File
@@ -1,6 +1,5 @@
const file = require('./file');
const pinyin = require('pinyin');
const pinyinCompare = new Intl.Collator('zh-Hans-CN-u-co-pinyin').compare;
const isASCII = (str) => /^[\x00-\x7F]*$/.test(str);
module.exports = {
@@ -41,7 +40,7 @@ module.exports = {
} else if (ia || ib) {
return ia > ib ? -1 : 1;
} else {
return pinyin.compare(a.title, b.title);
return pinyinCompare(a.title, b.title);
}
})
.map((x) => x.content.join('\n'))
+1 -1
View File
@@ -1,4 +1,4 @@
const pinyin = require('pinyin');
const { pinyin } = require('@napi-rs/pinyin');
const { slugify: _slugify } = require('@vuepress/shared-utils');
module.exports = {
+1 -1
View File
@@ -25,7 +25,7 @@ RSSHub 是一个开源、简单易用、易于扩展的 RSS 生成器,可以
### Special Sponsors
<a style="margin-right: 10px;" href="https://sa.net/" target="_blank"><img alt="Riven Cloud" height="60px" src="https://cn-south-17-rsshub-16857749.oss.dogecdn.com/rivencloudd.png"></a>
<a style="margin-right: 50px;" href="https://rss3.io/" target="_blank"><img alt="RSS3" height="60px" src="https://cn-south-17-rsshub-16857749.oss.dogecdn.com/rss3_.png"></a><a href="https://sa.net/" target="_blank"><img alt="Riven Cloud" height="60px" src="https://cn-south-17-rsshub-16857749.oss.dogecdn.com/rivencloudd.png"></a>
### Sponsors
+6 -6
View File
@@ -266,6 +266,12 @@ pageClass: routes
</Route>
## 咚漫
### 漫画更新
<Route author="machsix" path="/dongmanmanhua/:category/:name/:id" example="/dongmanmanhua/COMEDY/xin-xinlingdeshengyin/381" :paramsDesc="['类别','名称','ID']"/>
## 動畫瘋
### 最後更新
@@ -276,12 +282,6 @@ pageClass: routes
<Route author="maple3142" example="/anigamer/anime/90003" path="/anigamer/anime/:sn" :paramsDesc="['動畫 sn']"/>
## 咚漫
### 漫画更新
<Route author="machsix" path="/dongmanmanhua/:category/:name/:id" example="/dongmanmanhua/COMEDY/xin-xinlingdeshengyin/381" :paramsDesc="['类别','名称','ID']"/>
## 動漫狂
### 漫画更新
+5 -5
View File
@@ -390,13 +390,13 @@ pageClass: routes
## 龙腾网
### 转译网贴
### 网帖翻译
<Route author="sgqy" example="/ltaaa" path="/ltaaa/:type?" :paramsDesc="['热门类型.']">
<Route author="sgqy nczitzk" example="/ltaaa" path="/ltaaa/:category?" :paramsDesc="['分类,见下表,默认为最新']">
| 最新 | 每周 | 每月 | 全年 |
| ---- | ---- | ----- | ---- |
| (空) | week | month | year |
| 最新 | 科技 | 娱乐 | 文化 | 社会 | 体育 | 历史 | 趣闻 | 图说世界 |
| ------ | ---------- | ----- | ------- | --------- | ----- | ------- | ----------- | -------- |
| latest | technology | funny | culture | community | sport | history | curiosities | picture |
</Route>
+1 -1
View File
@@ -25,7 +25,7 @@ RSSHub can be used with browser extension [RSSHub Radar](https://github.com/DIYg
### Special Sponsors
<a style="margin-right: 10px;" href="https://sa.net/" target="_blank"><img height="60px" src="https://i.imgur.com/3rM8nWI.png"></a>
<a style="margin-right: 50px;" href="https://rss3.io/" target="_blank"><img alt="RSS3" height="60px" src="https://i.imgur.com/v7TF0jp.png"></a><a href="https://sa.net/" target="_blank"><img alt="Riven Cloud" height="60px" src="https://i.imgur.com/3rM8nWI.png"></a>
### Sponsors
+3 -7
View File
@@ -172,17 +172,13 @@ For instance, in `https://store.steampowered.com/search/?specials=1&term=atelier
### Steam news
<RouteEn author="maple3142" example="/steam/news/282800" path="/steam/news/:appids" :paramsDesc="['game id']" radar="1" rssbud="1"/>
::: tip
Steam provides some official RSS feeds:
- Game News: https://store.steampowered.com/feeds/news/app/412830/
- Curator/Group/Publisher/Developer News: https://store.steampowered.com/feeds/news/group/35143931/
Game News use the AppID while the rest are only available in the Steam News UI, it seems.
- News home page: [https://store.steampowered.com/feeds/news/?l=english](https://store.steampowered.com/feeds/news/?l=english) the parameter `l=english` specifiy the language.
- Game news rss can get from the rss buttom in page like this: [https://store.steampowered.com/news/app/648800/](https://store.steampowered.com/news/app/648800/) , rss link will looks like: [https://store.steampowered.com/feeds/news/app/648800/?cc=US&l=english](https://store.steampowered.com/feeds/news/app/648800/?cc=US&l=english)
- Steam group can add `/rss` behind Steam community URL to subscribe: [https://steamcommunity.com/groups/SteamLabs/rss](https://steamcommunity.com/groups/SteamLabs/rss) or add the `/feeds` in Steam News : [https://store.steampowered.com/feeds/news/group/35143931/](https://store.steampowered.com/feeds/news/group/35143931/)
:::
+9
View File
@@ -21,6 +21,15 @@ Deploy for public access may require:
1. [Heroku](https://devcenter.heroku.com/articles/getting-started-with-nodejs)
1. [Google App Engine](https://cloud.google.com/appengine/)
## Docker Image
We recommend using the latest version of the docker image.
When the latest version is unavailable , you can use image with date tag. For example :
```
$ docker pull diygod/rsshub:2021-06-18
```
Your can back to the latest version when code has been fixed and rebuild the image.
## Docker Compose Deployment
### Install
+1 -1
View File
@@ -104,7 +104,7 @@ Official Website: [https://www.ssm.gov.mo/apps1/PreventWuhanInfection/en.aspx](h
### Track & Trace Service
<RouteEn author="tuzi3040" example="/japanpost/EJ123456789JP/en" path="/japanpost/:reqCode/:locale?" :paramsDesc="['Package Number', 'Language, default to japanese `ja`']" radar="1" rssbud="1">
<RouteEn author="tuzi3040" example="/japanpost/track/EJ123456789JP/en" path="/japanpost/track/:reqCode/:locale?" :paramsDesc="['Package Number', 'Language, default to japanese `ja`']" radar="1" rssbud="1">
| Japanese | English |
| -------- | ------- |
+7 -1
View File
@@ -209,7 +209,13 @@ These feed do not include boosts (a.k.a. reblogs). RSSHub provides a feed for us
### Keyword
<RouteEn author="DIYgod" example="/pixiv/search/麻衣/popular/2" path="/pixiv/search/:keyword/:order?/:r18?" :paramsDesc="['keyword', 'rank mode, empty or other for time order, popular for popular order', 'filte R18 content, 0 to no filter, 1 to only not R18, 2 to only R18, default to 0']" radar="1" rssbud="1"/>
<RouteEn author="DIYgod" example="/pixiv/search/麻衣/popular/2" path="/pixiv/search/:keyword/:order?/:mode?" :paramsDesc="['keyword', 'rank mode, empty or other for time order, popular for popular order', 'filte R18 content']" radar="1" rssbud="1">
| only not R18 | only R18 | no filter |
| ----------------- | ------------------------- | ------------------------- |
| safe | r18 | empty or other |
</RouteEn>
### Following timeline
+39 -27
View File
@@ -342,15 +342,17 @@ Example: `https://store.steampowered.com/search/?specials=1&term=atelier` 中的
</Route>
### Steam news
### Steam 新闻中心
<Route author="maple3142" example="/steam/news/1091500/schinese" path="/steam/news/:appid/:language?" :paramsDesc="['游戏 id', '语言,默认简体中文']" radar="1" rssbud="1">
::: tip
| 语言 (Language) | 简体中文 (Simplified Chinese) | 繁體中文 (Traditional Chinese) | 日本語 (Japanese) | 한국어 (Korean) | Български (Bulgarian) | Čeština (Czech) | Dansk (Danish) | Deutsch (German) | Español - España (Spanish - Spain) | Español - Latinoamérica (Spanish - Latin America), | Ελληνικά (Greek) | Français (French) | Italiano (Italian) | Magyar (Hungarian) | Nederlands (Dutch) | Norsk (Norwegian) | Polski (Polish) | Português (Portuguese) | Português - Brasil (Portuguese - Brazil) | Română (Romanian) | Русский (Russian) | Suomi (Finnish) | Svenska (Swedish) | Türkçe (Turkish) | Tiếng Việt (Vietnamese) | Українська (Ukrainian) |
| --------------- | ----------------------------- | ------------------------------ | ----------------- | --------------- | --------------------- | --------------- | -------------- | ---------------- | ---------------------------------- | -------------------------------------------------- | ---------------- | ----------------- | ------------------ | ------------------ | ------------------ | ----------------- | --------------- | ---------------------- | ---------------------------------------- | ----------------- | ----------------- | --------------- | ----------------- | ---------------- | ----------------------- | ---------------------- |
| | schinese | tchinese | japanese | koreana | bulgarian | czech | danish | german | spanish | latam | greek | french | italian | hungarian | dutch | norwegian | polish | portuguese | brazilian | romanian | russian | finnish | swedish | turkish | vietnamese | ukrainian |
Steam 新闻中心支持官方的 RSS 订阅:
</Route>
- 新闻中心首页订阅地址为:<https://store.steampowered.com/feeds/news/?l=schinese> 其中参数 `l=english` 指定语言,`l=schinese` 为简体中文。
- Steam 游戏新闻可以在该游戏的 RSS 按钮订阅: <https://store.steampowered.com/news/app/648800/> ,获取的订阅链接类似为: <https://store.steampowered.com/feeds/news/app/648800/?cc=US&l=english>
- STEAM 组可以在 Steam 社区链接尾部添加 `/rss` 订阅: <https://steamcommunity.com/groups/SteamLabs/rss> 或者在 Steam 新闻中心的 URL 里添加 `/feeds` 订阅 <https://store.steampowered.com/feeds/news/group/35143931/>
:::
## SteamGifts
@@ -456,23 +458,9 @@ Example: `https://store.steampowered.com/search/?specials=1&term=atelier` 中的
## 旅法师营地
### 旅法师营地
<Route author="qwertyuiop6" example="/lfsyd/1" path="/lfsyd/:typecode" :paramsDesc="['订阅分区类型']">
| 主页资讯 | 炉石传说 | 万智牌 | 昆特牌 | 游戏王 | 电子游戏 | 手机游戏 | 桌面游戏 |
| -------- | -------- | ------ | ------ | ------ | -------- | -------- | -------- |
| 1 | 2 | 3 | 14 | 16 | 4 | 22 | 9 |
| 影之诗 | Artifact | 玩家杂谈 | 营地电台 | 2047 | 魂武 |
| ------ | -------- | -------- | -------- | ---- | ---- |
| 17 | 67 | 21 | 5 | 62 | 68 |
</Route>
### 分区
<Route author="auto-bot-ty" example="/lfsyd/tag/17" path="/lfsyd/tag/:tag" :paramsDesc="['订阅分区类型']">
<Route author="auto-bot-ty" example="/lfsyd/tag/17" path="/lfsyd/tag/:tag" :paramsDesc="['订阅分区类型']" radar="1" rssbud="1">
| 炉石传说 | 万智牌 | 游戏王 | 昆特牌 | 影之诗 | 符文之地传奇 | 阴阳师百闻牌 |
| :------: | :----: | :----: | :----: | :----: | :----------: | :----------: |
@@ -484,6 +472,14 @@ Example: `https://store.steampowered.com/search/?specials=1&term=atelier` 中的
</Route>
### 用户的帖子
<Route author="auto-bot-ty" example="/lfsyd/user/55547" path="/lfsyd/user/:id" :paramsDesc="['用户 id']" radar="1" rssbud="1"/>
可以在用户主页的 URL 中找到
Example:`https://www.iyingdi.com/tz/people/55547` ,id 是 `55547`
## 米哈游
### 崩坏 2 - 游戏公告
@@ -512,6 +508,10 @@ Example: `https://store.steampowered.com/search/?specials=1&term=atelier` 中的
<Route author="Astrian" example="/arknights/news" path="/arknights/news"/>
### 塞壬唱片
<Route author="rikkablue" example="/siren/news" path="/siren/news"/>
## 奶牛关
### 元素文章
@@ -530,18 +530,18 @@ Example: `https://store.steampowered.com/search/?specials=1&term=atelier` 中的
</Route>
## 网易大神
### 用户发帖
<Route author="luyuhuang" example="/netease/ds/63dfbaf4117741daaf73404601165843" path="/netease/ds/:id" :paramsDesc="['用户ID']"/>
## 王者荣耀
### 新闻中心
<Route author="Jeason0228 HenryQW" example="/tencent/pvp/newsindex/all" path="/tencent/pvp/newsindex/:type" :paramsDesc="['栏目分类,all=全部,rm=热门,xw=新闻,gg=公告,hd=活动,ss=赛事']"/>
## 网易大神
### 用户发帖
<Route author="luyuhuang" example="/netease/ds/63dfbaf4117741daaf73404601165843" path="/netease/ds/:id" :paramsDesc="['用户ID']"/>
## 小黑盒
### 用户动态
@@ -606,6 +606,18 @@ Example: `https://store.steampowered.com/search/?specials=1&term=atelier` 中的
| 1 | 2 | 3 | 4 |
</Route>
## 游戏年轮
### 分类
<Route author="nczitzk" example="/bibgame/sgame" path="/bibgame/:category?/:type?" :paramsDesc="['分类,见下表,默认为PC游戏', '类型,可在各分类页中导航栏中找到']">
| PC 游戏 | PS4 游戏 | Switch 游戏 | NS 其他板块 | galgame | VR 游戏 | 3DS 游戏 | psv 游戏 | xbox360 游戏 | ps3 游戏 | 其他掌机 |
| ------- | -------- | ----------- | ----------- | ------- | ------- | -------- | -------- | ------------ | -------- | -------- |
| pcgame | ps4 | sgame | nsaita | ps | bt | 3ds | psv | jiaocheng | ps3yx | zhangji |
</Route>
## 游戏时光
### 游戏时光新闻
+35 -35
View File
@@ -16,6 +16,24 @@ pageClass: routes
</Route>
## 重庆市人民政府
### 两江新区信息公开网
#### 党务公开
<Route author="nczitzk" example="/gov/chongqing/ljxq/dwgk" path="/gov/chongqing/ljxq/dwgk"/>
#### 政务公开
<Route author="nczitzk" example="/gov/chongqing/ljxq/zwgk/lzyj" path="/gov/chongqing/ljxq/zwgk/:caty" :paramsDesc="['分类名']">
| 履职依据 | 公示公告 |
| -------- | -------- |
| lzyj | gsgg |
</Route>
## 广东省人民政府
### 广东省教育厅
@@ -247,6 +265,20 @@ pageClass: routes
<Route author="nczitzk" example="/gov/caict/caictgd" path="/gov/caict/caictgd"/>
## 中国证券监督管理委员会
### 发审委公告
<Route author="chinobing" example="/csrc/fashenwei" path="/csrc/fashenwei"/>
### 证监会消息
<Route author="chinobing LogicJake" example="/csrc/news/zjhxwfb-xwfbh" path="/csrc/news/:suffix?" :paramsDesc="['支持形如`http://www.csrc.gov.cn/pub/newsite/*/*`的网站,将 newsite 后面的两段网址后缀以 - 连接']" />
### 申请事项进度
<Route author="hillerliao" example="/csrc/auditstatus/:apply_id" path="/csrc/auditstatus" :paramsDesc="['事项类别id, `https://neris.csrc.gov.cn/alappl/home/xkDetail` 列表中各地址的 appMatrCde 参数']"/>
## 中国政府
### 数据
@@ -318,20 +350,6 @@ pageClass: routes
<Route author="EsuRt" example="/gov/statecouncil/briefing" path="/gov/statecouncil/briefing"/>
## 中国证券监督管理委员会
### 发审委公告
<Route author="chinobing" example="/csrc/fashenwei" path="/csrc/fashenwei"/>
### 证监会消息
<Route author="chinobing LogicJake" example="/csrc/news/zjhxwfb-xwfbh" path="/csrc/news/:suffix?" :paramsDesc="['支持形如`http://www.csrc.gov.cn/pub/newsite/*/*`的网站,将 newsite 后面的两段网址后缀以 - 连接']" />
### 申请事项进度
<Route author="hillerliao" example="/csrc/auditstatus/:apply_id" path="/csrc/auditstatus" :paramsDesc="['事项类别id, `https://neris.csrc.gov.cn/alappl/home/xkDetail` 列表中各地址的 appMatrCde 参数']"/>
## 中国政协网
### 栏目
@@ -542,12 +560,6 @@ pageClass: routes
| 贝尔法斯特 | `/embassy/uk/belfast` |
| 曼彻斯特 | `/embassy/uk/manchester` |
## 中華民國國防部
### 即時軍事動態
<Route author="nczitzk" example="/gov/taiwan/mnd" path="/gov/taiwan/mnd"/>
## 中华人民共和国国家发展和改革委员会
### 新闻动态
@@ -645,23 +657,11 @@ pageClass: routes
<Route author="nczitzk" example="/gov/mohurd/policy" path="/gov/mohurd/policy"/>
## 重庆市人民政府
## 中華民國國防部
### 两江新区信息公开网
### 即時軍事動態
#### 党务公开
<Route author="nczitzk" example="/gov/chongqing/ljxq/dwgk" path="/gov/chongqing/ljxq/dwgk"/>
#### 政务公开
<Route author="nczitzk" example="/gov/chongqing/ljxq/zwgk/lzyj" path="/gov/chongqing/ljxq/zwgk/:caty" :paramsDesc="['分类名']">
| 履职依据 | 公示公告 |
| -------- | -------- |
| lzyj | gsgg |
</Route>
<Route author="nczitzk" example="/gov/taiwan/mnd" path="/gov/taiwan/mnd"/>
## 中央纪委国家监委
+11
View File
@@ -21,6 +21,17 @@ sidebar: auto
4. [Heroku](https://devcenter.heroku.com/articles/getting-started-with-nodejs)
5. [Google App Engine](https://cloud.google.com/appengine/)
## Docker 镜像
默认推荐使用`diygod/rsshub`即`diygod/rsshub:latest`最新版镜像以获取最新路由.
当`diygod/rsshub:latest`存在问题时,可以使用以日期为标签的近期镜像临时使用,例如:
```bash
$ docker pull diygod/rsshub:2021-06-18
```
待最新镜像更新后在切换回`diygod/rsshub:latest`最新版镜像.
## Docker Compose 部署
### 安装
+6 -1
View File
@@ -8,7 +8,12 @@
## 规范
`pubDate`接受一个[Date Object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date)。或者是可以被正确解析的字符串。这里**并不推荐直接返回字符串的方式**,因为其行为可能在不同环境下不一致,[Date.parse()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/parse)
`pubDate`必须是一个
1. [Date Object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date)。
2. **不推荐,用于兼容** 可以被正确解析的字符串。因为其行为可能在不同环境下不一致,[Date.parse()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/parse),请尽量避免
同时,脚本传入的`pubDate`应当是对应**服务器所使用的时区/时间**。更多细节参阅下方工具类
## 使用工具类
+1 -1
View File
@@ -687,7 +687,7 @@ pageClass: routes
### 首页
<Route author="nczitzk" example="/bde4" path="/bde4/:type?/:caty?/:area?/:year?/:order?" :paramsDesc="['资源分类,见下表,默认为 `all` 即不限', '影视类型,见下表,默认为 `all` 即不限','制片地区,见下表,默认为 `all` 即不限','上映时间,此处填写年份不小于2000,默认为 `all` 即不限','影视排序,见下表,默认为更新时间']">
<Route author="nczitzk" example="/mp4er" path="/mp4er/:type?/:caty?/:area?/:year?/:order?" :paramsDesc="['资源分类,见下表,默认为 `all` 即不限', '影视类型,见下表,默认为 `all` 即不限','制片地区,见下表,默认为 `all` 即不限','上映时间,此处填写年份不小于2000,默认为 `all` 即不限','影视排序,见下表,默认为更新时间']">
#### 资源分类
+244 -170
View File
@@ -288,6 +288,18 @@ Tag
<Route author="loganrockmore" example="/grubstreet" path="/grubstreet" />
## HKEPC
### HKEPC 電腦領域
<Route author="TonyRL" example="/hkepc/news" path="/hkepc/:category?" :paramsDesc="['分類,見下表,默认为最新消息']">
| 專題報導 | 新聞中心 | 新品快遞 | 超頻領域 | 流動數碼 | 生活娛樂 | 會員消息 | 腦場新聞 | 業界資訊 | 最新消息 |
| ---------- | -------- | -------- | -------- | -------- | ------------- | -------- | -------- | -------- | -------- |
| coverStory | news | review | ocLab | digital | entertainment | member | price | press | latest |
</Route>
## iDaily 每日环球视野
### 今日 Timeline
@@ -599,6 +611,16 @@ Provides all of the Thrillist articles with the specified tag.
</Route>
## Topbook
### Overview
<Route author="nczitzk" example="/topbook/overview/24" path="/topbook/overview/:id?" :paramsDesc="['id,可在对应页面 URL 中找到,默认为今天看什么']"/>
### 今天看什么
<Route author="nczitzk" example="/topbook/today" path="/topbook/today"/>
## TOPYS
### 分类
@@ -652,16 +674,6 @@ Supported sub-sites:
</Route>
## 巴比特
### 作者专栏
<Route author="kt286" example="/8btc/45703" path="/8btc/:authorid" :paramsDesc="['作者ID,可在对应专辑页面的 URL 中找到']"/>
### 快讯
<Route author="hillerliao" example="/8btc/news/flash" path="/8btc/news/flash"/>
## 八阕
### 广角新闻
@@ -674,11 +686,15 @@ Supported sub-sites:
</Route>
## 百度知道日报
## 巴比特
### 精选
### 作者专栏
<Route author="1813927768" example="/baidu/daily" path="/baidu/daily"/>
<Route author="kt286" example="/8btc/45703" path="/8btc/:authorid" :paramsDesc="['作者ID,可在对应专辑页面的 URL 中找到']"/>
### 快讯
<Route author="hillerliao" example="/8btc/news/flash" path="/8btc/news/flash"/>
## 白鲸出海
@@ -686,6 +702,12 @@ Supported sub-sites:
<Route author="jeffcottLu" example="/baijing" path="/baijing"></Route>
## 百度知道日报
### 精选
<Route author="1813927768" example="/baidu/daily" path="/baidu/daily"/>
## 坂道系列官网资讯
### 乃木坂 46 新闻
@@ -914,54 +936,6 @@ area 分区选项
</Route>
## 懂球帝
::: tip 提示
- 可以通过头条新闻 + 参数过滤的形式获得早报、专题等内容。
:::
### 新闻
<Route author="HendricksZheng" example="/dongqiudi/top_news/1" path="/dongqiudi/top_news/:id?" :paramsDesc="['类别 id,不填默认头条新闻']" />
| 头条 | 深度 | 闲情 | D 站 | 中超 | 国际 | 英超 | 西甲 | 意甲 | 德甲 |
| ---- | ---- | ---- | ---- | ---- | ---- | ---- | ---- | ---- | ---- |
| 1 | 55 | 37 | 219 | 56 | 120 | 3 | 5 | 4 | 6 |
### 专题
<Route author="dxmpalb" example="/dongqiudi/special/41" path="/dongqiudi/special/:id" :paramsDesc="['专题 id, 可自行通过 https://www.dongqiudi.com/special/+数字匹配']">
| 新闻大爆炸 | 懂球帝十佳球 | 懂球帝本周 MVP |
| ---------- | ------------ | -------------- |
| 41 | 52 | 53 |
</Route>
### 早报
<Route author="HenryQW" example="/dongqiudi/daily" path="/dongqiudi/daily"/>
::: tip 提示
部分球队和球员可能会有两个 id, 正确 id 应该由 `5000` 开头.
:::
### 足球赛果
<Route author="HenryQW" example="/dongqiudi/result/50001755" path="/dongqiudi/result/:team" :paramsDesc="['球队 id, 可在[懂球帝数据](https://www.dongqiudi.com/data)中找到']"/>
### 球队新闻
<Route author="HenryQW" example="/dongqiudi/team_news/50001755" path="/dongqiudi/team_news/:team" :paramsDesc="['球队 id, 可在[懂球帝数据](https://www.dongqiudi.com/data)中找到']"/>
### 球员新闻
<Route author="HenryQW" example="/dongqiudi/player_news/50000339" path="/dongqiudi/player_news/:id" :paramsDesc="['球员 id, 可在[懂球帝数据](https://www.dongqiudi.com/data)中通过其队伍找到']"/>
## 东西智库
### 分类
@@ -1025,6 +999,54 @@ area 分区选项
</Route>
## 懂球帝
::: tip 提示
- 可以通过头条新闻 + 参数过滤的形式获得早报、专题等内容。
:::
### 新闻
<Route author="HendricksZheng" example="/dongqiudi/top_news/1" path="/dongqiudi/top_news/:id?" :paramsDesc="['类别 id,不填默认头条新闻']" />
| 头条 | 深度 | 闲情 | D 站 | 中超 | 国际 | 英超 | 西甲 | 意甲 | 德甲 |
| ---- | ---- | ---- | ---- | ---- | ---- | ---- | ---- | ---- | ---- |
| 1 | 55 | 37 | 219 | 56 | 120 | 3 | 5 | 4 | 6 |
### 专题
<Route author="dxmpalb" example="/dongqiudi/special/41" path="/dongqiudi/special/:id" :paramsDesc="['专题 id, 可自行通过 https://www.dongqiudi.com/special/+数字匹配']">
| 新闻大爆炸 | 懂球帝十佳球 | 懂球帝本周 MVP |
| ---------- | ------------ | -------------- |
| 41 | 52 | 53 |
</Route>
### 早报
<Route author="HenryQW" example="/dongqiudi/daily" path="/dongqiudi/daily"/>
::: tip 提示
部分球队和球员可能会有两个 id, 正确 id 应该由 `5000` 开头.
:::
### 足球赛果
<Route author="HenryQW" example="/dongqiudi/result/50001755" path="/dongqiudi/result/:team" :paramsDesc="['球队 id, 可在[懂球帝数据](https://www.dongqiudi.com/data)中找到']"/>
### 球队新闻
<Route author="HenryQW" example="/dongqiudi/team_news/50001755" path="/dongqiudi/team_news/:team" :paramsDesc="['球队 id, 可在[懂球帝数据](https://www.dongqiudi.com/data)中找到']"/>
### 球员新闻
<Route author="HenryQW" example="/dongqiudi/player_news/50000339" path="/dongqiudi/player_news/:id" :paramsDesc="['球员 id, 可在[懂球帝数据](https://www.dongqiudi.com/data)中通过其队伍找到']"/>
## 多知网
### 首页
@@ -1219,16 +1241,6 @@ others = 热点新闻 + 滚动新闻
<Route author="ciaranchen" example="/houxu/events" path="/houxu/events"/>
## 互动吧
### 活动
<Route author="nczitzk" example="/hudongba/beijing/98-0-2-0-1-1" path="/hudongba/:city/:id" :paramsDesc="['城市,可在选定所在城市后的页面 URL 中找到', '编号,可在选定筛选条件后的页面 URL 中找到']">
如例子 `/hudongba/beijing/98-0-2-0-1-1` 对应的网址 `https://www.hudongba.com/beijing/98-0-2-0-0-1` 中,`beijing` 即所在城市为北京;`98-0-2-0-0-1` 则是所选择的分类编号,指分类不限、时间不限、综合排序的所有亲子活动。
</Route>
## 虎嗅
### 首页资讯
@@ -1251,6 +1263,16 @@ others = 热点新闻 + 滚动新闻
<Route author="AlexdanerZe" example="/huxiu/collection/212" path="/huxiu/collection/:id" :paramsDesc="['文集 id']" />
## 互动吧
### 活动
<Route author="nczitzk" example="/hudongba/beijing/98-0-2-0-1-1" path="/hudongba/:city/:id" :paramsDesc="['城市,可在选定所在城市后的页面 URL 中找到', '编号,可在选定筛选条件后的页面 URL 中找到']">
如例子 `/hudongba/beijing/98-0-2-0-1-1` 对应的网址 `https://www.hudongba.com/beijing/98-0-2-0-0-1` 中,`beijing` 即所在城市为北京;`98-0-2-0-0-1` 则是所选择的分类编号,指分类不限、时间不限、综合排序的所有亲子活动。
</Route>
## 汇通网
### 7x24 小时快讯
@@ -1269,6 +1291,16 @@ others = 热点新闻 + 滚动新闻
</Route>
## 加美财经
<Route author="nczitzk" example="/caus" path="/caus/:category?" :paramsDesc="['分类,见下表,默认为全部']">
| 全部 | 要闻 | 商业 | 快讯 | 投资理财 | 生活 |
| ---- | ---- | ---- | ---- | -------- | ---- |
| 0 | 1 | 2 | 3 | 4 | 6 |
</Route>
## 贾真的电商 108 将
### 「108 将」实战分享
@@ -1524,6 +1556,34 @@ column 为 third 时可选的 category:
</Route>
## 梅花网
### 作品
<Route author="nczitzk" example="/meihua/shots/latest" path="/meihua/shots/:caty">
| 最新 | 热门 | 推荐 |
| ------ | ---- | --------- |
| latest | hot | recommend |
</Route>
### 文章
<Route author="nczitzk" example="/meihua/article/latest" path="/meihua/article/:caty">
| 最新 | 热门 |
| ------ | ---- |
| latest | hot |
</Route>
## 梅斯医学 MedSci
### 推荐
<Route author="nczitzk" example="/medsci/recommend" path="/medsci/recommend"/>
## 美国半导体行业协会
### 新闻
@@ -1548,28 +1608,6 @@ column 为 third 时可选的 category:
<Route author="nczitzk" example="/aflcio/blog" path="/aflcio/blog"/>
## 梅花网
### 作品
<Route author="nczitzk" example="/meihua/shots/latest" path="/meihua/shots/:caty">
| 最新 | 热门 | 推荐 |
| ------ | ---- | --------- |
| latest | hot | recommend |
</Route>
### 文章
<Route author="nczitzk" example="/meihua/article/latest" path="/meihua/article/:caty">
| 最新 | 热门 |
| ------ | ---- |
| latest | hot |
</Route>
## 镁客网 im2maker
### 镁客网频道
@@ -1582,11 +1620,43 @@ column 为 third 时可选的 category:
</Route>
## 梅斯医学 MedSci
## 摩点
### 推荐
### 众筹
<Route author="nczitzk" example="/medsci/recommend" path="/medsci/recommend"/>
<Route author="nczitzk" example="/modian/zhongchou" path="/modian/zhongchou/:category?/:sort?/:status?" :paramsDesc="['分类,见下表,默认为全部', '排序,见下表,默认为最新上线', '状态,见下表,默认为全部']">
分类
| 全部 | 游戏 | 动漫 | 出版 | 桌游 |
| ---- | ----- | ------ | ---------- | ---------- |
| all | games | comics | publishing | tablegames |
| 潮玩模型 | 影视 | 音乐 | 活动 | 设计 |
| -------- | ---------- | ----- | ---------- | ------ |
| toys | film-video | music | activities | design |
| 科技 | 食品 | 爱心通道 | 动物救助 |
| ---------- | ---- | -------- | -------- |
| technology | food | charity | animals |
| 个人愿望 | 其他 |
| -------- | ------ |
| wishes | others |
排序
| 最新上线 | 金额最高 | 评论最多 |
| -------- | --------- | ----------- |
| top_time | top_money | top_comment |
状态
| 全部 | 创意 | 预热 | 众筹中 | 众筹成功 |
| ---- | ---- | ------- | ------ | -------- |
| all | idea | preheat | going | success |
</Route>
## 摩根大通研究所
@@ -1788,6 +1858,10 @@ column 为 third 时可选的 category:
## 深圳新闻网
### 深圳市政府新闻发布厅
<Route author="nczitzk" example="/sznews/press" path="/sznews/press"/>
### 排行榜
<Route author="nczitzk" example="/sznews/ranking" path="/sznews/ranking"/>
@@ -1903,6 +1977,12 @@ column 为 third 时可选的 category:
</Route>
## 歪脑 wainao.me
### 所有文章
<Route author="shuiRong" example="/wainao-reads/all-articles" path="/wainao-reads/all-articles" />
## 外接大脑
### 文章
@@ -1915,12 +1995,6 @@ column 为 third 时可选的 category:
</Route>
## 歪脑 wainao.me
### 所有文章
<Route author="shuiRong" example="/wainao-reads/all-articles" path="/wainao-reads/all-articles" />
## 晚点 LatePost
<Route author="HaitianLiu nczitzk" example="/latepost" path="/latepost/:proma?" :paramsDesc="['栏目 id,见下表,默认为最新报道']">
@@ -1943,12 +2017,6 @@ column 为 third 时可选的 category:
</Route>
## 網路天文館
### 天象預報
<Route author="nczitzk" example="/tam/forecast" path="/tam/forecast"/>
## 网易号
### 更新
@@ -2002,23 +2070,11 @@ column 为 third 时可选的 category:
</Route>
## 维基百科
## 網路天文館
### 中国大陆新闻动态
### 天象預報
<Route author="HenryQW" example="/wikipedia/mainland" path="/wikipedia/mainland"/>
## 未名新闻
### 分类
<Route author="nczitzk" example="/mitbbs" path="/mitbbs/:caty?" :paramsDesc="['新闻分类,参见下表,默认为“新闻大杂烩”']">
| 新闻大杂烩 | 军事 | 国际 | 体育 | 娱乐 | 科技 | 财经 |
| ---------- | -------- | ------ | ---- | ---- | ---- | ------- |
| | zhongguo | haiwai | tiyu | yule | keji | caijing |
</Route>
<Route author="nczitzk" example="/tam/forecast" path="/tam/forecast"/>
## 微信
@@ -2096,6 +2152,24 @@ column 为 third 时可选的 category:
<Route author="xyqfer" example="/wechat/miniprogram/plugins" path="/wechat/miniprogram/plugins" />
## 维基百科
### 中国大陆新闻动态
<Route author="HenryQW" example="/wikipedia/mainland" path="/wikipedia/mainland"/>
## 未名新闻
### 分类
<Route author="nczitzk" example="/mitbbs" path="/mitbbs/:caty?" :paramsDesc="['新闻分类,参见下表,默认为“新闻大杂烩”']">
| 新闻大杂烩 | 军事 | 国际 | 体育 | 娱乐 | 科技 | 财经 |
| ---------- | -------- | ------ | ---- | ---- | ---- | ------- |
| | zhongguo | haiwai | tiyu | yule | keji | caijing |
</Route>
## 无产者评论
### 分类
@@ -2132,12 +2206,6 @@ column 为 third 时可选的 category:
</Route>
## 橡树岭国家实验室
### 新闻
<Route author="nczitzk" example="/ornl/news" path="/ornl/news"/>
## 香水时代
### 首页
@@ -2148,6 +2216,12 @@ column 为 third 时可选的 category:
<Route author="kt286" example="/nosetime/59247733/discuss/new" path="/nosetime/:id/:type/:sort?" :paramsDesc="['用户id,可在用户主页 URL 中找到', '类型,short 一句话香评 discuss 香评', '排序, new 最新 agree 最有用']"/>
## 橡树岭国家实验室
### 新闻
<Route author="nczitzk" example="/ornl/news" path="/ornl/news"/>
## 小刀娱乐网
<Route author="nczitzk" example="/x6d/34" path="/x6d/:id?" :paramsDesc="['分类 id,可在对应分类页面的 URL 中找到,默认为首页最近更新']">
@@ -2200,23 +2274,6 @@ column 为 third 时可选的 category:
<Route author="nczitzk" example="/yaohuo/new" path="/yaohuo/:type?" :paramsDesc="['排序类型,可选 `new` 指最新,`hot` 指最热,默认为 `new`']"/>
## 异次元软件世界
### 首页
<Route author="kimi360" example="/iplay/home" path="/iplay/home"/>
## 移动支付网
### 新闻
<Route author="LogicJake" example="/mpaypass/news" path="/mpaypass/news"/>
### 分类
<Route author="zhuan-zhu" example="/mpaypass/main/policy" path="mpaypass/main/:type?"
:paramsDesc="['新闻类型,类型可在URL中找到,类似policy,eye等,空或其他任意值展示最新新闻']"/>
## 一兜糖
### 首页精选
@@ -2243,12 +2300,41 @@ column 为 third 时可选的 category:
</Route>
## 移动支付网
### 新闻
<Route author="LogicJake" example="/mpaypass/news" path="/mpaypass/news"/>
### 分类
<Route author="zhuan-zhu" example="/mpaypass/main/policy" path="mpaypass/main/:type?"
:paramsDesc="['新闻类型,类型可在URL中找到,类似policy,eye等,空或其他任意值展示最新新闻']"/>
## 亿欧网
### 资讯
<Route author="WenryXu" example="/iyiou" path="/iyiou"/>
## 异次元软件世界
### 首页
<Route author="kimi360" example="/iplay/home" path="/iplay/home"/>
## 游戏葡萄
### 文章
<Route author="KotoriK nczitzk" example="/gamegrape/13" path="/gamegrape/:id?" :paramsDesc="['分类 id,见下表,默认为全部']">
| 全部 | 深度 | 资讯 | DemoWall | 酷玩 | 海外 | 专栏 | 葡萄观察 |
| ---- | ---- | ---- | -------- | ---- | ---- | ---- | -------- |
| | 13 | 14 | 15 | 16 | 17 | 18 | 19 |
</Route>
## 有趣天文奇观
### 首页
@@ -2263,18 +2349,6 @@ column 为 third 时可选的 category:
<Route author="nczitzk" example="/interesting-sky/recent-interesting" path="/interesting-sky/recent-interesting"/>
## 游戏葡萄
### 文章
<Route author="KotoriK nczitzk" example="/gamegrape/13" path="/gamegrape/:id?" :paramsDesc="['分类 id,见下表,默认为全部']">
| 全部 | 深度 | 资讯 | DemoWall | 酷玩 | 海外 | 专栏 | 葡萄观察 |
| ---- | ---- | ---- | -------- | ---- | ---- | ---- | -------- |
| | 13 | 14 | 15 | 16 | 17 | 18 | 19 |
</Route>
## 鱼塘热榜
<Route author="TheresaQWQ" example="/mofish/2" path="/mofish/:id" :paramsDesc="['分类id,可以在 https://api.tophub.fun/GetAllType 获取']" />
@@ -2288,18 +2362,6 @@ column 为 third 时可选的 category:
</Route>
## 中国计算机学会
### 新闻
<Route author="nczitzk" example="/ccf/news" path="/ccf/news/:category?" :paramsDesc="['分类,见下表,默认为 CCF 新闻']">
| CCF 新闻 | CCF 聚焦 | ACM 信息 |
| ---------- | -------- | -------- |
| Media_list | Focus | ACM_News |
</Route>
## 中国机械工程学会
### 学会新闻
@@ -2312,6 +2374,18 @@ column 为 third 时可选的 category:
</Route>
## 中国计算机学会
### 新闻
<Route author="nczitzk" example="/ccf/news" path="/ccf/news/:category?" :paramsDesc="['分类,见下表,默认为 CCF 新闻']">
| CCF 新闻 | CCF 聚焦 | ACM 信息 |
| ---------- | -------- | -------- |
| Media_list | Focus | ACM_News |
</Route>
## 中国科学院青年创新促进会
### 最新博文
+25 -13
View File
@@ -310,6 +310,12 @@ type 为 all 时,category 参数不支持 cost 和 free
</Route>
## 艾瑞
### 产业研究报告
<Route author="brilon" example="/iresearch/report" path="/iresearch/report"/>
## 爱 Q 生活网
### 最近更新
@@ -339,12 +345,6 @@ type 为 all 时,category 参数不支持 cost 和 free
<Route author="sanmmm" example="/afdian/dynamic/@afdian" path="/afdian/dynamic/:uid?" :paramsDesc="['用户id, 用户动态页面url里可找到']"/>
## 艾瑞
### 产业研究报告
<Route author="brilon" example="/iresearch/report" path="/iresearch/report"/>
## 百度搜索风云榜
### 榜单
@@ -686,7 +686,7 @@ type 为 all 时,category 参数不支持 cost 和 free
### 郵便追跡サービス
<Route author="tuzi3040" example="/japanpost/EJ123456789JP/ja" path="/japanpost/:reqCode/:locale?" :paramsDesc="['运单号', '语言,默认为`ja`']" radar="1" rssbud="1">
<Route author="tuzi3040" example="/japanpost/track/EJ123456789JP/ja" path="/japanpost/track/:reqCode/:locale?" :paramsDesc="['运单号', '语言,默认为`ja`']" radar="1" rssbud="1">
| 日语 | 英语 |
| ---- | ---- |
@@ -854,12 +854,6 @@ type 为 all 时,category 参数不支持 cost 和 free
<Route author="luyuhuang" example="/emi-nitta/news" path="/emi-nitta/news"/>
## 油价
### 今日油价
<Route author="xyqfer" example="/oilprice/shanghai" path="/oilprice/:area" :paramsDesc="['地区拼音,详见[成品油价格网](http://oil.usd-cny.com/)']"/>
## 邮箱
### 邮件列表
@@ -868,6 +862,12 @@ type 为 all 时,category 参数不支持 cost 和 free
<Route author="kt286" example="/mail/imap/rss@rsshub.app" path="/mail/imap/:email" :paramsDesc="['邮箱账号']" selfhost="1"/>
## 油价
### 今日油价
<Route author="xyqfer" example="/oilprice/shanghai" path="/oilprice/:area" :paramsDesc="['地区拼音,详见[成品油价格网](http://oil.usd-cny.com/)']"/>
## 源仓库
### 源仓库更新
@@ -973,3 +973,15 @@ type 为 all 时,category 参数不支持 cost 和 free
### はてな匿名ダイアリー - 人気記事アーカイブ
<Route author="masakichi" example="/hatena/anonymous_diary/archive" path="/hatena/anonymous_diary/archive"/>
### 澳門特別行政區政府各公共部門獎助貸學金服務平台
官方網址:<https://www.bolsas.gov.mo/>
<Route author="KeiLongW" example="/macau-bolsas" path="/macau-bolsas/:lang?" :paramsDesc="['語言']" >
| 中文 | 葡文 |
| ---- | ---- |
| ch | pt |
</Route>
+16 -1
View File
@@ -302,6 +302,16 @@ Tiny Tiny RSS 会给所有 iframe 元素添加 `sandbox="allow-scripts"` 属性
<Route author="hoilc" example="/bilibili/manga/update/26009" path="/bilibili/manga/update/:comicid" :paramsDesc="['漫画 id, 可在 URL 中找到, 支持带有`mc`前缀']"/>
### 用户追漫更新
<Route author="yindaheng98" example="/bilibili/manga/followings/26009" path="/manga/followings/:uid/:limits?" :paramsDesc="['用户 id', '抓取最近更新前多少本漫画,默认为10']" selfhost="1">
::: warning 注意
用户追漫需要 b 站登录后的 Cookie 值,所以只能自建,详情见部署页面的配置模块。
:::
</Route>
## Dev.to
### 最高职位
@@ -519,8 +529,13 @@ Tiny Tiny RSS 会给所有 iframe 元素添加 `sandbox="allow-scripts"` 属性
### 关键词
<Route author="DIYgod" example="/pixiv/search/麻衣/popular/2" path="/pixiv/search/:keyword/:order?/:r18?" :paramsDesc="['关键词', '排序方式,popular 按热门度排序,空或其他任意值按时间排序', '过滤 R18 内容,0 为不过滤,1 为只看非 R18 内容,2 为只看 R18 内容,默认为 0']" radar="1" rssbud="1"/>
<Route author="DIYgod" example="/pixiv/search/麻衣/popular/2" path="/pixiv/search/:keyword/:order?/:mode?" :paramsDesc="['关键词', '排序方式,popular 按热门度排序,空或其他任意值按时间排序', '过滤方式']" radar="1" rssbud="1">
| 只看非 R18 内容 | 只看 R18 内容 | 不过滤 |
| --------------- | ------------- | -------------- |
| safe | r18 | 空或其他任意值 |
</Route>
### 关注的新作品
<Route author="ClarkeCheng" example="/pixiv/user/illustfollows" path="/pixiv/user/illustfollows" radar="1" rssbud="1" selfhost="1"/>
+1 -1
View File
@@ -246,7 +246,7 @@ pageClass: routes
## 幕布精选
<Route author="laampui" example="/mubu/explore/16/读书笔记" path="/mubu/explore/:tagId/:title?" :paramsDesc="['标签 id', '显示标题']" />
<Route author="laampui nczitzk" example="/mubu/explore/16/读书笔记" path="/mubu/explore/:category?/:title?" :paramsDesc="['分类 id', '显示标题']" />
## 扇贝
+226 -71
View File
@@ -29,7 +29,7 @@ pageClass: routes
### 话题
<Route author="mjysci" example="/apnews/topics2/ap-top-news" path="/apnews/topics2/:topic" :paramsDesc="['话题名称,可在 URL 中找到,例如 AP Top News [https://apnews.com/hub/ap-top-news](https://apnews.com/hub/ap-top-news) 的话题为 `ap-top-news`']" anticrawler="1"/>
采用了`puppeteer`规避`Project Shield`,无全文抓取,建议自建。
采用了 `puppeteer` 规避 `Project Shield`,无全文抓取,建议自建。
## BBC
@@ -186,7 +186,7 @@ pageClass: routes
<Route author="tpnonthealps" example="/mediadigest/latest" path="/mediadigest/:range" :paramsDesc="['时间范围']">
细则:
细则:
- `:range` 时间范围参数
(可为 `latest` 或 `四位数字的年份`)
@@ -213,9 +213,9 @@ Solidot 提供的 feed:
:::
| 全部 | 创业 | Linux | 科学 | 科技 | 移动 | 苹果 | 硬件 | 软件 | 安全 | 游戏 | 书籍 | ask | idle | 博客 | 云计算 |
| ---- | ------- | ----- | ------- | ---------- | ------ | ----- | -------- | -------- | -------- | ----- | ----- | --- | ---- | ---- | ------ |
| www | startup | linux | science | technology | mobile | apple | hardware | software | security | games | books | ask | idle | blog | cloud |
| 全部 | 创业 | Linux | 科学 | 科技 | 移动 | 苹果 | 硬件 | 软件 | 安全 | 游戏 | 书籍 | ask | idle | 博客 | 云计算 | 奇客故事 |
| ---- | ------- | ----- | ------- | ---------- | ------ | ----- | -------- | -------- | -------- | ----- | ----- | --- | ---- | ---- | ------ | -------- |
| www | startup | linux | science | technology | mobile | apple | hardware | software | security | games | books | ask | idle | blog | cloud | story |
</Route>
@@ -389,6 +389,130 @@ Category 列表:
<Route author="boypt" example="/caixin/yxnews" path="/caixin/yxnews"/>
## 朝日新聞中文網(繁體中文版)
::: tip 提示
朝日新闻中文网已于 2021 年 3 月 31 日关闭。
:::
### 新聞
<Route author="nczitzk" example="/asahi" path="/asahi/:genre?/:category?" :paramsDesc="['类型,见下表,默认为トップ', '分类,见下表,默认为空,即该类型下所有新闻']">
::: tip 提示
以下小标题即类型 `genre`,标题下表格中为对应类型的分类 `category`,两者需要配合使用。
如订阅 **社会** 类型中的 **事件・事故・裁判** 分类,填入 [`/asahi/national/incident`](http://rsshub.app/asahi/national/incident)。
若类型下没有分类,如 **トップ** 类型,直接填入 [`/asahi/top`](http://rsshub.app/asahi/top)。
或者欲订阅该类型下的所有分类,如订阅 **社会** 中的所有分类,则直接将分类 `category` 留空,即 [`/asahi/national`](http://rsshub.app/asahi/national)。
:::
トップ top
社会 national
| 事件・事故・裁判 | 災害・交通情報 | その他・話題 | おくやみ |
| ---------------- | -------------- | ------------ | ---------- |
| incident | calamity | etc | obituaries |
経済 business
| 産業・商品 | 金融・財政 | 経済政策 | 労働・雇用 | 市況・統計 |
| ---------- | ---------- | -------------- | ---------- | ---------- |
| industry | finance | economicpolicy | work | statistics |
政治 politics
| 国政 | 地方政治 | 発言録 | 世論調査 |
| ---------- | -------- | ------------ | -------- |
| government | local | hatsugenroku | yoron |
国際 international
| アジア・太平洋 | 北米 | 中南米 | ヨーロッパ | 中東 | アフリカ | 国連・その他 |
| -------------- | -------- | -------- | ---------- | ---------- | -------- | ------------ |
| asia | namerica | samerica | europe | middleeast | africa | etc |
スポーツ sports
| 野球 | サッカー | 相撲 | フィギュア | ゴルフ | 一般スポーツ | 東京オリンピック 2020 | 東京パラリンピック 2020 |
| -------- | -------- | ---- | ------------------ | ------ | ------------ | --------------------- | ----------------------- |
| baseball | soccer | sumo | winter_figureskate | golf | general | olympics | paralympics |
IT・科学 tech_science
| 環境・エネルギー | 科学 | デジもの | 企業・サービス | 製品ファイル |
| ---------------- | ------- | -------- | -------------- | ------------ |
| eco | science | digital | service | products |
文化・芸能 culture
| 映画 | 音楽 | アイドル | アート | テレビ・芸能 | 舞台・演芸 | マンガ・アニメ・ゲーム | ひと・歴史 | 囲碁 | 将棋 |
| ------ | ----- | -------- | ------ | ------------ | ---------- | ---------------------- | ---------- | ---- | ------ |
| movies | music | idol | art | showbiz | stage | manga | history | igo | shougi |
ライフ life
| 介護 | 働き方・就活 | 食・料理 |
| --------- | ------------ | -------- |
| eldercare | hataraku | food |
教育・子育て edu
| 小中高 | 大学 | 教育制度・話題 | 教育問題 | 地域の教育ニュース | 吹奏楽 | 合唱 | 子育て | ハグスタ |
| ------- | ---------- | -------------- | -------- | ------------------ | --------- | ------ | -------- | -------- |
| student | university | system | issue | chiiki | suisogaku | gassho | hagukumu | msta |
</Route>
## 朝日新聞デジタル
<Route author="nczitzk" example="/asahi/area/hokkaido" path="/asahi/area/:id" :paramsDesc="['地方 id,见下表']">
北海道・東北
| 北海道 | 青森 | 秋田 | 岩手 | 山形 | 宮城 | 福島 |
| -------- | ------ | ----- | ----- | -------- | ------ | --------- |
| hokkaido | aomori | akita | iwate | yamagata | miyagi | fukushima |
関東
| 群馬 | 茨城 | 栃木 | 埼玉 | 千葉 | 東京 | 神奈川 |
| ----- | ------- | ------- | ------- | ----- | ----- | -------- |
| gunma | ibaraki | tochigi | saitama | chiba | tokyo | kanagawa |
東海・甲信越
| 静岡 | 岐阜 | 愛知 | 三重 | 新潟 | 山梨 | 長野 |
| -------- | ---- | ----- | ---- | ------- | --------- | ------ |
| shizuoka | gifu | aichi | mie | niigata | yamanashi | nagano |
近畿・北陸
| 滋賀 | 京都 | 奈良 | 和歌山 | 大阪 | 兵庫 | 富山 | 石川 | 福井 |
| ----- | ----- | ---- | -------- | ----- | ----- | ------ | -------- | ----- |
| shiga | kyoto | nara | wakayama | osaka | hyogo | toyama | ishikawa | fukui |
中国・四国
| 鳥取 | 島根 | 岡山 | 広島 | 山口 | 香川 | 愛媛 | 徳島 | 高知 |
| ------- | ------- | ------- | --------- | --------- | ------ | ----- | --------- | ----- |
| tottori | shimane | okayama | hiroshima | yamaguchi | kagawa | ehime | tokushima | kochi |
九州・沖縄
| 福岡 | 大分 | 宮崎 | 鹿児島 | 佐賀 | 長崎 | 熊本 | 沖縄 |
| ------- | ---- | -------- | --------- | ---- | -------- | -------- | ------- |
| fukuoka | oita | miyazaki | kagoshima | saga | nagasaki | kumamoto | okinawa |
</Route>
## 第一财经
### 直播区
@@ -514,6 +638,92 @@ Type 栏目:
## 经济观察网
### 栏目
<Route author="nczitzk" example="/eeo/yaowen/dashi" path="/eeo/:column?/:category?" :paramsDesc="['栏目,见下表,默认为 商业产业', '分类,见下表,默认为该栏目下所有分类']">
::: tip 提示
以下小标题即栏目 `column`,标题下表格中为对应栏目的分类 `category`,两者需要配合使用。
如订阅 **时事・政策・宏观** 栏目中的 **大宗商品** 分类,填入 [`/eeo/yaowen/dzsp`](http://rsshub.app/eeo/yaowen/dzsp)。
若栏目下没有分类,如 **商业产业** 栏目,直接填入 [`/eeo/shangyechanye`](http://rsshub.app/eeo/shangyechanye)。
或者欲订阅该栏目下的所有分类,如订阅 **时事・政策・宏观** 中的所有分类,则直接将分类 `category` 留空,即 [`/eeo/yaowen`](http://rsshub.app/eeo/yaowen)。
:::
商业产业 shangyechanye [`/eeo/shangyechanye`](http://rsshub.app/eeo/shangyechanye)
财经 caijing [`/eeo/caijing`](http://rsshub.app/eeo/caijing)
上市公司 ssgsn [`/eeo/ssgsn`](http://rsshub.app/eeo/ssgsn)
地产 dichan [`/eeo/dichan`](http://rsshub.app/eeo/dichan)
汽车 qiche [`/eeo/qiche`](http://rsshub.app/eeo/qiche)
TMT tmt [`/eeo/tmt`](http://rsshub.app/eeo/tmt)
评论 pinglun [`/eeo/pinglun`](http://rsshub.app/eeo/pinglun)
研究院 yanjiuyuan [`/eeo/yanjiuyuan`](http://rsshub.app/eeo/yanjiuyuan)
::: tip 建议
请优先选择订阅以上栏目,下面的栏目大部分已经很久没有更新。
:::
两会 lianghui [`/eeo/lianghui`](http://rsshub.app/eeo/lianghui)
时事・政策・宏观 yaowen [`/eeo/yaowen`](http://rsshub.app/eeo/yaowen)
| 时事 | 政策 | 宏观 | 智库 | 首席观点 | 大宗商品 |
| ----- | ------ | ------- | ---------- | -------- | -------- |
| dashi | hfggzc | hfshuju | hfdongjian | sxgd | dzsp |
证券・资本・理财 jinrong [`/eeo/jinrong`](http://rsshub.app/eeo/jinrong)
| 债市 | 资本 | 理财 | 证券 | 银行 |
| ------- | ----- | ----- | --------- | ----- |
| zhaishi | ziben | licai | zhengquan | jijin |
| 保险 | PE / 创投 | 科创板 | 新三板 | 互联网金融 |
| ------- | --------- | ----------- | --------- | ---------- |
| jinkong | chuangtou | kechuangban | xinsanban | hlwjr |
新科技・互联网・O2O shangye [`/eeo/shangye`](http://rsshub.app/eeo/shangye)
| 新科技 | 互联网 | 大健康 | O2O | 花蕾之约 | 创业家笔记 | 环境 |
| ----------- | --------- | ------ | ----- | ------------ | ---------- | -------- |
| xinnengyuan | dianshang | yiliao | wuliu | hualeizhiyue | cyjbj | huanjing |
房产・汽车・消费 fcqcxf [`/eeo/fcqcxf`](http://rsshub.app/eeo/fcqcxf)
| 房产 | 汽车 | 消费 |
| ------ | ----- | ------- |
| dichan | qiche | xiaofei |
影视・体育・娱乐 yule [`/eeo/yule`](http://rsshub.app/eeo/yule)
| 娱乐 | 影视 | 体育 | 教育 |
| ---- | ------- | ---- | ------ |
| yule | yingshi | tiyu | jiaoyu |
观察家・书评・思想 gcj [`/eeo/gcj`](http://rsshub.app/eeo/gcj)
| 观察家 | 专栏 | 个人历史 | 书评 |
| ---------- | -------- | -------- | ------- |
| guanchajia | zhuanlan | lishi | shuping |
| 纵深 | 文化 | 领读 |
| -------- | ------ | ------ |
| zongshen | wenhua | lingdu |
</Route>
### 分类资讯
<Route author="epirus" example="/eeo/15" path="/eeo/:category" :paramsDesc="['分类']">
@@ -532,6 +742,14 @@ category 对应的关键词有
<Route author="wushijishan" example="/kaopunews/all" path="/kaopunews/all"/>
## 连线 Wired
非订阅用户每月有阅读全文次数限制。
### 标签
<Route author="Naiqus" example="/wired/tag/bitcoin" path="/wired/tag/:tag" :paramsDesc="['标签']"/>
## 联合早报
### 即时新闻
@@ -560,14 +778,6 @@ category 对应的关键词有
<Route author="lengthmin" example="/zaobao/wencui/politic" path="/zaobao/:type/:section" :paramsDesc="['https://www.zaobao.com/**wencui**/politic 中的 **wencui**', 'https://www.zaobao.com/wencui/**politic** 中的 **politic**']" />
## 连线 Wired
非订阅用户每月有阅读全文次数限制。
### 标签
<Route author="Naiqus" example="/wired/tag/bitcoin" path="/wired/tag/:tag" :paramsDesc="['标签']"/>
## 路透社
### 实时资讯
@@ -656,9 +866,10 @@ category 对应的关键词有
</Route>
### 每日简报
### 新闻简报
<Route author="xyqfer" example="/nytimes/morning_post" path="/nytimes/morning_post"/>
<Route author="yueyericardo" example="/nytimes/daily_briefing_chinese" path="/nytimes/daily_briefing_chinese"/>
网站地址:<https://www.nytimes.com/zh-hans/series/daily-briefing-chinese/>
### 畅销书排行榜
@@ -934,62 +1145,6 @@ category 对应的关键词有
<Route author="nczitzk" example="/cctv/photo/jx" path="/cctv/photo/jx" />
## 朝日新聞中文網(繁體中文版)
### 新聞分類
<Route author="qiwihui" example="/asahichinese-f/society" path="/asahichinese-f/:category/:subCate?" :paramsDesc="['版块', '子版块']">
版块:
| society | politics_economy | cool_japan | travel | sports | business | technology | world | opinion | whatsnew |
| -------- | ---------------- | ---------- | ---------- | ---------- | ---------- | ---------- | ---------- | ---------- | -------- |
| 國內綜合 | 政治・經濟 | 文化・生活 | 旅遊・活動 | 體育・奧運 | 商業・商品 | IT ・科技 | 國際・東亞 | 評論・專欄 | 最新消息 |
版块 `cool_japan` 和 `travel` 包含子版块:
`cool_japan`:
| entertainment | anime | life | style_culture |
| ------------- | ----- | ---------- | ------------- |
| 藝能 | 動漫 | 生活・美食 | 時尚・藝文 |
`travel`:
| news | scenery | topic | move |
| ---- | ------- | ----- | ---- |
| 資訊 | 風景 | 體驗 | 交通 |
</Route>
## 朝日新聞中文网(简体中文版)
### 新闻分类
<Route author="zhouchang29" example="/asahichinese-j/society" path="/asahichinese-j/:category/:subCate?" :paramsDesc="['版块', '子版块']">
版块:
| society | politics_economy | cool_japan | travel | sports | business | technology | world | opinion | whatsnew |
| -------- | ---------------- | ---------- | ---------- | ---------- | ---------- | ---------- | ---------- | ---------- | -------- |
| 日本社会 | 政治・经济 | 文娱・生活 | 旅游・活动 | 体育・奥运 | 商务・商品 | IT ・科技 | 国际・东亚 | 观点・专栏 | 最新 |
版块 `cool_japan` 和 `travel` 包含子版块:
`cool_japan`:
| entertainment | anime | life | style_culture |
| ------------- | ----- | ---------- | ------------- |
| 艺能 | 动漫 | 生活・美食 | 时尚・文化 |
`travel`:
| news | scenery | topic | move |
| ---- | ------- | ----- | ---- |
| 资讯 | 风景 | 体验 | 交通 |
</Route>
## 中国日报
### 英语点津
+142 -94
View File
@@ -301,6 +301,94 @@ pageClass: routes
</Route>
## 重庆大学
### 教务网通知公告
<Route author="El-Chiang" example="/cqu/jwc/announcement" path="/cqu/jwc/announcement"/>
### 新闻网讲座预告
<Route author="nicolaszf" example="/cqu/news/jzyg" path="/cqu/news/jzyg"/>
### 新闻网通知公告简报
<Route author="Hagb" example="/cqu/news/tz" path="/cqu/news/tz"/>
### 校团委
<Route author="Hagb" example="/cqu/youth/gzdt" path="/cqu/youth/:category" :paramsDesc="['分类名']">
| 工作动态 | 院系风采 | 通知公告(可能需内网) | 文件转载 |
| -------- | -------- | ---------------------- | -------- |
| gzdt | yxfc | tzgg | wjzz |
</Route>
### 数学与统计学院
<Route author="Hagb" example="/cqu/sci/1053" path="/cqu/sci/:category" :paramsDesc="['分类名']">
| 学院新闻 | 学院公告 | 学院活动 | 学术活动 |
| -------- | -------- | -------- | -------- |
| 1053 | 1054 | 1055 | 1056 |
</Route>
### 信息化办公室
<Route author="Hagb" example="/cqu/net/tzgg" path="/cqu/net/:category" :paramsDesc="['分类名']">
| 通知公告 | 单位动态 | 语言文字 |
| -------- | -------- | -------- |
| tzgg | dwdt | yywz |
</Route>
## 重庆科技学院
### 教务处公告
<Route author="binarization" example="/cqust/jw/notify" path="/cqust/jw/:type?" :paramsDesc="['可选, 默认为 `notify`']">
| 通知公告 | 教务快讯 |
| -------- | -------- |
| notify | news |
</Route>
### 图书馆公告
<Route author="binarization" example="/cqust/lib/news" path="/cqust/lib/:type?" :paramsDesc="['可选, 默认为 `news`']">
| 本馆公告 |
| -------- |
| news |
</Route>
## 重庆理工大学
### 学校通知
<Route author="Colin-XKL" example="/cqut/news" path="/cqut/news" radar="1"/>
### 图书馆通知
<Route author="Colin-XKL" example="/cqut/libnews" path="/cqut/libnews" radar="1"/>
## 重庆文理学院
### 通知公告
<Route author="Fatpandac" example="/cqwu/news/academiceve" path="/cqwu/news/:type?" :paramsDesc="['可选,默认为 academiceve ']" radar="1">
| 通知公告 | 学术活动公告 |
| -------- | ------------ |
| notify | academiceve |
</Route>
## 大连大学
### 教务处信息
@@ -354,6 +442,38 @@ pageClass: routes
</Route>
## 大连理工大学
### 教务处
<Route author="beautyyuyanli" example="/dut/teach/zytg" path="/dut/teach/:type" :paramsDesc="['通知类型']">
| 重要通告 | 新闻快递 | 教学文件 | 其他文件 |
| -------- | -------- | -------------- | ----------- |
| zytg | xwkd | jiaoxuewenjian | qitawenjian |
</Route>
### 体育场馆中心
<Route author="beautyyuyanli" example="/dut/tycgzx/hdrc" path="/dut/tycgzx/:type" :paramsDesc="['通知类型']">
| 通知公告 | 活动日程 | 新闻动态 |
| -------- | -------- | -------- |
| tzgg | hdrc | xwdt |
</Route>
### 国际处及港澳台办
<Route author="beautyyuyanli" example="/dut/dutdice/xwsd" path="/dut/dutdice/:type" :paramsDesc="['通知类型']">
| 学生通知 | 教师通知 | 新闻速递 |
| ---------- | -------- | -------- |
| xstong_zhi | jstz | xwsd |
</Route>
## 电子科技大学
### 教务处
@@ -492,12 +612,6 @@ xskb1 对应 <http://www.auto.uestc.edu.cn/index/xskb1.htm>
</Route>
## 复旦大学继续教育学院
### 成人夜大通知公告
<Route author="mrbruce516" example="/fudan/cce" path="/fudan/cce" />
## 福州大学
### 教务处通知
@@ -508,6 +622,12 @@ xskb1 对应 <http://www.auto.uestc.edu.cn/index/xskb1.htm>
| -------- | -------- |
| jxtz | zjjz |
## 复旦大学继续教育学院
### 成人夜大通知公告
<Route author="mrbruce516" example="/fudan/cce" path="/fudan/cce" />
## 广东工业大学
### 校内新闻网
@@ -711,6 +831,12 @@ category 列表:
<Route author="raptazure" example="/hitwh/today" path="hitwh/today" />
## 海南大学
### 硕士研究生招生动态
<Route author="OdinZhang" example="/hainanu/ssszs" path="hainanu/ssszs"/>
## 合肥工业大学
### 通知公告
@@ -2155,6 +2281,16 @@ type 列表:
</Route>
### 中国科学技术大学就业信息网
<Route author="nczitzk" example="/ustc/job" path="/ustc/job/:category?" :paramsDesc="['分类,见下表,默认为招聘公告']">
| 专场招聘会 | 校园双选会 | 空中宣讲 | 招聘公告 |
| ----------- | ------------ | --------- | -------- |
| RecruitList | Doublechoice | Broadcast | joblist2 |
</Route>
## 中国科学院
### 成果转化
@@ -2249,94 +2385,6 @@ type 列表:
</Route>
## 重庆大学
### 教务网通知公告
<Route author="El-Chiang" example="/cqu/jwc/announcement" path="/cqu/jwc/announcement"/>
### 新闻网讲座预告
<Route author="nicolaszf" example="/cqu/news/jzyg" path="/cqu/news/jzyg"/>
### 新闻网通知公告简报
<Route author="Hagb" example="/cqu/news/tz" path="/cqu/news/tz"/>
### 校团委
<Route author="Hagb" example="/cqu/youth/gzdt" path="/cqu/youth/:category" :paramsDesc="['分类名']">
| 工作动态 | 院系风采 | 通知公告(可能需内网) | 文件转载 |
| -------- | -------- | ---------------------- | -------- |
| gzdt | yxfc | tzgg | wjzz |
</Route>
### 数学与统计学院
<Route author="Hagb" example="/cqu/sci/1053" path="/cqu/sci/:category" :paramsDesc="['分类名']">
| 学院新闻 | 学院公告 | 学院活动 | 学术活动 |
| -------- | -------- | -------- | -------- |
| 1053 | 1054 | 1055 | 1056 |
</Route>
### 信息化办公室
<Route author="Hagb" example="/cqu/net/tzgg" path="/cqu/net/:category" :paramsDesc="['分类名']">
| 通知公告 | 单位动态 | 语言文字 |
| -------- | -------- | -------- |
| tzgg | dwdt | yywz |
</Route>
## 重庆科技学院
### 教务处公告
<Route author="binarization" example="/cqust/jw/notify" path="/cqust/jw/:type?" :paramsDesc="['可选, 默认为 `notify`']">
| 通知公告 | 教务快讯 |
| -------- | -------- |
| notify | news |
</Route>
### 图书馆公告
<Route author="binarization" example="/cqust/lib/news" path="/cqust/lib/:type?" :paramsDesc="['可选, 默认为 `news`']">
| 本馆公告 |
| -------- |
| news |
</Route>
## 重庆理工大学
### 学校通知
<Route author="Colin-XKL" example="/cqut/news" path="/cqut/news" radar="1"/>
### 图书馆通知
<Route author="Colin-XKL" example="/cqut/libnews" path="/cqut/libnews" radar="1"/>
## 重庆文理学院
### 通知公告
<Route author="Fatpandac" example="/cqwu/news/academiceve" path="/cqwu/news/:type?" :paramsDesc="['可选,默认为 academiceve ']" radar="1">
| 通知公告 | 学术活动公告 |
| -------- | ------------ |
| notify | academiceve |
</Route>
## 中山大学
### 数据科学与计算机学院动态
+1 -1
View File
@@ -107,7 +107,7 @@ Please ensure you have deployed the [master branch](https://github.com/DIYgod/RS
if (config.isPackage) {
ctx.body = {
error: {
message: err.message,
message: err.message ? err.message : err,
},
};
} else {
+42 -15
View File
@@ -86,6 +86,7 @@ router.get('/bilibili/followings/article/:uid', require('./routes/bilibili/follo
router.get('/bilibili/readlist/:listid', require('./routes/bilibili/readlist'));
router.get('/bilibili/weekly', require('./routes/bilibili/weekly_recommend'));
router.get('/bilibili/manga/update/:comicid', require('./routes/bilibili/manga_update'));
router.get('/bilibili/manga/followings/:uid/:limits?', require('./routes/bilibili/manga_followings'));
router.get('/bilibili/app/:id?', require('./routes/bilibili/app'));
// bangumi
@@ -173,7 +174,7 @@ router.get('/pixiv/user/bookmarks/:id', require('./routes/pixiv/bookmarks'));
router.get('/pixiv/user/illustfollows', require('./routes/pixiv/illustfollow'));
router.get('/pixiv/user/:id', require('./routes/pixiv/user'));
router.get('/pixiv/ranking/:mode/:date?', require('./routes/pixiv/ranking'));
router.get('/pixiv/search/:keyword/:order?/:r18?', require('./routes/pixiv/search'));
router.get('/pixiv/search/:keyword/:order?/:mode?', require('./routes/pixiv/search'));
// pixiv-fanbox
router.get('/fanbox/:user?', require('./routes/fanbox/main'));
@@ -336,7 +337,7 @@ router.get('/yande.re/post/popular_recent', require('./routes/yande.re/post_popu
router.get('/yande.re/post/popular_recent/:period', require('./routes/yande.re/post_popular_recent'));
// 纽约时报
router.get('/nytimes/morning_post', require('./routes/nytimes/morning_post'));
router.get('/nytimes/daily_briefing_chinese', require('./routes/nytimes/daily_briefing_chinese'));
router.get('/nytimes/book/:category?', require('./routes/nytimes/book.js'));
router.get('/nytimes/:lang?', require('./routes/nytimes/index'));
@@ -346,6 +347,7 @@ router.get('/3dm/news', require('./routes/3dm/news_center'));
// 旅法师营地
router.get('/lfsyd/:typecode', require('./routes/lfsyd/index'));
router.get('/lfsyd/user/:id', require('./routes/lfsyd/user'));
router.get('/lfsyd/tag/:tag', require('./routes/lfsyd/tag'));
// 喜马拉雅
@@ -625,6 +627,9 @@ router.get('/bjtu/gs/:type', require('./routes/universities/bjtu/gs'));
router.get('/dpu/jiaowu/news/:type?', require('./routes/universities/dpu/jiaowu/news'));
router.get('/dpu/wlfw/news/:type?', require('./routes/universities/dpu/wlfw/news'));
// 大连理工大学
router.get('/dut/:subsite/:type', require('./routes/universities/dut/index'));
// 东南大学
router.get('/seu/radio/academic', require('./routes/universities/seu/radio/academic'));
router.get('/seu/yzb/:type', require('./routes/universities/seu/yzb'));
@@ -717,6 +722,7 @@ router.get('/cuc/yz', require('./routes/universities/cuc/yz'));
// 中国科学技术大学
router.get('/ustc/news/:type?', require('./routes/universities/ustc/index'));
router.get('/ustc/jwc/:type?', require('./routes/universities/ustc/jwc/index'));
router.get('/ustc/job/:category?', require('./routes/universities/ustc/job'));
// UTdallas ISSO
router.get('/utdallas/isso', require('./routes/universities/utdallas/isso'));
@@ -1067,7 +1073,7 @@ router.get('/nhentai/search/:keyword/:mode?', require('./routes/nhentai/search')
router.get('/nhentai/:key/:keyword/:mode?', require('./routes/nhentai/other'));
// 龙腾网
router.get('/ltaaa/:type?', require('./routes/ltaaa/main'));
router.get('/ltaaa/:category?', require('./routes/ltaaa/index'));
// AcFun
router.get('/acfun/bangumi/:id', require('./routes/acfun/bangumi'));
@@ -1121,7 +1127,7 @@ router.get('/xiachufang/user/created/:id', require('./routes/xiachufang/user/cre
router.get('/xiachufang/popular/:timeframe?', require('./routes/xiachufang/popular'));
// 经济观察报
router.get('/eeo/:category?', require('./routes/eeo/index'));
router.get('/eeo/:column?/:category?', require('./routes/eeo/index'));
// 腾讯视频
router.get('/tencentvideo/playlist/:id', require('./routes/tencent/video/playlist'));
@@ -1240,7 +1246,6 @@ router.get('/huxiu/collection/:id', require('./routes/huxiu/collection'));
// Steam
router.get('/steam/search/:params', require('./routes/steam/search'));
router.get('/steam/news/:appid/:language?', require('./routes/steam/news'));
// Steamgifts
router.get('/steamgifts/discussions/:category?', require('./routes/steam/steamgifts/discussions'));
@@ -1716,13 +1721,9 @@ router.get('/the-economist/:endpoint', require('./routes/the-economist/full'));
// 鼠绘漫画
router.get('/shuhui/comics/:id', require('./routes/shuhui/comics'));
// 朝日新聞中文网(简体中文版)
router.get('/asahichinese-j/:category/:subCate', require('./routes/asahichinese-j/index'));
router.get('/asahichinese-j/:category', require('./routes/asahichinese-j/index'));
// 朝日新聞中文網(繁體中文版)
router.get('/asahichinese-f/:category/:subCate', require('./routes/asahichinese-f/index'));
router.get('/asahichinese-f/:category', require('./routes/asahichinese-f/index'));
// 朝日新闻
router.get('/asahi/area/:id', require('./routes/asahi/area'));
router.get('/asahi/:genre?/:category?', require('./routes/asahi/index'));
// 7x24小时快讯
router.get('/fx678/kx', require('./routes/fx678/kx'));
@@ -1983,6 +1984,8 @@ router.get('/tencent/pvp/newsindex/:type', require('./routes/tencent/pvp/newsind
// 《明日方舟》游戏
router.get('/arknights/news', require('./routes/arknights/news'));
// 塞壬唱片
router.get('/siren/news', require('./routes/siren/index'));
// ff14
router.get('/ff14/ff14_zh/:type', require('./routes/ff14/ff14_zh'));
@@ -2083,7 +2086,7 @@ router.get('/leboncoin/ad/:query', require('./routes/leboncoin/ad.js'));
router.get('/dhl/:id', require('./routes/dhl/shipment-tracking'));
// Japanpost
router.get('/japanpost/:reqCode/:locale?', require('./routes/japanpost/index'));
router.get('/japanpost/track/:reqCode/:locale?', require('./routes/japanpost/track'));
// 中华人民共和国商务部
router.get('/mofcom/article/:suffix', require('./routes/mofcom/article'));
@@ -3687,7 +3690,7 @@ router.get('/mind42/search/:keyword', require('./routes/mind42/search'));
router.get('/mind42/:caty?', require('./routes/mind42/index'));
// 幕布网
router.get('/mubu/explore/:tagId/:title?', require('./routes/mubu/explore'));
router.get('/mubu/explore/:category?/:title?', require('./routes/mubu/explore'));
// Esquirehk
router.get('/esquirehk/tag/:id', require('./routes/esquirehk/tag'));
@@ -3850,7 +3853,8 @@ router.get('/voa/:language/:channel?', require('./routes/voa/index'));
router.get('/6park/:id?/:type?/:keyword?', require('./routes/6park/index'));
// 哔嘀影视
router.get('/bde4/:type?/:caty?/:area?/:year?/:order?', require('./routes/bde4/index'));
router.get('/mp4er/:type?/:caty?/:area?/:year?/:order?', require('./routes/mp4er/index'));
router.get('/bde4/:type?/:caty?/:area?/:year?/:order?', require('./routes/mp4er/index'));
// 上海证券交易所
router.get('/sse/sserules/:slug?', require('./routes/sse/sserules'));
@@ -3963,6 +3967,7 @@ router.get('/babehub/search/:keyword?', require('./routes/babehub/search'));
router.get('/babehub/:category?', require('./routes/babehub/index'));
// 深圳新闻网
router.get('/sznews/press', require('./routes/sznews/press'));
router.get('/sznews/ranking', require('./routes/sznews/ranking'));
// Shuax
@@ -4072,6 +4077,10 @@ router.get('/jisilu/topic/:user', require('./routes/jisilu/topic'));
// Constitutional Court of Baden-Württemberg (Germany)
router.get('/verfghbw/press/:keyword?', require('./routes/verfghbw/press'));
// Topbook
router.get('/topbook/overview/:id?', require('./routes/topbook/overview'));
router.get('/topbook/today', require('./routes/topbook/today'));
// Melon
router.get('/melon/chart/:category?', require('./routes/melon/chart'));
@@ -4095,4 +4104,22 @@ router.get('/tongli/news/:type', require('./routes/tongli/news'));
// OR
router.get('/or/:id?', require('./routes/or'));
// HKEPC
router.get('/hkepc/:category?', require('./routes/hkepc/index'));
// 海南大学
router.get('/hainanu/ssszs', require('./routes/hainanu/ssszs'));
// 游戏年轮
router.get('/bibgame/:category?/:type?', require('./routes/bibgame/category'));
// 澳門特別行政區政府各公共部門獎助貸學金服務平台
router.get('/macau-bolsas/:lang?', require('./routes/macau-bolsas/index'));
// 加美财经
router.get('/caus/:category?', require('./routes/caus'));
// 摩点
router.get('/modian/zhongchou/:category?/:sort?/:status?', require('./routes/modian/zhongchou'));
module.exports = router;
+58
View File
@@ -0,0 +1,58 @@
const got = require('@/utils/got');
const cheerio = require('cheerio');
module.exports = async (ctx) => {
const id = ctx.params.id;
const rootUrl = 'https://www.asahi.com';
const currentUrl = `${rootUrl}/area/${id}`;
const response = await got({
method: 'get',
url: currentUrl,
});
const $ = cheerio.load(response.data);
$('.Time').remove();
const list = $('#MainInner .Section .List li a')
.slice(0, 6)
.map((_, item) => {
item = $(item);
const link = item.attr('href');
return {
link: link.indexOf('//') < 0 ? `${rootUrl}${link}` : `https:${link}`,
};
})
.get();
const items = await Promise.all(
list.map(
async (item) =>
await ctx.cache.tryGet(item.link, async () => {
const detailResponse = await got({
method: 'get',
url: item.link,
});
const content = cheerio.load(detailResponse.data);
content('._30SFw, .-Oj2D, .notPrint').remove();
item.description = content('._3YqJ1').html();
item.title = content('meta[name="TITLE"]').attr('content');
item.pubDate = Date.parse(content('meta[name="pubdate"]').attr('content'));
return item;
})
)
);
ctx.state.data = {
title: $('title').text(),
link: currentUrl,
item: items,
description: '朝日新聞社のニュースサイト、朝日新聞デジタルの社会ニュースについてのページです',
};
};
+82
View File
@@ -0,0 +1,82 @@
const got = require('@/utils/got');
const cheerio = require('cheerio');
const categories = {
obituaries: '/obituaries',
yoron: '/politics/yoron',
baseball: '/sports/baseball',
soccer: '/sports/soccer',
sumo: '/sports/sumo',
winter_figureskate: '/sports/winter/figureskate',
golf: '/sports/golf',
general: '/sports/general',
olympics: '/olympics',
paralympics: '/paralympics',
eco: '/eco',
igo: '/igo',
shougi: '/shougi',
eldercare: '/national/eldercare',
hataraku: '/special/hataraku',
food: '/culture/food',
gassho: '/edu/gassho',
suisogaku: '/edu/suisogaku',
hagukumu: '/edu/hagukumu',
msta: '/msta',
};
module.exports = async (ctx) => {
const genre = ctx.params.genre || '';
const category = ctx.params.category || '';
const rootUrl = 'https://www.asahi.com';
const currentUrl = `${rootUrl}${genre ? `${category ? `${category in categories ? categories[category] : `/${genre}/list/${category}.html`}` : `/${genre}`}` : '/news/history.html'}`;
const response = await got({
method: 'get',
url: currentUrl,
});
const $ = cheerio.load(response.data);
$('.Time').remove();
const list = $('#MainInner .Section .List li a')
.slice(0, 6)
.map((_, item) => {
item = $(item);
const link = item.attr('href');
return {
link: link.indexOf('//') < 0 ? `${rootUrl}${link}` : `https:${link}`,
};
})
.get();
const items = await Promise.all(
list.map(
async (item) =>
await ctx.cache.tryGet(item.link, async () => {
const detailResponse = await got({
method: 'get',
url: item.link,
});
const content = cheerio.load(detailResponse.data);
content('._30SFw, .-Oj2D, .notPrint').remove();
item.description = content('._3YqJ1').html();
item.title = content('meta[name="TITLE"]').attr('content');
item.pubDate = Date.parse(content('meta[name="pubdate"]').attr('content'));
return item;
})
)
);
ctx.state.data = {
title: $('title').text(),
link: currentUrl,
item: items,
description: '朝日新聞社のニュースサイト、朝日新聞デジタルの社会ニュースについてのページです',
};
};
-102
View File
@@ -1,102 +0,0 @@
const got = require('@/utils/got');
const cheerio = require('cheerio');
const logger = require('@/utils/logger');
const categoryCodes = new Map([
['society', { name: '國內綜合', types: {} }],
['politics_economy', { name: '政治・經濟', types: {} }],
[
'cool_japan',
{
name: '文化・生活',
types: {
entertainment: '藝能',
anime: '動漫',
life: '生活・美食',
style_culture: '時尚・藝文',
},
},
],
[
'travel',
{
name: '旅遊・活動',
types: {
news: '資訊',
scenery: '風景',
topic: '體驗',
move: '交通',
},
},
],
['sports', { name: '體育・奧運', types: {} }],
['business', { name: '商業・商品', types: {} }],
['technology', { name: 'IT・科技', types: {} }],
['world', { name: '國際・東亞', types: {} }],
['opinion', { name: '評論・專欄', types: {} }],
['whatsnew', { name: '最新消息', types: {} }],
]);
const host = 'https://asahichinese-f.com';
module.exports = async (ctx) => {
const category = ctx.params.category;
const type = ctx.params.subCate;
let iTitle = categoryCodes.get(category).name;
let link = `https://asahichinese-f.com/${category}/`;
if (type !== undefined) {
link = link + `${type}/`;
iTitle = iTitle + '-' + categoryCodes.get(category).types[type];
}
const response = await got.get(link);
const $ = cheerio.load(response.data);
const list = $('ul.List li')
.slice(1, 11)
.map(function () {
const info = {
title: $(this).find('a').text(),
link: $(this).find('a').attr('href'),
date: $(this).find('span.Date').text(),
};
logger.info(info.date);
return info;
})
.get();
const out = await Promise.all(
list.map(async (info) => {
const title = info.title;
const date = info.date;
const itemUrl = host + info.link;
const cache = await ctx.cache.get(itemUrl);
if (cache) {
return Promise.resolve(JSON.parse(cache));
}
const response = await got.get(itemUrl);
const $ = cheerio.load(response.data);
const description = $('div.ArticleText').html().trim();
const single = {
title: title,
link: itemUrl,
description: description,
pubDate: new Date(date).toUTCString(),
};
ctx.cache.set(itemUrl, JSON.stringify(single));
return Promise.resolve(single);
})
);
ctx.state.data = {
title: `${iTitle}-朝日新聞中文網`,
link: link,
item: out,
};
};
-102
View File
@@ -1,102 +0,0 @@
const got = require('@/utils/got');
const cheerio = require('cheerio');
const logger = require('@/utils/logger');
const categoryCodes = new Map([
['society', { name: '日本社会', types: {} }],
['politics_economy', { name: '政治・经济', types: {} }],
[
'cool_japan',
{
name: '文娱・生活',
types: {
entertainment: '艺能',
anime: '动漫',
life: '生活・美食',
style_culture: '时尚・文化',
},
},
],
[
'travel',
{
name: '旅游・活动',
types: {
news: '资讯',
scenery: '风景',
topic: '体验',
move: '交通',
},
},
],
['sports', { name: '体育・奥运', types: {} }],
['business', { name: '商务・商品', types: {} }],
['technology', { name: 'IT・科技', types: {} }],
['world', { name: '国际・东亚', types: {} }],
['opinion', { name: '观点・专栏', types: {} }],
['whatsnew', { name: '最新', types: {} }],
]);
const host = 'https://asahichinese-j.com';
module.exports = async (ctx) => {
const category = ctx.params.category;
const type = ctx.params.subCate;
let iTitle = categoryCodes.get(category).name;
let link = `https://asahichinese-j.com/${category}/`;
if (type !== undefined) {
link = link + `${type}/`;
iTitle = iTitle + '-' + categoryCodes.get(category).types[type];
}
const response = await got.get(link);
const $ = cheerio.load(response.data);
const list = $('ul.List li')
.slice(1, 11)
.map(function () {
const info = {
title: $(this).find('a').text(),
link: $(this).find('a').attr('href'),
date: $(this).find('span.Date').text(),
};
logger.info(info.date);
return info;
})
.get();
const out = await Promise.all(
list.map(async (info) => {
const title = info.title;
const date = info.date;
const itemUrl = host + info.link;
const cache = await ctx.cache.get(itemUrl);
if (cache) {
return Promise.resolve(JSON.parse(cache));
}
const response = await got.get(itemUrl);
const $ = cheerio.load(response.data);
const description = $('div.ArticleText').html().trim();
const single = {
title: title,
link: itemUrl,
description: description,
pubDate: new Date(date).toUTCString(),
};
ctx.cache.set(itemUrl, JSON.stringify(single));
return Promise.resolve(single);
})
);
ctx.state.data = {
title: `${iTitle}-朝日新聞中文网`,
link: link,
item: out,
};
};
+57
View File
@@ -0,0 +1,57 @@
const got = require('@/utils/got');
const cheerio = require('cheerio');
const timezone = require('@/utils/timezone');
module.exports = async (ctx) => {
const category = ctx.params.category || 'pcgame';
const type = ctx.params.type || '';
const rootUrl = 'https://www.bibgame.com';
const currentUrl = `${rootUrl}/${category}/${type}`;
const response = await got({
method: 'get',
url: currentUrl,
});
const $ = cheerio.load(response.data);
const list = $('.info_box a')
.slice(0, 15)
.map((_, item) => {
item = $(item);
const link = item.attr('href');
return {
title: item.text(),
link: link.indexOf('http') > -1 ? link : `${rootUrl}${link}`,
};
})
.get();
const items = await Promise.all(
list.map(
async (item) =>
await ctx.cache.tryGet(item.link, async () => {
const detailResponse = await got({
method: 'get',
url: item.link,
});
const content = cheerio.load(detailResponse.data);
content('#comment').parent().remove();
item.description = content('.abstract').html();
item.pubDate = timezone(new Date(content('.time_box').text().trim()), +8);
return item;
})
)
);
ctx.state.data = {
title: $('title').text(),
link: currentUrl,
item: items,
};
};
+9 -5
View File
@@ -1,6 +1,7 @@
const got = require('@/utils/got');
const cache = require('./cache');
const utils = require('./utils');
const { parseDate } = require('@/utils/parse-date');
module.exports = async (ctx) => {
const uid = ctx.params.uid;
@@ -9,13 +10,15 @@ module.exports = async (ctx) => {
const name = await cache.getUsernameFromUID(ctx, uid);
const response = await got({
method: 'get',
url: `https://api.bilibili.com/x/space/coin/video?vmid=${uid}&jsonp=jsonp`,
url: `https://api.bilibili.com/x/space/coin/video?vmid=${uid}`,
headers: {
Referer: `https://space.bilibili.com/${uid}/`,
},
});
const data = response.data.data;
const { data, code, message } = response.data;
if (code) {
throw new Error(message ? message : code);
}
ctx.state.data = {
title: `${name} 的 bilibili 投币视频`,
@@ -23,9 +26,10 @@ module.exports = async (ctx) => {
description: `${name} 的 bilibili 投币视频`,
item: data.map((item) => ({
title: item.title,
description: `${item.desc}${!disableEmbed ? `<br><br>${utils.iframe(item.aid)}` : ''}<br><img src="${item.pic}">`,
pubDate: new Date(item.time * 1000).toUTCString(),
description: `${item.desc}${!disableEmbed ? `<br><br>${utils.iframe(item.aid)}` : ''}<br><img src='${item.pic}'>`,
pubDate: parseDate(item.time * 1000),
link: item.time > utils.bvidTime && item.bvid ? `https://www.bilibili.com/video/${item.bvid}` : `https://www.bilibili.com/video/av${item.aid}`,
author: item.owner.name,
})),
};
};
+9 -5
View File
@@ -1,5 +1,6 @@
const got = require('@/utils/got');
const utils = require('./utils');
const { parseDate } = require('@/utils/parse-date');
module.exports = async (ctx) => {
const fid = ctx.params.fid;
@@ -7,13 +8,16 @@ module.exports = async (ctx) => {
const disableEmbed = ctx.params.disableEmbed;
const response = await got({
method: 'get',
url: `https://api.bilibili.com/medialist/gateway/base/spaceDetail?media_id=${fid}&pn=1&ps=20&keyword=&order=mtime&type=0&tid=0`,
url: `https://api.bilibili.com/x/v3/fav/resource/list?media_id=${fid}&ps=20`,
headers: {
Referer: `https://space.bilibili.com/${uid}/`,
},
});
const data = response.data.data;
const { data, code, message } = response.data;
if (code) {
throw new Error(message ? message : code);
}
const userName = data.info.upper.name;
const favName = data.info.title;
@@ -26,8 +30,8 @@ module.exports = async (ctx) => {
data.medias &&
data.medias.map((item) => ({
title: item.title,
description: `${item.intro}${!disableEmbed ? `<br><br>${utils.iframe(item.id)}` : ''}<br><img src="${item.cover}">`,
pubDate: new Date(item.fav_time * 1000).toUTCString(),
description: `${item.intro}${!disableEmbed ? `<br><br>${utils.iframe(item.id)}` : ''}<br><img src='${item.cover}'>`,
pubDate: parseDate(item.fav_time * 1000),
link: item.fav_time > utils.bvidTime && item.bvid ? `https://www.bilibili.com/video/${item.bvid}` : `https://www.bilibili.com/video/av${item.id}`,
author: item.upper.name,
})),
+39
View File
@@ -0,0 +1,39 @@
const got = require('@/utils/got');
const cache = require('./cache');
const config = require('@/config').value;
module.exports = async (ctx) => {
const uid = String(ctx.params.uid);
const name = await cache.getUsernameFromUID(ctx, uid);
const cookie = config.bilibili.cookies[uid];
if (cookie === undefined) {
throw Error('缺少对应 uid 的 Bilibili 用户登录后的 Cookie 值');
}
const page_size = ctx.params.limits || 10;
const link = 'https://manga.bilibili.com/account-center';
const response = await got({
method: 'POST',
url: `https://manga.bilibili.com/twirp/bookshelf.v1.Bookshelf/ListFavorite?device=pc&platform=web`,
json: { page_num: 1, page_size: page_size, order: 2, wait_free: 0 },
headers: {
Referer: link,
Cookie: cookie,
},
});
if (response.data.code === -6) {
throw Error('对应 uid 的 Bilibili 用户的 Cookie 已过期');
}
const comics = response.data.data;
ctx.state.data = {
title: `${name} 的追漫更新 - 哔哩哔哩漫画`,
link: link,
item: comics.map((item) => ({
title: `${item.title} ${item.latest_ep_short_title}`,
description: `<img src='${item.vcover}'>`,
pubDate: new Date(item.last_ep_publish_time + ' +0800'),
link: `https://manga.bilibili.com/detail/mc${item.comic_id}`,
})),
};
};
+1
View File
@@ -29,6 +29,7 @@ module.exports = async (ctx) => {
description: `${item.desc}${!disableEmbed ? `<br><br>${utils.iframe(item.aid)}` : ''}<br><img src="${item.pic}">`,
pubDate: new Date(item.fav_at * 1000).toUTCString(),
link: item.fav_at > utils.bvidTime && item.bvid ? `https://www.bilibili.com/video/${item.bvid}` : `https://www.bilibili.com/video/av${item.aid}`,
author: item.owner.name,
})),
};
};
+3 -3
View File
@@ -4,7 +4,7 @@ const cheerio = require('cheerio');
module.exports = async (ctx) => {
const response = await got({
method: 'get',
url: 'https://www.bookwalker.com.tw/more/index/1',
url: 'https://www.bookwalker.com.tw/search?order=sell_desc&series_display=1&d=1',
});
const data = response.data;
@@ -14,13 +14,13 @@ module.exports = async (ctx) => {
let bookid;
ctx.state.data = {
title: 'BOOKWALKERTW热门新书',
link: 'https://www.bookwalker.com.tw/more/index/1',
link: 'https://www.bookwalker.com.tw/search?order=sell_desc&series_display=1&d=1',
item:
list &&
list
.map((index, item) => {
item = $(item);
bookid = item.find('a').attr('href').split('/')[4];
bookid = item.find('img').attr('data-src').split('/')[5];
return {
title: item.find('.bookname').text(),
description: `${item.find('.booknamesub').text()}&nbsp;|&nbsp;${item.find('.bprice').text()}<br><img src="https://image.bookwalker.com.tw/upload/product/${bookid}/zoom_big_${bookid}.jpg">`,
+88
View File
@@ -0,0 +1,88 @@
const got = require('@/utils/got');
const categories = {
0: {
title: '全部',
link: 'home?id=0',
},
1: {
title: '要闻',
link: 'focus_news?id=1',
},
2: {
title: '商业',
link: 'business?id=2',
},
3: {
title: '快讯',
link: 'hours?id=3',
},
4: {
title: '投资理财',
link: 'CFT?id=4',
},
6: {
title: '生活',
link: 'life?id=6',
},
};
module.exports = async (ctx) => {
const category = ctx.params.category || '0';
const isHome = category === '0';
const rootUrl = 'https://www.caus.com';
const apiRootUrl = 'https://api.caus.money';
const currentUrl = `${rootUrl}/${categories[category].link}`;
const searchUrl = `${apiRootUrl}/toronto/display/searchList`;
const listUrl = `${apiRootUrl}/toronto/display/lanmuArticlelistNew`;
const response = await got({
method: 'post',
url: isHome ? searchUrl : listUrl,
json: isHome
? {
pageQ: {
pageSize: 10,
sortFiled: 'id',
sortType: 'DESC',
},
types: ['ARTICLE', 'VIDEO'],
}
: {
filterIds: [],
lanmuId: parseInt(category),
},
});
const list = (isHome ? response.data.data : response.data.data.articleList).map((item) => ({
title: item.title,
link: item.contentId,
pubDate: new Date(item.createTime),
}));
const items = await Promise.all(
list.map(
async (item) =>
await ctx.cache.tryGet(item.link, async () => {
const detailResponse = await got({
method: 'get',
url: `${apiRootUrl}/toronto/display/contentWithRelate?contentId=${item.link}`,
});
item.link = `${rootUrl}/detail/${item.link}`;
item.description = detailResponse.data.data.content.content;
return item;
})
)
);
ctx.state.data = {
title: `${categories[category].title} - 加美财经`,
link: currentUrl,
item: items,
};
};
+6 -1
View File
@@ -38,7 +38,12 @@ const getHeaders = () => ({
const parseTuwenFromRaw = (raw) =>
raw.map((i) => {
if (i.type === 'text') {
return `<p>${i.message}</p>`;
const output = i.message
.split('\n')
.filter((t) => t !== '')
.map((t) => `<p>${t}</p>`)
.join('');
return output;
} else if (i.type === 'image') {
return `<div class="img-container" style="text-align: center;">
<img src="${i.url}">
+1 -1
View File
@@ -117,7 +117,7 @@ const ProcessFeedType2 = (item, response) => {
runScripts: 'dangerously',
});
const data = dom.window.__NUXT__.data[1].newData;
const data = dom.window.__NUXT__.data[0].newData;
if (Object.keys(data).length > 0) {
const body = ProcessVideo(cheerio.load(data.body));
+73 -36
View File
@@ -1,47 +1,84 @@
const got = require('@/utils/got');
const cheerio = require('cheerio');
const timezone = require('@/utils/timezone');
const legacyUrls = {
1: '/yaowen/dashi',
2: '/yaowen/hfggzc',
3: '/jinrong/zhengquan',
4: '/jinrong/ziben',
5: '/jinrong/licai',
6: '/shangye/xinnengyuan',
7: '/shangye/yiliao',
8: '/fcqcxf/dichan',
9: '/fcqcxf/qiche',
10: '/fcqcxf/xiaofei',
11: '/yule/yingshi',
12: '/yule/yule',
13: '/yule/tiyu',
14: '/yule/jiaoyu',
15: '/gcj/guanchajia',
16: '/gcj/zhuanlan',
17: '/gcj/shuping',
18: '/gcj/lishi',
19: '/yaowen/hfshuju',
};
module.exports = async (ctx) => {
const category = ctx.params.category || '观察家';
const category_url_relation = {
'01': 'http://www.eeo.com.cn/yaowen/dashi/',
'02': 'http://www.eeo.com.cn/yaowen/hfggzc/',
'03': 'http://www.eeo.com.cn/jinrong/zhengquan/',
'04': 'http://www.eeo.com.cn/jinrong/ziben/',
'05': 'http://www.eeo.com.cn/jinrong/licai/',
'06': 'http://www.eeo.com.cn/shangye/xinnengyuan/',
'07': 'http://www.eeo.com.cn/shangye/yiliao/',
'08': 'http://www.eeo.com.cn/fcqcxf/dichan/',
'09': 'http://www.eeo.com.cn/fcqcxf/qiche/',
10: 'http://www.eeo.com.cn/fcqcxf/xiaofei/',
11: 'http://www.eeo.com.cn/yule/yingshi/',
12: 'http://www.eeo.com.cn/yule/yule/',
13: 'http://www.eeo.com.cn/yule/tiyu/',
14: 'http://www.eeo.com.cn/yule/jiaoyu/',
15: 'http://www.eeo.com.cn/gcj/guanchajia/',
16: 'http://www.eeo.com.cn/gcj/zhuanlan/',
17: 'http://www.eeo.com.cn/gcj/shuping/',
18: 'http://www.eeo.com.cn/gcj/lishi/',
19: 'http://www.eeo.com.cn/yaowen/hfshuju/',
};
const column = ctx.params.column || 'shangyechanye';
const category = ctx.params.category || '';
const rootUrl = 'http://www.eeo.com.cn';
let currentUrl = rootUrl;
if (parseInt(column)) {
currentUrl += legacyUrls[parseInt(column)];
} else {
currentUrl += `/${column}/${category}`;
}
const response = await got({
method: 'get',
url: category_url_relation[category],
url: currentUrl,
});
const data = response.data;
const $ = cheerio.load(data);
const list = $('#lyp_article li').get();
const result = list.map((item) => ({
title: $(item).find('div span a').text(),
description: $(item).find('div p').text(),
pubDate: new Date().toUTCString(),
link: $(item).find('>a').attr('href'),
}));
const $ = cheerio.load(response.data);
const list = $('#lyp_article li div span a')
.slice(0, 15)
.map((_, item) => {
item = $(item);
return {
link: item.attr('href'),
};
})
.get();
const items = await Promise.all(
list.map(
async (item) =>
await ctx.cache.tryGet(item.link, async () => {
const detailResponse = await got({
method: 'get',
url: item.link,
});
const content = cheerio.load(detailResponse.data);
content('.xd-xd-xd-rwm, .xd_zuozheinfo, .xd-lj, .xd-gg').remove();
item.title = content('h1').text();
item.description = content('.xd-nr').html();
item.pubDate = timezone(new Date(content('.thiszihao-box-add').nextUntil('.cls').find('span').eq(0).text()), +8);
return item;
})
)
);
ctx.state.data = {
title: '经济观察网',
link: 'http://www.eeo.com.cn',
description: '经济观察网是《经济观察报》社倾力制作的全新商业资讯平台',
item: result,
title: $('title').text().replace('_', ' - '),
link: currentUrl,
item: items,
description: '经济观察网是《经济观察报》社倾力制作的全新商业资讯平台,经济观察网冷静理智的报道风格,并糅合最新的网络技术,拥有专业的采编力量以及独家的新闻报道,为您提供及时、便捷、专业的信息服务。',
};
};
+36
View File
@@ -0,0 +1,36 @@
const got = require('@/utils/got');
const cheerio = require('cheerio');
const { parseDate } = require('@/utils/parse-date');
module.exports = async (ctx) => {
const url = 'https://ha.hainanu.edu.cn/gs/yjszs/ssszs.htm';
const response = await got({
method: 'get',
url,
});
const data = response.data;
const $ = cheerio.load(data);
const list = $('.m_new13>ul>li');
ctx.state.data = {
title: '海南大学研究生招生',
link: url,
description: '海南大学研究生招生公告',
item:
list &&
list
.map((index, item) => {
item = $(item);
const date = item.find('span').text();
const pubDate = parseDate(date, 'YYYY-MM-DD');
return {
title: item.find('a').text(),
link: item.find('a').attr('href'),
pubDate,
};
})
.get(),
};
};
+164
View File
@@ -0,0 +1,164 @@
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 category = ctx.params.category || '';
const baseUrl = `https://www.hkepc.com`;
let itemResponse;
if (category === 'price' || category === 'review' || category === 'coverStory' || category === 'news' || category === 'press' || category === 'member') {
itemResponse = await ctx.cache.tryGet(`${baseUrl}/news`, async () => {
const resp = await got({
method: 'get',
url: `${baseUrl}/news`,
headers: {
Referer: baseUrl,
},
});
return resp.data;
});
} else if (category === 'digital' || category === 'entertainment' || category === 'latest' || category === '') {
itemResponse = await ctx.cache.tryGet(baseUrl, async () => {
const resp = await got(baseUrl);
return resp.data;
});
} else {
itemResponse = await ctx.cache.tryGet(`${baseUrl}/${category}`, async () => {
const resp = await got({
method: 'get',
url: `${baseUrl}/${category}`,
headers: {
Referer: baseUrl,
},
});
return resp.data;
});
}
const $ = cheerio.load(itemResponse);
let title = '電腦領域 HKEPC';
let articleList;
switch (category) {
case 'price':
title += ' - 腦場新聞';
articleList = $('#sidebar > div:nth-child(1) > div.content > ul > li');
break;
case 'review':
title += ' - 新品快遞';
articleList = $('#sidebar > div:nth-child(2) > div.content > ul > li');
break;
case 'coverStory':
title += ' - 專題報導';
articleList = $('#sidebar > div:nth-child(3) > div.content > ul > li');
break;
case 'news':
title += ' - 新聞中心';
articleList = $('#sidebar > div:nth-child(4) > div.content > ul > li');
break;
case 'press':
title += ' - 專題報導';
articleList = $('#sidebar > div:nth-child(5) > div.content > ul > li');
break;
case 'member':
title += ' - 會員消息';
articleList = $('#sidebar > div:nth-child(6) > div.content > ul > li');
break;
case 'digital':
title += ' - 流動數碼';
articleList = $('#contentR5 > div.left > div.article > div.heading');
break;
case 'entertainment':
title += ' - 生活娛樂';
articleList = $('#contentR5 > div.right > div.article > div.heading');
break;
case 'latest':
case '':
title += ' - 最新消息';
articleList = $('div .item');
break;
case 'ocLab':
title += ' - 超頻領域';
articleList = $('.heading');
break;
default:
break;
}
const ProcessFeed = async (link) => {
const resp = await got({
method: 'get',
url: link,
headers: {
Referer: `${baseUrl}`,
},
});
return cheerio.load(resp.data)('#article').html();
};
const items = await Promise.all(
articleList.get().map(async (item) => {
const $ = cheerio.load(item);
const $a = $('a').html($('a').html().replace(/<br>/g, ' '));
const title = $a.text().trim();
const link = baseUrl + $a.attr('href');
const cache = await ctx.cache.get(link);
if (cache) {
return Promise.resolve(JSON.parse(cache));
}
const categories = [];
const $article = cheerio.load(await ProcessFeed(link));
// remove unwanted elements
$article('#view > div.advertisement').remove();
$article('#view > p').each((i, e) => {
if (
// &#xA0; = &nbsp;
$(e)
.html()
.replace(/&#xA0;/g, '').length === 0
) {
$(e).remove();
}
});
// extract categories
$article('#articleHead > div.tags > a').each((i, e) => {
categories.push($article(e).text().trim());
});
// fix lazyload image
$article('#view > p > img').each((i, e) => {
$(e).after(`<img src="${$(e).attr('rel')}" alt="${$(e).attr('alt')}" referrerpolicy="no-referrer">`);
$(e).remove();
});
const description = $article('#view').html();
const single = {
title: title,
author: $article('.newsAuthor').text().trim() || $article('#articleHead div.author').text().trim(),
category: categories,
description: description,
pubDate: timezone(parseDate($article('.publishDate').text()), +8),
guid: link.substring(0, link.lastIndexOf('/')),
link: link,
};
ctx.cache.set(link, JSON.stringify(single));
return Promise.resolve(single);
})
);
ctx.state.data = {
title: title,
link: `https://www.hkepc.com/${category}`,
description: '電腦領域 HKEPC Hardware - 全港 No.1 PC網站',
language: 'zh-hk',
item: items,
};
};
-67
View File
@@ -1,67 +0,0 @@
const got = require('@/utils/got');
const cheerio = require('cheerio');
const utils = require('./utils');
const baseTitle = '日本郵便';
const baseUrl = 'https://trackings.post.japanpost.jp/services/srv/search/direct?';
const util = new utils();
util.expandEven();
util.expandReverse();
module.exports = async (ctx) => {
const reqCode = ctx.params.reqCode;
const reqReqCode = 'reqCodeNo1=' + reqCode;
let locale;
switch (ctx.params.locale) {
case 'ja':
locale = 'ja';
break;
case 'en':
locale = 'en';
break;
default:
locale = 'ja';
}
const reqLocale = '&locale=' + locale;
const link = baseUrl + reqReqCode + reqLocale;
const response = await got({
method: 'get',
url: link,
});
const $ = cheerio.load(response.data);
const list = $('.tableType01').eq(1).find('tr').slice(2);
const listEven = list.even();
const packageType = $('.tableType01').eq(0).find('tr').eq(1).find('td').eq(1).text();
ctx.state.data = {
title: `${baseTitle} ${packageType} ${reqCode}`,
link: link,
description: 'Reserved for further development.',
item: listEven
.reverse()
.map((index, item) => {
item = $(item);
const itemTd = item.find('td');
const packageStatus = itemTd.eq(1).text().trim();
const packageRegion = itemTd.eq(4).text().trim();
const packageOffice = itemTd.eq(3).text().trim();
const itemTitle = `${packageStatus} ${packageRegion} ${packageOffice}`;
const itemDescription = itemTd.eq(2).text();
const itemPubDateText = itemTd.eq(0).text();
const itemGuid = util.generateGuid(itemTitle + itemDescription + itemPubDateText);
return {
title: itemTitle,
description: itemDescription,
pubDate: new Date(itemPubDateText),
link: link,
guid: itemGuid.slice(0, 32),
};
})
.get(),
};
};
+106
View File
@@ -0,0 +1,106 @@
const got = require('@/utils/got');
const cheerio = require('cheerio');
const utils = require('./utils');
let baseTitle = '日本郵便';
const baseUrl = 'https://trackings.post.japanpost.jp/services/srv/search/direct?';
utils.expandEven();
utils.expandOdd();
module.exports = async (ctx) => {
const reqCode = ctx.params.reqCode;
const reqReqCode = 'reqCodeNo1=' + reqCode;
let locale = 'ja';
if (ctx.params.locale === 'en') {
locale = 'en';
baseTitle = 'Japanpost';
}
const reqLocale = '&locale=' + locale;
const link = baseUrl + reqReqCode + reqLocale;
const response = await got({
method: 'get',
url: link,
});
const $ = cheerio.load(response.data);
const list = $('.tableType01').eq(1).find('tr').slice(2);
const officeList = $('.tableType03').eq(0).find('tr').slice(1);
if (!list.length) {
const resErrorText = $('.tableType01').eq(0).find('tr').eq(2).find('td').eq(1).text().trim();
throw new Error(resErrorText);
}
const listEven = list.even();
const listOdd = list.odd();
const packageType = $('.tableType01').eq(0).find('tr').eq(1).find('td').eq(1).text().trim();
let lastItemTimeStamp;
let tz;
ctx.state.data = {
title: `${baseTitle} ${packageType} ${reqCode}`,
link: link,
description: `${baseTitle} ${packageType} ${reqCode}`,
language: locale,
item: listEven
.map((index, item) => {
const itemTd = $(item).find('td');
const packageStatus = itemTd.eq(1).text().trim();
const packageRegion = itemTd.eq(4).text().trim();
const packageOffice = itemTd.eq(3).text().trim();
const packageOfficeZipCode = listOdd.eq(index).find('td').eq(0).text().trim();
const itemTitle = `${packageStatus} ${packageOffice} ${packageRegion}`;
const packageTrackRecord = itemTd.eq(2).text().trim();
let itemDescription = `${packageStatus}<br>`;
itemDescription += packageTrackRecord ? `${packageTrackRecord}<br>` : '';
itemDescription += packageOfficeZipCode ? `${packageOfficeZipCode} ` : '';
itemDescription += packageOffice ? `${packageOffice} ` : '';
itemDescription += `${packageRegion}`;
if (index === 0) {
if (officeList.length) {
const officeItemList = officeList
.map((i, e) => {
const eTd = $(e).find('td');
let officeItem = eTd.eq(0).text().trim();
officeItem += ` ${eTd.eq(1).html().trim()}`;
officeItem += ` ${eTd.eq(2).html().trim()}`;
return officeItem;
})
.get();
itemDescription += '<br>';
for (const i of officeItemList) {
itemDescription += `<br>${i}`;
}
}
}
const itemPubDateText = itemTd.eq(0).text().trim();
const itemGuid = utils.generateGuid(itemTitle + itemDescription + itemPubDateText);
let thisItemTimeStamp;
[thisItemTimeStamp, tz] = utils.parseDatetime(itemPubDateText, packageOffice, packageRegion, tz, locale);
if (lastItemTimeStamp) {
if (thisItemTimeStamp <= lastItemTimeStamp) {
thisItemTimeStamp = lastItemTimeStamp + 1000;
}
}
lastItemTimeStamp = thisItemTimeStamp;
return {
title: itemTitle,
description: itemDescription,
pubDate: new Date(thisItemTimeStamp),
link: link,
guid: itemGuid.slice(0, 32),
};
})
.get(),
};
};
+56 -13
View File
@@ -1,8 +1,17 @@
const cheerio = require('cheerio');
const crypto = require('crypto');
function utils() {
this.expandOdd = function () {
const cityTimezones = require('city-timezones');
const dayjs = require('dayjs');
const customParseFormat = require('dayjs/plugin/customParseFormat');
const utc = require('dayjs/plugin/utc');
const timezone = require('dayjs/plugin/timezone');
dayjs.extend(customParseFormat);
dayjs.extend(utc);
dayjs.extend(timezone);
const utils = {
expandOdd: () => {
cheerio.prototype.odd = function () {
const odds = [];
this.each(function (index, item) {
@@ -12,9 +21,8 @@ function utils() {
});
return cheerio(odds);
};
};
this.expandEven = function () {
},
expandEven: () => {
cheerio.prototype.even = function () {
const evens = [];
this.each(function (index, item) {
@@ -24,9 +32,8 @@ function utils() {
});
return cheerio(evens);
};
};
this.expandReverse = function () {
},
expandReverse: () => {
cheerio.prototype.reverse = function () {
const reverses = [];
this.each(function (index, item) {
@@ -35,14 +42,50 @@ function utils() {
reverses.reverse();
return cheerio(reverses);
};
};
this.generateGuid = function (t) {
},
generateGuid: (t) => {
const hash = crypto.createHash('sha512');
hash.update(t);
const r = hash.digest('hex').toUpperCase();
return r;
};
}
},
parseDatetime: (t, o, r, tz, l) => {
const formatJaDate = 'YYYY/MM/DD';
const formatJaDateTime = 'YYYY/MM/DD HH:mm';
const formatEnDate = 'MM/DD/YYYY';
const formatEnDateTime = 'MM/DD/YYYY HH:mm';
let customFormat;
switch (l) {
case 'ja':
customFormat = dayjs(t, formatJaDate, true).isValid() ? formatJaDate : dayjs(t, formatJaDateTime, true).isValid() ? formatJaDateTime : undefined;
break;
case 'en':
customFormat = dayjs(t, formatEnDate, true).isValid() ? formatEnDate : dayjs(t, formatEnDateTime, true).isValid() ? formatEnDateTime : undefined;
break;
}
if (!customFormat) {
return [new Date(t).getTime(), tz];
}
if (o) {
if (o.indexOf('郵便局') !== -1) {
tz = 'Asia/Tokyo';
} else {
const oS = o.replace(' EMS', '').replace(' INT', '');
try {
try {
tz = cityTimezones.lookupViaCity(oS)[0].timezone;
} catch {
tz = cityTimezones.lookupViaCity(r)[0].timezone;
}
} catch {
// empty
}
}
}
return [dayjs.tz(t, customFormat, tz).valueOf(), tz];
},
};
module.exports = utils;
+1 -1
View File
@@ -18,7 +18,7 @@ module.exports = async (ctx) => {
let out = await Promise.all(
list.map(async (item) => {
const $ = cheerio.load(item);
const title = $('.item-main a').text();
const title = $('.item-main a').text().replace('target="_blank">', '');
const itemUrl = $('.item-main a').attr('href');
const cache = await ctx.cache.get(itemUrl);
if (cache) {
+10 -11
View File
@@ -1,11 +1,10 @@
const got = require('@/utils/got');
const util = require('./utils');
const timezone = require('@/utils/timezone');
const { parseDate } = require('@/utils/parse-date');
module.exports = async (ctx) => {
const tag_id = ctx.params.tag;
const tag_list = {
const tagId = ctx.params.tag;
const tagList = {
17: '炉石传说',
18: '万智牌',
16: '游戏王',
@@ -20,13 +19,13 @@ module.exports = async (ctx) => {
23: '玩家杂谈',
117: '二次元',
};
const tag_name = tag_list[tag_id];
const tagName = tagList[tagId];
const rootUrl = 'https://www.iyingdi.com';
const tagUrl = 'https://api.iyingdi.com/web/feed/tag-content-list';
const form = {
page: 1,
size: 30,
tag_id: tag_id,
tag_id: tagId,
timestamp: '',
version: 0,
};
@@ -44,22 +43,22 @@ module.exports = async (ctx) => {
form: util.getForm(form),
});
const list = response.data.list;
const tag_json = JSON.parse(list[0].feed.tag_json);
const tagJson = JSON.parse(list[0].feed.tag_json);
const articleList = list.map((item) => ({
title: item.feed.title,
pubDate: timezone(parseDate(item.feed.show_time * 1000), +8),
pubDate: parseDate(item.feed.show_time * 1000),
link: `${rootUrl}/tz/post/${item.feed.source_id}`,
guid: item.feed.title,
post_id: item.feed.source_id,
postId: item.feed.source_id,
}));
const items = await Promise.all(articleList.map(async (item) => await util.ProcessFeed(ctx, item)));
ctx.state.data = {
title: `${!tag_name ? tag_json[0].tag : tag_name} - 旅法师营地 `,
link: `${rootUrl}/tz/tag/${tag_id}`,
description: `${!tag_name ? tag_json[0].tag : tag_name} - 旅法师营地 `,
title: `${!tagName ? tagJson[0].tag : tagName} - 旅法师营地 `,
link: `${rootUrl}/tz/tag/${tagId}`,
description: `${!tagName ? tagJson[0].tag : tagName} - 旅法师营地 `,
item: items,
};
};
+48
View File
@@ -0,0 +1,48 @@
const got = require('@/utils/got');
const util = require('./utils');
const { parseDate } = require('@/utils/parse-date');
module.exports = async (ctx) => {
const id = ctx.params.id;
const rootUrl = 'https://www.iyingdi.com';
const listUrl = 'https://api.iyingdi.com/web/user/event-list';
const form = {
event_types: 'content',
page: 1,
size: 15,
timestamp: '',
user_id: id,
};
const response = await got({
method: 'post',
url: listUrl,
headers: {
Host: 'api.iyingdi.com',
'Login-Token': 'nologin',
Origin: rootUrl,
Platform: 'pc',
Referer: `${rootUrl}/tz/people/${id}/postList`,
},
form: util.getForm(form),
});
const list = response.data.data;
const nickname = list[0].author.nickname;
const articleList = list.map((item) => ({
title: item.event_data.title,
pubDate: parseDate(item.event_data.show_time * 1000),
link: `${rootUrl}/tz/post/${item.event_data.post_id}`,
guid: item.event_data.title,
postId: item.event_data.post_id,
}));
const items = await Promise.all(articleList.map(async (item) => await util.ProcessFeed(ctx, item)));
ctx.state.data = {
title: `${nickname} - 旅法师营地 `,
link: `${rootUrl}/tz/people/${id}`,
description: `${nickname} - 旅法师营地`,
item: items,
};
};
+42 -12
View File
@@ -1,14 +1,14 @@
const cheerio = require('cheerio');
const got = require('@/utils/got');
const md5 = require('@/utils/md5');
const rootUrl = 'https://www.iyingdi.com';
const ProcessFeed = async (ctx, item) => {
const infoUrL = 'https://api.iyingdi.com/web/post/info';
const rootUrl = 'https://www.iyingdi.com';
const info_form = {
post_id: item.post_id,
const infoForm = {
post_id: item.postId,
timestamp: '',
};
const description = await ctx.cache.tryGet(item.link, async () => {
const response = await got({
method: 'post',
@@ -20,25 +20,55 @@ const ProcessFeed = async (ctx, item) => {
Platform: 'pc',
Referer: `${rootUrl}/`,
},
form: getForm(info_form),
form: getForm(infoForm),
});
const content_body = JSON.parse(response.body);
return content_body.post.content;
return cleanHtml(JSON.parse(response.body).post.content);
});
item.description = description;
delete item.post_id;
delete item.postId;
return item;
};
const getForm = function (form) {
const key = 'b8d5b38577b8bb382b0c783b474b95f9';
const getForm = function (form, type) {
const key = type ? '8a11ed3712b699e749185674f1dc20b4' : 'b8d5b38577b8bb382b0c783b474b95f9';
form.key = key;
form.timestamp = Math.floor(new Date().getTime() / 1000);
form.sign = md5(new URLSearchParams(form).toString());
delete form.key;
return form;
};
const cleanHtml = function (htmlString) {
const regex = new RegExp('(<p>|<div>)(.*?)?<strong>(标准|狂野)日报投稿.*?</strong>(.*?)?(</p>|</div>)(.|\n)*$');
const $ = cheerio.load(htmlString.replace(regex, ''));
$('.yingdi-car,.bbspost,.deck-set').each(function (i, e) {
const className = $(e).attr('class');
const dataId = $(e).attr('data-id');
const decksUrl = `${rootUrl}/web/tools/hearthstone/decks/setdetail?setid=${dataId}`;
const url = className === 'yingdi-card bbspost' ? `${rootUrl}/tz/post/${dataId}` : decksUrl;
$(e).find('.card-status').remove();
$(e).find('.card-info').wrap(`<a href = "${url}"></a>`);
});
$('.yingdi-image.gif').each(function (i, e) {
const imgsrc = $(e).attr('data-original');
$(e).attr('src', imgsrc);
});
$('.yingdi-audio').each(function (i, e) {
$(e).find('.audio-cover').remove();
$(e).find('.audio-area.hidden').attr('class', 'audio-area');
});
// 用户头像
$('.yingdi-card.user').remove();
// 套牌代码复制
$('.action-button').remove();
// 投票
$('.yingdi-ballot').remove();
$('hr').remove();
return $.html();
};
module.exports = {
getForm,
ProcessFeed,
-35
View File
@@ -1,35 +0,0 @@
const got = require('@/utils/got'); // get web content
const cheerio = require('cheerio'); // html parser
const domain = 'http://www.ltaaa.com';
module.exports = async function get_article(url) {
if (/^\/.*$/.test(url)) {
url = domain + url;
}
const response = await got({
method: 'get',
url: url,
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:62.0) Gecko/20100101 Firefox/62.0',
responseType: 'buffer',
});
const data = response.data;
const $ = cheerio.load(data);
const title = $('div.post-title > h1').text();
const author = $('div.post-param > a').text();
const pub_date_raw = $('div.post-param').clone().children().remove().end().text();
let date = new Date(pub_date_raw);
date.setHours(date.getHours() - 8);
date = new Date(Date.UTC(date.getFullYear(), date.getMonth(), date.getDate(), date.getHours(), date.getMinutes(), date.getSeconds()));
const content = $('div.post-content').html() + '<br/><hr/><br/>' + $('div.post-comment').html();
const item = {
title: title,
pubDate: date.toUTCString(),
author: author,
link: url,
description: content,
};
return item;
};
+70
View File
@@ -0,0 +1,70 @@
const got = require('@/utils/got');
const cheerio = require('cheerio');
const timezone = require('@/utils/timezone');
const { parseDate } = require('@/utils/parse-date');
module.exports = async (ctx) => {
const category = ctx.params.category || 'latest';
const rootUrl = 'http://www.ltaaa.cn';
const currentUrl = `${rootUrl}/${category === 'picture' ? category : `article${category === 'latest' ? '' : `/${category}`}`}`;
const response = await got({
method: 'get',
url: currentUrl,
});
const $ = cheerio.load(response.data);
const list = $(category === 'picture' || category === 'curiosities' ? 'dd .title' : '.li-title a')
.slice(0, 10)
.map((_, item) => {
item = $(item);
return {
title: item.text(),
link: `${rootUrl}${item.attr('href')}`,
};
})
.get();
const items = await Promise.all(
list.map(
async (item) =>
await ctx.cache.tryGet(item.link, async () => {
const detailResponse = await got({
method: 'get',
url: item.link,
});
const content = cheerio.load(detailResponse.data);
if (category === 'picture') {
item.description = '';
content('.show li').each(function () {
item.description += content(this).find('a').html() + (content(this).find('.pic-p').html() || '');
});
item.pubDate = parseDate(
content('.view a img')
.attr('src')
.match(/http:\/\/img\.ltaaa\.cn\/uploadfile\/(.*)\/\d+\.jpg/)[1],
'YYYY/MM/DD'
);
} else {
content('.post-param').find('a, span').remove();
item.pubDate = timezone(new Date(content('.post-param').text().trim()), +8);
content('.post-title, .post-param, .post-keywords, .like-post, .clear, .hook').remove();
item.description = content('.post-body').html();
}
return item;
})
)
);
ctx.state.data = {
title: $('title').text(),
link: currentUrl,
item: items,
};
};
-58
View File
@@ -1,58 +0,0 @@
// Warning: The author still knows nothing about javascript!
// params:
// type: notification type
const got = require('@/utils/got'); // get web content
const cheerio = require('cheerio'); // html parser
const get_article = require('./_article');
const base_url = 'http://www.ltaaa.com';
module.exports = async (ctx) => {
const type = ctx.params.type || 'news'; // week, month or year
let target = '';
switch (type) {
case 'week':
target = 'ul.vweek';
break;
case 'month':
target = 'ul.vmonth';
break;
case 'year':
target = 'ul.vyear';
break;
default:
target = 'ul.wlist';
}
const list_url = base_url + '/wtfy.html';
const response = await got({
method: 'get',
url: list_url,
});
const data = response.data; // content is html format
const $ = cheerio.load(data);
// get urls
const detail_urls = [];
let a = $(target).find('a.rtitle');
if (!a || a.length <= 0) {
a = $(target).find('div.li-title > a');
}
for (let i = 0; i < a.length; ++i) {
const tmp = $(a[i]).attr('href');
detail_urls.push(tmp);
}
// get articles
const article_list = await Promise.all(detail_urls.map((url) => get_article(url)));
// feed the data
ctx.state.data = {
title: '龙腾网转译网贴',
link: list_url,
item: article_list,
};
};
+47
View File
@@ -0,0 +1,47 @@
const got = require('@/utils/got');
const cheerio = require('cheerio');
module.exports = async (ctx) => {
const lang = ctx.params.lang;
const url = `https://www.bolsas.gov.mo/${lang === 'pt' ? lang : ''}`;
const response = await got({
method: 'get',
url: url,
});
const $Wrapper = cheerio.load(response.data);
const liItems = $Wrapper('ul.news-list li');
const items = await Promise.all(
liItems &&
liItems
.map(async (_, item) => {
const $item = $Wrapper(item);
const $newsItem = $item.find('.news-item');
const bureau = $newsItem.find('.label').text();
const title = $newsItem.find('.title').text();
const link = $newsItem.find('.title').attr('href');
const pubDate = new Date($item.find('.date').text() + 'T00:00:00+0800');
const description = await ctx.cache.tryGet(link, async () => {
const response = await got({
method: 'get',
url: link,
});
const $ = cheerio.load(response.data);
return $('.news-content').html();
});
return Promise.resolve({
title: `[${bureau}] ${title}`,
link,
description,
pubDate,
});
})
.get()
);
ctx.state.data = {
title: '澳門特別行政區政府各公共部門獎助貸學金服務平台',
link: url,
description: '澳門特別行政區政府各公共部門獎助貸學金服務平台',
item: items,
};
};
+62
View File
@@ -0,0 +1,62 @@
const got = require('@/utils/got');
const cheerio = require('cheerio');
module.exports = async (ctx) => {
const category = ctx.params.category || 'all';
const sort = ctx.params.sort || 'top_time';
const status = ctx.params.status || 'all';
const rootUrl = 'https://zhongchou.modian.com';
const currentUrl = `${rootUrl}/${category}/${sort}/${status}`;
const response = await got({
method: 'get',
url: currentUrl,
});
const $ = cheerio.load(response.data);
const list = $('.pro_title')
.slice(0, 12)
.map((_, item) => {
item = $(item).parent();
return {
title: item.text(),
link: item.attr('href'),
};
})
.get();
const items = await Promise.all(
list.map(
async (item) =>
await ctx.cache.tryGet(item.link, async () => {
const detailResponse = await got({
method: 'get',
url: item.link,
});
const content = cheerio.load(detailResponse.data);
const startTime = detailResponse.data.match(/realtime_sync\.pro_time\('(\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2})', '\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}'\);/);
if (startTime === null) {
item.pubDate = Date.parse(content('.start-time h3').text() || content('h3[start_time]').attr('start_time'));
} else {
item.pubDate = Date.parse(startTime[1]);
}
item.author = content('span[data-nickname]').text();
item.description = `<img src="${content('#big_logo').attr('src')}"><br>` + content('.center-top').html() + content('#my_back_info').html() + content('#cont_match_htmlstr').html();
return item;
})
)
);
ctx.state.data = {
title: `${$('.category div span').text()} - ${$('.status div span').text()} - ${$('.sort div span').text()} - 摩点众筹`,
link: currentUrl,
item: items,
};
};
@@ -8,7 +8,7 @@ module.exports = async (ctx) => {
const year = ctx.params.year || 'all';
const order = ctx.params.order || '0';
const rootUrl = 'https://bde4.icu';
const rootUrl = 'https://www.mp4er.com';
const currentUrl = `${rootUrl}/s/${caty}?${type === 'all' ? '' : '&type=' + type}${area === 'all' ? '' : '&area=' + area}${year === 'all' ? '' : '&year=' + year}&order=${order}`;
const response = await got({
method: 'get',
@@ -28,7 +28,7 @@ module.exports = async (ctx) => {
return {
title: item.attr('title'),
link: `${rootUrl}${link[0]}`,
pubDate: new Date(item.parent().find('.meta span').text()).toUTCString(),
pubDate: Date.parse(item.parent().find('.meta span').text()),
};
})
.get();
@@ -61,7 +61,7 @@ module.exports = async (ctx) => {
const torrents = content('#torrent-list .list');
item.description = content('.info0').html() + `<div><b>下载地址:</b>${downloadLinks}</div>` + `${torrents.html() ? `<div><b>种子列表:</b>${torrents.html()}</div>` : ''}`;
item.enclosure_url = torrents.html() ? torrents.find('a.header').last().attr('href') : downloadResponse.data.pop().url;
item.enclosure_url = torrents.html() ? `${rootUrl}${torrents.find('a.header').last().attr('href')}` : downloadResponse.data.pop().url;
item.enclosure_type = 'application/x-bittorrent';
return item;
+26 -28
View File
@@ -2,21 +2,22 @@ const got = require('@/utils/got');
const cheerio = require('cheerio');
module.exports = async (ctx) => {
const tagId = ctx.params.tagId;
const title = ctx.params.title || '';
const category = ctx.params.category || '0';
const rootUrl = 'https://mubu.com';
const apiUrl = 'https://api2.mubu.com';
const exploreUrl = `${apiUrl}/v3/api/explore/get_explore_doc_list`;
const documentUrl = `${apiUrl}/v3/api/explore/get`;
const response = await got({
method: 'post',
url: `https:mubu.com/api/community/query_document`,
form: {
page: 1,
tagId,
title: '',
type: '',
docRecommend: '',
},
headers: {
referer: 'https:mubu.com/explore',
url: exploreUrl,
json: {
categoryId: '3',
pageSize: '20',
start: '',
type: category === '0' ? 0 : 1,
},
});
@@ -29,8 +30,8 @@ module.exports = async (ctx) => {
}
if (Array.isArray(node.images)) {
ele += node.images
.map((pic) => `https://api2.mubu.com/v3/${pic.uri}`)
.map((uri) => `<div style="text-align: center;"><img src="${uri}" style="max-width: 100%;object-fit: contain;" /></div>`)
.map((pic) => `${apiUrl}/v3/${pic.url}`)
.map((url) => `<div style="text-align: center;"><img src="${url}" style="max-width: 100%;object-fit: contain;" /></div>`)
.join('');
}
@@ -41,20 +42,17 @@ module.exports = async (ctx) => {
return `<ul>${list}</ul>`;
};
const item = await Promise.all(
const items = await Promise.all(
response.data.data.rows.slice(0, 20).map((item) =>
ctx.cache.tryGet(`https://mubu.com/doc/explore/${item.id}`, async () => {
const res = await got({
ctx.cache.tryGet(item.link, async () => {
const detailResponse = await got({
method: 'post',
url: `https://api2.mubu.com/v3/api/document/view/get`,
url: documentUrl,
json: {
docId: item.documentId,
},
headers: {
referer: 'https://mubu.com/',
exploreDocId: item.exploreDocId,
},
});
const content = JSON.parse(res.data.data.definition);
const content = JSON.parse(detailResponse.data.data.definition);
const description = h(content.nodes);
const $ = cheerio.load(description);
@@ -63,18 +61,18 @@ module.exports = async (ctx) => {
return {
title: item.title,
link: `https://mubu.com/doc/explore/${item.id}`,
description: `<h2>${item.title}</h2>` + $('*').html(),
pubDate: new Date(item.publishTime),
author: item.userName,
pubDate: new Date(item.submitTime),
link: `${rootUrl}/explore/${item.exploreDocId}`,
description: `<h2>${item.title}</h2>` + $('*').html(),
};
})
)
);
ctx.state.data = {
title: title ? `幕布 - ${title}` : '幕布',
link: `https://mubu.com/explore#${tagId}`,
item,
title: `${title ? `${title} - ` : ''}幕布精选社区`,
link: `${rootUrl}/explore?categoryId=${category}`,
item: items,
};
};
+1 -2
View File
@@ -2,7 +2,7 @@ const got = require('@/utils/got');
const cheerio = require('cheerio');
const iconv = require('iconv-lite');
const baseUrl = 'http://www.shuquge.com/txt/';
const baseUrl = 'http://www.sizhicn.com/txt/';
// 获取小说的最新章节列表
module.exports = async (ctx) => {
const id = ctx.params.id; // 小说id
@@ -10,7 +10,6 @@ module.exports = async (ctx) => {
const response = await got({
method: 'get',
url: `${baseUrl}${id}/index.html`,
// responseEncoding: 'gbk', //该配置项在 0.18版本中没有打包进去
responseType: 'buffer',
});
const responseHtml = iconv.decode(response.data, 'utf-8');
@@ -0,0 +1,51 @@
const got = require('@/utils/got');
const cheerio = require('cheerio');
const { parseDate } = require('@/utils/parse-date');
module.exports = async (ctx) => {
const url = 'https://www.nytimes.com/zh-hans/series/daily-briefing-chinese';
const response = await got({
method: 'get',
url,
});
const data = response.data;
const $ = cheerio.load(data);
const post = $('.css-13mho3u .css-ye6x8s')
.map((index, elem) => {
const $item = $(elem);
const $link = $item.find('a');
const $title = $item.find('h2');
return {
title: $title.text(),
link: 'https://www.nytimes.com' + $link.attr('href'),
};
})
.get();
const items = await Promise.all(
post.map(
async (item) =>
await ctx.cache.tryGet(item.link, async () => {
const response = await got.get(item.link);
const $ = cheerio.load(response.data);
$('.css-pncxxs.etfikam0').remove();
$('.css-1xdhyk6.erfvjey0').each((_, item) => {
item = $(item);
const link = item.find('img').attr('src');
item.replaceWith(`<img src="${link}">`);
});
item.description = $('.meteredContent.css-1r7ky0e').html();
const date = $('.css-x7rtpa.e16638kd0').attr('datetime');
item.pubDate = parseDate(date);
return item;
})
)
);
ctx.state.data = {
title: '纽约时报中文网|新闻简报',
link: url,
item: items,
};
};
-52
View File
@@ -1,52 +0,0 @@
const got = require('@/utils/got');
const cheerio = require('cheerio');
const utils = require('./utils');
module.exports = async (ctx) => {
const url = 'https://www.nytimes.com/svc/collections/v1/publish/https://www.nytimes.com/zh-hans/series/daily-briefing-chinese/rss.xml';
const response = await got({
method: 'get',
url,
});
const data = response.data;
const $ = cheerio.load(data);
const post = $('item')
.map((index, elem) => {
const title = $(elem).find('title').text();
const link = $(elem).find('link').next().text();
return {
link: link,
title: title,
};
})
.get();
const browser = await require('@/utils/puppeteer')();
const items = await Promise.all(
post.map(async (item) => {
// use puppeter cause all the image is lazy-load
const result = utils.ProcessFeed(await utils.PuppeterGetter(ctx, browser, item.link), true);
item.pubDate = result.pubDate;
// Match 感谢|謝.*?cn.letters@nytimes.com。
const ending = /&#x611F;(&#x8C22|&#x8B1D);.*?cn\.letters@nytimes\.com&#x3002;/g;
const matching = '<div class="article-paragraph">';
const formatted = '<br>' + matching;
item.description = result.description.replace(ending, '').split(matching).join(formatted);
return Promise.resolve(item);
})
);
browser.close();
ctx.state.data = {
title: '纽约时报中文网|每日简报',
link: url,
item: items,
};
};
+2 -1
View File
@@ -1,4 +1,5 @@
const cheerio = require('cheerio');
const { parseDate } = require('@/utils/parse-date');
const ProcessImage = ($, e) => {
const photo = $(e).find('figure').find('picture').find('img');
@@ -87,7 +88,7 @@ const ProcessFeed = (data, hasEnVersion = false) => {
const time = $('time').attr('datetime');
if (time) {
result.pubDate = new Date(time).toUTCString();
result.pubDate = parseDate(time);
}
result.description = content.html();
+1 -1
View File
@@ -1,4 +1,4 @@
exports.modules = {
module.exports = {
maskHeader: {
'App-OS': 'ios',
'App-OS-Version': '10.3.1',
+16 -1
View File
@@ -32,12 +32,27 @@ const links = {
week_r18g: 'https://www.pixiv.net/ranking.php?mode=r18g',
};
const alias = {
daily: 'day',
weekly: 'week',
monthly: 'month',
male: 'day_male',
female: 'day_female',
original: 'week_original',
rookie: 'week_rookie',
daily_r18: 'day_r18',
male_r18: 'day_male_r18',
female_r18: 'day_female_r18',
weekly_r18: 'week_r18',
r18g: 'week_r18g',
};
module.exports = async (ctx) => {
if (!config.pixiv || !config.pixiv.refreshToken) {
throw 'pixiv RSS is disabled due to the lack of <a href="https://docs.rsshub.app/install/#%E9%83%A8%E5%88%86-rss-%E6%A8%A1%E5%9D%97%E9%85%8D%E7%BD%AE">relevant config</a>';
}
const mode = ctx.params.mode;
const mode = alias[ctx.params.mode] ? alias[ctx.params.mode] : ctx.params.mode;
const date = ctx.params.date ? new Date(ctx.params.date) : new Date();
if (!getToken()) {
+3 -3
View File
@@ -10,7 +10,7 @@ module.exports = async (ctx) => {
const keyword = ctx.params.keyword;
const order = ctx.params.order || 'date';
const r18 = ctx.params.r18;
const mode = ctx.params.mode;
if (!getToken()) {
throw 'pixiv not login';
@@ -24,9 +24,9 @@ module.exports = async (ctx) => {
}
let illusts = response.data.illusts;
if (r18 === '1') {
if (mode === 'safe' || mode === '1') {
illusts = illusts.filter((item) => item.x_restrict === 0);
} else if (r18 === '2') {
} else if (mode === 'r18' || mode === '2') {
illusts = illusts.filter((item) => item.x_restrict === 1);
}
+6 -2
View File
@@ -2,7 +2,7 @@ const config = require('@/config').value;
const logger = require('@/utils/logger');
const wait = require('@/utils/wait');
const got = require('./pixiv-got');
const maskHeader = require('./constants').maskHeader;
const { maskHeader } = require('./constants');
let token = null;
@@ -25,11 +25,13 @@ async function refreshToken() {
headers: {
...maskHeader,
},
responseType: 'json',
resolveBodyOnly: true,
}).catch(function (e) {
logger.error('Pixiv refresh token failed.');
logger.debug(e);
});
return response && response.data && response.data.response;
return response;
}
async function tokenLoop() {
@@ -62,3 +64,5 @@ if (config.pixiv && config.pixiv.refreshToken) {
module.exports = function getToken() {
return token;
};
module.exports.refreshToken = refreshToken;
+33
View File
@@ -0,0 +1,33 @@
const got = require('@/utils/got');
const { parseDate } = require('@/utils/parse-date');
module.exports = async (ctx) => {
const response = await got({
method: 'get',
url: `https://monster-siren.hypergryph.com/api/news`,
headers: {
Referer: `https://monster-siren.hypergryph.com/info`,
},
});
const data = response.data.data.list;
ctx.state.data = {
// 源标题
title: `塞壬唱片新闻`,
// 源链接
link: `https://monster-siren.hypergryph.com/info/`,
// 源说明
description: `塞壬唱片新闻`,
// 遍历此前获取的数据
item: data.map((item) => ({
// 文章标题
title: item.title,
// 文章正文
description: `${item.title}<br>${item.date}`,
// 文章发布时间
pubDate: parseDate(`${item.date}`),
// 文章链接
link: `https://monster-siren.hypergryph.com/info/${item.cid}`,
})),
};
};
+1 -1
View File
@@ -11,7 +11,7 @@ const generateResponse = async (items) => ({
description: item.content,
pubDate: new Date(item.createTime).toUTCString(),
guid: item.pId,
link: `https://w3.soulapp-inc.cn/activity/#/web/topic/detail?postIdEcpt=${item.pId}`,
link: `https://w3.soulsmile.cn/activity/#/web/topic/detail?postIdEcpt=${item.pId}`,
})),
});
+2 -2
View File
@@ -4,14 +4,14 @@ const generateResponse = async (info, items) => ({
// 源标题
title: `「${info.name}」的瞬间`,
// 源链接
link: `https://w3.soulapp-inc.cn/activity/#/web/user?userIdEcpt=${info.id}`,
link: `https://w3.soulsmile.cn/activity/#/web/user?userIdEcpt=${info.id}`,
item: items.map((item) => ({
title: `「${info.name}」的新瞬间:${item.pureContent}`,
author: info.name,
description: item.content,
pubDate: new Date(item.createTime).toUTCString(),
guid: item.id,
link: `https://w3.soulapp-inc.cn/activity/#/web/topic/detail?postIdEcpt=${item.id}`,
link: `https://w3.soulsmile.cn/activity/#/web/topic/detail?postIdEcpt=${item.id}`,
})),
});
-45
View File
@@ -1,45 +0,0 @@
const got = require('@/utils/got');
const cheerio = require('cheerio');
module.exports = async (ctx) => {
const { appid, language = 'schinese' } = ctx.params;
const response = await got.get(`https://store.steampowered.com/news/app/${appid}`, {
headers: {
cookie: `Steam_Language=${language}`,
},
});
const $ = cheerio.load(response.data);
const { events } = JSON.parse($('#application_config').attr('data-initialevents'));
const item = events.map((event) => {
event.announcement_body.body = event.announcement_body.body
.replace(/\[img]\{STEAM_CLAN_IMAGE}/g, '<img noopener noreferer style="max-width:100%;" src="https://cdn.cloudflare.steamstatic.com/steamcommunity/public/images/clans')
.replace(/\[\/img]/g, '"/>')
.replace(/\[h1]/g, '<h1>')
.replace(/\[\/h1]/g, '</h1>')
.replace(/\[h2]/g, '<h2>')
.replace(/\[\/h2]/g, '</h2>')
.replace(/\[b]/g, '<b>')
.replace(/\[\/b]/g, '</b>')
.replace(/\[i]/g, '<i>')
.replace(/\[\/i]/g, '</i>')
.replace(/\[url=\s?(http.*?)]/g, '<a href="$1">')
.replace(/\[\/url]/g, '</a>')
.replace(/\[list]/g, '<ul>')
.replace(/\[\/list]/g, '</ul>')
.replace(/\[\*]/g, '<li>');
return {
title: event.event_name,
link: `https://store.steampowered.com/news/app/${appid}/view/${event.gid}`,
pubDate: new Date(event.announcement_body.posttime * 1000),
description: event.announcement_body.body,
};
});
ctx.state.data = {
title: $('head title').text(),
link: `https://store.steampowered.com/news/app/${appid}`,
item,
};
};
+51
View File
@@ -0,0 +1,51 @@
const got = require('@/utils/got');
const cheerio = require('cheerio');
const timezone = require('@/utils/timezone');
module.exports = async (ctx) => {
const rootUrl = 'http://www.sznews.com';
const currentUrl = `${rootUrl}/zhuanti/node_210611.htm`;
const response = await got({
method: 'get',
url: currentUrl,
});
const $ = cheerio.load(response.data);
const list = $('.list-pt-li a h3')
.slice(0, 10)
.map((_, item) => {
item = $(item).parent();
return {
title: item.text(),
link: item.attr('href'),
pubDate: timezone(new Date(item.parent().find('.date').text()), +8),
};
})
.get();
const items = await Promise.all(
list.map(
async (item) =>
await ctx.cache.tryGet(item.link, async () => {
const detailResponse = await got({
method: 'get',
url: item.link,
});
const content = cheerio.load(detailResponse.data);
item.description = content('#picBox').html() + content('.pos').html();
return item;
})
)
);
ctx.state.data = {
title: '往期回顾 - 深圳市政府新闻发布厅',
link: currentUrl,
item: items,
};
};
+1 -1
View File
@@ -42,7 +42,7 @@ module.exports = async (ctx) => {
item.description = content('.article-content').html();
item.author = content('.a_source').text().replace('来源: ', '');
item.pubDate = new Date(content('.a_time').text() + ' GMT+8').toUTCString();
item.pubDate = Date.parse(content('.a_time').text());
return item;
})
+48
View File
@@ -0,0 +1,48 @@
const got = require('@/utils/got');
module.exports = async (ctx) => {
const id = ctx.params.id || '24';
const rootUrl = 'https://topbook.cc';
const categoryUrl = `${rootUrl}/webapi/content/category/${id}/query`;
const currentUrl = `${rootUrl}/webapi/content/article/${id}/page?start=0&limit=24`;
const response = await got({
method: 'get',
url: currentUrl,
});
const categoryResponse = await got({
method: 'get',
url: categoryUrl,
});
const list = response.data.data.items.map((item) => ({
title: item.title,
pubDate: Date.parse(item.createTime),
link: `${rootUrl}/webapi/content/article/query/${item.articleId}`,
}));
const items = await Promise.all(
list.map(
async (item) =>
await ctx.cache.tryGet(item.link, async () => {
const detailResponse = await got({
method: 'get',
url: item.link,
});
item.author = detailResponse.data.data.nickname;
item.description = detailResponse.data.data.content;
item.link = `${rootUrl}/overview?selectedArticle=${item.link.split('/query/')[1]}`;
return item;
})
)
);
ctx.state.data = {
title: `${categoryResponse.data.data.name} - Topbook`,
link: `${rootUrl}/overview/${id}`,
item: items,
};
};
+40
View File
@@ -0,0 +1,40 @@
const got = require('@/utils/got');
module.exports = async (ctx) => {
const rootUrl = 'https://topbook.cc';
const currentUrl = `${rootUrl}/webapi/content/article/24/page?start=0&limit=24`;
const response = await got({
method: 'get',
url: currentUrl,
});
const list = response.data.data.items.map((item) => ({
title: item.title,
pubDate: Date.parse(item.createTime),
link: `${rootUrl}/webapi/content/article/query/${item.articleId}`,
}));
const items = await Promise.all(
list.map(
async (item) =>
await ctx.cache.tryGet(item.link, async () => {
const detailResponse = await got({
method: 'get',
url: item.link,
});
item.author = detailResponse.data.data.nickname;
item.description = detailResponse.data.data.content;
item.link = `${rootUrl}/overview?selectedArticle=${item.link.split('/query/')[1]}`;
return item;
})
)
);
ctx.state.data = {
title: '今天看点啥 - Topbook',
link: `${rootUrl}/overview/24`,
item: items,
};
};
+25 -33
View File
@@ -1,45 +1,37 @@
const got = require('@/utils/got');
const iconv = require('iconv-lite');
const cheerio = require('cheerio');
const resolve_url = require('url').resolve;
const { parseDate } = require('@/utils/parse-date');
const timezone = require('@/utils/timezone');
const base_url = 'http://jwc1.dlu.edu.cn/';
const baseUrl = 'http://jwc1.dlu.edu.cn/';
// const map = {
// 2: '/gsgg.htm',
// 3: '/jwtz.htm',
// 4: '/jwwj.htm',
// 5: '/xxwj.htm'
// };
module.exports = async (ctx) => {
// const type = ctx.params.type || '2';
// const link = `${base_url}${map[type]}`;
let resp = await got({ url: baseUrl, responseType: 'buffer' });
const index = cheerio.load(iconv.decode(resp.data, 'utf-8'));
const response = await got({
method: 'get',
url: base_url,
// url:link,
responseType: 'buffer',
headers: {
Referer: base_url,
},
});
const $ = cheerio.load(iconv.decode(response.data, 'utf-8'));
const regex = /(\d+)\.htm/;
const items = index('td[valign="top"]>table[cellspacing="3"][width="100%"] tr')
.toArray()
.map(async (elem) => {
const link = new URL(index('a', elem).attr('href'), baseUrl).href;
return await ctx.cache.tryGet(link, async () => {
resp = await got({ url: link, responseType: 'buffer' });
const article = cheerio.load(iconv.decode(resp.data, 'utf-8'), { decodeEntities: false });
return {
link: link.toString(),
title: index('a', elem).attr('title'),
pubDate: timezone(parseDate(article('td[height="28"]').text(), 'YYYY年MM月DD日 HH:mm'), +8).toUTCString(),
description: article('form[name="_newscontent_fromname"] > div > *:not(table)')
.toArray()
.map((it) => article(it).html())
.join('\n'),
};
});
});
ctx.state.data = {
link: base_url,
link: baseUrl,
title: '大连大学教务处',
item: $('td[valign="top"]>table[cellspacing="3"][width="100%"] tr')
.map((_, elem) => ({
link: resolve_url(base_url, $('a', elem).attr('href')),
title: $('a', elem).attr('title'),
pubDate: new Date(new Date().getFullYear() + '-' + $('[class*="timestyle"]', elem).text().replace('/', '-')).toUTCString(),
}))
.get()
.sort((one, two) => two.link.match(regex)[1] - one.link.match(regex)[1])
.slice(0, 20),
item: await Promise.all(items),
};
};
+60
View File
@@ -0,0 +1,60 @@
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: 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: title,
link: link,
pubDate: pubDate,
description: description,
};
return JSON.stringify(entry);
});
return Promise.resolve(JSON.parse(cache));
})
);
ctx.state.data = {
title: typeMap.title,
link: frontUrl,
item: entries,
};
};
+50
View File
@@ -0,0 +1,50 @@
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;
+193
View File
@@ -0,0 +1,193 @@
const got = require('@/utils/got');
const titles = {
RecruitList: '专场招聘会',
Doublechoice: '校园双选会',
Broadcast: '空中宣讲',
joblist2: '招聘公告',
};
module.exports = async (ctx) => {
const category = ctx.params.category || 'joblist2';
const rand = 0.01234567890123456;
const apiRootUrl = 'http://ustc.ahbys.com';
const rootUrl = 'http://www.job.ustc.edu.cn';
const currentUrl = `${rootUrl}/${category}.html`;
const response = await got({
method: (() => {
switch (category) {
case 'RecruitList':
case 'Broadcast':
case 'joblist2':
return 'get';
case 'Doublechoice':
return 'post';
}
})(),
url: (() => {
switch (category) {
case 'RecruitList':
return `${apiRootUrl}/API/Web/index10358.ashx?rd=${rand}&pagesize=20&pageindex=1&action=bookinglist&kind=13`;
case 'Doublechoice':
return `${apiRootUrl}/API/Web/index10358.ashx?rd=${rand}`;
case 'Broadcast':
return `${apiRootUrl}/API/Web/index10358.ashx?rd=${rand}&pagesize=20&pageindex=1&action=bookinglist2&kind=2`;
case 'joblist2':
return `${apiRootUrl}/API/Web/index10358.ashx?action=joblist2&pagesize=50&pageindex=1&rand=${rand}`;
}
})(),
form: (() => {
switch (category) {
case 'RecruitList':
case 'Broadcast':
case 'joblist2':
return {};
case 'Doublechoice':
return {
pagesize: 15,
pageindex: 1,
action: 'recruitlist',
rand: rand,
};
}
})(),
allowGetBody: true,
});
const list = response.data.data.slice(0, 10).map((item) => {
switch (category) {
case 'RecruitList':
return {
title: item.ID,
pubDate: new Date(item.HoldDate),
link: `${rootUrl}/Recruit.html?id=${item.ID}`,
};
case 'Doublechoice':
return {
ID: item.ID,
title: item.Theme,
pubDate: new Date(item.HoldDate),
link: `${rootUrl}/R2.html?id=${item.ID}`,
};
case 'Broadcast':
return {
title: item.ID,
pubDate: new Date(item.HoldDate),
link: `${rootUrl}/R2.html?id=${item.ID}`,
};
case 'joblist2':
return {
title: item.JID,
pubDate: new Date(item.UpdateDate),
link: `${rootUrl}/Job2.html?jid=${item.JID}&cid=${item.CompanyID}`,
};
default:
return {};
}
});
const items = await Promise.all(
list.map(
async (item) =>
await ctx.cache.tryGet(item.link, async () => {
const detailResponse = await got({
method: (() => {
switch (category) {
case 'RecruitList':
case 'Broadcast':
case 'joblist2':
return 'get';
case 'Doublechoice':
return 'post';
}
})(),
url: (() => {
switch (category) {
case 'RecruitList':
return `${apiRootUrl}/API/Web/index10358.ashx?rd=${rand}&action=bookinginfo&rid=${item.title}&rand=${rand}`;
case 'Doublechoice':
return `${apiRootUrl}/API/Web/index10358.ashx`;
case 'Broadcast':
return `${apiRootUrl}/API/Web/index10358.ashx?rd=${rand}&action=binfo&rid=${item.title}&rand=${rand}`;
case 'joblist2':
return `${apiRootUrl}/API/Web/index10358.ashx?rd=${rand}&action=jobinfo2&jid=${item.title}&rand=${rand}`;
}
})(),
form: (() => {
switch (category) {
case 'RecruitList':
case 'Broadcast':
case 'joblist2':
return {};
case 'Doublechoice':
return {
pagesize: 100,
pageindex: 1,
action: 'recruitcompany',
rid: item.ID,
rand: rand,
};
}
})(),
allowGetBody: true,
});
item.title = (() => {
switch (category) {
case 'RecruitList':
case 'Broadcast':
return detailResponse.data.Theme;
case 'Doublechoice':
return item.title;
case 'joblist2':
return detailResponse.data.JobName;
}
})();
item.description = (() => {
switch (category) {
case 'RecruitList':
case 'Broadcast':
return detailResponse.data.Description;
case 'Doublechoice': {
let tbody =
'<table><thead style="background-color: #f6f6ee"><tr>' +
'<th style="white-space: nowrap;">单位名称</th>' +
'<th style="white-space: nowrap;">展位号</th>' +
'<th>职位信息</th></tr><tr></tr></thead><tbody>';
for (const company of detailResponse.data.CompanyList) {
tbody += `<tr><td style="white-space:nowrap"><a style="color:#004276;font-size:14px;"'+
'href="${rootUrl}/Company.html?cid=${company.CompanyID}" target="_blank">${company.CompanyName}</a></td>'+
'<td style="white-space:nowrap">${item.nPos}</td><td>${item.JobList}</td></tr>`;
}
return `${tbody}</tbody></table>`;
}
case 'joblist2':
return detailResponse.data.PostionDesc;
}
})();
return item;
})
)
);
ctx.state.data = {
title: `${titles[category]} - 中国科学技术大学就业信息网`,
link: currentUrl,
item: items,
};
};
+5 -4
View File
@@ -1,4 +1,5 @@
const got = require('@/utils/got');
const { parseDate } = require('@/utils/parse-date');
const cheerio = require('cheerio');
module.exports = async (ctx) => {
@@ -17,10 +18,10 @@ module.exports = async (ctx) => {
const $ = cheerio.load(htmlString);
const date_and_author = $('.content_other').text();
const matched_date = /(\d+)年(\d+)月(\d+)日 (\d+):(\d+):(\d+)/.exec(date_and_author);
const date = new Date(parseInt(matched_date[1]), parseInt(matched_date[2]) - 1, parseInt(matched_date[3]), parseInt(matched_date[4]), parseInt(matched_date[5]), parseInt(matched_date[6]));
// the format is "日期:YYYY年MM月DD日 HH:mm:ss\n\s+作者:xxx"
// The timezone is GMT+8.
const dateString = date_and_author.split('\n')[0].substr(3);
const date = parseDate(`${dateString}+0800`, 'YYYY年MM月DD日 HH:mm:ssZZ');
const author = date_and_author.split(':').slice(-1)[0];
const content = $('.content_info');
+21 -20
View File
@@ -1,34 +1,36 @@
const got = require('@/utils/got');
const utils = require('./utils');
const { parseDate } = require('@/utils/parse-date');
// 参考:https://github.com/izzyleung/ZhihuDailyPurify/wiki/%E7%9F%A5%E4%B9%8E%E6%97%A5%E6%8A%A5-API-%E5%88%86%E6%9E%90
// 文章给出了v4版 api的信息,包含全文api
module.exports = async (ctx) => {
const api = 'https://news-at.zhihu.com/api/4/news';
const listRes = await got({
method: 'get',
url: 'https://news-at.zhihu.com/api/4/news/latest',
url: `${api}/latest`,
headers: {
...utils.header,
Referer: 'https://news-at.zhihu.com/api/4/news/latest',
Referer: `${api}/latest`,
},
});
// 根据api的说明,过滤掉极个别站外链接
const storyList = listRes.data.stories.filter((el) => el.type === 0);
const resultItem = await Promise.all(
storyList.map(async (story) => {
const url = 'https://news-at.zhihu.com/api/4/news/' + story.id;
const item = {
title: story.title,
description: '',
link: 'https://daily.zhihu.com/story/' + story.id,
};
const key = 'daily' + story.id;
const value = await ctx.cache.get(key);
const date = listRes.data.date;
if (value) {
item.description = value;
} else {
const articleList = storyList.map((item) => ({
title: item.title,
pubDate: parseDate(date, 'YYYYMMDD'),
link: item.url,
guid: item.url,
storyId: item.id,
}));
const items = await Promise.all(
articleList.map(async (item) => {
const url = `${api}/${item.storyId}`;
const description = await ctx.cache.tryGet(item.link, async () => {
const storyDetail = await got({
method: 'get',
url: url,
@@ -36,10 +38,9 @@ module.exports = async (ctx) => {
Referer: url,
},
});
item.description = utils.ProcessImage(storyDetail.data.body.replace(/<div class="meta">([\s\S]*?)<\/div>/g, '<strong>$1</strong>').replace(/<\/?h2.*?>/g, ''));
ctx.cache.set(key, item.description);
}
return utils.ProcessImage(storyDetail.data.body.replace(/<div class="meta">([\s\S]*?)<\/div>/g, '<strong>$1</strong>').replace(/<\/?h2.*?>/g, ''));
});
item.description = description;
return Promise.resolve(item);
})
);
@@ -48,6 +49,6 @@ module.exports = async (ctx) => {
title: '知乎日报',
link: 'https://daily.zhihu.com',
description: '每天3次,每次7分钟',
item: resultItem,
item: items,
};
};
+3067 -2112
View File
File diff suppressed because it is too large Load Diff
+7 -6
View File
@@ -36,6 +36,7 @@
},
"homepage": "https://github.com/DIYgod/RSSHub#readme",
"devDependencies": {
"@napi-rs/pinyin": "^1.6.1",
"@types/cheerio": "0.22.24",
"@types/got": "9.6.11",
"@types/koa": "2.13.1",
@@ -43,17 +44,16 @@
"@vuepress/plugin-google-analytics": "1.8.2",
"@vuepress/plugin-pwa": "1.8.2",
"cross-env": "7.0.3",
"eslint": "7.26.0",
"eslint": "7.29.0",
"eslint-config-prettier": "8.3.0",
"eslint-plugin-prettier": "3.4.0",
"jest": "26.6.3",
"mockdate": "3.0.5",
"nock": "13.0.11",
"nodemon": "2.0.7",
"pinyin": "2.10.2",
"prettier": "2.2.1",
"prettier-check": "2.0.0",
"pretty-quick": "3.1.0",
"pretty-quick": "3.1.1",
"remark": "12.0.1",
"remark-frontmatter": "2.0.0",
"remark-pangu": "2.2.0",
@@ -67,12 +67,13 @@
"dependencies": {
"@koa/router": "10.0.0",
"@postlight/mercury-parser": "2.2.0",
"@sentry/node": "6.3.5",
"@sentry/node": "6.7.2",
"aes-js": "3.1.2",
"art-template": "4.13.2",
"bbcodejs": "0.0.4",
"cheerio": "1.0.0-rc.3",
"chrono-node": "2.2.6",
"city-timezones": "^1.2.0",
"crypto-js": "4.0.0",
"currency-symbol-map": "4.0.4",
"dayjs": "1.10.3",
@@ -106,12 +107,12 @@
"pidusage": "2.0.21",
"plist": "3.0.2",
"puppeteer": "9.1.1",
"query-string": "7.0.0",
"query-string": "7.0.1",
"require-all": "3.0.0",
"rss-parser": "3.10.0",
"showdown": "1.9.1",
"simplecc-wasm": "0.1.2",
"socks-proxy-agent": "5.0.0",
"socks-proxy-agent": "5.0.1",
"string-similarity": "^4.0.3",
"tiny-async-pool": "1.2.0",
"torrent-search-api": "^2.1.3",
+3 -4
View File
@@ -20,7 +20,6 @@
state: present
with_items:
- https://deb.nodesource.com/gpgkey/nodesource.gpg.key
- https://dl.yarnpkg.com/debian/pubkey.gpg
- https://download.docker.com/linux/ubuntu/gpg
- https://dl.cloudsmith.io/public/caddy/stable/cfg/gpg/gpg.155B6D79CA56EA34.key
-
@@ -31,7 +30,6 @@
update_cache: yes
with_items:
- deb https://deb.nodesource.com/node_12.x focal main
- deb https://dl.yarnpkg.com/debian/ stable main
- deb https://download.docker.com/linux/ubuntu focal stable
- deb https://dl.cloudsmith.io/public/caddy/stable/deb/debian any-version main
-
@@ -39,7 +37,6 @@
apt:
name:
- nodejs
- yarn
- build-essential
- python-is-python2
- redis-server
@@ -101,9 +98,11 @@
update: yes
-
name: Install repo dependencies
command: yarn install --production
command: npm ci --production
args:
chdir: /home/rsshub/app
environment:
PUPPETEER_SKIP_DOWNLOAD: true
-
name: Copy configuration
copy:
+3 -1
View File
@@ -1,5 +1,5 @@
const noFound = 'Auto: Route No Found';
const whiteListedUser = ['dependabot-preview[bot]'];
const whiteListedUser = ['dependabot[bot]'];
module.exports = async ({ github, context, core }, body, number) => {
core.debug(`sender: ${context.payload.sender.login}`);
@@ -34,6 +34,8 @@ module.exports = async ({ github, context, core }, body, number) => {
core.warning(e);
});
return;
} else {
core.debug('PR created by ' + context.payload.sender.login);
}
if (m && m[1]) {