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,443 @@
1
+ export interface Feed {
2
+ abstract: string;
3
+ aggr_type: number;
4
+ article_sub_type: number;
5
+ article_type: number;
6
+ article_url: string;
7
+ article_version: number;
8
+ ban_comment: boolean;
9
+ behot_time: number;
10
+ bury_count: number;
11
+ bury_style_show: number;
12
+ cell_ctrls: CellCtrls;
13
+ cell_flag: number;
14
+ cell_layout_style: number;
15
+ /**
16
+ * 0: video
17
+ * 32: text (w)
18
+ * 49: video
19
+ * 60: article
20
+ */
21
+ cell_type: number;
22
+ comment_count: number;
23
+ common_raw_data: string;
24
+ /**
25
+ * Appears only if cell_type is 32
26
+ */
27
+ content: string;
28
+ content_decoration: string;
29
+ control_meta: ControlMeta;
30
+ cursor: number;
31
+ data_type: number;
32
+ digg_count: number;
33
+ display_url: string;
34
+ forum_extra_data: string;
35
+ forward_info: ForwardInfo;
36
+ gallary_image_count: number;
37
+ group_flags: number;
38
+ group_id: string;
39
+ group_source: number;
40
+ group_type: number;
41
+ has_image: boolean;
42
+ has_m3u8_video: boolean;
43
+ has_mp4_video: boolean;
44
+ has_video: boolean;
45
+ hot: number;
46
+ id: string;
47
+ is_original: boolean;
48
+ itemCell: ItemCell;
49
+ itemCellDebug: null;
50
+ item_id: string;
51
+ item_id_str: string;
52
+ item_version: number;
53
+ label_style: number;
54
+ level: number;
55
+ like_count: number;
56
+ log_pb: LogPb;
57
+ lynx_server: LynxServer;
58
+ natant_level: number;
59
+ preload_web: number;
60
+ publish_time: number;
61
+ /**
62
+ * Appears only if cell_type is 32
63
+ */
64
+ rich_content: string;
65
+ read_count: number;
66
+ reback_flag: number;
67
+ repin_count: number;
68
+ repin_time: number;
69
+ req_id: string;
70
+ share_url: string;
71
+ show_more: ShowMore;
72
+ source: string;
73
+ subject_group_id: number;
74
+ tag_id: number;
75
+ tip: number;
76
+ title: string;
77
+ url: string;
78
+ /**
79
+ * Appears only if cell_type is 32, 49(0)
80
+ */
81
+ user: UserInfoCell32 | UserInfoCell49;
82
+ user_bury: number;
83
+ user_digg: number;
84
+ /**
85
+ * Appears only if cell_type is 0, 60
86
+ */
87
+ user_info: UserInfoCell60;
88
+ user_like: number;
89
+ user_repin: number;
90
+ user_repin_time: number;
91
+ /**
92
+ * Appears only if cell_type is 0, 49
93
+ */
94
+ video: Video;
95
+ video_duration: number;
96
+ video_style: number;
97
+ image_list: ImageListItem[];
98
+ large_image_list: LargeImageListItem[];
99
+ middle_image: MiddleImage;
100
+ video_detail_info: VideoDetailInfo;
101
+ }
102
+
103
+ interface CellCtrls {
104
+ cell_flag: number;
105
+ cell_height: number;
106
+ cell_layout_style: number;
107
+ }
108
+
109
+ interface ControlMeta {
110
+ modify: Modify;
111
+ remove: Remove;
112
+ share: Share;
113
+ }
114
+
115
+ interface Modify {
116
+ hide: boolean;
117
+ name: string;
118
+ permission: boolean;
119
+ tips: string;
120
+ }
121
+
122
+ interface Remove {
123
+ hide: boolean;
124
+ name: string;
125
+ permission: boolean;
126
+ tips: string;
127
+ }
128
+
129
+ interface Share {
130
+ hide: boolean;
131
+ name: string;
132
+ permission: boolean;
133
+ tips: string;
134
+ }
135
+
136
+ interface ForwardInfo {
137
+ forward_count: number;
138
+ }
139
+
140
+ interface ItemCell {
141
+ actionCtrl: ActionCtrl;
142
+ articleBase: ArticleBase;
143
+ articleClassification: ArticleClassification;
144
+ cellCtrl: CellCtrl;
145
+ extra: Extra;
146
+ imageList: ImageList;
147
+ itemCounter: ItemCounter;
148
+ locationInfo: LocationInfo;
149
+ shareInfo: ShareInfo;
150
+ tagInfo: TagInfo;
151
+ userInteraction: UserInteraction;
152
+ videoInfo: VideoInfo;
153
+ }
154
+
155
+ interface ActionCtrl {
156
+ actionBar: ActionBar;
157
+ banBury: boolean;
158
+ banComment: boolean;
159
+ banDigg: boolean;
160
+ controlMeta: ActionControlMeta;
161
+ }
162
+
163
+ interface ActionBar {
164
+ actionSettingList: ActionSetting[];
165
+ }
166
+
167
+ interface ActionSetting {
168
+ actionType: number;
169
+ styleSetting: StyleSetting;
170
+ }
171
+
172
+ interface StyleSetting {
173
+ iconKey: string;
174
+ layoutDirection: number;
175
+ text: string;
176
+ }
177
+
178
+ interface ActionControlMeta {
179
+ modify: ActionModify;
180
+ remove: ActionRemove;
181
+ share: ActionShare;
182
+ }
183
+
184
+ interface ActionModify {
185
+ permission: boolean;
186
+ tips: string;
187
+ }
188
+
189
+ interface ActionRemove {
190
+ permission: boolean;
191
+ tips: string;
192
+ }
193
+
194
+ interface ActionShare {
195
+ permission: boolean;
196
+ tips: string;
197
+ }
198
+
199
+ interface ArticleBase {
200
+ gidStr: string;
201
+ itemStatus: number;
202
+ }
203
+
204
+ interface ArticleClassification {
205
+ aggrType: number;
206
+ articleSubType: number;
207
+ articleType: number;
208
+ bizID: number;
209
+ bizTag: number;
210
+ groupSource: number;
211
+ isForAudioPlaylist: boolean;
212
+ isOriginal: boolean;
213
+ isSubject: boolean;
214
+ level: number;
215
+ }
216
+
217
+ interface CellCtrl {
218
+ buryStyleShow: number;
219
+ cellFlag: number;
220
+ cellLayoutStyle: number;
221
+ cellType: number;
222
+ cellUIType: string;
223
+ groupFlags: number;
224
+ }
225
+
226
+ interface Extra {
227
+ ping: string;
228
+ }
229
+
230
+ type ImageList = unknown;
231
+
232
+ interface ItemCounter {
233
+ commentCount: number;
234
+ diggCount: number;
235
+ forwardCount: number;
236
+ readCount: number;
237
+ repinCount: number;
238
+ shareCount: number;
239
+ showCount: number;
240
+ textCount: number;
241
+ videoWatchCount: number;
242
+ buryCount: number;
243
+ }
244
+
245
+ interface LocationInfo {
246
+ publishLocInfo: string;
247
+ }
248
+
249
+ interface ShareInfo {
250
+ shareURL: string;
251
+ shareControl: ShareControl;
252
+ }
253
+
254
+ interface ShareControl {
255
+ isHighQuality: boolean;
256
+ }
257
+
258
+ type TagInfo = unknown;
259
+
260
+ interface UserInteraction {
261
+ userDigg: boolean;
262
+ userRepin: boolean;
263
+ }
264
+
265
+ type VideoInfo = unknown;
266
+
267
+ interface Video {
268
+ bitrate: number;
269
+ codec_type: string;
270
+ definition: string;
271
+ download_addr: DownloadAddr;
272
+ duration: number;
273
+ encode_user_tag: string;
274
+ file_hash: string;
275
+ height: number;
276
+ origin_cover: OriginCover;
277
+ play_addr: PlayAddr;
278
+ play_addr_list: PlayAddrListItem[];
279
+ ratio: string;
280
+ size: number;
281
+ url_expire: number;
282
+ video_id: string;
283
+ volume: Volume;
284
+ vtype: string;
285
+ width: number;
286
+ }
287
+
288
+ interface DownloadAddr {
289
+ uri: string;
290
+ url_list: string[];
291
+ }
292
+
293
+ interface OriginCover {
294
+ uri: string;
295
+ url_list: string[];
296
+ }
297
+
298
+ interface PlayAddr {
299
+ uri: string;
300
+ url_list: string[];
301
+ }
302
+
303
+ interface PlayAddrListItem {
304
+ bitrate: number;
305
+ codec_type: string;
306
+ definition: string;
307
+ encode_user_tag: string;
308
+ file_hash: string;
309
+ play_url_list: string[];
310
+ quality: string;
311
+ size: number;
312
+ url_expire: number;
313
+ video_quality: number;
314
+ volume: Volume;
315
+ vtype: string;
316
+ }
317
+
318
+ interface Volume {
319
+ Loudness: number;
320
+ Peak: number;
321
+ }
322
+
323
+ interface LogPb {
324
+ cell_layout_style: string;
325
+ group_id_str: string;
326
+ group_source: string;
327
+ impr_id: string;
328
+ is_following: string;
329
+ is_yaowen: string;
330
+ }
331
+
332
+ type LynxServer = unknown;
333
+
334
+ interface ShowMore {
335
+ title: string;
336
+ url: string;
337
+ }
338
+
339
+ interface UserInfoCell32 {
340
+ avatar_url: string;
341
+ desc: string;
342
+ id: number;
343
+ is_blocked: number;
344
+ is_blocking: number;
345
+ is_followed: number;
346
+ is_following: number;
347
+ is_friend: number;
348
+ live_info_type: number;
349
+ medals: unknown;
350
+ name: string;
351
+ remark_name: string;
352
+ schema: string;
353
+ screen_name: string;
354
+ theme_day: string;
355
+ user_auth_info: string;
356
+ user_decoration: string;
357
+ user_id: string;
358
+ user_verified: number;
359
+ verified_content: string;
360
+ }
361
+
362
+ interface UserInfoCell49 {
363
+ info: {
364
+ avatar_uri: string;
365
+ avatar_url: string;
366
+ ban_status: boolean;
367
+ desc: string;
368
+ media_id: string;
369
+ name: string;
370
+ origin_profile_url: boolean;
371
+ origin_user_id: string;
372
+ schema: string;
373
+ user_auth_info: string;
374
+ user_id: string;
375
+ user_verified: number;
376
+ verified_content: string;
377
+ };
378
+ relation: {
379
+ is_followed: number;
380
+ is_following: number;
381
+ is_friend: number;
382
+ };
383
+ relation_count: {
384
+ followers_count: number;
385
+ following_count: number;
386
+ };
387
+ user_id: string;
388
+ }
389
+
390
+ interface UserInfoCell60 {
391
+ avatar_url: string;
392
+ description: string;
393
+ follow: boolean;
394
+ name: string;
395
+ user_auth_info: string;
396
+ user_id: string;
397
+ user_verified: boolean;
398
+ verified_content: string;
399
+ }
400
+
401
+ interface ImageListItem {
402
+ height: number;
403
+ uri: string;
404
+ url: string;
405
+ url_list: UrlList[];
406
+ width: number;
407
+ }
408
+
409
+ interface UrlList {
410
+ url: string;
411
+ }
412
+
413
+ interface LargeImageListItem {
414
+ height: number;
415
+ uri: string;
416
+ url: string;
417
+ url_list: UrlList[];
418
+ width: number;
419
+ }
420
+
421
+ interface MiddleImage {
422
+ height: number;
423
+ uri: string;
424
+ url: string;
425
+ url_list: UrlList[];
426
+ width: number;
427
+ }
428
+
429
+ interface VideoDetailInfo {
430
+ detail_video_large_image: DetailVideoLargeImage;
431
+ direct_play: number;
432
+ group_flags: number;
433
+ show_pgc_subscribe: number;
434
+ video_id: string;
435
+ }
436
+
437
+ interface DetailVideoLargeImage {
438
+ height: number;
439
+ uri: string;
440
+ url: string;
441
+ url_list: UrlList[];
442
+ width: number;
443
+ }
@@ -0,0 +1,127 @@
1
+ import { Route } from '@/types';
2
+ import cache from '@/utils/cache';
3
+ import ofetch from '@/utils/ofetch';
4
+ import { parseDate } from '@/utils/parse-date';
5
+ import randUserAgent from '@/utils/rand-user-agent';
6
+ import { generate_a_bogus } from './a-bogus';
7
+ import { Feed } from './types';
8
+ import RejectError from '@/errors/types/reject';
9
+ import { config } from '@/config';
10
+ import path from 'node:path';
11
+ import { getCurrentPath } from '@/utils/helpers';
12
+ import { art } from '@/utils/render';
13
+
14
+ const __dirname = getCurrentPath(import.meta.url);
15
+
16
+ export const route: Route = {
17
+ path: '/user/token/:token',
18
+ categories: ['new-media'],
19
+ example: '/toutiao/user/token/MS4wLjABAAAAEmbqJP2CmC8XXv1BpMvQ3sQHKAxFsq8wHxj8XVIQWja6tMcB-QEbFkzkRNgMl12M',
20
+ parameters: { token: '用户 token,可在用户主页 URL 找到' },
21
+ features: {
22
+ antiCrawler: true,
23
+ },
24
+ radar: [
25
+ {
26
+ source: ['www.toutiao.com/c/user/token/:token'],
27
+ },
28
+ ],
29
+ name: '头条主页',
30
+ maintainers: ['TonyRL'],
31
+ handler,
32
+ };
33
+
34
+ async function handler(ctx) {
35
+ const { token } = ctx.req.param();
36
+ const ua = randUserAgent({ browser: 'chrome', os: 'windows', device: 'desktop' });
37
+
38
+ const feed = (await cache.tryGet(
39
+ `toutiao:user:${token}`,
40
+ async () => {
41
+ const query = `category=profile_all&token=${token}&max_behot_time=0&entrance_gid&aid=24&app_name=toutiao_web`;
42
+
43
+ const data = await ofetch(`https://www.toutiao.com/api/pc/list/feed?${query}&a_bogus=${generate_a_bogus(query, ua)}`, {
44
+ headers: {
45
+ 'User-Agent': ua,
46
+ },
47
+ });
48
+
49
+ return data.data;
50
+ },
51
+ config.cache.routeExpire,
52
+ false
53
+ )) as Feed[];
54
+
55
+ if (!feed) {
56
+ throw new RejectError('无法获取用户信息');
57
+ }
58
+
59
+ const items = feed.map((item) => {
60
+ switch (item.cell_type) {
61
+ case 0:
62
+ case 49: {
63
+ const video = item.video.play_addr_list.sort((a, b) => b.bitrate - a.bitrate)[0];
64
+ return {
65
+ title: item.title,
66
+ description: art(path.join(__dirname, 'templates', 'video.art'), {
67
+ poster: item.video.origin_cover.url_list[0],
68
+ url: item.video.play_addr_list.sort((a, b) => b.bitrate - a.bitrate)[0].play_url_list[0],
69
+ }),
70
+ link: `https://www.toutiao.com/video/${item.id}/`,
71
+ pubDate: parseDate(item.publish_time, 'X'),
72
+ author: item.user?.info.name ?? item.source,
73
+ enclosure_url: video?.play_url_list[0],
74
+ enclosure_type: video?.play_url_list[0] ? 'video/mp4' : undefined,
75
+ user: {
76
+ name: item.user?.info.name,
77
+ avatar: item.user?.info.avatar_url,
78
+ description: item.user?.info.desc,
79
+ },
80
+ };
81
+ }
82
+
83
+ // text w/o title
84
+ case 32: {
85
+ const enclosure = item.large_image_list?.pop();
86
+ return {
87
+ title: item.content?.split('\n')[0],
88
+ description: item.rich_content,
89
+ link: `https://www.toutiao.com/w/${item.id}/`,
90
+ pubDate: parseDate(item.publish_time, 'X'),
91
+ author: item.user?.name,
92
+ enclosure_url: enclosure?.url,
93
+ enclosure_type: enclosure?.url ? `image/${new URL(enclosure.url).pathname.split('.').pop()}` : undefined,
94
+ user: {
95
+ name: item.user?.name,
96
+ avatar: item.user?.avatar_url,
97
+ description: item.user?.desc,
98
+ },
99
+ };
100
+ }
101
+
102
+ // text w/ title
103
+ case 60:
104
+ default:
105
+ return {
106
+ title: item.title,
107
+ description: item.abstract,
108
+ link: `https://www.toutiao.com/article/${item.id}/`,
109
+ pubDate: parseDate(item.publish_time, 'X'),
110
+ author: item.user_info?.name,
111
+ user: {
112
+ name: item.user_info?.name,
113
+ avatar: item.user_info?.avatar_url,
114
+ description: item.user_info?.description,
115
+ },
116
+ };
117
+ }
118
+ });
119
+
120
+ return {
121
+ title: `${items[0].user.name}的头条主页 - 今日头条(www.toutiao.com)`,
122
+ description: items[0].user.description,
123
+ link: `https://www.toutiao.com/c/user/token/${token}/`,
124
+ image: items[0].user.avatar,
125
+ item: items,
126
+ };
127
+ }
@@ -160,6 +160,14 @@ function gatherLegacyFromData(entries, filterNested, userId) {
160
160
  t.legacy.quoted_status = quote.legacy;
161
161
  t.legacy.quoted_status.user = quote.core.user_result?.result?.legacy || quote.core.user_results?.result?.legacy;
162
162
  }
