diff --git a/blog.py b/blog.py new file mode 100644 index 0000000..d8fb8d4 --- /dev/null +++ b/blog.py @@ -0,0 +1,59 @@ +import os +from flask import render_template +from datetime import datetime +import markdown +from markdown.extensions.codehilite import CodeHiliteExtension +from markdown.extensions.fenced_code import FencedCodeExtension + + +def list_blog_page_files(): + blog_pages = os.listdir("data/blog") + # Remove .md extension + blog_pages = [page.removesuffix(".md") for page in blog_pages if page.endswith(".md")] + + return blog_pages + + +def render_blog_page(date,handshake_scripts=None): + # Convert md to html + if not os.path.exists(f"data/blog/{date}.md"): + return render_template("404.html"), 404 + + with open(f"data/blog/{date}.md", "r") as f: + content = f.read() + # Get the title from the file name + title = date.removesuffix(".md").replace("_", " ").title() + # Convert the md to html + content = markdown.markdown(content, extensions=['codehilite', 'fenced_code']) + # Add target="_blank" to all links + content = content.replace(' + {page.replace("_"," ")} + """ + for page in blog_pages + ] + # Join the list + blog_pages = "\n".join(blog_pages) + # Render the template + return render_template( + "blog/blog.html", + blogs=blog_pages, + handshake_scripts=handshake_scripts, + ) \ No newline at end of file diff --git a/data/blog/Fingertip_on_Linux_Mint.md b/data/blog/Fingertip_on_Linux_Mint.md new file mode 100644 index 0000000..3748564 --- /dev/null +++ b/data/blog/Fingertip_on_Linux_Mint.md @@ -0,0 +1,27 @@ +[View video tutorial](https://cloud.woodburn.au/s/n7Q3k7QyEnwygjX) + + +Install prerequisites: +```bash +sudo apt install libfuse2 libunbound-dev +``` + +Download latest release AppImage from SANE version of Fingertip: +[Fingertip Github Repo](https://github.com/randomlogin/fingertip) + +Make the AppImage executable: +```bash +chmod +x Fingertip-*.AppImage +``` +Run the AppImage: +```bash +./Fingertip-*.AppImage +``` + +You should see the fingertip notification icon in the system tray, right-click and select Options > Help. This should open a browser window with the Fingertip status page. +Go to the "Manual Setup" page, download the certificate and copy the proxy pac URL. + +Open the system settings > Network > Network Proxy. Set the Method to Automatic and paste in the URL. + +Next we need to import the certificate authority into your preferred browser. +You can usually just open the settings in the browser and search for "Certificates". Then import the certificate into the "Authorities" tab and make sure you select the option to trust it for identifying websites. \ No newline at end of file diff --git a/requirements.txt b/requirements.txt index 0210796..a862d58 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,14 +1,16 @@ -pydantic == 1.10.9 +pydantic flask Flask-Cors python-dotenv gunicorn requests -cloudflare == 3.1.1 +cloudflare qrcode Pillow ansi2html cachetools -solana == 0.34.2 -solders == 0.21.0 -weasyprint \ No newline at end of file +solana +solders +weasyprint +markdown +pygments \ No newline at end of file diff --git a/server.py b/server.py index 35c9f80..43577b7 100644 --- a/server.py +++ b/server.py @@ -25,7 +25,7 @@ from solders.keypair import Keypair from solders.pubkey import Pubkey from solana.rpc.api import Client from solders.system_program import TransferParams, transfer -from solana.transaction import Transaction +from solders.transaction import Transaction from solders.hash import Hash from solders.message import MessageV0 from solders.transaction import VersionedTransaction @@ -33,6 +33,7 @@ from solders.null_signer import NullSigner from PIL import Image from mail import sendEmail import now +import blog app = Flask(__name__) CORS(app) @@ -757,6 +758,69 @@ def now_json(): # endregion +# region blog Pages +@app.route("/blog") +@app.route("/blog/") +def blog_page(): + global handshake_scripts + + # If localhost, don't load handshake + if ( + request.host == "localhost:5000" + or request.host == "127.0.0.1:5000" + or os.getenv("dev") == "true" + or request.host == "test.nathan.woodburn.au" + ): + handshake_scripts = "" + + return blog.render_blog_home(handshake_scripts) + + +@app.route("/blog/") +def blog_path(path): + global handshake_scripts + # If localhost, don't load handshake + if ( + request.host == "localhost:5000" + or request.host == "127.0.0.1:5000" + or os.getenv("dev") == "true" + or request.host == "test.nathan.woodburn.au" + ): + handshake_scripts = "" + + return blog.render_blog_page(path,handshake_scripts) + +#TODO add rss json and xml for blog +# @app.route("/blog.rss") +# @app.route("/blog.xml") +# @app.route("/rss.xml") +# def blog_rss(): +# host = "https://" + request.host +# if ":" in request.host: +# host = "http://" + request.host +# # Generate RSS feed +# blog_pages = blog.list_blog_page_files() +# rss = f'Nathan.Woodburn/{host}See what I\'ve been up toen-us{datetime.datetime.blog(tz=datetime.timezone.utc).strftime("%a, %d %b %Y %H:%M:%S %z")}' +# for page in blog_pages: +# link = page.strip(".html") +# date = datetime.datetime.strptime(link, "%y_%m_%d") +# date = date.strftime("%A, %B %d, %Y") +# rss += f'What\'s Happening {date}{host}/blog/{link}Latest updates for {date}{host}/blog/{link}' +# rss += "" +# return make_response(rss, 200, {"Content-Type": "application/rss+xml"}) + +# @app.route("/blog.json") +# def blog_json(): +# blog_pages = blog.list_blog_page_files() +# host = "https://" + request.host +# if ":" in request.host: +# host = "http://" + request.host +# blog_pages = [{"url":host+"/blog/"+page.strip(".html"), "date":datetime.datetime.strptime(page.strip(".html"), "%y_%m_%d").strftime("%A, %B %d, %Y"), "title":"What's Happening "+datetime.datetime.strptime(page.strip(".html"), "%y_%m_%d").strftime("%A, %B %d, %Y")} for page in blog_pages] +# return jsonify(blog_pages) + +# endregion + + # region Donate @app.route("/donate") @@ -1122,4 +1186,4 @@ def not_found(e): # endregion if __name__ == "__main__": - app.run(debug=True, port=5000, host="0.0.0.0") + app.run(debug=True, port=5000, host="127.0.0.1") diff --git a/templates/assets/css/blog.min.css b/templates/assets/css/blog.min.css new file mode 100644 index 0000000..ba9f3a3 --- /dev/null +++ b/templates/assets/css/blog.min.css @@ -0,0 +1 @@ +p{margin:auto!important}pre{line-height:125%}span.linenos,td.linenos .normal{color:inherit;background-color:transparent;padding-left:5px;padding-right:5px}span.linenos.special,td.linenos .special{color:#000;background-color:#ffffc0;padding-left:5px;padding-right:5px}.codehilite .hll{background-color:#ffc}.codehilite{background:#f8f8f8;color:#333}.codehilite .c,.codehilite .c1,.codehilite .ch,.codehilite .cm,.codehilite .cpf,.codehilite .cs{color:#3d7b7b;font-style:italic}.codehilite .err{border:1px solid red}.codehilite .k,.codehilite .kc,.codehilite .kd,.codehilite .kn,.codehilite .kr,.codehilite .nt{color:green;font-weight:700}.codehilite .il,.codehilite .m,.codehilite .mb,.codehilite .mf,.codehilite .mh,.codehilite .mi,.codehilite .mo,.codehilite .o{color:#666}.codehilite .cp{color:#9c6500}.codehilite .gd{color:#a00000}.codehilite .ge{font-style:italic}.codehilite .ges{font-weight:700;font-style:italic}.codehilite .gr{color:#e40000}.codehilite .gh,.codehilite .gp{color:navy;font-weight:700}.codehilite .gi{color:#008400}.codehilite .go{color:#717171}.codehilite .gs{font-weight:700}.codehilite .gu{color:purple;font-weight:700}.codehilite .gt{color:#04d}.codehilite .bp,.codehilite .kp,.codehilite .nb,.codehilite .sx{color:green}.codehilite .kt{color:#b00040}.codehilite .dl,.codehilite .s,.codehilite .s1,.codehilite .s2,.codehilite .sa,.codehilite .sb,.codehilite .sc,.codehilite .sh{color:#ba2121}.codehilite .na{color:#687822}.codehilite .nc,.codehilite .nn{color:#00f;font-weight:700}.codehilite .no{color:#800}.codehilite .nd{color:#a2f}.codehilite .ni{color:#717171;font-weight:700}.codehilite .ne{color:#cb3f38;font-weight:700}.codehilite .fm,.codehilite .nf{color:#00f}.codehilite .nl{color:#767600}.codehilite .nv,.codehilite .ss,.codehilite .vc,.codehilite .vg,.codehilite .vi,.codehilite .vm{color:#19177c}.codehilite .ow{color:#a2f;font-weight:700}.codehilite .w{color:#bbb}.codehilite .sd{color:#ba2121;font-style:italic}.codehilite .se{color:#aa5d1f;font-weight:700}.codehilite .si{color:#a45a77;font-weight:700}.codehilite .sr{color:#a45a77} \ No newline at end of file diff --git a/templates/blog/blog.html b/templates/blog/blog.html new file mode 100644 index 0000000..d88924d --- /dev/null +++ b/templates/blog/blog.html @@ -0,0 +1,149 @@ + + + + + + + Blog | Nathan.Woodburn/ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {{handshake_scripts | safe}} +
+
+

Nathan.Woodburn/

+

BlogS

+
Check out my various blog posts below
+
+
+

{{blogs | safe}}

+
+
+
+
+
+
+ + +
+
+ + +
+
+
+
+ + + + + + + \ No newline at end of file diff --git a/templates/blog/template.html b/templates/blog/template.html new file mode 100644 index 0000000..da5290e --- /dev/null +++ b/templates/blog/template.html @@ -0,0 +1,147 @@ + + + + + + + Blog | Nathan.Woodburn/ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {{handshake_scripts | safe}} +
+
+

Nathan.Woodburn/

+

{{title}}

+
+
{{content | safe}}
+
+
+
+
+
+ + +
+
+ + +
+
+
+
+ + + + + + + \ No newline at end of file diff --git a/templates/sitemap.xml b/templates/sitemap.xml index 75d49ed..13eca2b 100644 --- a/templates/sitemap.xml +++ b/templates/sitemap.xml @@ -1,5 +1,8 @@ + + https://nathan.woodburn.au/blog/blog + https://nathan.woodburn.au/now/24_02_18