rsshub 1.0.0-master.f72af1b → 1.0.0-master.f7347d9

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 (222) hide show
  1. package/lib/config.ts +18 -0
  2. package/lib/middleware/template.tsx +10 -2
  3. package/lib/routes/163/music/playlist.ts +2 -1
  4. package/lib/routes/5eplay/index.ts +1 -51
  5. package/lib/routes/a9vg/index.ts +214 -0
  6. package/lib/routes/a9vg/namespace.ts +1 -0
  7. package/lib/routes/a9vg/templates/description.art +17 -0
  8. package/lib/routes/aibase/discover.ts +388 -0
  9. package/lib/routes/aibase/namespace.ts +8 -0
  10. package/lib/routes/aibase/news.ts +118 -0
  11. package/lib/routes/aibase/templates/description.art +100 -0
  12. package/lib/routes/aibase/topic.ts +614 -0
  13. package/lib/routes/aibase/util.ts +114 -0
  14. package/lib/routes/apnews/api.ts +18 -3
  15. package/lib/routes/apnews/rss.ts +1 -1
  16. package/lib/routes/apnews/topics.ts +4 -3
  17. package/lib/routes/apple/podcast.ts +19 -15
  18. package/lib/routes/bangumi/templates/tv/subject.art +6 -0
  19. package/lib/routes/bangumi/tv/other/followrank.ts +19 -22
  20. package/lib/routes/bangumi/tv/user/collections.ts +172 -0
  21. package/lib/routes/bilibili/cache.ts +16 -8
  22. package/lib/routes/bilibili/utils.ts +85 -3
  23. package/lib/routes/bilibili/video.ts +7 -9
  24. package/lib/routes/bilibili/vsearch.ts +1 -1
  25. package/lib/routes/bjnews/cat.ts +9 -1
  26. package/lib/routes/cbpanet/index.ts +380 -0
  27. package/lib/routes/cbpanet/namespace.ts +8 -0
  28. package/lib/routes/ceph/blog.ts +72 -0
  29. package/lib/routes/ceph/namespace.ts +7 -0
  30. package/lib/routes/chinanews/index.ts +1 -1
  31. package/lib/routes/chinaventure/index.ts +1 -1
  32. package/lib/routes/cisia/index.ts +264 -0
  33. package/lib/routes/cisia/namespace.ts +8 -0
  34. package/lib/routes/cjlu/namespace.ts +10 -0
  35. package/lib/routes/cjlu/yjsy/index.ts +107 -0
  36. package/lib/routes/cnki/journals.ts +31 -2
  37. package/lib/routes/cohere/index.ts +54 -0
  38. package/lib/routes/cohere/namespace.ts +6 -0
  39. package/lib/routes/coolapk/dyh.ts +7 -1
  40. package/lib/routes/coolapk/hot.ts +7 -1
  41. package/lib/routes/coolapk/huati.ts +7 -1
  42. package/lib/routes/coolapk/namespace.ts +6 -0
  43. package/lib/routes/coolapk/toutiao.ts +7 -1
  44. package/lib/routes/coolapk/tuwen.ts +10 -5
  45. package/lib/routes/coolapk/user-dynamic.ts +7 -1
  46. package/lib/routes/damai/activity.ts +3 -2
  47. package/lib/routes/dcfever/trading.ts +3 -5
  48. package/lib/routes/dcfever/utils.ts +13 -4
  49. package/lib/routes/dealstreetasia/home.ts +72 -0
  50. package/lib/routes/dealstreetasia/namespace.ts +6 -0
  51. package/lib/routes/dealstreetasia/section.ts +57 -0
  52. package/lib/routes/dlsite/campaign.ts +1 -2
  53. package/lib/routes/dlsite/new.ts +1 -2
  54. package/lib/routes/dlsite/{index.ts → z-index/index.ts} +1 -1
  55. package/lib/routes/douban/other/topic.ts +10 -4
  56. package/lib/routes/douyin/types.ts +795 -0
  57. package/lib/routes/douyin/user.ts +51 -23
  58. package/lib/routes/douyin/utils.ts +1 -87
  59. package/lib/routes/dribbble/keyword.ts +1 -1
  60. package/lib/routes/dribbble/popular.ts +1 -1
  61. package/lib/routes/dribbble/user.ts +1 -1
  62. package/lib/routes/dribbble/utils.ts +16 -18
  63. package/lib/routes/famitsu/category.ts +1 -1
  64. package/lib/routes/fanbox/index.ts +1 -1
  65. package/lib/routes/fanbox/types.ts +1 -5
  66. package/lib/routes/fediverse/timeline.ts +21 -3
  67. package/lib/routes/follow/profile.ts +4 -2
  68. package/lib/routes/follow/types.ts +11 -1
  69. package/lib/routes/github/advisor.ts +97 -0
  70. package/lib/routes/github/discussions.ts +194 -0
  71. package/lib/routes/github/issue.ts +1 -1
  72. package/lib/routes/github/pulls.ts +1 -1
  73. package/lib/routes/gmcmonline/chinacustoms.ts +130 -0
  74. package/lib/routes/gmcmonline/namespace.ts +8 -0
  75. package/lib/routes/gov/csrc/csrc.ts +541 -0
  76. package/lib/routes/gov/customs/list.ts +5 -2
  77. package/lib/routes/gov/customs/namespace.ts +7 -0
  78. package/lib/routes/gov/jgjcndrc/index.ts +95 -66
  79. package/lib/routes/gov/moa/moa.ts +3 -3
  80. package/lib/routes/gov/moa/szcpxx.ts +115 -0
  81. package/lib/routes/gov/moa/zdscxx.ts +71 -21
  82. package/lib/routes/gov/ndrc/zfxxgk.ts +106 -0
  83. package/lib/routes/gov/pudong/zwgk.ts +65 -0
  84. package/lib/routes/gov/zj/search.ts +17 -12
  85. package/lib/routes/guancha/member.ts +1 -1
  86. package/lib/routes/hellogithub/index.ts +17 -67
  87. package/lib/routes/hellogithub/report.ts +1 -1
  88. package/lib/routes/hex-rays/index.ts +23 -29
  89. package/lib/routes/hfut/hf/notice.ts +43 -0
  90. package/lib/routes/hfut/hf/utils.ts +80 -0
  91. package/lib/routes/hfut/namespace.ts +6 -0
  92. package/lib/routes/hfut/xc/notice.ts +43 -0
  93. package/lib/routes/hfut/xc/utils.ts +73 -0
  94. package/lib/routes/hko/earthquake.ts +56 -0
  95. package/lib/routes/hko/namespace.ts +8 -0
  96. package/lib/routes/hko/weather.ts +56 -0
  97. package/lib/routes/huggingface/blog-zh.ts +1 -1
  98. package/lib/routes/hust/mse.ts +575 -0
  99. package/lib/routes/i-cable/namespace.ts +6 -0
  100. package/lib/routes/i-cable/news.ts +77 -0
  101. package/lib/routes/i-cable/templates/description.art +8 -0
  102. package/lib/routes/infoq/presentations.ts +203 -0
  103. package/lib/routes/infoq/templates/description.art +41 -0
  104. package/lib/routes/ipsw.dev/index.ts +64 -0
  105. package/lib/routes/ipsw.dev/namespace.ts +7 -0
  106. package/lib/routes/ipsw.dev/templates/description.art +20 -0
  107. package/lib/routes/ixigua/user-video.ts +18 -7
  108. package/lib/routes/javtiful/actress.ts +37 -0
  109. package/lib/routes/javtiful/channel.ts +37 -0
  110. package/lib/routes/javtiful/namespace.ts +6 -0
  111. package/lib/routes/javtiful/templates/description.art +7 -0
  112. package/lib/routes/javtiful/utils.ts +18 -0
  113. package/lib/routes/kisskiss/blog.ts +74 -0
  114. package/lib/routes/kisskiss/namespace.ts +6 -0
  115. package/lib/routes/ktown4u/artist-brandlist.ts +61 -0
  116. package/lib/routes/ktown4u/namespace.ts +6 -0
  117. package/lib/routes/lorientlejour/index.ts +186 -0
  118. package/lib/routes/lorientlejour/namespace.ts +7 -0
  119. package/lib/routes/lorientlejour/templates/description.art +18 -0
  120. package/lib/routes/lovelive-anime/namespace.ts +1 -1
  121. package/lib/routes/lovelive-anime/news.ts +56 -26
  122. package/lib/routes/lovelive-anime/schedules.ts +18 -6
  123. package/lib/routes/lovelive-anime/templates/description.art +1 -1
  124. package/lib/routes/lovelive-anime/templates/scheduleDesc.art +0 -1
  125. package/lib/routes/lovelive-anime/topics.ts +1 -1
  126. package/lib/routes/manhuagui/comic.ts +1 -1
  127. package/lib/routes/mi/crowdfunding.ts +43 -22
  128. package/lib/routes/mi/templates/crowdfunding.art +28 -0
  129. package/lib/routes/mi/types.ts +40 -0
  130. package/lib/routes/mi/utils.ts +80 -0
  131. package/lib/routes/misskey/utils.ts +1 -0
  132. package/lib/routes/misskon/namespace.ts +6 -0
  133. package/lib/routes/misskon/posts.ts +33 -0
  134. package/lib/routes/misskon/tag.ts +38 -0
  135. package/lib/routes/misskon/top.ts +67 -0
  136. package/lib/routes/misskon/utils.ts +41 -0
  137. package/lib/routes/natgeo/dailyphoto.ts +1 -1
  138. package/lib/routes/natgeo/dailyselection.ts +1 -1
  139. package/lib/routes/ncku/namespace.ts +1 -1
  140. package/lib/routes/ncku/phys.ts +95 -0
  141. package/lib/routes/news/namespace.ts +1 -1
  142. package/lib/routes/nikkei/cn/index.ts +12 -1
  143. package/lib/routes/nudt/yjszs.ts +33 -13
  144. package/lib/routes/nytimes/book.ts +11 -11
  145. package/lib/routes/nytimes/daily-briefing-chinese.ts +4 -4
  146. package/lib/routes/nytimes/namespace.ts +1 -1
  147. package/lib/routes/oncc/templates/article.art +1 -1
  148. package/lib/routes/papers/index.ts +7 -1
  149. package/lib/routes/parliament.uk/commonslibrary.ts +55 -0
  150. package/lib/routes/parliament.uk/lordslibrary.ts +55 -0
  151. package/lib/routes/parliament.uk/namespace.ts +6 -0
  152. package/lib/routes/picuki/profile.ts +50 -39
  153. package/lib/routes/pornhub/model.ts +3 -5
  154. package/lib/routes/pornhub/pornstar.ts +3 -5
  155. package/lib/routes/pornhub/users.ts +3 -5
  156. package/lib/routes/resonac/namespace.ts +6 -0
  157. package/lib/routes/resonac/products.ts +85 -0
  158. package/lib/routes/rsshub/transform/html.ts +114 -75
  159. package/lib/routes/rsshub/transform/json.ts +14 -8
  160. package/lib/routes/sciencenet/user.ts +3 -1
  161. package/lib/routes/scmp/utils.ts +2 -2
  162. package/lib/routes/skeb/following-creators.ts +52 -0
  163. package/lib/routes/skeb/following-works.ts +52 -0
  164. package/lib/routes/skeb/friend-works.ts +52 -0
  165. package/lib/routes/skeb/index.ts +131 -0
  166. package/lib/routes/skeb/namespace.ts +6 -0
  167. package/lib/routes/skeb/search.ts +77 -0
  168. package/lib/routes/skeb/templates/creator.art +8 -0
  169. package/lib/routes/skeb/templates/work.art +10 -0
  170. package/lib/routes/skeb/utils.ts +155 -0
  171. package/lib/routes/skeb/works.ts +88 -0
  172. package/lib/routes/skebetter/illust.ts +83 -0
  173. package/lib/routes/skebetter/index.ts +83 -0
  174. package/lib/routes/skebetter/manga.ts +65 -0
  175. package/lib/routes/skebetter/namespace.ts +6 -0
  176. package/lib/routes/skebetter/utils.ts +72 -0
  177. package/lib/routes/spankbang/namespace.ts +6 -0
  178. package/lib/routes/spankbang/new-videos.ts +90 -0
  179. package/lib/routes/spankbang/templates/video.art +7 -0
  180. package/lib/routes/straitstimes/index.ts +135 -0
  181. package/lib/routes/straitstimes/namespace.ts +7 -0
  182. package/lib/routes/straitstimes/templates/description.art +27 -0
  183. package/lib/routes/szftedu/dongtai.ts +62 -0
  184. package/lib/routes/szftedu/gonggao.ts +62 -0
  185. package/lib/routes/szftedu/namespace.ts +6 -0
  186. package/lib/routes/the/index.ts +1 -1
  187. package/lib/routes/tkww/index.ts +83 -0
  188. package/lib/routes/tkww/namespace.ts +6 -0
  189. package/lib/routes/ttv/index.ts +1 -1
  190. package/lib/routes/tvb/news.ts +2 -1
  191. package/lib/routes/twitter/api/mobile-api/login.ts +5 -0
  192. package/lib/routes/twitter/api/web-api/api.ts +16 -10
  193. package/lib/routes/twitter/api/web-api/constants.ts +1 -1
  194. package/lib/routes/twitter/api/web-api/utils.ts +94 -56
  195. package/lib/routes/twitter/list.ts +4 -12
  196. package/lib/routes/twitter/media.ts +13 -4
  197. package/lib/routes/twitter/user.ts +15 -6
  198. package/lib/routes/udn/breaking-news.ts +2 -2
  199. package/lib/routes/uestc/gr.ts +65 -37
  200. package/lib/routes/uestc/jwc.ts +49 -28
  201. package/lib/routes/wechat/ershcimi.ts +4 -2
  202. package/lib/routes/weibo/user.ts +10 -2
  203. package/lib/routes/xaut/index.ts +13 -20
  204. package/lib/routes/xaut/namespace.ts +1 -1
  205. package/lib/routes/xbookcn/blog.ts +66 -0
  206. package/lib/routes/xbookcn/namespace.ts +6 -0
  207. package/lib/routes/xiaoyuzhou/podcast.ts +35 -7
  208. package/lib/routes/xueqiu/cookies.ts +5 -3
  209. package/lib/routes/xueqiu/stock-info.ts +6 -12
  210. package/lib/routes/yande/namespace.ts +1 -1
  211. package/lib/routes/yande/post.ts +6 -6
  212. package/lib/routes/zaobao/util.ts +41 -43
  213. package/lib/routes/zhihu/activities.ts +2 -1
  214. package/lib/routes/zhihu/timeline.ts +6 -1
  215. package/lib/routes/zhihu/utils.ts +1 -1
  216. package/lib/routes/zjut/cs/index.ts +105 -0
  217. package/lib/routes/zjut/jwc/index.ts +117 -0
  218. package/lib/utils/cache/redis.ts +1 -1
  219. package/package.json +35 -36
  220. package/lib/routes/a9vg/a9vg.ts +0 -45
  221. package/lib/routes/gov/ndrc/zfxxgk/articles.ts +0 -73
  222. package/lib/routes-deprecated/hko/weather.js +0 -44
