| import xml2js from "xml2js"; |
| import { savePosts, isGuidExists } from "./db.js"; |
|
|
| |
| function cleanDescription(desc) { |
| if (!desc) return "无内容"; |
| |
| let text = desc.replace(/<[^>]+>/g, ""); |
| |
| text = text.replace(/阅读完整话题/g, ""); |
| text = text.replace(/Read full topic/gi, ""); |
| |
| text = text.replace(/\s+/g, " "); |
| return text.trim() || "无内容"; |
| } |
|
|
| |
| |
| |
| |
| |
| export async function parseRss(xmlData) { |
| const parser = new xml2js.Parser({ explicitArray: false, trim: true }); |
| const result = await parser.parseStringPromise(xmlData); |
| const channel = result.rss.channel; |
| const items = channel.item; |
| const extractedItems = []; |
| if (items && Array.isArray(items)) { |
| for (const item of items) { |
| extractedItems.push({ |
| title: item.title, |
| creator: item["dc:creator"], |
| description: item.description, |
| link: item.link, |
| pubDate: item.pubDate, |
| guid: item.guid?._, |
| guidIsPermaLink: item.guid?.$?.isPermaLink, |
| source: item.source?._, |
| sourceUrl: item.source?.$?.url, |
| }); |
| } |
| } else if (items) { |
| extractedItems.push({ |
| title: items.title, |
| creator: items["dc:creator"], |
| description: items.description, |
| link: items.link, |
| pubDate: items.pubDate, |
| guid: items.guid?._, |
| guidIsPermaLink: items.guid?.$?.isPermaLink, |
| source: items.source?._, |
| sourceUrl: items.source?.$?.url, |
| }); |
| } |
| const reversedItems = extractedItems.reverse(); |
|
|
| |
| const newItems = []; |
| for (const item of reversedItems) { |
| if (item.guid) { |
| const exists = await isGuidExists(item.guid); |
| if (exists) { |
| console.warn(`GUID ${item.guid} 已存在,跳过。`); |
| continue; |
| } |
| } |
| newItems.push(item); |
| } |
|
|
| |
| if (newItems.length === 0) { |
| console.log("没有新帖子需要处理"); |
| return ""; |
| } |
|
|
| |
| try { |
| await savePosts(newItems); |
| console.log(`成功保存 ${newItems.length} 个新帖子到数据库`); |
| } catch (e) { |
| console.error("保存帖子到数据库失败:", e); |
| |
| return ""; |
| } |
|
|
| |
| const textContentArr = []; |
| for (let idx = 0; idx < newItems.length; idx++) { |
| const item = newItems[idx]; |
| const isFirst = idx === 0; |
| const isLast = idx === newItems.length - 1; |
| const msg = [ |
| isFirst ? `标题: ${item.title}` : "", |
| `作者: ${item.creator}`, |
| isFirst |
| ? `内容: ${cleanDescription(item.description)}` |
| : `回复: ${cleanDescription(item.description)}`, |
| `时间: ${item.pubDate}`, |
| isLast ? `链接: ${item.link}` : "", |
| "", |
| ] |
| .filter(Boolean) |
| .join("\n") |
| .trim(); |
| if (msg) { |
| textContentArr.push(msg); |
| } |
| } |
|
|
| const textContent = textContentArr.filter(Boolean).join("\n"); |
| return textContent; |
| } |
|
|