rsshub 1.0.0-master.fc5a2f6 → 1.0.0-master.fc648b5

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 (292) hide show
  1. package/lib/config.js +4 -0
  2. package/lib/middleware/anti-hotlink.js +90 -22
  3. package/lib/middleware/parameter.js +65 -32
  4. package/lib/middleware/templates/iframe.art +14 -0
  5. package/lib/radar-rules.js +0 -92
  6. package/lib/router.js +22 -22
  7. package/lib/routes/agefans/update.js +1 -1
  8. package/lib/routes/novel/biqugeinfo.js +2 -2
  9. package/lib/routes/universities/uestc/sice.js +12 -33
  10. package/lib/routes/weibo/user.js +10 -19
  11. package/lib/v2/19lou/index.js +74 -0
  12. package/lib/v2/19lou/maintainer.js +3 -0
  13. package/lib/v2/19lou/radar.js +29 -0
  14. package/lib/v2/19lou/router.js +3 -0
  15. package/lib/v2/36kr/router.js +1 -1
  16. package/lib/v2/36kr/user.js +47 -22
  17. package/lib/v2/acfun/article.js +100 -0
  18. package/lib/{routes → v2}/acfun/bangumi.js +7 -7
  19. package/lib/v2/acfun/maintainer.js +5 -0
  20. package/lib/v2/acfun/radar.js +25 -0
  21. package/lib/v2/acfun/router.js +5 -0
  22. package/lib/v2/acfun/video.js +45 -0
  23. package/lib/v2/agora0/index.js +54 -0
  24. package/lib/v2/agora0/maintainer.js +3 -0
  25. package/lib/v2/agora0/radar.js +13 -0
  26. package/lib/v2/agora0/router.js +3 -0
  27. package/lib/v2/apnews/maintainer.js +3 -0
  28. package/lib/v2/apnews/radar.js +13 -0
  29. package/lib/v2/apnews/router.js +3 -0
  30. package/lib/v2/apnews/templates/description.art +14 -0
  31. package/lib/v2/apnews/topics.js +44 -0
  32. package/lib/v2/appleinsider/index.js +59 -0
  33. package/lib/v2/appleinsider/maintainer.js +3 -0
  34. package/lib/v2/appleinsider/radar.js +13 -0
  35. package/lib/v2/appleinsider/router.js +3 -0
  36. package/lib/v2/cbnweek/index.js +46 -0
  37. package/lib/v2/cbnweek/maintainer.js +3 -0
  38. package/lib/v2/cbnweek/radar.js +13 -0
  39. package/lib/v2/cbnweek/router.js +3 -0
  40. package/lib/v2/ccac/news.js +12 -3
  41. package/lib/v2/cde/index.js +2 -2
  42. package/lib/v2/cde/maintainer.js +1 -0
  43. package/lib/v2/cde/radar.js +22 -4
  44. package/lib/v2/cde/router.js +1 -0
  45. package/lib/v2/cde/templates/xxgk/breakthroughCure.art +18 -0
  46. package/lib/v2/cde/templates/xxgk/cliniCal.art +16 -0
  47. package/lib/v2/cde/templates/xxgk/priorityApproval.art +18 -0
  48. package/lib/v2/cde/utils.js +2 -2
  49. package/lib/v2/cde/xxgk.js +73 -0
  50. package/lib/v2/chinadegrees/maintainer.js +3 -0
  51. package/lib/v2/chinadegrees/province.js +66 -0
  52. package/lib/v2/chinadegrees/radar.js +13 -0
  53. package/lib/v2/chinadegrees/router.js +3 -0
  54. package/lib/v2/chinadegrees/templates/description.art +4 -0
  55. package/lib/v2/cnjxol/index.js +94 -0
  56. package/lib/v2/cnjxol/maintainer.js +4 -0
  57. package/lib/v2/cnjxol/radar.js +19 -0
  58. package/lib/v2/cnjxol/router.js +3 -0
  59. package/lib/v2/cnjxol/templates/description.art +2 -0
  60. package/lib/v2/cscse/maintainer.js +3 -0
  61. package/lib/v2/cscse/radar.js +13 -0
  62. package/lib/v2/cscse/router.js +3 -0
  63. package/lib/v2/cscse/tzgg.js +54 -0
  64. package/lib/v2/dgjyw/index.js +67 -0
  65. package/lib/v2/dgjyw/maintainer.js +3 -0
  66. package/lib/v2/dgjyw/radar.js +13 -0
  67. package/lib/v2/dgjyw/router.js +3 -0
  68. package/lib/v2/domp4/detail.js +67 -0
  69. package/lib/v2/domp4/latest.js +31 -0
  70. package/lib/v2/domp4/maintainer.js +4 -0
  71. package/lib/v2/domp4/radar.js +25 -0
  72. package/lib/v2/domp4/router.js +4 -0
  73. package/lib/v2/domp4/utils.js +72 -0
  74. package/lib/v2/douyin/hashtag.js +5 -43
  75. package/lib/v2/douyin/live.js +68 -0
  76. package/lib/v2/douyin/maintainer.js +2 -0
  77. package/lib/v2/douyin/radar.js +8 -0
  78. package/lib/v2/douyin/router.js +1 -0
  79. package/lib/v2/douyin/user.js +5 -43
  80. package/lib/v2/douyin/utils.js +50 -0
  81. package/lib/v2/economist/full.js +6 -4
  82. package/lib/v2/elsevier/issue.js +62 -0
  83. package/lib/v2/elsevier/journal.js +72 -0
  84. package/lib/v2/elsevier/maintainer.js +2 -2
  85. package/lib/v2/elsevier/radar.js +5 -5
  86. package/lib/v2/elsevier/router.js +4 -2
  87. package/lib/v2/elsevier/templates/description.art +5 -5
  88. package/lib/v2/gov/beijing/jw/tzgg.js +58 -0
  89. package/lib/v2/gov/customs/list.js +21 -17
  90. package/lib/v2/gov/customs/utils.js +9 -5
  91. package/lib/v2/gov/maintainer.js +3 -0
  92. package/lib/v2/gov/nmpa/generic.js +76 -0
  93. package/lib/v2/gov/pbc/goutongjiaoliu.js +20 -15
  94. package/lib/v2/gov/pbc/tradeAnnouncement.js +18 -14
  95. package/lib/v2/gov/radar.js +57 -27
  96. package/lib/v2/gov/router.js +3 -0
  97. package/lib/v2/gov/xuzhou/hrss.js +54 -0
  98. package/lib/v2/hackertalk/index.js +23 -0
  99. package/lib/v2/hackertalk/maintainer.js +3 -0
  100. package/lib/v2/hackertalk/radar.js +13 -0
  101. package/lib/v2/hackertalk/router.js +3 -0
  102. package/lib/v2/hashnode/blog.js +62 -0
  103. package/lib/v2/hashnode/maintainer.js +3 -0
  104. package/lib/v2/hashnode/radar.js +13 -0
  105. package/lib/v2/hashnode/router.js +3 -0
  106. package/lib/v2/hashnode/templates/description.art +2 -0
  107. package/lib/v2/hdu/cs/{index.js → notice.js} +1 -4
  108. package/lib/v2/hdu/cs/pg.js +54 -0
  109. package/lib/v2/hdu/maintainer.js +1 -0
  110. package/lib/v2/hdu/radar.js +6 -0
  111. package/lib/v2/hdu/router.js +2 -1
  112. package/lib/v2/heu/gx/list.js +2 -2
  113. package/lib/v2/heu/job/list.js +2 -2
  114. package/lib/v2/heu/uae/list.js +2 -2
  115. package/lib/v2/heu/yjsy/list.js +2 -2
  116. package/lib/v2/hk01/channel.js +40 -0
  117. package/lib/{routes → v2}/hk01/hot.js +2 -1
  118. package/lib/v2/hk01/issue.js +41 -0
  119. package/lib/v2/hk01/maintainer.js +7 -0
  120. package/lib/v2/hk01/radar.js +37 -0
  121. package/lib/v2/hk01/router.js +7 -0
  122. package/lib/{routes → v2}/hk01/tag.js +2 -1
  123. package/lib/{routes → v2}/hk01/zone.js +3 -2
  124. package/lib/v2/hotukdeals/index.js +1 -1
  125. package/lib/v2/ieee/journal.js +78 -0
  126. package/lib/v2/ieee/maintainer.js +2 -2
  127. package/lib/v2/ieee/radar.js +4 -4
  128. package/lib/v2/ieee/{latestdate.js → recent.js} +34 -42
  129. package/lib/v2/ieee/router.js +4 -2
  130. package/lib/v2/ieee/templates/description.art +5 -5
  131. package/lib/v2/ielts/index.js +7 -2
  132. package/lib/v2/keep/maintainer.js +3 -0
  133. package/lib/v2/keep/radar.js +13 -0
  134. package/lib/v2/keep/router.js +3 -0
  135. package/lib/v2/keep/templates/user.art +16 -0
  136. package/lib/{routes → v2}/keep/user.js +14 -4
  137. package/lib/v2/mdpi/journal.js +65 -0
  138. package/lib/v2/mdpi/maintainer.js +3 -0
  139. package/lib/v2/mdpi/radar.js +13 -0
  140. package/lib/v2/mdpi/router.js +3 -0
  141. package/lib/v2/mdpi/templates/description.art +12 -0
  142. package/lib/v2/mindmeister/example.js +44 -0
  143. package/lib/v2/mindmeister/maintainer.js +3 -0
  144. package/lib/v2/mindmeister/radar.js +13 -0
  145. package/lib/v2/mindmeister/router.js +3 -0
  146. package/lib/v2/mindmeister/templates/image.art +1 -0
  147. package/lib/v2/mirror/index.js +34 -0
  148. package/lib/v2/mirror/maintainer.js +3 -0
  149. package/lib/v2/mirror/radar.js +17 -0
  150. package/lib/v2/mirror/router.js +3 -0
  151. package/lib/v2/nbd/radar.js +2 -2
  152. package/lib/v2/ncwu/maintainer.js +3 -0
  153. package/lib/v2/ncwu/notice.js +27 -0
  154. package/lib/v2/ncwu/radar.js +13 -0
  155. package/lib/v2/ncwu/router.js +3 -0
  156. package/lib/v2/netease/exclusive.js +148 -0
  157. package/lib/v2/netease/maintainer.js +1 -0
  158. package/lib/v2/netease/radar.js +8 -0
  159. package/lib/v2/netease/router.js +1 -0
  160. package/lib/v2/netease/templates/exclusive.art +11 -0
  161. package/lib/v2/nju/rczp.js +34 -24
  162. package/lib/v2/njust/utils.js +4 -0
  163. package/lib/v2/nuaa/utils/pypasswaf.js +4 -5
  164. package/lib/v2/nyaa/maintainer.js +4 -0
  165. package/lib/v2/nyaa/radar.js +32 -0
  166. package/lib/v2/nyaa/router.js +4 -0
  167. package/lib/{routes → v2}/nyaa/search.js +4 -2
  168. package/lib/v2/nytimes/daily_briefing_chinese.js +47 -41
  169. package/lib/v2/nytimes/index.js +3 -3
  170. package/lib/v2/nytimes/maintainer.js +1 -1
  171. package/lib/v2/nytimes/templates/image.art +3 -0
  172. package/lib/v2/nytimes/utils.js +7 -1
  173. package/lib/v2/oceanengine/arithmeticIndex.js +145 -0
  174. package/lib/v2/oceanengine/maintainer.js +3 -0
  175. package/lib/v2/oceanengine/radar.js +13 -0
  176. package/lib/v2/oceanengine/router.js +3 -0
  177. package/lib/v2/oceanengine/templates/content.art +14 -0
  178. package/lib/v2/openwrt/maintainer.js +3 -0
  179. package/lib/v2/openwrt/radar.js +13 -0
  180. package/lib/v2/openwrt/releases.js +25 -0
  181. package/lib/v2/openwrt/router.js +3 -0
  182. package/lib/v2/pincong/utils.js +7 -1
  183. package/lib/v2/pku/maintainer.js +3 -0
  184. package/lib/v2/pku/radar.js +20 -0
  185. package/lib/v2/pku/router.js +3 -0
  186. package/lib/v2/pku/ss/admission.js +53 -0
  187. package/lib/v2/pku/ss/notice.js +53 -0
  188. package/lib/v2/pku/ss/pg_admin.js +53 -0
  189. package/lib/v2/prestige-av/maintainer.js +3 -0
  190. package/lib/v2/prestige-av/radar.js +18 -0
  191. package/lib/v2/prestige-av/router.js +3 -0
  192. package/lib/{routes → v2}/prestige-av/series.js +8 -5
  193. package/lib/v2/qq/kg/cache.js +28 -0
  194. package/lib/v2/qq/kg/reply.js +21 -0
  195. package/lib/v2/qq/kg/user.js +50 -0
  196. package/lib/v2/qq/maintainer.js +2 -0
  197. package/lib/v2/qq/radar.js +14 -0
  198. package/lib/v2/qq/router.js +2 -0
  199. package/lib/v2/samsung/maintainer.js +3 -0
  200. package/lib/v2/samsung/radar.js +13 -0
  201. package/lib/v2/samsung/research/blog.js +49 -0
  202. package/lib/v2/samsung/router.js +3 -0
  203. package/lib/v2/{jasa/latest.js → scitation/journal.js} +24 -27
  204. package/lib/v2/scitation/maintainer.js +4 -0
  205. package/lib/v2/scitation/radar.js +19 -0
  206. package/lib/v2/scitation/router.js +4 -0
  207. package/lib/v2/scitation/section.js +90 -0
  208. package/lib/v2/scitation/templates/description.art +11 -0
  209. package/lib/v2/shuiguopai/index.js +76 -0
  210. package/lib/v2/shuiguopai/maintainer.js +3 -0
  211. package/lib/v2/shuiguopai/radar.js +13 -0
  212. package/lib/v2/shuiguopai/router.js +3 -0
  213. package/lib/v2/shuiguopai/templates/description.art +6 -0
  214. package/lib/v2/springer/journal.js +72 -0
  215. package/lib/v2/springer/maintainer.js +3 -0
  216. package/lib/v2/springer/radar.js +13 -0
  217. package/lib/v2/springer/router.js +3 -0
  218. package/lib/v2/springer/templates/description.art +12 -0
  219. package/lib/v2/supchina/index.js +67 -0
  220. package/lib/v2/supchina/maintainer.js +4 -0
  221. package/lib/v2/supchina/podcasts.js +66 -0
  222. package/lib/v2/supchina/radar.js +19 -0
  223. package/lib/v2/supchina/router.js +4 -0
  224. package/lib/v2/techflow520/index.js +34 -0
  225. package/lib/v2/techflow520/maintainer.js +4 -0
  226. package/lib/v2/techflow520/newsflash.js +32 -0
  227. package/lib/v2/techflow520/radar.js +19 -0
  228. package/lib/v2/techflow520/router.js +4 -0
  229. package/lib/v2/tencent/cloud/column.js +51 -0
  230. package/lib/v2/tencent/maintainer.js +1 -0
  231. package/lib/v2/tencent/radar.js +11 -0
  232. package/lib/v2/tencent/router.js +1 -0
  233. package/lib/v2/test/index.js +16 -1
  234. package/lib/v2/tiktok/user.js +28 -38
  235. package/lib/v2/trending/allTrending.js +169 -0
  236. package/lib/v2/trending/maintainer.js +3 -0
  237. package/lib/v2/trending/radar.js +35 -0
  238. package/lib/v2/trending/router.js +3 -0
  239. package/lib/v2/trending/templates/content.art +24 -0
  240. package/lib/v2/u3c3/index.js +59 -0
  241. package/lib/v2/u3c3/maintainer.js +3 -0
  242. package/lib/v2/u3c3/radar.js +29 -0
  243. package/lib/v2/u3c3/router.js +3 -0
  244. package/lib/v2/uraaka-joshi/uraaka-joshi-user.js +7 -1
  245. package/lib/v2/uraaka-joshi/uraaka-joshi.js +8 -1
  246. package/lib/v2/vlive/index.js +71 -0
  247. package/lib/v2/vlive/maintainer.js +3 -0
  248. package/lib/v2/vlive/radar.js +13 -0
  249. package/lib/v2/vlive/router.js +3 -0
  250. package/lib/v2/vlive/templates/post.art +8 -0
  251. package/lib/v2/vlive/templates/video.art +3 -0
  252. package/lib/v2/xiaohongshu/util.js +6 -6
  253. package/lib/v2/xjtu/2yuan/news.js +61 -0
  254. package/lib/v2/xjtu/dean.js +83 -0
  255. package/lib/{routes/universities → v2}/xjtu/ee.js +5 -5
  256. package/lib/{routes/universities → v2}/xjtu/gs/tzgg.js +6 -6
  257. package/lib/v2/xjtu/international.js +51 -0
  258. package/lib/v2/xjtu/job.js +81 -0
  259. package/lib/v2/xjtu/maintainer.js +9 -0
  260. package/lib/v2/xjtu/radar.js +53 -0
  261. package/lib/v2/xjtu/router.js +9 -0
  262. package/lib/v2/xjtu/std.js +58 -0
  263. package/lib/v2/xjtu/templates/attachments.art +3 -0
  264. package/lib/v2/xjtu/templates/std.art +4 -0
  265. package/lib/v2/xueqiu/column.js +42 -0
  266. package/lib/v2/xueqiu/maintainer.js +1 -0
  267. package/lib/v2/xueqiu/radar.js +6 -0
  268. package/lib/v2/xueqiu/router.js +1 -0
  269. package/lib/v2/zhangyoubao/index.js +42 -0
  270. package/lib/v2/zhangyoubao/maintainer.js +3 -0
  271. package/lib/v2/zhangyoubao/radar.js +13 -0
  272. package/lib/v2/zhangyoubao/router.js +3 -0
  273. package/lib/v2/zhangyoubao/templates/article.art +1 -0
  274. package/package.json +20 -19
  275. package/lib/routes/acfun/video.js +0 -44
  276. package/lib/routes/apnews/topics.js +0 -43
  277. package/lib/routes/dgjyw/index.js +0 -66
  278. package/lib/routes/hk01/channel.js +0 -22
  279. package/lib/routes/hk01/issue.js +0 -22
  280. package/lib/routes/mirror/entries.js +0 -80
  281. package/lib/routes/universities/ncwu/notice.js +0 -42
  282. package/lib/routes/universities/xjtu/dean.js +0 -86
  283. package/lib/routes/universities/xjtu/international.js +0 -53
  284. package/lib/routes/universities/xjtu/job.js +0 -50
  285. package/lib/v2/elsevier/latest.js +0 -87
  286. package/lib/v2/elsevier/volume.js +0 -75
  287. package/lib/v2/ieee/latestvol.js +0 -87
  288. package/lib/v2/jasa/maintainer.js +0 -4
  289. package/lib/v2/jasa/radar.js +0 -19
  290. package/lib/v2/jasa/router.js +0 -4
  291. package/lib/v2/jasa/section.js +0 -95
  292. package/lib/v2/jasa/templates/description.art +0 -11
