mirror of
https://github.com/ajnart/homarr.git
synced 2026-03-04 19:30:57 +01:00
fix: rss widget post sorting (#1855)
This commit is contained in:
@@ -18,7 +18,7 @@ type CustomItem = {
|
||||
'media:group'?: {
|
||||
'media:description'?: string;
|
||||
'media:thumbnail'?: string;
|
||||
},
|
||||
};
|
||||
pubDate?: string;
|
||||
};
|
||||
|
||||
@@ -44,10 +44,10 @@ const rssFeedResultObjectSchema = z
|
||||
title: z.string(),
|
||||
content: z.string(),
|
||||
pubDate: z.date().optional(),
|
||||
}),
|
||||
})
|
||||
),
|
||||
}),
|
||||
}),
|
||||
})
|
||||
);
|
||||
|
||||
export const rssRouter = createTRPCRouter({
|
||||
@@ -57,7 +57,7 @@ export const rssRouter = createTRPCRouter({
|
||||
widgetId: z.string().uuid(),
|
||||
feedUrls: z.array(z.string()),
|
||||
configName: z.string(),
|
||||
}),
|
||||
})
|
||||
)
|
||||
.output(z.array(rssFeedResultObjectSchema))
|
||||
.query(async ({ input }) => {
|
||||
@@ -80,13 +80,23 @@ export const rssRouter = createTRPCRouter({
|
||||
|
||||
return await Promise.all(
|
||||
input.feedUrls.map(async (feedUrl) =>
|
||||
getFeedUrl(feedUrl, rssWidget.properties.dangerousAllowSanitizedItemContent),
|
||||
),
|
||||
getFeedUrl(
|
||||
feedUrl,
|
||||
rssWidget.properties.dangerousAllowSanitizedItemContent,
|
||||
rssWidget.properties.sortPostsWithoutPublishDateToTheTop,
|
||||
rssWidget.properties.maximumAmountOfPosts
|
||||
)
|
||||
)
|
||||
);
|
||||
}),
|
||||
});
|
||||
|
||||
const getFeedUrl = async (feedUrl: string, dangerousAllowSanitizedItemContent: boolean) => {
|
||||
const getFeedUrl = async (
|
||||
feedUrl: string,
|
||||
dangerousAllowSanitizedItemContent: boolean,
|
||||
sortPostsWithoutPubDateToTop: boolean,
|
||||
maximumAmountOfPosts: number
|
||||
) => {
|
||||
Consola.info(`Requesting RSS feed at url ${feedUrl}`);
|
||||
const stopWatch = new Stopwatch();
|
||||
const feed = await parser.parseURL(feedUrl);
|
||||
@@ -103,32 +113,34 @@ const getFeedUrl = async (feedUrl: string, dangerousAllowSanitizedItemContent: b
|
||||
'media:group'?: {
|
||||
'media:description'?: string;
|
||||
'media:thumbnail'?: string;
|
||||
}
|
||||
};
|
||||
categories: string[] | { _: string }[];
|
||||
pubDate?: string;
|
||||
}) => ({
|
||||
...item,
|
||||
categories: item.categories
|
||||
?.map((category) => (typeof category === 'string' ? category : category._))
|
||||
.filter((category: unknown): category is string => typeof category === 'string'),
|
||||
title: item.title ? decode(item.title) : undefined,
|
||||
content: processItemContent(
|
||||
item['content:encoded'] ?? item.content ?? item['media:group']?.['media:description'],
|
||||
dangerousAllowSanitizedItemContent,
|
||||
),
|
||||
enclosure: createEnclosure(item),
|
||||
link: createLink(item),
|
||||
pubDate: item.pubDate ? new Date(item.pubDate) : null,
|
||||
}),
|
||||
}) => {
|
||||
Consola.info('item ' + item.title + ' has pub date ' + item.pubDate);
|
||||
return {
|
||||
...item,
|
||||
categories: item.categories
|
||||
?.map((category) => (typeof category === 'string' ? category : category._))
|
||||
.filter((category: unknown): category is string => typeof category === 'string'),
|
||||
title: item.title ? decode(item.title) : undefined,
|
||||
content: processItemContent(
|
||||
item['content:encoded'] ?? item.content ?? item['media:group']?.['media:description'],
|
||||
dangerousAllowSanitizedItemContent
|
||||
),
|
||||
enclosure: createEnclosure(item),
|
||||
link: createLink(item),
|
||||
pubDate: item.pubDate ? new Date(item.pubDate) : null,
|
||||
};
|
||||
}
|
||||
)
|
||||
.sort((a: { pubDate: number }, b: { pubDate: number }) => {
|
||||
if (!a.pubDate || !b.pubDate) {
|
||||
return 0;
|
||||
.sort((post1: { pubDate: number }, post2: { pubDate: number }) => {
|
||||
if (!post1.pubDate || !post2.pubDate) {
|
||||
return sortPostsWithoutPubDateToTop ? 1 : 0;
|
||||
}
|
||||
|
||||
return a.pubDate - b.pubDate;
|
||||
})
|
||||
.slice(0, 20),
|
||||
return post1.pubDate - post2.pubDate;
|
||||
}),
|
||||
};
|
||||
|
||||
return {
|
||||
@@ -169,7 +181,7 @@ const processItemContent = (content: string, dangerousAllowSanitizedItemContent:
|
||||
}
|
||||
|
||||
return encode(content, {
|
||||
level: "html5"
|
||||
level: 'html5',
|
||||
});
|
||||
};
|
||||
|
||||
@@ -195,7 +207,7 @@ const createEnclosure = (item: any) => {
|
||||
if (item['media:group'] && item['media:group']['media:thumbnail']) {
|
||||
// no clue why this janky parse is needed
|
||||
return {
|
||||
url: item['media:group']['media:thumbnail'][0].$.url
|
||||
url: item['media:group']['media:thumbnail'][0].$.url,
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user