diff --git a/.github/ISSUE_TEMPLATE/rss_request_en.yml b/.github/ISSUE_TEMPLATE/rss_request_en.yml index a876130bebdf55..85ad25a14bb3a6 100644 --- a/.github/ISSUE_TEMPLATE/rss_request_en.yml +++ b/.github/ISSUE_TEMPLATE/rss_request_en.yml @@ -10,7 +10,7 @@ body: Please ensure the RSS proposal is not listed in [documentation](https://docs.rsshub.app/en) or [issue](https://github.com/DIYgod/RSSHub/issues), website doesn't provide this kind of RSS feed, and provide all the information required by this template. Otherwise the issue will be closed immediately. - We are flooded with feature requests and short-handed, please try to make it yourself, the [guide](https://docs.rsshub.app/en/joinus) is a good place to start. Submit a pull request when done! + We are flooded with feature requests and short-handed, please try to make it yourself, the [guide](https://docs.rsshub.app/joinus) is a good place to start. Submit a pull request when done! - type: dropdown id: category diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 412aa64ff59e3f..fb401f50abd56d 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -1,47 +1,49 @@ -## 该 PR 相关 Issue / Involved Issue +## Involved Issue / 该 PR 相关 Issue Close # -## 路由地址示例 / Example for the Proposed Route(s) +## Example for the Proposed Route(s) / 路由地址示例 ```routes ``` -## 新 RSS 路由检查表 / New RSS Route Checklist +## New RSS Route Checklist / 新 RSS 路由检查表 -- [ ] 新的路由 New Route - - [ ] 跟随 [v2 路由规范](https://docs.rsshub.app/joinus/advanced/script-standard) Follows [v2 Script Standard](https://docs.rsshub.app/en/joinus/advanced/script-standard) -- [ ] 文档说明 Documentation - - [ ] 中文文档 CN - - [ ] 英文文档 EN -- [ ] 全文获取 full article - - [ ] 使用缓存 Use cache -- [ ] 反爬/频率限制 anti-bot or rate limit? - - [ ] 如果有, 是否有对应的措施? If yes, do your code reflect this sign? -- [ ] [日期和时间](https://docs.rsshub.app/joinus/advanced/pub-date) [date and time](https://docs.rsshub.app/en/joinus/advanced/pub-date) - - [ ] 可以解析 Parsed - - [ ] 时区正确 Correct time zone -- [ ] 添加了新的包 New package added +- [ ] New Route / 新的路由 + - [ ] Follows [v2 Script Standard](https://docs.rsshub.app/joinus/advanced/script-standard) / 跟随 [v2 路由规范](https://docs.rsshub.app/zh/joinus/advanced/script-standard) +- [ ] Documentation / 文档说明 + - [ ] EN / 英文文档 + - [ ] CN / 中文文档 +- [ ] Full text / 全文获取 + - [ ] Use cache / 使用缓存 +- [ ] Anti-bot or rate limit / 反爬/频率限制 + - [ ] If yes, do your code reflect this sign? / 如果有, 是否有对应的措施? +- [ ] [Date and time](https://docs.rsshub.app/joinus/advanced/pub-date) / [日期和时间](https://docs.rsshub.app/zh/joinus/advanced/pub-date) + - [ ] Parsed / 可以解析 + - [ ] Correct time zone / 时区正确 +- [ ] New package added / 添加了新的包 - [ ] `Puppeteer` -## 说明 / Note +## Note / 说明 diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 2f604ddb30fb73..963776c93615e5 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,3 +1,3 @@ -## 请参见[参与我们](https://docs.rsshub.app/joinus/quick-start) +## 请参见[参与我们](https://docs.rsshub.app/zh/joinus/quick-start) -## Please refer to [Join Us](https://docs.rsshub.app/en/joinus/quick-start) +## Please refer to [Join Us](https://docs.rsshub.app/joinus/quick-start) diff --git a/README.md b/README.md index ab3f4ca466b187..eb5564d8b8b4b9 100644 --- a/README.md +++ b/README.md @@ -39,7 +39,7 @@ RSSHub 是一个开源、简单易用、易于扩展的 RSS 生成器,可以

-[![](https://opencollective.com/static/images/become_sponsor.svg)](https://docs.rsshub.app/en/support/) +[![](https://opencollective.com/static/images/become_sponsor.svg)](https://docs.rsshub.app/support/) ### Contributors @@ -62,21 +62,21 @@ Logo designer [sheldonrrr](https://dribbble.com/sheldonrrr) We welcome all pull requests. Suggestions and feedback are also welcomed [here](https://github.com/DIYgod/RSSHub/issues). -Refer to [Join Us](https://docs.rsshub.app/en/joinus/quick-start) +Refer to [Join Us](https://docs.rsshub.app/joinus/quick-start) -见 [参与我们](https://docs.rsshub.app/joinus/quick-start) +见 [参与我们](https://docs.rsshub.app/zh/joinus/quick-start) ## Deployment -Refer to [Deployment](https://docs.rsshub.app/en/install/) +Refer to [Deployment](https://docs.rsshub.app/install/) -见 [部署](https://docs.rsshub.app/install/) +见 [部署](https://docs.rsshub.app/zh/install/) ## Support RSSHub -Refer to [Support RSSHub](https://docs.rsshub.app/en/support/) +Refer to [Support RSSHub](https://docs.rsshub.app/support/) -见 [支持 RSSHub](https://docs.rsshub.app/support/) +见 [支持 RSSHub](https://docs.rsshub.app/zh/support/) RSSHub is open source and completely free under the MIT license. However, just like any other open source project, as the project grows, the hosting, development and maintenance requires funding support. diff --git a/assets/radar-rules.js b/assets/radar-rules.js index 72cb7a8e537f3a..c7ab64a7e63d17 100644 --- a/assets/radar-rules.js +++ b/assets/radar-rules.js @@ -100,7 +100,7 @@ }, 'alter-shanghai.cn': { _name: 'Alter', '.': [{ title: '新闻', docs: 'https://docs.rsshub.app/routes/shopping#alter-zhong-guo', source: '/cn/news', target: '/alter-cn/news' }] }, 'itslide.com': { _name: 'ITSlide', www: [{ title: '最新', docs: 'https://docs.rsshub.app/routes/programming#itslide', source: '/*', target: '/itslide/new' }] }, - 'leboncoin.fr': { _name: 'leboncoin', www: [{ title: 'ads', docs: 'https://docs.rsshub.app/routes/en/shopping#leboncoin', source: '/recherche', target: (params, url) => '/leboncoin/ad/' + url.split('?')[1] }] }, + 'leboncoin.fr': { _name: 'leboncoin', www: [{ title: 'ads', docs: 'https://docs.rsshub.app/routes/shopping#leboncoin', source: '/recherche', target: (params, url) => '/leboncoin/ad/' + url.split('?')[1] }] }, 'yuancheng.work': { _name: '远程.work', '.': [ @@ -312,13 +312,13 @@ 'umass.edu': { _name: 'UMASS Amherst', ece: [ - { title: 'ECE News', docs: 'http://docs.rsshub.app/en/routes/university#umass-amherst', source: '/news', target: '/umass/amherst/ecenews' }, - { title: 'ECE Seminar', docs: 'http://docs.rsshub.app/en/routes/university#umass-amherst', source: '/seminars', target: '/umass/amherst/eceseminar' }, + { title: 'ECE News', docs: 'http://docs.rsshub.app/routes/university#umass-amherst', source: '/news', target: '/umass/amherst/ecenews' }, + { title: 'ECE Seminar', docs: 'http://docs.rsshub.app/routes/university#umass-amherst', source: '/seminars', target: '/umass/amherst/eceseminar' }, ], - 'www.cics': [{ title: 'CICS News', docs: 'http://docs.rsshub.app/en/routes/university#umass-amherst', source: '/news', target: '/umass/amherst/csnews' }], + 'www.cics': [{ title: 'CICS News', docs: 'http://docs.rsshub.app/routes/university#umass-amherst', source: '/news', target: '/umass/amherst/csnews' }], www: [ - { title: 'IPO Events', docs: 'http://docs.rsshub.app/en/routes/university#umass-amherst', source: '/ipo/iss/events', target: '/umass/amherst/ipoevents' }, - { title: 'IPO Featured Stories', docs: 'http://docs.rsshub.app/en/routes/university#umass-amherst', source: '/ipo/iss/featured-stories', target: '/umass/amherst/ipostories' }, + { title: 'IPO Events', docs: 'http://docs.rsshub.app/routes/university#umass-amherst', source: '/ipo/iss/events', target: '/umass/amherst/ipoevents' }, + { title: 'IPO Featured Stories', docs: 'http://docs.rsshub.app/routes/university#umass-amherst', source: '/ipo/iss/featured-stories', target: '/umass/amherst/ipostories' }, ], }, 'bjeea.com': { diff --git a/lib/index.js b/lib/index.js index 8f62afb18ea396..cf7e0f63fc0097 100644 --- a/lib/index.js +++ b/lib/index.js @@ -29,7 +29,7 @@ if (config.enableCluster && cluster.isMaster && process.env.NODE_ENV !== 'test' } logger.info('🎉 RSSHub start! Cheers!'); - logger.info('💖 Can you help keep this open source project alive? Please sponsor 👉 https://docs.rsshub.app/en/support'); + logger.info('💖 Can you help keep this open source project alive? Please sponsor 👉 https://docs.rsshub.app/support'); module.exports = server; } diff --git a/lib/radar-rules.js b/lib/radar-rules.js index bb3c1ab9f57f04..43e5206b3cfc07 100644 --- a/lib/radar-rules.js +++ b/lib/radar-rules.js @@ -264,7 +264,7 @@ module.exports = { www: [ { title: 'ads', - docs: 'https://docs.rsshub.app/routes/en/shopping#leboncoin', + docs: 'https://docs.rsshub.app/routes/shopping#leboncoin', source: '/recherche', target: (params, url) => '/leboncoin/ad/' + url.split('?')[1], }, @@ -817,13 +817,13 @@ module.exports = { ece: [ { title: 'ECE News', - docs: 'http://docs.rsshub.app/en/routes/university#umass-amherst', + docs: 'http://docs.rsshub.app/routes/university#umass-amherst', source: '/news', target: '/umass/amherst/ecenews', }, { title: 'ECE Seminar', - docs: 'http://docs.rsshub.app/en/routes/university#umass-amherst', + docs: 'http://docs.rsshub.app/routes/university#umass-amherst', source: '/seminars', target: '/umass/amherst/eceseminar', }, @@ -831,7 +831,7 @@ module.exports = { 'www.cics': [ { title: 'CICS News', - docs: 'http://docs.rsshub.app/en/routes/university#umass-amherst', + docs: 'http://docs.rsshub.app/routes/university#umass-amherst', source: '/news', target: '/umass/amherst/csnews', }, @@ -839,13 +839,13 @@ module.exports = { www: [ { title: 'IPO Events', - docs: 'http://docs.rsshub.app/en/routes/university#umass-amherst', + docs: 'http://docs.rsshub.app/routes/university#umass-amherst', source: '/ipo/iss/events', target: '/umass/amherst/ipoevents', }, { title: 'IPO Featured Stories', - docs: 'http://docs.rsshub.app/en/routes/university#umass-amherst', + docs: 'http://docs.rsshub.app/routes/university#umass-amherst', source: '/ipo/iss/featured-stories', target: '/umass/amherst/ipostories', }, diff --git a/website/docs/.format/format.js b/website/docs/.format/format.js index a2535e8ee76859..bbe5b0291c6846 100644 --- a/website/docs/.format/format.js +++ b/website/docs/.format/format.js @@ -49,7 +49,7 @@ const loopNav = (nav, lang) => * Iterate config and build document object: * E.g. * { - path: 'docs/en/other.md', <-- full path here + path: 'docs/other.md', <-- full path here type: 'route', <--- Defined in file.js lang: 'en' <-- Defined in file.js } @@ -65,7 +65,7 @@ const buildFileList = async () => { .concat( config.guideSidebar[2].items.map((item) => ({ type: file.ROUTE_TYPE, - path: path.resolve(__dirname, '../../i18n/en/docusaurus-plugin-content-docs/current', `./${item}.md`), + path: path.resolve(__dirname, '../../i18n/docusaurus-plugin-content-docs/current', `./${item}.md`), lang: 'en-US', })) ); diff --git a/website/docs/.format/tojson.js b/website/docs/.format/tojson.js new file mode 100644 index 00000000000000..33ce7c6ee255fc --- /dev/null +++ b/website/docs/.format/tojson.js @@ -0,0 +1,132 @@ +const fs = require('fs'); + +function parse(data) { + const lines = data.split('\n'); + + const result = { + h1: '', + h2: [], + }; + let current = ''; + + lines.forEach((line) => { + if (line.startsWith('# ')) { + result.h1 = line.replace(/^# /, ''); + result.h1 = result.h1.replace(/ {([^}])*}$/, ''); + } else if (line.startsWith('## ')) { + let h2 = line.replace(/^## /, ''); + // h2 = h2.replace(/ {([^}])*}$/, ''); + current = { + h2, + content: '', + h3: [], + }; + result.h2.push(current); + } else if (line.startsWith('### ')) { + let h3 = line.replace(/^### /, ''); + // h3 = h3.replace(/ {([^}])*}$/, ''); + current = { + h3, + content: '', + }; + result.h2[result.h2.length - 1].h3.push(current); + } else if (current) { + current.content += line + '\n'; + } + }); + + result.h2.forEach((item) => { + item.content = item.content.trim(); + item.h3.forEach((h3) => { + h3.content = h3.content.trim(); + h3.id = h3.content.match(/path="([^"]+)"/)?.[1]; + if (!h3.id) { + console.log('no id', h3.content); + } + }); + }); + + return result; + + // console.log(JSON.stringify(result, null, 2)); +} + +function parseMd(name) { + const cn = fs.readFileSync(`./docs/routes/${name}.md`, 'utf8'); + const cnParsed = parse(cn); + + // const en = fs.readFileSync(`./i18n/en/docusaurus-plugin-content-docs/current/routes/${name}.md`, 'utf8') + // const enParsed = parse(en); + + // cnParsed.h1 = enParsed.h1 + + // enParsed.h2.forEach((item, index) => { + // item.h3.forEach((h3) => { + // if (h3.id) { + // let found = false + // cnParsed.h2.forEach((cnitem, index) => { + // cnitem.h3.forEach((cnh3) => { + // if (!found && cnh3.id === h3.id) { + // found = true + // console.log('found', h3.id) + // cnh3.content = h3.content + // cnh3.h3 = h3.h3 + // cnitem.content = item.content + // cnitem.h2 = item.h2 + // } + // }) + // }) + // if (!found) { + // console.log('not found', h3.id) + // cnParsed.h2.push(item) + // } + // } + // }) + // }) + + let newContent = `import Route from '@site/src/components/Route';\n\n` + `# ${cnParsed.h1}\n\n`; + cnParsed.h2.forEach((item) => { + newContent += `## ${item.h2}\n\n`; + if (item.content) { + newContent += `${item.content}\n\n`; + } + item.h3.forEach((h3) => { + newContent += `### ${h3.h3}\n\n`; + newContent += `${h3.content}\n\n`; + }); + }); + fs.writeFile(`./docs/routes/${name}.md`, newContent, (err) => { + if (err) throw err; + console.log('The file has been saved!'); + }); + // fs.writeFile(`./docs/routes/${name}.json`, JSON.stringify(cnParsed, null, 2), (err) => { + // if (err) throw err; + // console.log('The file has been saved!'); + // }); +} + +[ + 'routes/social-media', + 'routes/new-media', + 'routes/traditional-media', + 'routes/bbs', + 'routes/blog', + 'routes/programming', + 'routes/design', + 'routes/live', + 'routes/multimedia', + 'routes/picture', + 'routes/anime', + 'routes/program-update', + 'routes/university', + 'routes/forecast', + 'routes/travel', + 'routes/shopping', + 'routes/game', + 'routes/reading', + 'routes/government', + 'routes/study', + 'routes/journal', + 'routes/finance', + 'routes/other', +].map((name) => parseMd(name.replace(/^routes\//, ''))); diff --git a/website/docs/README.md b/website/docs/README.md index 21398090df3268..76beb3f09b691e 100644 --- a/website/docs/README.md +++ b/website/docs/README.md @@ -1,15 +1,13 @@ ---- -displayed_sidebar: guideSidebar ---- -# 介绍 + +# Introduction

RSSHub

RSSHub

-> 🍰 万物皆可 RSS +> 🍰 Everything is RSSible [![telegram](https://img.shields.io/badge/chat-telegram-brightgreen.svg?logo=telegram&style=flat-square)](https://t.me/rsshub) [![npm publish](https://img.shields.io/github/actions/workflow/status/DIYgod/RSSHub/npm-publish.yml?branch=master&label=npm%20publish&logo=npm&style=flat-square)](https://www.npmjs.com/package/rsshub) @@ -19,18 +17,20 @@ displayed_sidebar: guideSidebar [![CodeFactor](https://www.codefactor.io/repository/github/diygod/rsshub/badge)](https://www.codefactor.io/repository/github/diygod/rsshub) [![DeepScan grade](https://deepscan.io/api/teams/6244/projects/8135/branches/92448/badge/grade.svg)](https://deepscan.io/dashboard#view=project&tid=6244&pid=8135&bid=92448) -RSSHub 是一个开源、简单易用、易于扩展的 RSS 生成器,可以给任何奇奇怪怪的内容生成 RSS 订阅源。RSSHub 借助于开源社区的力量快速发展中,目前已适配数百家网站的上千项内容 +RSSHub is an open source, easy to use, and extensible RSS feed aggregator, it's capable of generating RSS feeds from pretty much everything. + +RSSHub delivers millions of contents aggregated from all kinds of sources, our vibrant open source community is ensuring the deliver of RSSHub's new routes, new features and bug fixes. -可以配合浏览器扩展 [RSSHub Radar](https://github.com/DIYgod/RSSHub-Radar) 和 移动端辅助 App [RSSBud](https://github.com/Cay-Zhang/RSSBud) (iOS) 与 [RSSAid](https://github.com/LeetaoGoooo/RSSAid) (Android) 食用 +RSSHub can be used with browser extension [RSSHub Radar](https://github.com/DIYgod/RSSHub-Radar) and mobile auxiliary app [RSSBud](https://github.com/Cay-Zhang/RSSBud) (iOS) and [RSSAid](https://github.com/LeetaoGoooo/RSSAid) (Android) -[Telegram 群](https://t.me/rsshub) | [Telegram 频道](https://t.me/awesomeRSSHub) +[Telegram Group](https://t.me/rsshub) | [Telegram Channel](https://t.me/awesomeRSSHub) -## 鸣谢 +## Special Thanks -### 赞助商 +### Special Sponsors

- +

[![](https://opencollective.com/static/images/become_sponsor.svg)](https://docs.rsshub.app/support/) @@ -43,11 +43,11 @@ Logo designer [sheldonrrr](https://dribbble.com/sheldonrrr) ### Backers - + -## 相关项目 +## Related Projects -- [RSSHub Radar](https://github.com/DIYgod/RSSHub-Radar) | 一个可以帮助你快速发现和订阅当前网站 RSS 和 RSSHub 的浏览器扩展 -- [RSSBud](https://github.com/Cay-Zhang/RSSBud) ([TestFlight 公测](https://testflight.apple.com/join/rjCVzzHP)) | iOS 平台的 RSSHub Radar,专为移动生态优化 -- [RSSAid](https://github.com/LeetaoGoooo/RSSAid) | 基于 Flutter 构建的 Android 平台的 RSSHub Radar +- [RSSHub Radar](https://github.com/DIYgod/RSSHub-Radar) | A browser extension that can help you quickly discover and subscribe to the RSS and RSSHub of current websites. +- [RSSBud](https://github.com/Cay-Zhang/RSSBud) ([TestFlight](https://testflight.apple.com/join/rjCVzzHP)) | RSSHub Radar for iOS platform, designed specifically for mobile ecosystem optimization. +- [RSSAid](https://github.com/LeetaoGoooo/RSSAid) | RSSHub Radar for Android platform built with Flutter. - [DocSearch](https://github.com/Fatpandac/DocSearch) | Link RSSHub DocSearch into Raycast diff --git a/website/docs/api.md b/website/docs/api.md index df78a705635d8c..bdfa2541514ba2 100644 --- a/website/docs/api.md +++ b/website/docs/api.md @@ -1,62 +1,42 @@ # API -:::caution 注意 -API 仍处于开发状态中, 并可能会有改动。欢迎提供建议! +:::caution Warning +The API is under active development and is subject to change. All suggestions are welcome! ::: -RSSHub 提供下列 API: +RSSHub provides the following APIs: -## 可用公共路由列表 +## List of Public Routes -:::tip 提示 -`protected_router.js`下的路由**不会被**包含在此 API 返回的结果当中. +:::tip Tip +This API **will not** return any routes under `lib/protected_router.js`. ::: -举例: +Eg: -路由: `/api/routes/:name?` +Route: `/api/routes/:name?` -参数: +Parameters: -- `name`, 路由一级名称,对应 中的文件夹名称。可选,**缺省则返回所有可用路由**. +- `name`, route's top level name as in [https://github.com/DIYgod/RSSHub/tree/master/lib/routes](https://github.com/DIYgod/RSSHub/tree/master/lib/routes). Optional, **returns all public routes if not specified**. -成功请求将会返回 HTTP 状态码 `200 OK` 与 JSON 结果,格式如下: +A successful request returns an HTTP status code `200 OK` with the result in JSON: ```js { "status": "success", "data": { - "bilibili": { + "github": { "routes": [ - "/bilibili/user/video/:uid", - "/bilibili/user/article/:uid", - "/bilibili/user/fav/:uid", - "/bilibili/user/coin/:uid", - "/bilibili/user/dynamic/:uid", - "/bilibili/user/followers/:uid", - "/bilibili/user/followings/:uid", - "/bilibili/user/channel/collections/:uid/:sid", - "/bilibili/user/channel/series/:uid/:sid", - "/bilibili/partion/:tid", - "/bilibili/partion/ranking/:tid/:days?", - "/bilibili/bangumi/:seasonid", - "/bilibili/video/page/:aid", - "/bilibili/video/reply/:aid", - "/bilibili/link/news/:product", - "/bilibili/live/room/:roomID", - "/bilibili/live/search/:key/:order", - "/bilibili/live/area/:areaID/:order", - "/bilibili/fav/:uid/:fid", - "/bilibili/blackboard", - "/bilibili/mall/new", - "/bilibili/mall/ip/:id", - "/bilibili/ranking/:rid?/:day?", - "/bilibili/topic/:topic" + "/github/trending/:since/:language?", + "/github/issue/:user/:repo", + "/github/user/followers/:user", + "/github/stars/:user/:repo" ] } }, - "message": "request returned 22 routes" + "message": "request returned 4 routes" } ``` -若无符合请求路由,请求将会返回 HTTP 状态码 `204 No Content`. +If no matching results were found, the server returns only an HTTP status code `204 No Content`. diff --git a/website/docs/faq.md b/website/docs/faq.md index e051660fb6f326..876f70782ed748 100644 --- a/website/docs/faq.md +++ b/website/docs/faq.md @@ -1,33 +1,27 @@ -# 常见问题 +import Badge from '@site/src/components/Badge'; -**Q: RSS 是什么?RSS 如何使用?可以推荐一下好用的 RSS 阅读器么?** +# FAQs -**A:** [我有特别的 RSS 使用技巧](https://diygod.cc/ohmyrss/) +**Q: How does RSSHub work?** -**Q: RSSHub 是如何工作的?** +**A:** When a request is received, RSSHub fetches the corresponding data from the original site, the resulting contents will be outputted in RSS format. Caching is implemented to avoid requesting original sites for content. And of course, we throw in a little magic 🎩. -**A:** 请求路由时,RSSHub 会按照给定规则请求源站数据,然后以 RSS 格式输出;如果在设定缓存时间内重新请求路由,则会直接返回缓存内容,不请求源站;再加一点点魔法。 +**Q: Can I use the demo instance?** -**Q: RSSHub Radar 是如何工作的?** +**A:** [rsshub.app](https://rsshub.app) is the demo instance provided, running the latest build of RSSHub from master branch, the cache is set 120 minutes and it's free to use. However, if you see an badge for route, this means popular websites such as Facebook etc. may pose a request quota on individual IP address, which means it can get unreliable from time to time for the demo instance. You are encouraged to [host your own RSSHub instance](/install/) to get a better usability. -**A:** 进入新页面时, RSSHub Radar 先根据页面 link 标签[寻找](https://github.com/DIYgod/RSSHub-Radar/blob/master/src/js/content/utils.js#L25)页面自带 RSS,再根据远程更新的[规则](https://github.com/DIYgod/RSSHub/blob/master/assets/radar-rules.js)寻找适用当前页面和当前网站的 RSSHub 路由;再加一点点魔法。 +**Q: Why are images/videos not loading in some RSSHub routes?** -**Q: 演示地址可以用么?** +**A:** RSSHub fetches and respects the original image/video URLs from original sites, in which some are behind anti-hotlink filters. `referrerpolicy="no-referrer"` attribute is added to all images to solve the issues caused by cross-domain requests. Third party RSS service providers such as Feedly and Inoreader, strip this attribute off, resulting in cross-domain requests being blocked. Meanwhile, the attribute is not available for videos yet, resulting in most RSS readers unable to pass the anti-hotlink check. Here are some workarounds: -**A:** 演示地址为 [rsshub.app](https://rsshub.app), 缓存时间 120 分钟,可以随意使用。但如果你看到路由有 标记,如微博、知乎等,意味着目标网站有严重的反爬策略,demo 无法确保可用性,建议自建来提高稳定性。 +1. Migrate to RSS readers that do not send Referer,such as [Inoreader for Web](https://www.inoreader.com/) with a [user script disabling Referer](https://greasyfork.org/en/scripts/376884), [fix-image-error at inoreader](https://greasyfork.org/scripts/463461-fix-image-error-at-inoreader), [RSS to Telegram Bot](https://github.com/Rongronggg9/RSS-to-Telegram-Bot), etc. If your RSS reader can bypass the anti-hotlink check successfully and play embedded videos, it's an RSS reader that do not send Referer. Please consider adding it to the documentation to help more people. +2. Set up a reverse proxy, refer to [Parameters->Multimedia processing](/parameter#multimedia-processing) for more details. +3. Navigate back to the original site. -**Q: 为什么 RSSHub 里的图片 / 视频加载不出来?** +**Q: The website I want is not supported QAQ** -**A:** RSSHub 里的图片 / 视频地址都是源站地址,部分有防盗链,所以 RSSHub 给图片加了 `referrerpolicy="no-referrer"` 属性来防止跨域问题,但部分 RSS 服务会自作主张去掉这个属性,如 Feedly、Inoreader,在它们的网页端图片会触发跨域加载不出来。同时,视频目前没有类似的属性,因此大部分阅读器都无法通过防盗链检查。下面是一些解决方案: +**A:** If you are a JavaScript developer, please follow [this guide](/joinus/quick-start) for submitting a pull request, otherwise, follow the issue template to [submit a new issue](https://github.com/DIYgod/RSSHub/issues/new?template=rss_request_en.md), and patiently wait for Santa Claus. For priority responses, consider [sponsoring us](/support). -1. 使用不发送 Referer 的阅读器,如 [Inoreader 网页版](https://www.inoreader.com/)配合[禁用 Referer 的 user script](https://greasyfork.org/scripts/376884)、[修复 inoreader 图片异常](https://greasyfork.org/scripts/463461-fix-image-error-at-inoreader)、[RSS to Telegram Bot](https://github.com/Rongronggg9/RSS-to-Telegram-Bot) 等。如果你的阅读器能够绕过防盗链成功播放内嵌视频,那么它就是不发送 Referer 的,请考虑添加到文档里帮助更多的人。 -2. 设置反代,参考 [通用参数 -> 多媒体处理](/parameter#多媒体处理)。 -3. 回到原网站查看相关资源。 +**Q: Where do I get the changelog for RSSHub?** -**Q: 没有我想订阅的网站怎么办嘤嘤嘤 QAQ** - -**A:** 如果你会写 JavaScript,请按照[规则](/joinus/quick-start#提交新的-rsshub-规则)提交 pull request,否则按照要求[提交 issue](https://github.com/DIYgod/RSSHub/issues/new?template=rss_request_zh.md),然后等待有缘人完成你的需求,也可以考虑[赞助项目](/support)或附上一张你自己的女装照来获得更快的 issue 响应速度。 - -**Q: 我怎么才能知道 RSSHub 更新了哪些路由?** - -**A:** 可以使用 RSS 订阅[RSSHub 有新路由啦](/routes/program-update#rsshub)。 +**A:** Subscribe our RSS here: [RSSHub added a new route](/routes/program-update#rsshub). diff --git a/website/docs/install/README.md b/website/docs/install/README.md index 45aa05f2c8bdc6..839f9891783cd3 100644 --- a/website/docs/install/README.md +++ b/website/docs/install/README.md @@ -2,155 +2,155 @@ sidebar: auto --- -# 部署 +# Deployment -部署 RSSHub 需要基本的计算机编程常识,如果您在部署过程中遇到无法解决的问题请到 [issues](https://github.com/DIYgod/RSSHub/issues) 寻找类似的问题或 [向我们提问](https://github.com/DIYgod/RSSHub/issues/new/choose),我们会尽快给您答复。 +RSSHub provides a painless deployment process if you are equipped with basic programming knowledge, you may open an [issue](https://github.com/DIYgod/RSSHub/issues/new/choose) if you believe you have encountered a problem not listed [here](https://github.com/DIYgod/RSSHub/issues), the community will try to sort it out asap. -部署涉及到以下基本编程常识: +The deployment may involve the followings: -1. 命令行操作 +1. Command line interface 2. [Git](https://git-scm.com/) 3. [Node.js](https://nodejs.org/) -4. [npm](https://www.npmjs.com/get-npm) 或 [yarn](https://yarnpkg.com/zh-Hans/docs/install) +4. [npm](https://www.npmjs.com/get-npm) or [yarn](https://yarnpkg.com/zh-Hans/docs/install) -部署到可外网访问则可能涉及到: +Deploy for public access may require: 1. [Nginx](https://www.nginx.com/resources/wiki/start/topics/tutorials/install/) -2. [Docker](https://www.docker.com/get-started) 或 [docker-compose](https://docs.docker.com/compose/install/) +2. [Docker](https://www.docker.com/get-started) or [docker-compose](https://docs.docker.com/compose/install/) 3. [Redis](https://redis.io/download) 4. [Heroku](https://devcenter.heroku.com/articles/getting-started-with-nodejs) 5. [Google App Engine](https://cloud.google.com/appengine/) 6. [Fly.io](https://fly.io/) 7. [Zeabur](https://zeabur.com) -## Docker 镜像 +## Docker Image -默认推荐使用 `diygod/rsshub` 即 `diygod/rsshub:latest` 最新版镜像以获取最新路由。 +We recommend using the latest version `diygod/rsshub` (i.e. `diygod/rsshub:latest`) of the docker image. -当 `diygod/rsshub:latest` 存在问题时,可以使用以日期为标签的近期镜像临时使用,例如: +When the latest version is unstable, you can use the image with a date tag for temporary use. For example: ```bash $ docker pull diygod/rsshub:2021-06-18 ``` -待最新镜像更新后再切换回 `diygod/rsshub:latest` 最新版镜像。 +You can back to the latest version when the code has been fixed and rebuild the image. -如需启用 puppeteer,可使用 `diygod/rsshub:chromium-bundled`;若指定日期则为 `diygod/rsshub:chromium-bundled-2021-06-18`。 +To enable puppeteer, `diygod/rsshub:chromium-bundled` is a good choice. If date specified, it will become: `diygod/rsshub:chromium-bundled-2021-06-18`. -亦可使用 Docker Compose 部署以启用 puppeteer,但更消耗磁盘空间和内存。通过修改 `docker-compose.yml`,也可以使用 `diygod/rsshub:chromium-bundled`,这样就没有更消耗资源的问题了。 +Another approach to enable puppeteer is deploying with Docker Compose. However, it consumes more disk space and memory. By modifying `docker-compose.yml`, you can use `diygod/rsshub:chromium-bundled` instead to reduce the disk space and memory consumption. -## Docker Compose 部署 +## Docker Compose Deployment -### 安装 +### Install -下载 [docker-compose.yml](https://github.com/DIYgod/RSSHub/blob/master/docker-compose.yml) +Download [docker-compose.yml](https://github.com/DIYgod/RSSHub/blob/master/docker-compose.yml) ```bash $ wget https://raw.githubusercontent.com/DIYgod/RSSHub/master/docker-compose.yml ``` -检查有无需要修改的配置 +Check if any configuration needs to be changed ```bash -$ vi docker-compose.yml # 也可以是你喜欢的编辑器 +$ vi docker-compose.yml # or your favorite editor ``` -创建 volume 持久化 Redis 缓存 +Create a docker volume to persist Redis caches ```bash $ docker volume create redis-data ``` -启动 +Launch ```bash $ docker-compose up -d ``` -### 更新 +### Update -删除旧容器 +Remove old containers ```bash $ docker-compose down ``` -如果之前已经下载 / 使用过镜像,下方命令可以帮助你获取最新版本:这可能可以解决一些问题。 +Repull the latest image if you have downloaded the image before. It is helpful to resolve some issues. ```bash $ docker pull diygod/rsshub ``` -然后重复安装步骤 +Then repeat the installation steps -### 添加配置 +### Configuration -修改 [docker-compose.yml](https://github.com/DIYgod/RSSHub/blob/master/docker-compose.yml) 中的 `environment` 进行配置 +Edit `environment` in [docker-compose.yml](https://github.com/DIYgod/RSSHub/blob/master/docker-compose.yml) -## Docker 部署 +## Docker Deployment -:::tip 提示 +:::tip Tip -如需启用 puppeteer,请在**每条**命令中均将 `diygod/rsshub` 替换为 `diygod/rsshub:chromium-bundled`。 +To enable puppeteer, replace `diygod/rsshub` with `diygod/rsshub:chromium-bundled` in **EACH** command. ::: -### 安装 +### Install -运行下面的命令下载 RSSHub 镜像 +Execute the following command to pull RSSHub's docker image. ```bash $ docker pull diygod/rsshub ``` -然后运行 RSSHub 即可 +Start an RSSHub container ```bash $ docker run -d --name rsshub -p 1200:1200 diygod/rsshub ``` -在浏览器中打开 ,enjoy it! ✅ +Visit [http://127.0.0.1:1200/](http://127.0.0.1:1200/), and enjoy it! ✅ -您可以使用下面的命令来关闭 RSSHub +Execute the following command to stop `RSSHub`. ```bash $ docker stop rsshub ``` -### 更新 +### Update -删除旧容器 +Remove the old container ```bash $ docker stop rsshub $ docker rm rsshub ``` -然后重复安装步骤 +Then repeat the installation steps -### 添加配置 +### Configuration -配置运行在 docker 中的 RSSHub,最便利的方法是使用 docker 环境变量 +The simplest way to configure RSSHub container is via system environment variables. -以设置缓存时间为 1 小时举例,只需要在运行时增加参数:`-e CACHE_EXPIRE=3600` +For example, adding `-e CACHE_EXPIRE=3600` will set the cache time to 1 hour. ```bash $ docker run -d --name rsshub -p 1200:1200 -e CACHE_EXPIRE=3600 -e GITHUB_ACCESS_TOKEN=example diygod/rsshub ``` -该部署方式不包括 puppeteer(除非改用 `diygod/rsshub:chromium-bundled`)和 redis 依赖,如有需要请改用 Docker Compose 部署方式或自行部署外部依赖 +This deployment method does not include puppeteer (unless using `diygod/rsshub:chromium-bundled` instead) and Redis dependencies. Use the Docker Compose deployment method or deploy external dependencies yourself if you need it. -更多配置项请看 [#配置](#pei-zhi) +To configure more options please refer to [Configuration](#configuration). -## Ansible 部署 +## Ansible Deployment -这个 Ansible playbook 包括了 RSSHub, Redis, browserless (依赖 Docker) 以及 Caddy 2 +This Ansible playbook includes RSSHub, Redis, browserless (uses Docker) and Caddy 2 -目前只支持 Ubuntu 20.04 +Currently only support Ubuntu 20.04 -需要 sudo 权限和虚拟化能力(Docker 将会被自动安装) +Requires sudo privilege and virtualization capability (Docker will be automatically installed) -### 安装 +### Install ```bash sudo apt update @@ -158,33 +158,33 @@ 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.example.com 访问您的 RSSHub 实例,输入 rsshub.example.com(去掉 https://) +# 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.example.com to access your RSSHub instance, enter rsshub.example.com (remove the https://) ``` -### 更新 +### Update ```bash cd ~/RSSHub/scripts/ansible sudo ansible-playbook rsshub.yaml -# 当提示输入 domain name 的时候,输入该主机所使用的域名 -# 举例:如果您的 RSSHub 用户使用 https://rsshub.example.com 访问您的 RSSHub 实例,输入 rsshub.example.com(去掉 https://) +# 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.example.com to access your RSSHub instance, enter rsshub.example.com (remove the https://) ``` -## 手动部署 +## Manual Deployment -部署 `RSSHub` 最直接的方式,您可以按照以下步骤将 `RSSHub` 部署在您的电脑、服务器或者其他任何地方 +The most direct way to deploy `RSSHub`, you can follow the steps below to deploy`RSSHub` on your computer, server or anywhere. -### 安装 +### Install -首先是下载 `RSSHub` 的源码 +Execute the following commands to download the source code ```bash $ git clone https://github.com/DIYgod/RSSHub.git $ cd RSSHub ``` -下载完成后,需要安装依赖(开发不要加 `--production` 参数) +Execute the following commands to install dependencies (Do not add the `--production` parameter for development). @@ -210,37 +210,35 @@ npm install --omit=dev -由于众所周知的原因,在中国使用 `npm` 下载依赖十分缓慢,建议挂一个代理或者考虑使用 [NPM 镜像](https://npm.taobao.org/) +### Launch -### 启动 - -然后在 `RSSHub` 文件夹中运行下面的命令就可以启动 +Under `RSSHub`'s root directory, execute the following commands to launch ```bash $ yarn start ``` -或 +Or ```bash $ npm start ``` -或使用 [PM2](https://pm2.keymetrics.io/docs/usage/quick-start/) +Or use [PM2](https://pm2.io/docs/plus/quick-start/) ```bash $ pm2 start lib/index.js --name rsshub ``` -在浏览器中打开 ,enjoy it! ✅ +Visit [http://127.0.0.1:1200/](http://127.0.0.1:1200/), and enjoy it! ✅ -详细使用说明参照 [指南](https://docs.rsshub.app/),替换所有路由例子中的 `https://rsshub.app/` 为 `http://localhost:1200` 即可正常使用 +Refer to our [Guide](https://docs.rsshub.app/) for usage. Replace `https://rsshub.app/` with `http://localhost:1200` in any route example to see the effect. -### 添加配置 +### Configuration -:::tip 提示 +:::tip Tip -在 arm/arm64 上,此部署方式不包含 puppeteer 依赖。要启用 puppeteer,你需要先从发行版安装 Chromium,然后设置 `CHROMIUM_EXECUTABLE_PATH` 为其可执行路径。 +On arm/arm64, this deployment method does not include puppeteer dependencies. To enable puppeteer, install Chromium from your distribution repositories first, then set `CHROMIUM_EXECUTABLE_PATH` to its executable path. Debian: @@ -260,34 +258,34 @@ $ echo 'CHROMIUM_EXECUTABLE_PATH=chromium-browser' >> .env ::: -可以通过设置环境变量来配置 RSSHub +RSSHub can be configured by setting environment variables. -在项目根目录新建一个 `.env` 文件,每行以 `NAME=VALUE` 格式添加环境变量,例如 +Create a `.env` file in the root directory of your project. Add environment-specific variables on new lines in the form of `NAME=VALUE`. For example: -```env +``` CACHE_TYPE=redis CACHE_EXPIRE=600 ``` -注意它不会覆盖已有的环境变量,更多规则请参考 [dotenv](https://github.com/motdotla/dotenv) +Please notice that it will not override already existed environment variables, more rules please refer to [dotenv](https://github.com/motdotla/dotenv) -该部署方式不包括 redis 依赖,如有需要请改用 Docker Compose 部署方式或自行部署外部依赖 +This deployment method does not include Redis dependencies. Use the Docker Compose deployment method or deploy external dependencies yourself if you need it. -更多配置项请看 [#配置](#pei-zhi) +To configure more options please refer to [Configuration](#configuration). -### 更新 +### Update -在 `RSSHub` 文件夹中运行下面的命令就从 github 仓库拉取最新版本 +Under `RSSHub`'s directory, execute the following commands to pull the latest source code for `RSSHub` ```bash $ git pull ``` -然后重复安装步骤。 +Then repeat the installation steps. -### Nix 用户提示 +### A tip for Nix users -通过 `nix-shell` 配置简化安装 nodejs, yarn 和 jieba: +To install nodejs, yarn and jieba (to build documentation) you can use the following `nix-shell` configuration script. ```nix let @@ -299,144 +297,137 @@ in pkgs.stdenv.mkDerivation { } ``` -## 部署到 Railway +## Deploy to Railway -包含自动更新。 +Automatic updates are included. -[![Deploy on Railway](https://railway.app/button.svg)](https://railway.app/template/QxW\_\_f?referralCode=9wT3hc) +[![Deploy on Railway](https://railway.app/button.svg)](https://railway.app/template/QxW__f?referralCode=9wT3hc) -## 部署到 Heroku +## Deploy to Heroku -### 注意 +### Notice -:::caution 更新 +:::caution Update -Heroku [不再](https://blog.heroku.com/next-chapter) 提供免费服务。 +Heroku [no longer](https://blog.heroku.com/next-chapter) offers free product plans. ::: -~~未验证支付方式的 heroku 账户每月仅有 550 小时额度(约 23 天),验证支付方式后可达每月 1000 小时。~~ +~~Heroku accounts with unverified payment methods have only 550 hours of credit per month (about 23 days), and up to 1,000 hours per month with verified payment methods.~~ -### 一键部署(无自动更新) +### Instant deploy (without automatic update) [![Deploy to Heroku](https://www.herokucdn.com/deploy/button.svg)](https://heroku.com/deploy?template=https%3A%2F%2Fgithub.com%2FDIYgod%2FRSSHub) -### 自动更新部署 +### Automatic deploy upon update -1. 将 RSSHub [分叉(fork)](https://github.com/DIYgod/RSSHub/fork) 到自己的账户下。 -2. 把自己的分叉部署到 Heroku:`https://heroku.com/deploy?template=URL`,其中 `URL` 改为分叉地址 (例如 `https://github.com/USERNAME/RSSHub`)。 -3. 检查 Heroku 设置,随代码库更新自动部署。 -4. 安装 [Pull](https://github.com/apps/pull) 应用,定期将 RSSHub 改动自动同步至你的分叉。 +1. [Fork RSSHub](https://github.com/DIYgod/RSSHub/fork) to your GitHub account. +2. Deploy your fork to Heroku: `https://heroku.com/deploy?template=URL`, where `URL` is your fork address (_e.g._ `https://github.com/USERNAME/RSSHub`). +3. Configure `automatic deploy` in Heroku app to follow the changes to your fork. +4. Install [Pull](https://github.com/apps/pull) app to keep your fork synchronized with RSSHub. -## 部署到 Vercel (ZEIT Now) +## Deploy to Vercel (ZEIT Now) -### 一键部署(无自动更新) +### Instant deploy (without automatic update) [![Deploy to Vercel](https://vercel.com/button)](https://vercel.com/import/project?template=https://github.com/DIYgod/RSSHub) -### 自动更新部署 +### Automatic deploy upon update -1. 将 RSSHub [分叉(fork)](https://github.com/DIYgod/RSSHub/fork) 到自己的账户下 -2. 去 Vercel 部署一个新项目:使用 GitHub 账户登录 Vercel,进入[项目创建页面](https://vercel.com/new/) 选择导入 RSSHub 仓库进行部署 -3. 安装 [Pull](https://github.com/apps/pull) 应用,定期将 RSSHub 改动自动同步至你的仓库 +1. [Fork RSSHub](https://github.com/DIYgod/RSSHub/fork) to your GitHub account. +2. Deploy your fork to Vercel: Login Vercel with your GitHub account, create and deploy [new Vercel project](https://vercel.com/new/) with your RSSHub repository. +3. Install [Pull](https://github.com/apps/pull) app to keep your fork synchronized with RSSHub. -## 部署到 Fly.io +## Deploy to Fly.io -### 方案一:Fork +### Method 1: Fork -1. 将 RSSHub [Fork](https://github.com/DIYgod/RSSHub/fork) 到自己的账户下; - -2. 下载分叉的源码 +1. [Fork RSSHub](https://github.com/DIYgod/RSSHub/fork) to your GitHub account; +2. Clone the source code from your fork ```bash $ git clone https://github.com//RSSHub.git $ cd RSSHub ``` -3. 前往 [Fly.io 完成注册](https://fly.io/app/sign-up),并安装 [flyctl CLI](https://fly.io/docs/hands-on/install-flyctl/); - -4. 运行 `fly launch`, 并选择一个唯一的名称和实例地区; +3. [Sign up for Fly.io](https://fly.io/app/sign-up) and install the [flyctl CLI](https://fly.io/docs/hands-on/install-flyctl/); +4. Run `fly launch` and choose a unique name and region to deploy; +5. Use `fly secrets set KEY=VALUE` to [configure some modules](#configuration-route-specific-configurations); +6. [Set up automatic deployment via GitHub Actions](https://fly.io/docs/app-guides/continuous-deployment-with-github-actions/); +7. (Optional) Use `fly certs add your domain` to configure a custom domain, and follow the instructions to configure the related domain resolution at your DNS service provider (you can check the domain configuration status on the Dashboard Certificate page). -5. 使用 `fly secrets set KEY=VALUE` [对部分模块进行配置](#pei-zhi-bu-fen-rss-mo-kuai-pei-zhi); +Upgrade: On the homepage of your Forked repository, click "Sync fork - Update Branch" to manually update to the latest official master branch, or install the [Pull](https://github.com/apps/pull) GitHub app to keep your fork synchronized with upstream. -6. [配置通过 GitHub Actions 自动部署](https://fly.io/docs/app-guides/continuous-deployment-with-github-actions/); +### Method 2: Maintain fly.toml by yourself -7. (可选)利用 `fly certs add 你的域名` 来配置自定义域名,并根据指引在你的 DNS 服务商配置相关域名解析(你可在 Dashboard Certificate 页面查看域名的配置状态)。 +1. [Sign up for Fly.io](https://fly.io/app/sign-up) and install the [flyctl CLI](https://fly.io/docs/hands-on/install-flyctl/); +2. Create a new empty directory locally, run `fly launch` in it, and choose a unique name and instance region; +3. Edit the generated fly.toml file, add -更新:在你 Fork 出来的仓库首页点击「Sync fork - Update Branch」来手动更新至官方最新的 master 分支,或安装 [Pull](https://github.com/apps/pull) 应用来定期自动同步。 - -### 方案二:自行维护 fly.toml - -1. 前往 [Fly.io 完成注册](https://fly.io/app/sign-up),并安装 [flyctl CLI](https://fly.io/docs/hands-on/install-flyctl/); -2. 自行在本地新建一个空目录,在其中运行 `fly launch`, 并选择一个唯一的名称和实例地区; -3. 编辑生成的 fly.toml 文件,新增 - - ```toml - [build] - image = "diygod/rsshub:latest" - ``` + ```toml + [build] + image = "diygod/rsshub:latest" + ``` - 根据实际情况,你可能希望使用其他镜像标签,请阅读 [Docker 镜像](#docker-jing-xiang) 的有关内容; -4. 修改 fly.toml 中的 `[env]` 段或使用`fly secrets set KEY=VALUE` [对部分模块进行配置](#pei-zhi-bu-fen-rss-mo-kuai-pei-zhi); -5. 执行 `fly deploy` 启动应用; -6. (可选)利用 `fly certs add 你的域名` 来配置自定义域名,并根据指引在你的 DNS 服务商配置相关域名解析(你可在 Dashboard Certificate 页面查看域名的配置状态)。 + Depending on the actual situation, you may want to use other image tags, please read the relevant content of [Docker Image](#docker-image); +4. Modify the `[env]` section in fly.toml or use `fly secrets set KEY=VALUE` to [configure some modules](#configuration-route-specific-configurations); +5. Execute `fly deploy` to start the application; +6. (Optional) Use `fly certs add your domain` to configure a custom domain, and follow the instructions to configure the related domain resolution at your DNS service provider (you can check the domain configuration status on the Dashboard Certificate page). -更新:进入你存储了 `fly.toml` 文件的目录,执行 `fly deploy` 即可触发拉取最新镜像、启动应用的步骤。 +Upgrade: Enter the directory where you saved the `fly.toml` file and execute `fly deploy` to trigger the steps of pulling the latest image and starting the upgraded application. -### 配置内置的 Upstash Redis 缓存 +### Configure built-in Upstash Redis as cache -在 `RSSHub` 文件夹下运行 +Run in the `RSSHub` folder ```bash -$ fly redis create +$ flyctl redis create ``` -来创建一个新的 Redis 数据库,地域选择与你上面创建 RSSHub app 时相同的地域,建议选择开启 [eviction](https://redis.io/docs/reference/eviction/)。创建完成后会输出类似于 `redis://default:@.upstash.io` 的字符串。 +to create a new Redis database. Choose the same region as when you created the RSSHub app above, and it is recommended to enable [eviction](https://redis.io/docs/reference/eviction/). After creation, a string in the form of `redis://default:@.upstash.io` will be printed. -因目前[上游依赖的一个 bug](https://github.com/luin/ioredis/issues/1576),你暂时需要在 Fly.io 给你的连接 URL 后追加 `family=6` 的参数,即使用 `redis://default:@.upstash.io/?family=6` 作为连接 URL。 +Due to [a bug in a dependency](https://github.com/luin/ioredis/issues/1576), you currently need to append the `family=6` parameter to the URL provided by Fly.io, i.e., use `redis://default:@.upstash.io/?family=6` as the connection URL. -再配置 fly.toml 中的 `[env]` 段或运行 +Then configure the `[env]` section in fly.toml or run ```bash -$ fly secrets set CACHE_TYPE=redis REDIS_URL='<刚才的连接 URL>' +$ fly secrets set CACHE_TYPE=redis REDIS_URL='' ``` -并执行 `fly deploy` 触发重新部署来完成配置。 +and execute `fly deploy` (if use the second install method) to trigger a redeployment to complete the configuration. -## 部署到 PikaPods +## Deploy to PikaPods -每月只需 1 美元即可运行 RSSHub。包括自动更新和 5 美元的免费起始额度。 +Run RSSHub from just $1/month. Includes automatic updates and $5 free starting credit. [![Run on PikaPods](https://www.pikapods.com/static/run-button.svg)](https://www.pikapods.com/pods?run=rsshub) -## 部署到 Zeabur +## Deploy to Zeabur -1. 前往 [Zeabur 完成注册](https://dash.zeabur.com) -2. 创建一个新项目 -3. 在项目中选择创建新服务,选择从**服务市场**部署。 -4. 添加域名,若使用自定义域名,可参见 [Zeabur 的域名绑定文档](https://docs.zeabur.com/zh-CN/deploy/domain-binding)。 +1. [Sign up for Zeabur](https://dash.zeabur.com) +2. Create a new project. +3. Create a new service in the project, select deploying from the **marketplace**. +4. Add a domain name, if you use a custom domain name, you can refer to [Zeabur's domain name binding document](https://docs.zeabur.com/deploy/domain-binding). [![Deploy on Zeabur](https://zeabur.com/button.svg)](https://dash.zeabur.com/templates/X46PTP) -## 部署到 Google App Engine +## Deploy to Google App Engine(GAE) -### 准备 +### Before You Begin -[Before you begin](https://cloud.google.com/appengine/docs/flexible/nodejs/quickstart) +Follow the [official guide](https://cloud.google.com/appengine/docs/flexible/nodejs/quickstart) for completing your GCP account settings, creating a new Node project, adding billing information (required), installing git and initializing gcloud([link](https://cloud.google.com/sdk/gcloud/)). Node.js is not required if you don't plan to debug RSSHub locally. -按照这里的引导完成 GCP 账号设置,创建 GCP 项目,创建 App Engine 项目,开通付费功能(必须),安装 git 与 gcloud 工具。并完成 gcloud 工具的初始化,初始化具体方式 [请查看这个链接](https://cloud.google.com/sdk/gcloud/?hl=zh-CN)。如果你不打算在本地调试本项目,可以不安装 Node.js 环境。 +Please note, GAE free tier doesn't support Flexible Environment, please check the pricing plan prior to deployment. -请注意,GAE 免费用量不支持 Flexible Environment,部署到 Flexible Environment 前请确认收费标准。 +Node.js standard environment is still under beta, unknown or unexpected errors might be encountered during the deployment. -Node.JS 的 standard environment 仍在测试中,您可能会在部署或使用中遇到某些不可预期的问题。 +Execute `git clone https://github.com/DIYgod/RSSHub.git` to pull the latest code -运行 `git clone https://github.com/DIYgod/RSSHub.git` 拉取本项目的最新版本。 +### app.yaml Settings -### app.yaml 配置 +#### Deploy to Flexible Environment -#### 部署到 Flexible Environment - -在 RSSHub 项目根目录下建立一个 app.yaml 文件,内容示例如下: +Under RSSHub's root directory, create a file `app.yaml` with the following content: ```yaml # [START app_yaml] @@ -449,7 +440,7 @@ env: flex # https://cloud.google.com/appengine/docs/flexible/nodejs/configuring-your-app-with-app-yaml manual_scaling: instances: 1 -# 以下是 app engine 资源配置,可以自行修改,硬盘最低为 10G +# app engine resources, adjust to suit your needs, the required disk space is 10 GB resources: cpu: 1 memory_gb: 0.5 @@ -458,15 +449,15 @@ network: forwarded_ports: - 80:1200 - 443:1200 -# 以下是环境配置示例,具体可配置项见本文档配置章节 +# environment variables section, refer to Settings env_variables: CACHE_EXPIRE: '300' # [END app_yaml] ``` -#### 部署到 standard environment +#### Deploy to standard environment -在 RSSHub 项目根目录下建立一个 app.yaml 文件,内容示例如下: +Under RSSHub's root directory, create a file `app.yaml` with the following content: ```yaml # [START app_yaml] @@ -476,124 +467,113 @@ network: forwarded_ports: - 80:1200 - 443:1200 -# 以下是环境配置示例,具体可配置项见本文档配置章节 +# environment variables section, refer to Settings env_variables: CACHE_EXPIRE: '300' # [END app_yaml] ``` -### 安装 +### Install -在 RSSHub 项目根目录下运行 +Under RSSHub's root directory, execute the following commands to launch RSSHub ```bash gcloud app deploy ``` -进行项目部署,如果您需要变更 app.yaml 文件名称或者变更部署的项目 ID 或者指定版本号等,请参考 [Deploying a service](https://cloud.google.com/appengine/docs/flexible/nodejs/testing-and-deploying-your-app#deploying_a_service\_2)。 +For changing the deployment project id or version id, please refer to `Deploying a service` section [here](https://cloud.google.com/appengine/docs/flexible/nodejs/testing-and-deploying-your-app). -部署完成后可访问您的 Google App Engine URL 查看部署情况。 +You can access your `Google App Engine URL` to check the deployment status ## Play with Docker -如果想要测试因为反爬规则导致无法访问的路由,您可以点击下方按钮拉起一套免费,临时,专属于您的 RSSHub +If you would like to test routes or avoid IP limits, etc., you may build your own RSSHub for free by clicking the button below. [![Try in PWD](https://raw.githubusercontent.com/play-with-docker/stacks/master/assets/images/button.png)](https://labs.play-with-docker.com/?stack=https://raw.githubusercontent.com/DIYgod/RSSHub/master/docker-compose.yml) -:::caution 注意 +:::caution Warning -- 需要 [DockerHub](https://hub.docker.com) 账号 -- [Play with Docker](https://labs.play-with-docker.com/) 一次仅能使用 4 小时,不能作为持久化解决方案,应当用于测试 / 验证路由规则 -- 如果部署完成后不能看到自动识别的端口,请手动点击顶部按钮`open port`并输入`1200` -- 有的时候 PWD 会抽风,如果遇到点击`Start`后空白页面,或者拉起失败,请重试 +- [DockerHub](https://hub.docker.com) account required +- [Play with Docker](https://labs.play-with-docker.com/) instance will last for 4 hours at most. It should only be used for testing purpose +- If deploy success but port cannot be auto-deteced,please click the `open port` button on the top and type `1200` +- Sometimes PWD won't work as expected. If you encounter blank screen after `Start`, or some error during initialization, please retry ::: -## 配置 +## Configuration -通过设置环境变量来配置 RSSHub +Configure RSSHub by setting environment variables -### 网络配置 +### Network Configuration -`PORT`: 监听端口,默认为 `1200` +`PORT`: listening port, default to `1200` -`SOCKET`: 监听 Unix Socket,默认 `null` +`SOCKET`: listening Unix Socket, default to `null` -`LISTEN_INADDR_ANY`: 是否允许公网连接,默认 `1` +`LISTEN_INADDR_ANY`: open up for external access, default to `1` -`REQUEST_RETRY`: 请求失败重试次数,默认 `2` +`REQUEST_RETRY`: retries allowed for failed requests, default to `2` -`REQUEST_TIMEOUT`: 请求超时毫秒数,默认 `3000` +`REQUEST_TIMEOUT`: milliseconds to wait for the server to end the response before aborting the request with error, default to `3000` -`UA`: 用户代理,默认为随机用户代理用户代理(macOS 上的 Chrome) +`UA`: user agent, using random user agent (Chrome on macOS) by default -`NO_RANDOM_UA`: 是否禁用随机用户代理,默认 `null` +`NO_RANDOM_UA`: disable random user agent, default to `null` -### 跨域请求 +### CORS Request -RSSHub 默认对跨域请求限制为当前连接所在的域名,即不允许跨域。可以通过 `ALLOW_ORIGIN: *` 或者 `ALLOW_ORIGIN: www.example.com` 以对跨域访问进行修改。 +RSSHub by default reject CORS requests. This behavior can be modified via setting `ALLOW_ORIGIN: *` or `ALLOW_ORIGIN: www.example.com`. -### 缓存配置 +### Cache Configurations -RSSHub 支持 `memory` 和 `redis` 两种缓存方式 +RSSHub supports two caching methods: memory and redis -`CACHE_TYPE`: 缓存类型,可为 `memory` 和 `redis`,设为空可以禁止缓存,默认为 `memory` +`CACHE_TYPE`: cache type, `memory` or `redis`, empty this value will disable caching, default to `memory` -`CACHE_EXPIRE`: 路由缓存过期时间,单位为秒,默认 `5 * 60` +`CACHE_EXPIRE`: route cache expiry time in seconds, default to `5 * 60` -`CACHE_CONTENT_EXPIRE`: 内容缓存过期时间,每次访问会重新计算过期时间,单位为秒,默认 `1 * 60 * 60` +`CACHE_CONTENT_EXPIRE`: content cache expiry time in seconds, it will be recalculated when it is accessed, default to `1 * 60 * 60` -`REDIS_URL`: Redis 连接地址(redis 缓存类型时有效),默认为 `redis://localhost:6379/` +`REDIS_URL`: Redis target address (invalid when `CACHE_TYPE` is set to memory), default to `redis://localhost:6379/` -`MEMORY_MAX`: 最大缓存数量(memory 缓存类型时有效),默认 `256` +`MEMORY_MAX`: maximum number of cached items (invalid when `CACHE_TYPE` is set to redis), default to `256` -### 代理配置 +### Proxy Configurations -部分路由反爬严格,可以配置使用代理抓取。 +Partial routes have a strict anti-crawler policy, and can be configured to use proxy. -可通过**代理 URI**或**代理选项**或**反向代理**三种方式来配置代理。 +Proxy can be configured through **Proxy URI**, **Proxy options**, or **Reverse proxy**. -#### 代理 URI +#### Proxy URI -`PROXY_URI`: 代理 URI,支持 socks4, socks5(本地查询域名的 SOCKS5,不推荐使用), socks5h(传域名的 SOCKS5,推荐使用,以防止 DNS 污染或 DNS 泄露), http, https,具体以 [socks-proxy-agent](https://www.npmjs.com/package/socks-proxy-agent) NPM 包的支持为准,也可参考[curl 中 SOCKS 代理协议的用法](https://daniel.haxx.se/blog/2020/05/26/curl-ootw-socks5/)。 +`PROXY_URI`: Proxy supports socks4, socks5(hostname is resolved locally, not recommanded), socks5h(hostname is +resolved by the SOCKS server, recommanded, prevents DNS poisoning or DNS leak), http, https. See [socks-proxy-agent](https://www.npmjs.com/package/socks-proxy-agent) NPM package page. See also [cURL OOTW: SOCKS5](https://daniel.haxx.se/blog/2020/05/26/curl-ootw-socks5/). -> 代理 URI 的格式为: +> Proxy URI's format: > > - `{protocol}://{host}:{port}` -> - `{protocol}://{username}:{password}@{host}:{port}` (带身份凭证) +> - `{protocol}://{username}:{password}@{host}:{port}` (with credentials) > -> 一些示例: +> Some examples: > > - `socks4://127.0.0.1:1080` -> - `socks5h://user:pass@127.0.0.1:1080` (用户名为 `user`, 密码为 `pass`) -> - `socks://127.0.0.1:1080` (protocol 为 socks 时表示 `socks5h`) +> - `socks5h://user:pass@127.0.0.1:1080` (username as `user`, password as `pass`) +> - `socks://127.0.0.1:1080` (`socks5h` when protocol is `socks`) > - `http://127.0.0.1:8080` > - `http://user:pass@127.0.0.1:8080` > - `https://127.0.0.1:8443` -#### 代理选项 - -`PROXY_PROTOCOL`: 使用代理,支持 socks,http,https - -`PROXY_HOST`: 代理服务器域名或 IP - -`PROXY_PORT`: 代理服务器端口 - -`PROXY_AUTH`: 给代理服务器的身份验证凭证,`Proxy-Authorization: Basic ${process.env.PROXY_AUTH}` - -`PROXY_URL_REGEX`: 启用代理的 URL 正则表达式,默认全部开启 `.*` - -### 反向代理 +### Reverse proxy -:::caution 注意 +:::caution -这种代理方式无法代理包含 cookie 的请求。 +This proxy method cannot proxy requests that contain cookies. ::: -`REVERSE_PROXY_URL`: 反向代理地址,RSSHub 将会使用该地址作为前缀来发起请求,例如 `https://proxy.example.com/?target=`,对 `https://google.com` 发起的请求将被自动转换为 `https://proxy.example.com/?target=https%3A%2F%2Fgoogle.com` +`REVERSE_PROXY_URL`: Reverse proxy URL, RSSHub will use this URL as a prefix to initiate requests, for example `https://proxy.example.com?target=`, requests to `https://google.com` will be automatically converted to `https://proxy.example.com?target=https%3A%2F%2Fgoogle.com` -你可以使用 Cloudflare Workers 来搭建一个简易的反向代理,例如: +You can use Cloudflare Workers to build a simple reverse proxy, for example: ```js addEventListener('fetch', event => { @@ -618,125 +598,138 @@ async function handleRequest(request) { } ``` -### 用户认证 +#### Proxy options -`protected_route.js` 内的路由将启用 HTTP Basic Authentication 认证 +`PROXY_PROTOCOL`: Using proxy, supports socks, http, https, etc. See [socks-proxy-agent](https://www.npmjs.com/package/socks-proxy-agent) NPM package page and [source](https://github.com/TooTallNate/proxy-agents/blob/63adbcefdb4783cc67c0eb90200886b4064e8639/packages/socks-proxy-agent/src/index.ts#L81) for what these protocols mean. See also [cURL OOTW: SOCKS5](https://daniel.haxx.se/blog/2020/05/26/curl-ootw-socks5/) for reference. -支持该认证协议的阅读器,在添加源地址时,需要在源地址前添加认证信息,例如:`http://usernam3:passw0rd@rsshub.app/protected/rsshub/routes`。 +`PROXY_HOST`: host or IP of the proxy -对于不支持该认证协议的阅读器,请参考 [访问控制配置](#fang-wen-kong-zhi-pei-zhi)。 +`PROXY_PORT`: port of the proxy -`HTTP_BASIC_AUTH_NAME`: Http basic authentication 用户名,默认为 `usernam3`,请务必修改 +`PROXY_AUTH`: credentials to authenticate a user agent to proxy server, `Proxy-Authorization: Basic ${process.env.PROXY_AUTH}` -`HTTP_BASIC_AUTH_PASS`: Http basic authentication 密码,默认为 `passw0rd`,请务必修改 +`PROXY_URL_REGEX`: regex for url of enabling proxy, default to `.*` -### 访问控制配置 +### User Authentication Configurations -RSSHub 支持使用访问密钥 / 码,白名单和黑名单三种方式进行访问控制。开启任意选项将会激活全局访问控制,没有访问权限将会导致访问被拒绝。同时可以通过 `ALLOW_LOCALHOST: true` 赋予所有本地 IP 访问权限。 +Routes in `protected_route.js` will be protected using HTTP Basic Authentication. -#### 黑白名单 +When adding feeds using RSS readers with HTTP Basic Authentication support, authentication information is required, eg: . -- `WHITELIST`: 白名单,设置白名单后黑名单无效 +For readers that do not support HTTP Basic authentication, please refer to [Access Control Configuration](#access-control-configuration). -- `BLACKLIST`: 黑名单 +`HTTP_BASIC_AUTH_NAME`: HTTP basic authentication username, default to `usernam3`, please change asap -黑白名单支持 IP、路由和 UA,模糊匹配,设置多项时用英文逗号 `,` 隔开,例如 `WHITELIST=1.1.1.1,2.2.2.2,/qdaily/column/59` +`HTTP_BASIC_AUTH_PASS`: HTTP basic authentication password, default to `passw0rd`, please change asap -#### 访问密钥 / 码 +### Access Control Configuration -- `ACCESS_KEY`: 访问密钥,用于直接访问所有路由或者生成访问码 +RSSHub supports access control via access key/code, whitelisting and blacklisting, enabling any will activate access control for all routes. `ALLOW_LOCALHOST: true` will grant access to all localhost IP addresses. -访问码为 访问密钥 + 路由 共同生成的 md5,例如: +#### White/blacklisting -| 访问密钥 | 路由 | 生成过程 | 访问码 | +- `WHITELIST`: the blacklist. When set, values in `BLACKLIST` are disregarded + +- `BLACKLIST`: the blacklist + +White/blacklisting support IP, route and UA as values, fuzzy matching. Use `,` as the delimiter to separate multiple values, eg: `WHITELIST=1.1.1.1,2.2.2.2,/qdaily/column/59` + +#### Access Key/Code + +- `ACCESS_KEY`: the access key. When set, access via the key directly or the access code described above + +Access code is the md5 generated based on the access key + route, eg: + +| Access key | Route | Generating access code | Access code | | ----------- | ----------------- | ---------------------------------------- | -------------------------------- | | ILoveRSSHub | /qdaily/column/59 | md5('/qdaily/column/59' + 'ILoveRSSHub') | 0f820530128805ffc10351f22b5fd121 | -- 此时可以通过 `code` 访问路由,例如: +- Routes are accessible via `code`, eg: -- 或使用访问密钥 `key` 直接访问所有路由,例如: +- Or using `key` directly, eg: -访问密钥 / 码与黑白名单的访问控制关系如下: +See the relation between access key/code and white/blacklisting. -| | 正确访问密钥 / 码 | 错误访问密钥 / 码 | 无访问密钥 / 码 | -| ---------- | ----------------- | ----------------- | --------------- | -| 在白名单中 | ✅ | ✅ | ✅ | -| 在黑名单中 | ✅ | ❌ | ❌ | -| 无黑白名单 | ✅ | ❌ | ❌ | +| | Whitelisted | Blacklisted | Correct access key/code | Wrong access key/code | No access key/code | +| ----------- | ----------- | ----------- | ----------------------- | --------------------- | ------------------ | +| Whitelisted | ✅ | ✅ | ✅ | ✅ | ✅ | +| Blacklisted | ✅ | ❌ | ✅ | ❌ | ❌ | -### 日志配置 +### Logging Configurations -`DEBUG_INFO`: 是否在首页显示路由信息。值为非 `true` `false` 时,在请求中带上参数 `debug` 开启显示,例如: 。默认 `true` +`DEBUG_INFO`: display route information on the homepage for debugging purposes. When set to neither `true` nor `false`, use parameter `debug` to enable display, eg: . Default to `true` -`LOGGER_LEVEL`: 指明输出到 console 和日志文件的日志的最大 [等级](https://github.com/winstonjs/winston#logging-levels),默认 `info` +`LOGGER_LEVEL`: specifies the maximum [level](https://github.com/winstonjs/winston#logging-levels) of messages to the console and log file, default to `info` -`NO_LOGFILES`: 是否禁用日志文件输出,默认 `false` +`NO_LOGFILES`: disable logging to log files, default to `false` -`SENTRY`: [Sentry](https://sentry.io) dsn,用于错误追踪 +`SENTRY`: [Sentry](https://sentry.io) dsn, used for error tracking -`SENTRY_ROUTE_TIMEOUT`: 路由耗时超过此毫秒值上报 Sentry,默认 `3000` +`SENTRY_ROUTE_TIMEOUT`: Report Sentry if route execution takes more than this milliseconds, default to `3000` -### 图片处理 +### Image Processing -:::tip 新配置方式 +:::tip New Config Format -我们正在试验新的,更灵活的配置方式。如果有需要,请转到 [通用参数 -> 多媒体处理](/parameter#多媒体处理) 了解更多。 +We are currently testing out a new format, providing end-user with more flexibility. For more info, please refer to [Parameters->Multimedia processing](/parameter#multimedia-processing). -在使用新配置时,请将下方环境变量留空。否则默认图片模版会继续遵循下方配置。 +When using our new config, please leave the following environment vairable blank. By default, image hotlink template will be forced when present. ::: -`HOTLINK_TEMPLATE`: 用于处理描述中图片的 URL,绕过防盗链等限制,留空不生效。用法参考 [#2769](https://github.com/DIYgod/RSSHub/issues/2769)。可以使用 [URL](https://developer.mozilla.org/en-US/docs/Web/API/URL#Properties) 的所有属性(加上后缀 `_ue` 则会对其进行 URL 编码),格式为 JS 变量模板。例子:`${protocol}//${host}${pathname}`, `https://i3.wp.com/${host}${pathname}`, `https://images.weserv.nl?url=${href_ue}` +`HOTLINK_TEMPLATE`: replace image URL in the description to avoid anti-hotlink protection, leave it blank to disable this function. Usage reference [#2769](https://github.com/DIYgod/RSSHub/issues/2769). You may use any property listed in [URL](https://developer.mozilla.org/en-US/docs/Web/API/URL#Properties) (suffixing with `_ue` results in URL encoding), format of JS template literal. e.g. `${protocol}//${host}${pathname}`, `https://i3.wp.com/${host}${pathname}`, `https://images.weserv.nl?url=${href_ue}` -`HOTLINK_INCLUDE_PATHS`: 限制需要处理的路由,只有匹配成功的路由会被处理,设置多项时用英文逗号 `,` 隔开。若不设置,则所有路由都将被处理 +`HOTLINK_INCLUDE_PATHS`: limit the routes to be processed, only matched routes will be processed. Set multiple values with comma `,` as delimiter. If not set, all routes will be processed -`HOTLINK_EXCLUDE_PATHS`: 排除不需处理的路由,所有匹配成功的路由都不被处理,设置多项时用英文逗号 `,` 隔开。可单独使用,也可用于排除已被前者包含的路由。若不设置,则没有任何路由会被过滤 +`HOTLINK_EXCLUDE_PATHS`: exclude routes that do not need to be processed, all matched routes will be ignored. Set multiple values with comma `,` as delimiter. Can be used alone, or to exclude routes that are already included by `HOTLINK_INCLUDE_PATHS`. If not set, no routes will be ignored -:::tip 路由匹配模式 +:::tip Route matching pattern -`HOTLINK_INCLUDE_PATHS` 和 `HOTLINK_EXCLUDE_PATHS` 均匹配路由根路径及其所有递归子路径,但并非子字符串匹配。注意必须以 `/` 开头,且结尾不需要 `/`。 +`HOTLINK_INCLUDE_PATHS` and `HOTLINK_EXCLUDE_PATHS` match the root path and all recursive sub-paths of the route, but not substrings. Note that the path must start with `/` and end without `/`. -例:`/example`, `/example/sub` 和 `/example/anthoer/sub/route` 均可被 `/example` 匹配,但 `/example_route` 不会被匹配。 +e.g. `/example`, `/example/sub` and `/example/anthoer/sub/route` will be matched by `/example`, but `/example_route` will not be matched. -也可带有路由参数,如 `/weibo/user/2612249974` 也是合法的。 +It is also valid to contain route parameters, e.g. `/weibo/user/2612249974`. ::: -### 功能特性 +### Features -:::tip 测试特性 +:::tip Experimental features -这个板块控制的是一些新特性的选项,他们都是**默认关闭**的。如果有需要请阅读对应说明后按需开启 +Configs in this sections are in beta stage, and **are turn off by default**. Please read corresponded description and turn on if necessary. ::: -`ALLOW_USER_HOTLINK_TEMPLATE`: [通用参数 -> 多媒体处理](/parameter#多媒体处理)特性控制 +`ALLOW_USER_HOTLINK_TEMPLATE`: [Parameters->Multimedia processing](/parameter#multimedia-processing) -`FILTER_REGEX_ENGINE`: 控制 [通用参数 -> 内容过滤](/parameter#内容过滤) 使用的正则引擎。可选`[re2, regexp]`,默认`re2`。我们推荐公开实例不要调整这个选项,这个选项目前主要用于向后兼容。 +`FILTER_REGEX_ENGINE`: Define Regex engine used in [Parameters->filtering](/parameter#filtering). Valid value are `[re2, regexp]`. Default value is `re2`. We suggest public instance should leave this value to default, and this option right now is mainly for backward compatibility. -`ALLOW_USER_SUPPLY_UNSAFE_DOMAIN`: 允许用户为路由提供域名作为参数。建议公共实例不要调整此选项,开启后可能会导致 [服务端请求伪造(SSRF)](https://owasp.org/www-community/attacks/Server_Side_Request_Forgery) +`ALLOW_USER_SUPPLY_UNSAFE_DOMAIN`: allow users to provide a domain as a parameter to routes that are not in their allow list, respectively. Public instances are suggested to leave this value default, as it may lead to [Server-Side Request Forgery (SSRF)](https://owasp.org/www-community/attacks/Server_Side_Request_Forgery) -### 其他应用配置 +### Other Application Configurations -`DISALLOW_ROBOT`: 阻止搜索引擎收录,默认开启,设置 false 或 0 关闭 +`DISALLOW_ROBOT`: prevent indexing by search engine, default to enable, set false or 0 to disable -`ENABLE_CLUSTER`: 是否开启集群模式,默认 `false` +`ENABLE_CLUSTER`: enable cluster mode, default to `false` -`NODE_ENV`: 是否显示错误输出,默认 `production` (即关闭输出) +`NODE_ENV`: display error message on pages for authentication failing, default to `production` (i.e. no display) -`NODE_NAME`: 节点名,用于负载均衡,识别当前节点 +`NODE_NAME`: node name, used for load balancing, identify the current node -`PUPPETEER_WS_ENDPOINT`: 用于 puppeteer.connect 的浏览器 websocket 链接,见 [browserWSEndpoint](https://zhaoqize.github.io/puppeteer-api-zh_CN/#?product=Puppeteer&show=api-browserwsendpoint) +`PUPPETEER_WS_ENDPOINT`: browser WebSocket endpoint which can be used as an argument to puppeteer.connect, refer to [browserWSEndpoint](https://pptr.dev/api/puppeteer.browser.wsendpoint) -`CHROMIUM_EXECUTABLE_PATH`: Chromium(或 Chrome)的可执行路径。若 puppeteer 没有下载捆绑的 Chromium(主动跳过下载或体系架构为 arm/arm64),设置此项可启用 puppeteer。或者,偏好 Chrome 而不是 Chromium 时,此项也很有用。**注意**:`PUPPETEER_WS_ENDPOINT` 被设置时,此项不生效;仅在手动部署时有用,对于 Docker 部署,请改用 `chromium-bundled` 版本镜像。 +`CHROMIUM_EXECUTABLE_PATH`: path to the Chromium (or Chrome) executable. If puppeteer is not bundled with Chromium (manually skipped downloading or system architecture is arm/arm64), configuring this can effectively enable puppeteer. Or alternatively, if you prefer Chrome to Chromium, this configuration will help. **WARNING**: only effective when `PUPPETEER_WS_ENDPOINT` is not set; only useful for manual deployment, for Docker, please use the `chromium-bundled` image instead. -`TITLE_LENGTH_LIMIT`: 限制输出标题的字节长度,一个英文字符的长度为 1 字节,部分语言如中文,日文,韩文或阿拉伯文等,统一算作 2 字节,默认 `150` +`TITLE_LENGTH_LIMIT`: limit the length of feed title generated in bytes, an English alphabet counts as 1 byte, the rest such as Chinese, Japanese, Korean or Arabic counts as 2 bytes by design, default to `150` -### 部分 RSS 模块配置 +### Route-specific Configurations -:::tip 提示 +:::tip Notice -此处信息不完整。完整配置请参考路由对应的文档和 `lib/config.js`。 +Configs here are incomplete. + +See docs of the specified route and `lib/config.js` for detailed information. ::: @@ -757,8 +750,8 @@ RSSHub 支持使用访问密钥 / 码,白名单和黑名单三种方式进行 - Bitbucket: [Basic auth with App passwords](https://developer.atlassian.com/cloud/bitbucket/rest/intro/#basic-auth) - - `BITBUCKET_USERNAME`: 你的 Bitbucket 用户名 - - `BITBUCKET_PASSWORD`: 你的 Bitbucket 密码 + - `BITBUCKET_USERNAME`: Your Bitbucket username + - `BITBUCKET_PASSWORD`: Your Bitbucket app password - BTBYR @@ -779,156 +772,169 @@ RSSHub 支持使用访问密钥 / 码,白名单和黑名单三种方式进行 5. 找到请求头中的 Cookie - Civitai - - `CIVITAI_COOKIE`: Civitai 登录后的 cookie 值 + - `CIVITAI_COOKIE`: Cookie of Civitai + +- Discord -- discuz cookies 设定 + - `DISCORD_AUTHORIZATION`: Discord authorization token, can be found in the header of XHR requests after logging in Discord web client - - `DISCUZ_COOKIE_{cid}`: 某 Discuz 驱动的论坛,用户注册后的 Cookie 值,cid 可自由设定,取值范围 \[00, 99], 使用 discuz 通用路由时,通过指定 cid 来调用该 cookie +- Discuz cookie -- disqus 全部路由:[申请地址](https://disqus.com/api/applications/) + - `DISCUZ_COOKIE_{cid}`: Cookie of a forum powered by Discuz, cid can be anything from 00 to 99. When visiting a Discuz route, use cid to specify this cookie. + +- Disqus: [API Key application](https://disqus.com/api/applications/) - `DISQUS_API_KEY`: Disqus API +- douban + + - `DOUBAN_COOKIE`: Cookie of douban user + - E-Hentai - - `EH_IPB_MEMBER_ID`: E-Hentai 账户登录后 cookie 的 `ipb_member_id` 值 - - `EH_IPB_PASS_HASH`: E-Hentai 账户登录后 cookie 的 `ipb_pass_hash` 值 - - `EH_SK`: E-Hentai 账户登录后 cookie 中的`sk`值 - - `EH_IGNEOUS`: ExHentai 账户登录后 cookie 中的`igneous`值。若设置此值,RSS 数据将全部从里站获取 - - `EH_STAR`: E-Hentai 账户获得捐赠等级后将出现该 cookie。若设置此值,图片访问量限制将与账号关联而非 IP 地址 - - `EH_IMG_PROXY`: 封面代理访问地址。若设置此值,封面图链接将被替换为以此值开头。使用 ExHentai 时,封面图需要有 Cookie 才能访问,在一些阅读软件上没法显示封面,可以使用此值搭配一个加 Cookie 的代理服务器实现阅读软件无 Cookie 获取封面图。 + - `EH_IPB_MEMBER_ID`: The value of `ipb_member_id` in the cookie header after logging in E-Hentai + - `EH_IPB_PASS_HASH`: The value of `ipb_pass_hash` in the cookie header after logging in E-Hentai + - `EH_SK`: The value of `sk` in the cookie header after logging in E-Hentai + - `EH_STAR`: The value of `star` in the cookie header if your account has stars. If this value is set, image limit allocation will links to the account rather than IP address + - `EH_IGNEOUS`: The value of `igneous` in the cookie header after logging in ExHentai. If this value is set, RSS will be generated from ExHentai + - `EH_IMG_PROXY`: Cover proxy address. If this is set, the link to the cover image will be replaced with this value at the beginning. When using ExHentai, the cover image requires cookies to access it, so you can use this with a cookie-added proxy server to access the cover image without cookies in some readers. - Fantia - - `FANTIA_COOKIE`: 登录后的 `cookie` , 可以在控制台中查看请求头获取。如果不填会导致部分需要登录后才能阅读的帖子获取异常 + - `FANTIA_COOKIE`: The `cookie` after login can be obtained by viewing the request header in the console, If not filled in will cause some posts that require login to read to get exceptions - Gitee 全部路由:[申请地址](https://gitee.com/api/v5/swagger) - `GITEE_ACCESS_TOKEN`: Gitee 私人令牌 -- GitHub 全部路由:[申请地址](https://github.com/settings/tokens) +- GitHub: [Access Token application](https://github.com/settings/tokens) - `GITHUB_ACCESS_TOKEN`: GitHub Access Token -- Google Fonts:[申请地址](https://developers.google.com/fonts/docs/developer_api#a_quick_example) +- Google Fonts: [API key application](https://developers.google.com/fonts/docs/developer_api#a_quick_example) - `GOOGLE_FONTS_API_KEY`: API key - Instagram: - - `IG_USERNAME`: Instagram 用户名(仅 Private API) - - `IG_PASSWORD`: Instagram 密码(仅 Private API) - - `IG_PROXY`: Instagram 代理 URL(仅 Private API,可选) - - `IG_COOKIE`: Instagram 登录后的 Cookie(仅 Cookie) + - `IG_USERNAME`: Your Instagram username (Private API only) + - `IG_PASSWORD`: Your Instagram password (Private API only) + - `IG_PROXY`: Proxy URL for Instagram (Private API only, optional) + - `IG_COOKIE`: Your Instagram cookie (Cookie only) - 注意,暂**不支持**两步验证。 + Warning: Two Factor Authentication is **not** supported. - Iwara: - - `IWARA_USERNAME`: Iwara 用户名 - - `IWARA_PASSWORD`: Iwara 密码 + - `IWARA_USERNAME`: username of Iwara User + - `IWARA_PASSWORD`: password of Iwara User -- Last.fm 全部路由:[申请地址](https://www.last.fm/api/) +- Last.fm - `LASTFM_API_KEY`: Last.fm API Key -- Mastodon 用户时间线路由:访问 `https://mastodon.example/settings/applications` 申请(替换掉 `mastodon.example`)。需要 `read:search` 权限 +- Email: - - `MASTODON_API_HOST`: API 请求的实例,仅域名,不包括 `http://` 或 `https://` 协议头 - - `MASTODON_API_ACCESS_TOKEN`: 用户 access token, 申请应用后,在应用配置页可以看到申请者的 access token - - `MASTODON_API_ACCT_DOMAIN`: 该实例本地用户 acct 标识的域名,Webfinger account URI,形如 `user@host` + - `EMAIL_CONFIG_{email}`: Mail setting, replace `{email}` with the email account, replace `@` and `.` in email account with `_`, e.g. `EMAIL_CONFIG_xxx_gmail_com`. The value is in the format of `password=password&host=server&port=port`, eg: + - Linux env: `EMAIL_CONFIG_xxx_qq_com="password=123456&host=imap.qq.com&port=993"` + - docker env: `EMAIL_CONFIG_xxx_qq_com=password=123456&host=imap.qq.com&port=993`, please do not include quotations `'`,`"` -- Medium 相关路由:打开控制台,复制 Cookie(理论上只需要 uid 和 sid 即可) +- Mastodon user timeline: apply API here `https://mastodon.example/settings/applications`(repalce `mastodon.example`), please check scope `read:search` - - `MEDIUM_ARTICLE_COOKIE`:请求全文时使用的 Cookie,存在活跃的 Member 订阅时可获取付费内容全文 - - `MEDIUM_COOKIE_{username}`:对应 username 的用户的 Cookie,个性推荐相关路由需要 + - `MASTODON_API_HOST`: API instance domain, only domain, no `http://` or `https://` protocol header + - `MASTODON_API_ACCESS_TOKEN`: user access token + - `MASTODON_API_ACCT_DOMAIN`: acct domain for particular instance, Webfinger account URI, like `user@host` -- MiniFlux 全部路由: +- Medium related routes: Open the console, copy the cookie (in theory, only uid and sid are required) - - `MINIFLUX_INSTANCE`: 用户所用的实例,默认为 MiniFlux 官方提供的 [付费服务地址](https://reader.miniflux.app) - - `MINIFLUX_TOKEN`: 用户的 API 密钥,请登录所用实例后于 `设置` -> `API 密钥` -> `创建一个新的 API 密钥` 处获取 + - `MEDIUM_ARTICLE_COOKIE`: Cookie used when requesting the full article, can access the full text of paid content when there is an active Member subscription. + - `MEDIUM_COOKIE_{username}`: Cookie of the user corresponding to the username, required for personalized recommendation related routes. -- NGA BBS 用于获取帖子内文 +- MiniFlux: - - `NGA_PASSPORT_UID`: 对应 cookie 中的 `ngaPassportUid`. - - `NGA_PASSPORT_CID`: 对应 cookie 中的 `ngaPassportCid`. + - `MINIFLUX_INSTANCE`: The instance used by the user, by default, is the official MiniFlux [paid service address](https://reader.miniflux.app) + - `MINIFLUX_TOKEN`: User's API key, please log in to the instance used and go to `Settings` -> `API Key` -> `Create a new API key` to obtain. -- nhentai torrent:[注册地址](https://nhentai.net/register/) +- nhentai torrent: [Registration](https://nhentai.net/register/) - - `NHENTAI_USERNAME`: nhentai 用户名或邮箱 - - `NHENTAI_PASSWORD`: nhentai 密码 + - `NHENTAI_USERNAME`: nhentai username or email + - `NHENTAI_PASSWORD`: nhentai password - Notion - - `NOTION_TOKEN`: Notion 内部集成 Token,请按照[Notion 官方指引](https://developers.notion.com/docs/authorization#internal-integration-auth-flow-set-up)申请 Token + - `NOTION_TOKEN`: Notion Internal Integration Token, Refer to [Notion Official Set Up Flow](https://developers.notion.com/docs/authorization#internal-integration-auth-flow-set-up) to create Token - pianyuan 全部路由:[注册地址](https://pianyuan.org) - `PIANYUAN_COOKIE`: 对应 cookie 中的 `py_loginauth`, 例: PIANYUAN_COOKIE='py_loginauth=xxxxxxxxxx' -- pixiv 全部路由:[注册地址](https://accounts.pixiv.net/signup) +- Pixabay: [Documentation](https://pixabay.com/api/docs/) + + - `PIXABAY_KEY`: Pixabay API key - - `PIXIV_REFRESHTOKEN`: Pixiv Refresh Token, 请参考 [此文](https://gist.github.com/ZipFile/c9ebedb224406f4f11845ab700124362) 获取,或自行对客户端抓包获取 - - `PIXIV_BYPASS_CDN`: 绕过 Pixiv 前置的 Cloudflare CDN, 使用`PIXIV_BYPASS_HOSTNAME`指示的 IP 地址访问 Pixiv API, 可以解决因 Cloudflare 机器人验证导致的登录失败问题,默认关闭,设置 true 或 1 开启 - - `PIXIV_BYPASS_HOSTNAME`: Pixiv 源站的主机名或 IP 地址,主机名会被解析为 IPv4 地址,默认为`public-api.secure.pixiv.net`;仅在`PIXIV_BYPASS_CDN`开启时生效 - - `PIXIV_BYPASS_DOH`: 用于解析 `PIXIV_BYPASS_HOSTNAME` 的 DoH 端点 URL,需要兼容 Cloudflare 或 Google 的 DoH 服务的 JSON 查询格式,默认为 `https://1.1.1.1/dns-query` - - `PIXIV_IMG_PROXY`: 用于图片地址的代理,因为 pixiv 图片有防盗链,默认为 `https://i.pixiv.re` +- pixiv: [Registration](https://accounts.pixiv.net/signup) -- pixiv fanbox 用于获取付费内容 + - `PIXIV_REFRESHTOKEN`: Please refer to [this article](https://gist.github.com/ZipFile/c9ebedb224406f4f11845ab700124362) to get a `refresh_token` + - `PIXIV_BYPASS_CDN`: bypass Cloudflare bot check by directly accessing Pixiv source server, defaults to disable, set `true` or `1` to enable + - `PIXIV_BYPASS_HOSTNAME`: Pixiv source server hostname or IP address, hostname will be resolved to IPv4 address via `PIXIV_BYPASS_DOH`, defaults to `public-api.secure.pixiv.net` + - `PIXIV_BYPASS_DOH`: DNS over HTTPS endpoint, it must be compatible with Cloudflare or Google DoH JSON schema, defaults to `https://1.1.1.1/dns-query` + - `PIXIV_IMG_PROXY`: Used as a proxy for image addresses, as pixiv images have anti-theft, default to `https://i.pixiv.re` - - `FANBOX_SESSION_ID`: 对应 cookies 中的`FANBOXSESSID`。 +- pixiv fanbox: Get paid content + + - `FANBOX_SESSION_ID`: equals to `FANBOXSESSID` in site cookies. - Saraba1st 用于获取帖子里的图片 - `SARABA1ST_COOKIE`: 对应网页端的 Cookie。 -- Sci-hub 设置,用于科学期刊路由。 +- Sci-hub for scientific journal routes: - - `SCIHUB_HOST`: 可访问的 sci-hub 镜像地址,默认为 `https://sci-hub.se`。 + - `SCIHUB_HOST`: The Sci-hub mirror address that is accessible from your location, default to `https://sci-hub.se`. -- Spotify 全部路由:[注册地址](https://developer.spotify.com) +- Spotify: [API key registration](https://developer.spotify.com) - - `SPOTIFY_CLIENT_ID`: Spotify 应用的 client ID - - `SPOTIFY_CLIENT_SECRET`: Spotify 应用的 client secret + - `SPOTIFY_CLIENT_ID`: Client ID of the application + - `SPOTIFY_CLIENT_SECRET`: Client secret of the application -- Spotify 用户相关路由 +- Spotify (user data related routes): - - `SPOTIFY_REFRESHTOKEN`:用户在此 Spotify 应用的 refresh token。可以利用 [此 gist](https://gist.github.com/outloudvi/d1bbeb5e989db5385384a223a7263744) 获取。 + - `SPOTIFY_REFRESHTOKEN`: The refresh token of the user from the Spotify application. Check [this gist](https://gist.github.com/outloudvi/d1bbeb5e989db5385384a223a7263744) for detailed information. -- Telegram - 贴纸包路由:[Telegram 机器人](https://telegram.org/blog/bot-revolution) +- Telegram: [Bot application](https://telegram.org/blog/bot-revolution) - - `TELEGRAM_TOKEN`: Telegram 机器人 token + - `TELEGRAM_TOKEN`: Telegram bot token -- Twitter 全部路由:[申请地址](https://apps.twitter.com) +- Twitter: [Application creation](https://apps.twitter.com) - - `TWITTER_CONSUMER_KEY`: Twitter Developer API key,支持多个 key,用英文逗号 `,` 隔开 - - `TWITTER_CONSUMER_SECRET`: Twitter Developer API key secret,支持多个 key,用英文逗号 `,` 隔开,顺序与 key 对应 - - `TWITTER_WEBAPI_AUTHORIZAION`: Twitter Web API authorization,格式为 `key:secret` 或 `Bearer ****`,支持多个,用英文逗号 `,` 隔开。如果上述两个环境变量中的任意一个未设置,就会使用 Twitter Web API。然而,没有必要设置这个环境变量,因为 RSSHub 已经内置了目前已知可用的 token。 - - `TWITTER_TOKEN_{handler}`: 对应 Twitter 用户名生成的 token,`{handler}` 替换为用于生成该 token 的 Twitter 用户名,值为 `Twitter API key, Twitter API key secret, Access token, Access token secret` 用逗号隔开,例如:`TWITTER_TOKEN_RSSHub=bX1zry5nG4d1RbESQbnADpVIo,2YrD8qo9sXbB8VlYfVmo1Qtw0xsexnOliU5oZofq7aPIGou0Xx,123456789-hlkUHFYmeXrRcf6SEQciP8rP4lzmRgMgwdqIN9aK,pHcPnfa28rCIKhSICUCiaw9ppuSSl7T2f3dnGYpSM0bod` + - `TWITTER_CONSUMER_KEY`: Twitter Developer API key, support multiple keys, split them with `,` + - `TWITTER_CONSUMER_SECRET`: Twitter Developer API key secret, support multiple keys, split them with `,` + - `TWITTER_WEBAPI_AUTHORIZAION`: Twitter Web API authorization, in format `key:secret` or `Bearer ****`, support multiple ones, split them with `,`. If either of the above environment variables is not set, the Twitter Web API will be used. However, no need to set this environment var since currently known tokens have already been built into RSSHub. + - `TWITTER_TOKEN_{handler}`: The token generated by the corresponding Twitter handler, replace `{handler}` with the Twitter handler, the value is a combination of `Twitter API key, Twitter API key secret, Access token, Access token secret` connected by a comma `,`. Eg. `TWITTER_TOKEN_RSSHub=bX1zry5nG4d1RbESQbnADpVIo,2YrD8qo9sXbB8VlYfVmo1Qtw0xsexnOliU5oZofq7aPIGou0Xx,123456789-hlkUHFYmeXrRcf6SEQciP8rP4lzmRgMgwdqIN9aK,pHcPnfa28rCIKhSICUCiaw9ppuSSl7T2f3dnGYpSM0bod`. -- Wordpress +- Wordpress: - - `WORDPRESS_CDN`: 用于中转 http 图片链接。可供考虑的服务见下表: + - `WORDPRESS_CDN`: Proxy HTTP image link with HTTPS link. Consider using: - | url | backbone | - | ---------------------------------------- | ------------ | + | url | backbone | + | -------------------------------------- | ------------ | | | akamai | | | cloudflare | | | cloudflare | | | cloudflare | | | digitalocean | -- YouTube:[申请地址](https://console.developers.google.com/) +- YouTube: [API Key application](https://console.developers.google.com/) - - 全部路由 - - `YOUTUBE_KEY`: YouTube API Key,支持多个 key,用英文逗号 `,` 隔开 - - 订阅列表路由额外设置 - - `YOUTUBE_CLIENT_ID`: YouTube API 的 OAuth 2.0 客户端 ID - - `YOUTUBE_CLIENT_SECRET`: YouTube API 的 OAuth 2.0 客户端 Secret - - `YOUTUBE_REFRESH_TOKEN`: YouTube API 的 OAuth 2.0 客户端 Refresh Token。可以按照[此 gist](https://gist.github.com/Kurukshetran/5904e8cb2361623498481f4a9a1338aa) 获取。 + - All routes: + - `YOUTUBE_KEY`: YouTube API Key, support multiple keys, split them with `,` + - Extra requirements for subscriptions route: + - `YOUTUBE_CLIENT_ID`: YouTube API OAuth 2.0 client ID + - `YOUTUBE_CLIENT_SECRET`: YouTube API OAuth 2.0 client secret + - `YOUTUBE_REFRESH_TOKEN`: YouTube API OAuth 2.0 refresh token. Check [this gist](https://gist.github.com/Kurukshetran/5904e8cb2361623498481f4a9a1338aa) for detailed instructions. - ZodGame: - - `ZODGAME_COOKIE`: ZodGame 登录后的 Cookie 值 + - `ZODGAME_COOKIE`: Cookie of ZodGame User - 北大未名 BBS 全站十大 @@ -989,12 +995,6 @@ RSSHub 支持使用访问密钥 / 码,白名单和黑名单三种方式进行 - `SEHUATANG_COOKIE`: 登陆色花堂后的 cookie 值。 -- 邮箱 邮件列表路由: - - - `EMAIL_CONFIG_{email}`: 邮箱设置,替换 `{email}` 为 邮箱账号,邮件账户的 `@` 与 `.` 替换为 `_`,例如 `EMAIL_CONFIG_xxx_qq_com`。Linux 内容格式为 `password=密码&host=服务器&port=端口`,docker 内容格式为 `password=密码&host=服务器&port=端口`,例如: - - Linux 环境变量:`EMAIL_CONFIG_xxx_qq_com="password=123456&host=imap.qq.com&port=993"` - - docker 环境变量:`EMAIL_CONFIG_xxx_qq_com=password=123456&host=imap.qq.com&port=993`,请勿添加引号 `'`,`"`。 - - 网易云歌单及听歌排行 - `NCM_COOKIES`: 网易云音乐登陆后的 cookie 值. diff --git a/website/docs/joinus/advanced/_category_.json b/website/docs/joinus/advanced/_category_.json index 56eb5360d44794..9ce123ad03cd71 100644 --- a/website/docs/joinus/advanced/_category_.json +++ b/website/docs/joinus/advanced/_category_.json @@ -1,5 +1,5 @@ { - "label": "高级用法", + "label": "Advanced", "position": 4, "collapsed": false } diff --git a/website/docs/joinus/advanced/advanced-feed.md b/website/docs/joinus/advanced/advanced-feed.md index 945a74f6220166..4a900f45540fde 100644 --- a/website/docs/joinus/advanced/advanced-feed.md +++ b/website/docs/joinus/advanced/advanced-feed.md @@ -4,168 +4,168 @@ sidebar_position: 1 import Route from '@site/src/components/Route'; -# RSS 基础 - -本指南面向希望深入了解如何制作 RSS 订阅源的高级用户。如果您是第一次制作 RSS 订阅源,我们建议先阅读 [制作自己的 RSSHub 路由](/joinus/new-rss/start-code)。 - -一旦您获取了要包含在您的 RSS 订阅源中的数据,就可以将其传递给 `ctx.state.data`。然后RSSHub的中间件 [`template.js`](https://github.com/DIYgod/RSSHub/blob/master/lib/middleware/template.js) 将处理数据并以所需的格式呈现 RSS 输出(默认为RSS 2.0)。除了 [制作自己的 RSSHub 路由](/joinus/new-rss/start-code) 中提到的字段外,您还可以使用以下字段进一步自定义 RSS 订阅源。 - -需要注意的是,并非所有字段都适用于所有的输出格式,因为 RSSHub 支持多种输出格式。下表显示了不同输出格式兼容的字段。我们使用以下符号表示兼容性:`A` 表示 Atom,`J` 表示 JSON Feed,`R` 表示 RSS 2.0。 - -频道级别 - -以下表格列出了你可以用来定制你的 RSS 订阅源频道级别的字段: - -| 字段 | 描述 | 默认值 | 兼容性 | -| :---------- | :---------- | :----------- | :------------ | -| **`title`** | *(推荐)* 源的名称,应为纯文本 | `RSSHub` | A, J, R | -| **`link`** | *(推荐)* 与源关联的网站网址,应链接到一个可读的网站 | `https://rsshub.app` | A, J, R | -| **`description`** | *(可选)* 源的摘要,应为纯文本 | 如果未指定,默认为 **`title`** | J, R | -| **`language`** | *(可选)* 源的主要语言,应为 [RSS语言代码](https://www.rssboard.org/rss-language-codes) 或 ISO 639 语言代码之一 | `zh-cn` | J, R | -| **`image`** | *(推荐)* 表示频道的高清图片的网址 | `undefinded` | J, R | -| **`icon`** | *(可选)* Atom 源的图标 | `undefinded` | J | -| **`logo`** | *(可选)* RSS 源的标志 | `undefinded` | J | -| **`subtitle`** | *(可选)* Atom 源的副标题 | `undefinded` | A | -| **`author`** | *(可选)* Atom 源的作者或 JSON Feed 的作者 | `RSSHub` | A, J | -| **`itunes_author`** | *(可选)* 播客源的作者 | `undefinded` | R | -| **`itunes_category`** | *(可选)* 播客源的分类 | `undefinded` | R | -| **`itunes_explicit`** | *(可选)* 播客源是否含有煽情露骨内容 | `undefinded` | R | -| **`allowEmpty`** | *(可选)* 是否允许空源。如果设置为 `true`,即使没有文章,也会生成源 | `undefinded` | A, J, R | - -在 RSS 订阅源中,每个条目都由描述它的一组字段表示。下表列出了可用的字段: - -| 字段 | 描述 | 默认值 | 兼容性 | -| :---------- | :---------- | :------ | :------ | -| **`title`** | *(必填)* 条目的标题,应仅使用纯文本 | `undefinded` | A, J, R | -| **`link`** | *(推荐)* 条目的链接,应链接到可读的网站 | `undefinded` | A, J, R | -| **`description`** | *(推荐)* 条目的内容。对于 Atom 订阅,应是 `atom:content` 元素。对于 JSON Feed,应是 `content_html` 字段 | `undefinded` | A, J, R | -| **`author`** | *(可选)* 条目的作者 | `undefinded` | A, J, R | -| **`category`** | *(可选)* 条目的分类。字符串或字符串数组皆可 | `undefinded` | A, J, R | -| **`guid`** | *(可选)* 条目的唯一标识符 | **`link || title`** | A, J, R | -| **`pubDate`** | *(推荐)* 条目的发布日期,应该 [遵从规范](/joinus/advanced/pub-date) 是 [Date object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Date) | `undefinded` | A, J, R | -| **`updated`** | *(可选)* 条目的最后修改日期,应该是 [Date object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Date) | `undefinded` | A, J | -| **`itunes_item_image`** | *(可选)* 条目相关联的图片的网址 | `undefinded` | R | -| **`itunes_duration`** | *(可选)* 音频或视频条目的长度,以秒为单位(或格式为 H:mm:ss),应为数字或字符串 | `undefinded` | J, R | -| **`enclosure_url`** | *(可选)* 条目相关联的附件的网址 | `undefinded` | J, R | -| **`enclosure_length`** | *(可选)* 附件文件的大小(以 **byte** 为单位),应为数字 | `undefinded` | J, R | -| **`enclosure_type`** | *(可选)* 附件文件的 MIME 类型,应为字符串 | `undefinded` | J, R | -| **`upvotes`** | *(可选)* 条目的赞数,应为数字 | `undefinded` | A | -| **`downvotes`** | *(可选)* 条目的踩数,应为数字 | `undefinded` | A | -| **`comments`** | *(可选)* 条目的评论数,应为数字 | `undefinded` | A | -| **`media.*`** | *(可选)* 条目相关的媒体。更多详情请参见 [媒体 RSS](https://www.rssboard.org/media-rss) | `undefinded` | R | -| **`doi`** | *(可选)* 条目的数字对象标识符 (DOI),应为格式为 `10.xxx/xxxxx.xxxx` 的字符串 | `undefinded` | R | - -:::caution 格式考虑 -在指定 RSS 订阅源中的某些字段时,重要的是要注意一些格式考虑因素。具体来说,您应避免在以下字段中包含任何换行符、连续的空格或前导/尾随空格:**`title`**,**`subtitle`**(仅适用于 Atom),**`author`**(仅适用于 Atom),**`item.title`** 和 **`item.author`**。 - -虽然大多数 RSS 阅读器将自动修剪这些空字符,但有些阅读器可能无法正确处理它们。因此,为确保与所有 RSS 阅读器兼容,我们建议在输出这些字段之前将其修剪。如果您制作的路由无法容忍修剪这些空字符,您应考虑更改它们的格式。 - -另外,虽然其他字段不会被强制修剪,但我们建议尽可能避免违反上述格式规则。如果您正在使用 Cheerio 从网页中提取内容,时刻谨记 Cheerio 会保留换行和缩进。特别是对于 **`item.description`** 字段,任何预期之内的换行都应转换为 `
` 标签,以防止其被 RSS 阅读器修剪。尤其是您从 JSON 数据中制作 RSS 订阅时,目标网站返回的 JSON 很有可能含有需要显示的换行符,在这种情况下,应将它们转换为 `
` 标签。 - -请牢记这些格式考虑因素,以确保您的 RSS 订阅源与所有 RSS 阅读器兼容。 +# RSS Feed Fundamentals + +This guide is intended for advanced users who want to know how to create an RSS feed in detail. If you're new to creating RSS feeds, we recommend reading [Create Your Own RSSHub Route](/joinus/new-rss/start-code) first. + +Once you have collected the data you want to include in your RSS feed, you can pass it to `ctx.state.data`. RSSHub's middleware [`template.js`](https://github.com/DIYgod/RSSHub/blob/master/lib/middleware/template.js) will then process the data and render the RSS output in the required format (which is RSS 2.0 by default). In addition to the fields mentioned in [Create your own RSSHub route](/joinus/new-rss/start-code), you can customize your RSS feed further using the following fields. + +It's important to note that not all fields are applicable to all output formats since RSSHub supports multiple output formats. The table below shows which fields are compatible with different output formats. We use the following symbols to denote compatibility: `A` for Atom, `J` for JSON Feed, `R` for RSS 2.0. + +Channel level + +The following table lists the fields you can use to customize your RSS feed at channel level: + +| Field | Description | Default | Compatibility | +| :---------- | :---------- | :----------- | :------------ | +| **`title`** | *(Recommended)* The name of the feed, which should be plain text only | `RSSHub` | A, J, R | +| **`link`** | *(Recommended)* The URL of the website associated with the feed, which should link to a human-readable website | `https://rsshub.app` | A, J, R | +| **`description`** | *(Optional)* The summary of the feed, which should be plain text only | If not specified, defaults to **`title`** | J, R | +| **`language`** | *(Optional)* The primary language of the feed, which should be a value from [RSS Language Codes](https://www.rssboard.org/rss-language-codes) or ISO 639 language codes | `zh-cn` | J, R | +| **`image`** | *(Recommended)* The URL of the image that represents the channel, which should be relatively large and square | `undefinded` | J, R | +| **`icon`** | *(Optional)* The icon of an Atom feed | `undefinded` | J | +| **`logo`** | *(Optional)* The logo of an RSS feed | `undefinded` | J | +| **`subtitle`** | *(Optional)* The subtitle of an Atom feed | `undefinded` | A | +| **`author`** | *(Optional)* The author of an Atom feed or the authors of a JSON feed | `RSSHub` | A, J | +| **`itunes_author`** | *(Optional)* The author of a podcast feed | `undefinded` | R | +| **`itunes_category`** | *(Optional)* The category of a podcast feed | `undefinded` | R | +| **`itunes_explicit`** | *(Optional)* Use this to indicate that a feed contains [explicit](https://help.apple.com/itc/podcasts_connect/#/itcfafb6d665) content. | `undefinded` | R | +| **`allowEmpty`** | *(Optional)* Whether to allow empty feeds. If set to `true`, the feed will be generated even if there are no items | `undefinded` | A, J, R | + +Each item in an RSS feed is represented by an object with a set of fields that describe it. The table below lists the available fields: + +| Field | Description | Default | Compatibility | +| :---------- | :---------- | :------------- | :------------ | +| **`title`** | *(Required)* The title of the item, which should be plain text only | `undefinded` | A, J, R | +| **`link`** | *(Recommended)* The URL of the item, which should link to a human-readable website | `undefinded` | A, J, R | +| **`description`** | *(Recommended)* The content of the item. For an Atom feed, it's the `atom:content` element. For a JSON feed, it's the `content_html` field | `undefinded` | A, J, R | +| **`author`** | *(Optional)* The author of the item | `undefinded` | A, J, R | +| **`category`** | *(Optional)* The category of the item. You can use a plain string or an array of strings | `undefinded` | A, J, R | +| **`guid`** | *(Optional)* The unique identifier of the item | **`link || title`** | A, J, R | +| **`pubDate`** | *(Recommended)* The publication date of the item, which should be a [Date object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Date) following [the standard](/joinus/advanced/pub-date) | `undefinded` | A, J, R | +| **`updated`** | *(Optional)* The date of the last modification of the item, which should be a [Date object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Date) | `undefinded` | A, J | +| **`itunes_item_image`** | *(Optional)* The URL of an image associated with the item | `undefinded` | R | +| **`itunes_duration`** | *(Optional)* The length of an audio or video item in seconds (or in the format H:mm:ss), which should be a number or string | `undefinded` | J, R | +| **`enclosure_url`** | *(Optional)* The URL of an enclosure associated with the item | `undefinded` | J, R | +| **`enclosure_length`** | *(Optional)* The size of the enclosure file in **byte**, which should be a number | `undefinded` | J, R | +| **`enclosure_type`** | *(Optional)* The MIME type of the enclosure file, which should be a string | `undefinded` | J, R | +| **`upvotes`** | *(Optional)* The number of upvotes the item has received, which should be a number | `undefinded` | A | +| **`downvotes`** | *(Optional)* The number of downvotes the item has received, which should be a number | `undefinded` | A | +| **`comments`** | *(Optional)* The number of comments for the item, which should be a number | `undefinded` | A | +| **`media.*`** | *(Optional)* The media associated with the item. See [Media RSS](https://www.rssboard.org/media-rss) for more details | `undefinded` | R | +| **`doi`** | *(Optional)* The Digital Object Identifier of the item, which should be a string in the format `10.xxxx/xxxxx.xxxx` | `undefinded` | R | + +:::caution Formatting Considerations +When specifying certain fields in an RSS feed, it's important to keep in mind some formatting considerations. Specifically, you should avoid including any linebreaks, consecutive whitespace, or leading/trailing whitespace in the following fields: **`title`**, **`subtitle`** (only for Atom), **`author`** (only for Atom), **`item.title`**, and **`item.author`**. + +While most RSS readers will automatically trim these fields, some may not process them properly. Therefore, to ensure compatibility with all RSS readers, we recommend trimming these fields before outputting them. If your route cannot tolerate trimming these fields, you should consider changing their format. + +Additionally, while other fields will not be forced to be trimmed, we suggest avoiding violations of the above formatting rules as much as possible. If you are using Cheerio to extract content from web pages, be aware that Cheerio will retain line breaks and indentation. For the **`item.description`** field, in particular, any intended linebreaks should be converted to `
` tags to prevent them from being trimmed by the RSS reader. If you're extracting an RSS feed from JSON data, be aware that the JSON may contain linebreaks that need to be displayed, so you should convert them to `
` tags in this case. + +It's important to keep these formatting considerations in mind to ensure your RSS feed is compatible with all RSS readers. ::: -## 制作 BitTorrent/磁力订阅源 +## Create a BitTorrent/Magnet Feed -RSSHub 支持制作 BitTorrent/磁力订阅源,这将帮助你的 RSS 订阅源。要制作 BitTorrent/磁力订阅源,您需要在 RSS 源添加附加字段,以符合 BitTorrent 客户端的订阅格式。 +RSSHub allows you to create BitTorrent/Magnet feeds, which can be useful for triggering automated downloads. To create a BitTorrent/Magnet feed, you'll need to add **additional** fields to your RSS feed that are in accordance with many downloaders' subscription formats. -以下是制作 BitTorrent/磁力订阅源的示例: +Here's an example of how to create a BitTorrent/Magnet feed: ```js ctx.state.data = { item: [ { - enclosure_url: '', // 磁力链接 - enclosure_length: '', // 文件大小(以 bytes 为单位)(可选) - enclosure_type: 'application/x-bittorrent', // 应固定为 'application/x-bittorrent' + enclosure_url: '', // This should be the Magnet URI + enclosure_length: '', // The file size in bytes (this field is optional) + enclosure_type: 'application/x-bittorrent', // This field should be fixed to 'application/x-bittorrent' }, ], }; ``` -在 RSS 源中包含这些字段,您将能够制作被 BitTorrent 客户端识别并自动下载的 BitTorrent/磁力订阅源。 +By including these fields in your RSS feed, you'll be able to create BitTorrent/Magnet feeds that can be automatically downloaded by compatible downloaders. -### 更新文档 +### Update the documentation -如果您要在 RSSHub 路由中添加对 BitTorrent/磁力订阅支持,最重要的是在文档以反映此功能。要做到这一点,您需要将 `Route` 组件的 `supportBT` 属性设置为 `"1"`。 以下是一个示例: +If you're adding support for BitTorrent/Magnet feeds in your RSSHub route, it's important to update the documentation to reflect this change. To do this, you'll need to set the `supportBT` attribute of the `Route` component to `"1"`. Here's an example: ```vue ``` -通过将 `supportBT` 属性设置为 `"1"`,您将能够准确反映您的路由支持 BitTorrent/磁力订阅。 +By setting the `supportBT` attribute to `"1"`, you'll be able to update your documentation to accurately reflect your route's support for BitTorrent/Magnet feeds. -## 制作期刊订阅源 +## Create a Journal Feed -RSSHub支持制作期刊订阅源。如果用户提供 [通用参数](/parameter#输出-sci-hub-链接) `scihub`,则可以将 `item.link` 替换为 Sci-hub 链接。要制作期刊订阅源,您需要在您的 RSS 源中包含一个附加字段: +RSSHub supports creating journal feeds that can replace `item.link` with a Sci-hub link if users provide the [common parameter](/parameter#sci-hub-link) `scihub`. To create a journal feed, you'll need to include an **additional** field in your RSS feed: ```js ctx.state.data = { item: [ { - doi: '', // 条目的 DOI(例如,'10.47366/sabia.v5n1a3') + doi: '', // This should be the DOI of the item (e.g., '10.47366/sabia.v5n1a3') }, ], }; ``` -通过在 RSS 源中包含 `doi` 字段,您将能够制作与 RSSHub 的 Sci-hub 功能兼容的期刊订阅源。 +By including this `doi` field in your RSS feed, you'll be able to create journal feeds that are compatible with RSSHub's Sci-hub functionality. -### 更新文档 +### Update the documentation -要显示您制作的期刊订阅源支持 Sci-hub 功能,您需要将 `Route` 组件的 `supportScihub` 属性设置为 `"1"`。以下是一个示例: +To update the documentation for your route with support for Sci-hub, you'll need to set the `supportScihub` attribute of the Route component to `"1"`. Here's an example: ```vue ``` -通过将 `supportSciHub` 属性设置为 `"1"`,路由文档将准确反映其支持提供具有 Sci-hub 链接的期刊订阅源。 +By setting the `supportSciHub` attribute to `"1"`, the documentation for your route will accurately reflect its support for creating journal feeds with Sci-hub links. -## 制作播客订阅源 +## Create a Podcast Feed -RSSHub 支持制作与播客播放器订阅格式兼容的播客订阅源。要制作播客订阅源,您需要在RSS源中包含几个附加字段: +RSSHub supports creating podcast feeds that can be used with many podcast players' subscription formats. To create a podcast feed, you'll need to include several **additional** fields in your RSS feed: ```js ctx.state.data = { - itunes_author: '', // **必需**,应为主播名称 - itunes_category: '', // 播客分类 - image: '', // 专辑封面,作为播客源时**必填** + itunes_author: '', // This field is **required** and should specify the podcast author's name + itunes_category: '', // This field specifies the channel category + image: '', // This field specifies the channel's cover image or album art item: [ { - itunes_item_image: '', // 条目的封面图像 - itunes_duration: '', // 可选,音频的长度,以秒为单位 或 H:mm:ss 格式 - enclosure_url: '', // 音频直链 - enclosure_length: '', // 可选,文件大小,以 Byte 为单位 - enclosure_type: '', // 音频文件 MIME 类型(常见类型 .mp3 是 'audio/mpeg',.m4a 是 'audio/x-m4a',.mp4 是 'video/mp4') + itunes_item_image: '', // This field specifies the item's cover image + itunes_duration: '', // This field is optional and specifies the length of the audio in seconds or the format H:mm:ss + enclosure_url: '', // This should be the item's direct audio link + enclosure_length: '', // This field is optional and specifies the size of the file in **bytes** + enclosure_type: '', // This field specifies the MIME type of the audio file (common types are 'audio/mpeg' for .mp3, 'audio/x-m4a' for .m4a, and 'video/mp4' for .mp4) }, ], }; ``` -通过在 RSS 源中包含这些字段,您将能够制作与播客播放器兼容的播客订阅源。 +By including these fields in your RSS feed, you'll be able to create podcast feeds that are compatible with many podcast players. -:::tip 进一步阅读 +:::tip Further Reading - [A Podcaster’s Guide to RSS](https://help.apple.com/itc/podcasts_connect/#/itcb54353390) -- [Google 播客的 RSS Feed 指南](https://support.google.com/podcast-publishers/answer/9889544) +- [RSS feed guidelines for Google Podcasts](https://support.google.com/podcast-publishers/answer/9889544) ::: -### 更新文档 +### Update the documentation -要显示您制作的订阅源与播客播放器兼容,您需要将 `Route` 组件的 `supportPodcast` 属性设置为 `"1"`。以下是一个示例: +To update the documentation for your route with support for podcast feeds, you'll need to set the `supportPodcast` attribute of the `Route` component to `"1"`. Here's an example: ```vue ``` -通过将 `supportPodcast` 属性设置为 `"1"`,路由文档将准确反映其支持播客订阅。 +By setting the `supportPodcast` attribute to `"1"`, the documentation for your route will accurately reflect its support for creating podcast feeds. -## 制作媒体订阅源 +## Create a Media Feed -RSSHub支持制作与 [Media RSS](https://www.rssboard.org/media-rss) 格式兼容的媒体订阅源。要制作体订阅源订阅源,您需要在 RSS 源中包含这些附加字段。 +RSSHub supports creating [Media RSS](https://www.rssboard.org/media-rss) feeds that are compatible with many [Media RSS](https://www.rssboard.org/media-rss) software subscription formats. To create a [Media RSS](https://www.rssboard.org/media-rss) feed, you'll need to include those **additional** fields in your RSS feed. -以下是制作媒体订阅源的示例: +Here's an example of how to create a [Media RSS](https://www.rssboard.org/media-rss) feed: ```js ctx.state.data = { @@ -173,14 +173,14 @@ ctx.state.data = { { media: { content: { - url: '...', // 媒体内容的 URL - type: '...', // 媒体内容的 MIME 类型(例如,对于 .mp3 文件是 'audio/mpeg') + url: '...', // This should be the URL of the media content + type: '...', // This should be the MIME type of the media content (e.g., 'audio/mpeg' for an .mp3 file) }, thumbnail: { - url: '...', // 缩略图 URL + url: '...', // This should be the URL of the thumbnail image }, '...': { - '...': '...', // 亦可包含其他媒体属性 + '...': '...', // Additional media properties can be included here } }, }, @@ -188,24 +188,24 @@ ctx.state.data = { }; ``` -通过在 RSS 源中包含这些字段,您将能够制作与 [Media RSS](https://www.rssboard.org/media-rss) 格式兼容的媒体订阅源。 +By including these fields in your RSS feed, you'll be able to create [Media RSS](https://www.rssboard.org/media-rss) feeds that are compatible with many [Media RSS](https://www.rssboard.org/media-rss) software subscription formats. -## 制作包含互动的 Atom 订阅源 +## Create an Atom Feed with Interactions -RSSHub支持制作包含互动,如点赞、反对和评论的 Atom 订阅源。要制作带有互动的 Atom 订阅源,您需要在 RSS 源中包含附加字段,用于指定每个条目的互动计数。 +RSSHub supports creating Atom feeds that include interactions like upvotes, downvotes, and comments. To create an Atom feed with interactions, you'll need to include **additional** fields in your RSS feed that specify the interaction counts for each item. -以下是制作带有互动的 Atom 订阅源的示例: +Here's an example of how to create an Atom feed with interactions: ```js ctx.state.data = { item: [ { - upvotes: 0, // 条目的点赞数 - downvotes: 0, // 条目的踩数 - comments: 0, // 条目的评论数 + upvotes: 0, // This should be the number of upvotes for this item + downvotes: 0, // This should be the number of downvotes for this item + comments: 0, // This should be the number of comments for this item }, ], }; ``` -通过在 Atom 源中包含这些字段,您将能够制作包含互动的 Atom 订阅源,这些源与支持 Atom 订阅源的阅读器兼容。 +By including these fields in your Atom feed, you'll be able to create Atom feeds with interactions that are compatible with many Atom feed readers. diff --git a/website/docs/joinus/advanced/debug.md b/website/docs/joinus/advanced/debug.md index 7c713c0ac06167..b48ac718f4d955 100644 --- a/website/docs/joinus/advanced/debug.md +++ b/website/docs/joinus/advanced/debug.md @@ -2,21 +2,21 @@ sidebar_position: 5 --- -# 调试 +# Debugging -当调试代码时,除了使用 `console.log` 或将 node 进程附加到调试器,您还可以使用如下方式进行调试。 +When debugging your code, you can use more than just `console.log` or attaching the node process to a debugger. You can also use the following methods for debugging. -注意:需要实例运行在 `debugInfo=true` 的情况下以下方式才有效 +Note: The following methods are only effective when the instance is running with `debugInfo=true`. -## 使用 `ctx.state.json` +## Using `ctx.state.json` -要将自定义对象传递给 ctx.state.json 进行调试,请跟随以下步骤: +To pass a custom object to ctx.state.json for debugging, follow these steps: -1. 创建自定义对象。 -2. 将对象传递给 `ctx.state.json`。 -3. 访问相应的路由 + `.debug.json` 来查看您的对象。例如,如果您想调试 `/furstar/characters/en`,您可以访问 URL:`/furstar/characters/en.debug.json`。 +1. Create your custom object. +2. Assign your object to `ctx.state.json`. +3. Access the corresponding route + `.debug.json` to view your object. For example, if you want to debug the route `/furstar/characters/:lang?`, you can access the URL: `/furstar/characters/en.debug.json` -以下是来自 [furstar/index.js](https://github.com/DIYgod/RSSHub/blob/master/lib/v2/furstar/index.js) 的使用 `ctx.state.json` 的示例: +Here's an example of how to use `ctx.state.json` taken from [furstar/index.js](https://github.com/DIYgod/RSSHub/blob/master/lib/v2/furstar/index.js) ```js const info = utils.fetchAllCharacters(res.data, base); @@ -26,10 +26,10 @@ ctx.state.json = { }; ``` -在上面的示例中,我们将 `info` 对象传递给 `ctx.state.json`,然后可以使用相应的路由 + `.debug.json` 来访问它。 +In the example above, we're passing the `info` object to `ctx.state.json`, which we can then access using the corresponding route + `.debug.json`. ## debug.html -为了快速测试 `ctx.state.data` 中的 description 是否正确,你可以利用 `debug.html` 机制来获取相关条目的 HTML,该链接可以直接在浏览器中打开以预览渲染结果。 +In order to quickly test if the `description` in `ctx.state.data` is correct, you can use the `.debug.html` file suffix to obtain the HTML of the corresponding entry. The link can be directly opened in the browser to preview the rendering result. -使用方式:访问相应的路由 + `.{index}.debug.html`,其中 `{index}` 为你的 `ctx.state.data.item` 中的项目序号(从 0 开始),即返回对应路由结果中的 `ctx.state.data.item[index].description` 信息。 +Usage: Access the corresponding route + `.{index}.debug.html`, where `{index}` is the item number (starting from 0) in your `ctx.state.data.item`. And the data corresponds to the `ctx.state.data.item[index].description` information will be returned as route result. diff --git a/website/docs/joinus/advanced/pub-date.md b/website/docs/joinus/advanced/pub-date.md index 26de7a84c22b7c..4654d801314783 100644 --- a/website/docs/joinus/advanced/pub-date.md +++ b/website/docs/joinus/advanced/pub-date.md @@ -2,58 +2,58 @@ sidebar_position: 4 --- -# 日期处理 +# Date Handling -当你访问网站时,网站通常会提供一个日期或时间戳。本指南将展示如何在代码中正确处理它们。 +When you visit a website, the website usually provides you with a date or timestamp. This tutorial will show you how to properly handle them in your code. -## 规范 +## The Standard -### 没有日期 +### No Date -- 当网站没有提供日期时,**请勿**添加日期,`pubDate` 应当被留空。 -- 当网站提供一个日期但没有准确的时间时,只需要解析日期并**不要添加时间**到 `pubDate` 中。 +- **Do not** add a date when a website does not provide one. Leave the `pubDate` field undefined. +- Parse only the date and **do not add a time** to the `pubDate` field when a website provides a date but not an accurate time. -`pubDate` 必须是: +The `pubDate` field must be a: -1. [Date 对象](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Date) -2. **不推荐**: 使用字符串时,要确保可正确解析,因为它们的行为可能会在部署环境中发生不一致。请尽量避免 `Date.parse()`。 +1. [Date Object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Date) +2. **Not recommended. Only use for compatibility**: Strings that can be parsed correctly because their behavior can be inconsistent across deployment environments. Use `Date.parse()` with caution. -从路由传入的 `pubDate` 应该对应于**服务器使用的时区 / 时间**。有关更多详细信息,请参见下方工具类: +The `pubDate` passed from the route script should correspond to the time zone/time used by the server. For more details, see the following: -## 使用工具类 +## Use utilities class -我们推荐使用 [day.js](https://github.com/iamkun/dayjs) 进行日期处理和时区调整。有两个相关的工具类: +We recommend using [day.js](https://github.com/iamkun/dayjs) for date processing and time zone adjustment. There are two related utility classes: -### 日期时间 +### Date and Time -RSSHub 工具类包括了一个 [day.js](https://github.com/iamkun/dayjs) 的包装函数,它允许你直接解析日期字符串并在大多数情况下获得一个 [Date 对象](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Date)。 +The RSSHub utility class includes a wrapper for [day.js](https://github.com/iamkun/dayjs) that allows you to easily parse date strings and obtain a [Date Object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Date) in most cases. ```js const { parseDate } = require('@/utils/parse-date'); const pubDate = parseDate('2020/12/30'); -// 或 +// OR const pubDate = parseDate('2020/12/30', 'YYYY/MM/DD'); ``` -:::tip 提示 -你可以参考 [day.js 文档](https://day.js.org/docs/zh-CN/parse/string-format#支持的解析占位符列表) 查看所有可用日期格式。 +:::tip Tips +You can refer to the [day.js documentation](https://day.js.org/docs/en/parse/string-format#list-of-all-available-parsing-tokens) for all available date formats. ::: -如果你需要解析相对日期,请使用 `parseRelativeDate`。 +If you need to parse a relative date, use `parseRelativeDate`. ```js const { parseRelativeDate } = require('@/utils/parse-date'); -const pubDate = parseRelativeDate('2天前'); -const pubDate = parseRelativeDate('前天 15:36'); +const pubDate = parseRelativeDate('2 days ago'); +const pubDate = parseRelativeDate('day before yesterday 15:36'); ``` -### 时区 +### Timezone -从网站解析日期时,考虑时区非常重要。有些网站可能不会根据访问者的位置转换时区,导致日期不准确地反映用户的本地时间。为避免此问题,你可以手动指定时区。 +When parsing dates from websites, it's important to consider time zones. Some websites may not convert the time zone according to the visitor's location, resulting in a date that doesn't accurately reflect the user's local time. To avoid this issue, you can manually specify the time zone. -要在代码中手动指定时区,可以使用以下代码: +To manually specify the time zone in your code, use the following code: ```js const timezone = require('@/utils/timezone'); @@ -61,6 +61,6 @@ const timezone = require('@/utils/timezone'); const pubDate = timezone(parseDate('2020/12/30 13:00'), +1); ``` -`timezone` 函数接受两个参数:第一个是 [日期对象](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Date),第二个是时区偏移量。偏移量以小时为单位指定,在此示例中使用了 UTC+1 的时区。 +The timezone function takes two parameters: the first is the original [Date Object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Date), and the second is the time zone offset. The offset is specified in hours, so in this example, a time zone of UTC+1 is used. -这样做将时间转换为服务器时间,方便后续中间件进行处理。 +By doing this, the time will be converted to server time and it will facilitate middleware processing. diff --git a/website/docs/joinus/advanced/script-standard.md b/website/docs/joinus/advanced/script-standard.md index 6e042ab4289608..1ef29747fe2e4d 100644 --- a/website/docs/joinus/advanced/script-standard.md +++ b/website/docs/joinus/advanced/script-standard.md @@ -2,138 +2,138 @@ sidebar_position: 2 --- -# 路由规范 +# Script Standard -## 代码规范 +## Code Style -### 通用准则 +### General Guidelines -- **保持一致!** -- 避免使用已经被废弃的特性。 -- 避免修改 `yarn.lock` 和 `package.json`,除非您添加了新的依赖。 -- 将重复的代码合并为函数。 -- 优先使用更高版本的 ECMAScript 标准特性,而不是使用低版本特性。 -- 按字母顺序排序(大写字母优先),以便更容易找到条目。 -- 尽量使用 HTTPS 而非 HTTP 传输数据。 -- 尽量使用 WebP 格式而非 JPG 格式,因为前者支持更好的压缩。 +- **Be consistent!** +- Avoid using deprecated features. +- Avoid modifying `yarn.lock` and `package.json`, unless you are adding a new dependency. +- Conbine repetitive code into functions. +- Prefer higher ECMAScript Standard features over lower ones. +- Sort the entries alphabetically (uppercase first) to make it easier to find an entry. +- Use HTTPS instead of HTTP whenever possible. +- Use WebP format instead of JPG whenever possible since it offers better compression. -### 代码格式 +### Formatting -#### 缩进 +#### Indentation -- 使用 4 个空格缩进。 +- Use 4 spaces for indentation for consistent and easy-to-read code. -#### 分号 +#### Semicolons -- 在每条语句结尾添加分号。 +- Add a semicolon at the end of each statement for improved readability and consistency. -#### 字符串 +#### String -- 使用单引号而不是双引号。 -- 使用 [模板字符串](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Template_literals) 而非复杂的字符串拼接。 -- 对于 GraphQL 查询,使用 [模板字符串](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Template_literals)。 +- Use single quotes instead of double quotes whenever possible for consistency and readability. +- Use [template literals](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Template_literals) over complex string concatenation. +- Use [template literals](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Template_literals) for GraphQL queries as they make the code more concise and easy to read. -#### 空格 +#### Whitespace -- 在每个文件末尾添加一个空行。 -- 避免尾随空格,代码应整洁易读。 +- Add an empty line at the end of each file. +- Avoid trailing whitespace for a clean and readable codebase. -### 语言特性 +### Language Features -#### 类型转换 +#### Casting -- 避免重复转换同一类型。 +- Avoid re-casting the same type. -#### 函数 +#### Functions -- 优先使用 [箭头函数](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Functions/Arrow_functions),而不是使用 `function` 关键字定义函数。 +- Prefer [arrow functions](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Functions/Arrow_functions) over the `function` keyword. -#### 循环 +#### Loops -- 对于数组,使用 `for-of`,而不是使用 `for`。([javascript:S4138](https://rules.sonarsource.com/javascript/RSPEC-4138)) +- Use `for-of` instead of `for` for arrays ([javascript:S4138](https://rules.sonarsource.com/javascript/RSPEC-4138)). -#### 变量 +#### Variables -- 使用 `const` 和 `let` 而不是 `var`。 -- 每次声明一个变量。 +- Use `const` and `let` instead of `var`. +- Declare one variable per declaration. -### 命名 +### Naming -- 使用 `lowerCamelCase` 命名变量和函数 -- 使用 `kebab-case` 命名文件和文件夹,也可以使用 `snake_case`。 -- 使用 `CONSTANT_CASE` 命名常量。 +- Use `lowerCamelCase` for variables and functions to adhere to standard naming conventions. +- Use `kebab-case` for files and folders. `snake_case` is also acceptable. +- Use `CONSTANT_CASE` for constants. -## v2 路由规范 +## v2 Route Standard -当在 RSSHub 中编写新的路由时,需要按特定方式组织文件。命名空间文件夹应该存储在 `lib/v2` 目录下,并且应包括三个必需文件: +When creating a new route in RSSHub, you need to organize your files in a specific way. Your namespace folder should be stored in the `lib/v2` directory and should include three mandatory files: -- `router.js` 注册路由 -- `maintainer.js` 提供路由维护者信息 -- `radar.js` 为每个路由提供对应 [RSSHub Radar](https://github.com/DIYgod/RSSHub-Radar) 规则 +- `router.js` Registers the routes +- `maintainer.js` Provides information about the route maintainer +- `radar.js` Provide a [RSSHub Radar](https://github.com/DIYgod/RSSHub-Radar) rule for each route -命名空间文件夹结构应该像这样: +Your namespace folder structure should look like this: - ├───lib/v2 - │ ├───furstar - │ ├─── templates - │ ├─── description.art - │ ├─── router.js - │ ├─── maintainer.js - │ ├─── radar.js - │ ├─── someOtherJs.js - │ └───test - │ └───someOtherNamespaces - ... +``` +├───lib/v2 +│ ├───furstar +│ ├─── templates +│ ├─── description.art +│ ├─── router.js +│ ├─── maintainer.js +│ ├─── radar.js +│ ├─── someOtherJs.js +│ └───test +│ └───someOtherNamespaces +... +``` -**所有符合条件的,在 `lib/v2` 路径下的路由将会被自动载入,无需更新 `lib/router.js`** +**All eligible routes under the `lib/v2` path will be automatically loaded without the need for updating the `lib/router.js`.** -### 命名空间 +### Namespace -RSSHub 会将所有路由命名空间的文件夹名附加到路由前面。路由维护者可命名空间视为根目录。 +RSSHub appends the name of all route namespace folders in front of the actual route. Route maintainers should think of the namespace as the root. -#### 命名规范 +#### Naming Standard -- 使用二级域名 (second-level domain, SLD) 作为命名空间。有关 URL 结构的更多信息,请参阅 [此页面](/joinus/new-radar#顶层对象键)。 -- 不要创建相同命名空间的变体。有关更多信息,请参阅 [此页面](/joinus/new-rss/before-start#创建命名空间) +- Use the second-level domain (SLD) as your namespace. You can find more information about URL structure [here](/joinus/new-radar#top-level-object-key). +- Do not create variations of the same namespace. For more information, see [this page](/joinus/new-rss/before-start#create-a-namespace) -### 注册路由 +### Registering a Route -`router.js` 文件应导出一个方法,提供在初始化路由时使用的 `@koa/router` 对象。 +To register a route, the `router.js` file should export a method that provides a `@koa/router` object when initializing the route. -### 维护者列表 +### Maintainer List -`maintainer.js` 文件应导出一个对象,提供与路由相关的维护者信息,包括: +The `maintainer.js` file should export an object that provides maintainer information related to the route, including: -- 键: `@koa/router` 对象中对应的路由 -- 值:一个字符串数组,包括所有维护者的 GitHub ID。 +- Key: Corresponding path in the `@koa/router` object +- Value: Array of string, including all maintainers' GitHub ID. -要生成维护者列表,可使用以下命令:`pnpm run build:maintainer`,它将在 `assets/build/` 目录下一份维护者列表。 +To generate a list of maintainers, use the following command: `pnpm run build:maintainer`, which will create the list under `assets/build/`. -:::danger 警告 -在 `@koa/router` 对象中的路由应该与相应的文档中添加命名空间前的 `path` 一致。 +:::danger Warning +The path in the `@koa/router` object should be the same as the `path` in the corresponding documentation before the namespace appended in front of it. ::: -### Radar 规则 +### Radar Rules -所有路由都需要包含 `radar.js` 文件,其中包括相应的域名。最低要求是规则出现在相应的站点上,即需要填写 `title` 和 `docs` 字段。 +All routes are required to include the `radar.js` file, which includes the corresponding domain name. The minimum requirement for a successful match is for the rule to show up on the corresponding site which requires filling in the `title` and `docs` fields. -要生成完整的 `radar-rules.js` 文件,可使用以下命令:`yarn build:radar`,它将在 `assets/build/` 目录下创建文件。 +To generate a complete `radar-rules.js` file, use the following command: `yarn build:radar`, which will create the file under `assets/build/`. -:::tip 提示 -在提交代码之前,请记得删除所有在 `assets/build/` 中的生成的资源。 +:::tip Tips +Remember to remove all build artifacts in `assets/build/` before committing. ::: -### 渲染模板 +### Rendering Templates -当渲染自定义 HTML 内容(例如 `item.description`)时,**必须**使用 [art-template](https://aui.github.io/art-template/) 进行排版。 +When rendering custom content with HTML, such as `item.description`, using [art-template](https://aui.github.io/art-template/) for layout is mandatory. -所有模板都应放置在路由命名空间下的 `templates` 文件夹中,并使用 `.art` 文件扩展名命名。 +All templates should be placed in the namespace's `templates` folder with the `.art` file extension. -#### 示例 +#### Example -下面是在 [furstar](https://github.com/DIYgod/RSSHub/blob/master/lib/v2/furstar) 命名空间中示例: - - +Here's an example taken from the [furstar](https://github.com/DIYgod/RSSHub/blob/master/lib/v2/furstar) namespace: ```html
@@ -152,12 +152,10 @@ const { art } = require('@/utils/render'); const renderAuthor = (author) => art(path.join(__dirname, 'templates/author.art'), author); ``` - - -### v1 路由规范 +### v1 Route Standard -:::danger 警告 +:::danger Warning -v1 路由规范已被弃用。所有新路由都应遵循 [v2 路由规范](#v2-lu-you-gui-fan)。 +The v1 Route Standard is deprecated. All new routes should be following the [v2 Route Standard](/joinus/advanced/script-standard#v2-route-standard). ::: diff --git a/website/docs/joinus/advanced/use-cache.md b/website/docs/joinus/advanced/use-cache.md index b8cd519947511c..2d61a71981c045 100644 --- a/website/docs/joinus/advanced/use-cache.md +++ b/website/docs/joinus/advanced/use-cache.md @@ -2,13 +2,13 @@ sidebar_position: 3 --- -# 使用缓存 +# Using Cache -所有路由都有一个缓存,该缓存在短时间后过期。您可以通过环境变量来修改 `lib/config.js` 文件中的 `CACHE_EXPIRE` 值使用来更改缓存的持续时间。然而,对于那些内容更新较少的接口,最好是使用 `CACHE_CONTENT_EXPIRE` 来指定较长的缓存过期时间。 +All routes have a cache that expires after a short duration. You can change how long the cache lasts by modifying the `CACHE_EXPIRE` value in the `lib/config.js` file using environment variables. However, for interfaces that have less frequently updated content, it's better to specify a longer cache expiration time using `CACHE_CONTENT_EXPIRE` instead. -例如,为了获取每个 GitHub Issue 的第一个评论的正文,您可以向 `${baseUrl}/${user}/${repo}/issues/${id}` 发出请求,因为 `${baseUrl}/${user}/${repo}/issues` 无法提供此数据。推荐将此数据存储在缓存中,以避免重复向服务器发出请求。 +For example, to retrieve the full text of the first comment for each issue, you can make a request to `${baseUrl}/${user}/${repo}/issues/${id}`, since this data is unavailable through `${baseUrl}/${user}/${repo}/issues`. It's recommended to store this data in the cache to avoid making repeated requests to the server. -以下是如何使用缓存获取数据的示例代码: +Here's an example of how you can use the cache to retrieve the data: ```js const items = await Promise.all( @@ -25,12 +25,12 @@ sidebar_position: 3 ); ``` -以上代码片段来自 [制作自己的 RSSHub 路由](/joinus/new-rss/start-code),展示了如何使用缓存获取每个问题的第一个评论的全文。使用 `ctx.cache.tryGet()` 来确定数据是否已经在缓存中。如果不在,则代码会获取数据并将其存储在缓存中。 +The above code snippet from [Create Your Own RSSHub Route](/joinus/new-rss/start-code#better-reading-experience) shows how to use the cache to get the full text of the first comment of each issue. `ctx.cache.tryGet()` is used to determine if the data is already available within the cache. If it's not, the code retrieves the data and stores it in the cache. -上一个语句返回的对象将被重复使用,并且会添加一个额外的 `description` 属性。每个 `item.link` 的返回缓存将是`{ title, link, pubDate, author, category, description }`。下一次请求相同路由时,将直接返回处理过后的缓存而不是向服务器发出请求并重新计算数据。 +The object returned from the previous statement will be reused, and an extra `description` property will be added to it. The returned cache for each `item.link` will be `{ title, link, pubDate, author, category, description }`. The next time the same path is requested, this processed cache will be used instead of making a request to the server and recomputing the data. -:::caution 注意 -在 `tryGet()` 函数之外声明的变量的任何赋值都不会在缓存命中的情况下被处理。例如,以下代码将无法按预期工作: +:::caution Warning +Any assignments to variables that are declared outside of the `tryGet()` function will not be processed under a cache-hit scenario. For example, the following code will not work as expected: ```js let x = '1'; @@ -39,7 +39,7 @@ sidebar_position: 3 const y = '3'; return y; }) - console.log(x); // 缓存未命中: '2', 缓存命中: '1' + console.log(x); // cache miss: '2', cache hit: '1' console.log(z): // '3' ``` @@ -47,42 +47,42 @@ sidebar_position: 3 ## API -### ctx.cache.tryGet(key, getValueFunc \[, maxAge \[, refresh ]]) +### ctx.cache.tryGet(key, getValueFunc [, maxAge [, refresh ]]) -#### 参数 +#### Parameters -| 名称 | 类型 | 描述 | -| ------------ | ---------------------- | ------------------------------------------------------------------------------------------ | -| key | `string` | *(必填)* 用于存储和获取缓存的键。您可以使用 `:` 作为分隔符创建层次结构。 | -| getValueFunc | `function` \| `string` | *(必填)* 当发生缓存未命中时返回要缓存的数据的函数。 | -| maxAge | `number` | *(可选)* 缓存的最大过期时间(以秒为单位)。如果没有指定,将使用 `CACHE_CONTENT_EXPIRE`。 | -| refresh | `boolean` | *(可选)* 是否在缓存命中时更新缓存过期时间。默认为 `true`。 | +| Name | Type | Description | +| ---- | ---- | ----------- | +| key | `string` | *(Required)* The key used to store and retrieve the cache. You can use `:` as a separator to create a hierarchy. | +| getValueFunc | `function` \| `string` | *(Required)* A function that returns data to be cached when a cache miss occurs. +| maxAge | `number` | *(Optional)* The maximum age of the cache in seconds. If not specified, `CACHE_CONTENT_EXPIRE` will be used. | +| refresh | `boolean` | *(Optional)* Whether to renew the cache expiration time when the cache is hit. `true` by default. | -#### 定义在 +#### Defined in [lib/middleware/cache/index.js](https://github.com/DIYgod/RSSHub/blob/master/lib/middleware/cache/index.js#L58) -:::tip 提示 -以下是使用缓存的高级方法。大多数情况下,您应使用 `ctx.cache.tryGet()`。 +:::tip Tips +Below are advanced methods for using cache. You should use `ctx.cache.tryGet()` most of the time. -请注意,当使用 `ctx.cache.get()` 获取缓存时,您需要使用 `JSON.parse()`。 +Note that you need to use `JSON.parse()` when retrieving the cache using `ctx.cache.get()`. ::: -### ctx.cache.get(key \[, refresh ]) +### ctx.cache.get(key [, refresh ]) -#### 参数 +#### Parameters -| 名称 | 类型 | 描述 | -| ------- | --------- | -------------------------------------------------------------------- | -| key | `string` | *(必填)* 用于检索缓存的键。您可以使用 `:` 作为分隔符创建层次结构。 | -| refresh | `boolean` | *(可选)* 是否在缓存命中时更新缓存过期时间。默认为`true`。 | +| Name | Type | Description | +| ---- | ---- | ----------- | +| key | `string` | *(Required)* The key used to retrieve the cache. You can use `:` as a separator to create a hierarchy. | +| refresh | `boolean` | *(Optional)* Whether to renew the cache expiration time when the cache is hit. `true` by default. | -### ctx.cache.set(key, value \[, maxAge ]) +### ctx.cache.set(key, value [, maxAge ]) -#### 参数 +#### Parameters -| 名称 | 类型 | 描述 | -| ------ | --------------------- | ----------------------------------------------------------------------------------------- | -| key | `string` | *(必填)* 用于存储缓存的键。您可以使用`:`作为分隔符创建层次结构。 | -| value | `function`\| `string` | *(必填)* 要缓存的值。 | -| maxAge | `number` | *(可选)* 缓存的最大过期时间 (以秒为单位)。如果没有指定,将使用 `CACHE_CONTENT_EXPIRE`。 | +| Name | Type | Description | +| ---- | ---- | ----------- | +| key | `string` | *(Required)* The key used to store the cache. You can use `:` as a separator to create a hierarchy. | +| value | `function`\| `string` | *(Required)* The value to be cached. | +| maxAge | `number` | *(Optional)* The maximum age of the cache in seconds. If not specified, `CACHE_CONTENT_EXPIRE` will be used. | diff --git a/website/docs/joinus/new-radar.md b/website/docs/joinus/new-radar.md index 0248f5588dc727..9a813a251b8cd5 100644 --- a/website/docs/joinus/new-radar.md +++ b/website/docs/joinus/new-radar.md @@ -2,13 +2,13 @@ sidebar_position: 3 --- -# 提交新的 RSSHub Radar 规则 +# New RSSHub Radar Rules -如果需要查看新规则的结果,建议您安装浏览器扩展程序。您可以在 [参与我们](/joinus/quick-start#提交新的-rsshub-radar-规则) 页面下载适合您浏览器的扩展程序。 +If you want to see the results, we suggest you install the browser extension. You can download it for your browser on the [Join Us](/joinus/quick-start#submit-new-rsshub-radar-rules-before-you-start) page. -## 编写规则 +## Code the rule -要制作新的 RSSHub Radar 规则,需要在 `/lib/v2/` 目录下,相应的域名空间创建 `radar.js` 文件。下面以制作 `GitHub 仓库 Issues` 的 RSS 源为例,详见此处。编写的代码应如下所示: +To create a new RSS feed, create a file called `radar.js` under the corresponding namespace in [/lib/v2/](https://github.com/DIYgod/RSSHub/tree/master/lib/v2). We will continue to use the example of creating an RSS feed for `GitHub Repo Issues`, which is described [here](/joinus/new-rss/before-start). The resulting code will look like this: ```js module.exports = { @@ -16,8 +16,8 @@ module.exports = { _name: 'GitHub', '.': [ { - title: '仓库 Issues', - docs: 'https://docs.rsshub.app/programming#github', + title: 'Repo Issues', + docs: 'https://docs.rsshub.app/routes/programming#github', source: ['/:user/:repo/issues/:id', '/:user/:repo/issues', '/:user/:repo'], target: '/github/issue/:user/:repo', }, @@ -26,22 +26,22 @@ module.exports = { }; ``` -## 顶层对象键 +## Top-level Object key -对象键是域名本身,不含任何子域名、URL 路径或协议。 +The object key is the domain name without any subdomains, URL path, or protocol. -![URL 构成](https://wsrv.nl/?url=https://enwpgo.files.wordpress.com/2022/10/image-30.png&output=webp) +![Struction of a URL](https://wsrv.nl/?url=https://enwpgo.files.wordpress.com/2022/10/image-30.png&output=webp) -在此示例中,域名为 `github.com`,对象键则为 `github.com`。 +In this case, the domain name is `github.com`, so the object key is `github.com`. -## 内部对象键 +## Inner object key -第一个内部对象键是 `_name`,是网站的名称。这应与路由文档的二级标题 (`##`) 相同。在此示例中是 `GitHub`。 +The first inner object key is `_name`, which is the name of the website. This should be the same as the level 2 heading (`##`) of the route documentation. In this case, it's `GitHub`. -其余的内部对象键是网站的子域名。如果要匹配的网站没有子域名,或者想同时匹配 `www.example.com` 和 `example.com`,则应使用 `'.'`。在此示例中,我们将使用 `'.'`,因为我们希望匹配 `github.com`。请注意,每个子域名键应返回**一个对象数组**。 +The rest of the inner object keys are the subdomains of a website. If a website you want to match does not have any subdomains, or you want to match both `www.example.com` and `example.com`, use `'.'` instead. In this case, we will use `'.'` since we want to match `github.com`. Note that each subdomain should return **an array of objects**. - + ```js{4} module.exports = { @@ -102,42 +102,46 @@ module.exports = { ### `title` -标题是*必填*字段,应与路由文档的三级标题 (`###`) 相同。在此示例中,它是`仓库 Issues`。在 `title` 中无须重复网站名称 (`_name`),即 `GitHub`。 +The title is a *required* field and should be the same as the level 3 heading (`###`) of the route documentation. In this case, it's `Repo Issues`. Do not repeat the website name (`_name`), which is `GitHub`, in `title`. ### `docs` -文档链接也是*必填*字段。在这种情况下,`GitHub 仓库 Issues` 的文档链接将是 `https://docs.rsshub.app/programming#github`。请注意,URL hash 应位于二级标题 (`##`) 处,而不是三级标题 (`###`) `https://docs.rsshub.app/programming#github-cang-ku-issues`。 +The documentation link is also a *required* field. In this case, the documentation link for `GitHub Repo Issues` will be `https://docs.rsshub.app/routes/programming#github`. + +Note that the hash should be positioned to the level 2 heading (`##`), and not `https://docs.rsshub.app/routes/programming#github-repo-issues`. ### `source` -source 是*可选*字段,应指定 URL 路径。如果不想匹配任何 URL 路径,请将其留空。它只会出现在 RSSHub Radar 浏览器扩展程序的`适用于当前网站的 RSSHub`选项中。 +The source field is *optional* and should specifies the URL path. Leave it blank if you don't want to match any URL paths. It only appears in `RSSHub for the current site` option of the RSSHub Radar browser extension. -source 应为一个字符串数组。例如,如果 `GitHub 仓库 Issues` 的 source 是 `/:user/:repo`,则意味着当您访问 `https://github.com/DIYgod/RSSHub` 时将匹配 `/:user/:repo`,此时返回的结果 params 将是:`{user: 'DIYgod', repo: 'RSSHub'}`。浏览器扩展程序使用这些参数根据 target 字段建立 RSSHub 订阅地址。 +The source should be an array of strings. For example, if the source for `GitHub Repo Issues` is `/:user/:repo`, it means that when you visit `https://github.com/DIYgod/RSSHub`, which matches the `github.com/:user/:repo` pattern, the parameters for this URL will be: `{user: 'DIYgod', repo: 'RSSHub'}`. The browser extension uses these parameters to create an RSSHub subscription address based on the `target` field. -:::caution 注意 -如果要提取的值在 URL 参数或 URL hash 中,请使用 target 函数而不是 source 字段。 此外,请记住,source 字段仅匹配 URL 路径,而不匹配 URL 的任何其他部分。 +:::caution Warning +If the value you want to extract is in the URL search parameters or URL hash, use target as a function instead of the `source` field. Also, remember that the `source` field only matches the URL path and not any other parts of the URL. ::: -您也可以使用 `*` 符号执行通配符匹配。请注意,此处的语法与 [path-to-regexp](https://github.com/pillarjs/path-to-regexp) 不同。例如,`/:user/:repo/*` 将匹配 `https://github.com/DIYgod/RSSHub/issues` 和 `https://github.com/DIYgod/RSSHub/issues/1234`。如果要对匹配结果进行命名,可以在 `*` 符号后放置变量名。例如,`/user/:repo/*path`,在此情况下,`path` 将是 `issues` 和 `issues/1234`。 +You can use the `*` symbol to perform wildcard matching. Note that the syntax here is not the same as the [path-to-regexp](https://github.com/pillarjs/path-to-regexp). For instance, `/:user/:repo/*` will match both `https://github.com/DIYgod/RSSHub/issues` and `https://github.com/DIYgod/RSSHub/issues/1234`. If you want to name the matching result, you can place the variable name after the `*` symbol. For example, `/user/:repo/*path`, whereby path will be `issues` and `issues/1234` in the above scenario. ### `target` -目标是**可选**字段,并用于生成 RSSHub 订阅地址,它可以接受字符串或函数作为输入。如果你不想建立 RSSHub 订阅地址,可以将此字段留空。 +The target field is *optional* and is used to generate an RSSHub subscription address. It accepts both a string or a function. If you don't want to create an RSSHub subscription address, leave this field empty. + +For the `GitHub Repo Issues` example, the corresponding route path in the RSSHub documentation is `/github/issue/:user/:repo`. -以 `GitHub 仓库 Issues` 为例,在 RSSHub 文档中相应的路由为 `/github/issue/:user/:repo`。 +After matching the `user` with `DIYgod` and `repo` with `RSSHub` in the source path, the `:user` in the RSSHub route path will be replaced with `DIYgod`, and `:repo` will be replaced with `RSSHub`, resulting in `/github/issue/DIYgod/RSSHub`. -在将 source 路径中的 `user` 匹配为 `DIYgod`,`repo` 匹配为 `RSSHub` 后,RSSHub 路由中的 `:user` 将被替换为 `DIYgod`,`:repo` 将被替换为 `RSSHub`,结果为 `/github/issue/DIYgod/RSSHub`。 +#### `target` as a function -#### `target` 函数 +In some cases, the source path may not match the desired parameters for an RSSHub route. In these situations, we can use the `target` field as a function with `params`, `url`, and `document` parameters. -如果 source 路径不能匹配 RSSHub 路由的期望参数,则可以将 target 作为函数使用,与 `params`、`url` 和 `document` 参数一起使用。其中,`params` 参数包含 `source` 字段匹配到的参数,而 `url` 参数是当前的网页 URL 字符串,`document` 参数是 [document 接口](https://developer.mozilla.org/docs/Web/API/document)。 +The `params` parameter contains the parameters matched by the `source` field, while the `url` parameter is the current web page URL string, and the `document` parameter is the [document interface](https://developer.mozilla.org/docs/Web/API/document). -需要注意的是,`target` 函数在沙盒中运行,对 `document` 的任何更改都不会反映在网页中。 +It is essential to note that the `target` method runs in a sandbox, and any changes made to `document` will not be reflected in the web page. -下面是使用 `target` 字段作为函数的两个示例: +Here are two examples of how to use the `target` field as a function: - + ```js{9} module.exports = { @@ -145,8 +149,8 @@ module.exports = { _name: 'GitHub', '.': [ { - title: '仓库 Issues', - docs: 'https://docs.rsshub.app/en/routes/programming#github', + title: 'Repo Issues', + docs: 'https://docs.rsshub.app/routes/programming#github', source: ['/:user/:repo/issues/:id', '/:user/:repo/issues', '/:user/:repo'], target: (params) => `/github/issue/${params.user}/${params.repo}`, }, @@ -156,7 +160,7 @@ module.exports = { ``` - + ```js{9} module.exports = { @@ -164,8 +168,8 @@ module.exports = { _name: 'GitHub', '.': [ { - title: '仓库 Issues', - docs: 'https://docs.rsshub.app/en/routes/programming#github', + title: 'Repo Issues', + docs: 'https://docs.rsshub.app/routes/programming#github', source: ['/:user/:repo'], target: (_, url) => `/github/issue${new URL(url).pathname}` }, @@ -177,26 +181,26 @@ module.exports = { -两个示例将返回与 [第一个示例](/joinus/new-radar#编写规则) 相同的 RSSHub 订阅地址。 +Both the above examples will return the same RSSHub subscription address as the [first example](/joinus/new-radar#code-the-rule). ### RSSBud -[RSSBud](https://github.com/Cay-Zhang/RSSBud) 支持 RSSHub Radar 的规则并且也会自动更新,但是请注意: +[RSSBud](https://github.com/Cay-Zhang/RSSBud) supports RSSHub Radar rules and will also be updated automatically, but please note that: -- 使用 `'.'` 子域名可以使 RSSBud 支持常见的移动端子域名,例如 `m`/`mobile`。 -- 在 `target` 中使用 `document` 的规则并不适用于 RSSBud:RSSBud 不是浏览器扩展程序,它只能获取和分析网站的 URL,不能运行 JavaScript。 +- Use `'.'` subdomain allows RSSBud to support common mobile domains such as `m` / `mobile` +- Use `document` in `target` does not apply to RSSBud: RSSBud is not a browser extension, it only fetches and analyzes the URL of a website, it cannot run JavaScript -### 补充文档 +### Update the Documentation -[如前所述](/joinus/new-rss/add-docs#其他组件),在 RSSHub 文档添加 radar="1" 将显示“支持浏览器扩展”的徽章。如果规则还与 RSSBud 兼容,则添加 rssbud="1" 将显示“支持 RSSBud”的徽章。 +As mentioned earlier in [Other components](/joinus/new-rss/add-docs#documentation-examples-other-components), adding `radar="1"` in the RSSHub docs will show a `Support browser extension` badge. If the rule is also compatible with RSSBud, adding `rssbud="1"` will show a `Support RSSBud` badge. -## 调试 Radar 规则 +## Debugging Radar Rules -你可以在浏览器中的 RSSHub Radar 扩展设置中调试你的 radar 规则。首先,打开设置并切换到 “规则列表” 选项页。然后滚动到页面底部,您会看到一个文本框。在这里,您可以使用您的新规则替换旧规则以进行调试。 +You can debug your radar rules in the RSSHub Radar extension settings of your browser. First, open the settings and switch to the "List of rules" tab. Then scroll down to the bottom of the page and you will see a text field. Here, you can replace the old rules with your new rules for debugging. -如果担心失去原来的 RSSHub Radar 规则,那就不要担心,如果你在设置页面中点击“立即更新”按钮,它将会被恢复。 +If you are worried about losing the original RSSHub radar, don't be. It will be restored if you click the "Update Now" button in the settings page. -以下是几个可以用来调试的 radar 规则示例: +Here's an example radar rule that you can play with: ```js ({ @@ -204,8 +208,8 @@ module.exports = { _name: 'GitHub', '.': [ { - title: '仓库 Issues', - docs: 'https://docs.rsshub.app/en/routes/programming#github', + title: 'Repo Issues', + docs: 'https://docs.rsshub.app/routes/programming#github', source: ['/:user/:repo/issues/:id', '/:user/:repo/issues', '/:user/:repo'], target: '/github/issue/:user/:repo', }, @@ -214,7 +218,7 @@ module.exports = { }) ``` -:::note 其他示例 +:::note Extra examples ```js ({ diff --git a/website/docs/joinus/new-rss/_category_.json b/website/docs/joinus/new-rss/_category_.json index bdf18947a92163..64278cf29b3ace 100644 --- a/website/docs/joinus/new-rss/_category_.json +++ b/website/docs/joinus/new-rss/_category_.json @@ -1,5 +1,5 @@ { - "label": "提交新的 RSSHub 规则", + "label": "New RSSHub Rules", "position": 2, "collapsed": false } diff --git a/website/docs/joinus/new-rss/add-docs.md b/website/docs/joinus/new-rss/add-docs.md index f980deefbb506d..6dcff33591f843 100644 --- a/website/docs/joinus/new-rss/add-docs.md +++ b/website/docs/joinus/new-rss/add-docs.md @@ -4,11 +4,11 @@ sidebar_position: 4 import Route from '@site/src/components/Route'; -# 添加文档 +# Add documentation -现在我们完成了代码,是时候为您的路由添加文档了。在 [文档 (/website/)](https://github.com/DIYgod/RSSHub/blob/master/website) 中打开相应的文件,本例中是 `website/docs/routes/programming.md`。 +Now that we have completed the code, it's time to add the documentation for your route. Open the appropriate file in the [document (/website/docs)](https://github.com/DIYgod/RSSHub/blob/master/website/docs), which in this example is `/website/i18n/en/docusaurus-plugin-content-docs/current/routes/programming.md`. -为了实时预览文档,您需要在 **`website` 目录** 下安装文档的依赖项。在终端中输入以下命令: +In order to preview the documentation in real-time, you need to install the dependencies for the documentation. Run the following command in the **`website` directory**: @@ -34,49 +34,50 @@ npm install -您现在可以在 **`website` 目录** 下运行以下命令实时预览文档: +You can now preview the documentation in real-time by running the following command in the **`website` directory**: ```bash -pnpm run start +pnpm run start -- --locale en ``` ```bash -yarn start +yarn start --locale en ``` ```bash -npm run start +npm run start -- --locale en ``` -文档使用 Markdown 编写,并使用 [VuePress v1](https://v1.vuepress.vuejs.org) 渲染。 +The documentation is written in Markdown and rendered with [VuePress v1](https://v1.vuepress.vuejs.org). -要为您的路由添加文档,请使用 Vue 组件。它们类似于 HTML 标签。以下是最常用的组件: +To add documentation to your route, use Vue components. They work like HTML tags. The following are the most commonly used components: -- `author`:路由维护者,用单个空格分隔。应与 [`maintainer.js`](/joinus/new-rss/before-start#maintainerjs) 相同 -- `example`:路由示例,以 `/` 开头 -- `path`:路由,应与添加命名空间后 [maintainer.js](/joinus/new-rss/before-start#maintainerjs) 中的键相同。在之前的教程中,它为 `/github/issue/:user/:repo?` -- `paramsDesc`:路由参数描述,以字符串数组形式,支持 Markdown。 - - 描述必须按照它们在路由中出现的顺序。 - - 描述的数量**应**与 `path` 中的参数数量匹配。如果漏掉一个描述,则构建过程会失败。 - - 以 `?`,`*` 或 `+` 结尾的路由参数将自动分别标记为`可选`,`零个或多个`或`一个或多个`,无须再次提及。 - - 没有符号后缀的路由参数将自动标记为`必选` - - 如果参数是可选的,请提及其默认值。 +- `author`: The route maintainer(s), separated by a single space. It should be the same as [`maintainer.js`](/joinus/new-rss/before-start#understand-the-basics-maintainer-js) +- `example`: The route example, with a leading `/` +- `path`: The route path, which should be the same as the key in [`maintainer.js`](/joinus/new-rss/before-start#understand-the-basics-maintainer-js) with the namespace. In the above example, it is `/github/issue/:user/:repo?` +- `paramsDesc`: The route parameter description, in an array of strings that support Markdown. + - The description **must** follow the order in which they appear in the path. + - The number of description should match with the number of parameters in `path`. If you miss a description, the build will fail. + - Route parameters ending with `?`, `*` or `+` will be automatically marked as `optional`, `zero or more` or `one or more`, respectively. + - Route parameters without a suffix are marked as `required` + - There's no need to explicitly mention the necessity of path parameters again. + - If a parameter is optional, make sure to mention the default value. -## 文档示例 +## Documentation examples -### 仓库 Issues(无参数) +### Repo Issues (No parameter) ```vue @@ -88,117 +89,117 @@ npm run start --- -### 仓库 Issues(多个参数) +### Repo Issues (Multiple parameters) ```vue - + ``` --- - + --- -### 关键词(带表格的说明) +### Keyword (Description with table) ```vue - + -| 只看非 R18 内容 | 只看 R18 内容 | 不过滤 | -| ------------ | -------- | ------------ | -| safe | r18 | 空或其他任意值 | +| only not R18 | only R18 | no filter | +| ------------ | -------- | -------------- | +| safe | r18 | empty or other | ``` --- - + -| 只看非 R18 内容 | 只看 R18 内容 | 不过滤 | -| ------------ | -------- | ------------ | -| safe | r18 | 空或其他任意值 | +| only not R18 | only R18 | no filter | +| ------------ | -------- | -------------- | +| safe | r18 | empty or other | --- -### 自定义容器 +### Custom containers -如果您想提供关于路由的更多信息,可以使用这些自定义容器: +If you'd like to provide additional information about a particular route, you can use these custom containers: ```md -:::tip 提示标题 -这是一个提示。 +:::tip Tips title +This is a tip. ::: -:::caution 警告标题 -这是一个警告。 +:::caution Warning title +This is a warning. ::: -:::danger 危险标题 -这是一条危险的警告。 +:::danger Danger title +This is a dangerous warning. ::: -:::note 详细标题 -这是一个详细块。 +:::note Details title +This is a details block. ::: ``` --- -:::tip 提示标题 -这是一个提示。 +:::tip Tips title +This is a tip. ::: -:::caution 警告标题 -这是一个警告。 +:::caution Warning title +This is a warning. ::: -:::danger 危险标题 -这是一条危险的警告。 +:::danger Danger title +This is a dangerous warning. ::: -:::note 详细标题 -这是一个详细块。 +:::note Details title +This is a details block. ::: --- -### 其他组件 +### Other components -除了路由组件之外,还有几个组件可用于提供有关路径的更多信息: +In addition to the route components, there are several other components you can use to provide more information about your route: -- `anticrawler`:如果目标网站有反爬机制,则设置为 `1`。 -- `puppeteer`:如果源使用 puppeteer 抓取,则设置为 `1`。 -- `radar`:如果此源有相应的 Radar 规则,则设置为 `1`。 -- `rssbud`:如果 Radar 规则与 RSSBud 兼容,则设置为 `1`。 -- `selfhost`:如果 RSS 源需要通过环境变量进行额外配置,则设置为 `1`。 -- `supportBT`:如果支持被 BitTorrent 客户端识别,则设置为 `1`。 -- `supportPodcast`:如果源支持播客,则设置为 `1`。 -- `supportScihub`:如果源支持 Sci-Hub,则设置为 `1`。 +- `anticrawler`: set to `1` if the target website has an anti-crawler mechanism. +- `puppeteer`: set to `1` if the feed uses puppeteer. +- `radar`: set to `1` if the feed has a radar rule. +- `rssbud`: set to `1` if the radar rule is also compatible with RSSBud +- `selfhost`: set to `1` if the feed requires extra configuration through environment variables. +- `supportBT`: set to `1` if the feed supports BitTorrent. +- `supportPodcast`: set to `1` if the feed supports podcasts. +- `supportScihub`: set to `1` if the feed supports Sci-Hub. -通过添加这些组件,您可以向用户提供有用的信息,并使其更易于理解和使用您的路由。将这些组件添加到路由文档中将在其前面添加一个徽章。 +By using these components, you can provide valuable information to users and make it easier for them to understand and use your route. Adding these components to your route documentation will add a badge in front of it. ```vue - + ``` --- - + --- -## 其他事项 +## Other things to keep in mind -- 为路由添加文档时,请使用三级标题(`###`)。如果路由文档没有二级标题,则添加二级标题(`##`)。 -- 在每个标题和内容之间留一个空行。这有助于确保文档可以成功构建。 -- 如果文档包含大型表格,建议将其放入 [details 容器](#wen-dang-shi-li-zi-ding-yi-rong-qi) 中。 -- 组件可以有两种写法:自闭合标签形式(``)或成对标签形式(`...`)。 -- **别忘了关闭标签!** -- 在提交 Pull Request 之前,请务必运行在 RSSHub 的根目录运行以下命令检查和格式化您的代码: +- When documenting a route, use a level 3 heading (`###`). If the route documentation doesn't have a main section heading, add a level 2 heading (`##`). +- Leave a blank line between each heading and the following content. This will help ensure that your documentation can be built successfully. +- If the documentation contains a large table, it is suggested to put it inside a [details container](/joinus/new-rss/add-docs#documentation-examples-custom-containers) +- Components can be written in two ways: as a self-closing tag (``) or as a pair of tags (`...`). +- **Remember to close the tag!** +- Don't forget to run the following command in the **root directory** of the project to check and format your code before committing and submitting a merge request: diff --git a/website/docs/joinus/new-rss/before-start.md b/website/docs/joinus/new-rss/before-start.md index b978def6f9c39e..8f616a3d9aae36 100644 --- a/website/docs/joinus/new-rss/before-start.md +++ b/website/docs/joinus/new-rss/before-start.md @@ -2,13 +2,13 @@ sidebar_position: 2 --- -# 开始之前 +# Just before you start -在本教程中,我们将通过制作一个 [GitHub 仓库 Issues](/routes/programming#github-yong-hu-cang-ku) 的 RSS 源为例,向您展示制作 RSS 源的过程。 +In this tutorial, we will walk you through the process of creating an RSS feed for [GitHub Repo Issues](/routes/programming#github-repo-issues) as an example. -## 安装依赖 +## Install dependencies -开始之前,您需要安装 RSSHub 的依赖项。您可以在 RSSHub 的根目录下运行以下命令来完成安装: +Before you start, you need to install the dependencies for RSSHub. You can do this by running the following command in the root directory of RSSHub: @@ -34,9 +34,9 @@ npm install -## 开始调试 +## Start debugging -一旦您成功安装了依赖,您可以通过运行以下命令来开始调试 RSSHub: +Once you have successfully installed the dependencies, you can start debugging RSSHub by running the following command: @@ -62,36 +62,36 @@ npm run dev -请务必密切关注控制台输出的任何错误消息或其他有用的信息,这些信息可以帮助您诊断和解决问题。另外,如果您遇到任何困难,不要犹豫向 RSSHub 文档或社区寻求帮助。 +Make sure to keep an eye on the console output for any error messages or other useful information that can help you diagnose and resolve issues. Additionally, don't hesitate to consult the RSSHub documentation or seek help from the community if you encounter any difficulties. -要查看您所做更改的结果,请在浏览器中打开 `http://localhost:1200`。您将能够在浏览器中自动反映您对代码的更改。 +To view the result of your changes, open `http://localhost:1200` in your browser. You'll be able to see the changes you made to the code automatically reflected in the browser. -## 遵循路由规范 +## Follow the Script Standard -确保所有新的 RSS 源路由均遵循 [路由规范](/joinus/advanced/script-standard) 非常重要。不遵循规范可能导致您的 Pull Request 在合理的时间内无法合并。 +It's important to ensure that all new RSS routes adhere to the [Script Standard](/joinus/advanced/script-standard). Failure to comply with this standard may result in your Pull Request not being merged in a reasonable timeframe. -[路由规范](/joinus/advanced/script-standard) 提供了制作高质量和可靠源代码的指导方针。通过遵循这些指南,您可以确保您的 RSS 源按照预期工作,并且易于其他社区维护者阅读。 +The [Script Standard](/joinus/advanced/script-standard) provides guidelines for creating high-quality and reliable source code. By following these guidelines, you can ensure that your RSS feed works as intended and is easy for other community maintainers to read. -在提交您的 Pull Request 之前,请仔细阅读 [路由规范](/joinus/advanced/script-standard),并确保您的代码符合所有要求。这将有助于加快审查过程。 +Before submitting your Pull Request, make sure to carefully review the [Script Standard](/joinus/advanced/script-standard) and ensure that your code meets all of the requirements. This will help to expedite the review process. -## 创建命名空间 +## Create a namespace -制作新的 RSS 路由的第一步是创建命名空间。命名空间应该与您制作 RSS 源的主要网站的二级域名**相同**。例如,如果您正在为 制作 RSS 源,第二级域名是 `github`。因此,您应该在 `lib/v2` 下创建名为 `github` 的文件夹,作为您的 RSS 路由的命名空间。 +The first step in creating a new RSS route is to create a namespace. The namespace should be the **same** as the second level domain name of the main website for which you are creating the RSS feed. For example, if you are creating an RSS feed for , the second level domain name is `github`. Therefore, you should create a folder called `github` under `lib/v2` to serve as the namespace for your RSS route. -:::tip 提示 -在创建命名空间时,避免为同一命名空间的创建多个变体。例如,如果您为 `yahoo.co.jp` 和 `yahoo.com` 制作 RSS 源,则应该使用单个命名空间 `yahoo`,而不是创建多个命名空间如 `yahoo-jp`、`yahoojp`、`yahoo.jp`、`jp.yahoo`、`yahoocojp` 等。 +:::tip Tips +When creating a namespace, it's important to avoid creating multiple namespaces for variations of the same domain. For example, if you are creating an RSS feed for both `yahoo.co.jp` and `yahoo.com`, you should stick with a single namespace `yahoo`, rather than creating multiple namespaces like `yahoo-jp`, `yahoojp`, `yahoo.jp`, `jp.yahoo`, `yahoocojp`, etc. ::: -## 理解基础知识 +## Understand the Basics ### router.js -一旦您为 RSS 路由创建了命名空间,下一步就是在 `router.js` 中注册它。 +Once you have created the namespace for your RSS route, the next step is to register it in the `router.js` -例如,如果您为 [GitHub 仓库 Issues](/routes/programming#github-yong-hu-cang-ku) 制作 RSS 源,并且假设您希望用户输入 GitHub 用户名和仓库名,如果他们没有输入仓库名,则返回到 `RSSHub`,您可以使用以下代码在 `github/router.js` 中注册您的新 RSS 路由: +For example, if you are creating an RSS feed for [GitHub Repo Issues](/routes/programming#github-repo-issues) and suppose you want users to enter a GitHub username and a repository name, and fall back to `RSSHub` if they don't enter the repository name, you can register your new RSS route in `github/router.js` using the following code: - + ```js{2} module.exports = (router) => { @@ -100,7 +100,7 @@ module.exports = (router) => { ``` - + ```js{2} module.exports = function (router) { @@ -111,23 +111,23 @@ module.exports = function (router) { -在 `router.js` 中注册您的新 RSS 路由时,您可以定义路由路径并指定要执行的相应函数。在上面的代码中,`router.get()` 方法用于指定新的 RSS 路由的 HTTP 方法和路径。`router.get()` 的第一个参数是使用 [path-to-regexp](https://github.com/pillarjs/path-to-regexp) 语法的路由路径。第二个参数是您新的 RSS 规则 `issue.js` 中导出的函数。您可以省略 `.js` 扩展名。 +When registering your new RSS route in `router.js`, you can define the route path and specify the corresponding function to be executed. In the code above, the `router.get()` method is used to specify the HTTP method and the path of the new RSS route. The first parameter of `router.get()` is the route path using [path-to-regexp](https://github.com/pillarjs/path-to-regexp) syntax. The second parameter is the exported function from your new RSS rule, `issue.js`. Note that you can omit the `.js` extension. -在上面的示例中,`issue` 是一个精确匹配,`:user` 是一个必需参数,`:repo?` 是一个可选参数。`?` 在 `:repo` 之后表示该参数是可选的。如果用户没有输入仓库名,则会返回到您代码中指定的内容(这里是 `RSSHub`)。 +In the example above, `issue` is an exact match, `:user` is a required parameter, and `:repo?` is an optional parameter. The `?` after `:repo` means that the parameter is optional. If the user does not enter repo, it will fall back to whatever is specified in your code (in this case, `RSSHub`). -一旦您定义了路由路径,您可以从 `ctx.params` 对象中获取参数的值。例如,如果用户访问了 `/github/issue/DIYgod/RSSHub`,您可以分别从 `ctx.params.user` 和 `ctx.params.repo` 中获取 `user` 和 `repo` 的值。例如,如果用户访问了 `/github/issue/DIYgod/RSSHub`,则 `ctx.params.user` 和 `ctx.params.repo` 将分别为 `DIYgod` 和 `RSSHub`。 +Once you have defined the route path, you can retrieve the value of the parameters from the `ctx.params` object. For example, if the user visits `/github/issue/DIYgod/RSSHub`, you can get the value of `user` and `repo` from `ctx.params.user` and `ctx.params.repo`, respectively. For example, if an user visits `/github/issue/DIYgod/RSSHub`, `ctx.params.user` and `ctx.params.repo` which will be `DIYgod` and `RSSHub`. -**请注意,值的类型将是 String 或 undefined。** +**Note that the type of the value will be either `String` or `undefined`**. -您可以使用 `*` 或 `+` 符号来匹配路径的其余部分,例如 `/some/path/:variable*`。请注意,`*` 和 `+` 分别意味着“零个或多个”和“一个或多个”。您还可以使用模式,例如 `/some/path/:variable(\\d+)?`,甚至是正则表达式。 +You can use the `*` or `+` symbols to match the rest of the path, like `/some/path/:variable*`. Note that `*` and `+` mean "zero or more" and "one or more", respectively. You can also use patterns like `/some/path/:variable(\\d+)?` or even RegExp. -:::tip 提示 -有关 `router` 的更高级用法,请参阅 [@koa/router API 参考文档](https://github.com/koajs/router/blob/master/API.md)。 +:::tip Tips +For more advanced usage of `router`, see the [@koa/router API Reference](https://github.com/koajs/router/blob/master/API.md). ::: ### maintainer.js -该文件用于存储 RSS 路由的维护者信息。您可以将您的 GitHub 用户名添加到该值数组中。请注意,此处的键应与 `router.js` 中的路径完全匹配: +This file is used to store information about the maintainer of the RSS routes. You can add your GitHub username to the value array. Note that the key here should exactly match the path in `router.js` : ```js{2} module.exports = { @@ -135,34 +135,34 @@ module.exports = { }; ``` -`maintainer.js` 文件有助于跟踪负责维护 RSS 路由的人员。当用户遇到 RSS 路由的问题时,他们可以联系此文件中列出的维护者。 +The `maintainer.js` file is useful for keeping track of who is responsible for maintaining an RSS route. When a user encounters an issue with your RSS route, they can reach out to the maintainers listed in this file. -### `templates` 文件夹 +### `templates` folder -`templates` 文件夹包含您的新 RSS 路由的模板。如果您不需要呈现任何自定义 HTML 内容,可以跳过此文件夹。 +The `templates` folder contains templates for your new RSS route. You only need this folder if you want to render custom HTML content instead of using the original website's HTML content. If you don't need to render any custom HTML content, you can skip this folder. -每个模板文件应该有一个 `.art` 文件扩展名。 +Each template file should have a `.art` file extension. ### radar.js -文件可以帮助用户在使用 [RSSHub Radar](https://github.com/DIYgod/RSSHub-Radar) 或其他兼容其格式的软件时订阅您的新 RSS 路由。我们将在后面的部分更多介绍。 +The `radar.js` file helps users subscribe to your new RSS route when they use [RSSHub Radar](https://github.com/DIYgod/RSSHub-Radar) or other software that is compatible with its format. We'll cover more about this in a later section. -### 您的新 RSS 路由 `issue.js` +### Your new RSS route `issue.js` -现在您可以开始 [编写](/joinus/new-rss/start-code) 新的 RSS 路由了。 +Now you can [start writing](/joinus/new-rss/start-code) your new RSS route. -## 获取数据 +## Acquire Data -要为新的 RSS 路由获取数据,通常需要使用 [got](https://github.com/sindresorhus/got) 进行 HTTP 请求到 API 或网页。在某些情况下,您可能需要使用 [puppeteer](https://github.com/puppeteer/puppeteer) 模拟浏览器并呈现网页以获取数据。 +To acquire data for your new RSS route, you will typically make HTTP requests using [got](https://github.com/sindresorhus/got) to an API or webpage. In some cases, you may need to use [puppeteer](https://github.com/puppeteer/puppeteer) to simulate a browser and render a webpage in order to acquire data. -您获取的数据通常会以 JSON 或 HTML 格式呈现。如果您需要处理的是 HTML,可以使用 [cheerio](https://github.com/cheeriojs/cheerio) 进行进一步处理。 +The data you retrieve will typically be in JSON or HTML format. If you're working with HTML, you can use [cheerio](https://github.com/cheeriojs/cheerio) for further processing. -以下是推荐的数据获取方法列表,按优先顺序排列: +Here's a list of recommended data collection methods, ordered by preference: -1. **通过 API**:这是获取数据最推荐的方法,因为 API 通常比从 HTML 网页中提取数据更稳定和更快。 +1. **Via API**: This is the most recommended way to retrieve data, as APIs are usually more stable and faster than extracting data from an HTML webpage. -2. **通过 got 从 HTML 获取数据**:如果 API 不可用,则可以尝试从 HTML 网页中提取数据。这通常是您大部分时候使用的方法。请注意,如果 HTML 包含嵌入 JSON,则应该使用它而不是其他 HTML 元素。 +2. **Via HTML webpage using got**: If an API is not available, you can try to retrieve data from the HTML webpage. This is the method you'll use most of the time. Note that if the HTML contains embedded JSON, you should use that instead of the rest of the HTML elements. -3. **通用配置路由**:通用配置路由是一条特殊的路由,它可以通过 cheerio(CSS 选择器和 jQuery 函数)读取 JSON 数据轻松生成 RSS。 +3. **Common Configured Route**: The Common Configured Route is a special route that can easily generate RSS by reading JSON data through cheerio (CSS selectors and jQuery functions). -4. **Puppeteer**:在某些罕见情况下,您可能需要使用 puppeteer 模拟浏览器并获取数据。这是最不推荐的方法,只有在绝对必要时才应该使用,例如网页带有浏览器完整性检查或强加密。如果可能,请使用其他方法,例如 API 请求或使用 [got](https://github.com/sindresorhus/got) 或 [cheerio](https://github.com/cheeriojs/cheerio) 直接从 HTML 页面中提取数据。 +4. **Puppeteer**: In some rare cases, you might need to use puppeteer to simulate a browser and retrieve data. This is the least recommended method and should only be used if absolutely necessary, such as when the webpage is blocked behind a browser integrity check or heavily encrypted. If possible, it's best to use other methods such as API requests or retrieving data from the HTML page directly using [got](https://github.com/sindresorhus/got) or [cheerio](https://github.com/cheeriojs/cheerio). diff --git a/website/docs/joinus/new-rss/prerequisites.md b/website/docs/joinus/new-rss/prerequisites.md index 8ce806654b2cbd..bcdffb15663df5 100644 --- a/website/docs/joinus/new-rss/prerequisites.md +++ b/website/docs/joinus/new-rss/prerequisites.md @@ -2,42 +2,42 @@ sidebar_position: 1 --- -# 准备工作 +# Prerequisites -在开始编写新的 RSS 规则之前,确保您的开发环境已正确配置很重要。 +Before you begin, it is important that your development environment set up properly. -## 安装 Node.js +## Install Node.js -为了能够编写新的 RSS 规则,您必须首先安装 Node.js。RSSHub 使用 Node.js 运行其代码以及制作 RSS 订阅源,需要 Node v16 或更高版本。您可以从 [这里](https://nodejs.org/en/download) 下载最新的 Node.js LTS 版本。 +To be able to write new RSS rules, you must first install Node.js first. RSSHub uses Node.js to run its code and create RSS feeds and requires Node v16 or above. You can download the latest LTS version of Node.js from [here](https://nodejs.org/en/download). -在 Windows 系统下,您可以下载安装程序并按照安装程序的步骤进行操作。记得勾选安装 **原生模块的工具(Tools for Native Modules)** 选项。 +On Windows, you can simply download the installer and follow the steps from the installer. Remember to check the option to install **Tools for Native Modules** as well. -在 macOS 系统下,您可以从 Node.js 网站下载安装程序,或者使用 [Homebrew](https://brew.sh) 命令 `brew install node` 安装 Node.js。 +On macOS, you can either download the installer from the Node.js website or use [Homebrew](https://brew.sh) to install Node.js with the command `brew install node`. -在 Linux 系统下,您可以参考 [这个页面](https://nodejs.org/en/download/package-manager) 决定如何安装 Node.js。 +On Linux, you can refer to [this page](https://nodejs.org/en/download/package-manager) to decide how to install Node.js. -## 安装代码编辑器 +## Install a code editor -编写代码需要一个代码编辑器。如果您已经有一个,您可以跳过这一部分。如果您还没有一个编辑器,可以从以下列表中选择一个: +To write code, you need a code editor. If you already have one, you can skip this section. If you don't have one, you can choose one from the following list: - [Visual Studio Code](https://code.visualstudio.com) - [WebStorm](https://www.jetbrains.com/webstorm) - [Neovim](https://neovim.io) - [Sublime Text](https://www.sublimetext.com) -为了加速开发过程并更容易维护代码风格的一致性,可以为您选择的代码编辑器安装一些适当的扩展。在本指南的后半部分,我们将使用 Visual Studio Code 作为示例,您可以安装以下扩展: +To speed up the development process and make it easier to keep your code clean, you can install some appropriate extensions to the code editor of your choice. In the latter part of this guide, we will use Visual Studio Code as an example, you can install the following extensions: -- [Art Template Helper](https://marketplace.visualstudio.com/items?itemName=ZihanLi.at-helper)(为 RSSHub 使用的一种模板引擎提供语法高亮) -- [EditorConfig for VS Code](https://marketplace.visualstudio.com/items?itemName=EditorConfig.EditorConfig)(保持在不同的 IDE 中的一致的代码风格) -- [ESLint](https://marketplace.visualstudio.com/items?itemName=dbaeumer.vscode-eslint)(识别并修复代码中的常见错误) -- [Prettier - Code formatter](https://marketplace.visualstudio.com/items?itemName=esbenp.prettier-vscode)(使您的代码更易读和更一致地格式化) +- [Art Template Helper](https://marketplace.visualstudio.com/items?itemName=ZihanLi.at-helper)(provides syntax highlighting for a template engine used by RSSHub) +- [EditorConfig for VS Code](https://marketplace.visualstudio.com/items?itemName=EditorConfig.EditorConfig)(maintain consistent coding styles across different editors and IDEs) +- [ESLint](https://marketplace.visualstudio.com/items?itemName=dbaeumer.vscode-eslint)(identify and fix common errors in your code) +- [Prettier - Code formatter](https://marketplace.visualstudio.com/items?itemName=esbenp.prettier-vscode)(formats your code to make it more readable and consistent) -### 云托管的开发环境 +### Cloud hosted development environment -如果您不想在计算机上安装 Node.js 和代码编辑器,您可以使用云托管的开发环境。您可以使用 [GitHub Codespaces](https://codespace.new) 或 [Gitpod](https://www.gitpod.io)。只需点击以下按钮即可启动新的工作区: +If you don't want to install Node.js and a code editor on your computer, you can use a cloud-hosted development environment. You may use [GitHub Codespaces](https://codespace.new/) or [Gitpod](https://www.gitpod.io). Just click one of the buttons below to start a new workspace: [![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/DIYgod/RSSHub?quickstart=1) [![Open in Gitpod](https://gitpod.io/button/open-in-gitpod.svg)](https://gitpod.io/#https://github.com/DIYgod/RSSHub) -有关如何使用 [GitHub Codespaces](https://codespace.new) 或 [Gitpod](https://www.gitpod.io) 的更多信息,请参见 [GitHub 文档](https://docs.github.com/codespaces) 和 [Gitpod 文档](https://www.gitpod.io/docs)。 +For more information about how to use [GitHub Codespaces](https://codespace.new/) or [Gitpod](https://www.gitpod.io/) , see [GitHub's documentation](https://docs.github.com/codespaces) and [Gitpod's documentation](https://www.gitpod.io/docs/). diff --git a/website/docs/joinus/new-rss/start-code.md b/website/docs/joinus/new-rss/start-code.md index 7f061f5db14ded..e710ad400bb105 100644 --- a/website/docs/joinus/new-rss/start-code.md +++ b/website/docs/joinus/new-rss/start-code.md @@ -2,40 +2,40 @@ sidebar_position: 3 --- -# 制作自己的 RSSHub 路由 +# Create Your Own RSSHub Route -如前所述,我们以 [GitHub 仓库 Issues](/routes/programming#github-yong-hu-cang-ku) 为例制作 RSS 源。我们将展示前面提到的四种数据获取方法: +As mentioned earlier, we will create an RSS feed for [GitHub Repo Issues](/routes/programming#github-repo-issues) as an example. We will show all four data collection methods mentioned: -1. [通过 API](#tong-guo-api) -2. [通过 got 从 HTML 获取数据](#tong-guo-got-cong-html-huo-qu-shu-ju) -3. [使用通用配置路由](#shi-yong-tong-yong-pei-zhi-lu-you) -4. [使用 puppeteer](#shi-yong-puppeteer) +1. [Via API](#via-api) +2. [Via HTML web page using got](#via-html-web-page-using-got) +3. [Using the Common Configured Route](#using-the-common-configured-route) +4. [Using puppeteer](#using-puppeteer) -## 通过 API +## Via API -### 查看 API 文档 +### Check the API documentation -不同的站点有不同的 API。您可以查看要为其制作 RSS 源的站点的 API 文档。在本例中,我们将使用 [GitHub Issues API](https://docs.github.com/zh/rest/issues/issues#list-repository-issues)。 +Different sites have different APIs. You can check the API documentation for the site you want to create an RSS feed for. In this case, we will use the [GitHub Issues API](https://docs.github.com/en/rest/issues/issues#list-repository-issues). -### 创建主文件 +### Create the main file -打开您的代码编辑器并创建一个新文件。由于我们要为 GitHub 仓库 Issues 制作 RSS 源,因此建议将文件命名为 `issue.js`。 +Open your code editor and create a new file. Since we are going to create an RSS feed for GitHub issues, it is suggested that you save the file as `issue.js`, but you can name it whatever you like. -以下是让您开始的基本代码: +Here's the basic code to get you started: ```js -// 导入所需模组 -const got = require('@/utils/got'); // 自订的 got +// Import the necessary modules +const got = require('@/utils/got'); // a customised got const { parseDate } = require('@/utils/parse-date'); module.exports = async (ctx) => { - // 在此处编写您的逻辑 + // Your logic here ctx.state.data = { - // 在此处输出您的 RSS + // Your RSS output here }; }; ``` @@ -43,25 +43,25 @@ module.exports = async (ctx) => { -### 获取用户输入 +### Retrieving user input -如前所述,我们需要从用户输入中获取 GitHub 用户名和仓库名称。如果请求 URL 中未提供仓库名称,则应默认为 `RSSHub`。您可以使用以下代码实现: +As mentioned earlier, we need to retrieve the GitHub username and repository name from user input. The repository name should default to `RSSHub` if it is not provided in the request URL. Here's how you can do it: - + ```js{2} module.exports = async (ctx) => { const { user, repo = 'RSSHub' } = ctx.params; ctx.state.data = { - // 在此处输出您的 RSS + // Your RSS output here }; }; ``` - + ```js{2,3} module.exports = async (ctx) => { @@ -69,7 +69,7 @@ module.exports = async (ctx) => { const repo = ctx.params.repo ?? 'RSSHub'; ctx.state.data = { - // 在此处输出您的 RSS + // Your RSS output here }; }; ``` @@ -77,45 +77,47 @@ module.exports = async (ctx) => { -这两个代码片段都执行相同的操作。第一个使用对象解构将 `user` 和 `repo` 变量赋值,而第二个使用传统赋值和空值合并运算符在请求 URL 中未提供它的情况下将 `repo` 变量分配默认值 `RSSHub`。 +Both of these code snippets do the same thing. The first one uses object destructuring to assign the `user` and `repo` variables, while the second one uses traditional assignment with a nullish coalescing operator to assign the `repo` variable a default value of `RSSHub` if it is not provided in the request URL. -### 从 API 获取数据 +### Getting data from the API -在获取用户输入后,我们可以使用它向 API 发送请求。大多数情况下,您需要使用 `@/utils/got` 中的 `got`(一个自订的 [got](https://www.npmjs.com/package/got) 包装函数)发送 HTTP 请求。有关更多信息,请参阅 [got 文档](https://github.com/sindresorhus/got/tree/v11#usage)。 +After we have the user input, we can use it to make a request to the API. In most cases, you will need to use `got` from `@/utils/got` (a customized got wrapper) to make HTTP requests. For more information, please refer to the [got documentation](https://github.com/sindresorhus/got/tree/v11#usage). - + -```js{3-14} +```js{3-16} module.exports = async (ctx) => { const { user, repo = 'RSSHub' } = ctx.params; - // 发送 HTTP GET 请求到 API 并解构返回的数据对象 + // Send an HTTP GET request to the API + // and destruct the data object returned by the request const { data } = await got(`https://api.github.com/repos/${user}/${repo}/issues`, { headers: { - // 为简单起见,此示例使用 HTML 而不是推荐的 'application/vnd.github+json', - // 因后者返回 Markdown 并需要进一步处理 + // This example uses HTML for simplicity instead of the + // recommended 'application/vnd.github+json', which returns + // Markdown and requires additional processing accept: 'application/vnd.github.html+json', }, searchParams: { - // 这允许用户设置条数限制 + // This allows users to set the number of feed items they want per_page: ctx.query.limit ? parseInt(ctx.query.limit, 10) : 30, }, }); ctx.state.data = { - // 在此处输出您的 RSS + // Your RSS output here }; }; ``` - + ```js{4-14} module.exports = async (ctx) => { const user = ctx.params.user; const repo = ctx.params.repo ?? 'RSSHub'; - // 发送 HTTP GET 请求到 API + // Send an HTTP GET request to the API const response = await got(`https://api.github.com/repos/${user}/${repo}/issues`, { headers: { accept: 'application/vnd.github.html+json', @@ -124,11 +126,11 @@ module.exports = async (ctx) => { per_page: ctx.query.limit ? parseInt(ctx.query.limit, 10) : 30, }, }); - // response.data 是上述请求返回的数据对象 + // response.data is the data object returned by the above request const data = response.data; ctx.state.data = { - // 在此处输出您的 RSS + // Your RSS output here }; }; ``` @@ -136,16 +138,16 @@ module.exports = async (ctx) => { -### 生成 RSS 源 +### Outputting the RSS -一旦我们从 API 获取到数据,我们需要进一步处理它以生成符合 RSS 规范的 RSS 源。具体来说,我们需要提取源标题、源链接、文章标题、文章链接、文章正文和文章发布日期。 +Once we have retrieved the data from the API, we need to process it further to generate an RSS feed that conforms to the RSS specification. Specifically, we need to extract the channel title, channel link, item title, item link, item description, and item publication date. -为此,我们可以将相关数据赋值给 `ctx.state.data` 对象,RSSHub 的中间件将处理其余部分。 +To do this, we can assign the relevant data to the `ctx.state.data` object, and RSSHub's middleware will take care of the rest. -以下是应有的最终代码: +Here is the final code that you should have: - + ```js{16-30,32-39} const got = require('@/utils/got'); @@ -163,35 +165,35 @@ module.exports = async (ctx) => { }, }); - // 从 API 响应中提取相关数据 + // extract the relevant data from the API response const items = data.map((item) => ({ - // 文章标题 + // item title title: item.title, - // 文章链接 + // item link link: item.html_url, - // 文章正文 + // item description description: item.body_html, - // 文章发布日期 + // item publish date or time pubDate: parseDate(item.created_at), - // 如果有的话,文章作者 + // item author, if available author: item.user.login, - // 如果有的话,文章分类 + // item category, if available category: item.labels.map((label) => label.name), })); ctx.state.data = { - // 源标题 + // channel title title: `${user}/${repo} issues`, - // 源链接 + // channel link link: `https://github.com/${user}/${repo}/issues`, - // 源文章 + // each feed item item: items, }; }; ``` - + ```js{16-36} const got = require('@/utils/got'); @@ -210,23 +212,23 @@ module.exports = async (ctx) => { }); ctx.state.data = { - // 源标题 + // channel title title: `${user}/${repo} issues`, - // 源链接 + // channel link link: `https://github.com/${user}/${repo}/issues`, - // 遍历所有此前获取的数据 + // iterate through all leaf objects item: data.map((item) => ({ - // 文章标题 + // item title title: item.title, - // 文章链接 + // item link link: item.html_url, - // 文章正文 + // item description description: item.body_html, - // 文章发布日期 + // item publish date or time pubDate: parseDate(item.created_at), - // 如果有的话,文章作者 + // item author, if available author: item.user.login, - // 如果有的话,文章分类 + // item category, if available category: item.labels.map((label) => label.name), })); }; @@ -236,80 +238,80 @@ module.exports = async (ctx) => { -## 通过 got 从 HTML 获取数据 +## Via HTML web page using got -### 创建主文件 +### Creat the main file -打开您的代码编辑器并创建一个新文件。由于我们要为 GitHub 仓库 Issues 制作 RSS 源,因此建议将文件命名为 `issue.js`。 +To start, open your code editor and create a new file. Since we are going to create an RSS feed for GitHub issues, it is suggested that you save the file as `issue.js`. However, you can also name it whatever you like. -以下是让您开始的基本代码: +Here's the basic code to get you started: ```js -// 导入必要的模组 -const got = require('@/utils/got'); // 自订的 got -const cheerio = require('cheerio'); // 可以使用类似 jQuery 的 API HTML 解析器 +// Require necessary modules +const got = require('@/utils/got'); // a customised got +const cheerio = require('cheerio'); // an HTML parser with a jQuery-like API const { parseDate } = require('@/utils/parse-date'); module.exports = async (ctx) => { - // 在此处编写您的逻辑 + // Your logic here ctx.state.data = { - // 在此处输出您的 RSS + // Your RSS output here }; }; ``` -`parseDate` 函数是 RSSHub 提供的一个工具函数,在代码的后面我们会用到它来解析日期。 +The `parseDate` function is a utility function provided by RSSHub that we will use to parse dates later in the code. -您需要添加自己的代码来从 HTML 文档中提取数据、处理数据并以 RSS 格式输出。在下一步中,我们将详细介绍此过程的细节。 +You will add your own code to extract data from the HTML document, process it, and output it in RSS format. We will cover the details of this process in the next steps. -### 获取用户输入 +### Retrieving user input -如前所述,我们需要从用户输入中获取 GitHub 用户名和仓库名称。如果请求 URL 中未提供仓库名称,则应默认为 `RSSHub`。您可以使用以下代码实现: +As mentioned before, we want users to enter a GitHub username and a repository name, and fall back to `RSSHub` if they don't enter the repository name in the request URL. ```js{2-3} module.exports = async (ctx) => { - // 从 URL 参数中获取用户名和仓库名称 + // Retrieve user and repository name from the URL parameters const { user, repo = 'RSSHub' } = ctx.params; ctx.state.data = { - // 在此处输出您的 RSS + // Your RSS output here }; }; ``` -在这段代码中,`user` 将被设置为 `user` 参数的值,如果存在 `repo` 参数,则 `repo` 将被设置为该参数的值,否则为 `RSSHub`。 +In this code, `user` will be set to the value of `user` parameter, and `repo` will be set to the value of `repo` parameter if it exists, and `RSSHub` otherwise. -### 从网页获取数据 +### Getting data from the web page -在获取了用户输入之后,我们需要向网页发起请求,以检索所需的信息。在大多数情况下,我们将使用 `@/utils/got` 中的 `got`(一个自订的 [got](https://www.npmjs.com/package/got) 包装函数)发送 HTTP 请求。您可以在 [got 文档](https://github.com/sindresorhus/got/tree/v11#usage) 中找到有关如何使用 got 的更多信息。 +After receiving the user input, we need to make a request to the web page to retrieve the information we need. In most cases, we'll use `got` from `@/utils/got` (a customized [got](https://www.npmjs.com/package/got) wrapper) to make HTTP requests. You can find more information on how to use got in the [got documentation](https://github.com/sindresorhus/got/tree/v11#usage). -首先,我们将向 API 发送 HTTP GET 请求,并将 HTML 响应加载到 Cheerio 中,Cheerio 是一个帮助我们解析和操作 HTML 的库。 +To begin, we'll make an HTTP GET request to the API and load the HTML response into Cheerio, a library that helps us parse and manipulate HTML. ```js{5-6} const baseUrl = 'https://github.com'; const { user, repo = 'RSSHub' } = ctx.params; - // 注意,".data" 属性包含了请求返回的目标页面的完整 HTML 源代码 + // Note that the ".data" property contains the full HTML source of the target page returned by the request const { data: response } = await got(`${baseUrl}/${user}/${repo}/issues`); const $ = cheerio.load(response); ``` -接下来,我们将使用 Cheerio 选择器选择相关的 HTML 元素,解析我们需要的数据,并将其转换为数组。 +Next, we'll use Cheerio selectors to select the relevant HTML elements, parse the data we need, and convert it into an array. ```js{3-21} - // 我们使用 Cheerio 选择器选择所有带类名“js-navigation-container”的“div”元素, - // 其中包含带类名“flex-auto”的子元素。 + // We use a Cheerio selector to select all 'div' elements with the class name 'js-navigation-container' + // that contain child elements with the class name 'flex-auto'. const item = $('div.js-navigation-container .flex-auto') - // 使用“toArray()”方法将选择的所有 DOM 元素以数组的形式返回。 + // We use the `toArray()` method to retrieve all the DOM elements selected as an array. .toArray() - // 使用“map()”方法遍历数组,并从每个元素中解析需要的数据。 + // We use the `map()` method to traverse the array and parse the data we need from each element. .map((item) => { item = $(item); const a = item.find('a').first(); return { title: a.text(), - // `link` 需要一个绝对 URL,但 `a.attr('href')` 返回一个相对 URL。 + // We need an absolute URL for `link`, but `a.attr('href')` returns a relative URL. link: `${baseUrl}${a.attr('href')}`, pubDate: parseDate(item.find('relative-time').attr('datetime')), author: item.find('.opened-by a').text(), @@ -321,17 +323,17 @@ module.exports = async (ctx) => { }); ctx.state.data = { - // 在此处输出您的 RSS + // Your RSS output here }; ``` -### 生成 RSS 源 +### Outputting the RSS -一旦我们从 API 获取到数据,我们需要进一步处理它以生成符合 RSS 规范的 RSS 源。具体来说,我们需要提取源标题、源链接、文章标题、文章链接、文章正文和文章发布日期。 +Once we have the data from the web page, we need to further process it to generate RSS in accordance with the RSS specification. Mainly, we need the channel title, channel link, item title, item link, item description, and item publication date. -为此,我们可以将相关数据赋值给 `ctx.state.data` 对象,RSSHub 的中间件将处理其余部分。 +Assign them to the `ctx.state.data` object, and RSSHub's middleware will take care of the rest. -以下是应有的最终代码: +Here's an example code: ```js{29-36} const got = require('@/utils/got'); @@ -363,21 +365,21 @@ module.exports = async (ctx) => { }); ctx.state.data = { - // 源标题 + // channel title title: `${user}/${repo} issues`, - // 源链接 + // channel link link: `${baseUrl}/${user}/${repo}/issues`, - // 源文章 + // each feed item item: items, }; }; ``` -### 更好的阅读体验 +### Better Reading Experience -上述的代码仅针对每个订阅项提供部分信息。为了提供更好的阅读体验,我们可以在每个订阅项中添加完整的文章,例如每个 GitHub Issue 的正文。 +The previous code provides only part of the information for each feed item. To provide a better reading experience, we can add the full article to each feed item, in this case the issue body. -以下是更新后的代码: +Here's the updated code: ```js{12,29-43,48} const got = require('@/utils/got'); @@ -414,11 +416,11 @@ module.exports = async (ctx) => { const { data: response } = await got(item.link); const $ = cheerio.load(response); - // 选择类名为“comment-body”的第一个元素 + // Select the first element with the class name 'comment-body' item.description = $('.comment-body').first().html(); - // 上面每个列表项的每个属性都在此重用, - // 并增加了一个新属性“description” + // Every property of a list item defined above is reused here + // and we add a new property 'description' return item; }) ) @@ -433,48 +435,47 @@ module.exports = async (ctx) => { ``` -现在,这个 RSS 源将具有类似于原始网站的阅读体验。 +Now the RSS feed will have a similar reading experience to the original website. -:::tip 提示 -请注意,在先前的部分中,我们仅需向 API 发送一个 HTTP 请求即可获得所需的所有数据。然而,在此部分中,我们需要发送 `1 + n` 个 HTTP 请求,其中 `n` 是从第一个请求获取的文章列表中的数量。 +:::tip Note +Note that in the previous section, we only needed to send one HTTP request using an API to get all the data we needed. However, in this section, we need to send `1 + n` HTTP requests, where `n` is the number of feed items in the list from the first request. -部分网站可能不喜欢在短时间内接收大量请求,并返回类似于“429 Too Many Requests”的错误。 +Some websites may not want to receive too many requests in a short amount of time, which can cause them to return an error message like `429 Too Many Requests`. ::: -## 使用通用配置路由 +## Using the common configured route -### 创建主文件 +### Create the main file -首先,我们需要一些数据: +First, we need a few data: -1. RSS 来源链接 -2. 数据来源链接 -3. RSS 订阅标题(不是每个文章的标题) +1. The RSS source link +2. The data source link +3. The RSS feed title (not the title of individual items) -打开您的代码编辑器并创建一个新文件。由于我们要为 GitHub 仓库 Issues 制作 RSS 源,因此建议将文件命名为 `issue.js`。 +Open your code editor and create a new file. Since we're going to create an RSS feed for GitHub issues, it's suggested that you save the file as `issue.js`, but you can name it whatever you like. -这是一些基础代码,你可以从这里开始: +Here's some basic code to get you started: ```js -// 导入所需模组 +// Import necessary modules const buildData = require('@/utils/common-config'); module.exports = async (ctx) => { ctx.state.data = await buildData({ - link: '', // RSS 来源链接 - url: '', // 数据来源链接 - // 此处可以使用变量 - // 如 %xxx% 会被解析为 **params** 中同名变量的值 + link: '', // The RSS source link + url: '', // The data source link + // Variables can be used here, such as %xxx% will be parsed into + // variables with values of the same name under **params** title: '%title%', params: { - title: '', // 标题变量 + title: '', // Additional title }, }); }; ``` -我们的 RSS 订阅源目前缺少内容。必须设置 `item` 才能添加内容。以下是一个示例: - +Our RSS feed currently lacks content. The `item` must be set to add the content. Here's an example: ```js{15-22} const buildData = require('@/utils/common-config'); @@ -486,28 +487,28 @@ module.exports = async (ctx) => { ctx.state.data = await buildData({ link, url: link, - title: `${user}/${repo} issues`, // 也可以使用 $('head title').text() + title: `${user}/${repo} issues`, // you can also use $('head title').text() params: { title: `${user}/${repo} issues`, baseUrl: 'https://github.com', }, item: { item: 'div.js-navigation-container .flex-auto', - // 如果要使用变量,必须使用模板字符串 - title: `$('a').first().text() + ' - %title%'`, // 仅支持像 $().xxx() 这样的 js 语句 - link: `'%baseUrl%' + $('a').first().attr('href')`, // .text() 为获取元素的文本 - // description: ..., 目前没有文章正文 + // You need to use template literals if you want to use variables + title: `$('a').first().text() + ' - %title%'`, // Only supports js statements like $().xxx() + link: `'%baseUrl%' + $('a').first().attr('href')`, // .text() means get the text of the element + // description: ..., we don't have description for now pubDate: `parseDate($('relative-time').attr('datetime'))`, }, }); }; ``` -你会发现,此代码与上面的 [从网页获取数据](#tong-guo-got-cong-html-huo-qu-shu-ju-cong-wang-ye-huo-qu-shu-ju) 部分相似。但是,这个 RSS 订阅源不包含 GitHub Issue 的正文。 +You'll notice that the code is similar to the [Obtaining data from the webpage](#getting-data-from-the-web-page) section above. However, this RSS feed doesn't contain the full article of the issue. -### 获取完整文章 +### Retrieving full articles -要获取每个 GitHub Issue 的正文,你需要添加一些代码。以下是一个示例: +To get the full article of each issue, you need to add a few more lines of code. Here is an example: ```js{2-3,25-34} const buildData = require('@/utils/common-config'); @@ -547,34 +548,34 @@ module.exports = async (ctx) => { }; ``` -你可以看到,上面的代码与 [前一节](#tong-guo-got-cong-html-huo-qu-shu-ju-geng-hao-de-yue-du-ti-yan) 非常相似,通过添加一些代码它获取了完整文章。建议你尽可能使用 [前一节](#tong-guo-got-cong-html-huo-qu-shu-ju-geng-hao-de-yue-du-ti-yan) 中的方法,因为它比使用 `@/utils/common-config` 更加灵活。 +You can see that the above code is very similar to the [previous section](#better-reading-experience) which retrieves full articles by adding a few more lines of code. It is recommended that you use the method in the [previous section](#better-reading-experience) whenever possible, as it is more flexible than using `@/utils/common-config`. -## 使用 puppeteer +## Using puppeteer -使用 Puppeteer 是从网站获取数据的另一种方法。不过,建议您首先尝试 [上述方法](#tong-guo-got-cong-html-huo-qu-shu-ju)。还建议您先阅读 [通过 got 从 HTML 获取数据](#tong-guo-got-cong-html-huo-qu-shu-ju),因为本节是前一节的扩展,不会解释一些基本概念。 +Using puppeteer is another approach to obtain data from websites. However, it is recommended that you try the [above methods](#via-html-web-page-using-got) first. It is also recommended that you read [via HTML web page using got](#via-html-web-page-using-got) first since this section is an extension of the previous section and will not explain some basic concepts. -### 创建主文件 +### Creat the main file -创建一个新文件并使用适当的名称保存,例如 `issue.js`。然后,导入所需模组并设置函数的基本结构: +To get started with puppeteer, create a new file in your code editor and save it with an appropriate name, such as `issue.js`. Then, require the necessary modules and set up the basic structure of the function: ```js -// 导入所需模组 -const cheerio = require('cheerio'); // 可以使用类似 jQuery 的 API HTML 解析器 +// Require some useful modules +const cheerio = require('cheerio'); // an HTML parser with a jQuery-like API const { parseDate } = require('@/utils/parse-date'); const logger = require('@/utils/logger'); module.exports = async (ctx) => { - // 在此处编写您的逻辑 + // Your logic here ctx.state.data = { - // 在此处输出您的 RSS + // Your RSS output here }; }; ``` -### 将 got 替换为 puppeteer +### Replace got with puppeteer -现在,我们将使用 `puppeteer` 代替 `got` 来从网页获取数据。 +Now, we will be using `puppeteer` instead of `got` to retrieve data from the web page. @@ -588,41 +589,41 @@ module.exports = async (ctx) => { const baseUrl = 'https://github.com'; const { user, repo = 'RSSHub' } = ctx.params; - // 导入 puppeteer 工具类并初始化浏览器实例 + // require puppeteer utility class and initialise a browser instance const browser = await require('@/utils/puppeteer')(); - // 打开一个新标签页 + // open a new tab const page = await browser.newPage(); - // 拦截所有请求 + // intercept all requests await page.setRequestInterception(true); - // 仅允许某些类型的请求 + // only allow certain types of requests to proceed page.on('request', (request) => { - // 在这次例子,我们只允许 HTML 请求 + // in this case, we only allow document requests to proceed request.resourceType() === 'document' ? request.continue() : request.abort(); }); - // 访问目标链接 + // visit the target link const link = `${baseUrl}/${user}/${repo}/issues`; - // got 请求会被自动记录, - // 但 puppeteer 请求不会 - // 所以我们需要手动记录它们 + // got requests will be logged automatically + // but puppeteer requests are not + // so we need to log them manually logger.debug(`Requesting ${link}`); await page.goto(link, { - // 指定页面等待载入的时间 + // specify how long to wait for the page to load waitUntil: 'domcontentloaded', }); - // 获取页面的 HTML 内容 + // retrieve the HTML content of the page const response = await page.content(); - // 关闭标签页 + // close the tab page.close(); const $ = cheerio.load(response); // const item = ...; - // 不要忘记关闭浏览器实例 + // don't forget to close the browser instance at the end of the function browser.close(); ctx.state.data = { - // 在此处输出您的 RSS + // Your RSS output here }; } ``` @@ -643,7 +644,7 @@ module.exports = async (ctx) => { const $ = cheerio.load(response); ctx.state.data = { - // 在此处输出您的 RSS + // Your RSS output here }; } ``` @@ -651,9 +652,9 @@ module.exports = async (ctx) => { -### 获取完整文章 +### Retrieving full articles -使用浏览器新标签页获取每个 GitHub Issue 的正文,类似于 [上一节](#tong-guo-got-cong-html-huo-qu-shu-ju-geng-hao-de-yue-du-ti-yan)。我们可以使用以下代码: +Retrieving the full articles of each issue using a new browser page is similar to the [previous section](#better-reading-experience). We can use the following code: ```js{46-60,71-72} const cheerio = require('cheerio'); @@ -701,9 +702,9 @@ module.exports = async (ctx) => { const items = await Promise.all( list.map((item) => ctx.cache.tryGet(item.link, async () => { - // 重用浏览器实例并打开新标签页 + // reuse the browser instance and open a new tab const page = await browser.newPage(); - // 设置请求拦截,仅允许 HTML 请求 + // set up request interception to only allow document requests await page.setRequestInterception(true); page.on('request', (request) => { request.resourceType() === 'document' ? request.continue() : request.abort(); @@ -714,7 +715,7 @@ module.exports = async (ctx) => { waitUntil: 'domcontentloaded', }); const response = await page.content(); - // 获取 HTML 内容后关闭标签页 + // close the tab after retrieving the HTML content page.close(); const $ = cheerio.load(response); @@ -726,7 +727,7 @@ module.exports = async (ctx) => { ) ); - // 所有请求完成后关闭浏览器实例 + // close the browser instance after all requests are done browser.close(); ctx.state.data = { @@ -737,34 +738,33 @@ module.exports = async (ctx) => { }; ``` -### 额外资源 +### Additional Resources -这里有一些您可以使用的资源来了解 puppeteer: +Here are some resources you can use to learn more about puppeteer: -- [puppeteer's 旧版文档](https://github.com/puppeteer/puppeteer/blob/v15.2.0/docs/api.md) -- [puppeteer's 当前文档](https://pptr.dev) -- [puppeteer's 非官方中文文档](https://zhaoqize.github.io/puppeteer-api-zh_CN/) +- [puppeteer's good ol' docs](https://github.com/puppeteer/puppeteer/blob/v15.2.0/docs/api.md) +- [puppeteer's current docs](https://pptr.dev) -#### 拦截请求 +#### Intercepting requests -在爬取网页时,您可能会遇到您不需要的图像、字体和其他资源。这些资源会减慢页面加载速度并消耗宝贵的 CPU 和内存资源。为了避免这种情况,您可以在 puppeteer 中启用请求拦截。 +When scraping web pages, you may encounter images, fonts, and other resources that you don't need. These resources can slow down the page load time and use up valuable CPU and memory resources. To avoid this, you can enable request interception in puppeteer. -这是如何实现的: +Here's how to do it: ```js await page.setRequestInterception(true); page.on('request', (request) => { request.resourceType() === 'document' ? request.continue() : request.abort(); }); -// 这两条语句必须放在 page.goto() 之前 +// These two statements must be placed before page.goto() ``` -您可以在 [这里](https://chromedevtools.github.io/devtools-protocol/tot/Network/#type-ResourceType) 找到 `request.resourceType()` 的所有可能值。在代码中使用这些值时,请确保使用**小写**字母。 +You can find all the possible values of `request.resourceType()` [here](https://chromedevtools.github.io/devtools-protocol/tot/Network/#type-ResourceType). When using these values in your code, make sure to use **lowercase** letters. #### Wait Until -在上面的代码中,您将看到在 `page.goto()` 函数中使用了 `waitUntil: 'domcontentloaded'`。这是 puppeteer 的一个选项,它告诉它在何时认为导航成功。您可以在 [这里](https://pptr.dev/api/puppeteer.page.goto/#remarks) 找到所有可能的值及其含义。 +In the code above, you'll see that `waitUntil: 'domcontentloaded'` is used in the page.goto() function. This is a Puppeteer option that tells it when to consider a navigation successful. You can find all the possible values and their meanings [here](https://pptr.dev/api/puppeteer.page.goto/#remarks). -需要注意的是,`domcontentloaded` 的等待时间较短,而 `networkidle0` 可能不适用于始终发送后台遥测或获取数据的网站。 +It's worth noting that `domcontentloaded `waits for a shorter time than the default value `load`, and `networkidle0` may not be suitable for websites that keep sending background telemetry or fetching data. -此外,重要的是避免等待特定的超时时间,而是等待选择器出现。等待超时是不准确的,因为它取决于 puppeteer 实例的负载情况。 +Additionally, it's important to avoid waiting for a specific timeout and instead wait for a selector to appear. Waiting for a timeout is inaccurate, as it depends on the load of the Puppeteer instance. diff --git a/website/docs/joinus/new-rss/submit-route.md b/website/docs/joinus/new-rss/submit-route.md index 9fd04ef39c071b..59f9450b3e7f4f 100644 --- a/website/docs/joinus/new-rss/submit-route.md +++ b/website/docs/joinus/new-rss/submit-route.md @@ -2,23 +2,23 @@ sidebar_position: 5 --- -# 提交路由 +# Submit your route -当您完成您的路由后,您可以提交一个 Pull Request(下称 PR)到 [RSSHub](https://github.com/DIYgod/RSSHub)。我们将使用 squash merge 策略,这意味着您分支中的所有提交将合并成 RSSHub 仓库上的一个提交。然而,保持您的提交历史干净整洁仍然很重要。我们还提供了一个直观的模板供您填写。 +Once you have finished your route, you can submit a pull request (hereafter referred to as PR) to [RSSHub](https://github.com/DIYgod/RSSHub). We use a squash merge strategy, meaning all commits in your branch will be merged into one commit on RSSHub's repository. However, keeping your commit history clean and tidy is still important. We've also provided an intuitive template for you to fill out. -## PR 模板 +## Pull Request Template ````md ## 该 PR 相关 Issue / Involved Issue Close # -## 路由地址示例 / Example for the Proposed Route(s) +## 完整路由地址 / Example for the Proposed Route(s) ```routes ``` -## 新 RSS 路由检查列表 / New RSS Route Checklist +## 新 RSS 路由检查表 / New RSS Route Checklist - [ ] 新的路由 New Route - - [ ] 跟随 [v2 路由规范](https://docs.rsshub.app/joinus/advanced/script-standard) Follows [v2 Script Standard](https://docs.rsshub.app/en/joinus/advanced/script-standard) + - [ ] 跟随 [v2 路由规范](https://docs.rsshub.app/joinus/advanced/script-standard) Follows [v2 Script Standard](https://docs.rsshub.app/joinus/advanced/script-standard) - [ ] 文档说明 Documentation - [ ] 中文文档 CN - [ ] 英文文档 EN -- [ ] 全文获取 fulltext +- [ ] 全文获取 full article - [ ] 使用缓存 Use cache - [ ] 反爬/频率限制 anti-bot or rate limit? - [ ] 如果有, 是否有对应的措施? If yes, do your code reflect this sign? -- [ ] [日期和时间](https://docs.rsshub.app/joinus/advanced/pub-date) [Date and time](https://docs.rsshub.app/en/joinus/advanced/pub-date) +- [ ] [日期和时间](https://docs.rsshub.app/joinus/advanced/pub-date) [Date and time](https://docs.rsshub.app/joinus/advanced/pub-date) - [ ] 可以解析 Parsed - [ ] 时区正确 Correct time zone - [ ] 添加了新的包 New package added @@ -58,13 +58,13 @@ If your changes are not related to route, please fill in `routes` with `NOROUTE` ## 说明 / Note ```` -### 相关的 Issue +### Involved Issue -您可以在此处填写此 PR 相关的 Issue 编号。如果没有相关的 Issue,请将其留空。如果您的 PR 被合并,相关的 Issue 将自动关闭。如果您想关闭多个 Issue,请添加另一个以空格或逗号分隔的 `Close #`。例如,`Close #123, Close #456, Close #789` 或 `Close #123 Close #456 Close #789`。 +You can fill in the issue number that this PR is related to here. If there's no related issue, leave it blank. If your pull request gets merged, the related issue will be automatically closed. If you want to close multiple issues, add another `Close #` separated by a space or comma. For example, `Close #123, Close #456, Close #789` or `Close #123 Close #456 Close #789`. -### 路由地址示例 +### Example for the Proposed Route(s) -在这里,您可以添加您添加的路由以及所有必需和可选参数。如果您想添加多条路由,请在新行中添加每条路由。例如: +Here you can add the route(s) you're proposing to add, along with all required and optional parameters. If you want to add multiple routes, add each one in a new line. For example: ````md ```routes @@ -75,9 +75,9 @@ If your changes are not related to route, please fill in `routes` with `NOROUTE` ``` ```` -**不要**填写`/github/issue/:user/:repo?` 或 `/issue/:user/:repo?`。 +**Do not** fill in `/github/issue/:user/:repo?` or `/issue/:user/:repo?`. -如果您的更改与路由无关,例如文档,请在 `routes` 区域中填写 `NOROUTE`。 +If your changes are not related to a route, such as documentation, you can fill in `routes` section with `NOROUTE`. ````md ```routes @@ -85,39 +85,39 @@ NOROUTE ``` ```` -**不要**删除或不理会 `routes` 区域,否则您的 PR 将自动关闭。 +**Do not** delete or leave the `routes` section untouched, or your pull request will be automatically closed. -对于路由相关的 PR,**不要**使用 `NOROUTE`,否则它们也将被自动关闭。 +**Do not** use `NOROUTE` for route-related pull requests, or they will be automatically closed as well. -### 新 RSS 路由检查表 - -此检查表将帮助您确保您的 PR 包含所有必要的组件。虽然您不必勾选所有项目,以使您的 PR 合并,但请确保您的新路由遵循 [路由规范](/joinus/advanced/script-standard)。这是所有新路由的强制性要求。 +### New RSS Route Checklist +This checklist will help you ensure that your pull request includes all necessary components. Although you don't have to check off all items to get your PR merged, please make sure that your new route follows the [v2 Script Standard](/joinus/advanced/script-standard). This is a **mandatory** requirement for all new routes. ```md - [ ] 新的路由 New Route ``` -要勾选项目,请将 `[ ]` 修改为 `[x]`. +To check off an item, replace `[ ]` with `[x]`. ```md - [x] 新的路由 New Route ``` -### 说明 +### Note -此部分包含您想要分享的任何附加信息或评论。 +Use this section to include any additional information or comments you'd like to share. -## PR 标题 +## Pull Request Title -当您的拉取请求被合并时,拉取请求标题将用作提交信息。请遵循 [约定式提交](https://www.conventionalcommits.org/zh-hans/v1.0.0/#概述) 规范。 +The pull request title will be used as the commit message when your pull request is merged. Please follow the [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/#summary) specification. -如果您正在添加新的路由,包括所有必需的文档和 `radar.js`,请以 `route` 作为范围。如果仅添加新的 Radar 规则,则请以 `radar` 作为范围。 +If you are adding a new route, including all required documentation and `radar.js`, use `route` as the scope. If you are adding new radar rules only, use `radar` as the scope. -## 回复代码审查 +## Response to Code Review -您的拉取请求将由 RSSHub 维护者和机器人审核。您可以点击检查名称旁边的“Details”来检查自动检查的详细信息。如果 RSSHub 维护者要求更改,您可以提交并将更改推送到您的分支。PR 将自动更新以反映您的更改。您也可以使用 [“添加建议到批次 (Add suggestion to batch)”](https://docs.github.com/zh/pull-requests/collaborating-with-pull-requests/reviewing-changes-in-pull-requests/incorporating-feedback-in-your-pull-request#applying-suggested-changes) 批量整合维护者的反馈。 +Your pull request will be reviewed by both bots and RSSHub maintainers. You can check the details of the automated checks by clicking on the `Details` link next to the check name. +If an RSSHub maintainer requests changes, you can commit and push your changes to your branch. The pull request will automatically update to reflect your changes. You can also incorporate feedback from the maintainer in batch by using the [suggested changes feature](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/reviewing-changes-in-pull-requests/incorporating-feedback-in-your-pull-request#applying-suggested-changes). -## 接下来怎么做 +## What's Next -当您的 PR 被合并后,将会构建一个新的 Docker 镜像。由于我们需要构建多个平台(包括 `linux/arm/v7`、`linux/arm64` 和 `linux/amd64`)以及包含和不包含 Chromium,该过程可能需要长达一个小时。 +After your pull request is merged, a new docker image will be built. This process can take up to an hour since we are building for multiple platforms, including `linux/arm/v7`, `linux/arm64`, and `linux/amd64`, with and without bundled Chromium. diff --git a/website/docs/joinus/quick-start.md b/website/docs/joinus/quick-start.md index 98cb7ec05d10fb..005951b3809974 100644 --- a/website/docs/joinus/quick-start.md +++ b/website/docs/joinus/quick-start.md @@ -2,49 +2,51 @@ sidebar_position: 1 --- +# Quick Start -# 快速开始 +If you've found a bug or have a suggestion for improving RSSHub, we'd love to hear from you! You can submit your changes by creating a pull request. Don't worry if you're new to pull requests - we welcome contributions from developers of all experience levels. Don't know how to code? You can also help by [reporting bugs](https://github.com/DIYgod/RSSHub/issues). -如果您在使用 RSSHub 过程中遇到了问题或者有建议改进,我们很乐意听取您的意见!您可以通过 Pull Request 来提交您的修改。无论您对 Pull Request 的使用是否熟悉,我们都欢迎不同经验水平的开发者参与贡献。如果您不懂编程,也可以通过 [报告错误](https://github.com/DIYgod/RSSHub/issues) 的方式来帮助我们。 +## Join the discussion -## 参与讨论 +[![Telegram Group](https://img.shields.io/badge/chat-telegram-brightgreen.svg?logo=telegram&style=for-the-badge)](https://t.me/rsshub) [![GitHub issues](https://img.shields.io/github/issues/DIYgod/RSSHub?color=bright-green&logo=github&style=for-the-badge)](https://github.com/DIYgod/RSSHub/issues) [![GitHub Discussions](https://img.shields.io/github/discussions/DIYgod/RSSHub?logo=github&style=for-the-badge)](https://github.com/DIYgod/RSSHub/discussions) -[![Telegram 群组](https://img.shields.io/badge/chat-telegram-brightgreen.svg?logo=telegram&style=for-the-badge)](https://t.me/rsshub) [![GitHub Issues](https://img.shields.io/github/issues/DIYgod/RSSHub?color=bright-green&logo=github&style=for-the-badge)](https://github.com/DIYgod/RSSHub/issues) [![GitHub 讨论](https://img.shields.io/github/discussions/DIYgod/RSSHub?logo=github&style=for-the-badge)](https://github.com/DIYgod/RSSHub/discussions) +## Before you begin -## 开始之前 +To create an RSS feed, you'll need to use a combination of Git, HTML, JavaScript, jQuery, and Node.js. -要制作一个 RSS 订阅,您需要结合使用 Git、HTML、JavaScript、jQuery 和 Node.js。 +If you don't know much about them but would like to learn them, here are some good resources: -如果您对它们不是很了解,但想要学习它们,以下是一些好的资源: +- [JavaScript Tutorials on MDN Web Docs](https://developer.mozilla.org/en-US/docs/Web/JavaScript#tutorials) +- [W3Schools](https://www.w3schools.com/) +- [Git course on Codecademy](https://www.codecademy.com/learn/learn-git) -- [MDN Web Docs 上的 JavaScript 指南](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript#教程) -- [W3Schools](https://www.w3schools.com) -- [Codecademy 上的 Git 课程](https://www.codecademy.com/learn/learn-git) +If you'd like to see examples of how other developers use these technologies to create RSS feeds, you can take a look at some of the code in [our repository](https://github.com/DIYgod/RSSHub/tree/master/lib/v2). -如果您想查看其他开发人员如何使用这些技术来制作 RSS 订阅的示例,您可以查看 [我们的代码库](https://github.com/DIYgod/RSSHub/tree/master/lib/v2) 中的一些代码。 +## Submit new RSSHub rules -## 提交新的 RSSHub 规则 +If you've found a website that doesn't offer an RSS feed, you can create an RSS rule for it using RSSHub. An RSS rule is a short Node.js program code (hereafter referred to as "route") that tells RSSHub how to extract content from a website and generate an RSS feed. By creating a new RSS route, you can help make content from your favourite websites more accessible and easier to follow. -如果您发现一个网站没有提供 RSS 订阅,您可以使用 RSSHub 制作一个 RSS 规则。RSS 规则是一个短小的 Node.js 程序代码(以下简称 “路由”),它告诉 RSSHub 如何从网站中提取内容并生成 RSS 订阅。通过制作新的 RSS 路由,您可以帮助让您喜爱的网站的内容被更容易访问和关注。 +Before you start writing an RSS route, please make sure that the source site does not provide RSS. Some web pages will include a link element with type `application/atom+xml` or `application/rss+xml` in the HTML header to indicate the RSS link. -在您开始编写 RSS 路由之前,请确保源站点没有提供 RSS。一些网页会在 HTML 头部中包含一个 type 为 `application/atom+xml` 或 `application/rss+xml` 的 link 元素来指示 RSS 链接。 +Here's an example of what an RSS link might look like in the HTML header: ``. If you see a link like this, it means that the website already has an RSS feed and you don't need to create a new RSS route for it. -这是在 HTML 头部中看到 RSS 链接可能会长成这样:``。如果您看到这样的链接,这意味着这个网站已经有了一个 RSS 订阅,您不需要为它制作一个新的 RSS 路由。 +### Getting started -### 开始 +In this guide, you'll learn how to create a new RSS route from scratch. We'll cover everything from setting up your development environment to submitting your code to the RSSHub repository. By the end of this guide, you'll be able to create your own RSS feeds for websites that don't offer them. -在本指南中,您将学习从头制作一个新的 RSS 路由的方法。我们将涵盖从设置开发环境到提交代码到 RSSHub 仓库的所有内容。到本指南结束时,您将能够为不提供 RSS 的网站制作自己的 RSS 订阅源。 +[Ready to get started? Click here to dive into the guide!](/joinus/new-rss/prerequisites) -[准备好了吗?点这里开始学习!](/joinus/new-rss/prerequisites) +## Submit new RSSHub Radar rules -## 提交新的 RSSHub Radar 规则 +### Before you start -### 开始之前 +It's recommended that you download and install RSSHub Radar in your browser before you start. -建议您在开始之前,在浏览器中下载并安装 RSSHub Radar。 +Once you have installed RSSHub Radar, open the settings and switch to the "List of rules" tab. Then scroll down to the bottom of the page and you will see a text field. Here, you can replace the old rules with your new rules for debugging. -安装 RSSHub Radar 后,打开设置并切换到 “规则列表” 选项页。然后滚动到页面底部,您会看到一个文本框。在这里,您可以使用您的新规则替换旧规则以进行调试。 +[Let's start!](/joinus/new-radar) -[开始吧!](/joinus/new-radar) - -为 Chromium 安装 RSSHub Radar 为 Firefox 安装 RSSHub Radar for 为 Edge 安装 RSSHub Radar 为 Safari 安装 RSSHub Radar +Get RSSHub Radar for Chromium +Get Get RSSHub Radar for Firefox +Get RSSHub Radar for Edge +Get RSSHub Radar for Safari diff --git a/website/docs/parameter.md b/website/docs/parameter.md index b13a1232c8217a..9974532e625698 100644 --- a/website/docs/parameter.md +++ b/website/docs/parameter.md @@ -1,195 +1,176 @@ -# 通用参数 +# Parameters -:::tip 提示 +:::tip -通用参数实际上是 URI 中的 query,可以使用 `&` 连接组合使用,效果叠加。 +Parameters here are actually URI query and can be linked together with `&` to generate a complex feed. -通用参数需要置于路由路径的最后。有些路由在路由路径(route path)的最后引入了**自定义参数****通用参数**也需要置于它们之后。 +Parameters here need to be placed after the route path. Some routes may have **custom route parameters** and **parameters here** need to be placed after them. -举例: +E.g. - -https://rsshub.app/twitter/user/durov/ - - readable=1&includeRts=0 - -? - - brief=100&limit=5 - - +https://rsshub.app/twitter/user/durov/readable=1&includeRts=0?brief=100&limit=5 -如果设置了**输出格式**(`.atom`, `.rss`, `.json`, `.debug.json`),则需要置于路由路径(含**自定义参数**)与**其它通用参数**之间。 +If a **output format** (`.atom`, `.rss`, `.json`, `.debug.json`) is set, it needs to be placed between the route path (including **custom route parameters**) and **other parameters**. -举例: +E.g. - -https://rsshub.app/twitter/user/durov/ - - readable=1&includeRts=0 - - - .atom - -? - - brief=100&limit=5 - - +https://rsshub.app/twitter/user/durov/readable=1&includeRts=0.atom?brief=100&limit=5 ::: -## 内容过滤 +## Filtering -:::caution 注意 +:::caution Warning -请务必显式进行[彻底的 URL 编码](https://gchq.github.io/CyberChef/#recipe=URL_Encode\(true\))。切勿依赖浏览器的自动 URL 编码,某些字符,如 `+`, `&`,将不会被自动编码,进而导致最终解析结果不正确。 +Please make sure you've [fully URL-encoded](https://gchq.github.io/CyberChef/#recipe=URL_Encode(true)) the parameters. Do not rely on the browser's automatic URL encoding. Some characters, such as `+`, `&`, will not be automatically encoded, resulting in the final parsing result not being correct. ::: -:::caution 注意 +:::caution Warning -filter 支持正则表达式。由于正则部分特性可被利用于 DoS (ReDOS),默认引擎`re2`屏蔽了部分`Regexp`功能,且在部分情况下表现不一致。具体差异可以[查看文档](https://github.com/uhop/node-re2#limitations-things-re2-does-not-support) +filter supports Regex, and due to the fact that some Regex are vulnerable to DoS (ReDoS), default engine `re2` blocks some of these functionalities available in node `Regexp`. These two engines also behaves a bit different in some corner cases. [Details](https://github.com/uhop/node-re2#limitations-things-re2-does-not-support) -如果需要指定不同的引擎,请参考[功能特性 -> FILTER_REGEX_ENGINE](install/#pei-zhi-gong-neng-te-xing)。 + +If you need to use a different engine, please refer to [Deploy->Features->FILTER_REGEX_ENGINE](/install/#configuration-features). ::: -可以使用以下 URL query 过滤内容,支持通过正则表达式过滤 -`filter` 选出想要的内容 +The following URL query parameters are supported, Regex support is built-in. + +Set `filter` to include the content -- `filter`: 过滤标题和描述 +- `filter`: filter `title` and description -- `filter_title`: 过滤标题 +- `filter_title`: filter `title` only -- `filter_description`: 过滤描述 +- `filter_description`: filter `description` only -- `filter_author`: 过滤作者 +- `filter_author`: filter `author` only -- `filter_category`: 过滤分类 +- `filter_category`: filter `category` only -- `filter_time`: 过滤时间,仅支持数字,单位为秒。返回指定时间范围内的内容。如果条目没有输出`pubDate`或者格式不正确将不会被过滤 +- `filter_time`: filter `pubDate`, in seconds, return specified time range. Item without `pubDate` will not be filtered. -举例 1: `https://rsshub.app/bilibili/fav/2267573/801952073?filter=编曲|摄影` -举例 2: +E.g. [https://rsshub.app/dribbble/popular?filter=Blue|Yellow|Black](https://rsshub.app/dribbble/popular?filter=Blue|Yellow|Black) -`filterout` 去掉不要的内容 +Set `filterout` to exclude unwanted content. -- `filterout`: 过滤标题和描述 +- `filterout`: filter `title` and description -- `filterout_title`: 过滤标题 +- `filterout_title`: filter `title` only -- `filterout_description`: 过滤描述 +- `filterout_description`: filter `description` only -- `filterout_author`: 过滤作者 +- `filterout_author`: filter `author` only -- `filterout_category`: 过滤分类 +- `filterout_category`: filter `category` only -举例: `https://rsshub.app/bilibili/fav/2267573/801952073?filterout=编曲|摄影` +E.g. [https://rsshub.app/dribbble/popular?filterout=Blue|Yellow|Black](https://rsshub.app/dribbble/popular?filterout=Blue|Yellow|Black) -`filter_case_sensitive` 过滤是否区分大小写,`filter` 和 `filterout`同时适用 +Set `filter_case_sensitive` to determine whether the filtering keywords should be case sensitive. The parameter would apply to both `filter` and `filterout`. -默认为 `true`,区分大小写 +Default: `true` -举例 1: +E.g. [https://rsshub.app/dribbble/popular?filter=BluE|yeLLow|BlaCK&filter_case_sensitive=false](https://rsshub.app/dribbble/popular?filter=BluE|yeLLow|BlaCK&filter_case_sensitive=false) -## 条数限制 +## Limit Entries -可以使用 `limit` 参数限制最大条数,主要用于排行榜类 RSS +Set `limit` to limit the number of articles in the feed. -举例: bilibili 排行榜前 10 +E.g. Dribbble Popular Top 10 [https://rsshub.app/dribbble/popular?limit=10](https://rsshub.app/dribbble/popular?limit=10) -## 排序结果 +## Sorted -通过 `sorted` 参数控制是否对输出的条目按照发布时间进行排序,这对一些会把部分新闻等置顶的源比较有用(如信息发布网)。默认为 `true` 即进行排序。 +Set `sorted` to control whether to sort the output by the publish date (`pubDate`). This is useful for some feeds that pin some entries at the top. Default to `true` i.e. the output is sorted. -举例:不重新排序南京大学本科生院教学信息网的公告通知: +E.g. NJU Undergraduate Bulletin Board -## 全文输出 +## Fulltext -可以使用 `mode` 参数来开启自动提取全文内容功能 +Enable fulltext via `mode` parameter. -举例: bilibili 专栏全文输出 +E.g. Bilibili article -## 访问控制 +## Access Control -可以使用 `code` 或 `key` 进行访问控制。参考[访问控制配置](install/#pei-zhi-fang-wen-kong-zhi-pei-zhi-fang-wen-mi-yue-ma)。 +Set `key` or `code` to grant access to requests. See [Access Control Configuration](install/#configuration-access-control-configuration-access-key-code). -## 输出 Telegram 即时预览链接 +## Telegram Instant View -可以输出 Telegram 可识别的即时预览链接,主要用于文章类 RSS +Replace website link with Telegram's Instant View link. -Telegram 即时预览模式需要在官网制作页面处理模板,请前往[官网](https://instantview.telegram.org/)了解更多 +Enable Telegram Instant View requires a page template, it can be obtained from Telegram's [Instant View page](https://instantview.telegram.org/) -- `tgiv`: 模板 hash,可从模板制作页面分享出来的链接末尾获取(`&rhash=`后面跟着的字符串) +- `tgiv`: template hash, obtained from the link of template page generated(the string after `&rhash=`) -举例: +E.g. -## 输出 Sci-hub 链接 +## Sci-hub link -可以输出 Sci-hub 链接,用于知名期刊或输出 DOI 的科学期刊类 RSS。 +Output Sci-hub link in scientific journal routes, this supports major journals or routes that output DOIs. -- `scihub`: 任意值开启 +- `scihub`: set to any value -举例: +E.g. -## 中文简繁体转换 +## Conversion between Traditional and Simplified Chinese -- `opencc`: `s2t` 简体转繁体、`t2s` 繁体转简体,其它可选值见 [simple-wasm - Configurations](https://github.com/fengkx/simplecc-wasm#%E9%85%8D%E7%BD%AE-configurations) +- `opencc`: `s2t` (Simplified Chinese to Traditional Chinese)、`t2s` (Traditional Chinese to Simplified Chinese), other optional values refer to [simplecc-wasm - Configurations](https://github.com/fengkx/simplecc-wasm#%E9%85%8D%E7%BD%AE-configurations) -举例: +E.g. -## 多媒体处理 +## Multimedia processing -:::caution 注意 +:::caution Warning -这是个测试中的 API +This is an experimental API -`image_hotlink_template` 和 `multimedia_hotlink_template` 允许用户提供链接模版用于替换媒体 URL。特定的路由和阅读器组合可能导致用户需要这些功能,但不是非常普遍。敏感字符将被自动转义,不会发生 XSS 攻击。替换范围仅限于媒体元素,即使注入脚本 URL 也不会被加载而造成 XSS。用户能且仅能控制的是「媒体从哪里来」。该功能通常不会带来副作用,如果需要开启这两个参数,请将 `ALLOW_USER_HOTLINK_TEMPLATE` 环境变量设置为 `true` +`image_hotlink_template` and `multimedia_hotlink_template` allow users to supply templates to replace media URLs. Certain routes plus certain RSS readers may result in users needing these features, but it's not very common. Vulnerable characters will be escaped automatically, making XSS attack impossible. The scope of URL replacement is limited to media elements, making any script URL unable to load and unable to cause XSS. As a result, users can only take the control of "where are the media from". These features are commonly side-effect-free. To enable these two parameters, please set `ALLOW_USER_HOTLINK_TEMPLATE` to `true` ::: -- `image_hotlink_template`: 用于处理描述中图片的 URL,绕过防盗链等限制,留空不生效。用法参考 [#2769](https://github.com/DIYgod/RSSHub/issues/2769)。可以使用 [URL](https://developer.mozilla.org/en-US/docs/Web/API/URL#Properties) 的所有属性(加上后缀 `_ue` 则会对其进行 URL 编码),格式为 JS 变量模板。例子:`${protocol}//${host}${pathname}`, `https://i3.wp.com/${host}${pathname}`, `https://images.weserv.nl?url=${href_ue}` -- `multimedia_hotlink_template`: 用法同 `image_hotlink_template`,但应用于音频和视频。注意:该服务必须跟随跳转、允许反代音频和视频,且必须在反代时丢弃 `Referer` 请求头。[这里有一个符合要求的易于自行搭建的项目](https://github.com/Rongronggg9/rsstt-img-relay/blob/main/README_zh-CN.md),该项目接受直接拼接 URL,即 `https://example.com/${href}`,其中 `example.com` 应替换为自行搭建的服务的域名 -- `wrap_multimedia_in_iframe`: 将音频和视频包裹在 `