Skip to content
Snippets Groups Projects
Select Git revision
  • 557eddbb397a364e178a8b608f809ea62bae3d50
  • test default protected
  • master protected
  • feat/custom-css
  • feat/redesign-improvements-10
  • feat/redesign-improvements-8
  • feat/redesign-fixes-3
  • feat/pirstan-changes
  • feat/separate-import-thread
  • feat/dary-improvements
  • features/add-pdf-page
  • features/add-typed-table
  • features/fix-broken-calendar-categories
  • features/add-embed-to-articles
  • features/create-mastodon-feed-block
  • features/add-custom-numbering-for-candidates
  • features/add-timeline
  • features/create-wordcloud-from-article-page
  • features/create-collapsible-extra-legal-info
  • features/extend-hero-banner
  • features/add-link-to-images
21 results

export_program.py

Blame
  • export_program.py 5.12 KiB
    import re
    from datetime import date
    from io import BytesIO
    from pathlib import Path
    
    from django.core.management.base import BaseCommand, CommandError
    from django.template.loader import render_to_string
    from django.utils import timezone
    from PyPDF2 import PdfFileMerger
    from weasyprint import CSS, HTML, default_url_fetcher
    from weasyprint.text.fonts import FontConfiguration
    
    from ...constants import BENEFITS_CHOICES, MINISTRY_CHOICES, MINISTRY_CODES
    from ...models import Elections2021ProgramPointPage
    
    FORMAT_PDF = "pdf"
    FORMAT_HTML = "html"
    
    STATICS_DIR = (Path(__file__).parent / "../../static/elections2021/pdf/").resolve()
    
    
    def get_ministry_points(ministry):
        weight = f"weight_ministry_{MINISTRY_CODES[ministry]}"
        return Elections2021ProgramPointPage.filter_by_weights([weight])
    
    
    def local_fetcher(url):
        if url.startswith("file://"):
            file = Path(url[7:])
            if not file.is_absolute():
                file = STATICS_DIR / (url[7:])
            return dict(file_obj=file.open(mode="rb"))
        return default_url_fetcher(url)
    
    
    def plain_export(output_file, output_format):
        benefits_titles = dict(BENEFITS_CHOICES)
    
        toc = []
        body = []
    
        for ministry, title in MINISTRY_CHOICES:
            sub_toc = []
            points = []
            for page in get_ministry_points(ministry):
                value = render_to_string(
                    "elections2021/export_program_point.html",
                    {"page": page, "benefits_titles": benefits_titles},
                )
                value = re.sub(r'href="#zdroje"', f'href="#zdroje_{page.id}"', value)
                points.append(value)
                sub_toc.append({"anchor": page.slug, "title": page.title})
    
            body.append({"anchor": ministry, "title": title, "points": points})
            toc.append({"anchor": ministry, "title": title, "sub_toc": sub_toc})
    
        content = render_to_string(
            "elections2021/export_program.html",
            {
                "toc": toc,
                "body": body,
                "now": timezone.localtime().strftime("%d.%m.%Y %H:%M"),
            },
        )
    
        if output_format == FORMAT_PDF:
            font_config = FontConfiguration()
            html = HTML(string=content)
            css = CSS(
                string="""
                    @page {
                        size: A4;
                        margin: 1cm;
                    }
                    @font-face {
                        font-family: "Roboto Condensed";
                        src: url("https://github.com/google/fonts/blob/main/apache/roboto/static/RobotoCondensed-Regular.ttf?raw=true");
                    }
                """,
                font_config=font_config,
            )
            html.write_pdf(output_file, stylesheets=[css], font_config=font_config)
    
        elif output_format == FORMAT_HTML:
            with open(output_file, "w") as file:
                file.write(content)
    
    
    def fancy_export(output_file, ministry=None):
        tmp_file = f"{output_file}.tmp"
        benefits_titles = dict(BENEFITS_CHOICES)
    
        if ministry is None:
            pages = (
                Elections2021ProgramPointPage.objects.live()
                .specific()
                .order_by("-default_order")
            )
        else:
            pages = get_ministry_points(ministry)
    
        points = []
        for page in pages:
            value = render_to_string(
                "elections2021/export_program_point_fancy.html",
                {"page": page, "benefits_titles": benefits_titles},
            )
            value = re.sub(r'href="#', f'href="#{page.id}_', value)
            value = re.sub(r'id="', f'id="{page.id}_', value)
            points.append(value)
    
        content = render_to_string(
            "elections2021/export_program_fancy.html", {"points": points}
        )
        today = date.today().strftime("%d.%m.%Y")
        extra_css = '@page { @bottom-left { content: "%s" }}' % today
    
        font_config = FontConfiguration()
        html = HTML(string=content, url_fetcher=local_fetcher)
        css = CSS(str(STATICS_DIR / "style.css"), font_config=font_config)
        css2 = CSS(BytesIO(extra_css.encode("utf-8")), font_config=font_config)
        document = html.render(stylesheets=[css, css2], font_config=font_config)
        document.write_pdf(tmp_file)
    
        merger = PdfFileMerger()
        merger.append(str(STATICS_DIR / "beginning.pdf"))
        merger.append(tmp_file, pages=(2, len(document.pages)))
        merger.append(str(STATICS_DIR / "ending.pdf"))
        merger.write(output_file)
        merger.close()
    
        Path(tmp_file).unlink()
    
    
    class Command(BaseCommand):
        def add_arguments(self, parser):
            parser.add_argument("output", type=str, help=".pdf nebo .html soubor")
            parser.add_argument("--fancy", action="store_true")
            parser.add_argument("--ministry", type=str)
    
        def handle(self, *args, **options):
            output_file = options["output"]
    
            if output_file.endswith(".pdf"):
                output_format = FORMAT_PDF
            elif output_file.endswith(".html"):
                output_format = FORMAT_HTML
            else:
                raise CommandError("Jako výstup zadej soubor .html nebo .pdf")
    
            if options["fancy"]:
                if output_format != FORMAT_PDF:
                    raise CommandError("Fancy export lze udělat jen do .pdf")
                fancy_export(output_file, options["ministry"])
            else:
                plain_export(output_file, output_format)