|
7 | 7 | import dataclasses
|
8 | 8 | import datetime
|
9 | 9 | import logging
|
10 |
| -import re |
11 | 10 | from typing import Any, Self
|
12 | 11 |
|
13 | 12 | import icalendar.cal
|
|
28 | 27 | from integreat_cms.cms.models import EventTranslation, ExternalCalendar, RecurrenceRule
|
29 | 28 | from integreat_cms.cms.utils.content_utils import clean_content
|
30 | 29 |
|
31 |
| -# Copied from https://github.com/collective/icalendar/blob/4725c1bd57ca3afe61e7d45805a2b337842fbd29/src/icalendar/prop.py#L68-L69 |
32 |
| -WEEKDAY_RULE = re.compile( |
33 |
| - r"(?P<signal>[+-]?)(?P<relative>[\d]{0,2})(?P<weekday>[\w]{2})$" |
34 |
| -) |
35 |
| - |
36 | 30 |
|
37 | 31 | @dataclasses.dataclass(frozen=True, kw_only=True)
|
38 | 32 | class ImportResult:
|
@@ -196,7 +190,6 @@ class RecurrenceRuleData:
|
196 | 190 | def from_ical_rrule(
|
197 | 191 | cls, recurrence_rule: vRecur, start: datetime.date, logger: logging.Logger
|
198 | 192 | ) -> Self:
|
199 |
| - # pylint: disable=too-many-locals |
200 | 193 | """
|
201 | 194 | Constructs this class from an ical recurrence rule.
|
202 | 195 | :return: An instance of this class
|
@@ -226,19 +219,17 @@ def pop_single_value(name: str, *, required: bool = False) -> Any:
|
226 | 219 |
|
227 | 220 | # by_set_pos can also be specified in `by_day`. We don't support multiple days with `by_set_pos` right now, though.
|
228 | 221 | if by_day and len(by_day) == 1:
|
229 |
| - set_pos, weekday = _parse_weekday(by_day[0]) |
230 |
| - if by_set_pos is not None and set_pos is not None: |
| 222 | + if by_set_pos is not None and by_day[0].relative is not None: |
231 | 223 | raise ValueError(
|
232 | 224 | f"Conflicting `BYSETPOS` and `BYDAY`: {by_set_pos} and {by_day}"
|
233 | 225 | )
|
234 |
| - by_day[0] = weekday |
235 |
| - by_set_pos = set_pos or by_set_pos |
| 226 | + by_set_pos = by_day[0].relative or by_set_pos |
| 227 | + by_day[0] = by_day[0].weekday |
236 | 228 | elif by_day:
|
237 | 229 | updated_days = []
|
238 | 230 | for day in by_day:
|
239 |
| - set_pos, weekday = _parse_weekday(day) |
240 |
| - updated_days.append(weekday) |
241 |
| - if set_pos is not None: |
| 231 | + updated_days.append(day.weekday) |
| 232 | + if day.relative is not None: |
242 | 233 | raise ValueError(
|
243 | 234 | f"Cannot support multiple days with frequency right now: {by_day}"
|
244 | 235 | )
|
@@ -338,30 +329,6 @@ def decode_by_day(self) -> list[int]:
|
338 | 329 | return weekdays
|
339 | 330 |
|
340 | 331 |
|
341 |
| -def _parse_weekday(weekdaynum: str) -> tuple[int | None, str]: |
342 |
| - """ |
343 |
| - Parses a weekday according to https://www.rfc-editor.org/rfc/rfc5545#section-3.3.10 (see `weekdaynum`) |
344 |
| - TODO: This should be handled by our icalendar package. Remove this code when a new version of icalendar is released. |
345 |
| - :param weekdaynum: The weekday + frequency number |
346 |
| - :return: A tuple of frequency and weekday, where the frequency is None if the weekdaynum only contained a weekday. |
347 |
| - """ |
348 |
| - match = WEEKDAY_RULE.match(weekdaynum) |
349 |
| - assert match is not None |
350 |
| - sign = match["signal"] |
351 |
| - ordinal_week_number = match["relative"] |
352 |
| - weekday = match["weekday"] |
353 |
| - if not ordinal_week_number: |
354 |
| - return None, weekday |
355 |
| - ordinal_week_number = int(ordinal_week_number) |
356 |
| - match sign: |
357 |
| - case "-": |
358 |
| - return -ordinal_week_number, weekday |
359 |
| - case "+" | "": |
360 |
| - return ordinal_week_number, weekday |
361 |
| - case _: |
362 |
| - return None, weekday |
363 |
| - |
364 |
| - |
365 | 332 | def import_events(calendar: ExternalCalendar, logger: logging.Logger) -> ImportResult:
|
366 | 333 | """
|
367 | 334 | Imports events from this calendar and sets or clears the errors field of the calendar
|
|
0 commit comments