feat(route): add blogs from cockroach labs (#19421)
This commit is contained in:
parent
02645435aa
commit
97c8fa93f6
|
|
@ -0,0 +1,113 @@
|
|||
import { Route } from '@/types';
|
||||
import ofetch from '@/utils/ofetch';
|
||||
import { load } from 'cheerio';
|
||||
import cache from '@/utils/cache';
|
||||
import { parseDate } from '@/utils/parse-date';
|
||||
|
||||
export const route: Route = {
|
||||
name: 'Blogs',
|
||||
maintainers: ['CookiePieWw'],
|
||||
categories: ['programming'],
|
||||
path: '/blog/:category?',
|
||||
example: '/cockroachlabs/blog/engineering',
|
||||
parameters: { category: 'Blog category, e.g., engineering. Subscribe all recent articles if empty.' },
|
||||
features: {
|
||||
requireConfig: false,
|
||||
requirePuppeteer: false,
|
||||
antiCrawler: false,
|
||||
supportBT: false,
|
||||
supportPodcast: false,
|
||||
supportScihub: false,
|
||||
},
|
||||
radar: [
|
||||
{
|
||||
source: ['cockroachlabs.com/blog/:category', 'cockroachlabs.com/blog'],
|
||||
target: '/blog',
|
||||
},
|
||||
],
|
||||
handler,
|
||||
};
|
||||
|
||||
async function handler(ctx) {
|
||||
const category = ctx.req.param('category');
|
||||
const rootUrl = 'https://www.cockroachlabs.com';
|
||||
const currentUrl = `${rootUrl}/blog${category ? `/${category}/` : '/'}`;
|
||||
|
||||
const webpage = await ofetch(currentUrl);
|
||||
const html = load(webpage);
|
||||
|
||||
// Title article:
|
||||
// <a href="href..">
|
||||
// <h2 class="mb-3 truncate text-display-md font-semibold tracking-tight md:max-w-full md:text-white">
|
||||
// Title...
|
||||
// </h2>
|
||||
// </a>
|
||||
const titleH2Element = html('[class="mb-3 truncate text-display-md font-semibold tracking-tight md:max-w-full md:text-white"]');
|
||||
|
||||
// Left articles:
|
||||
// <a href="href..">
|
||||
// <p class="mb-2 line-clamp-2 text-lg font-semibold leading-5">
|
||||
// Title..
|
||||
// </p>
|
||||
// </a>
|
||||
const leftArticles = html('a > p[class="mb-2 line-clamp-2 text-lg font-semibold leading-5"]');
|
||||
const articleList = titleH2Element.add(leftArticles).map((_, element) => {
|
||||
const title = html(element).text();
|
||||
const link = `${rootUrl}${html(element).parent('a').attr('href')}`;
|
||||
return { title, link };
|
||||
});
|
||||
|
||||
const items = await Promise.all(
|
||||
articleList.toArray().map((article) =>
|
||||
cache.tryGet(article.link, async () => {
|
||||
const response = await ofetch(article.link);
|
||||
const $ = load(response);
|
||||
|
||||
// <article class="blog-content null">
|
||||
// ..multiple <div>/<a>/<img>/<p>..
|
||||
// </article>
|
||||
const content = $('article.blog-content').html() || '';
|
||||
|
||||
// <div class="mt-4 flex flex-col items-center justify-center gap-1 sm:flex-row sm:gap-4">
|
||||
// <div>
|
||||
// <p>
|
||||
// Last edited on June 13, 2025
|
||||
// </p>
|
||||
// </div>
|
||||
// ...
|
||||
// </div>
|
||||
const dateText = $(String.raw`div.mt-4.flex.flex-col.items-center.justify-center.gap-1.sm\:flex-row.sm\:gap-4`)
|
||||
.find('p')
|
||||
.first()
|
||||
.text()
|
||||
.match(/Last edited on (.+)/)?.[1];
|
||||
|
||||
let pubDate: Date | undefined;
|
||||
if (dateText) {
|
||||
try {
|
||||
const date = new Date(dateText);
|
||||
if (!Number.isNaN(date.getTime())) {
|
||||
pubDate = parseDate(date.toISOString().split('T')[0]);
|
||||
}
|
||||
} catch {
|
||||
// Ignore parsing errors
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
title: article.title,
|
||||
link: article.link,
|
||||
description: content,
|
||||
pubDate,
|
||||
};
|
||||
})
|
||||
)
|
||||
);
|
||||
|
||||
return {
|
||||
title: `Cockroach Labs Blog${category ? ` - ${category}` : ''}`,
|
||||
link: currentUrl,
|
||||
item: items,
|
||||
description: 'Cockroach Labs Blog',
|
||||
};
|
||||
}
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
import type { Namespace } from '@/types';
|
||||
|
||||
export const namespace: Namespace = {
|
||||
name: 'Cockroach Labs',
|
||||
url: 'cockroachlabs.com',
|
||||
lang: 'en',
|
||||
};
|
||||
Loading…
Reference in New Issue