Ostatnio aktywny 3 hours ago

Astro-theme-fuwari的Ech0说说获取参数

ech0-api.ts Surowy
1// Ech0 API 工具函数
2
3interface EssayData {
4 id: number;
5 content: string;
6 time: string;
7 tags: string[];
8 images?: string[];
9}
10
11/**
12 * 从Ech0 RSS获取动态数据
13 * @param apiUrl Ech0 API地址
14 * @returns 转换后的动态数据数组
15 */
16export async function fetchEch0Posts(apiUrl: string): Promise<EssayData[]> {
17 try {
18 const response = await fetch(`${apiUrl}/rss`);
19
20 if (!response.ok) {
21 throw new Error(`Failed to fetch Ech0 posts: ${response.status}`);
22 }
23
24 const xmlText = await response.text();
25 return parseRssData(xmlText);
26 } catch (error) {
27 console.error('Error fetching Ech0 posts:', error);
28 // 出错时返回空数组,避免页面崩溃
29 return [];
30 }
31}
32
33/**
34 * 解析RSS XML数据
35 * @param xmlText RSS XML文本
36 * @returns 转换后的动态数据数组
37 */
38function parseRssData(xmlText: string): EssayData[] {
39 // 使用正则表达式解析RSS数据,避免使用DOMParser(浏览器特有API)
40 const entryRegex = /<entry>([\s\S]*?)<\/entry>/g;
41 const entries: EssayData[] = [];
42 let match;
43
44 let index = 0;
45 while ((match = entryRegex.exec(xmlText)) !== null) {
46 const entryText = match[1];
47 index++;
48
49 // 提取更新时间
50 const updatedRegex = /<updated>([\s\S]*?)<\/updated>/;
51 const updatedMatch = entryText.match(updatedRegex);
52 const updated = updatedMatch ? updatedMatch[1] : '';
53
54 // 提取摘要(使用更宽松的正则表达式,支持换行符)
55 const summaryRegex = /<summary[^>]*>([\s\S]*?)<\/summary>/i;
56 const summaryMatch = entryText.match(summaryRegex);
57 const summary = summaryMatch ? summaryMatch[1] : '';
58
59 // 提取纯文本内容
60 const content = extractPlainText(summary);
61
62 // 提取图片
63 const images = extractImages(summary);
64
65 entries.push({
66 id: index,
67 content,
68 time: formatDate(updated),
69 tags: ['生活'], // 默认标签
70 images: images.length > 0 ? images : undefined
71 });
72 }
73
74 // 按ID倒序排列
75 return entries.sort((a, b) => b.id - a.id);
76}
77
78/**
79 * 从HTML中提取纯文本
80 * @param html HTML文本
81 * @returns 纯文本
82 */
83function extractPlainText(html: string): string {
84 // 解码HTML实体
85 let decodedHtml = html
86 .replace(/&lt;/g, '<')
87 .replace(/&gt;/g, '>')
88 .replace(/&amp;/g, '&')
89 .replace(/&quot;/g, '"')
90 .replace(/&#34;/g, '"')
91 .replace(/&#39;/g, "'")
92 .replace(/&#xA;/g, '\n');
93
94 // 使用正则表达式移除HTML标签
95 let plainText = decodedHtml.replace(/<[^>]*>/g, '').trim();
96
97 // 如果纯文本为空,说明可能是纯图片的说说,返回一个占位符
98 return plainText || '[图片]';
99}
100
101/**
102 * 从HTML中提取图片URL
103 * @param html HTML文本
104 * @returns 图片URL数组
105 */
106function extractImages(html: string): string[] {
107 console.log('原始HTML:', html);
108
109 // 解码HTML实体
110 let decodedHtml = html
111 .replace(/&lt;/g, '<')
112 .replace(/&gt;/g, '>')
113 .replace(/&amp;/g, '&')
114 .replace(/&quot;/g, '"')
115 .replace(/&#34;/g, '"')
116 .replace(/&#39;/g, "'");
117
118 console.log('解码后HTML:', decodedHtml);
119
120 // 使用更宽松的正则表达式提取图片URL
121 const imgRegex = /<img[^>]*src=["']([^"']+)["']/gi;
122 const images: string[] = [];
123 let match;
124
125 while ((match = imgRegex.exec(decodedHtml)) !== null) {
126 let url = match[1];
127 console.log('找到图片URL:', url);
128
129 // 将HTTP URL转换为HTTPS
130 if (url.startsWith('http://')) {
131 url = url.replace('http://', 'https://');
132 console.log('转换为HTTPS:', url);
133 }
134
135 images.push(url);
136 }
137
138 console.log('最终图片数组:', images);
139 return images;
140}
141
142/**
143 * 格式化日期
144 * @param dateString ISO日期字符串
145 * @returns YYYY-MM-DD格式的日期字符串
146 */
147function formatDate(dateString: string): string {
148 const date = new Date(dateString);
149 return date.toISOString().split('T')[0];
150}
151