chuvsu-js 0.2.0 → 0.3.0
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.
- package/dist/lk/client.d.ts +3 -0
- package/dist/lk/client.js +15 -2
- package/dist/tt/client.d.ts +5 -0
- package/dist/tt/client.js +38 -6
- package/package.json +1 -1
package/dist/lk/client.d.ts
CHANGED
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
import type { PersonalData } from "./types.js";
|
|
2
2
|
export declare class LkClient {
|
|
3
3
|
private http;
|
|
4
|
+
private credentials;
|
|
4
5
|
login(opts: {
|
|
5
6
|
email: string;
|
|
6
7
|
password: string;
|
|
7
8
|
}): Promise<void>;
|
|
9
|
+
private isSessionExpired;
|
|
10
|
+
private authGet;
|
|
8
11
|
getPersonalData(): Promise<PersonalData>;
|
|
9
12
|
getGroupId(): Promise<number | null>;
|
|
10
13
|
}
|
package/dist/lk/client.js
CHANGED
|
@@ -6,14 +6,27 @@ const LOGIN_URL = `${BASE}/info/login.php`;
|
|
|
6
6
|
const STUDENT_BASE = `${BASE}/student`;
|
|
7
7
|
export class LkClient {
|
|
8
8
|
http = new HttpClient();
|
|
9
|
+
credentials = null;
|
|
9
10
|
async login(opts) {
|
|
10
11
|
const res = await this.http.post(LOGIN_URL, { email: opts.email, password: opts.password, role: "1", enter: "" }, false);
|
|
11
12
|
if (!(res.status === 302 && res.location?.includes("student"))) {
|
|
12
13
|
throw new AuthError("LK login failed");
|
|
13
14
|
}
|
|
15
|
+
this.credentials = opts;
|
|
16
|
+
}
|
|
17
|
+
isSessionExpired(body) {
|
|
18
|
+
return body.includes("login.php");
|
|
19
|
+
}
|
|
20
|
+
async authGet(url) {
|
|
21
|
+
const res = await this.http.get(url);
|
|
22
|
+
if (this.credentials && this.isSessionExpired(res.body)) {
|
|
23
|
+
await this.login(this.credentials);
|
|
24
|
+
return this.http.get(url);
|
|
25
|
+
}
|
|
26
|
+
return res;
|
|
14
27
|
}
|
|
15
28
|
async getPersonalData() {
|
|
16
|
-
const { body } = await this.
|
|
29
|
+
const { body } = await this.authGet(`${STUDENT_BASE}/personal_data.php`);
|
|
17
30
|
const vals = extractScriptValues(body, "form_personal_data");
|
|
18
31
|
return {
|
|
19
32
|
lastName: vals.fam ?? "",
|
|
@@ -32,7 +45,7 @@ export class LkClient {
|
|
|
32
45
|
};
|
|
33
46
|
}
|
|
34
47
|
async getGroupId() {
|
|
35
|
-
const { body } = await this.
|
|
48
|
+
const { body } = await this.authGet(`${STUDENT_BASE}/tt.php`);
|
|
36
49
|
const match = body.match(/tt\.chuvsu\.ru\/index\/grouptt\/gr\/(\d+)/);
|
|
37
50
|
return match ? parseInt(match[1]) : null;
|
|
38
51
|
}
|
package/dist/tt/client.d.ts
CHANGED
|
@@ -5,6 +5,7 @@ export declare class TtClient {
|
|
|
5
5
|
private http;
|
|
6
6
|
private educationType;
|
|
7
7
|
private cache;
|
|
8
|
+
private loginMode;
|
|
8
9
|
constructor(opts?: TtClientOptions);
|
|
9
10
|
private get pertt();
|
|
10
11
|
clearCache(category?: keyof CacheConfig): void;
|
|
@@ -15,6 +16,10 @@ export declare class TtClient {
|
|
|
15
16
|
password: string;
|
|
16
17
|
}): Promise<void>;
|
|
17
18
|
loginAsGuest(): Promise<void>;
|
|
19
|
+
private isSessionExpired;
|
|
20
|
+
private relogin;
|
|
21
|
+
private authGet;
|
|
22
|
+
private authPost;
|
|
18
23
|
getGroupSchedule(opts: {
|
|
19
24
|
groupId: number;
|
|
20
25
|
period?: Period;
|
package/dist/tt/client.js
CHANGED
|
@@ -9,6 +9,7 @@ export class TtClient {
|
|
|
9
9
|
http = new HttpClient();
|
|
10
10
|
educationType;
|
|
11
11
|
cache;
|
|
12
|
+
loginMode = null;
|
|
12
13
|
constructor(opts) {
|
|
13
14
|
this.educationType = opts?.educationType ?? 1 /* EducationType.HigherEducation */;
|
|
14
15
|
if (opts?.cache == null) {
|
|
@@ -51,12 +52,43 @@ export class TtClient {
|
|
|
51
52
|
if (res.status !== 302) {
|
|
52
53
|
throw new AuthError("TT login failed");
|
|
53
54
|
}
|
|
55
|
+
this.loginMode = { type: "credentials", ...opts };
|
|
54
56
|
}
|
|
55
57
|
async loginAsGuest() {
|
|
56
58
|
const res = await this.http.post(AUTH_URL, { guest: "Войти гостем", hfac: "0", pertt: this.pertt }, false);
|
|
57
59
|
if (res.status !== 302) {
|
|
58
60
|
throw new AuthError("TT guest login failed");
|
|
59
61
|
}
|
|
62
|
+
this.loginMode = { type: "guest" };
|
|
63
|
+
}
|
|
64
|
+
isSessionExpired(body) {
|
|
65
|
+
return body.includes('name="wname"');
|
|
66
|
+
}
|
|
67
|
+
async relogin() {
|
|
68
|
+
if (!this.loginMode)
|
|
69
|
+
return;
|
|
70
|
+
if (this.loginMode.type === "credentials") {
|
|
71
|
+
await this.login(this.loginMode);
|
|
72
|
+
}
|
|
73
|
+
else {
|
|
74
|
+
await this.loginAsGuest();
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
async authGet(url) {
|
|
78
|
+
const res = await this.http.get(url);
|
|
79
|
+
if (this.loginMode && this.isSessionExpired(res.body)) {
|
|
80
|
+
await this.relogin();
|
|
81
|
+
return this.http.get(url);
|
|
82
|
+
}
|
|
83
|
+
return res;
|
|
84
|
+
}
|
|
85
|
+
async authPost(url, data) {
|
|
86
|
+
const res = await this.http.post(url, data);
|
|
87
|
+
if (this.loginMode && this.isSessionExpired(res.body)) {
|
|
88
|
+
await this.relogin();
|
|
89
|
+
return this.http.post(url, data);
|
|
90
|
+
}
|
|
91
|
+
return res;
|
|
60
92
|
}
|
|
61
93
|
// --- Schedule ---
|
|
62
94
|
async getGroupSchedule(opts) {
|
|
@@ -67,10 +99,10 @@ export class TtClient {
|
|
|
67
99
|
const url = `${BASE}/index/grouptt/gr/${opts.groupId}`;
|
|
68
100
|
let body;
|
|
69
101
|
if (opts.period !== undefined) {
|
|
70
|
-
({ body } = await this.
|
|
102
|
+
({ body } = await this.authPost(url, { htype: String(opts.period) }));
|
|
71
103
|
}
|
|
72
104
|
else {
|
|
73
|
-
({ body } = await this.
|
|
105
|
+
({ body } = await this.authGet(url));
|
|
74
106
|
}
|
|
75
107
|
const data = parseFullSchedule(body);
|
|
76
108
|
this.cache?.set("schedule", cacheKey, data);
|
|
@@ -193,7 +225,7 @@ export class TtClient {
|
|
|
193
225
|
const cached = this.cache?.get("faculties", "all");
|
|
194
226
|
if (cached)
|
|
195
227
|
return cached;
|
|
196
|
-
const { body } = await this.
|
|
228
|
+
const { body } = await this.authGet(`${BASE}/`);
|
|
197
229
|
const data = parseFacultyButtons(body);
|
|
198
230
|
this.cache?.set("faculties", "all", data);
|
|
199
231
|
return data;
|
|
@@ -203,7 +235,7 @@ export class TtClient {
|
|
|
203
235
|
const cached = this.cache?.get("groups", cacheKey);
|
|
204
236
|
if (cached)
|
|
205
237
|
return cached;
|
|
206
|
-
const { body } = await this.
|
|
238
|
+
const { body } = await this.authPost(`${BASE}/`, {
|
|
207
239
|
hfac: String(opts.facultyId),
|
|
208
240
|
pertt: this.pertt,
|
|
209
241
|
});
|
|
@@ -212,7 +244,7 @@ export class TtClient {
|
|
|
212
244
|
return data;
|
|
213
245
|
}
|
|
214
246
|
async searchGroup(opts) {
|
|
215
|
-
const { body } = await this.
|
|
247
|
+
const { body } = await this.authPost(`${BASE}/`, {
|
|
216
248
|
grname: opts.name,
|
|
217
249
|
findgr: "найти",
|
|
218
250
|
hfac: "0",
|
|
@@ -221,7 +253,7 @@ export class TtClient {
|
|
|
221
253
|
return parseGroupButtons(body);
|
|
222
254
|
}
|
|
223
255
|
async searchTeacher(opts) {
|
|
224
|
-
const { body } = await this.
|
|
256
|
+
const { body } = await this.authPost(`${BASE}/`, {
|
|
225
257
|
techname: opts.name,
|
|
226
258
|
findtech: "найти",
|
|
227
259
|
hfac: "0",
|