forked from DIYgod/RSSHub
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #324 from DIYgod/master
[pull] master from diygod:master
- Loading branch information
Showing
13 changed files
with
842 additions
and
213 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
import type { Namespace } from '@/types'; | ||
|
||
export const namespace: Namespace = { | ||
name: 'Deepseek', | ||
url: 'api-docs.deepseek.com', | ||
description: 'Deepseek API 文档。', | ||
lang: 'zh-CN', | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
import { Route, Data, DataItem } from '@/types'; | ||
import ofetch from '@/utils/ofetch'; | ||
import { load } from 'cheerio'; | ||
import cache from '@/utils/cache'; | ||
|
||
const ROOT_URL = 'https://api-docs.deepseek.com/zh-cn'; | ||
|
||
const NEWS_LIST_SELECTOR = 'ul.menu__list > li:nth-child(2) ul > li.theme-doc-sidebar-item-link'; | ||
const ARTICLE_CONTENT_SELECTOR = '.theme-doc-markdown > div > div'; | ||
const ARTICLE_TITLE_SELECTOR = ARTICLE_CONTENT_SELECTOR + ' > h1'; | ||
|
||
// 获取消息列表 / get article list | ||
const fetchPageContent = async (url: string) => { | ||
const response = await ofetch(url); | ||
return load(response); | ||
}; | ||
|
||
// 提取正文内容 / extract article content | ||
const extractArticleInfo = ($article: cheerio.Root, pageURL: string) => { | ||
const contentElement = $article(ARTICLE_CONTENT_SELECTOR); | ||
const title = $article(ARTICLE_TITLE_SELECTOR).text(); | ||
$article(ARTICLE_TITLE_SELECTOR).remove(); // 移除标题,避免重复 / remove title to avoid duplication | ||
const content = contentElement.html(); | ||
return { title, content, pageURL }; | ||
}; | ||
|
||
const parseDateString = (dateString: string) => { | ||
const pubDate = new Date(dateString); | ||
return pubDate.toUTCString(); | ||
}; | ||
|
||
// 创建消息 / create article | ||
const createDataItem = (item: cheerio.Element, $: cheerio.Root): Promise<DataItem> => { | ||
const $item = $(item); | ||
const link = $item.find('a').attr('href'); | ||
const dateString = $item.find('a').text().split(' ').at(-1); | ||
const pageURL = new URL(link || '', ROOT_URL).href; | ||
|
||
return cache.tryGet(pageURL, async () => { | ||
const $article = await fetchPageContent(pageURL); | ||
const { title, content } = extractArticleInfo($article, pageURL); | ||
const pubDate = parseDateString(dateString); | ||
|
||
return { | ||
title, | ||
link: pageURL, | ||
pubDate, | ||
description: content || undefined, | ||
}; | ||
}); | ||
}; | ||
|
||
const handler = async (): Promise<Data> => { | ||
const $ = await fetchPageContent(ROOT_URL); | ||
const newsList = $(NEWS_LIST_SELECTOR); | ||
|
||
const items: DataItem[] = await Promise.all(newsList.toArray().map((li) => createDataItem(li, $))); | ||
|
||
return { | ||
title: 'DeepSeek 新闻', | ||
link: ROOT_URL, | ||
item: items, | ||
allowEmpty: true, | ||
}; | ||
}; | ||
|
||
export const route: Route = { | ||
path: '/news', | ||
categories: ['programming'], | ||
example: '/deepseek/news', | ||
features: { | ||
requireConfig: false, | ||
requirePuppeteer: false, | ||
antiCrawler: false, | ||
supportBT: false, | ||
supportPodcast: false, | ||
supportScihub: false, | ||
}, | ||
radar: [ | ||
{ | ||
source: ['api-docs.deepseek.com'], | ||
target: '/news', | ||
}, | ||
], | ||
name: '新闻', | ||
maintainers: ['1837634311'], | ||
handler, | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,115 @@ | ||
import { type CheerioAPI, load } from 'cheerio'; | ||
import { type Context } from 'hono'; | ||
|
||
import { type DataItem, type Route, type Data, ViewType } from '@/types'; | ||
|
||
import ofetch from '@/utils/ofetch'; | ||
|
||
import { rootUrl, processItems } from './util'; | ||
import InvalidParameterError from '@/errors/types/invalid-parameter'; | ||
|
||
export const handler = async (ctx: Context): Promise<Data> => { | ||
const { id } = ctx.req.param(); | ||
|
||
if (!id) { | ||
throw new InvalidParameterError('请填入合法的分类 id,参见广场 https://www.jisilu.cn/explore/'); | ||
} | ||
|
||
const limit: number = Number.parseInt(ctx.req.query('limit') ?? '30', 10); | ||
|
||
const targetUrl: string = new URL(`/category/${id}`, rootUrl).href; | ||
|
||
const response = await ofetch(targetUrl); | ||
const $: CheerioAPI = load(response); | ||
const language: string = $('html').prop('lang') ?? 'zh'; | ||
|
||
const items: DataItem[] = await processItems($, $('div.aw-question-list'), limit); | ||
|
||
$('div.pagination').remove(); | ||
|
||
const author = $('meta[name="keywords"]').prop('content').split(/,/)[0]; | ||
const feedImage = $('div.aw-logo img').prop('src'); | ||
|
||
return { | ||
title: `${$('title').text()} - ${$('li.active') | ||
.slice(1) | ||
.toArray() | ||
.map((l) => $(l).text()) | ||
.join('|')}`, | ||
description: $('meta[name="description"]').prop('content'), | ||
link: targetUrl, | ||
item: items, | ||
allowEmpty: true, | ||
image: feedImage, | ||
author, | ||
language, | ||
id: targetUrl, | ||
}; | ||
}; | ||
|
||
export const route: Route = { | ||
path: '/category/:id', | ||
name: '分类', | ||
url: 'www.jisilu.cn', | ||
maintainers: ['nczitzk'], | ||
handler, | ||
example: '/jisilu/category/4', | ||
parameters: { | ||
id: '分类 id,可在对应分类页 URL 中找到', | ||
}, | ||
description: `:::tip | ||
若订阅 [债券/可转债](https://www.jisilu.cn/category/4),网址为 \`https://www.jisilu.cn/category/4\`,请截取 \`https://www.jisilu.cn/category/\` 到末尾的部分 \`4\` 作为 \`id\` 参数填入,此时目标路由为 [\`/jisilu/category/4\`](https://rsshub.app/jisilu/category/4)。 | ||
::: | ||
| 新股 | 债券/可转债 | 套利 | 其他 | 基金 | 股票 | | ||
| ---- | ----------- | ---- | ---- | ---- | ---- | | ||
| 3 | 4 | 5 | 6 | 7 | 8 | | ||
`, | ||
categories: ['finance'], | ||
features: { | ||
requireConfig: false, | ||
requirePuppeteer: false, | ||
antiCrawler: false, | ||
supportRadar: true, | ||
supportBT: false, | ||
supportPodcast: false, | ||
supportScihub: false, | ||
}, | ||
radar: [ | ||
{ | ||
source: ['www.jisilu.cn/category/:id'], | ||
target: '/category/:id', | ||
}, | ||
{ | ||
title: '新股', | ||
source: ['www.jisilu.cn/category/3'], | ||
target: '/category/3', | ||
}, | ||
{ | ||
title: '债券/可转债', | ||
source: ['www.jisilu.cn/category/4'], | ||
target: '/category/4', | ||
}, | ||
{ | ||
title: '套利', | ||
source: ['www.jisilu.cn/category/5'], | ||
target: '/category/5', | ||
}, | ||
{ | ||
title: '其他', | ||
source: ['www.jisilu.cn/category/6'], | ||
target: '/category/6', | ||
}, | ||
{ | ||
title: '基金', | ||
source: ['www.jisilu.cn/category/7'], | ||
target: '/category/7', | ||
}, | ||
{ | ||
title: '股票', | ||
source: ['www.jisilu.cn/category/8'], | ||
target: '/category/8', | ||
}, | ||
], | ||
view: ViewType.Articles, | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
import { type CheerioAPI, load } from 'cheerio'; | ||
import { type Context } from 'hono'; | ||
|
||
import { type DataItem, type Route, type Data, ViewType } from '@/types'; | ||
|
||
import ofetch from '@/utils/ofetch'; | ||
|
||
import { rootUrl, processItems } from './util'; | ||
|
||
export const handler = async (ctx: Context): Promise<Data> => { | ||
const { filter } = ctx.req.param(); | ||
const limit: number = Number.parseInt(ctx.req.query('limit') ?? '30', 10); | ||
|
||
const targetUrl: string = new URL(`/${filter ? 'home/' : ''}explore/${filter ?? ''}`, rootUrl).href; | ||
|
||
const response = await ofetch(targetUrl); | ||
const $: CheerioAPI = load(response); | ||
const language: string = $('html').prop('lang') ?? 'zh'; | ||
|
||
const items: DataItem[] = await processItems($, $('div.aw-question-list'), limit); | ||
|
||
$('div.pagination').remove(); | ||
|
||
const author = $('meta[name="keywords"]').prop('content').split(/,/)[0]; | ||
const feedImage = $('div.aw-logo img').prop('src'); | ||
|
||
return { | ||
title: `${$('title').text()} - ${$('li.active') | ||
.slice(1) | ||
.toArray() | ||
.map((l) => $(l).text()) | ||
.join('|')}`, | ||
description: $('meta[name="description"]').prop('content'), | ||
link: targetUrl, | ||
item: items, | ||
allowEmpty: true, | ||
image: feedImage, | ||
author, | ||
language, | ||
id: targetUrl, | ||
}; | ||
}; | ||
|
||
export const route: Route = { | ||
path: '/explore/:filter?', | ||
name: '广场', | ||
url: 'www.jisilu.cn', | ||
maintainers: ['nczitzk'], | ||
handler, | ||
example: '/jisilu/explore', | ||
parameters: { | ||
category: '过滤器,默认为空,可在对应页 URL 中找到', | ||
}, | ||
description: `:::tip | ||
若订阅 [债券/可转债 - 热门 - 30天](https://www.jisilu.cn/home/explore/category-4__sort_type-hot__day-30),网址为 \`https://www.jisilu.cn/home/explore/category-4__sort_type-hot__day-30\`,请截取 \`https://www.jisilu.cn/home/explore/\` 到末尾的部分 \`category-4__sort_type-hot__day-30\` 作为 \`filter\` 参数填入,此时目标路由为 [\`/jisilu/explore/category-4__sort_type-hot__day-30\`](https://rsshub.app/jisilu/explore/category-4__sort_type-hot__day-30)。 | ||
::: | ||
`, | ||
categories: ['finance'], | ||
features: { | ||
requireConfig: false, | ||
requirePuppeteer: false, | ||
antiCrawler: false, | ||
supportRadar: true, | ||
supportBT: false, | ||
supportPodcast: false, | ||
supportScihub: false, | ||
}, | ||
radar: [ | ||
{ | ||
source: ['www.jisilu.cn/home/explore/:filter', 'www.jisilu.cn/home/explore', 'www.jisilu.cn/explore'], | ||
target: (params) => { | ||
const filter = params.filter; | ||
|
||
return `/jisilu/explore${filter ? `/${filter}` : ''}`; | ||
}, | ||
}, | ||
], | ||
view: ViewType.Articles, | ||
}; |
Oops, something went wrong.