@@ -0,0 +1,3 @@
1
+ module.exports = function (router) {
2
+ router.get('/journal/:journal', require('./journal'));
3
+ };
@@ -0,0 +1,12 @@
1
+ <p>
2
+ <span><big>{{ item.title }}</big></span><br>
3
+ </p>
4
+ <p>
5
+ <span><small><i>{{ item.authors }}</i></small></span><br>
6
+ <span><small><i>https://doi.org/{{ item.doi }}</i></small></span><br>
7
+ <span><small><i>{{ item.issue }}</i></small></span><br>
8
+ <img src={{ item.img }}>
9
+ </p>
10
+ <p>
11
+ <span>{{ item.abstract }}</span><br>
12
+ </p>
@@ -0,0 +1,67 @@
1
+ const got = require('@/utils/got');
2
+ const cheerio = require('cheerio');
3
+ const { parseDate } = require('@/utils/parse-date');
4
+
5
+ module.exports = async (ctx) => {
6
+ const rootUrl = 'https://supchina.com';
7
+ const currentUrl = `${rootUrl}/feed/`;
8
+
9
+ const response = await got({
10
+ method: 'get',
11
+ url: currentUrl,
12
+ });
13
+
14
+ const $ = cheerio.load(response.data);
15
+
16
+ let items = $('item')
17
+ .slice(0, ctx.query.limit ? parseInt(ctx.query.limit) : 50)
18
+ .toArray()
19
+ .map((item) => {
20
+ item = $(item);
21
+
22
+ return {
23
+ guid: item.find('guid').text(),
24
+ title: item.find('title').text(),
25
+ link: item.find('guid').text(),
26
+ author: item
27
+ .find('dc\\:creator')
28
+ .html()
29
+ .match(/CDATA\[(.*?)\]/)[1],
30
+ category: item
31
+ .find('category')
32
+ .toArray()
33
+ .map(
34
+ (c) =>
35
+ $(c)
36
+ .html()
37
+ .match(/CDATA\[(.*?)\]/)[1]
38
+ ),
39
+ pubDate: parseDate(item.find('pubDate').text()),
40
+ };
41
+ });
42
+
43
+ items = await Promise.all(
44
+ items.map((item) =>
45
+ ctx.cache.tryGet(item.link, async () => {
46
+ const detailResponse = await got({
47
+ method: 'get',
48
+ url: item.link,
49
+ });
50
+
51
+ const content = cheerio.load(detailResponse.data);
52
+
53
+ content('.aspect-spacer, .post-recs, .author-bio').remove();
54
+
55
+ item.description = content('.post__main').html();
56
+
57
+ return item;
58
+ })
59
+ )
60
+ );
61
+
62
+ ctx.state.data = {
63
+ title: $('title').first().text(),
64
+ link: rootUrl,
65
+ item: items,
66
+ };
67
+ };
@@ -0,0 +1,4 @@
1
+ module.exports = {
2
+ '/podcasts': ['nczitzk'],
3
+ '/': ['nczitzk'],
4
+ };
@@ -0,0 +1,66 @@
1
+ const got = require('@/utils/got');
2
+ const cheerio = require('cheerio');
3
+ const { parseDate } = require('@/utils/parse-date');
4
+
5
+ module.exports = async (ctx) => {
6
+ const rootUrl = 'https://supchina.com';
7
+ const currentUrl = `${rootUrl}/feed/podcast`;
8
+
9
+ const response = await got({
10
+ method: 'get',
11
+ url: currentUrl,
12
+ });
13
+
14
+ const $ = cheerio.load(response.data);
15
+
16
+ let items = $('item')
17
+ .slice(0, ctx.query.limit ? parseInt(ctx.query.limit) : 50)
18
+ .toArray()
19
+ .map((item) => {
20
+ item = $(item);
21
+
22
+ return {
23
+ link: item.find('guid').text(),
24
+ author: item.find('itunes\\:author').text(),
25
+ };
26
+ });
27
+
28
+ items = await Promise.all(
29
+ items.map((item) =>
30
+ ctx.cache.tryGet(item.link, async () => {
31
+ const detailResponse = await got({
32
+ method: 'get',
33
+ url: item.link,
34
+ });
35
+
36
+ const episodeResponse = await got({
37
+ method: 'get',
38
+ url: `https://rss.art19.com/episodes/${detailResponse.data.match(/data-episode-id="(.*?)"/)[1]}`,
39
+ headers: {
40
+ accept: 'application/json',
41
+ },
42
+ });
43
+
44
+ const data = episodeResponse.data;
45
+
46
+ item.title = data.content.episode_title;
47
+ item.itunes_item_image = data.content.cover_image;
48
+ item.itunes_duration = data.content.duration;
49
+ item.enclosure_url = data.content.media.mp3.url;
50
+ item.enclosure_type = data.content.media.mp3.content_type;
51
+ item.description = data.content.episode_description;
52
+ item.pubDate = parseDate(data.performed_at);
53
+
54
+ return item;
55
+ })
56
+ )
57
+ );
58
+
59
+ ctx.state.data = {
60
+ title: 'SupChina - Podcasts',
61
+ link: `${rootUrl}/podcasts`,
62
+ itunes_author: $('channel itunes\\:author').first().text(),
63
+ image: $('itunes\\:image').attr('href'),
64
+ item: items,
65
+ };
66
+ };
@@ -0,0 +1,19 @@
1
+ module.exports = {
2
+ 'supchina.com': {
3
+ _name: 'SupChina',
4
+ '.': [
5
+ {
6
+ title: 'Feed',
7
+ docs: 'https://docs.rsshub.app/new-media.html#supchina-feed',
8
+ source: ['/feed', '/'],
9
+ target: '/supchina',
10
+ },
11
+ {
12
+ title: 'Podcasts',
13
+ docs: 'https://docs.rsshub.app/new-media.html#supchina-podcasts',
14
+ source: ['/podcasts', '/'],
15
+ target: '/supchina/podcasts',
16
+ },
17
+ ],
18
+ },
19
+ };
@@ -0,0 +1,4 @@
1
+ module.exports = function (router) {
2
+ router.get('/podcasts', require('./podcasts'));
3
+ router.get('/', require('./index'));
4
+ };
@@ -0,0 +1,34 @@
1
+ const got = require('@/utils/got');
2
+ const { parseDate } = require('@/utils/parse-date');
3
+
4
+ module.exports = async (ctx) => {
5
+ const category = ctx.params.category ?? '头条';
6
+
7
+ const rootUrl = 'https://www.techflow520.com';
8
+ const apiUrl = `${rootUrl}/index/index/tab_centet`;
9
+
10
+ const response = await got({
11
+ method: 'post',
12
+ url: apiUrl,
13
+ form: {
14
+ offect: 0,
15
+ typename: category,
16
+ pageval: 50,
17
+ },
18
+ });
19
+
20
+ const items = response.data.map((item) => ({
21
+ title: item.title,
22
+ link: `${rootUrl}/news/${item.id}`,
23
+ description: item.content,
24
+ pubDate: parseDate(item.time),
25
+ category: [item.keywords],
26
+ author: item.source,
27
+ }));
28
+
29
+ ctx.state.data = {
30
+ title: `深潮TechFlow - ${category}`,
31
+ link: rootUrl,
32
+ item: items,
33
+ };
34
+ };
@@ -0,0 +1,4 @@
1
+ module.exports = {
2
+ '/newsflash': ['nczitzk'],
3
+ '/:category?': ['nczitzk'],
4
+ };
@@ -0,0 +1,32 @@
1
+ const got = require('@/utils/got');
2
+ const { parseDate } = require('@/utils/parse-date');
3
+
4
+ module.exports = async (ctx) => {
5
+ const rootUrl = 'https://www.techflow520.com';
6
+ const currentUrl = `${rootUrl}/newflash`;
7
+ const apiUrl = `${rootUrl}/index/kuaixun/load_kuaixun`;
8
+
9
+ const response = await got({
10
+ method: 'post',
11
+ url: apiUrl,
12
+ form: {
13
+ offect: 0,
14
+ pageval: 50,
15
+ },
16
+ });
17
+
18
+ const items = response.data.map((item) => ({
19
+ title: item.title,
20
+ link: `${rootUrl}/news/${item.id}`,
21
+ description: item.content,
22
+ pubDate: parseDate(item.time),
23
+ category: [item.keywords],
24
+ author: item.source,
25
+ }));
26
+
27
+ ctx.state.data = {
28
+ title: '深潮TechFlow - 快讯',
29
+ link: currentUrl,
30
+ item: items,
31
+ };
32
+ };
@@ -0,0 +1,19 @@
1
+ module.exports = {
2
+ 'techflow520.com': {
3
+ _name: '深潮TechFlow',
4
+ '.': [
5
+ {
6
+ title: '分类',
7
+ docs: 'https://docs.rsshub.app/new-media.html#shen-chao-techflow-fen-lei',
8
+ source: ['/'],
9
+ target: '/techflow520/:category?',
10
+ },
11
+ {
12
+ title: '快讯',
13
+ docs: 'https://docs.rsshub.app/new-media.html#shen-chao-techflow-kuai-xun',
14
+ source: ['/newsflash'],
15
+ target: '/techflow520/newsflash',
16
+ },
17
+ ],
18
+ },
19
+ };
@@ -0,0 +1,4 @@
1
+ module.exports = function (router) {
2
+ router.get('/newsflash', require('./newsflash'));
3
+ router.get('/:category?', require('./index'));
4
+ };
@@ -0,0 +1,51 @@
1
+ const got = require('@/utils/got');
2
+ const cheerio = require('cheerio');
3
+ const { parseDate } = require('@/utils/parse-date');
4
+
5
+ module.exports = async (ctx) => {
6
+ const id = ctx.params.id ?? '86410';
7
+ const tag = ctx.params.tag ?? '';
8
+
9
+ const rootUrl = 'https://cloud.tencent.com';
10
+ const currentUrl = `${rootUrl}/developer/column/${id}${tag ? `/tag-${tag}` : ''}`;
11
+
12
+ const response = await got({
13
+ method: 'get',
14
+ url: currentUrl,
15
+ });
16
+
17
+ const data = JSON.parse(response.data.match(/window\.\$render\((.*?)\);/)[1]);
18
+
19
+ let items = data.articleData.list.map((item) => ({
20
+ title: item.title,
21
+ author: item.author.name,
22
+ link: `${rootUrl}/developer/article/${item.id}`,
23
+ pubDate: parseDate(item.updateTime * 1000),
24
+ category: item.tags.map((tag) => tag.name),
25
+ }));
26
+
27
+ items = await Promise.all(
28
+ items.map((item) =>
29
+ ctx.cache.tryGet(item.link, async () => {
30
+ const detailResponse = await got({
31
+ method: 'get',
32
+ url: item.link,
33
+ });
34
+
35
+ const content = cheerio.load(detailResponse.data);
36
+
37
+ content('.developer-code-block').remove();
38
+
39
+ item.description = content('.rno-markdown').html();
40
+
41
+ return item;
42
+ })
43
+ )
44
+ );
45
+
46
+ ctx.state.data = {
47
+ title: `${data.columnDetail.name} - ${data.documentBaseTitle}`,
48
+ link: currentUrl,
49
+ item: items,
50
+ };
51
+ };
@@ -1,3 +1,4 @@
1
1
  module.exports = {
2
2
  '/qq/sdk/changelog/:platform': ['nuomi1'],
3
+ '/cloud/column/:id?/:tag?': ['nczitzk'],
3
4
  };