@@ -38,7 +38,7 @@ const parseList = async (
38
38
  }> => {
39
39
  const response = await got_ins.get(baseUrl + sectionUrl);
40
40
  const $ = load(response.data);
41
- let data = /realtime/.test(sectionUrl) ? $('.card-listing .card') : $('.article-list').find('.article-type');
41
+ let data = $('.card-listing .card');
42
42
  if (data.length === 0) {
43
43
  // for HK version
44
44
  data = $('.clearfix').find('.list-block');
@@ -104,48 +104,7 @@ const parseList = async (
104
104
 
105
105
  const articleBody = articleBodyNode.html();
106
106
 
107
- const imageDataArray = [];
108
- if ($1('.inline-figure-img').length) {
109
- // for SG version
110
- imageDataArray.push({
111
- type: 'normalHTML',
112
- html: $1('.inline-figure-img')
113
- .html()
114
- .replace(/\/\/.*\.com\/s3fs-public/, '//static.zaobao.com/s3fs-public')
115
- .replace(/s3\/files/, 's3fs-public'),
116
- });
117
- }
118
- if ($1('.body-content .loadme picture img').length) {
119
- // Unused?
120
- imageDataArray.push({
121
- type: 'data',
122
- src: $1('.body-content .loadme picture source')
123
- .attr('data-srcset')
124
- .replace(/\/\/.*\.com\/s3fs-public/, '//static.zaobao.com/s3fs-public')
125
- .replace(/s3\/files/, 's3fs-public'),
126
- title: $1('.body-content .loadme picture img').attr('title'),
127
- });
128
- }
129
- if ($1('.inline-figure-gallery').length) {
130
- // for SG version
131
- imageDataArray.push({
132
- type: 'normalHTML',
133
- html: $1('.inline-figure-gallery')
134
- .html()
135
- .replaceAll(/\/\/.*\.com\/s3fs-public/g, '//static.zaobao.com/s3fs-public')
136
- .replaceAll('s3/files', 's3fs-public'),
137
- });
138
- }
139
- if ($1('#carousel-article').length) {
140
- // for HK version, HK version of multi images use same selector as single image, so g is needed for all pages
141
- imageDataArray.push({
142
- type: 'normalHTML',
143
- html: $1('#carousel-article .carousel-inner')
144
- .html()
145
- .replaceAll(/\/\/.*\.com\/s3fs-public/g, '//static.zaobao.com/s3fs-public')
146
- .replaceAll('s3/files', 's3fs-public'),
147
- });
148
- }
107
+ const imageDataArray = processImageData($1);
149
108
 
150
109
  return {
151
110
  // <- for SG version -> for HK version
@@ -182,4 +141,43 @@ const orderContent = (parent) => {
182
141
  }
183
142
  };
184
143
 
144
+ interface ImageData {
145
+ type: string;
146
+ html: string;
147
+ src?: string;
148
+ title?: string;
149
+ }
150
+
151
+ const processImageData = ($1) => {
152
+ const imageDataArray: ImageData[] = [];
153
+
154
+ const imageSelectors = [
155
+ '.inline-figure-img', // for SG version
156
+ '.body-content .loadme picture img', // Unused?
157
+ '.inline-figure-gallery', // for SG version
158
+ '#carousel-article', // for HK version, HK version of multi images use same selector as single image, so g is needed for all pages
159
+ ];
160
+
161
+ for (const selector of imageSelectors) {
162
+ if ($1(selector).length) {
163
+ let html = $1(selector === '#carousel-article' ? '#carousel-article .carousel-inner' : selector).html();
164
+
165
+ if (html) {
166
+ html = html.replaceAll(/\/\/.*\.com\/s3fs-public/g, '//static.zaobao.com/s3fs-public').replaceAll('s3/files', 's3fs-public');
167
+
168
+ imageDataArray.push({
169
+ type: selector === '.body-content .loadme picture img' ? 'data' : 'normalHTML',
170
+ html,
171
+ ...(selector === '.body-content .loadme picture img' && {
172
+ src: $1('.body-content .loadme picture source').attr('data-srcset'),
173
+ title: $1(selector).attr('title'),
174
+ }),
175
+ });
176
+ }
177
+ }
178
+ }
179
+
180
+ return imageDataArray;
181
+ };
182
+
185
183
  export { parseList, orderContent };
@@ -2,6 +2,7 @@ import { Route, ViewType } from '@/types';
2
2
  import got from '@/utils/got';
3
3
  import { header, processImage, getSignedHeader } from './utils';
4
4
  import { parseDate } from '@/utils/parse-date';
5
+ import sanitizeHtml from 'sanitize-html';
5
6
 
6
7
  export const route: Route = {
7
8
  path: '/people/activities/:id',
@@ -75,7 +76,7 @@ async function handler(ctx) {
75
76
  url = `https://zhuanlan.zhihu.com/p/${detail.id}`;
76
77
  break;
77
78
  case 'pin':
78
- title = detail.excerpt_title;
79
+ title = sanitizeHtml(detail.excerpt_title);
79
80
  author = detail.author.name;
80
81
  for (const contentItem of detail.content) {
81
82
  switch (contentItem.type) {
@@ -60,10 +60,13 @@ async function handler(ctx) {
60
60
  const questionId = e.target.question.id;
61
61
  return `${urlBase}/question/${questionId}/answer/${id}`;
62
62
  }
63
+ case 'pin':
63
64
  case 'article':
64
65
  return e.target.url;
65
66
  case 'question':
66
67
  return `${urlBase}/question/${id}`;
68
+ default:
69
+ return;
67
70
  }
68
71
  return '';
69
72
  };
@@ -111,11 +114,12 @@ async function handler(ctx) {
111
114
  link,
112
115
  author: e.target.author ? e.target.author.name : '',
113
116
  guid: link,
117
+ category: [e.verb],
114
118
  };
115
119
  };
116
120
 
117
121
  const out = feeds
118
- .filter((e) => e.verb && e.verb !== 'MEMBER_VOTEUP_ARTICLE' && e.verb !== 'MEMBER_VOTEUP_ANSWER')
122
+ .filter((e) => e.verb)
119
123
  .map((e) => {
120
124
  if (e && e.type && e.type === 'feed_group') {
121
125
  // A feed group contains a list of feeds whose structure is the same as a single feed
@@ -134,6 +138,7 @@ async function handler(ctx) {
134
138
  description,
135
139
  pubDate,
136
140
  guid,
141
+ category: [e.verb],
137
142
  };
138
143
  }
139
144
  return buildItem(e);
@@ -75,7 +75,7 @@ export const getSignedHeader = async (url: string, apiPath: string) => {
75
75
  }
76
76
  const response1 = await ofetch.raw('https://static.zhihu.com/zse-ck/v3.js');
77
77
  const script = await response1._data.text();
78
- const zseCk = script.match(/__g\.ck\|\|"([\w+/=\\]*?)",_=630e8;/)?.[1];
78
+ const zseCk = script.match(/__g\.ck\|\|"([\w+/=\\]*?)",_=/)?.[1];
79
79
 
80
80
  const response2 = zseCk
81
81
  ? await ofetch.raw(url, {
@@ -0,0 +1,105 @@
1
+ import { Data, Route } from '@/types';
2
+ import cache from '@/utils/cache';
3
+ import { parseDate } from '@/utils/parse-date';
4
+ import { load } from 'cheerio';
5
+ import ofetch from '@/utils/ofetch';
6
+ import timezone from '@/utils/timezone';
7
+
8
+ const rootUrl = 'https://cs.zjut.edu.cn/jsp/newsclass.jsp?wcId=';
9
+ const host = 'cs.zjut.edu.cn';
10
+
11
+ export const route: Route = {
12
+ path: '/cs/:type',
13
+ categories: ['university'],
14
+ example: '/zjut/cs/54',
15
+ parameters: { type: '分类,见下表' },
16
+ features: {
17
+ requireConfig: false,
18
+ requirePuppeteer: false,
19
+ antiCrawler: false,
20
+ supportBT: false,
21
+ supportPodcast: false,
22
+ supportScihub: false,
23
+ },
24
+ name: '浙江工业大学计算机科学与技术学院、软件学院',
25
+ maintainers: ['zhullyb'],
26
+ url: 'cs.zjut.edu.cn',
27
+ handler,
28
+ radar: [
29
+ {
30
+ source: ['cs.zjut.edu.cn/jsp/newsclass.jsp?wcId=:type'],
31
+ target: '/cs/:type',
32
+ },
33
+ ],
34
+ description: `| 新闻资讯 | 学术动态 | 通知公告 |
35
+ | ------- | ------- | ------- |
36
+ | 54 | 55 | 53 |`,
37
+ };
38
+
39
+ async function handler(ctx) {
40
+ const type = Number.parseInt(ctx.req.param('type'));
41
+ const response = await ofetch(rootUrl + type);
42
+ const $ = load(response);
43
+
44
+ const list = $('dl.news')
45
+ .toArray()
46
+ .map((item) => {
47
+ const cheerioItem = $(item);
48
+ const a = cheerioItem.find('a');
49
+
50
+ try {
51
+ const title = a.text() || '';
52
+ let link = a.attr('href');
53
+ if (!link) {
54
+ link = '';
55
+ } else if (!link.startsWith('http')) {
56
+ link = 'https://' + host + '/jsp/' + link;
57
+ }
58
+ const pubDate = timezone(parseDate(cheerioItem.find('.datetime').text().slice(1, -1)), +8);
59
+
60
+ return {
61
+ title,
62
+ link,
63
+ pubDate,
64
+ };
65
+ } catch {
66
+ return {
67
+ title: '',
68
+ link: '',
69
+ pubDate: Date.now(),
70
+ };
71
+ }
72
+ })
73
+ .filter((item) => item.title && item.link);
74
+
75
+ const items = await Promise.all(
76
+ list.map((item) =>
77
+ cache.tryGet(item.link, async () => {
78
+ const newItem = {
79
+ ...item,
80
+ description: '',
81
+ };
82
+ if (host === new URL(item.link).hostname) {
83
+ if (new URL(item.link).pathname.startsWith('/upload')) {
84
+ // 链接为一个文件,直接返回链接
85
+ newItem.description = item.link;
86
+ } else {
87
+ const response = await ofetch(item.link);
88
+ const $ = load(response);
89
+ newItem.description = $('div.news1content').html() || '';
90
+ }
91
+ } else {
92
+ // 涉及到其他站点,不方便做统一的 html 解析,直接返回链接
93
+ newItem.description = item.link;
94
+ }
95
+ return newItem;
96
+ })
97
+ )
98
+ );
99
+
100
+ return {
101
+ title: $('li#classname').text() + ' - 浙江工业大学计算机科学与技术学院、软件学院',
102
+ link: rootUrl + type,
103
+ item: items,
104
+ } as Data;
105
+ }
@@ -0,0 +1,117 @@
1
+ import { Data, Route } from '@/types';
2
+ import cache from '@/utils/cache';
3
+ import { parseDate } from '@/utils/parse-date';
4
+ import { load } from 'cheerio';
5
+ import ofetch from '@/utils/ofetch';
6
+ import timezone from '@/utils/timezone';
7
+
8
+ const rootUrl = 'http://www.jwc.zjut.edu.cn/';
9
+ const host = 'www.jwc.zjut.edu.cn';
10
+
11
+ export const route: Route = {
12
+ path: '/jwc/:type',
13
+ categories: ['university'],
14
+ example: '/zjut/jwc/1839',
15
+ parameters: { type: '分类,见下表' },
16
+ features: {
17
+ requireConfig: false,
18
+ requirePuppeteer: false,
19
+ antiCrawler: false,
20
+ supportBT: false,
21
+ supportPodcast: false,
22
+ supportScihub: false,
23
+ },
24
+ name: '浙江工业大学教务处',
25
+ maintainers: ['zhullyb'],
26
+ url: 'www.jwc.zjut.edu.cn',
27
+ handler,
28
+ radar: [
29
+ {
30
+ source: ['www.jwc.zjut.edu.cn/:type/list.htm'],
31
+ target: '/jwc/:type',
32
+ },
33
+ ],
34
+ description: `| 板块 | 参数 |
35
+ | ------- | ------- |
36
+ | 新闻动态 | 1838 |
37
+ | 课程思政 | 1842 |
38
+ | 校内动态 | 2613 |
39
+ | 学习思考 | 2614 |
40
+ | 成果展示 | 2615 |
41
+ | 媒体聚焦 | 2616 |
42
+ | 制度文件 | 2617 |
43
+ | 教学运行 | 1849 |
44
+ | 实践竞赛 | 1850 |
45
+ | 留学生Notice | 1851 |
46
+ | 项目申报 | 1852 |
47
+ | 学籍管理 | 1853 |
48
+ | 办事指南 | 1839 |`,
49
+ };
50
+
51
+ async function handler(ctx) {
52
+ const type = Number.parseInt(ctx.req.param('type'));
53
+ const response = await ofetch(rootUrl + type + '/list.htm');
54
+ const $ = load(response);
55
+
56
+ const list = $('.news.clearfix')
57
+ .toArray()
58
+ .map((item) => {
59
+ const cheerioItem = $(item);
60
+ const a = cheerioItem.find('a');
61
+
62
+ try {
63
+ const title = a.attr('title') || '';
64
+ let link = a.attr('href');
65
+ if (!link) {
66
+ link = '';
67
+ } else if (!link.startsWith('http')) {
68
+ link = rootUrl.slice(0, -1) + link;
69
+ }
70
+ const pubDate = timezone(parseDate(cheerioItem.find('.news_meta').text()), +8);
71
+
72
+ return {
73
+ title,
74
+ link,
75
+ pubDate,
76
+ };
77
+ } catch {
78
+ return {
79
+ title: '',
80
+ link: '',
81
+ pubDate: Date.now(),
82
+ };
83
+ }
84
+ })
85
+ .filter((item) => item.title && item.link);
86
+
87
+ const items = await Promise.all(
88
+ list.map((item) =>
89
+ cache.tryGet(item.link, async () => {
90
+ const newItem = {
91
+ ...item,
92
+ description: '',
93
+ };
94
+ if (host === new URL(item.link).hostname) {
95
+ if (new URL(item.link).pathname.startsWith('/_upload')) {
96
+ // 链接为一个文件,直接返回链接
97
+ newItem.description = item.link;
98
+ } else {
99
+ const response = await ofetch(item.link);
100
+ const $ = load(response);
101
+ newItem.description = $('.wp_articlecontent').html() || '';
102
+ }
103
+ } else {
104
+ // 涉及到其他站点,不方便做统一的 html 解析,直接返回链接
105
+ newItem.description = item.link;
106
+ }
107
+ return newItem;
108
+ })
109
+ )
110
+ );
111
+
112
+ return {
113
+ title: $('head > title').text() + ' - 浙江工业大学教务处',
114
+ link: rootUrl + type + '/list.htm',
115
+ item: items,
116
+ } as Data;
117
+ }
@@ -64,7 +64,7 @@ export default {
64
64
  }
65
65
  if (key) {
66
66
  if (maxAge !== config.cache.contentExpire) {
67
- // Only set cacheTtlKey if maxAge !== contentExpire
67
+ // intentionally store the cache ttl if it is not the default value
68
68
  clients.redisClient.set(getCacheTtlKey(key), maxAge, 'EX', maxAge);
69
69
  }
70
70
  return clients.redisClient.set(key, value, 'EX', maxAge); // setMode: https://redis.io/commands/set
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rsshub",
3
- "version": "1.0.0-master.f72af1b",
3
+ "version": "1.0.0-master.f7347d9",
4
4
  "description": "Make RSS Great Again!",
5
5
  "keywords": [
6
6
  "RSS"
@@ -32,8 +32,8 @@
32
32
  "*.yml": "eslint --cache --fix"
33
33
  },
34
34
  "dependencies": {
35
- "@hono/node-server": "1.13.1",
36
- "@hono/zod-openapi": "0.16.2",
35
+ "@hono/node-server": "1.13.2",
36
+ "@hono/zod-openapi": "0.16.4",
37
37
  "@notionhq/client": "2.2.15",
38
38
  "@opentelemetry/api": "1.9.0",
39
39
  "@opentelemetry/exporter-prometheus": "0.53.0",
@@ -43,10 +43,10 @@
43
43
  "@opentelemetry/sdk-trace-base": "1.26.0",
44
44
  "@opentelemetry/semantic-conventions": "1.27.0",
45
45
  "@postlight/parser": "2.2.3",
46
- "@rss3/sdk": "0.0.19",
47
- "@scalar/hono-api-reference": "0.5.148",
48
- "@sentry/node": "7.116.0",
49
- "@tonyrl/rand-user-agent": "2.0.79",
46
+ "@rss3/sdk": "0.0.22",
47
+ "@scalar/hono-api-reference": "0.5.155",
48
+ "@sentry/node": "7.119.1",
49
+ "@tonyrl/rand-user-agent": "2.0.81",
50
50
  "aes-js": "3.1.2",
51
51
  "art-template": "4.13.2",
52
52
  "bbcodejs": "0.0.4",
@@ -63,9 +63,9 @@
63
63
  "entities": "5.0.0",
64
64
  "etag": "1.8.1",
65
65
  "fanfou-sdk": "5.0.0",
66
- "form-data": "4.0.0",
66
+ "form-data": "4.0.1",
67
67
  "googleapis": "144.0.0",
68
- "hono": "4.6.3",
68
+ "hono": "4.6.5",
69
69
  "html-to-text": "9.0.5",
70
70
  "http-cookie-agent": "6.0.6",
71
71
  "https-proxy-agent": "7.0.5",
@@ -84,45 +84,45 @@
84
84
  "module-alias": "2.2.3",
85
85
  "notion-to-md": "3.1.1",
86
86
  "oauth-1.0a": "2.2.6",
87
- "ofetch": "1.4.0",
87
+ "ofetch": "1.4.1",
88
88
  "otplib": "12.0.1",
89
89
  "pac-proxy-agent": "7.0.2",
90
- "proxy-chain": "2.5.3",
90
+ "proxy-chain": "2.5.4",
91
91
  "puppeteer": "22.6.2",
92
92
  "puppeteer-extra": "3.3.6",
93
93
  "puppeteer-extra-plugin-stealth": "2.11.2",
94
94
  "puppeteer-extra-plugin-user-data-dir": "2.4.1",
95
95
  "puppeteer-extra-plugin-user-preferences": "2.4.1",
96
- "query-string": "9.1.0",
96
+ "query-string": "9.1.1",
97
97
  "rate-limiter-flexible": "5.0.3",
98
98
  "re2js": "0.4.2",
99
99
  "rfc4648": "1.5.3",
100
100
  "rss-parser": "3.13.0",
101
- "sanitize-html": "2.13.0",
102
- "simplecc-wasm": "1.0.0",
101
+ "sanitize-html": "2.13.1",
102
+ "simplecc-wasm": "1.1.0",
103
103
  "socks-proxy-agent": "8.0.4",
104
104
  "source-map": "0.7.4",
105
- "telegram": "2.25.11",
105
+ "telegram": "2.25.15",
106
106
  "tiny-async-pool": "2.1.0",
107
107
  "title": "3.5.3",
108
- "tldts": "6.1.47",
108
+ "tldts": "6.1.52",
109
109
  "tosource": "2.0.0-alpha.3",
110
- "tough-cookie": "4.1.4",
110
+ "tough-cookie": "5.0.0",
111
111
  "tsx": "4.19.1",
112
- "twitter-api-v2": "1.17.2",
113
- "undici": "6.19.8",
112
+ "twitter-api-v2": "1.18.0",
113
+ "undici": "6.20.1",
114
114
  "uuid": "10.0.0",
115
- "winston": "3.14.2",
115
+ "winston": "3.15.0",
116
116
  "xxhash-wasm": "1.0.2",
117
117
  "zod": "3.23.8"
118
118
  },
119
119
  "devDependencies": {
120
- "@babel/preset-env": "7.25.4",
121
- "@babel/preset-typescript": "7.24.7",
120
+ "@babel/preset-env": "7.25.8",
121
+ "@babel/preset-typescript": "7.25.7",
122
122
  "@eslint/eslintrc": "3.1.0",
123
- "@eslint/js": "9.11.1",
123
+ "@eslint/js": "9.12.0",
124
124
  "@microsoft/eslint-formatter-sarif": "3.1.0",
125
- "@stylistic/eslint-plugin": "2.8.0",
125
+ "@stylistic/eslint-plugin": "2.9.0",
126
126
  "@types/aes-js": "3.1.4",
127
127
  "@types/babel__preset-env": "7.9.7",
128
128
  "@types/crypto-js": "4.2.2",
@@ -136,31 +136,30 @@
136
136
  "@types/json-bigint": "1.0.4",
137
137
  "@types/jsrsasign": "10.5.13",
138
138
  "@types/lint-staged": "13.3.0",
139
- "@types/mailparser": "3.4.4",
139
+ "@types/mailparser": "3.4.5",
140
140
  "@types/markdown-it": "14.1.2",
141
141
  "@types/module-alias": "2.0.4",
142
- "@types/node": "22.7.0",
142
+ "@types/node": "22.7.6",
143
143
  "@types/sanitize-html": "2.13.0",
144
144
  "@types/supertest": "6.0.2",
145
145
  "@types/tiny-async-pool": "2.0.3",
146
146
  "@types/title": "3.4.3",
147
- "@types/tough-cookie": "4.0.5",
148
147
  "@types/uuid": "10.0.0",
149
- "@typescript-eslint/eslint-plugin": "8.7.0",
150
- "@typescript-eslint/parser": "8.7.0",
148
+ "@typescript-eslint/eslint-plugin": "8.10.0",
149
+ "@typescript-eslint/parser": "8.10.0",
151
150
  "@vercel/nft": "0.27.4",
152
151
  "@vitest/coverage-v8": "2.0.5",
153
- "discord-api-types": "0.37.101",
154
- "eslint": "9.11.1",
152
+ "discord-api-types": "0.37.102",
153
+ "eslint": "9.12.0",
155
154
  "eslint-config-prettier": "9.1.0",
156
155
  "eslint-nibble": "8.1.0",
157
- "eslint-plugin-n": "17.10.3",
156
+ "eslint-plugin-n": "17.11.1",
158
157
  "eslint-plugin-prettier": "5.2.1",
159
- "eslint-plugin-unicorn": "55.0.0",
158
+ "eslint-plugin-unicorn": "56.0.0",
160
159
  "eslint-plugin-yml": "1.14.0",
161
160
  "fs-extra": "11.2.0",
162
- "globals": "15.9.0",
163
- "got": "14.4.2",
161
+ "globals": "15.11.0",
162
+ "got": "14.4.3",
164
163
  "husky": "9.1.6",
165
164
  "js-beautify": "1.15.1",
166
165
  "lint-staged": "15.2.10",
@@ -169,7 +168,7 @@
169
168
  "prettier": "3.3.3",
170
169
  "remark-parse": "11.0.0",
171
170
  "supertest": "7.0.0",
172
- "typescript": "5.6.2",
171
+ "typescript": "5.6.3",
173
172
  "unified": "11.0.5",
174
173
  "vite-tsconfig-paths": "5.0.1",
175
174
  "vitest": "2.0.5",
@@ -1,45 +0,0 @@
1
- import { Route } from '@/types';
2
- import got from '@/utils/got';
3
- import * as cheerio from 'cheerio';
4
- import { parseDate } from '@/utils/parse-date';
5
- import timezone from '@/utils/timezone';
6
-
7
- export const route: Route = {
8
- path: '/',
9
- radar: [
10
- {
11
- source: ['a9vg.com/list/news', 'a9vg.com/'],
12
- target: '',
13
- },
14
- ],
15
- name: 'Unknown',
16
- maintainers: ['monnerHenster'],
17
- handler,
18
- url: 'a9vg.com/list/news',
19
- };
20
-
21
- async function handler() {
22
- const baseUrl = 'http://www.a9vg.com';
23
- const link = `${baseUrl}/list/news`;
24
- const { data } = await got(link);
25
-
26
- const $ = cheerio.load(data);
27
- const list = $('.a9-rich-card-list li')
28
- .toArray()
29
- .map((elem) => {
30
- const item = $(elem);
31
- return {
32
- title: item.find('.a9-rich-card-list_label').text(),
33
- description: `<img src="${item.find('img').attr('src')}"><br>${item.find('.a9-rich-card-list_summary').text().trim()}`,
34
- pubDate: timezone(parseDate(item.find('.a9-rich-card-list_infos').text().trim(), 'YYYY-MM-DD HH:mm:ss'), 8),
35
- link: `${baseUrl}${item.find('.a9-rich-card-list_item').attr('href')}`,
36
- };
37
- });
38
-
39
- return {
40
- title: 'A9VG 电玩部落',
41
- link,
42
- description: $('meta[name="description"]').attr('content'),
43
- item: list,
44
- };
45
- }
@@ -1,73 +0,0 @@
1
- import { Route } from '@/types';
2
- import cache from '@/utils/cache';
3
- import got from '@/utils/got';
4
- import { load } from 'cheerio';
5
- import { parseDate } from '@/utils/parse-date';
6
-
7
- export const route: Route = {
8
- path: '/ndrc/zfxxgk/iteminfo',
9
- categories: ['government'],
10
- example: '/gov/ndrc/zfxxgk/iteminfo',
11
- parameters: {},
12
- features: {
13
- requireConfig: false,
14
- requirePuppeteer: false,
15
- antiCrawler: false,
16
- supportBT: false,
17
- supportPodcast: false,
18
- supportScihub: false,
19
- },
20
- name: '国家发展改革委 - 政府信息公开',
21
- maintainers: ['howfool'],
22
- handler,
23
- url: 'zfxxgk.ndrc.gov.cn/web/dirlist.jsp',
24
- };
25
-
26
- async function handler() {
27
- const homeUrl = 'https://zfxxgk.ndrc.gov.cn/web/dirlist.jsp';
28
- const rootUrl = 'https://zfxxgk.ndrc.gov.cn/web/';
29
-
30
- const response = await got({
31
- method: 'get',
32
- url: homeUrl,
33
- });
34
-
35
- const $ = load(response.data);
36
-
37
- let items = $('div.zwgk-right .zwxxkg-result tr')
38
- .toArray()
39
- .slice(1)
40
- .map((item) => {
41
- item = $(item);
42
-
43
- return {
44
- title: item.find('a').text().replace(/^\s*/, ''),
45
- link: rootUrl + item.find('a').attr('href'),
46
- data: item.find('td:last').text(),
47
- };
48
- });
49
-
50
- items = await Promise.all(
51
- items.map((item) =>
52
- cache.tryGet(item.link, async () => {
53
- const detailResponse = await got({
54
- method: 'get',
55
- url: item.link,
56
- });
57
-
58
- const content = load(detailResponse.data);
59
- content('[class$="top"]').remove();
60
- item.description = content('.zwgkbg').html();
61
- item.pubDate = parseDate(item.data);
62
-
63
- return item;
64
- })
65
- )
66
- );
67
-
68
- return {
69
- title: '国家发展改革委 - 政府信息公开',
70
- link: homeUrl,
71
- item: items,
72
- };
73
- }