Merge branch 'master' of https://github.com/zytomorrow/RSSHub
This commit is contained in:
commit
cbe1088bb2
|
|
@ -104,6 +104,35 @@ $ docker run -d --name rsshub -p 1200:1200 -e CACHE_EXPIRE=3600 -e GITHUB_ACCESS
|
|||
|
||||
To configure more options please refer to [Configuration](#configuration).
|
||||
|
||||
# Ansible Deployment
|
||||
|
||||
This Ansible playbook includes RSSHub, Redis, browserless (uses Docker) and Caddy 2
|
||||
|
||||
Currently only support Ubuntu 20.04
|
||||
|
||||
Requires sudo privilege and virtualization capability (Docker will be automatically installed)
|
||||
|
||||
### Install
|
||||
|
||||
```bash
|
||||
sudo apt update
|
||||
sudo apt install ansible
|
||||
git clone https://github.com/DIYgod/RSSHub.git ~/RSSHub
|
||||
cd ~/RSSHub/scripts/ansible
|
||||
sudo ansible-playbook rsshub.yaml
|
||||
# When prompt to enter a domain name, enter the domain name that this machine/VM will use
|
||||
# For example, if your users use https://rsshub.exmaple.com to access your RSSHub instance, enter rsshub.exmaple.com (remove the https://)
|
||||
```
|
||||
|
||||
### Update
|
||||
|
||||
```bash
|
||||
cd ~/RSSHub/scripts/ansible
|
||||
sudo ansible-playbook rsshub.yaml
|
||||
# When prompt to enter a domain name, enter the domain name that this machine/VM will use
|
||||
# For example, if your users use https://rsshub.exmaple.com to access your RSSHub instance, enter rsshub.exmaple.com (remove the https://)
|
||||
```
|
||||
|
||||
## Manual Deployment
|
||||
|
||||
The most direct way to deploy `RSSHub`, you can follow the steps below to deploy`RSSHub` on your computer, server or anywhere.
|
||||
|
|
|
|||
|
|
@ -67,6 +67,10 @@ Compared to the official one, the RSS feed generated by RSSHub not only has more
|
|||
|
||||
## CGTN
|
||||
|
||||
### Opinions
|
||||
|
||||
<RouteEn author="nczitzk" example="/cgtn/opinions" path="/cgtn/opinions"/>
|
||||
|
||||
### Most Read & Most Share
|
||||
|
||||
<RouteEn author="nczitzk" example="/cgtn/most/read/day" path="/cgtn/most/:type?/:time?" :paramsDesc="['Type, `read` as most read, `share` as most share, `read` by default', 'Time range, `all` as all the time, `day` as today, `week` as this week, `month` as this month, `year` as this year, `all` by default']"/>
|
||||
|
|
|
|||
|
|
@ -164,6 +164,12 @@ The owner of the official image fills in the library, for example: https://rsshu
|
|||
|
||||
<RouteEn author="hoilc" example="/edge/addon/gangkeiaobmjcjokiofpkfpcobpbmnln" path="/edge/addon/:crxid" :paramsDesc="['Addon id, can be found in addon url']"/>
|
||||
|
||||
## Microsoft Store
|
||||
|
||||
### Updates
|
||||
|
||||
<Route author="hellodword" example="/microsoft-store/updates/9WZDNCRFHVN5/CN" path="/microsoft-store/updates/:productid/:market?" :paramsDesc="['`Share` - `Copy Link` in the Store', '`CN` as default']" />
|
||||
|
||||
## Minecraft
|
||||
|
||||
Refer to [#minecraft](/en/game.html#minecraft)
|
||||
|
|
|
|||
|
|
@ -149,6 +149,18 @@ Generates full-text feeds that the official feed doesn't provide.
|
|||
|
||||
<RouteEn author="oppliate" example="/phoronix/news_topic/Intel" path="/phoronix/:page/:queryOrItem?" :paramsDesc="['Page name', 'For `category` it corresponds to `item`, for other pages it\'s `q`. You may find available parameters from their navigator links. E.g. to subscribe to the category page `https://www.phoronix.com/scan.php?page=category&item=Computers`, fill in the path `/phoronix/category/Computers`']" />
|
||||
|
||||
## Radio Free Asia (RFA)
|
||||
|
||||
<RouteEn author="zphw" example="/rfa/english" path="/rfa/:language?/:channel?/:subChannel?" :paramsDesc="['language, English by default', 'channel', 'subchannel, where applicable']" />
|
||||
|
||||
Delivers a better experience by supporting parameter specification.
|
||||
|
||||
Parameters can be obtained from the official website, for instance:
|
||||
|
||||
`https://www.rfa.org/cantonese/news` corresponds to `/rfa/cantonese/news`
|
||||
|
||||
`https://www.rfa.org/cantonese/news/htm` corresponds to `/rfa/cantonese/news/htm`
|
||||
|
||||
## Reuters
|
||||
|
||||
### Channel
|
||||
|
|
|
|||
|
|
@ -106,6 +106,35 @@ $ docker run -d --name rsshub -p 1200:1200 -e CACHE_EXPIRE=3600 -e GITHUB_ACCESS
|
|||
|
||||
更多配置项请看 [#配置](#pei-zhi)
|
||||
|
||||
## Ansible 部署
|
||||
|
||||
这个 Ansible playbook 包括了 RSSHub, Redis, browserless (依赖 Docker) 以及 Caddy 2
|
||||
|
||||
目前只支持 Ubuntu 20.04
|
||||
|
||||
需要 sudo 权限和虚拟化能力(Docker 将会被自动安装)
|
||||
|
||||
### 安装
|
||||
|
||||
```bash
|
||||
sudo apt update
|
||||
sudo apt install ansible
|
||||
git clone https://github.com/DIYgod/RSSHub.git ~/RSSHub
|
||||
cd ~/RSSHub/scripts/ansible
|
||||
sudo ansible-playbook rsshub.yaml
|
||||
# 当提示输入 domain name 的时候,输入该主机所使用的域名
|
||||
# 举例:如果您的 RSSHub 用户使用 https://rsshub.exmaple.com 访问您的 RSSHub 实例,输入 rsshub.exmaple.com(去掉 https://)
|
||||
```
|
||||
|
||||
### 更新
|
||||
|
||||
```bash
|
||||
cd ~/RSSHub/scripts/ansible
|
||||
sudo ansible-playbook rsshub.yaml
|
||||
# 当提示输入 domain name 的时候,输入该主机所使用的域名
|
||||
# 举例:如果您的 RSSHub 用户使用 https://rsshub.exmaple.com 访问您的 RSSHub 实例,输入 rsshub.exmaple.com(去掉 https://)
|
||||
```
|
||||
|
||||
## 手动部署
|
||||
|
||||
部署 `RSSHub` 最直接的方式,您可以按照以下步骤将 `RSSHub` 部署在您的电脑、服务器或者其他任何地方
|
||||
|
|
@ -619,3 +648,8 @@ RSSHub 支持使用访问密钥 / 码,白名单和黑名单三种方式进行
|
|||
|
||||
- `DIDA365_USERNAME`: 滴答清单用户名
|
||||
- `DIDA365_PASSWORD`: 滴答清单密码
|
||||
|
||||
- 知乎用户关注时间线
|
||||
|
||||
- `ZHIHU_COOKIES`: 知乎登录后的 cookie 值.
|
||||
1. 可以在知乎网页版的一些请求的请求头中找到,如 `GET /moments` 请求头中的 `cookie` 值.
|
||||
|
|
|
|||
|
|
@ -122,6 +122,10 @@ pageClass: routes
|
|||
|
||||
## CGTN
|
||||
|
||||
### Opinions
|
||||
|
||||
<Route author="nczitzk" example="/cgtn/opinions" path="/cgtn/opinions"/>
|
||||
|
||||
### Most Read & Most Share
|
||||
|
||||
<Route author="nczitzk" example="/cgtn/most/read/day" path="/cgtn/most/:type?/:time?" :paramsDesc="['类型,`read` 指最多阅读,`share` 指最多分享,默认为 `read`', '时间,`all` 指所有时间,`day` 指今天,`week` 指本周,`month` 指本月,`year` 指今年,默认为 `all`']"/>
|
||||
|
|
|
|||
|
|
@ -212,6 +212,12 @@ pageClass: routes
|
|||
|
||||
<Route author="hoilc" example="/edge/addon/gangkeiaobmjcjokiofpkfpcobpbmnln" path="/edge/addon/:crxid" :paramsDesc="['扩展 id, 可在扩展页 URL 中找到']" />
|
||||
|
||||
## Microsoft Store
|
||||
|
||||
### Updates
|
||||
|
||||
<Route author="hellodword" example="/microsoft-store/updates/9WZDNCRFHVN5/CN" path="/microsoft-store/updates/:productid/:market?" :paramsDesc="['在 Store 中点击 `分享` - `复制链接` 即可获得', '默认为 `CN`']" />
|
||||
|
||||
## Minecraft
|
||||
|
||||
见 [#minecraft](/game.html#minecraft)
|
||||
|
|
|
|||
|
|
@ -1141,3 +1141,12 @@ rule
|
|||
### 知乎书店 - 知乎周刊
|
||||
|
||||
<Route author="LogicJake" example="/zhihu/weekly" path="/zhihu/weekly" anticrawler="1" radar="1" rssbud="1"/>
|
||||
|
||||
### 用户关注时间线
|
||||
|
||||
<Route author="SeanChao" example="/zhihu/timeline" path="/zhihu/timeline" anticrawler="1" selfhost="1"/>
|
||||
::: warning 注意
|
||||
|
||||
用户关注动态需要登录后的 Cookie 值,所以只能自建,详情见部署页面的配置模块。
|
||||
|
||||
:::
|
||||
|
|
|
|||
|
|
@ -965,3 +965,15 @@ category 对应的关键词有
|
|||
### 九江新闻
|
||||
|
||||
<Route author="jjlzg" example="/fjnews/jjnews" path="/fjnews/jjnews"/>
|
||||
|
||||
## 自由亚洲电台
|
||||
|
||||
<Route author="zphw" example="/rfa/mandarin" path="/rfa/:language?/:channel?/:subChannel?" :paramsDesc="['语言,默认 English', '频道', '子频道(如存在)']" />
|
||||
|
||||
通过指定频道参数,提供比官方源更佳的阅读体验。
|
||||
|
||||
参数均可在官网获取,如:
|
||||
|
||||
`https://www.rfa.org/cantonese/news` 对应 `/rfa/cantonese/news`
|
||||
|
||||
`https://www.rfa.org/cantonese/news/htm` 对应 `/rfa/cantonese/news/htm`
|
||||
|
|
|
|||
|
|
@ -89,6 +89,9 @@ const calculateValue = () => {
|
|||
yuque: {
|
||||
token: envs.YUQUE_TOKEN,
|
||||
},
|
||||
zhihu: {
|
||||
cookies: envs.ZHIHU_COOKIES,
|
||||
},
|
||||
puppeteerWSEndpoint: envs.PUPPETEER_WS_ENDPOINT,
|
||||
loggerLevel: envs.LOGGER_LEVEL || 'info',
|
||||
proxyUri: envs.PROXY_URI,
|
||||
|
|
|
|||
|
|
@ -158,6 +158,7 @@ router.get('/zhihu/people/pins/:id', require('./routes/zhihu/pin/people'));
|
|||
router.get('/zhihu/bookstore/newest', require('./routes/zhihu/bookstore/newest'));
|
||||
router.get('/zhihu/pin/daily', require('./routes/zhihu/pin/daily'));
|
||||
router.get('/zhihu/weekly', require('./routes/zhihu/weekly'));
|
||||
router.get('/zhihu/timeline', require('./routes/zhihu/timeline'));
|
||||
|
||||
// 妹子图
|
||||
router.get('/mzitu/home/:type?', require('./routes/mzitu/home'));
|
||||
|
|
@ -2852,6 +2853,9 @@ router.get('/xposed/module/:mod', require('./routes/xposed/module'));
|
|||
// Microsoft Edge
|
||||
router.get('/edge/addon/:crxid', require('./routes/edge/addon'));
|
||||
|
||||
// Microsoft Store
|
||||
router.get('/microsoft-store/updates/:productid/:market?', require('./routes/microsoft-store/updates'));
|
||||
|
||||
// 上海立信会计金融学院
|
||||
router.get('/slu/tzgg/:id', require('./routes/universities/slu/tzgg'));
|
||||
router.get('/slu/jwc/:id', require('./routes/universities/slu/jwc'));
|
||||
|
|
@ -3338,6 +3342,7 @@ router.get('/fulinian/:caty?', require('./routes/fulinian/index'));
|
|||
|
||||
// CGTN
|
||||
router.get('/cgtn/most/:type?/:time?', require('./routes/cgtn/most'));
|
||||
router.get('/cgtn/opinions', require('./routes/cgtn/opinions'));
|
||||
|
||||
// AppSales
|
||||
router.get('/appsales/:caty?/:time?', require('./routes/appsales/index'));
|
||||
|
|
@ -3782,8 +3787,10 @@ router.get('/caixin/latest', require('./routes/caixin/latest'));
|
|||
|
||||
// SimpRead-消息通知
|
||||
router.get('/simpread/notice', require('./routes/simpread/notice'));
|
||||
|
||||
// SimpRead-更新日志
|
||||
router.get('/simpread/changelog', require('./routes/simpread/changelog'));
|
||||
|
||||
// Radio Free Asia
|
||||
router.get('/rfa/:language?/:channel?/:subChannel?', require('./routes/rfa/index'));
|
||||
|
||||
module.exports = router;
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
const got = require('@/utils/got');
|
||||
const cheerio = require('cheerio');
|
||||
|
||||
module.exports = async (ctx) => {
|
||||
const response = await got({
|
||||
|
|
@ -12,15 +13,33 @@ module.exports = async (ctx) => {
|
|||
|
||||
const data = response.data.data.list;
|
||||
|
||||
const items = await Promise.all(
|
||||
data.map(async (item) => {
|
||||
const link = item.web_url;
|
||||
const summary = `<blockquote><p>${item.summary}</p></blockquote><img src="${item.pics}">`;
|
||||
|
||||
const fullText = await ctx.cache.tryGet(link, async () => {
|
||||
const result = await got.get(link);
|
||||
|
||||
const $ = cheerio.load(result.data);
|
||||
|
||||
return $('#Main_Content_Val').html();
|
||||
});
|
||||
|
||||
return {
|
||||
title: item.title,
|
||||
description: fullText ? summary + fullText : summary,
|
||||
link: link,
|
||||
pubDate: new Date(item.time * 1000),
|
||||
author: item.author_name,
|
||||
};
|
||||
})
|
||||
);
|
||||
|
||||
ctx.state.data = {
|
||||
title: `财新网 - 首页`,
|
||||
link: `http://www.caixin.com/`,
|
||||
description: '财新网 - 首页',
|
||||
item: data.map((item) => ({
|
||||
title: item.title,
|
||||
description: `<p>${item.summary}</p><img src="${item.pics}">`,
|
||||
link: item.web_url,
|
||||
pubDate: new Date(item.time * 1000),
|
||||
})),
|
||||
item: items,
|
||||
};
|
||||
};
|
||||
|
|
|
|||
|
|
@ -0,0 +1,51 @@
|
|||
const got = require('@/utils/got');
|
||||
const cheerio = require('cheerio');
|
||||
|
||||
module.exports = async (ctx) => {
|
||||
const rootUrl = `https://www.cgtn.com/opinions`;
|
||||
const response = await got({
|
||||
method: 'get',
|
||||
url: rootUrl,
|
||||
});
|
||||
|
||||
const $ = cheerio.load(response.data);
|
||||
|
||||
$('.cg-pic').parent().remove();
|
||||
|
||||
const list = $(`.cg-title h4`)
|
||||
.slice(0, 15)
|
||||
.map((_, item) => {
|
||||
item = $(item);
|
||||
const a = item.find('a');
|
||||
return {
|
||||
title: a.text(),
|
||||
link: a.attr('href'),
|
||||
pubDate: new Date(parseInt(a.attr('data-time'))).toUTCString(),
|
||||
};
|
||||
})
|
||||
.get();
|
||||
|
||||
const items = await Promise.all(
|
||||
list.map(
|
||||
async (item) =>
|
||||
await ctx.cache.tryGet(item.link, async () => {
|
||||
const detailResponse = await got({
|
||||
method: 'get',
|
||||
url: item.link,
|
||||
});
|
||||
const content = cheerio.load(detailResponse.data);
|
||||
|
||||
item.author = content('.news-author-name').text();
|
||||
item.description = content('#cmsMainContent').html();
|
||||
|
||||
return item;
|
||||
})
|
||||
)
|
||||
);
|
||||
|
||||
ctx.state.data = {
|
||||
title: 'CGTN - Opinions',
|
||||
link: rootUrl,
|
||||
item: items,
|
||||
};
|
||||
};
|
||||
|
|
@ -1,19 +1,32 @@
|
|||
const got = require('@/utils/got');
|
||||
const cheerio = require('cheerio');
|
||||
|
||||
module.exports = async (ctx) => {
|
||||
const response = await got({
|
||||
method: 'get',
|
||||
url: 'https://api.douban.com/v2/movie/coming_soon?apikey=0df993c66c0c636e29ecbb5344252a4a',
|
||||
url: 'https://movie.douban.com/cinema/later/beijing/',
|
||||
});
|
||||
const movieList = response.data.subjects;
|
||||
const $ = cheerio.load(response.data);
|
||||
|
||||
const item = $('#showing-soon .item')
|
||||
.map((index, ele) => {
|
||||
const description = $(ele).html();
|
||||
const name = $('h3', ele).text().trim();
|
||||
const date = $('ul li', ele).eq(0).text().trim();
|
||||
const type = $('ul li', ele).eq(1).text().trim();
|
||||
const link = $('a.thumb', ele).attr('href');
|
||||
|
||||
return {
|
||||
title: `${date} - 《${name}》 - ${type}`,
|
||||
link,
|
||||
description,
|
||||
};
|
||||
})
|
||||
.get();
|
||||
|
||||
ctx.state.data = {
|
||||
title: '即将上映的电影',
|
||||
link: 'https://movie.douban.com/cinema/later/',
|
||||
item: movieList.map((item) => ({
|
||||
title: item.title,
|
||||
description: `标题:${item.title}<br> 影片类型:${item.genres.join(' | ')} <br>评分:${item.rating.stars === '00' ? '无' : item.rating.average} <br/> <img src="${item.images.large}">`,
|
||||
link: item.alt,
|
||||
})),
|
||||
item,
|
||||
};
|
||||
};
|
||||
|
|
|
|||
|
|
@ -0,0 +1,32 @@
|
|||
const got = require('@/utils/got');
|
||||
|
||||
module.exports = async (ctx) => {
|
||||
const { market = 'CN', productid } = ctx.params;
|
||||
|
||||
const { data } = await got({
|
||||
method: 'get',
|
||||
url: `https://displaycatalog.mp.microsoft.com/v7.0/products/${productid}/?fieldsTemplate=&market=${market}&languages=en`,
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'MS-CV': `${Array(16)
|
||||
.join()
|
||||
.split(',')
|
||||
.map(function () {
|
||||
return 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'.charAt(Math.floor(Math.random() * 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'.length));
|
||||
})
|
||||
.join('')}.1`,
|
||||
},
|
||||
});
|
||||
|
||||
ctx.state.data = {
|
||||
title: `${data.Product.LocalizedProperties[0].ProductTitle} - Microsoft Store Updates`,
|
||||
link: `https://www.microsoft.com/store/productId/${productid}`,
|
||||
item: [
|
||||
{
|
||||
title: data.Product.DisplaySkuAvailabilities[0].Sku.Properties.Packages[0].PackageFullName,
|
||||
pubDate: new Date(data.Product.DisplaySkuAvailabilities[0].Sku.LastModifiedDate),
|
||||
link: `https://www.microsoft.com/store/productId/${productid}`,
|
||||
},
|
||||
],
|
||||
};
|
||||
};
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
const cheerio = require('cheerio');
|
||||
const got = require('@/utils/got');
|
||||
|
||||
module.exports = async (ctx) => {
|
||||
let url = 'https://www.rfa.org/' + (ctx.params.language || 'english');
|
||||
|
||||
if (ctx.params.channel) {
|
||||
url += '/' + ctx.params.channel;
|
||||
}
|
||||
if (ctx.params.subChannel) {
|
||||
url += '/' + ctx.params.subChannel;
|
||||
}
|
||||
|
||||
const response = await got.get(url);
|
||||
const $ = cheerio.load(response.data);
|
||||
|
||||
const selectors = ['div[id=topstorywidefulltease]', 'div.two_featured', 'div.three_featured', 'div.single_column_teaser', 'div.sectionteaser', 'div.specialwrap'];
|
||||
const list = [];
|
||||
selectors.forEach(function (selector) {
|
||||
$(selector).each(function (_, e) {
|
||||
const item = {};
|
||||
item.title = $(e).find('h2 a span').first().text();
|
||||
item.link = $(e).find('h2 a').first().attr('href');
|
||||
list.push(item);
|
||||
});
|
||||
});
|
||||
|
||||
const result = await Promise.all(
|
||||
list.map(
|
||||
async (item) =>
|
||||
await ctx.cache.tryGet(item.link, async () => {
|
||||
const content = await got.get(item.link);
|
||||
|
||||
const description = cheerio.load(content.data);
|
||||
item.description = description('div[id=storytext]').html();
|
||||
item.pubDate = new Date(description('span[id=story_date]').text()).toUTCString();
|
||||
return item;
|
||||
})
|
||||
)
|
||||
);
|
||||
|
||||
ctx.state.data = {
|
||||
title: 'RFA',
|
||||
link: 'https://www.rfa.org/',
|
||||
item: result,
|
||||
};
|
||||
};
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
const got = require('@/utils/got');
|
||||
const config = require('@/config').value;
|
||||
|
||||
module.exports = async (ctx) => {
|
||||
const cookie = config.zhihu.cookies;
|
||||
if (cookie === undefined) {
|
||||
throw Error('缺少知乎用户登录后的 Cookie 值');
|
||||
}
|
||||
|
||||
const response = await got({
|
||||
method: 'get',
|
||||
url: `https://www.zhihu.com/api/v3/moments?limit=10`,
|
||||
headers: {
|
||||
Cookie: cookie,
|
||||
},
|
||||
});
|
||||
const feeds = response.data.data;
|
||||
|
||||
const out = feeds.map((e) => ({
|
||||
title: `${e.action_text}: ${e.target.title ? e.target.title : e.target.question.title}`,
|
||||
description: `${e.target.excerpt}`,
|
||||
pubDate: new Date(e.updated_time * 1000),
|
||||
link: e.target.url.replace('api.zhihu.com', 'zhihu.com'),
|
||||
author: e.target.author.name,
|
||||
guid: e.id,
|
||||
}));
|
||||
|
||||
ctx.state.data = {
|
||||
title: `知乎关注动态`,
|
||||
link: `https://www.zhihu.com/follow`,
|
||||
item: out,
|
||||
};
|
||||
};
|
||||
|
|
@ -48,7 +48,7 @@
|
|||
"jest": "26.6.3",
|
||||
"mockdate": "3.0.2",
|
||||
"nock": "13.0.5",
|
||||
"nodemon": "2.0.6",
|
||||
"nodemon": "2.0.7",
|
||||
"pinyin": "2.9.1",
|
||||
"prettier": "2.2.1",
|
||||
"prettier-check": "2.0.0",
|
||||
|
|
@ -75,14 +75,14 @@
|
|||
"co-redis": "2.1.1",
|
||||
"crypto-js": "4.0.0",
|
||||
"currency-symbol-map": "4.0.4",
|
||||
"dayjs": "1.10.2",
|
||||
"dayjs": "1.10.3",
|
||||
"dotenv": "8.2.0",
|
||||
"emailjs-imap-client": "3.1.0",
|
||||
"entities": "2.1.0",
|
||||
"etag": "1.8.1",
|
||||
"fanfou-sdk": "4.2.0",
|
||||
"git-rev-sync": "3.0.1",
|
||||
"googleapis": "66.0.0",
|
||||
"googleapis": "67.0.0",
|
||||
"got": "11.8.1",
|
||||
"https-proxy-agent": "5.0.0",
|
||||
"iconv-lite": "0.6.2",
|
||||
|
|
|
|||
|
|
@ -0,0 +1,90 @@
|
|||
# Created by https://www.toptal.com/developers/gitignore/api/windows,linux,macos,ansible,vagrant
|
||||
# Edit at https://www.toptal.com/developers/gitignore?templates=windows,linux,macos,ansible,vagrant
|
||||
|
||||
### Ansible ###
|
||||
*.retry
|
||||
|
||||
### Linux ###
|
||||
*~
|
||||
|
||||
# temporary files which can be created if a process still has a handle open of a deleted file
|
||||
.fuse_hidden*
|
||||
|
||||
# KDE directory preferences
|
||||
.directory
|
||||
|
||||
# Linux trash folder which might appear on any partition or disk
|
||||
.Trash-*
|
||||
|
||||
# .nfs files are created when an open file is removed but is still being accessed
|
||||
.nfs*
|
||||
|
||||
### macOS ###
|
||||
# General
|
||||
.DS_Store
|
||||
.AppleDouble
|
||||
.LSOverride
|
||||
|
||||
# Icon must end with two \r
|
||||
Icon
|
||||
|
||||
|
||||
# Thumbnails
|
||||
._*
|
||||
|
||||
# Files that might appear in the root of a volume
|
||||
.DocumentRevisions-V100
|
||||
.fseventsd
|
||||
.Spotlight-V100
|
||||
.TemporaryItems
|
||||
.Trashes
|
||||
.VolumeIcon.icns
|
||||
.com.apple.timemachine.donotpresent
|
||||
|
||||
# Directories potentially created on remote AFP share
|
||||
.AppleDB
|
||||
.AppleDesktop
|
||||
Network Trash Folder
|
||||
Temporary Items
|
||||
.apdisk
|
||||
|
||||
### Vagrant ###
|
||||
# General
|
||||
.vagrant/
|
||||
|
||||
# Log files (if you are creating logs in debug mode, uncomment this)
|
||||
# *.log
|
||||
|
||||
### Vagrant Patch ###
|
||||
*.box
|
||||
|
||||
### Windows ###
|
||||
# Windows thumbnail cache files
|
||||
Thumbs.db
|
||||
Thumbs.db:encryptable
|
||||
ehthumbs.db
|
||||
ehthumbs_vista.db
|
||||
|
||||
# Dump file
|
||||
*.stackdump
|
||||
|
||||
# Folder config file
|
||||
[Dd]esktop.ini
|
||||
|
||||
# Recycle Bin used on file shares
|
||||
$RECYCLE.BIN/
|
||||
|
||||
# Windows Installer files
|
||||
*.cab
|
||||
*.msi
|
||||
*.msix
|
||||
*.msm
|
||||
*.msp
|
||||
|
||||
# Windows shortcuts
|
||||
*.lnk
|
||||
|
||||
# End of https://www.toptal.com/developers/gitignore/api/windows,linux,macos,ansible,vagrant
|
||||
|
||||
# vagrant logs
|
||||
*.log
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
# Readme
|
||||
|
||||
Ansible playbook to deploy [RSSHub](https://github.com/DIYgod/RSSHub) on bare-metal with Redis, browserless and Caddy 2
|
||||
|
||||
Requires sudo permission
|
||||
|
||||
## Usage
|
||||
On `Ubuntu 20.04`, [install ansible](https://www.digitalocean.com/community/tutorials/how-to-install-and-configure-ansible-on-ubuntu-20-04), then
|
||||
|
||||
```bash
|
||||
sudo ansible-playbook rsshub.yaml
|
||||
```
|
||||
|
||||
## Development
|
||||
Install `vagrant`, then
|
||||
|
||||
```bash
|
||||
./try.sh
|
||||
ansible-playbook rsshub.yaml
|
||||
```
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
Vagrant.configure("2") do |config|
|
||||
config.vm.box = "generic/ubuntu2004"
|
||||
config.vm.synced_folder ".", "/vagrant", type: "rsync", rsync__exclude: ".git/"
|
||||
config.ssh.extra_args = ["-t", "cd /vagrant; bash --login"]
|
||||
end
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
{{ domain_name }}
|
||||
|
||||
reverse_proxy localhost:1200
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
NODE_ENV=production
|
||||
CACHE_TYPE=redis
|
||||
PUPPETEER_WS_ENDPOINT=ws://localhost:3000
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
[Unit]
|
||||
Description=RSSHub is an open source, easy to use, and extensible RSS feed aggregator
|
||||
|
||||
[Service]
|
||||
User=rsshub
|
||||
WorkingDirectory=/home/rsshub/app
|
||||
ExecStart=yarn start
|
||||
EnvironmentFile=/home/rsshub/app/.env
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
|
|
@ -0,0 +1,130 @@
|
|||
-
|
||||
name: Install RSSHub
|
||||
hosts: localhost
|
||||
become: true
|
||||
vars_prompt:
|
||||
-
|
||||
name: domain_name
|
||||
prompt: What is the domain name (without www, e.g. rsshub.example.com)? Use "http://localhost" for development in Vagrant VM.
|
||||
private: no
|
||||
tasks:
|
||||
-
|
||||
name: Check OS
|
||||
fail:
|
||||
msg: This playbook can only be run on Ubuntu 20.04 at this moment
|
||||
when: ansible_distribution != 'Ubuntu' or ansible_distribution_version !='20.04'
|
||||
-
|
||||
name: Install GPG keys for repos
|
||||
apt_key:
|
||||
url: '{{ item }}'
|
||||
state: present
|
||||
with_items:
|
||||
- https://deb.nodesource.com/gpgkey/nodesource.gpg.key
|
||||
- https://dl.yarnpkg.com/debian/pubkey.gpg
|
||||
- https://download.docker.com/linux/ubuntu/gpg
|
||||
- https://dl.cloudsmith.io/public/caddy/stable/cfg/gpg/gpg.155B6D79CA56EA34.key
|
||||
-
|
||||
name: Install repos
|
||||
apt_repository:
|
||||
repo: '{{ item }}'
|
||||
state: present
|
||||
update_cache: yes
|
||||
with_items:
|
||||
- deb https://deb.nodesource.com/node_12.x focal main
|
||||
- deb https://dl.yarnpkg.com/debian/ stable main
|
||||
- deb https://download.docker.com/linux/ubuntu focal stable
|
||||
- deb https://dl.cloudsmith.io/public/caddy/stable/deb/debian any-version main
|
||||
-
|
||||
name: Install prerequisites
|
||||
apt:
|
||||
name:
|
||||
- nodejs
|
||||
- yarn
|
||||
- build-essential
|
||||
- python-is-python2
|
||||
- redis-server
|
||||
- docker-ce
|
||||
- python3-pip
|
||||
- virtualenv
|
||||
- python3-setuptools
|
||||
- caddy
|
||||
state: present
|
||||
update_cache: yes
|
||||
-
|
||||
name: Install python module for docker
|
||||
pip:
|
||||
name: docker
|
||||
-
|
||||
name: Pull docker image for browserless
|
||||
docker_image:
|
||||
name: browserless/chrome
|
||||
source: pull
|
||||
-
|
||||
name: Start redis
|
||||
systemd:
|
||||
state: restarted
|
||||
enabled: yes
|
||||
name: redis
|
||||
daemon_reload: yes
|
||||
-
|
||||
name: Copy caddy configuration
|
||||
template:
|
||||
src: rsshub.Caddyfile
|
||||
dest: /etc/caddy/Caddyfile
|
||||
-
|
||||
name: Start caddy
|
||||
systemd:
|
||||
state: restarted
|
||||
enabled: yes
|
||||
name: caddy
|
||||
daemon_reload: yes
|
||||
-
|
||||
name: Create and start browserless container
|
||||
docker_container:
|
||||
name: browserless
|
||||
image: browserless/chrome
|
||||
state: started
|
||||
restart_policy: always
|
||||
published_ports:
|
||||
- "3000:3000"
|
||||
-
|
||||
name: Create the user
|
||||
user:
|
||||
name: rsshub
|
||||
create_home: true
|
||||
shell: /bin/bash
|
||||
-
|
||||
name: Clone the repo
|
||||
git:
|
||||
repo: https://github.com/DIYgod/RSSHub.git
|
||||
dest: /home/rsshub/app
|
||||
update: yes
|
||||
-
|
||||
name: Install repo dependencies
|
||||
command: yarn install --production
|
||||
args:
|
||||
chdir: /home/rsshub/app
|
||||
-
|
||||
name: Copy configuration
|
||||
copy:
|
||||
src: rsshub.env
|
||||
dest: /home/rsshub/app/.env
|
||||
-
|
||||
name: Own repo to the user
|
||||
file:
|
||||
path: /home/rsshub/app
|
||||
owner: rsshub
|
||||
group: rsshub
|
||||
recurse: yes
|
||||
-
|
||||
name: Install the systemd unit
|
||||
copy:
|
||||
src: rsshub.service
|
||||
dest: /etc/systemd/system/rsshub.service
|
||||
-
|
||||
name: Start the systemd service
|
||||
systemd:
|
||||
state: restarted
|
||||
enabled: yes
|
||||
name: rsshub
|
||||
daemon_reload: yes
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
vagrant rsync
|
||||
vagrant ssh
|
||||
30
yarn.lock
30
yarn.lock
|
|
@ -4304,10 +4304,10 @@ date-now@^0.1.4:
|
|||
resolved "https://registry.yarnpkg.com/date-now/-/date-now-0.1.4.tgz#eaf439fd4d4848ad74e5cc7dbef200672b9e345b"
|
||||
integrity sha1-6vQ5/U1ISK105cx9vvIAZyueNFs=
|
||||
|
||||
dayjs@1.10.2, dayjs@^1.8.29:
|
||||
version "1.10.2"
|
||||
resolved "https://registry.yarnpkg.com/dayjs/-/dayjs-1.10.2.tgz#8f3a424ceb944a8193506804b0045a773d2d0672"
|
||||
integrity sha512-h/YtykNNTR8Qgtd1Fxl5J1/SFP1b7SOk/M1P+Re+bCdFMV0IMkuKNgHPN7rlvvuhfw24w0LX78iYKt4YmePJNQ==
|
||||
dayjs@1.10.3, dayjs@^1.8.29:
|
||||
version "1.10.3"
|
||||
resolved "https://registry.yarnpkg.com/dayjs/-/dayjs-1.10.3.tgz#cf3357c8e7f508432826371672ebf376cb7d619b"
|
||||
integrity sha512-/2fdLN987N8Ki7Id8BUN2nhuiRyxTLumQnSQf9CNncFCyqFsSKb9TNhzRYcC8K8eJSJOKvbvkImo/MKKhNi4iw==
|
||||
|
||||
de-indent@^1.0.2:
|
||||
version "1.0.2"
|
||||
|
|
@ -6077,10 +6077,10 @@ googleapis-common@^4.4.1:
|
|||
url-template "^2.0.8"
|
||||
uuid "^8.0.0"
|
||||
|
||||
googleapis@66.0.0:
|
||||
version "66.0.0"
|
||||
resolved "https://registry.yarnpkg.com/googleapis/-/googleapis-66.0.0.tgz#008062d06b13954bd3a0425c17e8f8396e884957"
|
||||
integrity sha512-jdEleRoyo/AeJZjKGC7Z2mHgochn2vR2JKqey6kydRkIBmCZxoQKLisRR4H8CRYZeEd6+c8Ns/LzS1S7qUjoFw==
|
||||
googleapis@67.0.0:
|
||||
version "67.0.0"
|
||||
resolved "https://registry.yarnpkg.com/googleapis/-/googleapis-67.0.0.tgz#ce0b92dcf5e4bc0fd1b82666a1625eb37fd3dc36"
|
||||
integrity sha512-luhulHrk42DruR+c12W2sY2rrEVoKVdjaZDuHWSxcp1qz+VxvWQpuiK2QDLCXmo36/VFPMaa+Y7rRUR+Qqzd7w==
|
||||
dependencies:
|
||||
google-auth-library "^6.0.0"
|
||||
googleapis-common "^4.4.1"
|
||||
|
|
@ -9197,10 +9197,10 @@ nodemailer@6.4.16:
|
|||
resolved "https://registry.yarnpkg.com/nodemailer/-/nodemailer-6.4.16.tgz#5cb6391b1d79ab7eff32d6f9f48366b5a7117293"
|
||||
integrity sha512-68K0LgZ6hmZ7PVmwL78gzNdjpj5viqBdFqKrTtr9bZbJYj6BRj5W6WGkxXrEnUl3Co3CBXi3CZBUlpV/foGnOQ==
|
||||
|
||||
nodemon@2.0.6:
|
||||
version "2.0.6"
|
||||
resolved "https://registry.yarnpkg.com/nodemon/-/nodemon-2.0.6.tgz#1abe1937b463aaf62f0d52e2b7eaadf28cc2240d"
|
||||
integrity sha512-4I3YDSKXg6ltYpcnZeHompqac4E6JeAMpGm8tJnB9Y3T0ehasLa4139dJOcCrB93HHrUMsCrKtoAlXTqT5n4AQ==
|
||||
nodemon@2.0.7:
|
||||
version "2.0.7"
|
||||
resolved "https://registry.yarnpkg.com/nodemon/-/nodemon-2.0.7.tgz#6f030a0a0ebe3ea1ba2a38f71bf9bab4841ced32"
|
||||
integrity sha512-XHzK69Awgnec9UzHr1kc8EomQh4sjTQ8oRf8TsGrSmHDx9/UmiGG9E/mM3BuTfNeFwdNBvrqQq/RHL0xIeyFOA==
|
||||
dependencies:
|
||||
chokidar "^3.2.2"
|
||||
debug "^3.2.6"
|
||||
|
|
@ -11977,9 +11977,9 @@ string-length@^4.0.1:
|
|||
strip-ansi "^6.0.0"
|
||||
|
||||
string-similarity@^4.0.3:
|
||||
version "4.0.3"
|
||||
resolved "https://registry.yarnpkg.com/string-similarity/-/string-similarity-4.0.3.tgz#ef52d6fc59c8a0fc93b6307fbbc08cc6e18cde21"
|
||||
integrity sha512-QEwJzNFCqq+5AGImk5z4vbsEPTN/+gtyKfXBVLBcbPBRPNganZGfQnIuf9yJ+GiwSnD65sT8xrw/uwU1Q1WmfQ==
|
||||
version "4.0.4"
|
||||
resolved "https://registry.yarnpkg.com/string-similarity/-/string-similarity-4.0.4.tgz#42d01ab0b34660ea8a018da8f56a3309bb8b2a5b"
|
||||
integrity sha512-/q/8Q4Bl4ZKAPjj8WerIBJWALKkaPRfrvhfF8k/B23i4nzrlRj2/go1m90In7nG/3XDSbOo0+pu6RvCTM9RGMQ==
|
||||
|
||||
string-width@4.2.0, string-width@^4.0.0, string-width@^4.2.0:
|
||||
version "4.2.0"
|
||||
|
|
|
|||
Loading…
Reference in New Issue