72 lines
1.9 KiB
TypeScript
72 lines
1.9 KiB
TypeScript
|
|
import { Hono } from 'hono';
|
||
|
|
import { serve } from 'bun';
|
||
|
|
import Parser from 'rss-parser';
|
||
|
|
import { Feed, type Item } from 'feed';
|
||
|
|
|
||
|
|
const app = new Hono();
|
||
|
|
const parser = new Parser();
|
||
|
|
|
||
|
|
app.get('/group-by-day', async (c) => {
|
||
|
|
const feedUrl = c.req.query('feedUrl');
|
||
|
|
if (!feedUrl) {
|
||
|
|
return c.text('Missing feedUrl query parameter', 400);
|
||
|
|
}
|
||
|
|
try {
|
||
|
|
const { title, feedUrl: feedId, link: feedLink, items } = await parser.parseURL(feedUrl);
|
||
|
|
|
||
|
|
const grouped = items.reduce((acc, { pubDate, content, contentSnippet, summary, link }) => {
|
||
|
|
const day = new Date(pubDate as string).toISOString().slice(0, 10);
|
||
|
|
acc[day] = acc[day] || [];
|
||
|
|
acc[day].push({
|
||
|
|
link,
|
||
|
|
content: content || contentSnippet || summary || ''
|
||
|
|
});
|
||
|
|
return acc;
|
||
|
|
}, {});
|
||
|
|
|
||
|
|
const days = Object.keys(grouped).sort().reverse();
|
||
|
|
const today = new Date();
|
||
|
|
today.setHours(0, 0, 0, 0);
|
||
|
|
|
||
|
|
const feedItems: Item[] = days.map(day => {
|
||
|
|
const dateStr = new Date(day).toLocaleDateString('en-US', {
|
||
|
|
year: 'numeric',
|
||
|
|
month: 'long',
|
||
|
|
day: 'numeric'
|
||
|
|
});
|
||
|
|
return {
|
||
|
|
title: `${title} - ${dateStr}`,
|
||
|
|
id: day,
|
||
|
|
date: new Date(day),
|
||
|
|
link: grouped[day][0].link,
|
||
|
|
content: grouped[day].map((p: any) => p.content).join('\n\n---------------------\n\n')
|
||
|
|
};
|
||
|
|
}).filter(p => p.date < today);
|
||
|
|
|
||
|
|
const outFeed = new Feed({
|
||
|
|
title: title as string,
|
||
|
|
id: feedId as string,
|
||
|
|
link: feedLink,
|
||
|
|
copyright: ''
|
||
|
|
});
|
||
|
|
|
||
|
|
for (const item of feedItems) {
|
||
|
|
outFeed.addItem(item)
|
||
|
|
}
|
||
|
|
|
||
|
|
const xml = outFeed.rss2();
|
||
|
|
|
||
|
|
return c.text(xml, 200, {
|
||
|
|
'Content-Type': 'text/xml',
|
||
|
|
});
|
||
|
|
} catch (err: any) {
|
||
|
|
return c.text(`Error fetching or processing feed: ${err.message}`, 500);
|
||
|
|
}
|
||
|
|
});
|
||
|
|
|
||
|
|
// Start Bun server on port 3000
|
||
|
|
serve({
|
||
|
|
fetch: app.fetch,
|
||
|
|
port: 3000
|
||
|
|
});
|