/
dean.ts
91 lines (78 loc) · 2.65 KB
/
dean.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
import { Route, Data, DataItem } from '@/types';
import cache from '@/utils/cache';
import ofetch from '@/utils/ofetch';
import { load } from 'cheerio';
import { parseDate } from '@/utils/parse-date';
import timezone from '@/utils/timezone';
const parseContent = (htmlString) => {
const $ = load(htmlString);
const info = $('.detail_main_content > h1')
.contents()
.filter(function () {
return this.nodeType === 3;
})
.map(function () {
return $(this).text().trim();
})
.get();
const content = $('[id^="vsb_content"]');
$('form > div > ul a').each(function () {
$(this).appendTo(content);
$('<br>').appendTo(content);
});
return {
author: info[0] || '教务处',
description: content.html(),
};
};
export const route: Route = {
path: '/dean/:subpath{.+}',
name: '教务处',
maintainers: ['hoilc'],
example: '/xjtu/dean/jxxx/jxtz2',
description: '打开一个类似 <https://dean.xjtu.edu.cn/jxxx/jxtz2.htm> 的网址,在 `.cn` 后的内容就是 subpath,此例中是 `jxxx/jxtz2`',
handler,
};
async function handler(ctx) {
const subpath = ctx.req.param('subpath');
const url = `http://dean.xjtu.edu.cn/${subpath.replaceAll('.htm', '')}.htm`;
const base = url.split('/').slice(0, -1).join('/');
const list_response = await ofetch(url);
const $ = load(list_response);
const subName = $('#ny-main > div.ny-tit > div > span')
.toArray()
.map((item) => $(item).text())
.join(' - ');
const list = $('#ny-main > div.ny.wp > ul > li')
.toArray()
.map((item: any) => {
item = $(item);
const title = item.find('a').text();
const link = new URL(item.find('a').attr('href'), base).href;
return {
title,
link,
pubDate: timezone(parseDate(item.find('span').text(), 'YYYY-MM-DD'), +8),
};
});
const out = await Promise.all(
list.map((item: DataItem) =>
cache.tryGet(item.link!, async () => {
try {
const response = await ofetch(item.link!);
const result = parseContent(response);
item.description = result.description ?? undefined;
item.author = result.author;
} catch {
return item;
}
return item;
})
)
);
return {
title: `西安交大教务处 - ${subName}`,
link: url,
item: out.filter((item) => item !== ''),
} as Data;
}