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!')
+
+
+
+ |
+
+ |
+
+
+ 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