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.
Files changed (388) hide show
  1. package/lib/config.ts +38 -0
  2. package/lib/errors/index.tsx +3 -2
  3. package/lib/middleware/debug.ts +6 -4
  4. package/lib/middleware/header.ts +4 -2
  5. package/lib/registry.test.ts +24 -1
  6. package/lib/registry.ts +40 -11
  7. package/lib/router.js +1 -1
  8. package/lib/routes/121/namespace.ts +9 -0
  9. package/lib/routes/121/templates/description.art +17 -0
  10. package/lib/routes/121/weather-live.ts +104 -0
  11. package/lib/routes/141jav/index.ts +3 -0
  12. package/lib/routes/141ppv/index.ts +3 -0
  13. package/lib/routes/163/news/rank.ts +1 -1
  14. package/lib/routes/18comic/album.ts +59 -64
  15. package/lib/routes/18comic/index.ts +1 -0
  16. package/lib/routes/18comic/search.ts +53 -4
  17. package/lib/routes/18comic/utils.ts +70 -1
  18. package/lib/routes/2048/index.ts +1 -0
  19. package/lib/routes/30secondsofcode/utils.ts +0 -1
  20. package/lib/routes/6park/index.ts +1 -1
  21. package/lib/routes/7mmtv/index.ts +1 -0
  22. package/lib/routes/91porn/index.ts +1 -0
  23. package/lib/routes/95mm/tab.ts +1 -0
  24. package/lib/routes/agefans/detail.ts +1 -1
  25. package/lib/routes/aliyun/database-month.ts +1 -1
  26. package/lib/routes/anthropic/research.ts +112 -0
  27. package/lib/routes/apnews/topics.ts +2 -1
  28. package/lib/routes/apnews/utils.ts +1 -1
  29. package/lib/routes/apple/design.ts +54 -0
  30. package/lib/routes/apple/namespace.ts +1 -1
  31. package/lib/routes/aqara/post.ts +1 -1
  32. package/lib/routes/augmentcode/blog.ts +161 -0
  33. package/lib/routes/augmentcode/namespace.ts +9 -0
  34. package/lib/routes/augmentcode/templates/description.art +17 -0
  35. package/lib/routes/azul/namespace.ts +9 -0
  36. package/lib/routes/azul/packages.ts +105 -0
  37. package/lib/routes/banshujiang/index.ts +763 -0
  38. package/lib/routes/banshujiang/namespace.ts +9 -0
  39. package/lib/routes/banshujiang/templates/description.art +17 -0
  40. package/lib/routes/bfl/announcements.ts +1 -1
  41. package/lib/routes/bilibili/cache.ts +78 -0
  42. package/lib/routes/bilibili/danmaku.ts +1 -1
  43. package/lib/routes/bilibili/dynamic.ts +8 -2
  44. package/lib/routes/bilibili/video.ts +31 -73
  45. package/lib/routes/biquge/index.ts +1 -1
  46. package/lib/routes/bsky/keyword.ts +15 -10
  47. package/lib/routes/capitalmind/insights.ts +40 -0
  48. package/lib/routes/capitalmind/namespace.ts +8 -0
  49. package/lib/routes/capitalmind/podcasts.ts +41 -0
  50. package/lib/routes/capitalmind/utils.ts +122 -0
  51. package/lib/routes/cartoonmad/comic.ts +1 -1
  52. package/lib/routes/chikubi/index.ts +1 -0
  53. package/lib/routes/chikubi/tag.ts +1 -0
  54. package/lib/routes/chocolatey/namespace.ts +9 -0
  55. package/lib/routes/chocolatey/packages.ts +122 -0
  56. package/lib/routes/cmde/index.ts +1 -1
  57. package/lib/routes/cockroachlabs/blog.ts +113 -0
  58. package/lib/routes/cockroachlabs/namespace.ts +7 -0
  59. package/lib/routes/cool18/index.ts +4 -1
  60. package/lib/routes/coomer/index.ts +12 -6
  61. package/lib/routes/coomer/namespace.ts +1 -1
  62. package/lib/routes/copymanga/comic.ts +7 -9
  63. package/lib/routes/css-tricks/articles.ts +48 -0
  64. package/lib/routes/css-tricks/collections.ts +62 -0
  65. package/lib/routes/css-tricks/namespace.ts +8 -0
  66. package/lib/routes/css-tricks/popular.ts +39 -0
  67. package/lib/routes/css-tricks/utils.ts +103 -0
  68. package/lib/routes/cursor/changelog.ts +26 -17
  69. package/lib/routes/cursor/namespace.ts +1 -1
  70. package/lib/routes/cw/utils.ts +6 -13
  71. package/lib/routes/dealstreetasia/home.ts +1 -1
  72. package/lib/routes/dedao/index.ts +3 -3
  73. package/lib/routes/deepl/blog.ts +422 -0
  74. package/lib/routes/deepl/namespace.ts +9 -0
  75. package/lib/routes/deepl/templates/description.art +21 -0
  76. package/lib/routes/deeplearning/the-batch.ts +1 -1
  77. package/lib/routes/dev.to/guides.ts +100 -0
  78. package/lib/routes/dev.to/namespace.ts +8 -0
  79. package/lib/routes/dev.to/top.ts +105 -0
  80. package/lib/routes/dgut/jwb.ts +73 -0
  81. package/lib/routes/dgut/namespace.ts +9 -0
  82. package/lib/routes/digitalpolicyalert/activity-tracker.ts +135 -0
  83. package/lib/routes/digitalpolicyalert/namespace.ts +9 -0
  84. package/lib/routes/dnaindia/common.ts +26 -8
  85. package/lib/routes/douban/other/list.ts +3 -3
  86. package/lib/routes/e-hentai/index.ts +4 -1
  87. package/lib/routes/ehentai/tag.ts +1 -0
  88. package/lib/routes/englishhome/index.ts +55 -0
  89. package/lib/routes/englishhome/namespace.ts +6 -0
  90. package/lib/routes/epicgames/index.ts +2 -2
  91. package/lib/routes/espn/news.ts +1 -1
  92. package/lib/routes/expats/czech-news.ts +272 -0
  93. package/lib/routes/expats/namespace.ts +9 -0
  94. package/lib/routes/fanbox/index.ts +1 -0
  95. package/lib/routes/fanbox/utils.ts +1 -1
  96. package/lib/routes/fansly/tag.ts +1 -0
  97. package/lib/routes/fantia/search.ts +1 -1
  98. package/lib/routes/fantube/creator.ts +69 -0
  99. package/lib/routes/fantube/namespace.ts +7 -0
  100. package/lib/routes/fantube/templates/post.art +17 -0
  101. package/lib/routes/fantube/types.ts +100 -0
  102. package/lib/routes/fantube/utils.ts +268 -0
  103. package/lib/routes/follow/profile.ts +1 -1
  104. package/lib/routes/followin/news.ts +1 -1
  105. package/lib/routes/foresightnews/util.ts +1 -1
  106. package/lib/routes/freexcomic/book.ts +4 -1
  107. package/lib/routes/gamer/hot.ts +5 -5
  108. package/lib/routes/gaoyu/blog.ts +145 -0
  109. package/lib/routes/gaoyu/namespace.ts +9 -0
  110. package/lib/routes/gaoyu/templates/description.art +7 -0
  111. package/lib/routes/geocaching/blogs.ts +2 -2
  112. package/lib/routes/github/namespace.ts +1 -1
  113. package/lib/routes/github/private-feed.ts +229 -0
  114. package/lib/routes/github/star.ts +1 -1
  115. package/lib/routes/google/extension.ts +9 -10
  116. package/lib/routes/gov/beijing/bphc/index.ts +1 -1
  117. package/lib/routes/gov/ccdi/index.ts +1 -1
  118. package/lib/routes/gov/chongqing/sydwgkzp.ts +22 -6
  119. package/lib/routes/gov/customs/list.ts +1 -1
  120. package/lib/routes/gov/general/general.ts +1 -1
  121. package/lib/routes/gov/hangzhou/zwfw.ts +1 -1
  122. package/lib/routes/gov/pbc/goutongjiaoliu.ts +1 -1
  123. package/lib/routes/gov/shenzhen/szlh/index.ts +77 -0
  124. package/lib/routes/gov/shenzhen/szlh/namespace.ts +8 -0
  125. package/lib/routes/grist/utils.ts +5 -4
  126. package/lib/routes/hanime1/search.ts +4 -2
  127. package/lib/routes/hellogithub/report.ts +1 -1
  128. package/lib/routes/hit/hitgs.ts +240 -54
  129. package/lib/routes/hit/templates/description.art +7 -0
  130. package/lib/routes/hlju/namespace.ts +8 -0
  131. package/lib/routes/hlju/news.ts +141 -0
  132. package/lib/routes/hostmonit/cloudflareyes.ts +1 -1
  133. package/lib/routes/hotukdeals/index.ts +1 -1
  134. package/lib/routes/hyperdash/namespace.ts +7 -0
  135. package/lib/routes/hyperdash/templates/description.art +34 -0
  136. package/lib/routes/hyperdash/top-traders.ts +84 -0
  137. package/lib/routes/hyperdash/utils.ts +49 -0
  138. package/lib/routes/hypergryph/arknights/announce.ts +1 -1
  139. package/lib/routes/ielts/index.ts +1 -1
  140. package/lib/routes/infoq/topic.ts +16 -13
  141. package/lib/routes/instagram/web-api/index.ts +17 -13
  142. package/lib/routes/instagram/web-api/utils.ts +46 -63
  143. package/lib/routes/jamesclear/book-summaries.ts +40 -0
  144. package/lib/routes/jamesclear/great-speeches.ts +40 -0
  145. package/lib/routes/jamesclear/namespace.ts +8 -0
  146. package/lib/routes/jamesclear/quotes.ts +40 -0
  147. package/lib/routes/jamesclear/three-two-one.ts +41 -0
  148. package/lib/routes/jamesclear/utils.ts +22 -0
  149. package/lib/routes/japanpost/utils.ts +2 -2
  150. package/lib/routes/javbus/index.ts +3 -0
  151. package/lib/routes/javdb/tags.ts +1 -0
  152. package/lib/routes/javlibrary/star.ts +1 -0
  153. package/lib/routes/javtiful/actress.ts +3 -0
  154. package/lib/routes/javtiful/channel.ts +3 -0
  155. package/lib/routes/javtrailers/casts.ts +3 -0
  156. package/lib/routes/jetbrains/comments.ts +99 -0
  157. package/lib/routes/jetbrains/namespace.ts +8 -0
  158. package/lib/routes/jimmyspa/books.ts +1 -1
  159. package/lib/routes/jimmyspa/news.ts +1 -1
  160. package/lib/routes/jpxgmn/tab.ts +3 -0
  161. package/lib/routes/kakuyomu/works.ts +3 -0
  162. package/lib/routes/kaopu/news.ts +1 -1
  163. package/lib/routes/kemono/const.ts +1 -1
  164. package/lib/routes/kemono/index.ts +12 -11
  165. package/lib/routes/kemono/namespace.ts +1 -1
  166. package/lib/routes/kiro/blog.ts +131 -0
  167. package/lib/routes/kiro/changelog.ts +128 -0
  168. package/lib/routes/kiro/namespace.ts +9 -0
  169. package/lib/routes/konachan/post.ts +3 -0
  170. package/lib/routes/kovidgoyal/kitty/changelog.ts +83 -0
  171. package/lib/routes/kovidgoyal/namespace.ts +7 -0
  172. package/lib/routes/kunchengblog/essay.ts +1 -1
  173. package/lib/routes/landiannews/category.ts +1 -1
  174. package/lib/routes/landiannews/index.ts +1 -1
  175. package/lib/routes/landiannews/tag.ts +1 -1
  176. package/lib/routes/line/utils.ts +1 -1
  177. package/lib/routes/lineageos/changes.ts +79 -0
  178. package/lib/routes/lineageos/namespace.ts +9 -0
  179. package/lib/routes/linkedin/cn/renderer.ts +1 -1
  180. package/lib/routes/liquipedia/cs-matches.ts +42 -14
  181. package/lib/routes/literotica/new.ts +1 -0
  182. package/lib/routes/lofter/tag.ts +27 -3
  183. package/lib/routes/makerworld/contest.ts +51 -0
  184. package/lib/routes/makerworld/namespace.ts +7 -0
  185. package/lib/routes/makerworld/trending.ts +45 -0
  186. package/lib/routes/makerworld/user-upload.ts +54 -0
  187. package/lib/routes/makerworld/utils.ts +18 -0
  188. package/lib/routes/manhuagui/comic.ts +1 -1
  189. package/lib/routes/manus/blog.ts +77 -0
  190. package/lib/routes/manus/namespace.ts +7 -0
  191. package/lib/routes/mastodon/tag.ts +48 -0
  192. package/lib/routes/mathpix/blog.ts +155 -0
  193. package/lib/routes/mathpix/namespace.ts +9 -0
  194. package/lib/routes/mathpix/templates/description.art +21 -0
  195. package/lib/routes/mckinsey/cn/category-map.ts +9 -15
  196. package/lib/routes/mckinsey/cn/index.ts +77 -40
  197. package/lib/routes/melonbooks/search.ts +1 -0
  198. package/lib/routes/metacritic/index.ts +2 -2
  199. package/lib/routes/meteoblue/namespace.ts +8 -0
  200. package/lib/routes/meteoblue/weathernews.ts +75 -0
  201. package/lib/routes/meteor/index.ts +1 -1
  202. package/lib/routes/microsoft/addon.ts +7 -9
  203. package/lib/routes/mihoyo/zzz/news.ts +106 -0
  204. package/lib/routes/missav/new.ts +2 -1
  205. package/lib/routes/mit/hanlab.ts +61 -0
  206. package/lib/routes/mit/namespace.ts +6 -0
  207. package/lib/routes/mittrchina/index.ts +3 -3
  208. package/lib/routes/mixcloud/config.ts +129 -0
  209. package/lib/routes/mixcloud/index.ts +163 -107
  210. package/lib/routes/mixcloud/user-playlist.ts +31 -0
  211. package/lib/routes/mixi2/community.ts +72 -0
  212. package/lib/routes/mixi2/discovery.ts +52 -0
  213. package/lib/routes/mixi2/home.ts +51 -0
  214. package/lib/routes/mixi2/namespace.ts +8 -0
  215. package/lib/routes/mixi2/user.ts +77 -0
  216. package/lib/routes/mixi2/utils.ts +56 -0
  217. package/lib/routes/modelscope/learn.ts +94 -0
  218. package/lib/routes/moodysmismicrosite/report.ts +1 -1
  219. package/lib/routes/musify/index.ts +130 -0
  220. package/lib/routes/musify/namespace.ts +9 -0
  221. package/lib/routes/musikguru/namespace.ts +9 -0
  222. package/lib/routes/musikguru/news.ts +146 -0
  223. package/lib/routes/musikguru/templates/description.art +21 -0
  224. package/lib/routes/myfans/post.ts +1 -0
  225. package/lib/routes/nankai/cc-notice.ts +114 -0
  226. package/lib/routes/nankai/jwc.ts +131 -0
  227. package/lib/routes/nankai/namespace.ts +7 -0
  228. package/lib/routes/nankai/notice.ts +84 -0
  229. package/lib/routes/nankai/yzb.ts +97 -0
  230. package/lib/routes/neu/yz.ts +172 -0
  231. package/lib/routes/newslaundry/explainer.ts +30 -0
  232. package/lib/routes/newslaundry/namespace.ts +8 -0
  233. package/lib/routes/newslaundry/nl-cheatsheet.ts +30 -0
  234. package/lib/routes/newslaundry/nl-collaborations.ts +30 -0
  235. package/lib/routes/newslaundry/podcast.ts +61 -0
  236. package/lib/routes/newslaundry/reports.ts +30 -0
  237. package/lib/routes/newslaundry/shot.ts +30 -0
  238. package/lib/routes/newslaundry/subscriber-only.ts +30 -0
  239. package/lib/routes/newslaundry/templates/description.art +28 -0
  240. package/lib/routes/newslaundry/utils.ts +108 -0
  241. package/lib/routes/newswav/latest.ts +100 -0
  242. package/lib/routes/newswav/namespace.ts +7 -0
  243. package/lib/routes/nhentai/index.ts +1 -0
  244. package/lib/routes/nifd/research.ts +16 -0
  245. package/lib/routes/nio/namespace.ts +9 -0
  246. package/lib/routes/nio/nioradio.ts +75 -0
  247. package/lib/routes/njust/cs.ts +58 -0
  248. package/lib/routes/njust/utils.ts +1 -1
  249. package/lib/routes/ntdm/video.ts +1 -1
  250. package/lib/routes/nuaa/utils/pypasswaf.ts +1 -1
  251. package/lib/routes/oilchem/index.ts +1 -1
  252. package/lib/routes/oncc/money18.ts +1 -1
  253. package/lib/routes/openai/cookbook.ts +1 -1
  254. package/lib/routes/paulgraham/article.ts +2 -2
  255. package/lib/routes/picuki/profile.ts +4 -0
  256. package/lib/routes/pixiv/bookmarks.ts +1 -1
  257. package/lib/routes/pixiv/novel-api/series/sfw.ts +1 -1
  258. package/lib/routes/pixiv/novels.ts +2 -2
  259. package/lib/routes/pixiv/user.ts +1 -1
  260. package/lib/routes/playno1/av.ts +1 -0
  261. package/lib/routes/pornhub/model.ts +3 -7
  262. package/lib/routes/pornhub/pornstar.ts +2 -7
  263. package/lib/routes/pornhub/users.ts +2 -7
  264. package/lib/routes/pornhub/utils.ts +12 -1
  265. package/lib/routes/qingting/podcast.ts +2 -1
  266. package/lib/routes/qipamaijia/index.ts +1 -0
  267. package/lib/routes/questmobile/report.ts +1 -1
  268. package/lib/routes/railway/index.ts +73 -0
  269. package/lib/routes/railway/namespace.ts +8 -0
  270. package/lib/routes/reuters/common.ts +0 -3
  271. package/lib/routes/rockthejvm/articles.ts +167 -0
  272. package/lib/routes/rockthejvm/namespace.ts +9 -0
  273. package/lib/routes/rockthejvm/templates/description.art +7 -0
  274. package/lib/routes/samrdprc/namespace.ts +7 -0
  275. package/lib/routes/samrdprc/news.ts +79 -0
  276. package/lib/routes/sankei/namespace.ts +7 -0
  277. package/lib/routes/sankei/news.ts +68 -0
  278. package/lib/routes/sankei/topics.ts +71 -0
  279. package/lib/routes/sciencenet/user.ts +1 -1
  280. package/lib/routes/scoop/apps.ts +188 -0
  281. package/lib/routes/scoop/namespace.ts +9 -0
  282. package/lib/routes/scoop/templates/description.art +56 -0
  283. package/lib/routes/scpta/namespace.ts +8 -0
  284. package/lib/routes/scpta/news.ts +101 -0
  285. package/lib/routes/seekingalpha/index.ts +1 -1
  286. package/lib/routes/sehuatang/index.ts +29 -31
  287. package/lib/routes/setn/index.ts +11 -2
  288. package/lib/routes/seu/cyber/index.ts +78 -0
  289. package/lib/routes/sicau/jiaowu.ts +42 -34
  290. package/lib/routes/sis001/forum.ts +1 -0
  291. package/lib/routes/sjtu/seiee/icisee.ts +67 -0
  292. package/lib/routes/sketis/isabelle-dev/blog/index.ts +1 -1
  293. package/lib/routes/smartlink/index.ts +13 -3
  294. package/lib/routes/sohu/mp.ts +17 -6
  295. package/lib/routes/sotwe/namespace.ts +1 -0
  296. package/lib/routes/sotwe/user.ts +98 -0
  297. package/lib/routes/spankbang/new-videos.ts +1 -0
  298. package/lib/routes/spglobal/ratings.ts +1 -1
  299. package/lib/routes/stanford/blog.ts +77 -0
  300. package/lib/routes/stanford/namespace.ts +7 -0
  301. package/lib/routes/syosetu/index.ts +1 -1
  302. package/lib/routes/t66y/index.ts +1 -0
  303. package/lib/routes/taobao/mysql.ts +157 -0
  304. package/lib/routes/taobao/namespace.ts +2 -2
  305. package/lib/routes/techcrunch/category.ts +48 -0
  306. package/lib/routes/telegram/channel.ts +2 -2
  307. package/lib/routes/tesla/cx.ts +1 -1
  308. package/lib/routes/test/index.ts +1 -1
  309. package/lib/routes/themoviedb/episodes.ts +1 -1
  310. package/lib/routes/thewirehindi/category.ts +78 -0
  311. package/lib/routes/thewirehindi/index.ts +43 -0
  312. package/lib/routes/thewirehindi/namespace.ts +7 -0
  313. package/lib/routes/thewirehindi/templates/description.art +9 -0
  314. package/lib/routes/thewirehindi/utils.ts +33 -0
  315. package/lib/routes/threads/utils.ts +2 -2
  316. package/lib/routes/tidb/blog.ts +314 -0
  317. package/lib/routes/tidb/namespace.ts +9 -0
  318. package/lib/routes/tumblr/namespace.ts +17 -0
  319. package/lib/routes/tumblr/posts.ts +74 -0
  320. package/lib/routes/tumblr/utils.ts +110 -0
  321. package/lib/routes/tver/namespace.ts +7 -0
  322. package/lib/routes/tver/series.ts +98 -0
  323. package/lib/routes/twitter/api/web-api/login.ts +1 -3
  324. package/lib/routes/twitter/api/web-api/utils.ts +23 -1
  325. package/lib/routes/twitter/utils.ts +21 -21
  326. package/lib/routes/udn/breaking-news.ts +2 -2
  327. package/lib/routes/uestc/auto.ts +1 -1
  328. package/lib/routes/uestc/cqe.ts +1 -1
  329. package/lib/routes/uestc/scse.ts +1 -1
  330. package/lib/routes/uestc/sice.ts +1 -1
  331. package/lib/routes/uestc/sise.ts +1 -1
  332. package/lib/routes/upc/jwc.ts +32 -46
  333. package/lib/routes/uptimerobot/rss.ts +1 -1
  334. package/lib/routes/visionias/daily-news-summary.ts +65 -0
  335. package/lib/routes/visionias/monthly-magazine.ts +68 -0
  336. package/lib/routes/visionias/news-today.ts +3 -13
  337. package/lib/routes/visionias/utils.ts +5 -5
  338. package/lib/routes/visionias/weekly-focus.ts +2 -2
  339. package/lib/routes/wdfxw/bookfree.ts +528 -0
  340. package/lib/routes/wdfxw/namespace.ts +8 -0
  341. package/lib/routes/wdfxw/templates/description.art +13 -0
  342. package/lib/routes/whu/swrh.ts +1 -1
  343. package/lib/routes/windsurf/blog.ts +118 -0
  344. package/lib/routes/windsurf/changelog.ts +100 -0
  345. package/lib/routes/windsurf/namespace.ts +9 -0
  346. package/lib/routes/windsurf/templates/description.art +21 -0
  347. package/lib/routes/x6d/index.ts +1 -1
  348. package/lib/routes/xbookcn/blog.ts +1 -0
  349. package/lib/routes/xiaohongshu/util.ts +1 -3
  350. package/lib/routes/xiaoyuzhou/pickup.ts +1 -1
  351. package/lib/routes/ximalaya/album.ts +32 -70
  352. package/lib/routes/ximalaya/types.ts +48 -0
  353. package/lib/routes/ximalaya/utils.ts +9 -7
  354. package/lib/routes/xmanhua/index.ts +1 -0
  355. package/lib/routes/xueqiu/cookies.ts +1 -1
  356. package/lib/routes/xueqiu/user.ts +1 -1
  357. package/lib/routes/xwenming/index.ts +184 -0
  358. package/lib/routes/xwenming/namespace.ts +9 -0
  359. package/lib/routes/yahoo/news/utils.ts +1 -1
  360. package/lib/routes/yande/post.ts +3 -0
  361. package/lib/routes/ymgal/game.ts +1 -0
  362. package/lib/routes/youtube/api/google.ts +27 -0
  363. package/lib/routes/youtube/api/youtubei.ts +70 -20
  364. package/lib/routes/youtube/community.ts +3 -1
  365. package/lib/routes/youtube/utils.ts +16 -14
  366. package/lib/routes/zaobao/util.ts +8 -5
  367. package/lib/routes/zhihu/activities.ts +3 -0
  368. package/lib/routes/zhihu/execlib/x-zse-96-v3.ts +5 -5
  369. package/lib/routes/zhizhuan100/namespace.ts +7 -0
  370. package/lib/routes/zhizhuan100/report.ts +79 -0
  371. package/lib/routes/zimuxia/portfolio.ts +1 -1
  372. package/lib/routes/zju/sis/index.ts +161 -0
  373. package/lib/server.ts +5 -0
  374. package/lib/types.ts +58 -54
  375. package/lib/utils/helpers.ts +1 -1
  376. package/lib/utils/logger.ts +1 -1
  377. package/lib/utils/proxy/index.ts +102 -18
  378. package/lib/utils/proxy/multi-proxy.ts +139 -0
  379. package/lib/utils/proxy/unify-proxy.ts +3 -1
  380. package/lib/utils/puppeteer-utils.test.ts +1 -1
  381. package/lib/utils/puppeteer.test.ts +14 -27
  382. package/lib/utils/puppeteer.ts +51 -37
  383. package/lib/utils/readable-social.test.ts +65 -0
  384. package/lib/utils/readable-social.ts +15 -1
  385. package/lib/utils/request-rewriter/fetch.ts +42 -4
  386. package/package.json +54 -56
  387. package/lib/routes/mixcloud/queries.ts +0 -2274
  388. 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,9 @@
