Source code for eucrim.core.abstracts

# SPDX-FileCopyrightText: 2024 Thomas Breitner <t.breitner@csl.mpg.de>
#
# SPDX-License-Identifier: EUPL-1.2

import pathlib
from dataclasses import dataclass
from typing import Optional

from django.db import models
from django.utils.html import strip_tags
from django.utils.text import Truncator
from django.db.models.fields.files import ImageFieldFile

from wagtail.models import Page
from wagtail.admin.panels import (
    FieldPanel,
    MultiFieldPanel,
    PageChooserPanel,
)
from wagtail.images.models import Image


# Links
[docs] class LinkFields(models.Model): link_external = models.URLField("External link", blank=True) link_page = models.ForeignKey( "wagtailcore.Page", null=True, blank=True, related_name="+", on_delete=models.SET_NULL, ) link_document = models.ForeignKey( "wagtaildocs.Document", null=True, blank=True, related_name="+", on_delete=models.SET_NULL, ) @property def link_target(self): if self.link_external.endswith("feed/"): return "feed" elif self.link_page: return "internal_link" elif self.link_document: extension = self.link_document.file_extension if extension == "pdf": return "document_pdf" elif extension.startswith("doc") or extension.startswith("dot"): return "document_word" else: return "internal_link" else: return "external_link" @property def link(self): if self.link_page: return self.link_page.url elif self.link_document: return self.link_document.url else: return self.link_external panels = [ FieldPanel("link_external"), PageChooserPanel("link_page"), FieldPanel("link_document"), ]
[docs] class Meta: abstract = True
# Related links # Carousel items
[docs] class CarouselItem(LinkFields): image = models.ForeignKey( "wagtailimages.Image", null=True, blank=True, on_delete=models.SET_NULL, related_name="+", ) embed_url = models.URLField("Embed URL", blank=True) caption = models.CharField(max_length=255, blank=True) panels = [ FieldPanel("image"), FieldPanel("embed_url"), FieldPanel("caption"), MultiFieldPanel(LinkFields.panels, "Link"), ]
[docs] class Meta: abstract = True
# Categories
[docs] class AbstractNewsCategory(models.Model): title = models.CharField( max_length=200, help_text="Short descriptive title for this category.", ) description = models.CharField( max_length=255, blank=True, help_text="Additional descriptive text", ) slug = models.SlugField( max_length=255, unique=True, help_text="Short descriptive unique name for use in urls.", ) print_order = models.PositiveSmallIntegerField( default=999, help_text="Positive integer by which the news exported for the printed issue will be ordered. Small integer means ordered first.", ) panels = [ FieldPanel("title"), FieldPanel("slug"), FieldPanel("description"), FieldPanel("print_order"), ] search_fields = Page.search_fields + [ "title__icontains", "description__icontains", "slug__icontains", ] def __str__(self): return self.title
[docs] class Meta: abstract = True ordering = ["print_order", "title"]
[docs] class BasePage(Page): @property def get_og_title(self): og_title = self.get_site().site_name if hasattr(self, "get_obj_og_title") and self.get_obj_og_title: og_title = self.get_obj_og_title elif self.seo_title: og_title = self.seo_title elif self.title: og_title = self.title return og_title @property def get_og_description(self): og_description = self.title if self.search_description: og_description = self.search_description elif hasattr(self, "get_obj_og_description") and self.get_obj_og_description: og_description = strip_tags(self.get_obj_og_description) og_description = Truncator(og_description).words(40) return og_description @property def og_image(self): og_image = { "image": None, "image_extension": None, "image_class": None, } _image = _image_extension = _image_class = None if hasattr(self, "get_obj_og_image") and self.get_obj_og_image: obj_image = self.get_obj_og_image if isinstance(obj_image, Image): _image = obj_image _image_extension = pathlib.Path(obj_image.filename).suffix[1:] _image_class = "wagtail_Image" elif isinstance(obj_image, ImageFieldFile): _image = obj_image.url _image_extension = pathlib.Path(obj_image.url).suffix[1:] _image_class = "django_ImageFieldFile" og_image = { "image": _image, "image_extension": _image_extension, "image_class": _image_class, } # print(f"{og_image=}") return og_image
[docs] class Meta: abstract = True
[docs] @dataclass(frozen=True) class PdfPageReference: """PDF page numbering text and optional anchor (PDF page number).""" text: str anchor: Optional[int] = None
[docs] class AbstractPublicationPage(BasePage): """ Base Page class. Currently used for ArticlePage and NewsPage. """ @property def get_pdf_page_reference(self) -> Optional[PdfPageReference]: """ Return a PdfPageReference with human-readable page numbering text and the corresponding anchor page in the PDF, or None if not applicable. """ if not self.issue: return None print_cover_pages = 3 print_start_page = self.issue.start_page_numbering_at or print_cover_pages subtrahend = print_start_page - print_cover_pages anchor_page = ( (self.issue_page_from - subtrahend) if self.issue_page_from else None ) page_abbr = "pp" if self.issue_page_to else "p" page_from = self.issue_page_from or "" page_to = self.issue_page_to or "" page_delimiter = " – " if self.issue_page_to else "" text = "" if page_from: text = f"{page_abbr} {page_from}{page_delimiter}{page_to}" return PdfPageReference(text=text, anchor=anchor_page)
[docs] class Meta: abstract = True