rsshub 1.0.0-master.f9ec483 → 1.0.0-master.fa1dcc5

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 (334) hide show
  1. package/lib/config.ts +42 -1
  2. package/lib/middleware/access-control.ts +3 -3
  3. package/lib/middleware/cache.ts +5 -3
  4. package/lib/middleware/template.test.ts +6 -0
  5. package/lib/middleware/template.tsx +3 -1
  6. package/lib/router.js +0 -6
  7. package/lib/routes/141jav/index.ts +1 -1
  8. package/lib/routes/141ppv/index.ts +1 -1
  9. package/lib/routes/36kr/hot-list.ts +1 -1
  10. package/lib/routes/36kr/index.ts +1 -1
  11. package/lib/routes/78dm/index.ts +429 -43
  12. package/lib/routes/78dm/namespace.ts +2 -0
  13. package/lib/routes/78dm/templates/description.art +17 -0
  14. package/lib/routes/abc/index.ts +10 -9
  15. package/lib/routes/aeon/category.ts +1 -1
  16. package/lib/routes/aeon/type.ts +1 -1
  17. package/lib/routes/afr/latest.ts +69 -0
  18. package/lib/routes/afr/namespace.ts +7 -0
  19. package/lib/routes/afr/navigation.ts +75 -0
  20. package/lib/routes/afr/query.ts +349 -0
  21. package/lib/routes/afr/utils.ts +80 -0
  22. package/lib/routes/aibase/discover.ts +1 -1
  23. package/lib/routes/aibase/news.ts +1 -1
  24. package/lib/routes/aibase/topic.ts +1 -1
  25. package/lib/routes/air-level/index.ts +49 -0
  26. package/lib/routes/air-level/levelrank.ts +65 -0
  27. package/lib/routes/air-level/namespace.ts +12 -0
  28. package/lib/routes/ajcass/namespace.ts +11 -0
  29. package/lib/routes/ajcass/shxyj.ts +73 -0
  30. package/lib/routes/alpinelinux/pkgs.ts +2 -2
  31. package/lib/routes/anime1/anime.ts +1 -1
  32. package/lib/routes/apnews/utils.ts +6 -2
  33. package/lib/routes/appleinsider/index.ts +1 -1
  34. package/lib/routes/aqara/region.ts +1 -1
  35. package/lib/routes/asus/bios.ts +0 -1
  36. package/lib/routes/baoyu/index.ts +57 -0
  37. package/lib/routes/baoyu/namespace.ts +8 -0
  38. package/lib/routes/bilibili/article.ts +37 -14
  39. package/lib/routes/bilibili/dynamic.ts +15 -7
  40. package/lib/routes/bilibili/followings-dynamic.ts +2 -2
  41. package/lib/routes/bilibili/manga-update.ts +3 -0
  42. package/lib/routes/bilibili/ranking.ts +188 -117
  43. package/lib/routes/bilibili/reply.ts +2 -0
  44. package/lib/routes/bilibili/templates/description.art +2 -0
  45. package/lib/routes/bing/daily-wallpaper.ts +5 -1
  46. package/lib/routes/bsky/posts.ts +0 -1
  47. package/lib/routes/bsky/templates/post.art +8 -1
  48. package/lib/routes/buaa/lib/space/newbook.ts +1 -1
  49. package/lib/routes/c114/namespace.ts +2 -0
  50. package/lib/routes/c114/roll.ts +71 -42
  51. package/lib/routes/cags/edu/index.ts +84 -0
  52. package/lib/routes/cags/namespace.ts +9 -0
  53. package/lib/routes/caixin/article.ts +1 -1
  54. package/lib/routes/caixin/blog.ts +2 -3
  55. package/lib/routes/caixin/category.ts +1 -1
  56. package/lib/routes/caixin/latest.ts +12 -16
  57. package/lib/routes/caixin/namespace.ts +1 -1
  58. package/lib/routes/caixin/utils-fulltext.ts +51 -0
  59. package/lib/routes/caixin/utils.ts +37 -37
  60. package/lib/routes/cara/likes.ts +1 -1
  61. package/lib/routes/cara/portfolio.ts +1 -1
  62. package/lib/routes/cara/timeline.ts +1 -1
  63. package/lib/routes/ccfa/index.ts +11 -11
  64. package/lib/routes/chub/characters.ts +1 -1
  65. package/lib/routes/cnbeta/namespace.ts +1 -1
  66. package/lib/routes/cngold/index.ts +195 -0
  67. package/lib/routes/cngold/namespace.ts +9 -0
  68. package/lib/routes/cnki/author.ts +120 -48
  69. package/lib/routes/cnki/utils.ts +4 -4
  70. package/lib/routes/coomer/artist.ts +1 -1
  71. package/lib/routes/coomer/namespace.ts +1 -1
  72. package/lib/routes/coomer/posts.ts +2 -2
  73. package/lib/routes/coomer/utils.ts +1 -1
  74. package/lib/routes/cpcaauto/index.ts +22 -22
  75. package/lib/routes/cs/zzkx.ts +1 -1
  76. package/lib/routes/csdn/blog.ts +17 -13
  77. package/lib/routes/cybersecurityventures/namespace.ts +7 -0
  78. package/lib/routes/cybersecurityventures/news.ts +121 -0
  79. package/lib/routes/cybersecurityventures/types.ts +17 -0
  80. package/lib/routes/daily/discussed.ts +22 -21
  81. package/lib/routes/daily/index.ts +14 -11
  82. package/lib/routes/daily/namespace.ts +1 -1
  83. package/lib/routes/daily/source.ts +186 -0
  84. package/lib/routes/daily/upvoted.ts +17 -17
  85. package/lib/routes/daily/user.ts +6 -23
  86. package/lib/routes/daily/utils.ts +27 -32
  87. package/lib/routes/dataguidance/index.ts +19 -30
  88. package/lib/routes/dcfever/news.ts +1 -1
  89. package/lib/routes/dcfever/reviews.ts +1 -1
  90. package/lib/routes/dcfever/trading-search.ts +1 -1
  91. package/lib/routes/dcfever/trading.ts +1 -1
  92. package/lib/routes/deeplearning/namespace.ts +3 -1
  93. package/lib/routes/deeplearning/templates/description.art +21 -0
  94. package/lib/routes/deeplearning/the-batch.ts +296 -0
  95. package/lib/routes/deepmind/blog.ts +1 -1
  96. package/lib/routes/digitalcameraworld/news.ts +1 -1
  97. package/lib/routes/discord/discord-api.ts +44 -2
  98. package/lib/routes/discord/search.ts +106 -0
  99. package/lib/routes/dn/news.ts +1 -1
  100. package/lib/routes/dockerhub/repositories.ts +42 -0
  101. package/lib/routes/dongqiudi/daily.ts +1 -1
  102. package/lib/routes/dw/namespace.ts +6 -0
  103. package/lib/routes/dw/news.ts +89 -0
  104. package/lib/routes/dw/rss.ts +62 -0
  105. package/lib/routes/dw/templates/description.art +23 -0
  106. package/lib/routes/dw/templates/liveblog.art +13 -0
  107. package/lib/routes/dw/templates/video.art +14 -0
  108. package/lib/routes/dw/utils.ts +172 -0
  109. package/lib/routes/ecnu/jwc.ts +5 -1
  110. package/lib/routes/espn/news.ts +1 -1
  111. package/lib/routes/fashionnetwork/namespace.ts +1 -1
  112. package/lib/routes/flyert/forum.ts +99 -0
  113. package/lib/routes/flyert/namespace.ts +1 -0
  114. package/lib/routes/flyert/templates/description.art +21 -0
  115. package/lib/routes/flyert/util.ts +188 -0
  116. package/lib/routes/follow/profile.ts +2 -2
  117. package/lib/routes/foresightnews/article.ts +1 -1
  118. package/lib/routes/foresightnews/column.ts +1 -1
  119. package/lib/routes/foresightnews/index.ts +3 -1
  120. package/lib/routes/foresightnews/news.ts +1 -1
  121. package/lib/routes/freecomputerbooks/index.ts +0 -10
  122. package/lib/routes/ftm/index.ts +1 -1
  123. package/lib/routes/furaffinity/art.ts +85 -0
  124. package/lib/routes/furaffinity/browse.ts +58 -0
  125. package/lib/routes/furaffinity/commissions.ts +55 -0
  126. package/lib/routes/furaffinity/home.ts +80 -0
  127. package/lib/routes/furaffinity/journal-comments.ts +64 -0
  128. package/lib/routes/furaffinity/journals.ts +56 -0
  129. package/lib/routes/furaffinity/namespace.ts +7 -0
  130. package/lib/routes/furaffinity/search.ts +72 -0
  131. package/lib/routes/furaffinity/shouts.ts +56 -0
  132. package/lib/routes/furaffinity/status.ts +58 -0
  133. package/lib/routes/furaffinity/submission-comments.ts +64 -0
  134. package/lib/{routes-deprecated/furaffinity/user.js → routes/furaffinity/user.ts} +53 -41
  135. package/lib/routes/furaffinity/watchers.ts +62 -0
  136. package/lib/routes/furaffinity/watching.ts +62 -0
  137. package/lib/routes/google/developers.ts +71 -0
  138. package/lib/routes/google/news.ts +26 -6
  139. package/lib/routes/gov/cbirc/index.ts +35 -35
  140. package/lib/routes/hamel/index.ts +81 -0
  141. package/lib/routes/hamel/namespace.ts +7 -0
  142. package/lib/routes/hellogithub/volume.ts +3 -0
  143. package/lib/routes/hket/index.ts +13 -1
  144. package/lib/routes/hostmonit/cloudflareyesv6.ts +1 -1
  145. package/lib/routes/hrbeu/sec/list.ts +80 -0
  146. package/lib/routes/hrbust/jwzx.ts +6 -0
  147. package/lib/routes/hunau/gfxy/index.ts +1 -1
  148. package/lib/routes/hunau/ied.ts +1 -1
  149. package/lib/routes/hunau/jwc.ts +1 -1
  150. package/lib/routes/hunau/xky/index.ts +1 -1
  151. package/lib/routes/hust/gs.ts +4 -3
  152. package/lib/routes/idolmaster/namespace.ts +7 -0
  153. package/lib/routes/idolmaster/news.ts +112 -0
  154. package/lib/routes/ieee/author.ts +95 -0
  155. package/lib/routes/ikea/cn/low-price.ts +2 -1
  156. package/lib/routes/imdb/chart.ts +1 -1
  157. package/lib/routes/inspirehep/author.ts +9 -1
  158. package/lib/routes/isct/namespace.ts +11 -0
  159. package/lib/routes/isct/news.ts +66 -0
  160. package/lib/routes/javtrailers/casts.ts +41 -0
  161. package/lib/routes/javtrailers/categories.ts +40 -0
  162. package/lib/routes/javtrailers/namespace.ts +7 -0
  163. package/lib/routes/javtrailers/studios.ts +39 -0
  164. package/lib/routes/javtrailers/templates/description.art +31 -0
  165. package/lib/routes/javtrailers/types.ts +59 -0
  166. package/lib/routes/javtrailers/utils.ts +48 -0
  167. package/lib/routes/jiemian/list.ts +1 -1
  168. package/lib/routes/jiuyangongshe/community.ts +1 -1
  169. package/lib/routes/jlu/phy/index.ts +55 -0
  170. package/lib/routes/joins/chinese.ts +13 -13
  171. package/lib/routes/kcna/news.ts +7 -5
  172. package/lib/routes/keep/user.ts +1 -1
  173. package/lib/routes/langchain/index.ts +74 -0
  174. package/lib/routes/langchain/namespace.ts +7 -0
  175. package/lib/routes/last-origin/namespace.ts +7 -0
  176. package/lib/routes/last-origin/news.ts +65 -0
  177. package/lib/routes/linkresearcher/index.ts +108 -46
  178. package/lib/routes/linkresearcher/namespace.ts +8 -2
  179. package/lib/routes/linkresearcher/templates/bilingual.art +7 -0
  180. package/lib/routes/linkresearcher/types.ts +103 -0
  181. package/lib/routes/liulinblog/itnews.ts +1 -1
  182. package/lib/routes/lofter/collection.ts +1 -1
  183. package/lib/routes/lofter/tag.ts +1 -1
  184. package/lib/routes/logrocket/index.ts +71 -0
  185. package/lib/routes/logrocket/namespace.ts +7 -0
  186. package/lib/routes/m-78/namespace.ts +7 -0
  187. package/lib/routes/m-78/news.ts +115 -0
  188. package/lib/routes/m-78/types.ts +13 -0
  189. package/lib/routes/mastodon/account-id.ts +1 -1
  190. package/lib/routes/mastodon/acct.ts +1 -1
  191. package/lib/routes/mastodon/timeline-local.ts +2 -2
  192. package/lib/routes/mastodon/timeline-remote.ts +2 -2
  193. package/lib/routes/mastodon/utils.ts +1 -1
  194. package/lib/routes/metacritic/index.ts +1 -1
  195. package/lib/routes/mi/utils.ts +1 -1
  196. package/lib/routes/mihoyo/bbs/official.ts +2 -1
  197. package/lib/routes/misskey/utils.ts +19 -1
  198. package/lib/routes/mittrchina/index.ts +2 -2
  199. package/lib/routes/natgeo/natgeo.ts +25 -24
  200. package/lib/routes/nbd/daily.ts +1 -1
  201. package/lib/routes/nielsberglund/index.ts +78 -0
  202. package/lib/routes/nielsberglund/namespace.ts +7 -0
  203. package/lib/routes/nytimes/rss.ts +57 -0
  204. package/lib/routes/openrice/chart.ts +68 -0
  205. package/lib/routes/openrice/templates/chart.art +9 -0
  206. package/lib/routes/openrice/voting.ts +84 -0
  207. package/lib/routes/oschina/news.ts +26 -7
  208. package/lib/routes/patreon/feed.ts +126 -0
  209. package/lib/routes/patreon/namespace.ts +7 -0
  210. package/lib/routes/patreon/templates/description.art +39 -0
  211. package/lib/routes/patreon/types.ts +387 -0
  212. package/lib/routes/pixiv/api/get-illust-detail.ts +22 -0
  213. package/lib/routes/pixiv/novel-api/content/nsfw.ts +73 -0
  214. package/lib/routes/pixiv/novel-api/content/sfw.ts +63 -0
  215. package/lib/routes/pixiv/novel-api/content/types.ts +254 -0
  216. package/lib/routes/pixiv/novel-api/content/utils.ts +133 -0
  217. package/lib/routes/pixiv/novel-api/series/nsfw.ts +84 -0
  218. package/lib/routes/pixiv/novel-api/series/sfw.ts +70 -0
  219. package/lib/routes/pixiv/novel-api/series/types.ts +94 -0
  220. package/lib/routes/pixiv/novel-api/user-novels/nsfw.ts +82 -0
  221. package/lib/routes/pixiv/novel-api/user-novels/sfw.ts +74 -0
  222. package/lib/routes/pixiv/novel-api/user-novels/types.ts +133 -0
  223. package/lib/routes/pixiv/novel-series.ts +52 -0
  224. package/lib/routes/pixiv/novels.ts +69 -44
  225. package/lib/routes/pixiv/utils.ts +3 -0
  226. package/lib/routes/plurk/anonymous.ts +1 -1
  227. package/lib/routes/plurk/hotlinks.ts +1 -1
  228. package/lib/routes/plurk/news.ts +1 -1
  229. package/lib/routes/plurk/search.ts +1 -1
  230. package/lib/routes/qstheory/index.ts +121 -0
  231. package/lib/routes/qstheory/magazine.ts +64 -0
  232. package/lib/routes/qstheory/namespace.ts +7 -0
  233. package/lib/routes/qstheory/utils.ts +25 -0
  234. package/lib/routes/ruc/ai.ts +1 -1
  235. package/lib/routes/scmp/coronavirus.ts +1 -1
  236. package/lib/routes/scu/jwc/tzgg.ts +75 -0
  237. package/lib/routes/scu/namespace.ts +7 -0
  238. package/lib/routes/scu/scupi/_utils.ts +62 -0
  239. package/lib/routes/scu/scupi/notice.ts +41 -0
  240. package/lib/routes/solidot/namespace.ts +1 -1
  241. package/lib/routes/stbu/jsjxy.ts +4 -1
  242. package/lib/routes/steam/search.ts +7 -0
  243. package/lib/routes/sycl/feeds.ts +1 -1
  244. package/lib/routes/syosetu/dev.ts +67 -0
  245. package/lib/routes/syosetu/index.ts +85 -0
  246. package/lib/routes/syosetu/namespace.ts +2 -2
  247. package/lib/routes/syosetu/ranking-isekai.ts +93 -0
  248. package/lib/routes/syosetu/ranking-r18.ts +192 -0
  249. package/lib/routes/syosetu/ranking.ts +285 -0
  250. package/lib/routes/syosetu/search.ts +161 -0
  251. package/lib/routes/syosetu/templates/description.art +73 -0
  252. package/lib/routes/syosetu/types/ranking-r18.ts +60 -0
  253. package/lib/routes/syosetu/types/ranking.ts +67 -0
  254. package/lib/routes/syosetu/types/search.ts +138 -0
  255. package/lib/routes/syosetu/utils.ts +50 -0
  256. package/lib/routes/telegram/channel.ts +31 -1
  257. package/lib/routes/telegram/scripts/get-telegram-session.mjs +16 -6
  258. package/lib/routes/telegram/stickerpack.ts +1 -1
  259. package/lib/routes/telegram/tglib/channel.ts +12 -9
  260. package/lib/routes/telegram/tglib/client.ts +13 -9
  261. package/lib/routes/test/index.ts +4 -0
  262. package/lib/routes/theblockbeats/index.ts +1 -1
  263. package/lib/routes/thegradient/index.ts +80 -0
  264. package/lib/routes/thegradient/namespace.ts +7 -0
  265. package/lib/routes/theinitium/app.ts +4 -0
  266. package/lib/routes/thepaper/channel.ts +1 -1
  267. package/lib/routes/thepaper/factpaper.ts +1 -1
  268. package/lib/routes/thepaper/featured.ts +1 -1
  269. package/lib/routes/thepaper/list.ts +1 -1
  270. package/lib/routes/thepaper/user.ts +174 -0
  271. package/lib/routes/tongji/sem/_utils.ts +65 -0
  272. package/lib/routes/tongji/sem/notice.ts +58 -0
  273. package/lib/routes/toutiao/a-bogus.ts +540 -0
  274. package/lib/routes/toutiao/namespace.ts +7 -0
  275. package/lib/routes/toutiao/templates/video.art +7 -0
  276. package/lib/routes/toutiao/types.ts +443 -0
  277. package/lib/routes/toutiao/user.ts +127 -0
  278. package/lib/routes/twitter/api/mobile-api/api.ts +8 -0
  279. package/lib/routes/twitter/api/web-api/utils.ts +21 -9
  280. package/lib/routes/twitter/namespace.ts +1 -0
  281. package/lib/routes/twitter/utils.ts +7 -1
  282. package/lib/routes/vertikal/latest.ts +73 -0
  283. package/lib/routes/vertikal/namespace.ts +7 -0
  284. package/lib/routes/vice/topic.ts +1 -1
  285. package/lib/routes/vocus/publication.ts +1 -1
  286. package/lib/routes/vocus/user.ts +1 -1
  287. package/lib/routes/wallstreetcn/calendar.ts +90 -0
  288. package/lib/routes/wallstreetcn/hot.ts +2 -2
  289. package/lib/routes/wallstreetcn/live.ts +1 -1
  290. package/lib/routes/wallstreetcn/news.ts +5 -3
  291. package/lib/routes/weibo/timeline.ts +3 -2
  292. package/lib/routes/wellcee/rent.ts +1 -1
  293. package/lib/routes/wufazhuce/namespace.ts +7 -0
  294. package/lib/routes/wufazhuce/one.ts +90 -0
  295. package/lib/routes/xiaoheihe/discount.ts +72 -28
  296. package/lib/routes/xiaohongshu/user.ts +40 -3
  297. package/lib/routes/xiaohongshu/util.ts +112 -105
  298. package/lib/routes/xsijishe/rank.ts +33 -7
  299. package/lib/routes/xueqiu/cookies.ts +13 -18
  300. package/lib/routes/yahoo/news/listid.ts +4 -1
  301. package/lib/routes/yahoo/news/provider-helper.ts +4 -1
  302. package/lib/routes/yahoo/news/provider.ts +4 -1
  303. package/lib/routes/yande/post.ts +13 -3
  304. package/lib/routes/youtube/user.ts +37 -25
  305. package/lib/routes/zhonglun/index.ts +5 -6
  306. package/lib/routes/zjut/cs/index.ts +1 -1
  307. package/lib/utils/got.ts +2 -1
  308. package/lib/utils/helpers.test.ts +13 -1
  309. package/lib/utils/helpers.ts +10 -0
  310. package/lib/utils/ofetch.ts +3 -0
  311. package/lib/utils/request-rewriter/fetch.test.ts +94 -0
  312. package/lib/utils/request-rewriter/fetch.ts +14 -1
  313. package/lib/views/error.tsx +1 -1
  314. package/package.json +40 -37
  315. package/lib/routes/78dm/templates/image.art +0 -1
  316. package/lib/routes/deeplearning/thebatch.ts +0 -74
  317. package/lib/routes/syosetu/chapter.ts +0 -87
  318. package/lib/routes/xiaohongshu/notes.ts +0 -39
  319. package/lib/routes-deprecated/furaffinity/browse.js +0 -44
  320. package/lib/routes-deprecated/furaffinity/commissions.js +0 -39
  321. package/lib/routes-deprecated/furaffinity/favorites.js +0 -56
  322. package/lib/routes-deprecated/furaffinity/gallery.js +0 -56
  323. package/lib/routes-deprecated/furaffinity/home.js +0 -72
  324. package/lib/routes-deprecated/furaffinity/journal-comments.js +0 -50
  325. package/lib/routes-deprecated/furaffinity/journals.js +0 -49
  326. package/lib/routes-deprecated/furaffinity/scraps.js +0 -56
  327. package/lib/routes-deprecated/furaffinity/search.js +0 -56
  328. package/lib/routes-deprecated/furaffinity/shouts.js +0 -40
  329. package/lib/routes-deprecated/furaffinity/status.js +0 -38
  330. package/lib/routes-deprecated/furaffinity/submission-comments.js +0 -50
  331. package/lib/routes-deprecated/furaffinity/watchers.js +0 -47
  332. package/lib/routes-deprecated/furaffinity/watching.js +0 -47
  333. package/lib/routes-deprecated/ieee/author.js +0 -30
  334. package/lib/routes-deprecated/qstheory/index.js +0 -122
