feat(route): add route of obsidian publish (#16872)
* feat(route): add route of obsidian publish * feat(obsidian): Improve type safety by using DataItem in publish route * Update lib/routes/obsidian/publish.ts Co-authored-by: Tony <TonyRL@users.noreply.github.com> * Update lib/routes/obsidian/publish.ts Co-authored-by: Tony <TonyRL@users.noreply.github.com> * feat(obsidian): improve publish page data extraction * fix(obsidian): remove redundant namespace from route names * Update lib/routes/obsidian/publish.ts
This commit is contained in:
parent
2c58daa520
commit
d5f7821d65
|
|
@ -0,0 +1,6 @@
|
|||
import type { Namespace } from '@/types';
|
||||
|
||||
export const namespace: Namespace = {
|
||||
name: 'Obsidian',
|
||||
url: 'obsidian.md',
|
||||
};
|
||||
|
|
@ -0,0 +1,83 @@
|
|||
import { Route, DataItem } from '@/types';
|
||||
import { load } from 'cheerio';
|
||||
import ofetch from '@/utils/ofetch';
|
||||
import { getTitle } from './utils';
|
||||
import { config } from '@/config';
|
||||
import { parseDate } from '@/utils/parse-date';
|
||||
|
||||
export const route: Route = {
|
||||
path: '/publish/:id',
|
||||
categories: ['blog'],
|
||||
example: '/obsidian/publish/marshallontheroad',
|
||||
parameters: { id: '网站 id,由Publish持有者自定义' },
|
||||
features: {
|
||||
requireConfig: false,
|
||||
requirePuppeteer: false,
|
||||
antiCrawler: false,
|
||||
supportBT: false,
|
||||
supportPodcast: false,
|
||||
supportScihub: false,
|
||||
},
|
||||
radar: [
|
||||
{
|
||||
source: ['publish.obsidian.md/'],
|
||||
},
|
||||
],
|
||||
name: 'Publish',
|
||||
maintainers: ['Xy2002'],
|
||||
handler,
|
||||
url: 'publish.obsidian.md/',
|
||||
};
|
||||
|
||||
async function handler(ctx) {
|
||||
const id = ctx.req.param('id');
|
||||
const items = await fetchPage(id);
|
||||
|
||||
return {
|
||||
title: 'Obsidian Publish',
|
||||
language: 'en-us',
|
||||
item: items,
|
||||
link: 'https://publish.obsidian.md/',
|
||||
};
|
||||
}
|
||||
|
||||
async function fetchPage(id: string) {
|
||||
const baseUrl = `https://publish.obsidian.md/${id}`;
|
||||
const response = await ofetch(baseUrl);
|
||||
const $ = load(response);
|
||||
const preloadCacheUrl =
|
||||
$('script:contains("preloadCache")')
|
||||
.text()
|
||||
.match(/preloadCache\s*=\s*f\("([^"]+)"\);/)?.[1] || '';
|
||||
|
||||
let preloadCacheResponse: Record<string, { frontmatter?: Record<string, string> }>;
|
||||
try {
|
||||
preloadCacheResponse = await ofetch(preloadCacheUrl, {
|
||||
headers: {
|
||||
'User-Agent': config.trueUA,
|
||||
Referer: 'https://publish.obsidian.md/',
|
||||
Origin: 'https://publish.obsidian.m/',
|
||||
},
|
||||
});
|
||||
} catch {
|
||||
preloadCacheResponse = {};
|
||||
}
|
||||
|
||||
const items: DataItem[] = Object.entries(preloadCacheResponse)
|
||||
.map(([postKey, post]) => {
|
||||
if (!post) {
|
||||
return null;
|
||||
}
|
||||
const item: DataItem = {
|
||||
title: post.frontmatter?.title || getTitle(postKey),
|
||||
link: `${baseUrl}/${postKey.replaceAll(' ', '+').split('.md')[0]}`,
|
||||
pubDate: post.frontmatter?.['date created'] ? parseDate(post.frontmatter['date created']) : undefined,
|
||||
...post.frontmatter,
|
||||
};
|
||||
|
||||
return item;
|
||||
})
|
||||
.filter(Boolean) as DataItem[];
|
||||
|
||||
return items;
|
||||
}
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
const regex = /([^/]+)\.md$/;
|
||||
|
||||
const getTitle = (path: string): string => {
|
||||
const match = path.match(regex);
|
||||
return match ? match[1] : '';
|
||||
};
|
||||
|
||||
export { getTitle };
|
||||
Loading…
Reference in New Issue