From 44a7e6046b2f94193c589e43593473341b8d165f Mon Sep 17 00:00:00 2001 From: Jordan Matelsky Date: Thu, 29 Apr 2021 08:28:34 -0400 Subject: [PATCH] Enable custom font size (#40) * Update example config * Accept font_size in output generator * Add font-size argument to main multiparser * Default to using integer font size * Update changelog; reduce example config for speed * Update version marker --- CHANGELOG.md | 4 +- example-config.json | 10 +- goosepaper/__main__.py | 9 +- goosepaper/goosepaper.py | 26 ++-- goosepaper/storyprovider.py | 3 +- goosepaper/styles.py | 268 +++++++++++++++++------------------- setup.py | 3 +- 7 files changed, 155 insertions(+), 168 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index fdc09de..ecd6c99 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,8 +1,8 @@ # CHANGELOG -### **???** (Unreleased) +### **0.3.1** (April 29 2021) -> This version adds a test suite and improvements to the upload mechanism. +> This version adds a test suite and improvements to the upload and config mechanisms, as well as several more performance and feature improvements. - Improvements - Add test suite diff --git a/example-config.json b/example-config.json index aec7a95..a22476a 100644 --- a/example-config.json +++ b/example-config.json @@ -1,4 +1,5 @@ { + "font_size": 12, "stories": [ { "provider": "weather", @@ -7,7 +8,7 @@ { "provider": "twitter", "config": { - "usernames": ["reuters", "bbcWorld", "axios", "NPR"], + "usernames": ["axios", "NPR"], "limit_per": 8 } }, @@ -22,13 +23,6 @@ "limit": 5 } }, - { - "provider": "rss", - "config": { - "rss_path": "https://www.statnews.com/feed/", - "limit": 2 - } - }, { "provider": "reddit", "config": { "subreddit": "news" } diff --git a/goosepaper/__main__.py b/goosepaper/__main__.py index 9d68ce3..12fc667 100644 --- a/goosepaper/__main__.py +++ b/goosepaper/__main__.py @@ -17,10 +17,12 @@ def main(): subtitle = config["subtitle"] if "subtitle" in config else None filename = multiparser.argumentOrConfig( "output", - default=f"Goosepaper-{datetime.datetime.now().strftime('%Y-%B-%d-%H-%M')}.pdf" + default=f"Goosepaper-{datetime.datetime.now().strftime('%Y-%B-%d-%H-%M')}.pdf", ) replace = multiparser.argumentOrConfig("replace", False) folder = multiparser.argumentOrConfig("folder", None) + font_size = multiparser.argumentOrConfig("font_size", 14) + print(font_size) paper = Goosepaper(story_providers=story_providers, title=title, subtitle=subtitle) @@ -28,9 +30,9 @@ def main(): with open(filename, "w") as fh: fh.write(paper.to_html()) elif filename.endswith(".pdf"): - paper.to_pdf(filename) + paper.to_pdf(filename, font_size=font_size) elif filename.endswith(".epub"): - paper.to_epub(filename) + paper.to_epub(filename, font_size=font_size) else: raise ValueError(f"Unknown file extension '{filename.split('.')[-1]}'.") @@ -39,5 +41,6 @@ def main(): return 0 + if __name__ == "__main__": sys.exit(main()) diff --git a/goosepaper/goosepaper.py b/goosepaper/goosepaper.py index 56c3287..2073376 100644 --- a/goosepaper/goosepaper.py +++ b/goosepaper/goosepaper.py @@ -2,7 +2,7 @@ import os from uuid import uuid4 -from typing import List +from typing import List, Type from ebooklib import epub from .styles import Style, AutumnStyle @@ -21,9 +21,7 @@ def __init__( ): self.story_providers = story_providers self.title = title if title else "Daily Goosepaper" - self.subtitle = ( - subtitle + "\n" if subtitle else "" - ) + self.subtitle = subtitle + "\n" if subtitle else "" self.subtitle += datetime.datetime.today().strftime("%B %d, %Y") def get_stories(self, deduplicate: bool = False): @@ -90,7 +88,9 @@ def to_html(self) -> str: """ - def to_pdf(self, filename: str, style: Style = AutumnStyle) -> str: + def to_pdf( + self, filename: str, style: Type[Style] = AutumnStyle, font_size: int = 14 + ) -> str: """ Renders the current Goosepaper to a PDF file on disk. @@ -99,14 +99,16 @@ def to_pdf(self, filename: str, style: Style = AutumnStyle) -> str: """ from weasyprint import HTML, CSS - style = style() + style_obj = style() html = self.to_html() h = HTML(string=html) - c = CSS(string=style.get_css()) - h.write_pdf(filename, stylesheets=[c, *style.get_stylesheets()]) + c = CSS(string=style_obj.get_css(font_size)) + h.write_pdf(filename, stylesheets=[c, *style_obj.get_stylesheets()]) return filename - def to_epub(self, filename: str, style: Style = AutumnStyle) -> str: + def to_epub( + self, filename: str, style: Type[Style] = AutumnStyle, font_size: int = 14 + ) -> str: """ Render the current Goosepaper to an epub file on disk """ @@ -129,12 +131,12 @@ def to_epub(self, filename: str, style: Style = AutumnStyle) -> str: book.set_title(title) book.set_language("en") - style = Style() + style_obj = Style() css = epub.EpubItem( uid="style_default", file_name="style/default.css", media_type="text/css", - content=style.get_css(), + content=style_obj.get_css(font_size), ) book.add_item(css) @@ -167,5 +169,5 @@ def to_epub(self, filename: str, style: Style = AutumnStyle) -> str: book.add_item(epub.EpubNav()) book.spine = ["nav"] + chapters - print(f"Honk! Writing out epub {filename}") epub.write_epub(filename, book) + return filename diff --git a/goosepaper/storyprovider.py b/goosepaper/storyprovider.py index bd74aa2..9e800d6 100644 --- a/goosepaper/storyprovider.py +++ b/goosepaper/storyprovider.py @@ -1,4 +1,5 @@ import abc +from typing import List from .story import Story @@ -7,7 +8,7 @@ class StoryProvider(abc.ABC): An abstract class for a class that provides stories to be rendered. """ - def get_stories(self, limit: int = 5): + def get_stories(self, limit: int = 5) -> List["Story"]: """ Get a list of stories from this Provider. """ diff --git a/goosepaper/styles.py b/goosepaper/styles.py index ccbf672..c324ebe 100644 --- a/goosepaper/styles.py +++ b/goosepaper/styles.py @@ -1,152 +1,140 @@ +from typing import Union + + class Style: - def get_stylesheets(self): + def get_stylesheets(self) -> list: ... - def get_css(self): + def get_css(self, font_size: int = 14): ... class AutumnStyle(Style): - def get_stylesheets(self): + def get_stylesheets(self) -> list: return [ "https://fonts.googleapis.com/css?family=Oswald", "https://fonts.googleapis.com/css?family=Playfair+Display", ] - def get_css(self): - return self.CSS - - CSS = """ - @page { - margin-top: 0.5in; - margin-right: 0.2in; - margin-left: 0.65in; - } - - body { - font-family: "Playfair Display"; - } - - .header { - padding: 1em; - height: 10em; - } - - .header div { - float: left; - display: block; - } - - .header .ear { - float: right; - } - - ul, li, ol { - margin-left: 0; padding-left: 0.15em; - } - - .stories { - font-size: 16pt; - } - - .ear article { - border: 1px groove black; - padding: 1em; - margin: 1em; - font-size: 11pt; - } - .ear article h1 { - font-family: "Playfair Display"; - font-size: 10pt; - font-weight: normal; - } - - article { - text-align: justify; - line-height: 1.25em; - } - - .longform { - page-break-after: always; - } - - article>h1 { - font-family: "Oswald"; - font-weight: 400; - font-size: 23pt; - text-indent: 0; - margin-bottom: 0.25em; - line-height: 1.2em; - text-align: left; - } - article>h1.priority-low { - font-family: "Oswald"; - font-size: 18pt; - font-weight: 400; - text-indent: 0; - border-bottom: 1px solid #dedede; - margin-bottom: 0.15em; - } - - article>h4.byline { - font-family: "Oswald"; - font-size: 12pt; - font-weight: 400; - text-indent: 0; - border-bottom: 1px solid #dedede; - } - - article>h3 { - font-family: "Oswald"; - font-weight: 400; - font-size: 18pt; - text-indent: 0; - } - - section>h1, - section>h2, - section>h3, - section>h4, - section>h5 { - border-left: 5px solid #dedede; - padding-left: 1em; - } - - figure { - border: 1px solid black; - text-indent: 0; - width: auto; - } - - .stories article.story img { - width: 100%; - } - - figure>span { - font-size: 0; - } - - .row { - column-count: 2; - } - - /* - .row { - display: flex; - flex-direction: row; - flex-wrap: wrap; - width: 100%; - justify-content: space-between; - align-items: start; - align-content: start; - } - - .column { - display: flex; - flex-direction: column; - flex-basis: 100%; - flex: 1; - } - */ - - """ + def get_css(self, font_size: int = 14): + return ( + """ + @page { + margin-top: 0.5in; + margin-right: 0.2in; + margin-left: 0.65in; + } + + body { + font-family: "Playfair Display"; + } + + .header { + padding: 1em; + height: 10em; + } + + .header div { + float: left; + display: block; + } + + .header .ear { + float: right; + } + + ul, li, ol { + margin-left: 0; padding-left: 0.15em; + } + + .stories { + font-size: """ + + str(font_size) + + """pt; + } + + .ear article { + border: 1px groove black; + padding: 1em; + margin: 1em; + font-size: 11pt; + } + .ear article h1 { + font-family: "Playfair Display"; + font-size: 10pt; + font-weight: normal; + } + + article { + text-align: justify; + line-height: 1.25em; + } + + .longform { + page-break-after: always; + } + + article>h1 { + font-family: "Oswald"; + font-weight: 400; + font-size: 23pt; + text-indent: 0; + margin-bottom: 0.25em; + line-height: 1.2em; + text-align: left; + } + article>h1.priority-low { + font-family: "Oswald"; + font-size: 18pt; + font-weight: 400; + text-indent: 0; + border-bottom: 1px solid #dedede; + margin-bottom: 0.15em; + } + + article>h4.byline { + font-family: "Oswald"; + font-size: """ + + str(font_size) + + """pt; + font-weight: 400; + text-indent: 0; + border-bottom: 1px solid #dedede; + } + + article>h3 { + font-family: "Oswald"; + font-weight: 400; + font-size: 18pt; + text-indent: 0; + } + + section>h1, + section>h2, + section>h3, + section>h4, + section>h5 { + border-left: 5px solid #dedede; + padding-left: 1em; + } + + figure { + border: 1px solid black; + text-indent: 0; + width: auto; + } + + .stories article.story img { + width: 100%; + } + + figure>span { + font-size: 0; + } + + .row { + column-count: 2; + } + + """ + ) diff --git a/setup.py b/setup.py index e3b872d..7448ebe 100644 --- a/setup.py +++ b/setup.py @@ -4,7 +4,7 @@ from codecs import open as copen from setuptools import setup, find_packages -__version__ = "0.3.0" +__version__ = "0.3.1" here = path.abspath(path.dirname(__file__)) @@ -33,7 +33,6 @@ classifiers=[ "Development Status :: 4 - Beta", "Intended Audience :: Developers", - "Programming Language :: Python :: 3.6", "Programming Language :: Python :: 3.7", "Programming Language :: Python :: 3.8", "Programming Language :: Python :: 3.9",