diff --git a/.gitignore b/.gitignore
index a5c841183ab023..368a4c547ba8e7 100644
--- a/.gitignore
+++ b/.gitignore
@@ -30,5 +30,3 @@ package-lock.json
# pnpm-lock.yaml
yarn.lock
yarn-error.log
-
-scripts/twitter-token/accounts.*
diff --git a/README.md b/README.md
index 8eb2654555ec1d..debaf1bff5cd97 100644
--- a/README.md
+++ b/README.md
@@ -11,7 +11,7 @@
[![test](https://img.shields.io/github/actions/workflow/status/DIYgod/RSSHub/test.yml?branch=master&label=test&logo=github&style=flat-square)](https://github.com/DIYgod/RSSHub/actions/workflows/test.yml?query=event%3Apush+branch%3Amaster)
[![Test coverage](https://img.shields.io/codecov/c/github/DIYgod/RSSHub.svg?style=flat-square&logo=codecov)](https://app.codecov.io/gh/DIYgod/RSSHub/branch/master)
-[![Telegram group](https://img.shields.io/badge/dynamic/json?url=https%3A%2F%2Fapi.swo.moe%2Fstats%2Ftelegram%2Frsshub&query=count&color=2CA5E0&label=Telegram%20Group&logo=telegram&cacheSeconds=3600&style=flat-square)](https://t.me/rsshub) [![Telegram channel](https://img.shields.io/badge/dynamic/json?url=https%3A%2F%2Fapi.swo.moe%2Fstats%2Ftelegram%2FawesomeRSSHub&query=count&color=2CA5E0&label=Telegram%20Channel&logo=telegram&cacheSeconds=3600&style=flat-square)](https://t.me/awesomeRSSHub) [![Twitter](https://img.shields.io/badge/any_text-Follow-blue?color=2CA5E0&label=Twitter&logo=twitter&cacheSeconds=3600&style=flat-square)](https://twitter.com/intent/follow?screen_name=_RSSHub)
+[![Telegram group](https://img.shields.io/badge/dynamic/json?url=https%3A%2F%2Fapi.swo.moe%2Fstats%2Ftelegram%2Frsshub&query=count&color=2CA5E0&label=Telegram%20Group&logo=telegram&cacheSeconds=3600&style=flat-square)](https://t.me/rsshub) [![Telegram channel](https://img.shields.io/badge/dynamic/json?url=https%3A%2F%2Fapi.swo.moe%2Fstats%2Ftelegram%2FawesomeRSSHub&query=count&color=2CA5E0&label=Telegram%20Channel&logo=telegram&cacheSeconds=3600&style=flat-square)](https://t.me/awesomeRSSHub) [![Twitter](https://img.shields.io/badge/any_text-Follow-blue?color=2CA5E0&label=Twitter&logo=twitter&cacheSeconds=3600&style=flat-square)](https://x.com/intent/follow?screen_name=_RSSHub)
## Introduction
@@ -21,18 +21,10 @@ RSSHub delivers millions of contents aggregated from all kinds of sources, our v
RSSHub can be used with browser extension [RSSHub Radar](https://github.com/DIYgod/RSSHub-Radar) and mobile auxiliary app [RSSBud](https://github.com/Cay-Zhang/RSSBud) (iOS) and [RSSAid](https://github.com/LeetaoGoooo/RSSAid) (Android)
-[English docs](https://docs.rsshub.app) | [Telegram Group](https://t.me/rsshub) | [Telegram Channel](https://t.me/awesomeRSSHub) | [Twitter](https://twitter.com/intent/follow?screen_name=_RSSHub) | [中文文档](https://docs.rsshub.app/zh/)
+[English docs](https://docs.rsshub.app) | [Telegram Group](https://t.me/rsshub) | [Telegram Channel](https://t.me/awesomeRSSHub) | [Twitter](https://x.com/intent/follow?screen_name=_RSSHub) | [中文文档](https://docs.rsshub.app/zh/)
## Special Thanks
-### Special Sponsors
-
-
-
-
-
-[![](https://opencollective.com/static/images/become_sponsor.svg)](https://docs.rsshub.app/sponsor/)
-
### Contributors
[![](https://opencollective.com/RSSHub/contributors.svg?width=890)](https://github.com/DIYgod/RSSHub/graphs/contributors)
@@ -99,4 +91,4 @@ Open source is a very expensive thing. RSSHub would not be possible without the
**RSSHub** © [DIYgod](https://github.com/DIYgod), Released under the [MIT](./LICENSE) License.
Authored and maintained by DIYgod with help from contributors ([list](https://github.com/DIYgod/RSSHub/contributors)).
-> Blog [@DIYgod](https://diygod.cc) · GitHub [@DIYgod](https://github.com/DIYgod) · Twitter [@DIYgod](https://twitter.com/DIYgod) · Telegram Channel [@awesomeDIYgod](https://t.me/awesomeDIYgod)
+> Blog [@DIYgod](https://diygod.cc) · GitHub [@DIYgod](https://github.com/DIYgod) · Twitter [@DIYgod](https://x.com/DIYgod) · Telegram Channel [@awesomeDIYgod](https://t.me/awesomeDIYgod)
diff --git a/lib/routes-deprecated/universities/bjtu/gs/index.js b/lib/routes-deprecated/universities/bjtu/gs/index.js
deleted file mode 100644
index 742c56bb985fa7..00000000000000
--- a/lib/routes-deprecated/universities/bjtu/gs/index.js
+++ /dev/null
@@ -1,130 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-
-module.exports = async (ctx) => {
- const type = ctx.params.type;
- const struct = {
- zs: {
- selector: {
- list: '.mainleft_box li',
- },
- url: 'https://gs.bjtu.edu.cn/cms/zszt/item/?tag=1',
- name: '招生 - 北京交通大学研究生院',
- },
- noti: {
- selector: {
- list: '.tab-content li',
- },
- url: 'https://gs.bjtu.edu.cn/cms/item/?tag=2',
- name: '通知公告 - 北京交通大学研究生院',
- },
- news: {
- selector: {
- list: '.tab-content li',
- },
- url: 'https://gs.bjtu.edu.cn/cms/item/?tag=3',
- name: '新闻动态 - 北京交通大学研究生院',
- },
- zsxc: {
- selector: {
- list: '.tab-content li',
- },
- url: 'https://gs.bjtu.edu.cn/cms/item/?tag=4',
- name: '招生宣传 - 北京交通大学研究生院',
- },
- py: {
- selector: {
- list: '.tab-content li',
- },
- url: 'https://gs.bjtu.edu.cn/cms/item/?tag=5',
- name: '培养 - 北京交通大学研究生院',
- },
- xw: {
- selector: {
- list: '.tab-content li',
- },
- url: 'https://gs.bjtu.edu.cn/cms/item/?tag=7',
- name: '学位 - 北京交通大学研究生院',
- },
- ygbtzgg: {
- selector: {
- list: '.tab-content li',
- },
- url: 'https://gs.bjtu.edu.cn/cms/item/?tag=9',
- name: '通知公告 - 研工部 - 北京交通大学研究生院',
- },
- ygbnews: {
- selector: {
- list: '.tab-content li',
- },
- url: 'https://gs.bjtu.edu.cn/cms/item/?tag=10',
- name: '新闻动态 - 研工部 - 北京交通大学研究生院',
- },
- all: {
- selector: {
- list: '.tab-content li',
- },
- url: 'https://gs.bjtu.edu.cn/cms/item/?tag=12',
- name: '所有文章 - 北京交通大学研究生院',
- },
- bszs: {
- selector: {
- list: '.mainleft_box li',
- },
- url: 'https://gs.bjtu.edu.cn/cms/zszt/item/?cat=2',
- name: '博士招生 - 北京交通大学研究生院',
- },
- sszs: {
- selector: {
- list: '.mainleft_box li',
- },
- url: 'https://gs.bjtu.edu.cn/cms/zszt/item/?cat=3',
- name: '硕士招生 - 北京交通大学研究生院',
- },
- zsjz: {
- selector: {
- list: '.mainleft_box li',
- },
- url: 'https://gs.bjtu.edu.cn/cms/zszt/item/?cat=4',
- name: '招生简章 - 北京交通大学研究生院',
- },
- zcfg: {
- selector: {
- list: '.mainleft_box li',
- },
- url: 'https://gs.bjtu.edu.cn/cms/zszt/item/?cat=5',
- name: '政策法规 - 北京交通大学研究生院',
- },
- };
-
- const url = struct[type].url;
- const response = await got({
- method: 'get',
- url,
- });
-
- const data = response.data;
-
- const $ = cheerio.load(data);
- const list = $(struct[type].selector.list);
-
- ctx.state.data = {
- title: struct[type].name,
- link: url,
- description: '北京交通大学研究生院',
- item:
- list &&
- list
- .map((index, item) => {
- item = $(item);
- const date = new Date(Date.parse(item.find('li span').text().slice(1, 11).replaceAll('-', '/')));
- const bj_date = date.getTime() / 1000 + 8 * 60 * 60;
- const title = item
- .find('li a')
- .text()
- .replaceAll(/\[.*?]/g, '');
- return { title, description: title, link: item.find('li a').attr('href'), pubDate: new Date(Number.parseInt(bj_date) * 1000) };
- })
- .get(),
- };
-};
diff --git a/lib/routes/apnews/rss.ts b/lib/routes/apnews/rss.ts
index edf24f65b74bec..3b5f3cc8f0576d 100644
--- a/lib/routes/apnews/rss.ts
+++ b/lib/routes/apnews/rss.ts
@@ -5,7 +5,7 @@ const HOME_PAGE = 'https://apnews.com';
export const route: Route = {
path: '/rss/:rss?',
- categories: ['traditional-media'],
+ categories: ['traditional-media', 'popular'],
example: '/apnews/rss/business',
parameters: { rss: 'Route name from the first segment of the corresponding site, or `index` for the front page(default).' },
features: {
diff --git a/lib/routes/bilibili/dynamic.ts b/lib/routes/bilibili/dynamic.ts
index 487a41e53aafa8..8ec42a6ed1a2c8 100644
--- a/lib/routes/bilibili/dynamic.ts
+++ b/lib/routes/bilibili/dynamic.ts
@@ -10,7 +10,7 @@ import { BilibiliWebDynamicResponse, Item2, Modules } from './api-interface';
export const route: Route = {
path: '/user/dynamic/:uid/:routeParams?',
- categories: ['social-media'],
+ categories: ['social-media', 'popular'],
example: '/bilibili/user/dynamic/2267573',
parameters: { uid: '用户 id, 可在 UP 主主页中找到', routeParams: '额外参数;请参阅以下说明和表格' },
features: {
diff --git a/lib/routes/bilibili/ranking.ts b/lib/routes/bilibili/ranking.ts
index 800ecbb3a43255..a2c1967804b252 100644
--- a/lib/routes/bilibili/ranking.ts
+++ b/lib/routes/bilibili/ranking.ts
@@ -6,7 +6,7 @@ export const route: Route = {
path: '/ranking/:rid?/:day?/:arc_type?/:disableEmbed?',
name: '排行榜',
maintainers: ['DIYgod'],
- categories: ['social-media'],
+ categories: ['social-media', 'popular'],
example: '/bilibili/ranking/0/3/1',
parameters: {
rid: '排行榜分区 id, 默认 0',
diff --git a/lib/routes/bilibili/video.ts b/lib/routes/bilibili/video.ts
index 8c8a7d5ed1e044..7059a2a1870b50 100644
--- a/lib/routes/bilibili/video.ts
+++ b/lib/routes/bilibili/video.ts
@@ -6,7 +6,7 @@ import logger from '@/utils/logger';
export const route: Route = {
path: '/user/video/:uid/:disableEmbed?',
- categories: ['social-media'],
+ categories: ['social-media', 'popular'],
example: '/bilibili/user/video/2267573',
parameters: { uid: '用户 id, 可在 UP 主主页中找到', disableEmbed: '默认为开启内嵌视频, 任意值为关闭' },
features: {
diff --git a/lib/routes/bjtu/gs.ts b/lib/routes/bjtu/gs.ts
new file mode 100644
index 00000000000000..833eae04dd8939
--- /dev/null
+++ b/lib/routes/bjtu/gs.ts
@@ -0,0 +1,224 @@
+import { Route } from '@/types';
+import cache from '@/utils/cache';
+import ofetch from '@/utils/ofetch';
+import { load } from 'cheerio';
+import { parseDate } from '@/utils/parse-date';
+
+const rootURL = 'https://gs.bjtu.edu.cn';
+const urlCms = `${rootURL}/cms/item/?tag=`;
+const urlZszt = `${rootURL}/cms/zszt/item/?cat=`;
+const title = ' - 北京交通大学研究生院';
+const zsztRegex = /_zszt/;
+const struct = {
+ noti_zs: {
+ selector: {
+ list: '.tab-content li',
+ },
+ tag: 1,
+ name: '通知公告_招生',
+ },
+ noti: {
+ selector: {
+ list: '.tab-content li',
+ },
+ tag: 2,
+ name: '通知公告',
+ },
+ news: {
+ selector: {
+ list: '.tab-content li',
+ },
+ tag: 3,
+ name: '新闻动态',
+ },
+ zsxc: {
+ selector: {
+ list: '.tab-content li',
+ },
+ tag: 4,
+ name: '招生宣传',
+ },
+ py: {
+ selector: {
+ list: '.tab-content li',
+ },
+ tag: 5,
+ name: '培养',
+ },
+ zs: {
+ selector: {
+ list: '.tab-content li',
+ },
+ tag: 6,
+ name: '招生',
+ },
+ xw: {
+ selector: {
+ list: '.tab-content li',
+ },
+ tag: 7,
+ name: '学位',
+ },
+ ygb: {
+ selector: {
+ list: '.tab-content li',
+ },
+ tag: 8,
+ name: '研工部',
+ },
+ ygbtzgg: {
+ selector: {
+ list: '.tab-content li',
+ },
+ tag: 9,
+ name: '通知公告 - 研工部',
+ },
+ ygbnews: {
+ selector: {
+ list: '.tab-content li',
+ },
+ tag: 10,
+ name: '新闻动态 - 研工部',
+ },
+ ygbnewscover: {
+ selector: {
+ list: '.tab-content li',
+ },
+ tag: 11,
+ name: '新闻封面 - 研工部',
+ },
+ all: {
+ selector: {
+ list: '.tab-content li',
+ },
+ tag: 12,
+ name: '文章列表',
+ },
+ bszs_zszt: {
+ selector: {
+ list: '.mainleft_box li',
+ },
+ tag: 2,
+ name: '博士招生 - 招生专题',
+ },
+ sszs_zszt: {
+ selector: {
+ list: '.mainleft_box li',
+ },
+ tag: 3,
+ name: '硕士招生 - 招生专题',
+ },
+ zsjz_zszt: {
+ selector: {
+ list: '.mainleft_box li',
+ },
+ tag: 4,
+ name: '招生简章 - 招生专题',
+ },
+ zcfg_zszt: {
+ selector: {
+ list: '.mainleft_box li',
+ },
+ tag: 5,
+ name: '政策法规 - 招生专题',
+ },
+};
+
+const getItem = (item, selector) => {
+ const newsInfo = item.find('a');
+ const newsDate = item
+ .find('span')
+ .text()
+ .match(/\d{4}(-|\/|.)\d{1,2}\1\d{1,2}/)[0];
+
+ const infoTitle = newsInfo.text();
+ const link = rootURL + newsInfo.attr('href');
+ return cache.tryGet(link, async () => {
+ const resp = await ofetch(link);
+ const $$ = load(resp);
+ const infoText = $$(selector).html();
+
+ return {
+ title: infoTitle,
+ pubDate: parseDate(newsDate),
+ link,
+ description: infoText,
+ };
+ }) as any;
+};
+
+export const route: Route = {
+ path: '/gs/:type?',
+ categories: ['university'],
+ example: '/bjtu/gs/noti',
+ parameters: { type: 'Article type' },
+ features: {
+ requireConfig: false,
+ requirePuppeteer: false,
+ antiCrawler: true,
+ supportBT: false,
+ supportPodcast: false,
+ supportScihub: false,
+ },
+ radar: [
+ {
+ source: ['gs.bjtu.edu.cn'],
+ },
+ ],
+ name: '研究生院',
+ maintainers: ['E1nzbern'],
+ handler,
+ description: `
+ | 文章来源 | 参数 |
+ | ----------------- | ------------ |
+ | 通知公告_招生 | noti_zs |
+ | 通知公告 | noti |
+ | 新闻动态 | news |
+ | 招生宣传 | zsxc |
+ | 培养 | py |
+ | 招生 | zs |
+ | 学位 | xw |
+ | 研工部 | ygb |
+ | 通知公告 - 研工部 | ygbtzgg |
+ | 新闻动态 - 研工部 | ygbnews |
+ | 新闻封面 - 研工部 | ygbnewscover |
+ | 文章列表 | all |
+ | 博士招生 - 招生专题 | bszs_zszt |
+ | 硕士招生 - 招生专题 | sszs_zszt |
+ | 招生简章 - 招生专题 | zsjz_zszt |
+ | 政策法规 - 招生专题 | zcfg_zszt |
+
+ :::tip 文章来源
+ 文章来源的命名均来自研究生院网站标题。
+ 最常用的几项有“通知公告_招生”、“通知公告”、“博士招生 - 招生专题”、“硕士招生 - 招生专题”。
+ :::`,
+};
+
+async function handler(ctx) {
+ const { type = 'noti' } = ctx.req.param();
+ let url = urlCms;
+ let selectorArticle = 'div.main_left.main_left_list';
+ if (zsztRegex.test(type)) {
+ url = urlZszt;
+ selectorArticle = 'div.mainleft_box';
+ }
+ const urlAddr = `${url}${struct[type].tag}`;
+ const resp = await ofetch(urlAddr);
+ const $ = load(resp);
+
+ const list = $(struct[type].selector.list);
+
+ const items = await Promise.all(
+ list.toArray().map((i) => {
+ const item = $(i);
+ return getItem(item, selectorArticle);
+ })
+ );
+
+ return {
+ title: `${struct[type].name}${title}`,
+ link: urlAddr,
+ item: items,
+ allowEmpty: true,
+ };
+}
diff --git a/lib/routes/bjtu/namespace.ts b/lib/routes/bjtu/namespace.ts
new file mode 100644
index 00000000000000..74f3a9a242c099
--- /dev/null
+++ b/lib/routes/bjtu/namespace.ts
@@ -0,0 +1,8 @@
+import type { Namespace } from '@/types';
+export const namespace: Namespace = {
+ name: 'Beijing Jiaotong University',
+ url: 'bjtu.edu.cn',
+ zh: {
+ name: '北京交通大学',
+ },
+};
diff --git a/lib/routes/dockerhub/build.ts b/lib/routes/dockerhub/build.ts
index ebbc86d8a0636f..3b3d432b18d9c9 100644
--- a/lib/routes/dockerhub/build.ts
+++ b/lib/routes/dockerhub/build.ts
@@ -4,7 +4,7 @@ import { hash } from './utils';
export const route: Route = {
path: '/build/:owner/:image/:tag?',
- categories: ['program-update'],
+ categories: ['program-update', 'popular'],
example: '/dockerhub/build/wangqiru/ttrss',
parameters: { owner: 'Image owner', image: 'Image name', tag: 'Image tag,default to latest' },
features: {
diff --git a/lib/routes/douban/other/group.ts b/lib/routes/douban/other/group.ts
index d7105995112bfb..5360275fdd4e01 100644
--- a/lib/routes/douban/other/group.ts
+++ b/lib/routes/douban/other/group.ts
@@ -5,7 +5,7 @@ import { load } from 'cheerio';
export const route: Route = {
path: '/group/:groupid/:type?',
- categories: ['social-media'],
+ categories: ['social-media', 'popular'],
example: '/douban/group/648102',
parameters: { groupid: '豆瓣小组的 id', type: '缺省 最新,essence 最热,elite 精华' },
features: {
diff --git a/lib/routes/github/issue.ts b/lib/routes/github/issue.ts
index 6f39650c9360d6..1d6eb384acb53c 100644
--- a/lib/routes/github/issue.ts
+++ b/lib/routes/github/issue.ts
@@ -11,7 +11,7 @@ import { parseDate } from '@/utils/parse-date';
export const route: Route = {
path: '/issue/:user/:repo/:state?/:labels?',
- categories: ['programming'],
+ categories: ['programming', 'popular'],
example: '/github/issue/vuejs/core/all/wontfix',
parameters: { user: 'GitHub username', repo: 'GitHub repo name', state: 'the state of the issues. Can be either `open`, `closed`, or `all`. Default: `open`.', labels: 'a list of comma separated label names' },
radar: [
diff --git a/lib/routes/instagram/private-api/index.ts b/lib/routes/instagram/private-api/index.ts
index b42a8beda7752c..137c873f696762 100644
--- a/lib/routes/instagram/private-api/index.ts
+++ b/lib/routes/instagram/private-api/index.ts
@@ -58,7 +58,7 @@ async function loadContent(category, nameOrId, tryGet) {
export const route: Route = {
path: '/:category/:key',
- categories: ['social-media'],
+ categories: ['social-media', 'popular'],
example: '/instagram/user/stefaniejoosten',
parameters: { category: 'Feed category, see table above', key: 'Username / Hashtag name' },
features: {
diff --git a/lib/routes/javbus/index.ts b/lib/routes/javbus/index.ts
index 37ed73efa21bd7..c2ff9015ff2d05 100644
--- a/lib/routes/javbus/index.ts
+++ b/lib/routes/javbus/index.ts
@@ -20,17 +20,18 @@ const toSize = (raw) => {
const allowDomain = new Set(['javbus.com', 'javbus.org', 'javsee.icu', 'javsee.one']);
export const route: Route = {
- path: '*',
+ path: '/:path{.+}?',
radar: [
{
- source: ['www.seejav.pw/'],
- target: '',
+ source: ['www.javbus.com/:path*'],
+ target: '/:path',
},
],
- name: 'Unknown',
- maintainers: [],
+ name: 'Works',
+ maintainers: ['MegrezZhu', 'CoderTonyChan', 'nczitzk', 'Felix2yu'],
+ categories: ['multimedia', 'popular'],
handler,
- url: 'www.seejav.pw/',
+ url: 'www.javbus.com',
};
async function handler(ctx) {
diff --git a/lib/routes/jike/topic.ts b/lib/routes/jike/topic.ts
index d1b84bd0b91520..88382b42e580e7 100644
--- a/lib/routes/jike/topic.ts
+++ b/lib/routes/jike/topic.ts
@@ -9,7 +9,7 @@ const urlRegex = /(https?:\/\/[^\s"'<>]+)/g;
export const route: Route = {
path: '/topic/:id/:showUid?',
- categories: ['social-media'],
+ categories: ['social-media', 'popular'],
example: '/jike/topic/556688fae4b00c57d9dd46ee',
parameters: { id: '圈子 id, 可在即刻 web 端圈子页或 APP 分享出来的圈子页 URL 中找到', showUid: '是否在内容中显示用户信息,设置为 1 则开启' },
features: {
diff --git a/lib/routes/jike/user.ts b/lib/routes/jike/user.ts
index 42441a9ac0925c..d2736d10e806f4 100644
--- a/lib/routes/jike/user.ts
+++ b/lib/routes/jike/user.ts
@@ -5,7 +5,7 @@ import { parseDate } from '@/utils/parse-date';
export const route: Route = {
path: '/user/:id',
- categories: ['social-media'],
+ categories: ['social-media', 'popular'],
example: '/jike/user/3EE02BC9-C5B3-4209-8750-4ED1EE0F67BB',
parameters: { id: '用户 id, 可在即刻分享出来的单条动态页点击用户头像进入个人主页,然后在个人主页的 URL 中找到,或者在单条动态页使用 RSSHub Radar 插件' },
features: {
diff --git a/lib/routes/lofter/user.ts b/lib/routes/lofter/user.ts
index 65cc415f051356..a9f0a6dc1b8db0 100644
--- a/lib/routes/lofter/user.ts
+++ b/lib/routes/lofter/user.ts
@@ -6,7 +6,7 @@ import { isValidHost } from '@/utils/valid-host';
export const route: Route = {
path: '/user/:name?',
- categories: ['social-media'],
+ categories: ['social-media', 'popular'],
example: '/lofter/user/i',
parameters: { name: 'Lofter user name, can be found in the URL' },
features: {
diff --git a/lib/routes/pixiv/ranking.ts b/lib/routes/pixiv/ranking.ts
index 2b231df377e318..4c70dd3d3a0d53 100644
--- a/lib/routes/pixiv/ranking.ts
+++ b/lib/routes/pixiv/ranking.ts
@@ -60,7 +60,7 @@ const alias = {
export const route: Route = {
path: '/ranking/:mode/:date?',
- categories: ['social-media'],
+ categories: ['social-media', 'popular'],
example: '/pixiv/ranking/week',
parameters: { mode: 'rank type', date: 'format: `2018-4-25`' },
features: {
diff --git a/lib/routes/pixiv/search.ts b/lib/routes/pixiv/search.ts
index 8d9dda5fa73b0b..3823ae1d023397 100644
--- a/lib/routes/pixiv/search.ts
+++ b/lib/routes/pixiv/search.ts
@@ -10,7 +10,7 @@ import ConfigNotFoundError from '@/errors/types/config-not-found';
export const route: Route = {
path: '/search/:keyword/:order?/:mode?',
- categories: ['social-media'],
+ categories: ['social-media', 'popular'],
example: '/pixiv/search/Nezuko/popular/2',
parameters: { keyword: 'keyword', order: 'rank mode, empty or other for time order, popular for popular order', mode: 'filte R18 content' },
features: {
diff --git a/lib/routes/pixiv/user.ts b/lib/routes/pixiv/user.ts
index 08243ad2e38c33..2678c1aa85c06a 100644
--- a/lib/routes/pixiv/user.ts
+++ b/lib/routes/pixiv/user.ts
@@ -9,7 +9,7 @@ import ConfigNotFoundError from '@/errors/types/config-not-found';
export const route: Route = {
path: '/user/:id',
- categories: ['social-media'],
+ categories: ['social-media', 'popular'],
example: '/pixiv/user/15288095',
parameters: { id: "user id, available in user's homepage URL" },
features: {
diff --git a/lib/routes/rsshub/routes.ts b/lib/routes/rsshub/routes.ts
index 26e4cb9af04814..f755d8de2e824a 100644
--- a/lib/routes/rsshub/routes.ts
+++ b/lib/routes/rsshub/routes.ts
@@ -4,7 +4,7 @@ import { load } from 'cheerio';
export const route: Route = {
path: '/routes/:lang?',
- categories: ['program-update'],
+ categories: ['program-update', 'popular'],
example: '/rsshub/routes/en',
parameters: { lang: 'Language, `zh` means Chinese docs, other values or null means English docs, `en` by default' },
radar: [
diff --git a/lib/routes/sehuatang/user.ts b/lib/routes/sehuatang/user.ts
index 7046f2f933e64a..26dd329f21cb56 100644
--- a/lib/routes/sehuatang/user.ts
+++ b/lib/routes/sehuatang/user.ts
@@ -11,7 +11,7 @@ const baseUrl = 'https://sehuatang.org/';
export const route: Route = {
path: '/user/:uid',
- categories: ['multimedia'],
+ categories: ['multimedia', 'popular'],
example: '/sehuatang/user/411096',
parameters: { uid: '用户 uid, 可在用户主页 URL 中找到' },
features: {
diff --git a/lib/routes/swjtu/gsee/yjs.ts b/lib/routes/swjtu/gsee/yjs.ts
new file mode 100644
index 00000000000000..4c747778c3815e
--- /dev/null
+++ b/lib/routes/swjtu/gsee/yjs.ts
@@ -0,0 +1,76 @@
+import { Route } from '@/types';
+import cache from '@/utils/cache';
+import ofetch from '@/utils/ofetch';
+import { load } from 'cheerio';
+import { parseDate } from '@/utils/parse-date';
+
+const rootURL = 'https://gsee.swjtu.edu.cn';
+const urlAddr = `${rootURL}/xwzx/tzgg.htm`;
+
+const getItem = (item) => {
+ const newsInfo = item.find('dt');
+ const newsDate = item
+ .find('dd')
+ .text()
+ .match(/\d{4}(-|\/|.)\d{1,2}\1\d{1,2}/)[0];
+
+ const infoTitle = newsInfo.text();
+ const link = rootURL + newsInfo.find('a').last().attr('href').slice(2);
+ return cache.tryGet(link, async () => {
+ const resp = await ofetch(link);
+ const $$ = load(resp);
+ const infoText = $$('.article').html();
+
+ return {
+ title: infoTitle,
+ pubDate: parseDate(newsDate),
+ link,
+ description: infoText,
+ };
+ }) as any;
+};
+
+export const route: Route = {
+ path: '/gsee/yjs',
+ categories: ['university'],
+ example: '/swjtu/gsee/yjs',
+ parameters: {},
+ features: {
+ requireConfig: false,
+ requirePuppeteer: false,
+ antiCrawler: true,
+ supportBT: false,
+ supportPodcast: false,
+ supportScihub: false,
+ },
+ radar: [
+ {
+ source: ['gsee.swjtu.edu.cn/'],
+ },
+ ],
+ name: '地球科学与工程学院',
+ maintainers: ['E1nzbern'],
+ handler,
+ description: `研究生教育通知公告`,
+};
+
+async function handler() {
+ const resp = await ofetch(urlAddr);
+ const $ = load(resp);
+
+ const list = $('dl');
+
+ const items = await Promise.all(
+ list.toArray().map((i) => {
+ const item = $(i);
+ return getItem(item);
+ })
+ );
+
+ return {
+ title: '西南交大地学学院-研究生通知',
+ link: urlAddr,
+ item: items,
+ allowEmpty: true,
+ };
+}
diff --git a/lib/routes/telegram/channel.ts b/lib/routes/telegram/channel.ts
index ea7c3bdfa8c561..b36b5670537129 100644
--- a/lib/routes/telegram/channel.ts
+++ b/lib/routes/telegram/channel.ts
@@ -57,7 +57,7 @@ const mediaTagDict = {
export const route: Route = {
path: '/channel/:username/:routeParams?',
- categories: ['social-media'],
+ categories: ['social-media', 'popular'],
example: '/telegram/channel/awesomeDIYgod/searchQuery=twitter',
parameters: { username: 'channel username', routeParams: 'extra parameters, see the table below' },
features: {
diff --git a/lib/routes/twitter/api/developer-api/search.ts b/lib/routes/twitter/api/developer-api/search.ts
index 5a9fc81b47ee1d..484b93cd115b41 100644
--- a/lib/routes/twitter/api/developer-api/search.ts
+++ b/lib/routes/twitter/api/developer-api/search.ts
@@ -13,7 +13,7 @@ const handler = async (ctx) => {
return {
title: `Twitter Keyword - ${keyword}`,
- link: `https://twitter.com/search?q=${encodeURIComponent(keyword)}`,
+ link: `https://x.com/search?q=${encodeURIComponent(keyword)}`,
item: utils.ProcessFeed(ctx, {
data: data.statuses,
}),
diff --git a/lib/routes/twitter/api/developer-api/user.ts b/lib/routes/twitter/api/developer-api/user.ts
index 2d94a7165533f6..94954de30d982b 100644
--- a/lib/routes/twitter/api/developer-api/user.ts
+++ b/lib/routes/twitter/api/developer-api/user.ts
@@ -27,7 +27,7 @@ const handler = async (ctx) => {
return {
title: `Twitter @${userInfo.name}`,
- link: `https://twitter.com/${screen_name}`,
+ link: `https://x.com/${screen_name}`,
image: profileImageUrl,
description: userInfo.description,
item: utils.ProcessFeed(ctx, {
diff --git a/lib/routes/twitter/api/mobile-api/api.ts b/lib/routes/twitter/api/mobile-api/api.ts
index 199f21c6e217a8..1d6d26cb38af47 100644
--- a/lib/routes/twitter/api/mobile-api/api.ts
+++ b/lib/routes/twitter/api/mobile-api/api.ts
@@ -28,7 +28,7 @@ const twitterGot = async (url, params) => {
connection: 'keep-alive',
'content-type': 'application/json',
'x-twitter-active-user': 'yes',
- authority: 'api.twitter.com',
+ authority: 'api.x.com',
'accept-encoding': 'gzip',
'accept-language': 'en-US,en;q=0.9',
accept: '*/*',
diff --git a/lib/routes/twitter/api/mobile-api/constants.ts b/lib/routes/twitter/api/mobile-api/constants.ts
index c4bedb05fb169c..cd9b92bbbf36a4 100644
--- a/lib/routes/twitter/api/mobile-api/constants.ts
+++ b/lib/routes/twitter/api/mobile-api/constants.ts
@@ -1,4 +1,4 @@
-const baseUrl = 'https://api.twitter.com';
+const baseUrl = 'https://api.x.com';
const consumerKey = '3nVuSoBZnx6U4vzUxf5w';
const consumerSecret = 'Bcs59EFbbsdF6Sl9Ng71smgStWEGwXXKSjYvPVt7qys';
diff --git a/lib/routes/twitter/api/mobile-api/login.ts b/lib/routes/twitter/api/mobile-api/login.ts
index fe7feb9a3cc2f0..3bf1ac688fff5f 100644
--- a/lib/routes/twitter/api/mobile-api/login.ts
+++ b/lib/routes/twitter/api/mobile-api/login.ts
@@ -51,7 +51,7 @@ async function login() {
headers['x-guest-token'] = guestToken.data.guest_token;
const task1 = await ofetch.raw(
- 'https://api.twitter.com/1.1/onboarding/task.json?' +
+ 'https://api.x.com/1.1/onboarding/task.json?' +
new URLSearchParams({
flow_name: 'login',
api_version: '1',
@@ -84,7 +84,7 @@ async function login() {
headers.att = task1.headers.get('att');
- const task2 = await got.post('https://api.twitter.com/1.1/onboarding/task.json', {
+ const task2 = await got.post('https://api.x.com/1.1/onboarding/task.json', {
headers,
json: {
flow_token: task1._data.flow_token,
@@ -102,7 +102,7 @@ async function login() {
});
logger.debug('Twitter login 3 finished: LoginEnterUserIdentifier.');
- const task3 = await got.post('https://api.twitter.com/1.1/onboarding/task.json', {
+ const task3 = await got.post('https://api.x.com/1.1/onboarding/task.json', {
headers,
json: {
flow_token: task2.data.flow_token,
@@ -119,7 +119,7 @@ async function login() {
});
logger.debug('Twitter login 4 finished: LoginEnterPassword.');
- const task4 = await got.post('https://api.twitter.com/1.1/onboarding/task.json', {
+ const task4 = await got.post('https://api.x.com/1.1/onboarding/task.json', {
headers,
json: {
flow_token: task3.data.flow_token,
@@ -142,7 +142,7 @@ async function login() {
} else if (subtask.subtask_id === 'LoginTwoFactorAuthChallenge') {
const token = authenticator.generate(authenticationSecret);
- const task5 = await got.post('https://api.twitter.com/1.1/onboarding/task.json', {
+ const task5 = await got.post('https://api.x.com/1.1/onboarding/task.json', {
headers,
json: {
flow_token: task4.data.flow_token,
diff --git a/lib/routes/twitter/api/web-api/constants.ts b/lib/routes/twitter/api/web-api/constants.ts
index f0500752ea5b47..dc4a2f2a80b55f 100644
--- a/lib/routes/twitter/api/web-api/constants.ts
+++ b/lib/routes/twitter/api/web-api/constants.ts
@@ -1,4 +1,4 @@
-const baseUrl = 'https://twitter.com/i/api';
+const baseUrl = 'https://x.com/i/api';
const graphQLEndpointsPlain = [
'/graphql/eS7LO5Jy3xgmd3dbL044EA/UserTweets',
diff --git a/lib/routes/twitter/api/web-api/utils.ts b/lib/routes/twitter/api/web-api/utils.ts
index 7cf210f5b84c31..20bdd99633906c 100644
--- a/lib/routes/twitter/api/web-api/utils.ts
+++ b/lib/routes/twitter/api/web-api/utils.ts
@@ -23,7 +23,7 @@ export const twitterGot = async (url, params) => {
url: `${url}?${queryString.stringify(params)}`,
method: 'GET',
headers: {
- authority: 'twitter.com',
+ authority: 'x.com',
accept: '*/*',
'accept-language': 'en-US,en;q=0.9',
authorization: bearerToken,
@@ -32,7 +32,7 @@ export const twitterGot = async (url, params) => {
cookie: config.twitter.cookie,
dnt: '1',
pragma: 'no-cache',
- referer: 'https://twitter.com/narendramodi',
+ referer: 'https://x.com/narendramodi',
'x-csrf-token': jsonCookie.ct0,
'x-twitter-active-user': 'yes',
'x-twitter-auth-type': 'OAuth2Session',
diff --git a/lib/routes/twitter/home.ts b/lib/routes/twitter/home.ts
index 4b8b1254c9c7b9..f666a2e191a3ce 100644
--- a/lib/routes/twitter/home.ts
+++ b/lib/routes/twitter/home.ts
@@ -32,7 +32,7 @@ export const route: Route = {
handler,
radar: [
{
- source: ['twitter.com/home'],
+ source: ['x.com/home'],
target: '/home',
},
],
@@ -51,7 +51,7 @@ async function handler(ctx) {
return {
title: `Twitter following timeline`,
- link: `https://twitter.com/home`,
+ link: `https://x.com/home`,
// description: userInfo?.description,
item: utils.ProcessFeed(ctx, {
data,
diff --git a/lib/routes/twitter/keyword.ts b/lib/routes/twitter/keyword.ts
index 2954a0ab6b5cdb..d458989879123e 100644
--- a/lib/routes/twitter/keyword.ts
+++ b/lib/routes/twitter/keyword.ts
@@ -4,7 +4,7 @@ import utils from './utils';
export const route: Route = {
path: '/keyword/:keyword/:routeParams?',
- categories: ['social-media'],
+ categories: ['social-media', 'popular'],
example: '/twitter/keyword/RSSHub',
parameters: { keyword: 'keyword', routeParams: 'extra parameters, see the table above' },
features: {
@@ -33,7 +33,7 @@ export const route: Route = {
handler,
radar: [
{
- source: ['twitter.com/search'],
+ source: ['x.com/search'],
},
],
};
@@ -45,7 +45,7 @@ async function handler(ctx) {
return {
title: `Twitter Keyword - ${keyword}`,
- link: `https://twitter.com/search?q=${encodeURIComponent(keyword)}`,
+ link: `https://x.com/search?q=${encodeURIComponent(keyword)}`,
item: utils.ProcessFeed(ctx, {
data,
}),
diff --git a/lib/routes/twitter/likes.ts b/lib/routes/twitter/likes.ts
index 27d1c013f96a25..b14677d3996531 100644
--- a/lib/routes/twitter/likes.ts
+++ b/lib/routes/twitter/likes.ts
@@ -38,7 +38,7 @@ async function handler(ctx) {
return {
title: `Twitter Likes - ${id}`,
- link: `https://twitter.com/${id}/likes`,
+ link: `https://x.com/${id}/likes`,
item: utils.ProcessFeed(ctx, {
data,
}),
diff --git a/lib/routes/twitter/list.ts b/lib/routes/twitter/list.ts
index 645c17c0cc8018..af1250c0531855 100644
--- a/lib/routes/twitter/list.ts
+++ b/lib/routes/twitter/list.ts
@@ -33,7 +33,7 @@ export const route: Route = {
handler,
radar: [
{
- source: ['twitter.com/i/lists/:id'],
+ source: ['x.com/i/lists/:id'],
target: '/list/:id',
},
],
@@ -49,7 +49,7 @@ async function handler(ctx) {
return {
title: `Twitter List - ${id}`,
- link: `https://twitter.com/i/lists/${id}`,
+ link: `https://x.com/i/lists/${id}`,
item: utils.ProcessFeed(ctx, {
data,
}),
diff --git a/lib/routes/twitter/media.ts b/lib/routes/twitter/media.ts
index c43ad10c289f7d..979160dcf5ad9b 100644
--- a/lib/routes/twitter/media.ts
+++ b/lib/routes/twitter/media.ts
@@ -4,7 +4,7 @@ import utils from './utils';
export const route: Route = {
path: '/media/:id/:routeParams?',
- categories: ['social-media'],
+ categories: ['social-media', 'popular'],
example: '/twitter/media/DIYgod',
parameters: { id: 'username; in particular, if starts with `+`, it will be recognized as a [unique ID](https://github.com/DIYgod/RSSHub/issues/12221), e.g. `+44196397`', routeParams: 'extra parameters, see the table above.' },
features: {
@@ -33,7 +33,7 @@ export const route: Route = {
handler,
radar: [
{
- source: ['twitter.com/:id/media'],
+ source: ['x.com/:id/media'],
target: '/media/:id',
},
],
@@ -51,7 +51,7 @@ async function handler(ctx) {
return {
title: `Twitter @${userInfo?.name}`,
- link: `https://twitter.com/${userInfo?.screen_name}/media`,
+ link: `https://x.com/${userInfo?.screen_name}/media`,
image: profileImageUrl.replace(/_normal.jpg$/, '.jpg'),
description: userInfo?.description,
item: utils.ProcessFeed(ctx, {
diff --git a/lib/routes/twitter/namespace.ts b/lib/routes/twitter/namespace.ts
index 38f1269e0db080..6ef292d9273ba3 100644
--- a/lib/routes/twitter/namespace.ts
+++ b/lib/routes/twitter/namespace.ts
@@ -1,8 +1,8 @@
import type { Namespace } from '@/types';
export const namespace: Namespace = {
- name: 'Twitter',
- url: 'twitter.com',
+ name: 'X (Twitter)',
+ url: 'x.com',
description: `Specify options (in the format of query string) in parameter \`routeParams\` to control some extra features for Tweets
| Key | Description | Accepts | Defaults to |
diff --git a/lib/routes/twitter/trends.ts b/lib/routes/twitter/trends.ts
index 37d28812d45731..5bfb1d56e1310c 100644
--- a/lib/routes/twitter/trends.ts
+++ b/lib/routes/twitter/trends.ts
@@ -32,7 +32,7 @@ async function handler(ctx) {
return {
title: `Twitter Trends on ${data[0].locations[0].name}`,
- link: `https://twitter.com/i/trends`,
+ link: `https://x.com/i/trends`,
item: trends
.filter((t) => !t.promoted_content)
.map((t) => ({
diff --git a/lib/routes/twitter/tweet.ts b/lib/routes/twitter/tweet.ts
index 1883869ce5392c..d921e2dc25d892 100644
--- a/lib/routes/twitter/tweet.ts
+++ b/lib/routes/twitter/tweet.ts
@@ -57,7 +57,7 @@ async function handler(ctx) {
return {
title: `Twitter @${userInfo.name}`,
- link: `https://twitter.com/${userInfo.screen_name}/status/${status}`,
+ link: `https://x.com/${userInfo.screen_name}/status/${status}`,
image: profileImageUrl.replace(/_normal.jpg$/, '.jpg'),
description: userInfo.description,
item,
diff --git a/lib/routes/twitter/user.ts b/lib/routes/twitter/user.ts
index 6d78b8f152c191..7b35743991f35b 100644
--- a/lib/routes/twitter/user.ts
+++ b/lib/routes/twitter/user.ts
@@ -4,7 +4,7 @@ import api from './api';
export const route: Route = {
path: '/user/:id/:routeParams?',
- categories: ['social-media'],
+ categories: ['social-media', 'popular'],
example: '/twitter/user/DIYgod',
parameters: {
id: 'username; in particular, if starts with `+`, it will be recognized as a [unique ID](https://github.com/DIYgod/RSSHub/issues/12221), e.g. `+44196397`',
@@ -42,7 +42,7 @@ export const route: Route = {
handler,
radar: [
{
- source: ['twitter.com/:id'],
+ source: ['x.com/:id'],
target: '/user/:id',
},
],
@@ -66,7 +66,7 @@ async function handler(ctx) {
return {
title: `Twitter @${userInfo?.name}`,
- link: `https://twitter.com/${userInfo?.screen_name}`,
+ link: `https://x.com/${userInfo?.screen_name}`,
image: profileImageUrl.replace(/_normal.jpg$/, '.jpg'),
description: userInfo?.description,
item: utils.ProcessFeed(ctx, {
diff --git a/lib/routes/twitter/utils.ts b/lib/routes/twitter/utils.ts
index d6a8e3815d6ab8..5bd33ae3e1c7b8 100644
--- a/lib/routes/twitter/utils.ts
+++ b/lib/routes/twitter/utils.ts
@@ -114,7 +114,7 @@ const ProcessFeed = (ctx, { data = [] }, params = {}) => {
let img = '';
if (item.extended_entities) {
for (const media of item.extended_entities.media) {
- // https://developer.twitter.com/en/docs/tweets/data-dictionary/overview/extended-entities-object
+ // https://developer.x.com/en/docs/tweets/data-dictionary/overview/extended-entities-object
let content = '';
let style = '';
let originalImg;
@@ -211,7 +211,7 @@ const ProcessFeed = (ctx, { data = [] }, params = {}) => {
}
if (readable) {
- quote += ``;
+ quote += ``;
}
if (showQuotedAuthorAvatarInDesc) {
@@ -244,7 +244,7 @@ const ProcessFeed = (ctx, { data = [] }, params = {}) => {
quoteInTitle += `${author.name}: ${formatText(quoteData)}`;
if (readable) {
- quote += `
Link: https://twitter.com/${
+ quote += `
Link: https://x.com/${
author.screen_name
}/status/${quoteData.id_str || quoteData.conversation_id_str}`;
}
@@ -298,7 +298,7 @@ const ProcessFeed = (ctx, { data = [] }, params = {}) => {
if (showAuthorInDesc) {
if (readable) {
description += '';
- description += ``;
+ description += ``;
}
if (authorNameBold) {
description += ``;
@@ -316,7 +316,7 @@ const ProcessFeed = (ctx, { data = [] }, params = {}) => {
if (!showAuthorInDesc) {
description += ' ';
if (readable) {
- description += ``;
+ description += ``;
}
if (authorNameBold) {
description += ``;
@@ -336,7 +336,7 @@ const ProcessFeed = (ctx, { data = [] }, params = {}) => {
}
if (showAuthorInDesc) {
if (readable) {
- description += ``;
+ description += ``;
}
if (showAuthorAvatarInDesc) {
@@ -376,14 +376,15 @@ const ProcessFeed = (ctx, { data = [] }, params = {}) => {
const authorName = originalItem.user.name;
const link =
originalItem.user.screen_name && (originalItem.id_str || originalItem.conversation_id_str)
- ? `https://twitter.com/${originalItem.user.screen_name}/status/${originalItem.id_str || originalItem.conversation_id_str}`
- : `https://twitter.com/${item.user.screen_name}/status/${item.id_str || item.conversation_id_str}`;
+ ? `https://x.com/${originalItem.user.screen_name}/status/${originalItem.id_str || originalItem.conversation_id_str}`
+ : `https://x.com/${item.user.screen_name}/status/${item.id_str || item.conversation_id_str}`;
return {
title,
author: authorName,
description,
pubDate: parseDate(item.created_at),
link,
+ guid: link.replace('x.com', 'twitter.com'),
_extra:
(isRetweet && {
@@ -396,7 +397,7 @@ const ProcessFeed = (ctx, { data = [] }, params = {}) => {
(item.is_quote_status && {
links: [
{
- url: `https://twitter.com/${item.quoted_status?.user?.screen_name}/status/${item.quoted_status?.id_str || item.quoted_status?.conversation_id_str}`,
+ url: `https://x.com/${item.quoted_status?.user?.screen_name}/status/${item.quoted_status?.id_str || item.quoted_status?.conversation_id_str}`,
type: 'quote',
},
],
@@ -405,7 +406,7 @@ const ProcessFeed = (ctx, { data = [] }, params = {}) => {
item.in_reply_to_status_id_str && {
links: [
{
- url: `https://twitter.com/${item.in_reply_to_screen_name}/status/${item.in_reply_to_status_id_str}`,
+ url: `https://x.com/${item.in_reply_to_screen_name}/status/${item.in_reply_to_status_id_str}`,
type: 'reply',
},
],
diff --git a/lib/routes/weibo/keyword.ts b/lib/routes/weibo/keyword.ts
index df8b1b2cd27bab..8eb2619c3bfae2 100644
--- a/lib/routes/weibo/keyword.ts
+++ b/lib/routes/weibo/keyword.ts
@@ -9,7 +9,7 @@ import { config } from '@/config';
export const route: Route = {
path: '/keyword/:keyword/:routeParams?',
- categories: ['social-media'],
+ categories: ['social-media', 'popular'],
example: '/weibo/keyword/DIYgod',
parameters: { keyword: '你想订阅的微博关键词', routeParams: '额外参数;请参阅上面的说明和表格' },
features: {
diff --git a/lib/routes/weibo/user.ts b/lib/routes/weibo/user.ts
index 153baaad4fe494..07e508fb876655 100644
--- a/lib/routes/weibo/user.ts
+++ b/lib/routes/weibo/user.ts
@@ -10,7 +10,7 @@ import { fallback, queryToBoolean } from '@/utils/readable-social';
export const route: Route = {
path: '/user/:uid/:routeParams?',
- categories: ['social-media'],
+ categories: ['social-media', 'popular'],
example: '/weibo/user/1195230310',
parameters: { uid: '用户 id, 博主主页打开控制台执行 `$CONFIG.oid` 获取', routeParams: '额外参数;请参阅上面的说明和表格;特别地,当 `routeParams=1` 时开启微博视频显示' },
features: {
diff --git a/lib/routes/xiaoyuzhou/podcast.ts b/lib/routes/xiaoyuzhou/podcast.ts
index c208e89d9c951a..d4493aa354d709 100644
--- a/lib/routes/xiaoyuzhou/podcast.ts
+++ b/lib/routes/xiaoyuzhou/podcast.ts
@@ -5,7 +5,7 @@ import { parseDate } from '@/utils/parse-date';
export const route: Route = {
path: '/podcast/:id',
- categories: ['multimedia'],
+ categories: ['multimedia', 'popular'],
example: '/xiaoyuzhou/podcast/6021f949a789fca4eff4492c',
parameters: { id: '播客id,可以在小宇宙播客的 URL 中找到' },
features: {
diff --git a/lib/routes/ximalaya/album.ts b/lib/routes/ximalaya/album.ts
index 519d5a7e3cef5b..ffde92729c0213 100644
--- a/lib/routes/ximalaya/album.ts
+++ b/lib/routes/ximalaya/album.ts
@@ -82,8 +82,8 @@ function judgeTrue(str, ...validStrings) {
}
export const route: Route = {
- path: ['/:type/:id/:all?', '/:type/:id/:all/:shownote?'],
- categories: ['multimedia'],
+ path: ['/:type/:id/:all/:shownote?'],
+ categories: ['multimedia', 'popular'],
example: '/ximalaya/album/299146',
parameters: { type: '专辑类型, 通常可以使用 `album`,可在对应专辑页面的 URL 中找到', id: '专辑 id, 可在对应专辑页面的 URL 中找到', all: '是否需要获取全部节目,填入 `1`、`true`、`all` 视为获取所有节目,填入其他则不获取。' },
features: {
@@ -99,10 +99,10 @@ export const route: Route = {
supportPodcast: true,
supportScihub: false,
},
- name: '专辑(不输出 ShowNote)',
+ name: '专辑',
maintainers: ['lengthmin', 'jjeejj', 'prnake'],
handler,
- description: `目前喜马拉雅的 API 只能一集一集的获取各节目上的 ShowNote,会极大的占用系统资源,所以默认为不获取节目的 ShowNote。下方有一个新的路径可选获取 ShowNote。
+ description: `目前喜马拉雅的 API 只能一集一集的获取各节目上的 ShowNote,会极大的占用系统资源,所以默认为不获取节目的 ShowNote。
:::warning
专辑类型即 url 中的分类拼音,使用通用分类 \`album\` 通常是可行的,专辑 id 是跟在**分类拼音**后的那个 id, 不要输成某集的 id 了
diff --git a/lib/routes/youtube/user.ts b/lib/routes/youtube/user.ts
index 71893c868ded00..e3a3127accd070 100644
--- a/lib/routes/youtube/user.ts
+++ b/lib/routes/youtube/user.ts
@@ -9,7 +9,7 @@ import ConfigNotFoundError from '@/errors/types/config-not-found';
export const route: Route = {
path: '/user/:username/:embed?',
- categories: ['social-media'],
+ categories: ['social-media', 'popular'],
example: '/youtube/user/@JFlaMusic',
parameters: { username: 'YouTuber username with @', embed: 'Default to embed the video, set to any value to disable embedding' },
features: {
diff --git a/lib/routes/zhihu/activities.ts b/lib/routes/zhihu/activities.ts
index 9ab887444d219e..ee3738e1cb3c57 100644
--- a/lib/routes/zhihu/activities.ts
+++ b/lib/routes/zhihu/activities.ts
@@ -5,7 +5,7 @@ import { parseDate } from '@/utils/parse-date';
export const route: Route = {
path: '/people/activities/:id',
- categories: ['social-media'],
+ categories: ['social-media', 'popular'],
example: '/zhihu/people/activities/diygod',
parameters: { id: '作者 id,可在用户主页 URL 中找到' },
features: {
diff --git a/lib/types.ts b/lib/types.ts
index a45dc653710495..67f20d420bf9b7 100644
--- a/lib/types.ts
+++ b/lib/types.ts
@@ -3,6 +3,7 @@ import type { Context } from 'hono';
// Make sure it's synchronise with scripts/workflow/data.ts
// and lib/routes/rsshub/routes.ts
type Category =
+ | 'popular'
| 'social-media'
| 'new-media'
| 'traditional-media'
diff --git a/lib/views/error.tsx b/lib/views/error.tsx
index 50e724b8f50e43..3d532136aacc78 100644
--- a/lib/views/error.tsx
+++ b/lib/views/error.tsx
@@ -81,7 +81,7 @@ const Index: FC<{
Telegram channel
{' '}
and{' '}
-
+
Twitter
{' '}
to get community support and news.
@@ -96,7 +96,7 @@ const Index: FC<{
Telegram 频道
和{' '}
-
+
Twitter
{' '}
获取社区支持和新闻。
@@ -115,7 +115,7 @@ const Index: FC<{
-
+
diff --git a/lib/views/index.tsx b/lib/views/index.tsx
index cc5394000c06e9..9293815af22fd5 100644
--- a/lib/views/index.tsx
+++ b/lib/views/index.tsx
@@ -176,7 +176,7 @@ const Index: FC<{ debugQuery: string | undefined }> = ({ debugQuery }) => {
-
+
diff --git a/scripts/workflow/data.ts b/scripts/workflow/data.ts
index dcf4cf8ffe5b87..24726828f79818 100644
--- a/scripts/workflow/data.ts
+++ b/scripts/workflow/data.ts
@@ -1,4 +1,10 @@
export const categories = [
+ {
+ icon: '🌟',
+ link: '/routes/popular',
+ en: 'Popular',
+ zh: '热门',
+ },
{
icon: '💬',
link: '/routes/social-media',