42 lines
1.5 KiB
TypeScript
42 lines
1.5 KiB
TypeScript
import { COIN_KEYWORDS } from './watchlist';
|
|
|
|
export interface TruthPost {
|
|
url: string;
|
|
ts: number; // Unix ms
|
|
text: string;
|
|
}
|
|
|
|
const esc = (s: string) => s.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
|
|
/** RSS-Items per Regex (kein XML-Parser nötig — Feed ist flach und stabil). */
|
|
export function parseTruthFeed(xml: string): TruthPost[] {
|
|
const posts: TruthPost[] = [];
|
|
for (const item of xml.match(/<item>[\s\S]*?<\/item>/g) ?? []) {
|
|
const url = item.match(/<link>([^<]+)<\/link>/)?.[1]?.trim();
|
|
const pubDate = item.match(/<pubDate>([^<]+)<\/pubDate>/)?.[1];
|
|
const descRaw = item.match(/<description>([\s\S]*?)<\/description>/)?.[1] ?? '';
|
|
if (!url || !pubDate) continue;
|
|
const ts = Date.parse(pubDate);
|
|
if (Number.isNaN(ts)) continue;
|
|
const text = descRaw
|
|
.replace(/^<!\[CDATA\[|\]\]>$/g, '')
|
|
.replace(/<[^>]+>/g, ' ')
|
|
.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>').replace(/"/g, '"').replace(/'/g, "'").replace(/ /g, ' ')
|
|
.replace(/\s+/g, ' ')
|
|
.trim();
|
|
posts.push({ url, ts, text });
|
|
}
|
|
return posts;
|
|
}
|
|
|
|
/** Erwähnte Coins (Symbole, dedupliziert, in COIN_KEYWORDS-Reihenfolge). */
|
|
export function matchCoins(text: string): string[] {
|
|
const hits: string[] = [];
|
|
for (const c of COIN_KEYWORDS) {
|
|
const nameHit = c.names.some((n) => new RegExp(`\\b${esc(n)}\\b`, 'i').test(text));
|
|
const tickerHit = c.tickers.some((t) => new RegExp(`\\b${esc(t)}\\b`).test(text)); // case-sensitive
|
|
if (nameHit || tickerHit) hits.push(c.symbol);
|
|
}
|
|
return hits;
|
|
}
|