From 0a79a862a7e46ec2b944b3f0271e4f545b52a143 Mon Sep 17 00:00:00 2001 From: pandada8 Date: Wed, 2 Oct 2024 03:34:24 +0800 Subject: [PATCH] feat(routes/ceph): add ceph blog (#16980) * feat(routes/ceph): add ceph blog * Apply suggestions from code review Co-authored-by: Tony * fix(route/ceph): add 1hour cache for index, fix url double slash * fix(route/ceph): remove unnecessary caching --------- --- lib/routes/ceph/blog.ts | 72 ++++++++++++++++++++++++++++++++++++ lib/routes/ceph/namespace.ts | 7 ++++ 2 files changed, 79 insertions(+) create mode 100644 lib/routes/ceph/blog.ts create mode 100644 lib/routes/ceph/namespace.ts diff --git a/lib/routes/ceph/blog.ts b/lib/routes/ceph/blog.ts new file mode 100644 index 000000000..7c5e1dc9a --- /dev/null +++ b/lib/routes/ceph/blog.ts @@ -0,0 +1,72 @@ +import { Data, Route } from '@/types'; +import cache from '@/utils/cache'; +import got from '@/utils/got'; +import { load } from 'cheerio'; +import { parseDate } from '@/utils/parse-date'; +import { Context } from 'hono'; + +export const route: Route = { + path: '/blog/:topic?', + categories: ['blog'], + example: '/ceph/blog/a11y', + parameters: { + category: 'filter blog post by category, return all posts if not specified', + }, + features: { + requireConfig: false, + requirePuppeteer: false, + antiCrawler: false, + supportBT: false, + supportPodcast: false, + supportScihub: false, + }, + radar: [ + { + source: ['ceph.io/'], + }, + ], + name: 'Blog', + maintainers: ['pandada8'], + handler, + url: 'ceph.io', +}; + +async function handler(ctx: Context): Promise { + const { category } = ctx.req.param(); + const url = category ? `https://ceph.io/en/news/blog/category/${category}/` : 'https://ceph.io/en/news/blog/'; + const response = await got.get(url); + const data = response.data; + const $ = load(data); + const list = $('#main .section li') + .toArray() + .map((e) => { + const element = $(e); + const title = element.find('a').text().trim(); + const pubDate = parseDate(element.find('time').attr('datetime')); + return { + title, + link: new URL(element.find('a').attr('href'), 'https://ceph.io').href, + pubDate, + }; + }); + + const result = await Promise.all( + list.map((item) => + cache.tryGet(item.link, async () => { + const itemReponse = await got.get(item.link); + const data = itemReponse.data; + const item$ = load(data); + + item.author = item$('#main section > div:nth-child(1) span').text().trim(); + item.description = item$('#main section > div:nth-child(2) > div').html(); + return item; + }) + ) + ); + + return { + title: 'Ceph Blog', + link: url, + item: result, + }; +} diff --git a/lib/routes/ceph/namespace.ts b/lib/routes/ceph/namespace.ts new file mode 100644 index 000000000..0585fb5b5 --- /dev/null +++ b/lib/routes/ceph/namespace.ts @@ -0,0 +1,7 @@ +import type { Namespace } from '@/types'; + +export const namespace: Namespace = { + name: 'Ceph', + url: 'ceph.io', + description: 'Ceph is an open source distributed storage system designed to evolve with data.', +};