diff --git a/requirements.txt b/requirements.txt index 3341fb8..893fc6c 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,4 +1,5 @@ attrs==22.1.0 +beautifulsoup4==4.11.1 blinker==1.4 cffi==1.15.0 chardet==4.0.0 @@ -23,5 +24,6 @@ pytest-snapshot==0.9.0 python-frontmatter==1.0.0 PyYAML==6.0 six==1.16.0 +soupsieve==2.3.2.post1 tomli==2.0.1 Werkzeug==2.1.2 diff --git a/tests/snapshots/goodbye-cruel-world.snapshot.html b/tests/snapshots/goodbye-cruel-world.snapshot.html index f5aa65d..fad6242 100644 --- a/tests/snapshots/goodbye-cruel-world.snapshot.html +++ b/tests/snapshots/goodbye-cruel-world.snapshot.html @@ -1,213 +1,599 @@ - - - - - - - - - - - - - - - - - - -Goodbye Cruel World - Johnathan Irvin - - -
-
Johnathan Irvin - + + -
-

Goodbye Cruel World

- -

JohnathanIrvin.com commits seppuku. Now an Isekai, the website is reborn.

-

Nearly two forsaken years have passed since JohnathanIrvin.com received enhancements. The stagnant beast lacked honor. The creature of horror ignored the security bells. It cared not to provide value. Death was the only way to ensure reincarnation.

-

Thrust forth the crisis of covid has sprung the need for software engineers. Elite hackers must rise to defeat the cybersecurity crisis. An onslaught of recruiter messages bombarded Johnathan's LinkedIn. The site knew the stakes were high. Little did we know how desperate the industry was for talented engineers.

-

With a harness of experience, we set out to change the status quo.

-

Table Of Contents

- -

Beautification Warning

-

Blessed not with visual creativity, the engineer was not a designer. He was an engineer.

-

The engineer had heard, "Your design skills are laughable."

-

The engineer replied, "I'm not a designer. I'm an engineer."

-

"I want my website to be beautiful."

-

The engineer laughed, "I use frameworks like Bootstrap and Materialize."

-

Minimalist sycophants beware the following:

- -

Bravado Justification

-

The readers stakeholders needed justification for the engineer's bravado.

-

The engineer summoned a value proposition to justify the coming adventure.

-

He championed three areas of value.

-
    -
  1. Security
  2. -
  3. Content
  4. -
  5. Metrics
  6. -
-

Dumpster Fire (Security)

-

Security issues plagued the repository.

-

Dependabot alerted the engineer daily.

-

The engineer provided the hackers stakeholders with a truncated warrant list.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
CVESeverityDescription
CVE-2021-38037.5 HighInefficient Regular Expression Complexity
CVE-2021-233417.5 HighRegular Expression Denial of Service (ReDoSI)
CVE-2022-03557.5 HighExposure of Sensitive Information
CVE-2020-77887.3 HighMalicious INI file
-

The rabbit hole had only begun. An issue inside of Node.js led to the rise of these little devils popping up multiple times in different dependencies.

-

The hydra needed to stop. The engineer had not the time to learn how to stop the beast in its JavaScript landscape. The engineering effort would be better suited to Python.

-

The engineer emphasized protective measures benefits.

-
    -
  1. Avoid litigation.
  2. -
  3. Protect information.
  4. -
  5. Stabalize mental health.
  6. -
-

The engineer's security alert stress traumatized him with constant anxiety.

-

Value Add (Content)

-

The engineer navigated the lack-luster site map to identify hidden treasures. There were no treasures in these catacombs.

-

The engineer had a single article -- Hello World.

-

The wife stakeholders flogged the engineer for not producing content. An epic conflict ensued. Nearly fired, The engineer agreed to:

-
    -
  1. Document experiments.
  2. -
  3. Produce "regular" content.
  4. -
  5. Make lists.
  6. -
-

Stalking (Metrics)

-

The Google Analytics spies were able to provide decent intelligence.

