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
@@ -68,7 +68,7 @@ async function handler(ctx) {
68
68
 
69
69
  for (const i of item.items) {
70
70
  const newPubDate = new Date(i.publish_time);
71
- pubDate = pubDate > newPubDate ? pubDate : newPubDate;
71
+ pubDate = Math.max(pubDate, newPubDate);
72
72
  description += `<a href="${rootUrl}/zaixianke/content.html?id=${i.id}">${i.title}</a><br>`;
73
73
  }
74
74
 
@@ -1,24 +1,19 @@
1
1
  import { Route } from '@/types';
2
- import { getCurrentPath } from '@/utils/helpers';
3
- const __dirname = getCurrentPath(import.meta.url);
4
-
5
- import cache from '@/utils/cache';
6
2
  import got from '@/utils/got';
3
+
7
4
  import { load } from 'cheerio';
8
5
  import { parseDate } from '@/utils/parse-date';
9
- import { art } from '@/utils/render';
10
- import path from 'node:path';
11
6
 
12
7
  const sorts = {
13
- hot: '热门',
14
- last: '最近',
8
+ featured: '精选',
9
+ all: '全部',
15
10
  };
16
11
 
17
12
  export const route: Route = {
18
- path: ['/article/:sort?/:id?'],
13
+ path: ['/home/:sort?/:id?'],
19
14
  categories: ['programming'],
20
- example: '/hellogithub/article',
21
- parameters: { sort: '排序方式,见下表,默认为 `hot`,即热门', id: '标签 id,可在对应标签页 URL 中找到,默认为全部标签' },
15
+ example: '/hellogithub/home',
16
+ parameters: { sort: '排序方式,见下表,默认为 `featured`,即精选', id: '标签 id,可在对应标签页 URL 中找到,默认为全部标签' },
22
17
  features: {
23
18
  requireConfig: false,
24
19
  requirePuppeteer: false,
@@ -27,16 +22,16 @@ export const route: Route = {
27
22
  supportPodcast: false,
28
23
  supportScihub: false,
29
24
  },
30
- name: '文章',
25
+ name: '开源项目',
31
26
  maintainers: ['moke8', 'nczitzk'],
32
27
  handler,
33
- description: `| 热门 | 最近 |
28
+ description: `| 精选 | 全部 |
34
29
  | ---- | ---- |
35
- | hot | last |`,
30
+ | featured | all |`,
36
31
  };
37
32
 
38
33
  async function handler(ctx) {
39
- const sort = ctx.req.param('sort') ?? 'hot';
34
+ const sort = ctx.req.param('sort') ?? 'featured';
40
35
  const id = ctx.req.param('id') ?? '';
41
36
  const limit = ctx.req.query('limit') ? Number.parseInt(ctx.req.query('limit')) : 20;
42
37
 
@@ -50,7 +45,7 @@ async function handler(ctx) {
50
45
  url: apiUrl,
51
46
  });
52
47
 
53
- let buildId, tag;
48
+ let tag;
54
49
  if (id) {
55
50
  const tagUrl = `${rootUrl}/tags/${id}`;
56
51
 
@@ -62,66 +57,21 @@ async function handler(ctx) {
62
57
  const $ = load(tagResponse.data);
63
58
 
64
59
  tag = $('meta[property="og:title"]')?.attr('content')?.split(' ').pop();
65
- buildId = tagResponse.data.match(/"buildId":"(.*?)",/)[1];
66
- }
67
-
68
- if (!buildId) {
69
- const buildResponse = await got({
70
- method: 'get',
71
- url: rootUrl,
72
- });
73
-
74
- buildId = buildResponse.data.match(/"buildId":"(.*?)",/)[1];
75
60
  }
76
61
 
77
- let items = response.data.data.slice(0, limit).map((item) => ({
62
+ const items = response.data.data.slice(0, limit).map((item) => ({
78
63
  guid: item.item_id,
79
- title: item.title,
64
+ title: `${item.name}: ${item.title}`,
80
65
  author: item.author,
81
66
  link: `${rootUrl}/repository/${item.item_id}`,
82
- description: item.description,
83
67
  pubDate: parseDate(item.updated_at),
68
+ name: `${item.author}/${item.name}`,
69
+ summary: item.summary,
70
+ language: item.primary_lang,
84
71
  }));
85
72
 
86
- items = await Promise.all(
87
- items.map((item) =>
88
- cache.tryGet(item.link, async () => {
89
- const detailUrl = `${rootUrl}/_next/data/${buildId}/repository/${item.guid}.json`;
90
-
91
- const detailResponse = await got({
92
- method: 'get',
93
- url: detailUrl,
94
- });
95
-
96
- const data = detailResponse.data.pageProps.repo;
97
-
98
- item.title = `${data.name}: ${data.title}`;
99
- item.category = [`No.${data.volume_name}`, ...data.tags.map((t) => t.name)];
100
- item.description = art(path.join(__dirname, 'templates/description.art'), {
101
- name: data.full_name,
102
- description: data.description,
103
- summary: data.summary,
104
- image: data.image_url,
105
- stars: data.stars ?? data.stars_str,
106
- isChinese: data.has_chinese,
107
- language: data.primary_lang,
108
- isActive: data.is_active,
109
- license: data.license,
110
- isOrganization: data.is_org,
111
- forks: data.forks,
112
- openIssues: data.open_issues,
113
- subscribers: data.subscribers,
114
- homepage: data.homepage,
115
- url: data.url,
116
- });
117
-
118
- return item;
119
- })
120
- )
121
- );
122
-
123
73
  return {
124
- title: `HelloGithub - ${sorts[sort]}${tag || ''}项目`,
74
+ title: `HelloGithub - ${sorts[sort]}${tag || ''}开源项目`,
125
75
  link: currentUrl,
126
76
  item: items,
127
77
  };
@@ -39,7 +39,7 @@ async function handler(ctx) {
39
39
 
40
40
  const buildId = buildResponse.data.match(/"buildId":"(.*?)",/)[1];
41
41
 
42
- const apiUrl = `${rootUrl}/_next/data/${buildId}/report/${type}.json`;
42
+ const apiUrl = `${rootUrl}/_next/data/${buildId}/zh/report/${type}.json`;
43
43
 
44
44
  const response = await got({
45
45
  method: 'get',
@@ -1,4 +1,4 @@
1
- import { Route } from '@/types';
1
+ import type { Data, DataItem, Route } from '@/types';
2
2
  import cache from '@/utils/cache';
3
3
  import got from '@/utils/got';
4
4
  import { load } from 'cheerio';
@@ -23,51 +23,45 @@ export const route: Route = {
23
23
  },
24
24
  ],
25
25
  name: 'Hex-Rays News',
26
- maintainers: ['hellodword ', 'TonyRL'],
26
+ maintainers: ['hellodword ', 'TonyRL', 'Mas0n'],
27
27
  handler,
28
28
  url: 'hex-rays.com/',
29
29
  };
30
30
 
31
- async function handler() {
32
- const link = 'https://www.hex-rays.com/blog/';
31
+ async function handler(/* ctx*/): Promise<Data> {
32
+ const link = 'https://hex-rays.com/blog/';
33
33
  const response = await got.get(link);
34
34
  const $ = load(response.data);
35
35
 
36
- const list = $('.post-list-container')
37
- .map((_, ele) => ({
38
- title: $('h3 > a', ele).text(),
39
- link: $('h3 > a', ele).attr('href'),
40
- pubDate: parseDate($('.post-meta:nth-of-type(1)', ele).first().text().trim().replace('Posted on:', '')),
41
- author: $('.post-meta:nth-of-type(2)', ele).first().text().replace('By:', '').trim(),
42
- }))
43
- .get();
36
+ const list: DataItem[] = $('.article ')
37
+ .toArray()
38
+ .map(
39
+ (ele): DataItem => ({
40
+ title: $('h2 > a', ele).text(),
41
+ link: $('h2 > a', ele).attr('href'),
42
+ pubDate: parseDate($('div.by-line > time', ele).attr('datetime')!),
43
+ author: $('div.by-line > a', ele).text(),
44
+ })
45
+ );
44
46
 
45
- const items = await Promise.all(
46
- list.map((item) =>
47
- cache.tryGet(item.link, async () => {
47
+ const items: DataItem[] = await Promise.all(
48
+ list.map((item: DataItem) =>
49
+ cache.tryGet(item.link!, async () => {
48
50
  const detailResponse = await got.get(item.link);
49
51
  const content = load(detailResponse.data);
50
-
51
- item.category = (
52
- content('.category-link')
53
- .toArray()
54
- .map((e) => $(e).text()) +
55
- ',' +
56
- content('.tag-link')
57
- .toArray()
58
- .map((e) => $(e).text())
59
- ).split(',');
60
-
61
- item.description = content('.post-content').html();
62
-
52
+ item.category = content('.div.topics > a')
53
+ .toArray()
54
+ .map((ele) => content(ele).text());
55
+ item.description = content('.post-body').toString();
63
56
  return item;
64
57
  })
65
- )
58
+ ) as Promise<DataItem>[]
66
59
  );
67
60
 
68
61
  return {
69
62
  title: 'Hex-Rays Blog',
70
63
  link,
71
64
  item: items,
65
+ image: 'https://hex-rays.com/hubfs/Ico-logo.png',
72
66
  };
73
67
  }
@@ -0,0 +1,43 @@
1
+ import { Route } from '@/types';
2
+ import parseList from './utils';
3
+
4
+ export const route: Route = {
5
+ path: '/hf/notice/:type?',
6
+ categories: ['university'],
7
+ example: '/hfut/hf/notice/tzgg',
8
+ parameters: { type: '分类,见下表(默认为 `tzgg`)' },
9
+ features: {
10
+ requireConfig: false,
11
+ requirePuppeteer: false,
12
+ antiCrawler: false,
13
+ supportBT: false,
14
+ supportPodcast: false,
15
+ supportRadar: true,
16
+ supportScihub: false,
17
+ },
18
+ radar: [
19
+ {
20
+ source: ['news.hfut.edu.cn'],
21
+ },
22
+ ],
23
+ name: '合肥校区通知',
24
+ maintainers: ['batemax'],
25
+ handler,
26
+ description: `| 通知公告(https://news.hfut.edu.cn/tzgg2.htm) | 教学科研(https://news.hfut.edu.cn/tzgg2/jxky.htm) | 其他通知(https://news.hfut.edu.cn/tzgg2/qttz.htm) |
27
+ | ------------ | -------------- | ------------------ |
28
+ | tzgg | jxky | qttz |`,
29
+ };
30
+
31
+ async function handler(ctx) {
32
+ // set default router type
33
+ const type = ctx.req.param('type') ?? 'tzgg';
34
+
35
+ const { link, title, resultList } = await parseList(ctx, type);
36
+
37
+ return {
38
+ title,
39
+ link,
40
+ description: '合肥工业大学 - 通知公告',
41
+ item: resultList,
42
+ };
43
+ }
@@ -0,0 +1,80 @@
1
+ import cache from '@/utils/cache';
2
+ import got from '@/utils/got';
3
+ import { load } from 'cheerio';
4
+ import { parseDate } from '@/utils/parse-date';
5
+
6
+ const typeMap = {
7
+ tzgg: { name: 'tzgg', url: 'https://news.hfut.edu.cn/tzgg2.htm', root: 'https://news.hfut.edu.cn', title: '合肥工业大学 - 通知公告' },
8
+ jxky: { name: 'jxky', url: 'https://news.hfut.edu.cn/tzgg2.htm', root: 'https://news.hfut.edu.cn', title: '合肥工业大学 - 通知公告 - 教学科研' },
9
+ qttz: { name: 'qttz', url: 'https://news.hfut.edu.cn/tzgg2.htm', root: 'https://news.hfut.edu.cn', title: '合肥工业大学 - 通知公告 - 其它通知' },
10
+ };
11
+
12
+ const commLink = 'https://news.hfut.edu.cn/';
13
+
14
+ const parseList = async (ctx, type) => {
15
+ const link = typeMap[type].url;
16
+ const title = typeMap[type].title;
17
+
18
+ const response = await got(link);
19
+ const $ = load(response.data);
20
+
21
+ const resultList = await parseArticle(typeMap[type].name, $);
22
+
23
+ return {
24
+ title,
25
+ link,
26
+ resultList,
27
+ };
28
+ };
29
+
30
+ async function parseArticle(type, $) {
31
+ let data = $('#tzz').find('li').toArray();
32
+
33
+ if (type === 'jxky') {
34
+ data = $('#c01').find('li').toArray();
35
+ } else if (type === 'qttz') {
36
+ data = $('#c02').find('li').toArray();
37
+ }
38
+
39
+ const items = data.map((item) => {
40
+ item = $(item);
41
+ const oriLink = item.find('a').attr('href');
42
+ let linkRes = oriLink;
43
+ if (!oriLink.startsWith('http')) {
44
+ linkRes = commLink + item.find('a').attr('href');
45
+ }
46
+ const pubDate = parseDate(item.find('i').text(), 'YYYY-MM-DD');
47
+
48
+ return {
49
+ title: item.find('p').text(),
50
+ pubDate,
51
+ link: linkRes,
52
+ };
53
+ });
54
+
55
+ const resultItems = await Promise.all(
56
+ items.map((item) =>
57
+ cache.tryGet(item.link, async () => {
58
+ let description;
59
+ try {
60
+ const response = await got(item.link);
61
+ const $ = load(response.data);
62
+ description = $('.wp_articlecontent').html() ?? $('.v_news_content').html() ?? item.link;
63
+ } catch {
64
+ description = item.link;
65
+ }
66
+
67
+ return {
68
+ title: item.title,
69
+ link: item.link,
70
+ description,
71
+ pubDate: item.pubDate,
72
+ };
73
+ })
74
+ )
75
+ );
76
+
77
+ return resultItems;
78
+ }
79
+
80
+ export default parseList;
@@ -0,0 +1,6 @@
1
+ import type { Namespace } from '@/types';
2
+
3
+ export const namespace: Namespace = {
4
+ name: '合肥工业大学',
5
+ url: 'hfut.edu.cn',
6
+ };
@@ -0,0 +1,43 @@
1
+ import { Route } from '@/types';
2
+ import parseList from './utils';
3
+
4
+ export const route: Route = {
5
+ path: '/xc/notice/:type?',
6
+ categories: ['university'],
7
+ example: '/hfut/xc/notice/tzgg',
8
+ parameters: { type: '分类,见下表(默认为 `tzgg`)' },
9
+ features: {
10
+ requireConfig: false,
11
+ requirePuppeteer: false,
12
+ antiCrawler: false,
13
+ supportBT: false,
14
+ supportPodcast: false,
15
+ supportRadar: true,
16
+ supportScihub: false,
17
+ },
18
+ radar: [
19
+ {
20
+ source: ['xc.hfut.edu.cn'],
21
+ },
22
+ ],
23
+ name: '宣城校区通知',
24
+ maintainers: ['batemax'],
25
+ handler,
26
+ description: `| 通知公告(https://xc.hfut.edu.cn/1955/list.htm) | 院系动态-工作通知(https://xc.hfut.edu.cn/gztz/list.htm) |
27
+ | ------------ | -------------- |
28
+ | tzgg | gztz |`,
29
+ };
30
+
31
+ async function handler(ctx) {
32
+ // set default router type
33
+ const type = ctx.req.param('type') ?? 'tzgg';
34
+
35
+ const { link, title, resultList } = await parseList(ctx, type);
36
+
37
+ return {
38
+ title,
39
+ link,
40
+ description: '合肥工业大学宣城校区 - 通知公告',
41
+ item: resultList,
42
+ };
43
+ }
@@ -0,0 +1,73 @@
1
+ import cache from '@/utils/cache';
2
+ import got from '@/utils/got';
3
+ import { load } from 'cheerio';
4
+ import { parseDate } from '@/utils/parse-date';
5
+
6
+ const typeMap = {
7
+ tzgg: { name: 'tzgg', url: 'https://xc.hfut.edu.cn/1955/list.htm', root: 'https://xc.hfut.edu.cn', title: '合肥工业大学宣城校区 - 通知公告' },
8
+ gztz: { name: 'gztz', url: 'https://xc.hfut.edu.cn/gztz/list.htm', root: 'https://xc.hfut.edu.cn', title: '合肥工业大学宣城校区 - 院系动态 - 工作通知' },
9
+ };
10
+
11
+ const commLink = 'https://xc.hfut.edu.cn/';
12
+
13
+ const parseList = async (ctx, type) => {
14
+ const link = typeMap[type].url;
15
+ const title = typeMap[type].title;
16
+
17
+ const response = await got(link);
18
+ const $ = load(response.data);
19
+
20
+ const resultList = await parseArticle($);
21
+
22
+ return {
23
+ title,
24
+ link,
25
+ resultList,
26
+ };
27
+ };
28
+
29
+ async function parseArticle($) {
30
+ const data = $('#wp_news_w6').find('li').toArray();
31
+
32
+ const items = data.map((item) => {
33
+ item = $(item);
34
+ const oriLink = item.find('a').attr('href');
35
+ let linkRes = oriLink;
36
+ if (!oriLink.startsWith('http')) {
37
+ linkRes = commLink + item.find('a').attr('href');
38
+ }
39
+ const pubDate = parseDate(item.find('.news_meta').text(), 'YYYY-MM-DD');
40
+
41
+ return {
42
+ title: item.find('a').attr('title'),
43
+ pubDate,
44
+ link: linkRes,
45
+ };
46
+ });
47
+
48
+ const resultItems = await Promise.all(
49
+ items.map((item) =>
50
+ cache.tryGet(item.link, async () => {
51
+ let description;
52
+ try {
53
+ const response = await got(item.link);
54
+ const $ = load(response.data);
55
+ description = $('.wp_articlecontent').html() ?? $('.v_news_content').html() ?? item.link;
56
+ } catch {
57
+ description = item.link;
58
+ }
59
+
60
+ return {
61
+ title: item.title,
62
+ link: item.link,
63
+ description,
64
+ pubDate: item.pubDate,
65
+ };
66
+ })
67
+ )
68
+ );
69
+
70
+ return resultItems;
71
+ }
72
+
73
+ export default parseList;
@@ -0,0 +1,56 @@
1
+ import { Route } from '@/types';
2
+ import ofetch from '@/utils/ofetch';
3
+ import { load } from 'cheerio';
4
+ import { parseDate } from '@/utils/parse-date';
5
+ import timezone from '@/utils/timezone';
6
+
7
+ export const route: Route = {
8
+ path: '/earthquake',
9
+ name: '全球地震資訊網',
10
+ maintainers: ['after9'],
11
+ handler,
12
+ example: '/hko/earthquake',
13
+ categories: ['forecast'],
14
+ description: '来自香港天文台的全球5级以上地震记录',
15
+ };
16
+
17
+ async function handler() {
18
+ const title = '来自香港天文台的全球5级以上地震记录';
19
+ const link = 'https://www.hko.gov.hk/tc/gts/equake/quake-info.htm';
20
+ const description = '提供經天文台分析的全球5.0級或以上及本地有感的地震資訊。';
21
+
22
+ // 发送 HTTP GET 请求到 API 并解构返回的数据对象
23
+ const response = await ofetch('https://www.hko.gov.hk/gts/QEM/eq_app-30d_uc.xml', {
24
+ headers: {
25
+ accept: 'application/xml',
26
+ },
27
+ });
28
+
29
+ const $ = load(response);
30
+
31
+ const items = $('Earthquake > EventGroup > Event')
32
+ // 使用“toArray()”方法将选择的所有 DOM 元素以数组的形式返回。
33
+ .toArray()
34
+ // 使用“map()”方法遍历数组,并从每个元素中解析需要的数据。
35
+ .map((item) => {
36
+ item = $(item);
37
+ const degree = item.find('Mag').text();
38
+ const city = item.find('City').text();
39
+ const citystring = item.find('citystring').text();
40
+ const hktDate = item.find('HKTDate').text();
41
+ const hktTime = item.find('HKTTime').text();
42
+ const latAndLon = '經緯:[' + item.find('Lat').text() + ',' + item.find('Lon').text() + ']';
43
+ return {
44
+ title: `[震級:${degree}] [地點:${city}]`,
45
+ description: `${citystring}, ${latAndLon}`,
46
+ pubDate: timezone(parseDate(hktDate + hktTime, 'YYYYMMDDHHMM'), +8),
47
+ };
48
+ });
49
+
50
+ return {
51
+ title,
52
+ link,
53
+ description,
54
+ item: items,
55
+ };
56
+ }
@@ -0,0 +1,8 @@
1
+ import type { Namespace } from '@/types';
2
+
3
+ export const namespace: Namespace = {
4
+ name: 'Hong Kong Observatory',
5
+ url: 'www.hko.gov.hk',
6
+ categories: ['forecast'],
7
+ description: '来自香港天文台的全球地震记录',
8
+ };
@@ -0,0 +1,56 @@
1
+ import type { Route } from '@/types';
2
+ import ofetch from '@/utils/ofetch';
3
+ import * as cheerio from 'cheerio';
4
+ import { parseDate } from '@/utils/parse-date';
5
+
6
+ const handler = async () => {
7
+ const url = 'http://rss.weather.gov.hk/rss/CurrentWeather.xml';
8
+ const pageUrl = 'https://www.weather.gov.hk/en/wxinfo/currwx/current.htm';
9
+
10
+ const data = await ofetch(url);
11
+ const $ = cheerio.load(data, {
12
+ xmlMode: true,
13
+ });
14
+
15
+ const description = $('item').first().find('description');
16
+
17
+ const $$ = cheerio.load(description.text());
18
+
19
+ const items = $$('table tr')
20
+ .toArray()
21
+ .map((item) => {
22
+ const $item = $(item);
23
+ const area = $item.find('td').first().text();
24
+ const degree = $item.find('td').last().text();
25
+
26
+ return {
27
+ title: area,
28
+ description: degree,
29
+ pubDate: parseDate($('pubDate').text()),
30
+ link: pageUrl,
31
+ guid: `${$('guid').text()}#${area}`,
32
+ };
33
+ });
34
+
35
+ return {
36
+ title: 'Current Weather Report',
37
+ description: `provided by the Hong Kong Observatory: ${$('pubDate').text()}`,
38
+ link: pageUrl,
39
+ item: items,
40
+ };
41
+ };
42
+
43
+ export const route: Route = {
44
+ path: '/weather',
45
+ radar: [
46
+ {
47
+ source: ['www.weather.gov.hk/en/wxinfo/currwx/current.htm'],
48
+ },
49
+ ],
50
+ name: 'Current Weather Report',
51
+ example: '/hko/weather',
52
+ maintainers: ['calpa'],
53
+ categories: ['forecast'],
54
+ handler,
55
+ url: 'www.weather.gov.hk/en/wxinfo/currwx/current.htm',
56
+ };
@@ -47,7 +47,7 @@ async function handler() {
47
47
  title: item.blog.title,
48
48
  link: `https://huggingface.co${item.link}`,
49
49
  category: item.blog.tags,
50
- pubDate: parseDate(item.blog.date),
50
+ pubDate: parseDate(item.blog.publishedAt),
51
51
  author: item.blog.author,
52
52
  }));
53
53