replace express and request with koa and axios

This commit is contained in:
DIYgod
2018-04-16 02:47:09 +08:00
parent 2b52117f98
commit 3f940a6906
32 changed files with 1001 additions and 1495 deletions
+1 -1
View File
@@ -1,7 +1,7 @@
{
"extends": "eslint:recommended",
"parserOptions": {
"ecmaVersion": 6,
"ecmaVersion": 2017,
"sourceType": "module"
},
"env": {
+5
View File
@@ -0,0 +1,5 @@
module.exports = {
port: 1200,
cacheExpire: 5 * 60,
ua: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36',
};
+28 -36
View File
@@ -1,45 +1,37 @@
const express = require('express');
const Koa = require('koa');
const cache = require('koa-redis-cache');
const logger = require('./utils/logger');
const config = require('./config');
const onerror = require('./middleware/onerror');
const header = require('./middleware/header.js');
const router = require('./router');
process.on('uncaughtException', (e) => {
logger.error('uncaughtException: ' + e);
});
logger.info('🍻 RSSHub start! Cheers!');
const app = express();
const app = new Koa();
app.all('*', require('./routes/all'));
// global error handing
app.use(onerror);
// bilibili
app.get('/bilibili/user/video/:uid', require('./routes/bilibili/video'));
app.get('/bilibili/user/fav/:uid', require('./routes/bilibili/fav'));
app.get('/bilibili/user/coin/:uid', require('./routes/bilibili/coin'));
app.get('/bilibili/user/dynamic/:uid', require('./routes/bilibili/dynamic'));
app.get('/bilibili/partion/:tid', require('./routes/bilibili/partion'));
app.get('/bilibili/bangumi/:seasonid', require('./routes/bilibili/bangumi'));
// set header
app.use(header);
// 微博
app.get('/weibo/user/:uid', require('./routes/weibo/user'));
// cache
app.use(cache({
expire: config.cacheExpire,
onerror: (e) => {
logger.error('cache error', e);
}
}));
// 网易云音乐
app.get('/ncm/playlist/:id', require('./routes/ncm/playlist'));
app.get('/ncm/user/playlist/:uid', require('./routes/ncm/userplaylist'));
app.get('/ncm/artist/:id', require('./routes/ncm/artist'));
// router
app.use(router.routes()).use(router.allowedMethods());
// 掘金
app.get('/juejin/category/:category', require('./routes/juejin/category'));
// 自如
app.get('/ziroom/room/:city/:iswhole/:room/:keyword', require('./routes/ziroom/room'));
// 快递
app.get('/express/:company/:number', require('./routes/express/express'));
// 简书
app.get('/jianshu/home', require('./routes/jianshu/home'));
app.get('/jianshu/trending/weekly', require('./routes/jianshu/weekly'));
app.get('/jianshu/trending/monthly', require('./routes/jianshu/monthly'));
app.get('/jianshu/collection/:id', require('./routes/jianshu/collection'));
app.get('/jianshu/user/:id', require('./routes/jianshu/user'));
// 知乎
app.get('/zhihu/collection/:id', require('./routes/zhihu/collection'));
app.listen(1200);
app.listen(config.port);
+14
View File
@@ -0,0 +1,14 @@
const logger = require('../utils/logger');
module.exports = async (ctx, next) => {
logger.info(`${ctx.url}, user IP: ${ctx.ip}`);
const headers = {
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Headers': 'Content-Type, Content-Length, Authorization, Accept, X-Requested-With , yourHeaderFeild',
'Access-Control-Allow-Methods': 'PUT, POST, GET, DELETE, OPTIONS',
'Content-Type': 'application/xml; charset=utf-8',
};
ctx.set(headers);
await next();
};
+11
View File
@@ -0,0 +1,11 @@
const logger = require('../utils/logger');
module.exports = async (ctx, next) => {
try {
await next();
} catch (err) {
logger.error('Promise error: ' + err);
ctx.body = 'RSSHub 发生了一些意外: ' + err;
ctx.status = 500;
}
};
+4 -3
View File
@@ -19,11 +19,12 @@
"devDependencies": {},
"dependencies": {
"art-template": "4.12.2",
"axios": "0.18.0",
"cheerio": "1.0.0-rc.2",
"eslint": "4.19.1",
"express": "^4.16.3",
"redis": "2.8.0",
"request": "^2.85.0",
"koa": "2.5.0",
"koa-redis-cache": "3.0.0",
"koa-router": "7.4.0",
"winston": "3.0.0-rc3"
}
}
+39
View File
@@ -0,0 +1,39 @@
const Router = require('koa-router');
const router = new Router();
// // bilibili
router.get('/bilibili/user/video/:uid', require('./routes/bilibili/video'));
router.get('/bilibili/user/fav/:uid', require('./routes/bilibili/fav'));
router.get('/bilibili/user/coin/:uid', require('./routes/bilibili/coin'));
router.get('/bilibili/user/dynamic/:uid', require('./routes/bilibili/dynamic'));
router.get('/bilibili/partion/:tid', require('./routes/bilibili/partion'));
router.get('/bilibili/bangumi/:seasonid', require('./routes/bilibili/bangumi'));
// // 微博
router.get('/weibo/user/:uid', require('./routes/weibo/user'));
// // 网易云音乐
router.get('/ncm/playlist/:id', require('./routes/ncm/playlist'));
router.get('/ncm/user/playlist/:uid', require('./routes/ncm/userplaylist'));
router.get('/ncm/artist/:id', require('./routes/ncm/artist'));
// // 掘金
router.get('/juejin/category/:category', require('./routes/juejin/category'));
// // 自如
router.get('/ziroom/room/:city/:iswhole/:room/:keyword', require('./routes/ziroom/room'));
// // 快递
router.get('/express/:company/:number', require('./routes/express/express'));
// // 简书
router.get('/jianshu/home', require('./routes/jianshu/home'));
router.get('/jianshu/trending/weekly', require('./routes/jianshu/weekly'));
router.get('/jianshu/trending/monthly', require('./routes/jianshu/monthly'));
router.get('/jianshu/collection/:id', require('./routes/jianshu/collection'));
router.get('/jianshu/user/:id', require('./routes/jianshu/user'));
// // 知乎
router.get('/zhihu/collection/:id', require('./routes/zhihu/collection'));
module.exports = router;
-13
View File
@@ -1,13 +0,0 @@
module.exports = function (req, res, next) {
res.header('Access-Control-Allow-Origin', '*');
res.header('Access-Control-Allow-Headers', 'Content-Type, Content-Length, Authorization, Accept, X-Requested-With , yourHeaderFeild');
res.header('Access-Control-Allow-Methods', 'PUT, POST, GET, DELETE, OPTIONS');
res.header('Content-Type', 'application/xml; charset=utf-8');
if (req.method === 'OPTIONS') {
res.send(200);
}
else {
next();
}
};
-25
View File
@@ -1,25 +0,0 @@
const logger = require('../utils/logger');
const redis = require('../utils/redis');
const mix = require('../utils/mix');
module.exports = (options) => {
logger.info(`${options.req.url}, user IP: ${mix.getIp(options.req)}`);
redis.get(options.req.url, (reply) => {
if (reply) {
options.res.send(reply);
}
else {
try {
options.getHTML((html) => {
redis.set(options.req.url, html);
options.res.send(html);
});
}
catch (e) {
redis.set(options.req.url, '');
options.res.send('');
}
}
});
};
+27 -39
View File
@@ -1,46 +1,34 @@
const request = require('request');
const axios = require('axios');
const art = require('art-template');
const path = require('path');
const base = require('../base');
const mix = require('../../utils/mix');
const config = require('../../config');
module.exports = (req, res) => {
const seasonid = req.params.seasonid;
module.exports = async (ctx, next) => {
const seasonid = ctx.params.seasonid;
base({
req: req,
res: res,
getHTML: (callback) => {
request.get({
url: `https://bangumi.bilibili.com/jsonp/seasoninfo/${seasonid}.ver?callback=seasonListCallback&jsonp=jsonp&_=${+new Date()}`,
headers: {
'User-Agent': mix.ua,
'Referer': `https://bangumi.bilibili.com/anime/${seasonid}/`
}
}, (err, httpResponse, body) => {
let data;
try {
data = JSON.parse(body.match(/^seasonListCallback\((.*)\);$/)[1]);
}
catch (e) {
data = {};
}
const result = data.result || {};
const html = art(path.resolve(__dirname, '../../views/rss.art'), {
title: result.title,
link: `https://bangumi.bilibili.com/anime/${seasonid}/`,
description: result.evaluate,
lastBuildDate: new Date().toUTCString(),
item: result.episodes && result.episodes.map((item) => ({
title: `第${item.index}话 ${item.index_title}`,
description: `更新时间:${item.update_time}<img referrerpolicy="no-referrer" src="${item.cover}">`,
pubDate: new Date(item.update_time).toUTCString(),
link: item.webplay_url
})),
});
callback(html);
});
const response = await axios({
method: 'get',
url: `https://bangumi.bilibili.com/jsonp/seasoninfo/${seasonid}.ver?callback=seasonListCallback&jsonp=jsonp&_=${+new Date()}`,
headers: {
'User-Agent': config.ua,
'Referer': `https://bangumi.bilibili.com/anime/${seasonid}/`
}
});
const data = JSON.parse(response.data.match(/^seasonListCallback\((.*)\);$/)[1]).result || {};
ctx.body = art(path.resolve(__dirname, '../../views/rss.art'), {
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}">`,
pubDate: new Date(item.update_time).toUTCString(),
link: item.webplay_url
})),
});
next();
};
+39 -49
View File
@@ -1,57 +1,47 @@
const request = require('request');
const axios = require('axios');
const qs = require('querystring');
const art = require('art-template');
const path = require('path');
const base = require('../base');
const mix = require('../../utils/mix');
const config = require('../../config');
module.exports = (req, res) => {
const uid = req.params.uid;
module.exports = async (ctx, next) => {
const uid = ctx.params.uid;
base({
req: req,
res: res,
getHTML: (callback) => {
request.post({
url: 'https://space.bilibili.com/ajax/member/GetInfo',
headers: {
'User-Agent': mix.ua,
'Referer': `https://space.bilibili.com/${uid}/`,
'Origin': 'https://space.bilibili.com'
},
form: {
mid: uid
}
}, function (err, httpResponse, body) {
const name = JSON.parse(body).data.name;
request.get({
url: `https://space.bilibili.com/ajax/member/getCoinVideos?mid=${uid}`,
headers: {
'User-Agent': mix.ua,
'Referer': `https://space.bilibili.com/${uid}/`
}
}, function (err, httpResponse, body) {
let data;
try {
data = JSON.parse(body);
}
catch (e) {
data = {};
}
const nameResponse = await axios({
method: 'post',
url: 'https://space.bilibili.com/ajax/member/GetInfo',
headers: {
'User-Agent': config.ua,
'Referer': `https://space.bilibili.com/${uid}/`,
'Content-Type': 'application/x-www-form-urlencoded',
},
data: qs.stringify({
mid: uid
}),
});
const name = nameResponse.data.data.name;
const html = art(path.resolve(__dirname, '../../views/rss.art'), {
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}">`,
link: `https://www.bilibili.com/video/av${item.stat.aid}`
})),
});
callback(html);
});
});
const response = await axios({
method: 'get',
url: `https://space.bilibili.com/ajax/member/getCoinVideos?mid=${uid}`,
headers: {
'User-Agent': config.ua,
'Referer': `https://space.bilibili.com/${uid}/`
}
});
const data = response.data;
ctx.body = art(path.resolve(__dirname, '../../views/rss.art'), {
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}">`,
link: `https://www.bilibili.com/video/av${item.stat.aid}`
})),
});
next();
};
+54 -67
View File
@@ -1,74 +1,61 @@
const request = require('request');
const axios = require('axios');
const art = require('art-template');
const path = require('path');
const base = require('../base');
const mix = require('../../utils/mix');
const config = require('../../config');
module.exports = (req, res) => {
const uid = req.params.uid;
module.exports = async (ctx, next) => {
const uid = ctx.params.uid;
base({
req: req,
res: res,
getHTML: (callback) => {
request.get({
url: `https://api.vc.bilibili.com/dynamic_svr/v1/dynamic_svr/space_history?host_uid=${uid}`,
headers: {
'User-Agent': mix.ua,
'Referer': `https://space.bilibili.com/${uid}/`
}
}, (err, httpResponse, body) => {
let data;
try {
data = JSON.parse(body);
}
catch (e) {
data = {};
}
const result = data.data && data.data.cards || {};
const html = art(path.resolve(__dirname, '../../views/rss.art'), {
title: `${result[0].desc.user_profile.info.uname} 的 bilibili 动态`,
link: `https://space.bilibili.com/${uid}/#/dynamic`,
description: `${result[0].desc.user_profile.info.uname} 的 bilibili 动态`,
lastBuildDate: new Date().toUTCString(),
item: result.map((item) => {
const parsed = JSON.parse(item.card);
const data = parsed.item || parsed;
// img
let imgHTML = '';
if (data.pictures) {
for (let i = 0; i < data.pictures.length; i++) {
imgHTML += `<img referrerpolicy="no-referrer" src="${data.pictures[i].img_src}">`;
}
}
if (data.pic) {
imgHTML += `<img referrerpolicy="no-referrer" src="${data.pic}">`;
}
// link
let link = '';
if (data.dynamic_id) {
link = `https://t.bilibili.com/${data.dynamic_id}`;
}
else if (data.aid) {
link = `https://www.bilibili.com/video/av${data.aid}`;
}
else if (data.id) {
link = `https://h.bilibili.com/${data.id}`;
}
return {
title: data.title || data.description || data.content,
description: `${data.desc || data.description || data.content}${imgHTML}`,
pubDate: new Date((data.pubdate || data.upload_time || data.timestamp) * 1000).toUTCString(),
link: link
};
}),
});
callback(html);
});
const response = await axios({
method: 'get',
url: `https://api.vc.bilibili.com/dynamic_svr/v1/dynamic_svr/space_history?host_uid=${uid}`,
headers: {
'User-Agent': config.ua,
'Referer': `https://space.bilibili.com/${uid}/`
}
});
const data = response.data.data.cards;
ctx.body = art(path.resolve(__dirname, '../../views/rss.art'), {
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 = JSON.parse(item.card);
const data = parsed.item || parsed;
// img
let imgHTML = '';
if (data.pictures) {
for (let i = 0; i < data.pictures.length; i++) {
imgHTML += `<img referrerpolicy="no-referrer" src="${data.pictures[i].img_src}">`;
}
}
if (data.pic) {
imgHTML += `<img referrerpolicy="no-referrer" src="${data.pic}">`;
}
// link
let link = '';
if (data.dynamic_id) {
link = `https://t.bilibili.com/${data.dynamic_id}`;
}
else if (data.aid) {
link = `https://www.bilibili.com/video/av${data.aid}`;
}
else if (data.id) {
link = `https://h.bilibili.com/${data.id}`;
}
return {
title: data.title || data.description || data.content,
description: `${data.desc || data.description || data.content}${imgHTML}`,
pubDate: new Date((data.pubdate || data.upload_time || data.timestamp) * 1000).toUTCString(),
link: link
};
}),
});
next();
};
+40 -50
View File
@@ -1,58 +1,48 @@
const request = require('request');
const axios = require('axios');
const qs = require('querystring');
const art = require('art-template');
const path = require('path');
const base = require('../base');
const mix = require('../../utils/mix');
const config = require('../../config');
module.exports = (req, res) => {
const uid = req.params.uid;
module.exports = async (ctx, next) => {
const uid = ctx.params.uid;
base({
req: req,
res: res,
getHTML: (callback) => {
request.post({
url: 'https://space.bilibili.com/ajax/member/GetInfo',
headers: {
'User-Agent': mix.ua,
'Referer': `https://space.bilibili.com/${uid}/`,
'Origin': 'https://space.bilibili.com'
},
form: {
mid: uid
}
}, function (err, httpResponse, body) {
const name = JSON.parse(body).data.name;
request.get({
url: `https://api.bilibili.com/x/v2/fav/video?vmid=${uid}&ps=30&tid=0&keyword=&pn=1&order=fav_time`,
headers: {
'User-Agent': mix.ua,
'Referer': `https://space.bilibili.com/${uid}/#/favlist`
}
}, function (err, httpResponse, body) {
let data;
try {
data = JSON.parse(body);
}
catch (e) {
data = {};
}
const nameResponse = await axios({
method: 'post',
url: 'https://space.bilibili.com/ajax/member/GetInfo',
headers: {
'User-Agent': config.ua,
'Referer': `https://space.bilibili.com/${uid}/`,
'Content-Type': 'application/x-www-form-urlencoded',
},
data: qs.stringify({
mid: uid
}),
});
const name = nameResponse.data.data.name;
const html = art(path.resolve(__dirname, '../../views/rss.art'), {
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}">`,
pubDate: new Date(item.fav_at * 1000).toUTCString(),
link: `https://www.bilibili.com/video/av${item.aid}`
})),
});
callback(html);
});
});
const response = await axios({
method: 'get',
url: `https://api.bilibili.com/x/v2/fav/video?vmid=${uid}&ps=30&tid=0&keyword=&pn=1&order=fav_time`,
headers: {
'User-Agent': config.ua,
'Referer': `https://space.bilibili.com/${uid}/#/favlist`
}
});
const data = response.data;
ctx.body = art(path.resolve(__dirname, '../../views/rss.art'), {
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}">`,
pubDate: new Date(item.fav_at * 1000).toUTCString(),
link: `https://www.bilibili.com/video/av${item.aid}`
})),
});
next();
};
+31 -44
View File
@@ -1,51 +1,38 @@
const request = require('request');
const axios = require('axios');
const art = require('art-template');
const path = require('path');
const base = require('../base');
const mix = require('../../utils/mix');
const config = require('../../config');
module.exports = (req, res) => {
const tid = req.params.tid;
module.exports = async (ctx, next) => {
const tid = ctx.params.tid;
base({
req: req,
res: res,
getHTML: (callback) => {
request.get({
url: `https://api.bilibili.com/x/web-interface/newlist?ps=15&rid=${tid}&_=${+new Date()}`,
headers: {
'User-Agent': mix.ua,
'Referer': 'https://www.bilibili.com/'
}
}, (err, httpResponse, body) => {
let data;
try {
data = JSON.parse(body);
}
catch (e) {
data = {};
}
const list = data.data && data.data.archives;
let name = '未知';
if (list && list[0] && list[0].tname) {
name = list[0].tname;
}
const html = art(path.resolve(__dirname, '../../views/rss.art'), {
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}">`,
pubDate: new Date(item.pubdate * 1000).toUTCString(),
link: `https://www.bilibili.com/video/av${item.aid}`
})),
});
callback(html);
});
const response = await axios({
method: 'get',
url: `https://api.bilibili.com/x/web-interface/newlist?ps=15&rid=${tid}&_=${+new Date()}`,
headers: {
'User-Agent': config.ua,
'Referer': 'https://www.bilibili.com/'
}
});
const list = response.data.data.archives;
let name = '未知';
if (list && list[0] && list[0].tname) {
name = list[0].tname;
}
ctx.body = art(path.resolve(__dirname, '../../views/rss.art'), {
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}">`,
pubDate: new Date(item.pubdate * 1000).toUTCString(),
link: `https://www.bilibili.com/video/av${item.aid}`
})),
});
next();
};
+40 -50
View File
@@ -1,58 +1,48 @@
const request = require('request');
const axios = require('axios');
const qs = require('querystring');
const art = require('art-template');
const path = require('path');
const base = require('../base');
const mix = require('../../utils/mix');
const config = require('../../config');
module.exports = (req, res) => {
const uid = req.params.uid;
module.exports = async (ctx, next) => {
const uid = ctx.params.uid;
base({
req: req,
res: res,
getHTML: (callback) => {
request.post({
url: 'https://space.bilibili.com/ajax/member/GetInfo',
headers: {
'User-Agent': mix.ua,
'Referer': `https://space.bilibili.com/${uid}/`,
'Origin': 'https://space.bilibili.com'
},
form: {
mid: uid
}
}, function (err, httpResponse, body) {
const name = JSON.parse(body).data.name;
request.get({
url: `https://space.bilibili.com/ajax/member/getSubmitVideos?mid=${uid}`,
headers: {
'User-Agent': mix.ua,
'Referer': `https://space.bilibili.com/${uid}/`,
}
}, function (err, httpResponse, body) {
let data;
try {
data = JSON.parse(body);
}
catch (e) {
data = {};
}
const nameResponse = await axios({
method: 'post',
url: 'https://space.bilibili.com/ajax/member/GetInfo',
headers: {
'User-Agent': config.ua,
'Referer': `https://space.bilibili.com/${uid}/`,
'Content-Type': 'application/x-www-form-urlencoded',
},
data: qs.stringify({
mid: uid
}),
});
const name = nameResponse.data.data.name;
const html = art(path.resolve(__dirname, '../../views/rss.art'), {
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}">`,
pubDate: new Date(item.created * 1000).toUTCString(),
link: `https://www.bilibili.com/video/av${item.aid}`
})),
});
callback(html);
});
});
const response = await axios({
method: 'get',
url: `https://space.bilibili.com/ajax/member/getSubmitVideos?mid=${uid}`,
headers: {
'User-Agent': config.ua,
'Referer': `https://space.bilibili.com/${uid}/`
}
});
const data = response.data;
ctx.body = art(path.resolve(__dirname, '../../views/rss.art'), {
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}">`,
pubDate: new Date(item.created * 1000).toUTCString(),
link: `https://www.bilibili.com/video/av${item.aid}`
})),
});
next();
};
+28 -40
View File
@@ -1,47 +1,35 @@
const request = require('request');
const axios = require('axios');
const art = require('art-template');
const path = require('path');
const base = require('../base');
const mix = require('../../utils/mix');
const config = require('../../config');
module.exports = (req, res) => {
const company = req.params.company;
const number = req.params.number;
module.exports = async (ctx, next) => {
const company = ctx.params.company;
const number = ctx.params.number;
base({
req: req,
res: res,
getHTML: (callback) => {
request.get({
url: `https://www.kuaidi100.com/query?type=${company}&postid=${number}`,
headers: {
'User-Agent': mix.ua,
'Referer': 'https://www.kuaidi100.com'
}
}, (err, httpResponse, body) => {
let data;
try {
data = JSON.parse(body);
}
catch (e) {
data = {};
}
const result = data.data || [];
const html = art(path.resolve(__dirname, '../../views/rss.art'), {
title: `快递 ${company}-${number}`,
link: 'https://www.kuaidi100.com',
description: `快递 ${company}-${number}`,
lastBuildDate: new Date().toUTCString(),
item: result && result.map((item) => ({
title: item.context,
description: item.context,
pubDate: new Date(item.time || item.ftime).toUTCString(),
link: item.context
})),
});
callback(html);
});
const response = await axios({
method: 'get',
url: `https://www.kuaidi100.com/query?type=${company}&postid=${number}`,
headers: {
'User-Agent': config.ua,
'Referer': 'https://www.kuaidi100.com'
}
});
const data = response.data.data;
ctx.body = art(path.resolve(__dirname, '../../views/rss.art'), {
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,
pubDate: new Date(item.time || item.ftime).toUTCString(),
link: item.context
})),
});
next();
};
+33 -36
View File
@@ -1,44 +1,41 @@
const request = require('request');
const axios = require('axios');
const art = require('art-template');
const path = require('path');
const cheerio = require('cheerio');
const base = require('../base');
const mix = require('../../utils/mix');
const config = require('../../config');
module.exports = (req, res) => {
const id = req.params.id;
module.exports = async (ctx, next) => {
const id = ctx.params.id;
base({
req: req,
res: res,
getHTML: (callback) => {
request.get({
url: `https://www.jianshu.com/c/${id}`,
headers: {
'User-Agent': mix.ua,
'Referer': `https://www.jianshu.com/c/${id}`
}
}, (err, httpResponse, body) => {
const $ = cheerio.load(body);
const list = $('.note-list li');
const html = art(path.resolve(__dirname, '../../views/rss.art'), {
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 {
title: item.find('.title').text(),
description: `作者:${item.find('.nickname').text()}<br>描述:${item.find('.abstract').text()}<br><img referrerpolicy="no-referrer" src="https:${item.find('.img-blur').data('echo')}">`,
pubDate: new Date(item.find('.time').data('shared-at')).toUTCString(),
link: `https://www.jianshu.com${item.find('.title').attr('href')}`
};
}).get(),
});
callback(html);
});
const response = await axios({
method: 'get',
url: `https://www.jianshu.com/c/${id}`,
headers: {
'User-Agent': config.ua,
'Referer': `https://www.jianshu.com/c/${id}`
}
});
const data = response.data;
const $ = cheerio.load(data);
const list = $('.note-list li');
ctx.body = art(path.resolve(__dirname, '../../views/rss.art'), {
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 {
title: item.find('.title').text(),
description: `作者:${item.find('.nickname').text()}<br>描述:${item.find('.abstract').text()}<br><img referrerpolicy="no-referrer" src="https:${item.find('.img-blur').data('echo')}">`,
pubDate: new Date(item.find('.time').data('shared-at')).toUTCString(),
link: `https://www.jianshu.com${item.find('.title').attr('href')}`
};
}).get(),
});
next();
};
+32 -35
View File
@@ -1,42 +1,39 @@
const request = require('request');
const axios = require('axios');
const art = require('art-template');
const path = require('path');
const cheerio = require('cheerio');
const base = require('../base');
const mix = require('../../utils/mix');
const config = require('../../config');
module.exports = (req, res) => {
base({
req: req,
res: res,
getHTML: (callback) => {
request.get({
url: 'https://www.jianshu.com',
headers: {
'User-Agent': mix.ua,
'Referer': 'https://www.jianshu.com'
}
}, (err, httpResponse, body) => {
const $ = cheerio.load(body);
const list = $('.note-list li');
const html = art(path.resolve(__dirname, '../../views/rss.art'), {
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 {
title: item.find('.title').text(),
description: `作者:${item.find('.nickname').text()}<br>描述:${item.find('.abstract').text()}<br><img referrerpolicy="no-referrer" src="https:${item.find('.img-blur').data('echo')}">`,
pubDate: new Date(item.find('.time').data('shared-at')).toUTCString(),
link: `https://www.jianshu.com${item.find('.title').attr('href')}`
};
}).get(),
});
callback(html);
});
module.exports = async (ctx, next) => {
const response = await axios({
method: 'get',
url: 'https://www.jianshu.com',
headers: {
'User-Agent': config.ua,
'Referer': 'https://www.jianshu.com'
}
});
const data = response.data;
const $ = cheerio.load(data);
const list = $('.note-list li');
ctx.body = art(path.resolve(__dirname, '../../views/rss.art'), {
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 {
title: item.find('.title').text(),
description: `作者:${item.find('.nickname').text()}<br>描述:${item.find('.abstract').text()}<br><img referrerpolicy="no-referrer" src="https:${item.find('.img-blur').data('echo')}">`,
pubDate: new Date(item.find('.time').data('shared-at')).toUTCString(),
link: `https://www.jianshu.com${item.find('.title').attr('href')}`
};
}).get(),
});
next();
};
+32 -35
View File
@@ -1,42 +1,39 @@
const request = require('request');
const axios = require('axios');
const art = require('art-template');
const path = require('path');
const cheerio = require('cheerio');
const base = require('../base');
const mix = require('../../utils/mix');
const config = require('../../config');
module.exports = (req, res) => {
base({
req: req,
res: res,
getHTML: (callback) => {
request.get({
url: 'https://www.jianshu.com/trending/monthly',
headers: {
'User-Agent': mix.ua,
'Referer': 'https://www.jianshu.com/trending/monthly'
}
}, (err, httpResponse, body) => {
const $ = cheerio.load(body);
const list = $('.note-list li');
const html = art(path.resolve(__dirname, '../../views/rss.art'), {
title: '简书 30 日热门',
link: 'https://www.jianshu.com/trending/monthly',
description: '简书 30 日热门',
lastBuildDate: new Date().toUTCString(),
item: list && list.map((index, item) => {
item = $(item);
return {
title: item.find('.title').text(),
description: `作者:${item.find('.nickname').text()}<br>描述:${item.find('.abstract').text()}<br><img referrerpolicy="no-referrer" src="https:${item.find('.img-blur').data('echo')}">`,
pubDate: new Date(item.find('.time').data('shared-at')).toUTCString(),
link: `https://www.jianshu.com${item.find('.title').attr('href')}`
};
}).get(),
});
callback(html);
});
module.exports = async (ctx, next) => {
const response = await axios({
method: 'get',
url: 'https://www.jianshu.com/trending/monthly',
headers: {
'User-Agent': config.ua,
'Referer': 'https://www.jianshu.com/trending/monthly'
}
});
const data = response.data;
const $ = cheerio.load(data);
const list = $('.note-list li');
ctx.body = art(path.resolve(__dirname, '../../views/rss.art'), {
title: '简书 30 日热门',
link: 'https://www.jianshu.com/trending/monthly',
description: '简书 30 日热门',
lastBuildDate: new Date().toUTCString(),
item: list && list.map((index, item) => {
item = $(item);
return {
title: item.find('.title').text(),
description: `作者:${item.find('.nickname').text()}<br>描述:${item.find('.abstract').text()}<br><img referrerpolicy="no-referrer" src="https:${item.find('.img-blur').data('echo')}">`,
pubDate: new Date(item.find('.time').data('shared-at')).toUTCString(),
link: `https://www.jianshu.com${item.find('.title').attr('href')}`
};
}).get(),
});
next();
};
+33 -36
View File
@@ -1,44 +1,41 @@
const request = require('request');
const axios = require('axios');
const art = require('art-template');
const path = require('path');
const cheerio = require('cheerio');
const base = require('../base');
const mix = require('../../utils/mix');
const config = require('../../config');
module.exports = (req, res) => {
const id = req.params.id;
module.exports = async (ctx, next) => {
const id = ctx.params.id;
base({
req: req,
res: res,
getHTML: (callback) => {
request.get({
url: `https://www.jianshu.com/u/${id}`,
headers: {
'User-Agent': mix.ua,
'Referer': `https://www.jianshu.com/u/${id}`
}
}, (err, httpResponse, body) => {
const $ = cheerio.load(body);
const list = $('.note-list li');
const html = art(path.resolve(__dirname, '../../views/rss.art'), {
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 {
title: item.find('.title').text(),
description: `作者:${item.find('.nickname').text()}<br>描述:${item.find('.abstract').text()}<br><img referrerpolicy="no-referrer" src="https:${item.find('.img-blur').data('echo')}">`,
pubDate: new Date(item.find('.time').data('shared-at')).toUTCString(),
link: `https://www.jianshu.com${item.find('.title').attr('href')}`
};
}).get(),
});
callback(html);
});
const response = await axios({
method: 'get',
url: `https://www.jianshu.com/u/${id}`,
headers: {
'User-Agent': config.ua,
'Referer': `https://www.jianshu.com/u/${id}`
}
});
const data = response.data;
const $ = cheerio.load(data);
const list = $('.note-list li');
ctx.body = art(path.resolve(__dirname, '../../views/rss.art'), {
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 {
title: item.find('.title').text(),
description: `作者:${item.find('.nickname').text()}<br>描述:${item.find('.abstract').text()}<br><img referrerpolicy="no-referrer" src="https:${item.find('.img-blur').data('echo')}">`,
pubDate: new Date(item.find('.time').data('shared-at')).toUTCString(),
link: `https://www.jianshu.com${item.find('.title').attr('href')}`
};
}).get(),
});
next();
};
+32 -35
View File
@@ -1,42 +1,39 @@
const request = require('request');
const axios = require('axios');
const art = require('art-template');
const path = require('path');
const cheerio = require('cheerio');
const base = require('../base');
const mix = require('../../utils/mix');
const config = require('../../config');
module.exports = (req, res) => {
base({
req: req,
res: res,
getHTML: (callback) => {
request.get({
url: 'https://www.jianshu.com/trending/weekly',
headers: {
'User-Agent': mix.ua,
'Referer': 'https://www.jianshu.com/trending/weekly'
}
}, (err, httpResponse, body) => {
const $ = cheerio.load(body);
const list = $('.note-list li');
const html = art(path.resolve(__dirname, '../../views/rss.art'), {
title: '简书 7 日热门',
link: 'https://www.jianshu.com/trending/weekly',
description: '简书 7 日热门',
lastBuildDate: new Date().toUTCString(),
item: list && list.map((index, item) => {
item = $(item);
return {
title: item.find('.title').text(),
description: `作者:${item.find('.nickname').text()}<br>描述:${item.find('.abstract').text()}<br><img referrerpolicy="no-referrer" src="https:${item.find('.img-blur').data('echo')}">`,
pubDate: new Date(item.find('.time').data('shared-at')).toUTCString(),
link: `https://www.jianshu.com${item.find('.title').attr('href')}`
};
}).get(),
});
callback(html);
});
module.exports = async (ctx, next) => {
const response = await axios({
method: 'get',
url: 'https://www.jianshu.com/trending/weekly',
headers: {
'User-Agent': config.ua,
'Referer': 'https://www.jianshu.com/trending/weekly'
}
});
const data = response.data;
const $ = cheerio.load(data);
const list = $('.note-list li');
ctx.body = art(path.resolve(__dirname, '../../views/rss.art'), {
title: '简书 7 日热门',
link: 'https://www.jianshu.com/trending/weekly',
description: '简书 7 日热门',
lastBuildDate: new Date().toUTCString(),
item: list && list.map((index, item) => {
item = $(item);
return {
title: item.find('.title').text(),
description: `作者:${item.find('.nickname').text()}<br>描述:${item.find('.abstract').text()}<br><img referrerpolicy="no-referrer" src="https:${item.find('.img-blur').data('echo')}">`,
pubDate: new Date(item.find('.time').data('shared-at')).toUTCString(),
link: `https://www.jianshu.com${item.find('.title').attr('href')}`
};
}).get(),
});
next();
};
+43 -63
View File
@@ -1,70 +1,50 @@
const request = require('request');
const axios = require('axios');
const art = require('art-template');
const path = require('path');
const base = require('../base');
const mix = require('../../utils/mix');
const config = require('../../config');
module.exports = (req, res) => {
const category = req.params.category;
module.exports = async (ctx, next) => {
const category = ctx.params.category;
base({
req: req,
res: res,
getHTML: (callback) => {
request.get({
url: 'https://gold-tag-ms.juejin.im/v1/categories',
headers: {
'User-Agent': mix.ua,
'Referer': `https://juejin.im/welcome/${category}`,
'X-Juejin-Client': '',
'X-Juejin-Src': 'web',
'X-Juejin-Token': '',
'X-Juejin-Uid': ''
}
}, function (err, httpResponse, body) {
let data;
try {
data = JSON.parse(body);
}
catch (e) {
data = {};
}
const cat = data.d && data.d.categoryList && data.d.categoryList.filter((item) => item.title === category)[0];
if (cat && cat.id) {
request.get({
url: `https://timeline-merger-ms.juejin.im/v1/get_entry_by_timeline?src=web&limit=20&category=${cat.id}`,
headers: {
'User-Agent': mix.ua,
'Referer': `https://juejin.im/welcome/${category}`,
}
}, function (err, httpResponse, body) {
let data;
try {
data = JSON.parse(body);
}
catch (e) {
data = {};
}
const html = art(path.resolve(__dirname, '../../views/rss.art'), {
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, '')}`,
pubDate: new Date(item.createdAt).toUTCString(),
link: item.originalUrl
})),
});
callback(html);
});
}
else {
callback('');
}
});
const idResponse = await axios({
method: 'get',
url: 'https://gold-tag-ms.juejin.im/v1/categories',
headers: {
'User-Agent': config.ua,
'Referer': `https://juejin.im/welcome/${category}`,
'X-Juejin-Client': '',
'X-Juejin-Src': 'web',
'X-Juejin-Token': '',
'X-Juejin-Uid': ''
}
});
const cat = idResponse.data.d.categoryList.filter((item) => item.title === category)[0];
const id = cat.id;
const response = await axios({
method: 'get',
url: `https://timeline-merger-ms.juejin.im/v1/get_entry_by_timeline?src=web&limit=20&category=${id}`,
headers: {
'User-Agent': config.ua,
'Referer': `https://juejin.im/welcome/${category}`,
}
});
const data = response.data;
ctx.body = art(path.resolve(__dirname, '../../views/rss.art'), {
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, '')}`,
pubDate: new Date(item.createdAt).toUTCString(),
link: item.originalUrl
})),
});
next();
};
+30 -42
View File
@@ -1,48 +1,36 @@
const request = require('request');
const axios = require('axios');
const art = require('art-template');
const path = require('path');
const base = require('../base');
const mix = require('../../utils/mix');
const config = require('../../config');
module.exports = (req, res) => {
const id = req.params.id;
module.exports = async (ctx, next) => {
const id = ctx.params.id;
base({
req: req,
res: res,
getHTML: (callback) => {
request.get({
url: 'https://music.163.com/api/artist/albums/' + id,
headers: {
'User-Agent': mix.ua,
'Referer': 'https://music.163.com/'
}
}, (err, httpResponse, body) => {
let data;
try {
data = JSON.parse(body);
}
catch (e) {
data = {};
}
const result = data;
const html = art(path.resolve(__dirname, '../../views/rss.art'), {
title: result.artist.name,
link: `https://music.163.com/#/artist/album?id=${id}`,
description: `网易云音乐歌手专辑 - ${result.artist.name}`,
lastBuildDate: new Date().toUTCString(),
item: result.hotAlbums && result.hotAlbums.map((item) => {
const singer = item.artists.length === 1 ? item.artists[0].name : item.artists.reduce((prev, cur) => (prev.name || prev) + '/' + cur.name);
return {
title: `${item.name} - ${singer}`,
description: `歌手:${singer}<br>专辑:${item.name}<br>日期:${new Date(item.publishTime).toLocaleDateString()}<br><img referrerpolicy="no-referrer" src="${item.picUrl}">`,
link: `https://music.163.com/#/album?id=${item.id}`
};
}),
});
callback(html);
});
const response = await axios({
method: 'get',
url: `https://music.163.com/api/artist/albums/${id}`,
headers: {
'User-Agent': config.ua,
'Referer': 'https://music.163.com/'
}
});
};
const data = response.data;
ctx.body = art(path.resolve(__dirname, '../../views/rss.art'), {
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 {
title: `${item.name} - ${singer}`,
description: `歌手:${singer}<br>专辑:${item.name}<br>日期:${new Date(item.publishTime).toLocaleDateString()}<br><img referrerpolicy="no-referrer" src="${item.picUrl}">`,
link: `https://music.163.com/#/album?id=${item.id}`
};
}),
});
next();
};
+35 -45
View File
@@ -1,51 +1,41 @@
const request = require('request');
const axios = require('axios');
const qs = require('querystring');
const art = require('art-template');
const path = require('path');
const base = require('../base');
const mix = require('../../utils/mix');
const config = require('../../config');
module.exports = (req, res) => {
const id = req.params.id;
module.exports = async (ctx, next) => {
const id = ctx.params.id;
base({
req: req,
res: res,
getHTML: (callback) => {
request.post({
url: 'https://music.163.com/api/v3/playlist/detail',
headers: {
'User-Agent': mix.ua,
'Referer': 'https://music.163.com/'
},
form: {
id: id
}
}, (err, httpResponse, body) => {
let data;
try {
data = JSON.parse(body);
}
catch (e) {
data = {};
}
const result = data.playlist || {};
const html = art(path.resolve(__dirname, '../../views/rss.art'), {
title: result.name,
link: `https://music.163.com/#/playlist?id=${id}`,
description: `网易云音乐歌单 - ${result.name}`,
lastBuildDate: new Date().toUTCString(),
item: result.tracks && result.tracks.map((item) => {
const singer = item.ar.length === 1 ? item.ar[0].name : item.ar.reduce((prev, cur) => (prev.name || prev) + '/' + cur.name);
return {
title: `${item.name} - ${singer}`,
description: `歌手:${singer}<br>专辑:${item.al.name}<br>日期:${new Date(item.publishTime).toLocaleDateString()}<br><img referrerpolicy="no-referrer" src="${item.al.picUrl}">`,
link: `https://music.163.com/#/song?id=${item.id}`
};
}),
});
callback(html);
});
}
const response = await axios({
method: 'post',
url: 'https://music.163.com/api/v3/playlist/detail',
headers: {
'User-Agent': config.ua,
'Referer': 'https://music.163.com/',
'Content-Type': 'application/x-www-form-urlencoded',
},
data: qs.stringify({
id: id
}),
});
const data = response.data.playlist;
ctx.body = art(path.resolve(__dirname, '../../views/rss.art'), {
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 {
title: `${item.name} - ${singer}`,
description: `歌手:${singer}<br>专辑:${item.al.name}<br>日期:${new Date(item.publishTime).toLocaleDateString()}<br><img referrerpolicy="no-referrer" src="${item.al.picUrl}">`,
link: `https://music.163.com/#/song?id=${item.id}`
};
}),
});
next();
};
+40 -61
View File
@@ -1,66 +1,45 @@
const request = require('request');
const axios = require('axios');
const qs = require('querystring');
const art = require('art-template');
const path = require('path');
const base = require('../base');
const mix = require('../../utils/mix');
const config = require('../../config');
module.exports = (req, res) => {
const uid = req.params.uid;
module.exports = async (ctx, next) => {
const uid = ctx.params.uid;
base({
req: req,
res: res,
getHTML: (callback) => {
request.post(
{
url: 'http://music.163.com/api/user/playlist',
headers: {
'User-Agent': mix.ua,
Referer: 'https://music.163.com/'
},
form: {
uid: uid,
limit: 1000,
offset: 0
}
},
(err, httpResponse, body) => {
let data;
try {
data = JSON.parse(body);
} catch (e) {
data = {};
}
const playlist = data.playlist || [{ creator: {} }];
const creator = playlist[0].creator;
const { nickname, signature } = creator;
const html = art(
path.resolve(__dirname, '../../views/rss.art'),
{
title: `${nickname} 的所有歌单`,
link: `http://music.163.com/user/home?id=${uid}`,
description: signature,
lastBuildDate: new Date().toUTCString(),
item:
playlist[0].id &&
playlist.map((pl) => ({
title: pl.name,
description: pl.description,
pubDate: new Date(
pl.createTime
).toUTCString(),
link: `http://music.163.com/playlist?id=${
pl.id
}`
}))
}
);
callback(html);
}
);
}
const response = await axios({
method: 'post',
url: 'http://music.163.com/api/user/playlist',
headers: {
'User-Agent': config.ua,
'Referer': 'https://music.163.com/',
'Content-Type': 'application/x-www-form-urlencoded',
},
data: qs.stringify({
uid: uid,
limit: 1000,
offset: 0
}),
});
};
const playlist = response.data.playlist || [{ creator: {} }];
const creator = playlist[0].creator;
const { nickname, signature } = creator;
ctx.body = art(path.resolve(__dirname, '../../views/rss.art'), {
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,
pubDate: new Date(pl.createTime).toUTCString(),
link: `http://music.163.com/playlist?id=${pl.id}`
}))
});
next();
};
+72 -92
View File
@@ -1,103 +1,83 @@
const request = require('request');
const axios = require('axios');
const art = require('art-template');
const path = require('path');
const base = require('../base');
const mix = require('../../utils/mix');
const config = require('../../config');
module.exports = (req, res) => {
const uid = req.params.uid;
// 格式化每条微博的HTML
function format (status) {
// 长文章的处理
let temp = status.longText ? status.longText.longTextContent.replace(/\n/g, '<br>') : status.text;
// 表情图标转换为文字
temp = temp.replace(/<span class="url-icon"><img src=".*?" style="width:1em;height:1em;" alt="(.*?)"><\/span>/g, '$1');
// 去掉外部链接的图标
temp = temp.replace(/<span class="url-icon"><img src=".*?"><\/span><\/i>/g, '');
// 去掉多余无意义的标签
temp = temp.replace(/<span class="surl-text">/g, '');
// 最后插入两个空行,让转发的微博排版更加美观一些
temp += '<br><br>';
base({
req: req,
res: res,
getHTML: (callback) => {
request.get({
url: `https://m.weibo.cn/api/container/getIndex?type=uid&value=${uid}`,
headers: {
'User-Agent': mix.ua,
'Referer': 'https://m.weibo.cn/'
},
}, function (err, httpResponse, body) {
let data;
try {
data = JSON.parse(body).data;
}
catch (e) {
data = {};
}
const name = data.userInfo && data.userInfo.screen_name;
const containerid = data.tabsInfo && data.tabsInfo.tabs && data.tabsInfo.tabs[1] && data.tabsInfo.tabs[1].containerid || '';
// 处理外部链接
temp = temp.replace(/https:\/\/weibo\.cn\/sinaurl\/.*?&u=(http.*?")/g, function (match, p1) {
return decodeURIComponent(p1);
});
request.get({
url: `https://m.weibo.cn/api/container/getIndex?type=uid&value=${uid}&containerid=${containerid}`,
headers: {
'User-Agent': mix.ua,
'Referer': `https://m.weibo.cn/u/${uid}`
},
}, function (err, httpResponse, body) {
let data;
try {
data = JSON.parse(body);
}
catch (e) {
data = {};
}
// 处理转发的微博
if (status.retweeted_status) {
// 当转发的微博被删除时user为null
if (status.retweeted_status.user) {
temp += `转发 <a href="https://weibo.com/${status.retweeted_status.user.id}" target="_blank">@${status.retweeted_status.user.screen_name}</a>: `;
}
// 插入转发的微博
temp += format(status.retweeted_status);
}
// 格式化每条微博的HTML
function format (status) {
// 长文章的处理
let temp = status.longText ? status.longText.longTextContent.replace(/\n/g, '<br>') : status.text;
// 表情图标转换为文字
temp = temp.replace(/<span class="url-icon"><img src=".*?" style="width:1em;height:1em;" alt="(.*?)"><\/span>/g, '$1');
// 去掉外部链接的图标
temp = temp.replace(/<span class="url-icon"><img src=".*?"><\/span><\/i>/g, '');
// 去掉多余无意义的标签
temp = temp.replace(/<span class="surl-text">/g, '');
// 最后插入两个空行,让转发的微博排版更加美观一些
temp += '<br><br>';
// 添加微博配图
if (status.pics) {
status.pics.forEach(function (item) {
temp += '<img referrerpolicy="no-referrer" src="' + item.large.url + '"><br><br>';
});
}
return temp;
}
// 处理外部链接
temp = temp.replace(/https:\/\/weibo\.cn\/sinaurl\/.*?&u=(http.*?")/g, function (match, p1) {
return decodeURIComponent(p1);
});
module.exports = async (ctx, next) => {
const uid = ctx.params.uid;
// 处理转发的微博
if (status.retweeted_status) {
// 当转发的微博被删除时user为null
if (status.retweeted_status.user) {
temp += `转发 <a href="https://weibo.com/${status.retweeted_status.user.id}" target="_blank">@${status.retweeted_status.user.screen_name}</a>: `;
}
// 插入转发的微博
temp += format(status.retweeted_status);
}
// 添加微博配图
if (status.pics) {
status.pics.forEach(function (item) {
temp += '<img referrerpolicy="no-referrer" src="' + item.large.url + '"><br><br>';
});
}
return temp;
}
const html = art(path.resolve(__dirname, '../../views/rss.art'), {
title: `${name}的微博`,
link: `http://weibo.com/${uid}/`,
description: `${name}的微博`,
lastBuildDate: new Date().toUTCString(),
item: data.data.cards.filter((item) => item.mblog && !item.mblog.isTop).map((item) => {
const title = item.mblog.text.replace(/<.*?>/g, '');
return {
title: title.length > 24 ? title.slice(0, 24) + '...' : title,
description: format(item.mblog),
pubDate: new Date(item.mblog.created_at.length === 5 ? `${new Date().getFullYear()}-${item.mblog.created_at}` : item.mblog.created_at).toUTCString(),
link: `https://weibo.com/${uid}/${item.mblog.bid}`
};
}),
});
callback(html);
});
});
const containerResponse = await axios({
method: 'get',
url: `https://m.weibo.cn/api/container/getIndex?type=uid&value=${uid}`,
headers: {
'User-Agent': config.ua,
'Referer': 'https://m.weibo.cn/'
}
});
const name = containerResponse.data.data.userInfo.screen_name;
const containerid = containerResponse.data.data.tabsInfo.tabs[1].containerid;
const response = await axios({
method: 'get',
url: `https://m.weibo.cn/api/container/getIndex?type=uid&value=${uid}&containerid=${containerid}`,
headers: {
'User-Agent': config.ua,
'Referer': `https://m.weibo.cn/u/${uid}`
}
});
ctx.body = art(path.resolve(__dirname, '../../views/rss.art'), {
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 {
title: title.length > 24 ? title.slice(0, 24) + '...' : title,
description: format(item.mblog),
pubDate: new Date(item.mblog.created_at.length === 5 ? `${new Date().getFullYear()}-${item.mblog.created_at}` : item.mblog.created_at).toUTCString(),
link: `https://weibo.com/${uid}/${item.mblog.bid}`
};
}),
});
next();
};
+31 -34
View File
@@ -1,42 +1,39 @@
const request = require('request');
const axios = require('axios');
const art = require('art-template');
const path = require('path');
const cheerio = require('cheerio');
const base = require('../base');
const mix = require('../../utils/mix');
const config = require('../../config');
module.exports = (req, res) => {
const id = req.params.id;
module.exports = async (ctx, next) => {
const id = ctx.params.id;
base({
req: req,
res: res,
getHTML: (callback) => {
request.get({
url: `https://www.zhihu.com/collection/${id}`,
headers: {
'User-Agent': mix.ua,
'Referer': `https://www.zhihu.com/collection/${id}`
}
}, (err, httpResponse, body) => {
const $ = cheerio.load(body);
const list = $('div.zm-item');
const html = art(path.resolve(__dirname, '../../views/rss.art'), {
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);
return {
title: item.find('.zm-item-title a').text(),
description: `内容:${item.find('textarea').text()}`,
link: `https://www.zhihu.com${item.find('.zm-item-title a').attr('href')}`
};
}).get(),
});
callback(html);
});
const response = await axios({
method: 'get',
url: `https://www.zhihu.com/collection/${id}`,
headers: {
'User-Agent': config.ua,
'Referer': `https://www.zhihu.com/collection/${id}`
}
});
const data = response.data;
const $ = cheerio.load(data);
const list = $('div.zm-item');
ctx.body = art(path.resolve(__dirname, '../../views/rss.art'), {
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);
return {
title: item.find('.zm-item-title a').text(),
description: `内容:${item.find('textarea').text()}`,
link: `https://www.zhihu.com${item.find('.zm-item-title a').attr('href')}`
};
}).get(),
});
next();
};
+39 -50
View File
@@ -1,57 +1,46 @@
const request = require('request');
const axios = require('axios');
const qs = require('querystring');
const art = require('art-template');
const path = require('path');
const base = require('../base');
const mix = require('../../utils/mix');
const config = require('../../config');
module.exports = (req, res) => {
const city = req.params.city || 'sh';
const keyword = req.params.keyword || '';
const iswhole = req.params.iswhole || 0;
const room = req.params.room || 1;
module.exports = async (ctx, next) => {
const city = ctx.params.city || 'sh';
const keyword = ctx.params.keyword || '';
const iswhole = ctx.params.iswhole || 0;
const room = ctx.params.room || 1;
const domain = `${city === 'bj' ? '' : city + '.'}m.ziroom.com`;
base({
req: req,
res: res,
getHTML: (callback) => {
request.post({
url: `http://${domain}/list/ajax-get-data`,
headers: {
'User-Agent': mix.ua,
'Referer': `http://${domain}/${city.toUpperCase()}/search.html`
},
form: {
'recent_money': 0,
'sort': 0,
'is_whole': iswhole,
'room': room,
'key_word': keyword,
'step': 0
}
}, (err, httpResponse, body) => {
let data;
try {
data = JSON.parse(body);
}
catch (e) {
data = {};
}
const result = data.data || [];
const html = art(path.resolve(__dirname, '../../views/rss.art'), {
title: `自如的${keyword}${iswhole ? '整租' : '合租'}${room}室房源`,
link: `http://${domain}`,
description: `自如的${keyword}${iswhole ? '整租' : '合租'}${room}室房源`,
lastBuildDate: new Date().toUTCString(),
item: result && result.map((item) => ({
title: item.title,
description: `${item.room_name}<img referrerpolicy="no-referrer" src="${item.list_img}">`,
link: `http://${domain}/${city.toUpperCase()}/room/${item.id}.html`
})),
});
callback(html);
});
}
const response = await axios({
method: 'post',
url: `http://${domain}/list/ajax-get-data`,
headers: {
'User-Agent': config.ua,
'Referer': `http://${domain}/${city.toUpperCase()}/search.html`
},
data: qs.stringify({
'recent_money': 0,
'sort': 0,
'is_whole': iswhole,
'room': room,
'key_word': keyword,
'step': 0
}),
});
const data = response.data.data;
ctx.body = art(path.resolve(__dirname, '../../views/rss.art'), {
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}">`,
link: `http://${domain}/${city.toUpperCase()}/room/${item.id}.html`
})),
});
next();
};
-7
View File
@@ -1,7 +0,0 @@
module.exports = {
getIp: (req) => req.headers['x-forwarded-for'] ||
req.connection.remoteAddress ||
req.socket.remoteAddress ||
req.connection.socket.remoteAddress,
ua: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36',
};
-29
View File
@@ -1,29 +0,0 @@
const logger = require('./logger');
const redis = require('redis');
let client;
if (process.env.REDIS_PORT_6379_TCP_ADDR && process.env.REDIS_PORT_6379_TCP_PORT) {
client = redis.createClient({
host: process.env.REDIS_PORT_6379_TCP_ADDR,
port: process.env.REDIS_PORT_6379_TCP_PORT
});
}
else {
client = redis.createClient();
}
client.on('error', (err) => {
logger.error('Redis Error ' + err);
});
module.exports = {
set: (key, value, time = 5 * 60) => {
client.set(key, value, 'EX', time);
logger.info('Redis Set: ' + key);
},
get: (key, callback) => {
client.get(key, (err, reply) => {
callback(reply);
});
},
client: client
};
+1 -1
View File
@@ -3,7 +3,7 @@
<channel>
<title><![CDATA[{{ title || 'RSSHub' }}]]></title>
<link>{{ link }}</link>
<description><![CDATA[{{ description }} - 使用 RSSHub(https://github.com/DIYgod/RSSHub) 构建]]></description>
<description><![CDATA[{{ description || title }} - 使用 RSSHub(https://github.com/DIYgod/RSSHub) 构建]]></description>
<generator>RSSHub</generator>
<webMaster>i@html.love</webMaster>
<language>zh-cn</language>
+187 -477
View File
File diff suppressed because it is too large Load Diff