-
    -
  • Number of visitors
  • -
  • Number of page views
  • -
  • Country of origin
  • -
  • Demographics
  • -
  • Behavior
  • -
-

The engineer knew relying on Google Analytics required JavaScript and could be unreliable. A trained engineer demanded more.

-
    -
  • Page Requests
  • -
  • A / B Tracking
  • -
  • Page Load Time
  • -
  • Users w/o JavaScript
  • -
  • Suspicious Behavior
  • -
  • Rate Limiting
  • -
  • Errors
  • -
-

The engineer wanted to track unexpected behavior. The engineer needed to use the scientific method to deliver valuable features to the clients stakeholders.

-

New features take time to implement. The engineer would deliver more in the coming sprints.

-

Heroic Engineering

-

The engineer has been in the industry for over a decade. If stakeholders identify feature loss, they will fire the engineer.

-

The stakeholders need assurances of the engineer's heroics.

-

The engineer created a list of functionality to keep the stakeholders out of his man cave.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FeatureDescription
FaviconBrowser/bookmark image.
NavigationPage links.
Social MediaContact links.
FooterPage's bottom. 😂
RSS FeedArticle subscription.
Site MapTreasure trove. 🤦
AnalyticsUsage statistics.
BlogArticle list. ⬇️
ArticleSemi-cohesive thoughts.
-

The engineer composed a fancy email to management stakeholders.

-
Hello Mr. Fancy Manager,
+ 
+
+

+ Goodbye Cruel World +

+ +
+

+ + JohnathanIrvin.com + + commits + + seppuku + + . Now an + + Isekai + + , the website is reborn. +

+

+ Nearly + + two forsaken years + + have passed since + + JohnathanIrvin.com + + received enhancements. The stagnant beast lacked honor. The creature of horror ignored the security bells. It cared not to provide value. Death was the only way to ensure + + reincarnation + + . +

+

+ Thrust forth the crisis of covid has sprung the + + need for software engineers + + . Elite + + hackers + + must rise to defeat the + + cybersecurity crisis + + . An onslaught of recruiter messages bombarded Johnathan's LinkedIn. The site knew the stakes were high. Little did we know how desperate the industry was for talented engineers. +

+

+ With a harness of experience, we set out to change the status quo. +

+

+ Table Of Contents +

+ +

+ Beautification Warning +

+

+ Blessed not with visual creativity, the engineer was not a designer. He was an engineer. +

+

+ The engineer had heard, "Your design skills are laughable." +

+

+ The engineer replied, "I'm not a designer. I'm an engineer." +

+

+ "I want my website to be beautiful." +

+

+ The engineer laughed, "I use frameworks like + + Bootstrap + + and + + Materialize + + ." +

+

+ + Minimalist + + + sycophants + + beware the following: +

+ +

+ Bravado Justification +

+

+ The + + readers + + stakeholders needed justification for the engineer's bravado. +

+

+ The engineer summoned a + + value proposition + + to justify the coming adventure. +

+

+ He championed + + three + + areas of value. +

+
    +
  1. + + Security + +
  2. +
  3. + + Content + +
  4. +
  5. + + Metrics + +
  6. +
+

+ Dumpster Fire (Security) +

+

+ Security issues plagued the repository. +

+

+ + Dependabot + + alerted the engineer daily. +

+

+ The engineer provided the + + hackers + + stakeholders with a truncated warrant list. +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ CVE + + Severity + + Description +
+ + CVE-2021-3803 + + + 7.5 High + + Inefficient Regular Expression Complexity +
+ + CVE-2021-23341 + + + 7.5 High + + Regular Expression Denial of Service (ReDoSI) +
+ + CVE-2022-0355 + + + 7.5 High + + Exposure of Sensitive Information +
+ + CVE-2020-7788 + + + 7.3 High + + Malicious INI file +
+

+ The + + rabbit hole + + had only begun. An issue inside of + + Node.js + + led to the rise of these little devils popping up multiple times in different dependencies. +

+

