Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
4 changes: 3 additions & 1 deletion tests/snapshots/goodbye-cruel-world.snapshot.html
Original file line number Diff line number Diff line change
Expand Up @@ -593,7 +593,8 @@ <h2 id="heroic-engineering">
</del>
stakeholders.
</p>
<pre><code>Hello Mr. Fancy Manager,
<div class="highlight">
<pre><span></span><code>Hello Mr. Fancy Manager,

I am pleased to supply you with features maintained in the new version of the site.

Expand All @@ -603,6 +604,7 @@ <h2 id="heroic-engineering">

The engineer
</code></pre>
</div>
<p>
The engineer's written proof reassured the
<del>
Expand Down
17 changes: 16 additions & 1 deletion tests/snapshots/hello-world.snapshot.html
Original file line number Diff line number Diff line change
Expand Up @@ -88,8 +88,23 @@ <h2 id="first-program">
</code>
:
</p>
<pre><code class="language-python">print('Hello World!')
<div class="codehilite highlight">
<table class="highlighttable">
<tr>
<td class="linenos">
<div class="linenodiv">
<pre><span></span><span class="normal">1</span></pre>
</div>
</td>
<td class="code">
<div>
<pre><span></span><code><span class="nb">print</span><span class="p">(</span><span class="s1">'Hello World!'</span><span class="p">)</span>
</code></pre>
</div>
</td>
</tr>
</table>
</div>
<p>
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
<code>
Expand Down
38 changes: 22 additions & 16 deletions website/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -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__)

Expand All @@ -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:
Expand Down Expand Up @@ -152,17 +152,16 @@ 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,
extensions=['fenced_code', 'toc', 'tables'],
extensions=['pymdownx.superfences', 'toc', 'tables', 'codehilite'],
)
)

Expand Down Expand Up @@ -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


Expand All @@ -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:
Expand Down
2 changes: 1 addition & 1 deletion website/blog/2020/hello_world.md
Original file line number Diff line number Diff line change
Expand Up @@ -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!')
```

Expand Down
5 changes: 2 additions & 3 deletions website/blog/2022/missed-article-titles.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
```
Expand Down
3 changes: 0 additions & 3 deletions website/repositories/image_repositories.py
Original file line number Diff line number Diff line change
Expand Up @@ -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))
Expand Down
74 changes: 74 additions & 0 deletions website/static/css/hilite.css
Original file line number Diff line number Diff line change
@@ -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 */
1 change: 1 addition & 0 deletions website/templates/article.pug
Original file line number Diff line number Diff line change
Expand Up @@ -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}}
Expand Down
31 changes: 27 additions & 4 deletions website/templates/sitemap.xml
Original file line number Diff line number Diff line change
@@ -1,7 +1,30 @@
<urlset>
{% for item in items %}
<url>
<loc>{{ 'articles/' + item.get_identifier() }}</loc>
</url>
<url>
<loc>index</loc>
</url>
<url>
<loc>faq</loc>
</url>
{% for item in articles %}
<url>
<loc>{{ 'articles/' + item.get_identifier() }}</loc>
</url>
{% endfor %}
{% for item in images %}
<url>
<loc>{{ 'images/' + item.get_identifier() }}</loc>
</url>
<url>
<loc>{{ 'images/' + item.get_identifier() + '/thumbnail'}}</loc>
</url>
{% endfor %}
<url>
<loc>favicon</loc>
</url>
<url>
<loc>rss</loc>
</url>
<url>
<loc>sitemap</loc>
</url>
</urlset>