chuvsu-js 2.2.0 → 2.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/README.md +4 -0
- package/dist/index.d.ts +2 -1
- package/dist/index.js +1 -1
- package/dist/tt/schedule.d.ts +4 -1
- package/dist/tt/schedule.js +13 -8
- package/dist/tt/utils.d.ts +16 -0
- package/dist/tt/utils.js +104 -15
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -5,6 +5,10 @@ Node.js библиотека для работы с порталами ЧувГ
|
|
|
5
5
|
- **tt.chuvsu.ru** — расписание занятий (факультеты, группы, преподаватели)
|
|
6
6
|
- **lk.chuvsu.ru** — личный кабинет студента (персональные данные)
|
|
7
7
|
|
|
8
|
+
> [!WARNING]
|
|
9
|
+
> Пока не доработана, код говно, замены занятий пока не парсит.
|
|
10
|
+
> Не надейтесь на правильный вывод расписания.
|
|
11
|
+
|
|
8
12
|
## Установка
|
|
9
13
|
|
|
10
14
|
```bash
|
package/dist/index.d.ts
CHANGED
|
@@ -2,7 +2,8 @@ export { LkClient } from "./lk/client.js";
|
|
|
2
2
|
export { TtClient } from "./tt/client.js";
|
|
3
3
|
export { Schedule } from "./tt/schedule.js";
|
|
4
4
|
export type { CacheEntry } from "./common/cache.js";
|
|
5
|
-
export { getCurrentPeriod, isSessionPeriod, getSemesterStart, getSemesterWeeks, getWeekNumber, getWeekdayName, getTimeSlots, getLessonNumber, getAdjacentSemester, } from "./tt/utils.js";
|
|
5
|
+
export { getCurrentPeriod, isSessionPeriod, getSemesterStart, getSemesterWeeks, getWeekNumber, getWeekdayName, getTimeSlots, getLessonNumber, getAdjacentSemester, isHoliday, RUSSIAN_HOLIDAYS, } from "./tt/utils.js";
|
|
6
|
+
export type { Holiday } from "./tt/utils.js";
|
|
6
7
|
export { Period, EducationType, AuthError, ParseError } from "./common/types.js";
|
|
7
8
|
export type { Time, WeekRange, Teacher, } from "./common/types.js";
|
|
8
9
|
export type { PersonalData, } from "./lk/types.js";
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export { LkClient } from "./lk/client.js";
|
|
2
2
|
export { TtClient } from "./tt/client.js";
|
|
3
3
|
export { Schedule } from "./tt/schedule.js";
|
|
4
|
-
export { getCurrentPeriod, isSessionPeriod, getSemesterStart, getSemesterWeeks, getWeekNumber, getWeekdayName, getTimeSlots, getLessonNumber, getAdjacentSemester, } from "./tt/utils.js";
|
|
4
|
+
export { getCurrentPeriod, isSessionPeriod, getSemesterStart, getSemesterWeeks, getWeekNumber, getWeekdayName, getTimeSlots, getLessonNumber, getAdjacentSemester, isHoliday, RUSSIAN_HOLIDAYS, } from "./tt/utils.js";
|
|
5
5
|
export { AuthError, ParseError } from "./common/types.js";
|
package/dist/tt/schedule.d.ts
CHANGED
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
import type { FullScheduleDay, SemesterWeek, Lesson } from "./types.js";
|
|
2
2
|
import { Period, EducationType } from "../common/types.js";
|
|
3
|
+
import { type Holiday } from "./utils.js";
|
|
3
4
|
export declare class Schedule {
|
|
4
5
|
readonly groupId: number;
|
|
5
6
|
readonly scheduleMap: Map<number, FullScheduleDay[]>;
|
|
6
7
|
readonly educationType: EducationType;
|
|
8
|
+
/** List of holidays to exclude from schedule queries. Pass `[]` to disable. */
|
|
9
|
+
readonly holidays: Holiday[];
|
|
7
10
|
private _period?;
|
|
8
|
-
constructor(groupId: number, scheduleMap: Map<number, FullScheduleDay[]>, period?: Period, educationType?: EducationType);
|
|
11
|
+
constructor(groupId: number, scheduleMap: Map<number, FullScheduleDay[]>, period?: Period, educationType?: EducationType, holidays?: Holiday[] | null);
|
|
9
12
|
/** Current (or fixed) period for this schedule. */
|
|
10
13
|
get period(): Period;
|
|
11
14
|
/** Days for the current period. */
|
package/dist/tt/schedule.js
CHANGED
|
@@ -1,14 +1,17 @@
|
|
|
1
|
-
import { getCurrentPeriod, isSessionPeriod, getWeekdayName, getMonday, getSemesterStart, getSemesterWeeks, getWeekNumber, getAdjacentSemester, filterSlots, slotsToLessons, } from "./utils.js";
|
|
1
|
+
import { getCurrentPeriod, isSessionPeriod, getWeekdayName, getMonday, getSemesterStart, getSemesterWeeks, getWeekNumber, getAdjacentSemester, filterSlots, slotsToLessons, sortLessons, isHoliday, RUSSIAN_HOLIDAYS, } from "./utils.js";
|
|
2
2
|
export class Schedule {
|
|
3
3
|
groupId;
|
|
4
4
|
scheduleMap;
|
|
5
5
|
educationType;
|
|
6
|
+
/** List of holidays to exclude from schedule queries. Pass `[]` to disable. */
|
|
7
|
+
holidays;
|
|
6
8
|
_period;
|
|
7
|
-
constructor(groupId, scheduleMap, period, educationType) {
|
|
9
|
+
constructor(groupId, scheduleMap, period, educationType, holidays) {
|
|
8
10
|
this.groupId = groupId;
|
|
9
11
|
this.scheduleMap = scheduleMap;
|
|
10
12
|
this.educationType = educationType ?? 1 /* EducationType.HigherEducation */;
|
|
11
13
|
this._period = period;
|
|
14
|
+
this.holidays = holidays ?? RUSSIAN_HOLIDAYS;
|
|
12
15
|
}
|
|
13
16
|
/** Current (or fixed) period for this schedule. */
|
|
14
17
|
get period() {
|
|
@@ -70,13 +73,15 @@ export class Schedule {
|
|
|
70
73
|
lessons.push(...slotsToLessons(d.slots, d.date));
|
|
71
74
|
}
|
|
72
75
|
}
|
|
73
|
-
return lessons;
|
|
76
|
+
return lessons.sort(sortLessons);
|
|
74
77
|
}
|
|
75
78
|
const slots = this.getSlotsForWeekday(weekday, days, opts);
|
|
76
79
|
const date = this.getDateForWeekday(weekday, period, opts?.week);
|
|
77
80
|
return slotsToLessons(slots, date);
|
|
78
81
|
}
|
|
79
82
|
forDate(date, opts) {
|
|
83
|
+
if (isHoliday(date, this.holidays))
|
|
84
|
+
return [];
|
|
80
85
|
const period = getCurrentPeriod({ date });
|
|
81
86
|
const lessons = [];
|
|
82
87
|
// 1. Check all periods for date-based (session) entries matching this date
|
|
@@ -103,7 +108,7 @@ export class Schedule {
|
|
|
103
108
|
lessons.push(...slotsToLessons(slots, date));
|
|
104
109
|
}
|
|
105
110
|
}
|
|
106
|
-
return lessons;
|
|
111
|
+
return lessons.sort(sortLessons);
|
|
107
112
|
}
|
|
108
113
|
forWeek(week, opts) {
|
|
109
114
|
const period = this.period;
|
|
@@ -127,18 +132,18 @@ export class Schedule {
|
|
|
127
132
|
date.setHours(0, 0, 0, 0);
|
|
128
133
|
lessons.push(...this.forDate(date, opts));
|
|
129
134
|
}
|
|
130
|
-
return lessons;
|
|
135
|
+
return lessons.sort(sortLessons);
|
|
131
136
|
}
|
|
132
137
|
today(opts) {
|
|
133
|
-
return this.forDate(new Date(), opts);
|
|
138
|
+
return this.forDate(new Date(), opts).sort(sortLessons);
|
|
134
139
|
}
|
|
135
140
|
tomorrow(opts) {
|
|
136
141
|
const date = new Date();
|
|
137
142
|
date.setDate(date.getDate() + 1);
|
|
138
|
-
return this.forDate(date, opts);
|
|
143
|
+
return this.forDate(date, opts).sort(sortLessons);
|
|
139
144
|
}
|
|
140
145
|
thisWeek(opts) {
|
|
141
|
-
return this.forWeek(undefined, opts);
|
|
146
|
+
return this.forWeek(undefined, opts).sort(sortLessons);
|
|
142
147
|
}
|
|
143
148
|
currentLesson(opts) {
|
|
144
149
|
const now = new Date();
|
package/dist/tt/utils.d.ts
CHANGED
|
@@ -5,6 +5,7 @@ export declare function getCurrentPeriod(opts?: {
|
|
|
5
5
|
date?: Date;
|
|
6
6
|
}): Period;
|
|
7
7
|
export declare function isSessionPeriod(period: Period): boolean;
|
|
8
|
+
export declare function sortLessons(a: Lesson, b: Lesson): number;
|
|
8
9
|
export declare function getWeekdayName(weekday: number): string;
|
|
9
10
|
export declare function getMonday(date: Date): Date;
|
|
10
11
|
/**
|
|
@@ -40,3 +41,18 @@ export declare function slotsToLessons(slots: FullScheduleSlot[], date: Date): L
|
|
|
40
41
|
export declare function getTimeSlots(educationType: EducationType): LessonTimeSlot[];
|
|
41
42
|
export declare function getLessonNumber(time: Time, educationType: EducationType): number;
|
|
42
43
|
export declare function getAdjacentSemester(session: Period): Period;
|
|
44
|
+
export interface Holiday {
|
|
45
|
+
/** Month number, 1–12. */
|
|
46
|
+
month: number;
|
|
47
|
+
/** Day of month. */
|
|
48
|
+
day: number;
|
|
49
|
+
/** Human-readable name. */
|
|
50
|
+
name: string;
|
|
51
|
+
}
|
|
52
|
+
/** Russian non-working public holidays (Статья 112 ТК РФ). */
|
|
53
|
+
export declare const RUSSIAN_HOLIDAYS: Holiday[];
|
|
54
|
+
/**
|
|
55
|
+
* Returns true if the given date falls on a holiday.
|
|
56
|
+
* Pass an empty array to disable holiday checking.
|
|
57
|
+
*/
|
|
58
|
+
export declare function isHoliday(date: Date, holidays?: Holiday[]): boolean;
|
package/dist/tt/utils.js
CHANGED
|
@@ -17,6 +17,9 @@ export function getCurrentPeriod(opts) {
|
|
|
17
17
|
export function isSessionPeriod(period) {
|
|
18
18
|
return period === 2 /* Period.WinterSession */ || period === 4 /* Period.SummerSession */;
|
|
19
19
|
}
|
|
20
|
+
export function sortLessons(a, b) {
|
|
21
|
+
return a.start.date.getTime() - b.start.date.getTime();
|
|
22
|
+
}
|
|
20
23
|
const WEEKDAY_NAMES = [
|
|
21
24
|
"Воскресенье",
|
|
22
25
|
"Понедельник",
|
|
@@ -143,23 +146,83 @@ export function slotsToLessons(slots, date) {
|
|
|
143
146
|
}
|
|
144
147
|
// --- Lesson time slots ---
|
|
145
148
|
const VO_TIME_SLOTS = [
|
|
146
|
-
{
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
{
|
|
152
|
-
|
|
153
|
-
|
|
149
|
+
{
|
|
150
|
+
number: 1,
|
|
151
|
+
start: { hours: 8, minutes: 20 },
|
|
152
|
+
end: { hours: 9, minutes: 40 },
|
|
153
|
+
},
|
|
154
|
+
{
|
|
155
|
+
number: 2,
|
|
156
|
+
start: { hours: 9, minutes: 50 },
|
|
157
|
+
end: { hours: 11, minutes: 10 },
|
|
158
|
+
},
|
|
159
|
+
{
|
|
160
|
+
number: 3,
|
|
161
|
+
start: { hours: 11, minutes: 40 },
|
|
162
|
+
end: { hours: 13, minutes: 0 },
|
|
163
|
+
},
|
|
164
|
+
{
|
|
165
|
+
number: 4,
|
|
166
|
+
start: { hours: 13, minutes: 30 },
|
|
167
|
+
end: { hours: 14, minutes: 50 },
|
|
168
|
+
},
|
|
169
|
+
{
|
|
170
|
+
number: 5,
|
|
171
|
+
start: { hours: 15, minutes: 0 },
|
|
172
|
+
end: { hours: 16, minutes: 20 },
|
|
173
|
+
},
|
|
174
|
+
{
|
|
175
|
+
number: 6,
|
|
176
|
+
start: { hours: 16, minutes: 40 },
|
|
177
|
+
end: { hours: 18, minutes: 0 },
|
|
178
|
+
},
|
|
179
|
+
{
|
|
180
|
+
number: 7,
|
|
181
|
+
start: { hours: 18, minutes: 10 },
|
|
182
|
+
end: { hours: 19, minutes: 30 },
|
|
183
|
+
},
|
|
184
|
+
{
|
|
185
|
+
number: 8,
|
|
186
|
+
start: { hours: 19, minutes: 40 },
|
|
187
|
+
end: { hours: 21, minutes: 0 },
|
|
188
|
+
},
|
|
154
189
|
];
|
|
155
190
|
const SPO_TIME_SLOTS = [
|
|
156
|
-
{
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
{
|
|
162
|
-
|
|
191
|
+
{
|
|
192
|
+
number: 1,
|
|
193
|
+
start: { hours: 8, minutes: 10 },
|
|
194
|
+
end: { hours: 9, minutes: 40 },
|
|
195
|
+
},
|
|
196
|
+
{
|
|
197
|
+
number: 2,
|
|
198
|
+
start: { hours: 9, minutes: 55 },
|
|
199
|
+
end: { hours: 11, minutes: 25 },
|
|
200
|
+
},
|
|
201
|
+
{
|
|
202
|
+
number: 3,
|
|
203
|
+
start: { hours: 11, minutes: 55 },
|
|
204
|
+
end: { hours: 13, minutes: 25 },
|
|
205
|
+
},
|
|
206
|
+
{
|
|
207
|
+
number: 4,
|
|
208
|
+
start: { hours: 13, minutes: 40 },
|
|
209
|
+
end: { hours: 15, minutes: 10 },
|
|
210
|
+
},
|
|
211
|
+
{
|
|
212
|
+
number: 5,
|
|
213
|
+
start: { hours: 15, minutes: 25 },
|
|
214
|
+
end: { hours: 16, minutes: 55 },
|
|
215
|
+
},
|
|
216
|
+
{
|
|
217
|
+
number: 6,
|
|
218
|
+
start: { hours: 17, minutes: 10 },
|
|
219
|
+
end: { hours: 18, minutes: 40 },
|
|
220
|
+
},
|
|
221
|
+
{
|
|
222
|
+
number: 7,
|
|
223
|
+
start: { hours: 18, minutes: 55 },
|
|
224
|
+
end: { hours: 20, minutes: 25 },
|
|
225
|
+
},
|
|
163
226
|
];
|
|
164
227
|
export function getTimeSlots(educationType) {
|
|
165
228
|
return educationType === 2 /* EducationType.VocationalEducation */
|
|
@@ -188,3 +251,29 @@ export function getAdjacentSemester(session) {
|
|
|
188
251
|
? 1 /* Period.FallSemester */
|
|
189
252
|
: 3 /* Period.SpringSemester */;
|
|
190
253
|
}
|
|
254
|
+
/** Russian non-working public holidays (Статья 112 ТК РФ). */
|
|
255
|
+
export const RUSSIAN_HOLIDAYS = [
|
|
256
|
+
{ month: 1, day: 1, name: "Новый год" },
|
|
257
|
+
{ month: 1, day: 2, name: "Новогодние каникулы" },
|
|
258
|
+
{ month: 1, day: 3, name: "Новогодние каникулы" },
|
|
259
|
+
{ month: 1, day: 4, name: "Новогодние каникулы" },
|
|
260
|
+
{ month: 1, day: 5, name: "Новогодние каникулы" },
|
|
261
|
+
{ month: 1, day: 6, name: "Новогодние каникулы" },
|
|
262
|
+
{ month: 1, day: 7, name: "Рождество Христово" },
|
|
263
|
+
{ month: 1, day: 8, name: "Новогодние каникулы" },
|
|
264
|
+
{ month: 2, day: 23, name: "День защитника Отечества" },
|
|
265
|
+
{ month: 3, day: 8, name: "Международный женский день" },
|
|
266
|
+
{ month: 5, day: 1, name: "Праздник Весны и Труда" },
|
|
267
|
+
{ month: 5, day: 9, name: "День Победы" },
|
|
268
|
+
{ month: 6, day: 12, name: "День России" },
|
|
269
|
+
{ month: 11, day: 4, name: "День народного единства" },
|
|
270
|
+
];
|
|
271
|
+
/**
|
|
272
|
+
* Returns true if the given date falls on a holiday.
|
|
273
|
+
* Pass an empty array to disable holiday checking.
|
|
274
|
+
*/
|
|
275
|
+
export function isHoliday(date, holidays = RUSSIAN_HOLIDAYS) {
|
|
276
|
+
const month = date.getMonth() + 1;
|
|
277
|
+
const day = date.getDate();
|
|
278
|
+
return holidays.some((h) => h.month === month && h.day === day);
|
|
279
|
+
}
|