+ The + + hydra + + needed to stop. The engineer had not the time to learn how to stop the beast in its + + JavaScript + + landscape. The engineering effort would be better suited to + + Python + + . +

+

+ The engineer emphasized protective measures benefits. +

+
    +
  1. + Avoid litigation. +
  2. +
  3. + Protect information. +
  4. +
  5. + Stabalize mental health. +
  6. +
+

+ The engineer's security alert stress traumatized him with constant anxiety. +

+

+ Value Add (Content) +

+

+ The engineer navigated the lack-luster + + site map + + to identify hidden treasures. There were no treasures in these catacombs. +

+

+ The engineer had a single article -- + + Hello World. + +

+

+ The + + wife + + stakeholders flogged the engineer for not producing content. An epic conflict ensued. Nearly fired, The engineer agreed to: +

+
    +
  1. + Document experiments. +
  2. +
  3. + Produce "regular" content. +
  4. +
  5. + Make lists. +
  6. +
+

+ Stalking (Metrics) +

+

+ The + + Google Analytics + + spies were able to provide decent intelligence. +

+
    +
  • + Number of visitors +
  • +
  • + Number of page views +
  • +
  • + Country of origin +
  • +
  • + Demographics +
  • +
  • + Behavior +
  • +
+

+ The engineer knew relying on Google Analytics required JavaScript and could be unreliable. A trained engineer demanded more. +

+
    +
  • + Page Requests +
  • +
  • + A / B Tracking +
  • +
  • + Page Load Time +
  • +
  • + Users w/o JavaScript +
  • +
  • + Suspicious Behavior +
  • +
  • + Rate Limiting +
  • +
  • + Errors +
  • +
+

+ The engineer wanted to track unexpected behavior. The engineer needed to use the scientific method to deliver valuable features to the + + clients + + stakeholders. +

+

+ New features take time to implement. The engineer would deliver more in the coming sprints. +

+

+ Heroic Engineering +

+

+ The engineer has been in the industry for over a decade. If stakeholders identify feature loss, they will fire the engineer. +

+

+ The stakeholders need assurances of the engineer's heroics. +

+

+ The engineer created a list of functionality to keep the stakeholders out of his man cave. +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ Feature + + Description +
+ Favicon + + Browser/bookmark image. +
+ Navigation + + Page links. +
+ Social Media + + Contact links. +
+ Footer + + Page's bottom. 😂 +
+ RSS Feed + + Article subscription. +
+ Site Map + + Treasure trove. 🤦 +
+ Analytics + + Usage statistics. +
+ Blog + + Article list. ⬇️ +
+ Article + + Semi-cohesive thoughts. +
+

+ The engineer composed a fancy email to + + management + + stakeholders. +

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

Heroic Engineering

The engineer
-

The engineer's written proof reassured the boss stakeholders. The engineer took a break of thirty minutes to entertain the children stakeholders.

-

Language Swap

-

The engineer agonized with JavaScript to absorb the knowledge of Jamstack. The engineer cried nightly and lamented the loss of security. Harassed with notifications from Dependabot, security concerns forced the engineer to switch to Python.

-

The engineer drank Death Wish. He cracked his knuckles and readied for several long weeks of smashing keys and criticizing himself.

-

The engineer drooled over the thought of eventually adding PyScript. Not that this release would have it. Maybe next release.

-

The Python microframework, Flask, boasted simplicity and speed. The engineer was inspired to use it. Flask replaced a non-existent backend with a simple, fast, and secure web framework.

-

The engineer discovered Starlite. Sorely disappointed, he lamented the community for its constant change. The engineer pushed forward despite a lack of motivation.

-

Shorter Templates

-

Hypertext Markup Language (HTML) is a redundancy goblin. Goblins are to be slain with simplicity. The engineer called forth PugJS. The engineer began to double his productivity. Behold the goblin slaying power of PugJS:

- - - - - - - - - - - - - - - - - - - - - - - - - -
PugJSHTML
.p<p></p>
.h1<h1></h1>
article.p<article><p></p></article>
article#id1<article id="id1"></article>
-

