feat: Add initial ascii art for curl connections
This commit is contained in:
121
curl.py
Normal file
121
curl.py
Normal file
@@ -0,0 +1,121 @@
|
|||||||
|
from flask import render_template
|
||||||
|
from tools import error_response, getAddress
|
||||||
|
import os
|
||||||
|
from functools import lru_cache
|
||||||
|
import requests
|
||||||
|
|
||||||
|
|
||||||
|
def clean_path(path:str):
|
||||||
|
path = path.strip("/ ").lower()
|
||||||
|
# Strip any .html extension
|
||||||
|
if path.endswith(".html"):
|
||||||
|
path = path[:-5]
|
||||||
|
|
||||||
|
# If the path is empty, set it to "index"
|
||||||
|
if path == "":
|
||||||
|
path = "index"
|
||||||
|
return path
|
||||||
|
|
||||||
|
@lru_cache(maxsize=1)
|
||||||
|
def get_header():
|
||||||
|
with open("templates/header.ascii", "r") as f:
|
||||||
|
return f.read()
|
||||||
|
|
||||||
|
@lru_cache(maxsize=1)
|
||||||
|
def get_current_project():
|
||||||
|
git = requests.get(
|
||||||
|
"https://git.woodburn.au/api/v1/users/nathanwoodburn/activities/feeds?only-performed-by=true&limit=1",
|
||||||
|
headers={"Authorization": os.getenv("GIT_AUTH") if os.getenv("GIT_AUTH") else os.getenv("git_token")},
|
||||||
|
)
|
||||||
|
git = git.json()
|
||||||
|
git = git[0]
|
||||||
|
repo_name = git["repo"]["name"]
|
||||||
|
repo_name = repo_name.lower()
|
||||||
|
repo_description = git["repo"]["description"]
|
||||||
|
return f"[1m{repo_name}[0m - {repo_description}"
|
||||||
|
|
||||||
|
|
||||||
|
@lru_cache(maxsize=1)
|
||||||
|
def get_projects():
|
||||||
|
projectsreq = requests.get(
|
||||||
|
"https://git.woodburn.au/api/v1/users/nathanwoodburn/repos"
|
||||||
|
)
|
||||||
|
|
||||||
|
projects = projectsreq.json()
|
||||||
|
|
||||||
|
# Check for next page
|
||||||
|
pageNum = 1
|
||||||
|
while 'rel="next"' in projectsreq.headers["link"]:
|
||||||
|
projectsreq = requests.get(
|
||||||
|
"https://git.woodburn.au/api/v1/users/nathanwoodburn/repos?page="
|
||||||
|
+ str(pageNum)
|
||||||
|
)
|
||||||
|
projects += projectsreq.json()
|
||||||
|
pageNum += 1
|
||||||
|
|
||||||
|
# Sort by last updated
|
||||||
|
projectsList = sorted(
|
||||||
|
projects, key=lambda x: x["updated_at"], reverse=True)
|
||||||
|
projects = ""
|
||||||
|
projectNum = 0
|
||||||
|
includedNames = []
|
||||||
|
while len(includedNames) < 5 and projectNum < len(projectsList):
|
||||||
|
# Avoid duplicates
|
||||||
|
if projectsList[projectNum]["name"] in includedNames:
|
||||||
|
projectNum += 1
|
||||||
|
continue
|
||||||
|
includedNames.append(projectsList[projectNum]["name"])
|
||||||
|
project = projectsList[projectNum]
|
||||||
|
projects += f"""[1m{project['name']}[0m - {project['description'] if project['description'] else 'No description'}
|
||||||
|
{project['html_url']}
|
||||||
|
|
||||||
|
"""
|
||||||
|
projectNum += 1
|
||||||
|
|
||||||
|
return projects
|
||||||
|
|
||||||
|
def curl_response(request):
|
||||||
|
# Check if <path>.ascii exists
|
||||||
|
path = clean_path(request.path)
|
||||||
|
|
||||||
|
# Handle special cases
|
||||||
|
if path == "index":
|
||||||
|
# Get current project
|
||||||
|
return render_template("index.ascii",header=get_header(),repo=get_current_project()), 200, {'Content-Type': 'text/plain; charset=utf-8'}
|
||||||
|
if path == "projects":
|
||||||
|
# Get projects
|
||||||
|
return render_template("projects.ascii",header=get_header(),projects=get_projects()), 200, {'Content-Type': 'text/plain; charset=utf-8'}
|
||||||
|
|
||||||
|
if path == "donate":
|
||||||
|
# Get donation info
|
||||||
|
return render_template("donate.ascii",header=get_header(),
|
||||||
|
HNS=getAddress("HNS"), BTC=getAddress("BTC"),
|
||||||
|
SOL=getAddress("SOL"), ETH=getAddress("ETH")
|
||||||
|
), 200, {'Content-Type': 'text/plain; charset=utf-8'}
|
||||||
|
|
||||||
|
if path == "donate/more":
|
||||||
|
coinList = os.listdir(".well-known/wallets")
|
||||||
|
coinList = [file for file in coinList if file[0] != "."]
|
||||||
|
coinList.sort()
|
||||||
|
return render_template("donate_more.ascii",header=get_header(),
|
||||||
|
coins=coinList
|
||||||
|
), 200, {'Content-Type': 'text/plain; charset=utf-8'}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# For other donation pages, fall back to ascii if it exists
|
||||||
|
if path.startswith("donate/"):
|
||||||
|
coin = path.split("/")[1]
|
||||||
|
address = getAddress(coin)
|
||||||
|
if address != "":
|
||||||
|
return render_template("donate_coin.ascii",header=get_header(),coin=coin.upper(),address=address), 200, {'Content-Type': 'text/plain; charset=utf-8'}
|
||||||
|
|
||||||
|
|
||||||
|
if os.path.exists(f"templates/{path}.ascii"):
|
||||||
|
return render_template(f"{path}.ascii",header=get_header()), 200, {'Content-Type': 'text/plain; charset=utf-8'}
|
||||||
|
|
||||||
|
# Fallback to html if it exists
|
||||||
|
if os.path.exists(f"templates/{path}.html"):
|
||||||
|
return render_template(f"{path}.html")
|
||||||
|
|
||||||
|
return error_response(request)
|
||||||
19
server.py
19
server.py
@@ -25,7 +25,8 @@ from blueprints.wellknown import wk_bp
|
|||||||
from blueprints.api import api_bp
|
from blueprints.api import api_bp
|
||||||
from blueprints.podcast import podcast_bp
|
from blueprints.podcast import podcast_bp
|
||||||
from blueprints.acme import acme_bp
|
from blueprints.acme import acme_bp
|
||||||
from tools import isCurl, isCrawler, getAddress, getFilePath, error_response, getClientIP, json_response, getGitCommit, isDev, getHandshakeScript, get_tools_data
|
from tools import isCurl, isCrawler, getAddress, getFilePath, error_response, getClientIP, json_response, getHandshakeScript, get_tools_data
|
||||||
|
from curl import curl_response
|
||||||
|
|
||||||
app = Flask(__name__)
|
app = Flask(__name__)
|
||||||
CORS(app)
|
CORS(app)
|
||||||
@@ -242,14 +243,7 @@ def index():
|
|||||||
if request.args.get("load"):
|
if request.args.get("load"):
|
||||||
loaded = False
|
loaded = False
|
||||||
if isCurl(request):
|
if isCurl(request):
|
||||||
return jsonify(
|
return curl_response(request)
|
||||||
{
|
|
||||||
"message": "Welcome to Nathan.Woodburn/! This is a personal website. For more information, visit https://nathan.woodburn.au",
|
|
||||||
"ip": getClientIP(request),
|
|
||||||
"dev": isDev(request.host),
|
|
||||||
"version": getGitCommit()
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
if not loaded and not isCrawler(request):
|
if not loaded and not isCrawler(request):
|
||||||
# Set cookie
|
# Set cookie
|
||||||
@@ -401,6 +395,9 @@ def index():
|
|||||||
# region Donate
|
# region Donate
|
||||||
@app.route("/donate")
|
@app.route("/donate")
|
||||||
def donate():
|
def donate():
|
||||||
|
if isCurl(request):
|
||||||
|
return curl_response(request)
|
||||||
|
|
||||||
coinList = os.listdir(".well-known/wallets")
|
coinList = os.listdir(".well-known/wallets")
|
||||||
coinList = [file for file in coinList if file[0] != "."]
|
coinList = [file for file in coinList if file[0] != "."]
|
||||||
coinList.sort()
|
coinList.sort()
|
||||||
@@ -702,6 +699,10 @@ def catch_all(path: str):
|
|||||||
if path.lower().replace(".html", "") in RESTRICTED_ROUTES:
|
if path.lower().replace(".html", "") in RESTRICTED_ROUTES:
|
||||||
return error_response(request, message="Restricted route", code=403)
|
return error_response(request, message="Restricted route", code=403)
|
||||||
|
|
||||||
|
# If curl request, return curl response
|
||||||
|
if isCurl(request):
|
||||||
|
return curl_response(request)
|
||||||
|
|
||||||
if path in REDIRECT_ROUTES:
|
if path in REDIRECT_ROUTES:
|
||||||
return redirect(REDIRECT_ROUTES[path], code=302)
|
return redirect(REDIRECT_ROUTES[path], code=302)
|
||||||
|
|
||||||
|
|||||||
14
templates/contact.ascii
Normal file
14
templates/contact.ascii
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
{{header}}
|
||||||
|
[1;36m───────────────────────────────────────────────[0m
|
||||||
|
[1;36m CONTACT ME [0m
|
||||||
|
[1;36m────────────[0m
|
||||||
|
|
||||||
|
Here are my socials — I’m most active on Discord 💬
|
||||||
|
|
||||||
|
- Twitter: https://twitter.com/woodburn_nathan
|
||||||
|
- GitHub: https://github.com/Nathanwoodburn
|
||||||
|
- Email: mailto:about@nathan.woodburn.au
|
||||||
|
- Discord: https://l.woodburn.au/discord
|
||||||
|
- Mastodon: https://mastodon.woodburn.au/@nathanwoodburn
|
||||||
|
- YouTube: https://www.youtube.com/@nathanjwoodburn
|
||||||
|
|
||||||
25
templates/donate.ascii
Normal file
25
templates/donate.ascii
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
{{header}}
|
||||||
|
[1;36m───────────────────────────────────────────────[0m
|
||||||
|
[1;36m DONATE [0m
|
||||||
|
[1;36m────────[0m
|
||||||
|
|
||||||
|
If you’d like to support my work 💙
|
||||||
|
|
||||||
|
- PayPal: [https://paypal.me/nathanwoodburn]
|
||||||
|
- GitHub: [https://github.com/sponsors/Nathanwoodburn]
|
||||||
|
- Stripe: [https://donate.stripe.com/8wM6pv0VD08Xe408ww]
|
||||||
|
|
||||||
|
[1mHNS: nathan.woodburn[0m
|
||||||
|
[1m{{ HNS }}[0m
|
||||||
|
|
||||||
|
[1mBTC: thinbadger6@primal.net[0m
|
||||||
|
[1m{{ BTC }}[0m
|
||||||
|
|
||||||
|
[1mSOL: woodburn.sol[0m
|
||||||
|
[1m{{ SOL }}[0m
|
||||||
|
|
||||||
|
[1mETH: woodburn.au[0m
|
||||||
|
[1m{{ ETH }}[0m
|
||||||
|
|
||||||
|
More donation options → [/donate/more]
|
||||||
|
|
||||||
10
templates/donate_coin.ascii
Normal file
10
templates/donate_coin.ascii
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
{{header}}
|
||||||
|
[1;36m───────────────────────────────────────────────[0m
|
||||||
|
[1;36m DONATE [0m
|
||||||
|
[1;36m────────[0m
|
||||||
|
|
||||||
|
Here is my [1m{{ coin }}[0m address if you'd like to send a donation 💙
|
||||||
|
[1m{{ address }}[0m
|
||||||
|
|
||||||
|
Thank you for your support! 🙏
|
||||||
|
|
||||||
13
templates/donate_more.ascii
Normal file
13
templates/donate_more.ascii
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
{{header}}
|
||||||
|
[1;36m───────────────────────────────────────────────[0m
|
||||||
|
[1;36m DONATE [0m
|
||||||
|
[1;36m────────[0m
|
||||||
|
|
||||||
|
Here is a list of additional cryptocurrencies and donation methods 💙
|
||||||
|
For each coin below, you can get the address from [1m/donate/<coin>[0m
|
||||||
|
|
||||||
|
{% for coin in coins %}{% if loop.index0 % 4 == 0 and loop.index0 != 0 %}
|
||||||
|
{% endif %}[1m{{ coin }}[0m{% if not loop.last %}, {% endif %}{% endfor %}
|
||||||
|
|
||||||
|
Thank you for your support! 🙏
|
||||||
|
|
||||||
25
templates/favicon.ascii
Normal file
25
templates/favicon.ascii
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
▒▒▒ ▓▓▓
|
||||||
|
▒░░░░▒▓ ▓▓▓▓▓▓▓
|
||||||
|
▒░░░░░░▒▒▒▒ ▓▓▓▓▓▓▓▓▓▓▓
|
||||||
|
▒░░░░░▒▒▒▒▒▒▒ ▓▓▒▓▓▓▓▓▓▓▓▓▓
|
||||||
|
▒░░░▒▒▒▒▒▒▒▒▒ ▓▓▓▓▓▓▓▓▓▓▓▓▓
|
||||||
|
▒░░▒▒▒▒▒▒▒▒▒▒ ▓▓▓▓▓▓▓▓▓▓▓▓▓
|
||||||
|
▒▒▒▒▒▒▒▒▒▒▒▒▒ ▓▓▓▓▓▓▓▓▓▓▓▓▓
|
||||||
|
▒▒▒▒▒▒▒▒▒▒▒▒▒ ▒▒▒ ▒▓ ▓▓▓▓▓▓▓▓▓▓▓▓▓
|
||||||
|
▒▒▒▒▒▒▒▒▒▒▒▒▒ ▓▒▒▒▒ ▒▒▓▓ ▓▓▓▓▓▓▓▓▓▓▓▓▓
|
||||||
|
▒▒▒▒▒▒▒▒▒▒▒▒▒ ▓▒▒▒▒▒▒ ▒▒▒▒▓▓ ▓▓▓▓▓▓▓▓▓▓▓▓▓
|
||||||
|
▒▒▒▒▒▒▒▒▒▒▒▒▒ ▒▒▒▒▒▒▒▒ ▒▒▒▒▓▓▓ ▓▓▓▓▓▓▓▓▓▓▓▓▓
|
||||||
|
▒▒▒▒▒▒▒▒▒▒▒▒▒ ▓▒▒▒▒▒▒▒▒▒ ▒▒▒▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓▓▓▓
|
||||||
|
▒▒▒▒▒▒▒▒▒▒▒▒▒ ▓▒▒▒▒▒▒▒▒▒▒▒ ▒▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓▓▓▓
|
||||||
|
▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒ ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
|
||||||
|
▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒ ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
|
||||||
|
▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▓▓▓ ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
|
||||||
|
▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
|
||||||
|
▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
|
||||||
|
▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
|
||||||
|
▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
|
||||||
|
▓▒▒▒▒▒▒▒▒▒▒▒▒▒▒▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓█
|
||||||
|
▓▒▒▒▒▒▒▒▒▒▒▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
|
||||||
|
▓▓▒▒▒▒▓▓▓ ▓▓▓▓▓▓▓▓█
|
||||||
|
▓▓▓▓ ▓▓▓█
|
||||||
|
|
||||||
11
templates/header.ascii
Normal file
11
templates/header.ascii
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
[1;36m─────────────────────────────────────────────────────[0m
|
||||||
|
[1;36m . . , . . . .. / [0m
|
||||||
|
[1;36m |\ | _.-+-|_ _.._ | | _ _ _||_ . .._.._ / [0m
|
||||||
|
[1;36m | \|(_] | [ )(_][ ) * |/\|(_)(_)(_][_)(_|[ [ )/ [0m
|
||||||
|
[1;36m─────────────────────────────────────────────────────[0m
|
||||||
|
|
||||||
|
Home [/]
|
||||||
|
Contact [/contact]
|
||||||
|
Projects [/projects]
|
||||||
|
Donate [/donate]
|
||||||
|
|
||||||
28
templates/index.ascii
Normal file
28
templates/index.ascii
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
{{header}}
|
||||||
|
[1;36m───────────────────────────────────────────────[0m
|
||||||
|
[1;36m ABOUT ME [0m
|
||||||
|
[1;36m──────────[0m
|
||||||
|
|
||||||
|
Hi, I'm [1mNathan Woodburn[0m from Canberra, Australia.
|
||||||
|
I've been homeschooled through Year 12 and am now studying a
|
||||||
|
[1mBachelor of Computer Science[0m.
|
||||||
|
|
||||||
|
I love building random projects, so this site is always evolving.
|
||||||
|
I'm also one of the founders of [1;36mHandshake AU[0m [https://hns.au],
|
||||||
|
working to grow Handshake adoption across Australia.
|
||||||
|
|
||||||
|
I'm currently working on: {{ repo | safe }}
|
||||||
|
|
||||||
|
[1;36m───────────────────────────────────────────────[0m
|
||||||
|
[1;36m SKILLS [0m
|
||||||
|
[1;36m────────[0m
|
||||||
|
|
||||||
|
- Linux servers & CLI
|
||||||
|
- DNS, DNSSEC, and Trustless SSL
|
||||||
|
- NGINX web servers
|
||||||
|
- Programming:
|
||||||
|
- Python 3
|
||||||
|
- C#
|
||||||
|
- Java
|
||||||
|
- Bash
|
||||||
|
|
||||||
7
templates/projects.ascii
Normal file
7
templates/projects.ascii
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
{{header}}
|
||||||
|
[1;36m───────────────────────────────────────────────[0m
|
||||||
|
[1;36m RECENT PROJECTS [0m
|
||||||
|
[1;36m─────────────────[0m
|
||||||
|
|
||||||
|
{{projects}}
|
||||||
|
|
||||||
Reference in New Issue
Block a user