163
+ if (t.note_tweet) {
164
+ const tmp = t.note_tweet.note_tweet_results.result;
165
+ t.legacy.entities.hashtags = tmp.entity_set.hashtags;
166
+ t.legacy.entities.symbols = tmp.entity_set.symbols;
167
+ t.legacy.entities.urls = tmp.entity_set.urls;
168
+ t.legacy.entities.user_mentions = tmp.entity_set.user_mentions;
169
+ t.legacy.full_text = tmp.text;
170
+ }
163
171
  }
164
172
  const legacy = tweet.legacy;
165
173
  if (legacy) {
@@ -14,11 +14,12 @@ import login from './login';
14
14
  let authTokenIndex = 0;
15
15
 
16
16
  const token2Cookie = async (token) => {
17
- if (cache.get(`twitter:cookie:${token}`)) {
18
- return cache.get(`twitter:cookie:${token}`);
17
+ const c = await cache.get(`twitter:cookie:${token}`);
18
+ if (c) {
19
+ return c;
19
20
  }
20
21
  const jar = new CookieJar();
21
- jar.setCookieSync(`auth_token=${token}`, 'https://x.com');
22
+ await jar.setCookie(`auth_token=${token}`, 'https://x.com');
22
23
  try {
23
24
  const agent = proxy.proxyUri
24
25
  ? new ProxyAgent({
@@ -56,6 +57,7 @@ const getAuth = async (retry: number) => {
56
57
  const token = config.twitter.authToken[index];
57
58
  const lock = await cache.get(`${lockPrefix}${token}`, false);
58
59
  if (lock) {
60
+ logger.debug(`twitter debug: twitter cookie for token ${token} is locked, retry: ${retry}`);
59
61
  await new Promise((resolve) => setTimeout(resolve, Math.random() * 500 + 500));
60
62
  return await getAuth(retry - 1);
61
63
  } else {
@@ -160,13 +162,15 @@ export const twitterGot = async (
160
162
  const remaining = response.headers.get('x-rate-limit-remaining');
161
163
  const remainingInt = Number.parseInt(remaining || '0');
162
164
  const reset = response.headers.get('x-rate-limit-reset');
163
- logger.debug(`twitter debug: twitter rate limit remaining for token ${auth?.token} is ${remaining} and reset at ${reset}`);
165
+ logger.debug(
166
+ `twitter debug: twitter rate limit remaining for token ${auth?.token} is ${remaining} and reset at ${reset}, auth: ${JSON.stringify(auth)}, status: ${response.status}, data: ${JSON.stringify(response._data?.data)}, cookie: ${JSON.stringify(dispatchers?.jar.serializeSync())}`
167
+ );
164
168
  if (auth) {
165
169
  if (remaining && remainingInt < 2 && reset) {
166
170
  const resetTime = new Date(Number.parseInt(reset) * 1000);
167
171
  const delay = (resetTime.getTime() - Date.now()) / 1000;
168
172
  logger.debug(`twitter debug: twitter rate limit exceeded for token ${auth.token} with status ${response.status}, will unlock after ${delay}s`);
169
- await cache.set(`${lockPrefix}${auth.token}`, '1', Math.ceil(delay));
173
+ await cache.set(`${lockPrefix}${auth.token}`, '1', Math.ceil(delay) * 2);
170
174
  } else if (response.status === 429 || JSON.stringify(response._data?.data) === '{"user":{}}') {
171
175
  logger.debug(`twitter debug: twitter rate limit exceeded for token ${auth.token} with status ${response.status}`);
172
176
  await cache.set(`${lockPrefix}${auth.token}`, '1', 2000);
@@ -209,10 +213,10 @@ export const twitterGot = async (
209
213
  },
210
214
  });
211
215
 
212
- // if (auth?.token) {
213
- // logger.debug(`twitter debug: update twitter cookie for token ${auth.token}`);
214
- // await cache.set(`twitter:cookie:${auth.token}`, JSON.stringify(dispatchers?.jar.serializeSync()), config.cache.contentExpire);
215
- // }
216
+ if (auth?.token) {
217
+ logger.debug(`twitter debug: update twitter cookie for token ${auth.token}`);
218
+ await cache.set(`twitter:cookie:${auth.token}`, JSON.stringify(dispatchers?.jar.serializeSync()), config.cache.contentExpire);
219
+ }
216
220
 
217
221
  return response._data;
218
222
  };
@@ -282,6 +286,14 @@ export function gatherLegacyFromData(entries: any[], filterNested?: string[], us
282
286
  t.legacy.quoted_status = quote.legacy;
283
287
  t.legacy.quoted_status.user = quote.core.user_result?.result?.legacy || quote.core.user_results?.result?.legacy;
284
288
  }
289
+ if (t.note_tweet) {
290
+ const tmp = t.note_tweet.note_tweet_results.result;
291
+ t.legacy.entities.hashtags = tmp.entity_set.hashtags;
292
+ t.legacy.entities.symbols = tmp.entity_set.symbols;
293
+ t.legacy.entities.urls = tmp.entity_set.urls;
294
+ t.legacy.entities.user_mentions = tmp.entity_set.user_mentions;
295
+ t.legacy.full_text = tmp.text;
296
+ }
285
297
  }
286
298
  const legacy = tweet.legacy;
287
299
  if (legacy) {
@@ -10,6 +10,7 @@ export const namespace: Namespace = {
10
10
  | \`readable\` | Enable readable layout | \`0\`/\`1\`/\`true\`/\`false\` | \`false\` |
11
11
  | \`authorNameBold\` | Display author name in bold | \`0\`/\`1\`/\`true\`/\`false\` | \`false\` |
12
12
  | \`showAuthorInTitle\` | Show author name in title | \`0\`/\`1\`/\`true\`/\`false\` | \`false\` (\`true\` in \`/twitter/followings\`) |
13
+ | \`showAuthorAsTitleOnly\` | Show only author name as title | \`0\`/\`1\`/\`true\`/\`false\` | \`false\` |
13
14
  | \`showAuthorInDesc\` | Show author name in description (RSS body) | \`0\`/\`1\`/\`true\`/\`false\` | \`false\` (\`true\` in \`/twitter/followings\`) |
14
15
  | \`showQuotedAuthorAvatarInDesc\` | Show avatar of quoted Tweet's author in description (RSS body) (Not recommended if your RSS reader extracts images from description) | \`0\`/\`1\`/\`true\`/\`false\` | \`false\` |
15
16
  | \`showAuthorAvatarInDesc\` | Show avatar of author in description (RSS body) (Not recommended if your RSS reader extracts images from description) | \`0\`/\`1\`/\`true\`/\`false\` | \`false\` |
@@ -35,7 +35,7 @@ const formatText = (item) => {
35
35
  const urls = item.entities.urls || [];
36
36
  for (const url of urls) {
37
37
  // trim link pointing to the tweet itself (usually appears when the tweet is truncated)
38
- text = text.replaceAll(url.url, url.expanded_url.endsWith(id_str) ? '' : url.expanded_url);
38
+ text = text.replaceAll(url.url, url.expanded_url?.endsWith(id_str) ? '' : url.expanded_url);
39
39
  }
40
40
  const media = item.extended_entities?.media || [];
41
41
  for (const m of media) {
@@ -52,6 +52,7 @@ const ProcessFeed = (ctx, { data = [] }, params = {}) => {
52
52
  readable: fallback(params.readable, queryToBoolean(routeParams.get('readable')), false),
53
53
  authorNameBold: fallback(params.authorNameBold, queryToBoolean(routeParams.get('authorNameBold')), false),
54
54
  showAuthorInTitle: fallback(params.showAuthorInTitle, queryToBoolean(routeParams.get('showAuthorInTitle')), false),
55
+ showAuthorAsTitleOnly: fallback(params.showAuthorAsTitleOnly, queryToBoolean(routeParams.get('showAuthorAsTitleOnly')), false),
55
56
  showAuthorInDesc: fallback(params.showAuthorInDesc, queryToBoolean(routeParams.get('showAuthorInDesc')), false),
56
57
  showQuotedAuthorAvatarInDesc: fallback(params.showQuotedAuthorAvatarInDesc, queryToBoolean(routeParams.get('showQuotedAuthorAvatarInDesc')), false),
57
58
  showAuthorAvatarInDesc: fallback(params.showAuthorAvatarInDesc, queryToBoolean(routeParams.get('showAuthorAvatarInDesc')), false),
@@ -74,6 +75,7 @@ const ProcessFeed = (ctx, { data = [] }, params = {}) => {
74
75
  readable,
75
76
  authorNameBold,
76
77
  showAuthorInTitle,
78
+ showAuthorAsTitleOnly,
77
79
  showAuthorInDesc,
78
80
  showQuotedAuthorAvatarInDesc,
79
81
  showAuthorAvatarInDesc,
@@ -292,6 +294,10 @@ const ProcessFeed = (ctx, { data = [] }, params = {}) => {
292
294
  title += quoteInTitle;
293
295
  }
294
296
 
297
+ if (showAuthorAsTitleOnly) {
298
+ title = originalItem.user.name;
299
+ }
300
+
295
301
  // Make description
296
302
  let description = '';
297
303
  if (showAuthorInDesc && showAuthorAvatarInDesc) {