The engineer required a rendering engine for Flask to be able to render the PugJS templates. The engineer discovered PyPugJs.

-

PyPugJS was implemented.

-

Borrowing Layout

-

The engineer stole borrowed the layout of the original website. The original code fruited a good base. Then with a little bit of creativity, the engineer stole borrowed more:

- - - - - - - - - - - - - - - - - - - - - -
Feature"Borrowed" From
HeaderBootStrap Headers
BodyOriginal Code
FooterBootStrap Footers
-

The engineer was ashamed of hard coded scalable vector graphics (SVGs). The engineer stole borrowed icons from bootstrap icons:

- -

Keeping Old Pages

-

The engineer journalist lazily wrote a a single article, 'Hello World'. The engineer was saddened by the lack of content. Yet, readers stakeholders were not to lose previous content. Previous content used article/<year>/<month>/<day>/<title> routes. Previous content kept this information in the front matter of the article.

-

The engineer did not know of the term "front matter". The engineer stole borrowed ideas from Gridsome's GitHub repository. Gridsome outsources its front matter parsing to Gray Matter. A similar library must exist for Python.

-

The engineer googled python front matter and discovered python-frontmatter. The engineer was now able to parse the front matter of the article and use that to deliver the content.

-

Other Changes

-

The journalist lived in the past. The journalist could no longer write for his sites, IGamePress and EnomView. The journalist died.

-

The tagline removed journalist.

-

The researcher was born bright-eyed. The researcher examined all details closely. Experiments performed were recorded.

-

The tagline added the researcher.

-

Next Sprint

-

The manager said "Enjoy the weekend! Next sprint will be here on Monday."

-

The engineer grunted and said "I'll be back on Monday!"

-
-
+

+ The engineer's written proof reassured the + + boss + + stakeholders. The engineer took a break of thirty minutes to entertain the + + children + + stakeholders. +

+

+ Language Swap +

+

+ The engineer agonized with + + JavaScript + + to absorb the knowledge of + + Jamstack + + . The engineer cried nightly and lamented the loss of security. Harassed with notifications from Dependabot, security concerns forced the engineer to switch to + + Python + + . +

+

+ The engineer drank + + Death Wish + + . He cracked his knuckles and readied for several long weeks of smashing keys and criticizing himself. +

+

+ The engineer drooled over the thought of eventually adding + + PyScript + + . Not that this release would have it. Maybe next release. +

+

+ The Python microframework, + + Flask + + , boasted simplicity and speed. The engineer was inspired to use it. Flask replaced a non-existent backend with a simple, fast, and secure web framework. +

+

+ The engineer discovered + + Starlite + + . Sorely disappointed, he lamented the community for its constant change. The engineer pushed forward despite a lack of motivation. +

+

+ Shorter Templates +

+

+ Hypertext Markup Language (HTML) is a redundancy goblin. Goblins are to be slain with simplicity. The engineer called forth + + PugJS + + . The engineer began to double his productivity. Behold the goblin slaying power of PugJS: +

+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ PugJS + + HTML +
+ + .p + + + + <p></p> + +
+ + .h1 + + + + <h1></h1> + +
+ + article.p + + + + <article><p></p></article> + +
+ + article#id1 + + + + <article id="id1"></article> + +
+

+ The engineer required a rendering engine for Flask to be able to render the PugJS templates. The engineer discovered + + PyPugJs + + . +

+

+ PyPugJS was implemented. +

+

+ Borrowing Layout +

+

+ The engineer + + stole + + borrowed + + the layout + + of the original website. + + The original code + + fruited a good base. Then with a little bit of creativity, the engineer + + stole + + borrowed more: +

+ + + + + + + + + + + + + + + + + + + + + +
+ Feature + + "Borrowed" From +
+ Header + + + BootStrap Headers + +
+ Body + + + Original Code + +
+ Footer + + + BootStrap Footers + +
+

+ The engineer was ashamed of + + hard coded scalable vector graphics + + ( + + SVGs + + ). The engineer + + stole + + borrowed icons from + + bootstrap icons + + : +

