mirror of
https://github.com/n08i40k/schedule-parser-next.git
synced 2025-12-06 09:47:46 +03:00
Фикс парсинга подгруппы и добавление парсинга пары типа "экзамен".
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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, // Экзамен
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
// });
|
||||
});
|
||||
});
|
||||
|
||||
@@ -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("ЗАЧЕТ")) {
|
||||
|
||||
@@ -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],
|
||||
|
||||
@@ -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<ScheduleDto> {
|
||||
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<GroupScheduleDto> {
|
||||
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<TeacherScheduleDto> {
|
||||
return await this.scheduleService.getTeacher(name);
|
||||
return await this.scheduleService.getTeacher(name).then((result) =>
|
||||
instanceToInstance2(TeacherScheduleDto, result, {
|
||||
groups: ["v2"],
|
||||
}),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
105
src/schedule/v4-schedule.controller.ts
Normal file
105
src/schedule/v4-schedule.controller.ts
Normal file
@@ -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<ScheduleDto> {
|
||||
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<GroupScheduleDto> {
|
||||
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<TeacherScheduleDto> {
|
||||
return await this.scheduleService.getTeacher(name).then((result) =>
|
||||
instanceToInstance2(TeacherScheduleDto, result, {
|
||||
groups: ["v3"],
|
||||
}),
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user