from dateutil.relativedelta import relativedelta from django.conf import settings from django.contrib import messages from django.core.paginator import Paginator from django.db import models from django.forms.models import model_to_dict from django.http import HttpResponseRedirect, JsonResponse from django.shortcuts import render from django.utils import timezone from modelcluster.contrib.taggit import ClusterTaggableManager from modelcluster.fields import ParentalKey from taggit.models import Tag, TaggedItemBase from wagtail.admin.panels import ( FieldPanel, HelpPanel, MultiFieldPanel, ObjectList, PageChooserPanel, TabbedInterface, ) from wagtail.blocks import PageChooserBlock, RichTextBlock from wagtail.contrib.routable_page.models import RoutablePageMixin, route from wagtail.fields import RichTextField, StreamField from wagtail.models import Page from wagtail.search import index from wagtailmetadata.models import MetadataPageMixin from calendar_utils.models import CalendarMixin from shared import blocks as shared_blocks from shared.forms import SubscribeForm from shared.models import ( # MenuMixin, ArticleMixin, ArticlesMixin, ArticlesPageMixin, ExtendedMetadataHomePageMixin, ExtendedMetadataPageMixin, MainArticlePageMixin, MainArticlesPageMixin, MainContactPageMixin, MainHomePageMixin, MainSearchPageMixin, MainSimplePageMixin, PageInMenuMixin, SharedTaggedMainArticle, SubpageMixin, ) from shared.utils import make_promote_panels, subscribe_to_newsletter from tuning import admin_help from . import blocks from .forms import JekyllImportForm class MainHomePage(MainHomePageMixin): # content content = StreamField( [ ("carousel", blocks.HomePageCarouseSlideBlock()), ( "news", shared_blocks.NewsBlock( template="styleguide2/includes/organisms/articles/articles_section.html" ), ), ("europarl_news", blocks.EuroparlNewsBlock()), ("people", blocks.PeopleOverviewBlock()), ("regions", blocks.RegionsBlock()), ("boxes", blocks.BoxesBlock()), ], verbose_name="Hlavní obsah", blank=True, use_json_field=True, ) # settings gdpr_and_cookies_page = models.ForeignKey( "main.MainSimplePage", verbose_name="Stránka pro GDPR", on_delete=models.PROTECT, blank=True, null=True, ) subpage_types = [ "main.MainArticlesPage", "main.MainProgramPage", "main.MainPeoplePage", "main.MainPersonPage", "main.MainSimplePage", "main.MainContactPage", "main.MainCrossroadPage", "main.MainHoaxPage", "main.MainSearchPage", ] ### OTHERS class Meta: verbose_name = "HomePage pirati.cz" @property def article_page_model(self): return MainArticlePage @property def articles_page_model(self): return MainArticlesPage @property def contact_page_model(self): return MainContactPage @property def search_page_model(self): return MainSearchPage @property def people_page(self): return self._first_subpage_of_type(MainPeoplePage) @property def root_page(self): return self def _first_subpage_of_type(self, page_type) -> Page or None: try: return self.get_descendants().type(page_type).live().specific()[0] except IndexError: return None @route(r"^sdilene/$", name="shared") def shared(self, request): return self.setup_article_page_context(request) class MainArticlesPage(MainArticlesPageMixin): base_form_class = JekyllImportForm parent_page_types = ["main.MainHomePage"] subpage_types = ["main.MainArticlePage"] class MainArticleTag(TaggedItemBase): content_object = ParentalKey( "main.MainArticlePage", on_delete=models.CASCADE, related_name="main_tagged_items", ) class MainArticlePage(MainArticlePageMixin): author_page = models.ForeignKey( "main.MainPersonPage", on_delete=models.SET_NULL, null=True, blank=True, verbose_name="Stránka autora (osoby)", ) tags = ClusterTaggableManager( through=MainArticleTag, related_name="main_tagged_articles", blank=True ) shared_tags = ClusterTaggableManager( verbose_name="Tagy pro sdílení mezi weby", through=SharedTaggedMainArticle, blank=True, ) parent_page_types = ["main.MainArticlesPage"] subpage_types = [] class MainProgramPage( ExtendedMetadataPageMixin, SubpageMixin, MetadataPageMixin, PageInMenuMixin, Page ): ### FIELDS program = StreamField( [ ("program_group", blocks.ProgramGroupBlock()), ("program_group_crossroad", blocks.ProgramGroupBlockCrossroad()), ("program_group_popout", blocks.ProgramGroupBlockPopout()), ], verbose_name="Program", blank=True, use_json_field=True, ) ### PANELS content_panels = Page.content_panels + [FieldPanel("program")] promote_panels = make_promote_panels() settings_panels = [] ### RELATIONS parent_page_types = ["main.MainHomePage"] subpage_types = [] ### OTHERS class Meta: verbose_name = "Program" class MainPeoplePage( ExtendedMetadataPageMixin, SubpageMixin, MetadataPageMixin, PageInMenuMixin, Page ): ### FIELDS perex_col_1 = models.TextField( verbose_name="Perex - první sloupec", ) perex_col_2 = models.TextField( verbose_name="Perex - druhý sloupec", ) people = StreamField( [ ("people_group", blocks.PeopleGroupBlock(label="Seznam osob")), ("team_group", blocks.TeamBlock()), ], verbose_name="Lidé a týmy", blank=True, use_json_field=True, ) ### PANELS content_panels = Page.content_panels + [ FieldPanel("perex_col_1"), FieldPanel("perex_col_2"), FieldPanel("people"), ] promote_panels = make_promote_panels() settings_panels = [] ### RELATIONS parent_page_types = ["main.MainHomePage"] subpage_types = [ "main.MainPersonPage", "main.MainSimplePage", ] ### OTHERS @property def perex(self) -> str: return self.perex_col_1 + " \n" + self.perex_col_2 class Meta: verbose_name = "Lidé a týmy" class MainPersonPage( ExtendedMetadataPageMixin, SubpageMixin, MetadataPageMixin, CalendarMixin, PageInMenuMixin, Page, ): ### FIELDS main_image = models.ForeignKey( "wagtailimages.Image", on_delete=models.PROTECT, blank=True, null=True, verbose_name="Hlavní obrázek", related_name="+", ) profile_image = models.ForeignKey( "wagtailimages.Image", on_delete=models.PROTECT, blank=True, null=True, verbose_name="Profilový obrázek", related_name="+", ) before_name = models.CharField( "Tituly před jménem", max_length=32, blank=True, null=True ) after_name = models.CharField( "Tituly za jménem", max_length=16, blank=True, null=True ) position = models.CharField( "Pozice/povolání", max_length=200, blank=True, null=True ) primary_group = models.CharField( "Kategorie", help_text="např. 'Europarlament' nebo 'Sněmovna'", max_length=32, blank=True, null=True, ) perex = models.TextField() text = RichTextField() social_links = StreamField( [ ("social_links", shared_blocks.SocialLinkBlock()), ], verbose_name="Odkazy na sociální sítě", blank=True, use_json_field=True, ) related_people = StreamField( [ ( "person", PageChooserBlock(page_type="main.MainPersonPage", label="Detail osoby"), ) ], verbose_name="Další lidé", blank=True, use_json_field=True, ) email = models.CharField("E-mail", max_length=128, blank=True, null=True) phone = models.CharField("Telefonní kontakt", max_length=16, blank=True, null=True) settings_panels = [] ### RELATIONS parent_page_types = ["main.MainPeoplePage"] subpage_types = [] ### PANELS content_panels = Page.content_panels + [ FieldPanel("main_image"), FieldPanel("profile_image"), FieldPanel("before_name"), FieldPanel("after_name"), FieldPanel("position"), FieldPanel("perex"), FieldPanel("text"), FieldPanel("email"), FieldPanel("phone"), FieldPanel("calendar_url"), FieldPanel("social_links"), FieldPanel("related_people"), ] def get_context(self, request) -> dict: context = super().get_context(request) context["article_page_list"] = ( MainArticlePage.objects.filter(author_page=self.id) .order_by("-timestamp") .live()[:3] ) return context ### OTHERS class Meta: verbose_name = "Detail osoby" # ordering = ("title",) def get_background_photo(self): """ Vrací background_photo pro pozadí na stránce, pokud není nastaveno, vezme falbback z homepage """ return ( self.background_photo if self.background_photo else self.root_page.fallback_image ) class MainSimplePage(MainSimplePageMixin): parent_page_types = [ "main.MainHomePage", "main.MainSimplePage", "main.MainCrossroadPage", "main.MainPeoplePage", ] subpage_types = ["main.MainSimplePage"] class MainContactPage(MainContactPageMixin): ### RELATIONS parent_page_types = ["main.MainHomePage"] subpage_types = [] class MainCrossroadPage( ExtendedMetadataPageMixin, SubpageMixin, MetadataPageMixin, PageInMenuMixin, Page ): ### FIELDS headlined_cards_content = StreamField( [(("headlined_cards"), blocks.CardLinkWithHeadlineBlock())], verbose_name="Karty rozcestníku s nadpisem", blank=True, use_json_field=True, ) cards_content = StreamField( [("cards", blocks.CardLinkBlock())], verbose_name="Karty rozcestníku", blank=True, use_json_field=True, ) ### PANELS content_panels = Page.content_panels + [ FieldPanel("headlined_cards_content"), FieldPanel("cards_content"), ] promote_panels = make_promote_panels() settings_panels = [] ### RELATIONS parent_page_types = [ "main.MainHomePage", "main.MainCrossroadPage", ] subpage_types = [ "main.MainSimplePage", "main.MainCrossroadPage", ] ### OTHERS class Meta: verbose_name = "Rozcestník s kartami" class MainHoaxPage( ExtendedMetadataPageMixin, SubpageMixin, MetadataPageMixin, PageInMenuMixin, Page ): ### FIELDS description = RichTextField( "Popis", blank=True, null=True, ) content = StreamField( [(("hoax"), blocks.HoaxBlock())], verbose_name="Hoaxy a jejich vysvětlení", blank=True, use_json_field=True, ) ### PANELS content_panels = Page.content_panels + [ FieldPanel("description"), FieldPanel("content"), ] promote_panels = make_promote_panels() settings_panels = [] ### RELATIONS parent_page_types = ["main.MainHomePage"] subpage_types = [] ### OTHERS class Meta: verbose_name = "Hoaxy" class MainSearchPage(MainSearchPageMixin): parent_page_types = ["main.MainHomePage"] subpage_types = [] @property def searchable_models(self) -> list: return [ MainArticlePage, MainPersonPage, MainSimplePage, ]