+ +

+ Keeping Old Pages +

+

+ The + + engineer + + journalist lazily wrote a a single article, + + 'Hello World' + + . The engineer was saddened by the lack of content. Yet, + + readers + + stakeholders were not to lose previous content. Previous content used + + article/<year>/<month>/<day>/<title> + + routes. Previous content kept this information in the + + front matter + + of the article. +

+

+ The engineer did not know of the term "front matter". The engineer + + stole + + borrowed ideas from + + Gridsome's GitHub repository + + . Gridsome outsources its front matter parsing to + + Gray Matter + + . A similar library must exist for Python. +

+

+ The engineer googled + + python front matter + + and discovered + + python-frontmatter + + . The engineer was now able to parse the front matter of the article and use that to deliver the content. +

+

+ Other Changes +

+

+ The journalist lived in the past. The journalist could no longer write for his sites, IGamePress and + + EnomView + + . The journalist died. +

+

+ The tagline removed journalist. +

+

+ The researcher was born bright-eyed. The researcher examined all details closely. Experiments performed were recorded. +

+

+ The tagline added the researcher. +

+

+ Next Sprint +

+

+ The manager said "Enjoy the weekend! Next sprint will be here on Monday." +

+

+ The engineer grunted and said "I'll be back on Monday!" +

+ + +
-
- - \ No newline at end of file +
+ diff --git a/tests/snapshots/hello-world.snapshot.html b/tests/snapshots/hello-world.snapshot.html index 0c25524..8bf03f5 100644 --- a/tests/snapshots/hello-world.snapshot.html +++ b/tests/snapshots/hello-world.snapshot.html @@ -1,76 +1,200 @@ - - - - - - - - - - - - - - - - - - -Hello World - Johnathan Irvin - - -
-
Johnathan Irvin - + + -
-

Hello World

- -

For many programmers, the first program they write in any given language is the "Hello World" program first found in A Tutorial Introduction to the Language B by Bell Laboratories. It seemed apt to label this article accordingly and incorporate "Hello World" into the content. As an homage to the history of programming, let's write this simple program.

-

Prerequisites

-

We will need a text editor. A text editor is a program that allows you to edit just the letters of a file without adding any additional information. This is not to be confused with Microsoft Word or a similar tool known as a Word Processor. We will ignore Word Processors and focus on text editors. You may use any simple text editor program; examples include Microsoft Notepad, Notepad++, Vim, and GNU Nano. I will use Vim. Installing and using your preferred text editor will not be explained in this article.

-

This example will be using the programming language Python. It is not required to know Python or have any prior programming experience to understand and create our first program. Writing your first program requires that you have your environment set up to run Python. To do so, follow the Beginners Guide on the Python wiki or follow the Python3 Installation and Setup Guide by Real Python. I recommend the latter.

-

First Program

-

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:

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

+ Hello World +

+ +
+

+ For many programmers, the first program they write in any given language is the "Hello World" program first found in + + + A Tutorial Introduction to the Language B by Bell Laboratories + + + . It seemed apt to label this article accordingly and incorporate "Hello World" into the content. As an homage to the history of programming, let's write this simple program. +

+

+ Prerequisites +

+

+ We will need a text editor. A text editor is a program that allows you to edit just the letters of a file without adding any additional information. This is not to be confused with Microsoft Word or a similar tool known as a Word Processor. We will ignore Word Processors and focus on text editors. You may use any simple text editor program; examples include + + Microsoft Notepad + + , + + Notepad++ + + , + + Vim + + , and + + GNU Nano + + . I will use Vim. Installing and using your preferred text editor will not be explained in this article. +

+

+ This example will be using the programming language + + Python + + . It is not required to know Python or have any prior programming experience to understand and create our first program. Writing your first program requires that you have your environment set up to run Python. To do so, follow the + + Beginners Guide + + on the Python wiki or follow the + + Python3 Installation and Setup Guide by Real Python + + . I recommend the latter. +

+

+ First Program +

+

+ 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 + + : +

