Source code for blabel.Blabel

import os
from io import BytesIO

import jinja2
from weasyprint import HTML
from . import label_tools
from . import tools

THIS_PATH = os.path.dirname(os.path.realpath(__file__))
with open(os.path.join(THIS_PATH, "data", "print_template.html"), "r") as f:
    PRINT_TEMPLATE = jinja2.Template(f.read())

GLOBALS = {
    "list": list,
    "len": len,
    "enumerate": enumerate,
    "label_tools": label_tools,
    "str": str,
}


def write_pdf(html, target=None, base_url=None, extra_stylesheets=()):
    """Write the provided HTML in a PDF file.

    Parameters
    ----------
    html
      A HTML string

    target
      A PDF file path or file-like object, or None for returning the raw bytes
      of the PDF.

    base_url
      The base path from which relative paths in the HTML template start.

    use_default_styling
      Setting this parameter to False, your PDF will have no styling at all by
      default. This means no Semantic UI, which can speed up the rendering.

    extra_stylesheets
      List of paths to other ".css" files used to define new styles or
      overwrite default styles.
    """
    weasy_html = HTML(string=html, base_url=base_url)
    if target in [None, "@memory"]:
        with BytesIO() as buffer:
            weasy_html.write_pdf(buffer, stylesheets=extra_stylesheets)
            pdf_data = buffer.getvalue()
        return pdf_data
    else:
        weasy_html.write_pdf(target, stylesheets=extra_stylesheets)


[docs] class LabelWriter: """Class to write labels. Parameters ---------- item_template_path Path to an HTML/jinja2 html template file that will serve as template for translating a dict record into the HTML of one item. Alternatively an ``item_template`` parameter can be provided. Set encoding of the file with the ``encoding`` parameter (e.g. utf-8). item_template jinja2.Template object to serve as a template for translating a dict record into the HTML of one item. default_stylesheets List of ``weasyprint.CSS`` objects or path to ``.css`` spreadsheets to be used for default styling. default_base_url Path to use as origin for relative paths in the HTML document. (Only useful when using assets such as images etc.) items_per_page Number of items per page (= per sticker). This is particularly practical if you only have "landscape" stickers and want to print square labels by printing 2 labels per stickers and cutting the stickers in two afterwards. encoding The encoding of the item template file. **default_context Use keywords to add any variable, function, etc. that you are using in the templates. """ def __init__( self, item_template_path=None, item_template=None, default_stylesheets=(), default_base_url=None, items_per_page=1, encoding=None, **default_context ): if item_template_path is not None: if encoding is not None: with open(item_template_path, "r", encoding=encoding) as f: item_template = f.read() else: # use locale.getpreferredencoding() with open(item_template_path, "r") as f: item_template = f.read() if isinstance(item_template, str): item_template = jinja2.Template(item_template) self.default_context = default_context if default_context else {} self.default_stylesheets = default_stylesheets self.default_base_url = default_base_url self.item_template = item_template self.items_per_page = items_per_page
[docs] def record_to_html(self, record): """Convert one record to an html string using the item template.""" context = dict(GLOBALS.items()) context.update(self.default_context) context.update(record) return self.item_template.render(**context)
[docs] def records_to_html(self, records, target=None): """Build the full HTML document to be printed. If ``target`` is None, the raw HTML string is returned, else the HTML is written at the path specified by ``target``.""" items_htmls = [self.record_to_html(record) for record in records] items_chunks = tools.list_chunks(items_htmls, self.items_per_page) html = PRINT_TEMPLATE.render(items_chunks=items_chunks) if target is not None: with open(target, "w") as f: f.write(html) else: return html
[docs] def write_labels(self, records, target=None, extra_stylesheets=(), base_url=None): """Write the PDF document containing the labels to be printed. Parameters ---------- records List of dictionaries with the parameters of each label to print. target Path of the PDF file to be generated. If left to None or "@memory", the raw file data will be returned. extra_stylesheets List of path to stylesheets of Weasyprint CSS objects to complement the default stylesheets. base_url Path of the origin for the different relative path inside the HTML document getting printed. """ return write_pdf( self.records_to_html(records), target=target, extra_stylesheets=self.default_stylesheets + extra_stylesheets, base_url=base_url if base_url else self.default_base_url, )