diff --git a/lib/routes/openai/blog.ts b/lib/routes/openai/blog.ts index b7814380c27163..5f77ffc8d920e8 100644 --- a/lib/routes/openai/blog.ts +++ b/lib/routes/openai/blog.ts @@ -5,7 +5,7 @@ import { getApiUrl, parseArticle } from './common'; export const route: Route = { path: '/blog/:tag?', - categories: ['new-media'], + categories: ['programming'], example: '/openai/blog', parameters: { tag: 'Tag, see below, All by default' }, features: { diff --git a/lib/routes/openai/chatgpt.ts b/lib/routes/openai/chatgpt.ts index 507dc15a54facc..15aba9dde7dd8c 100644 --- a/lib/routes/openai/chatgpt.ts +++ b/lib/routes/openai/chatgpt.ts @@ -10,7 +10,7 @@ dayjs.extend(isSameOrBefore); export const route: Route = { path: '/chatgpt/release-notes', - categories: ['new-media'], + categories: ['program-update'], example: '/openai/chatgpt/release-notes', parameters: {}, features: { diff --git a/lib/routes/openai/cookbook.ts b/lib/routes/openai/cookbook.ts new file mode 100644 index 00000000000000..e0f87f90942881 --- /dev/null +++ b/lib/routes/openai/cookbook.ts @@ -0,0 +1,77 @@ +import { Route } from '@/types'; +import cache from '@/utils/cache'; +import { load } from 'cheerio'; +import logger from '@/utils/logger'; +import ofetch from '@/utils/ofetch'; + +export const route: Route = { + path: '/cookbook', + categories: ['programming'], + description: + 'OpenAI Cookbook 提供了大量使用 OpenAI API 的实用指南和示例代码,涵盖了从基础到高级的各种主题,包括 GPT 模型、嵌入、函数调用、微调等。这里汇集了最新的 API 功能介绍和流行的应用案例,是开发者学习和应用 OpenAI 技术的宝贵资源。', + maintainers: ['liyaozhong'], + radar: [ + { + source: ['cookbook.openai.com/'], + }, + ], + url: 'cookbook.openai.com/', + handler, + example: '/openai/cookbook', + name: 'Cookbook', +}; + +async function handler() { + const rootUrl = 'https://cookbook.openai.com'; + const currentUrl = `${rootUrl}/`; + + try { + const response = await ofetch(currentUrl); + const $ = load(response); + + let items = $('[class="min-h-[90vh]"] .grid a') + .toArray() + .map((element) => { + const $element = $(element); + const $title = $element.find('div.font-semibold.text-sm.text-primary.line-clamp-1.overflow-ellipsis'); + const $date = $element.find(String.raw`span.text-xs.text-muted-foreground.md\:w-24.text-end`); + const $author = $element.find('p:contains("OpenAI")'); + const $tags = $element.find('span[style^="color:"]'); + + return { + title: $title.text().trim(), + link: `${rootUrl}/${$element.attr('href')}`, + pubDate: $date.text().trim(), + author: $author.text().replace('OpenAI', '').trim(), + category: $tags.toArray().map((tag) => $(tag).text().trim()), + }; + }); + + items = ( + await Promise.all( + items.map((item) => + cache.tryGet(item.link, async () => { + try { + const detailResponse = await ofetch(item.link); + const $ = load(detailResponse); + + item.description = $(String.raw`article.prose.prose-sm.sm\:prose-base.max-w-none.dark\:prose-invert`).html(); + return item; + } catch { + return { ...item, description: '' }; + } + }) + ) + ) + ).filter((item) => item?.description); + + return { + title: 'OpenAI Cookbook', + link: currentUrl, + item: items, + }; + } catch (error) { + logger.error(`处理 OpenAI Cookbook 请求时发生错误: ${error}`); + throw error; + } +} diff --git a/lib/routes/openai/research.ts b/lib/routes/openai/research.ts index 9a6dba2352596a..b0a0b0e6f50532 100644 --- a/lib/routes/openai/research.ts +++ b/lib/routes/openai/research.ts @@ -4,7 +4,7 @@ import { getApiUrl, parseArticle } from './common'; export const route: Route = { path: '/research', - categories: ['new-media'], + categories: ['programming'], example: '/openai/research', parameters: {}, features: {