+
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 Powershell in your search. On Ubuntu, you can press your corresponding key to open up the search and look for Terminal. One the application appears, click it to start the terminal application. One the terminal has started, type python hello_world.py and press enter. If all has gone well, you should see Hello World! appear in your terminal.

-

The following image will illustrate by using Vim, the text editor I mentioned before, to create a new file, save it, and then run our program using Python:

-

Animated image displaying "hello world"

-

Conclusion

-

We've barely scratched the surface of programming. Ask yourself a few of the following questions: What exactly is print? Can I change Hello World! to any text I'd like? Try changing Hello World! to Hello Johnny! and rerunning the program. What happened? Is there a way that I could have a different output time I run the program? While the Hello World! program ensures that our environment is set up correctly; it doesn't do much.

-

What's next? I recommend researching variables in Python.

-
-
+

+ 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 + + Powershell + + in your search. On Ubuntu, you can press your corresponding key to open up the search and look for + + Terminal + + . One the application appears, click it to start the terminal application. One the terminal has started, type + + python hello_world.py + + and press enter. If all has gone well, you should see + + Hello World! + + appear in your terminal. +

+

+ The following image will illustrate by using Vim, the text editor I mentioned before, to create a new file, save it, and then run our program using Python: +

+

+ Animated image displaying "hello world" +

+

+ Conclusion +

+

+ We've barely scratched the surface of programming. Ask yourself a few of the following questions: What exactly is + + print + + ? Can I change + + Hello World! + + to any text I'd like? Try changing + + Hello World! + + to + + Hello Johnny! + + and rerunning the program. What happened? Is there a way that I could have a different output time I run the program? While the + + Hello World! + + program ensures that our environment is set up correctly; it doesn't do much. +

+

+ What's next? I recommend researching variables in Python. +

