fix: Cleanup blueprint names and add tests
All checks were successful
Build Docker / BuildImage (push) Successful in 2m17s
All checks were successful
Build Docker / BuildImage (push) Successful in 2m17s
This commit is contained in:
@@ -7,7 +7,7 @@ acme_bp = Blueprint('acme', __name__)
|
|||||||
|
|
||||||
|
|
||||||
@acme_bp.route("/hnsdoh-acme", methods=["POST"])
|
@acme_bp.route("/hnsdoh-acme", methods=["POST"])
|
||||||
def acme_post():
|
def post():
|
||||||
# Get the TXT record from the request
|
# Get the TXT record from the request
|
||||||
if not request.is_json or not request.json:
|
if not request.is_json or not request.json:
|
||||||
return json_response(request, "415 Unsupported Media Type", 415)
|
return json_response(request, "415 Unsupported Media Type", 415)
|
||||||
|
|||||||
@@ -1,13 +1,16 @@
|
|||||||
from flask import Blueprint, request, jsonify, make_response
|
from flask import Blueprint, request, jsonify
|
||||||
import os
|
import os
|
||||||
import datetime
|
import datetime
|
||||||
import requests
|
import requests
|
||||||
from mail import sendEmail
|
from mail import sendEmail
|
||||||
from sol import create_transaction
|
|
||||||
from tools import getClientIP, getGitCommit, json_response
|
from tools import getClientIP, getGitCommit, json_response
|
||||||
|
from blueprints.sol import sol_bp
|
||||||
|
|
||||||
|
|
||||||
api_bp = Blueprint('api', __name__)
|
api_bp = Blueprint('api', __name__)
|
||||||
|
# Register solana blueprint
|
||||||
|
|
||||||
|
api_bp.register_blueprint(sol_bp)
|
||||||
|
|
||||||
NC_CONFIG = requests.get(
|
NC_CONFIG = requests.get(
|
||||||
"https://cloud.woodburn.au/s/4ToXgFe3TnnFcN7/download/website-conf.json"
|
"https://cloud.woodburn.au/s/4ToXgFe3TnnFcN7/download/website-conf.json"
|
||||||
@@ -19,7 +22,7 @@ if 'time-zone' not in NC_CONFIG:
|
|||||||
|
|
||||||
@api_bp.route("/")
|
@api_bp.route("/")
|
||||||
@api_bp.route("/help")
|
@api_bp.route("/help")
|
||||||
def help_get():
|
def help():
|
||||||
return jsonify({
|
return jsonify({
|
||||||
"message": "Welcome to Nathan.Woodburn/ API! This is a personal website. For more information, visit https://nathan.woodburn.au",
|
"message": "Welcome to Nathan.Woodburn/ API! This is a personal website. For more information, visit https://nathan.woodburn.au",
|
||||||
"endpoints": {
|
"endpoints": {
|
||||||
@@ -39,12 +42,12 @@ def help_get():
|
|||||||
|
|
||||||
|
|
||||||
@api_bp.route("/version")
|
@api_bp.route("/version")
|
||||||
def version_get():
|
def version():
|
||||||
return jsonify({"version": getGitCommit()})
|
return jsonify({"version": getGitCommit()})
|
||||||
|
|
||||||
|
|
||||||
@api_bp.route("/time")
|
@api_bp.route("/time")
|
||||||
def time_get():
|
def time():
|
||||||
timezone_offset = datetime.timedelta(hours=NC_CONFIG["time-zone"])
|
timezone_offset = datetime.timedelta(hours=NC_CONFIG["time-zone"])
|
||||||
timezone = datetime.timezone(offset=timezone_offset)
|
timezone = datetime.timezone(offset=timezone_offset)
|
||||||
time = datetime.datetime.now(tz=timezone)
|
time = datetime.datetime.now(tz=timezone)
|
||||||
@@ -59,7 +62,7 @@ def time_get():
|
|||||||
|
|
||||||
|
|
||||||
@api_bp.route("/timezone")
|
@api_bp.route("/timezone")
|
||||||
def timezone_get():
|
def timezone():
|
||||||
return jsonify({
|
return jsonify({
|
||||||
"timezone": NC_CONFIG["time-zone"],
|
"timezone": NC_CONFIG["time-zone"],
|
||||||
"ip": getClientIP(request),
|
"ip": getClientIP(request),
|
||||||
@@ -67,7 +70,7 @@ def timezone_get():
|
|||||||
})
|
})
|
||||||
|
|
||||||
@api_bp.route("/message")
|
@api_bp.route("/message")
|
||||||
def message_get():
|
def message():
|
||||||
return jsonify({
|
return jsonify({
|
||||||
"message": NC_CONFIG["message"],
|
"message": NC_CONFIG["message"],
|
||||||
"ip": getClientIP(request),
|
"ip": getClientIP(request),
|
||||||
@@ -76,7 +79,7 @@ def message_get():
|
|||||||
|
|
||||||
|
|
||||||
@api_bp.route("/ip")
|
@api_bp.route("/ip")
|
||||||
def ip_get():
|
def ip():
|
||||||
return jsonify({
|
return jsonify({
|
||||||
"ip": getClientIP(request),
|
"ip": getClientIP(request),
|
||||||
"status": 200
|
"status": 200
|
||||||
@@ -105,7 +108,7 @@ def email_post():
|
|||||||
|
|
||||||
|
|
||||||
@api_bp.route("/project")
|
@api_bp.route("/project")
|
||||||
def project_get():
|
def project():
|
||||||
gitinfo = {
|
gitinfo = {
|
||||||
"website": None,
|
"website": None,
|
||||||
}
|
}
|
||||||
@@ -135,83 +138,3 @@ def project_get():
|
|||||||
"ip": getClientIP(request),
|
"ip": getClientIP(request),
|
||||||
"status": 200
|
"status": 200
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
# region Solana Links
|
|
||||||
SOLANA_HEADERS = {
|
|
||||||
"Content-Type": "application/json",
|
|
||||||
"X-Action-Version": "2.4.2",
|
|
||||||
"X-Blockchain-Ids": "solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp"
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@api_bp.route("/donate", methods=["GET", "OPTIONS"])
|
|
||||||
def sol_donate_get():
|
|
||||||
data = {
|
|
||||||
"icon": "https://nathan.woodburn.au/assets/img/profile.png",
|
|
||||||
"label": "Donate to Nathan.Woodburn/",
|
|
||||||
"title": "Donate to Nathan.Woodburn/",
|
|
||||||
"description": "Student, developer, and crypto enthusiast",
|
|
||||||
"links": {
|
|
||||||
"actions": [
|
|
||||||
{"label": "0.01 SOL", "href": "/api/v1/donate/0.01"},
|
|
||||||
{"label": "0.1 SOL", "href": "/api/v1/donate/0.1"},
|
|
||||||
{"label": "1 SOL", "href": "/api/v1/donate/1"},
|
|
||||||
{
|
|
||||||
"href": "/api/v1/donate/{amount}",
|
|
||||||
"label": "Donate",
|
|
||||||
"parameters": [
|
|
||||||
{"name": "amount", "label": "Enter a custom SOL amount"}
|
|
||||||
],
|
|
||||||
},
|
|
||||||
]
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
response = make_response(jsonify(data), 200, SOLANA_HEADERS)
|
|
||||||
|
|
||||||
if request.method == "OPTIONS":
|
|
||||||
response.headers["Access-Control-Allow-Origin"] = "*"
|
|
||||||
response.headers["Access-Control-Allow-Methods"] = "GET, POST, PUT, OPTIONS"
|
|
||||||
response.headers["Access-Control-Allow-Headers"] = (
|
|
||||||
"Content-Type,Authorization,Content-Encoding,Accept-Encoding,X-Action-Version,X-Blockchain-Ids"
|
|
||||||
)
|
|
||||||
|
|
||||||
return response
|
|
||||||
|
|
||||||
|
|
||||||
@api_bp.route("/donate/<amount>")
|
|
||||||
def sol_donate_amount_get(amount):
|
|
||||||
data = {
|
|
||||||
"icon": "https://nathan.woodburn.au/assets/img/profile.png",
|
|
||||||
"label": f"Donate {amount} SOL to Nathan.Woodburn/",
|
|
||||||
"title": "Donate to Nathan.Woodburn/",
|
|
||||||
"description": f"Donate {amount} SOL to Nathan.Woodburn/",
|
|
||||||
}
|
|
||||||
return jsonify(data), 200, SOLANA_HEADERS
|
|
||||||
|
|
||||||
|
|
||||||
@api_bp.route("/donate/<amount>", methods=["POST"])
|
|
||||||
def sol_donate_post(amount):
|
|
||||||
|
|
||||||
if not request.json:
|
|
||||||
return jsonify({"message": "Error: No JSON data provided"}), 400, SOLANA_HEADERS
|
|
||||||
|
|
||||||
if "account" not in request.json:
|
|
||||||
return jsonify({"message": "Error: No account provided"}), 400, SOLANA_HEADERS
|
|
||||||
|
|
||||||
sender = request.json["account"]
|
|
||||||
|
|
||||||
# Make sure amount is a number
|
|
||||||
try:
|
|
||||||
amount = float(amount)
|
|
||||||
except ValueError:
|
|
||||||
amount = 1 # Default to 1 SOL if invalid
|
|
||||||
|
|
||||||
if amount < 0.0001:
|
|
||||||
return jsonify({"message": "Error: Amount too small"}), 400, SOLANA_HEADERS
|
|
||||||
|
|
||||||
transaction = create_transaction(sender, amount)
|
|
||||||
return jsonify({"message": "Success", "transaction": transaction}), 200, SOLANA_HEADERS
|
|
||||||
|
|
||||||
# endregion
|
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ from tools import isCurl, getClientIP
|
|||||||
blog_bp = Blueprint('blog', __name__)
|
blog_bp = Blueprint('blog', __name__)
|
||||||
|
|
||||||
|
|
||||||
def list_blog_page_files():
|
def list_page_files():
|
||||||
blog_pages = os.listdir("data/blog")
|
blog_pages = os.listdir("data/blog")
|
||||||
# Remove .md extension
|
# Remove .md extension
|
||||||
blog_pages = [page.removesuffix(".md")
|
blog_pages = [page.removesuffix(".md")
|
||||||
@@ -17,7 +17,7 @@ def list_blog_page_files():
|
|||||||
return blog_pages
|
return blog_pages
|
||||||
|
|
||||||
|
|
||||||
def render_blog_page(date, handshake_scripts=None):
|
def render_page(date, handshake_scripts=None):
|
||||||
# Convert md to html
|
# Convert md to html
|
||||||
if not os.path.exists(f"data/blog/{date}.md"):
|
if not os.path.exists(f"data/blog/{date}.md"):
|
||||||
return render_template("404.html"), 404
|
return render_template("404.html"), 404
|
||||||
@@ -83,9 +83,9 @@ def fix_numbered_lists(html):
|
|||||||
return str(soup)
|
return str(soup)
|
||||||
|
|
||||||
|
|
||||||
def render_blog_home(handshake_scripts=None):
|
def render_home(handshake_scripts=None):
|
||||||
# Get a list of pages
|
# Get a list of pages
|
||||||
blog_pages = list_blog_page_files()
|
blog_pages = list_page_files()
|
||||||
# Create a html list of pages
|
# Create a html list of pages
|
||||||
blog_pages = [
|
blog_pages = [
|
||||||
f"""<li class="list-group-item">
|
f"""<li class="list-group-item">
|
||||||
@@ -105,7 +105,7 @@ def render_blog_home(handshake_scripts=None):
|
|||||||
|
|
||||||
|
|
||||||
@blog_bp.route("/")
|
@blog_bp.route("/")
|
||||||
def blog_index_get():
|
def index():
|
||||||
if not isCurl(request):
|
if not isCurl(request):
|
||||||
global handshake_scripts
|
global handshake_scripts
|
||||||
|
|
||||||
@@ -117,10 +117,10 @@ def blog_index_get():
|
|||||||
or request.host == "test.nathan.woodburn.au"
|
or request.host == "test.nathan.woodburn.au"
|
||||||
):
|
):
|
||||||
handshake_scripts = ""
|
handshake_scripts = ""
|
||||||
return render_blog_home(handshake_scripts)
|
return render_home(handshake_scripts)
|
||||||
|
|
||||||
# Get a list of pages
|
# Get a list of pages
|
||||||
blog_pages = list_blog_page_files()
|
blog_pages = list_page_files()
|
||||||
# Create a html list of pages
|
# Create a html list of pages
|
||||||
blog_pages = [
|
blog_pages = [
|
||||||
{"name":page.replace("_", " "),"url":f"/blog/{page}", "download": f"/blog/{page}.md"} for page in blog_pages
|
{"name":page.replace("_", " "),"url":f"/blog/{page}", "download": f"/blog/{page}.md"} for page in blog_pages
|
||||||
@@ -138,7 +138,7 @@ def blog_index_get():
|
|||||||
|
|
||||||
|
|
||||||
@blog_bp.route("/<path:path>")
|
@blog_bp.route("/<path:path>")
|
||||||
def blog_path_get(path):
|
def path(path):
|
||||||
if not isCurl(request):
|
if not isCurl(request):
|
||||||
global handshake_scripts
|
global handshake_scripts
|
||||||
# If localhost, don't load handshake
|
# If localhost, don't load handshake
|
||||||
@@ -150,7 +150,7 @@ def blog_path_get(path):
|
|||||||
):
|
):
|
||||||
handshake_scripts = ""
|
handshake_scripts = ""
|
||||||
|
|
||||||
return render_blog_page(path, handshake_scripts)
|
return render_page(path, handshake_scripts)
|
||||||
|
|
||||||
# Convert md to html
|
# Convert md to html
|
||||||
if not os.path.exists(f"data/blog/{path}.md"):
|
if not os.path.exists(f"data/blog/{path}.md"):
|
||||||
@@ -170,7 +170,7 @@ def blog_path_get(path):
|
|||||||
}), 200
|
}), 200
|
||||||
|
|
||||||
@blog_bp.route("/<path:path>.md")
|
@blog_bp.route("/<path:path>.md")
|
||||||
def blog_path_md_get(path):
|
def path_md(path):
|
||||||
if not os.path.exists(f"data/blog/{path}.md"):
|
if not os.path.exists(f"data/blog/{path}.md"):
|
||||||
return render_template("404.html"), 404
|
return render_template("404.html"), 404
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import os
|
|||||||
# Create blueprint
|
# Create blueprint
|
||||||
now_bp = Blueprint('now', __name__)
|
now_bp = Blueprint('now', __name__)
|
||||||
|
|
||||||
def list_now_page_files():
|
def list_page_files():
|
||||||
now_pages = os.listdir("templates/now")
|
now_pages = os.listdir("templates/now")
|
||||||
now_pages = [
|
now_pages = [
|
||||||
page for page in now_pages if page != "template.html" and page != "old.html"
|
page for page in now_pages if page != "template.html" and page != "old.html"
|
||||||
@@ -13,31 +13,31 @@ def list_now_page_files():
|
|||||||
now_pages.sort(reverse=True)
|
now_pages.sort(reverse=True)
|
||||||
return now_pages
|
return now_pages
|
||||||
|
|
||||||
def list_now_dates():
|
def list_dates():
|
||||||
now_pages = list_now_page_files()
|
now_pages = list_page_files()
|
||||||
now_dates = [page.split(".")[0] for page in now_pages]
|
now_dates = [page.split(".")[0] for page in now_pages]
|
||||||
return now_dates
|
return now_dates
|
||||||
|
|
||||||
def get_latest_now_date(formatted=False):
|
def get_latest_date(formatted=False):
|
||||||
if formatted:
|
if formatted:
|
||||||
date=list_now_dates()[0]
|
date=list_dates()[0]
|
||||||
date = datetime.datetime.strptime(date, "%y_%m_%d")
|
date = datetime.datetime.strptime(date, "%y_%m_%d")
|
||||||
date = date.strftime("%A, %B %d, %Y")
|
date = date.strftime("%A, %B %d, %Y")
|
||||||
return date
|
return date
|
||||||
return list_now_dates()[0]
|
return list_dates()[0]
|
||||||
|
|
||||||
def render_latest_now(handshake_scripts=None):
|
def render_latest(handshake_scripts=None):
|
||||||
now_page = list_now_dates()[0]
|
now_page = list_dates()[0]
|
||||||
return render_now_page(now_page,handshake_scripts=handshake_scripts)
|
return render(now_page,handshake_scripts=handshake_scripts)
|
||||||
|
|
||||||
def render_now_page(date,handshake_scripts=None):
|
def render(date,handshake_scripts=None):
|
||||||
# If the date is not available, render the latest page
|
# If the date is not available, render the latest page
|
||||||
if date is None:
|
if date is None:
|
||||||
return render_latest_now(handshake_scripts=handshake_scripts)
|
return render_latest(handshake_scripts=handshake_scripts)
|
||||||
# Remove .html
|
# Remove .html
|
||||||
date = date.removesuffix(".html")
|
date = date.removesuffix(".html")
|
||||||
|
|
||||||
if date not in list_now_dates():
|
if date not in list_dates():
|
||||||
return render_template("404.html"), 404
|
return render_template("404.html"), 404
|
||||||
|
|
||||||
|
|
||||||
@@ -46,7 +46,7 @@ def render_now_page(date,handshake_scripts=None):
|
|||||||
return render_template(f"now/{date}.html",DATE=date_formatted,handshake_scripts=handshake_scripts)
|
return render_template(f"now/{date}.html",DATE=date_formatted,handshake_scripts=handshake_scripts)
|
||||||
|
|
||||||
@now_bp.route("/")
|
@now_bp.route("/")
|
||||||
def now_index_get():
|
def index():
|
||||||
handshake_scripts = ''
|
handshake_scripts = ''
|
||||||
# If localhost, don't load handshake
|
# If localhost, don't load handshake
|
||||||
if (
|
if (
|
||||||
@@ -59,11 +59,11 @@ def now_index_get():
|
|||||||
else:
|
else:
|
||||||
handshake_scripts = '<script src="https://nathan.woodburn/handshake.js" domain="nathan.woodburn" async></script><script src="https://nathan.woodburn/https.js" async></script>'
|
handshake_scripts = '<script src="https://nathan.woodburn/handshake.js" domain="nathan.woodburn" async></script><script src="https://nathan.woodburn/https.js" async></script>'
|
||||||
|
|
||||||
return render_latest_now(handshake_scripts)
|
return render_latest(handshake_scripts)
|
||||||
|
|
||||||
|
|
||||||
@now_bp.route("/<path:path>")
|
@now_bp.route("/<path:path>")
|
||||||
def now_path_get(path):
|
def path(path):
|
||||||
handshake_scripts = ''
|
handshake_scripts = ''
|
||||||
# If localhost, don't load handshake
|
# If localhost, don't load handshake
|
||||||
if (
|
if (
|
||||||
@@ -76,12 +76,12 @@ def now_path_get(path):
|
|||||||
else:
|
else:
|
||||||
handshake_scripts = '<script src="https://nathan.woodburn/handshake.js" domain="nathan.woodburn" async></script><script src="https://nathan.woodburn/https.js" async></script>'
|
handshake_scripts = '<script src="https://nathan.woodburn/handshake.js" domain="nathan.woodburn" async></script><script src="https://nathan.woodburn/https.js" async></script>'
|
||||||
|
|
||||||
return render_now_page(path, handshake_scripts)
|
return render(path, handshake_scripts)
|
||||||
|
|
||||||
|
|
||||||
@now_bp.route("/old")
|
@now_bp.route("/old")
|
||||||
@now_bp.route("/old/")
|
@now_bp.route("/old/")
|
||||||
def now_old_get():
|
def old():
|
||||||
handshake_scripts = ''
|
handshake_scripts = ''
|
||||||
# If localhost, don't load handshake
|
# If localhost, don't load handshake
|
||||||
if (
|
if (
|
||||||
@@ -94,9 +94,9 @@ def now_old_get():
|
|||||||
else:
|
else:
|
||||||
handshake_scripts = '<script src="https://nathan.woodburn/handshake.js" domain="nathan.woodburn" async></script><script src="https://nathan.woodburn/https.js" async></script>'
|
handshake_scripts = '<script src="https://nathan.woodburn/handshake.js" domain="nathan.woodburn" async></script><script src="https://nathan.woodburn/https.js" async></script>'
|
||||||
|
|
||||||
now_dates = list_now_dates()[1:]
|
now_dates = list_dates()[1:]
|
||||||
html = '<ul class="list-group">'
|
html = '<ul class="list-group">'
|
||||||
html += f'<a style="text-decoration:none;" href="/now"><li class="list-group-item" style="background-color:#000000;color:#ffffff;">{get_latest_now_date(True)}</li></a>'
|
html += f'<a style="text-decoration:none;" href="/now"><li class="list-group-item" style="background-color:#000000;color:#ffffff;">{get_latest_date(True)}</li></a>'
|
||||||
|
|
||||||
for date in now_dates:
|
for date in now_dates:
|
||||||
link = date
|
link = date
|
||||||
@@ -113,12 +113,12 @@ def now_old_get():
|
|||||||
@now_bp.route("/now.rss")
|
@now_bp.route("/now.rss")
|
||||||
@now_bp.route("/now.xml")
|
@now_bp.route("/now.xml")
|
||||||
@now_bp.route("/rss.xml")
|
@now_bp.route("/rss.xml")
|
||||||
def now_rss_get():
|
def rss():
|
||||||
host = "https://" + request.host
|
host = "https://" + request.host
|
||||||
if ":" in request.host:
|
if ":" in request.host:
|
||||||
host = "http://" + request.host
|
host = "http://" + request.host
|
||||||
# Generate RSS feed
|
# Generate RSS feed
|
||||||
now_pages = list_now_page_files()
|
now_pages = list_page_files()
|
||||||
rss = f'<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Nathan.Woodburn/</title><link>{host}</link><description>See what I\'ve been up to</description><language>en-us</language><lastBuildDate>{datetime.datetime.now(tz=datetime.timezone.utc).strftime("%a, %d %b %Y %H:%M:%S %z")}</lastBuildDate><atom:link href="{host}/now.rss" rel="self" type="application/rss+xml" />'
|
rss = f'<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Nathan.Woodburn/</title><link>{host}</link><description>See what I\'ve been up to</description><language>en-us</language><lastBuildDate>{datetime.datetime.now(tz=datetime.timezone.utc).strftime("%a, %d %b %Y %H:%M:%S %z")}</lastBuildDate><atom:link href="{host}/now.rss" rel="self" type="application/rss+xml" />'
|
||||||
for page in now_pages:
|
for page in now_pages:
|
||||||
link = page.strip(".html")
|
link = page.strip(".html")
|
||||||
@@ -130,8 +130,8 @@ def now_rss_get():
|
|||||||
|
|
||||||
|
|
||||||
@now_bp.route("/now.json")
|
@now_bp.route("/now.json")
|
||||||
def now_json_get():
|
def json():
|
||||||
now_pages = list_now_page_files()
|
now_pages = list_page_files()
|
||||||
host = "https://" + request.host
|
host = "https://" + request.host
|
||||||
if ":" in request.host:
|
if ":" in request.host:
|
||||||
host = "http://" + request.host
|
host = "http://" + request.host
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import requests
|
|||||||
podcast_bp = Blueprint('podcast', __name__)
|
podcast_bp = Blueprint('podcast', __name__)
|
||||||
|
|
||||||
@podcast_bp.route("/ID1")
|
@podcast_bp.route("/ID1")
|
||||||
def podcast_index_get():
|
def index():
|
||||||
# Proxy to ID1 url
|
# Proxy to ID1 url
|
||||||
req = requests.get("https://podcasts.c.woodburn.au/ID1")
|
req = requests.get("https://podcasts.c.woodburn.au/ID1")
|
||||||
if req.status_code != 200:
|
if req.status_code != 200:
|
||||||
@@ -17,7 +17,7 @@ def podcast_index_get():
|
|||||||
|
|
||||||
|
|
||||||
@podcast_bp.route("/ID1/")
|
@podcast_bp.route("/ID1/")
|
||||||
def podcast_contents_get():
|
def contents():
|
||||||
# Proxy to ID1 url
|
# Proxy to ID1 url
|
||||||
req = requests.get("https://podcasts.c.woodburn.au/ID1/")
|
req = requests.get("https://podcasts.c.woodburn.au/ID1/")
|
||||||
if req.status_code != 200:
|
if req.status_code != 200:
|
||||||
@@ -28,7 +28,7 @@ def podcast_contents_get():
|
|||||||
|
|
||||||
|
|
||||||
@podcast_bp.route("/ID1/<path:path>")
|
@podcast_bp.route("/ID1/<path:path>")
|
||||||
def podcast_path_get(path):
|
def path(path):
|
||||||
# Proxy to ID1 url
|
# Proxy to ID1 url
|
||||||
req = requests.get("https://podcasts.c.woodburn.au/ID1/" + path)
|
req = requests.get("https://podcasts.c.woodburn.au/ID1/" + path)
|
||||||
if req.status_code != 200:
|
if req.status_code != 200:
|
||||||
@@ -39,7 +39,7 @@ def podcast_path_get(path):
|
|||||||
|
|
||||||
|
|
||||||
@podcast_bp.route("/ID1.xml")
|
@podcast_bp.route("/ID1.xml")
|
||||||
def podcast_xml_get():
|
def xml():
|
||||||
# Proxy to ID1 url
|
# Proxy to ID1 url
|
||||||
req = requests.get("https://podcasts.c.woodburn.au/ID1.xml")
|
req = requests.get("https://podcasts.c.woodburn.au/ID1.xml")
|
||||||
if req.status_code != 200:
|
if req.status_code != 200:
|
||||||
@@ -50,7 +50,7 @@ def podcast_xml_get():
|
|||||||
|
|
||||||
|
|
||||||
@podcast_bp.route("/podsync.opml")
|
@podcast_bp.route("/podsync.opml")
|
||||||
def podcast_podsync_get():
|
def podsync():
|
||||||
req = requests.get("https://podcasts.c.woodburn.au/podsync.opml")
|
req = requests.get("https://podcasts.c.woodburn.au/podsync.opml")
|
||||||
if req.status_code != 200:
|
if req.status_code != 200:
|
||||||
return error_response(request, "Error from Podcast Server", req.status_code)
|
return error_response(request, "Error from Podcast Server", req.status_code)
|
||||||
|
|||||||
125
blueprints/sol.py
Normal file
125
blueprints/sol.py
Normal file
@@ -0,0 +1,125 @@
|
|||||||
|
from flask import Blueprint, request, jsonify, make_response
|
||||||
|
from solders.pubkey import Pubkey
|
||||||
|
from solana.rpc.api import Client
|
||||||
|
from solders.system_program import TransferParams, transfer
|
||||||
|
from solders.message import MessageV0
|
||||||
|
from solders.transaction import VersionedTransaction
|
||||||
|
from solders.null_signer import NullSigner
|
||||||
|
import binascii
|
||||||
|
import base64
|
||||||
|
import os
|
||||||
|
|
||||||
|
sol_bp = Blueprint('sol', __name__)
|
||||||
|
|
||||||
|
SOLANA_HEADERS = {
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
"X-Action-Version": "2.4.2",
|
||||||
|
"X-Blockchain-Ids": "solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp"
|
||||||
|
}
|
||||||
|
|
||||||
|
SOLANA_ADDRESS = None
|
||||||
|
if os.path.isfile(".well-known/wallets/SOL"):
|
||||||
|
with open(".well-known/wallets/SOL") as file:
|
||||||
|
address = file.read()
|
||||||
|
SOLANA_ADDRESS = Pubkey.from_string(address.strip())
|
||||||
|
|
||||||
|
def create_transaction(sender_address: str, amount: float) -> str:
|
||||||
|
if SOLANA_ADDRESS is None:
|
||||||
|
raise ValueError("SOLANA_ADDRESS is not set. Please ensure the .well-known/wallets/SOL file exists and contains a valid address.")
|
||||||
|
# Create transaction
|
||||||
|
sender = Pubkey.from_string(sender_address)
|
||||||
|
transfer_ix = transfer(
|
||||||
|
TransferParams(
|
||||||
|
from_pubkey=sender, to_pubkey=SOLANA_ADDRESS, lamports=int(
|
||||||
|
amount * 1000000000)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
solana_client = Client("https://api.mainnet-beta.solana.com")
|
||||||
|
blockhashData = solana_client.get_latest_blockhash()
|
||||||
|
blockhash = blockhashData.value.blockhash
|
||||||
|
|
||||||
|
msg = MessageV0.try_compile(
|
||||||
|
payer=sender,
|
||||||
|
instructions=[transfer_ix],
|
||||||
|
address_lookup_table_accounts=[],
|
||||||
|
recent_blockhash=blockhash,
|
||||||
|
)
|
||||||
|
tx = VersionedTransaction(message=msg, keypairs=[NullSigner(sender)])
|
||||||
|
tx = bytes(tx).hex()
|
||||||
|
raw_bytes = binascii.unhexlify(tx)
|
||||||
|
base64_string = base64.b64encode(raw_bytes).decode("utf-8")
|
||||||
|
return base64_string
|
||||||
|
|
||||||
|
def get_solana_address() -> str:
|
||||||
|
if SOLANA_ADDRESS is None:
|
||||||
|
raise ValueError("SOLANA_ADDRESS is not set. Please ensure the .well-known/wallets/SOL file exists and contains a valid address.")
|
||||||
|
return str(SOLANA_ADDRESS)
|
||||||
|
|
||||||
|
@sol_bp.route("/donate", methods=["GET", "OPTIONS"])
|
||||||
|
def sol_donate():
|
||||||
|
data = {
|
||||||
|
"icon": "https://nathan.woodburn.au/assets/img/profile.png",
|
||||||
|
"label": "Donate to Nathan.Woodburn/",
|
||||||
|
"title": "Donate to Nathan.Woodburn/",
|
||||||
|
"description": "Student, developer, and crypto enthusiast",
|
||||||
|
"links": {
|
||||||
|
"actions": [
|
||||||
|
{"label": "0.01 SOL", "href": "/api/v1/donate/0.01"},
|
||||||
|
{"label": "0.1 SOL", "href": "/api/v1/donate/0.1"},
|
||||||
|
{"label": "1 SOL", "href": "/api/v1/donate/1"},
|
||||||
|
{
|
||||||
|
"href": "/api/v1/donate/{amount}",
|
||||||
|
"label": "Donate",
|
||||||
|
"parameters": [
|
||||||
|
{"name": "amount", "label": "Enter a custom SOL amount"}
|
||||||
|
],
|
||||||
|
},
|
||||||
|
]
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
response = make_response(jsonify(data), 200, SOLANA_HEADERS)
|
||||||
|
|
||||||
|
if request.method == "OPTIONS":
|
||||||
|
response.headers["Access-Control-Allow-Origin"] = "*"
|
||||||
|
response.headers["Access-Control-Allow-Methods"] = "GET, POST, PUT, OPTIONS"
|
||||||
|
response.headers["Access-Control-Allow-Headers"] = (
|
||||||
|
"Content-Type,Authorization,Content-Encoding,Accept-Encoding,X-Action-Version,X-Blockchain-Ids"
|
||||||
|
)
|
||||||
|
|
||||||
|
return response
|
||||||
|
|
||||||
|
|
||||||
|
@sol_bp.route("/donate/<amount>")
|
||||||
|
def sol_donate_amount(amount):
|
||||||
|
data = {
|
||||||
|
"icon": "https://nathan.woodburn.au/assets/img/profile.png",
|
||||||
|
"label": f"Donate {amount} SOL to Nathan.Woodburn/",
|
||||||
|
"title": "Donate to Nathan.Woodburn/",
|
||||||
|
"description": f"Donate {amount} SOL to Nathan.Woodburn/",
|
||||||
|
}
|
||||||
|
return jsonify(data), 200, SOLANA_HEADERS
|
||||||
|
|
||||||
|
|
||||||
|
@sol_bp.route("/donate/<amount>", methods=["POST"])
|
||||||
|
def sol_donate_post(amount):
|
||||||
|
|
||||||
|
if not request.json:
|
||||||
|
return jsonify({"message": "Error: No JSON data provided"}), 400, SOLANA_HEADERS
|
||||||
|
|
||||||
|
if "account" not in request.json:
|
||||||
|
return jsonify({"message": "Error: No account provided"}), 400, SOLANA_HEADERS
|
||||||
|
|
||||||
|
sender = request.json["account"]
|
||||||
|
|
||||||
|
# Make sure amount is a number
|
||||||
|
try:
|
||||||
|
amount = float(amount)
|
||||||
|
except ValueError:
|
||||||
|
amount = 1 # Default to 1 SOL if invalid
|
||||||
|
|
||||||
|
if amount < 0.0001:
|
||||||
|
return jsonify({"message": "Error: Amount too small"}), 400, SOLANA_HEADERS
|
||||||
|
|
||||||
|
transaction = create_transaction(sender, amount)
|
||||||
|
return jsonify({"message": "Success", "transaction": transaction}), 200, SOLANA_HEADERS
|
||||||
@@ -5,12 +5,12 @@ wk_bp = Blueprint('well-known', __name__)
|
|||||||
|
|
||||||
|
|
||||||
@wk_bp.route("/<path:path>")
|
@wk_bp.route("/<path:path>")
|
||||||
def wk_index_get(path):
|
def index(path):
|
||||||
return send_from_directory(".well-known", path)
|
return send_from_directory(".well-known", path)
|
||||||
|
|
||||||
|
|
||||||
@wk_bp.route("/wallets/<path:path>")
|
@wk_bp.route("/wallets/<path:path>")
|
||||||
def wk_wallet_get(path):
|
def wallets(path):
|
||||||
if path[0] == "." and 'proof' not in path:
|
if path[0] == "." and 'proof' not in path:
|
||||||
return send_from_directory(
|
return send_from_directory(
|
||||||
".well-known/wallets", path, mimetype="application/json"
|
".well-known/wallets", path, mimetype="application/json"
|
||||||
@@ -29,7 +29,7 @@ def wk_wallet_get(path):
|
|||||||
|
|
||||||
|
|
||||||
@wk_bp.route("/nostr.json")
|
@wk_bp.route("/nostr.json")
|
||||||
def wk_nostr_get():
|
def nostr():
|
||||||
# Get name parameter
|
# Get name parameter
|
||||||
name = request.args.get("name")
|
name = request.args.get("name")
|
||||||
if name:
|
if name:
|
||||||
@@ -51,7 +51,7 @@ def wk_nostr_get():
|
|||||||
|
|
||||||
|
|
||||||
@wk_bp.route("/xrp-ledger.toml")
|
@wk_bp.route("/xrp-ledger.toml")
|
||||||
def wk_xrp_get():
|
def xrp():
|
||||||
# Create a response with the xrp-ledger.toml file
|
# Create a response with the xrp-ledger.toml file
|
||||||
with open(".well-known/xrp-ledger.toml") as file:
|
with open(".well-known/xrp-ledger.toml") as file:
|
||||||
toml = file.read()
|
toml = file.read()
|
||||||
|
|||||||
36
server.py
36
server.py
@@ -81,7 +81,7 @@ NC_CONFIG = requests.get(
|
|||||||
|
|
||||||
|
|
||||||
@app.route("/assets/<path:path>")
|
@app.route("/assets/<path:path>")
|
||||||
def asset_get(path):
|
def asset(path):
|
||||||
if path.endswith(".json"):
|
if path.endswith(".json"):
|
||||||
return send_from_directory(
|
return send_from_directory(
|
||||||
"templates/assets", path, mimetype="application/json"
|
"templates/assets", path, mimetype="application/json"
|
||||||
@@ -121,7 +121,7 @@ def asset_get(path):
|
|||||||
|
|
||||||
@app.route("/sitemap")
|
@app.route("/sitemap")
|
||||||
@app.route("/sitemap.xml")
|
@app.route("/sitemap.xml")
|
||||||
def sitemap_get():
|
def sitemap():
|
||||||
# Remove all .html from sitemap
|
# Remove all .html from sitemap
|
||||||
if not os.path.isfile("templates/sitemap.xml"):
|
if not os.path.isfile("templates/sitemap.xml"):
|
||||||
return error_response(request)
|
return error_response(request)
|
||||||
@@ -133,14 +133,14 @@ def sitemap_get():
|
|||||||
|
|
||||||
|
|
||||||
@app.route("/favicon.<ext>")
|
@app.route("/favicon.<ext>")
|
||||||
def favicon_get(ext):
|
def favicon(ext):
|
||||||
if ext not in ("png", "svg", "ico"):
|
if ext not in ("png", "svg", "ico"):
|
||||||
return error_response(request)
|
return error_response(request)
|
||||||
return send_from_directory("templates/assets/img/favicon", f"favicon.{ext}")
|
return send_from_directory("templates/assets/img/favicon", f"favicon.{ext}")
|
||||||
|
|
||||||
|
|
||||||
@app.route("/<name>.js")
|
@app.route("/<name>.js")
|
||||||
def javascript_get(name):
|
def javascript(name):
|
||||||
# Check if file in js directory
|
# Check if file in js directory
|
||||||
if not os.path.isfile("templates/assets/js/" + request.path.split("/")[-1]):
|
if not os.path.isfile("templates/assets/js/" + request.path.split("/")[-1]):
|
||||||
return error_response(request)
|
return error_response(request)
|
||||||
@@ -148,7 +148,7 @@ def javascript_get(name):
|
|||||||
|
|
||||||
|
|
||||||
@app.route("/download/<path:path>")
|
@app.route("/download/<path:path>")
|
||||||
def download_get(path):
|
def download(path):
|
||||||
if path not in DOWNLOAD_ROUTES:
|
if path not in DOWNLOAD_ROUTES:
|
||||||
return error_response(request, message="Invalid download")
|
return error_response(request, message="Invalid download")
|
||||||
# Check if file exists
|
# Check if file exists
|
||||||
@@ -163,7 +163,7 @@ def download_get(path):
|
|||||||
|
|
||||||
|
|
||||||
@app.route("/manifest.json")
|
@app.route("/manifest.json")
|
||||||
def manifest_get():
|
def manifest():
|
||||||
host = request.host
|
host = request.host
|
||||||
|
|
||||||
# Read as json
|
# Read as json
|
||||||
@@ -179,7 +179,7 @@ def manifest_get():
|
|||||||
|
|
||||||
|
|
||||||
@app.route("/sw.js")
|
@app.route("/sw.js")
|
||||||
def serviceWorker_get():
|
def serviceWorker():
|
||||||
return send_from_directory("pwa", "sw.js")
|
return send_from_directory("pwa", "sw.js")
|
||||||
|
|
||||||
# endregion
|
# endregion
|
||||||
@@ -191,19 +191,19 @@ def serviceWorker_get():
|
|||||||
@app.route("/meet")
|
@app.route("/meet")
|
||||||
@app.route("/meeting")
|
@app.route("/meeting")
|
||||||
@app.route("/appointment")
|
@app.route("/appointment")
|
||||||
def meetingLink_get():
|
def meetingLink():
|
||||||
return redirect(
|
return redirect(
|
||||||
"https://cloud.woodburn.au/apps/calendar/appointment/PamrmmspWJZr", code=302
|
"https://cloud.woodburn.au/apps/calendar/appointment/PamrmmspWJZr", code=302
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@app.route("/links")
|
@app.route("/links")
|
||||||
def links_get():
|
def links():
|
||||||
return render_template("link.html")
|
return render_template("link.html")
|
||||||
|
|
||||||
|
|
||||||
@app.route("/api/<path:function>")
|
@app.route("/api/<path:function>")
|
||||||
def api_legacy_get(function):
|
def api_legacy(function):
|
||||||
# Check if function is in api blueprint
|
# Check if function is in api blueprint
|
||||||
for rule in app.url_map.iter_rules():
|
for rule in app.url_map.iter_rules():
|
||||||
# Check if the redirect route exists
|
# Check if the redirect route exists
|
||||||
@@ -213,7 +213,7 @@ def api_legacy_get(function):
|
|||||||
|
|
||||||
|
|
||||||
@app.route("/actions.json")
|
@app.route("/actions.json")
|
||||||
def sol_actions_get():
|
def sol_actions():
|
||||||
return jsonify(
|
return jsonify(
|
||||||
{"rules": [{"pathPattern": "/donate**", "apiPath": "/api/v1/donate**"}]}
|
{"rules": [{"pathPattern": "/donate**", "apiPath": "/api/v1/donate**"}]}
|
||||||
)
|
)
|
||||||
@@ -224,7 +224,7 @@ def sol_actions_get():
|
|||||||
|
|
||||||
|
|
||||||
@app.route("/")
|
@app.route("/")
|
||||||
def index_get():
|
def index():
|
||||||
global HANDSHAKE_SCRIPTS
|
global HANDSHAKE_SCRIPTS
|
||||||
global PROJECTS
|
global PROJECTS
|
||||||
global PROJECTS_UPDATED
|
global PROJECTS_UPDATED
|
||||||
@@ -413,7 +413,7 @@ def index_get():
|
|||||||
|
|
||||||
|
|
||||||
@app.route("/donate")
|
@app.route("/donate")
|
||||||
def donate_get():
|
def donate():
|
||||||
global HANDSHAKE_SCRIPTS
|
global HANDSHAKE_SCRIPTS
|
||||||
# If localhost, don't load handshake
|
# If localhost, don't load handshake
|
||||||
if (
|
if (
|
||||||
@@ -539,7 +539,7 @@ def donate_get():
|
|||||||
|
|
||||||
|
|
||||||
@app.route("/address/<path:address>")
|
@app.route("/address/<path:address>")
|
||||||
def qraddress_get(address):
|
def qraddress(address):
|
||||||
qr = qrcode.QRCode(
|
qr = qrcode.QRCode(
|
||||||
version=1,
|
version=1,
|
||||||
error_correction=ERROR_CORRECT_L,
|
error_correction=ERROR_CORRECT_L,
|
||||||
@@ -560,7 +560,7 @@ def qraddress_get(address):
|
|||||||
|
|
||||||
@app.route("/qrcode/<path:data>")
|
@app.route("/qrcode/<path:data>")
|
||||||
@app.route("/qr/<path:data>")
|
@app.route("/qr/<path:data>")
|
||||||
def qrcode_get(data):
|
def qrcodee(data):
|
||||||
qr = qrcode.QRCode(
|
qr = qrcode.QRCode(
|
||||||
error_correction=ERROR_CORRECT_H, box_size=10, border=2)
|
error_correction=ERROR_CORRECT_H, box_size=10, border=2)
|
||||||
qr.add_data(data)
|
qr.add_data(data)
|
||||||
@@ -586,7 +586,7 @@ def qrcode_get(data):
|
|||||||
|
|
||||||
|
|
||||||
@app.route("/supersecretpath")
|
@app.route("/supersecretpath")
|
||||||
def supersecretpath_get():
|
def supersecretpath():
|
||||||
ascii_art = ""
|
ascii_art = ""
|
||||||
if os.path.isfile("data/ascii.txt"):
|
if os.path.isfile("data/ascii.txt"):
|
||||||
with open("data/ascii.txt") as file:
|
with open("data/ascii.txt") as file:
|
||||||
@@ -704,7 +704,7 @@ def hosting_post():
|
|||||||
|
|
||||||
|
|
||||||
@app.route("/resume.pdf")
|
@app.route("/resume.pdf")
|
||||||
def resume_pdf_get():
|
def resume_pdf():
|
||||||
# Check if file exists
|
# Check if file exists
|
||||||
if os.path.isfile("data/resume.pdf"):
|
if os.path.isfile("data/resume.pdf"):
|
||||||
return send_file("data/resume.pdf")
|
return send_file("data/resume.pdf")
|
||||||
@@ -717,7 +717,7 @@ def resume_pdf_get():
|
|||||||
|
|
||||||
|
|
||||||
@app.route("/<path:path>")
|
@app.route("/<path:path>")
|
||||||
def catch_all_get(path: str):
|
def catch_all(path: str):
|
||||||
global HANDSHAKE_SCRIPTS
|
global HANDSHAKE_SCRIPTS
|
||||||
# If localhost, don't load handshake
|
# If localhost, don't load handshake
|
||||||
if (
|
if (
|
||||||
|
|||||||
47
sol.py
47
sol.py
@@ -1,47 +0,0 @@
|
|||||||
from solders.pubkey import Pubkey
|
|
||||||
from solana.rpc.api import Client
|
|
||||||
from solders.system_program import TransferParams, transfer
|
|
||||||
from solders.message import MessageV0
|
|
||||||
from solders.transaction import VersionedTransaction
|
|
||||||
from solders.null_signer import NullSigner
|
|
||||||
import binascii
|
|
||||||
import base64
|
|
||||||
import os
|
|
||||||
|
|
||||||
SOLANA_ADDRESS = None
|
|
||||||
if os.path.isfile(".well-known/wallets/SOL"):
|
|
||||||
with open(".well-known/wallets/SOL") as file:
|
|
||||||
address = file.read()
|
|
||||||
SOLANA_ADDRESS = Pubkey.from_string(address.strip())
|
|
||||||
|
|
||||||
def create_transaction(sender_address: str, amount: float) -> str:
|
|
||||||
if SOLANA_ADDRESS is None:
|
|
||||||
raise ValueError("SOLANA_ADDRESS is not set. Please ensure the .well-known/wallets/SOL file exists and contains a valid address.")
|
|
||||||
# Create transaction
|
|
||||||
sender = Pubkey.from_string(sender_address)
|
|
||||||
transfer_ix = transfer(
|
|
||||||
TransferParams(
|
|
||||||
from_pubkey=sender, to_pubkey=SOLANA_ADDRESS, lamports=int(
|
|
||||||
amount * 1000000000)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
solana_client = Client("https://api.mainnet-beta.solana.com")
|
|
||||||
blockhashData = solana_client.get_latest_blockhash()
|
|
||||||
blockhash = blockhashData.value.blockhash
|
|
||||||
|
|
||||||
msg = MessageV0.try_compile(
|
|
||||||
payer=sender,
|
|
||||||
instructions=[transfer_ix],
|
|
||||||
address_lookup_table_accounts=[],
|
|
||||||
recent_blockhash=blockhash,
|
|
||||||
)
|
|
||||||
tx = VersionedTransaction(message=msg, keypairs=[NullSigner(sender)])
|
|
||||||
tx = bytes(tx).hex()
|
|
||||||
raw_bytes = binascii.unhexlify(tx)
|
|
||||||
base64_string = base64.b64encode(raw_bytes).decode("utf-8")
|
|
||||||
return base64_string
|
|
||||||
|
|
||||||
def get_solana_address() -> str:
|
|
||||||
if SOLANA_ADDRESS is None:
|
|
||||||
raise ValueError("SOLANA_ADDRESS is not set. Please ensure the .well-known/wallets/SOL file exists and contains a valid address.")
|
|
||||||
return str(SOLANA_ADDRESS)
|
|
||||||
17
tests/api.hurl
Normal file
17
tests/api.hurl
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
GET http://127.0.0.1:5000/api/v1/
|
||||||
|
HTTP 200
|
||||||
|
GET http://127.0.0.1:5000/api/v1/help
|
||||||
|
HTTP 200
|
||||||
|
GET http://127.0.0.1:5000/api/v1/ip
|
||||||
|
HTTP 200
|
||||||
|
[Asserts]
|
||||||
|
jsonpath "$.ip" == "127.0.0.1"
|
||||||
|
GET http://127.0.0.1:5000/api/v1/time
|
||||||
|
HTTP 200
|
||||||
|
GET http://127.0.0.1:5000/api/v1/timezone
|
||||||
|
HTTP 200
|
||||||
|
GET http://127.0.0.1:5000/api/v1/message
|
||||||
|
HTTP 200
|
||||||
|
GET http://127.0.0.1:5000/api/v1/project
|
||||||
|
HTTP 200
|
||||||
|
|
||||||
9
tests/blog.hurl
Normal file
9
tests/blog.hurl
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
GET http://127.0.0.1:5000/blog/
|
||||||
|
HTTP 200
|
||||||
|
|
||||||
|
GET http://127.0.0.1:5000/blog/Fingertip_on_Linux_Mint
|
||||||
|
HTTP 200
|
||||||
|
|
||||||
|
GET http://127.0.0.1:5000/blog/Fingertip_on_Linux_Mint.md
|
||||||
|
HTTP 200
|
||||||
|
|
||||||
41
tests/legacy_api.hurl
Normal file
41
tests/legacy_api.hurl
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
|
||||||
|
GET http://127.0.0.1:5000/api/help
|
||||||
|
HTTP 301
|
||||||
|
[Asserts]
|
||||||
|
header "Location" == "/api/v1/help"
|
||||||
|
|
||||||
|
GET http://127.0.0.1:5000/api/ip
|
||||||
|
HTTP 301
|
||||||
|
[Asserts]
|
||||||
|
header "Location" == "/api/v1/ip"
|
||||||
|
|
||||||
|
GET http://127.0.0.1:5000/api/message
|
||||||
|
HTTP 301
|
||||||
|
[Asserts]
|
||||||
|
header "Location" == "/api/v1/message"
|
||||||
|
|
||||||
|
GET http://127.0.0.1:5000/api/project
|
||||||
|
HTTP 301
|
||||||
|
[Asserts]
|
||||||
|
header "Location" == "/api/v1/project"
|
||||||
|
|
||||||
|
GET http://127.0.0.1:5000/api/donate
|
||||||
|
HTTP 301
|
||||||
|
[Asserts]
|
||||||
|
header "Location" == "/api/v1/donate"
|
||||||
|
|
||||||
|
GET http://127.0.0.1:5000/api/time
|
||||||
|
HTTP 301
|
||||||
|
[Asserts]
|
||||||
|
header "Location" == "/api/v1/time"
|
||||||
|
|
||||||
|
GET http://127.0.0.1:5000/api/timezone
|
||||||
|
HTTP 301
|
||||||
|
[Asserts]
|
||||||
|
header "Location" == "/api/v1/timezone"
|
||||||
|
|
||||||
|
GET http://127.0.0.1:5000/api/version
|
||||||
|
HTTP 301
|
||||||
|
[Asserts]
|
||||||
|
header "Location" == "/api/v1/version"
|
||||||
|
|
||||||
24
tests/now.hurl
Normal file
24
tests/now.hurl
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
GET http://127.0.0.1:5000/now/
|
||||||
|
HTTP 200
|
||||||
|
|
||||||
|
GET http://127.0.0.1:5000/now/old
|
||||||
|
HTTP 200
|
||||||
|
|
||||||
|
GET http://127.0.0.1:5000/now/24_02_18
|
||||||
|
HTTP 200
|
||||||
|
|
||||||
|
GET http://127.0.0.1:5000/now/24_02_18
|
||||||
|
HTTP 200
|
||||||
|
|
||||||
|
GET http://127.0.0.1:5000/now/now.json
|
||||||
|
HTTP 200
|
||||||
|
|
||||||
|
GET http://127.0.0.1:5000/now/now.xml
|
||||||
|
HTTP 200
|
||||||
|
|
||||||
|
GET http://127.0.0.1:5000/now/now.rss
|
||||||
|
HTTP 200
|
||||||
|
|
||||||
|
GET http://127.0.0.1:5000/now/rss.xml
|
||||||
|
HTTP 200
|
||||||
|
|
||||||
14
tests/sol.hurl
Normal file
14
tests/sol.hurl
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
POST http://127.0.0.1:5000/api/v1/donate/1
|
||||||
|
{"account": "1111111111111111111111111111111B"}
|
||||||
|
|
||||||
|
POST http://127.0.0.1:5000/api/v1/donate/0.01
|
||||||
|
{"account": "1111111111111111111111111111111C"}
|
||||||
|
|
||||||
|
POST http://127.0.0.1:5000/api/v1/donate/0.1
|
||||||
|
{"account": "1111111111111111111111111111111D"}
|
||||||
|
|
||||||
|
POST http://127.0.0.1:5000/api/v1/donate/0.02
|
||||||
|
{"account": "1111111111111111111111111111111E"}
|
||||||
|
|
||||||
|
POST http://127.0.0.1:5000/api/v1/donate/{amount}
|
||||||
|
{"account": "11111111111111111111111111111112"}
|
||||||
11
tests/well-known.hurl
Normal file
11
tests/well-known.hurl
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
GET http://127.0.0.1:5000/.well-known/xrp-ledger.toml
|
||||||
|
HTTP 200
|
||||||
|
|
||||||
|
GET http://127.0.0.1:5000/.well-known/nostr.json?name=hurl
|
||||||
|
HTTP 200
|
||||||
|
[Asserts]
|
||||||
|
jsonpath "$.names.hurl" == "b57b6a06fdf0a4095eba69eee26e2bf6fa72bd1ce6cbe9a6f72a7021c7acaa82"
|
||||||
|
|
||||||
|
GET http://127.0.0.1:5000/.well-known/wallets/BTC
|
||||||
|
HTTP 200
|
||||||
|
|
||||||
6
tools.py
6
tools.py
@@ -35,7 +35,7 @@ def getGitCommit():
|
|||||||
|
|
||||||
def isCurl(request: Request) -> bool:
|
def isCurl(request: Request) -> bool:
|
||||||
"""
|
"""
|
||||||
Check if the request is from curl
|
Check if the request is from curl or hurl
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
request (Request): The Flask request object
|
request (Request): The Flask request object
|
||||||
@@ -45,7 +45,9 @@ def isCurl(request: Request) -> bool:
|
|||||||
"""
|
"""
|
||||||
if request.headers and request.headers.get("User-Agent"):
|
if request.headers and request.headers.get("User-Agent"):
|
||||||
# Check if curl
|
# Check if curl
|
||||||
if "curl" in request.headers.get("User-Agent", "curl"):
|
if "curl" in request.headers.get("User-Agent", ""):
|
||||||
|
return True
|
||||||
|
if "hurl" in request.headers.get("User-Agent",""):
|
||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user