zdu-student-api 1.1.6 → 1.1.7

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 (47) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +231 -18
  3. package/dist/cabinet/cabinet.d.ts +79 -79
  4. package/dist/cabinet/cabinet.js +162 -162
  5. package/dist/cabinet/data.d.ts +33 -4
  6. package/dist/cabinet/data.js +52 -6
  7. package/dist/cabinet/disciplines.d.ts +19 -19
  8. package/dist/cabinet/disciplines.js +87 -87
  9. package/dist/cabinet/index.d.ts +2 -5
  10. package/dist/cabinet/index.js +2 -5
  11. package/dist/cabinet/parsers.d.ts +22 -3
  12. package/dist/cabinet/parsers.js +118 -0
  13. package/dist/cabinet/scores.d.ts +12 -12
  14. package/dist/cabinet/scores.js +101 -101
  15. package/dist/cabinet/sesId.d.ts +10 -10
  16. package/dist/cabinet/sesId.js +40 -40
  17. package/dist/cabinet/session.d.ts +33 -0
  18. package/dist/cabinet/session.js +99 -0
  19. package/dist/cabinet/types.d.ts +0 -137
  20. package/dist/cabinet/utils.d.ts +6 -6
  21. package/dist/cabinet/utils.js +16 -19
  22. package/dist/cabinet/validSession.d.ts +8 -8
  23. package/dist/cabinet/validSession.js +29 -29
  24. package/dist/cabinetStudent/cabinetStudent.d.ts +87 -0
  25. package/dist/cabinetStudent/cabinetStudent.js +181 -0
  26. package/dist/cabinetStudent/disciplines.d.ts +19 -0
  27. package/dist/cabinetStudent/disciplines.js +86 -0
  28. package/dist/cabinetStudent/index.d.ts +4 -0
  29. package/dist/cabinetStudent/index.js +4 -0
  30. package/dist/cabinetStudent/scores.d.ts +12 -0
  31. package/dist/cabinetStudent/scores.js +101 -0
  32. package/dist/cabinetStudent/types.d.ts +137 -0
  33. package/dist/cabinetStudent/types.js +1 -0
  34. package/dist/cabinetTeacher/academicGroups.d.ts +10 -0
  35. package/dist/cabinetTeacher/academicGroups.js +36 -0
  36. package/dist/cabinetTeacher/cabinetTeacher.d.ts +71 -0
  37. package/dist/cabinetTeacher/cabinetTeacher.js +132 -0
  38. package/dist/cabinetTeacher/index.d.ts +3 -0
  39. package/dist/cabinetTeacher/index.js +3 -0
  40. package/dist/cabinetTeacher/types.d.ts +68 -0
  41. package/dist/cabinetTeacher/types.js +1 -0
  42. package/dist/examples.d.ts +1 -1
  43. package/dist/examples.js +48 -36
  44. package/dist/index.d.ts +2 -0
  45. package/dist/index.js +2 -0
  46. package/dist/types.d.ts +4 -3
  47. package/package.json +35 -34