1
+ import type { Namespace } from '@/types';
2
+
3
+ export const namespace: Namespace = {
4
+ name: 'Windsurf',
5
+ url: 'windsurf.com',
6
+ categories: ['programming'],
7
+ description: '',
8
+ lang: 'en',
9
+ };
@@ -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 }}
@@ -69,7 +69,7 @@ export async function handler(ctx) {
69
69
  ? ''
70
70
  : firstResponse
71
71
  .match(/'([\w./=?]+)'/g)
72
- .reverse()
72
+ .toReversed()
73
73
  .join('')
74
74
  .replaceAll("'", ''),
75
75
  rootUrl
@@ -15,6 +15,7 @@ export const route: Route = {
15
15
  supportBT: false,
16
16
  supportPodcast: false,
17
17
  supportScihub: false,
18
+ nsfw: true,
18
19
  },
19
20
  name: '短篇', // 源名称
20
21
  maintainers: ['Lyunvy'], // 维护者
@@ -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 : (item.episode.podcast.image ? item.episode.podcast.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
- // function parseState(state_string) {
22
- // const data = {};
23
- // new Function('window', state_string)(data);
24
- // return data.__INITIAL_STATE__ || {};
25
- // }
26
- /**
27
- *
28
- * @param {string} stateString 网页中的有一处 script 标签内有语句
29
- * `window.__INITIAL_STATE__ = {"xx": "xx"};`
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: { type: '专辑类型, 通常可以使用 `album`,可在对应专辑页面的 URL 中找到', id: '专辑 id, 可在对应专辑页面的 URL 中找到', all: '是否需要获取全部节目,填入 `1`、`true`、`all` 视为获取所有节目,填入其他则不获取。' },
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 parseAlbumData(type, id);
122
-
123
- const { albumPageMainInfo, currentCategory, anchorInfo } = albumData?.store?.AlbumDetailPage || {};
90
+ const albumData = await getAlbumData(id);
124
91
 
125
- const isPaid = albumPageMainInfo.isPaid;
92
+ const isPaid = albumData.isPaid;
126
93
 
127
- const authorInfo = anchorInfo; // 作者数据
128
- const author = authorInfo.nickName;
94
+ const author = albumData.anchorName;
129
95
 
130
- const albumInfo = albumPageMainInfo; // 专辑数据
131
- const albumTitle = albumInfo.albumTitle; // 专辑标题
132
- const albumCover = 'http:' + albumInfo.cover.split('!')[0];
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 categoryInfo = currentCategory;
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 = `http://mobile.ximalaya.com/mobile/v1/album/track/?albumId=${id}&pageSize=${pageSize}&pageId=`;
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
- const link = baseUrl + albumUrl + item.trackId;
169
- item.desc = await cache.tryGet('ximalaya:' + shouldShowNote.toString() + 'trackRichInfo' + link, async () => {
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 = `<a href="${link}">在网页中查看</a>`;
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 + albumUrl + trackId;
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 + albumUrl,
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 encrypted_data = Buffer.from(encryptedUrl.replace('_', '/').replace('-', '+') + padding, 'base64');
143
- if (encrypted_data.length < 16) {
144
+ const encryptedData = Buffer.from(encryptedUrl.replace('_', '/').replace('-', '+') + padding, 'base64');
145
+ if (encryptedData.length < 16) {
144
146
  return encryptedUrl;
145
147
  }
146
- const data = encrypted_data.slice(0, -16);
147
- const iv = encrypted_data.slice(-16);
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.slice(i, i + 16);
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.slice(i, i + 32);
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 };
@@ -15,6 +15,7 @@ export const route: Route = {
15
15
  supportBT: false,
16
16
  supportPodcast: false,
17
17
  supportScihub: false,
18
+ nsfw: true,
18
19
  },
19
20
  radar: [
20
21
  {
@@ -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({ stealth: true });
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({ stealth: true });
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
+ };