"""Generates PDF cards from a calibre metadata.db.""" import os import shutil from pathlib import Path from textwrap import shorten from calibrestekje import Book, Comment, Publisher, init_session from reportlab.lib.pagesizes import * from reportlab.lib.styles import ParagraphStyle, getSampleStyleSheet from reportlab.pdfgen import canvas from reportlab.platypus import PageBreak, Paragraph, SimpleDocTemplate, Spacer CWD = Path().resolve() NUM_WORDS_COMMENT = 50 from html.parser import HTMLParser from io import StringIO class MLStripper(HTMLParser): """https://stackoverflow.com/a/925630""" def __init__(self): super().__init__() self.reset() self.strict = False self.convert_charrefs = True self.text = StringIO() def handle_data(self, d): self.text.write(d) def get_data(self): return self.text.getvalue() def strip_tags(html): """HTML stripper.""" s = MLStripper() s.feed(html) return s.get_data() def make_cards(filepath, db_path, side_a, side_b): """The main entrypoint for card generation.""" filename = os.path.basename(filepath) doc = create_doc(filename) content = get_fields(db_path, side_a, side_b) doc.build(content) shutil.move(os.path.join(CWD, filename), filepath) def select_fields(fields, content, styles, book): if "title" in fields: tag = "{}".format(strip_tags(book.title)) ptitle = Paragraph(tag, styles["Italic"]) content.append(ptitle) content.append(Spacer(1, 12)) if "timestamp" in fields: tag = "Timestamp: {}".format(book.timestamp) ptime = Paragraph(tag, styles["Normal"]) content.append(ptime) content.append(Spacer(1, 12)) if "comments" in fields: trimmed = " ".join([c.text for c in book.comments]).split() if len(trimmed) > NUM_WORDS_COMMENT: comments = "{}...".format(" ".join(trimmed[:NUM_WORDS_COMMENT])) else: comments = "{}".format(" ".join(trimmed[:NUM_WORDS_COMMENT])) tag = "{}".format(strip_tags(comments)) pcomments = Paragraph(tag) content.append(pcomments) content.append(Spacer(6, 12)) if "authors" in fields: format_string = "{}" all_authors = [strip_tags(author.name) for author in book.authors] glued_together = format_string.format(", ".join(all_authors)) p = Paragraph(glued_together, styles["Normal"]) content.append(p) content.append(Spacer(6, 12)) if "tags" in fields: format_string = "{}" all_tags = [strip_tags(tag.name) for tag in book.tags] tags_glued_together = format_string.format(", ".join(all_tags)) p = Paragraph(tags_glued_together, styles["Normal"]) content.append(p) content.append(Spacer(6, 12)) return content def get_fields(db_path, side_a, side_b): """Retrieve fields from the metadata.""" content = [] styles = getSampleStyleSheet() session = init_session(db_path) for book in session.query(Book).all(): content = select_fields(side_a, content, styles, book) content.append(PageBreak()) content = select_fields(side_b, content, styles, book) content.append(PageBreak()) return content def create_doc(filename): """Build the Report Lab document template.""" return SimpleDocTemplate( filename, pagesize=landscape(A6), rightMargin=18, leftMargin=18, topMargin=0, bottomMargin=18, )