@@ -0,0 +1,181 @@
1
+ import { getSesId, isValidSession } from '../cabinet/session.js';
2
+ import { getСurrentDisciplines } from './disciplines.js';
3
+ import { getScores } from './scores.js';
4
+ import { getSemester } from '../cabinet/utils.js';
5
+ import { getDataStudent } from '../cabinet/data.js';
6
+ /**
7
+ * Клас кабінету студента
8
+ * @category CabinetStudent
9
+ */
10
+ export class CabinetStudent {
11
+ /**
12
+ * Прізвище користувача
13
+ */
14
+ login;
15
+ /**
16
+ * Пароль від кабінету студента
17
+ */
18
+ password;
19
+ /**
20
+ * ID сесії користувача
21
+ */
22
+ sesID;
23
+ /**
24
+ * GUID сесії з cookie
25
+ */
26
+ sessGUID;
27
+ /**
28
+ * Семестр для пошуку оцінок (1 - перший, 2 - другий)
29
+ */
30
+ semester = 1;
31
+ /**
32
+ * Список дисциплін {@link Discipline}
33
+ */
34
+ disciplines = [];
35
+ /**
36
+ * Данні студента {@link Data}
37
+ */
38
+ data;
39
+ /**
40
+ * Оціки з усіх предметів {@link Scores}
41
+ */
42
+ allScores;
43
+ /**
44
+ * Айді в системі оцінювання
45
+ */
46
+ id;
47
+ /**
48
+ * Конструктор
49
+ * @param login - Прізвище користувача
50
+ * @param password - Пароль
51
+ */
52
+ constructor(login, password) {
53
+ this.login = login;
54
+ this.password = password;
55
+ }
56
+ /**
57
+ * Авторизація
58
+ */
59
+ async auth(login, password) {
60
+ const accountData = await getSesId(login ?? this.login, password ?? this.password, 'student');
61
+ this.setSemester();
62
+ if (accountData.ok) {
63
+ this.sesID = accountData.sesID;
64
+ this.sessGUID = accountData.sessGUID;
65
+ return true;
66
+ }
67
+ return false;
68
+ }
69
+ /**
70
+ * Базове значення семестру
71
+ */
72
+ setSemester() {
73
+ this.semester = getSemester();
74
+ }
75
+ /**
76
+ * Отримання всіх данних
77
+ */
78
+ async loadData() {
79
+ const one = (await this.getDisciplines()).ok;
80
+ const two = (await this.getData()).ok;
81
+ const three = (await this.getAllScores()).length > 0;
82
+ return one && two && three;
83
+ }
84
+ /**
85
+ * Відновлення сесії
86
+ */
87
+ async setSession(sesID, sessGUID) {
88
+ this.setSemester();
89
+ const ses = await isValidSession(sesID, sessGUID, 'student');
90
+ if (ses) {
91
+ this.sesID = sesID;
92
+ this.sessGUID = sessGUID;
93
+ }
94
+ return ses;
95
+ }
96
+ /**
97
+ * Перевірка валідності сесії
98
+ */
99
+ async isValidSession() {
100
+ if (!this.sesID || !this.sessGUID)
101
+ return false;
102
+ return await isValidSession(this.sesID, this.sessGUID, 'student');
103
+ }
104
+ /**
105
+ * Отримати дисципліни поточного семестру студента
106
+ * @returns Об'єкт дисциплін {@link Disciplines}
107
+ */
108
+ async getDisciplines() {
109
+ if (!this.sesID || !this.sessGUID)
110
+ return { ok: false, disciplines: [] };
111
+ try {
112
+ const disciplinesData = await getСurrentDisciplines(this.sesID, this.sessGUID);
113
+ if (disciplinesData.ok) {
114
+ this.disciplines = disciplinesData.disciplines;
115
+ }
116
+ return disciplinesData;
117
+ }
118
+ catch {
119
+ return { ok: false, disciplines: [] };
120
+ }
121
+ }
122
+ /**
123
+ * Отримати анкетні данні студента
124
+ * @returns Об'єкт {@link Data}
125
+ */
126
+ async getData() {
127
+ if (!this.sesID || !this.sessGUID)
128
+ return { ok: false };
129
+ try {
130
+ const data = await getDataStudent(this.sesID, this.sessGUID);
131
+ if (data.ok) {
132
+ this.data = data;
133
+ }
134
+ return data;
135
+ }
136
+ catch {
137
+ return { ok: false };
138
+ }
139
+ }
140
+ /**
141
+ * Отримати оцінки з всіх предметів
142
+ */
143
+ async getAllScores(semester) {
144
+ if (!this.sesID || !this.sessGUID)
145
+ return [];
146
+ if (!this.disciplines?.length)
147
+ return [];
148
+ const targetSemester = semester ?? this.semester;
149
+ try {
150
+ const scorePromises = this.disciplines.map((discipline) => getScores(this.sesID, this.sessGUID, discipline.prId, targetSemester));
151
+ const results = await Promise.all(scorePromises);
152
+ const allScores = results.filter((scores) => scores.ok);
153
+ this.allScores = allScores;
154
+ return allScores;
155
+ }
156
+ catch {
157
+ return [];
158
+ }
159
+ }
160
+ /**
161
+ * Отримати айді в системі оцінювання
162
+ */
163
+ async getId() {
164
+ if (this.id)
165
+ return this.id;
166
+ if (!this.sesID || !this.sessGUID)
167
+ return undefined;
168
+ if (!this.disciplines?.length) {
169
+ await this.getDisciplines();
170
+ }
171
+ if (!this.disciplines?.length)
172
+ return undefined;
173
+ try {
174
+ const result = await getScores(this.sesID, this.sessGUID, this.disciplines[0].prId, this.semester);
175
+ return result.studentId;
176
+ }
177
+ catch {
178
+ return undefined;
179
+ }
180
+ }
181
+ }
@@ -0,0 +1,19 @@
1
+ import { Disciplines } from './types.js';
2
+ /**
3
+ * Отримати всі дисципліни студента
4
+ * @category CabinetStudent
5
+ * @param sesId - ID сесії користувача
6
+ * @param sessGUID - GUID сесії з cookie
7
+ * @throws {Error} Якщо виникають проблеми з запитом або дані некоректні.
8
+ * @returns Масив дисциплін {@link Disciplines}
9
+ */
10
+ export declare function getDisciplines(sesId: string, sessGUID: string): Promise<Disciplines>;
11
+ /**
12
+ * Отримати поточні дисципліни студента
13
+ * @category CabinetStudent
14
+ * @param sesId - ID сесії користувача
15
+ * @param sessGUID - GUID сесії з cookie
16
+ * @throws {Error} Якщо виникають проблеми з запитом або дані некоректні.
17
+ * @returns Масив дисциплін {@link Disciplines}
18
+ */
19
+ export declare function getСurrentDisciplines(sesId: string, sessGUID: string): Promise<Disciplines>;
@@ -0,0 +1,86 @@
1
+ import fetch from 'cross-fetch';
2
+ import iconv from 'iconv-lite';
3
+ import { parseDisciplinesPageN6, parseDisciplinesPageN7 } from '../cabinet/parsers.js';
4
+ import { generateCookieString, isLoginPage } from '../cabinet/session.js';
5
+ /**
6
+ * Отримати всі дисципліни студента
7
+ * @category CabinetStudent
8
+ * @param sesId - ID сесії користувача
9
+ * @param sessGUID - GUID сесії з cookie
10
+ * @throws {Error} Якщо виникають проблеми з запитом або дані некоректні.
11
+ * @returns Масив дисциплін {@link Disciplines}
12
+ */
13
+ export async function getDisciplines(sesId, sessGUID) {
14
+ try {
15
+ const result = { ok: false, disciplines: [] };
16
+ const cookieString = generateCookieString(sessGUID);
17
+ const response1 = await fetch(`https://dekanat.zu.edu.ua/cgi-bin/classman.cgi?n=3&sesID=${sesId}`, { headers: { Cookie: cookieString } });
18
+ const buffer1 = await response1.arrayBuffer();
19
+ const html1 = iconv.decode(Buffer.from(buffer1), 'windows-1251');
20
+ if (isLoginPage(html1))
21
+ return result;
22
+ let data = extractStrongValue(html1, 'Семестрові бали');
23
+ if (data === undefined)
24
+ return result;
25
+ const response2 = await fetch(`https://dekanat.zu.edu.ua/cgi-bin/${data.slice(2)}`, {
26
+ headers: { Cookie: cookieString },
27
+ });
28
+ const buffer2 = await response2.arrayBuffer();
29
+ const html2 = iconv.decode(Buffer.from(buffer2), 'windows-1251');
30
+ if (isLoginPage(html2))
31
+ return result;
32
+ result.disciplines = parseDisciplinesPageN6(html2);
33
+ result.ok = true;
34
+ return result;
35
+ }
36
+ catch (e) {
37
+ console.error('Error in getDisciplines:', e);
38
+ throw e;
39
+ }
40
+ }
41
+ /**
42
+ * Витягує значення з HTML після label до кінця li тегу
43
+ */
44
+ function extractStrongValue(html, label) {
45
+ const textIdx = html.indexOf(label);
46
+ if (textIdx === -1)
47
+ return undefined;
48
+ const liStart = html.lastIndexOf('<li', textIdx);
49
+ if (liStart === -1)
50
+ return undefined;
51
+ const liEnd = html.indexOf('</li>', textIdx);
52
+ if (liEnd === -1)
53
+ return undefined;
54
+ const liContent = html.substring(liStart, liEnd);
55
+ const hrefMatch = liContent.match(/href\s*=\s*["']([^"']+)["']/i);
56
+ if (!hrefMatch)
57
+ return undefined;
58
+ const href = hrefMatch[1].trim();
59
+ return href || undefined;
60
+ }
61
+ /**
62
+ * Отримати поточні дисципліни студента
63
+ * @category CabinetStudent
64
+ * @param sesId - ID сесії користувача
65
+ * @param sessGUID - GUID сесії з cookie
66
+ * @throws {Error} Якщо виникають проблеми з запитом або дані некоректні.
67
+ * @returns Масив дисциплін {@link Disciplines}
68
+ */
69
+ export async function getСurrentDisciplines(sesId, sessGUID) {
70
+ try {
71
+ const result = { ok: false, disciplines: [] };
72
+ const cookieString = generateCookieString(sessGUID);
73
+ const response1 = await fetch(`https://dekanat.zu.edu.ua/cgi-bin/classman.cgi?n=7&sesID=${sesId}`, { headers: { Cookie: cookieString } });
74
+ const buffer1 = await response1.arrayBuffer();
75
+ const html1 = iconv.decode(Buffer.from(buffer1), 'windows-1251');
76
+ if (isLoginPage(html1))
77
+ return result;
78
+ result.disciplines = parseDisciplinesPageN7(html1);
79
+ result.ok = true;
80
+ return result;
81
+ }
82
+ catch (e) {
83
+ console.error('Error in getСurrentDisciplines:', e);
84
+ throw e;
85
+ }
86
+ }
@@ -0,0 +1,4 @@
1
+ export * from './types.js';
2
+ export * from './disciplines.js';
3
+ export * from './scores.js';
4
+ export * from './cabinetStudent.js';
@@ -0,0 +1,4 @@
1
+ export * from './types.js';
2
+ export * from './disciplines.js';
3
+ export * from './scores.js';
4
+ export * from './cabinetStudent.js';
@@ -0,0 +1,12 @@
1
+ import { Scores } from './types.js';
2
+ /**
3
+ * Отримати оцінки пвибраного предмета студента
4
+ * @category CabinetStudent
5
+ * @param sesId - ID сесії користувача
6
+ * @param sessGUID - GUID сесії з cookie
7
+ * @param prId - ID дисципліни
8
+ * @param semester - Семестр
9
+ * @throws {Error} Якщо виникають проблеми з запитом або дані некоректні.
10
+ * @returns Масив дисциплін {@link Disciplines}
11
+ */
12
+ export declare function getScores(sesId: string, sessGUID: string, prId: string, semester: 1 | 2): Promise<Scores>;
@@ -0,0 +1,101 @@
1
+ import fetch from 'cross-fetch';
2
+ import iconv from 'iconv-lite';
3
+ import { generateCookieString, isLoginPage } from '../cabinet/session.js';
4
+ /**
5
+ * Отримати оцінки пвибраного предмета студента
6
+ * @category CabinetStudent
7
+ * @param sesId - ID сесії користувача
8
+ * @param sessGUID - GUID сесії з cookie
9
+ * @param prId - ID дисципліни
10
+ * @param semester - Семестр
11
+ * @throws {Error} Якщо виникають проблеми з запитом або дані некоректні.
12
+ * @returns Масив дисциплін {@link Disciplines}
13
+ */
14
+ export async function getScores(sesId, sessGUID, prId, semester) {
15
+ try {
16
+ const result = {
17
+ ok: false,
18
+ prId: prId,
19
+ studentId: '',
20
+ scheduleItem: [],
21
+ studentScores: [],
22
+ };
23
+ const cookieString = generateCookieString(sessGUID);
24
+ const formData = `n=7&sesID=${sesId}&teacher=0&irc=0&tid=0&CYKLE=-1&prt=${prId}&hlf=${semester === 1 ? 0 : 1}&grade=0&m=-1`;
25
+ const encodedFormData = iconv.encode(formData, 'windows-1251');
26
+ const response1 = await fetch(`https://dekanat.zu.edu.ua/cgi-bin/classman.cgi?n=7&sesID=${sesId}`, {
27
+ method: 'POST',
28
+ body: new Uint8Array(encodedFormData),
29
+ redirect: 'manual',
30
+ headers: { Cookie: cookieString },
31
+ });
32
+ const buffer1 = await response1.arrayBuffer();
33
+ let html1 = iconv.decode(Buffer.from(buffer1), 'windows-1251');
34
+ if (isLoginPage(html1))
35
+ return result;
36
+ result.scheduleItem = parseSchedule(html1);
37
+ result.studentScores = parseScores(html1);
38
+ result.studentId = result.studentScores[0].id;
39
+ result.studentScores.sort((a, b) => a.id.localeCompare(b.id));
40
+ result.ok = true;
41
+ return result;
42
+ }
43
+ catch (e) {
44
+ console.error('Error in getQuestionnaireData:', e);
45
+ throw e;
46
+ }
47
+ }
48
+ /**
49
+ * Витягує список пар з HTML
50
+ */
51
+ function parseSchedule(html) {
52
+ let idx = html.indexOf('<th></th>');
53
+ html = idx === -1 ? html : html.slice(idx + '<th></th>'.length);
54
+ idx = html.indexOf('<th class="dh">');
55
+ html = idx === -1 ? html : html.slice(0, idx);
56
+ const regex = /<th[^>]*data-hth="([^"]+)"[^>]*>[\s\S]*?<a[^>]*data-ind="([^"]+)"[^>]*>[^<]+<\/a>[\s\S]*?<br>([^<]+)<\/th>/g;
57
+ const result = [];
58
+ let match;
59
+ while ((match = regex.exec(html)) !== null) {
60
+ const [_, dataHth, index, time] = match;
61
+ const parts = dataHth.split(',');
62
+ const teacher = parts[0].trim();
63
+ const dateType = parts[1]?.trim().split(' ') || [];
64
+ const date = dateType[0] || '';
65
+ const type = dateType[1] || '';
66
+ result.push({ teacher, date, type, time: time.trim(), index });
67
+ }
68
+ return result;
69
+ }
70
+ /**
71
+ * Витягує список оцінок з HTML
72
+ */
73
+ function parseScores(html) {
74
+ const studentRows = html.match(/<tr\s+[^>]*id="s\d+"[\s\S]*?<\/tr>/g) || [];
75
+ const result = [];
76
+ for (const row of studentRows) {
77
+ const idMatch = row.match(/id="(s\d+)"/);
78
+ const id = idMatch ? idMatch[1] : '';
79
+ const tdMatches = [...row.matchAll(/<td[^>]*data-item="(\d+)"[^>]*>([\s\S]*?)<\/td>/g)];
80
+ const scoresMap = new Map();
81
+ for (const td of tdMatches) {
82
+ const dataItem = Number(td[1]);
83
+ const score = td[2].trim() || '';
84
+ if (!scoresMap.has(dataItem)) {
85
+ scoresMap.set(dataItem, [score]);
86
+ }
87
+ else {
88
+ scoresMap.get(dataItem).push(score);
89
+ }
90
+ }
91
+ const scores = Array.from(scoresMap.values());
92
+ scores.shift();
93
+ const finalMatch = row.match(/<td[^>]*class="f f1"[^>]*>([\s\S]*?)<\/td>/);
94
+ const finalScore = finalMatch ? finalMatch[1].trim() : '';
95
+ const absenceMatches = [...row.matchAll(/<td[^>]*class="f f2"[^>]*>([\s\S]*?)<\/td>/g)];
96
+ const absences = absenceMatches[0] ? Number(absenceMatches[0][1].trim() || 0) : 0;
97
+ const uabsences = absenceMatches[1] ? Number(absenceMatches[1][1].trim() || 0) : 0;
98
+ result.push({ id, scores, absences, uabsences, finalScore });
99
+ }
100
+ return result;
101
+ }
@@ -0,0 +1,137 @@
1
+ /**
2
+ * Анкетні дані студента
3
+ * @category CabinetStudent
4
+ * @remarks
5
+ * **Статус запиту:**
6
+ * - `ok` — Успіх отримання даних (true/false)
7
+ *
8
+ * **ПІБ студента:**
9
+ * - `fullName` — Повне ім'я студента (Прізвище Ім'я По батькові)
10
+ * - `lastName` — Прізвище
11
+ * - `firstName` — Ім'я
12
+ * - `middleName` — По батькові
13
+ *
14
+ * **Загальні дані:**
15
+ * - `birthDate` — Дата народження (формат: DD.MM.YYYY)
16
+ * - `gender` — Стать (Чол/Жін)
17
+ * - `previousFullName` — Попереднє ПІБ студента (якщо змінювалось)
18
+ * - `country` — Країна, з якої навчається студент
19
+ * - `lastNameEng` — Прізвище англійською
20
+ * - `firstNameEng` — Ім'я англійською
21
+ * - `middleNameEng` — По батькові англійською (зазвичай немає)
22
+ *
23
+ * **Контактні дані:**
24
+ * - `email` — Електронна пошта студента
25
+ * - `phones` — Масив телефонних номерів студента
26
+ *
27
+ * **Дані про навчання:**
28
+ * - `faculty` — Факультет
29
+ * - `specialty` — Спеціальність (назва освітньої програми)
30
+ * - `degree` — Ступінь / Освітньо-професійний ступінь (бакалавр, магістр тощо)
31
+ * - `group` — Академічна група
32
+ * - `studyForm` — Форма навчання (Денна, Заочна, Вечірня)
33
+ * - `paymentForm` — Форма оплати навчання (Держ.замовлення, Контракт)
34
+ * - `enrollmentOrder` — Номер наказу на зарахування
35
+ * - `enrollmentDate` — Дата наказу на зарахування (формат: DD.MM.YYYY)
36
+ * - `studyDuration` — Термін навчання (наприклад: "4 роки")
37
+ * - `graduationDate` — Дата закінчення навчання (формат: DD.MM.YYYY)
38
+ */
39
+ export interface DataStudent {
40
+ ok: boolean;
41
+ fullName?: string;
42
+ lastName?: string;
43
+ firstName?: string;
44
+ middleName?: string;
45
+ birthDate?: string;
46
+ gender?: string;
47
+ previousFullName?: string;
48
+ country?: string;
49
+ lastNameEng?: string;
50
+ firstNameEng?: string;
51
+ middleNameEng?: string;
52
+ email?: string;
53
+ phones?: string[];
54
+ faculty?: string;
55
+ specialty?: string;
56
+ degree?: string;
57
+ group?: string;
58
+ studyForm?: string;
59
+ paymentForm?: string;
60
+ enrollmentOrder?: string;
61
+ enrollmentDate?: string;
62
+ studyDuration?: string;
63
+ graduationDate?: string;
64
+ }
65
+ /**
66
+ * name та prId дисципліни
67
+ * @category CabinetStudent
68
+ * @remarks
69
+ * - `name` — Повна назва дисципліни
70
+ * - `prId` — Айді дисципліни
71
+ */
72
+ export interface Discipline {
73
+ name: string;
74
+ prId: string;
75
+ }
76
+ /**
77
+ * name та prId дисципліни
78
+ * @category CabinetStudent
79
+ * @remarks
80
+ * - `ok` — Успіх отримання токену
81
+ * - `disciplines` — Масив дисциплін {@link Discipline}
82
+ */
83
+ export interface Disciplines {
84
+ ok: boolean;
85
+ disciplines: Discipline[];
86
+ }
87
+ /**
88
+ * Опис заняття у кабінеті студента
89
+ * @category CabinetStudent
90
+ * @remarks
91
+ * - `teacher` — Прізвище та ініціали викладача
92
+ * - `date` — Дата заняття у форматі "dd.mm.yyyy"
93
+ * - `type` — Тип заняття: "Лек", "ПрСем", "Лаб", "МК", "Екз"
94
+ * - `time` — Час заняття у форматі "HH:MM-HH:MM"
95
+ * - `index` — Значення атрибута `data-ind`, унікальний ідентифікатор
96
+ */
97
+ export interface ScheduleItem {
98
+ teacher: string;
99
+ date: string;
100
+ type: string;
101
+ time: string;
102
+ index: string;
103
+ }
104
+ /**
105
+ * Список оцінок студента.
106
+ * @category CabinetStudent
107
+ * @remarks
108
+ * - `id` — Унікальний ідентифікатор студента
109
+ * - `scores` — Оцінки по днях, масив масивів рядків (перший елемент - основна оцінка, другий елемент - оцінка перездачі)
110
+ * - `absences` — Кількість пропусків
111
+ * - `uabsences` — Кількість невиправлених пропусків
112
+ * - `finalScore` — Фінальна оцінка
113
+ */
114
+ export interface StudentScores {
115
+ id: string;
116
+ scores: string[][];
117
+ absences: number;
118
+ uabsences: number;
119
+ finalScore: string;
120
+ }
121
+ /**
122
+ * Об'єкт оцінок з предмету.
123
+ * @category CabinetStudent
124
+ * @remarks
125
+ * - `ok` — Успіх отримання токену
126
+ * - `prId` — Айді дисципліни
127
+ * - `studentId` — Унікальний айді студента для предметів
128
+ * - `scheduleItem` — Опис заняття у кабінеті студента {@link ScheduleItem}
129
+ * - `studentScores` — Список оцінок студента {@link StudentScores}
130
+ */
131
+ export interface Scores {
132
+ ok: boolean;
133
+ prId: string;
134
+ studentId: string;
135
+ scheduleItem: ScheduleItem[];
136
+ studentScores: StudentScores[];
137
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,10 @@
1
+ import { AcademicGroups } from './types.js';
2
+ /**
3
+ * Отримати всі академічні групи
4
+ * @category CabinetTeacher
5
+ * @param sesId - ID сесії користувача
6
+ * @param sessGUID - GUID сесії з cookie
7
+ * @throws {Error} Якщо виникають проблеми з запитом або дані некоректні.
8
+ * @returns Об'єкт академічних груп {@link AcademicGroups}
9
+ */
10
+ export declare function getAcademicGroups(sesId: string, sessGUID: string): Promise<AcademicGroups>;
@@ -0,0 +1,36 @@
1
+ import fetch from 'cross-fetch';
2
+ import iconv from 'iconv-lite';
3
+ import { generateCookieString, isLoginPage } from '../cabinet/session.js';
4
+ import { parseGroupsPage } from '../cabinet/parsers.js';
5
+ /**
6
+ * Отримати всі академічні групи
7
+ * @category CabinetTeacher
8
+ * @param sesId - ID сесії користувача
9
+ * @param sessGUID - GUID сесії з cookie
10
+ * @throws {Error} Якщо виникають проблеми з запитом або дані некоректні.
11
+ * @returns Об'єкт академічних груп {@link AcademicGroups}
12
+ */
13
+ export async function getAcademicGroups(sesId, sessGUID) {
14
+ try {
15
+ let result = { ok: false, groups: [] };
16
+ const cookieString = generateCookieString(sessGUID);
17
+ const response1 = await fetch(`https://dekanat.zu.edu.ua/cgi-bin/kaf.cgi?half=0&sesID=${sesId}&n=2&action=groups`, { headers: { Cookie: cookieString } });
18
+ const buffer1 = await response1.arrayBuffer();
19
+ const html1 = iconv.decode(Buffer.from(buffer1), 'windows-1251');
20
+ if (isLoginPage(html1))
21
+ return result;
22
+ result.groups = parseGroupsPage(html1, 1);
23
+ const response2 = await fetch(`https://dekanat.zu.edu.ua/cgi-bin/kaf.cgi?half=1&sesID=${sesId}&n=2&action=groups`, { headers: { Cookie: cookieString } });
24
+ const buffer2 = await response2.arrayBuffer();
25
+ const html2 = iconv.decode(Buffer.from(buffer2), 'windows-1251');
26
+ if (isLoginPage(html2))
27
+ return result;
28
+ result.groups = [...result.groups, ...parseGroupsPage(html2, 2)];
29
+ result.ok = true;
30
+ return result;
31
+ }
32
+ catch (e) {
33
+ console.error('Error in getAcademicGroups:', e);
34
+ throw e;
35
+ }
36
+ }
@@ -0,0 +1,71 @@
1
+ import { DataTeacher, AcademicGroups, AcademicGroup } from './types.js';
2
+ /**
3
+ * Клас кабінету викладача
4
+ * @category CabinetTeacher
5
+ */
6
+ export declare class CabinetTeacher {
7
+ /**
8
+ * Логін користувача
9
+ */
10
+ login: string;
11
+ /**
12
+ * Пароль від кабінету викладача
13
+ */
14
+ password: string;
15
+ /**
16
+ * ID сесії викладача
17
+ */
18
+ sesID?: string;
19
+ /**
20
+ * GUID сесії з cookie
21
+ */
22
+ sessGUID?: string;
23
+ /**
24
+ * Семестр для пошуку оцінок (0 - перший, 1 - другий)
25
+ */
26
+ semester: 1 | 2;
27
+ /**
28
+ * Данні викладача {@link DataTeacher}
29
+ */
30
+ data?: DataTeacher;
31
+ /**
32
+ * Список академічних груп {@link AcademicGroup}
33
+ */
34
+ academicGroups: AcademicGroup[];
35
+ /**
36
+ * Конструктор
37
+ * @param login - Логін користувача
38
+ * @param password - Пароль
39
+ */
40
+ constructor(login: string, password: string);
41
+ /**
42
+ * Авторизація
43
+ */
44
+ auth(login?: string, password?: string): Promise<boolean>;
45
+ /**
46
+ * Базове значення семестру
47
+ */
48
+ private setSemester;
49
+ /**
50
+ * Отримання всіх данних
51
+ */
52
+ loadData(): Promise<boolean>;
53
+ /**
54
+ * Відновлення сесії
55
+ */
56
+ setSession(sesID: string, sessGUID: string): Promise<boolean>;
57
+ /**
58
+ * Перевірка валідності сесії
59
+ */
60
+ isValidSession(): Promise<boolean>;
61
+ /**
62
+ * Отримати всі академічні групи
63
+ * @returns Об'єкт академічних груп {@link AcademicGroups}
64
+ */
65
+ getAcademicGroups(): Promise<AcademicGroups>;
66
+ /**
67
+ * Отримати анкетні данні викладача
68
+ * @returns Об'єкт {@link Data}
69
+ */
70
+ getData(): Promise<DataTeacher>;
71
+ }