mirror of
https://github.com/DIYgod/RSSHub.git
synced 2026-10-16 21:02:57 +08:00
fix(zsxq): correct feed handling
Combine the reviewed route corrections and their follow-up adjustments. Affected files: - lib/routes/zsxq/group.ts - lib/routes/zsxq/user.ts - lib/routes/zsxq/utils.ts
This commit is contained in:
@@ -3,6 +3,7 @@ import type { Context } from 'hono';
|
||||
import { config } from '@/config';
|
||||
import ConfigNotFoundError from '@/errors/types/config-not-found';
|
||||
import type { Data, Route } from '@/types';
|
||||
import { getRouteLimit } from '@/utils/route-limit';
|
||||
|
||||
import type { GroupInfoResponse, TopicsResponse } from './types';
|
||||
import { customFetch, generateTopicDataItem } from './utils';
|
||||
@@ -46,10 +47,7 @@ async function handler(ctx: Context): Promise<Data> {
|
||||
throw new ConfigNotFoundError('该 RSS 源由于配置不正确而被禁用:令牌丢失。');
|
||||
}
|
||||
|
||||
let count = Number(ctx.req.query('limit')) || 20;
|
||||
if (count > 30) {
|
||||
count = 30;
|
||||
}
|
||||
const count = Math.min(getRouteLimit(ctx, 20), 30);
|
||||
|
||||
const { group } = await customFetch<GroupInfoResponse>(`/groups/${groupId}`);
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@ import type { Context } from 'hono';
|
||||
import { config } from '@/config';
|
||||
import ConfigNotFoundError from '@/errors/types/config-not-found';
|
||||
import type { Data, Route } from '@/types';
|
||||
import { getRouteLimit } from '@/utils/route-limit';
|
||||
|
||||
import type { TopicsResponse, UserInfoResponse } from './types';
|
||||
import { customFetch, generateTopicDataItem } from './utils';
|
||||
@@ -41,10 +42,7 @@ async function handler(ctx: Context): Promise<Data> {
|
||||
throw new ConfigNotFoundError('该 RSS 源由于配置不正确而被禁用:令牌丢失。');
|
||||
}
|
||||
|
||||
let count = Number(ctx.req.query('limit')) || 20;
|
||||
if (count > 30) {
|
||||
count = 30;
|
||||
}
|
||||
const count = Math.min(getRouteLimit(ctx, 20), 30);
|
||||
|
||||
const userInfo = await customFetch<UserInfoResponse>(`/users/${uid}`);
|
||||
|
||||
|
||||
+44
-14
@@ -1,3 +1,5 @@
|
||||
import { html } from 'hono/html';
|
||||
|
||||
import { config } from '@/config';
|
||||
import type { DataItem } from '@/types';
|
||||
import got from '@/utils/got';
|
||||
@@ -21,53 +23,81 @@ export async function customFetch<T extends BasicResponse<ResponseData>>(path: s
|
||||
if (code === 1059 && retryCount < 3) {
|
||||
return customFetch(path, retryCount + 1);
|
||||
}
|
||||
throw new Error('something wrong');
|
||||
throw new Error(`Knowledge Planet API request failed (code ${code ?? 'unknown'}). Check the access token and permission for this group or user.`);
|
||||
}
|
||||
|
||||
function decodeTopicText(text: string) {
|
||||
try {
|
||||
return decodeURIComponent(text);
|
||||
} catch {
|
||||
return text;
|
||||
}
|
||||
}
|
||||
|
||||
function renderTopicLink(href: string, title: string) {
|
||||
const label = decodeTopicText(title);
|
||||
try {
|
||||
const url = new URL(decodeTopicText(href));
|
||||
if (url.protocol === 'https:' || url.protocol === 'http:') {
|
||||
return String(html`<a href="${url.href}">${label}</a>`);
|
||||
}
|
||||
} catch {
|
||||
// Malformed encoded links retain their readable label.
|
||||
}
|
||||
return String(html`${label}`);
|
||||
}
|
||||
|
||||
function parseTopicContent(text: string = '', images: TopicImage[] = []) {
|
||||
let result = text.replaceAll('\n', '<br>');
|
||||
result = result.replaceAll(/<e type="web" href="(.*?)" title="(.*?)" style="(.*?)" \/>/g, (_, p1, p2) => `<a href=${decodeURIComponent(p1)}>${decodeURIComponent(p2)}</a>`);
|
||||
result = result.replaceAll(/<e type="hashtag".*?title="(.*?)" \/>/g, (_, p1) => {
|
||||
const title = decodeURIComponent(p1);
|
||||
return `<span>${title}</span>`;
|
||||
});
|
||||
result += images.map((image) => `<img src="${image.original?.url ?? image.large?.url ?? image.thumbnail?.url}">`).join('<br>');
|
||||
result = result.replaceAll(/<e type="web" href="(.*?)" title="(.*?)" style="(.*?)" \/>/g, (_, href, title) => renderTopicLink(href, title));
|
||||
result = result.replaceAll(/<e type="hashtag".*?title="(.*?)" \/>/g, (_, title) => String(html`<span>${decodeTopicText(title)}</span>`));
|
||||
result += images
|
||||
.map((image) => {
|
||||
const url = image.original?.url ?? image.large?.url ?? image.thumbnail?.url;
|
||||
return url ? String(html`<img src="${url}" />`) : '';
|
||||
})
|
||||
.filter(Boolean)
|
||||
.join('<br>');
|
||||
return result;
|
||||
}
|
||||
|
||||
export function generateTopicDataItem(topics: Topic[]): DataItem[] {
|
||||
return topics.map((topic) => {
|
||||
if (topic.topic_id === undefined || topic.topic_id === null) {
|
||||
throw new Error('Missing Knowledge Planet topic ID; no unique article URL is available.');
|
||||
}
|
||||
let description: string | undefined;
|
||||
let title = '';
|
||||
const url = `https://wx.zsxq.com/topic/${topic.topic_id}`;
|
||||
switch (topic.type) {
|
||||
case 'talk':
|
||||
title = topic.talk?.text?.split('\n', 1)[0] ?? '文章';
|
||||
title = topic.talk?.text ?? '文章';
|
||||
description = parseTopicContent(topic.talk?.text, topic.talk?.images);
|
||||
break;
|
||||
case 'q&a':
|
||||
title = topic.question?.text?.split('\n', 1)[0] ?? '问答';
|
||||
title = topic.question?.text ?? '问答';
|
||||
description = parseTopicContent(topic.question?.text, topic.question?.images);
|
||||
description = `<blockquote>${topic.question?.owner?.name ?? '匿名用户'} 提问:${description}</blockquote>`;
|
||||
description = `<blockquote>${String(html`${topic.question?.owner?.name ?? '匿名用户'}`)} 提问:${description}</blockquote>`;
|
||||
if (topic.answered) {
|
||||
description += '<br>' + topic.answer?.owner.name + ' 回答:<br><br>';
|
||||
description += '<br>' + String(html`${topic.answer?.owner?.name ?? '匿名用户'}`) + ' 回答:<br><br>';
|
||||
description += parseTopicContent(topic.answer?.text, topic.answer?.images);
|
||||
}
|
||||
break;
|
||||
case 'task':
|
||||
title = topic.task?.text?.split('\n', 1)[0] ?? '作业';
|
||||
title = topic.task?.text ?? '作业';
|
||||
description = parseTopicContent(topic.task?.text, topic.task?.images);
|
||||
break;
|
||||
case 'solution':
|
||||
title = topic.solution?.text?.split('\n', 1)[0] ?? '写作业';
|
||||
title = topic.solution?.text ?? '写作业';
|
||||
description = parseTopicContent(topic.solution?.text, topic.solution?.images);
|
||||
break;
|
||||
default:
|
||||
throw new Error('Unsupported Knowledge Planet topic type; update RSSHub or report this topic format.');
|
||||
}
|
||||
return {
|
||||
title: topic.title ?? title,
|
||||
description,
|
||||
pubDate: parseDate(topic.create_time),
|
||||
pubDate: topic.create_time ? parseDate(topic.create_time) : undefined,
|
||||
link: url,
|
||||
};
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user