From 38badf3c2fa0758d70a6c209539e3c27669bc8f7 Mon Sep 17 00:00:00 2001 From: N08I40K Date: Mon, 2 Dec 2024 11:31:16 +0400 Subject: [PATCH] =?UTF-8?q?=D0=A4=D0=B8=D0=BA=D1=81=20=D0=BF=D0=B0=D1=80?= =?UTF-8?q?=D1=81=D0=B8=D0=BD=D0=B3=D0=B0=20=D0=BF=D0=BE=D0=B4=D0=B3=D1=80?= =?UTF-8?q?=D1=83=D0=BF=D0=BF=D1=8B=20=D0=B8=20=D0=B4=D0=BE=D0=B1=D0=B0?= =?UTF-8?q?=D0=B2=D0=BB=D0=B5=D0=BD=D0=B8=D0=B5=20=D0=BF=D0=B0=D1=80=D1=81?= =?UTF-8?q?=D0=B8=D0=BD=D0=B3=D0=B0=20=D0=BF=D0=B0=D1=80=D1=8B=20=D1=82?= =?UTF-8?q?=D0=B8=D0=BF=D0=B0=20"=D1=8D=D0=BA=D0=B7=D0=B0=D0=BC=D0=B5?= =?UTF-8?q?=D0=BD".?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/schedule/dto/lesson.dto.ts | 10 ++ src/schedule/enum/v2-lesson-type.enum.ts | 15 +-- .../v2-schedule-parser.spec.ts | 45 +------- .../schedule-parser/v2-schedule-parser.ts | 16 ++- src/schedule/schedule.module.ts | 2 + src/schedule/v3-schedule.controller.ts | 19 +++- src/schedule/v4-schedule.controller.ts | 105 ++++++++++++++++++ 7 files changed, 159 insertions(+), 53 deletions(-) create mode 100644 src/schedule/v4-schedule.controller.ts diff --git a/src/schedule/dto/lesson.dto.ts b/src/schedule/dto/lesson.dto.ts index b3291fb..450a89a 100644 --- a/src/schedule/dto/lesson.dto.ts +++ b/src/schedule/dto/lesson.dto.ts @@ -26,10 +26,18 @@ export class LessonDto { case V2LessonType.INDEPENDENT_WORK: case V2LessonType.EXAM: case V2LessonType.EXAM_WITH_GRADE: + case V2LessonType.EXAM_DEFAULT: return V2LessonType.DEFAULT; default: return value; } + } else if (options?.groups?.includes("v2")) { + switch (value as V2LessonType) { + case V2LessonType.EXAM_DEFAULT: + return V2LessonType.EXAM; + default: + return value; + } } return value; @@ -73,6 +81,8 @@ export class LessonDto { return `ЗАЧЕТ | ${value}`; case V2LessonType.EXAM_WITH_GRADE: return `ЗАЧЕТ С ОЦЕНКОЙ | ${value}`; + case V2LessonType.EXAM_DEFAULT: + return `ЗАЧЕТ С ОЦЕНКОЙ | ${value}`; default: return value; } diff --git a/src/schedule/enum/v2-lesson-type.enum.ts b/src/schedule/enum/v2-lesson-type.enum.ts index 744fb33..9e72291 100644 --- a/src/schedule/enum/v2-lesson-type.enum.ts +++ b/src/schedule/enum/v2-lesson-type.enum.ts @@ -1,9 +1,10 @@ export enum V2LessonType { - DEFAULT = 0, - ADDITIONAL, - BREAK, - CONSULTATION, - INDEPENDENT_WORK, - EXAM, - EXAM_WITH_GRADE, + DEFAULT = 0, // Обычная + ADDITIONAL, // Допы + BREAK, // Перемена + CONSULTATION, // Консультация + INDEPENDENT_WORK, // Самостоятельная работа + EXAM, // Зачёт + EXAM_WITH_GRADE, // Зачет с оценкой + EXAM_DEFAULT, // Экзамен } diff --git a/src/schedule/internal/schedule-parser/v2-schedule-parser.spec.ts b/src/schedule/internal/schedule-parser/v2-schedule-parser.spec.ts index 994b00f..9f73986 100644 --- a/src/schedule/internal/schedule-parser/v2-schedule-parser.spec.ts +++ b/src/schedule/internal/schedule-parser/v2-schedule-parser.spec.ts @@ -55,35 +55,13 @@ describe("V2ScheduleParser", () => { describe("Расписание", () => { beforeEach(async () => { await setLink( - "https://politehnikum-eng.ru/2024/poltavskaja_12_s_18_po_24_11.xls", + "https://politehnikum-eng.ru/2024/poltavskaja_14_s_2_po_8_12.xls", ); }); it("Должен вернуть расписание", defaultTest); it("Название дня не должно быть пустым или null", nameTest); - it("Зачёт с оценкой v1", async () => { - const schedule = await parser.getSchedule().then((v) => - instanceToInstance2(V2ScheduleParseResult, v, { - groups: ["v1"], - }), - ); - expect(schedule).toBeDefined(); - - const group: GroupDto | undefined = - schedule.groups.get("ИС-214/23"); - expect(group).toBeDefined(); - - const tuesday = group.days[1]; - expect(tuesday).toBeDefined(); - - const oseLesson = tuesday.lessons[6]; - expect(oseLesson).toBeDefined(); - - expect(oseLesson.name.startsWith("ЗАЧЕТ С ОЦЕНКОЙ | ")).toBe(true); - expect(oseLesson.type).toBe(V2LessonType.DEFAULT); - }); - it("Зачёт с оценкой v2", async () => { const schedule = await parser.getSchedule().then((v) => instanceToInstance2(V2ScheduleParseResult, v, { @@ -96,24 +74,13 @@ describe("V2ScheduleParser", () => { schedule.groups.get("ИС-214/23"); expect(group).toBeDefined(); - const tuesday = group.days[1]; - expect(tuesday).toBeDefined(); + const day = group.days[5]; + expect(day).toBeDefined(); - const oseLesson = tuesday.lessons[6]; - expect(oseLesson).toBeDefined(); + const lesson = day.lessons[0]; + expect(lesson).toBeDefined(); - expect(oseLesson.name.startsWith("Операционные")).toBe(true); - expect(oseLesson.type).toBe(V2LessonType.EXAM_WITH_GRADE); + expect(lesson.type).toBe(V2LessonType.EXAM); }); - - // it("Суббота не должна отсутствовать", async () => { - // const schedule = await parser.getSchedule(); - // expect(schedule).toBeDefined(); - // - // const group: V2GroupDto | undefined = schedule.groups["ИС-214/23"]; - // expect(group).toBeDefined(); - // - // expect(group.days.length).toBe(6); - // }); }); }); diff --git a/src/schedule/internal/schedule-parser/v2-schedule-parser.ts b/src/schedule/internal/schedule-parser/v2-schedule-parser.ts index d3bb62c..0682207 100644 --- a/src/schedule/internal/schedule-parser/v2-schedule-parser.ts +++ b/src/schedule/internal/schedule-parser/v2-schedule-parser.ts @@ -229,7 +229,7 @@ export class V2ScheduleParser { for (const teacherAndSubGroup of all) { const teacherRegex = /[А-ЯЁ][а-яё]+\s[А-ЯЁ]\.\s?[А-ЯЁ]\./g; - const subGroupRegex = /\([0-9]\s?подгруппа\)/g; + const subGroupRegex = /\([0-9]подгруппа\)/g; const teacherMatch = teacherRegex.exec(teacherAndSubGroup); if (teacherMatch === null) throw new Error("Парадокс"); @@ -242,7 +242,9 @@ export class V2ScheduleParser { teacherFIO = `${teacherFIO.substring(0, teacherSpaceIndex)}${teacherIO}`; - const subGroupMatch = subGroupRegex.exec(teacherAndSubGroup); + const subGroupMatch = subGroupRegex.exec( + teacherAndSubGroup.replaceAll(" ", ""), + ); const subGroup = subGroupMatch ? Number.parseInt(subGroupMatch[0][1]) : 1; @@ -277,7 +279,10 @@ export class V2ScheduleParser { } return { - name: lessonName.substring(0, allMatch.index).trim(), + name: lessonName + .substring(0, allMatch.index) + .replaceAll(".", "") + .trim(), subGroups: subGroups, }; } @@ -645,7 +650,10 @@ export class V2ScheduleParser { const lesson = new LessonDto(); if (this.otherStreetRegExp.test(rawName)) return rawName; - else if (rawName.includes("ЗАЧЕТ С ОЦЕНКОЙ")) { + else if (rawName.includes("ЭКЗАМЕН")) { + lesson.type = V2LessonType.EXAM_DEFAULT; + rawName = trimAll(rawName.replace("ЭКЗАМЕН", "")); + } else if (rawName.includes("ЗАЧЕТ С ОЦЕНКОЙ")) { lesson.type = V2LessonType.EXAM_WITH_GRADE; rawName = trimAll(rawName.replace("ЗАЧЕТ С ОЦЕНКОЙ", "")); } else if (rawName.includes("ЗАЧЕТ")) { diff --git a/src/schedule/schedule.module.ts b/src/schedule/schedule.module.ts index 7241634..793924a 100644 --- a/src/schedule/schedule.module.ts +++ b/src/schedule/schedule.module.ts @@ -7,6 +7,7 @@ import { ScheduleReplacerController } from "./schedule-replacer.controller"; import { ScheduleService } from "./schedule.service"; import { V2ScheduleController } from "./v2-schedule.controller"; import { V3ScheduleController } from "./v3-schedule.controller"; +import { V4ScheduleController } from "./v4-schedule.controller"; @Module({ imports: [forwardRef(() => UsersModule), FirebaseAdminModule], @@ -14,6 +15,7 @@ import { V3ScheduleController } from "./v3-schedule.controller"; controllers: [ V2ScheduleController, V3ScheduleController, + V4ScheduleController, ScheduleReplacerController, ], exports: [ScheduleService], diff --git a/src/schedule/v3-schedule.controller.ts b/src/schedule/v3-schedule.controller.ts index 67ef159..d0979d3 100644 --- a/src/schedule/v3-schedule.controller.ts +++ b/src/schedule/v3-schedule.controller.ts @@ -25,6 +25,7 @@ import { UserRole } from "../users/user-role.enum"; import { User } from "../users/entity/user.entity"; import { GroupScheduleDto } from "./dto/group-schedule.dto"; import { TeacherScheduleDto } from "./dto/teacher-schedule.dto"; +import instanceToInstance2 from "../utility/class-trasformer/instance-to-instance-2"; @ApiTags("v3/schedule") @ApiBearerAuth() @@ -49,7 +50,11 @@ export class V3ScheduleController { @HttpCode(HttpStatus.OK) @Get() async getSchedule(): Promise { - return await this.scheduleService.getSchedule(); + return await this.scheduleService.getSchedule().then((result) => + instanceToInstance2(ScheduleDto, result, { + groups: ["v2"], + }), + ); } @ApiOperation({ summary: "Получение расписания группы" }) @@ -68,7 +73,11 @@ export class V3ScheduleController { async getGroupSchedule( @UserToken(UserPipe) user: User, ): Promise { - return await this.scheduleService.getGroup(user.group); + return await this.scheduleService.getGroup(user.group).then((result) => + instanceToInstance2(GroupScheduleDto, result, { + groups: ["v2"], + }), + ); } @ApiOperation({ summary: "Получение расписания преподавателя" }) @@ -87,6 +96,10 @@ export class V3ScheduleController { async getTeacherSchedule( @Param("name") name: string, ): Promise { - return await this.scheduleService.getTeacher(name); + return await this.scheduleService.getTeacher(name).then((result) => + instanceToInstance2(TeacherScheduleDto, result, { + groups: ["v2"], + }), + ); } } diff --git a/src/schedule/v4-schedule.controller.ts b/src/schedule/v4-schedule.controller.ts new file mode 100644 index 0000000..0ecf002 --- /dev/null +++ b/src/schedule/v4-schedule.controller.ts @@ -0,0 +1,105 @@ +import { + Controller, + Get, + HttpCode, + HttpStatus, + Param, + UseGuards, + UseInterceptors, +} from "@nestjs/common"; +import { AuthGuard } from "../auth/auth.guard"; +import { ResultDto } from "../utility/validation/class-validator.interceptor"; +import { + ApiBearerAuth, + ApiOperation, + ApiResponse, + ApiTags, +} from "@nestjs/swagger"; +import { AuthRoles } from "../auth/auth-role.decorator"; +import { UserToken } from "../auth/auth.decorator"; +import { UserPipe } from "../auth/auth.pipe"; +import { ScheduleService } from "./schedule.service"; +import { ScheduleDto } from "./dto/schedule.dto"; +import { CacheInterceptor, CacheKey } from "@nestjs/cache-manager"; +import { UserRole } from "../users/user-role.enum"; +import { User } from "../users/entity/user.entity"; +import { GroupScheduleDto } from "./dto/group-schedule.dto"; +import { TeacherScheduleDto } from "./dto/teacher-schedule.dto"; +import instanceToInstance2 from "../utility/class-trasformer/instance-to-instance-2"; + +@ApiTags("v4/schedule") +@ApiBearerAuth() +@Controller({ path: "schedule", version: "4" }) +@UseGuards(AuthGuard) +export class V4ScheduleController { + constructor(private readonly scheduleService: ScheduleService) {} + + @ApiOperation({ + summary: "Получение расписания", + tags: ["admin"], + }) + @ApiResponse({ + status: HttpStatus.OK, + description: "Расписание получено успешно", + type: ScheduleDto, + }) + @ResultDto(ScheduleDto) + @AuthRoles([UserRole.ADMIN]) + @CacheKey("v4-schedule") + @UseInterceptors(CacheInterceptor) + @HttpCode(HttpStatus.OK) + @Get() + async getSchedule(): Promise { + return await this.scheduleService.getSchedule().then((result) => + instanceToInstance2(ScheduleDto, result, { + groups: ["v3"], + }), + ); + } + + @ApiOperation({ summary: "Получение расписания группы" }) + @ApiResponse({ + status: HttpStatus.OK, + description: "Расписание получено успешно", + type: GroupScheduleDto, + }) + @ApiResponse({ + status: HttpStatus.NOT_FOUND, + description: "Требуемая группа не найдена", + }) + @ResultDto(GroupScheduleDto) + @HttpCode(HttpStatus.OK) + @Get("group") + async getGroupSchedule( + @UserToken(UserPipe) user: User, + ): Promise { + return await this.scheduleService.getGroup(user.group).then((result) => + instanceToInstance2(GroupScheduleDto, result, { + groups: ["v3"], + }), + ); + } + + @ApiOperation({ summary: "Получение расписания преподавателя" }) + @ApiResponse({ + status: HttpStatus.OK, + description: "Расписание получено успешно", + type: TeacherScheduleDto, + }) + @ApiResponse({ + status: HttpStatus.NOT_FOUND, + description: "Требуемый преподаватель не найден", + }) + @ResultDto(TeacherScheduleDto) + @HttpCode(HttpStatus.OK) + @Get("teacher/:name") + async getTeacherSchedule( + @Param("name") name: string, + ): Promise { + return await this.scheduleService.getTeacher(name).then((result) => + instanceToInstance2(TeacherScheduleDto, result, { + groups: ["v3"], + }), + ); + } +}