scratch
All checks were successful
Build and push container image / build-and-push-image (push) Successful in 6m3s
All checks were successful
Build and push container image / build-and-push-image (push) Successful in 6m3s
This commit is contained in:
@@ -2,4 +2,5 @@ psycopg2-binary
|
|||||||
python-dotenv
|
python-dotenv
|
||||||
flask-session
|
flask-session
|
||||||
requests
|
requests
|
||||||
flask
|
flask
|
||||||
|
markdown
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
# Imports
|
# Imports
|
||||||
from flask import Blueprint, render_template, abort
|
from flask import Blueprint, render_template, abort
|
||||||
from os import getenv as env
|
from os import getenv as env
|
||||||
import logging, os, re
|
import logging, os, re, markdown
|
||||||
|
|
||||||
# Create blueprint
|
# Create blueprint
|
||||||
bp = Blueprint(
|
bp = Blueprint(
|
||||||
@@ -16,6 +16,7 @@ log = logging.getLogger(__name__)
|
|||||||
|
|
||||||
# Get all files in folder
|
# Get all files in folder
|
||||||
def ListFiles(path):
|
def ListFiles(path):
|
||||||
|
path = os.path.join(bp.template_folder, 'pages', path)[3:]
|
||||||
files = []
|
files = []
|
||||||
for root, dirs, files_in_dir in os.walk(path):
|
for root, dirs, files_in_dir in os.walk(path):
|
||||||
for file in files_in_dir:
|
for file in files_in_dir:
|
||||||
@@ -27,14 +28,27 @@ def ListFiles(path):
|
|||||||
# Catch-all route for generic pages
|
# Catch-all route for generic pages
|
||||||
@bp.route('/<path:filename>')
|
@bp.route('/<path:filename>')
|
||||||
def catch_all(filename):
|
def catch_all(filename):
|
||||||
try:
|
if os.path.exists(os.path.join(bp.template_folder, 'pages', filename)[3:]):
|
||||||
return render_template(f'pages/{filename if re.match(r'^.+\.[a-zA-Z0-9]+$', filename) else filename + '.html'}')
|
return render_template(f'pages/{filename}')
|
||||||
|
|
||||||
except Exception as e:
|
elif os.path.exists(os.path.join(bp.template_folder, 'pages', filename + '.html')[3:]):
|
||||||
os_path = os.path.join(bp.template_folder, 'pages', filename)[3:]
|
return render_template(f'pages/{filename}.html')
|
||||||
if os.path.isdir(os_path):
|
|
||||||
if not filename.endswith('/'): filename += '/'
|
|
||||||
return render_template('bases/directory.html', directory=filename, pages=ListFiles(os_path))
|
|
||||||
|
|
||||||
# If it is a file, return a 404 error
|
elif os.path.exists(os.path.join(bp.template_folder, 'pages', filename + '.md')[3:]):
|
||||||
abort(404, f"Template '{filename}' not found: {e}")
|
print("yay")
|
||||||
|
print(markdown.markdownFromFile("../templates/pages/test.md"))
|
||||||
|
return render_template(
|
||||||
|
f'bases/md.html',
|
||||||
|
title = filename.split("/")[-1],
|
||||||
|
markdown = markdown.markdownFromFile(os.path.join(bp.template_folder, 'pages', filename + '.md'))
|
||||||
|
)
|
||||||
|
|
||||||
|
elif os.path.isdir(os.path.join(bp.template_folder, 'pages', filename)[3:]):
|
||||||
|
return render_template(
|
||||||
|
'bases/directory.html',
|
||||||
|
directory=filename + "/" if not filename.endswith('/') else filename,
|
||||||
|
pages=ListFiles(filename)
|
||||||
|
)
|
||||||
|
|
||||||
|
else:
|
||||||
|
abort(404, f"'{filename}' not found")
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
# Imports
|
# Imports
|
||||||
from flask import Blueprint, render_template
|
from flask import Blueprint, render_template
|
||||||
|
from werkzeug.exceptions import HTTPException
|
||||||
from os import getenv as env
|
from os import getenv as env
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
@@ -17,23 +18,35 @@ log = logging.getLogger(__name__)
|
|||||||
# Route for 500 error
|
# Route for 500 error
|
||||||
@bp.route('/500')
|
@bp.route('/500')
|
||||||
@bp.app_errorhandler(500)
|
@bp.app_errorhandler(500)
|
||||||
def internal_server_error(error=None):
|
def internal_server_error(error:HTTPException=None):
|
||||||
if error is not None:
|
return render_template('errors/500.html', error=error), 500
|
||||||
log.error("Internal server error: %s", error)
|
|
||||||
return render_template('errors/500.html'), 500
|
|
||||||
|
|
||||||
# Route for 404 error
|
# Route for 404 error
|
||||||
@bp.route('/404')
|
@bp.route('/404')
|
||||||
@bp.app_errorhandler(404)
|
@bp.app_errorhandler(404)
|
||||||
def not_found(error=None):
|
def not_found(error:HTTPException=None):
|
||||||
if error is not None:
|
return render_template('errors/404.html', error=error), 404
|
||||||
log.warning("Page not found: %s", error)
|
|
||||||
return render_template('errors/404.html'), 404 if error is not None else 200
|
|
||||||
|
|
||||||
# Route for 400 error
|
# Route for 400 error
|
||||||
@bp.route('/400')
|
@bp.route('/400')
|
||||||
@bp.app_errorhandler(400)
|
@bp.app_errorhandler(400)
|
||||||
def bad_request(error=None):
|
def bad_request(error:HTTPException=None):
|
||||||
if error is not None:
|
return render_template('errors/400.html', error=error), 400
|
||||||
log.warning("Bad request: %s", error)
|
|
||||||
return render_template('errors/400.html', error=error), 400
|
# Route for all other errors
|
||||||
|
@bp.route('/error')
|
||||||
|
@bp.app_errorhandler(Exception)
|
||||||
|
def unauthorized(error:HTTPException=None):
|
||||||
|
if isinstance(error, HTTPException):
|
||||||
|
return render_template(
|
||||||
|
'errors/error.html',
|
||||||
|
code = error.code,
|
||||||
|
description = error.description,
|
||||||
|
name = error.name
|
||||||
|
), error.code
|
||||||
|
return render_template(
|
||||||
|
'errors/error.html',
|
||||||
|
code=418,
|
||||||
|
description="meow :3",
|
||||||
|
name="I'm a teapot"
|
||||||
|
), 418
|
||||||
@@ -1,26 +0,0 @@
|
|||||||
from flask import Blueprint, jsonify
|
|
||||||
from os import getenv as env
|
|
||||||
import logging, requests
|
|
||||||
|
|
||||||
# Create blueprint
|
|
||||||
bp = Blueprint(
|
|
||||||
'lastfm',
|
|
||||||
__name__,
|
|
||||||
template_folder=env('TEMPLATE_FOLDER', default='../templates'),
|
|
||||||
static_folder=env('STATIC_FOLDER', default='../static')
|
|
||||||
)
|
|
||||||
|
|
||||||
# Create logger
|
|
||||||
log = logging.getLogger(__name__)
|
|
||||||
|
|
||||||
# lastfm info
|
|
||||||
@bp.route('/info')
|
|
||||||
def lastfm_info():
|
|
||||||
url = f"http://ws.audioscrobbler.com/2.0/?method=user.getrecenttracks&user={env('LASTFM_USER')}&api_key={env('LASTFM_API_KEY')}&format=json&limit=1"
|
|
||||||
response = requests.get(url).json()
|
|
||||||
data = {
|
|
||||||
'artist': response['recenttracks']['track'][0]['artist']['#text'],
|
|
||||||
'track': response['recenttracks']['track'][0]['name'],
|
|
||||||
'image': response['recenttracks']['track'][0]['image'][3]['#text']
|
|
||||||
}
|
|
||||||
return jsonify(data)
|
|
||||||
@@ -8,7 +8,6 @@ import logging
|
|||||||
|
|
||||||
import src.routes.error_handlers
|
import src.routes.error_handlers
|
||||||
import src.routes.dynamic_routes
|
import src.routes.dynamic_routes
|
||||||
import src.routes.lastfm
|
|
||||||
|
|
||||||
# Load env
|
# Load env
|
||||||
load_dotenv()
|
load_dotenv()
|
||||||
@@ -43,7 +42,6 @@ Session(app)
|
|||||||
|
|
||||||
# Load routes
|
# Load routes
|
||||||
app.register_blueprint(src.routes.error_handlers.bp, url_prefix='/error')
|
app.register_blueprint(src.routes.error_handlers.bp, url_prefix='/error')
|
||||||
app.register_blueprint(src.routes.lastfm.bp, url_prefix='/lastfm')
|
|
||||||
app.register_blueprint(src.routes.dynamic_routes.bp, url_prefix='/')
|
app.register_blueprint(src.routes.dynamic_routes.bp, url_prefix='/')
|
||||||
|
|
||||||
# Generic routes
|
# Generic routes
|
||||||
|
|||||||
BIN
static/content/fonts/avali-scratch.otf.woff2
Normal file
BIN
static/content/fonts/avali-scratch.otf.woff2
Normal file
Binary file not shown.
@@ -5,6 +5,12 @@
|
|||||||
font-weight:normal;
|
font-weight:normal;
|
||||||
font-style:normal;
|
font-style:normal;
|
||||||
}
|
}
|
||||||
|
@font-face {
|
||||||
|
font-family:"Scratch";
|
||||||
|
src:url("/static/content/fonts/avali-scratch.otf.woff2") format("woff2");
|
||||||
|
font-weight:normal;
|
||||||
|
font-style:normal;
|
||||||
|
}
|
||||||
|
|
||||||
:root {
|
:root {
|
||||||
--primary-color: #5cdd8b;
|
--primary-color: #5cdd8b;
|
||||||
@@ -17,6 +23,7 @@
|
|||||||
--font-family: "Space Mono", "serif";
|
--font-family: "Space Mono", "serif";
|
||||||
--title-font: 'Roboto Mono', sans-serif;
|
--title-font: 'Roboto Mono', sans-serif;
|
||||||
--irken-font: 'Irken';
|
--irken-font: 'Irken';
|
||||||
|
--scratch-font: 'Scratch';
|
||||||
}
|
}
|
||||||
|
|
||||||
body {
|
body {
|
||||||
@@ -244,6 +251,10 @@ main section a {
|
|||||||
font-family: var(--irken-font);
|
font-family: var(--irken-font);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.scratch {
|
||||||
|
font-family: var(--scratch-font);
|
||||||
|
}
|
||||||
|
|
||||||
#alt-nav {
|
#alt-nav {
|
||||||
display: none;
|
display: none;
|
||||||
backdrop-filter: blur(2px) brightness(0.6);
|
backdrop-filter: blur(2px) brightness(0.6);
|
||||||
|
|||||||
@@ -72,41 +72,58 @@ typing();
|
|||||||
|
|
||||||
// HIDDEN STUFF (shh don't tell anyone >:3)
|
// HIDDEN STUFF (shh don't tell anyone >:3)
|
||||||
|
|
||||||
let last5Chars = "";
|
let last15Chars = "";
|
||||||
|
|
||||||
document.addEventListener('keydown', function(event) {
|
document.addEventListener('keydown', function(event) {
|
||||||
last5Chars += event.key;
|
last15Chars += event.key;
|
||||||
if (last5Chars == "furry") {
|
if (last15Chars.includes("furry")) {
|
||||||
console.log("owo, whats this?");
|
console.log("owo, whats this?");
|
||||||
document.getElementById('furry').style.display = 'block';
|
document.getElementById('furry').style.display = 'block';
|
||||||
|
last15Chars = "";
|
||||||
}
|
}
|
||||||
if (last5Chars == "irken") {
|
if (last15Chars.includes("irken")) {
|
||||||
console.log("doom doom doom!");
|
console.log("doom doom doom!");
|
||||||
document.querySelector(":root").style.setProperty('--font-family', 'Irken');
|
document.querySelector(":root").style.setProperty('--font-family', 'Irken');
|
||||||
document.querySelector(":root").style.setProperty('--title-font', '1.5em');
|
document.querySelector(":root").style.setProperty('--title-font', '1.5em');
|
||||||
|
last15Chars = "";
|
||||||
}
|
}
|
||||||
while (last5Chars.length >= 5) {
|
if (last15Chars.includes("scratch")) {
|
||||||
last5Chars = last5Chars.slice(1);
|
console.log("space chicken");
|
||||||
|
document.querySelector(":root").style.setProperty('--font-family', 'Scratch');
|
||||||
|
document.querySelector(":root").style.setProperty('--title-font', '1em');
|
||||||
|
last15Chars = "";
|
||||||
|
}
|
||||||
|
while (last15Chars.length >= 15) {
|
||||||
|
last15Chars = last15Chars.slice(1);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// Spotify API (now lastfm)
|
// Spotify API (now lastfm)
|
||||||
|
|
||||||
function getSpotify() {
|
function getSpotify() {
|
||||||
fetch('/lastfm/info').then(response => {
|
fetch('https://api.alfieking.dev/spotify/nowplaying/xz02oolstlvwxqu1pfcua9exz').then(response => {
|
||||||
return response.json();
|
return response.json();
|
||||||
}).then(data => {
|
}).then(data => {
|
||||||
document.getElementById('spotify').style.backgroundImage = "url(" + data.image + ")";
|
if (data.item == null) {
|
||||||
document.getElementById('spotify-title').innerHTML = data.track;
|
document.getElementById('spotify').style.backgroundImage = "none";
|
||||||
document.getElementById('spotify-artist').innerHTML = data.artist;
|
document.getElementById('spotify-title').innerHTML = "Spotify is not playing anything";
|
||||||
|
document.getElementById('spotify-artist').innerHTML = ":(";
|
||||||
|
document.getElementById('spotify-link').href = "https://open.spotify.com/";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
document.getElementById('spotify').style.backgroundImage = "url(" + data.item.album.images[0].url + ")";
|
||||||
|
document.getElementById('spotify-title').innerHTML = data.item.name;
|
||||||
|
document.getElementById('spotify-artist').innerHTML = data.item.artists[0].name;
|
||||||
|
document.getElementById('spotify-link').href = data.item.external_urls.spotify;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (document.getElementById('spotify')) {
|
if (document.getElementById('spotify')) {
|
||||||
getSpotify();
|
getSpotify();
|
||||||
setInterval(getSpotify, 60000);
|
setInterval(getSpotify, 15000);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// load buttons
|
// load buttons
|
||||||
|
|
||||||
function loadButtons() {
|
function loadButtons() {
|
||||||
|
|||||||
@@ -41,7 +41,7 @@
|
|||||||
</section>
|
</section>
|
||||||
</nav>
|
</nav>
|
||||||
<section>
|
<section>
|
||||||
<h6 class="irken">heya, try typing "furry" and "irken" into this page!</h6>
|
<h6 class="irken">heya, try typing "furry", "irken" or <span class="scratch">scratch</span> into this page!</h6>
|
||||||
</section>
|
</section>
|
||||||
<section id="buttons">
|
<section id="buttons">
|
||||||
<h1>BUTTONS</h1>
|
<h1>BUTTONS</h1>
|
||||||
|
|||||||
10
templates/bases/md.html
Normal file
10
templates/bases/md.html
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
{% extends "bases/base.html" %}
|
||||||
|
|
||||||
|
{% block title %}{{ title }} - Alfie's basement{% endblock %}
|
||||||
|
{% block description %}server backend survivor{% endblock %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<section>
|
||||||
|
{{ markdown }}
|
||||||
|
</section>
|
||||||
|
{% endblock %}
|
||||||
@@ -10,4 +10,10 @@
|
|||||||
It seems like the thing you are looking for does not exist or <code>rm -rf</code> itself out of exsistance.
|
It seems like the thing you are looking for does not exist or <code>rm -rf</code> itself out of exsistance.
|
||||||
</p>
|
</p>
|
||||||
</section>
|
</section>
|
||||||
|
<section>
|
||||||
|
<h2>Actual error</h2>
|
||||||
|
<p>
|
||||||
|
{{ error }}
|
||||||
|
</p>
|
||||||
|
</section>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
@@ -14,4 +14,10 @@
|
|||||||
Oopsie Woopsie! Uwu We made a fucky wucky!! A wittle fucko boingo! The code monkeys at our headquarters are working VEWY HAWD to fix this!
|
Oopsie Woopsie! Uwu We made a fucky wucky!! A wittle fucko boingo! The code monkeys at our headquarters are working VEWY HAWD to fix this!
|
||||||
</p>
|
</p>
|
||||||
</section>
|
</section>
|
||||||
|
<section>
|
||||||
|
<h2>Actual error</h2>
|
||||||
|
<p>
|
||||||
|
{{ error }}
|
||||||
|
</p>
|
||||||
|
</section>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
16
templates/errors/error.html
Normal file
16
templates/errors/error.html
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
{% extends "bases/base.html" %}
|
||||||
|
|
||||||
|
{% block title %}{{ code }} - {{ name }}{% endblock %}
|
||||||
|
{% block description %}The page you are looking for does not exist.{% endblock %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<section>
|
||||||
|
<img src="https://http.cat/images/{{ code }}.jpg" alt="">
|
||||||
|
</section>
|
||||||
|
<section>
|
||||||
|
<h2>Actual error</h2>
|
||||||
|
<p>
|
||||||
|
{{ description }}
|
||||||
|
</p>
|
||||||
|
</section>
|
||||||
|
{% endblock %}
|
||||||
2
templates/pages/test.md
Normal file
2
templates/pages/test.md
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
# hello
|
||||||
|
this is a test
|
||||||
Reference in New Issue
Block a user