@@ -0,0 +1,69 @@
1
+ import { Route } from '@/types';
2
+ import type { Context } from 'hono';
3
+
4
+ import cache from '@/utils/cache';
5
+ import ofetch from '@/utils/ofetch';
6
+ import { parseDate } from '@/utils/parse-date';
7
+ import { assetsConnectionByCriteriaQuery } from './query';
8
+ import { getItem } from './utils';
9
+
10
+ export const route: Route = {
11
+ path: '/latest',
12
+ categories: ['traditional-media'],
13
+ example: '/afr/latest',
14
+ features: {
15
+ requireConfig: false,
16
+ requirePuppeteer: false,
17
+ antiCrawler: false,
18
+ supportBT: false,
19
+ supportPodcast: false,
20
+ supportScihub: false,
21
+ },
22
+ radar: [
23
+ {
24
+ source: ['www.afr.com/latest', 'www.afr.com/'],
25
+ },
26
+ ],
27
+ name: 'Latest',
28
+ maintainers: ['TonyRL'],
29
+ handler,
30
+ url: 'www.afr.com/latest',
31
+ };
32
+
33
+ async function handler(ctx: Context) {
34
+ const limit = Number.parseInt(ctx.req.query('limit') ?? '10');
35
+ const response = await ofetch('https://api.afr.com/graphql', {
36
+ query: {
37
+ query: assetsConnectionByCriteriaQuery,
38
+ operationName: 'assetsConnectionByCriteria',
39
+ variables: {
40
+ brand: 'afr',
41
+ first: limit,
42
+ render: 'web',
43
+ types: ['article', 'bespoke', 'featureArticle', 'liveArticle', 'video'],
44
+ after: '',
45
+ },
46
+ },
47
+ });
48
+
49
+ const list = response.data.assetsConnectionByCriteria.edges.map(({ node }) => ({
50
+ title: node.asset.headlines.headline,
51
+ description: node.asset.about,
52
+ link: `https://www.afr.com${node.urls.published.afr.path}`,
53
+ pubDate: parseDate(node.dates.firstPublished),
54
+ updated: parseDate(node.dates.modified),
55
+ author: node.asset.byline,
56
+ category: [node.tags.primary.displayName, ...node.tags.secondary.map((tag) => tag.displayName)],
57
+ image: node.featuredImages && `https://static.ffx.io/images/${node.featuredImages.landscape16x9.data.id}`,
58
+ }));
59
+
60
+ const items = await Promise.all(list.map((item) => cache.tryGet(item.link, () => getItem(item))));
61
+
62
+ return {
63
+ title: 'Latest | The Australian Financial Review | AFR',
64
+ description: 'The latest news, events, analysis and opinion from The Australian Financial Review',
65
+ image: 'https://www.afr.com/apple-touch-icon-1024x1024.png',
66
+ link: 'https://www.afr.com/latest',
67
+ item: items,
68
+ };
69
+ }
@@ -0,0 +1,7 @@
1
+ import type { Namespace } from '@/types';
2
+
3
+ export const namespace: Namespace = {
4
+ name: 'The Australian Financial Review',
5
+ url: 'afr.com',
6
+ lang: 'en',
7
+ };
@@ -0,0 +1,75 @@
1
+ import { Route } from '@/types';
2
+ import type { Context } from 'hono';
3
+
4
+ import cache from '@/utils/cache';
5
+ import ofetch from '@/utils/ofetch';
6
+ import { parseDate } from '@/utils/parse-date';
7
+ import { pageByNavigationPathQuery } from './query';
8
+ import { getItem } from './utils';
9
+
10
+ export const route: Route = {
11
+ path: '/navigation/:path{.+}',
12
+ categories: ['traditional-media'],
13
+ example: '/afr/navigation/markets',
14
+ parameters: {
15
+ path: 'Navigation path, can be found in the URL of the page',
16
+ },
17
+ features: {
18
+ requireConfig: false,
19
+ requirePuppeteer: false,
20
+ antiCrawler: false,
21
+ supportBT: false,
22
+ supportPodcast: false,
23
+ supportScihub: false,
24
+ },
25
+ radar: [
26
+ {
27
+ source: ['www.afr.com/path*'],
28
+ },
29
+ ],
30
+ name: 'Navigation',
31
+ maintainers: ['TonyRL'],
32
+ handler,
33
+ url: 'www.afr.com',
34
+ };
35
+
36
+ async function handler(ctx: Context) {
37
+ const { path } = ctx.req.param();
38
+ const limit = Number.parseInt(ctx.req.query('limit') ?? '10');
39
+
40
+ const response = await ofetch('https://api.afr.com/api/content-audience/afr/graphql', {
41
+ query: {
42
+ query: pageByNavigationPathQuery,
43
+ operationName: 'pageByNavigationPath',
44
+ variables: {
45
+ input: { brandKey: 'afr', navigationPath: `/${path}`, renderName: 'web' },
46
+ firstStories: limit,
47
+ afterStories: '',
48
+ },
49
+ },
50
+ });
51
+
52
+ const list = response.data.pageByNavigationPath.page.latestStoriesConnection.edges.map(({ node }) => ({
53
+ title: node.headlines.headline,
54
+ description: node.overview.about,
55
+ link: `https://www.afr.com${node.urls.canonical.path}`,
56
+ pubDate: parseDate(node.dates.firstPublished),
57
+ updated: parseDate(node.dates.modified),
58
+ author: node.byline
59
+ .filter((byline) => byline.type === 'AUTHOR')
60
+ .map((byline) => byline.author.name)
61
+ .join(', '),
62
+ category: [node.tags.primary.displayName, ...node.tags.secondary.map((tag) => tag.displayName)],
63
+ image: node.images && `https://static.ffx.io/images/${node.images.landscape16x9.mediaId}`,
64
+ }));
65
+
66
+ const items = await Promise.all(list.map((item) => cache.tryGet(item.link, () => getItem(item))));
67
+
68
+ return {
69
+ title: response.data.pageByNavigationPath.page.seo.title,
70
+ description: response.data.pageByNavigationPath.page.seo.description,
71
+ image: 'https://www.afr.com/apple-touch-icon-1024x1024.png',
72
+ link: `https://www.afr.com/${path}`,
73
+ item: items,
74
+ };
75
+ }
@@ -0,0 +1,349 @@
1
+ export const pageByNavigationPathQuery = `query pageByNavigationPath(
2
+ $input: PageByNavigationPathInput!
3
+ $firstStories: Int
4
+ $afterStories: Cursor
5
+ ) {
6
+ pageByNavigationPath(input: $input) {
7
+ error {
8
+ message
9
+ type {
10
+ class
11
+ ... on ErrorTypeInvalidRequest {
12
+ fields {
13
+ field
14
+ message
15
+ }
16
+ }
17
+ }
18
+ }
19
+ page {
20
+ ads {
21
+ suppress
22
+ }
23
+ description
24
+ id
25
+ latestStoriesConnection(first: $firstStories, after: $afterStories) {
26
+ edges {
27
+ node {
28
+ byline {
29
+ ...AssetBylineFragment
30
+ }
31
+ headlines {
32
+ headline
33
+ }
34
+ ads {
35
+ sponsor {
36
+ name
37
+ }
38
+ }
39
+ overview {
40
+ about
41
+ label
42
+ }
43
+ type
44
+ dates {
45
+ firstPublished
46
+ published
47
+ }
48
+ id
49
+ publicId
50
+ images {
51
+ ...AssetImagesFragmentAudience
52
+ }
53
+ tags {
54
+ primary {
55
+ ...TagFragmentAudience
56
+ }
57
+ secondary {
58
+ ...TagFragmentAudience
59
+ }
60
+ }
61
+ urls {
62
+ ...AssetUrlsAudienceFragment
63
+ }
64
+ }
65
+ }
66
+ pageInfo {
67
+ endCursor
68
+ hasNextPage
69
+ }
70
+ }
71
+ name
72
+ seo {
73
+ canonical {
74
+ brand {
75
+ key
76
+ }
77
+ }
78
+ description
79
+ title
80
+ }
81
+ social {
82
+ image {
83
+ height
84
+ url
85
+ width
86
+ }
87
+ }
88
+ }
89
+ redirect
90
+ }
91
+ }
92
+ fragment AssetBylineFragment on AssetByline {
93
+ type
94
+ ... on AssetBylineAuthor {
95
+ author {
96
+ name
97
+ publicId
98
+ profile {
99
+ avatar
100
+ bio
101
+ body
102
+ canonical {
103
+ brand {
104
+ key
105
+ }
106
+ }
107
+ email
108
+ socials {
109
+ facebook {
110
+ publicId
111
+ }
112
+ twitter {
113
+ publicId
114
+ }
115
+ }
116
+ title
117
+ }
118
+ }
119
+ }
120
+ ... on AssetBylineName {
121
+ name
122
+ }
123
+ }
124
+ fragment AssetImagesFragmentAudience on ImageRenditions {
125
+ landscape16x9 {
126
+ ...ImageFragmentAudience
127
+ }
128
+ landscape3x2 {
129
+ ...ImageFragmentAudience
130
+ }
131
+ portrait2x3 {
132
+ ...ImageFragmentAudience
133
+ }
134
+ square1x1 {
135
+ ...ImageFragmentAudience
136
+ }
137
+ }
138
+ fragment ImageFragmentAudience on ImageRendition {
139
+ altText
140
+ animated
141
+ caption
142
+ credit
143
+ crop {
144
+ offsetX
145
+ offsetY
146
+ width
147
+ zoom
148
+ }
149
+ mediaId
150
+ mimeType
151
+ source
152
+ type
153
+ }
154
+ fragment AssetUrlsAudienceFragment on AssetURLs {
155
+ canonical {
156
+ brand {
157
+ key
158
+ }
159
+ path
160
+ }
161
+ external {
162
+ url
163
+ }
164
+ published {
165
+ brand {
166
+ key
167
+ }
168
+ path
169
+ }
170
+ }
171
+ fragment TagFragmentAudience on Tag {
172
+ company {
173
+ exchangeCode
174
+ stockCode
175
+ }
176
+ context {
177
+ name
178
+ }
179
+ description
180
+ displayName
181
+ externalEntities {
182
+ google {
183
+ placeId
184
+ }
185
+ wikipedia {
186
+ publicId
187
+ url
188
+ }
189
+ }
190
+ id
191
+ location {
192
+ latitude
193
+ longitude
194
+ postalCode
195
+ state
196
+ }
197
+ name
198
+ publicId
199
+ seo {
200
+ description
201
+ title
202
+ }
203
+ urls {
204
+ canonical {
205
+ brand {
206
+ key
207
+ }
208
+ path
209
+ }
210
+ published {
211
+ brand {
212
+ key
213
+ }
214
+ path
215
+ }
216
+ }
217
+ }`;
218
+
219
+ export const assetsConnectionByCriteriaQuery = `query assetsConnectionByCriteria(
220
+ $after: ID
221
+ $brand: Brand!
222
+ $categories: [Int!]
223
+ $first: Int!
224
+ $render: Render!
225
+ $types: [AssetType!]!
226
+ ) {
227
+ assetsConnectionByCriteria(
228
+ after: $after
229
+ brand: $brand
230
+ categories: $categories
231
+ first: $first
232
+ render: $render
233
+ types: $types
234
+ ) {
235
+ edges {
236
+ cursor
237
+ node {
238
+ ...AssetFragment
239
+ sponsor {
240
+ name
241
+ }
242
+ }
243
+ }
244
+ error {
245
+ message
246
+ type {
247
+ class
248
+ }
249
+ }
250
+ pageInfo {
251
+ endCursor
252
+ hasNextPage
253
+ }
254
+ }
255
+ }
256
+ fragment AssetFragment on Asset {
257
+ asset {
258
+ about
259
+ byline
260
+ duration
261
+ headlines {
262
+ headline
263
+ }
264
+ live
265
+ }
266
+ assetType
267
+ dates {
268
+ firstPublished
269
+ modified
270
+ published
271
+ }
272
+ id
273
+ featuredImages {
274
+ landscape16x9 {
275
+ ...ImageFragment
276
+ }
277
+ landscape3x2 {
278
+ ...ImageFragment
279
+ }
280
+ portrait2x3 {
281
+ ...ImageFragment
282
+ }
283
+ square1x1 {
284
+ ...ImageFragment
285
+ }
286
+ }
287
+ label
288
+ tags {
289
+ primary: primaryTag {
290
+ ...AssetTag
291
+ }
292
+ secondary {
293
+ ...AssetTag
294
+ }
295
+ }
296
+ urls {
297
+ ...AssetURLs
298
+ }
299
+ }
300
+ fragment AssetTag on AssetTagDetails {
301
+ ...AssetTagAudience
302
+ shortID
303
+ slug
304
+ }
305
+ fragment AssetTagAudience on AssetTagDetails {
306
+ company {
307
+ exchangeCode
308
+ stockCode
309
+ }
310
+ context
311
+ displayName
312
+ id
313
+ name
314
+ urls {
315
+ canonical {
316
+ brand
317
+ path
318
+ }
319
+ published {
320
+ afr {
321
+ path
322
+ }
323
+ }
324
+ }
325
+ }
326
+ fragment AssetURLs on AssetURLs {
327
+ canonical {
328
+ brand
329
+ path
330
+ }
331
+ published {
332
+ afr {
333
+ path
334
+ }
335
+ }
336
+ }
337
+ fragment ImageFragment on Image {
338
+ data {
339
+ altText
340
+ aspect
341
+ autocrop
342
+ caption
343
+ cropWidth
344
+ id
345
+ offsetX
346
+ offsetY
347
+ zoom
348
+ }
349
+ }`;
@@ -0,0 +1,80 @@
1
+ import * as cheerio from 'cheerio';
2
+ import ofetch from '@/utils/ofetch';
3
+
4
+ export const getItem = async (item) => {
5
+ const response = await ofetch(item.link);
6
+ const $ = cheerio.load(response);
7
+
8
+ const reduxState = JSON.parse($('script#__REDUX_STATE__').text().replaceAll(':undefined', ':null').match('__REDUX_STATE__=(.*);')?.[1] || '{}');
9
+
10
+ const content = reduxState.page.content;
11
+ const asset = content.asset;
12
+
13
+ switch (content.assetType) {
14
+ case 'liveArticle':
15
+ item.description = asset.posts.map((post) => `<h2>${post.asset.headlines.headline}</h2>${post.asset.body}`).join('');
16
+ break;
17
+
18
+ case 'article':
19
+ case 'featureArticle':
20
+ item.description = renderArticle(asset, item.link);
21
+ break;
22
+
23
+ default:
24
+ throw new Error(`Unknown asset type: ${content.assetType} in ${item.link}`);
25
+ }
26
+
27
+ return item;
28
+ };
29
+
30
+ const renderArticle = (asset, link: string) => {
31
+ const $ = cheerio.load(asset.body, null, false);
32
+ $('x-placeholder').each((_, el) => {
33
+ const $el = $(el);
34
+ const id = $el.attr('id');
35
+ if (!id) {
36
+ $el.replaceWith('');
37
+ }
38
+
39
+ const placeholder = asset.bodyPlaceholders[id!];
40
+ switch (placeholder?.type) {
41
+ case 'callout':
42
+ case 'relatedStory':
43
+ $el.replaceWith('');
44
+ break;
45
+
46
+ case 'iframe':
47
+ $el.replaceWith(`<iframe src="${placeholder.data.url}" frameborder="0" allowfullscreen></iframe>`);
48
+ break;
49
+
50
+ case 'image':
51
+ $el.replaceWith(`<img src="https://static.ffx.io/images/${placeholder.data.fileName}" alt="${placeholder.data.altText}" />`);
52
+ break;
53
+
54
+ case 'linkArticle':
55
+ $el.replaceWith(placeholder.data.text);
56
+ break;
57
+
58
+ case 'linkExternal':
59
+ $el.replaceWith(`<a href="${placeholder.data.url}" target="_blank" rel="noopener">${placeholder.data.text}</a>`);
60
+ break;
61
+
62
+ case 'quote':
63
+ $el.replaceWith(placeholder.data.markup);
64
+ break;
65
+
66
+ case 'scribd':
67
+ $el.replaceWith(`<a href="${placeholder.data.url}" target="_blank" rel="noopener">View on Scribd</a>`);
68
+ break;
69
+
70
+ case 'twitter':
71
+ $el.replaceWith(`<a href="${placeholder.data.url}">${placeholder.data.url}</a>`);
72
+ break;
73
+
74
+ default:
75
+ throw new Error(`Unknown placeholder type: ${placeholder?.type} in ${link}`);
76
+ }
77
+ });
78
+
79
+ return $.html();
80
+ };
@@ -189,7 +189,7 @@ export const route: Route = {
189
189
  | [法律](https://top.aibase.com/discover/138-139) | [138-139](https://rsshub.app/aibase/discover/138-139) |
190
190
  </details>
191
191
  `,
192
- categories: ['new-media'],
192
+ categories: ['new-media', 'popular'],
193
193
 
194
194
  features: {
195
195
  requireConfig: false,
@@ -58,7 +58,7 @@ export const route: Route = {
58
58
  },
59
59
  example: '/aibase/news',
60
60
  description: '获取 AI 资讯列表',
61
- categories: ['new-media'],
61
+ categories: ['new-media', 'popular'],
62
62
  features: {
63
63
  requireConfig: false,
64
64
  requirePuppeteer: false,
@@ -90,7 +90,7 @@ export const route: Route = {
90
90
  | [娱乐](https://top.aibase.com/topic/%E5%A8%B1%E4%B9%90) | [简历](https://top.aibase.com/topic/%E7%AE%80%E5%8E%86) | [OpenAI](https://top.aibase.com/topic/OpenAI) | [客户服务](https://top.aibase.com/topic/%E5%AE%A2%E6%88%B7%E6%9C%8D%E5%8A%A1) | [室内设计](https://top.aibase.com/topic/%E5%AE%A4%E5%86%85%E8%AE%BE%E8%AE%A1) |
91
91
  </details>
92
92
  `,
93
- categories: ['new-media'],
93
+ categories: ['new-media', 'popular'],
94
94
 
95
95
  features: {
96
96
  requireConfig: false,
@@ -0,0 +1,49 @@
1
+ import { Route } from '@/types';
2
+ import ofetch from '@/utils/ofetch'; // 统一使用的请求库
3
+ import { load } from 'cheerio'; // 类似 jQuery 的 API HTML 解析器
4
+
5
+ export const route: Route = {
6
+ path: '/air/:area',
7
+ radar: [
8
+ {
9
+ source: ['m.air-level.com/air/:area/'],
10
+ target: '/air/:area',
11
+ },
12
+ ],
13
+ parameters: {
14
+ area: '地区',
15
+ },
16
+ name: '空气质量',
17
+ maintainers: ['lifetraveler'],
18
+ example: '/air-level/air/xian',
19
+ handler,
20
+ };
21
+
22
+ async function handler(ctx) {
23
+ const area = ctx.req.param('area');
24
+ const currentUrl = `https://m.air-level.com/air/${area}`;
25
+ const response = await ofetch(currentUrl);
26
+ const $ = load(response);
27
+
28
+ const title = $('body > div.container > div.row.page > div:nth-child(1) > h2').text().replaceAll('[]', '');
29
+
30
+ const table = $('body > div.container > div.row.page > div:nth-child(1) > div:nth-child(3) > table');
31
+
32
+ const qt = $('body > div.container > div.row.page > div:nth-child(1) > div.aqi-dv > div > span.aqi-bg.aqi-level-2').text();
33
+ const pubtime = $('body > div.container > div.row.page > div:nth-child(1) > div.aqi-dv > div > span.label.label-info').text();
34
+
35
+ const items = [
36
+ {
37
+ title: title + ' ' + qt + ' ' + pubtime,
38
+ link: currentUrl,
39
+ description: `<table border="1 solid black">${table.html()}</table>`,
40
+ guid: pubtime,
41
+ },
42
+ ];
43
+ return {
44
+ title,
45
+ item: items,
46
+ description: '订阅每个城市的天气质量',
47
+ link: currentUrl,
48
+ };
49
+ }