Skip to content

Commit c2a1c58

Browse files
committed
整理
1 parent 0ff36d9 commit c2a1c58

File tree

15 files changed

+220
-164
lines changed

15 files changed

+220
-164
lines changed

browser/index.ts

Lines changed: 43 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
import { getDreamCampusTimetable } from '../src/dreamCampus.js';
1+
import { getDreamCampusTimetable } from '../src/dreamCampus/index.js';
2+
import type { WebViewMessage } from '../src/schemas/index.js';
23

34
declare global {
45
interface Window {
@@ -8,6 +9,44 @@ declare global {
89
}
910
}
1011

11-
window.ReactNativeWebView?.postMessage(
12-
JSON.stringify({ type: 'timetable', data: getDreamCampusTimetable() }),
13-
);
12+
(() => {
13+
try {
14+
if (
15+
location.href ===
16+
'https://kyomu.office.tut.ac.jp/portal/StudentApp/Top.aspx'
17+
) {
18+
window.ReactNativeWebView?.postMessage(
19+
JSON.stringify({ type: 'loading' } satisfies WebViewMessage),
20+
);
21+
(
22+
document.querySelector<HTMLAnchorElement>(
23+
'#ctl00_bhHeader_ctl350_lnk',
24+
) ??
25+
document.querySelector<HTMLAnchorElement>('#ctl00_bhHeader_ctl33_lnk')
26+
)?.click();
27+
}
28+
29+
if (
30+
location.href ===
31+
'https://kyomu.office.tut.ac.jp/portal/StudentApp/Blank.aspx#regist_results'
32+
) {
33+
document
34+
.querySelector<HTMLAnchorElement>('#ctl00_bhHeader_ctl47_lnk')
35+
?.click();
36+
}
37+
38+
if (
39+
location.href ===
40+
'https://kyomu.office.tut.ac.jp/portal/StudentApp/Regist/RegistList.aspx'
41+
) {
42+
const data = getDreamCampusTimetable();
43+
window.ReactNativeWebView?.postMessage(
44+
JSON.stringify({ type: 'successful', data } satisfies WebViewMessage),
45+
);
46+
}
47+
} catch {
48+
window.ReactNativeWebView?.postMessage(
49+
JSON.stringify({ type: 'failed' } satisfies WebViewMessage),
50+
);
51+
}
52+
})();

src/dreamCampus.ts

Lines changed: 0 additions & 70 deletions
This file was deleted.

src/dreamCampus/getTextOrNull.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
export function getTextOrNull(element: Element | null) {
2+
const text = element?.textContent?.trim();
3+
return text ? text : null;
4+
}

src/dreamCampus/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export * from './timetable.js';

src/dreamCampus/subject.ts

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import type { DreamCampusSubject } from '../schemas/index.js';
2+
import { getTextOrNull } from './getTextOrNull.js';
3+
4+
export function getDreamCampusSubject(element: Element): DreamCampusSubject {
5+
return {
6+
lctCd: getTextOrNull(element.querySelector('span[id$="_lblLctCd"]')),
7+
reqName: getTextOrNull(element.querySelector('span[id$="_lblReqName"]')),
8+
credit: getTextOrNull(element.querySelector('span[id$="_lblCredit"]')),
9+
termName: getTextOrNull(element.querySelector('span[id$="_lblTermName"]')),
10+
sbjDivName: getTextOrNull(
11+
element.querySelector('span[id$="_lblSbjDivName"]'),
12+
),
13+
sbjName: getTextOrNull(element.querySelector('span[id$="_lblSbjName"]')),
14+
url:
15+
element.querySelector<HTMLAnchorElement>('span[id$="_lblSbjName"] > a')
16+
?.href ?? null,
17+
cancelName: getTextOrNull(
18+
element.querySelector('span[id$="_lblCancelName"]'),
19+
),
20+
staffName: getTextOrNull(
21+
element.querySelector('span[id$="_lblStaffName"]'),
22+
),
23+
adjustName: getTextOrNull(
24+
element.querySelector('span[id$="_lblLotAdjustName"]'),
25+
),
26+
lotResultName: getTextOrNull(
27+
element.querySelector('span[id$="_lblLotResultName"]'),
28+
),
29+
};
30+
}

src/dreamCampus/timetable.ts

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
import type { DreamCampusTimetable } from '../schemas/index.js';
2+
import { getTextOrNull } from './getTextOrNull.js';
3+
import { getDreamCampusSubject } from './subject.js';
4+
5+
export function getDreamCampusTimetable(): DreamCampusTimetable {
6+
const lang = document.querySelector<HTMLInputElement>(
7+
'#ctl00_bhHeader_slLanguage_imgBtnJpn',
8+
)?.disabled
9+
? 'ja'
10+
: document.querySelector<HTMLInputElement>(
11+
'#ctl00_bhHeader_slLanguage_imgBtnEng',
12+
)?.disabled
13+
? 'en'
14+
: null;
15+
16+
const belong = getTextOrNull(
17+
document.querySelector('#ctl00_bhHeader_lblBelong'),
18+
);
19+
20+
const term =
21+
document.querySelector<HTMLSelectElement>('#ctl00_phContents_ddlTerm')
22+
?.value === '1'
23+
? 'spring'
24+
: document.querySelector<HTMLSelectElement>('#ctl00_phContents_ddlTerm')
25+
?.value === '2'
26+
? 'fall'
27+
: null;
28+
29+
const lecture = [...document.querySelectorAll('#tblLecture > tbody > tr')]
30+
.slice(2)
31+
.map((row) =>
32+
[...row.querySelectorAll(':scope > td')]
33+
.slice(1)
34+
.map((col) =>
35+
[
36+
...col.querySelectorAll(':scope > div > div[id$="_divDetail"]'),
37+
].flatMap((element) => getDreamCampusSubject(element) ?? []),
38+
),
39+
);
40+
41+
const others = [...document.querySelectorAll('#tblOhters > tbody > tr')].map(
42+
(row) =>
43+
[...row.querySelectorAll(':scope > td')]
44+
.slice(1)
45+
.map((col) =>
46+
[
47+
...col.querySelectorAll(':scope > div > div[id$="_divDetail"]'),
48+
].flatMap((element) => getDreamCampusSubject(element) ?? []),
49+
),
50+
);
51+
52+
return {
53+
lang,
54+
belong,
55+
term,
56+
lecture,
57+
others,
58+
};
59+
}

src/index.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,2 @@
1-
export * from './dreamCampus.js';
21
export * from './schemas/index.js';
32
export * from './timetable.js';

src/schemas/dreamCampusTimetable.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,9 @@ import { z } from 'zod';
22
import { DreamCampusSubject } from './dreamCampusSubject.js';
33

44
export const DreamCampusTimetable = z.strictObject({
5+
lang: z.enum(['ja', 'en']).nullable(),
56
belong: z.string().nullable(),
6-
term: z.string().nullable(),
7+
term: z.enum(['spring', 'fall']).nullable(),
78
lecture: z.array(z.array(z.array(DreamCampusSubject)).length(6)).length(6),
89
others: z.array(z.array(z.array(DreamCampusSubject)).length(6)).length(3),
910
});

src/schemas/timetable.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,12 @@ import { z } from 'zod';
22
import { Subject } from './subject.js';
33

44
export const Timetable = z.strictObject({
5-
year: z.string(),
65
belong: z.string(),
7-
semester: z.enum(['spring', 'fall']),
8-
firstHalf: Subject.nullable().array().array(),
9-
secondHalf: Subject.nullable().array().array(),
10-
intensive: Subject.nullable().array().array(),
6+
year: z.string(),
7+
term: z.enum(['spring', 'fall']),
8+
firstHalf: z.array(z.array(Subject.nullable())),
9+
secondHalf: z.array(z.array(Subject.nullable())),
10+
intensive: z.array(z.array(Subject.nullable())),
1111
});
1212

1313
export type Timetable = z.infer<typeof Timetable>;

src/schemas/webViewMessage.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { z } from 'zod';
22

33
export const WebViewMessage = z.strictObject({
4-
type: z.string(),
4+
type: z.enum(['loading', 'successful', 'failed']),
55
data: z.unknown(),
66
});
77

0 commit comments

Comments
 (0)