Source code for election_day.pdf

from babel.dates import format_date
from babel.dates import format_time
from copy import deepcopy
from onegov.election_day import _
from onegov.pdf import Pdf as PdfBase


from typing import Any
from typing import TYPE_CHECKING
if TYPE_CHECKING:
    from datetime import date
    from datetime import datetime
    from gettext import GNUTranslations
    from reportlab.lib.styles import PropertySet


[docs] class Pdf(PdfBase): """ Our custom PDF class. This adds some custom styles, two tables (factoids, tables) and the ability to translate texts. """ def __init__( self, *args: Any, locale: str | None = None, translations: dict[str, 'GNUTranslations'] | None = None, toc_levels: int = 3, created: str = '', logo: str | None = None, link_color: str | None = None, underline_links: bool = False, underline_width: float | str = 0.5, **kwargs: Any ): super().__init__( *args, toc_levels=toc_levels, created=created, logo=logo, link_color=link_color, underline_links=underline_links, underline_width=underline_width, **kwargs )
[docs] self.locale = locale
[docs] self.translations = translations or {}
[docs] def adjust_style(self, font_size: int = 10) -> None: """ Adds styles for votes and elections. """ super().adjust_style(font_size) self.style.indent_0 = deepcopy(self.style.normal) self.style.indent_1 = deepcopy(self.style.normal) self.style.indent_2 = deepcopy(self.style.normal) self.style.indent_0.leftIndent = 0 * self.style.indent_0.fontSize self.style.indent_1.leftIndent = 1 * self.style.indent_1.fontSize self.style.indent_2.leftIndent = 2 * self.style.indent_2.fontSize self.style.table_results = ( *self.style.tableHead, ('ALIGN', (0, 0), (0, -1), 'LEFT'), ('ALIGN', (1, 0), (-1, -1), 'RIGHT'), ) self.style.table_factoids = ( *self.style.table, ('ALIGN', (0, 0), (1, -1), 'LEFT'), ('ALIGN', (1, 0), (-1, -1), 'CENTER'), ('ALIGN', (-2, 0), (-1, -1), 'RIGHT'), ) self.style.table_dates = ( *self.style.table, ('ALIGN', (0, 0), (1, -1), 'LEFT'), ('ALIGN', (-2, 0), (-1, -1), 'RIGHT'), )
[docs] def translate(self, text: str) -> str: """ Translates the given string. """ if not hasattr(text, 'interpolate'): return text translated = None if self.locale is not None: translator = self.translations.get(self.locale) if translator is not None: translated = translator.gettext(text) return text.interpolate(translated)
[docs] def h1(self, title: str, style: 'PropertySet | None' = None) -> None: """ Translated H1. """ super().h1(self.translate(title), style=style)
[docs] def h2(self, title: str, style: 'PropertySet | None' = None) -> None: """ Translated H2. """ super().h2(self.translate(title), style=style)
[docs] def h3(self, title: str, style: 'PropertySet | None' = None) -> None: """ Translated H3. """ super().h3(self.translate(title), style=style)
[docs] def figcaption( self, text: str, style: 'PropertySet | None' = None ) -> None: """ Translated Figcaption. """ super().figcaption(self.translate(text), style=style)
[docs] def dates_line(self, date: 'date', changed: 'datetime | None') -> None: """ Adds the given date and timespamp. """ self.table( [[ format_date(date, format='long', locale=self.locale), '{}: {} {}'.format( self.translate(_('Last change')), format_date(changed, format='long', locale=self.locale), format_time(changed, format='short', locale=self.locale) ) ]], 'even', style=self.style.table_dates )
[docs] def factoids(self, headers: list[str], values: list[str]) -> None: """ Adds a table with factoids. """ assert len(headers) and len(headers) == len(values) self.table( [[self.translate(header) for header in headers], values], 'even', style=self.style.table_factoids )
[docs] def results( self, head: list[str], body: list[list[Any]], foot: list[Any] | None = None, hide: list[bool] | None = None ) -> None: """ Adds a table with results. """ assert not body or {len(column) for column in body} == {len(head)} assert not foot or len(foot) == len(head) assert not hide or len(hide) == len(head) columns = [[self.translate(cell) for cell in head], *body] if foot: columns += [foot] columns = [ [ str(cell) for index, cell in enumerate(column) if hide is None or not hide[index] ] for column in columns ] spacing = [None for index in enumerate(head)] self.table(columns, spacing, style=self.style.table_results)