@@ -53,4 +53,15 @@ module.exports = {
53
53
  },
54
54
  ],
55
55
  },
56
+ 'tencent.com': {
57
+ _name: '腾讯云',
58
+ '.': [
59
+ {
60
+ title: '云+社区专栏',
61
+ docs: 'https://docs.rsshub.app/programming.html#teng-xun-yun-yun-she-qu-zhuan-lan',
62
+ source: ['/developer/column/:id', '/developer/column/:id/:tag', '/'],
63
+ target: (params, url) => `/tencent/cloud/column/${url.match(/column\/(\d+)/)[1]}${/\/tag-\d+/.test(url) ? `/${url.match(/\/tag-(\d+)/)[1]}` : ''}`,
64
+ },
65
+ ],
66
+ },
56
67
  };
@@ -1,3 +1,4 @@
1
1
  module.exports = (router) => {
2
2
  router.get('/qq/sdk/changelog/:platform', require('./qq/sdk/changelog'));
3
+ router.get('/cloud/column/:id?/:tag?', require('./cloud/column'));
3
4
  };
@@ -98,6 +98,21 @@ module.exports = async (ctx) => {
98
98
  link: `https://mock.com/DIYgod/RSSHub`,
99
99
  author: `DIYgod`,
100
100
  });
101
+ } else if (ctx.params.id === 'multimedia') {
102
+ item.push({
103
+ title: `Multimedia Title`,
104
+ description: `<img src="/DIYgod/RSSHub.jpg">
105
+ <video src="/DIYgod/RSSHub.mp4"></video>
106
+ <video poster="/DIYgod/RSSHub.jpg">
107
+ <source src="/DIYgod/RSSHub.mp4" type="video/mp4">
108
+ <source src="/DIYgod/RSSHub.webm" type="video/webm">
109
+ </video>
110
+ <audio src="/DIYgod/RSSHub.mp3"></audio>
111
+ <iframe src="/DIYgod/RSSHub.html"></iframe>`,
112
+ pubDate: new Date(`2019-3-1`).toUTCString(),
113
+ link: `https://mock.com/DIYgod/RSSHub`,
114
+ author: `DIYgod`,
115
+ });
101
116
  } else if (ctx.params.id === 'sort') {
102
117
  item.push({
103
118
  title: `Sort Title 0`,
@@ -187,6 +202,6 @@ module.exports = async (ctx) => {
187
202
  link: 'https://github.com/DIYgod/RSSHub',
188
203
  item,
189
204
  allowEmpty: ctx.params.id === 'allow_empty',
190
- description: ctx.params.id === 'complicated' ? '<img src="http://mock.com/DIYgod/DIYgod/RSSHub">' : 'A test route for RSSHub',
205
+ description: ctx.params.id === 'complicated' ? '<img src="http://mock.com/DIYgod/DIYgod/RSSHub">' : ctx.params.id === 'multimedia' ? '<video src="http://mock.com/DIYgod/DIYgod/RSSHub"></video>' : 'A test route for RSSHub',
191
206
  };
192
207
  };
@@ -1,5 +1,3 @@
1
- const got = require('@/utils/got');
2
- const cheerio = require('cheerio');
3
1
  const config = require('@/config').value;
4
2
  const { parseDate } = require('@/utils/parse-date');
5
3
  const { art } = require('@/utils/render');
@@ -10,57 +8,49 @@ const baseUrl = 'https://www.tiktok.com';
10
8
  module.exports = async (ctx) => {
11
9
  const { user } = ctx.params;
12
10
 
13
- const html = await ctx.cache.tryGet(
11
+ const data = await ctx.cache.tryGet(
14
12
  `tiktok:user:${user}`,
15
13
  async () => {
16
14
  const browser = await require('@/utils/puppeteer')();
17
15
  const page = await browser.newPage();
16
+ await page.setRequestInterception(true);
17
+ page.on('request', (request) => {
18
+ request.resourceType() === 'document' || request.resourceType() === 'script' ? request.continue() : request.abort();
19
+ });
18
20
  await page.goto(`${baseUrl}/${user}`, {
19
- waitUntil: 'networkidle2',
21
+ waitUntil: 'domcontentloaded',
20
22
  });
21
- const html = await page.evaluate(() => document.documentElement.innerHTML);
23
+ const SIGI_STATE = await page.evaluate(() => window.SIGI_STATE);
22
24
  browser.close();
23
- return html;
25
+
26
+ const lang = SIGI_STATE.AppContext.lang;
27
+ const SharingMeta = SIGI_STATE.SharingMeta;
28
+ const ItemModule = SIGI_STATE.ItemModule;
29
+
30
+ return { lang, SharingMeta, ItemModule };
24
31
  },
25
32
  config.cache.routeExpire,
26
33
  false
27
34
  );
28
35
 
29
- const $ = cheerio.load(html);
30
-
31
- let items = $('[class*=-DivItemContainerV2]')
32
- .toArray()
33
- .map((item) => ({ link: $(item).find('[class*=-DivWrapper] a').attr('href') }));
34
-
35
- items = await Promise.all(
36
- items.map((item) =>
37
- ctx.cache.tryGet(item.link, async () => {
38
- const videoId = item.link.substring(item.link.lastIndexOf('/') + 1);
39
- const api = (
40
- await got(`${baseUrl}/node/share/video/${user}/${videoId}`, {
41
- headers: {
42
- referer: `${baseUrl}/${user}`,
43
- },
44
- })
45
- ).data;
46
-
47
- item.title = api.itemInfo.itemStruct.desc;
48
- item.description = art(path.join(__dirname, 'templates/user.art'), {
49
- poster: api.itemInfo.itemStruct.video.cover,
50
- source: api.itemInfo.itemStruct.video.playAddr,
51
- });
52
- item.author = api.itemInfo.itemStruct.author.nickname;
53
- item.pubDate = parseDate(api.itemInfo.itemStruct.createTime * 1000);
54
-
55
- return item;
56
- })
57
- )
58
- );
36
+ const items = Object.values(data.ItemModule).map((item) => ({
37
+ title: item.desc,
38
+ description: art(path.join(__dirname, 'templates/user.art'), {
39
+ poster: item.video.cover,
40
+ source: item.video.playAddr,
41
+ }),
42
+ author: item.nickname,
43
+ pubDate: parseDate(item.createTime, 'X'),
44
+ link: `${baseUrl}/@${item.author}/video/${item.id}`,
45
+ category: item.textExtra.map((t) => `#${t.hashtagName}`),
46
+ }));
59
47
 
60
48
  ctx.state.data = {
61
- title: $('title').text(),
62
- description: $('[data-e2e=user-bio]').text(),
49
+ title: data.SharingMeta.value['og:title'],
50
+ description: data.SharingMeta.value['og:description'],
51
+ image: data.SharingMeta.value['og:image'],
63
52
  link: `${baseUrl}/${user}`,
64
53
  item: items,
54
+ language: data.lang,
65
55
  };
66
56
  };
@@ -0,0 +1,169 @@
1
+ const dayjs = require('dayjs');
2
+ dayjs.extend(require('dayjs/plugin/utc'));
3
+ dayjs.extend(require('dayjs/plugin/timezone'));
4
+ const got = require('@/utils/got');
5
+ const { art } = require('@/utils/render');
6
+ const path = require('path');
7
+ const config = require('@/config').value;
8
+ const md5 = require('@/utils/md5');
9
+
10
+ // Constants
11
+ const DATA_REPO_BASE_URL = 'https://raw.githubusercontent.com/huqi-pr/trending-in-one/master/raw';
12
+ const DATE_FORMAT = 'YYYY-MM-DD';
13
+ // TODO: support custom data repo urls
14
+ const CHANNELS = {
15
+ 'toutiao-search': {
16
+ baseUrl: 'https://so.toutiao.com/search?keyword=',
17
+ name: '今日头条热搜',
18
+ },
19
+ 'weibo-search': {
20
+ baseUrl: 'https://s.weibo.com/weibo?q=',
21
+ name: '微博热搜',
22
+ },
23
+ 'zhihu-search': {
24
+ baseUrl: 'https://www.zhihu.com/search?q=',
25
+ name: '知乎热搜',
26
+ },
27
+ 'zhihu-questions': {
28
+ baseUrl: 'https://www.zhihu.com/search?type=question&q=',
29
+ name: '知乎热门话题',
30
+ },
31
+ 'zhihu-video': {
32
+ baseUrl: 'https://www.zhihu.com/search?type=video&q=',
33
+ name: '知乎热门视频',
34
+ },
35
+ };
36
+
37
+ // Helper Functions
38
+ // TODO: integrate into CHANNELS
39
+ const processRawDataByChannel = {
40
+ 'toutiao-search': ({ word: title }) => ({
41
+ // 源 url 存在 encoding 问题,暂时不使用
42
+ url: CHANNELS['toutiao-search'].baseUrl + encodeURIComponent(title),
43
+ title,
44
+ }),
45
+ 'weibo-search': ({ title }) => ({
46
+ // 源 url 存在 encoding 问题,暂时不使用
47
+ url: CHANNELS['weibo-search'].baseUrl + encodeURIComponent(title),
48
+ title,
49
+ }),
50
+ 'zhihu-questions': (item) => item,
51
+ 'zhihu-search': ({ query }) => {
52
+ const title = query.trim();
53
+ return {
54
+ // 源 url 存在 encoding 问题,暂时不使用
55
+ url: CHANNELS['zhihu-search'].baseUrl + encodeURIComponent(title),
56
+ title,
57
+ };
58
+ },
59
+ 'zhihu-video': (item) => item,
60
+ };
61
+
62
+ const hasKeyword = (str, keywordList) => keywordList.some((keyword) => str.includes(keyword));
63
+ const toShanghaiTimezone = (date) => dayjs.tz(date, 'Asia/Shanghai');
64
+
65
+ // Data Fetcher
66
+ // TODO: support channel selection
67
+ const fetchAllData = async (keywordList = [], dateList = [], cache) => {
68
+ const cachedGetData = (url, dataMappingFn) =>
69
+ cache.tryGet(
70
+ url,
71
+ () =>
72
+ got(url)
73
+ .json()
74
+ // Normalize data to { title, url } format
75
+ .then((res) => res.map((item) => dataMappingFn(item))),
76
+ config.cache.contentExpire,
77
+ false
78
+ );
79
+
80
+ const data = await Promise.all(
81
+ dateList.map(async (dateTime) => ({
82
+ dateTime,
83
+ data: await Promise.all(
84
+ Object.keys(CHANNELS).map(async (channel) => ({
85
+ name: CHANNELS[channel].name,
86
+ data: await cachedGetData(`${DATA_REPO_BASE_URL}/${channel}/${dateTime.format(DATE_FORMAT)}.json`, processRawDataByChannel[channel]).then((res) => res.filter(({ title }) => hasKeyword(title, keywordList))),
87
+ }))
88
+ ),
89
+ }))
90
+ );
91
+ for (const i of data) {
92
+ i.count = i.data.reduce((acc, { data }) => acc + data.length, 0);
93
+ }
94
+
95
+ return data.filter(({ count }) => count > 0);
96
+ };
97
+
98
+ // Generate Feed Items
99
+ const searchLinkUrls = (keyword) => [
100
+ `https://tophub.today/search?e=tophub&q=${keyword}`,
101
+ `https://www.baidu.com/s?wd=${keyword}`,
102
+ `https://www.google.com/search?q=${keyword}`,
103
+ `https://www.zhihu.com/search?type=content&q=${keyword}`,
104
+ `https://s.weibo.com/weibo/${keyword}`,
105
+ `https://www.douyin.com/search/${keyword}`,
106
+ `https://so.toutiao.com/search?keyword=${keyword}`,
107
+ ];
108
+
109
+ const searchLinkNames = ['热榜', '百度', '谷歌', '知乎', '微博', '抖音', '头条'];
110
+
111
+ const createItem = ({ dateTime, data, count }, keywords, isToday) => {
112
+ const EOD = dateTime.endOf('day');
113
+ const pubDate = isToday ? new Date() : EOD.toDate();
114
+ return {
115
+ title: `${keywords.join(', ')} | ${dateTime.format(DATE_FORMAT)} 热点追踪 (${count})`,
116
+ author: 'Trending All In One',
117
+ pubDate,
118
+ description: art(path.join(__dirname, 'templates/content.art'), {
119
+ data,
120
+ queries: keywords.map((query) => ({
121
+ links: searchLinkUrls(encodeURIComponent(query)).map((url, index) => `<a href="${url}" rel="noopener noreferrer" target="_blank">${searchLinkNames[index]}</a>`),
122
+ key: query,
123
+ })),
124
+ }),
125
+ guid: `trending-all-in-one-${EOD.toISOString()}-${md5(JSON.stringify(data))}-${keywords.join('-')}`,
126
+ };
127
+ };
128
+
129
+ // Main
130
+ module.exports = async (ctx) => {
131
+ // Prevent making over 100 requests per invocation
132
+ if (ctx.params.numberOfDays > 14) {
133
+ throw new Error('days must be less than 14');
134
+ }
135
+ const numberOfDays = ctx.params.numberOfDays || 3;
136
+ const currentShanghaiDateTime = dayjs(toShanghaiTimezone(new Date()));
137
+ const currentShanghaiDateStr = currentShanghaiDateTime.format(DATE_FORMAT);
138
+ const dateList = [];
139
+ for (let i = 0; i < numberOfDays; i++) {
140
+ const d = currentShanghaiDateTime.subtract(i, 'day');
141
+ dateList.push(d);
142
+ }
143
+
144
+ const keywordList = ctx.params.keywords
145
+ .replace(',', ',')
146
+ .split(',')
147
+ .map((keyword) => keyword.trim());
148
+ const keywordStr = keywordList.join(', ');
149
+
150
+ const data = await fetchAllData(keywordList, dateList, ctx.cache);
151
+ const item =
152
+ data.length > 0
153
+ ? data.map((i, index) => createItem(i, keywordList, index === 0))
154
+ : [
155
+ {
156
+ title: `${keywordStr} | ${currentShanghaiDateStr} 热点追踪 (0)`,
157
+ author: 'Trending All In One',
158
+ description: `近${numberOfDays}日的热搜都不包含下列关键词:${keywordStr}<br>请耐心等待,或添加更多关键词试试。`,
159
+ guid: `trending-all-in-one-${md5(JSON.stringify(data))}-${keywordList.join('-')}`,
160
+ },
161
+ ];
162
+
163
+ ctx.state.data = {
164
+ title: `${keywordStr} | 热点聚合`,
165
+ description: `${keywordStr} | 今日头条热搜,知乎热门视频,知乎热搜榜,知乎热门话题,微博热搜榜聚合追踪`,
166
+ language: 'zh-cn',
167
+ item,
168
+ };
169
+ };
@@ -0,0 +1,3 @@
1
+ module.exports = {
2
+ '/:keywords/:numberOfDays?': ['Jkker'],
3
+ };