diff --git a/calendar_utils/models.py b/calendar_utils/models.py index 939e7c02d2a9c7ea24019a8ca838b71588e60946..2f11fa7439611706197d4ac24615b8e3f0ad44fd 100644 --- a/calendar_utils/models.py +++ b/calendar_utils/models.py @@ -1,3 +1,4 @@ +import json import logging from datetime import date, timedelta @@ -102,3 +103,39 @@ class CalendarMixin(models.Model): self.calendar = None super().save(*args, **kwargs) + + +class PersonCalendarMixin(CalendarMixin): + def get_parsed_calendar_data(self) -> list: + calendar_format_events = [] + + for event in ( + self.calendar.past_events + + self.calendar.future_events + ): + parsed_event = { + "allDay": event["all_day"], + "start": event["start"].isoformat(), + "end": event["end"].isoformat(), + } + + if event["summary"] is not None: + parsed_event["title"] = event["summary"] + + if event["url"] is not None: + parsed_event["url"] = event["url"] + + calendar_format_events.append(parsed_event) + + return calendar_format_events + + def get_context(self, request) -> dict: + context = super().get_context(request) + + if self.calendar: + context["calendar_data"] = json.dumps(self.get_parsed_calendar_data()) + + return context + + class Meta: + abstract = True diff --git a/calendar_utils/parser.py b/calendar_utils/parser.py index 1cefdbd6318438a4a03df51cc6004f3ef9e80f7c..d5795aa0908a81d4f39ac78e7ceaf2109c2e043b 100644 --- a/calendar_utils/parser.py +++ b/calendar_utils/parser.py @@ -9,7 +9,7 @@ from django.conf import settings if TYPE_CHECKING: from icalevents.icalparser import Event -EVENT_KEYS = ("start", "end", "all_day", "summary", "description", "location") +EVENT_KEYS = ("start", "end", "all_day", "summary", "description", "location", "url") def split_event_dict_list(event_list: "list[dict]") -> tuple[list[dict], list[dict]]: diff --git a/district/migrations/0110_remove_districtpersonpage_ical_calendar_url_and_more.py b/district/migrations/0110_remove_districtpersonpage_ical_calendar_url_and_more.py new file mode 100644 index 0000000000000000000000000000000000000000..aaba09b6dde33a50c5a8235ece2f89bb45e4f949 --- /dev/null +++ b/district/migrations/0110_remove_districtpersonpage_ical_calendar_url_and_more.py @@ -0,0 +1,29 @@ +# Generated by Django 4.1.8 on 2023-04-16 12:45 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('calendar_utils', '0004_auto_20220505_1228'), + ('district', '0109_districtpersonpage_ical_calendar_url'), + ] + + operations = [ + migrations.RemoveField( + model_name='districtpersonpage', + name='ical_calendar_url', + ), + migrations.AddField( + model_name='districtpersonpage', + name='calendar', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, to='calendar_utils.calendar'), + ), + migrations.AddField( + model_name='districtpersonpage', + name='calendar_url', + field=models.URLField(blank=True, null=True, verbose_name='URL kalendáře ve formátu iCal'), + ), + ] diff --git a/district/models.py b/district/models.py index 9f99aee7eed335c7fc8e0fce67d7671380889fad..16e9c001837465d04977833a2be3b3f1afb39c1d 100644 --- a/district/models.py +++ b/district/models.py @@ -26,7 +26,7 @@ from wagtail.fields import RichTextField, StreamField from wagtail.models import Orderable, Page from wagtailmetadata.models import MetadataPageMixin -from calendar_utils.models import CalendarMixin +from calendar_utils.models import CalendarMixin, PersonCalendarMixin from maps_utils.blocks import MapPointBlock from maps_utils.const import ( DEFAULT_MAP_STYLE, @@ -50,7 +50,6 @@ from shared.models import ( ExtendedMetadataHomePageMixin, ExtendedMetadataPageMixin, MenuMixin, - PersonCalendarMixin, SubpageMixin, ) from shared.utils import make_promote_panels, strip_all_html_tags, trim_to_length @@ -694,7 +693,7 @@ class DistrictPersonPage( ], "Kontaktní informace", ), - FieldPanel("ical_calendar_url"), + FieldPanel("calendar_url"), MultiFieldPanel( [ FieldPanel("facebook_url"), diff --git a/district/templates/district/district_person_page.html b/district/templates/district/district_person_page.html index 45097a431c43259987fcd5d40efb21534ca58700..a21b9f4bf4c2c5458f4ec7e1a4f9745822db25f8 100644 --- a/district/templates/district/district_person_page.html +++ b/district/templates/district/district_person_page.html @@ -24,7 +24,7 @@ <div class="content-block w-full mb-16"> {{ page.text|richtext }} </div> - {% if page.ical_calendar_url %} + {% if calendar_data %} <section> <h2 class="head-alt-md mb-3"><i class="ico--calendar mr-4"></i>Kalendář</h2> <ui-person-calendar events='{{ calendar_data|safe }}'></ui-person-calendar> diff --git a/main/migrations/0056_remove_mainpersonpage_ical_calendar_url_and_more.py b/main/migrations/0056_remove_mainpersonpage_ical_calendar_url_and_more.py new file mode 100644 index 0000000000000000000000000000000000000000..6c828cdaa95ce9859687ec1eac3ce992a175be48 --- /dev/null +++ b/main/migrations/0056_remove_mainpersonpage_ical_calendar_url_and_more.py @@ -0,0 +1,29 @@ +# Generated by Django 4.1.8 on 2023-04-16 12:45 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('calendar_utils', '0004_auto_20220505_1228'), + ('main', '0055_remove_mainpersonpage_nextcloud_calendar_url_and_more'), + ] + + operations = [ + migrations.RemoveField( + model_name='mainpersonpage', + name='ical_calendar_url', + ), + migrations.AddField( + model_name='mainpersonpage', + name='calendar', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, to='calendar_utils.calendar'), + ), + migrations.AddField( + model_name='mainpersonpage', + name='calendar_url', + field=models.URLField(blank=True, null=True, verbose_name='URL kalendáře ve formátu iCal'), + ), + ] diff --git a/main/models.py b/main/models.py index 40eb46fc5618c12ce615cf8ea96f7a4570d1a1d4..a4c0f86b4184521a416599d4ec425d0542df53f9 100644 --- a/main/models.py +++ b/main/models.py @@ -29,6 +29,7 @@ from wagtail.models import Page from wagtail.search import index from wagtailmetadata.models import MetadataPageMixin +from calendar_utils.models import PersonCalendarMixin from elections2021.constants import REGION_CHOICES # pozor, import ze sousedního modulu from instagram_utils.models import InstagramPost from shared.forms import SubscribeForm @@ -36,7 +37,6 @@ from shared.models import ( # MenuMixin, ArticleMixin, ExtendedMetadataHomePageMixin, ExtendedMetadataPageMixin, - PersonCalendarMixin, SubpageMixin, ) from shared.utils import make_promote_panels, subscribe_to_newsletter @@ -813,7 +813,7 @@ class MainPersonPage( FieldPanel("text"), FieldPanel("email"), FieldPanel("phone"), - FieldPanel("ical_calendar_url"), + FieldPanel("calendar_url"), FieldPanel("social_links"), FieldPanel("people"), ] diff --git a/main/templates/main/main_person_page.html b/main/templates/main/main_person_page.html index 4dedd0ef5e60ef8bb092468962979ff47087e3b2..5d5605757efdf68d73d281147241d26e25554f9f 100644 --- a/main/templates/main/main_person_page.html +++ b/main/templates/main/main_person_page.html @@ -109,7 +109,7 @@ </section> {% endif %} - {% if page.ical_calendar_url %} + {% if calendar_data %} <section class="grid-container no-max mr-0 mb-4 xl:mb-20"> <div class="grid-content-with-right-side"> <h2 class="head-4xl text-left"> diff --git a/shared/models.py b/shared/models.py index 0eee12b66bc5cabf255171bc1d414e61c34e0833..61789c0a9c82876174a7ba48fa5b7b5afec44541 100644 --- a/shared/models.py +++ b/shared/models.py @@ -198,66 +198,3 @@ class ExtendedMetadataPageMixin(models.Model): return super().get_meta_title() return f"{super().get_meta_title()} | {self.get_meta_title_suffix()}" - - -class PersonCalendarMixin(models.Model): - ical_calendar_url = models.URLField( - "iCal adresa kalendáře", - max_length=256, - blank=True, - null=True, - help_text=( - "Podporuje Mrak, Google Kalendář a další. Návod na synchronizaci najdeš " - "na pi2.cz/kalendare" - ), - ) - - def get_context(self, request) -> dict: - context = super().get_context(request) - - if self.ical_calendar_url: - context["calendar_data"] = self.get_ical_data() - - return context - - def get_ical_data(self) -> list: - ical_response = cache.get(f"calendar_{self.ical_calendar_url}") - - if ical_response is None: - ical_response = requests.get(self.ical_calendar_url) - ical_response.raise_for_status() - ical_response = ical_response.text - - cache.set( - f"calendar_{self.ical_calendar_url}", - ical_response, - timeout=3600, # 1 hour - ) - - parsed_events = icalevents.parse_events( - ical_response, - start=date.today() - timedelta(days=30), - end=date.today() + timedelta(days=60), - ) - - calendar_format_events = [] - - for event in parsed_events: - parsed_event = { - "allDay": event.all_day, - "start": event.start.isoformat(), - "end": event.end.isoformat(), - } - - if event.summary is not None: - parsed_event["title"] = event.summary - - if event.url is not None: - parsed_event["url"] = event.url - - calendar_format_events.append(parsed_event) - - return json.dumps(calendar_format_events) - - class Meta: - abstract = True