diff --git a/.eslintrc b/.eslintrc index ee8c2132fc..3b874a7176 100644 --- a/.eslintrc +++ b/.eslintrc @@ -7,7 +7,8 @@ }, "env": { "node": true, - "es6": true + "es6": true, + "browser": true }, "rules": { "no-console": 2, @@ -52,6 +53,7 @@ "prettier/prettier": 0, "no-await-in-loop": 2, "require-atomic-updates": 0, - "no-prototype-builtins": 0 + "no-prototype-builtins": 0, + "no-new-func": 2 } } diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml index e8ae7c5955..d1487c26bd 100644 --- a/.github/FUNDING.yml +++ b/.github/FUNDING.yml @@ -1,3 +1,4 @@ # These are supported funding model platforms patreon: DIYgod +custom: ["https://afdian.net/@diygod", "https://diygod.me/images/zfb.jpg", "https://diygod.me/images/wx.jpg"] diff --git a/.github/ISSUE_TEMPLATE/bug_report_zh.md b/.github/ISSUE_TEMPLATE/bug_report_zh.md index dba7406ccd..d20baa3a49 100644 --- a/.github/ISSUE_TEMPLATE/bug_report_zh.md +++ b/.github/ISSUE_TEMPLATE/bug_report_zh.md @@ -7,15 +7,30 @@ about: 早起的小可爱有虫抓 请确保已阅读 [文档](https://docs.rsshub.app) 内相关部分,并按照模版提供信息,否则 issue 将被立即关闭。 由于部分源网站反爬缘故,演示地址一些 rss 会返回 status code 403,该问题不是 RSSHub 所致,请勿提交 issue。 + +请填写内容进code block区域,一行一个。 +如果没有符合条件的内容,请填写`NOTEXIST` --> -- 完整路由地址,包含所有必选与可选参数 +#### 路由地址(不包含参数) -- 预期是什么 +```routes +``` -- 实际发生了什么 +#### 完整路由地址,包含所有必选与可选参数 -- 部署相关信息 +```fullroutes +``` + +#### 相关文档地址 + +- https://docs.rsshub.app/... + +#### 预期是什么 + +#### 实际发生了什么 + +#### 部署相关信息 + ## 该 PR 相关 Issue / Involved issue Close # @@ -5,9 +13,64 @@ Close # ## 完整路由地址 / Example for the proposed route(s) + + +```routes +``` + + +## 新RSS检查列表 / New RSS Script Checklist + + + +- [ ] 这个PR中包含了新的路由吗? Does this PR add new route? + - 如果有, 请完成检查列表. If yes, please finish the check list + - **如果你的PR符合下方某个事项, 也请注明. If any of the checklist item meets your PR, please fill it out.** + - [x] <- 这样打勾 +- [ ] 是否提供了文档? Documentation provided? + - [ ] 是否提供了英文文档? EN Documentation provided? +- [ ] 是否支持全文获取? Is this RSS Script support fulltext? + - [ ] 如果全文获取中需要访问文章链接, 是否使用了缓存? If fulltext requires to fetch detail pages, is cache used in the process? + - [缓存说明](https://docs.rsshub.app/joinus/#ti-jiao-xin-de-rsshub-gui-ze-bian-xie-jiao-ben-shi-yong-huan-cun) | [How to use cache](https://docs.rsshub.app/joinus/#ti-jiao-xin-de-rsshub-gui-ze-bian-xie-jiao-ben-shi-yong-huan-cun) +- [ ] 目标是否有明显的反爬/频率限制? Is there any sign of anti-bot or rate limit? + - [ ] 如果有, 是否有对应的措施? (延长缓存时间, 写文档说明, etc.) If yes, do your code reflect this sign? (e.g. write documentations, use long cache time) +- [ ] 是否引入的新的包? Any new package introduced? + - 如果有, 请说明原因. If yes, please state your reason +- [ ] 是否使用了`Puppeteer`? Make use of `Puppeteer`? + - 如果有, 请说明原因. If yes, please state your reason + + +## 说明 / Note + + diff --git a/.github/workflows/docker-test.yml b/.github/workflows/docker-test.yml index 99753bf3d9..ec76708001 100644 --- a/.github/workflows/docker-test.yml +++ b/.github/workflows/docker-test.yml @@ -16,6 +16,7 @@ on: jobs: test: + if: github.repository == "DIYgod/RSSHub" runs-on: ubuntu-latest steps: - diff --git a/.github/workflows/format.yml b/.github/workflows/format.yml index 25d7ee7bd9..472953b0e4 100644 --- a/.github/workflows/format.yml +++ b/.github/workflows/format.yml @@ -13,7 +13,7 @@ jobs: - uses: actions/checkout@v2 - uses: actions/setup-node@v1 with: - node-version: '12' + node-version: '14' - run: yarn install - run: npm run format - name: Commit files diff --git a/.github/workflows/npm-publish.yml b/.github/workflows/npm-publish.yml index 6fbc11a90d..e5bbe3132f 100644 --- a/.github/workflows/npm-publish.yml +++ b/.github/workflows/npm-publish.yml @@ -8,14 +8,13 @@ on: jobs: build: - + if: github.repository == "DIYgod/RSSHub" runs-on: ubuntu-latest - steps: - uses: actions/checkout@v2 - uses: actions/setup-node@v1 with: - node-version: '12' + node-version: '14' registry-url: 'https://registry.npmjs.org' - name: Release run: | diff --git a/.github/workflows/pr-deploy-route-test.yml b/.github/workflows/pr-deploy-route-test.yml new file mode 100644 index 0000000000..2042fe5814 --- /dev/null +++ b/.github/workflows/pr-deploy-route-test.yml @@ -0,0 +1,47 @@ +name: PR route test + +# https://github.com/actions/first-interaction/issues/10#issuecomment-670968624 +# https://github.com/actions/first-interaction/issues/10#issuecomment-752360668 +# Reopen Included +on: +- pull_request_target + + +jobs: + testRoute: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: Fetch affected routes + id: fetchRoute + uses: actions/github-script@v3 + with: + # by default, JSON format returned + github-token: ${{ secrets.GITHUB_TOKEN }} + script: | + const body = context.payload.pull_request.body + const number = context.payload.pull_request.number + const script = require(`${process.env.GITHUB_WORKSPACE}/scripts/workflow/test-route/identify.js`) + return await script({github, context, core}, body, number) + - name: Waiting for 200 from the Vercel Preview + if: (env.TEST_CONTINUE) + uses: patrickedqvist/wait-for-vercel-preview@master + id: waitFor200 + with: + token: ${{ secrets.GITHUB_TOKEN }} + max_timeout: 300 + - name: Generate feedback + if: (env.TEST_CONTINUE) + uses: actions/github-script@v3 + env: + TEST_BASEURL: ${{steps.waitFor200.outputs.url}} + TEST_ROUTES: ${{ steps.fetchRoute.outputs.result }} + with: + github-token: ${{secrets.GITHUB_TOKEN}} + script: | + const link = process.env.TEST_BASEURL + const routes = JSON.parse(process.env.TEST_ROUTES) + const number = context.payload.pull_request.number + core.info(`${link}, ${routes}, ${number}`) + const script = require(`${process.env.GITHUB_WORKSPACE}/scripts/workflow/test-route/test.js`) + return await script({github, context, core}, link, routes, number) diff --git a/.github/workflows/rebase.yml b/.github/workflows/rebase.yml index 0449ddb8bb..917f6c0c41 100644 --- a/.github/workflows/rebase.yml +++ b/.github/workflows/rebase.yml @@ -6,7 +6,7 @@ on: jobs: rebase: - if: github.event.issue.pull_request != '' && contains(github.event.comment.body, '/rebase') + if: github.event.issue.pull_request != '' && contains(github.event.comment.body, '/rebase') && github.event.comment.author_association == 'COLLABORATOR' runs-on: ubuntu-latest steps: - @@ -16,6 +16,6 @@ jobs: fetch-depth: 0 - name: Automatic Rebase - uses: cirrus-actions/rebase@1.3.1 + uses: cirrus-actions/rebase@1.4 env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} \ No newline at end of file + GITHUB_TOKEN: ${{ secrets.TOKEN_SUPER }} \ No newline at end of file diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index a1847ad765..8dc7836c12 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -4,8 +4,7 @@ on: [push, pull_request] jobs: build: - - runs-on: ubuntu-16.04 + runs-on: ubuntu-latest services: redis: @@ -16,7 +15,7 @@ jobs: strategy: matrix: - node-version: [10.x, 12.x] + node-version: [10.x, 12.x, 14.x] steps: - uses: actions/checkout@v2 diff --git a/README.md b/README.md index 83855352e3..829bdc2221 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@ ## Introduction -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 is an open source, easy to use, and extensible RSS feed generator. 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. @@ -32,7 +32,7 @@ RSSHub 是一个开源、简单易用、易于扩展的 RSS 生成器,可以 ### Special Sponsors
-    +   
### Sponsors @@ -55,6 +55,7 @@ Logo designer [sheldonrrr](https://dribbble.com/sheldonrrr) - [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/lt94/RSSAid) | 基于 Flutter 构建的 Android 平台的 RSSHub Radar ## Join Us @@ -92,8 +93,8 @@ Recurring donors will be rewarded via express issue response, or even have your We accept donations via the following ways: -- [WeChat Pay](https://i.loli.net/2019/03/23/5c950ebbc373e.png) -- [Alipay](https://i.loli.net/2019/03/23/5c950ebbc980e.png) +- [WeChat Pay](https://diygod.me/images/wx.jpg) +- [Alipay](https://diygod.me/images/zfb.jpg) - [Paypal](https://www.paypal.me/DIYgod) ## Author diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 0000000000..d7e04b96a7 --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,9 @@ +# Security Policy + +## Supported Version + +Latest commits in master branch + +## Reporting a Vulnerability + +If you believe you have found a security vulnerability in RSSHub, please let us know right away, you can email us at [i@diygod.me](mailto:i@diygod.me). We will investigate all legitimate reports and do our best to quickly fix the problem. diff --git a/assets/radar-rules.js b/assets/radar-rules.js index ced4d2191a..654c9c3924 100644 --- a/assets/radar-rules.js +++ b/assets/radar-rules.js @@ -96,7 +96,10 @@ docs: 'https://docs.rsshub.app/social-media.html#wei-bo', source: ['/u/:id', '/:id'], target: (params, url, document) => { - const uid = document && document.documentElement.innerHTML.match(/\$CONFIG\['oid']='(\d+)'/)[1]; + let uid = document?.documentElement.innerHTML.match(/\$CONFIG\['oid']='(\d+)'/)?.[1]; + if (!uid && !isNaN(params.id)) { + uid = params.id; + } return uid ? `/weibo/user/${uid}` : ''; }, }, @@ -120,6 +123,17 @@ }, ], }, + 'weibo.cn': { + _name: '微博', + m: [ + { + title: '博主', + docs: 'https://docs.rsshub.app/social-media.html#wei-bo', + source: ['/u/:uid', '/profile/:uid'], + target: '/weibo/user/:uid', + }, + ], + }, 'pixiv.net': { _name: 'Pixiv', www: [ @@ -205,7 +219,7 @@ ], }, 'youtube.com': { - _name: 'Youtube', + _name: 'YouTube', www: [ { title: '用户', @@ -248,6 +262,12 @@ source: '/trending', target: '/github/trending/:since', }, + { + title: 'Trending', + docs: 'https://docs.rsshub.app/programming.html#github', + source: '/topics', + target: '/github/topics/:name/:qs?', + }, { title: '仓库 Issue', docs: 'https://docs.rsshub.app/programming.html#github', @@ -322,9 +342,10 @@ { title: '用户文章', docs: 'https://docs.rsshub.app/social-media.html#zhi-hu', - source: '/people/:id/posts', - target: '/zhihu/people/posts/:id', + source: '/:usertype/:id/posts', + target: '/zhihu/posts/:usertype/:id', }, + { title: '热榜', docs: 'https://docs.rsshub.app/social-media.html#zhi-hu', @@ -427,7 +448,7 @@ }, 'ximalaya.com': { _name: '喜马拉雅', - www: [ + '.': [ { title: '专辑', docs: 'https://docs.rsshub.app/multimedia.html#xi-ma-la-ya', @@ -460,15 +481,45 @@ }, ], }, - 'juejin.im': { + 'juejin.cn': { _name: '掘金', '.': [ + { + title: '标签', + docs: 'https://docs.rsshub.app/programming.html#jue-jin-biao-qian', + source: '/tag/:tag', + target: '/juejin/tag/:tag', + }, + { + title: '小册', + docs: 'https://docs.rsshub.app/programming.html#jue-jin-xiao-ce', + source: '/books', + target: '/juejin/books', + }, + { + title: '沸点', + docs: 'https://docs.rsshub.app/programming.html#jue-jin-fei-dian', + source: ['/pins/:type', '/pins/topic/:type'], + target: (params) => (params.type !== 'recommended' ? '/juejin/pins/:type' : '/juejin/pins'), + }, { title: '专栏', - docs: 'https://docs.rsshub.app/programming.html#jue-jin', - source: '/user/:id/posts', + docs: 'https://docs.rsshub.app/programming.html#jue-jin-zhuan-lan', + source: ['/user/:id', '/user/:id/posts'], target: '/juejin/posts/:id', }, + { + title: '收藏集', + docs: 'https://docs.rsshub.app/programming.html#jue-jin-shou-cang-ji', + source: ['/user/:id', '/user/:id/collections'], + target: '/juejin/collections/:id', + }, + { + title: '单个收藏夹', + docs: 'https://docs.rsshub.app/programming.html#jue-jin-dan-ge-shou-cang-jia', + source: '/collection/:collectionId', + target: '/juejin/collection/:collectionId', + }, ], }, 'anime1.me': { @@ -1710,7 +1761,7 @@ }, 'zhaishuyuan.com': { _name: '斋书苑', - www: [ + '.': [ { title: '最新章节', docs: 'https://docs.rsshub.app/reading.html#zhai-shu-yuan', @@ -2005,6 +2056,82 @@ }, ], }, + '141jav.com': { + _name: '141JAV BT', + '.': [ + { + title: '今日种子', + docs: 'https://docs.rsshub.app/multimedia.html#141jav', + source: '/', + target: (params, url, document) => { + const today = document.querySelector('div.card.mb-1.card-overview').getAttribute('data-date').replace(/-/g, ''); + return `/141jav/day/${today}`; + }, + }, + { + title: '今日演员', + docs: 'https://docs.rsshub.app/multimedia.html#141jav', + source: '/', + target: (params, url, document) => { + const star = document.querySelector('div.card-content > div > a').getAttribute('href'); + return `/141jav${star}`; + }, + }, + { + title: '页面种子', + docs: 'https://docs.rsshub.app/multimedia.html#141jav', + source: ['/:type', '/:type/:key', '/:type/:key/:morekey'], + target: (params, url, document) => { + const itype = params.morekey === undefined ? `${params.type}` : params.type === 'tag' ? 'tag' : 'day'; + let ikey = `${itype === 'day' ? params.type : ''}${params.key || ''}${itype === 'tag' && params.morekey !== undefined ? '%2F' : ''}${params.morekey || ''}`; + if (ikey === '' && itype === 'tag') { + ikey = document.querySelector('div.thumbnail.is-inline > a').getAttribute('href').replace('/tag/', '').replace('/', '%2F'); + } else if (ikey === '' && itype === 'actress') { + ikey = document.querySelector('div.card > a').getAttribute('href').replace('/actress/', ''); + } + return `/141jav/${itype}/${ikey}`; + }, + }, + ], + }, + '141ppv.com': { + _name: '141ppv BT', + '.': [ + { + title: '今日种子', + docs: 'https://docs.rsshub.app/multimedia.html#141pvp', + source: '/', + target: (params, url, document) => { + const today = document.querySelector('div.card.mb-1.card-overview').getAttribute('data-date').replace(/-/g, ''); + return `/141ppv/day/${today}`; + }, + }, + { + title: '今日演员', + docs: 'https://docs.rsshub.app/multimedia.html#141ppv', + source: '/', + target: (params, url, document) => { + const star = document.querySelector('div.card-content > div > a').getAttribute('href'); + return `/141ppv${star}`; + }, + }, + { + title: '页面种子', + docs: 'https://docs.rsshub.app/multimedia.html#141ppv', + source: ['/:type', '/:type/:key', '/:type/:key/:morekey'], + target: (params, url, document) => { + const itype = params.morekey === undefined ? `${params.type}` : params.type === 'tag' ? 'tag' : 'day'; + let ikey = `${itype === 'day' ? params.type : ''}${params.key || ''}${itype === 'tag' && params.morekey !== undefined ? '%2F' : ''}${params.morekey || ''}`; + if (ikey === '' && itype === 'tag') { + ikey = document.querySelector('div.thumbnail.is-inline > a').getAttribute('href').replace('/tag/', '').replace('/', '%2F'); + } else if (ikey === '' && itype === 'actress') { + ikey = document.querySelector('div.card > a').getAttribute('href').replace('/actress/', ''); + } + return `/141ppv/${itype}/${ikey}`; + }, + }, + ], + }, 'sexinsex.net': { _name: 'sexinsex', '.': [ @@ -2052,6 +2179,12 @@ source: '/news', target: '/umass/amherst/ecenews', }, + { + title: 'ECE Seminar', + docs: 'http://docs.rsshub.app/en/university.html#umass-amherst', + source: '/seminars', + target: '/umass/amherst/eceseminar', + }, ], 'www.cics': [ { @@ -2366,6 +2499,50 @@ }, ], }, + 'matataki.io': { + _name: 'matataki', + www: [ + { + title: '最热作品', + docs: 'https://docs.rsshub.app/new-media.html#matataki', + source: '/article/', + target: '/matataki/posts/hot', + }, + { + title: '最新作品', + docs: 'https://docs.rsshub.app/new-media.html#matataki', + source: '/article/latest', + target: '/matataki/posts/latest', + }, + { + title: '作者创作', + docs: 'https://docs.rsshub.app/new-media.html#matataki', + source: '/user/:uid', + target: (params) => `/matataki/users/${params.uid}/posts`, + }, + { + title: 'Fan票关联作品', + docs: 'https://docs.rsshub.app/new-media.html#matataki', + source: ['/token/:tokenId', '/token/:tokenId/circle'], + target: (params) => `/matataki/tokens/${params.tokenId}/posts`, + }, + { + title: '标签关联作品', + docs: 'https://docs.rsshub.app/new-media.html#matataki', + source: ['/tag/:tagId'], + target: (params, url) => { + const tagName = new URL(url).searchParams.get('name'); + return `/matataki/tags/${params.tagId}/${tagName}/posts`; + }, + }, + { + title: '收藏夹', + docs: 'https://docs.rsshub.app/new-media.html#matataki', + source: '/user/:uid/favlist/:fid', + target: (params) => `/matataki/users/${params.uid}/favorites/${params.fid}/posts`, + }, + ], + }, 'eventernote.com': { _name: 'Eventernote', www: [ @@ -2377,4 +2554,109 @@ }, ], }, + 'instagram.com': { + _name: 'Instagram', + www: [ + { + title: '用户', + docs: 'https://docs.rsshub.app/social-media.html#instagram', + source: '/:id', + target: (params) => { + if (params.id !== 'explore' && params.id !== 'developer') { + return '/instagram/user/:id'; + } + }, + }, + ], + }, + 'huya.com': { + _name: '虎牙直播', + '.': [ + { + title: '直播间开播', + docs: 'https://docs.rsshub.app/live.html#hu-ya-zhi-bo-zhi-bo-jian-kai-bo', + source: '/:id', + target: '/huya/live/:id', + }, + ], + }, + 'craigslist.org': { + _name: 'Craigslist', + '.': [ + { + title: '商品搜索列表', + docs: 'https://docs.rsshub.app/shopping.html#craigslist', + }, + ], + }, + 'saraba1st.com': { + _name: 'Saraba1st', + bbs: [ + { + title: '帖子', + docs: 'https://docs.rsshub.app/bbs.html#saraba1st', + source: '/2b/:id', + target: (params) => { + const id = params.id.includes('thread') ? params.id.split('-')[1] : ''; + return id ? `/saraba1st/thread/${id}` : ''; + }, + }, + ], + }, + 'scboy.com': { + _name: 'scboy 论坛', + www: [ + { + title: '帖子', + docs: 'https://docs.rsshub.app/bbs.html#scboy', + source: '', + target: (params, url) => { + const id = url.includes('thread') ? url.split('-')[1].split('.')[0] : ''; + return id ? `/scboy/thread/${id}` : ''; + }, + }, + ], + }, + 'cqut.edu.cn': { + _name: '重庆理工大学', + tz: [ + { + title: '通知', + docs: 'https://docs.rsshub.app/university.html#chong-qing-li-gong-da-xue', + source: '/*', + }, + ], + lib: [ + { + title: '图书馆通知', + docs: 'https://docs.rsshub.app/university.html#chong-qing-li-gong-da-xue', + source: '/*', + }, + ], + }, + 'cqwu.net': { + _name: '重庆文理学院', + www: [ + { + title: '通知', + docs: 'https://docs.rsshub.app/university.html#chong-qing-wen-li-xue-yuan', + source: '/:type', + target: (params) => { + if (params.type === 'channel_7721.html') { + return '/cqwu/news/notify'; + } + }, + }, + { + title: '学术活动', + docs: 'https://docs.rsshub.app/university.html#chong-qing-wen-li-xue-yuan', + source: '/:type', + target: (params) => { + if (params.type === 'channel_7722.html') { + return '/cqwu/news/academiceve'; + } + }, + }, + ], + }, }); diff --git a/docker-compose.yml b/docker-compose.yml index 238c7e35aa..08fa2adeb7 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -16,7 +16,8 @@ services: - browserless browserless: - image: browserless/chrome + # See issue 6680 + image: browserless/chrome:1.43-chrome-stable restart: always redis: diff --git a/docs/.vuepress/components/Route.vue b/docs/.vuepress/components/Route.vue index 6a1d7b8ac6..a83a40db54 100644 --- a/docs/.vuepress/components/Route.vue +++ b/docs/.vuepress/components/Route.vue @@ -1,13 +1,13 @@