├── .gitignore ├── .eslintignore ├── renovate.json ├── src ├── assets │ ├── icon16.png │ ├── icon48.png │ ├── rsshub.png │ ├── icon128.png │ ├── sandbox.html │ ├── background.html │ ├── options.html │ ├── popup.html │ └── manifest.json ├── css │ ├── options.scss │ └── popup.less ├── js │ ├── content │ │ ├── index.js │ │ └── utils.js │ ├── sandbox │ │ ├── index.js │ │ └── utils.js │ ├── options │ │ ├── index.js │ │ ├── views │ │ │ ├── About.vue │ │ │ ├── List.vue │ │ │ └── Setting.vue │ │ └── App.vue │ ├── common │ │ ├── utils.js │ │ ├── config.js │ │ ├── rules.js │ │ └── radar-rules.js │ ├── background │ │ ├── index.js │ │ └── utils.js │ └── popup │ │ └── index.js └── svg │ ├── about.svg │ └── setting.svg ├── .prettierignore ├── .prettierrc ├── .github └── dependabot.yml ├── LICENSE ├── .travis.yml ├── .eslintrc ├── package.json ├── README.md └── webpack.config.js /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | dist 3 | release 4 | yarn-error.log -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | .github/ 2 | .vscode/ 3 | dist 4 | release 5 | *.config.js -------------------------------------------------------------------------------- /renovate.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": [ 3 | "config:base" 4 | ] 5 | } 6 | -------------------------------------------------------------------------------- /src/assets/icon16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aliuq/RSSHub-Radar/master/src/assets/icon16.png -------------------------------------------------------------------------------- /src/assets/icon48.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aliuq/RSSHub-Radar/master/src/assets/icon48.png -------------------------------------------------------------------------------- /src/assets/rsshub.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aliuq/RSSHub-Radar/master/src/assets/rsshub.png -------------------------------------------------------------------------------- /src/assets/icon128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aliuq/RSSHub-Radar/master/src/assets/icon128.png -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | package.json 2 | package-lock.json 3 | .github/ 4 | .vscode/ 5 | dist 6 | release 7 | *.config.js 8 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "printWidth": 233, 3 | "tabWidth": 4, 4 | "singleQuote": true, 5 | "trailingComma": "es5", 6 | "arrowParens": "always" 7 | } 8 | -------------------------------------------------------------------------------- /src/css/options.scss: -------------------------------------------------------------------------------- 1 | $--color-primary: #f5712c; 2 | 3 | $--font-path: '~element-ui/lib/theme-chalk/fonts'; 4 | 5 | @import '~element-ui/packages/theme-chalk/src/index'; 6 | -------------------------------------------------------------------------------- /src/assets/sandbox.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | RSSHub Radar Sandbox 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /src/assets/background.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | RSSHub Radar Background 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /src/assets/options.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | RSSHub Radar 选项 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | -------------------------------------------------------------------------------- /src/js/content/index.js: -------------------------------------------------------------------------------- 1 | import { getPageRSS } from './utils'; 2 | 3 | chrome.runtime.onMessage.addListener((msg, sender, sendResponse) => { 4 | if (msg.text === 'getPageRSS') { 5 | sendResponse(getPageRSS()); 6 | } else if (msg.text === 'getHTML') { 7 | sendResponse(document.documentElement.innerHTML); 8 | } 9 | }); 10 | 11 | chrome.runtime.sendMessage(null, { 12 | text: 'setPageRSS', 13 | feeds: getPageRSS(), 14 | }); 15 | -------------------------------------------------------------------------------- /src/svg/about.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: npm 4 | directory: "/" 5 | schedule: 6 | interval: daily 7 | time: "21:00" 8 | open-pull-requests-limit: 10 9 | reviewers: 10 | - DIYgod 11 | labels: 12 | - dependencies 13 | ignore: 14 | - dependency-name: webpack 15 | versions: 16 | - 5.26.2 17 | - 5.27.2 18 | - 5.28.0 19 | - 5.28.0 20 | - 5.30.0 21 | - 5.31.0 22 | - 5.31.2 23 | - 5.35.0 24 | - 5.35.1 25 | - dependency-name: webpack-cli 26 | versions: 27 | - 4.4.0 28 | - 4.5.0 29 | - 4.5.0 30 | - 4.5.0 31 | - 4.6.0 32 | - 4.6.0 33 | - 4.6.0 34 | - 4.6.0 35 | - dependency-name: copy-webpack-plugin 36 | versions: 37 | - 8.1.0 38 | - dependency-name: postcss-loader 39 | versions: 40 | - 5.1.0 41 | -------------------------------------------------------------------------------- /src/assets/popup.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | RSSHub Radar 5 | 6 | 7 | 8 |
9 | 10 | 11 |
12 |
13 |

