Merge pull request #2 from DIYgod/master

update from source
This commit is contained in:
qixingchen 2018-05-09 20:53:06 +08:00 committed by GitHub
commit f4535fa79a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
59 changed files with 597 additions and 283 deletions

View File

@ -2,6 +2,8 @@ language: node_js
node_js: stable
before_install:
install:
- yarn
@ -11,12 +13,16 @@ script:
- echo 'rsshub.js.org' > CNAME
after_script:
- git init
- git config user.name "Travis CI"
- git config user.email "no-reply@html.love"
- git add -A
- git commit -m 'deploy'
- git push -f "https://${GH_TOKEN}@github.com/DIYgod/RSSHub.git" master:gh-pages
- |
if git diff --name-only $TRAVIS_COMMIT_RANGE | grep '^docs/'
then
git init
git config user.name "Travis CI"
git config user.email "no-reply@html.love"
git add -A
git commit -m 'deploy'
git push -f "https://${GH_TOKEN}@github.com/DIYgod/RSSHub.git" master:gh-pages
fi
cache:
yarn: true

View File

@ -1,4 +1,7 @@
# RSSHub
<p align="center">
<img src="https://i.imgur.com/NZpRScX.png" alt="RSSHub" width="100">
</p>
<h1 align="center">RSSHub</h1>
> 🍭 使用 RSS 连接全世界
@ -50,6 +53,7 @@ RSSHub 是一个轻量、易于扩展的 RSS 生成器,可以给任何奇奇
- 专题详情
- 详情
- pixiv
- 用户收藏
- 用户动态
- 排行榜
- 豆瓣
@ -65,14 +69,29 @@ RSSHub 是一个轻量、易于扩展的 RSS 生成器,可以给任何奇奇
- 周报
- 腾讯吐个槽
- 吐槽新帖
- 笔趣阁
- 小说章节
- 开发者头条
- 今天头条
- 独家号
- Disqus
- 评论
## 参与我们
如果有任何想法或需求,可以在 [issue](https://github.com/DIYgod/RSSHub/issues) 中告诉我们,同时我们欢迎各种 pull requests
可以通过以下途径参与讨论:
### 提交新的 RSS 内容
- [Telegram 群](https://t.me/rsshub)
1. 在 [/router.js](https://github.com/DIYgod/RSSHub/blob/master/router.js) 里添加路由
1. 在 [/routes/](https://github.com/DIYgod/RSSHub/tree/master/routes) 中的路由对应路径添加获取 RSS 内容的脚本
1. 更新 README 和文档: [/README.md](https://github.com/DIYgod/RSSHub/blob/master/README.md) [/docs/README.md](https://github.com/DIYgod/RSSHub/blob/master/docs/README.md)
### 参与讨论
1. [Telegram 群](https://t.me/rsshub)
## 搭建

View File

@ -8,5 +8,8 @@ module.exports = {
client_secret: 'lsACyCD94FhDUtGTXi3QzcFE2uU1hqtDaKeqrdwj',
username: 'rsshub@tmpmail.org',
password: 'rsshubpixiv'
},
disqus: {
api_key: 'E8Uh5l5fHZ6gD8U3KycjAIAk46f68Zw7C6eW8WSjZvCLXebZ7p0r1yrYDrLilk2F',
}
};

View File

@ -0,0 +1,22 @@
$accentColor = #F5712C
.navbar .site-name {
color: $accentColor;
}
.page .custom-block.tip {
border-color: $accentColor;
}
a.sidebar-link {
font-weight: bold;
}
.sidebar-sub-header a.sidebar-link {
font-weight: 400;
}
.page .content .logo {
padding-top: 2.6rem;
padding-bottom: 2rem;
}

View File

@ -2,17 +2,22 @@
sidebar: auto
---
# 使用
<p align="center">
<img src="https://i.imgur.com/NZpRScX.png" alt="RSSHub" width="100">
</p>
<h1 align="center" class="logo">RSSHub</h1>
RSSHub 是一个轻量、易于扩展的 RSS 生成器,可以给任何奇奇怪怪的内容生成 RSS 订阅源
演示域名为 rss.now.sh缓存时间 5 分钟
::: tip 提示
演示域名为 [rss.now.sh](https://rss.now.sh),缓存时间 5 分钟,可以随意使用
:::
## bilibili
### 番剧
举例: https://rss.now.sh/bilibili/bangumi/21680
举例: [https://rss.now.sh/bilibili/bangumi/21680](https://rss.now.sh/bilibili/bangumi/21680)
路由: `/bilibili/bangumi/:seasonid`
@ -20,7 +25,7 @@ RSSHub 是一个轻量、易于扩展的 RSS 生成器,可以给任何奇奇
### UP 主投稿
举例: https://rss.now.sh/bilibili/user/video/2267573
举例: [https://rss.now.sh/bilibili/user/video/2267573](https://rss.now.sh/bilibili/user/video/2267573)
路由: `/bilibili/user/video/:uid`
@ -28,7 +33,7 @@ RSSHub 是一个轻量、易于扩展的 RSS 生成器,可以给任何奇奇
### UP 主动态
举例: https://rss.now.sh/bilibili/user/dynamic/2267573
举例: [https://rss.now.sh/bilibili/user/dynamic/2267573](https://rss.now.sh/bilibili/user/dynamic/2267573)
路由: `/bilibili/user/dynamic/:uid`
@ -36,7 +41,7 @@ RSSHub 是一个轻量、易于扩展的 RSS 生成器,可以给任何奇奇
### UP 主收藏夹
举例: https://rss.now.sh/bilibili/user/fav/2267573
举例: [https://rss.now.sh/bilibili/user/fav/2267573](https://rss.now.sh/bilibili/user/fav/2267573)
路由: `/bilibili/user/fav/:uid`
@ -44,7 +49,7 @@ RSSHub 是一个轻量、易于扩展的 RSS 生成器,可以给任何奇奇
### UP 主投币视频
举例: https://rss.now.sh/bilibili/user/coin/2267573
举例: [https://rss.now.sh/bilibili/user/coin/2267573](https://rss.now.sh/bilibili/user/coin/2267573)
路由: `/bilibili/user/coin/:uid`
@ -52,7 +57,7 @@ RSSHub 是一个轻量、易于扩展的 RSS 生成器,可以给任何奇奇
### UP 主粉丝
举例: https://rss.now.sh/bilibili/user/followers/2267573
举例: [https://rss.now.sh/bilibili/user/followers/2267573](https://rss.now.sh/bilibili/user/followers/2267573)
路由: `/bilibili/user/followers/:uid`
@ -60,7 +65,7 @@ RSSHub 是一个轻量、易于扩展的 RSS 生成器,可以给任何奇奇
### UP 主关注用户
举例: https://rss.now.sh/bilibili/user/followings/2267573
举例: [https://rss.now.sh/bilibili/user/followings/2267573](https://rss.now.sh/bilibili/user/followings/2267573)
路由: `/bilibili/user/followings/:uid`
@ -68,7 +73,7 @@ RSSHub 是一个轻量、易于扩展的 RSS 生成器,可以给任何奇奇
### 分区视频
举例: https://rss.now.sh/bilibili/partion/33
举例: [https://rss.now.sh/bilibili/partion/33](https://rss.now.sh/bilibili/partion/33)
路由: `/bilibili/partion/:tid`
@ -154,17 +159,17 @@ s
### 视频评论
举例: https://rss.now.sh/bilibili/video/reply/7
举例: [https://rss.now.sh/bilibili/video/reply/21669336](https://rss.now.sh/bilibili/video/reply/21669336)
路由: `/bilibili/video/reply/:avid`
路由: `/bilibili/video/reply/:aid`
参数: avid视频 AV 号(仅数字)
参数: aid可在视频页 URL 中找到
## 微博
### 博主
举例: https://rss.now.sh/weibo/user/3306934123
举例: [https://rss.now.sh/weibo/user/3306934123](https://rss.now.sh/weibo/user/3306934123)
路由: `/weibo/user/:uid`
@ -174,7 +179,7 @@ s
### 歌单歌曲
举例: https://rss.now.sh/ncm/playlist/35798529
举例: [https://rss.now.sh/ncm/playlist/35798529](https://rss.now.sh/ncm/playlist/35798529)
路由: `/ncm/playlist/:id`
@ -182,7 +187,7 @@ s
### 用户歌单
举例: https://rss.now.sh/ncm/user/playlist/45441555
举例: [https://rss.now.sh/ncm/user/playlist/45441555](https://rss.now.sh/ncm/user/playlist/45441555)
路由: `/ncm/user/playlist/:uid`
@ -190,7 +195,7 @@ s
### 歌手专辑
举例: https://rss.now.sh/ncm/artist/2116
举例: [https://rss.now.sh/ncm/artist/2116](https://rss.now.sh/ncm/artist/2116)
路由: `/ncm/artist/:id`
@ -200,7 +205,7 @@ s
### 分类
举例: https://rss.now.sh/juejin/category/frontend
举例: [https://rss.now.sh/juejin/category/frontend](https://rss.now.sh/juejin/category/frontend)
路由: `/juejin/category/:category`
@ -214,7 +219,7 @@ s
### 首页
举例: https://rss.now.sh/jianshu/home
举例: [https://rss.now.sh/jianshu/home](https://rss.now.sh/jianshu/home)
路由: `/jianshu/home`
@ -222,7 +227,7 @@ s
### 7 日热门
举例: https://rss.now.sh/jianshu/trending/weekly
举例: [https://rss.now.sh/jianshu/trending/weekly](https://rss.now.sh/jianshu/trending/weekly)
路由: `/jianshu/trending/weekly`
@ -230,7 +235,7 @@ s
### 30 日热门
举例: https://rss.now.sh/jianshu/trending/monthly
举例: [https://rss.now.sh/jianshu/trending/monthly](https://rss.now.sh/jianshu/trending/monthly)
路由: `/jianshu/trending/monthly`
@ -238,7 +243,7 @@ s
### 专题
举例: https://rss.now.sh/jianshu/collection/xYuZYD
举例: [https://rss.now.sh/jianshu/collection/xYuZYD](https://rss.now.sh/jianshu/collection/xYuZYD)
路由: `/jianshu/collection/:id`
@ -246,7 +251,7 @@ s
### 作者
举例: https://rss.now.sh/jianshu/user/yZq3ZV
举例: [https://rss.now.sh/jianshu/user/yZq3ZV](https://rss.now.sh/jianshu/user/yZq3ZV)
路由: `/jianshu/user/:id`
@ -257,7 +262,7 @@ s
### 收藏夹
举例: https://rss.now.sh/zhihu/collection/26444956
举例: [https://rss.now.sh/zhihu/collection/26444956](https://rss.now.sh/zhihu/collection/26444956)
路由: `/zhihu/collection/:id`
@ -265,7 +270,7 @@ s
### 用户动态
举例: https://rss.now.sh/zhihu/people/activities/diygod
举例: [https://rss.now.sh/zhihu/people/activities/diygod](https://rss.now.sh/zhihu/people/activities/diygod)
路由: `/zhihu/people/activities/:id`
@ -273,7 +278,7 @@ s
### 专栏
举例: https://rss.now.sh/zhihu/zhuanlan/googledevelopers
举例: [https://rss.now.sh/zhihu/zhuanlan/googledevelopers](https://rss.now.sh/zhihu/zhuanlan/googledevelopers)
路由: `/zhihu/zhuanlan/:id`
@ -283,7 +288,7 @@ s
### 房源
举例: https://rss.now.sh/ziroom/room/sh/1/2/五角场
举例: [https://rss.now.sh/ziroom/room/sh/1/2/五角场](https://rss.now.sh/ziroom/room/sh/1/2/五角场)
路由: `/ziroom/room/:city/:iswhole/:room/:keyword`
@ -299,11 +304,11 @@ keyword: 关键词
## 快递
<p class="warning">
快递送达后请及时取消订阅,以免不必要地浪费服务器资源
</p>
::: warning 注意
快递送达后请及时取消订阅,以免不必要地浪费服务器资源
:::
举例: https://rss.now.sh/express/youzhengguoji/CV054432809US
举例: [https://rss.now.sh/express/youzhengguoji/CV054432809US](https://rss.now.sh/express/youzhengguoji/CV054432809US)
路由: `/express/:company/:number`
@ -315,13 +320,9 @@ number: 快递单号
## 贴吧
<p class="warning">
吧名如果包含中文,应该使用 `encodeURIComponent` 编码后使用
</p>
### 帖子列表
举例: https://rss.now.sh/tieba/forum/女图
举例: [https://rss.now.sh/tieba/forum/女图](https://rss.now.sh/tieba/forum/女图)
路由: `/tieba/forum/:kw`
@ -329,15 +330,19 @@ number: 快递单号
## 妹子图
::: warning 注意
该网站在国外无法访问,故以下演示无效
:::
### 首页(最新)
举例: https://rss.now.sh/mzitu
举例: [https://rss.now.sh/mzitu](https://rss.now.sh/mzitu)
路由: `/mzitu/`
### 分类
举例: https://rss.now.sh/mzitu/category/hot
举例: [https://rss.now.sh/mzitu/category/hot](https://rss.now.sh/mzitu/category/hot)
路由: `/mzitu/category/:category`
@ -350,13 +355,13 @@ number: 快递单号
### 所有专题
举例: https://rss.now.sh/mzitu/tags
举例: [https://rss.now.sh/mzitu/tags](https://rss.now.sh/mzitu/tags)
路由: `/mzitu/tags`
### 专题详情
举例: https://rss.now.sh/mzitu/tag/shishen
举例: [https://rss.now.sh/mzitu/tag/shishen](https://rss.now.sh/mzitu/tag/shishen)
路由: `/mzitu/tag/:tag`
@ -364,7 +369,7 @@ number: 快递单号
### 详情
举例: https://rss.now.sh/mzitu/post/129452
举例: [https://rss.now.sh/mzitu/post/129452](https://rss.now.sh/mzitu/post/129452)
路由: `/mzitu/post/:id`
@ -372,9 +377,17 @@ number: 快递单号
## pixiv
### 用户收藏
举例: [https://rss.now.sh/pixiv/user/bookmarks/15288095](https://rss.now.sh/pixiv/user/bookmarks/15288095)
路由: `/pixiv/user/bookmarks/:id`
参数: id用户 id可在用户主页 URL 中找到
### 用户动态
举例: https://rss.now.sh/pixiv/user/11
举例: [https://rss.now.sh/pixiv/user/11](https://rss.now.sh/pixiv/user/11)
路由: `/pixiv/user/:id`
@ -382,7 +395,7 @@ number: 快递单号
### 排行榜
举例: https://rss.now.sh/pixiv/ranking/week
举例: [https://rss.now.sh/pixiv/ranking/week](https://rss.now.sh/pixiv/ranking/week)
路由: `/pixiv/ranking/:mode/:date?`
@ -391,11 +404,11 @@ number: 快递单号
mode: 排行榜类型
| pixiv 日排行 | pixiv 周排行 | pixiv 月排行 | pixiv 受男性欢迎排行 | pixiv 受女性欢迎排行 | pixiv 原创作品排行 | pixiv 新人排行 |
| --------- | --------- |-------------- | ------------------ | ------------------ | -------------- | -------------- |
| --------- | --------- | --------- | ------------- | ------------- | ------------- | ----------- |
| day | week | month | day_male | day_female | week_original | week_rookie |
| pixiv R-18 日排行 | pixiv R-18 受男性欢迎排行 | pixiv R-18 受女性欢迎排行 | pixiv R-18 周排行 | pixiv R-18G 排行 |
| --------- | ------------- | ------------- | ------------- | ----------- |
| -------------- | ------------------ | ------------------ | -------------- | -------------- |
| day_r18 | day_male_r18 | day_female_r18 | week_r18 | week_r18g |
date: 日期,取值形如 `2018-4-25`
@ -404,7 +417,7 @@ date: 日期,取值形如 `2018-4-25`
### 正在上映的电影
举例: https://rss.now.sh/douban/movie/playing
举例: [https://rss.now.sh/douban/movie/playing](https://rss.now.sh/douban/movie/playing)
路由: `/douban/movie/playing`
@ -412,7 +425,7 @@ date: 日期,取值形如 `2018-4-25`
### 正在上映的高分电影
举例: https://rss.now.sh/douban/movie/playing/7.5
举例: [https://rss.now.sh/douban/movie/playing/7.5](https://rss.now.sh/douban/movie/playing/7.5)
路由
@ -428,7 +441,7 @@ city: 城市的中文名,可选,默认北京
### 即将上映的电影
举例: https://rss.now.sh/douban/movie/later
举例: [https://rss.now.sh/douban/movie/later](https://rss.now.sh/douban/movie/later)
路由: `/douban/movie/later`
@ -436,7 +449,7 @@ city: 城市的中文名,可选,默认北京
### 北美票房榜
举例: https://rss.now.sh/douban/movie/ustop
举例: [https://rss.now.sh/douban/movie/ustop](https://rss.now.sh/douban/movie/ustop)
路由: `/douban/movie/ustop`
@ -446,7 +459,7 @@ city: 城市的中文名,可选,默认北京
### 无聊图
举例: https://rss.now.sh/jandan/pic
举例: [https://rss.now.sh/jandan/pic](https://rss.now.sh/jandan/pic)
路由: `/jandan/pic`
@ -456,7 +469,7 @@ city: 城市的中文名,可选,默认北京
### 图卦
举例: https://rss.now.sh/dapenti/tugua
举例: [https://rss.now.sh/dapenti/tugua](https://rss.now.sh/dapenti/tugua)
路由: `/dapenti/tugua`
@ -466,7 +479,7 @@ city: 城市的中文名,可选,默认北京
### 周报
举例: https://rss.now.sh/dockone/weekly
举例: [https://rss.now.sh/dockone/weekly](https://rss.now.sh/dockone/weekly)
路由: `/dockone/weekly`
@ -476,7 +489,7 @@ city: 城市的中文名,可选,默认北京
### 吐槽新帖
举例: https://rss.now.sh/tucaoqq/post/28564/CdRI0728
举例: [https://rss.now.sh/tucaoqq/post/28564/CdRI0728](https://rss.now.sh/tucaoqq/post/28564/CdRI0728)
路由: `/tucaoqq/post/:project/:key`
@ -490,8 +503,34 @@ key: 产品密钥
### 小说章节
举例: https://rss.now.sh/biquge/novel/latestchapter/52_52542
举例: [https://rss.now.sh/biquge/novel/latestchapter/52_52542](https://rss.now.sh/biquge/novel/latestchapter/52_52542)
路由: `/biquge/novel/latestchapter/:id`
参数: id小说 id可在对应小说页 URL 中找到
参数: id小说 id可在对应小说页 URL 中找到
## 开发者头条
### 今天头条
举例: [https://rss.now.sh/toutiao/today](https://rss.now.sh/toutiao/today)
路由: `/toutiao/today`
### 独家号
举例: [https://rss.now.sh/toutiao/user/140544](https://rss.now.sh/toutiao/user/140544)
路由: `/toutiao/user/:id`
参数: id独家号 id可在对应独家号页 URL 中找到
## Disqus
### 评论
举例: [https://rss.now.sh/disqus/posts/diygod-me](https://rss.now.sh/disqus/posts/diygod-me)
路由: `/disqus/posts/:forum`
参数: forum网站的 disqus name

View File

@ -8,8 +8,8 @@
1. 在 [/routes/](https://github.com/DIYgod/RSSHub/tree/master/routes) 中的路由对应路径添加获取 RSS 内容的脚本
1. 更新文档 [/docs/README.md](https://github.com/DIYgod/RSSHub/blob/master/docs/README.md)
1. 更新 README 和文档: [/README.md](https://github.com/DIYgod/RSSHub/blob/master/README.md) [/docs/README.md](https://github.com/DIYgod/RSSHub/blob/master/docs/README.md)
## 参与讨论
- [Telegram 群](https://t.me/rsshub)
1. [Telegram 群](https://t.me/rsshub)

View File

@ -4,7 +4,7 @@ module.exports = async (ctx, next) => {
try {
await next();
} catch (err) {
logger.error('Promise error: ' + err);
logger.error('Promise error: ' + (err instanceof Error ? err.stack : err));
ctx.set({
'Content-Type': 'text/html; charset=UTF-8',
});

View File

@ -31,7 +31,6 @@
"crypto": "1.0.1",
"eslint": "4.19.1",
"form-data": "^2.3.2",
"js-md5": "^0.7.3",
"json-bigint": "0.2.3",
"koa": "2.5.0",
"koa-redis-cache": "3.0.0",

View File

@ -19,7 +19,7 @@ router.get('/bilibili/user/followers/:uid', require('./routes/bilibili/followers
router.get('/bilibili/user/followings/:uid', require('./routes/bilibili/followings'));
router.get('/bilibili/partion/:tid', require('./routes/bilibili/partion'));
router.get('/bilibili/bangumi/:seasonid', require('./routes/bilibili/bangumi'));
router.get('/bilibili/video/reply/:avid', require('./routes/bilibili/videoReply'));
router.get('/bilibili/video/reply/:aid', require('./routes/bilibili/reply'));
// // 微博
router.get('/weibo/user/:uid', require('./routes/weibo/user'));
@ -61,7 +61,8 @@ router.get('/mzitu/post/:id', require('./routes/mzitu/post'));
router.get('/mzitu/tag/:tag', require('./routes/mzitu/tag'));
// // Pixiv
router.get('/pixiv/user/:id', require('./routes/pixiv/user'));
router.get('/pixiv/user/bookmarks/:id', require('./routes/pixiv/bookmarks'));
router.get('/pixiv/user/:id/', require('./routes/pixiv/user'));
router.get('/pixiv/ranking/:mode/:date?', require('./routes/pixiv/ranking'));
// 豆瓣
@ -86,4 +87,11 @@ router.get('/tucaoqq/post/:project/:key', require('./routes/tucaoqq/post'));
// 笔趣阁
router.get('/biquge/novel/latestchapter/:id', require('./routes/biquge/chapter'));
// 开发者头条
router.get('/toutiao/today', require('./routes/toutiao/today'));
router.get('/toutiao/user/:id', require('./routes/toutiao/user'));
// Disqus
router.get('/disqus/posts/:forum', require('./routes/disqus/posts'));
module.exports = router;

View File

@ -1,6 +1,5 @@
const axios = require('axios');
const art = require('art-template');
const path = require('path');
const template = require('../../utils/template');
const config = require('../../config');
module.exports = async (ctx) => {
@ -17,11 +16,10 @@ module.exports = async (ctx) => {
const data = JSON.parse(response.data.match(/^seasonListCallback\((.*)\);$/)[1]).result || {};
ctx.body = art(path.resolve(__dirname, '../../views/rss.art'), {
ctx.body = template({
title: data.title,
link: `https://bangumi.bilibili.com/anime/${seasonid}/`,
description: data.evaluate,
lastBuildDate: new Date().toUTCString(),
item: data.episodes && data.episodes.map((item) => ({
title: `${item.index}${item.index_title}`,
description: `更新时间:${item.update_time}<img referrerpolicy="no-referrer" src="${item.cover}">`,

View File

@ -1,7 +1,6 @@
const axios = require('axios');
const qs = require('querystring');
const art = require('art-template');
const path = require('path');
const template = require('../../utils/template');
const config = require('../../config');
module.exports = async (ctx) => {
@ -31,11 +30,10 @@ module.exports = async (ctx) => {
});
const data = response.data;
ctx.body = art(path.resolve(__dirname, '../../views/rss.art'), {
ctx.body = template({
title: `${name} 的 bilibili 投币视频`,
link: `https://space.bilibili.com/${uid}`,
description: `${name} 的 bilibili 投币视频`,
lastBuildDate: new Date().toUTCString(),
item: data.data && data.data.list && data.data.list.map((item) => ({
title: item.title,
description: `${item.title}<br><img referrerpolicy="no-referrer" src="${item.pic}">`,

View File

@ -1,6 +1,5 @@
const axios = require('axios');
const art = require('art-template');
const path = require('path');
const template = require('../../utils/template');
const JSONbig = require('json-bigint');
const config = require('../../config');
@ -17,11 +16,10 @@ module.exports = async (ctx) => {
});
const data = response.data.data.cards;
ctx.body = art(path.resolve(__dirname, '../../views/rss.art'), {
ctx.body = template({
title: `${data[0].desc.user_profile.info.uname} 的 bilibili 动态`,
link: `https://space.bilibili.com/${uid}/#/dynamic`,
description: `${data[0].desc.user_profile.info.uname} 的 bilibili 动态`,
lastBuildDate: new Date().toUTCString(),
item: data.map((item) => {
const parsed = JSONbig.parse(item.card);
const data = parsed.item || parsed;

View File

@ -1,7 +1,6 @@
const axios = require('axios');
const qs = require('querystring');
const art = require('art-template');
const path = require('path');
const template = require('../../utils/template');
const config = require('../../config');
module.exports = async (ctx) => {
@ -31,11 +30,11 @@ module.exports = async (ctx) => {
});
const data = response.data;
ctx.body = art(path.resolve(__dirname, '../../views/rss.art'), {
ctx.body = template({
title: `${name} 的 bilibili 收藏夹`,
link: `https://space.bilibili.com/${uid}/#/favlist`,
description: `${name} 的 bilibili 收藏夹`,
lastBuildDate: new Date().toUTCString(),
item: data.data && data.data.archives && data.data.archives.map((item) => ({
title: item.title,
description: `${item.desc}<br><img referrerpolicy="no-referrer" src="${item.pic}">`,

View File

@ -1,7 +1,6 @@
const axios = require('axios');
const qs = require('querystring');
const art = require('art-template');
const path = require('path');
const template = require('../../utils/template');
const config = require('../../config');
module.exports = async (ctx) => {
@ -41,11 +40,10 @@ module.exports = async (ctx) => {
});
const data = response.data.data.list;
ctx.body = art(path.resolve(__dirname, '../../views/rss.art'), {
ctx.body = template({
title: `${name} 的 bilibili 粉丝`,
link: `https://space.bilibili.com/${uid}/#/fans/fans`,
description: `${name} 的 bilibili 粉丝`,
lastBuildDate: new Date().toUTCString(),
item: data.map((item) => ({
title: `${name} 新粉丝 ${item.uname}`,
description: `${item.uname}<br>${item.sign}<br>总计${count}`,

View File

@ -1,7 +1,6 @@
const axios = require('axios');
const qs = require('querystring');
const art = require('art-template');
const path = require('path');
const template = require('../../utils/template');
const config = require('../../config');
module.exports = async (ctx) => {
@ -41,11 +40,10 @@ module.exports = async (ctx) => {
});
const data = response.data.data.list;
ctx.body = art(path.resolve(__dirname, '../../views/rss.art'), {
ctx.body = template({
title: `${name} 的 bilibili 关注`,
link: `https://space.bilibili.com/${uid}/#/fans/follow`,
description: `${name} 的 bilibili 关注`,
lastBuildDate: new Date().toUTCString(),
item: data.map((item) => ({
title: `${name} 新关注 ${item.uname}`,
description: `${item.uname}<br>${item.sign}<br>总计${count}`,

View File

@ -1,6 +1,5 @@
const axios = require('axios');
const art = require('art-template');
const path = require('path');
const template = require('../../utils/template');
const config = require('../../config');
module.exports = async (ctx) => {
@ -21,11 +20,10 @@ module.exports = async (ctx) => {
name = list[0].tname;
}
ctx.body = art(path.resolve(__dirname, '../../views/rss.art'), {
ctx.body = template({
title: `bilibili ${name}分区`,
link: 'https://www.bilibili.com',
description: `bilibili ${name}分区`,
lastBuildDate: new Date().toUTCString(),
item: list && list.map((item) => ({
title: `${item.title} - ${item.owner.name}`,
description: `${item.desc}<img referrerpolicy="no-referrer" src="${item.pic}">`,

View File

@ -1,16 +1,15 @@
const axios = require('axios');
const art = require('art-template');
const path = require('path');
const template = require('../../utils/template');
const config = require('../../config');
const cheerio = require('cheerio');
const iconv = require('iconv-lite');
module.exports = async (ctx) => {
const avid = ctx.params.avid;
const aid = ctx.params.aid;
const nameResponse = await axios({
method: 'get',
url: `https://www.bilibili.com/video/av${avid}`,
url: `https://www.bilibili.com/video/av${aid}`,
headers: {
'User-Agent': config.ua,
},
@ -23,25 +22,24 @@ module.exports = async (ctx) => {
const response = await axios({
method: 'get',
url: `https://api.bilibili.com/x/v2/reply?type=1&oid=${avid}&sort=0`,
url: `https://api.bilibili.com/x/v2/reply?type=1&oid=${aid}&sort=0`,
headers: {
'User-Agent': config.ua,
'Referer': `https://www.bilibili.com/video/av${avid}`,
'Referer': `https://www.bilibili.com/video/av${aid}`,
}
});
const data = response.data.data.replies;
ctx.body = art(path.resolve(__dirname, '../../views/rss.art'), {
ctx.body = template({
title: `${name} 的 评论`,
link: `https://www.bilibili.com/video/av${avid}`,
description: `${name} 的 评论`,
lastBuildDate: new Date().toUTCString(),
link: `https://www.bilibili.com/video/av${aid}`,
description: `${name} 的评论`,
item: data.map((item) => ({
title: `${item.member.uname} : ${item.content.message}`,
description: `#${item.floor}<br> ${item.member.uname} : ${item.content.message}`,
pubDate: new Date(item.ctime * 1000).toUTCString(),
link: `https://www.bilibili.com/video/av${avid}/#reply${item.rpid}`
link: `https://www.bilibili.com/video/av${aid}/#reply${item.rpid}`
})),
});
};

View File

@ -1,7 +1,6 @@
const axios = require('axios');
const qs = require('querystring');
const art = require('art-template');
const path = require('path');
const template = require('../../utils/template');
const config = require('../../config');
module.exports = async (ctx) => {
@ -31,11 +30,10 @@ module.exports = async (ctx) => {
});
const data = response.data;
ctx.body = art(path.resolve(__dirname, '../../views/rss.art'), {
ctx.body = template({
title: `${name} 的 bilibili 空间`,
link: `https://space.bilibili.com/${uid}`,
description: `${name} 的 bilibili 空间`,
lastBuildDate: new Date().toUTCString(),
item: data.data && data.data.vlist && data.data.vlist.map((item) => ({
title: item.title,
description: `${item.description}<br><img referrerpolicy="no-referrer" src="${item.pic}">`,

View File

@ -1,6 +1,5 @@
const axios = require('axios');
const art = require('art-template');
const path = require('path');
const template = require('../../utils/template');
const cheerio = require('cheerio');
const config = require('../../config');
const iconv = require('iconv-lite');
@ -38,12 +37,11 @@ module.exports = async (ctx) => {
chapter_item.push(item);
}
// console.log('chapter_item',chapter_item)
ctx.body = art(path.resolve(__dirname, '../../views/rss.art'), {
ctx.body = template({
title: `笔趣阁 ${title}`,
link: `${baseUrl}${id}/`,
image: cover_url,
description: description,
lastBuildDate: new Date().toUTCString(),
item: chapter_item,
});
};

View File

@ -1,6 +1,5 @@
const axios = require('axios');
const art = require('art-template');
const path = require('path');
const template = require('../../utils/template');
const cheerio = require('cheerio');
const config = require('../../config');
const iconv = require('iconv-lite');
@ -47,11 +46,10 @@ module.exports = async (ctx) => {
result_item.push(item)
}
ctx.body = art(path.resolve(__dirname, '../../views/rss.art'), {
ctx.body = template({
title: `喷嚏图卦`,
link: `https://www.dapenti.com/blog/blog.asp?name=xilei&subjectid=70`,
description: `喷嚏图卦`,
lastBuildDate: new Date().toUTCString(),
item: result_item,
});
};

53
routes/disqus/posts.js Normal file
View File

@ -0,0 +1,53 @@
const axios = require('axios');
const template = require('../../utils/template');
const config = require('../../config');
module.exports = async (ctx) => {
const forum = ctx.params.forum;
const response = await axios({
method: 'get',
url: `https://disqus.com/api/3.0/forums/listPosts.json?api_key=${config.disqus.api_key}&forum=${forum}`,
headers: {
'User-Agent': config.ua,
'Referer': 'https://disqus.com/'
}
});
const data = response.data.response;
const threadsObj = {};
data.forEach((item) => {
threadsObj[item.thread] = 1;
});
let threadsQuery = '';
Object.keys(threadsObj).forEach((item) => {
threadsQuery += `&thread=${item}`;
});
const responseThreads = await axios({
method: 'get',
url: `https://disqus.com/api/3.0/forums/listThreads.json?api_key=${config.disqus.api_key}&forum=${forum}${threadsQuery}`,
headers: {
'User-Agent': config.ua,
'Referer': 'https://disqus.com/'
}
});
const threads = responseThreads.data.response;
ctx.body = template({
title: `${forum} 的评论`,
link: `https://disqus.com/home/forums/${forum}`,
description: `${forum} 的 disqus 评论`,
item: data.map((item) => {
const thread = threads.filter((i) => i.id === item.thread)[0];
return {
title: `${item.author.name}: ${item.raw_message > 24 ? item.raw_message.slice(0, 24) + '...' : item.raw_message}`,
description: `${item.author.name} 在《${thread.clean_title}》中发表评论: ${item.message}`,
pubDate: new Date(item.createdAt).toUTCString(),
link: `${thread.link}/#comment-${item.id}`
};
}),
});
};

View File

@ -1,6 +1,5 @@
const axios = require('axios');
const art = require('art-template');
const path = require('path');
const template = require('../../utils/template');
const cheerio = require('cheerio');
const config = require('../../config');
@ -27,11 +26,10 @@ module.exports = async (ctx) => {
const list = $('ul.i.issues>li');
ctx.body = art(path.resolve(__dirname, '../../views/rss.art'), {
ctx.body = template({
title: $('title').text(),
link: url,
description: $('meta[name="description"]').attr('content') || $('title').text(),
lastBuildDate: new Date().toUTCString(),
item: list && list.map((item,index) => {
item=$(index);
return {

View File

@ -1,6 +1,5 @@
const axios = require('axios');
const art = require('art-template');
const path = require('path');
const template = require('../../utils/template');
module.exports = async (ctx) => {
const response = await axios({
@ -9,10 +8,9 @@ module.exports = async (ctx) => {
});
const movieList = response.data.subjects;
ctx.body = art(path.resolve(__dirname, '../../views/rss.art'), {
ctx.body = template({
title: '即将上映的电影',
link: 'https://movie.douban.com/cinema/later/',
lastBuildDate: new Date().toUTCString(),
item: movieList.map((item) => ({
title: item.title,
description: `标题:${item.title}<br> 影片类型:${item.genres.join(' | ')} <br>评分:${item.rating.stars === '00' ? '无' : item.rating.average} <br/> <img referrerpolicy="no-referrer" src="${item.images.large}">`,

View File

@ -1,6 +1,5 @@
const axios = require('axios');
const art = require('art-template');
const path = require('path');
const template = require('../../utils/template');
module.exports = async (ctx) => {
const city = ctx.params.city;
@ -12,10 +11,9 @@ module.exports = async (ctx) => {
});
const movieList = score ? response.data.subjects.filter((item) => item.rating.average >= score) : response.data.subjects;
ctx.body = art(path.resolve(__dirname, '../../views/rss.art'), {
ctx.body = template({
title: `${city ? city : ''}正在上映的${score ? `超过 ${score} 分的` : ''}电影`,
link: 'https://movie.douban.com/cinema/nowplaying/',
lastBuildDate: new Date().toUTCString(),
item: movieList.map((item) => ({
title: item.title,
description: `标题:${item.title}<br> 影片类型:${item.genres.join(' | ')} <br>评分:${item.rating.average} <br/> <img referrerpolicy="no-referrer" src="${item.images.large}">`,

View File

@ -1,6 +1,5 @@
const axios = require('axios');
const art = require('art-template');
const path = require('path');
const template = require('../../utils/template');
module.exports = async (ctx) => {
const response = await axios({
@ -9,10 +8,9 @@ module.exports = async (ctx) => {
});
const movieList = response.data.subjects;
ctx.body = art(path.resolve(__dirname, '../../views/rss.art'), {
ctx.body = template({
title: '豆瓣电影北美票房榜',
link: 'https://movie.douban.com/chart',
lastBuildDate: new Date().toUTCString(),
item: movieList.map((item) => {
item = item.subject;
return {

View File

@ -1,6 +1,5 @@
const axios = require('axios');
const art = require('art-template');
const path = require('path');
const template = require('../../utils/template');
const config = require('../../config');
module.exports = async (ctx) => {
@ -18,11 +17,10 @@ module.exports = async (ctx) => {
const data = response.data.data;
ctx.body = art(path.resolve(__dirname, '../../views/rss.art'), {
ctx.body = template({
title: `快递 ${company}-${number}`,
link: 'https://www.kuaidi100.com',
description: `快递 ${company}-${number}`,
lastBuildDate: new Date().toUTCString(),
item: data.map((item) => ({
title: item.context,
description: item.context,

View File

@ -1,6 +1,5 @@
const axios = require('axios');
const art = require('art-template');
const path = require('path');
const template = require('../../utils/template');
const cheerio = require('cheerio');
const crypto = require('crypto');
const config = require('../../config');
@ -122,11 +121,10 @@ module.exports = async (ctx) => {
});
});
ctx.body = art(path.resolve(__dirname, '../../views/rss.art'), {
ctx.body = template({
title: '煎蛋无聊图',
link: 'http://jandan.net/pic',
description: '煎蛋官方无聊图,无限活力的热门图区。',
lastBuildDate: new Date().toUTCString(),
item: items
});
};

View File

@ -1,6 +1,5 @@
const axios = require('axios');
const art = require('art-template');
const path = require('path');
const template = require('../../utils/template');
const cheerio = require('cheerio');
const config = require('../../config');
@ -21,11 +20,10 @@ module.exports = async (ctx) => {
const $ = cheerio.load(data);
const list = $('.note-list li');
ctx.body = art(path.resolve(__dirname, '../../views/rss.art'), {
ctx.body = template({
title: $('title').text(),
link: `https://www.jianshu.com/c/${id}`,
description: $('meta[name="description"]').attr('content') || $('title').text(),
lastBuildDate: new Date().toUTCString(),
item: list && list.map((index, item) => {
item = $(item);
return {

View File

@ -1,6 +1,5 @@
const axios = require('axios');
const art = require('art-template');
const path = require('path');
const template = require('../../utils/template');
const cheerio = require('cheerio');
const config = require('../../config');
@ -19,11 +18,10 @@ module.exports = async (ctx) => {
const $ = cheerio.load(data);
const list = $('.note-list li');
ctx.body = art(path.resolve(__dirname, '../../views/rss.art'), {
ctx.body = template({
title: '简书首页',
link: 'https://www.jianshu.com',
description: $('meta[name="description"]').attr('content'),
lastBuildDate: new Date().toUTCString(),
item: list && list.map((index, item) => {
item = $(item);
return {

View File

@ -1,6 +1,5 @@
const axios = require('axios');
const art = require('art-template');
const path = require('path');
const template = require('../../utils/template');
const cheerio = require('cheerio');
const config = require('../../config');
@ -19,11 +18,10 @@ module.exports = async (ctx) => {
const $ = cheerio.load(data);
const list = $('.note-list li');
ctx.body = art(path.resolve(__dirname, '../../views/rss.art'), {
ctx.body = template({
title: '简书 30 日热门',
link: 'https://www.jianshu.com/trending/monthly',
description: '简书 30 日热门',
lastBuildDate: new Date().toUTCString(),
item: list && list.map((index, item) => {
item = $(item);
return {

View File

@ -1,6 +1,5 @@
const axios = require('axios');
const art = require('art-template');
const path = require('path');
const template = require('../../utils/template');
const cheerio = require('cheerio');
const config = require('../../config');
@ -21,11 +20,10 @@ module.exports = async (ctx) => {
const $ = cheerio.load(data);
const list = $('.note-list li');
ctx.body = art(path.resolve(__dirname, '../../views/rss.art'), {
ctx.body = template({
title: $('title').text(),
link: `https://www.jianshu.com/u/${id}`,
description: $('meta[name="description"]').attr('content') || $('title').text(),
lastBuildDate: new Date().toUTCString(),
item: list && list.map((index, item) => {
item = $(item);
return {

View File

@ -1,6 +1,5 @@
const axios = require('axios');
const art = require('art-template');
const path = require('path');
const template = require('../../utils/template');
const cheerio = require('cheerio');
const config = require('../../config');
@ -19,11 +18,10 @@ module.exports = async (ctx) => {
const $ = cheerio.load(data);
const list = $('.note-list li');
ctx.body = art(path.resolve(__dirname, '../../views/rss.art'), {
ctx.body = template({
title: '简书 7 日热门',
link: 'https://www.jianshu.com/trending/weekly',
description: '简书 7 日热门',
lastBuildDate: new Date().toUTCString(),
item: list && list.map((index, item) => {
item = $(item);
return {

View File

@ -1,6 +1,5 @@
const axios = require('axios');
const art = require('art-template');
const path = require('path');
const template = require('../../utils/template');
const config = require('../../config');
module.exports = async (ctx) => {
@ -33,11 +32,10 @@ module.exports = async (ctx) => {
const data = response.data;
ctx.body = art(path.resolve(__dirname, '../../views/rss.art'), {
ctx.body = template({
title: `掘金${cat.name}`,
link: `https://juejin.im/welcome/${category}`,
description: `掘金${cat.name}`,
lastBuildDate: new Date().toUTCString(),
item: data.d && data.d.entrylist && data.d.entrylist.map((item) => ({
title: item.title,
description: `${(item.content || item.summaryInfo || '无描述').replace(/[\x00-\x08\x0b-\x0c\x0e-\x1f\x7f]/g, '')}`,

View File

@ -1,6 +1,5 @@
const axios = require('axios');
const art = require('art-template');
const path = require('path');
const template = require('../../utils/template');
const cheerio = require('cheerio');
const config = require('../../config');
@ -24,11 +23,10 @@ module.exports = async (ctx) => {
const $ = cheerio.load(data);
const list = $('#pins li');
ctx.body = art(path.resolve(__dirname, '../../views/rss.art'), {
ctx.body = template({
title: $('title').text(),
link: url,
description: $('meta[name="description"]').attr('content') || $('title').text(),
lastBuildDate: new Date().toUTCString(),
item: list && list.map((item, index) => {
item = $(index);
const linkA = item.find('a');

View File

@ -1,6 +1,5 @@
const axios = require('axios');
const art = require('art-template');
const path = require('path');
const template = require('../../utils/template');
const cheerio = require('cheerio');
const config = require('../../config');
@ -50,11 +49,10 @@ module.exports = async (ctx) => {
const reg = /[1-9]\d{3}-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1])\s+(20|21|22|23|[0-1]\d):[0-5]\d:[0-5]\d/;
ctx.body = art(path.resolve(__dirname, '../../views/rss.art'), {
ctx.body = template({
title: title,
link: url,
description: $('meta[name="description"]').attr('content') || title,
lastBuildDate: new Date().toUTCString(),
item: list && list.map((item) => {
let date = new Date();
const dateStr = $('.main-meta > span:nth-child(2)').text();

View File

@ -1,6 +1,5 @@
const axios = require('axios');
const art = require('art-template');
const path = require('path');
const template = require('../../utils/template');
const cheerio = require('cheerio');
const config = require('../../config');
@ -23,11 +22,10 @@ module.exports = async (ctx) => {
const $ = cheerio.load(data);
const list = $('#pins li');
ctx.body = art(path.resolve(__dirname, '../../views/rss.art'), {
ctx.body = template({
title: $('title').text(),
link: url,
description: $('meta[name="description"]').attr('content') || $('title').text(),
lastBuildDate: new Date().toUTCString(),
item: list && list.map((item, index) => {
item = $(index);
const linkA = item.find('a');

View File

@ -1,6 +1,5 @@
const axios = require('axios');
const art = require('art-template');
const path = require('path');
const template = require('../../utils/template');
const cheerio = require('cheerio');
const config = require('../../config');
@ -21,11 +20,10 @@ module.exports = async (ctx) => {
const $ = cheerio.load(data);
const list = $('.main-content > div.postlist > dl > dd');
ctx.body = art(path.resolve(__dirname, '../../views/rss.art'), {
ctx.body = template({
title: $('title').text(),
link: url,
description: $('meta[name="description"]').attr('content') || $('title').text(),
lastBuildDate: new Date().toUTCString(),
item: list && list.map((item, index) => {
item = $(index);
const linkA = item.find('a');

View File

@ -1,6 +1,5 @@
const axios = require('axios');
const art = require('art-template');
const path = require('path');
const template = require('../../utils/template');
const config = require('../../config');
module.exports = async (ctx) => {
@ -17,11 +16,10 @@ module.exports = async (ctx) => {
const data = response.data;
ctx.body = art(path.resolve(__dirname, '../../views/rss.art'), {
ctx.body = template({
title: data.artist.name,
link: `https://music.163.com/#/artist/album?id=${id}`,
description: `网易云音乐歌手专辑 - ${data.artist.name}`,
lastBuildDate: new Date().toUTCString(),
item: data.hotAlbums.map((item) => {
const singer = item.artists.length === 1 ? item.artists[0].name : item.artists.reduce((prev, cur) => (prev.name || prev) + '/' + cur.name);
return {

View File

@ -1,7 +1,6 @@
const axios = require('axios');
const qs = require('querystring');
const art = require('art-template');
const path = require('path');
const template = require('../../utils/template');
const config = require('../../config');
module.exports = async (ctx) => {
@ -22,11 +21,10 @@ module.exports = async (ctx) => {
const data = response.data.playlist;
ctx.body = art(path.resolve(__dirname, '../../views/rss.art'), {
ctx.body = template({
title: data.name,
link: `https://music.163.com/#/playlist?id=${id}`,
description: `网易云音乐歌单 - ${data.name}`,
lastBuildDate: new Date().toUTCString(),
item: data.tracks && data.tracks.map((item) => {
const singer = item.ar.length === 1 ? item.ar[0].name : item.ar.reduce((prev, cur) => (prev.name || prev) + '/' + cur.name);
return {

View File

@ -1,7 +1,6 @@
const axios = require('axios');
const qs = require('querystring');
const art = require('art-template');
const path = require('path');
const template = require('../../utils/template');
const config = require('../../config');
module.exports = async (ctx) => {
@ -28,11 +27,10 @@ module.exports = async (ctx) => {
const { nickname, signature } = creator;
ctx.body = art(path.resolve(__dirname, '../../views/rss.art'), {
ctx.body = template({
title: `${nickname} 的所有歌单`,
link: `http://music.163.com/user/home?id=${uid}`,
description: signature,
lastBuildDate: new Date().toUTCString(),
item: playlist.map((pl) => ({
title: pl.name,
description: pl.description,

View File

@ -0,0 +1,25 @@
const axios = require('axios');
const maskHeader = require('../constants').maskHeader;
/**
* 获取用户的收藏
*
* @param {string} user_id 目标用户id
* @param {string} token pixiv oauth token
* @returns {Promise<axios.AxiosResponse<{illusts: illust[]}>>}
*/
module.exports = async function getBookmarks(user_id, token) {
return await axios({
method: 'get',
url: 'https://app-api.pixiv.net/v1/user/bookmarks/illust',
headers: {
...maskHeader,
'Authorization': 'Bearer ' + token
},
params: {
user_id: user_id,
restrict: 'public'
},
});
}

View File

@ -0,0 +1,24 @@
const axios = require('axios');
const maskHeader = require('../constants').maskHeader;
/**
* 获取用户插画作品
* @param {string} user_id 目标用户id
* @param {string} token pixiv oauth token
* @returns {Promise<axios.AxiosResponse<{illusts: illust[]}>>}
*/
module.exports = async function getIllusts(user_id, token) {
return await axios({
method: 'get',
url: 'https://app-api.pixiv.net/v1/user/illusts',
headers: {
...maskHeader,
'Authorization': 'Bearer ' + token
},
params: {
user_id: user_id,
filter: 'for_ios',
type: 'illust'
},
})
}

View File

@ -0,0 +1,33 @@
const axios = require('axios');
const maskHeader = require('../constants').maskHeader;
const assert = require('assert');
const allowMode = [
'day', 'week', 'month', 'day_male', 'day_female', 'week_original', 'week_rookie', 'day_r18', 'day_male_r18', 'day_female_r18', 'week_r18', 'week_r18g'
];
/**
* 获取某天的排行榜
* @param {string} mode 模式
* @param {Date} date 日期
* @param {string} token pixiv oauth token
* @returns {Promise<axios.AxiosResponse<{illusts: illust[]}>>}
*/
module.exports = async function getRanking(mode, date, token) {
assert(allowMode.includes(mode), 'Mode not allow.');
return await axios({
method: 'get',
url: 'https://app-api.pixiv.net/v1/illust/ranking',
headers: {
...maskHeader,
'Authorization': 'Bearer ' + token
},
params: {
mode: mode,
filter: 'for_ios',
...(date && {
date: `${date.getFullYear()}-${date.getMonth() + 1}-${date.getDate()}`
})
},
});
}

View File

@ -0,0 +1,29 @@
const axios = require('axios');
const maskHeader = require('../constants').maskHeader;
/**
* pixiv 用户
* @typedef {{user: {id: number, name: string, account: string, profile_image_urls: any, comment: string}, profile: any} userDetail
*/
/**
* 获取用户信息
*
* @param {string} user_id 目标用户id
* @param {string} token pixiv oauth token
* @returns {Promise<axios.AxiosResponse<userDetail>>}
*/
module.exports = async function getUserDetail(user_id, token) {
return await axios({
method: 'get',
url: 'https://app-api.pixiv.net/v1/user/detail',
headers: {
...maskHeader,
'Authorization': 'Bearer ' + token
},
params: {
user_id: user_id
},
});
}

51
routes/pixiv/bookmarks.js Normal file
View File

@ -0,0 +1,51 @@
const config = require('../../config');
const pixivConfig = config.pixiv;
if (!pixivConfig) {
module.exports = () => {};
return;
}
const template = require('../../utils/template');
const getToken = require('./token');
const getBookmarks = require('./api/getBookmarks');
const getUserDetail = require('./api/getUserDetail');
module.exports = async (ctx) => {
const id = ctx.params.id;
if (typeof getToken() === 'null') {
ctx.throw(500);
return;
}
const [bookmarksResponse, userDetailResponse] = await Promise.all([
getBookmarks(id, getToken()),
getUserDetail(id, getToken())
]);
const illusts = bookmarksResponse.data.illusts;
const username = userDetailResponse.data.user.name
ctx.body = template({
title: `${username} 的收藏`,
link: `https://www.pixiv.net/bookmark.php?id=${id}`,
description: `${username} 的 pixiv 最新收藏`,
item: illusts.map((illust, index) => {
const images = [];
if (illust.page_count === 1) {
images.push(`<p><img referrerpolicy="no-referrer" src="https://pixiv.cat/${illust.id}.jpg"/></p>`);
} else {
for (let i = 0; i < illust.page_count; i++) {
images.push(`<p><img referrerpolicy="no-referrer" src="https://pixiv.cat/${illust.id}-${i+1}.jpg"/></p>`);
}
}
return {
title: `${illust.title}`,
description: `<p>画师:${illust.user.name} - 上传于:${new Date(illust.create_date).toLocaleString('zh-cn')} - 阅览数:${illust.total_view} - 收藏数:${illust.total_bookmarks}</p>${images.join('')}`,
link: `https://www.pixiv.net/member_illust.php?mode=medium&illust_id=${illust.id}`
};
})
});
};

View File

@ -8,18 +8,9 @@ if (!pixivConfig) {
return;
}
const axios = require('axios');
const art = require('art-template');
const path = require('path');
const FormData = require('form-data');
const template = require('../../utils/template');
const getToken = require('./token');
const maskHeader = require('./constants').maskHeader;
const assert = require('assert');
const util = require('util');
const allowMode = [
'day', 'week', 'month', 'day_male', 'day_female', 'week_original', 'week_rookie', 'day_r18', 'day_male_r18', 'day_female_r18', 'week_r18', 'week_r18g'
];
const getRanking = require('./api/getRanking');
const titles = {
'day': 'pixiv 日排行',
@ -55,38 +46,21 @@ module.exports = async (ctx) => {
const mode = ctx.params.mode;
const date = ctx.params.date ? new Date(ctx.params.date) : new Date();
assert(allowMode.includes(mode), 'Mode not allow.');
if (typeof getToken() === 'null') {
ctx.throw(500);
return;
}
const response = await axios({
method: 'get',
url: 'https://app-api.pixiv.net/v1/illust/ranking',
headers: {
...maskHeader,
'Authorization': 'Bearer ' + getToken()
},
params: {
mode: mode,
filter: 'for_ios',
...(ctx.params.date && {
date: `${date.getFullYear()}-${date.getMonth() + 1}-${date.getDate()}`
})
},
});
const response = await getRanking(mode, ctx.params.date && date, getToken());
const illusts = response.data.illusts;
const dateStr = `${date.getFullYear()}${date.getMonth() + 1}${date.getDate()}`;
ctx.body = art(path.resolve(__dirname, '../../views/rss.art'), {
ctx.body = template({
title: (ctx.params.date ? dateStr : '') + titles[mode],
link: links[mode],
description: dateStr + titles[mode],
lastBuildDate: new Date().toUTCString(),
item: illusts.map((illust, index) => {
const images = [];
if (illust.page_count === 1) {

View File

@ -8,12 +8,9 @@ if (!pixivConfig) {
return;
}
const axios = require('axios');
const art = require('art-template');
const path = require('path');
const FormData = require('form-data');
const template = require('../../utils/template');
const getToken = require('./token');
const maskHeader = require('./constants').maskHeader;
const getIllusts = require('./api/getIllusts');
module.exports = async (ctx) => {
const id = ctx.params.id;
@ -23,28 +20,15 @@ module.exports = async (ctx) => {
return;
}
const response = await axios({
method: 'get',
url: 'https://app-api.pixiv.net/v1/user/illusts',
headers: {
...maskHeader,
'Authorization': 'Bearer ' + getToken()
},
params: {
user_id: id,
filter: 'for_ios',
type: 'illust'
},
});
const response = await getIllusts(id, getToken());
const illusts = response.data.illusts;
const username = illusts[0].user.name
ctx.body = art(path.resolve(__dirname, '../../views/rss.art'), {
ctx.body = template({
title: `${username} 的 pixiv 动态`,
link: `https://www.pixiv.net/member.php?id=${id}`,
description: `${username} 的 pixiv 最新动态`,
lastBuildDate: new Date().toUTCString(),
item: illusts.map((illust) => {
const images = [];
if (illust.page_count === 1) {

View File

@ -1,6 +1,5 @@
const axios = require('axios');
const art = require('art-template');
const path = require('path');
const template = require('../../utils/template');
const cheerio = require('cheerio');
const config = require('../../config');
@ -55,10 +54,9 @@ module.exports = async (ctx) => {
const $ = cheerio.load(threadListHTML);
const list = $('#thread_list > .j_thread_list[data-field]');
ctx.body = art(path.resolve(__dirname, '../../views/rss.art'), {
ctx.body = template({
title: `${kw}`,
link: `https://tieba.baidu.com/f?kw=${encodeURIComponent(kw)}`,
lastBuildDate: new Date().toUTCString(),
item:
list &&
list.

35
routes/toutiao/today.js Normal file
View File

@ -0,0 +1,35 @@
const axios = require('axios');
const template = require('../../utils/template');
const cheerio = require('cheerio');
const config = require('../../config');
const baseUrl = 'https://toutiao.io'
module.exports = async (ctx)=>{
const response = await axios({
method:'get',
url:baseUrl,
headers: {
'User-Agent': config.ua,
'Host':'toutiao.io'
},
responseType: 'text'
});
const $ = cheerio.load(response.data);
const title = $('#daily').find('.date>span').eq(0).text() + ' ' + $('#daily').find('.date>small').eq(0).text();
const list = $('.posts>.post', '#daily');
const article_item = [];
for(let i=0;i<list.length;i++){
const article_el = $(list[i]).find('.content').eq(0);
const item = {
title: article_el.find('a').eq(0).text(),
link: baseUrl + article_el.find('a').eq(0).attr('href')
};
article_item.push(item);
};
ctx.body = template({
title: '开发者头条:' + title,
link: baseUrl,
item: article_item,
});
};

42
routes/toutiao/user.js Normal file
View File

@ -0,0 +1,42 @@
const axios = require('axios');
const template = require('../../utils/template');
const cheerio = require('cheerio');
const config = require('../../config');
const baseUrl = 'https://toutiao.io';
module.exports = async (ctx)=>{
const id = ctx.params.id;
let requestUrl = `${baseUrl}/subjects/${id}?f=new`;
const response = await axios({
method:'get',
url:requestUrl,
headers: {
'User-Agent': config.ua,
'Host':'toutiao.io'
},
responseType: 'text'
});
const $ = cheerio.load(response.data);
const image = $('#main').find('.text-center>.subject-cover>img').eq(0).attr('src');
const link = requestUrl;
const title = $('#main').find('.text-center>h3').eq(0).text();
const description = $('#main').find('.social-share-button').eq(0).attr('data-title');
const list = $('.posts>.post', '#main');
const article_item = [];
for(let i=0;i<list.length;i++){
const article_el = $(list[i]).find('.content').eq(0);
const item = {
title: article_el.find('a').eq(0).text(),
link: baseUrl + article_el.find('a').eq(0).attr('href')
};
article_item.push(item);
};
ctx.body = template({
title: '开发者头条独家号:'+title,
description:description,
image: image,
link: baseUrl,
item: article_item,
});
};

View File

@ -1,8 +1,8 @@
const axios = require('axios');
const art = require('art-template');
const path = require('path');
const template = require('../../utils/template');
const config = require('../../config');
const md5 = require('js-md5');
const md5 = require('../../utils/md5');
module.exports = async (ctx) => {
const projectID = ctx.params.project;
@ -19,11 +19,10 @@ module.exports = async (ctx) => {
});
const data = response.data.data;
ctx.body = art(path.resolve(__dirname, '../../views/rss.art'), {
ctx.body = template({
title: `${projectID} 的 吐个槽新帖`,
link: `https://support.qq.com/product/${projectID}`,
description: `${projectID} 的 吐个槽新帖`,
lastBuildDate: new Date().toUTCString(),
item: data.map((item) => {
let pubdate = new Date(item.created_at.replace(' ', 'T') + "+08:00");
let imgHTML = '';

View File

@ -1,6 +1,5 @@
const axios = require('axios');
const art = require('art-template');
const path = require('path');
const template = require('../../utils/template');
const config = require('../../config');
// 格式化每条微博的HTML
@ -42,7 +41,6 @@ function format (status) {
// 格式化时间
function getTime (html) {
console.log(html);
let math;
let date = new Date();
if (/(\d+)分钟前/.exec(html)) {
@ -63,7 +61,15 @@ function getTime (html) {
return date.toUTCString();
} else if (/(\d+)月(\d+)日 (\d+):(\d+)/.exec(html)) {
math = /(\d+)月(\d+)日 (\d+):(\d+)/.exec(html);
date = new Date(date.getFullYear(), math[1] - 1, parseInt(math[2]), math[3], math[4]);
date = new Date(date.getFullYear(), parseInt(math[1]) - 1, math[2], math[3], math[4]);
return date.toUTCString();
} else if (/(\d+)-(\d+)-(\d+)/.exec(html)) {
math = /(\d+)-(\d+)-(\d+)/.exec(html);
date = new Date(math[1], parseInt(math[2]) - 1, math[3]);
return date.toUTCString();
} else if (/(\d+)-(\d+)/.exec(html)) {
math = /(\d+)-(\d+)/.exec(html);
date = new Date(date.getFullYear(), parseInt(math[1]) - 1, math[2]);
return date.toUTCString();
}
return html;
@ -92,11 +98,10 @@ module.exports = async (ctx) => {
}
});
ctx.body = art(path.resolve(__dirname, '../../views/rss.art'), {
ctx.body = template({
title: `${name}的微博`,
link: `http://weibo.com/${uid}/`,
description: `${name}的微博`,
lastBuildDate: new Date().toUTCString(),
item: response.data.data.cards.filter((item) => item.mblog && !item.mblog.isTop).map((item) => {
const title = item.mblog.text.replace(/<.*?>/g, '');
return {

View File

@ -1,6 +1,5 @@
const axios = require('axios');
const art = require('art-template');
const path = require('path');
const template = require('../../utils/template');
const cheerio = require('cheerio');
const config = require('../../config');
@ -24,11 +23,10 @@ module.exports = async (ctx) => {
const name = data.users[id].name;
const list = Object.values(data.activities).sort((a, b) => b.createdTime - a.createdTime);
ctx.body = art(path.resolve(__dirname, '../../views/rss.art'), {
ctx.body = template({
title: `${name}的知乎动态`,
link: `https://www.zhihu.com/people/${id}/activities`,
description: data.users[id].headline || data.users[id].description,
lastBuildDate: new Date().toUTCString(),
item: list && list.map((item) => {
const type = item.target.schema;
const detail = data[`${type}s`][item.target.id];
@ -49,7 +47,19 @@ module.exports = async (ctx) => {
break;
case 'pin':
title = detail.excerptTitle.length > 17 ? detail.excerptTitle.slice(0, 17) + '...' : detail.excerptTitle;
description = detail.excerptTitle;
const images = [];
let text = "";
let link = "";
detail.content.forEach(contentItem => {
if (contentItem.type === "text") {
text = `<p>${contentItem.ownText}</p>`;
} else if (contentItem.type === "image") {
images.push(`<p><img referrerpolicy="no-referrer" src="${contentItem.url.replace('xl', 'r')}"/></p>`);
} else if (contentItem.type === "link") {
link = `<p><a href="${contentItem.url}" target="_blank">${contentItem.title}</a></p>`
}
})
description = `${text}${link}${images.join('')}`;
url = `https://www.zhihu.com/pin/${detail.id}`;
break;
case 'question':
@ -57,6 +67,11 @@ module.exports = async (ctx) => {
description = detail.excerpt;
url = `https://www.zhihu.com/question/${detail.id}`;
break;
case 'column':
title = detail.title;
description = `<p>${detail.intro}</p><p><img referrerpolicy="no-referrer" src="${detail.imageUrl}"/></p>`;
url = `${detail.url}`;
break;
}
return {
@ -67,4 +82,4 @@ module.exports = async (ctx) => {
};
}),
});
};
};

View File

@ -1,6 +1,5 @@
const axios = require('axios');
const art = require('art-template');
const path = require('path');
const template = require('../../utils/template');
const cheerio = require('cheerio');
const config = require('../../config');
@ -20,14 +19,13 @@ module.exports = async (ctx) => {
const $ = cheerio.load(data);
const list = $('div.zm-item');
ctx.body = art(path.resolve(__dirname, '../../views/rss.art'), {
ctx.body = template({
title: $('title').text(),
link: `https://www.zhihu.com/collection/${id}`,
description: `${$('#zh-fav-head-description').text()}`,
lastBuildDate: new Date().toUTCString(),
item: list && list.map((index, item) => {
item = $(item);
let linkUrl = item.find('.zm-item-title a').attr('href');
let linkUrl = item.find('link').attr('href');
if (linkUrl.startsWith('/')) linkUrl = 'https://www.zhihu.com' + linkUrl;
return {
title: item.find('.zm-item-title a').text(),

View File

@ -1,6 +1,5 @@
const axios = require('axios');
const art = require('art-template');
const path = require('path');
const template = require('../../utils/template');
const config = require('../../config');
module.exports = async (ctx) => {
@ -26,11 +25,10 @@ module.exports = async (ctx) => {
const list = listRes.data;
const info = infoRes.data;
ctx.body = art(path.resolve(__dirname, '../../views/rss.art'), {
ctx.body = template({
title: `知乎专栏-${info.name}`,
link: `https://zhuanlan.zhihu.com/${id}`,
description: info.description,
lastBuildDate: new Date().toUTCString(),
item: list.map((item) => ({
title: item.title,
description: item.content.replace(/<img src="/g, '<img referrerpolicy="no-referrer" src="https://pic4.zhimg.com/'),

View File

@ -1,7 +1,6 @@
const axios = require('axios');
const qs = require('querystring');
const art = require('art-template');
const path = require('path');
const template = require('../../utils/template');
const config = require('../../config');
module.exports = async (ctx) => {
@ -31,11 +30,10 @@ module.exports = async (ctx) => {
//判断数据的类型,如果有数据就是数组类型的,没有数据的话,就赋值为空数组
data = (data instanceof Array) ? data : [{title:"我们找不到任何与您的搜索条件匹配的结果,但是调整您的搜索条件可能会有所帮助",room_name:"",list_img:"",city:"",id:""}];
ctx.body = art(path.resolve(__dirname, '../../views/rss.art'), {
ctx.body = template({
title: `自如的${keyword}${iswhole ? '整租' : '合租'}${room}室房源`,
link: `http://${domain}`,
description: `自如的${keyword}${iswhole ? '整租' : '合租'}${room}室房源`,
lastBuildDate: new Date().toUTCString(),
item: data.map((item) => ({
title: item.title,
description: `${item.room_name}<img referrerpolicy="no-referrer" src="${item.list_img}">`,

5
utils/md5.js Normal file
View File

@ -0,0 +1,5 @@
const crypto = require('crypto');
module.exports = function md5(date) {
return crypto.createHash('md5').update(date).digest("hex");
}

11
utils/template.js Normal file
View File

@ -0,0 +1,11 @@
const art = require('art-template');
const path = require('path');
const config = require('../config');
module.exports = function (options) {
return art(path.resolve(__dirname, '../views/rss.art'), {
lastBuildDate: new Date().toUTCString(),
ttl: config.cacheExpire,
...options,
});
};

View File

@ -2,7 +2,7 @@
<rss version="2.0">
<channel>
<title><![CDATA[{{ title || 'RSSHub' }}]]></title>
<link>{{ link }}</link>
<link>{{ link || 'https://github.com/DIYgod/RSSHub' }}</link>
<description><![CDATA[{{ description || title }} - 使用 RSSHub(https://github.com/DIYgod/RSSHub) 构建]]></description>
<generator>RSSHub</generator>
<webMaster>i@html.love</webMaster>
@ -15,7 +15,7 @@
</image>
{{ /if }}
<lastBuildDate>{{ lastBuildDate }}</lastBuildDate>
<ttl>300</ttl>
<ttl>{{ ttl }}</ttl>
{{ each item }}
<item>
<title><![CDATA[{{ $value.title }}]]></title>