rsshub 1.0.0-master.ff3a9ce → 1.0.0-master.ff3ea5a
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/config.ts +38 -0
- package/lib/errors/index.tsx +3 -2
- package/lib/middleware/debug.ts +6 -4
- package/lib/middleware/header.ts +4 -2
- package/lib/registry.test.ts +24 -1
- package/lib/registry.ts +40 -11
- package/lib/router.js +1 -1
- package/lib/routes/121/namespace.ts +9 -0
- package/lib/routes/121/templates/description.art +17 -0
- package/lib/routes/121/weather-live.ts +104 -0
- package/lib/routes/141jav/index.ts +3 -0
- package/lib/routes/141ppv/index.ts +3 -0
- package/lib/routes/163/news/rank.ts +1 -1
- package/lib/routes/18comic/album.ts +59 -64
- package/lib/routes/18comic/index.ts +1 -0
- package/lib/routes/18comic/search.ts +53 -4
- package/lib/routes/18comic/utils.ts +70 -1
- package/lib/routes/2048/index.ts +1 -0
- package/lib/routes/30secondsofcode/utils.ts +0 -1
- package/lib/routes/6park/index.ts +1 -1
- package/lib/routes/7mmtv/index.ts +1 -0
- package/lib/routes/91porn/index.ts +1 -0
- package/lib/routes/95mm/tab.ts +1 -0
- package/lib/routes/agefans/detail.ts +1 -1
- package/lib/routes/aliyun/database-month.ts +1 -1
- package/lib/routes/anthropic/research.ts +112 -0
- package/lib/routes/apnews/topics.ts +2 -1
- package/lib/routes/apnews/utils.ts +1 -1
- package/lib/routes/apple/design.ts +54 -0
- package/lib/routes/apple/namespace.ts +1 -1
- package/lib/routes/aqara/post.ts +1 -1
- package/lib/routes/augmentcode/blog.ts +161 -0
- package/lib/routes/augmentcode/namespace.ts +9 -0
- package/lib/routes/augmentcode/templates/description.art +17 -0
- package/lib/routes/azul/namespace.ts +9 -0
- package/lib/routes/azul/packages.ts +105 -0
- package/lib/routes/banshujiang/index.ts +763 -0
- package/lib/routes/banshujiang/namespace.ts +9 -0
- package/lib/routes/banshujiang/templates/description.art +17 -0
- package/lib/routes/bfl/announcements.ts +1 -1
- package/lib/routes/bilibili/cache.ts +78 -0
- package/lib/routes/bilibili/danmaku.ts +1 -1
- package/lib/routes/bilibili/dynamic.ts +8 -2
- package/lib/routes/bilibili/video.ts +31 -73
- package/lib/routes/biquge/index.ts +1 -1
- package/lib/routes/bsky/keyword.ts +15 -10
- package/lib/routes/capitalmind/insights.ts +40 -0
- package/lib/routes/capitalmind/namespace.ts +8 -0
- package/lib/routes/capitalmind/podcasts.ts +41 -0
- package/lib/routes/capitalmind/utils.ts +122 -0
- package/lib/routes/cartoonmad/comic.ts +1 -1
- package/lib/routes/chikubi/index.ts +1 -0
- package/lib/routes/chikubi/tag.ts +1 -0
- package/lib/routes/chocolatey/namespace.ts +9 -0
- package/lib/routes/chocolatey/packages.ts +122 -0
- package/lib/routes/cmde/index.ts +1 -1
- package/lib/routes/cockroachlabs/blog.ts +113 -0
- package/lib/routes/cockroachlabs/namespace.ts +7 -0
- package/lib/routes/cool18/index.ts +4 -1
- package/lib/routes/coomer/index.ts +12 -6
- package/lib/routes/coomer/namespace.ts +1 -1
- package/lib/routes/copymanga/comic.ts +7 -9
- package/lib/routes/css-tricks/articles.ts +48 -0
- package/lib/routes/css-tricks/collections.ts +62 -0
- package/lib/routes/css-tricks/namespace.ts +8 -0
- package/lib/routes/css-tricks/popular.ts +39 -0
- package/lib/routes/css-tricks/utils.ts +103 -0
- package/lib/routes/cursor/changelog.ts +26 -17
- package/lib/routes/cursor/namespace.ts +1 -1
- package/lib/routes/cw/utils.ts +6 -13
- package/lib/routes/dealstreetasia/home.ts +1 -1
- package/lib/routes/dedao/index.ts +3 -3
- package/lib/routes/deepl/blog.ts +422 -0
- package/lib/routes/deepl/namespace.ts +9 -0
- package/lib/routes/deepl/templates/description.art +21 -0
- package/lib/routes/deeplearning/the-batch.ts +1 -1
- package/lib/routes/dev.to/guides.ts +100 -0
- package/lib/routes/dev.to/namespace.ts +8 -0
- package/lib/routes/dev.to/top.ts +105 -0
- package/lib/routes/dgut/jwb.ts +73 -0
- package/lib/routes/dgut/namespace.ts +9 -0
- package/lib/routes/digitalpolicyalert/activity-tracker.ts +135 -0
- package/lib/routes/digitalpolicyalert/namespace.ts +9 -0
- package/lib/routes/dnaindia/common.ts +26 -8
- package/lib/routes/douban/other/list.ts +3 -3
- package/lib/routes/e-hentai/index.ts +4 -1
- package/lib/routes/ehentai/tag.ts +1 -0
- package/lib/routes/englishhome/index.ts +55 -0
- package/lib/routes/englishhome/namespace.ts +6 -0
- package/lib/routes/epicgames/index.ts +2 -2
- package/lib/routes/espn/news.ts +1 -1
- package/lib/routes/expats/czech-news.ts +272 -0
- package/lib/routes/expats/namespace.ts +9 -0
- package/lib/routes/fanbox/index.ts +1 -0
- package/lib/routes/fanbox/utils.ts +1 -1
- package/lib/routes/fansly/tag.ts +1 -0
- package/lib/routes/fantia/search.ts +1 -1
- package/lib/routes/fantube/creator.ts +69 -0
- package/lib/routes/fantube/namespace.ts +7 -0
- package/lib/routes/fantube/templates/post.art +17 -0
- package/lib/routes/fantube/types.ts +100 -0
- package/lib/routes/fantube/utils.ts +268 -0
- package/lib/routes/follow/profile.ts +1 -1
- package/lib/routes/followin/news.ts +1 -1
- package/lib/routes/foresightnews/util.ts +1 -1
- package/lib/routes/freexcomic/book.ts +4 -1
- package/lib/routes/gamer/hot.ts +5 -5
- package/lib/routes/gaoyu/blog.ts +145 -0
- package/lib/routes/gaoyu/namespace.ts +9 -0
- package/lib/routes/gaoyu/templates/description.art +7 -0
- package/lib/routes/geocaching/blogs.ts +2 -2
- package/lib/routes/github/namespace.ts +1 -1
- package/lib/routes/github/private-feed.ts +229 -0
- package/lib/routes/github/star.ts +1 -1
- package/lib/routes/google/extension.ts +9 -10
- package/lib/routes/gov/beijing/bphc/index.ts +1 -1
- package/lib/routes/gov/ccdi/index.ts +1 -1
- package/lib/routes/gov/chongqing/sydwgkzp.ts +22 -6
- package/lib/routes/gov/customs/list.ts +1 -1
- package/lib/routes/gov/general/general.ts +1 -1
- package/lib/routes/gov/hangzhou/zwfw.ts +1 -1
- package/lib/routes/gov/pbc/goutongjiaoliu.ts +1 -1
- package/lib/routes/gov/shenzhen/szlh/index.ts +77 -0
- package/lib/routes/gov/shenzhen/szlh/namespace.ts +8 -0
- package/lib/routes/grist/utils.ts +5 -4
- package/lib/routes/hanime1/search.ts +4 -2
- package/lib/routes/hellogithub/report.ts +1 -1
- package/lib/routes/hit/hitgs.ts +240 -54
- package/lib/routes/hit/templates/description.art +7 -0
- package/lib/routes/hlju/namespace.ts +8 -0
- package/lib/routes/hlju/news.ts +141 -0
- package/lib/routes/hostmonit/cloudflareyes.ts +1 -1
- package/lib/routes/hotukdeals/index.ts +1 -1
- package/lib/routes/hyperdash/namespace.ts +7 -0
- package/lib/routes/hyperdash/templates/description.art +34 -0
- package/lib/routes/hyperdash/top-traders.ts +84 -0
- package/lib/routes/hyperdash/utils.ts +49 -0
- package/lib/routes/hypergryph/arknights/announce.ts +1 -1
- package/lib/routes/ielts/index.ts +1 -1
- package/lib/routes/infoq/topic.ts +16 -13
- package/lib/routes/instagram/web-api/index.ts +17 -13
- package/lib/routes/instagram/web-api/utils.ts +46 -63
- package/lib/routes/jamesclear/book-summaries.ts +40 -0
- package/lib/routes/jamesclear/great-speeches.ts +40 -0
- package/lib/routes/jamesclear/namespace.ts +8 -0
- package/lib/routes/jamesclear/quotes.ts +40 -0
- package/lib/routes/jamesclear/three-two-one.ts +41 -0
- package/lib/routes/jamesclear/utils.ts +22 -0
- package/lib/routes/japanpost/utils.ts +2 -2
- package/lib/routes/javbus/index.ts +3 -0
- package/lib/routes/javdb/tags.ts +1 -0
- package/lib/routes/javlibrary/star.ts +1 -0
- package/lib/routes/javtiful/actress.ts +3 -0
- package/lib/routes/javtiful/channel.ts +3 -0
- package/lib/routes/javtrailers/casts.ts +3 -0
- package/lib/routes/jetbrains/comments.ts +99 -0
- package/lib/routes/jetbrains/namespace.ts +8 -0
- package/lib/routes/jimmyspa/books.ts +1 -1
- package/lib/routes/jimmyspa/news.ts +1 -1
- package/lib/routes/jpxgmn/tab.ts +3 -0
- package/lib/routes/kakuyomu/works.ts +3 -0
- package/lib/routes/kaopu/news.ts +1 -1
- package/lib/routes/kemono/const.ts +1 -1
- package/lib/routes/kemono/index.ts +12 -11
- package/lib/routes/kemono/namespace.ts +1 -1
- package/lib/routes/kiro/blog.ts +131 -0
- package/lib/routes/kiro/changelog.ts +128 -0
- package/lib/routes/kiro/namespace.ts +9 -0
- package/lib/routes/konachan/post.ts +3 -0
- package/lib/routes/kovidgoyal/kitty/changelog.ts +83 -0
- package/lib/routes/kovidgoyal/namespace.ts +7 -0
- package/lib/routes/kunchengblog/essay.ts +1 -1
- package/lib/routes/landiannews/category.ts +1 -1
- package/lib/routes/landiannews/index.ts +1 -1
- package/lib/routes/landiannews/tag.ts +1 -1
- package/lib/routes/line/utils.ts +1 -1
- package/lib/routes/lineageos/changes.ts +79 -0
- package/lib/routes/lineageos/namespace.ts +9 -0
- package/lib/routes/linkedin/cn/renderer.ts +1 -1
- package/lib/routes/liquipedia/cs-matches.ts +42 -14
- package/lib/routes/literotica/new.ts +1 -0
- package/lib/routes/lofter/tag.ts +27 -3
- package/lib/routes/makerworld/contest.ts +51 -0
- package/lib/routes/makerworld/namespace.ts +7 -0
- package/lib/routes/makerworld/trending.ts +45 -0
- package/lib/routes/makerworld/user-upload.ts +54 -0
- package/lib/routes/makerworld/utils.ts +18 -0
- package/lib/routes/manhuagui/comic.ts +1 -1
- package/lib/routes/manus/blog.ts +77 -0
- package/lib/routes/manus/namespace.ts +7 -0
- package/lib/routes/mastodon/tag.ts +48 -0
- package/lib/routes/mathpix/blog.ts +155 -0
- package/lib/routes/mathpix/namespace.ts +9 -0
- package/lib/routes/mathpix/templates/description.art +21 -0
- package/lib/routes/mckinsey/cn/category-map.ts +9 -15
- package/lib/routes/mckinsey/cn/index.ts +77 -40
- package/lib/routes/melonbooks/search.ts +1 -0
- package/lib/routes/metacritic/index.ts +2 -2
- package/lib/routes/meteoblue/namespace.ts +8 -0
- package/lib/routes/meteoblue/weathernews.ts +75 -0
- package/lib/routes/meteor/index.ts +1 -1
- package/lib/routes/microsoft/addon.ts +7 -9
- package/lib/routes/mihoyo/zzz/news.ts +106 -0
- package/lib/routes/missav/new.ts +2 -1
- package/lib/routes/mit/hanlab.ts +61 -0
- package/lib/routes/mit/namespace.ts +6 -0
- package/lib/routes/mittrchina/index.ts +3 -3
- package/lib/routes/mixcloud/config.ts +129 -0
- package/lib/routes/mixcloud/index.ts +163 -107
- package/lib/routes/mixcloud/user-playlist.ts +31 -0
- package/lib/routes/mixi2/community.ts +72 -0
- package/lib/routes/mixi2/discovery.ts +52 -0
- package/lib/routes/mixi2/home.ts +51 -0
- package/lib/routes/mixi2/namespace.ts +8 -0
- package/lib/routes/mixi2/user.ts +77 -0
- package/lib/routes/mixi2/utils.ts +56 -0
- package/lib/routes/modelscope/learn.ts +94 -0
- package/lib/routes/moodysmismicrosite/report.ts +1 -1
- package/lib/routes/musify/index.ts +130 -0
- package/lib/routes/musify/namespace.ts +9 -0
- package/lib/routes/musikguru/namespace.ts +9 -0
- package/lib/routes/musikguru/news.ts +146 -0
- package/lib/routes/musikguru/templates/description.art +21 -0
- package/lib/routes/myfans/post.ts +1 -0
- package/lib/routes/nankai/cc-notice.ts +114 -0
- package/lib/routes/nankai/jwc.ts +131 -0
- package/lib/routes/nankai/namespace.ts +7 -0
- package/lib/routes/nankai/notice.ts +84 -0
- package/lib/routes/nankai/yzb.ts +97 -0
- package/lib/routes/neu/yz.ts +172 -0
- package/lib/routes/newslaundry/explainer.ts +30 -0
- package/lib/routes/newslaundry/namespace.ts +8 -0
- package/lib/routes/newslaundry/nl-cheatsheet.ts +30 -0
- package/lib/routes/newslaundry/nl-collaborations.ts +30 -0
- package/lib/routes/newslaundry/podcast.ts +61 -0
- package/lib/routes/newslaundry/reports.ts +30 -0
- package/lib/routes/newslaundry/shot.ts +30 -0
- package/lib/routes/newslaundry/subscriber-only.ts +30 -0
- package/lib/routes/newslaundry/templates/description.art +28 -0
- package/lib/routes/newslaundry/utils.ts +108 -0
- package/lib/routes/newswav/latest.ts +100 -0
- package/lib/routes/newswav/namespace.ts +7 -0
- package/lib/routes/nhentai/index.ts +1 -0
- package/lib/routes/nifd/research.ts +16 -0
- package/lib/routes/nio/namespace.ts +9 -0
- package/lib/routes/nio/nioradio.ts +75 -0
- package/lib/routes/njust/cs.ts +58 -0
- package/lib/routes/njust/utils.ts +1 -1
- package/lib/routes/ntdm/video.ts +1 -1
- package/lib/routes/nuaa/utils/pypasswaf.ts +1 -1
- package/lib/routes/oilchem/index.ts +1 -1
- package/lib/routes/oncc/money18.ts +1 -1
- package/lib/routes/openai/cookbook.ts +1 -1
- package/lib/routes/paulgraham/article.ts +2 -2
- package/lib/routes/picuki/profile.ts +4 -0
- package/lib/routes/pixiv/bookmarks.ts +1 -1
- package/lib/routes/pixiv/novel-api/series/sfw.ts +1 -1
- package/lib/routes/pixiv/novels.ts +2 -2
- package/lib/routes/pixiv/user.ts +1 -1
- package/lib/routes/playno1/av.ts +1 -0
- package/lib/routes/pornhub/model.ts +3 -7
- package/lib/routes/pornhub/pornstar.ts +2 -7
- package/lib/routes/pornhub/users.ts +2 -7
- package/lib/routes/pornhub/utils.ts +12 -1
- package/lib/routes/qingting/podcast.ts +2 -1
- package/lib/routes/qipamaijia/index.ts +1 -0
- package/lib/routes/questmobile/report.ts +1 -1
- package/lib/routes/railway/index.ts +73 -0
- package/lib/routes/railway/namespace.ts +8 -0
- package/lib/routes/reuters/common.ts +0 -3
- package/lib/routes/rockthejvm/articles.ts +167 -0
- package/lib/routes/rockthejvm/namespace.ts +9 -0
- package/lib/routes/rockthejvm/templates/description.art +7 -0
- package/lib/routes/samrdprc/namespace.ts +7 -0
- package/lib/routes/samrdprc/news.ts +79 -0
- package/lib/routes/sankei/namespace.ts +7 -0
- package/lib/routes/sankei/news.ts +68 -0
- package/lib/routes/sankei/topics.ts +71 -0
- package/lib/routes/sciencenet/user.ts +1 -1
- package/lib/routes/scoop/apps.ts +188 -0
- package/lib/routes/scoop/namespace.ts +9 -0
- package/lib/routes/scoop/templates/description.art +56 -0
- package/lib/routes/scpta/namespace.ts +8 -0
- package/lib/routes/scpta/news.ts +101 -0
- package/lib/routes/seekingalpha/index.ts +1 -1
- package/lib/routes/sehuatang/index.ts +29 -31
- package/lib/routes/setn/index.ts +11 -2
- package/lib/routes/seu/cyber/index.ts +78 -0
- package/lib/routes/sicau/jiaowu.ts +42 -34
- package/lib/routes/sis001/forum.ts +1 -0
- package/lib/routes/sjtu/seiee/icisee.ts +67 -0
- package/lib/routes/sketis/isabelle-dev/blog/index.ts +1 -1
- package/lib/routes/smartlink/index.ts +13 -3
- package/lib/routes/sohu/mp.ts +17 -6
- package/lib/routes/sotwe/namespace.ts +1 -0
- package/lib/routes/sotwe/user.ts +98 -0
- package/lib/routes/spankbang/new-videos.ts +1 -0
- package/lib/routes/spglobal/ratings.ts +1 -1
- package/lib/routes/stanford/blog.ts +77 -0
- package/lib/routes/stanford/namespace.ts +7 -0
- package/lib/routes/syosetu/index.ts +1 -1
- package/lib/routes/t66y/index.ts +1 -0
- package/lib/routes/taobao/mysql.ts +157 -0
- package/lib/routes/taobao/namespace.ts +2 -2
- package/lib/routes/techcrunch/category.ts +48 -0
- package/lib/routes/telegram/channel.ts +2 -2
- package/lib/routes/tesla/cx.ts +1 -1
- package/lib/routes/test/index.ts +1 -1
- package/lib/routes/themoviedb/episodes.ts +1 -1
- package/lib/routes/thewirehindi/category.ts +78 -0
- package/lib/routes/thewirehindi/index.ts +43 -0
- package/lib/routes/thewirehindi/namespace.ts +7 -0
- package/lib/routes/thewirehindi/templates/description.art +9 -0
- package/lib/routes/thewirehindi/utils.ts +33 -0
- package/lib/routes/threads/utils.ts +2 -2
- package/lib/routes/tidb/blog.ts +314 -0
- package/lib/routes/tidb/namespace.ts +9 -0
- package/lib/routes/tumblr/namespace.ts +17 -0
- package/lib/routes/tumblr/posts.ts +74 -0
- package/lib/routes/tumblr/utils.ts +110 -0
- package/lib/routes/tver/namespace.ts +7 -0
- package/lib/routes/tver/series.ts +98 -0
- package/lib/routes/twitter/api/web-api/login.ts +1 -3
- package/lib/routes/twitter/api/web-api/utils.ts +23 -1
- package/lib/routes/twitter/utils.ts +21 -21
- package/lib/routes/udn/breaking-news.ts +2 -2
- package/lib/routes/uestc/auto.ts +1 -1
- package/lib/routes/uestc/cqe.ts +1 -1
- package/lib/routes/uestc/scse.ts +1 -1
- package/lib/routes/uestc/sice.ts +1 -1
- package/lib/routes/uestc/sise.ts +1 -1
- package/lib/routes/upc/jwc.ts +32 -46
- package/lib/routes/uptimerobot/rss.ts +1 -1
- package/lib/routes/visionias/daily-news-summary.ts +65 -0
- package/lib/routes/visionias/monthly-magazine.ts +68 -0
- package/lib/routes/visionias/news-today.ts +3 -13
- package/lib/routes/visionias/utils.ts +5 -5
- package/lib/routes/visionias/weekly-focus.ts +2 -2
- package/lib/routes/wdfxw/bookfree.ts +528 -0
- package/lib/routes/wdfxw/namespace.ts +8 -0
- package/lib/routes/wdfxw/templates/description.art +13 -0
- package/lib/routes/whu/swrh.ts +1 -1
- package/lib/routes/windsurf/blog.ts +118 -0
- package/lib/routes/windsurf/changelog.ts +100 -0
- package/lib/routes/windsurf/namespace.ts +9 -0
- package/lib/routes/windsurf/templates/description.art +21 -0
- package/lib/routes/x6d/index.ts +1 -1
- package/lib/routes/xbookcn/blog.ts +1 -0
- package/lib/routes/xiaohongshu/util.ts +1 -3
- package/lib/routes/xiaoyuzhou/pickup.ts +1 -1
- package/lib/routes/ximalaya/album.ts +32 -70
- package/lib/routes/ximalaya/types.ts +48 -0
- package/lib/routes/ximalaya/utils.ts +9 -7
- package/lib/routes/xmanhua/index.ts +1 -0
- package/lib/routes/xueqiu/cookies.ts +1 -1
- package/lib/routes/xueqiu/user.ts +1 -1
- package/lib/routes/xwenming/index.ts +184 -0
- package/lib/routes/xwenming/namespace.ts +9 -0
- package/lib/routes/yahoo/news/utils.ts +1 -1
- package/lib/routes/yande/post.ts +3 -0
- package/lib/routes/ymgal/game.ts +1 -0
- package/lib/routes/youtube/api/google.ts +27 -0
- package/lib/routes/youtube/api/youtubei.ts +70 -20
- package/lib/routes/youtube/community.ts +3 -1
- package/lib/routes/youtube/utils.ts +16 -14
- package/lib/routes/zaobao/util.ts +8 -5
- package/lib/routes/zhihu/activities.ts +3 -0
- package/lib/routes/zhihu/execlib/x-zse-96-v3.ts +5 -5
- package/lib/routes/zhizhuan100/namespace.ts +7 -0
- package/lib/routes/zhizhuan100/report.ts +79 -0
- package/lib/routes/zimuxia/portfolio.ts +1 -1
- package/lib/routes/zju/sis/index.ts +161 -0
- package/lib/server.ts +5 -0
- package/lib/types.ts +58 -54
- package/lib/utils/helpers.ts +1 -1
- package/lib/utils/logger.ts +1 -1
- package/lib/utils/proxy/index.ts +102 -18
- package/lib/utils/proxy/multi-proxy.ts +139 -0
- package/lib/utils/proxy/unify-proxy.ts +3 -1
- package/lib/utils/puppeteer-utils.test.ts +1 -1
- package/lib/utils/puppeteer.test.ts +14 -27
- package/lib/utils/puppeteer.ts +51 -37
- package/lib/utils/readable-social.test.ts +65 -0
- package/lib/utils/readable-social.ts +15 -1
- package/lib/utils/request-rewriter/fetch.ts +42 -4
- package/package.json +54 -56
- package/lib/routes/mixcloud/queries.ts +0 -2274
- package/lib/routes-deprecated/dev.to/top.js +0 -40
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import { type Data, type DataItem, type Route, ViewType } from '@/types';
|
|
2
|
+
|
|
3
|
+
import ofetch from '@/utils/ofetch';
|
|
4
|
+
import { parseDate } from '@/utils/parse-date';
|
|
5
|
+
|
|
6
|
+
import { type CheerioAPI, type Cheerio, load } from 'cheerio';
|
|
7
|
+
import type { Element } from 'domhandler';
|
|
8
|
+
import { type Context } from 'hono';
|
|
9
|
+
|
|
10
|
+
export const handler = async (ctx: Context): Promise<Data> => {
|
|
11
|
+
const limit: number = Number.parseInt(ctx.req.query('limit') ?? '100', 10);
|
|
12
|
+
|
|
13
|
+
const baseUrl: string = 'https://windsurf.com';
|
|
14
|
+
const targetUrl: string = new URL('changelog', baseUrl).href;
|
|
15
|
+
|
|
16
|
+
const response = await ofetch(targetUrl);
|
|
17
|
+
const $: CheerioAPI = load(response);
|
|
18
|
+
const language = $('html').attr('lang') ?? 'en';
|
|
19
|
+
|
|
20
|
+
const title: string = $('title').first().text();
|
|
21
|
+
const author: string | undefined = title.split(/\|/).pop()?.trim();
|
|
22
|
+
|
|
23
|
+
const items: DataItem[] = $('div[aria-label="changelog-layout"]')
|
|
24
|
+
.slice(0, limit)
|
|
25
|
+
.toArray()
|
|
26
|
+
.map((el): Element => {
|
|
27
|
+
const $el: Cheerio<Element> = $(el).parent();
|
|
28
|
+
|
|
29
|
+
const version: string | undefined = $el.find('header div').first().text()?.trim();
|
|
30
|
+
const h1: string | undefined = $el.find('article h1').text()?.trim();
|
|
31
|
+
|
|
32
|
+
const title: string = [version, h1].filter(Boolean).join(' ');
|
|
33
|
+
const description: string | undefined = $el.find('article div').first()?.html() ?? undefined;
|
|
34
|
+
const pubDateStr: string | undefined = $el.find('header div').last().text()?.trim();
|
|
35
|
+
const guid: string = version ? `windsurf-${version}` : '';
|
|
36
|
+
const image: string | undefined = $el.find('article img').attr('src');
|
|
37
|
+
const upDatedStr: string | undefined = pubDateStr;
|
|
38
|
+
|
|
39
|
+
const processedItem: DataItem = {
|
|
40
|
+
title,
|
|
41
|
+
description,
|
|
42
|
+
pubDate: pubDateStr ? parseDate(pubDateStr) : undefined,
|
|
43
|
+
link: targetUrl,
|
|
44
|
+
author,
|
|
45
|
+
doi: $el.find('meta[name="citation_doi"]').attr('content'),
|
|
46
|
+
guid,
|
|
47
|
+
id: guid,
|
|
48
|
+
content: {
|
|
49
|
+
html: description,
|
|
50
|
+
text: description,
|
|
51
|
+
},
|
|
52
|
+
image,
|
|
53
|
+
banner: image,
|
|
54
|
+
updated: upDatedStr ? parseDate(upDatedStr) : undefined,
|
|
55
|
+
language,
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
return processedItem;
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
return {
|
|
62
|
+
title,
|
|
63
|
+
description: $('meta[property="og:description"]').attr('content'),
|
|
64
|
+
link: targetUrl,
|
|
65
|
+
item: items,
|
|
66
|
+
allowEmpty: true,
|
|
67
|
+
image: $('meta[property="og:image"]').attr('content'),
|
|
68
|
+
author,
|
|
69
|
+
language,
|
|
70
|
+
id: $('meta[property="og:url"]').attr('content'),
|
|
71
|
+
};
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
export const route: Route = {
|
|
75
|
+
path: '/changelog',
|
|
76
|
+
name: 'Changelog',
|
|
77
|
+
url: 'windsurf.com',
|
|
78
|
+
maintainers: ['nczitzk'],
|
|
79
|
+
handler,
|
|
80
|
+
example: '/windsurf/changelog',
|
|
81
|
+
parameters: undefined,
|
|
82
|
+
description: undefined,
|
|
83
|
+
categories: ['programming'],
|
|
84
|
+
features: {
|
|
85
|
+
requireConfig: false,
|
|
86
|
+
requirePuppeteer: false,
|
|
87
|
+
antiCrawler: false,
|
|
88
|
+
supportRadar: true,
|
|
89
|
+
supportBT: false,
|
|
90
|
+
supportPodcast: false,
|
|
91
|
+
supportScihub: false,
|
|
92
|
+
},
|
|
93
|
+
radar: [
|
|
94
|
+
{
|
|
95
|
+
source: ['windsurf.com/changelog'],
|
|
96
|
+
target: '/changelog',
|
|
97
|
+
},
|
|
98
|
+
],
|
|
99
|
+
view: ViewType.Articles,
|
|
100
|
+
};
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
{{ if images }}
|
|
2
|
+
{{ each images image }}
|
|
3
|
+
{{ if image?.src }}
|
|
4
|
+
<figure>
|
|
5
|
+
<img
|
|
6
|
+
{{ if image.alt }}
|
|
7
|
+
alt="{{ image.alt }}"
|
|
8
|
+
{{ /if }}
|
|
9
|
+
src="{{ image.src }}">
|
|
10
|
+
</figure>
|
|
11
|
+
{{ /if }}
|
|
12
|
+
{{ /each }}
|
|
13
|
+
{{ /if }}
|
|
14
|
+
|
|
15
|
+
{{ if intro }}
|
|
16
|
+
<blockquote>{{ intro }}</blockquote>
|
|
17
|
+
{{ /if }}
|
|
18
|
+
|
|
19
|
+
{{ if description }}
|
|
20
|
+
{{@ description }}
|
|
21
|
+
{{ /if }}
|
package/lib/routes/x6d/index.ts
CHANGED
|
@@ -31,9 +31,7 @@ const getUser = (url, cache) =>
|
|
|
31
31
|
cache.tryGet(
|
|
32
32
|
url,
|
|
33
33
|
async () => {
|
|
34
|
-
const browser = await puppeteer(
|
|
35
|
-
stealth: true,
|
|
36
|
-
});
|
|
34
|
+
const browser = await puppeteer();
|
|
37
35
|
try {
|
|
38
36
|
const page = await browser.newPage();
|
|
39
37
|
await page.setRequestInterception(true);
|
|
@@ -57,7 +57,7 @@ const ProcessFeed = async () => {
|
|
|
57
57
|
return playList.map((item) => {
|
|
58
58
|
const title = item.episode.title + ' - ' + item.episode.podcast.title;
|
|
59
59
|
const eid = item.episode.eid;
|
|
60
|
-
const itunes_item_image = item.episode.image ? item.episode.image.picUrl :
|
|
60
|
+
const itunes_item_image = item.episode.image ? item.episode.image.picUrl : item.episode.podcast.image ? item.episode.podcast.image.picUrl : '';
|
|
61
61
|
const link = `https://www.xiaoyuzhoufm.com/episode/${eid}`;
|
|
62
62
|
const pubDate = item.pubDate;
|
|
63
63
|
const itunes_duration = item.episode.duration;
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { Route } from '@/types';
|
|
2
2
|
import cache from '@/utils/cache';
|
|
3
3
|
import ofetch from '@/utils/ofetch';
|
|
4
|
-
import { load } from 'cheerio';
|
|
5
4
|
import { getRandom16, decryptUrl } from './utils';
|
|
6
5
|
const baseUrl = 'https://www.ximalaya.com';
|
|
7
6
|
import { config } from '@/config';
|
|
8
7
|
import { parseDate } from '@/utils/parse-date';
|
|
9
|
-
import { RichIntro, TrackInfoResponse } from './types';
|
|
8
|
+
import { Album, RichIntro, TrackInfoResponse } from './types';
|
|
9
|
+
import sanitizeHtml from 'sanitize-html';
|
|
10
10
|
|
|
11
11
|
// Find category from: https://help.apple.com/itc/podcasts_connect/?lang=en#/itc9267a2f12
|
|
12
12
|
const categoryDict = {
|
|
@@ -18,51 +18,16 @@ const categoryDict = {
|
|
|
18
18
|
IT科技: 'Technology',
|
|
19
19
|
};
|
|
20
20
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
function parseStateSafe(stateString) {
|
|
32
|
-
const prefix = 'window.__INITIAL_STATE__ = ';
|
|
33
|
-
const suffix = ';';
|
|
34
|
-
stateString = stateString.slice(prefix.length, stateString.length - suffix.length);
|
|
35
|
-
try {
|
|
36
|
-
return JSON.parse(stateString);
|
|
37
|
-
} catch {
|
|
38
|
-
return {};
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
function getTextFromElement(element) {
|
|
43
|
-
if (element.children && element.children.length > 0) {
|
|
44
|
-
return element.children[0].data.trim();
|
|
45
|
-
}
|
|
46
|
-
return '';
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
async function parseAlbumData(category, album_id) {
|
|
50
|
-
// 解析网页版的 HTML 获取该专辑的信息
|
|
51
|
-
// 这里的 {category} 并不重要,系统会准确的返回该 id 对应专辑的信息
|
|
52
|
-
// 现在 {category} 必须要精确到大的类别
|
|
53
|
-
// https://www.ximalaya.com/{category}/{album_id}
|
|
54
|
-
const response = await ofetch(`${baseUrl}/${category}/${album_id}`);
|
|
55
|
-
const $ = load(response);
|
|
56
|
-
const stateElement = $('script')
|
|
57
|
-
.toArray()
|
|
58
|
-
.filter((element) => getTextFromElement(element).startsWith('window.__INITIAL_STATE__'));
|
|
59
|
-
if (stateElement.length > 0) {
|
|
60
|
-
const stateString = getTextFromElement(stateElement[0]);
|
|
61
|
-
if (stateString) {
|
|
62
|
-
return parseStateSafe(stateString);
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
return {};
|
|
21
|
+
function getAlbumData(albumId) {
|
|
22
|
+
return cache.tryGet(`ximalaya:albumInfo:${albumId}`, async () => {
|
|
23
|
+
const response = await ofetch(`${baseUrl}/revision/album/v1/simple`, {
|
|
24
|
+
query: {
|
|
25
|
+
albumId,
|
|
26
|
+
},
|
|
27
|
+
parseResponse: JSON.parse,
|
|
28
|
+
});
|
|
29
|
+
return response.data.albumPageMainInfo as Album;
|
|
30
|
+
});
|
|
66
31
|
}
|
|
67
32
|
|
|
68
33
|
function judgeTrue(str, ...validStrings) {
|
|
@@ -85,7 +50,11 @@ export const route: Route = {
|
|
|
85
50
|
path: ['/:type/:id/:all/:shownote?'],
|
|
86
51
|
categories: ['multimedia'],
|
|
87
52
|
example: '/ximalaya/album/299146',
|
|
88
|
-
parameters: {
|
|
53
|
+
parameters: {
|
|
54
|
+
type: '专辑类型, 通常可以使用 `album`,可在对应专辑页面的 URL 中找到',
|
|
55
|
+
id: '专辑 id, 可在对应专辑页面的 URL 中找到',
|
|
56
|
+
all: '是否需要获取全部节目,填入 `1`、`true`、`all` 视为获取所有节目,填入其他则不获取。',
|
|
57
|
+
},
|
|
89
58
|
features: {
|
|
90
59
|
requireConfig: [
|
|
91
60
|
{
|
|
@@ -118,28 +87,22 @@ async function handler(ctx) {
|
|
|
118
87
|
const shouldShowNote = judgeTrue(ctx.req.param('shownote'), 'shownote');
|
|
119
88
|
const pageSize = shouldAll ? 200 : 30;
|
|
120
89
|
|
|
121
|
-
const albumData = await
|
|
122
|
-
|
|
123
|
-
const { albumPageMainInfo, currentCategory, anchorInfo } = albumData?.store?.AlbumDetailPage || {};
|
|
90
|
+
const albumData = await getAlbumData(id);
|
|
124
91
|
|
|
125
|
-
const isPaid =
|
|
92
|
+
const isPaid = albumData.isPaid;
|
|
126
93
|
|
|
127
|
-
const
|
|
128
|
-
const author = authorInfo.nickName;
|
|
94
|
+
const author = albumData.anchorName;
|
|
129
95
|
|
|
130
|
-
const
|
|
131
|
-
const
|
|
132
|
-
const
|
|
133
|
-
const albumIntro = albumInfo.detailRichIntro; // 专辑介绍
|
|
96
|
+
const albumTitle = albumData.albumTitle; // 专辑标题
|
|
97
|
+
const albumCover = 'https:' + albumData.cover;
|
|
98
|
+
const albumIntro = sanitizeHtml(albumData.detailRichIntro, { allowedTags: [], allowedAttributes: {} }); // 专辑介绍
|
|
134
99
|
|
|
135
|
-
const
|
|
136
|
-
const albumCategory = categoryInfo?.categoryTitle || albumPageMainInfo.categoryTitle; // 专辑分类名字
|
|
137
|
-
const albumUrl = '/' + (categoryInfo?.categoryPinyin || type) + '/' + id + '/'; // 没有 categoryPinyin 这个字段了,用 type 兼容一下
|
|
100
|
+
const albumCategory = albumData.categoryTitle; // 专辑分类名字
|
|
138
101
|
|
|
139
102
|
// sort 为 1 时是降序
|
|
140
103
|
// const isAsc = albumData.store.AlbumDetailTrackList.sort === 0;
|
|
141
104
|
// 喜马拉雅的 API 的 query 参数 isAsc=0 时才是升序,不写就是降序。
|
|
142
|
-
const trackInfoApi = `
|
|
105
|
+
const trackInfoApi = `https://mobile.ximalaya.com/mobile/v1/album/track/?albumId=${id}&pageSize=${pageSize}&pageId=`;
|
|
143
106
|
const trackInfoResponse = await ofetch<TrackInfoResponse>(trackInfoApi + '1', {
|
|
144
107
|
parseResponse: JSON.parse,
|
|
145
108
|
});
|
|
@@ -165,16 +128,15 @@ async function handler(ctx) {
|
|
|
165
128
|
|
|
166
129
|
await Promise.all(
|
|
167
130
|
playList.map(async (item) => {
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
let _desc;
|
|
131
|
+
item.desc = await cache.tryGet(`ximalaya:trackRichInfo:${item.trackId}:${shouldShowNote.toString()}`, async () => {
|
|
132
|
+
let _desc: string = '';
|
|
171
133
|
if (shouldShowNote) {
|
|
172
134
|
const trackRichInfoApi = `https://mobile.ximalaya.com/mobile-track/richIntro?trackId=${item.trackId}`;
|
|
173
135
|
const trackRichInfoResponse = await ofetch<RichIntro>(trackRichInfoApi);
|
|
174
136
|
_desc = trackRichInfoResponse.richIntro;
|
|
175
137
|
}
|
|
176
138
|
if (!_desc) {
|
|
177
|
-
_desc =
|
|
139
|
+
_desc = item.intro;
|
|
178
140
|
}
|
|
179
141
|
return _desc;
|
|
180
142
|
});
|
|
@@ -182,8 +144,8 @@ async function handler(ctx) {
|
|
|
182
144
|
);
|
|
183
145
|
|
|
184
146
|
const token = config.ximalaya.token;
|
|
185
|
-
const randomToken = getRandom16(8) + '-' + getRandom16(4) + '-' + getRandom16(4) + '-' + getRandom16(4) + '-' + getRandom16(12);
|
|
186
147
|
if (isPaid && token) {
|
|
148
|
+
const randomToken = getRandom16(8) + '-' + getRandom16(4) + '-' + getRandom16(4) + '-' + getRandom16(4) + '-' + getRandom16(12);
|
|
187
149
|
await Promise.all(
|
|
188
150
|
playList.map(async (item) => {
|
|
189
151
|
const timestamp = Math.floor(Date.now());
|
|
@@ -217,8 +179,8 @@ async function handler(ctx) {
|
|
|
217
179
|
const resultItems = playList.map((item) => {
|
|
218
180
|
const title = item.title;
|
|
219
181
|
const trackId = item.trackId;
|
|
220
|
-
const itunesItemImage = item.coverLarge ?? albumCover;
|
|
221
|
-
const link = baseUrl
|
|
182
|
+
const itunesItemImage = item.coverLarge.split('!')[0] ?? albumCover;
|
|
183
|
+
const link = `${baseUrl}/sound/${trackId}`;
|
|
222
184
|
const pubDate = parseDate(item.createdAt, 'x');
|
|
223
185
|
const duration = item.duration; // 时间长度:单位(秒)
|
|
224
186
|
const enclosureUrl = item.playPathAacv224 || item.playPathAacv164;
|
|
@@ -250,7 +212,7 @@ async function handler(ctx) {
|
|
|
250
212
|
|
|
251
213
|
return {
|
|
252
214
|
title: albumTitle,
|
|
253
|
-
link: baseUrl
|
|
215
|
+
link: `${baseUrl}/${type}/${id}`,
|
|
254
216
|
description: albumIntro,
|
|
255
217
|
image: albumCover,
|
|
256
218
|
itunes_author: author,
|
|
@@ -66,3 +66,51 @@ export interface RichIntro {
|
|
|
66
66
|
ret: number;
|
|
67
67
|
richIntro: string;
|
|
68
68
|
}
|
|
69
|
+
|
|
70
|
+
interface SubscriptInfo {
|
|
71
|
+
albumSubscriptValue: number;
|
|
72
|
+
url: string;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
export interface Album {
|
|
76
|
+
anchorUid: number;
|
|
77
|
+
albumStatus: number;
|
|
78
|
+
showApplyFinishBtn: boolean;
|
|
79
|
+
showEditBtn: boolean;
|
|
80
|
+
showTrackManagerBtn: boolean;
|
|
81
|
+
showInformBtn: boolean;
|
|
82
|
+
cover: string;
|
|
83
|
+
albumTitle: string;
|
|
84
|
+
updateDate: string;
|
|
85
|
+
createDate: string;
|
|
86
|
+
playCount: number;
|
|
87
|
+
isPaid: boolean;
|
|
88
|
+
isFinished: number;
|
|
89
|
+
isSubscribe: boolean;
|
|
90
|
+
richIntro: string;
|
|
91
|
+
shortIntro: string;
|
|
92
|
+
detailRichIntro: string;
|
|
93
|
+
isPublic: boolean;
|
|
94
|
+
hasBuy: boolean;
|
|
95
|
+
vipType: number;
|
|
96
|
+
canCopyText: boolean;
|
|
97
|
+
subscribeCount: number;
|
|
98
|
+
sellingPoint: object;
|
|
99
|
+
personalDescription: string;
|
|
100
|
+
bigshotRecommend: string;
|
|
101
|
+
outline: string;
|
|
102
|
+
customTitle: string;
|
|
103
|
+
produceTeam: string;
|
|
104
|
+
recommendReason: string;
|
|
105
|
+
subscriptInfo: SubscriptInfo;
|
|
106
|
+
albumSubscript: number;
|
|
107
|
+
tags: string[];
|
|
108
|
+
categoryId: number;
|
|
109
|
+
ximiVipFreeType: number;
|
|
110
|
+
joinXimi: boolean;
|
|
111
|
+
freeExpiredTime: number;
|
|
112
|
+
categoryTitle: string;
|
|
113
|
+
anchorName: string;
|
|
114
|
+
albumSeoTitle: string;
|
|
115
|
+
visibleStatus: number;
|
|
116
|
+
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import crypto from 'node:crypto';
|
|
2
|
+
/*
|
|
2
3
|
const getParams = (ep) => {
|
|
3
4
|
const a1 = 'xkt3a41psizxrh9l';
|
|
4
5
|
const a = [
|
|
@@ -119,6 +120,7 @@ const getUrl = (r) => {
|
|
|
119
120
|
const url = `https://audiopay.cos.xmcdn.com/download/${r.apiVersion}/${getPath(r.seed, r.fileId)}?${paramsArray.join('&')}`;
|
|
120
121
|
return url;
|
|
121
122
|
};
|
|
123
|
+
*/
|
|
122
124
|
|
|
123
125
|
const getRandom16 = (len) =>
|
|
124
126
|
crypto
|
|
@@ -139,28 +141,28 @@ const decryptUrl = (encryptedUrl) => {
|
|
|
139
141
|
const a = [204, 53, 135, 197, 39, 73, 58, 160, 79, 24, 12, 83, 180, 250, 101, 60, 206, 30, 10, 227, 36, 95, 161, 16, 135, 150, 235, 116, 242, 116, 165, 171];
|
|
140
142
|
|
|
141
143
|
const padding = '='.repeat((4 - (encryptedUrl.length % 4)) % 4);
|
|
142
|
-
const
|
|
143
|
-
if (
|
|
144
|
+
const encryptedData = Buffer.from(encryptedUrl.replace('_', '/').replace('-', '+') + padding, 'base64');
|
|
145
|
+
if (encryptedData.length < 16) {
|
|
144
146
|
return encryptedUrl;
|
|
145
147
|
}
|
|
146
|
-
const data =
|
|
147
|
-
const iv =
|
|
148
|
+
const data = encryptedData.subarray(0, -16);
|
|
149
|
+
const iv = encryptedData.subarray(-16);
|
|
148
150
|
const decryptedData = new Uint8Array(data);
|
|
149
151
|
for (let i = 0; i < decryptedData.length; i++) {
|
|
150
152
|
decryptedData[i] = o[decryptedData[i]];
|
|
151
153
|
}
|
|
152
154
|
for (let i = 0; i < decryptedData.length; i += 16) {
|
|
153
|
-
const block = decryptedData.
|
|
155
|
+
const block = decryptedData.subarray(i, i + 16);
|
|
154
156
|
for (const [j, element] of block.entries()) {
|
|
155
157
|
decryptedData[i + j] = element ^ iv[j];
|
|
156
158
|
}
|
|
157
159
|
}
|
|
158
160
|
for (let i = 0; i < decryptedData.length; i += 32) {
|
|
159
|
-
const block = decryptedData.
|
|
161
|
+
const block = decryptedData.subarray(i, i + 32);
|
|
160
162
|
for (const [j, element] of block.entries()) {
|
|
161
163
|
decryptedData[i + j] = element ^ a[j];
|
|
162
164
|
}
|
|
163
165
|
}
|
|
164
166
|
return Buffer.from(decryptedData).toString('utf8');
|
|
165
167
|
};
|
|
166
|
-
export { getUrl, getRandom16, decryptUrl };
|
|
168
|
+
export { /* getUrl, */ getRandom16, decryptUrl };
|
|
@@ -7,7 +7,7 @@ export const parseToken = (link: string) =>
|
|
|
7
7
|
cache.tryGet(
|
|
8
8
|
'xueqiu:token',
|
|
9
9
|
async () => {
|
|
10
|
-
const browser = await puppeteer(
|
|
10
|
+
const browser = await puppeteer();
|
|
11
11
|
const page = await browser.newPage();
|
|
12
12
|
await page.setRequestInterception(true);
|
|
13
13
|
page.on('request', (request) => {
|
|
@@ -49,7 +49,7 @@ async function handler(ctx) {
|
|
|
49
49
|
const link = `${rootUrl}/u/${id}`;
|
|
50
50
|
const token = await parseToken(link);
|
|
51
51
|
|
|
52
|
-
const browser = await puppeteer(
|
|
52
|
+
const browser = await puppeteer();
|
|
53
53
|
try {
|
|
54
54
|
const mainPage = await browser.newPage();
|
|
55
55
|
|
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
import { type Data, type DataItem, type Route, ViewType } from '@/types';
|
|
2
|
+
|
|
3
|
+
import ofetch from '@/utils/ofetch';
|
|
4
|
+
import { parseDate } from '@/utils/parse-date';
|
|
5
|
+
|
|
6
|
+
import { type CheerioAPI, load } from 'cheerio';
|
|
7
|
+
import { type Context } from 'hono';
|
|
8
|
+
|
|
9
|
+
export const handler = async (ctx: Context): Promise<Data> => {
|
|
10
|
+
const { category } = ctx.req.param();
|
|
11
|
+
const limit: number = Number.parseInt(ctx.req.query('limit') ?? '50', 10);
|
|
12
|
+
|
|
13
|
+
const apiSlug = 'wp-json/wp/v2';
|
|
14
|
+
const baseUrl: string = 'https://www.xwenming.com';
|
|
15
|
+
|
|
16
|
+
const apiUrl = new URL(`${apiSlug}/posts`, baseUrl).href;
|
|
17
|
+
const apiSearchUrl = new URL(`${apiSlug}/categories`, baseUrl).href;
|
|
18
|
+
|
|
19
|
+
const searchResponse = await ofetch(apiSearchUrl, {
|
|
20
|
+
query: {
|
|
21
|
+
search: category,
|
|
22
|
+
},
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
const categoryObj = searchResponse.find((c) => c.slug === category || c.name === category);
|
|
26
|
+
const categoryId: number | undefined = categoryObj?.id ?? undefined;
|
|
27
|
+
const categorySlug: string | undefined = categoryObj?.slug ?? undefined;
|
|
28
|
+
|
|
29
|
+
const response = await ofetch(apiUrl, {
|
|
30
|
+
query: {
|
|
31
|
+
_embed: 'true',
|
|
32
|
+
per_page: limit,
|
|
33
|
+
categories: categoryId,
|
|
34
|
+
},
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
const targetUrl: string = new URL(categorySlug ? `index.php/category/${categorySlug}` : '', baseUrl).href;
|
|
38
|
+
|
|
39
|
+
const targetResponse = await ofetch(targetUrl);
|
|
40
|
+
const $: CheerioAPI = load(targetResponse);
|
|
41
|
+
const language = $('html').attr('lang') ?? 'zh';
|
|
42
|
+
|
|
43
|
+
const items: DataItem[] = response.slice(0, limit).map((item): DataItem => {
|
|
44
|
+
const title: string = item.title?.rendered ?? item.title;
|
|
45
|
+
const description: string | undefined = item.content.rendered;
|
|
46
|
+
const pubDate: number | string = item.date_gmt;
|
|
47
|
+
const linkUrl: string | undefined = item.link;
|
|
48
|
+
|
|
49
|
+
const terminologies = item._embedded?.['wp:term'];
|
|
50
|
+
|
|
51
|
+
const categories: string[] = terminologies?.flat().map((c) => c.name) ?? [];
|
|
52
|
+
const authors: DataItem['author'] =
|
|
53
|
+
item._embedded?.author.map((author) => ({
|
|
54
|
+
name: author.name,
|
|
55
|
+
url: author.link,
|
|
56
|
+
avatar: author.avatar_urls?.['96'] ?? author.avatar_urls?.['48'] ?? author.avatar_urls?.['24'] ?? undefined,
|
|
57
|
+
})) ?? [];
|
|
58
|
+
const guid: string = item.guid?.rendered ?? item.guid;
|
|
59
|
+
const image: string | undefined = item._embedded?.['wp:featuredmedia']?.[0].source_url ?? undefined;
|
|
60
|
+
const updated: number | string = item.modified_gmt ?? pubDate;
|
|
61
|
+
|
|
62
|
+
const processedItem: DataItem = {
|
|
63
|
+
title,
|
|
64
|
+
description,
|
|
65
|
+
pubDate: pubDate ? parseDate(pubDate) : undefined,
|
|
66
|
+
link: linkUrl ?? guid,
|
|
67
|
+
category: categories,
|
|
68
|
+
author: authors,
|
|
69
|
+
guid,
|
|
70
|
+
id: guid,
|
|
71
|
+
content: {
|
|
72
|
+
html: description,
|
|
73
|
+
text: description,
|
|
74
|
+
},
|
|
75
|
+
image,
|
|
76
|
+
banner: image,
|
|
77
|
+
updated: updated ? parseDate(updated) : undefined,
|
|
78
|
+
language,
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
return processedItem;
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
return {
|
|
85
|
+
title: $('title').text(),
|
|
86
|
+
description: $('meta[name="description"]').attr('content'),
|
|
87
|
+
link: targetUrl,
|
|
88
|
+
item: items,
|
|
89
|
+
allowEmpty: true,
|
|
90
|
+
image: $('meta[name="msapplication-TileImage"]').attr('content'),
|
|
91
|
+
language,
|
|
92
|
+
id: targetUrl,
|
|
93
|
+
};
|
|
94
|
+
};
|
|
95
|
+
|
|
96
|
+
export const route: Route = {
|
|
97
|
+
path: '/:category?',
|
|
98
|
+
name: '分类',
|
|
99
|
+
url: 'www.xwenming.com',
|
|
100
|
+
maintainers: ['nczitzk'],
|
|
101
|
+
handler,
|
|
102
|
+
example: '/xwenming/news',
|
|
103
|
+
parameters: {
|
|
104
|
+
category: {
|
|
105
|
+
description: '分类,默认为全部,可在对应分类页 URL 中找到',
|
|
106
|
+
options: [
|
|
107
|
+
{
|
|
108
|
+
label: '全部',
|
|
109
|
+
value: '',
|
|
110
|
+
},
|
|
111
|
+
{
|
|
112
|
+
label: '科技前沿',
|
|
113
|
+
value: 'news',
|
|
114
|
+
},
|
|
115
|
+
{
|
|
116
|
+
label: '疑难杂症',
|
|
117
|
+
value: 'solve',
|
|
118
|
+
},
|
|
119
|
+
{
|
|
120
|
+
label: '通知专栏',
|
|
121
|
+
value: 'notice',
|
|
122
|
+
},
|
|
123
|
+
{
|
|
124
|
+
label: '未分类',
|
|
125
|
+
value: 'uncategorized',
|
|
126
|
+
},
|
|
127
|
+
],
|
|
128
|
+
},
|
|
129
|
+
},
|
|
130
|
+
description: `:::tip
|
|
131
|
+
订阅 [科技前沿](https://www.xwenming.com/index.php/category/news),其源网址为 \`https://www.xwenming.com/index.php/category/news\`,请参考该 URL 指定部分构成参数,此时路由为 [\`/xwenming/category/news\`](https://rsshub.app/xwenming/category/news) 或 [\`/xwenming/category/科技前沿\`](https://rsshub.app/xwenming/category/科技前沿)。
|
|
132
|
+
:::
|
|
133
|
+
|
|
134
|
+
| 分类 | ID |
|
|
135
|
+
| ------------------------------------------------------------------- | ------------------------------------------------------------------- |
|
|
136
|
+
| [全部](https://www.xwenming.com) | [<空>](https://rsshub.app/xwenming) |
|
|
137
|
+
| [科技前沿](https://www.xwenming.com/index.php/category/news) | [news](https://rsshub.app/xwenming/category/news) |
|
|
138
|
+
| [疑难杂症](https://www.xwenming.com/index.php/category/solve) | [solve](https://rsshub.app/xwenming/category/solve) |
|
|
139
|
+
| [通知专栏](https://www.xwenming.com/index.php/category/notice) | [notice](https://rsshub.app/xwenming/category/notice) |
|
|
140
|
+
| [未分类](https://www.xwenming.com/index.php/category/uncategorized) | [uncategorized](https://rsshub.app/xwenming/category/uncategorized) |
|
|
141
|
+
`,
|
|
142
|
+
categories: ['new-media'],
|
|
143
|
+
features: {
|
|
144
|
+
requireConfig: false,
|
|
145
|
+
requirePuppeteer: false,
|
|
146
|
+
antiCrawler: false,
|
|
147
|
+
supportRadar: true,
|
|
148
|
+
supportBT: false,
|
|
149
|
+
supportPodcast: false,
|
|
150
|
+
supportScihub: false,
|
|
151
|
+
},
|
|
152
|
+
radar: [
|
|
153
|
+
{
|
|
154
|
+
source: ['www.xwenming.com', 'www.xwenming.com/index.php/category/:category'],
|
|
155
|
+
target: '/:category',
|
|
156
|
+
},
|
|
157
|
+
{
|
|
158
|
+
title: '全部',
|
|
159
|
+
source: ['www.xwenming.com'],
|
|
160
|
+
target: '/',
|
|
161
|
+
},
|
|
162
|
+
{
|
|
163
|
+
title: '科技前沿',
|
|
164
|
+
source: ['www.xwenming.com/index.php/category/news'],
|
|
165
|
+
target: '/news',
|
|
166
|
+
},
|
|
167
|
+
{
|
|
168
|
+
title: '疑难杂症',
|
|
169
|
+
source: ['www.xwenming.com/index.php/category/solve'],
|
|
170
|
+
target: '/solve',
|
|
171
|
+
},
|
|
172
|
+
{
|
|
173
|
+
title: '通知专栏',
|
|
174
|
+
source: ['www.xwenming.com/index.php/category/notice'],
|
|
175
|
+
target: '/notice',
|
|
176
|
+
},
|
|
177
|
+
{
|
|
178
|
+
title: '未分类',
|
|
179
|
+
source: ['www.xwenming.com/index.php/category/uncategorized'],
|
|
180
|
+
target: '/uncategorized',
|
|
181
|
+
},
|
|
182
|
+
],
|
|
183
|
+
view: ViewType.Articles,
|
|
184
|
+
};
|