Compare commits
50 Commits
05961e2a3c
..
main
| Author | SHA1 | Date | |
|---|---|---|---|
| 936cadfea8 | |||
| cb7ec029eb | |||
| af5116d931 | |||
| 8dae4c1b5d | |||
| 8e67e714d0 | |||
| 7c9aaa04ba | |||
| 93ecd4999f | |||
| 0d367e43a6 | |||
| 3afab4c7fa | |||
| 885d2559af | |||
| 8f1e4e60e1 | |||
| a47c2a3886 | |||
| 11d8621f9b | |||
| b683a2721a | |||
| 7a60ca468d | |||
| 1a5380e17e | |||
| 6e92e40f1c | |||
| b4e6b4c296 | |||
| 9700a5dc7f | |||
| 067f0e189d | |||
| 639a8e2fb0 | |||
| 25b03aa105 | |||
| 53cd3852aa | |||
| f67f377be1 | |||
| bfb1b8a21e | |||
| ef459d728a | |||
| 5690bcadf9 | |||
| 8b5b80f7c5 | |||
| 66806ad922 | |||
| b29a61a44b | |||
| a0562330a3 | |||
| df59a2c097 | |||
| 8209f52fa7 | |||
| b029eba456 | |||
| 1b2425a493 | |||
| e66f7e0588 | |||
| d48dd04af9 | |||
| f3d5cb9d53 | |||
| da447939bb | |||
| 968a4cb442 | |||
| 189d63d7ba | |||
| 4a577e928a | |||
| e95e424a1e | |||
| 2b6ae9c640 | |||
| 0115328180 | |||
| f2cffc4400 | |||
| 30884ecaa4 | |||
| 27fbade9f1 | |||
| e97255897c | |||
| 392e788d91 |
@@ -0,0 +1,65 @@
|
|||||||
|
name: Deploy website
|
||||||
|
run-name: ${{ gitea.actor }} is deploying update
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- main
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
deploy:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Setup SSH
|
||||||
|
run: |
|
||||||
|
mkdir -p ~/.ssh
|
||||||
|
echo "${{ secrets.SSH_PRIVATE_KEY }}" > ~/.ssh/id_rsa
|
||||||
|
chmod 600 ~/.ssh/id_rsa
|
||||||
|
ssh-keyscan ${{ secrets.SSH_HOST }} >> ~/.ssh/known_hosts
|
||||||
|
|
||||||
|
- name: Deploy
|
||||||
|
run: |
|
||||||
|
ssh ${{ secrets.SSH_USER }}@${{ secrets.SSH_HOST }} << 'EOF'
|
||||||
|
set -e
|
||||||
|
|
||||||
|
APP_DIR=/var/www/alfieking.dev
|
||||||
|
RELEASES_DIR=$APP_DIR/releases
|
||||||
|
TIMESTAMP=$(date +%Y%m%d%H%M%S)
|
||||||
|
NEW_RELEASE=$RELEASES_DIR/$TIMESTAMP
|
||||||
|
KEEP_RELEASES=5
|
||||||
|
|
||||||
|
echo "Creating release directory..."
|
||||||
|
mkdir -p $NEW_RELEASE
|
||||||
|
|
||||||
|
echo "Cloning public repository..."
|
||||||
|
git clone --depth 1 -b main \
|
||||||
|
https://git.alfieking.dev/acetheking987/alfieking.dev.git \
|
||||||
|
$NEW_RELEASE
|
||||||
|
|
||||||
|
echo "Installing dependencies..."
|
||||||
|
source $APP_DIR/venv/bin/activate
|
||||||
|
pip install -r $NEW_RELEASE/requirements.txt
|
||||||
|
|
||||||
|
echo "Switching symlink..."
|
||||||
|
ln -sfn $NEW_RELEASE $APP_DIR/current
|
||||||
|
|
||||||
|
echo "Changing ownership..."
|
||||||
|
chown -R www-data:www-data /var/www/alfieking.dev/releases/$TIMESTAMP
|
||||||
|
chown -R www-data:www-data /var/www/alfieking.dev/current
|
||||||
|
|
||||||
|
echo "Restarting Gunicorn (downtime incomming XD)..."
|
||||||
|
systemctl restart alfieking.dev.service
|
||||||
|
|
||||||
|
echo "Cleaning old releases..."
|
||||||
|
CURRENT_TARGET=$(readlink -f $APP_DIR/current)
|
||||||
|
|
||||||
|
cd $RELEASES_DIR
|
||||||
|
for dir in $(ls -dt */ | tail -n +$((KEEP_RELEASES+1))); do
|
||||||
|
FULL_PATH="$RELEASES_DIR/${dir%/}"
|
||||||
|
if [ "$FULL_PATH" != "$CURRENT_TARGET" ]; then
|
||||||
|
rm -rf "$FULL_PATH"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
echo "Deployment successful."
|
||||||
|
EOF
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
.env
|
||||||
|
__pycache__
|
||||||
|
.venv
|
||||||
@@ -1,192 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html lang="en">
|
|
||||||
<head>
|
|
||||||
<meta charset="UTF-8">
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
||||||
<title>Alfieking.dev</title>
|
|
||||||
<link rel="icon" href="/static/content/icon.webp">
|
|
||||||
<link rel="stylesheet" href="/static/css/main.css">
|
|
||||||
<meta name="description" content="Alfie King's personal website.">
|
|
||||||
<meta name="keywords" content="Alfie King, Alfie, King, Alfieking, Alfieking.dev">
|
|
||||||
<meta name="author" content="Alfie King">
|
|
||||||
<meta name="robots" content="all">
|
|
||||||
|
|
||||||
<meta name="theme-color" content="#63de90">
|
|
||||||
<meta property="og:site_name" content="Alfieking.dev">
|
|
||||||
<meta property="og:url" content="https://alfieking.dev">
|
|
||||||
<meta property="og:title" content="Alfie King">
|
|
||||||
<meta property="og:description" content="server backend survivor">
|
|
||||||
<meta property="og:type" content="website">
|
|
||||||
<meta name="og:image" itemprop="image" content="static/content/icon.webp">
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<nav>
|
|
||||||
<ul>
|
|
||||||
<li><a href="#home"><img src="/static/content/icon.webp"></a></li>
|
|
||||||
<li><a href="#about">About</a></li>
|
|
||||||
<li><a href="#projects">Projects</a></li>
|
|
||||||
<li><a href="#links">Links</a></li>
|
|
||||||
<li id="music">
|
|
||||||
<img id="music-icon" src="" alt="">
|
|
||||||
<div id="music-expand">
|
|
||||||
<h1 id="music-title"></h1>
|
|
||||||
<h2 id="music-info"></h2>
|
|
||||||
<div id="music-progress"></div>
|
|
||||||
</div>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</nav>
|
|
||||||
<main>
|
|
||||||
<header id="home">
|
|
||||||
<div class="row">
|
|
||||||
<img src="/static/content/icon.webp">
|
|
||||||
<div class="column">
|
|
||||||
<h1>Alfie King</h1>
|
|
||||||
<h2 id="typing">server backend survivor</h2>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</header>
|
|
||||||
<section id="about">
|
|
||||||
<h1>About</h1>
|
|
||||||
<p>
|
|
||||||
Im not good with writing so dont expect much here. I am a student who is learning c++ and python. I've Done a few projects that i think
|
|
||||||
are decent enough to show off, so I have put them on this website. I like to mess around with linux and have a few servers that I run. I've
|
|
||||||
been running a server for a few years now, and I have learned a lot from it. I have also switched to linux on my main computer, which has been
|
|
||||||
slightly annoying at times (mainly because one of my most played games' anticheat doesn't support on linux atm. Also, the lack of photoshop is
|
|
||||||
a pain).
|
|
||||||
<br><br>
|
|
||||||
I am also a fan of some 2000s internet culture, so I intend to "Eventualy" make a alternitive website that is a bit more like that. I have seen a
|
|
||||||
few sites that I like, such as <a href="https://ne0nbandit.neocities.org/">ne0nbandit street</a>. Neocities is a great place to find sites like that.
|
|
||||||
<br><br>
|
|
||||||
I would like to make some more projects in the future, but I am not sure what I want to make yet. I tend to make thing on impulse a lot, and motivation
|
|
||||||
is "lacking" at times. So the few ideas I do have may never come to fruition. I hope to get better at art so i could hopefully make a game that is somewhat
|
|
||||||
interesting. But im at a lack of ideas at the moment.
|
|
||||||
<br><br>
|
|
||||||
I would also like to have a functional blog on this site, but I bearly talk about much so I dont know what I would write about. I like to ramble on about
|
|
||||||
random things, but I dont think that would be very interesting to read, and I think that I would forget to update it. I have a tumblr that I have had for a few
|
|
||||||
years now, but I dont post on it (the social anxiety is too much for me :<). However I hope to get better at that in the future.
|
|
||||||
<br><br>
|
|
||||||
I will probably put this site on my git server at some point, but I dont know when that will be. I have a few other projects that I want to put on there, but
|
|
||||||
I have been lazy and havent done it yet (or maybe I have and just forgot to update this).
|
|
||||||
<br><br>
|
|
||||||
At this point i'm just trying to fill up space so that this site looks more interesting. I hope that I can make this site more interesting in the future, but
|
|
||||||
for now have this cat. :3
|
|
||||||
<br><br>
|
|
||||||
<pre>
|
|
||||||
|\ _,,,---,,_
|
|
||||||
ZZZzz /,`.-'`' -. ;-;;,_
|
|
||||||
|,4- ) )-,_. ,\ ( `'-'
|
|
||||||
'---''(_/--' `-'\_)
|
|
||||||
</pre>
|
|
||||||
</p>
|
|
||||||
</section>
|
|
||||||
<section id="projects">
|
|
||||||
<h1>Projects</h1>
|
|
||||||
<div class="projects">
|
|
||||||
<div class="project">
|
|
||||||
<img src="static/content/game_project.webp" alt="">
|
|
||||||
<div class="project-info">
|
|
||||||
<h2>Game without a name</h2>
|
|
||||||
<p>
|
|
||||||
This is a game that I made in c++ using sdl. It is a simple platformer at the moment and will probably
|
|
||||||
change in the future. It is supposed to be a school project, but I am mainly working on it to learn c++.
|
|
||||||
I hope to create a more interesting game in the future, but for now, this is what I have.
|
|
||||||
<br><br>
|
|
||||||
It is fully open source, but at the moment I havent got around to uploading it on my git server. However,
|
|
||||||
it does require sdl to run, so you will need to install that if you want to run it.
|
|
||||||
<br><br>
|
|
||||||
I plan on making a better "engine" for it in the future, with more quality of life features and a functioning
|
|
||||||
collision system. Currently, there i a very basic level editor that I made from recyling the code from the game.
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="project">
|
|
||||||
<img src="static/content/term owo.png" alt="">
|
|
||||||
<div class="project-info">
|
|
||||||
<h2>Term owo</h2>
|
|
||||||
<p>
|
|
||||||
I made this project as a joke, I can't remember exactly what I baised it off other than the fact that it was somthing
|
|
||||||
similar to this but in a different language. I originally made it in python, but I have since rewritten it in c++ so that
|
|
||||||
it would be faster and so that I could learn c++.
|
|
||||||
<br><br>
|
|
||||||
It is mostly just a bunch of regex replacements, but I plan on adding more features in the future that add more ":3" and such to the
|
|
||||||
output. It currently has a few features, such as reading and writing to files, and automatically putting the output to the clipboard.
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
<section id="links">
|
|
||||||
<h1>Links</h1>
|
|
||||||
<div class="links">
|
|
||||||
<a href="https://neocities.org/">
|
|
||||||
<img src="static/content/neocities-Logo.webp" alt="neocities">
|
|
||||||
</a>
|
|
||||||
<a href="https://git.alfieking.dev">
|
|
||||||
<img src="static/content/Gitea_Logo.webp" alt="gitea">
|
|
||||||
</a>
|
|
||||||
<div class="blinkies">
|
|
||||||
<a href="https://acetheking987.tumblr.com/">
|
|
||||||
<img src="/static/content/tumblr.gif" alt="tumblr">
|
|
||||||
</a>
|
|
||||||
<a href="https://www.twitch.tv/acetheking987">
|
|
||||||
<img src="/static/content/twitch.gif" alt="twitch">
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
<a href="https://blinkies.cafe/">
|
|
||||||
<img src="static/content/blinikes-cafe.webp" alt="blinkies cafe">
|
|
||||||
</a>
|
|
||||||
<a href="https://12ft.io/">
|
|
||||||
<img src="static/content/12ft-ladder.webp" alt="12ft.io">
|
|
||||||
</a>
|
|
||||||
<a href="https://www.badinternetbills.com/">
|
|
||||||
<img src="static/content/bad_internet_bills.webp" alt="badinternetbills">
|
|
||||||
</a>
|
|
||||||
<a href="https://aur.archlinux.org/packages?K=acetheking987&SeB=m">
|
|
||||||
<img src="static/content/Arch-linux-logo.webp" alt="aur">
|
|
||||||
</a>
|
|
||||||
<div class="blinkies">
|
|
||||||
<a href="https://ne0nbandit.neocities.org/">
|
|
||||||
<img class="btn" src="https://ne0nbandit.github.io/assets/img/btn/mine/nbbanner.png">
|
|
||||||
</a>
|
|
||||||
<a href="https://dimden.dev/">
|
|
||||||
<img class="btn" src="https://dimden.dev/images/88x31.gif">
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
<iframe width="120" height="120" style="border:none" src="https://dimden.neocities.org/navlink/" name="neolink"></iframe>
|
|
||||||
<div class="blinkies">
|
|
||||||
<a href="https://thinliquid.dev">
|
|
||||||
<img class="btn" src="https://thinliquid.dev/thnlqd.png" alt="thinliquid's button" />
|
|
||||||
</a>
|
|
||||||
<a href="https://nekoweb.org/">
|
|
||||||
<img class="btn" src="https://nekoweb.org/assets/buttons/button3.gif">
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
<div class="blinkies">
|
|
||||||
<a href="https://beeps.website/">
|
|
||||||
<img class="btn" src="static/content/bleeps.gif" alt="bleeps website" />
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<h2>Buttons!!! :3</h2>
|
|
||||||
<div class="btns">
|
|
||||||
<img src="static/content/btns/archlinux.gif" alt="archlinux">
|
|
||||||
<img src="static/content/btns/discord.gif" alt="discord">
|
|
||||||
<img src="static/content/btns/firefoxget.gif" alt="firefox">
|
|
||||||
<img src="static/content/btns/handcoded.gif" alt="handcoded">
|
|
||||||
<img src="static/content/btns/use-discord.gif" alt="use discord">
|
|
||||||
<img src="static/content/btns/vscbutton.gif" alt="vscode">
|
|
||||||
<img src="static/content/btns/deltarune.png" alt="deltarune">
|
|
||||||
<img src="static/content/btns/no_web3.gif" alt="no web3">
|
|
||||||
<img src="static/content/btns/learn_html.gif" alt="learn html">
|
|
||||||
<img src="static/content/btns/ublock_origin_now.png" alt="ublock origin">
|
|
||||||
<img src="static/content/btns/anything_but_chrome.gif" alt="naythong but chrome">
|
|
||||||
<img src="static/content/btns/made_with_paws.png" alt="made with paws">
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
</main>
|
|
||||||
</body>
|
|
||||||
<script src="/static/js/typing.js"></script>
|
|
||||||
<script src="/static/js/music.js"></script>
|
|
||||||
<script src="/static/js/links.js"></script>
|
|
||||||
</html>
|
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
psycopg2-binary
|
||||||
|
python-dotenv
|
||||||
|
flask-session
|
||||||
|
requests
|
||||||
|
flask
|
||||||
|
markdown
|
||||||
|
gunicorn
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
from os import getenv as env
|
||||||
|
import psycopg2, logging
|
||||||
|
|
||||||
|
|
||||||
|
log = logging.getLogger("blog")
|
||||||
|
|
||||||
|
|
||||||
|
log.info("connecting to database")
|
||||||
|
conn = psycopg2.connect(
|
||||||
|
host = env("PG_HOST"),
|
||||||
|
port = env("PG_PORT"),
|
||||||
|
dbname = env("PG_DBNAME"),
|
||||||
|
user= env("PG_USER"),
|
||||||
|
password = env("PG_PASSWORD")
|
||||||
|
)
|
||||||
|
cursor = conn.cursor()
|
||||||
@@ -0,0 +1,73 @@
|
|||||||
|
# Imports
|
||||||
|
from flask import Blueprint, render_template, abort
|
||||||
|
import os, importlib, logging
|
||||||
|
|
||||||
|
|
||||||
|
# Logging
|
||||||
|
log = logging.getLogger("__main__")
|
||||||
|
|
||||||
|
|
||||||
|
# Create blueprint
|
||||||
|
bp = Blueprint('dynamic', __name__)
|
||||||
|
template_folder = "templates"
|
||||||
|
|
||||||
|
|
||||||
|
# helper func
|
||||||
|
def get_path(file) -> str:
|
||||||
|
return os.path.join(template_folder, "pages", file)
|
||||||
|
|
||||||
|
|
||||||
|
# Get all files in folder
|
||||||
|
def ListFiles(path):
|
||||||
|
path = get_path(path)
|
||||||
|
files = []
|
||||||
|
for root, dirs, files_in_dir in os.walk(path):
|
||||||
|
for file in files_in_dir:
|
||||||
|
files.append(os.path.relpath(os.path.join(root, file), path))
|
||||||
|
for dir in dirs:
|
||||||
|
files.append(os.path.relpath(os.path.join(root, dir), path) + '/')
|
||||||
|
return files
|
||||||
|
|
||||||
|
|
||||||
|
# Import handlers
|
||||||
|
handlers_unloaded = os.listdir("src/handlers")
|
||||||
|
handlers_unloaded = [handler for handler in handlers_unloaded if handler.endswith(".py")]
|
||||||
|
handlers = {}
|
||||||
|
|
||||||
|
for handler in handlers_unloaded:
|
||||||
|
try:
|
||||||
|
try: module = importlib.import_module(f'src.handlers.{handler[:-3]}')
|
||||||
|
except ImportError: module = importlib.import_module(f'handlers.{handler[:-3]}')
|
||||||
|
handlers[handler[:-3]] = module.callback
|
||||||
|
log.info(f"Loaded handler {handler}: {module.callback}")
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
log.error(f"Failed to load handler {handler}: {e}")
|
||||||
|
continue
|
||||||
|
|
||||||
|
|
||||||
|
# Catch-all route for generic pages
|
||||||
|
@bp.route('/<path:filename>')
|
||||||
|
def catch_all(filename):
|
||||||
|
if os.path.exists(get_path(filename)):
|
||||||
|
if os.path.isdir(get_path(filename)):
|
||||||
|
return render_template(
|
||||||
|
'bases/directory.html',
|
||||||
|
directory=filename + "/" if not filename.endswith('/') else filename,
|
||||||
|
pages=ListFiles(filename)
|
||||||
|
)
|
||||||
|
|
||||||
|
if filename.split('.')[-1] in handlers.keys():
|
||||||
|
return handlers[filename.split('.')[-1]](filename)
|
||||||
|
|
||||||
|
return render_template(f'pages/{filename}')
|
||||||
|
|
||||||
|
elif os.path.exists(get_path(filename + '.html')):
|
||||||
|
return render_template(f'pages/{filename}.html')
|
||||||
|
|
||||||
|
else:
|
||||||
|
for ext in handlers.keys():
|
||||||
|
if os.path.exists(get_path(filename + f".{ext}")):
|
||||||
|
return handlers[ext](filename + f".{ext}")
|
||||||
|
|
||||||
|
abort(404, f"'{filename}' not found")
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
from flask import Blueprint, render_template
|
||||||
|
from werkzeug.exceptions import HTTPException
|
||||||
|
|
||||||
|
|
||||||
|
bp = Blueprint("errors", __name__)
|
||||||
|
|
||||||
|
|
||||||
|
@bp.route('/500')
|
||||||
|
@bp.app_errorhandler(500)
|
||||||
|
def internal_server_error(error:HTTPException=None):
|
||||||
|
return render_template('errors/500.html', error=error), 500
|
||||||
|
|
||||||
|
|
||||||
|
@bp.route('/404')
|
||||||
|
@bp.app_errorhandler(404)
|
||||||
|
def not_found(error:HTTPException=None):
|
||||||
|
return render_template('errors/404.html', error=error), 404
|
||||||
|
|
||||||
|
|
||||||
|
@bp.route('/400')
|
||||||
|
@bp.app_errorhandler(400)
|
||||||
|
def bad_request(error:HTTPException=None):
|
||||||
|
return render_template('errors/400.html', error=error), 400
|
||||||
|
|
||||||
|
|
||||||
|
@bp.route('/idk')
|
||||||
|
@bp.app_errorhandler(Exception)
|
||||||
|
def idk(error:HTTPException=None):
|
||||||
|
if not isinstance(error, HTTPException):
|
||||||
|
error = HTTPException("I honestly dont know")
|
||||||
|
error.code = 418
|
||||||
|
|
||||||
|
return render_template(
|
||||||
|
'errors/error.html',
|
||||||
|
code = error.code,
|
||||||
|
description = error.description,
|
||||||
|
err_name = error.name,
|
||||||
|
), error.code
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
from flask import render_template
|
||||||
|
import markdown, os
|
||||||
|
|
||||||
|
def callback(filename):
|
||||||
|
output = markdown.markdown(open(os.path.join("templates", "pages", filename), "r").read())
|
||||||
|
return render_template(
|
||||||
|
f'bases/md.html',
|
||||||
|
title = filename.split("/")[-1],
|
||||||
|
markdown = output
|
||||||
|
)
|
||||||
@@ -0,0 +1,84 @@
|
|||||||
|
# IMPORTS
|
||||||
|
from flask import Flask, render_template, request
|
||||||
|
from os import getenv as env
|
||||||
|
import logging
|
||||||
|
|
||||||
|
try:
|
||||||
|
import src.pg_log as pg_log
|
||||||
|
except ImportError:
|
||||||
|
import pg_log
|
||||||
|
from dotenv import load_dotenv
|
||||||
|
load_dotenv()
|
||||||
|
|
||||||
|
|
||||||
|
# LOGGING
|
||||||
|
pg_log_handler = pg_log.PgLog(
|
||||||
|
host = env("PG_HOST"),
|
||||||
|
port = env("PG_PORT"),
|
||||||
|
dbname = env("PG_DBNAME"),
|
||||||
|
user= env("PG_USER"),
|
||||||
|
password = env("PG_PASSWORD")
|
||||||
|
)
|
||||||
|
pg_log_handler.setLevel(logging.DEBUG)
|
||||||
|
|
||||||
|
stream_log_handler = logging.StreamHandler()
|
||||||
|
stream_log_handler.setFormatter(
|
||||||
|
logging.Formatter("%(asctime)s - %(levelname)s: %(message)s")
|
||||||
|
)
|
||||||
|
stream_log_handler.setLevel(logging.INFO)
|
||||||
|
|
||||||
|
log = logging.getLogger(__name__)
|
||||||
|
log.setLevel(logging.DEBUG)
|
||||||
|
log.addHandler(stream_log_handler)
|
||||||
|
log.addHandler(pg_log_handler)
|
||||||
|
|
||||||
|
werkzeug_logger = logging.getLogger("werkzeug")
|
||||||
|
werkzeug_logger.setLevel(logging.DEBUG)
|
||||||
|
werkzeug_logger.addHandler(pg_log_handler)
|
||||||
|
werkzeug_logger.addHandler(stream_log_handler)
|
||||||
|
|
||||||
|
log.info("Logging initialized.")
|
||||||
|
|
||||||
|
|
||||||
|
try:
|
||||||
|
import src.dynamic as dynamic
|
||||||
|
import src.errors as errors
|
||||||
|
import src.music_metadata as music_metadata
|
||||||
|
except ImportError:
|
||||||
|
import dynamic, errors, music_metadata
|
||||||
|
|
||||||
|
|
||||||
|
# CREATE FLASK APP
|
||||||
|
app = Flask(
|
||||||
|
__name__,
|
||||||
|
template_folder="../templates",
|
||||||
|
static_folder="../static"
|
||||||
|
)
|
||||||
|
log.info("Flask initialized.")
|
||||||
|
|
||||||
|
|
||||||
|
# BLUEPRINTS
|
||||||
|
app.register_blueprint(errors.bp, url_prefix="/errors")
|
||||||
|
app.register_blueprint(music_metadata.bp, url_prefix="/music")
|
||||||
|
app.register_blueprint(dynamic.bp, url_prefix="/")
|
||||||
|
log.info("Blueprints registered.")
|
||||||
|
|
||||||
|
|
||||||
|
# ROUTES
|
||||||
|
@app.route("/")
|
||||||
|
def index():
|
||||||
|
return render_template("index.html")
|
||||||
|
|
||||||
|
@app.route("/toaster")
|
||||||
|
def toaster():
|
||||||
|
return render_template("toaster.html")
|
||||||
|
|
||||||
|
@app.route("/terminal")
|
||||||
|
def terminal():
|
||||||
|
return render_template("terminal.html")
|
||||||
|
|
||||||
|
|
||||||
|
# DEBUG (DONT RUN LIKE THIS IN PROD)
|
||||||
|
if __name__ == "__main__":
|
||||||
|
log.warning(f"RUNNING IN DEBUG MODE DO NOT USE FOR PRODUCTION!")
|
||||||
|
app.run(debug=True)
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
from flask import Blueprint, request, abort
|
||||||
|
from os import getenv as env
|
||||||
|
from urllib.parse import quote
|
||||||
|
import requests
|
||||||
|
|
||||||
|
bp = Blueprint("music", __name__)
|
||||||
|
|
||||||
|
@bp.route("/metadata")
|
||||||
|
def metadata():
|
||||||
|
if not request.args.get("recording_name"):
|
||||||
|
abort(400, "Recording name is required")
|
||||||
|
if not request.args.get("artist_name"):
|
||||||
|
abort(400, "Artist name is required")
|
||||||
|
|
||||||
|
data = requests.get(
|
||||||
|
f"https://api.listenbrainz.org/1/metadata/lookup/?recording_name={quote(request.args.get('recording_name'))}&artist_name={quote(request.args.get('artist_name'))}&metadata=true&inc=artist+tag+release",
|
||||||
|
headers={
|
||||||
|
"Authorization": f"Token {env("LISTENBRAINZ_TOKEN")}"
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
if data.status_code == 200:
|
||||||
|
return data.json()
|
||||||
|
else:
|
||||||
|
abort(500, "Failed to retrieve metadata")
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
import psycopg2, logging
|
||||||
|
|
||||||
|
class PgLog(logging.StreamHandler):
|
||||||
|
def __init__(self, host, port, dbname, user, password):
|
||||||
|
super().__init__()
|
||||||
|
|
||||||
|
self.host = host
|
||||||
|
self.port = port
|
||||||
|
self.dbname = dbname
|
||||||
|
self.user = user
|
||||||
|
self.password = password
|
||||||
|
|
||||||
|
self.conn = psycopg2.connect(
|
||||||
|
database = dbname,
|
||||||
|
user = user,
|
||||||
|
password = password,
|
||||||
|
host = host,
|
||||||
|
port = port
|
||||||
|
)
|
||||||
|
|
||||||
|
self.cursor = self.conn.cursor()
|
||||||
|
|
||||||
|
def __del__(self):
|
||||||
|
self.cursor.close()
|
||||||
|
self.conn.close()
|
||||||
|
|
||||||
|
def emit(self, record):
|
||||||
|
self.cursor.execute(
|
||||||
|
f"INSERT INTO logs (level, message) VALUES (%s, %s)",
|
||||||
|
(
|
||||||
|
record.levelname,
|
||||||
|
record.getMessage(),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
self.conn.commit()
|
||||||
|
Before Width: | Height: | Size: 29 KiB |
|
Before Width: | Height: | Size: 24 KiB |
|
Before Width: | Height: | Size: 20 KiB |
|
Before Width: | Height: | Size: 31 KiB |
|
Before Width: | Height: | Size: 3.7 KiB |
|
Before Width: | Height: | Size: 168 B |
|
Before Width: | Height: | Size: 1.8 KiB |
|
Before Width: | Height: | Size: 3.0 KiB |
|
Before Width: | Height: | Size: 1.6 KiB |
|
Before Width: | Height: | Size: 297 B |
|
Before Width: | Height: | Size: 9.1 KiB |
|
Before Width: | Height: | Size: 5.1 KiB |
|
Before Width: | Height: | Size: 1.5 KiB |
|
Before Width: | Height: | Size: 3.6 KiB |
|
Before Width: | Height: | Size: 1.7 KiB |
|
Before Width: | Height: | Size: 483 B |
|
Before Width: | Height: | Size: 1.7 KiB |
|
Before Width: | Height: | Size: 9.8 KiB |
|
Before Width: | Height: | Size: 1.9 KiB |
|
After Width: | Height: | Size: 1.4 KiB |
|
After Width: | Height: | Size: 13 KiB |
|
After Width: | Height: | Size: 6.8 KiB |
|
After Width: | Height: | Size: 1.6 KiB |
|
After Width: | Height: | Size: 25 KiB |
|
After Width: | Height: | Size: 11 KiB |
|
After Width: | Height: | Size: 14 KiB |
|
After Width: | Height: | Size: 3.0 KiB |
|
After Width: | Height: | Size: 2.8 KiB |
|
After Width: | Height: | Size: 1.9 KiB |
@@ -0,0 +1,35 @@
|
|||||||
|
https://cyber.dabamos.de/88x31/88x31.gif
|
||||||
|
https://cyber.dabamos.de/88x31/anythingbut.gif
|
||||||
|
https://cyber.dabamos.de/88x31/bestdesktop.gif
|
||||||
|
https://kopawz.neocities.org/buttonhoard/buttonsfldr2/diagnosedwithGAY.gif
|
||||||
|
https://kopawz.neocities.org/indexgraphics/buttondecor/ilikecomputer.png
|
||||||
|
https://anlucas.neocities.org/best_viewed_with_eyes.gif
|
||||||
|
https://anlucas.neocities.org/html_learn_it_today.gif
|
||||||
|
https://highway.eightyeightthirty.one/badge/5d58a8f32b007d4897db6f862a895a81674fb35f5cc3947fc66595817ca174db
|
||||||
|
https://cyber.dabamos.de/88x31/keep.gif
|
||||||
|
https://cyber.dabamos.de/88x31/js-warning.gif
|
||||||
|
https://cyber.dabamos.de/88x31/linuxnow2.gif
|
||||||
|
https://cyber.dabamos.de/88x31/nano2.gif
|
||||||
|
https://cyber.dabamos.de/88x31/nocookie.gif
|
||||||
|
https://cyber.dabamos.de/88x31/nofuckingthanks.gif
|
||||||
|
https://cyber.dabamos.de/88x31/nyan.gif
|
||||||
|
https://cyber.dabamos.de/88x31/pgp-now.gif
|
||||||
|
https://cyber.dabamos.de/88x31/phonechump.gif
|
||||||
|
https://cyber.dabamos.de/88x31/pinguonline.gif
|
||||||
|
https://cyber.dabamos.de/88x31/piracy.gif
|
||||||
|
https://cyber.dabamos.de/88x31/proxmox.gif
|
||||||
|
https://cyber.dabamos.de/88x31/pride.gif
|
||||||
|
https://cyber.dabamos.de/88x31/relax-now.gif
|
||||||
|
https://cyber.dabamos.de/88x31/skirt.gif
|
||||||
|
https://cyber.dabamos.de/88x31/steam.gif
|
||||||
|
https://cyber.dabamos.de/88x31/svenbutton.gif
|
||||||
|
https://cyber.dabamos.de/88x31/tfnow.gif
|
||||||
|
https://cyber.dabamos.de/88x31/vscbutton.gif
|
||||||
|
https://cyber.dabamos.de/88x31/reddit.gif
|
||||||
|
https://cyber.dabamos.de/88x31/ralseismokingadart.gif
|
||||||
|
https://cyber.dabamos.de/88x31/blender.gif
|
||||||
|
https://cyber.dabamos.de/88x31/bob.gif
|
||||||
|
https://cyber.dabamos.de/88x31/censor_14c.gif
|
||||||
|
https://cyber.dabamos.de/88x31/chrmevil.gif
|
||||||
|
https://cyber.dabamos.de/88x31/dark-mode.gif
|
||||||
|
https://cyber.dabamos.de/88x31/firefox3.gif
|
||||||
|
After Width: | Height: | Size: 11 KiB |
|
After Width: | Height: | Size: 965 B |
|
After Width: | Height: | Size: 20 KiB |
|
Before Width: | Height: | Size: 96 KiB |
|
After Width: | Height: | Size: 743 KiB |
|
After Width: | Height: | Size: 4.5 KiB |
|
Before Width: | Height: | Size: 49 KiB After Width: | Height: | Size: 49 KiB |
|
Before Width: | Height: | Size: 31 KiB |
|
After Width: | Height: | Size: 240 KiB |
@@ -0,0 +1,7 @@
|
|||||||
|
User-agent: *
|
||||||
|
Allow: /
|
||||||
|
Disallow: /errors
|
||||||
|
|
||||||
|
Sitemap: https://alfieking.dev/sitemap.xml
|
||||||
|
|
||||||
|
# hewwo :3
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
|
||||||
|
<url>
|
||||||
|
<loc>https://alfieking.dev/</loc>
|
||||||
|
</url>
|
||||||
|
<url>
|
||||||
|
<loc>https://alfieking.dev/toaster</loc>
|
||||||
|
</url>
|
||||||
|
</urlset>
|
||||||
|
After Width: | Height: | Size: 3.6 MiB |
|
After Width: | Height: | Size: 4.6 MiB |
|
After Width: | Height: | Size: 3.2 MiB |
|
After Width: | Height: | Size: 2.0 MiB |
|
After Width: | Height: | Size: 4.6 MiB |
|
After Width: | Height: | Size: 3.3 MiB |
|
After Width: | Height: | Size: 3.5 MiB |
|
After Width: | Height: | Size: 2.7 MiB |
|
After Width: | Height: | Size: 3.5 MiB |
|
After Width: | Height: | Size: 4.4 MiB |
|
After Width: | Height: | Size: 4.9 MiB |
|
After Width: | Height: | Size: 5.1 MiB |
|
After Width: | Height: | Size: 3.3 MiB |
|
After Width: | Height: | Size: 4.0 MiB |
|
After Width: | Height: | Size: 4.5 MiB |
|
After Width: | Height: | Size: 4.7 MiB |
|
After Width: | Height: | Size: 17 KiB |
|
After Width: | Height: | Size: 710 B |
|
After Width: | Height: | Size: 170 B |
|
After Width: | Height: | Size: 11 KiB |
|
After Width: | Height: | Size: 126 B |
|
After Width: | Height: | Size: 86 B |
|
After Width: | Height: | Size: 170 B |
|
After Width: | Height: | Size: 88 B |
|
After Width: | Height: | Size: 82 B |
|
After Width: | Height: | Size: 68 B |
|
After Width: | Height: | Size: 134 B |
|
After Width: | Height: | Size: 122 B |
|
After Width: | Height: | Size: 116 B |
|
Before Width: | Height: | Size: 18 KiB |
|
After Width: | Height: | Size: 2.7 MiB |
|
After Width: | Height: | Size: 1.0 MiB |
|
After Width: | Height: | Size: 830 KiB |
|
Before Width: | Height: | Size: 3.4 KiB |
|
Before Width: | Height: | Size: 3.2 KiB |
@@ -0,0 +1,460 @@
|
|||||||
|
@import url('https://fonts.googleapis.com/css2?family=Fredoka:wdth,wght@125,700&family=Space+Mono:ital,wght@0,400;0,700;1,400;1,700&display=swap');
|
||||||
|
@font-face {
|
||||||
|
font-family:"Irken";
|
||||||
|
src:url("/static/content/fonts/Irken-Like-AllCaps.woff") format("woff");
|
||||||
|
font-weight: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;
|
||||||
|
}
|
||||||
|
@font-face {
|
||||||
|
font-family:"Ultrafont";
|
||||||
|
src:url("/static/content/fonts/ultrakill-font.woff2") format("woff2");
|
||||||
|
font-weight:normal;
|
||||||
|
font-style:normal;
|
||||||
|
}
|
||||||
|
@font-face {
|
||||||
|
font-family:"Ultrafont2";
|
||||||
|
src:url("/static/content/fonts/ultrakill-font-2.woff2") format("woff2");
|
||||||
|
font-weight:normal;
|
||||||
|
font-style:normal;
|
||||||
|
}
|
||||||
|
|
||||||
|
:root {
|
||||||
|
--primary-color: #5cdd8b;
|
||||||
|
--primary-color-but-slightly-transparent: #5cdd8b44;
|
||||||
|
--text-color: #b1b8c0;
|
||||||
|
--background-color: #020205;
|
||||||
|
--secondary-background-color: #090914;
|
||||||
|
--secondary-background-color-but-slightly-transparent: #09091444;
|
||||||
|
--font-size: 0.5cm;
|
||||||
|
--font-family: "Space Mono", "serif";
|
||||||
|
--title-font: 'Roboto Mono', sans-serif;
|
||||||
|
--irken-font: 'Irken';
|
||||||
|
--scratch-font: 'Scratch';
|
||||||
|
--ultrafont-font: 'Ultrafont';
|
||||||
|
--smileos2-box: url(/static/content/smileos/SmileOS_2_Box.webp) 17 3 3 fill / 51px 9px 9px;
|
||||||
|
--smileos2-font: 'Ultrafont2';
|
||||||
|
--smileos2-emphasis: #FF4343;
|
||||||
|
--line-height: normal;
|
||||||
|
--header-line-height: normal;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
background-color: var(--background-color);
|
||||||
|
background-image: url("https://blinkies.cafe/purple-stars-bg.gif");
|
||||||
|
color: var(--text-color);
|
||||||
|
font-size: var(--font-size);
|
||||||
|
font-family: var(--font-family);
|
||||||
|
line-height: var(--line-height);
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: auto auto;
|
||||||
|
grid-template-rows: 1fr;
|
||||||
|
grid-template-areas: "main sidebar";
|
||||||
|
margin: 7% auto 7% auto;
|
||||||
|
gap: 1rem;
|
||||||
|
justify-content: center;
|
||||||
|
width: 940px;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1, h2, h3, h4, h5, h6 {
|
||||||
|
line-height: var(--header-line-height);
|
||||||
|
}
|
||||||
|
|
||||||
|
#sidebar {
|
||||||
|
grid-area: sidebar;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 1rem;
|
||||||
|
width: 174px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#sidebar section {
|
||||||
|
backdrop-filter: blur(2px) brightness(0.6);
|
||||||
|
border: var(--secondary-background-color) 2px solid;
|
||||||
|
border-radius: 10px;
|
||||||
|
padding: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#sidebar ul {
|
||||||
|
list-style-type: none;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
#sidebar ul li {
|
||||||
|
width: fit-content;
|
||||||
|
}
|
||||||
|
|
||||||
|
#sidebar ul li a {
|
||||||
|
color: var(--text-color);
|
||||||
|
text-decoration: none;
|
||||||
|
font-weight: 100;
|
||||||
|
transition: all 0.2s ease-in-out
|
||||||
|
}
|
||||||
|
|
||||||
|
#sidebar ul li a:hover {
|
||||||
|
color: var(--primary-color);
|
||||||
|
font-weight: 900;
|
||||||
|
}
|
||||||
|
|
||||||
|
#sidebar ul li img {
|
||||||
|
transition: all 0.2s ease-in-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
#sidebar ul li img:hover {
|
||||||
|
transform: scale(1.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
#sidebar h1 {
|
||||||
|
font-family: var(--title-font);
|
||||||
|
font-size: 1.5rem;
|
||||||
|
font-weight: 900;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#sidebar h6 {
|
||||||
|
font-weight: 100;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#buttons {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
#buttons h1 {
|
||||||
|
font-family: var(--title-font);
|
||||||
|
font-size: 1.3rem;
|
||||||
|
font-weight: 900;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
text-shadow: var(--text-color) 1px 0 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#buttons ul {
|
||||||
|
list-style-type: none;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
margin-top: 5px;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.vsmoltext {
|
||||||
|
font-size: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
main {
|
||||||
|
grid-area: main;
|
||||||
|
width: 761px;
|
||||||
|
height: 100%;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
header {
|
||||||
|
backdrop-filter: blur(2px) brightness(0.6);
|
||||||
|
border: var(--secondary-background-color) 2px solid;
|
||||||
|
border-radius: 10px;
|
||||||
|
padding: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
header div.row {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
margin: 0;
|
||||||
|
gap: 1.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
header div.column {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: center;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
header img {
|
||||||
|
width: 9rem;
|
||||||
|
height: 9rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
header h1 {
|
||||||
|
font-family: var(--title-font);
|
||||||
|
font-size: 5rem;
|
||||||
|
font-weight: 900;
|
||||||
|
padding: 0;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
header h2 {
|
||||||
|
font-family: var(--title-font);
|
||||||
|
font-size: 1.75rem;
|
||||||
|
font-weight: 100;
|
||||||
|
padding: 0;
|
||||||
|
margin: 0;
|
||||||
|
position: relative;
|
||||||
|
top: -1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
main section {
|
||||||
|
backdrop-filter: blur(2px) brightness(0.6);
|
||||||
|
width: 100%;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
border: var(--secondary-background-color) 2px solid;
|
||||||
|
border-radius: 10px;
|
||||||
|
padding: 15px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
main section h1 {
|
||||||
|
font-size: 3rem;
|
||||||
|
font-weight: 900;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
main section h2 {
|
||||||
|
font-size: 1.5rem;
|
||||||
|
font-weight: 900;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
main section h6 {
|
||||||
|
font-size: 0.7rem;
|
||||||
|
font-weight: 100;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
main section p {
|
||||||
|
font-size: 1rem;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
font-weight: 300;
|
||||||
|
}
|
||||||
|
|
||||||
|
main section a {
|
||||||
|
color: var(--primary-color);
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.smileos {
|
||||||
|
border-image: var(--smileos2-box);
|
||||||
|
padding: 54px 15px 12px;
|
||||||
|
image-rendering: pixelated;
|
||||||
|
font-size: 1.25rem;
|
||||||
|
font-family: var(--smileos2-font);
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
#furry {
|
||||||
|
position: fixed;
|
||||||
|
left: 0;
|
||||||
|
top: 0;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
opacity: 0.1;
|
||||||
|
background-image: url('/static/content/general_images/background.png');
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-position: 50% 0;
|
||||||
|
background-size: cover;
|
||||||
|
z-index: -1;
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.haj {
|
||||||
|
width: 100%;
|
||||||
|
filter: drop-shadow(0 0 0.5rem rgb(88, 214, 245));
|
||||||
|
}
|
||||||
|
|
||||||
|
.irken {
|
||||||
|
font-family: var(--irken-font);
|
||||||
|
}
|
||||||
|
|
||||||
|
.scratch {
|
||||||
|
font-family: var(--scratch-font);
|
||||||
|
}
|
||||||
|
|
||||||
|
.ultrafont {
|
||||||
|
font-family: var(--ultrafont-font);
|
||||||
|
}
|
||||||
|
|
||||||
|
#alt-nav {
|
||||||
|
display: none;
|
||||||
|
backdrop-filter: blur(2px) brightness(0.6);
|
||||||
|
width: 100%;
|
||||||
|
border: var(--secondary-background-color) 2px solid;
|
||||||
|
border-radius: 10px;
|
||||||
|
padding: 15px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
#alt-nav ul {
|
||||||
|
list-style-type: none;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
flex-direction: row;
|
||||||
|
gap: 1.5rem;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
#alt-nav ul li {
|
||||||
|
width: fit-content;
|
||||||
|
}
|
||||||
|
#alt-nav ul li a {
|
||||||
|
color: var(--text-color);
|
||||||
|
text-decoration: none;
|
||||||
|
font-weight: 100;
|
||||||
|
transition: all 0.2s ease-in-out
|
||||||
|
}
|
||||||
|
|
||||||
|
#alt-nav ul li a:hover {
|
||||||
|
color: var(--primary-color);
|
||||||
|
font-weight: 900;
|
||||||
|
}
|
||||||
|
|
||||||
|
.title-font {
|
||||||
|
font-family: var(--title-font);
|
||||||
|
}
|
||||||
|
|
||||||
|
.flex-col {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.flex-row {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
gap: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.no-sect {
|
||||||
|
backdrop-filter: none;
|
||||||
|
border: none;
|
||||||
|
border-radius: 0;
|
||||||
|
padding: 0;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
code {
|
||||||
|
background-color: var(--secondary-background-color-but-slightly-transparent);
|
||||||
|
padding: 4px 6px;
|
||||||
|
border-radius: 4px;
|
||||||
|
font-size: 0.9rem;
|
||||||
|
color: var(--primary-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
#toaster-wave {
|
||||||
|
position: absolute;
|
||||||
|
left: -145px;
|
||||||
|
top: 200px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.webring {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.webring a {
|
||||||
|
text-decoration: none;
|
||||||
|
color: var(--primary-color);
|
||||||
|
font-size: 1.2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.webring a:hover {
|
||||||
|
font-weight: 900;
|
||||||
|
text-shadow: 0px 0px 10px var(--primary-color-but-slightly-transparent);
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (max-width: 1240px) {
|
||||||
|
#toaster-wave {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (max-width: 1000px) {
|
||||||
|
body {
|
||||||
|
background-color: var(--background-color);
|
||||||
|
background-image: url("https://blinkies.cafe/purple-stars-bg.gif");
|
||||||
|
color: var(--text-color);
|
||||||
|
font-size: var(--font-size);
|
||||||
|
font-family: var(--font-family);
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: auto;
|
||||||
|
grid-template-rows: 1fr;
|
||||||
|
grid-template-areas: "main";
|
||||||
|
margin: 7% 0 7% 0;
|
||||||
|
gap: 1rem;
|
||||||
|
justify-content: center;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
#sidebar {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
#alt-nav {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
main {
|
||||||
|
width: 100%;
|
||||||
|
box-sizing: border-box;
|
||||||
|
padding: 0 1rem 0 1rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (max-width: 650px) {
|
||||||
|
.flex-row {
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
.flex-col {
|
||||||
|
flex-direction: row;
|
||||||
|
}
|
||||||
|
|
||||||
|
header img {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
header div.row {
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
header div {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
header h2 {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
div#spotify {
|
||||||
|
box-sizing: border-box;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-size: contain;
|
||||||
|
height: 100%;
|
||||||
|
width: auto;
|
||||||
|
aspect-ratio: 1/1;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
section#directory ul {
|
||||||
|
list-style: none;
|
||||||
|
padding: 0;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
section#directory li {
|
||||||
|
margin: 0.5rem 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
section#directory a:hover {
|
||||||
|
scale: 1.05;
|
||||||
|
}
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
section h2 {
|
||||||
|
margin-top: 2rem !important;
|
||||||
|
}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
.bluescreen {
|
||||||
|
background-color: #0077D6;
|
||||||
|
color: #fff;
|
||||||
|
padding:40px;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 20px;
|
||||||
|
}
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
.gallery {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gallery .gallery-images {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: space-between;
|
||||||
|
gap: 1rem;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gallery .gallery-images img {
|
||||||
|
max-width: 100%;
|
||||||
|
height: auto;
|
||||||
|
border-radius: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gallery h2.gallery-date {
|
||||||
|
position: relative;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
}
|
||||||
@@ -0,0 +1,123 @@
|
|||||||
|
.blinkies {
|
||||||
|
justify-content: center;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.blinkies img {
|
||||||
|
width: 150px;
|
||||||
|
height: 20px;
|
||||||
|
transition: all 0.2s ease-in-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
.blinkies img:hover {
|
||||||
|
transform: scale(1.1) rotate(5deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
.blinkies img:nth-child(odd):hover {
|
||||||
|
transform: scale(1.1) rotate(-5deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
.stamps {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
padding: 10px;
|
||||||
|
gap: 5px;
|
||||||
|
justify-content: center;
|
||||||
|
align-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stamps img {
|
||||||
|
width: 99px;
|
||||||
|
height: 56px;
|
||||||
|
transition: all 0.2s ease-in-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stamps img:hover {
|
||||||
|
transform: scale(1.1) rotate(5deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
.stamps img:nth-child(odd):hover {
|
||||||
|
transform: scale(1.1) rotate(-5deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
#listenbrainz {
|
||||||
|
background-image: none;
|
||||||
|
backdrop-filter: blur(2px) brightness(0.6);
|
||||||
|
border: var(--secondary-background-color) 2px solid;
|
||||||
|
border-radius: 10px;
|
||||||
|
padding: 15px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-size: contain;
|
||||||
|
height: 300px;
|
||||||
|
width: 300px;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
#listenbrainz-title {
|
||||||
|
font-size: 1.2rem;
|
||||||
|
font-weight: 900;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
mix-blend-mode: difference;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
#listenbrainz-artist {
|
||||||
|
color: white;
|
||||||
|
font-size: 0.7rem;
|
||||||
|
font-weight: 900;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
mix-blend-mode: difference;
|
||||||
|
}
|
||||||
|
|
||||||
|
#listenbrainz-live {
|
||||||
|
color: white;
|
||||||
|
font-size: 0.6rem;
|
||||||
|
font-weight: 900;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
margin-top: auto;
|
||||||
|
margin-left: auto;
|
||||||
|
background-color: gray;
|
||||||
|
border-radius: 30px;
|
||||||
|
padding: 2px 6px;
|
||||||
|
font-family: var(--ultrafont-font);
|
||||||
|
}
|
||||||
|
|
||||||
|
#button-collection {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
justify-content: center;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
#button-collection img {
|
||||||
|
transition: all 0.2s ease-in-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
#button-collection img:hover {
|
||||||
|
transform: scale(1.1) rotate(5deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
#button-collection img:nth-child(odd):hover {
|
||||||
|
transform: scale(1.1) rotate(-5deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (max-width: 650px) {
|
||||||
|
div#spotify {
|
||||||
|
box-sizing: border-box;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-size: contain;
|
||||||
|
height: 100%;
|
||||||
|
width: auto;
|
||||||
|
aspect-ratio: 1/1;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
}
|
||||||