From 8d3577dcb870524157e8dac653b6ac95b81af5fd Mon Sep 17 00:00:00 2001 From: Johnny Irvin Date: Sat, 17 Sep 2022 21:31:48 -0400 Subject: [PATCH 1/4] Remove limitation Let's blindly trust the directory as images ;) --- website/repositories/image_repositories.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/website/repositories/image_repositories.py b/website/repositories/image_repositories.py index 5c3511f..7486d7f 100644 --- a/website/repositories/image_repositories.py +++ b/website/repositories/image_repositories.py @@ -55,9 +55,6 @@ def _load_images(self, directory: str) -> dict[str, Image]: directory = os.path.join('website', directory) for _, _, files in os.walk(directory): for file in files: - if not file.endswith('.jpg') and not file.endswith('.png'): - continue - with open(os.path.join(directory, file), 'rb') as f: content = f.read() created = os.path.getctime(os.path.join(directory, file)) From 2c3071d0ff0128e3fb05f63433ba7af2c0029e46 Mon Sep 17 00:00:00 2001 From: Johnny Irvin Date: Sat, 17 Sep 2022 21:33:01 -0400 Subject: [PATCH 2/4] All site urls for sitemap. Closes #58 - Icon repository - Not found bug fix for article --- website/__init__.py | 36 ++++++++++++++++++++--------------- website/templates/sitemap.xml | 31 ++++++++++++++++++++++++++---- 2 files changed, 48 insertions(+), 19 deletions(-) diff --git a/website/__init__.py b/website/__init__.py index 231d344..59942c4 100644 --- a/website/__init__.py +++ b/website/__init__.py @@ -26,8 +26,7 @@ import markdown from flask_talisman import Talisman -from website.repositories import (Repository, blog_repositories, - image_repositories) +from website.repositories import blog_repositories, image_repositories app = flask.Flask(__name__) @@ -52,6 +51,7 @@ blog_repo = blog_repositories.PostRepository('blog') image_repo = image_repositories.ImageRepository('images') +icon_repo = image_repositories.ImageRepository('static/icons') @app.route('/') def index() -> str: @@ -152,13 +152,12 @@ def article(year: int, month: int, day: int, description: str) -> str: """ try: post = blog_repo.get(f"{year}/{month}/{day}/{description}") - except Repository.NotFound: + except Exception: flask.abort(404) return flask.render_template( 'article.pug', title=post.title, - # Day Month Year date=post.date.strftime('%d %B %Y'), content=markdown.markdown( post.content, @@ -204,18 +203,25 @@ def sitemap() -> str: Returns: str: The rendered template. """ - sorted_items = sorted( + sorted_articles = sorted( blog_repo.get_all(), key=lambda post: post.date, reverse=True, ) + sorted_images = sorted( + image_repo.get_all(), + key=lambda image: image.created, + reverse=True, + ) response = flask.make_response( flask.render_template( 'sitemap.xml', - items=sorted_items, + articles=sorted_articles, + images=sorted_images, ) ) response.mimetype = 'application/xml' + return response @@ -228,17 +234,17 @@ def favicon() -> flask.Response: Returns: flask.Response: The image response. """ - directory = os.path.join( - app.root_path, - 'static', - 'icons', - ) - images = os.listdir(directory) + images = icon_repo.get_all() image = random.choice(images) - return flask.send_from_directory( - directory, - image, + mimetype = 'image/jpeg' if image.extension == 'jpg' else 'image/png' + mimetype = 'favicon' if image.extension == 'ico' else mimetype + img_io = io.BytesIO(image.content) + img_io.seek(0) + + return flask.send_file( + img_io, + mimetype=mimetype, ) with open('website/static/faq.md', 'r') as file: diff --git a/website/templates/sitemap.xml b/website/templates/sitemap.xml index 14cb467..df42c9d 100644 --- a/website/templates/sitemap.xml +++ b/website/templates/sitemap.xml @@ -1,7 +1,30 @@ - {% for item in items %} - - {{ 'articles/' + item.get_identifier() }} - + + index + + + faq + + {% for item in articles %} + + {{ 'articles/' + item.get_identifier() }} + {% endfor %} + {% for item in images %} + + {{ 'images/' + item.get_identifier() }} + + + {{ 'images/' + item.get_identifier() + '/thumbnail'}} + + {% endfor %} + + favicon + + + rss + + + sitemap + \ No newline at end of file From ca9916f8b1deabe2a2950627ccc57897257a7e82 Mon Sep 17 00:00:00 2001 From: Johnny Irvin Date: Sat, 24 Sep 2022 23:08:34 -0400 Subject: [PATCH 3/4] Fixes code hilite. - Add markdown hilite extension. - Add pymdownx.superfences for nested code blocks. - Updated hello_world.md - Updated missed-articles - Closes #76 --- requirements.txt | 2 + website/__init__.py | 2 +- website/blog/2020/hello_world.md | 2 +- website/blog/2022/missed-article-titles.md | 5 +- website/static/css/hilite.css | 74 ++++++++++++++++++++++ website/templates/article.pug | 1 + 6 files changed, 81 insertions(+), 5 deletions(-) create mode 100644 website/static/css/hilite.css diff --git a/requirements.txt b/requirements.txt index ca7213b..f952ae2 100644 --- a/requirements.txt +++ b/requirements.txt @@ -18,6 +18,8 @@ Pillow==9.2.0 pluggy==1.0.0 py==1.11.0 pycparser==2.21 +Pygments==2.13.0 +pymdown-extensions==9.5 pyparsing==3.0.9 pypugjs==5.9.11 pytest==7.1.2 diff --git a/website/__init__.py b/website/__init__.py index 59942c4..38c316a 100644 --- a/website/__init__.py +++ b/website/__init__.py @@ -161,7 +161,7 @@ def article(year: int, month: int, day: int, description: str) -> str: date=post.date.strftime('%d %B %Y'), content=markdown.markdown( post.content, - extensions=['fenced_code', 'toc', 'tables'], + extensions=['pymdownx.superfences', 'toc', 'tables', 'codehilite'], ) ) diff --git a/website/blog/2020/hello_world.md b/website/blog/2020/hello_world.md index 0466f3f..1185152 100644 --- a/website/blog/2020/hello_world.md +++ b/website/blog/2020/hello_world.md @@ -16,7 +16,7 @@ This example will be using the programming language [Python](https://www.python. Writing and executing a simple "Hello World" program is fairly simple. Most languages require you to tell the computer using a specific command that you would like to output some characters, in this case, "Hello World," to the screen. The ```print``` command allows us to output some text to the screen. Please note that we don't always output the screen (the terminal), and in the past, we've output to a physical printer or similar device. Using your preferred text editor, write the following in a new file named ```hello_world.py```: -```python +```{.python .codehilite linenums="1"} print('Hello World!') ``` diff --git a/website/blog/2022/missed-article-titles.md b/website/blog/2022/missed-article-titles.md index cbedd8c..a7c9609 100644 --- a/website/blog/2022/missed-article-titles.md +++ b/website/blog/2022/missed-article-titles.md @@ -20,15 +20,14 @@ Blocks, such as the title, can be overridden in the layout. The `block` tag acce The default looks like this: -```pugjs +```{.pugjs .codehilite linenums="1"} block title title Engineer, Researcher, Entrepreneur - Johnathan Irvin ``` The layout contains the default title. I overrode the block in the `article.pug` file. -``` -pugjs +```{.pugjs .codehilite linenums="1"} block title title {{ title }} - Johnathan Irvin ``` diff --git a/website/static/css/hilite.css b/website/static/css/hilite.css new file mode 100644 index 0000000..9a05b3a --- /dev/null +++ b/website/static/css/hilite.css @@ -0,0 +1,74 @@ +pre { line-height: 125%; } +td.linenos .normal { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; } +span.linenos { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; } +td.linenos .special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; } +span.linenos.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; } +.codehilite .hll { background-color: #ffffcc } +.codehilite { background: #f8f8f8; } +.codehilite .c { color: #3D7B7B; font-style: italic } /* Comment */ +.codehilite .err { border: 1px solid #FF0000 } /* Error */ +.codehilite .k { color: #008000; font-weight: bold } /* Keyword */ +.codehilite .o { color: #666666 } /* Operator */ +.codehilite .ch { color: #3D7B7B; font-style: italic } /* Comment.Hashbang */ +.codehilite .cm { color: #3D7B7B; font-style: italic } /* Comment.Multiline */ +.codehilite .cp { color: #9C6500 } /* Comment.Preproc */ +.codehilite .cpf { color: #3D7B7B; font-style: italic } /* Comment.PreprocFile */ +.codehilite .c1 { color: #3D7B7B; font-style: italic } /* Comment.Single */ +.codehilite .cs { color: #3D7B7B; font-style: italic } /* Comment.Special */ +.codehilite .gd { color: #A00000 } /* Generic.Deleted */ +.codehilite .ge { font-style: italic } /* Generic.Emph */ +.codehilite .gr { color: #E40000 } /* Generic.Error */ +.codehilite .gh { color: #000080; font-weight: bold } /* Generic.Heading */ +.codehilite .gi { color: #008400 } /* Generic.Inserted */ +.codehilite .go { color: #717171 } /* Generic.Output */ +.codehilite .gp { color: #000080; font-weight: bold } /* Generic.Prompt */ +.codehilite .gs { font-weight: bold } /* Generic.Strong */ +.codehilite .gu { color: #800080; font-weight: bold } /* Generic.Subheading */ +.codehilite .gt { color: #0044DD } /* Generic.Traceback */ +.codehilite .kc { color: #008000; font-weight: bold } /* Keyword.Constant */ +.codehilite .kd { color: #008000; font-weight: bold } /* Keyword.Declaration */ +.codehilite .kn { color: #008000; font-weight: bold } /* Keyword.Namespace */ +.codehilite .kp { color: #008000 } /* Keyword.Pseudo */ +.codehilite .kr { color: #008000; font-weight: bold } /* Keyword.Reserved */ +.codehilite .kt { color: #B00040 } /* Keyword.Type */ +.codehilite .m { color: #666666 } /* Literal.Number */ +.codehilite .s { color: #BA2121 } /* Literal.String */ +.codehilite .na { color: #687822 } /* Name.Attribute */ +.codehilite .nb { color: #008000 } /* Name.Builtin */ +.codehilite .nc { color: #0000FF; font-weight: bold } /* Name.Class */ +.codehilite .no { color: #880000 } /* Name.Constant */ +.codehilite .nd { color: #AA22FF } /* Name.Decorator */ +.codehilite .ni { color: #717171; font-weight: bold } /* Name.Entity */ +.codehilite .ne { color: #CB3F38; font-weight: bold } /* Name.Exception */ +.codehilite .nf { color: #0000FF } /* Name.Function */ +.codehilite .nl { color: #767600 } /* Name.Label */ +.codehilite .nn { color: #0000FF; font-weight: bold } /* Name.Namespace */ +.codehilite .nt { color: #008000; font-weight: bold } /* Name.Tag */ +.codehilite .nv { color: #19177C } /* Name.Variable */ +.codehilite .ow { color: #AA22FF; font-weight: bold } /* Operator.Word */ +.codehilite .w { color: #bbbbbb } /* Text.Whitespace */ +.codehilite .mb { color: #666666 } /* Literal.Number.Bin */ +.codehilite .mf { color: #666666 } /* Literal.Number.Float */ +.codehilite .mh { color: #666666 } /* Literal.Number.Hex */ +.codehilite .mi { color: #666666 } /* Literal.Number.Integer */ +.codehilite .mo { color: #666666 } /* Literal.Number.Oct */ +.codehilite .sa { color: #BA2121 } /* Literal.String.Affix */ +.codehilite .sb { color: #BA2121 } /* Literal.String.Backtick */ +.codehilite .sc { color: #BA2121 } /* Literal.String.Char */ +.codehilite .dl { color: #BA2121 } /* Literal.String.Delimiter */ +.codehilite .sd { color: #BA2121; font-style: italic } /* Literal.String.Doc */ +.codehilite .s2 { color: #BA2121 } /* Literal.String.Double */ +.codehilite .se { color: #AA5D1F; font-weight: bold } /* Literal.String.Escape */ +.codehilite .sh { color: #BA2121 } /* Literal.String.Heredoc */ +.codehilite .si { color: #A45A77; font-weight: bold } /* Literal.String.Interpol */ +.codehilite .sx { color: #008000 } /* Literal.String.Other */ +.codehilite .sr { color: #A45A77 } /* Literal.String.Regex */ +.codehilite .s1 { color: #BA2121 } /* Literal.String.Single */ +.codehilite .ss { color: #19177C } /* Literal.String.Symbol */ +.codehilite .bp { color: #008000 } /* Name.Builtin.Pseudo */ +.codehilite .fm { color: #0000FF } /* Name.Function.Magic */ +.codehilite .vc { color: #19177C } /* Name.Variable.Class */ +.codehilite .vg { color: #19177C } /* Name.Variable.Global */ +.codehilite .vi { color: #19177C } /* Name.Variable.Instance */ +.codehilite .vm { color: #19177C } /* Name.Variable.Magic */ +.codehilite .il { color: #666666 } /* Literal.Number.Integer.Long */ diff --git a/website/templates/article.pug b/website/templates/article.pug index d862406..6e22abb 100644 --- a/website/templates/article.pug +++ b/website/templates/article.pug @@ -5,6 +5,7 @@ block title block styles link(href="{{ url_for('static', filename='css/article.css') }}", rel="stylesheet") + link(href="{{ url_for('static', filename='css/hilite.css') }}", rel="stylesheet") block content h1.post-title.h1 {{title}} From ace956061cd1f031f1683cd456db92d968e9a526 Mon Sep 17 00:00:00 2001 From: Johnny Irvin Date: Sat, 24 Sep 2022 23:11:57 -0400 Subject: [PATCH 4/4] Update snapshots --- .../snapshots/goodbye-cruel-world.snapshot.html | 4 +++- tests/snapshots/hello-world.snapshot.html | 17 ++++++++++++++++- 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/tests/snapshots/goodbye-cruel-world.snapshot.html b/tests/snapshots/goodbye-cruel-world.snapshot.html index fad6242..309dd74 100644 --- a/tests/snapshots/goodbye-cruel-world.snapshot.html +++ b/tests/snapshots/goodbye-cruel-world.snapshot.html @@ -593,7 +593,8 @@

stakeholders.

-
Hello Mr. Fancy Manager,
+   
+
Hello Mr. Fancy Manager,
 
     I am pleased to supply you with features maintained in the new version of the site.
 
@@ -603,6 +604,7 @@ 

The engineer

+

The engineer's written proof reassured the diff --git a/tests/snapshots/hello-world.snapshot.html b/tests/snapshots/hello-world.snapshot.html index a209b1a..ffd21e2 100644 --- a/tests/snapshots/hello-world.snapshot.html +++ b/tests/snapshots/hello-world.snapshot.html @@ -88,8 +88,23 @@

:

-
print('Hello World!')
+   
+ + + + + +
+
+
1
+
+
+
+
print('Hello World!')
 
+
+
+

Save your work, and close the text editor. Open up a terminal application like Powershell on Windows or bash on Ubuntu. If you're on Windows, it is as easy as hitting your Windows Key and searching for