diff --git a/lib/routes.ts b/lib/routes.ts
index 7458881206..6470201d7c 100644
--- a/lib/routes.ts
+++ b/lib/routes.ts
@@ -3,8 +3,8 @@ import type { Hono, Handler } from 'hono';
import { serveStatic } from '@hono/node-server/serve-static';
import * as path from 'node:path';
-import index from '@/v3/index';
-import robotstxt from '@/v3/robots.txt';
+import index from '@/v2/index';
+import robotstxt from '@/v2/robots.txt';
type Root = {
get: (routePath: string, filePath: string) => void;
diff --git a/lib/v3/index.ts b/lib/v2/index.ts
similarity index 100%
rename from lib/v3/index.ts
rename to lib/v2/index.ts
diff --git a/lib/v3/robots.txt.ts b/lib/v2/robots.txt.ts
similarity index 100%
rename from lib/v3/robots.txt.ts
rename to lib/v2/robots.txt.ts
diff --git a/lib/v3/test/index.js b/lib/v2/test/index.js
similarity index 100%
rename from lib/v3/test/index.js
rename to lib/v2/test/index.js
diff --git a/lib/v3/test/maintainer.js b/lib/v2/test/maintainer.js
similarity index 100%
rename from lib/v3/test/maintainer.js
rename to lib/v2/test/maintainer.js
diff --git a/lib/v2/test/router.js b/lib/v2/test/router.js
new file mode 100644
index 0000000000..de87b52670
--- /dev/null
+++ b/lib/v2/test/router.js
@@ -0,0 +1,3 @@
+module.exports = function (router) {
+ router.get('/:id', './index');
+};
diff --git a/lib/v3/jike/maintainer.js b/lib/v3/jike/maintainer.js
deleted file mode 100644
index 28c9801b4e..0000000000
--- a/lib/v3/jike/maintainer.js
+++ /dev/null
@@ -1,5 +0,0 @@
-module.exports = {
- '/topic/text/:id': ['HenryQW'],
- '/topic/:id/:showUid?': ['DIYgod', 'prnake'],
- '/user/:id': ['DIYgod', 'prnake'],
-};
diff --git a/lib/v3/jike/radar.js b/lib/v3/jike/radar.js
deleted file mode 100644
index b226de810c..0000000000
--- a/lib/v3/jike/radar.js
+++ /dev/null
@@ -1,54 +0,0 @@
-module.exports = {
- 'okjike.com': {
- _name: '即刻',
- m: [
- {
- title: '用户动态',
- docs: 'https://docs.rsshub.app/routes/social-media#ji-ke',
- source: '/users/:uid',
- target: '/jike/user/:uid',
- },
- {
- title: '用户动态',
- docs: 'https://docs.rsshub.app/routes/social-media#ji-ke',
- source: '/reposts/:repostId',
- target: (params, url, document) => {
- const uid = document.querySelector('.avatar').getAttribute('href').replace('/users/', '');
- return uid ? `/jike/user/${uid}` : '';
- },
- },
- {
- title: '圈子',
- docs: 'https://docs.rsshub.app/routes/social-media#ji-ke',
- source: '/topics/:id',
- target: '/jike/topic/:id',
- },
- {
- title: '圈子 - 纯文字',
- docs: 'https://docs.rsshub.app/routes/social-media#ji-ke',
- source: '/topics/:id',
- target: '/jike/topic/text/:id',
- },
- ],
- web: [
- {
- title: '用户动态',
- docs: 'https://docs.rsshub.app/routes/social-media#ji-ke',
- source: '/u/:uid',
- target: '/jike/user/:uid',
- },
- {
- title: '圈子',
- docs: 'https://docs.rsshub.app/routes/social-media#ji-ke',
- source: '/topic/:id',
- target: '/jike/topic/:id',
- },
- {
- title: '圈子 - 纯文字',
- docs: 'https://docs.rsshub.app/routes/social-media#ji-ke',
- source: '/topic/:id',
- target: '/jike/topic/text/:id',
- },
- ],
- },
-};
diff --git a/lib/v3/jike/router.js b/lib/v3/jike/router.js
deleted file mode 100644
index fc0901c4b0..0000000000
--- a/lib/v3/jike/router.js
+++ /dev/null
@@ -1,5 +0,0 @@
-module.exports = (router) => {
- router.get('/topic/text/:id', require('./topic-text'));
- router.get('/topic/:id/:showUid?', require('./topic'));
- router.get('/user/:id', require('./user'));
-};
diff --git a/lib/v3/jike/topic-text.js b/lib/v3/jike/topic-text.js
deleted file mode 100644
index f243428f3c..0000000000
--- a/lib/v3/jike/topic-text.js
+++ /dev/null
@@ -1,21 +0,0 @@
-const dayjs = require('dayjs');
-const { constructTopicEntry } = require('./utils');
-
-module.exports = async (ctx) => {
- const id = ctx.req.param('id');
- const topicUrl = `https://m.okjike.com/topics/${id}`;
-
- const data = await constructTopicEntry(ctx, topicUrl);
-
- if (data) {
- ctx.state.data.item = data.posts.map((item) => {
- const date = dayjs(item.createdAt);
- return {
- title: `${data.topic.content} ${date.format('MM月DD日')}`,
- description: item.content.replaceAll('\n', '
'),
- pubDate: date.toDate(),
- link: `https://m.okjike.com/originalPosts/${item.id}`,
- };
- });
- }
-};
diff --git a/lib/v3/jike/topic.js b/lib/v3/jike/topic.js
deleted file mode 100644
index 336a1c30d4..0000000000
--- a/lib/v3/jike/topic.js
+++ /dev/null
@@ -1,48 +0,0 @@
-const got = require('@/utils/got');
-const { topicDataHanding } = require('./utils');
-const cheerio = require('cheerio');
-const dayjs = require('dayjs');
-const { constructTopicEntry } = require('@/v3/jike/utils');
-
-module.exports = async (ctx) => {
- const id = ctx.req.param('id');
- const topicUrl = `https://m.okjike.com/topics/${id}`;
-
- const data = await constructTopicEntry(ctx, topicUrl);
-
- if (data) {
- let item = topicDataHanding(data, ctx);
- if (id === '553870e8e4b0cafb0a1bef68' || id === '55963702e4b0d84d2c30ce6f') {
- item = await Promise.all(
- item.map(async (one) => {
- const item = { ...one };
- const regResult = /https:\/\/www\.okjike\.com\/medium\/[\dA-Za-z]*/.exec(item.description);
- if (regResult) {
- const newsUrl = regResult[0];
- item.description = await ctx.cache.tryGet(newsUrl, async () => {
- const { data } = await got(newsUrl);
- const $ = cheerio.load(data);
- const upper = $('ul.main > li.item');
- const links = upper.find('a').map((_, ele) => $(ele).attr('href'));
- const texts = upper.find('span.text').map((_, ele) => $(ele).text());
- let description = '';
- for (const [i, link] of links.entries()) {
- description += `${i + 1}、${texts[i]}
`;
- }
- description = description.replace(/
$/, '');
- return description;
- });
- }
- item.title = `${data.topic.content} ${dayjs(one.pubDate).format('MM月DD日')}`;
- return item;
- })
- );
- }
-
-
- ctx.set('data', {
- ...ctx.get('data'),
- item,
- });
- }
-};
diff --git a/lib/v3/jike/user.js b/lib/v3/jike/user.js
deleted file mode 100644
index bef1798231..0000000000
--- a/lib/v3/jike/user.js
+++ /dev/null
@@ -1,158 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-const { parseDate } = require('@/utils/parse-date');
-
-module.exports = async (ctx) => {
- const id = ctx.req.param('id');
-
- const response = await got({
- method: 'get',
- url: `https://m.okjike.com/users/${id}`,
- headers: {
- Referer: `https://m.okjike.com/users/${id}`,
- },
- });
-
- const html = response.data;
- const $ = cheerio.load(html);
- const raw = $('[type = "application/json"]').html();
- const data = JSON.parse(raw).props.pageProps;
-
- const getLink = (id, type) => {
- switch (type) {
- case 'REPOST':
- return `https://m.okjike.com/reposts/${id}`;
- case 'MEDIUM':
- return `https://www.okjike.com/medium/${id}`;
- default:
- return `https://m.okjike.com/originalPosts/${id}`;
- }
- };
-
- const items = await Promise.all(
- data.posts.map(async (item) => {
- const typeMap = {
- ORIGINAL_POST: '发布',
- REPOST: '转发',
- ANSWER: '回答',
- QUESTION: '提问',
- PERSONAL_UPDATE: '创建新主题',
- };
-
- let linkTemplate = '';
- if (item.linkInfo && item.linkInfo.linkUrl) {
- linkTemplate = `${item.linkInfo.title}
`;
- }
-
- let imgTemplate = '';
- if (item.pictures) {
- for (const picture of item.pictures) {
- imgTemplate += `
`;
- }
- }
-
- let content = item.content || (item.linkInfo && item.linkInfo.title) || (item.question && item.question.title) || item.title || '';
- content = content.replaceAll(/\r\n|\n|\r/g, '
');
-
- let shortenTitle = '一条动态';
- if (content) {
- shortenTitle = content.replaceAll(/(
)+/g, ' ');
- content = `${content}
`;
- }
-
- let repostContent;
- if (item.type === 'REPOST') {
- const screenNameTemplate = item.target.user ? `@${item.target.user.screenName}` : '';
-
- let repostImgTemplate = '';
- if (item.target.pictures) {
- for (const picture of item.target.pictures) {
- repostImgTemplate += `
`;
- }
- }
-
- repostContent = `
`.replaceAll(/\r\n|\n|\r/g, '
');
- content = `${content}${repostContent}`;
- }
- // 部分功能未知
- /* else if (item.type === 'ANSWER') {
- let answerTextTemplate = '';
- let answerImgTemplate = '';
- let answerImgKeys = [];
- item.richtextContent.blocks &&
- item.richtextContent.blocks.forEach((item) => {
- if (item.entityRanges.length && item.text === '[图片]') {
- answerImgKeys = [...answerImgKeys, ...Object.keys(item.entityRanges)];
- } else {
- answerTextTemplate += item.text;
- }
- });
-
- if (answerImgKeys.length) {
- answerImgKeys.forEach((key) => {
- const entity = item.richtextContent.entityMap[key];
- if (entity.type.toUpperCase() === 'IMAGE') {
- answerImgTemplate += `
`;
- }
- });
- }
- const answerContent = `回答: ${answerTextTemplate}${answerImgTemplate}`;
- content = `${content}${answerContent}`.replace(/\n|\r/g, '
');
- } else if (item.type === 'QUESTION') {
- content = `在主题 ${item.topic.content} 提出了一个问题:
${content}`;
- } else if (item.type === 'PERSONAL_UPDATE') {
- shortenTitle = item.topic.content;
- content = `
主题简介:
${item.topic.briefIntro.replace(/(?:\r\n|\r|\n)/g, '
')}`;
- }*/
-
- const single = {
- title: `${typeMap[item.type]}了: ${shortenTitle}`,
- description: `${content}${linkTemplate}${imgTemplate}`.replace(/(
|\s)+$/, ''),
- pubDate: parseDate(item.createdAt),
- link: getLink(item.id, item.type),
- _extra: repostContent && {
- links: [
- {
- url: getLink(item.target.id, item.target.type),
- type: 'quote',
- },
- ],
- },
- };
-
- if (id === 'wenhao1996' && item.topic.id === '553870e8e4b0cafb0a1bef68') {
- single.link = item.urlsInText[0].url;
-
- const { data } = await got({
- method: 'get',
- url: single.link,
- headers: {
- Referer: `https://m.okjike.com/users/${id}`,
- },
- });
- const $$ = cheerio.load(data);
- $$('span.num,span.arrow').remove();
-
- single.title = `一觉醒来世界发生了什么 ${$$('title').text()}`;
-
- single.description = '';
- $$('div.container')
- .find('li.item')
- // eslint-disable-next-line array-callback-return
- .map((i, j) => {
- single.description += `${$$(j).find('a').text()}
`;
- });
- }
-
- return single;
- })
- );
-
- ctx.set('data', {
- title: `${data.user.screenName}的即刻动态`,
- description: data.user.bio,
- link: `https://m.okjike.com/users/${id}`,
- image: data.user.avatarImage.picUrl,
- item: items,
- });
-};
diff --git a/lib/v3/jike/utils.js b/lib/v3/jike/utils.js
deleted file mode 100644
index ad3fece218..0000000000
--- a/lib/v3/jike/utils.js
+++ /dev/null
@@ -1,198 +0,0 @@
-const cheerio = require('cheerio');
-import parseDate from '@/utils/parse-date';
-import got from '@/utils/got';
-import { config } from '@/config';
-import cache from '@/utils/cache';
-
-const videoAPI = 'https://api.ruguoapp.com/1.0/mediaMeta/play?type=ORIGINAL_POST';
-
-module.exports = {
- topicDataHanding: (data, ctx) =>
- data.posts.map((item) => {
- let audioName, videoName, linkName;
-
- // 获取纯文字内容 和 即刻原文链接
- let content, link;
- switch (item.type) {
- case 'ORIGINAL_POST':
- content = item.content;
- link = `https://m.okjike.com/originalPosts/${item.id}`;
- break;
-
- /* case 'QUESTION':
- content = item.title;
- link = `https://m.okjike.com/questions/${item.id}`;
- break;
- case 'OFFICIAL_MESSAGE':
- content = item.content;
- link = `https://web.okjike.com/message-detail/${item.id}/officialMessage`;
- break;*/
- default:
- content = '未知类型,请前往GitHub提交issue';
- link = 'https://github.com/DIYgod/RSSHub/issues';
- }
-
- // rss内容
- let description = '';
- // 作者昵称
- let author = '';
-
- // 添加内容作者信息
- if (item.user) {
- author = item.user.screenName;
- if (ctx.req.param('showUid')) {
- description += `用户昵称:${author}
Username:${item.user.username}
`;
- }
- }
-
- if (item.linkInfo) {
- const linkUrl = item.linkInfo.originalLinkUrl || item.linkInfo.linkUrl;
-
- // 对于即刻抓取的微信公众号文章 特殊处理
- // 此时 Rss原文链接 变为 微信公众号链接
- if (new URL(linkUrl).host === 'mp.weixin.qq.com') {
- link = linkUrl;
- }
-
- // 1. 音频
- const audioObject = item.linkInfo.audio || item.audio;
- if (audioObject) {
- const audioImage = audioObject.image.picUrl || audioObject.image.thumbnailUrl;
- const audioLink = linkUrl;
- const audioTitle = audioObject.title;
- const audioAuthor = audioObject.author;
- audioName = `${audioTitle} - ${audioAuthor}`;
- description += `
-
- ${audioName}
- `;
- }
-
- // 2. 视频
- const videoObject = item.linkInfo.video || item.video;
- if (videoObject) {
- const videoImage = videoObject.image.picUrl || videoObject.image.thumbnailUrl;
- const videoLink = linkUrl;
- const videoDuration = Math.floor(videoObject.duration / 60000);
- videoName = item.linkInfo.title;
- description += `
-
- ${videoName || '观看视频'} - 约${videoDuration}分钟
- `;
- }
-
- // 3. 链接
- if (!audioObject && !videoObject && linkUrl) {
- // 部分链接有标题
- linkName = item.linkInfo.title;
- const linkTitle = linkName || '访问原文';
- // 部分链接有缩略图
- const linkImage = item.linkInfo.pictureUrl;
- const imageTag = `
`;
- description += `
- ${linkImage ? imageTag : ''}
- ${linkTitle}
- `;
- }
- }
-
- // 4. 文字内容
- description += description ? `
${content}` : content;
-
- // 5. 图片
- if (item.pictures) {
- for (const pic of item.pictures) {
- if (pic.format === 'gif') {
- description += `
`;
- } else {
- // jpeg, bmp, png, gif, webp
- // https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types
- // let type = 'jpeg';
- // switch (pic.format) {
- // case 'bmp':
- // type = 'bmp';
- // break;
- // case 'png':
- // type = 'png';
- // break;
- // default:
- // break;
- // }
- const imgUrl = /\.[\da-z]+?\?imageMogr2/.test(pic.picUrl) ? pic.picUrl.split('?imageMogr2/')[0] : pic.picUrl.replace(/thumbnail\/.+/, '');
- description += `
`;
- // description += `
`;
- }
- }
- }
-
- // 6. 视频
- if (item.video) {
- description += `
`;
- }
-
- // rss标题
- // 优先将音频和视频名作为标题
- // 其次将正文内容作为标题
- // 若都没有 则是推送型消息,将连接标题作为主题
- // “无题” fallback
- const title = audioName || videoName || content || linkName || '无题';
-
- return {
- title,
- description: description.trim().replaceAll('\n', '
'),
- pubDate: parseDate.parse(item.createdAt),
- author,
- link,
- };
- }),
- constructTopicEntry: async (ctx, url) => {
- const data = await cache.tryGet(
- url,
- async () => {
- const resp = await got(url);
- const html = resp.data;
- const $ = cheerio.load(html);
- const raw = $('[type = "application/json"]').html();
- const data = JSON.parse(raw).props.pageProps;
- data.posts = await Promise.all(
- data.posts.map(async (item) => {
- if (!item.video) {
- return item;
- }
-
- const videoUrl = `${videoAPI}&id=${item.id}`;
- const videoRes = await got(videoUrl);
- item.video = videoRes.data;
-
- return item;
- })
- );
-
- return data;
- },
- false,
- config.cache.routeExpire
- );
-
- if (data.length === 0) {
- ctx.set('data', {
- title: '主题 ID 不存在,或该主题暂无内容',
- });
- return null;
- }
-
- const topic = data.topic;
-
- ctx.set('data', {
- title: `${topic.content} - 即刻圈子`,
- link: url,
- description: topic.briefIntro,
- image: topic.squarePicture.picUrl || topic.squarePicture.middlePicUrl || topic.squarePicture.thumbnailUrl,
- // item: topicDataHanding(data),
- });
-
- return data;
- },
-};
diff --git a/lib/v3/rsshub/maintainer.js b/lib/v3/rsshub/maintainer.js
deleted file mode 100644
index 158998b451..0000000000
--- a/lib/v3/rsshub/maintainer.js
+++ /dev/null
@@ -1,6 +0,0 @@
-module.exports = {
- '/routes/:lang?': ['DIYgod'],
- '/transform/html/:url/:routeParams': ['ttttmr'],
- '/transform/json/:url/:routeParams': ['ttttmr'],
- '/transform/sitemap/:url/:routeParams?': ['flrngel'],
-};
diff --git a/lib/v3/rsshub/radar.js b/lib/v3/rsshub/radar.js
deleted file mode 100644
index 8327f7fec3..0000000000
--- a/lib/v3/rsshub/radar.js
+++ /dev/null
@@ -1,13 +0,0 @@
-module.exports = {
- 'rsshub.app': {
- _name: 'RSSHub',
- docs: [
- {
- title: '有新路由啦',
- docs: 'https://docs.rsshub.app/routes/program-update#rsshub',
- source: ['/*'],
- target: '/rsshub/routes',
- },
- ],
- },
-};
diff --git a/lib/v3/rsshub/router.js b/lib/v3/rsshub/router.js
deleted file mode 100644
index 7e580dcc58..0000000000
--- a/lib/v3/rsshub/router.js
+++ /dev/null
@@ -1,6 +0,0 @@
-module.exports = (router) => {
- router.get('/routes/:lang?', require('./routes'));
- router.get('/transform/html/:url/:routeParams', require('./transform/html'));
- router.get('/transform/json/:url/:routeParams', require('./transform/json'));
- router.get('/transform/sitemap/:url/:routeParams?', require('./transform/sitemap'));
-};
diff --git a/lib/v3/rsshub/routes.js b/lib/v3/rsshub/routes.js
deleted file mode 100644
index 9e9c2bc281..0000000000
--- a/lib/v3/rsshub/routes.js
+++ /dev/null
@@ -1,65 +0,0 @@
-import got from '@/utils/got';
-const cheerio = require('cheerio');
-
-module.exports = async (ctx) => {
- const isEnglish = ctx.req.param('lang') !== 'zh';
-
- const lang = isEnglish ? '' : 'zh/';
- const types = [
- 'social-media',
- 'new-media',
- 'traditional-media',
- 'bbs',
- 'blog',
- 'programming',
- 'design',
- 'live',
- 'multimedia',
- 'picture',
- 'anime',
- 'program-update',
- 'university',
- 'forecast',
- 'travel',
- 'shopping',
- 'game',
- 'reading',
- 'government',
- 'study',
- 'journal',
- 'finance',
- 'other',
- ];
- const all = await Promise.all(
- types.map(async (type) => {
- const response = await got(`https://docs.rsshub.app/${lang}routes/${type}`);
-
- const data = response.data;
-
- const $ = cheerio.load(data);
- const page = $('.page').toArray();
- const item = $('.routeBlock').toArray();
- return { page, item, type };
- })
- );
- const list = all.flatMap(({ page, item, type }) => item.map((item) => ({ page, item, type })));
-
- ctx.set('data', {
- title: isEnglish ? 'RSSHub has new routes' : 'RSSHub 有新路由啦',
- link: 'https://docs.rsshub.app',
- description: isEnglish ? 'Everything is RSSible' : '万物皆可 RSS',
- language: isEnglish ? 'en-us' : 'zh-cn',
- item: list.map(({ page, item, type }) => {
- const $ = cheerio.load(page);
- item = $(item);
- const h2Title = item.prevAll('h2').eq(0);
- const h3Title = item.prevAll('h3').eq(0);
- return {
- title: `${h2Title.text().trim()} - ${h3Title.text().trim()}`,
- description: item.html(),
- link: `https://docs.rsshub.app/${lang}routes/${type}#${encodeURIComponent(h2Title.find('.hash-link').attr('href') && h3Title.find('.hash-link').attr('href')?.substring(1))}`,
- guid: item.attr('id'),
- };
- }),
- });
-};
diff --git a/lib/v3/rsshub/transform/html.js b/lib/v3/rsshub/transform/html.js
deleted file mode 100644
index 0073580dad..0000000000
--- a/lib/v3/rsshub/transform/html.js
+++ /dev/null
@@ -1,65 +0,0 @@
-import got from '@/utils/got';
-const cheerio = require('cheerio');
-import { config } from '@/config';
-
-module.exports = async (ctx) => {
- if (!config.feature.allow_user_supply_unsafe_domain) {
- throw new Error(`This RSS is disabled unless 'ALLOW_USER_SUPPLY_UNSAFE_DOMAIN' is set to 'true'.`);
- }
- const url = ctx.req.param('url');
- const response = await got({
- method: 'get',
- url,
- });
-
- const routeParams = new URLSearchParams(ctx.req.param('routeParams'));
- const $ = cheerio.load(response.data);
- const rssTitle = routeParams.get('title') || $('title').text();
- const item = routeParams.get('item') || 'html';
- const items = $(item)
- .toArray()
- .map((item) => {
- try {
- item = $(item);
-
- const titleEle = routeParams.get('itemTitle') ? item.find(routeParams.get('itemTitle')) : item;
- const title = routeParams.get('itemTitleAttr') ? titleEle.attr(routeParams.get('itemTitleAttr')) : titleEle.text();
-
- let link;
- const linkEle = routeParams.get('itemLink') ? item.find(routeParams.get('itemLink')) : item;
- if (routeParams.get('itemLinkAttr')) {
- link = linkEle.attr(routeParams.get('itemLinkAttr'));
- } else {
- link = linkEle.is('a') ? linkEle.attr('href') : linkEle.find('a').attr('href');
- }
- // 补全绝对链接
- link = link.trim();
- if (link && !link.startsWith('http')) {
- link = `${new URL(url).origin}${link}`;
- }
-
- const descEle = routeParams.get('itemDesc') ? item.find(routeParams.get('itemDesc')) : item;
- const desc = routeParams.get('itemDescAttr') ? descEle.attr(routeParams.get('itemDescAttr')) : descEle.html();
-
- const pubDateEle = routeParams.get('itemPubDate') ? item.find(routeParams.get('itemPubDate')) : item;
- const pubDate = routeParams.get('itemPubDateAttr') ? pubDateEle.attr(routeParams.get('itemPubDateAttr')) : pubDateEle.html();
-
- return {
- title,
- link,
- description: desc,
- pubDate,
- };
- } catch {
- return null;
- }
- })
- .filter(Boolean);
-
- ctx.set('data', {
- title: rssTitle,
- link: url,
- description: `Proxy ${url}`,
- item: items,
- });
-};
diff --git a/lib/v3/rsshub/transform/json.js b/lib/v3/rsshub/transform/json.js
deleted file mode 100644
index 5ab74d2a30..0000000000
--- a/lib/v3/rsshub/transform/json.js
+++ /dev/null
@@ -1,58 +0,0 @@
-import got from '@/utils/got';
-const cheerio = require('cheerio');
-import { config } from '@/config';
-
-function jsonGet(obj, attr) {
- if (typeof attr !== 'string') {
- return obj;
- }
- // a.b.c
- // a.b[0].c => a.b.0.c
- for (const key of attr.split('.')) {
- obj = obj[key];
- }
- return obj;
-}
-
-module.exports = async (ctx) => {
- if (!config.feature.allow_user_supply_unsafe_domain) {
- throw new Error(`This RSS is disabled unless 'ALLOW_USER_SUPPLY_UNSAFE_DOMAIN' is set to 'true'.`);
- }
- const url = ctx.req.param('url');
- const response = await got({
- method: 'get',
- url,
- });
-
- const routeParams = new URLSearchParams(ctx.req.param('routeParams'));
- let rssTitle = routeParams.get('title');
- if (!rssTitle) {
- const resp = await got({
- method: 'get',
- url: new URL(url).origin,
- });
- const $ = cheerio.load(resp.data);
- rssTitle = $('title').text();
- }
-
- const items = jsonGet(response.data, routeParams.get('item')).map((item) => {
- let link = jsonGet(item, routeParams.get('itemLink')).trim();
- // 补全绝对链接
- if (link && !link.startsWith('http')) {
- link = `${new URL(url).origin}${link}`;
- }
- return {
- title: jsonGet(item, routeParams.get('itemTitle')),
- link,
- description: routeParams.get('itemDesc') ? jsonGet(item, routeParams.get('itemDesc')) : '',
- pubDate: routeParams.get('itemPubDate') ? jsonGet(item, routeParams.get('itemPubDate')) : '',
- };
- });
-
- ctx.set('data', {
- title: rssTitle,
- link: url,
- description: `Proxy ${url}`,
- item: items,
- });
-};
diff --git a/lib/v3/rsshub/transform/sitemap.js b/lib/v3/rsshub/transform/sitemap.js
deleted file mode 100644
index 4d7946e42e..0000000000
--- a/lib/v3/rsshub/transform/sitemap.js
+++ /dev/null
@@ -1,50 +0,0 @@
-import got from '@/utils/got';
-const cheerio = require('cheerio');
-import { config } from '@/config';
-
-module.exports = async (ctx) => {
- if (!config.feature.allow_user_supply_unsafe_domain) {
- throw new Error(`This RSS is disabled unless 'ALLOW_USER_SUPPLY_UNSAFE_DOMAIN' is set to 'true'.`);
- }
- const url = ctx.req.param('url');
- const response = await got({
- method: 'get',
- url,
- });
-
- const routeParams = new URLSearchParams(ctx.req.param('routeParams'));
- const $ = cheerio.load(response.data, { xmlMode: true });
-
- const rssTitle = routeParams.get('title') || ($('urlset url').length && $('urlset url').first().find('loc').text() ? $('urlset url').first().find('loc').text() : 'Sitemap');
-
- const urls = $('urlset url').toArray();
- const items =
- urls && urls.length
- ? urls
- .map((item) => {
- try {
- const title = $(item).find('loc').text() || '';
- const link = $(item).find('loc').text() || '';
- const description = $(item).find('loc').text() || '';
- const pubDate = $(item).find('lastmod').text() || undefined;
-
- return {
- title,
- link,
- description,
- pubDate,
- };
- } catch {
- return null;
- }
- })
- .filter(Boolean)
- : [];
-
- ctx.set('data', {
- title: rssTitle,
- link: url,
- description: `Proxy ${url}`,
- item: items,
- });
-};
diff --git a/lib/v3/test/router.js b/lib/v3/test/router.js
deleted file mode 100644
index 641c23df3a..0000000000
--- a/lib/v3/test/router.js
+++ /dev/null
@@ -1,3 +0,0 @@
-module.exports = function (router) {
- router.get('/:id', require('./index'));
-};