( ´・・)ノ(._.`) 当前页面没有检测到 RSS

14 |

参与到 RSSHub 让万物皆可 RSS 吧!

15 |
16 |
17 |

当前页面上的 RSS

18 | 19 |
20 |
21 |

适用于当前页面的 RSSHub

22 | 23 |
24 |
25 |

适用于当前网站的 RSSHub

26 | 27 |
28 | 29 | 30 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 DIYgod 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | 3 | node_js: "lts/*" 4 | 5 | install: 6 | - yarn 7 | 8 | before_install: 9 | - mkdir release 10 | 11 | script: 12 | - npm run format:check 13 | - npm run release 14 | 15 | deploy: 16 | provider: releases 17 | api_key: 18 | secure: lxDqLR2WT0Z1LyPaxebU7QVI9aUl0qr1tfXD+5oS8bTojyeEEh+G7q4nx+fue1GWAWf2Vzjvc2ZsVoGnu1B/82CjiWCy1Inmx2e/A+chmlh6kDjJT1iuk1FUO/isitKjWQ3+P1libuwitnjC/4APhkE6oZItyP3aJXjrIszZojuQaL14ESL0AN8xxd+3rtGrjXBnQPsMzJy8nr6UGKouVneKYEKi/L+PFY999Azq2YCb5rCKnGjOFeFjcdf2J1dFgkLHt1ZV0bUY2gKyxa9tiK+90GLfTtP0ufhjalappuiSFuYMRApImgtE6I41+gW33c42J/dLgXWgtdMMxGARZwKWiInqYuUTXlb29eVMf6R0dET77RuovSfx4TaWcDcWXSGIrFmvharm0OYkWMbQKowQx49LXQydfhQDp0UjcH1EdTu5VIcOGorPPjGbVCci+YtxpasaRa+mwLQJA5Lma/6r+191NQl1NZNEsu8RmCrvyy0QclLa5pyCNdbGh54rcNLdz5P/wNABCI8b4tWPynOJOYWTK1bMyBNl2IWGFT4+wAaGz7fNusOQK5TtLSkX6ZhRLDCCoLUGlA9N74I4/ABu7FssXbDfnhGF0EqKDCn3r1rJOSqc5PeJAn1ziayXVzhoWG/JfvcksOxAcjdwRHWpjf+q5UtBDWfoucqJnN8= 19 | file: release/radar.zip 20 | skip_cleanup: true 21 | on: 22 | repo: DIYgod/RSSHub-Radar 23 | tags: true 24 | 25 | cache: 26 | yarn: true 27 | directories: 28 | - node_modules -------------------------------------------------------------------------------- /src/assets/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "manifest_version": 2, 3 | "applications": { 4 | "gecko": { 5 | "id": "i@diygod.me" 6 | } 7 | }, 8 | "name": "RSSHub Radar", 9 | "description": "RSSHub Radar 是 RSSHub 的衍生项目,她可以帮助你快速发现和订阅当前网站的 RSS 和 RSSHub", 10 | "version": "1.7.0", 11 | "homepage_url": "https://docs.rsshub.app", 12 | "icons": { 13 | "16": "icon16.png", 14 | "48": "icon48.png", 15 | "128": "icon128.png" 16 | }, 17 | 18 | "browser_action": { 19 | "default_icon": "rsshub.png", 20 | "default_popup": "popup.html" 21 | }, 22 | "content_scripts": [{ 23 | "matches": ["https://*/*", "http://*/*"], 24 | "js": ["content.js"] 25 | }], 26 | "background" : { 27 | "page": "background.html", 28 | "persistent": true 29 | }, 30 | "options_page": "options.html", 31 | "sandbox": { 32 | "pages": ["sandbox.html"] 33 | }, 34 | "permissions": [ 35 | "tabs", 36 | "storage", 37 | "notifications", 38 | "alarms", 39 | "idle", 40 | "unlimitedStorage" 41 | ] 42 | } 43 | -------------------------------------------------------------------------------- /src/js/sandbox/index.js: -------------------------------------------------------------------------------- 1 | import { getPageRSSHub, getWebsiteRSSHub, getList } from './utils'; 2 | 3 | window.getPageRSSHub = getPageRSSHub; 4 | window.getWebsiteRSSHub = getWebsiteRSSHub; 5 | window.getList = getList; 6 | 7 | window.addEventListener('message', function (event) { 8 | const command = event.data.command; 9 | switch (command) { 10 | case 'getPageRSSHub': 11 | event.source.postMessage( 12 | { 13 | origin: event.data, 14 | result: getPageRSSHub(event.data.data), 15 | }, 16 | event.origin 17 | ); 18 | break; 19 | case 'getWebsiteRSSHub': 20 | event.source.postMessage( 21 | { 22 | origin: event.data, 23 | result: getWebsiteRSSHub(event.data.data), 24 | }, 25 | event.origin 26 | ); 27 | break; 28 | case 'getList': 29 | event.source.postMessage( 30 | { 31 | origin: event.data, 32 | result: getList(event.data.data), 33 | }, 34 | event.origin 35 | ); 36 | break; 37 | } 38 | }); 39 | -------------------------------------------------------------------------------- /src/js/options/index.js: -------------------------------------------------------------------------------- 1 | import '../../css/options.scss'; 2 | import Vue from 'vue'; 3 | import VueRouter from 'vue-router'; 4 | import App from './App.vue'; 5 | import Setting from './views/Setting.vue'; 6 | import List from './views/List.vue'; 7 | import About from './views/About.vue'; 8 | import { Container, Menu, MenuItem, Aside, Header, Main, Footer, Input, Checkbox, Message, Loading, Collapse, CollapseItem, Button, Progress, Tooltip } from 'element-ui'; 9 | 10 | Vue.use(VueRouter); 11 | Vue.use(Container); 12 | Vue.use(Menu); 13 | Vue.use(MenuItem); 14 | Vue.use(Aside); 15 | Vue.use(Header); 16 | Vue.use(Main); 17 | Vue.use(Footer); 18 | Vue.use(Input); 19 | Vue.use(Checkbox); 20 | Vue.use(Loading.directive); 21 | Vue.use(Collapse); 22 | Vue.use(CollapseItem); 23 | Vue.use(Button); 24 | Vue.use(Progress); 25 | Vue.use(Tooltip); 26 | 27 | Vue.prototype.$loading = Loading.service; 28 | Vue.prototype.$message = Message; 29 | Vue.config.productionTip = false; 30 | 31 | const routes = [ 32 | { path: '/', redirect: '/setting' }, 33 | { path: '/setting', component: Setting }, 34 | { path: '/list', component: List }, 35 | { path: '/about', component: About }, 36 | ]; 37 | const router = new VueRouter({ 38 | routes, 39 | }); 40 | 41 | new Vue({ 42 | render: (h) => h(App), 43 | router, 44 | }).$mount('#app'); 45 | -------------------------------------------------------------------------------- /src/js/common/utils.js: -------------------------------------------------------------------------------- 1 | export function secondToTime(second) { 2 | const hour = Math.floor(second / 3600); 3 | const min = Math.floor((second - hour * 3600) / 60); 4 | return `${hour ? hour + '小时' : ''}${min}分钟`; 5 | } 6 | 7 | const iframe = document.querySelector('#sandbox'); 8 | const returnResults = []; 9 | window.addEventListener('message', (event) => { 10 | returnResults.forEach((returnResult) => { 11 | returnResult(event); 12 | }); 13 | }); 14 | export function commandSandbox(command, data, callback) { 15 | if (data.rules && typeof data.rules === 'object') { 16 | try { 17 | callback(iframe.contentWindow[command](data)); 18 | return; 19 | } catch (e) { 20 | // nothing 21 | } 22 | } 23 | iframe.contentWindow.postMessage( 24 | { 25 | command: command, 26 | data: data, 27 | }, 28 | '*' 29 | ); 30 | 31 | const myReturn = (event) => { 32 | if (event.data.origin.command === command && (!data.url || event.data.origin.data.url === data.url)) { 33 | returnResults.splice(returnResults.indexOf(myReturn), 1); 34 | if (event.data && event.data.result) { 35 | callback(event.data.result); 36 | } 37 | } 38 | }; 39 | returnResults.push(myReturn); 40 | } 41 | -------------------------------------------------------------------------------- /src/js/common/config.js: -------------------------------------------------------------------------------- 1 | export const defaultConfig = { 2 | rsshubDomain: 'https://rsshub.app', 3 | rsshubAccessControl: { 4 | enabled: false, 5 | accessKey: '', 6 | useCode: false, 7 | }, 8 | notice: { 9 | badge: true, 10 | }, 11 | submitto: { 12 | ttrss: false, 13 | ttrssDomain: '', 14 | miniflux: false, 15 | minifluxDomain: '', 16 | freshrss: false, 17 | freshrssDomain: '', 18 | nextcloudnews: false, 19 | nextcloudnewsDomain: '', 20 | feedly: true, 21 | inoreader: false, 22 | feedbin: false, 23 | theoldreader: false, 24 | feedspub: false, 25 | bazqux: false, 26 | local: false, 27 | }, 28 | refreshTimeout: 5 * 60 * 60, 29 | enableRemoteRules: !navigator.userAgent.match(/firefox|safari/i), 30 | }; 31 | 32 | export function getConfig(success) { 33 | if (chrome.storage) { 34 | chrome.storage.sync.get('config', (result) => { 35 | success(Object.assign({}, defaultConfig, result.config)); 36 | }); 37 | } else { 38 | success && success(defaultConfig); 39 | } 40 | } 41 | 42 | export function saveConfig(config, success) { 43 | if (!config.rsshubDomain) { 44 | config.rsshubDomain = defaultConfig.rsshubDomain; 45 | } 46 | config.rsshubDomain = config.rsshubDomain.replace(/\/$/, ''); 47 | if (config.rsshubDomain === defaultConfig.rsshubDomain) { 48 | config.rsshubAccessControl.enabled = defaultConfig.rsshubAccessControl.enabled; 49 | } 50 | if (chrome.storage) { 51 | chrome.storage.sync.set( 52 | { 53 | config, 54 | }, 55 | () => { 56 | success && success(); 57 | } 58 | ); 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /src/js/common/rules.js: -------------------------------------------------------------------------------- 1 | import { defaultConfig } from './config'; 2 | import { defaultRules } from './radar-rules'; 3 | 4 | export function refreshRules(success) { 5 | if (defaultConfig.enableRemoteRules) { 6 | const done = (response) => { 7 | response.text().then((text) => { 8 | chrome.storage.local.set({ 9 | rules: text, 10 | rulesDate: +new Date(), 11 | }); 12 | success && success(); 13 | }); 14 | }; 15 | fetch('https://rsshub.js.org/build/radar-rules.js') 16 | .then((response) => { 17 | done(response); 18 | }) 19 | .catch(() => { 20 | fetch('https://cdn.jsdelivr.net/gh/DIYgod/RSSHub@gh-pages/build/radar-rules.js').then((response) => { 21 | done(response); 22 | }); 23 | }); 24 | } else { 25 | success && success(); 26 | } 27 | } 28 | 29 | export function getRules(success) { 30 | if (defaultConfig.enableRemoteRules) { 31 | chrome.storage.local.get('rules', (result) => { 32 | if (result && result.rules) { 33 | success(result.rules); 34 | } else { 35 | refreshRules(() => { 36 | getRules(success); 37 | }); 38 | } 39 | }); 40 | } else { 41 | success(defaultRules); 42 | } 43 | } 44 | 45 | export function getRulesDate(success) { 46 | chrome.storage.local.get('rulesDate', (result) => { 47 | if (result && result.rulesDate) { 48 | success(result.rulesDate); 49 | } else { 50 | success(null); 51 | } 52 | }); 53 | } 54 | 55 | export function updateRules(text, success) { 56 | chrome.storage.local.set({ 57 | rules: text, 58 | }); 59 | success && success(); 60 | } 61 | -------------------------------------------------------------------------------- /.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "extends": [ 3 | "eslint:recommended", 4 | "plugin:prettier/recommended" 5 | ], 6 | "plugins": [ 7 | "prettier" 8 | ], 9 | "parserOptions": { 10 | "ecmaVersion": 2020, 11 | "sourceType": "module" 12 | }, 13 | "env": { 14 | "node": true, 15 | "es6": true 16 | }, 17 | "rules": { 18 | "no-console": 0, 19 | "block-scoped-var": 1, 20 | "curly": 1, 21 | "eqeqeq": 1, 22 | "no-global-assign": 1, 23 | "no-implicit-globals": 1, 24 | "no-labels": 1, 25 | "no-multi-str": 1, 26 | "comma-spacing": 1, 27 | "comma-style": 1, 28 | "func-call-spacing": 1, 29 | "keyword-spacing": 1, 30 | "linebreak-style": 1, 31 | "lines-around-comment": 1, 32 | "no-multiple-empty-lines": 1, 33 | "space-infix-ops": 1, 34 | "arrow-spacing": 1, 35 | "no-var": 1, 36 | "prefer-const": 1, 37 | "no-unsafe-negation": 1, 38 | "array-callback-return": 1, 39 | "dot-notation": 1, 40 | "no-eval": 0, 41 | "no-extend-native": 1, 42 | "no-extra-label": 1, 43 | "semi": 1, 44 | "space-before-blocks": 1, 45 | "space-in-parens": 1, 46 | "space-unary-ops": 1, 47 | "spaced-comment": 1, 48 | "arrow-body-style": 1, 49 | "arrow-parens": 1, 50 | "no-restricted-imports": 1, 51 | "no-duplicate-imports": 1, 52 | "no-useless-computed-key": 1, 53 | "no-useless-rename": 1, 54 | "rest-spread-spacing": 1, 55 | "no-trailing-spaces": 1, 56 | "no-control-regex": 0, 57 | "prettier/prettier": 0, 58 | "no-await-in-loop": 1, 59 | "require-atomic-updates": 0, 60 | "no-prototype-builtins": 0, 61 | "no-undef": 0, 62 | "vue/no-use-v-if-with-v-for": "off", 63 | } 64 | } -------------------------------------------------------------------------------- /src/svg/setting.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/js/background/index.js: -------------------------------------------------------------------------------- 1 | import { handleRSS, removeRSS, addPageRSS, getAllRSS } from './utils'; 2 | import { getConfig, saveConfig } from '../common/config'; 3 | 4 | chrome.tabs.onActivated.addListener((tab) => { 5 | chrome.tabs.sendMessage( 6 | tab.tabId, 7 | { 8 | text: 'getPageRSS', 9 | }, 10 | (feeds) => { 11 | handleRSS(feeds, tab.tabId, true); 12 | } 13 | ); 14 | }); 15 | 16 | chrome.tabs.onUpdated.addListener((tabId, changeInfo, tab) => { 17 | if (changeInfo.url && tab.active) { 18 | chrome.tabs.sendMessage( 19 | tab.id, 20 | { 21 | text: 'getPageRSS', 22 | }, 23 | (feeds) => { 24 | handleRSS(feeds, tab.id); 25 | } 26 | ); 27 | } 28 | }); 29 | 30 | chrome.runtime.onMessage.addListener((msg, sender, sendResponse) => { 31 | if (sender.tab && sender.tab.active) { 32 | if (msg.text === 'setPageRSS') { 33 | handleRSS(msg.feeds, sender.tab.id); 34 | } else if (msg.text === 'addPageRSS') { 35 | addPageRSS(msg.feed, sender.tab.id); 36 | } 37 | } 38 | if (msg.text === 'getAllRSS') { 39 | sendResponse(getAllRSS(msg.tabId)); 40 | } 41 | }); 42 | 43 | chrome.tabs.onRemoved.addListener((tabId) => { 44 | removeRSS(tabId); 45 | }); 46 | 47 | getConfig((config) => { 48 | if (!config.version) { 49 | config.version = VERSION; 50 | saveConfig(config); 51 | } else if (config.version !== VERSION) { 52 | chrome.notifications.create('RSSHubRadarUpdate', { 53 | type: 'basic', 54 | iconUrl: './rsshub.png', 55 | title: '🎉 RSSHub Radar 更新', 56 | message: `v${VERSION},点击查看更新日志`, 57 | }); 58 | chrome.notifications.onClicked.addListener((id) => { 59 | if (id === 'RSSHubRadarUpdate') { 60 | chrome.tabs.create({ 61 | url: 'https://github.com/DIYgod/RSSHub-Radar/releases', 62 | }); 63 | chrome.notifications.clear('RSSHubRadarUpdate'); 64 | } 65 | }); 66 | config.version = VERSION; 67 | saveConfig(config); 68 | } 69 | }); 70 | -------------------------------------------------------------------------------- /src/js/options/views/About.vue: -------------------------------------------------------------------------------- 1 | 22 | 23 | 30 | 31 | 63 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "rsshub-radar", 3 | "version": "0.0.1", 4 | "description": "Browser extension to detect available RSS and RSSHub for current page", 5 | "scripts": { 6 | "test": "echo \"Error: no test specified\" && exit 1", 7 | "dev": "webpack -w --mode=production --progress", 8 | "build": "webpack --mode=production --progress", 9 | "release": "npm run build && zip -r release/radar.zip dist", 10 | "format": "eslint \"**/*.js\" --fix && prettier \"**/*.{js,scss,less}\" --write", 11 | "format:staged": "eslint \"**/*.js\" --fix && pretty-quick --staged --verbose --pattern \"**/*.{js,scss,less}\"", 12 | "format:check": "eslint \"**/*.js\" && prettier-check \"**/*.{js,scss,less}\"" 13 | }, 14 | "repository": { 15 | "type": "git", 16 | "url": "git+https://github.com/DIYgod/RSSHub-Radar.git" 17 | }, 18 | "keywords": [ 19 | "rsshub", 20 | "rss" 21 | ], 22 | "gitHooks": { 23 | "pre-commit": "npm run format:staged" 24 | }, 25 | "author": "DIYgod", 26 | "license": "MIT", 27 | "bugs": { 28 | "url": "https://github.com/DIYgod/RSSHub-Radar/issues" 29 | }, 30 | "homepage": "https://github.com/DIYgod/RSSHub-Radar#readme", 31 | "devDependencies": { 32 | "@babel/core": "7.15.5", 33 | "@babel/preset-env": "7.15.6", 34 | "autoprefixer": "10.3.6", 35 | "babel-loader": "8.2.2", 36 | "babel-plugin-component": "1.1.1", 37 | "copy-webpack-plugin": "9.0.1", 38 | "css-loader": "6.3.0", 39 | "cssnano": "5.0.8", 40 | "eslint": "7.32.0", 41 | "eslint-config-prettier": "8.3.0", 42 | "eslint-loader": "4.0.2", 43 | "eslint-plugin-prettier": "4.0.0", 44 | "file-loader": "6.2.0", 45 | "less": "4.1.1", 46 | "less-loader": "10.0.1", 47 | "mini-css-extract-plugin": "2.3.0", 48 | "node-sass": "^6.0.1", 49 | "postcss-loader": "6.1.1", 50 | "prettier": "2.4.1", 51 | "prettier-check": "2.0.0", 52 | "pretty-quick": "3.1.1", 53 | "sass-loader": "12.1.0", 54 | "svg-inline-loader": "0.8.2", 55 | "template-string-optimize-loader": "3.0.0", 56 | "url-loader": "4.1.1", 57 | "vue": "2.6.14", 58 | "vue-loader": "15.9.8", 59 | "vue-template-compiler": "2.6.14", 60 | "webpack": "5.54.0", 61 | "webpack-cli": "4.8.0", 62 | "yorkie": "2.0.0" 63 | }, 64 | "dependencies": { 65 | "buffer": "^6.0.3", 66 | "clipboard": "2.0.8", 67 | "element-ui": "2.15.6", 68 | "https-browserify": "^1.0.0", 69 | "md5.js": "^1.3.5", 70 | "psl": "1.8.0", 71 | "route-recognizer": "0.3.4", 72 | "rss-parser": "3.12.0", 73 | "stream-browserify": "^3.0.0", 74 | "stream-http": "^3.2.0", 75 | "timers-browserify": "^2.0.12", 76 | "url": "^0.11.0", 77 | "vue-router": "3.5.2" 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /src/js/options/App.vue: -------------------------------------------------------------------------------- 1 | 34 | 35 | 48 | 49 | 122 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

2 | RSSHub 3 |

4 |

RSSHub Radar

5 | 6 | > RSSHub Radar 是 [RSSHub](https://github.com/DIYgod/RSSHub) 的衍生项目,她是一个可以帮助你快速发现和订阅当前网站 RSS 和 RSSHub 的浏览器扩展 7 | > 万物皆可 RSS 8 | 9 | [![build status](https://img.shields.io/travis/DIYgod/RSSHub-Radar/master.svg?style=flat-square)](https://travis-ci.org/DIYgod/RSSHub-Radar) 10 | 11 | [![version](https://img.shields.io/chrome-web-store/v/kefjpfngnndepjbopdmoebkipbgkggaa.svg?style=flat-square)](https://chrome.google.com/webstore/detail/kefjpfngnndepjbopdmoebkipbgkggaa) 12 | [![users](https://img.shields.io/chrome-web-store/users/kefjpfngnndepjbopdmoebkipbgkggaa.svg?style=flat-square)](https://chrome.google.com/webstore/detail/kefjpfngnndepjbopdmoebkipbgkggaa) 13 | [![rating](https://img.shields.io/chrome-web-store/rating/kefjpfngnndepjbopdmoebkipbgkggaa.svg?style=flat-square)](https://chrome.google.com/webstore/detail/kefjpfngnndepjbopdmoebkipbgkggaa) 14 | 15 | [![Mozilla Add-on](https://img.shields.io/amo/v/rsshub-radar?style=flat-square)](https://addons.mozilla.org/zh-CN/firefox/addon/rsshub-radar/) 16 | [![Mozilla Add-on](https://img.shields.io/amo/users/rsshub-radar?color=%2344cc11&style=flat-square)](https://addons.mozilla.org/zh-CN/firefox/addon/rsshub-radar/) 17 | [![Mozilla Add-on](https://img.shields.io/amo/rating/rsshub-radar?style=flat-square)](https://addons.mozilla.org/zh-CN/firefox/addon/rsshub-radar/) 18 | 19 | ## 介绍 20 | 21 | [Telegram 群](https://t.me/rsshub) | [Telegram 频道](https://t.me/awesomeRSSHub) 22 | 23 | RSSHub Radar 是 [RSSHub](https://github.com/DIYgod/RSSHub) 的衍生项目,她是一个可以帮助你快速发现和订阅当前网站 RSS 和 RSSHub 的浏览器扩展 24 | 25 | - 快速发现和订阅当前页面自带的 RSS 26 | - 快速发现和订阅当前页面支持的 RSSHub 27 | - 快速发现当前网站支持的 RSSHub 28 | - 支持一键订阅 RSS 到 Tiny Tiny RSS、Miniflux、FreshRSS、Nextcloud News、Feedly、Inoreader、Feedbin、The Old Reader、Feeds.Pub、BazQux Reader、本地阅读器 29 | 30 | ![](https://i.imgur.com/K1cC5Ck.png) 31 | 32 | ![](https://i.imgur.com/JbLseIa.png) 33 | 34 | ## 安装 35 | 36 | ### 商店安装 37 | 38 | 39 | 40 | 41 | 42 | ### 手动安装 43 | 44 | 首先在 [release](https://github.com/DIYgod/RSSHub-Radar/releases) 页下载相应版本的 `radar.zip` 并解压 45 | 46 | **Chrome安装扩展:** 47 | 48 | 打开 `chrome://extensions/` 49 | 50 | 打开右上角 `开发者模式` 51 | 52 | 点击左上角 `加载已解压的扩展程序` 53 | 54 | 选择解压出的 `dist` 目录 55 | 56 | **Firefox安装扩展:** 57 | 58 | 打开 `about:debugging` 59 | 60 | 点击右上角 `加载临时扩展程序` 61 | 62 | 选择解压出的 `dist` 目录中的 `manifest.json` 文件 63 | 64 | ## 参与我们 65 | 66 | ### 安装开发版本 67 | 68 | **安装依赖并构建项目:** 69 | 70 | ``` 71 | yarn 72 | yarn build 73 | ``` 74 | 75 | 或者使用 npm 76 | 77 | ``` 78 | npm install 79 | npm run build 80 | ``` 81 | 82 | 得到 dist 目录,安装方式参考 [手动安装](#手动安装) 83 | 84 | ### 补充 RSSHub 规则 85 | 86 | [见文档](https://docs.rsshub.app/joinus/#%E6%8F%90%E4%BA%A4%E6%96%B0%E7%9A%84-rsshub-radar-%E8%A7%84%E5%88%99) 87 | 88 | ## 相关项目 89 | 90 | - [RSSHub](https://github.com/DIYgod/RSSHub) 91 | 92 | ## Author 93 | 94 | **RSSHub Radar** © [DIYgod](https://github.com/DIYgod), Released under the [MIT](./LICENSE) License.
95 | Authored and maintained by DIYgod with help from contributors ([list](https://github.com/DIYgod/RSSHub-radar/contributors)). 96 | 97 | > Blog [@DIYgod](https://diygod.me) · GitHub [@DIYgod](https://github.com/DIYgod) · Twitter [@DIYgod](https://twitter.com/DIYgod) · Telegram Channel [@awesomeDIYgod](https://t.me/awesomeDIYgod) 98 | -------------------------------------------------------------------------------- /src/js/options/views/List.vue: -------------------------------------------------------------------------------- 1 | 37 | 38 | 92 | 93 | 129 | -------------------------------------------------------------------------------- /src/js/background/utils.js: -------------------------------------------------------------------------------- 1 | import { getRules, getRulesDate, refreshRules } from '../common/rules'; 2 | import { commandSandbox } from '../common/utils'; 3 | import { getConfig } from '../common/config'; 4 | let config; 5 | let rules = {}; 6 | import RSSParser from 'rss-parser'; 7 | const rssParser = new RSSParser(); 8 | 9 | window.pageRSS = {}; 10 | window.pageRSSHub = {}; 11 | window.websiteRSSHub = {}; 12 | 13 | function schedule(time = +new Date() + config.refreshTimeout * 1000) { 14 | chrome.alarms.create('refreshRules', { 15 | when: time, 16 | periodInMinutes: config.refreshTimeout / 60, 17 | }); 18 | } 19 | 20 | function initSchedule() { 21 | getRulesDate((lastDate) => { 22 | if (!lastDate || +new Date() - lastDate > config.refreshTimeout * 1000) { 23 | refreshRules(); 24 | schedule(); 25 | } else { 26 | schedule(lastDate + config.refreshTimeout * 1000); 27 | } 28 | }); 29 | } 30 | 31 | chrome.storage.onChanged.addListener((result) => { 32 | if (result.config) { 33 | config = result.config.newValue; 34 | } 35 | if (result.rules) { 36 | getRules((rul) => { 37 | rules = rul; 38 | }); 39 | } 40 | }); 41 | 42 | chrome.alarms.onAlarm.addListener((alarm) => { 43 | if (alarm.name === 'refreshRules') { 44 | refreshRules(); 45 | } 46 | }); 47 | 48 | if ('idle' in chrome) { 49 | chrome.idle.onStateChanged.addListener((newState) => { 50 | if (newState === 'active') { 51 | initSchedule(); 52 | } 53 | }); 54 | } 55 | 56 | getConfig((conf) => { 57 | config = conf; 58 | 59 | getRules((rul) => { 60 | rules = rul; 61 | initSchedule(); 62 | }); 63 | }); 64 | 65 | chrome.browserAction.setBadgeBackgroundColor({ 66 | color: '#FF2800', 67 | }); 68 | 69 | chrome.browserAction.setBadgeTextColor && 70 | chrome.browserAction.setBadgeTextColor({ 71 | color: '#fff', 72 | }); 73 | 74 | function setBadge(tabId) { 75 | chrome.browserAction.setBadgeText({ 76 | text: config.notice.badge ? (window.pageRSS[tabId].length + (window.pageRSSHub[tabId] ? window.pageRSSHub[tabId].length : 0) || (window.websiteRSSHub[tabId] && window.websiteRSSHub[tabId].length ? ' ' : '')) + '' : '', 77 | tabId, 78 | }); 79 | } 80 | 81 | function getPageRSSHub(url, tabId, done) { 82 | chrome.tabs.sendMessage( 83 | tabId, 84 | { 85 | text: 'getHTML', 86 | }, 87 | (html) => { 88 | commandSandbox( 89 | 'getPageRSSHub', 90 | { 91 | url, 92 | html, 93 | rules, 94 | }, 95 | done 96 | ); 97 | } 98 | ); 99 | } 100 | 101 | function getWebsiteRSSHub(url, done) { 102 | commandSandbox( 103 | 'getWebsiteRSSHub', 104 | { 105 | url, 106 | rules, 107 | }, 108 | done 109 | ); 110 | } 111 | 112 | export function handleRSS(feeds, tabId, useCache) { 113 | if (useCache && window.pageRSS[tabId]) { 114 | setBadge(tabId); 115 | } else { 116 | chrome.tabs.get(tabId, (tab) => { 117 | feeds && 118 | feeds.forEach((feed) => { 119 | feed.image = tab.favIconUrl || feed.image; 120 | }); 121 | window.pageRSS[tabId] = (feeds && feeds.filter((feed) => !feed.uncertain)) || []; 122 | 123 | getWebsiteRSSHub(tab.url, (feeds) => { 124 | window.websiteRSSHub[tabId] = feeds || []; 125 | setBadge(tabId); 126 | }); 127 | 128 | getPageRSSHub(tab.url, tabId, (feeds) => { 129 | window.pageRSSHub[tabId] = feeds || []; 130 | setBadge(tabId); 131 | }); 132 | }); 133 | 134 | feeds && 135 | feeds 136 | .filter((feed) => feed.uncertain) 137 | .forEach((feed) => { 138 | rssParser.parseURL(feed.url, (err, result) => { 139 | if (!err) { 140 | feed.title = result.title; 141 | window.pageRSS[tabId].push(feed); 142 | setBadge(tabId); 143 | } 144 | }); 145 | }); 146 | } 147 | } 148 | 149 | export function removeRSS(tabId) { 150 | delete window.pageRSS[tabId]; 151 | delete window.websiteRSSHub[tabId]; 152 | delete window.pageRSSHub[tabId]; 153 | } 154 | 155 | export function addPageRSS(feed, tabId) { 156 | if (feed) { 157 | chrome.tabs.get(tabId, (tab) => { 158 | feed.image = tab.favIconUrl || feed.image; 159 | window.pageRSS[tabId].push(feed); 160 | setBadge(tabId); 161 | }); 162 | } 163 | } 164 | 165 | export function getAllRSS(tabId) { 166 | return { 167 | pageRSS: window.pageRSS[tabId] || {}, 168 | websiteRSSHub: window.websiteRSSHub[tabId] || {}, 169 | pageRSSHub: window.pageRSSHub[tabId] || {}, 170 | }; 171 | } 172 | -------------------------------------------------------------------------------- /src/js/content/utils.js: -------------------------------------------------------------------------------- 1 | import RSSParser from 'rss-parser'; 2 | const rssParser = new RSSParser(); 3 | 4 | let pageRSS = null; 5 | const defaultTitle = 6 | document.querySelector('title') && 7 | document.querySelector('title').innerHTML && 8 | document 9 | .querySelector('title') 10 | .innerHTML.replace(//, (match, p1) => p1) 11 | .trim(); 12 | const image = (document.querySelector('link[rel~="icon"]') && handleUrl(document.querySelector('link[rel~="icon"]').getAttribute('href'))) || document.location.origin + '/favicon.ico'; 13 | 14 | function handleUrl(url) { 15 | if (url.startsWith('//')) { 16 | url = document.location.protocol + url; 17 | } else if (url.startsWith('/')) { 18 | url = document.location.origin + url; 19 | } else if (!/^(http|https):\/\//i.test(url)) { 20 | url = document.location.href + '/' + url.replace(/^\//g, ''); 21 | } 22 | return url; 23 | } 24 | 25 | export function getPageRSS() { 26 | if (!pageRSS) { 27 | pageRSS = []; 28 | const unique = { 29 | data: {}, 30 | save: function (url) { 31 | this.data[url.replace(/^(https?:)?\/\//, '')] = 1; 32 | }, 33 | check: function (url) { 34 | return this.data[url.replace(/^(https?:)?\/\//, '')]; 35 | }, 36 | }; 37 | 38 | // links 39 | const types = [ 40 | 'application/rss+xml', 41 | 'application/atom+xml', 42 | 'application/rdf+xml', 43 | 'application/rss', 44 | 'application/atom', 45 | 'application/rdf', 46 | 'text/rss+xml', 47 | 'text/atom+xml', 48 | 'text/rdf+xml', 49 | 'text/rss', 50 | 'text/atom', 51 | 'text/rdf', 52 | ]; 53 | const links = document.querySelectorAll('link[type]'); 54 | for (let i = 0; i < links.length; i++) { 55 | if (links[i].hasAttribute('type') && types.indexOf(links[i].getAttribute('type')) !== -1) { 56 | const feed_url = links[i].getAttribute('href'); 57 | 58 | if (feed_url) { 59 | const feed = { 60 | url: handleUrl(feed_url), 61 | title: links[i].getAttribute('title') || defaultTitle, 62 | image, 63 | }; 64 | if (!unique.check(feed.url)) { 65 | pageRSS.push(feed); 66 | unique.save(feed.url); 67 | } 68 | } 69 | } 70 | } 71 | 72 | // a 73 | const aEles = document.querySelectorAll('a'); 74 | const check = /([^a-zA-Z]|^)rss([^a-zA-Z]|$)/i; 75 | for (let i = 0; i < aEles.length; i++) { 76 | if (aEles[i].hasAttribute('href')) { 77 | const href = aEles[i].getAttribute('href'); 78 | 79 | if ( 80 | href.match(/\/(feed|rss|atom)(\.(xml|rss|atom))?$/) || 81 | (aEles[i].hasAttribute('title') && aEles[i].getAttribute('title').match(check)) || 82 | (aEles[i].hasAttribute('class') && aEles[i].getAttribute('class').match(check)) || 83 | (aEles[i].innerText && aEles[i].innerText.match(check)) 84 | ) { 85 | const feed = { 86 | url: handleUrl(href), 87 | title: aEles[i].innerText || aEles[i].getAttribute('title') || defaultTitle, 88 | image, 89 | uncertain: 1, 90 | }; 91 | if (!unique.check(feed.url)) { 92 | pageRSS.push(feed); 93 | unique.save(feed.url); 94 | } 95 | } 96 | } 97 | } 98 | 99 | // whole page 100 | if (!unique.check(document.location.href)) { 101 | let html; 102 | if (document.body && document.body.childNodes && document.body.childNodes.length === 1 && document.body.childNodes[0].tagName && document.body.childNodes[0].tagName.toLowerCase()) { 103 | html = document.body.childNodes[0].innerText; 104 | } else if (document.querySelector('#webkit-xml-viewer-source-xml')) { 105 | html = document.querySelector('#webkit-xml-viewer-source-xml').innerHTML; 106 | } 107 | 108 | if (html) { 109 | rssParser.parseString(html, (err, result) => { 110 | if (!err) { 111 | chrome.runtime.sendMessage(null, { 112 | text: 'addPageRSS', 113 | feed: { 114 | url: document.location.href, 115 | title: result.title, 116 | image, 117 | }, 118 | }); 119 | } 120 | }); 121 | } 122 | } 123 | unique.save(document.location.href); 124 | } 125 | return pageRSS; 126 | } 127 | -------------------------------------------------------------------------------- /src/css/popup.less: -------------------------------------------------------------------------------- 1 | body { 2 | min-width: 310px; 3 | margin: 0; 4 | padding: 20px 20px 5px; 5 | font-family: 'Helvetica Neue', Helvetica, 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', '微软雅黑', Arial, sans-serif; 6 | 7 | &.something { 8 | .no-rss { 9 | display: none; 10 | } 11 | 12 | .icons { 13 | right: 25px; 14 | } 15 | } 16 | } 17 | 18 | .icons { 19 | position: absolute; 20 | right: 16px; 21 | top: 21px; 22 | 23 | .icons-item { 24 | width: 18px; 25 | display: inline-block; 26 | fill: #666; 27 | transition: 0.3s; 28 | margin-left: 5px; 29 | 30 | &:hover { 31 | fill: #000; 32 | } 33 | } 34 | } 35 | 36 | .page-rss, 37 | .page-rsshub, 38 | .website-rsshub { 39 | display: none; 40 | margin-bottom: 20px; 41 | 42 | h2 { 43 | font-size: 16px; 44 | margin: 0 0 15px; 45 | } 46 | 47 | ul, 48 | li { 49 | padding: 0; 50 | list-style-type: none; 51 | } 52 | 53 | ul { 54 | margin: 0 5px; 55 | } 56 | } 57 | 58 | .no-rss { 59 | margin-bottom: 20px; 60 | 61 | h2 { 62 | font-size: 16px; 63 | margin: 0 0 15px; 64 | } 65 | 66 | p { 67 | margin: 0; 68 | font-size: 14px; 69 | line-height: 20px; 70 | } 71 | 72 | a { 73 | color: #ff8549; 74 | text-decoration: none; 75 | } 76 | } 77 | .rss-item { 78 | display: flex; 79 | height: 30px; 80 | margin-bottom: 15px; 81 | 82 | .rss-image { 83 | width: 30px; 84 | height: 30px; 85 | margin-right: 10px; 86 | } 87 | 88 | .rss-info { 89 | width: 200px; 90 | cursor: pointer; 91 | display: flex; 92 | text-decoration: none; 93 | color: #000; 94 | line-height: 1; 95 | flex-direction: column; 96 | justify-content: space-between; 97 | 98 | .rss-title { 99 | font-size: 13px; 100 | overflow: hidden; 101 | text-overflow: ellipsis; 102 | white-space: nowrap; 103 | } 104 | 105 | .rss-url { 106 | font-size: 12px; 107 | color: #aaa; 108 | overflow: hidden; 109 | text-overflow: ellipsis; 110 | white-space: nowrap; 111 | display: block; 112 | } 113 | } 114 | 115 | .rss-action { 116 | white-space: nowrap; 117 | padding: 0 10px; 118 | font-size: 13px; 119 | color: #f5712c; 120 | background: #fff; 121 | border: 1px solid #f5712c; 122 | line-height: 30px; 123 | text-align: center; 124 | transition: 0.3s; 125 | border-radius: 4px; 126 | cursor: pointer; 127 | box-sizing: border-box; 128 | text-decoration: none; 129 | margin-left: 10px; 130 | min-width: 61px; 131 | 132 | &:hover { 133 | color: #fff; 134 | background: #f5712c; 135 | } 136 | 137 | &.rss-copy { 138 | width: 61px; 139 | } 140 | 141 | &.rss-submitto-ttrss { 142 | color: #f28f34; 143 | border: 1px solid #f28f34; 144 | 145 | &:hover { 146 | color: #fff; 147 | background: #f28f34; 148 | } 149 | } 150 | 151 | &.rss-submitto-miniflux { 152 | color: #33995b; 153 | border: 1px solid #33995b; 154 | 155 | &:hover { 156 | color: #fff; 157 | background: #33995b; 158 | } 159 | } 160 | 161 | &.rss-submitto-freshrss { 162 | color: #0062bd; 163 | border: 1px solid #0062db; 164 | 165 | &:hover { 166 | color: #fff; 167 | background: #0062db; 168 | } 169 | } 170 | 171 | &.rss-submitto-nextcloudnews { 172 | color: #0082c9; 173 | border: 1px solid #0082c9; 174 | 175 | &:hover { 176 | color: #fff; 177 | background: #0082c9; 178 | } 179 | } 180 | 181 | &.rss-submitto-feedly { 182 | color: #2bb24c; 183 | border: 1px solid #2bb24c; 184 | 185 | &:hover { 186 | color: #fff; 187 | background: #2bb24c; 188 | } 189 | } 190 | 191 | &.rss-submitto-inoreader { 192 | color: #0099eb; 193 | border: 1px solid #0099eb; 194 | 195 | &:hover { 196 | color: #fff; 197 | background: #0099eb; 198 | } 199 | } 200 | 201 | &.rss-submitto-feedbin { 202 | color: #0867e2; 203 | border: 1px solid #0867e2; 204 | 205 | &:hover { 206 | color: #fff; 207 | background: #0867e2; 208 | } 209 | } 210 | 211 | &.rss-submitto-theoldreader { 212 | color: #ff2300; 213 | border: 1px solid #ff2300; 214 | 215 | &:hover { 216 | color: #fff; 217 | background: #ff2300; 218 | } 219 | } 220 | 221 | &.rss-submitto-feedspub { 222 | color: #61af4b; 223 | border: 1px solid #61af4b; 224 | 225 | &:hover { 226 | color: #fff; 227 | background: #61af4b; 228 | } 229 | } 230 | 231 | &.rss-submitto-bazqux { 232 | color: #00af00; 233 | border: 1px solid #00af00; 234 | 235 | &:hover { 236 | color: #fff; 237 | background: #00af00; 238 | } 239 | } 240 | } 241 | } 242 | 243 | .website-rsshub { 244 | .rss-info { 245 | flex: 1; 246 | margin-right: 10px; 247 | } 248 | 249 | .rss-action { 250 | margin-left: auto; 251 | } 252 | } 253 | -------------------------------------------------------------------------------- /src/js/popup/index.js: -------------------------------------------------------------------------------- 1 | import '../../css/popup.less'; 2 | import ClipboardJS from 'clipboard'; 3 | import { getConfig } from '../common/config'; 4 | import settingIcon from '../../svg/setting.svg'; 5 | import aboutIcon from '../../svg/about.svg'; 6 | import MD5 from 'md5.js'; 7 | let config; 8 | 9 | function generateList(type, list) { 10 | let result = ''; 11 | if (list && list.length) { 12 | list.forEach((item) => { 13 | const replaced_url = item.url.replace('{rsshubDomain}', config.rsshubDomain); 14 | const url = encodeURI( 15 | type !== 'page-rsshub' || !config.rsshubAccessControl.enabled 16 | ? replaced_url 17 | : config.rsshubAccessControl.useCode 18 | ? `${replaced_url}?code=${new MD5().update(item.path + config.rsshubAccessControl.accessKey).digest('hex')}` 19 | : `${replaced_url}?key=${config.rsshubAccessControl.accessKey}` 20 | ); 21 | result += ` 22 |
  • 23 | 24 | 25 |
    ${item.title}
    26 |
    ${url.replace('https://', '').replace('http://', '')}
    27 |
    28 | ${ 29 | item.isDocs 30 | ? `文档` 31 | : `
    复制
    32 | ${ 33 | config.submitto.ttrss && config.submitto.ttrssDomain 34 | ? `订阅到 TTRSS` 35 | : '' 36 | } 37 | ${ 38 | config.submitto.miniflux && config.submitto.minifluxDomain 39 | ? `订阅到 Miniflux` 40 | : '' 41 | } 42 | ${ 43 | config.submitto.freshrss && config.submitto.freshrssDomain 44 | ? `订阅到 FreshRSS` 45 | : '' 46 | } 47 | ${ 48 | config.submitto.nextcloudnews && config.submitto.nextcloudnewsDomain 49 | ? `订阅到 Nextcloud News` 50 | : '' 51 | } 52 | ${config.submitto.feedly ? `订阅到 Feedly` : ''} 53 | ${config.submitto.inoreader ? `订阅到 Inoreader` : ''} 54 | ${config.submitto.feedbin ? `订阅到 Feedbin` : ''} 55 | ${config.submitto.theoldreader ? `订阅到 The Old Reader` : ''} 56 | ${config.submitto.feedspub ? `订阅到 Feeds.Pub` : ''} 57 | ${config.submitto.bazqux ? `订阅到 BazQux Reader` : ''} 58 | ${config.submitto.local ? `订阅到本地阅读器` : ''}` 59 | } 60 |
  • 61 | `; 62 | }); 63 | document.querySelector(`.${type} ul`).innerHTML = result; 64 | document.querySelector(`.${type}`).style.display = 'block'; 65 | document.body.classList.add('something'); 66 | } 67 | } 68 | 69 | document.querySelector('.icons-setting').innerHTML = settingIcon; 70 | document.querySelector('.icons-about').innerHTML = aboutIcon; 71 | 72 | chrome.tabs.query( 73 | { 74 | active: true, 75 | currentWindow: true, 76 | }, 77 | (tabs) => { 78 | const tabId = tabs[0].id; 79 | 80 | getConfig((conf) => { 81 | config = conf; 82 | chrome.runtime.sendMessage( 83 | null, 84 | { 85 | text: 'getAllRSS', 86 | tabId: tabId, 87 | }, 88 | (feeds) => { 89 | generateList('page-rss', feeds.pageRSS); 90 | generateList('page-rsshub', feeds.pageRSSHub); 91 | generateList('website-rsshub', feeds.websiteRSSHub); 92 | 93 | const clipboard = new ClipboardJS('.rss-copy'); 94 | clipboard.on('success', function (e) { 95 | e.trigger.innerHTML = '已复制'; 96 | setTimeout(() => { 97 | e.trigger.innerHTML = '复制'; 98 | }, 1000); 99 | }); 100 | 101 | document.querySelectorAll('.rss-image').forEach((ele) => { 102 | ele.addEventListener('error', function () { 103 | this.setAttribute('src', './rsshub.png'); 104 | }); 105 | }); 106 | 107 | document.querySelectorAll('a').forEach((ele) => { 108 | ele.addEventListener('click', (e) => { 109 | e.preventDefault(); 110 | chrome.tabs.create({ 111 | url: ele.getAttribute('href'), 112 | }); 113 | window.close(); 114 | }); 115 | }); 116 | } 117 | ); 118 | }); 119 | } 120 | ); 121 | -------------------------------------------------------------------------------- /webpack.config.js: -------------------------------------------------------------------------------- 1 | const webpack = require('webpack'); 2 | const path = require('path'); 3 | const MiniCssExtractPlugin = require('mini-css-extract-plugin'); 4 | const CopyPlugin = require('copy-webpack-plugin'); 5 | const VueLoaderPlugin = require('vue-loader/lib/plugin'); 6 | 7 | module.exports = { 8 | 9 | mode: 'production', 10 | 11 | bail: true, 12 | 13 | devtool: false, 14 | 15 | performance: { 16 | maxEntrypointSize: 1000000, 17 | }, 18 | 19 | entry: { 20 | 'popup': './src/js/popup/index.js', 21 | 'content': './src/js/content/index.js', 22 | 'background': './src/js/background/index.js', 23 | 'options': './src/js/options/index.js', 24 | 'sandbox': './src/js/sandbox/index.js', 25 | }, 26 | 27 | output: { 28 | path: path.resolve(__dirname, 'dist'), 29 | filename: '[name].js', 30 | publicPath: '/', 31 | }, 32 | 33 | resolve: { 34 | modules: ['node_modules'], 35 | extensions: ['.js', '.less'], 36 | fallback: { 37 | 'stream': require.resolve('stream-browserify'), 38 | 'buffer': require.resolve('buffer/'), 39 | 'http': require.resolve('stream-http'), 40 | "url": require.resolve("url/"), 41 | "https": require.resolve("https-browserify"), 42 | "timers": require.resolve("timers-browserify"), 43 | } 44 | }, 45 | 46 | module: { 47 | strictExportPresence: true, 48 | rules: [ 49 | { 50 | test: /\.js$/, 51 | enforce: 'pre', 52 | loader: 'eslint-loader', 53 | include: path.resolve(__dirname, '../src/js'), 54 | }, 55 | { 56 | test: /\.js$/, 57 | use: [ 58 | 'template-string-optimize-loader', 59 | { 60 | loader: 'babel-loader', 61 | options: { 62 | cacheDirectory: true, 63 | presets: ['@babel/preset-env'], 64 | plugins: [ 65 | [ 66 | "component", 67 | { 68 | "libraryName": "element-ui", 69 | "styleLibraryName": "theme-chalk" 70 | } 71 | ], 72 | ], 73 | } 74 | } 75 | ] 76 | }, 77 | { 78 | test: /\.css$/, 79 | use: [ 80 | 'vue-style-loader', 81 | { 82 | loader: MiniCssExtractPlugin.loader, 83 | options: { 84 | esModule: false, 85 | }, 86 | }, 87 | { 88 | loader: 'css-loader', 89 | options: { 90 | importLoaders: 2, 91 | }, 92 | }, 93 | { 94 | loader: 'postcss-loader', 95 | options: { 96 | postcssOptions: { 97 | plugins: [ 98 | require('autoprefixer'), 99 | require('cssnano')({ 100 | preset: 'default', 101 | }), 102 | ], 103 | }, 104 | } 105 | }, 106 | ], 107 | }, 108 | { 109 | test: /\.less$/, 110 | use: [ 111 | 'vue-style-loader', 112 | { 113 | loader: MiniCssExtractPlugin.loader, 114 | options: { 115 | esModule: false, 116 | }, 117 | }, 118 | { 119 | loader: 'css-loader', 120 | options: { 121 | importLoaders: 2, 122 | }, 123 | }, 124 | { 125 | loader: 'postcss-loader', 126 | options: { 127 | postcssOptions: { 128 | plugins: [ 129 | require('autoprefixer'), 130 | require('cssnano')({ 131 | preset: 'default', 132 | }), 133 | ], 134 | }, 135 | } 136 | }, 137 | 'less-loader' 138 | ], 139 | }, 140 | { 141 | test: /\.scss$/, 142 | use: [ 143 | 'vue-style-loader', 144 | { 145 | loader: MiniCssExtractPlugin.loader, 146 | options: { 147 | esModule: false, 148 | }, 149 | }, 150 | { 151 | loader: 'css-loader', 152 | options: { 153 | importLoaders: 2, 154 | }, 155 | }, 156 | { 157 | loader: 'postcss-loader', 158 | options: { 159 | postcssOptions: { 160 | plugins: [ 161 | require('autoprefixer'), 162 | require('cssnano')({ 163 | preset: 'default', 164 | }), 165 | ], 166 | }, 167 | } 168 | }, 169 | 'sass-loader' 170 | ], 171 | }, 172 | { 173 | test: /\.vue$/, 174 | loader: 'vue-loader' 175 | }, 176 | { 177 | test: /\.(png|jpg)$/, 178 | loader: 'url-loader', 179 | options: { 180 | 'limit': 40000 181 | } 182 | }, 183 | { 184 | test: /\.svg$/, 185 | loader: 'svg-inline-loader' 186 | }, 187 | { 188 | test: /\.(ttf|woff)$/, 189 | loader: 'file-loader', 190 | options: { 191 | name: '[name].[ext]', 192 | }, 193 | }, 194 | ] 195 | }, 196 | 197 | plugins: [ 198 | new MiniCssExtractPlugin({ 199 | filename: '[name].css' 200 | }), 201 | new CopyPlugin({ 202 | patterns: [ 203 | { 204 | from: 'src/assets', 205 | to: '', 206 | }, 207 | ], 208 | }), 209 | new VueLoaderPlugin(), 210 | new webpack.DefinePlugin({ 211 | VERSION: JSON.stringify(require('./src/assets/manifest.json').version) 212 | }), 213 | ], 214 | }; 215 | -------------------------------------------------------------------------------- /src/js/sandbox/utils.js: -------------------------------------------------------------------------------- 1 | import psl from 'psl'; 2 | import RouteRecognizer from 'route-recognizer'; 3 | 4 | function ruleHandler(rule, params, url, html, success, fail) { 5 | const run = () => { 6 | let reaultWithParams; 7 | if (typeof rule.target === 'function') { 8 | const parser = new DOMParser(); 9 | const document = parser.parseFromString(html, 'text/html'); 10 | try { 11 | reaultWithParams = rule.target(params, url, document); 12 | } catch (error) { 13 | console.warn(error); 14 | reaultWithParams = ''; 15 | } 16 | } else if (typeof rule.target === 'string') { 17 | reaultWithParams = rule.target; 18 | } 19 | 20 | if (reaultWithParams) { 21 | for (const param in params) { 22 | reaultWithParams = reaultWithParams.replace(`/:${param}`, `/${params[param]}`); 23 | } 24 | } 25 | 26 | return reaultWithParams; 27 | }; 28 | const reaultWithParams = run(); 29 | if (reaultWithParams && (!rule.verification || rule.verification(params))) { 30 | success(reaultWithParams); 31 | } else { 32 | fail(); 33 | } 34 | } 35 | 36 | function formatBlank(str1, str2) { 37 | if (str1 && str2) { 38 | return str1 + (str1[str1.length - 1].match(/[a-zA-Z0-9]/) || str2[0].match(/[a-zA-Z0-9]/) ? ' ' : '') + str2; 39 | } else { 40 | return (str1 || '') + (str2 || ''); 41 | } 42 | } 43 | 44 | function parseRules(rules) { 45 | return typeof rules === 'string' ? window['lave'.split('').reverse().join('')](rules) : rules; 46 | } 47 | 48 | export function getPageRSSHub(data) { 49 | const { url, html } = data; 50 | const rules = parseRules(data.rules); 51 | 52 | const parsedDomain = psl.parse(new URL(url).hostname); 53 | if (parsedDomain && parsedDomain.domain) { 54 | const subdomain = parsedDomain.subdomain; 55 | const domain = parsedDomain.domain; 56 | if (rules[domain]) { 57 | let rule = rules[domain][subdomain || '.']; 58 | if (!rule) { 59 | if (subdomain === 'www') { 60 | rule = rules[domain]['.']; 61 | } else if (!subdomain) { 62 | rule = rules[domain].www; 63 | } 64 | } 65 | if (rule) { 66 | const recognized = []; 67 | rule.forEach((ru, index) => { 68 | if (ru.source !== undefined) { 69 | if (Object.prototype.toString.call(ru.source) === '[object Array]') { 70 | ru.source.forEach((source) => { 71 | const router = new RouteRecognizer(); 72 | router.add([ 73 | { 74 | path: source, 75 | handler: index, 76 | }, 77 | ]); 78 | const result = router.recognize(new URL(url).pathname.replace(/\/$/, '')); 79 | if (result && result[0]) { 80 | recognized.push(result[0]); 81 | } 82 | }); 83 | } else if (typeof ru.source === 'string') { 84 | const router = new RouteRecognizer(); 85 | router.add([ 86 | { 87 | path: ru.source, 88 | handler: index, 89 | }, 90 | ]); 91 | const result = router.recognize(new URL(url).pathname.replace(/\/$/, '')); 92 | if (result && result[0]) { 93 | recognized.push(result[0]); 94 | } 95 | } 96 | } 97 | }); 98 | const result = []; 99 | Promise.all( 100 | recognized.map( 101 | (recog) => 102 | new Promise((resolve) => { 103 | ruleHandler( 104 | rule[recog.handler], 105 | recog.params, 106 | url, 107 | html, 108 | (parsed) => { 109 | if (parsed) { 110 | result.push({ 111 | title: formatBlank(rules[domain]._name ? '当前' : '', rule[recog.handler].title), 112 | url: '{rsshubDomain}' + parsed, 113 | path: parsed, 114 | }); 115 | } else { 116 | result.push({ 117 | title: formatBlank(rules[domain]._name ? '当前' : '', rule[recog.handler].title), 118 | url: rule[recog.handler].docs, 119 | isDocs: true, 120 | }); 121 | } 122 | resolve(); 123 | }, 124 | () => { 125 | resolve(); 126 | } 127 | ); 128 | }) 129 | ) 130 | ); 131 | return result; 132 | } else { 133 | return []; 134 | } 135 | } else { 136 | return []; 137 | } 138 | } else { 139 | return []; 140 | } 141 | } 142 | 143 | export function getWebsiteRSSHub(data) { 144 | const { url } = data; 145 | const rules = parseRules(data.rules); 146 | const parsedDomain = psl.parse(new URL(url).hostname); 147 | if (parsedDomain && parsedDomain.domain) { 148 | const domain = parsedDomain.domain; 149 | if (rules[domain]) { 150 | const domainRules = []; 151 | for (const subdomainRules in rules[domain]) { 152 | if (subdomainRules[0] !== '_') { 153 | domainRules.push(...rules[domain][subdomainRules]); 154 | } 155 | } 156 | return domainRules.map((rule) => ({ 157 | title: formatBlank(rules[domain]._name, rule.title), 158 | url: rule.docs, 159 | isDocs: true, 160 | })); 161 | } else { 162 | return []; 163 | } 164 | } else { 165 | return []; 166 | } 167 | } 168 | 169 | export function getList(data) { 170 | const rules = parseRules(data.rules); 171 | for (const rule in rules) { 172 | for (const subrule in rules[rule]) { 173 | if (subrule[0] !== '_') { 174 | rules[rule][subrule].forEach((item) => { 175 | delete item.source; 176 | delete item.target; 177 | delete item.script; 178 | delete item.verification; 179 | }); 180 | } 181 | } 182 | } 183 | return rules; 184 | } 185 | -------------------------------------------------------------------------------- /src/js/options/views/Setting.vue: -------------------------------------------------------------------------------- 1 | 95 | 96 | 162 | 163 | 229 | -------------------------------------------------------------------------------- /src/js/common/radar-rules.js: -------------------------------------------------------------------------------- 1 | export const defaultRules = { 2 | '8world.com': { _name: '8视界', '.': [{ title: '分类', docs: 'https://docs.rsshub.app/new-media.html#_8-shi-jie-fen-lei', source: ['/:category', '/'], target: '/8world/:category?' }] }, 3 | 'aamacau.com': { _name: '論盡媒體 AllAboutMacau Media', '.': [{ title: '话题', docs: 'https://docs.rsshub.app/new-media.html#lun-jin-mei-ti-allaboutmacau-media-hua-ti', source: ['/'], target: '/:category?/:id?' }] }, 4 | 'eprice.com.tw': { _name: 'ePrice', '.': [{ title: 'ePrice 比價王', docs: 'https://docs.rsshub.app/new-media.html#eprice', source: ['/'], target: '/:region?' }] }, 5 | 'eprice.com.hk': { _name: 'ePrice', '.': [{ title: 'ePrice 香港', docs: 'https://docs.rsshub.app/new-media.html#eprice', source: ['/'], target: '/:region?' }] }, 6 | 'furstar.jp': { 7 | _name: 'Furstar', 8 | '.': [ 9 | { title: '最新售卖角色列表', docs: 'https://docs.rsshub.app/shopping.html#furstar-zui-xin-shou-mai-jiao-se-lie-biao', source: ['/:lang', '/'], target: '/furstar/characters/:lang' }, 10 | { title: '已经出售的角色列表', docs: 'https://docs.rsshub.app/shopping.html#furstar-yi-jing-chu-shou-de-jiao-se-lie-biao', source: ['/:lang/archive.php', '/archive.php'], target: '/furstar/archive/:lang' }, 11 | { title: '画师列表', docs: 'https://docs.rsshub.app/shopping.html#furstar-hua-shi-lie-biao', source: ['/'], target: '/furstar/artists' }, 12 | ], 13 | }, 14 | 'https://www.icac.org.hk': { _name: '廉政公署', '.': [{ title: '新闻公布', docs: 'https://docs.rsshub.app/government.html#xiang-gang-lian-zheng-gong-shu', source: ['/:lang/press/index.html'], target: '/icac/news/:lang' }] }, 15 | 'jumpvg.com': { _name: 'jump app', switch: [{ title: '折扣清单', docs: 'https://docs.rsshub.app/game.html#jump', source: ['/'], target: '/jump/discount/switch' }] }, 16 | 'ruancan.com': { 17 | _name: '软餐', 18 | '.': [ 19 | { title: '首页', docs: 'https://docs.rsshub.app/new-media.html#ruan-can-shou-ye', source: ['/'], target: '/ruancan' }, 20 | { title: '分类', docs: 'https://docs.rsshub.app/new-media.html#ruan-can-fen-lei', source: ['/sort/:sort', '/'], target: '/ruancan/sort/:sort' }, 21 | { title: '标签', docs: 'https://docs.rsshub.app/new-media.html#ruan-can-biao-qian', source: ['/tag/:tag', '/'], target: '/ruancan/tag/:tag' }, 22 | ], 23 | }, 24 | 'trow.cc': { _name: 'The Ring of Wonder', '.': [{ title: '首页更新', docs: 'https://docs.rsshub.app/bbs.html#the-ring-of-wonder', source: ['/'], target: '/portal' }] }, 25 | 'bilibili.com': { 26 | _name: 'bilibili', 27 | www: [ 28 | { title: '分区视频', docs: 'https://docs.rsshub.app/social-media.html#bilibili', source: ['/v/*tpath', '/documentary', '/movie', '/tv'] }, 29 | { title: '视频评论', docs: 'https://docs.rsshub.app/social-media.html#bilibili', source: '/video/:aid', target: (params) => `/bilibili/video/reply/${params.aid.replace('av', '')}` }, 30 | { 31 | title: '视频弹幕', 32 | docs: 'https://docs.rsshub.app/social-media.html#bilibili', 33 | source: '/video/:aid', 34 | target: (params, url) => { 35 | const pid = new URL(url).searchParams.get('p'); 36 | return `/bilibili/video/danmaku/${params.aid.replace('av', '')}/${pid ? pid : 1}`; 37 | }, 38 | }, 39 | { title: '番剧', docs: 'https://docs.rsshub.app/social-media.html#bilibili', source: '/bangumi/media/:bid', target: (params) => `/bilibili/bangumi/media/${params.bid.replace('md', '')}` }, 40 | ], 41 | space: [ 42 | { title: 'UP 主动态', docs: 'https://docs.rsshub.app/social-media.html#bilibili', source: '/:uid', target: '/bilibili/user/dynamic/:uid' }, 43 | { title: 'UP 主投稿', docs: 'https://docs.rsshub.app/social-media.html#bilibili', source: '/:uid', target: '/bilibili/user/video/:uid' }, 44 | { title: 'UP 主专栏', docs: 'https://docs.rsshub.app/social-media.html#bilibili', source: '/:uid', target: '/bilibili/user/article/:uid' }, 45 | { title: 'UP 主默认收藏夹', docs: 'https://docs.rsshub.app/social-media.html#bilibili', source: '/:uid', target: '/bilibili/user/fav/:uid' }, 46 | { title: 'UP 主投币视频', docs: 'https://docs.rsshub.app/social-media.html#bilibili', source: '/:uid', target: '/bilibili/user/coin/:uid' }, 47 | { title: 'UP 主粉丝', docs: 'https://docs.rsshub.app/social-media.html#bilibili', source: '/:uid', target: '/bilibili/user/followers/:uid' }, 48 | { title: 'UP 主关注用户', docs: 'https://docs.rsshub.app/social-media.html#bilibili', source: '/:uid', target: '/bilibili/user/followings/:uid' }, 49 | { title: '用户追番列表', docs: 'https://docs.rsshub.app/social-media.html#bilibili', source: '/:uid', target: '/bilibili/user/bangumi/:uid' }, 50 | ], 51 | manga: [{ title: '漫画更新', docs: 'https://docs.rsshub.app/social-media.html#bilibili-man-hua-geng-xin', source: '/detail/:comicid', target: '/bilibili/manga/update/:comicid' }], 52 | }, 53 | 'weibo.com': { 54 | _name: '微博', 55 | '.': [ 56 | { 57 | title: '博主', 58 | docs: 'https://docs.rsshub.app/social-media.html#wei-bo', 59 | source: ['/u/:id', '/:id'], 60 | target: (params, url, document) => { 61 | let uid = document?.documentElement.innerHTML.match(/\$CONFIG\['oid']='(\d+)'/)?.[1]; 62 | if (!uid && !isNaN(params.id)) { 63 | uid = params.id; 64 | } 65 | return uid ? `/weibo/user/${uid}` : ''; 66 | }, 67 | }, 68 | { title: '关键词', docs: 'https://docs.rsshub.app/social-media.html#wei-bo' }, 69 | { title: '超话', docs: 'https://docs.rsshub.app/social-media.html#wei-bo', source: '/p/:id/super_index', target: '/weibo/super_index/:id' }, 70 | ], 71 | s: [{ title: '热搜榜', docs: 'https://docs.rsshub.app/social-media.html#wei-bo', source: '/top/summary', target: '/weibo/search/hot' }], 72 | }, 73 | 'weibo.cn': { _name: '微博', m: [{ title: '博主', docs: 'https://docs.rsshub.app/social-media.html#wei-bo', source: ['/u/:uid', '/profile/:uid'], target: '/weibo/user/:uid' }] }, 74 | 'pixiv.net': { 75 | _name: 'Pixiv', 76 | www: [ 77 | { title: '用户收藏', docs: 'https://docs.rsshub.app/social-media.html#pixiv', source: '/users/:id/bookmarks/artworks', target: '/pixiv/user/bookmarks/:id' }, 78 | { title: '用户动态', docs: 'https://docs.rsshub.app/social-media.html#pixiv', source: '/users/:id', target: '/pixiv/user/:id' }, 79 | { title: '排行榜', docs: 'https://docs.rsshub.app/social-media.html#pixiv', source: '/ranking.php', target: (params, url) => `/pixiv/ranking/${new URL(url).searchParams.get('mode') || 'daily'}` }, 80 | { 81 | title: '关键词', 82 | docs: 'https://docs.rsshub.app/social-media.html#pixiv', 83 | source: ['/tags/:keyword', '/tags/:keyword/:type?'], 84 | target: (params, url) => `/pixiv/search/:keyword/${new URL(url).searchParams.get('order')}/${new URL(url).searchParams.get('mode')}`, 85 | }, 86 | { title: '关注的新作品', docs: 'https://docs.rsshub.app/social-media.html#pixiv', source: '/bookmark_new_illust.php', target: '/pixiv/user/illustfollows' }, 87 | ], 88 | }, 89 | 'twitter.com': { 90 | _name: 'Twitter', 91 | '.': [ 92 | { 93 | title: '用户时间线', 94 | docs: 'https://docs.rsshub.app/social-media.html#twitter', 95 | source: '/:id', 96 | target: (params) => { 97 | if (params.id !== 'home' && params.id !== 'explore' && params.id !== 'notifications' && params.id !== 'messages' && params.id !== 'explore' && params.id !== 'search') { 98 | return '/twitter/user/:id'; 99 | } 100 | }, 101 | }, 102 | { 103 | title: '用户关注时间线', 104 | docs: 'https://docs.rsshub.app/social-media.html#twitter', 105 | source: '/:id', 106 | target: (params) => { 107 | if (params.id !== 'home' && params.id !== 'explore' && params.id !== 'notifications' && params.id !== 'messages' && params.id !== 'explore' && params.id !== 'search') { 108 | return '/twitter/followings/:id'; 109 | } 110 | }, 111 | }, 112 | { 113 | title: '用户喜欢列表', 114 | docs: 'https://docs.rsshub.app/social-media.html#twitter', 115 | source: '/:id', 116 | target: (params) => { 117 | if (params.id !== 'home' && params.id !== 'explore' && params.id !== 'notifications' && params.id !== 'messages' && params.id !== 'explore' && params.id !== 'search') { 118 | return '/twitter/likes/:id'; 119 | } 120 | }, 121 | }, 122 | { 123 | title: '列表时间线', 124 | docs: 'https://docs.rsshub.app/social-media.html#twitter', 125 | source: '/:id/lists/:name', 126 | target: (params) => { 127 | if (params.id !== 'home' && params.id !== 'explore' && params.id !== 'notifications' && params.id !== 'messages' && params.id !== 'explore' && params.id !== 'search') { 128 | return '/twitter/list/:id/:name'; 129 | } 130 | }, 131 | }, 132 | { title: '关键词', docs: 'https://docs.rsshub.app/social-media.html#twitter', source: '/search', target: (params, url) => `/twitter/keyword/${new URL(url).searchParams.get('q')}` }, 133 | ], 134 | }, 135 | 'youtube.com': { 136 | _name: 'YouTube', 137 | www: [ 138 | { title: '用户', docs: 'https://docs.rsshub.app/social-media.html#youtube', source: '/user/:username', target: '/youtube/user/:username' }, 139 | { title: '频道', docs: 'https://docs.rsshub.app/social-media.html#youtube', source: '/channel/:id', target: '/youtube/channel/:id' }, 140 | { title: '播放列表', docs: 'https://docs.rsshub.app/social-media.html#youtube', source: '/playlist', target: (params, url) => `/youtube/playlist/${new URL(url).searchParams.get('list')}` }, 141 | ], 142 | }, 143 | 'github.com': { 144 | _name: 'GitHub', 145 | '.': [ 146 | { title: '用户仓库', docs: 'https://docs.rsshub.app/programming.html#github', source: '/:user', target: '/github/repos/:user' }, 147 | { title: '用户 Followers', docs: 'https://docs.rsshub.app/programming.html#github', source: '/:user', target: '/github/user/followers/:user' }, 148 | { title: 'Trending', docs: 'https://docs.rsshub.app/programming.html#github', source: '/trending', target: '/github/trending/:since' }, 149 | { title: 'Trending', docs: 'https://docs.rsshub.app/programming.html#github', source: '/topics', target: '/github/topics/:name/:qs?' }, 150 | { title: '仓库 Issue', docs: 'https://docs.rsshub.app/programming.html#github', source: ['/:user/:repo/issues', '/:user/:repo/issues/:id', '/:user/:repo'], target: '/github/issue/:user/:repo' }, 151 | { title: '仓库 Pull Requests', docs: 'https://docs.rsshub.app/programming.html#github', source: ['/:user/:repo/pulls', '/:user/:repo/pulls/:id', '/:user/:repo'], target: '/github/pull/:user/:repo' }, 152 | { title: '仓库 Stars', docs: 'https://docs.rsshub.app/programming.html#github', source: ['/:user/:repo/stargazers', '/:user/:repo'], target: '/github/stars/:user/:repo' }, 153 | { title: '仓库 Branches', docs: 'https://docs.rsshub.app/programming.html#github', source: ['/:user/:repo/branches', '/:user/:repo'], target: '/github/branches/:user/:repo' }, 154 | { title: '文件 Commits', docs: 'https://docs.rsshub.app/programming.html#github', source: '/:user/:repo/blob/:branch/*filepath', target: '/github/file/:user/:repo/:branch/:filepath' }, 155 | { title: '用户 Starred Repositories', docs: 'https://docs.rsshub.app/programming.html#github', source: '/:user', target: '/github/starred_repos/:user' }, 156 | { title: '仓库 Contributors', docs: 'https://docs.rsshub.app/programming.html#github', source: ['/:user/:repo/graphs/contributors', '/:user/:repo'], target: '/github/contributors/:user/:repo' }, 157 | ], 158 | }, 159 | 'zhihu.com': { 160 | _name: '知乎', 161 | www: [ 162 | { title: '收藏夹', docs: 'https://docs.rsshub.app/social-media.html#zhi-hu', source: '/collection/:id', target: '/zhihu/collection/:id' }, 163 | { title: '用户动态', docs: 'https://docs.rsshub.app/social-media.html#zhi-hu', source: '/people/:id', target: '/zhihu/people/activities/:id' }, 164 | { title: '用户回答', docs: 'https://docs.rsshub.app/social-media.html#zhi-hu', source: '/people/:id/answers', target: '/zhihu/people/answers/:id' }, 165 | { title: '用户想法', docs: 'https://docs.rsshub.app/social-media.html#zhi-hu', source: '/people/:id/pins', target: '/zhihu/people/pins/:id' }, 166 | { title: '用户文章', docs: 'https://docs.rsshub.app/social-media.html#zhi-hu', source: '/:usertype/:id/posts', target: '/zhihu/posts/:usertype/:id' }, 167 | { title: '热榜', docs: 'https://docs.rsshub.app/social-media.html#zhi-hu', source: '/hot', target: '/zhihu/hotlist' }, 168 | { title: '想法热榜', docs: 'https://docs.rsshub.app/social-media.html#zhi-hu', target: '/zhihu/pin/hotlist' }, 169 | { title: '问题', docs: 'https://docs.rsshub.app/social-media.html#zhi-hu', source: '/question/:questionId', target: '/zhihu/question/:questionId' }, 170 | { title: '话题', docs: 'https://docs.rsshub.app/social-media.html#zhi-hu', source: '/topic/:topicId/:type', target: '/zhihu/topic/:topicId' }, 171 | { title: '新书', docs: 'https://docs.rsshub.app/social-media.html#zhi-hu', source: '/zhihu/bookstore/newest', target: '/zhihu/pin/hotlist' }, 172 | { title: '想法-24 小时新闻汇总', docs: 'https://docs.rsshub.app/social-media.html#zhi-hu', source: '/pin/special/972884951192113152', target: '/zhihu/pin/daily' }, 173 | { title: '书店-周刊', docs: 'https://docs.rsshub.app/social-media.html#zhi-hu', source: '/pub/weekly', target: '/zhihu/weekly' }, 174 | { title: '专栏', docs: 'https://docs.rsshub.app/social-media.html#zhi-hu', source: '/column/:id', target: '/zhihu/zhuanlan/:id' }, 175 | ], 176 | zhuanlan: [{ title: '专栏', docs: 'https://docs.rsshub.app/social-media.html#zhi-hu', source: '/:id', target: '/zhihu/zhuanlan/:id' }], 177 | daily: [ 178 | { title: '日报', docs: 'https://docs.rsshub.app/social-media.html#zhi-hu', source: '', target: '/zhihu/daily' }, 179 | { title: '日报', docs: 'https://docs.rsshub.app/social-media.html#zhi-hu', source: '/*tpath', target: '/zhihu/daily' }, 180 | ], 181 | }, 182 | 'smzdm.com': { 183 | _name: '什么值得买', 184 | www: [{ title: '排行榜', docs: 'https://docs.rsshub.app/shopping.html#shen-me-zhi-de-mai', source: '/top' }], 185 | search: [{ title: '关键词', docs: 'https://docs.rsshub.app/shopping.html#shen-me-zhi-de-mai', source: '/', target: (params, url) => `/smzdm/keyword/${new URL(url).searchParams.get('s')}` }], 186 | }, 187 | 'rsshub.app': { 188 | _name: 'RSSHub', 189 | docs: [ 190 | { title: '有新路由啦', docs: 'https://docs.rsshub.app/program-update.html#rsshub', source: ['', '/*tpath'], target: '/rsshub/routes' }, 191 | { title: '有新赞助商啦', docs: 'https://docs.rsshub.app/program-update.html#rsshub', source: ['', '/*tpath'], target: '/rsshub/sponsors' }, 192 | ], 193 | }, 194 | 'ximalaya.com': { 195 | _name: '喜马拉雅', 196 | '.': [ 197 | { 198 | title: '专辑', 199 | docs: 'https://docs.rsshub.app/multimedia.html#xi-ma-la-ya', 200 | source: '/:type/:id', 201 | target: (params) => { 202 | if (parseInt(params.id) + '' === params.id) { 203 | return '/ximalaya/album/:id/'; 204 | } 205 | }, 206 | }, 207 | ], 208 | }, 209 | 'algocasts.io': { _name: 'AlgoCasts', '.': [{ title: '视频更新', docs: 'https://docs.rsshub.app/programming.html#algocasts', source: '/episodes', target: '/algocasts' }] }, 210 | 'soulapp.cn': { _name: 'Soul', '.': [{ title: '瞬间更新', docs: 'https://docs.rsshub.app/social-media.html#soul' }] }, 211 | 'juejin.cn': { 212 | _name: '掘金', 213 | '.': [ 214 | { title: '标签', docs: 'https://docs.rsshub.app/programming.html#jue-jin-biao-qian', source: '/tag/:tag', target: '/juejin/tag/:tag' }, 215 | { title: '小册', docs: 'https://docs.rsshub.app/programming.html#jue-jin-xiao-ce', source: '/books', target: '/juejin/books' }, 216 | { 217 | title: '沸点', 218 | docs: 'https://docs.rsshub.app/programming.html#jue-jin-fei-dian', 219 | source: ['/pins/:type', '/pins/topic/:type'], 220 | target: (params) => (params.type !== 'recommended' ? '/juejin/pins/:type' : '/juejin/pins'), 221 | }, 222 | { title: '专栏', docs: 'https://docs.rsshub.app/programming.html#jue-jin-zhuan-lan', source: ['/user/:id', '/user/:id/posts'], target: '/juejin/posts/:id' }, 223 | { title: '收藏集', docs: 'https://docs.rsshub.app/programming.html#jue-jin-shou-cang-ji', source: ['/user/:id', '/user/:id/collections'], target: '/juejin/collections/:id' }, 224 | { title: '单个收藏夹', docs: 'https://docs.rsshub.app/programming.html#jue-jin-dan-ge-shou-cang-jia', source: '/collection/:collectionId', target: '/juejin/collection/:collectionId' }, 225 | ], 226 | }, 227 | 'anime1.me': { 228 | _name: 'Anime1', 229 | '.': [ 230 | { title: '動畫', docs: 'https://docs.rsshub.app/anime.html#anime1', source: '/category/:time/:name', target: '/anime1/anime/:time/:name' }, 231 | { 232 | title: '搜尋', 233 | docs: 'https://docs.rsshub.app/anime.html#anime1', 234 | source: '/', 235 | target: (params, url) => { 236 | const keyword = new URL(url).searchParams.get('s'); 237 | return keyword ? `/anime1/search/${keyword}` : ''; 238 | }, 239 | }, 240 | ], 241 | }, 242 | 'swufe.edu.cn': { 243 | _name: '西南财经大学', 244 | it: [ 245 | { title: '经济信息工程学院 - 通知公告', docs: 'https://docs.rsshub.app/university.html#xi-nan-cai-jing-da-xue', source: '/index/tzgg.htm', target: '/swufe/seie/tzgg' }, 246 | { title: '经济信息工程学院 - 学院新闻', docs: 'https://docs.rsshub.app/university.html#xi-nan-cai-jing-da-xue', source: '/index/xyxw.htm', target: '/swufe/seie/xyxw' }, 247 | ], 248 | }, 249 | 'ishuhui.com': { _name: '鼠绘漫画', www: [{ title: '鼠绘漫画', docs: 'https://docs.rsshub.app/anime.html#shu-hui-man-hua', source: '/comics/anime/:id', target: '/shuhui/comics/:id' }] }, 250 | 'www.chicagotribune.com': { _name: 'Chicago Tribune', www: [{ title: 'Chicago Tribune', docs: 'https://docs.rsshub.app/traditional_media.html#chicago-tribune', source: '/' }] }, 251 | 'haimaoba.com': { _name: '海猫吧', www: [{ title: '漫画更新', docs: 'https://docs.rsshub.app/anime.html#hai-mao-ba', source: '/catalog/:id', target: '/haimaoba/:id' }] }, 252 | 'manhuagui.com': { _name: '漫画柜', www: [{ title: '漫画更新', docs: 'https://docs.rsshub.app/anime.html#kan-man-hua', source: '/comic/:id/', target: '/manhuagui/comic/:id' }] }, 253 | 'mhgui.com': { _name: '漫画柜镜像站', www: [{ title: '漫画更新', docs: 'https://docs.rsshub.app/anime.html#kan-man-hua-jing-xiang-zhan', source: '/comic/:id/', target: '/mhgui/comic/:id' }] }, 254 | 'tw.manhuagui.com': { _name: '漫画柜台湾', www: [{ title: '漫画更新', docs: 'https://docs.rsshub.app/anime.html#kan-man-hua-tai-wan', source: '/comic/:id/', target: '/twmanhuagui/comic/:id' }] }, 255 | 'pgyer.com': { _name: '蒲公英应用分发', www: [{ title: 'app更新', docs: 'https://docs.rsshub.app/program-update.html#pu-gong-ying-ying-yong-fen-fa', source: '/:app', target: '/pgyer/:app' }] }, 256 | 'pianyuan.la': { _name: '片源网', '.': [{ title: '电影和剧集', docs: 'https://docs.rsshub.app/multimedia.html#pian-yuan', source: '/' }] }, 257 | 'sspai.com': { 258 | _name: '少数派', 259 | '.': [ 260 | { title: '最新上架付费专栏', docs: 'https://docs.rsshub.app/new-media.html#shao-shu-pai-sspai', source: '/series', target: '/sspai/series' }, 261 | { title: 'Matrix', docs: 'https://docs.rsshub.app/new-media.html#shao-shu-pai-sspai', source: '/matrix', target: '/sspai/matrix' }, 262 | { title: '专栏', docs: 'https://docs.rsshub.app/new-media.html#shao-shu-pai-sspai', source: '/column/:id', target: '/sspai/column/:id' }, 263 | { title: '作者动态', docs: 'https://docs.rsshub.app/new-media.html#shao-shu-pai-sspai', source: '/u/:id/updates', target: '/sspai/activity/:id' }, 264 | { title: '作者已发布文章', docs: 'https://docs.rsshub.app/new-media.html#shao-shu-pai-sspai', source: '/u/:id/posts', target: '/sspai/author/:id' }, 265 | { title: '专题', docs: 'https://docs.rsshub.app/new-media.html#shao-shu-pai-sspai', source: '/topics', target: '/sspai/topics' }, 266 | { title: '专题内文章更新', docs: 'https://docs.rsshub.app/new-media.html#shao-shu-pai-sspai', source: '/topic/:id', target: '/sspai/topic/:id' }, 267 | { title: '标签订阅', docs: 'https://docs.rsshub.app/new-media.html#shao-shu-pai-sspai', source: '/tag/:keyword', target: '/sspai/tag/:keyword' }, 268 | ], 269 | shortcuts: [{ title: 'Shortcuts Gallery', docs: 'https://docs.rsshub.app/new-media.html#shao-shu-pai-sspai', source: ['', '/*tpath'], target: '/sspai/shortcuts' }], 270 | }, 271 | 'baidu.com': { 272 | _name: '贴吧', 273 | tieba: [ 274 | { 275 | title: '帖子列表', 276 | docs: 'https://docs.rsshub.app/bbs.html#tie-ba', 277 | source: 'f', 278 | target: (params, url) => { 279 | const type = new URL(url).searchParams.get('tab'); 280 | if (!type || type === 'main') { 281 | return `/tieba/forum/${new URL(url).searchParams.get('kw')}`; 282 | } 283 | }, 284 | }, 285 | { 286 | title: '精品帖子', 287 | docs: 'https://docs.rsshub.app/bbs.html#tie-ba', 288 | source: 'f', 289 | target: (params, url) => { 290 | const type = new URL(url).searchParams.get('tab'); 291 | if (type === 'good') { 292 | return `/tieba/forum/good/${new URL(url).searchParams.get('kw')}`; 293 | } 294 | }, 295 | }, 296 | { title: '帖子动态', docs: 'https://docs.rsshub.app/bbs.html#tie-ba', source: '/p/:id', target: '/tieba/post/:id' }, 297 | { title: '只看楼主', docs: 'https://docs.rsshub.app/bbs.html#tie-ba', source: '/p/:id', target: '/tieba/post/lz/:id' }, 298 | { 299 | title: '用户帖子', 300 | docs: 'https://docs.rsshub.app/bbs.html#tie-ba', 301 | source: '/home/main', 302 | target: (params, url) => { 303 | const uid = new URL(url).searchParams.get('un'); 304 | if (uid) { 305 | return `/tieba/user/${uid}`; 306 | } 307 | }, 308 | }, 309 | ], 310 | }, 311 | 'wineyun.com': { _name: '酒云网', www: [{ title: '最新商品', docs: 'https://docs.rsshub.app/other.html#jiu-yun-wang', source: ['/:category'], target: '/wineyun/:category' }] }, 312 | 'epicgames.com': { _name: 'Epic Games', www: [{ title: '每周免费游戏', docs: 'https://docs.rsshub.app/game.html#epicgames-freegame', source: '/store/zh-CN/free-games', target: '/epicgames/freegames' }] }, 313 | 'docker.com': { 314 | _name: 'Docker', 315 | hub: [ 316 | { 317 | title: '镜像有新 Build', 318 | docs: 'https://docs.rsshub.app/program-update.html#docker-hub', 319 | source: ['/r/:owner/:image', '/r/:owner/:image/tags', '/_/:image'], 320 | target: (params) => `/dockerhub/build/${params.owner ? params.owner : 'library'}/${params.image}`, 321 | }, 322 | ], 323 | }, 324 | 'nga.cn': { 325 | _name: 'NGA', 326 | bbs: [ 327 | { title: '分区帖子', docs: 'https://docs.rsshub.app/bbs.html#nga', source: '/thread.php', target: (params, url) => new URL(url).searchParams.get('fid') && `/nga/forum/${new URL(url).searchParams.get('fid')}` }, 328 | { title: '帖子', docs: 'https://docs.rsshub.app/bbs.html#nga', source: '/read.php', target: (params, url) => new URL(url).searchParams.get('tid') && `/nga/post/${new URL(url).searchParams.get('tid')}` }, 329 | ], 330 | }, 331 | 'playstation.com': { 332 | _name: 'PlayStation', 333 | store: [ 334 | { title: '游戏列表', docs: 'https://docs.rsshub.app/game.html#playstation', source: '/zh-hans-hk/grid/:id/:page', target: '/ps/list/:id' }, 335 | { title: '折扣|价格', docs: 'https://docs.rsshub.app/game.html#playstation', source: ['/:lang/product/:gridName'], target: '/ps/:lang/product/:gridName' }, 336 | ], 337 | www: [ 338 | { title: '用户奖杯', docs: 'https://docs.rsshub.app/game.html#playstation' }, 339 | { title: '系统更新纪录', docs: 'https://docs.rsshub.app/game.html#playstation' }, 340 | ], 341 | }, 342 | 'monsterhunter.com': { 343 | _name: '怪物猎人世界', 344 | www: [ 345 | { title: '更新情报', docs: 'https://docs.rsshub.app/game.html#guai-wu-lie-ren-shi-jie', source: ['', '/*tpath'], target: '/mhw/update' }, 346 | { title: '最新消息', docs: 'https://docs.rsshub.app/game.html#guai-wu-lie-ren-shi-jie', source: ['', '/*tpath'], target: '/mhw/news' }, 347 | ], 348 | }, 349 | 'vgtime.com': { 350 | _name: '游戏时光', 351 | www: [ 352 | { title: '新闻', docs: 'https://docs.rsshub.app/game.html#you-xi-shi-guang', source: '/topic/index.jhtml', target: '/vgtime/news' }, 353 | { title: '游戏发售表', docs: 'https://docs.rsshub.app/game.html#you-xi-shi-guang', source: '/game/release.jhtml', target: '/vgtime/release' }, 354 | { title: '关键词资讯', docs: 'https://docs.rsshub.app/game.html#you-xi-shi-guang', source: '/search/list.jhtml', target: (params, url) => `/vgtime/keyword/${new URL(url).searchParams.get('keyword')}` }, 355 | ], 356 | }, 357 | 'bing.com': { _name: 'Bing', www: [{ title: '每日壁纸', docs: 'https://docs.rsshub.app/picture.html#bing-bi-zhi', source: '', target: '/bing' }] }, 358 | 'dcard.tw': { 359 | _name: 'Dcard', 360 | www: [ 361 | { title: '首頁帖子-最新', docs: 'https://docs.rsshub.app/bbs.html#dcard', source: '/f', target: '/dcard/posts/latest' }, 362 | { title: '首頁帖子-熱門', docs: 'https://docs.rsshub.app/bbs.html#dcard', source: '/f', target: '/dcard/posts/popular' }, 363 | { title: '板塊帖子-最新', docs: 'https://docs.rsshub.app/bbs.html#dcard', source: '/f/:section', target: '/dcard/:section/latest' }, 364 | { title: '板塊帖子-熱門', docs: 'https://docs.rsshub.app/bbs.html#dcard', source: '/f/:section', target: '/dcard/:section/popular' }, 365 | ], 366 | }, 367 | 'wegene.com': { 368 | _name: 'WeGene', 369 | www: [ 370 | { title: '最近更新', docs: 'https://docs.rsshub.app/other.html#wegene', source: '', target: '/wegene/newest' }, 371 | { title: '栏目', docs: 'https://docs.rsshub.app/other.html#wegene', source: '/crowdsourcing', target: '/wegene/column/all/all' }, 372 | ], 373 | }, 374 | 'qdaily.com': { 375 | _name: '好奇心日报', 376 | www: [ 377 | { title: '标签', docs: 'https://docs.rsshub.app/new-media.html#hao-qi-xin-ri-bao', source: '/tags/:idd', target: (params) => `/qdaily/tag/${params.idd.replace('.html', '')}` }, 378 | { title: '栏目', docs: 'https://docs.rsshub.app/new-media.html#hao-qi-xin-ri-bao', source: '/special_columns/:idd', target: (params) => `/qdaily/column/${params.idd.replace('.html', '')}` }, 379 | { title: '分类', docs: 'https://docs.rsshub.app/new-media.html#hao-qi-xin-ri-bao', source: '/categories/:idd', target: (params) => `/qdaily/category/${params.idd.replace('.html', '')}` }, 380 | ], 381 | }, 382 | '3ycy.com': { _name: '三界异次元', www: [{ title: '最近更新', docs: 'https://docs.rsshub.app/anime.html#san-jie-yi-ci-yuan', source: '/', target: '/3ycy/home' }] }, 383 | 'emi-nitta.net': { 384 | _name: 'Emi Nitta', 385 | '.': [ 386 | { title: '最近更新', docs: 'https://docs.rsshub.app/other.html#xin-tian-hui-hai-guan-fang-wang-zhan', source: '/updates', target: '/emi-nitta/updates' }, 387 | { title: '新闻', docs: 'https://docs.rsshub.app/other.html#xin-tian-hui-hai-guan-fang-wang-zhan', source: '/contents/news', target: '/emi-nitta/news' }, 388 | ], 389 | }, 390 | 'alter-shanghai.cn': { _name: 'Alter', '.': [{ title: '新闻', docs: 'https://docs.rsshub.app/shopping.html#alter-zhong-guo', source: '/cn/news.html', target: '/alter-cn/news' }] }, 391 | 'itslide.com': { _name: 'ITSlide', www: [{ title: '最新', docs: 'https://docs.rsshub.app/programming.html#itslide', source: '/*', target: '/itslide/new' }] }, 392 | 'leboncoin.fr': { _name: 'leboncoin', www: [{ title: 'ads', docs: 'https://docs.rsshub.app/en/shopping.html#leboncoin', source: '/recherche', target: (params, url) => '/leboncoin/ad/' + url.split('?')[1] }] }, 393 | 'yuancheng.work': { 394 | _name: '远程.work', 395 | '.': [ 396 | { 397 | title: '招聘信息', 398 | docs: 'https://docs.rsshub.app/other.html#yuan-cheng-work', 399 | source: '/:caty', 400 | target: (params, url) => { 401 | if (!url) { 402 | return '/remote-work'; 403 | } 404 | return '/remote-work/' + /\w+-(\w+)-\w+/.exec(url)[1]; 405 | }, 406 | }, 407 | ], 408 | }, 409 | 'chinatimes.com': { _name: '中時電子報', www: [{ title: '新聞', docs: 'https://docs.rsshub.app/traditional-media.html#zhong-shi-dian-zi-bao', source: '/:caty', target: (params) => '/chinatimes/' + params.caty }] }, 410 | 'ithome.com': { 411 | _name: 'IT 之家', 412 | '.': [ 413 | { title: '24 小时阅读榜', docs: 'https://docs.rsshub.app/new-media.html#it-zhi-jia', source: ['', '/*'], target: '/ithome/ranking/24h' }, 414 | { title: '7 天最热', docs: 'https://docs.rsshub.app/new-media.html#it-zhi-jia', source: ['', '/*'], target: '/ithome/ranking/7days' }, 415 | { title: '月榜', docs: 'https://docs.rsshub.app/new-media.html#it-zhi-jia', source: ['', '/*'], target: '/ithome/ranking/monthly' }, 416 | ], 417 | it: [{ title: 'IT 资讯', docs: 'https://docs.rsshub.app/new-media.html#it-zhi-jia', source: '/', target: '/ithome/it' }], 418 | soft: [{ title: '软件之家', docs: 'https://docs.rsshub.app/new-media.html#it-zhi-jia', source: '/', target: '/ithome/soft' }], 419 | win10: [{ title: 'win10 之家', docs: 'https://docs.rsshub.app/new-media.html#it-zhi-jia', source: '/', target: '/ithome/win10' }], 420 | iphone: [{ title: 'iphone 之家', docs: 'https://docs.rsshub.app/new-media.html#it-zhi-jia', source: '/', target: '/ithome/iphone' }], 421 | ipad: [{ title: 'ipad 之家', docs: 'https://docs.rsshub.app/new-media.html#it-zhi-jia', source: '/', target: '/ithome/ipad' }], 422 | android: [{ title: 'android 之家', docs: 'https://docs.rsshub.app/new-media.html#it-zhi-jia', source: '/', target: '/ithome/android' }], 423 | digi: [{ title: '数码之家', docs: 'https://docs.rsshub.app/new-media.html#it-zhi-jia', source: '/', target: '/ithome/digi' }], 424 | next: [{ title: '智能时代', docs: 'https://docs.rsshub.app/new-media.html#it-zhi-jia', source: '/', target: '/ithome/next' }], 425 | }, 426 | 'govopendata.com': { _name: '新闻联播文字版', cn: [{ title: '新闻联播文字版', docs: 'https://docs.rsshub.app/traditional-media.html#xin-wen-lian-bo-wen-zi-ban', source: '/xinwenlianbo', target: '/xinwenlianbo/index' }] }, 427 | 'steampowered.com': { _name: 'Steam', store: [{ title: 'search', docs: 'https://docs.rsshub.app/game.html#steam', source: '/search/', target: (params, url) => `/steam/search/${new URL(url).searchParams}` }] }, 428 | 'baijingapp.com': { _name: '白鲸出海', www: [{ title: '文章', docs: 'https://docs.rsshub.app/new-media.html#bai-jing-chu-hai', source: '', target: '/baijing' }] }, 429 | 'xiaomi.cn': { _name: '小米社区', www: [{ title: '圈子', docs: 'https://docs.rsshub.app/bbs.html#xiao-mi-she-qu', source: '/board/:boardId', target: '/mi/bbs/board/:boardId' }] }, 430 | '163.com': { 431 | _name: '网易', 432 | ds: [{ title: '大神', docs: 'https://docs.rsshub.app/game.html#wang-yi-da-shen', source: '/user/:id', target: '/netease/ds/:id' }], 433 | open: [ 434 | { title: '公开课 - 精品课程', docs: 'https://docs.rsshub.app/study.html#wang-yi-gong-kai-ke', source: '/', target: '/open163/vip' }, 435 | { title: '公开课 - 最新课程', docs: 'https://docs.rsshub.app/study.html#wang-yi-gong-kai-ke', source: '/', target: '/open163/latest' }, 436 | ], 437 | music: [ 438 | { 439 | title: '云音乐 - 用户歌单', 440 | docs: 'https://docs.rsshub.app/multimedia.html#wang-yi-yun-yin-yue', 441 | source: '/', 442 | target: (params, url) => { 443 | const id = new URL(url).hash.match(/home\?id=(.*)/)[1]; 444 | return id ? `/ncm/user/playlist/${id}` : ''; 445 | }, 446 | }, 447 | { 448 | title: '云音乐 - 歌单歌曲', 449 | docs: 'https://docs.rsshub.app/multimedia.html#wang-yi-yun-yin-yue', 450 | source: '/', 451 | target: (params, url) => { 452 | const id = new URL(url).hash.match(/playlist\?id=(.*)/)[1]; 453 | return id ? `/ncm/playlist/${id}` : ''; 454 | }, 455 | }, 456 | { 457 | title: '云音乐 - 歌手专辑', 458 | docs: 'https://docs.rsshub.app/multimedia.html#wang-yi-yun-yin-yue', 459 | source: '/', 460 | target: (params, url) => { 461 | const id = new URL(url).hash.match(/album\?id=(.*)/)[1]; 462 | return id ? `/ncm/artist/${id}` : ''; 463 | }, 464 | }, 465 | { 466 | title: '云音乐 - 电台节目', 467 | docs: 'https://docs.rsshub.app/multimedia.html#wang-yi-yun-yin-yue', 468 | source: '/', 469 | target: (params, url) => { 470 | const id = new URL(url).hash.match(/djradio\?id=(.*)/)[1]; 471 | return id ? `/ncm/djradio/${id}` : ''; 472 | }, 473 | }, 474 | ], 475 | 'y.music': [ 476 | { title: '云音乐 - 用户歌单', docs: 'https://docs.rsshub.app/multimedia.html#wang-yi-yun-yin-yue', source: '/m/user', target: (params, url) => `/ncm/playlist/${new URL(url).searchParams.get('id')}` }, 477 | { title: '云音乐 - 歌单歌曲', docs: 'https://docs.rsshub.app/multimedia.html#wang-yi-yun-yin-yue', source: '/m/playlist', target: (params, url) => `/ncm/playlist/${new URL(url).searchParams.get('id')}` }, 478 | { title: '云音乐 - 歌手专辑', docs: 'https://docs.rsshub.app/multimedia.html#wang-yi-yun-yin-yue', source: '/m/album', target: (params, url) => `/ncm/playlist/${new URL(url).searchParams.get('id')}` }, 479 | { title: '云音乐 - 播单声音', docs: 'https://docs.rsshub.app/multimedia.html#wang-yi-yun-yin-yue', source: ['/m/radio', '/m/djradio'], target: (params, url) => `/ncm/playlist/${new URL(url).searchParams.get('id')}` }, 480 | ], 481 | }, 482 | 'suzhou.gov.cn': { _name: '苏州市政府', www: [{ title: '政府新闻', docs: 'https://docs.rsshub.app/government.html#su-zhou-shi-ren-min-zheng-fu', source: '/szsrmzf/:uid/nav_list.shtml', target: '/gov/suzhou/news/:uid' }] }, 483 | 'mqube.net': { 484 | _name: 'MQube', 485 | www: [ 486 | { title: '全站最近更新', docs: 'https://docs.rsshub.app/multimedia.html#mqube', source: '/', target: '/mqube/latest' }, 487 | { title: '全站每日排行', docs: 'https://docs.rsshub.app/multimedia.html#mqube', source: '/', target: '/mqube/top' }, 488 | { title: '个人最近更新', docs: 'https://docs.rsshub.app/multimedia.html#mqube', source: '/user/:user', target: '/mqube/user/:user' }, 489 | { title: '标签最近更新', docs: 'https://docs.rsshub.app/multimedia.html#mqube', source: '/search/tag/:tag', target: '/mqube/tag/:tag' }, 490 | ], 491 | }, 492 | 'nikkei.com': { _name: '日本経済新聞', www: [{ title: 'ホームページ', docs: 'https://docs.rsshub.app/traditional-media.html#ri-ben-jing-ji-xin-wen', source: '/', target: '/nikkei/index' }] }, 493 | 'last.fm': { 494 | _name: 'Last.fm', 495 | www: [ 496 | { title: '用户播放记录', docs: 'https://docs.rsshub.app/multimedia.html#last-fm', source: ['/user/:user', '/user/:user/*'], target: '/lastfm/recent/:user' }, 497 | { title: '用户 Love 记录', docs: 'https://docs.rsshub.app/multimedia.html#last-fm', source: ['/user/:user', '/user/:user/*'], target: '/lastfm/loved/:user' }, 498 | { title: '站内 Top 榜单', docs: 'https://docs.rsshub.app/multimedia.html#last-fm', source: '/charts', target: '/lastfm/top' }, 499 | ], 500 | }, 501 | 'ddrk.me': { 502 | _name: '低端影视', 503 | www: [ 504 | { title: '首页', docs: 'https://docs.rsshub.app/multimedia.html#di-duan-ying-shi', source: '/', target: '/ddrk/index' }, 505 | { title: '标签', docs: 'https://docs.rsshub.app/multimedia.html#di-duan-ying-shi', source: '/tag/:tag', target: '/ddrk/tag/:tag' }, 506 | { title: '分类', docs: 'https://docs.rsshub.app/multimedia.html#di-duan-ying-shi', source: ['/category/:category', '/category/:uplevel/:category'], target: '/ddrk/category/:category' }, 507 | { 508 | title: '影视剧集更新', 509 | docs: 'https://docs.rsshub.app/multimedia.html#di-duan-ying-shi', 510 | source: ['/:name', '/:name/:season'], 511 | target: (params) => { 512 | if (params.name !== 'category' && params.name !== 'tag' && params.name !== 'ddrklogin' && params.name !== 'about' && params.name !== 'deleted') { 513 | return `/ddrk/update/${params.name}${params.season ? '/' + params.season : ''}`; 514 | } 515 | }, 516 | }, 517 | ], 518 | }, 519 | 'google.com': { 520 | _name: '谷歌', 521 | photos: [ 522 | { 523 | title: '相册', 524 | docs: 'https://docs.rsshub.app/picture.html#google-xiang-ce', 525 | source: '/share/*', 526 | target: (params, url, document) => { 527 | const id = document && document.querySelector('html').innerHTML.match(/photos.app.goo.gl\/(.*?)"/)[1]; 528 | return id ? `/google/album/${id}` : ''; 529 | }, 530 | }, 531 | ], 532 | sites: [{ title: 'Sites', docs: 'https://docs.rsshub.app/blog.html#google-sites', source: ['/site/:id/*', '/site/:id'], target: '/google/sites/:id' }], 533 | }, 534 | 'javlibrary.com': { 535 | _name: 'javlibrary', 536 | www: [ 537 | { title: '新话题', docs: 'https://docs.rsshub.app/multimedia.html#javlibrary', source: '/cn', target: '/javlibrary/videos/update' }, 538 | { title: '新发行', docs: 'https://docs.rsshub.app/multimedia.html#javlibrary', source: '/cn', target: '/javlibrary/videos/newrelease' }, 539 | { title: '新加入', docs: 'https://docs.rsshub.app/multimedia.html#javlibrary', source: '/cn', target: '/javlibrary/videos/newentries' }, 540 | { title: '最想要', docs: 'https://docs.rsshub.app/multimedia.html#javlibrary', source: '/cn', target: '/javlibrary/videos/mostwanted' }, 541 | { title: '高评价', docs: 'https://docs.rsshub.app/multimedia.html#javlibrary', source: '/cn', target: '/javlibrary/videos/bestrated' }, 542 | { title: '最佳评论', docs: 'https://docs.rsshub.app/multimedia.html#javlibrary', source: '/cn', target: '/javlibrary/bestreviews' }, 543 | { title: '影星', docs: 'https://docs.rsshub.app/multimedia.html#javlibrary', source: '/cn/vl_star.php', target: (params, url) => `/javlibrary/stars/${new URL(url).searchParams.get('s')}` }, 544 | { 545 | title: '用户文章', 546 | docs: 'https://docs.rsshub.app/multimedia.html#javlibrary', 547 | source: ['/cn/user.php', '/cn/userposts.php', '/cn/userwateched.php', '/cn/userowned.php', '/cn/userwanted.php'], 548 | target: (params, url) => `/javlibrary/users/${new URL(url).searchParams.get('u')}/userposts`, 549 | }, 550 | { 551 | title: '用户拥有', 552 | docs: 'https://docs.rsshub.app/multimedia.html#javlibrary', 553 | source: ['/cn/user.php', '/cn/userposts.php', '/cn/userwateched.php', '/cn/userowned.php', '/cn/userwanted.php'], 554 | target: (params, url) => `/javlibrary/users/${new URL(url).searchParams.get('u')}/userowned`, 555 | }, 556 | { 557 | title: '用户看过', 558 | docs: 'https://docs.rsshub.app/multimedia.html#javlibrary', 559 | source: ['/cn/user.php', '/cn/userposts.php', '/cn/userwateched.php', '/cn/userowned.php', '/cn/userwanted.php'], 560 | target: (params, url) => `/javlibrary/users/${new URL(url).searchParams.get('u')}/userwatched`, 561 | }, 562 | { 563 | title: '用户想要', 564 | docs: 'https://docs.rsshub.app/multimedia.html#javlibrary', 565 | source: ['/cn/user.php', '/cn/userposts.php', '/cn/userwateched.php', '/cn/userowned.php', '/cn/userwanted.php'], 566 | target: (params, url) => `/javlibrary/users/${new URL(url).searchParams.get('u')}/userwanted`, 567 | }, 568 | ], 569 | }, 570 | 'qidian.com': { 571 | _name: '起点', 572 | book: [ 573 | { title: '章节', docs: 'https://docs.rsshub.app/reading.html#qi-dian', source: '/info/:id', target: '/qidian/chapter/:id' }, 574 | { title: '讨论区', docs: 'https://docs.rsshub.app/reading.html#qi-dian', source: '/info/:id', target: '/qidian/forum/:id' }, 575 | ], 576 | www: [ 577 | { title: '限免', docs: 'https://docs.rsshub.app/reading.html#qi-dian', source: '/free', target: '/qidian/free' }, 578 | { title: '女生限免', docs: 'https://docs.rsshub.app/reading.html#qi-dian', source: '/mm/free', target: '/qidian/free/mm' }, 579 | ], 580 | }, 581 | 'hackerone.com': { _name: 'HackerOne', '.': [{ title: 'HackerOne Hacker Activity', docs: 'https://docs.rsshub.app/other.html#hackerone-hacker-activity', source: '/hacktivity', target: '/hackerone/hacktivity' }] }, 582 | 'cowlevel.net': { _name: '奶牛关', '.': [{ title: '元素文章', docs: 'https://docs.rsshub.app/game.html#nai-niu-guan', source: ['/element/:id', '/element/:id/article'], target: '/cowlevel/element/:id' }] }, 583 | 'beijing.gov.cn': { wjw: [{ title: '北京卫生健康委员会', docs: 'https://docs.rsshub.app/government.html#bei-jing-shi-wei-sheng-jian-kang-wei-yuan-hui', source: '/xwzx_20031/:caty', target: '/gov/beijing/mhc/:caty' }] }, 584 | 'ynu.edu.cn': { 585 | _name: '云南大学', 586 | home: [{ title: '官网消息通告', docs: 'https://docs.rsshub.app/university.html#yun-nan-da-xue', source: '/tzgg.htm', target: '/ynu/home' }], 587 | jwc: [ 588 | { title: '教务处教务科通知', docs: 'https://docs.rsshub.app/university.html#yun-nan-da-xue', source: '/*', target: '/jwc/1' }, 589 | { title: '教务处学籍科通知', docs: 'https://docs.rsshub.app/university.html#yun-nan-da-xue', source: '/*', target: '/jwc/2' }, 590 | { title: '教务处教学研究科通知', docs: 'https://docs.rsshub.app/university.html#yun-nan-da-xue', source: '/*', target: '/jwc/3' }, 591 | { title: '教务处实践科学科通知', docs: 'https://docs.rsshub.app/university.html#yun-nan-da-xue', source: '/*', target: '/jwc/4' }, 592 | ], 593 | grs: [{ title: '研究生院通知', docs: 'https://docs.rsshub.app/university.html#yun-nan-da-xue', source: '/*', target: '' }], 594 | }, 595 | 'zju.edu.cn': { 596 | _name: '浙江大学', 597 | cst: [ 598 | { title: '软件学院 - 全部通知', docs: 'https://docs.rsshub.app/university.html#zhe-jiang-da-xue', source: ['', '/*tpath'], target: '/zju/cst/0' }, 599 | { title: '软件学院 - 招生信息', docs: 'https://docs.rsshub.app/university.html#zhe-jiang-da-xue', source: '/32178/list.htm', target: '/zju/cst/1' }, 600 | { title: '软件学院 - 教务管理', docs: 'https://docs.rsshub.app/university.html#zhe-jiang-da-xue', source: '/36216/list.htm', target: '/zju/cst/2' }, 601 | { title: '软件学院 - 论文管理', docs: 'https://docs.rsshub.app/university.html#zhe-jiang-da-xue', source: '/36217/list.htm', target: '/zju/cst/3' }, 602 | { title: '软件学院 - 思政工作', docs: 'https://docs.rsshub.app/university.html#zhe-jiang-da-xue', source: '/36192/list.htm', target: '/zju/cst/4' }, 603 | { title: '软件学院 - 评奖评优', docs: 'https://docs.rsshub.app/university.html#zhe-jiang-da-xue', source: '/36228/list.htm', target: '/zju/cst/5' }, 604 | { title: '软件学院 - 实习就业', docs: 'https://docs.rsshub.app/university.html#zhe-jiang-da-xue', source: '/36193/list.htm', target: '/zju/cst/6' }, 605 | { title: '软件学院 - 国际实习', docs: 'https://docs.rsshub.app/university.html#zhe-jiang-da-xue', source: '/36235/list.htm', target: '/zju/cst/7' }, 606 | { title: '软件学院 - 国内合作科研', docs: 'https://docs.rsshub.app/university.html#zhe-jiang-da-xue', source: '/36194/list.htm', target: '/zju/cst/8' }, 607 | { title: '软件学院 - 国际合作科研', docs: 'https://docs.rsshub.app/university.html#zhe-jiang-da-xue', source: '/36246/list.htm', target: '/zju/cst/9' }, 608 | ], 609 | }, 610 | 'kuaidi100.com': { 611 | _name: '快递100', 612 | '.': [ 613 | { 614 | title: '快递追踪', 615 | docs: 'https://docs.rsshub.app/other.html#kuai-di-100', 616 | source: '/', 617 | target: (params, url, document) => { 618 | const postid = document && document.querySelector('#postid').value; 619 | const com = document && document.querySelector('#selectComBtn').childNodes[1].attributes[1].value; 620 | if (com && com !== 'default' && postid) { 621 | return `/kuaidi100/track/${com}/${postid}`; 622 | } 623 | }, 624 | }, 625 | { title: '支持的快递公司列表', docs: 'https://docs.rsshub.app/other.html#kuai-di-100', source: '/', target: '/kuaidi100/company' }, 626 | ], 627 | }, 628 | 'hrbeu.edu.cn': { 629 | _name: '哈尔滨工程大学', 630 | yjsy: [ 631 | { title: '研究生院 - 通知公告', docs: 'https://docs.rsshub.app/university.html#ha-er-bin-gong-cheng-da-xue', source: '/*', target: '/heu/yjsy/announcement' }, 632 | { title: '研究生院 - 新闻动态', docs: 'https://docs.rsshub.app/university.html#ha-er-bin-gong-cheng-da-xue', source: '/*', target: '/heu/yjsy/news' }, 633 | { title: '研究生院 - 国家公派项目', docs: 'https://docs.rsshub.app/university.html#ha-er-bin-gong-cheng-da-xue', source: '/*', target: '/heu/yjsy/gjgp' }, 634 | { title: '研究生院 - 国际合作与交流项目', docs: 'https://docs.rsshub.app/university.html#ha-er-bin-gong-cheng-da-xue', source: '/*', target: '/heu/yjsy/gjhz' }, 635 | ], 636 | job: [{ title: '就业服务平台 - 通知公告', docs: 'https://docs.rsshub.app/university.html#ha-er-bin-gong-cheng-da-xue', source: '/*', target: '/heu/job/tzgg' }], 637 | uae: [ 638 | { title: '水声学院 - 新闻动态', docs: 'https://docs.rsshub.app/university.html#ha-er-bin-gong-cheng-da-xue', source: '/*', target: '/heu/shuisheng/xwdt' }, 639 | { title: '研究生院 - 通知公告', docs: 'https://docs.rsshub.app/university.html#ha-er-bin-gong-cheng-da-xue', source: '/*', target: '/heu/shuisheng/tzgg' }, 640 | ], 641 | }, 642 | 'gongxue.cn': { 643 | _name: '工学网', 644 | '.': [ 645 | { title: '要闻', docs: 'https://docs.rsshub.app/university.html#ha-er-bin-gong-cheng-da-xue', source: '/*', target: '/heu/gongxue/yw' }, 646 | { title: '时讯', docs: 'https://docs.rsshub.app/university.html#ha-er-bin-gong-cheng-da-xue', source: '/*', target: '/heu/gongxue/sx' }, 647 | ], 648 | }, 649 | 'nsfc.gov.cn': { 650 | _name: '国家自然科学基金委员会', 651 | www: [ 652 | { title: '基金要闻', docs: 'https://docs.rsshub.app/other.html#guo-jia-zi-ran-ke-xue-ji-jin-wei-yuan-hui', source: '/*', target: '/nsfc/news/jjyw' }, 653 | { title: '通知公告', docs: 'https://docs.rsshub.app/other.html#guo-jia-zi-ran-ke-xue-ji-jin-wei-yuan-hui', source: '/*', target: '/nsfc/news/tzgg' }, 654 | { title: '资助成果', docs: 'https://docs.rsshub.app/other.html#guo-jia-zi-ran-ke-xue-ji-jin-wei-yuan-hui', source: '/*', target: '/nsfc/news/zzcg' }, 655 | { title: '科普快讯', docs: 'https://docs.rsshub.app/other.html#guo-jia-zi-ran-ke-xue-ji-jin-wei-yuan-hui', source: '/*', target: '/nsfc/news/kpkx' }, 656 | ], 657 | }, 658 | 'japanpost.jp': { 659 | _name: '日本郵便', 660 | 'trackings.post': [ 661 | { 662 | title: '郵便・荷物の追跡', 663 | docs: 'https://docs.rsshub.app/other.html#ri-ben-you-bian-you-bian-zhui-ji-サービス', 664 | source: '/services/srv/search/direct', 665 | target: (params, url) => { 666 | const reqCode = new URL(url).searchParams.get('reqCodeNo1').toUpperCase(); 667 | const locale = new URL(url).searchParams.get('locale').toLowerCase(); 668 | if ((reqCode.search(/^(?:\d{11,12}|[A-Z]{2}\d{9}[A-Z]{2})$/) === 0 && locale === 'ja') || locale === 'en') { 669 | return `/japanpost/track/${reqCode}/${locale}`; 670 | } 671 | }, 672 | }, 673 | ], 674 | }, 675 | 'apnews.com': { _name: 'AP News', '.': [{ title: '话题', docs: 'https://docs.rsshub.app/traditional-media.html#ap-news', source: '/:topic', target: '/apnews/topics/:topic' }] }, 676 | 'csc.edu.cn': { 677 | _name: '国家留学网', 678 | www: [ 679 | { title: '遴选通知', docs: 'https://docs.rsshub.app/other.html#guo-jia-liu-xue-wang', source: '/*', target: '/csc/notice/lxtz' }, 680 | { title: '综合项目专栏', docs: 'https://docs.rsshub.app/other.html#guo-jia-liu-xue-wang', source: '/*', target: '/csc/notice/xmzl' }, 681 | { title: '常见问题解答', docs: 'https://docs.rsshub.app/other.html#guo-jia-liu-xue-wang', source: '/*', target: '/csc/notice/wtjd' }, 682 | { title: '录取公告', docs: 'https://docs.rsshub.app/other.html#guo-jia-liu-xue-wang', source: '/*', target: '/csc/notice/lqgg' }, 683 | ], 684 | }, 685 | 'biquge5200.com': { www: [{ title: 'biquge5200.com', docs: 'https://docs.rsshub.app/reading.html#bi-qu-ge-biquge5200-com', source: '/:id', target: '/novel/biquge/:id' }] }, 686 | 'biquge.info': { www: [{ title: 'biquge.info', docs: 'https://docs.rsshub.app/reading.html#bi-qu-ge-biquge-info', source: '/:id', target: '/novel/biqugeinfo/:id' }] }, 687 | 'matters.news': { 688 | _name: 'Matters', 689 | '.': [ 690 | { title: '最新排序', docs: 'https://docs.rsshub.app/new-media.html#matters', source: '', target: '/matters/latest' }, 691 | { title: '标签', docs: 'https://docs.rsshub.app/new-media.html#matters', source: '/tags/:tid', target: '/matters/tags/:tid' }, 692 | { 693 | title: '作者', 694 | docs: 'https://docs.rsshub.app/new-media.html#matters', 695 | source: ['/:id', '/:id/comments'], 696 | target: (params) => { 697 | const uid = params.id.replace('@', ''); 698 | return uid ? `/matters/author/${uid}` : ''; 699 | }, 700 | }, 701 | ], 702 | }, 703 | 'zhaishuyuan.com': { _name: '斋书苑', '.': [{ title: '最新章节', docs: 'https://docs.rsshub.app/reading.html#zhai-shu-yuan', source: ['/book/:id', '/read/:id'], target: '/novel/zhaishuyuan/:id' }] }, 704 | 'hbut.edu.cn': { 705 | _name: '湖北工业大学', 706 | www: [ 707 | { 708 | title: '新闻中心', 709 | docs: 'http://docs.rsshub.app/university.html#hu-bei-gong-ye-da-xue', 710 | source: '/xwzx/:name', 711 | target: (params) => { 712 | const type = params.name.replace('.htm', ''); 713 | return type ? `/hbut/news/${type}` : '/hbut/news/tzgg'; 714 | }, 715 | }, 716 | ], 717 | jsjxy: [ 718 | { title: '新闻动态', docs: 'http://docs.rsshub.app/university.html#hu-bei-gong-ye-da-xue', source: '/index/xwdt.htm', target: '/hbut/cs/xwdt' }, 719 | { title: '通知公告', docs: 'http://docs.rsshub.app/university.html#hu-bei-gong-ye-da-xue', source: '/index/tzgg.htm', target: '/hbut/cs/tzgg' }, 720 | { title: '教学信息', docs: 'http://docs.rsshub.app/university.html#hu-bei-gong-ye-da-xue', source: '/jxxx.htm', target: '/hbut/cs/jxxx' }, 721 | { title: '科研动态', docs: 'http://docs.rsshub.app/university.html#hu-bei-gong-ye-da-xue', source: '/kxyj/kydt.htm', target: '/hbut/cs/kydt' }, 722 | { title: '党建活动', docs: 'http://docs.rsshub.app/university.html#hu-bei-gong-ye-da-xue', source: '/djhd/djhd.htm', target: '/hbut/cs/djhd' }, 723 | ], 724 | }, 725 | 'zcool.com.cn': { 726 | _name: '站酷', 727 | www: [ 728 | { title: '发现', docs: 'https://docs.rsshub.app/design.html#zhan-ku', source: '', target: '/zcool/discover' }, 729 | { title: '发现 - 精选 - 全部推荐', docs: 'https://docs.rsshub.app/design.html#zhan-ku', source: '', target: '/zcool/discover/all' }, 730 | { title: '发现 - 精选 - 首页推荐', docs: 'https://docs.rsshub.app/design.html#zhan-ku', source: '', target: '/zcool/discover/home' }, 731 | { title: '发现 - 精选 - 编辑精选', docs: 'https://docs.rsshub.app/design.html#zhan-ku', source: '', target: '/zcool/discover/home' }, 732 | { title: '发现 - 精选 - 文章 - 编辑精选', docs: 'https://docs.rsshub.app/design.html#zhan-ku', source: '', target: '/zcool/discover/article' }, 733 | { title: '作品榜单', docs: 'https://docs.rsshub.app/design.html#zhan-ku', source: '', target: '/zcool/top/design' }, 734 | { title: '文章榜单', docs: 'https://docs.rsshub.app/design.html#zhan-ku', source: '', target: '/zcool/top/article' }, 735 | { title: '用户作品', docs: 'https://docs.rsshub.app/design.html#zhan-ku', source: ['/u/:id'], target: '/zcool/user/:id' }, 736 | ], 737 | }, 738 | 't.me': { 739 | _name: 'Telegram', 740 | '.': [ 741 | { 742 | title: '频道', 743 | docs: 'https://docs.rsshub.app/social-media.html#telegram', 744 | source: '/:username', 745 | target: (params, url, document) => { 746 | const isChannel = document && document.querySelector('.tgme_action_button_label'); 747 | if (isChannel) { 748 | return '/telegram/channel/:username'; 749 | } 750 | }, 751 | }, 752 | { title: '频道', docs: 'https://docs.rsshub.app/social-media.html#telegram', source: '/s/:username', target: '/telegram/channel/:username' }, 753 | ], 754 | }, 755 | 'zhuixinfan.com': { _name: '追新番日剧站', '.': [{ title: '更新列表', docs: 'https://docs.rsshub.app/multimedia.html#zhui-xin-fan-ri-ju-zhan', source: ['/main.php'], target: '/zhuixinfan/list' }] }, 756 | 'etoland.co.kr': { 757 | _name: 'eTOLAND', 758 | '.': [{ title: '主题贴', docs: 'https://docs.rsshub.app/bbs.html#etoland', source: ['/bbs/board.php', '/plugin/mobile/board.php'], target: (params, url) => `/etoland/${new URL(url).searchParams.get('bo_table')}` }], 759 | }, 760 | 'qq.com': { 761 | _name: '腾讯', 762 | 'mp.weixin': [ 763 | { 764 | title: '微信公众号栏目', 765 | docs: 'https://docs.rsshub.app/new-media.html#gong-zhong-hao-lan-mu-fei-tui-song-li-shi-xiao-xi', 766 | source: '/mp/homepage', 767 | target: (params, url) => `/wechat/mp/homepage/${new URL(url).searchParams.get('__biz')}/${new URL(url).searchParams.get('hid')}/${new URL(url).searchParams.get('cid') ? new URL(url).searchParams.get('cid') : ''}`, 768 | }, 769 | { 770 | title: '微信公众号话题', 771 | docs: 'https://docs.rsshub.app/new-media.html#wei-xin-gong-zhong-hao-wen-zhang-hua-ti-tag', 772 | source: '/mp/appmsgalbum', 773 | target: (params, url) => `/wechat/mp/msgalbum/${new URL(url).searchParams.get('__biz')}/${new URL(url).searchParams.get('album_id')}`, 774 | }, 775 | ], 776 | egame: [ 777 | { 778 | title: '企鹅电竞直播间', 779 | docs: 'https://docs.rsshub.app/live.html#qi-e-dian-jing-zhi-bo-jian-kai-bo', 780 | source: '/:id', 781 | target: (params) => { 782 | if (params.id.match(/^\d+$/)) { 783 | return '/egameqq/room/:id'; 784 | } 785 | }, 786 | }, 787 | ], 788 | v: [ 789 | { 790 | title: '视频 - 播放列表', 791 | docs: 'https://docs.rsshub.app/multimedia.html#teng-xun-shi-pin', 792 | source: '/x/cover/:id', 793 | target: (params) => { 794 | const id = params.id.match('(.*).html')[1]; 795 | return id ? `/tencentvideo/playlist/${id}` : ''; 796 | }, 797 | }, 798 | { title: '视频 - 播放列表', docs: 'https://docs.rsshub.app/multimedia.html#teng-xun-shi-pin', source: '/x/cover/:id/:detail', target: '/tencentvideo/playlist/:id' }, 799 | ], 800 | }, 801 | 'javbus.com': { 802 | _name: 'JavBus', 803 | www: [ 804 | { title: '首页', docs: 'https://docs.rsshub.app/multimedia.html#javbus', source: '/', target: '/javbus/home' }, 805 | { title: '分类', docs: 'https://docs.rsshub.app/multimedia.html#javbus', source: '/genre/:gid', target: '/javbus/genre/:gid' }, 806 | { title: '演员', docs: 'https://docs.rsshub.app/multimedia.html#javbus', source: '/star/:sid', target: '/javbus/star/:sid' }, 807 | { title: '系列', docs: 'https://docs.rsshub.app/multimedia.html#javbus', source: '/series/:seriesid', target: '/javbus/series/:seriesid' }, 808 | { title: '首页 / 步兵', docs: 'https://docs.rsshub.app/multimedia.html#javbus', source: '/uncensored', target: '/javbus/uncensored/home' }, 809 | { title: '分类 / 步兵', docs: 'https://docs.rsshub.app/multimedia.html#javbus', source: '/uncensored/genre/:gid', target: '/javbus/uncensored/genre/:gid' }, 810 | { title: '演员 / 步兵', docs: 'https://docs.rsshub.app/multimedia.html#javbus', source: '/uncensored/star/:sid', target: '/javbus/uncensored/star/:sid' }, 811 | { title: '系列 / 步兵', docs: 'https://docs.rsshub.app/multimedia.html#javbus', source: '/uncensored/series/:seriesid', target: '/javbus/uncensored/series/:seriesid' }, 812 | ], 813 | }, 814 | 'javbus.one': { 815 | _name: 'JavBus', 816 | www: [ 817 | { title: '首页 / 欧陆风云', docs: 'https://docs.rsshub.app/multimedia.html#javbus', source: '/', target: '/javbus/western/home' }, 818 | { title: '分类 / 欧陆风云', docs: 'https://docs.rsshub.app/multimedia.html#javbus', source: '/genre/:gid', target: '/javbus/western/genre/:gid' }, 819 | { title: '演员 / 欧陆风云', docs: 'https://docs.rsshub.app/multimedia.html#javbus', source: '/star/:sid', target: '/javbus/western/star/:sid' }, 820 | { title: '系列 / 欧陆风云', docs: 'https://docs.rsshub.app/multimedia.html#javbus', source: '/series/:seriesid', target: '/javbus/western/series/:seriesid' }, 821 | ], 822 | }, 823 | 'onejav.com': { 824 | _name: 'OneJAV BT', 825 | '.': [ 826 | { 827 | title: '今日种子', 828 | docs: 'https://docs.rsshub.app/multimedia.html#onejav', 829 | source: '/', 830 | target: (params, url, document) => { 831 | const today = document.querySelector('div.card.mb-1.card-overview').getAttribute('data-date').replace(/-/g, ''); 832 | return `/onejav/day/${today}`; 833 | }, 834 | }, 835 | { 836 | title: '今日演员', 837 | docs: 'https://docs.rsshub.app/multimedia.html#onejav', 838 | source: '/', 839 | target: (params, url, document) => { 840 | const star = document.querySelector('div.card-content > div > a').getAttribute('href'); 841 | return `/onejav${star}`; 842 | }, 843 | }, 844 | { 845 | title: '页面种子', 846 | docs: 'https://docs.rsshub.app/multimedia.html#onejav', 847 | source: ['/:type', '/:type/:key', '/:type/:key/:morekey'], 848 | target: (params, url, document) => { 849 | const itype = params.morekey === undefined ? params.type : params.type === 'tag' ? 'tag' : 'day'; 850 | let ikey = `${itype === 'day' ? params.type : ''}${params.key || ''}${itype === 'tag' && params.morekey !== undefined ? '%2F' : ''}${params.morekey || ''}`; 851 | if (ikey === '' && itype === 'tag') { 852 | ikey = document.querySelector('div.thumbnail.is-inline > a').getAttribute('href').replace('/tag/', '').replace('/', '%2F'); 853 | } else if (ikey === '' && itype === 'actress') { 854 | ikey = document.querySelector('div.card > a').getAttribute('href').replace('/actress/', ''); 855 | } 856 | return `/onejav/${itype}/${ikey}`; 857 | }, 858 | }, 859 | ], 860 | }, 861 | '141jav.com': { 862 | _name: '141JAV BT', 863 | '.': [ 864 | { 865 | title: '今日种子', 866 | docs: 'https://docs.rsshub.app/multimedia.html#141jav', 867 | source: '/', 868 | target: (params, url, document) => { 869 | const today = document.querySelector('div.card.mb-1.card-overview').getAttribute('data-date').replace(/-/g, ''); 870 | return `/141jav/day/${today}`; 871 | }, 872 | }, 873 | { 874 | title: '今日演员', 875 | docs: 'https://docs.rsshub.app/multimedia.html#141jav', 876 | source: '/', 877 | target: (params, url, document) => { 878 | const star = document.querySelector('div.card-content > div > a').getAttribute('href'); 879 | return `/141jav${star}`; 880 | }, 881 | }, 882 | { 883 | title: '页面种子', 884 | docs: 'https://docs.rsshub.app/multimedia.html#141jav', 885 | source: ['/:type', '/:type/:key', '/:type/:key/:morekey'], 886 | target: (params, url, document) => { 887 | const itype = params.morekey === undefined ? params.type : params.type === 'tag' ? 'tag' : 'day'; 888 | let ikey = `${itype === 'day' ? params.type : ''}${params.key || ''}${itype === 'tag' && params.morekey !== undefined ? '%2F' : ''}${params.morekey || ''}`; 889 | if (ikey === '' && itype === 'tag') { 890 | ikey = document.querySelector('div.thumbnail.is-inline > a').getAttribute('href').replace('/tag/', '').replace('/', '%2F'); 891 | } else if (ikey === '' && itype === 'actress') { 892 | ikey = document.querySelector('div.card > a').getAttribute('href').replace('/actress/', ''); 893 | } 894 | return `/141jav/${itype}/${ikey}`; 895 | }, 896 | }, 897 | ], 898 | }, 899 | '141ppv.com': { 900 | _name: '141ppv BT', 901 | '.': [ 902 | { 903 | title: '今日种子', 904 | docs: 'https://docs.rsshub.app/multimedia.html#141pvp', 905 | source: '/', 906 | target: (params, url, document) => { 907 | const today = document.querySelector('div.card.mb-1.card-overview').getAttribute('data-date').replace(/-/g, ''); 908 | return `/141ppv/day/${today}`; 909 | }, 910 | }, 911 | { 912 | title: '今日演员', 913 | docs: 'https://docs.rsshub.app/multimedia.html#141ppv', 914 | source: '/', 915 | target: (params, url, document) => { 916 | const star = document.querySelector('div.card-content > div > a').getAttribute('href'); 917 | return `/141ppv${star}`; 918 | }, 919 | }, 920 | { 921 | title: '页面种子', 922 | docs: 'https://docs.rsshub.app/multimedia.html#141ppv', 923 | source: ['/:type', '/:type/:key', '/:type/:key/:morekey'], 924 | target: (params, url, document) => { 925 | const itype = params.morekey === undefined ? params.type : params.type === 'tag' ? 'tag' : 'day'; 926 | let ikey = `${itype === 'day' ? params.type : ''}${params.key || ''}${itype === 'tag' && params.morekey !== undefined ? '%2F' : ''}${params.morekey || ''}`; 927 | if (ikey === '' && itype === 'tag') { 928 | ikey = document.querySelector('div.thumbnail.is-inline > a').getAttribute('href').replace('/tag/', '').replace('/', '%2F'); 929 | } else if (ikey === '' && itype === 'actress') { 930 | ikey = document.querySelector('div.card > a').getAttribute('href').replace('/actress/', ''); 931 | } 932 | return `/141ppv/${itype}/${ikey}`; 933 | }, 934 | }, 935 | ], 936 | }, 937 | 'sexinsex.net': { 938 | _name: 'sexinsex', 939 | '.': [ 940 | { 941 | title: '分区帖子', 942 | docs: 'https://docs.rsshub.app/multimedia.html#sexinsex', 943 | source: '/bbs/:path', 944 | target: (params, url) => { 945 | let pid, typeid; 946 | const static_matched = params.path.match(/forum-(\d+)-\d+.html/); 947 | if (static_matched) { 948 | pid = static_matched[1]; 949 | } else if (params.path === 'forumdisplay.php') { 950 | pid = new URL(url).searchParams.get('fid'); 951 | typeid = new URL(url).searchParams.get('typeid'); 952 | } else { 953 | return false; 954 | } 955 | return `/sexinsex/${pid}/${typeid ? typeid : ''}`; 956 | }, 957 | }, 958 | ], 959 | }, 960 | 't66y.com': { 961 | _name: '草榴社区', 962 | www: [ 963 | { 964 | title: '分区帖子', 965 | docs: 'https://docs.rsshub.app/multimedia.html#cao-liu-she-qu', 966 | source: '/thread0806.php', 967 | target: (params, url) => { 968 | const id = new URL(url).searchParams.get('fid'); 969 | const type = new URL(url).searchParams.get('type'); 970 | return `/t66y/${id}/${type ? type : ''}`; 971 | }, 972 | }, 973 | ], 974 | }, 975 | 'umass.edu': { 976 | _name: 'UMASS Amherst', 977 | ece: [ 978 | { title: 'ECE News', docs: 'http://docs.rsshub.app/en/university.html#umass-amherst', source: '/news', target: '/umass/amherst/ecenews' }, 979 | { title: 'ECE Seminar', docs: 'http://docs.rsshub.app/en/university.html#umass-amherst', source: '/seminars', target: '/umass/amherst/eceseminar' }, 980 | ], 981 | 'www.cics': [{ title: 'CICS News', docs: 'http://docs.rsshub.app/en/university.html#umass-amherst', source: '/news', target: '/umass/amherst/csnews' }], 982 | www: [ 983 | { title: 'IPO Events', docs: 'http://docs.rsshub.app/en/university.html#umass-amherst', source: '/ipo/iss/events', target: '/umass/amherst/ipoevents' }, 984 | { title: 'IPO Featured Stories', docs: 'http://docs.rsshub.app/en/university.html#umass-amherst', source: '/ipo/iss/featured-stories', target: '/umass/amherst/ipostories' }, 985 | ], 986 | }, 987 | 'lofter.com': { 988 | _name: 'Lofter', 989 | www: [{ title: '话题 (标签)', docs: 'https://docs.rsshub.app/social-media.html#lofter', source: ['/tag/:name', '/tag/:name/:type'], target: (params) => `/lofter/tag/${params.name}/${params.type || ''}` }], 990 | }, 991 | 'yuque.com': { 992 | _name: '语雀', 993 | www: [ 994 | { 995 | title: '知识库', 996 | docs: 'https://docs.rsshub.app/study.html#yu-que', 997 | source: ['/:space/:book'], 998 | target: (params, url, document) => { 999 | const match = document.documentElement.innerHTML.match(/JSON\.parse\(decodeURIComponent\("(.*)"\)/); 1000 | if (match && match[1]) { 1001 | const dataStr = match[1]; 1002 | try { 1003 | const appData = JSON.parse(decodeURIComponent(dataStr)); 1004 | return `/yuque/doc/${appData.book.id}`; 1005 | } catch (e) { 1006 | // pass 1007 | } 1008 | } 1009 | }, 1010 | }, 1011 | ], 1012 | }, 1013 | 'bjeea.com': { 1014 | _name: '北京考试院', 1015 | www: [ 1016 | { title: '首页 / 通知公告', docs: 'https://docs.rsshub.app/government.html#bei-jing-jiao-yu-kao-shi-yuan', source: ['/html/bjeeagg'], target: '/gov/beijing/bjeea/bjeeagg' }, 1017 | { title: '首页 / 招考政策', docs: 'https://docs.rsshub.app/government.html#bei-jing-jiao-yu-kao-shi-yuan', source: ['/html/zkzc'], target: '/gov/beijing/bjeea/zkzc' }, 1018 | { title: '首页 / 自考快递', docs: 'https://docs.rsshub.app/government.html#bei-jing-jiao-yu-kao-shi-yuan', source: ['/html/zkkd'], target: '/gov/beijing/bjeea/zkkd' }, 1019 | ], 1020 | }, 1021 | 'hk01.com': { 1022 | _name: '香港01', 1023 | www: [ 1024 | { title: '最 Hit', docs: 'https://docs.rsshub.app/traditional-media.html#xiang-gang-01', source: ['/hot', '/'], target: '/hk01/hot' }, 1025 | { title: 'zone', docs: 'https://docs.rsshub.app/traditional-media.html#xiang-gang-01', source: '/zone/:id/:title', target: '/hk01/zone/:id' }, 1026 | { title: 'channel', docs: 'https://docs.rsshub.app/traditional-media.html#xiang-gang-01', source: '/channel/:id/:title', target: '/hk01/channel/:id' }, 1027 | { title: 'issue', docs: 'https://docs.rsshub.app/traditional-media.html#xiang-gang-01', source: '/issue/:id/:title', target: '/hk01/issue/:id' }, 1028 | { title: 'tag', docs: 'https://docs.rsshub.app/traditional-media.html#xiang-gang-01', source: '/tag/:id/:title', target: '/hk01/tag/:id' }, 1029 | ], 1030 | }, 1031 | 'douban.com': { 1032 | _name: '豆瓣', 1033 | www: [ 1034 | { 1035 | title: '用户的广播', 1036 | docs: 'https://docs.rsshub.app/social-media.html#dou-ban', 1037 | source: '/people/:user/', 1038 | target: (params, url, document) => { 1039 | const uid = document && document.querySelector('html').innerHTML.match(/"id":"([0-9]+)"/)[1]; 1040 | return uid ? `/douban/people/${uid}/status` : ''; 1041 | }, 1042 | }, 1043 | { title: '小组-最新', docs: 'https://docs.rsshub.app/social-media.html#dou-ban', source: '/group/:groupid', target: '/douban/group/:groupid' }, 1044 | { title: '小组-最热', docs: 'https://docs.rsshub.app/social-media.html#dou-ban', source: '/group/:groupid', target: '/douban/group/:groupid/essence' }, 1045 | { title: '小组-精华', docs: 'https://docs.rsshub.app/social-media.html#dou-ban', source: '/group/:groupid', target: '/douban/group/:groupid/elite' }, 1046 | ], 1047 | }, 1048 | 'okjike.com': { 1049 | _name: '即刻', 1050 | m: [ 1051 | { 1052 | title: '用户动态', 1053 | docs: 'https://docs.rsshub.app/social-media.html#ji-ke-yong-hu-dong-tai', 1054 | source: '/reposts/:repostId', 1055 | target: (params, url, document) => { 1056 | const uid = document.querySelector('.avatar').getAttribute('href').replace('/users/', ''); 1057 | return uid ? `/jike/user/${uid}` : ''; 1058 | }, 1059 | }, 1060 | { title: '圈子', docs: 'https://docs.rsshub.app/social-media.html#ji-ke-quan-zi', source: '/topics/:id', target: '/jike/topic/:id' }, 1061 | { title: '圈子 - 纯文字', docs: 'https://docs.rsshub.app/social-media.html#ji-ke-quan-zi-chun-wen-zi', source: '/topics/:id', target: '/jike/topic/text/:id' }, 1062 | ], 1063 | }, 1064 | 'ems.com.cn': { _name: '中国邮政速递物流', www: [{ title: '新闻', docs: 'https://docs.rsshub.app/other.html#zhong-guo-you-zheng-su-di-wu-liu', source: '/aboutus/xin_wen_yu_shi_jian.html', target: '/ems/news' }] }, 1065 | 'popiapp.cn': { 1066 | _name: 'Popi 提问箱', 1067 | www: [ 1068 | { 1069 | title: '提问箱新回答', 1070 | docs: 'https://docs.rsshub.app/social-media.html#popi-ti-wen-xiang', 1071 | source: '/:id', 1072 | target: (params) => { 1073 | if (params.id) { 1074 | return '/popiask/:id'; 1075 | } 1076 | }, 1077 | }, 1078 | ], 1079 | }, 1080 | 'nppa.gov.cn': { 1081 | _name: '国家新闻出版署', 1082 | www: [ 1083 | { title: '栏目', docs: 'https://docs.rsshub.app/government.html#guo-jia-xin-wen-chu-ban-shu', source: '/nppa/channels/:channel', target: (params, url) => `/gov/nppa/${/nppa\/channels\/(\d+)\.shtml/.exec(url)[1]}` }, 1084 | { 1085 | title: '内容', 1086 | docs: 'https://docs.rsshub.app/government.html#guo-jia-xin-wen-chu-ban-shu', 1087 | source: '/nppa/contents/:channel/:content', 1088 | target: (params, url) => `/gov/nppa/${/nppa\/contents\/(\d+\/\d+)\.shtml/.exec(url)[1]}`, 1089 | }, 1090 | ], 1091 | }, 1092 | 'acfun.cn': { 1093 | _name: 'AcFun', 1094 | www: [ 1095 | { tilte: '番剧', docs: 'https://docs.rsshub.app/anime.html#acfun-fan-ju', source: '/bangumi/:id', target: (params) => `/acfun/bangumi/${params.id.replace('aa', '')}` }, 1096 | { title: '用户投稿', docs: 'https://docs.rsshub.app/anime.html#acfun-yong-hu-tou-gao', source: '/u/:id', target: '/acfun/user/video/:id' }, 1097 | ], 1098 | }, 1099 | 'behance.net': { 1100 | _name: 'Behance', 1101 | www: [ 1102 | { 1103 | title: 'User', 1104 | docs: 'https://docs.rsshub.app/design.html#behance-user-works', 1105 | source: ['/:user'], 1106 | target: (params, url, document) => { 1107 | const uid1 = document && document.querySelector('html').innerHTML.match(/([^/]+)\/insights/)[1]; 1108 | return `/behance/${uid1}`; 1109 | }, 1110 | }, 1111 | ], 1112 | }, 1113 | 'picuki.com': { _name: 'Picuki', www: [{ title: '用户', docs: 'https://docs.rsshub.app/social-media.html#picuki-yong-hu', source: '/profile/:id', target: '/picuki/profile/:id' }] }, 1114 | 'jjmhw.cc': { _name: '漫小肆', www: [{ title: '漫画更新', docs: 'https://docs.rsshub.app/anime.html#man-xiao-si', source: '/book/:id', target: '/manxiaosi/book/:id' }] }, 1115 | 'wenxuecity.com': { 1116 | _name: '文学城', 1117 | blog: [ 1118 | { title: '博客', docs: 'https://docs.rsshub.app/bbs.html#wen-xue-cheng-bo-ke', source: '/myblog/:id', target: '/wenxuecity/blog/:id' }, 1119 | { title: '博客', docs: 'https://docs.rsshub.app/bbs.html#wen-xue-cheng-bo-ke', source: '/myoverview/:id', target: '/wenxuecity/blog/:id' }, 1120 | ], 1121 | bbs: [ 1122 | { title: '最新主题', docs: 'https://docs.rsshub.app/bbs.html#wen-xue-cheng-zui-xin-zhu-ti', source: '/:cat', target: '/wenxuecity/bbs/:cat' }, 1123 | { title: '最新主题 - 精华区', docs: 'https://docs.rsshub.app/bbs.html#wen-xue-cheng-zui-xin-zhu-ti', source: '/:cat', target: '/wenxuecity/bbs/:cat/1' }, 1124 | { 1125 | title: '最热主题', 1126 | docs: 'https://docs.rsshub.app/bbs.html#wen-xue-cheng-zui-re-zhu-ti', 1127 | source: '/?cid=*', 1128 | target: (params, url, document) => { 1129 | const cid = document && new URL(document.location).searchParams.get('cid'); 1130 | return `/wenxuecity/hot/${cid}`; 1131 | }, 1132 | }, 1133 | ], 1134 | }, 1135 | 'buaq.net': { _name: '不安全资讯', '.': [{ title: '不安全资讯', docs: 'http://docs.rsshub.app/new-media.html#bu-an-quan', source: '/', target: '/buaq' }] }, 1136 | 'jian-ning.com': { _name: '建宁闲谈', '.': [{ title: '文章', docs: 'https://docs.rsshub.app/blog.html#jian-ning-xian-tan', source: '/*', target: '/blogs/jianning' }] }, 1137 | 'matataki.io': { 1138 | _name: 'matataki', 1139 | www: [ 1140 | { title: '最热作品', docs: 'https://docs.rsshub.app/new-media.html#matataki', source: '/article/', target: '/matataki/posts/hot' }, 1141 | { title: '最新作品', docs: 'https://docs.rsshub.app/new-media.html#matataki', source: '/article/latest', target: '/matataki/posts/latest' }, 1142 | { title: '作者创作', docs: 'https://docs.rsshub.app/new-media.html#matataki', source: '/user/:uid', target: (params) => `/matataki/users/${params.uid}/posts` }, 1143 | { title: 'Fan票关联作品', docs: 'https://docs.rsshub.app/new-media.html#matataki', source: ['/token/:tokenId', '/token/:tokenId/circle'], target: (params) => `/matataki/tokens/${params.tokenId}/posts` }, 1144 | { 1145 | title: '标签关联作品', 1146 | docs: 'https://docs.rsshub.app/new-media.html#matataki', 1147 | source: ['/tag/:tagId'], 1148 | target: (params, url) => { 1149 | const tagName = new URL(url).searchParams.get('name'); 1150 | return `/matataki/tags/${params.tagId}/${tagName}/posts`; 1151 | }, 1152 | }, 1153 | { 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` }, 1154 | ], 1155 | }, 1156 | 'eventernote.com': { _name: 'Eventernote', www: [{ title: '声优活动及演唱会', docs: 'https://docs.rsshub.app/anime.html#eventernote', source: '/actors/:name/:id/events', target: '/eventernote/actors/:name/:id' }] }, 1157 | 'instagram.com': { 1158 | _name: 'Instagram', 1159 | www: [ 1160 | { 1161 | title: '用户', 1162 | docs: 'https://docs.rsshub.app/social-media.html#instagram', 1163 | source: '/:id', 1164 | target: (params) => { 1165 | if (params.id !== 'explore' && params.id !== 'developer') { 1166 | return '/instagram/user/:id'; 1167 | } 1168 | }, 1169 | }, 1170 | ], 1171 | }, 1172 | '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' }] }, 1173 | 'craigslist.org': { _name: 'Craigslist', '.': [{ title: '商品搜索列表', docs: 'https://docs.rsshub.app/shopping.html#craigslist' }] }, 1174 | 'saraba1st.com': { 1175 | _name: 'Saraba1st', 1176 | bbs: [ 1177 | { 1178 | title: '帖子', 1179 | docs: 'https://docs.rsshub.app/bbs.html#saraba1st', 1180 | source: '/2b/:id', 1181 | target: (params) => { 1182 | const id = params.id.includes('thread') ? params.id.split('-')[1] : ''; 1183 | return id ? `/saraba1st/thread/${id}` : ''; 1184 | }, 1185 | }, 1186 | ], 1187 | }, 1188 | 'scboy.com': { 1189 | _name: 'scboy 论坛', 1190 | www: [ 1191 | { 1192 | title: '帖子', 1193 | docs: 'https://docs.rsshub.app/bbs.html#scboy', 1194 | source: '', 1195 | target: (params, url) => { 1196 | const id = url.includes('thread') ? url.split('-')[1].split('.')[0] : ''; 1197 | return id ? `/scboy/thread/${id}` : ''; 1198 | }, 1199 | }, 1200 | ], 1201 | }, 1202 | 'cqut.edu.cn': { 1203 | _name: '重庆理工大学', 1204 | tz: [{ title: '通知', docs: 'https://docs.rsshub.app/university.html#chong-qing-li-gong-da-xue', source: '/*' }], 1205 | lib: [{ title: '图书馆通知', docs: 'https://docs.rsshub.app/university.html#chong-qing-li-gong-da-xue', source: '/*' }], 1206 | }, 1207 | 'cqwu.net': { 1208 | _name: '重庆文理学院', 1209 | www: [ 1210 | { 1211 | title: '通知', 1212 | docs: 'https://docs.rsshub.app/university.html#chong-qing-wen-li-xue-yuan', 1213 | source: '/:type', 1214 | target: (params) => { 1215 | if (params.type === 'channel_7721.html') { 1216 | return '/cqwu/news/notify'; 1217 | } 1218 | }, 1219 | }, 1220 | { 1221 | title: '学术活动', 1222 | docs: 'https://docs.rsshub.app/university.html#chong-qing-wen-li-xue-yuan', 1223 | source: '/:type', 1224 | target: (params) => { 1225 | if (params.type === 'channel_7722.html') { 1226 | return '/cqwu/news/academiceve'; 1227 | } 1228 | }, 1229 | }, 1230 | ], 1231 | }, 1232 | 'trakt.tv': { 1233 | _name: 'Trakt.tv', 1234 | '.': [ 1235 | { 1236 | title: '用户收藏', 1237 | docs: 'https://docs.rsshub.app/multimedia.html#trakt-tv-yong-hu-shou-cang', 1238 | source: ['/users/:username/collection/:type/added', '/users/:username/collection'], 1239 | target: (params) => `/trakt/collection/${params.username}/${params.type || 'all'}`, 1240 | }, 1241 | ], 1242 | }, 1243 | 'eagle.cool': { 1244 | _name: 'Eagle', 1245 | cn: [{ title: '更新日志', docs: 'https://docs.rsshub.app/program-update.html#eagle', source: '/changelog', target: '/eagle/changelog/cn' }], 1246 | tw: [{ title: '更新日誌', docs: 'https://docs.rsshub.app/program-update.html#eagle', source: '/changelog', target: '/eagle/changelog/tw' }], 1247 | en: [{ title: 'Release Notes', docs: 'https://docs.rsshub.app/program-update.html#eagle', source: '/changelog', target: '/eagle/changelog/en' }], 1248 | }, 1249 | 'furaffinity.net': { 1250 | _name: 'Fur Affinity', 1251 | www: [ 1252 | { title: '主页', docs: 'https://docs.rsshub.app/social-media.html#fur-affinity', source: '/', target: '/furaffinity/home' }, 1253 | { title: '浏览', docs: 'https://docs.rsshub.app/social-media.html#fur-affinity', source: '/browse/', target: '/furaffinity/browse' }, 1254 | { title: '站点状态', docs: 'https://docs.rsshub.app/social-media.html#fur-affinity', source: '/', target: '/furaffinity/status' }, 1255 | { 1256 | title: '搜索', 1257 | docs: 'https://docs.rsshub.app/social-media.html#fur-affinity', 1258 | source: '/search/', 1259 | target: (params, url) => { 1260 | const keyword = new URL(url).searchParams.get('q'); 1261 | if (keyword) { 1262 | return `/furaffinity/search/${keyword}`; 1263 | } 1264 | }, 1265 | }, 1266 | { title: '用户主页简介', docs: 'https://docs.rsshub.app/social-media.html#fur-affinity', source: '/user/:username/', target: '/furaffinity/user/:username' }, 1267 | { title: '用户关注列表', docs: 'https://docs.rsshub.app/social-media.html#fur-affinity', source: '/watchlist/by/:username/', target: '/furaffinity/watching/:username' }, 1268 | { title: '用户被关注列表', docs: 'https://docs.rsshub.app/social-media.html#fur-affinity', source: '/watchlist/to/:username/', target: '/furaffinity/watchers/:username' }, 1269 | { title: '用户接受委托信息', docs: 'https://docs.rsshub.app/social-media.html#fur-affinity', source: '/commissions/:username/', target: '/furaffinity/commissions/:username' }, 1270 | { title: '用户的 Shouts 留言', docs: 'https://docs.rsshub.app/social-media.html#fur-affinity', source: '/user/:username/', target: '/furaffinity/shouts/:username' }, 1271 | { title: '用户的日记', docs: 'https://docs.rsshub.app/social-media.html#fur-affinity', source: '/journals/:username/', target: '/furaffinity/journals/:username' }, 1272 | { title: '用户的创作画廊', docs: 'https://docs.rsshub.app/social-media.html#fur-affinity', source: '/gallery/:username/', target: '/furaffinity/gallery/:username' }, 1273 | { title: '用户非正式作品', docs: 'https://docs.rsshub.app/social-media.html#fur-affinity', source: '/scraps/:username/', target: '/furaffinity/scraps/:username' }, 1274 | { title: '用户的喜爱列表', docs: 'https://docs.rsshub.app/social-media.html#fur-affinity', source: '/favorites/:username/', target: '/furaffinity/favorites/:username' }, 1275 | { title: '作品评论区', docs: 'https://docs.rsshub.app/social-media.html#fur-affinity', source: '/view/:id/', target: '/furaffinity/submission_comments/:id' }, 1276 | { title: '日记评论区', docs: 'https://docs.rsshub.app/social-media.html#fur-affinity', source: '/journal/:id/', target: '/furaffinity/journal_comments/:id' }, 1277 | ], 1278 | }, 1279 | 'gcores.com': { 1280 | _name: '机核网', 1281 | www: [ 1282 | { title: '资讯', docs: 'https://docs.rsshub.app/program-update.html#eagle', source: '/news', target: '/gcores/category/news' }, 1283 | { title: '视频', docs: 'https://docs.rsshub.app/program-update.html#eagle', source: '/videos', target: '/gcores/category/videos' }, 1284 | { title: '电台', docs: 'https://docs.rsshub.app/program-update.html#eagle', source: '/radios', target: '/gcores/category/radios' }, 1285 | { title: '文章', docs: 'https://docs.rsshub.app/program-update.html#eagle', source: '/articles', target: '/gcores/category/articles' }, 1286 | ], 1287 | }, 1288 | 'bgm.tv': { 1289 | _name: 'Bangumi', 1290 | '.': [ 1291 | { title: '小组话题', docs: 'https://docs.rsshub.app/anime.html#bangumi', source: '/group/:id', target: '/bangumi/group/:id' }, 1292 | { title: '小组话题的新回复', docs: 'https://docs.rsshub.app/anime.html#bangumi', source: '/group/topic/:id', target: '/bangumi/topic/:id' }, 1293 | { title: '现实人物的新作品', docs: 'https://docs.rsshub.app/anime.html#bangumi', source: '/person/:id', target: '/bangumi/person/:id' }, 1294 | { title: '用户日志', docs: 'https://docs.rsshub.app/anime.html#bangumi', source: '/user/:id', target: '/bangumi/user/blog/:id' }, 1295 | { title: '条目的讨论', docs: 'https://docs.rsshub.app/anime.html#bangumi', source: '/subject/:id', target: '/bangumi/subject/:id/topics' }, 1296 | { title: '条目的评论', docs: 'https://docs.rsshub.app/anime.html#bangumi', source: '/subject/:id', target: '/bangumi/subject/:id/blogs' }, 1297 | { title: '条目的章节', docs: 'https://docs.rsshub.app/anime.html#bangumi', source: '/subject/:id', target: '/bangumi/subject/:id' }, 1298 | { title: '条目的吐槽箱', docs: 'https://docs.rsshub.app/anime.html#bangumi', source: '/subject/:id', target: '/bangumi/subject/:id/comments' }, 1299 | { title: '放送列表', docs: 'https://docs.rsshub.app/anime.html#bangumi', source: '/calendar', target: '/bangumi/calendar/today' }, 1300 | ], 1301 | }, 1302 | 'e-hentai.org/': { 1303 | _name: 'E-Hentai', 1304 | '.': [ 1305 | { title: '收藏', docs: 'https://docs.rsshub.app/picture.html#ehentai', source: '/favorites.php', target: '/ehentai/favorites' }, 1306 | { title: '标签', docs: 'https://docs.rsshub.app/picture.html#ehentai', source: '/tag/:tag', target: '/ehentai/tag/:tag' }, 1307 | { 1308 | title: '搜索', 1309 | docs: 'https://docs.rsshub.app/picture.html#ehentai', 1310 | source: '/', 1311 | target: (params, url) => { 1312 | const keyword = new URL(url).searchParams.toString(); 1313 | if (keyword) { 1314 | return `/ehentai/search/${keyword}`; 1315 | } 1316 | }, 1317 | }, 1318 | ], 1319 | }, 1320 | 'iyingdi.com': { 1321 | _name: '旅法师营地', 1322 | www: [ 1323 | { title: '分区', docs: 'https://docs.rsshub.app/game.html#lv-fa-shi-ying-di', source: '/tz/tag/:tag', target: '/lfsyd/tag/:tag' }, 1324 | { title: '用户发帖', docs: 'https://docs.rsshub.app/game.html#lv-fa-shi-ying-di', source: ['/tz/people/:id', '/tz/people/:id/*'], target: '/lfsyd/user/:id' }, 1325 | ], 1326 | mob: [{ title: '分区', docs: 'https://docs.rsshub.app/game.html#lv-fa-shi-ying-di', source: '/fine/:tag', target: '/lfsyd/tag/:tag' }], 1327 | }, 1328 | 'macwk.com': { _name: 'MacWk', '.': [{ title: '应用更新', docs: 'https://docs.rsshub.app/program-update.html#macwk', source: '/soft/:name', target: '/macwk/soft/:name' }] }, 1329 | 'zyshow.net': { www: [{ title: '', docs: 'https://docs.rsshub.app/game.html#lv-fa-shi-ying-di', source: '/:name/', target: '/zyshow/:name' }] }, 1330 | }; 1331 | --------------------------------------------------------------------------------