Skip to content

Commit

Permalink
Merge pull request #222 from ArtrenH/main
Browse files Browse the repository at this point in the history
2023-10-15
  • Loading branch information
Belissimo-T authored Oct 15, 2023
2 parents 2c22b81 + 1dac12e commit 2505d65
Show file tree
Hide file tree
Showing 27 changed files with 1,053 additions and 499 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -166,4 +166,5 @@ backend/schools/private_data
creds.json
proxies.json

/test_scripts
/test_scripts
/downloaded_files
18 changes: 0 additions & 18 deletions backend/cache.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,24 +34,6 @@ def remove_plan_file(self, day: datetime.date, timestamp: datetime.datetime | st
path = self.get_plan_path(day, timestamp) / filename
path.unlink(missing_ok=True)

def store_plan_file_link(
self,
day: datetime.date,
timestamp: datetime.datetime | str,
filename: str,
to_timestamp: datetime.datetime | str,
to_filename: str
):
"""Create a symlink to a plan file in the cache."""

path = self.get_plan_path(day, timestamp) / filename
to_path = self.get_plan_path(day, to_timestamp) / to_filename

path.parent.mkdir(parents=True, exist_ok=True)

path.unlink(missing_ok=True)
path.symlink_to(to_path)

def get_plan_file(self,
day: datetime.date,
timestamp: datetime.datetime | str,
Expand Down
53 changes: 53 additions & 0 deletions backend/default_plan.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
from __future__ import annotations

import copy
import dataclasses
import typing

from . import models


@dataclasses.dataclass
class DefaultPlanInfo:
unchanged_lessons: list[models.Lesson] = dataclasses.field(default_factory=list)
week: int | None = None

@classmethod
def from_lessons(cls, lessons: typing.Iterable[models.Lesson]) -> DefaultPlanInfo:
out = cls()

for lesson in lessons:
if len(lesson.parsed_info.paragraphs) != 0:
continue

if not lesson._is_scheduled or lesson.is_internal or lesson.subject_changed:
continue

lesson = copy.deepcopy(lesson)

if lesson.teacher_changed:
lesson.teachers = None

if lesson.room_changed:
lesson.rooms = None

if lesson.forms_changed:
lesson.forms = None
assert False, f"{cls.__name__}.from_lessons() only supports lessons from form plans."

out.unchanged_lessons.append(lesson)

return out

def serialize(self):
return {
"unchanged_lessons": [lesson.serialize() for lesson in self.unchanged_lessons],
"week": self.week
}

@classmethod
def deserialize(cls, data):
return cls(
unchanged_lessons=[models.Lesson.deserialize(lesson) for lesson in data["unchanged_lessons"]],
week=data["week"]
)
23 changes: 16 additions & 7 deletions backend/lesson_info.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,16 @@


class _InfoParsers:
_teacher_name = (r"[A-ZÄÖÜ][a-zäöüß]+(?: [A-ZÄÖÜ][a-zäöüß]+(?:-[A-ZÄÖÜ][a-zäöüß]+)?\.?)*"
r"(?: [A-ZÄÖÜ][a-zäöüß]+(?:-[A-ZÄÖÜ][a-zäöüß]+)?)")
_teacher_name = (r"[A-ZÄÖÜ][a-zäöüß]+"
r"(?: (?:[A-ZÄÖÜ]')?[A-ZÄÖÜ][a-zäöüß]+(?:-[A-ZÄÖÜ][a-zäöüß]+)*\.?)*"
r"(?: van)?"
r"(?: (?:[A-ZÄÖÜ]')?[A-ZÄÖÜ][a-zäöüß]+(?:-[A-ZÄÖÜ][a-zäöüß]+)*)")
_teacher_abbreviation = r"[A-ZÄÖÜ][A-ZÄÖÜa-zäöüß]{2,}"
_teacher = fr"(?:{_teacher_name})|(?:{_teacher_abbreviation})"

# teacher a,teacher b
_teachers = fr"{_teacher}(?:, ?{_teacher})*"
_course = r"([A-Za-z0-9ÄÖÜäöüß\/-]{2,8})" # maybe be more strict?
_course = r"([A-Za-z0-9ÄÖÜäöüß\/-_]{2,8})" # maybe be more strict?
_period = r"St\.(?P<periods>(?P<period_begin>\d{1,2})(?:-(?P<period_end>\d{1,2}))?)"
_form = _parse_form_pattern.pattern

Expand Down Expand Up @@ -71,7 +73,7 @@ class _InfoParsers:
# selbst. (v), Aufgaben stehen im LernSax, bitte zu Hause bearbeiten
# selbst. (v), Aufgaben stehen im LernSax
# selbst. (v), Aufgaben wurden erteilt, bitte zu Hause erledigen
independent = re.compile(rf'selbst\. \(.\)')
independent = re.compile(rf'selbst\.(?: \(.\))?')

tasks_in_lernsax = re.compile(rf'Aufgaben stehen im LernSax')
tasks_were_given = re.compile(rf'Aufgaben wurden erteilt')
Expand Down Expand Up @@ -507,6 +509,7 @@ def _parse_message(info: str, lesson: models.Lesson, plan_type: typing.Literal["
) -> ParsedLessonInfoMessage:
info = info.strip()
info = re.sub(r"(?<=\w)/ ", "/", info) # remove spaces after slashes like in G/ R/ W
info = re.sub(r"\b[´`]\b", "'", info)

if plan_type == "forms":
parsed_info, match = _parse_form_plan_message(info, lesson)
Expand Down Expand Up @@ -699,8 +702,8 @@ def extract_teachers(lesson: models.Lesson, classes: dict[str, models.Class], *,
surname = next(iter(message.parsed._teachers))
course = message.parsed.course

# TODO: Better discrimination criteria between teacher surname and abbreviation
if len(surname.split()) == 1:
logger.debug(f"Skipping teacher \"surname\" {surname!r}.")
continue

_class: dict[str, models.Class] = {
Expand Down Expand Up @@ -764,7 +767,8 @@ def process_additional_info_line(text: str, parsed_existing_forms: list[ParsedFo
return []
# TODO: Dates, Rooms
# remove spaces after slashes like in 5/ 3
text = re.sub(r"(?<=\w)/ {1,3}", "/", text.strip())
text = re.sub(r"\b/ {1,3}\b", "/", text.strip())
text = re.sub(r"\b {1,3}\b", " ", text.strip())

funcs = (
lambda s: add_fuzzy_teacher_links(s, teacher_abbreviation_by_surname, date),
Expand Down Expand Up @@ -829,7 +833,12 @@ def validator(match: re.Match) -> list[LessonInfoTextSegment] | None:
form_match = existing_form
break
elif MajorMinorParsedForm == type(parsed_form) == type(existing_form):
if existing_form[0].lower() == parsed_form[0].lower() and existing_form[2] == parsed_form[2]:
try:
is_match = int(existing_form[0]) == int(parsed_form[0].lower())
except ValueError:
is_match = existing_form[0].lower() == parsed_form[0].lower()

if is_match and existing_form[2] == parsed_form[2]:
form_match = existing_form
break

Expand Down
2 changes: 1 addition & 1 deletion backend/load_plans.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ async def get_clients(session: aiohttp.ClientSession | None = None,
# create crawler
p = PlanCrawler(plan_downloader, plan_processor)

clients |= {school_name: p}
clients[school_name] = p

return clients

Expand Down
Loading

0 comments on commit 2505d65

Please sign in to comment.