feat(route/railway): add Railway blog configuration (#19678)
* feat(route/railway): add Railway blog configuration * style: auto format * feat(route/railway): update namespace for Railway Blog * fix(route/railway): correct namespace name and URL for Railway * Update lib/routes/railway/index.ts Co-authored-by: Tony <TonyRL@users.noreply.github.com> --------- Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
This commit is contained in:
parent
5e92c1630c
commit
4a1e5c36aa
|
|
@ -0,0 +1,73 @@
|
|||
import { Route, DataItem } from '@/types';
|
||||
|
||||
import cache from '@/utils/cache';
|
||||
import { load } from 'cheerio';
|
||||
import { parseDate } from '@/utils/parse-date';
|
||||
import ofetch from '@/utils/ofetch';
|
||||
import { Context } from 'hono';
|
||||
|
||||
export const route: Route = {
|
||||
path: '/blog',
|
||||
categories: ['blog'],
|
||||
example: '/railway/blog',
|
||||
url: 'blog.railway.com',
|
||||
name: 'Blog',
|
||||
maintainers: ['jihuayu'],
|
||||
handler,
|
||||
};
|
||||
|
||||
async function handler(ctx: Context) {
|
||||
const limit = Number.parseInt(ctx.req.query('limit') || '10');
|
||||
|
||||
const items = await fetchArticles(limit);
|
||||
|
||||
return {
|
||||
title: 'Railway articles',
|
||||
link: 'https://blog.railway.com',
|
||||
item: items,
|
||||
};
|
||||
}
|
||||
|
||||
export const fetchArticles = async (limit: number): Promise<DataItem[]> => {
|
||||
const page = await ofetch('https://blog.railway.com/rss.xml', {
|
||||
responseType: 'text',
|
||||
});
|
||||
|
||||
const $ = load(page, { xml: true });
|
||||
|
||||
return Promise.all(
|
||||
$('item')
|
||||
.toArray()
|
||||
.slice(0, limit)
|
||||
.map<Promise<DataItem>>((element) => {
|
||||
const id = $(element).find('guid').text();
|
||||
|
||||
return cache.tryGet(`railway:blogs:${id}`, async () => {
|
||||
const title = $(element).find('title').text();
|
||||
const pubDate = $(element).find('pubDate').text();
|
||||
const link = $(element).find('link').text();
|
||||
|
||||
const { content } = await fetchArticleDetails(link);
|
||||
|
||||
return {
|
||||
guid: id,
|
||||
title,
|
||||
link,
|
||||
pubDate: parseDate(pubDate),
|
||||
description: content,
|
||||
} as DataItem;
|
||||
}) as Promise<DataItem>;
|
||||
})
|
||||
);
|
||||
};
|
||||
|
||||
export const fetchArticleDetails = async (url: string) => {
|
||||
const page = await ofetch(url);
|
||||
const $ = load(page);
|
||||
|
||||
const $article = $('article > section ');
|
||||
|
||||
return {
|
||||
content: $article.html() ?? undefined,
|
||||
};
|
||||
};
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
import type { Namespace } from '@/types';
|
||||
|
||||
export const namespace: Namespace = {
|
||||
name: 'Railway',
|
||||
url: 'railway.com',
|
||||
description: '',
|
||||
lang: 'en',
|
||||
};
|
||||
Loading…
Reference in New Issue