zdu-student-api 1.1.3 → 1.1.4

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.
@@ -1,4 +1,4 @@
1
- import { AudienceRoom, Blocks } from './types.ts';
1
+ import { AudienceRoom, Blocks } from './types';
2
2
  /**
3
3
  * Клас розкладу
4
4
  * @category Audience
@@ -0,0 +1,90 @@
1
+ import iconv from 'iconv-lite';
2
+ import fetch from 'cross-fetch';
3
+ /**
4
+ * Клас розкладу
5
+ * @category Audience
6
+ */
7
+ export class Audience {
8
+ /**
9
+ * Назва корпусу
10
+ */
11
+ blockName;
12
+ /**
13
+ * Номер пари
14
+ */
15
+ lesson = 1;
16
+ /**
17
+ * Тип аудиторій який є в даному корпусі
18
+ */
19
+ roomType;
20
+ /**
21
+ * Кількість місць не менше ніж
22
+ */
23
+ size_min;
24
+ /**
25
+ * Кількість місць не більше ніж
26
+ */
27
+ size_max;
28
+ /**
29
+ * Дата аудиторії
30
+ */
31
+ roomsDate = new Date();
32
+ /**
33
+ * Наявніть доп. обладнання типу 1, 2, 3, 4, 5, 6, 7, 8
34
+ */
35
+ dops = [];
36
+ /**
37
+ * Повертає список аудиторій
38
+ *
39
+ * @throws {Error} Якщо виникають проблеми з запитом або дані некоректні.
40
+ *
41
+ * @example
42
+ * ```ts
43
+ * import { Audience } from "./audience.ts";
44
+ * const audience = new Audience();
45
+ * try {
46
+ * const audiences = await audience.getAudience();
47
+ * console.log("Аудиторії:", audiences); // Поверне список аудиторій
48
+ * } catch (err: any) {
49
+ * console.error(err.message);
50
+ * }
51
+ * ```
52
+ *
53
+ * @remarks
54
+ * У `err.message` може повертатися простий текст помилки,
55
+ * або об’єкт у форматі:
56
+ * ```JSON
57
+ * {
58
+ * "error_message": "Текст помилки",
59
+ * "errorcode": "Код помилки"
60
+ * }
61
+ * ```
62
+ *
63
+ * Де:
64
+ * - `error_message` - текст помилки відповідно до {@link scheduleErrors}
65
+ * - `errorcode` - код помилки відповідно до {@link scheduleErrors}
66
+ */
67
+ async getAudience() {
68
+ const date = this.roomsDate.toLocaleDateString('uk-UA', {
69
+ day: '2-digit',
70
+ month: '2-digit',
71
+ year: 'numeric'
72
+ });
73
+ let dops = '';
74
+ this.dops.forEach(dop => {
75
+ dops += `&dop_${dop}=yes`;
76
+ });
77
+ const response = await fetch(`https://dekanat.zu.edu.ua/cgi-bin/timetable_export.cgi?req_type=free_rooms_list&&block_name=${this.blockName !== undefined ? this.encodeCP1251(this.blockName) : ''}&size_min=${this.size_min !== undefined ? this.size_min : ''}&size_max=${this.size_max !== undefined ? this.size_max : ''}&room_type=${this.roomType !== undefined ? this.encodeCP1251(this.roomType) : ''}&begin_date=${date}&lesson=${this.lesson}${dops}&req_format=json&coding_mode=UTF8&bs=%D1%F4%EE%F0%EC%F3%E2%E0%F2%E8+%E7%E0%EF%E8%F2`);
78
+ if (!response.ok)
79
+ throw new Error(`HTTP error ${response.status}: ${response.statusText}`);
80
+ const data = await response.json();
81
+ if (data.psrozklad_export.code !== '0') {
82
+ throw new Error(JSON.stringify(data.psrozklad_export.error) || "Unknown error");
83
+ }
84
+ return data.psrozklad_export.free_rooms.rooms;
85
+ }
86
+ encodeCP1251(str) {
87
+ const buf = iconv.encode(str, 'win1251');
88
+ return Array.from(buf).map(b => '%' + b.toString(16).toUpperCase().padStart(2, '0')).join('');
89
+ }
90
+ }
@@ -1,2 +1,2 @@
1
- export * from "./sesId.ts";
2
- export * from "./types.ts";
1
+ export * from "./sesId";
2
+ export * from "./types";
@@ -0,0 +1,2 @@
1
+ export * from "./sesId";
2
+ export * from "./types";
@@ -0,0 +1,39 @@
1
+ import fetch from 'cross-fetch';
2
+ import iconv from "iconv-lite";
3
+ /**
4
+ * Отримати sesID та sessGUID користувача
5
+ * @category Cabinet
6
+ * @param family - прізвище користувача
7
+ * @param password - пароль
8
+ * @returns Об'єкт { sesID, sessGUID }
9
+ */
10
+ export async function getSesId(family, password) {
11
+ try {
12
+ const formData = `user_name=${family}&user_pwd=${password}&n=1&rout=&t=16161`;
13
+ const encodedFormData = iconv.encode(formData, "windows-1251");
14
+ const response = await fetch("https://dekanat.zu.edu.ua/cgi-bin/classman.cgi?n=1&ts=16161", {
15
+ method: "POST",
16
+ body: new Uint8Array(encodedFormData),
17
+ redirect: "manual",
18
+ });
19
+ if (response.status === 302) {
20
+ const buffer = await response.arrayBuffer();
21
+ const responseText = iconv.decode(Buffer.from(buffer), "utf-8");
22
+ const cookies = response.headers.get("set-cookie");
23
+ let sessGUID = "";
24
+ if (cookies) {
25
+ const sessGUIDStart = cookies.indexOf("SessGUID=") + "SessGUID=".length;
26
+ const sessGUIDEnd = cookies.indexOf(";", sessGUIDStart);
27
+ sessGUID = cookies.substring(sessGUIDStart, sessGUIDEnd);
28
+ }
29
+ const sesIDIndex = responseText.indexOf("sesID=") + 6;
30
+ const sesID = responseText.substring(sesIDIndex, sesIDIndex + 36);
31
+ return { ok: true, sesID, sessGUID };
32
+ }
33
+ return { ok: false, sesID: '', sessGUID: '' };
34
+ }
35
+ catch (e) {
36
+ console.error("Error in getSesID:", e);
37
+ throw e;
38
+ }
39
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -1,4 +1,4 @@
1
- import { Faculty } from './types.ts';
1
+ import { Faculty } from './types';
2
2
  /**
3
3
  * Список факультетів університету.
4
4
  * @category Schedule
@@ -0,0 +1,100 @@
1
+ /**
2
+ * Список факультетів університету.
3
+ * @category Schedule
4
+ *
5
+ * @remarks
6
+ * - `none`: { id: 0, name: 'Оберіть факультет' }
7
+ * - `physicsMath`: { id: 1001, name: 'Фізико-математичний факультет' }
8
+ * - `philologyJournalism`: { id: 1002, name: 'Навчально-науковий інститут філології та журналістики' }
9
+ * - `historyLawPublic`: { id: 1003, name: 'Факультет історії, права та публічного управління' }
10
+ * - `foreignPhilology`: { id: 1004, name: 'Навчально-науковий інститут іноземної філології' }
11
+ * - `natural`: { id: 1005, name: 'Природничий факультет' }
12
+ * - `pedagogy`: { id: 1006, name: 'Навчально-науковий інститут педагогіки' }
13
+ * - `socialPsychology`: { id: 1007, name: 'Соціально-психологічний факультет' }
14
+ * - `physicalEducation`: { id: 1008, name: 'Факультет фізичного виховання і спорту' }
15
+ * - `preUniversityCenter`: { id: 1009, name: 'Центр доуніверситетської освіти та освіти дорослих' }
16
+ * - `partTime`: { id: 1010, name: 'Заочна форма навчання' }
17
+ * - `postgraduate`: { id: 1011, name: 'Відділ аспірантури та докторантури' }
18
+ * - `scientificLyceum`: { id: 1012, name: 'Науковий ліцей' }
19
+ */
20
+ export const faculties = {
21
+ none: { id: 0, name: 'Оберіть факультет' },
22
+ physicsMath: { id: 1001, name: 'Фізико-математичний факультет' },
23
+ philologyJournalism: { id: 1002, name: 'Навчально-науковий інститут філології та журналістики' },
24
+ historyLawPublic: { id: 1003, name: 'Факультет історії, права та публічного управління' },
25
+ foreignPhilology: { id: 1004, name: 'Навчально-науковий інститут іноземної філології' },
26
+ natural: { id: 1005, name: 'Природничий факультет' },
27
+ pedagogy: { id: 1006, name: 'Навчально-науковий інститут педагогіки' },
28
+ socialPsychology: { id: 1007, name: 'Соціально-психологічний факультет' },
29
+ physicalEducation: { id: 1008, name: 'Факультет фізичного виховання і спорту' },
30
+ preUniversityCenter: { id: 1009, name: 'Центр доуніверситетської освіти та освіти дорослих' },
31
+ partTime: { id: 1010, name: 'Заочна форма навчання' },
32
+ postgraduate: { id: 1011, name: 'Відділ аспірантури та докторантури' },
33
+ scientificLyceum: { id: 1012, name: 'Науковий ліцей' }
34
+ };
35
+ /**
36
+ * Список помилок для розкладу.
37
+ * @category Schedule
38
+ *
39
+ * @remarks
40
+ * Ключі — числові коди помилок.
41
+ * Значення — опис помилки.
42
+ *
43
+ * Коди помилок:
44
+ * - -200: Не має доступу до сервера або помилка доступу до бази даних
45
+ * - -100: Помилка у роботі модуля, зверніться до розробника
46
+ * - -90: Об`єкт, для якого потрібно показати розклад, не знайдено
47
+ * - -80: Неправильний режим (помилка у параметрі req_mode або req_type)
48
+ * - -70: Помилка у датах
49
+ * - -60: Помилка у параметрах
50
+ * - -7: Зараз відбувається технічне обслуговування бази, робота тимчасово неможлива!
51
+ * - -6: Вигрузка всього розкладу разом заборонена Адмiнiстратором
52
+ * - -5: Технічні роботи на сервері
53
+ * - -4: За даним запитом нічого не знайдено
54
+ * - -3: Перегляд розкладу на вказані дати заблоковано адміністратором (Розклад у процесі складання і ще не готовий для демонстрації)
55
+ * - -2: Перегляд розкладу заблоковано адміністратором (Розклад у процесі складання і ще не готовий для демонстрації)
56
+ * - -1: Розклад у базі відсутній
57
+ */
58
+ export const scheduleErrors = {
59
+ [-200]: 'Не має доступу до сервера або помилка доступу до бази даних',
60
+ [-100]: 'Помилка у роботі модуля, зверніться до розробника',
61
+ [-90]: 'Об`єкт, для якого потрібно показати розклад, не знайдено',
62
+ [-80]: 'Неправильний режим (помилка у параметрі req_mode або req_type)',
63
+ [-70]: 'Помилка у датах',
64
+ [-60]: 'Помилка у параметрах',
65
+ [-7]: 'Зараз відбувається технічне обслуговування бази, робота тимчасово неможлива!',
66
+ [-6]: 'Вигрузка всього розкладу разом заборонена Адмiнiстратором',
67
+ [-5]: 'Технічні роботи на сервері',
68
+ [-4]: 'За даним запитом нічого не знайдено',
69
+ [-3]: 'Перегляд розкладу на вказані дати заблоковано адміністратором (Розклад у процесі складання і ще не готовий для демонстрації)',
70
+ [-2]: 'Перегляд розкладу заблоковано адміністратором (Розклад у процесі складання і ще не готовий для демонстрації)',
71
+ [-1]: 'Розклад у базі відсутній'
72
+ };
73
+ /**
74
+ * Тип розкладу.
75
+ * @category Schedule
76
+ *
77
+ * @remarks
78
+ * Типи: group, teacher, room.
79
+ */
80
+ export const scheduleTypes = {
81
+ group: 'group',
82
+ teacher: 'teacher',
83
+ room: 'room',
84
+ };
85
+ /**
86
+ * Блоки
87
+ * @category Audience
88
+ */
89
+ export const blocks = {
90
+ block_1: '№1',
91
+ block_2: '№2',
92
+ block_3: '№3',
93
+ block_4: '№4',
94
+ block_5: '№5',
95
+ hostel_1: 'гуртож №1',
96
+ hostel_2: 'гуртож №2',
97
+ hostel_3: 'гуртож №3',
98
+ hostel_4: 'гуртож №4',
99
+ hostel_5: 'гуртож №5',
100
+ };
@@ -0,0 +1,41 @@
1
+ import { Audience } from "./audience";
2
+ import { getSesId } from "./cabinet/index";
3
+ // const schedule = new Schedule();
4
+ // schedule.group = '23Бд-СОінф123'
5
+ // schedule.type = 'group'
6
+ // schedule.rosText = true;
7
+ // //schedule.beginDate.setMonth(schedule.beginDate.getMonth() - 1);
8
+ // schedule.allStreamComponents = true;
9
+ // try {
10
+ // const sc = await schedule.getSchedule();
11
+ // console.log("Розклад:", sc);
12
+ // } catch (err: any) {
13
+ // console.error(err.message);
14
+ // console.error(scheduleErrors[JSON.parse(err.message).errorcode]);
15
+ // }
16
+ // schedule.roomId = 35
17
+ // schedule.type = 'room'
18
+ // schedule.rosText = true;
19
+ // //schedule.beginDate.setMonth(schedule.beginDate.getMonth() - 1);
20
+ // schedule.allStreamComponents = true;
21
+ // try {
22
+ // const sc = await schedule.getSchedule();
23
+ // console.log("Розклад:", sc);
24
+ // } catch (err: any) {
25
+ // console.error(err.message);
26
+ // }
27
+ //console.log((await getGroups('25Бд-Комп'))) // -3158
28
+ // console.log((await getTeachers('Кривонос Олександр')))
29
+ // console.log((await getRooms('319')))
30
+ const audience = new Audience();
31
+ audience.blockName = "гуртож №3";
32
+ try {
33
+ const audiences = await audience.getAudience();
34
+ console.log("Аудиторії:", audiences);
35
+ }
36
+ catch (err) {
37
+ console.error(err.message);
38
+ }
39
+ // console.log((await getTypesAudience('Ле')));
40
+ //console.log((await getDops()));
41
+ console.log((await getSesId("FFFFF", "123456789")));
package/dist/index.d.ts CHANGED
@@ -1,10 +1,10 @@
1
- export * from "./schedule.ts";
2
- export * from "./types.ts";
3
- export * from "./constants.ts";
4
- export * from "./utility/groups.ts";
5
- export * from "./utility/rooms.ts";
6
- export * from "./utility/teachers.ts";
7
- export * from "./audience.ts";
8
- export * from "./utility/types-audience.ts";
9
- export * from "./utility/dops.ts";
10
- export * from "./cabinet/index.ts";
1
+ export * from "./schedule";
2
+ export * from "./types";
3
+ export * from "./constants";
4
+ export * from "./utility/groups";
5
+ export * from "./utility/rooms";
6
+ export * from "./utility/teachers";
7
+ export * from "./audience";
8
+ export * from "./utility/types-audience";
9
+ export * from "./utility/dops";
10
+ export * from "./cabinet/index";
package/dist/index.js ADDED
@@ -0,0 +1,10 @@
1
+ export * from "./schedule";
2
+ export * from "./types";
3
+ export * from "./constants";
4
+ export * from "./utility/groups";
5
+ export * from "./utility/rooms";
6
+ export * from "./utility/teachers";
7
+ export * from "./audience";
8
+ export * from "./utility/types-audience";
9
+ export * from "./utility/dops";
10
+ export * from "./cabinet/index";
@@ -1,4 +1,4 @@
1
- import { BaseLesson, DetailedLesson, Faculty, ScheduleTypes } from './types.ts';
1
+ import { BaseLesson, DetailedLesson, Faculty, ScheduleTypes } from './types';
2
2
  /**
3
3
  * Клас розкладу
4
4
  * @category Schedule
@@ -0,0 +1,152 @@
1
+ import iconv from 'iconv-lite';
2
+ import fetch from 'cross-fetch';
3
+ import { faculties } from './constants';
4
+ /**
5
+ * Клас розкладу
6
+ * @category Schedule
7
+ */
8
+ export class Schedule {
9
+ /**
10
+ * Тип розкладу.
11
+ *
12
+ * Типи: group, teacher, room.
13
+ */
14
+ type = 'group';
15
+ /**
16
+ * Група
17
+ */
18
+ group = '';
19
+ /**
20
+ * Id групи
21
+ */
22
+ groupId;
23
+ /**
24
+ * Викладач
25
+ */
26
+ teacher = '';
27
+ /**
28
+ * Id викладача
29
+ */
30
+ teacherId;
31
+ /**
32
+ * Аудиторія
33
+ */
34
+ room = '';
35
+ /**
36
+ * Id аудиторії
37
+ */
38
+ roomId;
39
+ /**
40
+ * Факультет.
41
+ *
42
+ * @example
43
+ * Можна призначити одну з констант з `faculties`, наприклад:
44
+ * ```ts
45
+ * schedule.faculty = faculties.physicsMath;
46
+ * console.log(schedule.faculty.id); // 1001
47
+ * console.log(schedule.faculty.name); // 'Фізико-математичний факультет'
48
+ * ```
49
+ */
50
+ faculty = faculties.none;
51
+ /**
52
+ * Курс
53
+ *
54
+ * `0` - не вибрано
55
+ */
56
+ course = 0;
57
+ /**
58
+ * Початкова дата розкладу
59
+ */
60
+ beginDate = new Date();
61
+ /**
62
+ * Кінцева дата розкладу (за промовчанням +7 днів)
63
+ */
64
+ endDate = new Date(this.beginDate.getTime() + 7 * 24 * 60 * 60 * 1000);
65
+ /**
66
+ * Показувати пусті дні - false
67
+ */
68
+ showEmpty = false;
69
+ /**
70
+ * false - сформований текст (за промовчанням)
71
+ * true - окремі стовпчики
72
+ */
73
+ _rosText = false;
74
+ /**
75
+ * Показувати повний склад потоку (тільки для rosText=true)
76
+ */
77
+ allStreamComponents = false;
78
+ set rosText(value) {
79
+ this._rosText = value;
80
+ if (!value)
81
+ this.allStreamComponents = false;
82
+ }
83
+ get rosText() {
84
+ return this._rosText;
85
+ }
86
+ /**
87
+ * Повертає список пар (розклад)
88
+ *
89
+ * @throws {Error} Якщо виникають проблеми з запитом або дані некоректні.
90
+ *
91
+ * @example
92
+ * ```ts
93
+ * import { Schedule, scheduleErrors } from "./index.ts";
94
+ * const schedule = new Schedule();
95
+ * schedule.group = '23Бд-СОінф123' // встановлюєм неправильну назву групи
96
+ * schedule.type = 'group' // встановлєм тип пошуку по групі
97
+ * schedule.rosText = true; // встановлюєм окремі стовпчики
98
+ * schedule.allStreamComponents = true; // встановлюєм повний склад потоку
99
+ * try {
100
+ * const mySchedule = await schedule.getSchedule();
101
+ * console.log("Розклад:", mySchedule);
102
+ * } catch (err: any) {
103
+ * // Отримуєм помилку тому що ми неправильно вказали назву групи
104
+ * console.error(err.message); // Поверне: "{"error_message":"Об‘єкт - 23Бд-СОінф123 - Об‘єкт не знайдено ","errorcode":"-90"}"
105
+ * console.error(scheduleErrors[JSON.parse(err.message).errorcode]); // Поверне: "Об`єкт, для якого потрібно показати розклад, не знайдено"
106
+ * }
107
+ * ```
108
+ *
109
+ * @remarks
110
+ * У `err.message` може повертатися простий текст помилки,
111
+ * або об’єкт у форматі:
112
+ * ```JSON
113
+ * {
114
+ * "error_message": "Текст помилки",
115
+ * "errorcode": "Код помилки"
116
+ * }
117
+ * ```
118
+ *
119
+ * Де:
120
+ * - `error_message` - текст помилки відповідно до {@link scheduleErrors}
121
+ * - `errorcode` - код помилки відповідно до {@link scheduleErrors}
122
+ */
123
+ async getSchedule() {
124
+ const beginDate = this.beginDate.toLocaleDateString('uk-UA', {
125
+ day: '2-digit',
126
+ month: '2-digit',
127
+ year: 'numeric'
128
+ });
129
+ const endDate = this.endDate.toLocaleDateString('uk-UA', {
130
+ day: '2-digit',
131
+ month: '2-digit',
132
+ year: 'numeric'
133
+ });
134
+ let id = (this.type === 'group' ? this.groupId : this.type === 'teacher' ? this.teacherId : this.roomId);
135
+ if (!id)
136
+ id = '';
137
+ let name = (this.type === 'group' ? this.group : this.type === 'teacher' ? this.teacher : this.room);
138
+ name = this.encodeCP1251(name);
139
+ const response = await fetch(`https://dekanat.zu.edu.ua/cgi-bin/timetable_export.cgi?req_type=rozklad&req_mode=${this.type}&OBJ_ID=${id}&OBJ_name=${name}&dep_name=&begin_date=${beginDate}&end_date=${endDate}&ros_text=${this.rosText ? 'separated' : 'united'}${this.showEmpty ? '' : '&show_empty=yes'}${this.allStreamComponents ? '' : '&all_stream_components=yes'}&req_format=json&coding_mode=UTF8&bs=%D1%F4%EE%F0%EC%F3%E2%E0%F2%E8+%E7%E0%EF%E8%F2`);
140
+ if (!response.ok)
141
+ throw new Error(`HTTP error ${response.status}: ${response.statusText}`);
142
+ const data = await response.json();
143
+ if (data.psrozklad_export.code !== '0') {
144
+ throw new Error(JSON.stringify(data.psrozklad_export.error) || "Unknown error");
145
+ }
146
+ return data.psrozklad_export.roz_items;
147
+ }
148
+ encodeCP1251(str) {
149
+ const buf = iconv.encode(str, 'win1251');
150
+ return Array.from(buf).map(b => '%' + b.toString(16).toUpperCase().padStart(2, '0')).join('');
151
+ }
152
+ }
package/dist/types.js ADDED
@@ -0,0 +1,2 @@
1
+ ;
2
+ export {};
@@ -1,4 +1,4 @@
1
- import { Dop } from "../types.ts";
1
+ import { Dop } from "../types";
2
2
  /**
3
3
  * Повертає список доп. обладнання аудиторій
4
4
  * @category Utility
@@ -0,0 +1,61 @@
1
+ import fetch from 'cross-fetch';
2
+ /**
3
+ * Повертає список доп. обладнання аудиторій
4
+ * @category Utility
5
+ *
6
+ * @param query - Рядок пошуку доп. обладнання
7
+ * @returns Масив доп. обладнання
8
+ *
9
+ * @deprecated Ця функція не використовується і повертає безкорисливі данні.
10
+ *
11
+ * @example
12
+ * ```ts
13
+ * console.log((await getDops()));
14
+ * ```
15
+ *
16
+ * @remarks
17
+ * Виведе:
18
+ * ```JSON
19
+ * [
20
+ * {
21
+ * name: 'Не використовується',
22
+ * ...
23
+ * }
24
+ * ]
25
+ * ```
26
+ */
27
+ export async function getDops(query) {
28
+ try {
29
+ const url = `https://dekanat.zu.edu.ua/cgi-bin/timetable_export.cgi?req_type=room_dop_list&req_format=json&coding_mode=UTF8&bs=%D1%F4%EE%F0%EC%F3%E2%E0%F2%E8+%E7%E0%EF%E8%F2`;
30
+ const response = await fetch(url);
31
+ if (!response.ok)
32
+ return [];
33
+ const text = await response.text();
34
+ const fixed = fixBrokenJson(text);
35
+ const data = JSON.parse(fixed);
36
+ let dops = data.psrozklad_export.IDs;
37
+ if (query) {
38
+ dops = dops.filter(dop => dop.name.includes(query));
39
+ }
40
+ return dops;
41
+ }
42
+ catch (e) {
43
+ return [];
44
+ }
45
+ }
46
+ function fixBrokenJson(input) {
47
+ let s = input.replace(/,\s*(?=[}\]])/g, "")
48
+ .replace(/(?<=\[\s*),/g, "")
49
+ .replace(/,,+/g, ",")
50
+ .replace(/\[\s*,\s*{/g, "[{")
51
+ .replace(/}]+(?=\s*,\s*"code")/g, "}");
52
+ const firstValidEnd = s.indexOf('}}');
53
+ if (firstValidEnd !== -1) {
54
+ s = s.slice(0, firstValidEnd + 1);
55
+ }
56
+ const lastBrace = s.lastIndexOf("}");
57
+ if (lastBrace !== -1) {
58
+ s = s.slice(0, lastBrace + 1);
59
+ }
60
+ return s;
61
+ }
@@ -1,4 +1,4 @@
1
- import { Group } from "../types.ts";
1
+ import { Group } from "../types";
2
2
  /**
3
3
  * Повертає список груп
4
4
  * @category Utility
@@ -0,0 +1,46 @@
1
+ import fetch from 'cross-fetch';
2
+ /**
3
+ * Повертає список груп
4
+ * @category Utility
5
+ *
6
+ * @param query - Рядок пошуку групи
7
+ * @returns Масив груп
8
+ *
9
+ * @example
10
+ * ```ts
11
+ * console.log((await getGroups('23Бд-СОінф')));
12
+ * ```
13
+ *
14
+ * @remarks
15
+ * Виведе:
16
+ * ```JSON
17
+ * [
18
+ * {
19
+ * name: '23Бд-СОінф',
20
+ * id: '-3158',
21
+ * faculty: 'Фізико-математичний факультет'
22
+ * }
23
+ * ]
24
+ * ```
25
+ */
26
+ export async function getGroups(query) {
27
+ try {
28
+ const url = `https://dekanat.zu.edu.ua/cgi-bin/timetable_export.cgi?req_type=obj_list&req_mode=group&show_ID=yes&req_format=json&coding_mode=UTF8&bs=%D1%F4%EE%F0%EC%F3%E2%E0%F2%E8+%E7%E0%EF%E8%F2`;
29
+ const response = await fetch(url);
30
+ if (!response.ok)
31
+ return [];
32
+ const data = await response.json();
33
+ let groups = data.psrozklad_export.departments.flatMap((dept) => dept.objects.map((obj) => ({
34
+ name: obj.name,
35
+ id: obj.ID,
36
+ faculty: dept.name
37
+ })));
38
+ if (query) {
39
+ groups = groups.filter(g => g.name.includes(query));
40
+ }
41
+ return groups;
42
+ }
43
+ catch (e) {
44
+ return [];
45
+ }
46
+ }
@@ -1,4 +1,4 @@
1
- import { Room } from "../types.ts";
1
+ import { Room } from "../types";
2
2
  /**
3
3
  * Повертає список аудиторій
4
4
  * @category Utility
@@ -0,0 +1,50 @@
1
+ import fetch from 'cross-fetch';
2
+ /**
3
+ * Повертає список аудиторій
4
+ * @category Utility
5
+ *
6
+ * @param query - Рядок пошуку аудиторії
7
+ * @returns Масив аудиторій
8
+ *
9
+ * @example
10
+ * ```ts
11
+ * console.log((await getRooms('319')));
12
+ * ```
13
+ *
14
+ * @remarks
15
+ * Виведе:
16
+ * ```JSON
17
+ * [
18
+ * { name: '319/№1', id: '35', block: '№1' },
19
+ * { name: '319/№3', id: '270', block: '№3' }
20
+ * ]
21
+ * ```
22
+ */
23
+ export async function getRooms(query) {
24
+ try {
25
+ const url = "https://dekanat.zu.edu.ua/cgi-bin/timetable_export.cgi?req_type=obj_list&req_mode=room&show_ID=yes&req_format=json&coding_mode=UTF8&bs=%D1%F4%EE%F0%EC%F3%E2%E0%F2%E8+%E7%E0%EF%E8%F2";
26
+ const response = await fetch(url);
27
+ if (!response.ok)
28
+ return [];
29
+ const data = await response.json();
30
+ const rooms = [];
31
+ for (const block of data.psrozklad_export.blocks) {
32
+ for (const obj of block.objects) {
33
+ rooms.push({
34
+ name: obj.name,
35
+ id: obj.ID,
36
+ block: block.name,
37
+ });
38
+ }
39
+ }
40
+ if (query && query.trim() !== "") {
41
+ const q = query.toLowerCase();
42
+ return rooms.filter(room => room.name.toLowerCase().includes(q) ||
43
+ room.block.toLowerCase().includes(q));
44
+ }
45
+ return rooms;
46
+ }
47
+ catch (err) {
48
+ return [];
49
+ }
50
+ }
@@ -1,4 +1,4 @@
1
- import { Teacher } from "../types.ts";
1
+ import { Teacher } from "../types";
2
2
  /**
3
3
  * Повертає список викладачів
4
4
  * @category Utility
@@ -0,0 +1,67 @@
1
+ import fetch from 'cross-fetch';
2
+ /**
3
+ * Повертає список викладачів
4
+ * @category Utility
5
+ *
6
+ * @param query - Рядок пошуку викладача
7
+ * @returns Масив викладачів
8
+ *
9
+ * @example
10
+ * ```ts
11
+ * console.log((await getTeachers('Кривонос Олександр')));
12
+ * ```
13
+ *
14
+ * @remarks
15
+ * Виведе:
16
+ * ```JSON
17
+ * [
18
+ * {
19
+ * name: 'Кривонос О.М.',
20
+ * id: '420',
21
+ * faculty: 'Кафедра комп’ютерних наук та інформаційних технологій',
22
+ * surname: 'Кривонос',
23
+ * firstname: 'Олександр',
24
+ * lastname: 'Миколайович'
25
+ * }
26
+ * ]
27
+ * ```
28
+ */
29
+ export async function getTeachers(query) {
30
+ try {
31
+ const url = `https://dekanat.zu.edu.ua/cgi-bin/timetable_export.cgi?req_type=obj_list&req_mode=teacher&show_ID=yes&req_format=json&coding_mode=UTF8&bs=%D1%F4%EE%F0%EC%F3%E2%E0%F2%E8+%E7%E0%EF%E8%F2`;
32
+ const response = await fetch(url);
33
+ if (!response.ok)
34
+ return [];
35
+ const data = await response.json();
36
+ let teachers = data.psrozklad_export.departments.flatMap((dept) => dept.objects.map((t) => ({
37
+ name: t.name,
38
+ id: t.ID,
39
+ faculty: dept.name,
40
+ surname: t.P,
41
+ firstname: t.I,
42
+ lastname: t.B
43
+ })));
44
+ if (query) {
45
+ const q = query.toLowerCase();
46
+ teachers = teachers.filter(t => {
47
+ const shortName = t.name.toLowerCase();
48
+ const fullName = `${t.surname} ${t.firstname} ${t.lastname}`.toLowerCase();
49
+ const fullNameNoMiddle = `${t.surname} ${t.firstname}`.toLowerCase();
50
+ const surname = t.surname.toLowerCase();
51
+ const firstname = t.firstname.toLowerCase();
52
+ const lastname = t.lastname.toLowerCase();
53
+ return (shortName.includes(q) ||
54
+ fullName.includes(q) ||
55
+ fullNameNoMiddle.includes(q) ||
56
+ surname.includes(q) ||
57
+ firstname.includes(q) ||
58
+ lastname.includes(q) ||
59
+ t.id.includes(q));
60
+ });
61
+ }
62
+ return teachers;
63
+ }
64
+ catch (e) {
65
+ return [];
66
+ }
67
+ }
@@ -1,4 +1,4 @@
1
- import { TypeAudience } from "../types.ts";
1
+ import { TypeAudience } from "../types";
2
2
  /**
3
3
  * Повертає список типів аудиторій
4
4
  * @category Utility
@@ -0,0 +1,40 @@
1
+ import fetch from 'cross-fetch';
2
+ /**
3
+ * Повертає список типів аудиторій
4
+ * @category Utility
5
+ *
6
+ * @param query - Рядок пошуку типу
7
+ * @returns Масив типів аудиторій
8
+ *
9
+ * @example
10
+ * ```ts
11
+ * console.log((await getTypesAudience('Ле')));
12
+ * ```
13
+ *
14
+ * @remarks
15
+ * Виведе:
16
+ * ```JSON
17
+ * [
18
+ * {
19
+ * full: 'Лекція',
20
+ * short: 'лек'
21
+ * }
22
+ * ]
23
+ * ```
24
+ */
25
+ export async function getTypesAudience(query) {
26
+ try {
27
+ const url = `https://dekanat.zu.edu.ua/cgi-bin/timetable_export.cgi?req_type=room_type_list&req_format=json&coding_mode=UTF8&bs=%D1%F4%EE%F0%EC%F3%E2%E0%F2%E8+%E7%E0%EF%E8%F2`;
28
+ const response = await fetch(url);
29
+ if (!response.ok)
30
+ return [];
31
+ let typesAudience = (await response.json()).psrozklad_export.objects;
32
+ if (query) {
33
+ typesAudience = typesAudience.filter(ta => ta.full.includes(query));
34
+ }
35
+ return typesAudience;
36
+ }
37
+ catch (e) {
38
+ return [];
39
+ }
40
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zdu-student-api",
3
- "version": "1.1.3",
3
+ "version": "1.1.4",
4
4
  "description": "API client for ZDU student services",
5
5
  "author": "Nicita3 <ni596157@gmail.com> (https://github.com/Nicita-3)",
6
6
  "main": "dist/index.js",