+ + +
-
- - \ No newline at end of file +
+ diff --git a/tests/test_snapshots/test_articles.py b/tests/test_snapshots/test_articles.py index 76df163..ce39a83 100644 --- a/tests/test_snapshots/test_articles.py +++ b/tests/test_snapshots/test_articles.py @@ -18,6 +18,7 @@ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +import bs4 import pytest ARTICLE_SLUGS: list = [ @@ -47,7 +48,10 @@ def test_article_snapshots(article_slug: str, client, snapshot) -> None: snapshot (pytest_snapshot.plugin.Snapshot): The snapshot plugin. """ snapshot.snapshot_dir = "tests/snapshots" + html = client.get(f"/{article_slug}").text + soup = bs4.BeautifulSoup(html, "html.parser") + snapshot.assert_match( - client.get(f"/{article_slug}").text, + soup.body.prettify(), article_slug.split("/")[-1] + ".snapshot.html" ) diff --git a/website/__init__.py b/website/__init__.py index 0188f7a..7821437 100644 --- a/website/__init__.py +++ b/website/__init__.py @@ -19,6 +19,7 @@ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. import os +import random import flask import markdown @@ -164,6 +165,29 @@ def sitemap() -> str: return response +@app.route('/favicon') +@app.route('/favicon.ico') +def favicon() -> flask.Response: + """ + Returns a random favicon from the static -> favicons directory. + + Returns: + flask.Response: The image response. + """ + directory = os.path.join( + app.root_path, + 'static', + 'icons', + ) + images = os.listdir(directory) + image = random.choice(images) + + return flask.send_from_directory( + directory, + image, + filename='favicon.ico', + ) + with open('website/static/faq.md', 'r') as file: QUESTION_MARKDOWN = file.read() @app.route('/faq') diff --git a/website/static/favicon.ico b/website/static/favicon.ico deleted file mode 100644 index 6a66c11..0000000 Binary files a/website/static/favicon.ico and /dev/null differ diff --git a/website/static/favicon.jpg b/website/static/favicon.jpg deleted file mode 100644 index 7620a20..0000000 Binary files a/website/static/favicon.jpg and /dev/null differ diff --git a/website/static/icons/icon-1.ico b/website/static/icons/icon-1.ico new file mode 100644 index 0000000..53d6cf5 Binary files /dev/null and b/website/static/icons/icon-1.ico differ diff --git a/website/static/icons/icon-10.ico b/website/static/icons/icon-10.ico new file mode 100644 index 0000000..f15cfb6 Binary files /dev/null and b/website/static/icons/icon-10.ico differ diff --git a/website/static/icons/icon-11.ico b/website/static/icons/icon-11.ico new file mode 100644 index 0000000..c6f59fa Binary files /dev/null and b/website/static/icons/icon-11.ico differ diff --git a/website/static/icons/icon-12.ico b/website/static/icons/icon-12.ico new file mode 100644 index 0000000..c8c4fb1 Binary files /dev/null and b/website/static/icons/icon-12.ico differ diff --git a/website/static/icons/icon-13.ico b/website/static/icons/icon-13.ico new file mode 100644 index 0000000..30fc897 Binary files /dev/null and b/website/static/icons/icon-13.ico differ diff --git a/website/static/icons/icon-14.ico b/website/static/icons/icon-14.ico new file mode 100644 index 0000000..3e82660 Binary files /dev/null and b/website/static/icons/icon-14.ico differ diff --git a/website/static/icons/icon-15.ico b/website/static/icons/icon-15.ico new file mode 100644 index 0000000..c249e2f Binary files /dev/null and b/website/static/icons/icon-15.ico differ diff --git a/website/static/icons/icon-16.ico b/website/static/icons/icon-16.ico new file mode 100644 index 0000000..a31d52f Binary files /dev/null and b/website/static/icons/icon-16.ico differ diff --git a/website/static/icons/icon-17.ico b/website/static/icons/icon-17.ico new file mode 100644 index 0000000..71130ef Binary files /dev/null and b/website/static/icons/icon-17.ico differ diff --git a/website/static/icons/icon-18.ico b/website/static/icons/icon-18.ico new file mode 100644 index 0000000..3588ae9 Binary files /dev/null and b/website/static/icons/icon-18.ico differ diff --git a/website/static/icons/icon-19.ico b/website/static/icons/icon-19.ico new file mode 100644 index 0000000..eeb4af4 Binary files /dev/null and b/website/static/icons/icon-19.ico differ diff --git a/website/static/icons/icon-2.ico b/website/static/icons/icon-2.ico new file mode 100644 index 0000000..b4e1d1c Binary files /dev/null and b/website/static/icons/icon-2.ico differ diff --git a/website/static/icons/icon-20.ico b/website/static/icons/icon-20.ico new file mode 100644 index 0000000..6db7c1a Binary files /dev/null and b/website/static/icons/icon-20.ico differ diff --git a/website/static/icons/icon-21.ico b/website/static/icons/icon-21.ico new file mode 100644 index 0000000..9b359ab Binary files /dev/null and b/website/static/icons/icon-21.ico differ diff --git a/website/static/icons/icon-22.ico b/website/static/icons/icon-22.ico new file mode 100644 index 0000000..a3a998c Binary files /dev/null and b/website/static/icons/icon-22.ico differ diff --git a/website/static/icons/icon-23.ico b/website/static/icons/icon-23.ico new file mode 100644 index 0000000..5616645 Binary files /dev/null and b/website/static/icons/icon-23.ico differ diff --git a/website/static/icons/icon-24.ico b/website/static/icons/icon-24.ico new file mode 100644 index 0000000..5616645 Binary files /dev/null and b/website/static/icons/icon-24.ico differ diff --git a/website/static/icons/icon-25.ico b/website/static/icons/icon-25.ico new file mode 100644 index 0000000..d7e6d7e Binary files /dev/null and b/website/static/icons/icon-25.ico differ diff --git a/website/static/icons/icon-26.ico b/website/static/icons/icon-26.ico new file mode 100644 index 0000000..b4b3a13 Binary files /dev/null and b/website/static/icons/icon-26.ico differ diff --git a/website/static/icons/icon-27.ico b/website/static/icons/icon-27.ico new file mode 100644 index 0000000..7d71f1e Binary files /dev/null and b/website/static/icons/icon-27.ico differ diff --git a/website/static/icons/icon-28.ico b/website/static/icons/icon-28.ico new file mode 100644 index 0000000..96c3c3a Binary files /dev/null and b/website/static/icons/icon-28.ico differ diff --git a/website/static/icons/icon-29.ico b/website/static/icons/icon-29.ico new file mode 100644 index 0000000..19fab45 Binary files /dev/null and b/website/static/icons/icon-29.ico differ diff --git a/website/static/icons/icon-3.ico b/website/static/icons/icon-3.ico new file mode 100644 index 0000000..1cbcbed Binary files /dev/null and b/website/static/icons/icon-3.ico differ diff --git a/website/static/icons/icon-30.ico b/website/static/icons/icon-30.ico new file mode 100644 index 0000000..35f976f Binary files /dev/null and b/website/static/icons/icon-30.ico differ diff --git a/website/static/icons/icon-31.ico b/website/static/icons/icon-31.ico new file mode 100644 index 0000000..47cfcce Binary files /dev/null and b/website/static/icons/icon-31.ico differ diff --git a/website/static/icons/icon-32.ico b/website/static/icons/icon-32.ico new file mode 100644 index 0000000..1bde306 Binary files /dev/null and b/website/static/icons/icon-32.ico differ diff --git a/website/static/icons/icon-33.ico b/website/static/icons/icon-33.ico new file mode 100644 index 0000000..620332a Binary files /dev/null and b/website/static/icons/icon-33.ico differ diff --git a/website/static/icons/icon-34.ico b/website/static/icons/icon-34.ico new file mode 100644 index 0000000..16dbd4b Binary files /dev/null and b/website/static/icons/icon-34.ico differ diff --git a/website/static/icons/icon-35.ico b/website/static/icons/icon-35.ico new file mode 100644 index 0000000..966890c Binary files /dev/null and b/website/static/icons/icon-35.ico differ diff --git a/website/static/icons/icon-4.ico b/website/static/icons/icon-4.ico new file mode 100644 index 0000000..e2e34e5 Binary files /dev/null and b/website/static/icons/icon-4.ico differ diff --git a/website/static/icons/icon-5.ico b/website/static/icons/icon-5.ico new file mode 100644 index 0000000..8a021b2 Binary files /dev/null and b/website/static/icons/icon-5.ico differ diff --git a/website/static/icons/icon-6.ico b/website/static/icons/icon-6.ico new file mode 100644 index 0000000..35e8894 Binary files /dev/null and b/website/static/icons/icon-6.ico differ diff --git a/website/static/icons/icon-7.ico b/website/static/icons/icon-7.ico new file mode 100644 index 0000000..6c235de Binary files /dev/null and b/website/static/icons/icon-7.ico differ diff --git a/website/static/icons/icon-8.ico b/website/static/icons/icon-8.ico new file mode 100644 index 0000000..9c17c92 Binary files /dev/null and b/website/static/icons/icon-8.ico differ diff --git a/website/static/icons/icon-9.ico b/website/static/icons/icon-9.ico new file mode 100644 index 0000000..b81de82 Binary files /dev/null and b/website/static/icons/icon-9.ico differ diff --git a/website/templates/document.pug b/website/templates/document.pug index 75d11f5..2e1da7b 100644 --- a/website/templates/document.pug +++ b/website/templates/document.pug @@ -8,7 +8,7 @@ html meta(name="keywords", content="Vue,JavaScript,HTML,CSS,Python,VueJS,Bootstrap,C#,Engineer,Software,Coding,Development") meta(name="author", content="Johnathan Irvin") - link(rel="shortcut icon" href="{{ url_for('static', filename='favicon.ico') }}") + link(rel="shortcut icon" href="{{ url_for('favicon', ts=range(0, 10**10) | random) }}") link( href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.0-beta1/dist/css/bootstrap.min.css" rel="stylesheet"