chuvsu-js 4.2.0 → 5.0.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/README.md +165 -193
- package/dist/browser.d.ts +1 -1
- package/dist/browser.js +1 -1
- package/dist/common/cache.js +30 -9
- package/dist/common/http.d.ts +6 -0
- package/dist/common/http.js +8 -1
- package/dist/common/parse.d.ts +1 -1
- package/dist/common/parse.js +2 -2
- package/dist/common/types.d.ts +8 -2
- package/dist/common/types.js +12 -0
- package/dist/core.d.ts +10 -0
- package/dist/core.js +5 -0
- package/dist/index.d.ts +5 -3
- package/dist/index.js +4 -4
- package/dist/lk/client.d.ts +8 -6
- package/dist/lk/client.js +51 -23
- package/dist/lk/types.d.ts +7 -7
- package/dist/node.d.ts +1 -0
- package/dist/node.js +1 -0
- package/dist/parsers.d.ts +3 -0
- package/dist/parsers.js +2 -0
- package/dist/tt/client.d.ts +55 -63
- package/dist/tt/client.js +477 -226
- package/dist/tt/domain/directory.d.ts +14 -0
- package/dist/tt/domain/directory.js +116 -0
- package/dist/tt/domain/ids.d.ts +7 -0
- package/dist/tt/domain/ids.js +20 -0
- package/dist/tt/domain/index.d.ts +7 -0
- package/dist/tt/domain/index.js +5 -0
- package/dist/tt/domain/normalize.d.ts +7 -0
- package/dist/tt/domain/normalize.js +65 -0
- package/dist/tt/domain/repository.d.ts +51 -0
- package/dist/tt/domain/repository.js +805 -0
- package/dist/tt/domain/schedule.d.ts +37 -0
- package/dist/tt/domain/schedule.js +292 -0
- package/dist/tt/domain/types.d.ts +175 -0
- package/dist/tt/domain/types.js +1 -0
- package/dist/tt/observations.d.ts +11 -0
- package/dist/tt/observations.js +131 -0
- package/dist/tt/parse/audience.d.ts +3 -3
- package/dist/tt/parse/audience.js +47 -15
- package/dist/tt/parse/entry-parts.d.ts +1 -0
- package/dist/tt/parse/entry-parts.js +5 -2
- package/dist/tt/parse/full-schedule.d.ts +9 -4
- package/dist/tt/parse/full-schedule.js +32 -41
- package/dist/tt/parse/groups.d.ts +1 -1
- package/dist/tt/parse/groups.js +1 -1
- package/dist/tt/parse/index.d.ts +4 -4
- package/dist/tt/parse/index.js +4 -4
- package/dist/tt/parse/lists.d.ts +6 -5
- package/dist/tt/parse/lists.js +7 -2
- package/dist/tt/parse/overlays.d.ts +5 -4
- package/dist/tt/parse/overlays.js +13 -14
- package/dist/tt/parse/teacher.d.ts +2 -3
- package/dist/tt/parse/teacher.js +14 -56
- package/dist/tt/parse/webinars.js +3 -4
- package/dist/tt/types.d.ts +54 -69
- package/dist/tt/utils/date.d.ts +4 -0
- package/dist/tt/utils/date.js +30 -1
- package/dist/tt/utils/index.d.ts +2 -3
- package/dist/tt/utils/index.js +2 -3
- package/dist/tt/utils/period.d.ts +4 -4
- package/dist/tt/utils/period.js +9 -8
- package/dist/tt/utils/semester.d.ts +4 -4
- package/dist/tt/utils/semester.js +25 -5
- package/dist/tt/utils/time-slots.d.ts +3 -5
- package/dist/tt/utils/time-slots.js +19 -34
- package/dist/tt/webinars.d.ts +7 -0
- package/dist/tt/webinars.js +38 -0
- package/docs/fixture-review.md +56 -0
- package/docs/testing.md +23 -0
- package/docs/v5-architecture.md +144 -0
- package/docs/v5-migration.md +451 -0
- package/package.json +17 -7
- package/dist/shared.d.ts +0 -9
- package/dist/shared.js +0 -7
- package/dist/tt/schedule.d.ts +0 -55
- package/dist/tt/schedule.js +0 -233
- package/dist/tt/utils/lessons.d.ts +0 -16
- package/dist/tt/utils/lessons.js +0 -173
package/dist/common/types.d.ts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
export declare
|
|
1
|
+
export declare enum AcademicPeriod {
|
|
2
2
|
FallSemester = 1,
|
|
3
3
|
WinterSession = 2,
|
|
4
4
|
SpringSemester = 3,
|
|
5
5
|
SummerSession = 4
|
|
6
6
|
}
|
|
7
|
-
export declare
|
|
7
|
+
export declare enum EducationLevel {
|
|
8
8
|
HigherEducation = 1,
|
|
9
9
|
VocationalEducation = 2
|
|
10
10
|
}
|
|
@@ -12,6 +12,12 @@ export interface Time {
|
|
|
12
12
|
hours: number;
|
|
13
13
|
minutes: number;
|
|
14
14
|
}
|
|
15
|
+
export interface TimeRange {
|
|
16
|
+
start: Time;
|
|
17
|
+
end: Time;
|
|
18
|
+
}
|
|
19
|
+
/** Calendar date without a timezone or time component. */
|
|
20
|
+
export type LocalDate = `${number}-${number}-${number}`;
|
|
15
21
|
export interface WeekRange {
|
|
16
22
|
from: number;
|
|
17
23
|
to: number;
|
package/dist/common/types.js
CHANGED
|
@@ -1,3 +1,15 @@
|
|
|
1
|
+
export var AcademicPeriod;
|
|
2
|
+
(function (AcademicPeriod) {
|
|
3
|
+
AcademicPeriod[AcademicPeriod["FallSemester"] = 1] = "FallSemester";
|
|
4
|
+
AcademicPeriod[AcademicPeriod["WinterSession"] = 2] = "WinterSession";
|
|
5
|
+
AcademicPeriod[AcademicPeriod["SpringSemester"] = 3] = "SpringSemester";
|
|
6
|
+
AcademicPeriod[AcademicPeriod["SummerSession"] = 4] = "SummerSession";
|
|
7
|
+
})(AcademicPeriod || (AcademicPeriod = {}));
|
|
8
|
+
export var EducationLevel;
|
|
9
|
+
(function (EducationLevel) {
|
|
10
|
+
EducationLevel[EducationLevel["HigherEducation"] = 1] = "HigherEducation";
|
|
11
|
+
EducationLevel[EducationLevel["VocationalEducation"] = 2] = "VocationalEducation";
|
|
12
|
+
})(EducationLevel || (EducationLevel = {}));
|
|
1
13
|
export class AuthError extends Error {
|
|
2
14
|
constructor(message) {
|
|
3
15
|
super(message);
|
package/dist/core.d.ts
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export * from "./tt/domain/index.js";
|
|
2
|
+
export { attachWebinars, findWebinar } from "./tt/webinars.js";
|
|
3
|
+
export type { LessonWithWebinar } from "./tt/webinars.js";
|
|
4
|
+
export { getAdjacentSemester, getCompensatingWorkDays, getCurrentPeriod, getEffectiveHolidays, formatLocalDate, getHolidayTransfers, getSemesterStart, getSemesterWeeks, getStandardScheduleBlocks, getWeekNumber, getWeekdayName, isHoliday, isLocalDate, isSessionPeriod, parseLocalDate, RUSSIAN_HOLIDAYS, } from "./tt/utils/index.js";
|
|
5
|
+
export type { Holiday, HolidayTransfer } from "./tt/utils/index.js";
|
|
6
|
+
export { AuthError, EducationLevel, ParseError, AcademicPeriod, } from "./common/types.js";
|
|
7
|
+
export type { LocalDate, Teacher, Time, TimeRange, WeekRange, } from "./common/types.js";
|
|
8
|
+
export type { CacheAdapter, CacheEntry } from "./common/cache.js";
|
|
9
|
+
export type { CacheConfig, DirectoryPreloadOptions, EntityResolutionStrategy, Faculty, GetScheduleOptions, Group, StandardScheduleBlock, Room, RoomInfo, SemesterWeek, TeacherInfo, TimetableClientOptions, Webinar, } from "./tt/types.js";
|
|
10
|
+
export type { StudentPortalCacheConfig, StudentPortalClientOptions, StudentProfile, } from "./lk/types.js";
|
package/dist/core.js
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
// Runtime-safe core for Node.js, browsers, Deno, and workers.
|
|
2
|
+
export * from "./tt/domain/index.js";
|
|
3
|
+
export { attachWebinars, findWebinar } from "./tt/webinars.js";
|
|
4
|
+
export { getAdjacentSemester, getCompensatingWorkDays, getCurrentPeriod, getEffectiveHolidays, formatLocalDate, getHolidayTransfers, getSemesterStart, getSemesterWeeks, getStandardScheduleBlocks, getWeekNumber, getWeekdayName, isHoliday, isLocalDate, isSessionPeriod, parseLocalDate, RUSSIAN_HOLIDAYS, } from "./tt/utils/index.js";
|
|
5
|
+
export { AuthError, EducationLevel, ParseError, AcademicPeriod, } from "./common/types.js";
|
package/dist/index.d.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
-
export * from "./
|
|
2
|
-
export {
|
|
3
|
-
export {
|
|
1
|
+
export * from "./core.js";
|
|
2
|
+
export { StudentPortalClient } from "./lk/client.js";
|
|
3
|
+
export { TimetableClient } from "./tt/client.js";
|
|
4
|
+
export * from "./parsers.js";
|
|
5
|
+
export type { BlobAdapter, BlobPutOptions, } from "./common/cache.js";
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export * from "./
|
|
2
|
-
|
|
3
|
-
export {
|
|
4
|
-
export
|
|
1
|
+
export * from "./core.js";
|
|
2
|
+
export { StudentPortalClient } from "./lk/client.js";
|
|
3
|
+
export { TimetableClient } from "./tt/client.js";
|
|
4
|
+
export * from "./parsers.js";
|
package/dist/lk/client.d.ts
CHANGED
|
@@ -1,17 +1,19 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
export declare class
|
|
1
|
+
import type { StudentPortalClientOptions, StudentProfile } from "./types.js";
|
|
2
|
+
export declare class StudentPortalClient {
|
|
3
3
|
private http;
|
|
4
4
|
private credentials;
|
|
5
5
|
private cache;
|
|
6
6
|
private blobAdapter;
|
|
7
|
-
constructor(opts?:
|
|
7
|
+
constructor(opts?: StudentPortalClientOptions);
|
|
8
8
|
login(opts: {
|
|
9
9
|
email: string;
|
|
10
10
|
password: string;
|
|
11
11
|
}): Promise<void>;
|
|
12
12
|
private isSessionExpired;
|
|
13
13
|
private authGet;
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
14
|
+
private isBinarySessionExpired;
|
|
15
|
+
private authGetBuffer;
|
|
16
|
+
getProfile(): Promise<StudentProfile>;
|
|
17
|
+
getProfilePhoto(): Promise<Buffer>;
|
|
18
|
+
getTimetableGroupId(): Promise<number | null>;
|
|
17
19
|
}
|
package/dist/lk/client.js
CHANGED
|
@@ -1,18 +1,18 @@
|
|
|
1
|
-
import { HttpClient } from "../common/http.js";
|
|
1
|
+
import { HttpClient, } from "../common/http.js";
|
|
2
2
|
import { HybridCache } from "../common/cache.js";
|
|
3
|
-
import { AuthError } from "../common/types.js";
|
|
3
|
+
import { AuthError, ParseError } from "../common/types.js";
|
|
4
4
|
import { extractScriptValues } from "./parse.js";
|
|
5
5
|
const BASE = "https://lk.chuvsu.ru";
|
|
6
6
|
const LOGIN_URL = `${BASE}/info/login.php`;
|
|
7
7
|
const STUDENT_BASE = `${BASE}/student`;
|
|
8
8
|
function makeUniformCacheConfig(ttl) {
|
|
9
9
|
return {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
10
|
+
profile: ttl,
|
|
11
|
+
profilePhoto: ttl,
|
|
12
|
+
timetableGroupId: ttl,
|
|
13
13
|
};
|
|
14
14
|
}
|
|
15
|
-
export class
|
|
15
|
+
export class StudentPortalClient {
|
|
16
16
|
http = new HttpClient();
|
|
17
17
|
credentials = null;
|
|
18
18
|
cache;
|
|
@@ -40,19 +40,47 @@ export class LkClient {
|
|
|
40
40
|
return body.includes("login.php");
|
|
41
41
|
}
|
|
42
42
|
async authGet(url) {
|
|
43
|
-
|
|
43
|
+
let res = await this.http.get(url);
|
|
44
44
|
if (this.credentials && this.isSessionExpired(res.body)) {
|
|
45
45
|
await this.login(this.credentials);
|
|
46
|
-
|
|
46
|
+
res = await this.http.get(url);
|
|
47
|
+
}
|
|
48
|
+
if (this.isSessionExpired(res.body)) {
|
|
49
|
+
throw new AuthError("LK request returned an authentication page");
|
|
50
|
+
}
|
|
51
|
+
if (res.status < 200 || res.status >= 300) {
|
|
52
|
+
throw new Error(`LK request failed with HTTP ${res.status}: ${url}`);
|
|
47
53
|
}
|
|
48
54
|
return res;
|
|
49
55
|
}
|
|
50
|
-
|
|
51
|
-
const
|
|
56
|
+
isBinarySessionExpired(response) {
|
|
57
|
+
const prefix = response.body.subarray(0, 8_192).toString("utf8");
|
|
58
|
+
return this.isSessionExpired(prefix) ||
|
|
59
|
+
response.contentType?.toLowerCase().includes("text/html") === true;
|
|
60
|
+
}
|
|
61
|
+
async authGetBuffer(url) {
|
|
62
|
+
let res = await this.http.getBufferResponse(url);
|
|
63
|
+
if (this.credentials && this.isBinarySessionExpired(res)) {
|
|
64
|
+
await this.login(this.credentials);
|
|
65
|
+
res = await this.http.getBufferResponse(url);
|
|
66
|
+
}
|
|
67
|
+
if (res.status < 200 || res.status >= 300) {
|
|
68
|
+
throw new Error(`LK request failed with HTTP ${res.status}: ${url}`);
|
|
69
|
+
}
|
|
70
|
+
if (this.isBinarySessionExpired(res)) {
|
|
71
|
+
throw new AuthError("LK binary request returned an authentication page");
|
|
72
|
+
}
|
|
73
|
+
return res.body;
|
|
74
|
+
}
|
|
75
|
+
async getProfile() {
|
|
76
|
+
const cached = await this.cache?.get("profile", "self");
|
|
52
77
|
if (cached)
|
|
53
78
|
return cached;
|
|
54
79
|
const { body } = await this.authGet(`${STUDENT_BASE}/personal_data.php`);
|
|
55
80
|
const vals = extractScriptValues(body, "form_personal_data");
|
|
81
|
+
if (!vals.fam?.trim() || !vals.nam?.trim()) {
|
|
82
|
+
throw new ParseError("LK profile response has no student identity");
|
|
83
|
+
}
|
|
56
84
|
const data = {
|
|
57
85
|
lastName: vals.fam ?? "",
|
|
58
86
|
firstName: vals.nam ?? "",
|
|
@@ -68,12 +96,12 @@ export class LkClient {
|
|
|
68
96
|
email: vals.email ?? "",
|
|
69
97
|
phone: vals.phone ?? "",
|
|
70
98
|
};
|
|
71
|
-
await this.cache?.set("
|
|
99
|
+
await this.cache?.set("profile", "self", data);
|
|
72
100
|
return data;
|
|
73
101
|
}
|
|
74
|
-
async
|
|
75
|
-
const cached = this.cache?.getLocal("
|
|
76
|
-
await this.cache?.get("
|
|
102
|
+
async getProfilePhoto() {
|
|
103
|
+
const cached = this.cache?.getLocal("profilePhoto", "self") ??
|
|
104
|
+
await this.cache?.get("profilePhoto", "self");
|
|
77
105
|
if (cached !== null && cached !== undefined) {
|
|
78
106
|
const entry = cached;
|
|
79
107
|
if (typeof entry === "string")
|
|
@@ -84,33 +112,33 @@ export class LkClient {
|
|
|
84
112
|
if (entry.blobKey && this.blobAdapter) {
|
|
85
113
|
const photo = await this.blobAdapter.get(entry.blobKey);
|
|
86
114
|
if (photo) {
|
|
87
|
-
this.cache?.setLocal("
|
|
115
|
+
this.cache?.setLocal("profilePhoto", "self", { data: photo.toString("base64") });
|
|
88
116
|
return photo;
|
|
89
117
|
}
|
|
90
118
|
}
|
|
91
119
|
}
|
|
92
|
-
const photo = await this.
|
|
120
|
+
const photo = await this.authGetBuffer(`${STUDENT_BASE}/face.php`);
|
|
93
121
|
if (this.blobAdapter) {
|
|
94
122
|
const blobKey = "lk/photo/self";
|
|
95
|
-
this.cache?.setLocal("
|
|
123
|
+
this.cache?.setLocal("profilePhoto", "self", { data: photo.toString("base64") });
|
|
96
124
|
await this.blobAdapter.put(blobKey, photo, {
|
|
97
|
-
ttl: this.cache?.ttl("
|
|
125
|
+
ttl: this.cache?.ttl("profilePhoto"),
|
|
98
126
|
});
|
|
99
|
-
await this.cache?.setExternal("
|
|
127
|
+
await this.cache?.setExternal("profilePhoto", "self", { blobKey });
|
|
100
128
|
}
|
|
101
129
|
else {
|
|
102
|
-
await this.cache?.set("
|
|
130
|
+
await this.cache?.set("profilePhoto", "self", photo.toString("base64"));
|
|
103
131
|
}
|
|
104
132
|
return photo;
|
|
105
133
|
}
|
|
106
|
-
async
|
|
107
|
-
const cached = await this.cache?.get("
|
|
134
|
+
async getTimetableGroupId() {
|
|
135
|
+
const cached = await this.cache?.get("timetableGroupId", "self");
|
|
108
136
|
if (cached !== null && cached !== undefined)
|
|
109
137
|
return cached;
|
|
110
138
|
const { body } = await this.authGet(`${STUDENT_BASE}/tt.php`);
|
|
111
139
|
const match = body.match(/tt\.chuvsu\.ru\/index\/grouptt\/gr\/(\d+)/);
|
|
112
140
|
const groupId = match ? parseInt(match[1]) : null;
|
|
113
|
-
await this.cache?.set("
|
|
141
|
+
await this.cache?.set("timetableGroupId", "self", groupId);
|
|
114
142
|
return groupId;
|
|
115
143
|
}
|
|
116
144
|
}
|
package/dist/lk/types.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { BlobAdapter, CacheAdapter } from "../common/cache.js";
|
|
2
|
-
export interface
|
|
2
|
+
export interface StudentProfile {
|
|
3
3
|
lastName: string;
|
|
4
4
|
firstName: string;
|
|
5
5
|
patronymic: string;
|
|
@@ -14,13 +14,13 @@ export interface PersonalData {
|
|
|
14
14
|
email: string;
|
|
15
15
|
phone: string;
|
|
16
16
|
}
|
|
17
|
-
export interface
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
17
|
+
export interface StudentPortalCacheConfig {
|
|
18
|
+
profile?: number;
|
|
19
|
+
profilePhoto?: number;
|
|
20
|
+
timetableGroupId?: number;
|
|
21
21
|
}
|
|
22
|
-
export interface
|
|
23
|
-
cache?: number |
|
|
22
|
+
export interface StudentPortalClientOptions {
|
|
23
|
+
cache?: number | StudentPortalCacheConfig;
|
|
24
24
|
cacheAdapter?: CacheAdapter;
|
|
25
25
|
blobAdapter?: BlobAdapter;
|
|
26
26
|
}
|
package/dist/node.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./index.js";
|
package/dist/node.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./index.js";
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
export { parseAcademicYearFromPage, parseRoomButtons, parseRoomSchedule, parseRoomInfo, parseRoomName, parseFacultyButtons, parseGroupSchedule, parseGroupName, parseGroupButtons, parseGroupsString, parsePeriodFromPage, parseTeacherButtons, parseTeacherSchedule, parseTeacherInfo, parseWebinars, } from "./tt/parse/index.js";
|
|
2
|
+
export { createScheduleSourceSnapshot } from "./tt/observations.js";
|
|
3
|
+
export type { ParsedScheduleDay, ParsedLesson, ParsedScheduleBlock, } from "./tt/types.js";
|
package/dist/parsers.js
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
export { parseAcademicYearFromPage, parseRoomButtons, parseRoomSchedule, parseRoomInfo, parseRoomName, parseFacultyButtons, parseGroupSchedule, parseGroupName, parseGroupButtons, parseGroupsString, parsePeriodFromPage, parseTeacherButtons, parseTeacherSchedule, parseTeacherInfo, parseWebinars, } from "./tt/parse/index.js";
|
|
2
|
+
export { createScheduleSourceSnapshot } from "./tt/observations.js";
|
package/dist/tt/client.d.ts
CHANGED
|
@@ -1,16 +1,29 @@
|
|
|
1
1
|
import type { CacheEntry } from "../common/cache.js";
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import type {
|
|
5
|
-
|
|
2
|
+
import { Schedule } from "./domain/schedule.js";
|
|
3
|
+
import { TimetableRepository } from "./domain/repository.js";
|
|
4
|
+
import type { GroupRef, RoomRef, ScheduleOwner, TeacherRef, TimetableRepositorySnapshot } from "./domain/types.js";
|
|
5
|
+
import type { Room, RoomInfo, Faculty, Group, TeacherInfo, TimetableClientOptions, CacheConfig, DirectoryPreloadOptions, EntityResolutionStrategy, GetScheduleOptions, Webinar } from "./types.js";
|
|
6
|
+
export declare class TimetableClient {
|
|
6
7
|
private http;
|
|
7
|
-
private
|
|
8
|
+
private educationLevel;
|
|
8
9
|
private cache;
|
|
9
10
|
private blobAdapter;
|
|
11
|
+
private _repository;
|
|
12
|
+
private repositoryAdapter;
|
|
13
|
+
private repositoryReady;
|
|
14
|
+
private repositoryMutation;
|
|
10
15
|
private loginMode;
|
|
11
16
|
private timetableContext;
|
|
12
|
-
constructor(opts?:
|
|
17
|
+
constructor(opts?: TimetableClientOptions);
|
|
13
18
|
private get pertt();
|
|
19
|
+
get repository(): TimetableRepository;
|
|
20
|
+
private ensureRepository;
|
|
21
|
+
private mutateRepository;
|
|
22
|
+
private performRepositoryMutation;
|
|
23
|
+
exportRepository(): Promise<TimetableRepositorySnapshot>;
|
|
24
|
+
private rememberGroups;
|
|
25
|
+
private rememberTeachers;
|
|
26
|
+
private rememberRooms;
|
|
14
27
|
clearCache(category?: keyof CacheConfig): Promise<void>;
|
|
15
28
|
exportCache(): Record<string, CacheEntry>;
|
|
16
29
|
importCache(data: Record<string, CacheEntry>): void;
|
|
@@ -20,25 +33,21 @@ export declare class TtClient {
|
|
|
20
33
|
}): Promise<void>;
|
|
21
34
|
loginAsGuest(): Promise<void>;
|
|
22
35
|
private isSessionExpired;
|
|
36
|
+
private isBinarySessionExpired;
|
|
23
37
|
private relogin;
|
|
24
38
|
private authGet;
|
|
25
39
|
private authGetBuffer;
|
|
26
40
|
private authPost;
|
|
27
41
|
/** Resolve the academic year and active period from tt.chuvsu.ru itself. */
|
|
28
42
|
private getTimetableContext;
|
|
29
|
-
private
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
*/
|
|
38
|
-
getScheduleForPeriod(opts: {
|
|
39
|
-
groupId: number;
|
|
40
|
-
period: Period;
|
|
41
|
-
}): Promise<Schedule>;
|
|
43
|
+
private fetchGroupSchedule;
|
|
44
|
+
private validateSchedulePage;
|
|
45
|
+
private ownerUrl;
|
|
46
|
+
private sourceKey;
|
|
47
|
+
private resolveOwner;
|
|
48
|
+
private fetchOwnerSchedule;
|
|
49
|
+
getSchedule(owner: ScheduleOwner, options?: GetScheduleOptions): Promise<Schedule>;
|
|
50
|
+
getGroupSchedule(groupId: number, options?: GetScheduleOptions): Promise<Schedule>;
|
|
42
51
|
getWebinars(opts?: {
|
|
43
52
|
date?: Date;
|
|
44
53
|
facultyId?: number;
|
|
@@ -50,19 +59,13 @@ export declare class TtClient {
|
|
|
50
59
|
password: string;
|
|
51
60
|
}): Promise<string>;
|
|
52
61
|
getFaculties(): Promise<Faculty[]>;
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
}): Promise<Group[]>;
|
|
56
|
-
searchGroup(opts: {
|
|
57
|
-
name: string;
|
|
58
|
-
}): Promise<Group[]>;
|
|
62
|
+
getFacultyGroups(facultyId: number): Promise<Group[]>;
|
|
63
|
+
searchGroups(name: string): Promise<GroupRef[]>;
|
|
59
64
|
/**
|
|
60
65
|
* Search audiences by name (substring match). The server requires at
|
|
61
66
|
* least 3 characters in the query.
|
|
62
67
|
*/
|
|
63
|
-
|
|
64
|
-
name: string;
|
|
65
|
-
}): Promise<Audience[]>;
|
|
68
|
+
searchRooms(name: string): Promise<Room[]>;
|
|
66
69
|
/**
|
|
67
70
|
* Get every audience known to the system in a single request.
|
|
68
71
|
*
|
|
@@ -71,61 +74,50 @@ export declare class TtClient {
|
|
|
71
74
|
* 3-character wildcard `%%%` matches every audience at once and returns
|
|
72
75
|
* the full list of (id, name) pairs.
|
|
73
76
|
*/
|
|
74
|
-
|
|
77
|
+
getRooms(): Promise<Room[]>;
|
|
78
|
+
resolveGroup(value: string | GroupRef, options?: {
|
|
79
|
+
strategy?: EntityResolutionStrategy;
|
|
80
|
+
}): Promise<GroupRef>;
|
|
81
|
+
resolveTeacher(value: string | TeacherRef, options?: {
|
|
82
|
+
strategy?: EntityResolutionStrategy;
|
|
83
|
+
}): Promise<TeacherRef>;
|
|
84
|
+
resolveRoom(value: string | RoomRef, options?: {
|
|
85
|
+
strategy?: EntityResolutionStrategy;
|
|
86
|
+
}): Promise<RoomRef>;
|
|
87
|
+
preloadDirectory(options: DirectoryPreloadOptions): Promise<void>;
|
|
75
88
|
/**
|
|
76
89
|
* Resolve an audience id from its exact name by searching and
|
|
77
90
|
* selecting the button whose `value` equals the given name.
|
|
78
91
|
*/
|
|
79
|
-
|
|
80
|
-
name: string;
|
|
81
|
-
}): Promise<Audience | null>;
|
|
92
|
+
findRoomByName(name: string): Promise<Room | null>;
|
|
82
93
|
/** Fetch the audience's display name from its schedule page. */
|
|
83
|
-
|
|
94
|
+
getRoomName(roomId: number): Promise<string | null>;
|
|
84
95
|
/**
|
|
85
96
|
* Fetch detailed info about an audience (building, floor, usage,
|
|
86
97
|
* image URLs for the audience photo, building photo and floor plan).
|
|
87
98
|
*/
|
|
88
|
-
|
|
89
|
-
private
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
audienceId: number;
|
|
93
|
-
period: Period;
|
|
94
|
-
}): Promise<Schedule>;
|
|
95
|
-
private getCachedAudienceImage;
|
|
99
|
+
getRoomInfo(roomId: number): Promise<RoomInfo | null>;
|
|
100
|
+
private fetchRoomSchedule;
|
|
101
|
+
getRoomSchedule(roomId: number, options?: GetScheduleOptions): Promise<Schedule>;
|
|
102
|
+
private getCachedRoomImage;
|
|
96
103
|
/** Get the audience photo (audimage). Returns null if missing. */
|
|
97
|
-
|
|
104
|
+
getRoomImage(roomId: number): Promise<Buffer | null>;
|
|
98
105
|
/** Get the building exterior image (blockimage). Returns null if missing. */
|
|
99
|
-
|
|
106
|
+
getRoomBuildingImage(roomId: number): Promise<Buffer | null>;
|
|
100
107
|
/** Get the floor plan image for the audience. Returns null if missing. */
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
name: string;
|
|
104
|
-
}): Promise<{
|
|
105
|
-
id: number;
|
|
106
|
-
name: string;
|
|
107
|
-
}[]>;
|
|
108
|
+
getRoomFloorPlan(roomId: number): Promise<Buffer | null>;
|
|
109
|
+
searchTeachers(name: string): Promise<TeacherRef[]>;
|
|
108
110
|
getTeachers(): Promise<{
|
|
109
111
|
id: number;
|
|
110
112
|
name: string;
|
|
111
113
|
}[]>;
|
|
112
114
|
private fetchTeacherSchedule;
|
|
113
|
-
getTeacherSchedule(teacherId: number): Promise<Schedule>;
|
|
114
|
-
getTeacherScheduleForPeriod(opts: {
|
|
115
|
-
teacherId: number;
|
|
116
|
-
period: Period;
|
|
117
|
-
}): Promise<Schedule>;
|
|
115
|
+
getTeacherSchedule(teacherId: number, options?: GetScheduleOptions): Promise<Schedule>;
|
|
118
116
|
getTeacherInfo(teacherId: number): Promise<TeacherInfo | null>;
|
|
119
117
|
/**
|
|
120
|
-
* Get
|
|
118
|
+
* Get teacher photo directly by known URL pattern.
|
|
119
|
+
* Does not fetch or parse teacher info first.
|
|
121
120
|
* Returns null if the teacher has no photo.
|
|
122
|
-
* Uses cached teacher info when available to avoid extra requests.
|
|
123
121
|
*/
|
|
124
122
|
getTeacherPhoto(teacherId: number): Promise<Buffer | null>;
|
|
125
|
-
/**
|
|
126
|
-
* Get the teacher's photo without parsing the schedule page.
|
|
127
|
-
* Uses the known URL pattern directly — no extra page fetch needed.
|
|
128
|
-
* Returns null if the teacher has no photo.
|
|
129
|
-
*/
|
|
130
|
-
getTeacherPhotoLazy(teacherId: number): Promise<Buffer | null>;
|
|
131
123
|
}
|