major update

This commit is contained in:
2026-03-03 14:11:55 +00:00
parent 6e92e40f1c
commit 1a5380e17e
33 changed files with 193 additions and 231 deletions

View File

@@ -1,22 +1,21 @@
# Imports
from flask import Blueprint, render_template, abort
from os import getenv as env
import logging, os, markdown
import os, markdown
# Create blueprint
bp = Blueprint(
'dynamic_routes',
__name__,
template_folder=env('TEMPLATE_FOLDER', default='templates'),
static_folder=env('STATIC_FOLDER', default='../static')
)
bp = Blueprint('dynamic_routes', __name__)
template_folder = "templates"
# helper func
def get_path(file) -> str:
return os.path.join(template_folder, "pages", file)
# Create logger
log = logging.getLogger(__name__)
# Get all files in folder
def ListFiles(path):
path = os.path.join(bp.template_folder, 'pages', path)
path = get_path(path)
files = []
for root, dirs, files_in_dir in os.walk(path):
for file in files_in_dir:
@@ -25,11 +24,12 @@ def ListFiles(path):
files.append(os.path.relpath(os.path.join(root, dir), path) + '/')
return files
# Catch-all route for generic pages
@bp.route('/<path:filename>')
def catch_all(filename):
if os.path.exists(os.path.join(bp.template_folder, 'pages', filename)):
if os.path.isdir(os.path.join(bp.template_folder, 'pages', 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,
@@ -38,11 +38,11 @@ def catch_all(filename):
return render_template(f'pages/{filename}')
elif os.path.exists(os.path.join(bp.template_folder, 'pages', filename + '.html')):
elif os.path.exists(get_path(filename + '.html')):
return render_template(f'pages/{filename}.html')
elif os.path.exists(os.path.join(bp.template_folder, 'pages', filename + '.md')):
output = markdown.markdown(open(os.path.join(bp.template_folder, 'pages', filename + '.md'), "r").read())
elif os.path.exists(get_path(filename + '.md')):
output = markdown.markdown(open(get_path(filename + '.md'), "r").read())
return render_template(
f'bases/md.html',
title = filename.split("/")[-1],

39
src/errors.py Normal file
View File

@@ -0,0 +1,39 @@
from flask import Blueprint, render_template
from werkzeug.exceptions import HTTPException
from os import getenv as env
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,
name = error.name
), error.code

74
src/main.py Normal file
View File

@@ -0,0 +1,74 @@
# IMPORTS
from flask import Flask, render_template
from dotenv import load_dotenv
from os import getenv as env
import logging
try:
import src.dynamic_routes as dynamic_routes
import src.errors as errors
import src.pg_log as pg_log
except ImportError:
import dynamic_routes, errors, pg_log
# ENV
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.")
# CREATE FLASK APP
app = Flask(
__name__,
template_folder="../templates",
static_folder="../static"
)
# BLUEPRINTS
app.register_blueprint(errors.bp, url_prefix="/errors")
app.register_blueprint(dynamic_routes.bp, url_prefix="/")
# ROUTES
@app.route("/")
def index():
return render_template("index.html")
@app.route("/toaster")
def toaster():
return render_template("toaster.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)

35
src/pg_log.py Normal file
View File

@@ -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()

View File

@@ -1,52 +0,0 @@
# Imports
from flask import Blueprint, render_template
from werkzeug.exceptions import HTTPException
from os import getenv as env
import logging
# Create blueprint
bp = Blueprint(
'error_handlers',
__name__,
template_folder=env('TEMPLATE_FOLDER', default='../templates'),
static_folder=env('STATIC_FOLDER', default='../static')
)
# Create logger
log = logging.getLogger(__name__)
# Route for 500 error
@bp.route('/500')
@bp.app_errorhandler(500)
def internal_server_error(error:HTTPException=None):
return render_template('errors/500.html', error=error), 500
# Route for 404 error
@bp.route('/404')
@bp.app_errorhandler(404)
def not_found(error:HTTPException=None):
return render_template('errors/404.html', error=error), 404
# Route for 400 error
@bp.route('/400')
@bp.app_errorhandler(400)
def bad_request(error:HTTPException=None):
return render_template('errors/400.html', error=error), 400
# Route for all other errors
@bp.route('/idk')
@bp.app_errorhandler(Exception)
def nah(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="I honestly dont know",
name="I'm a teapot"
), 418

View File

@@ -1,63 +0,0 @@
# Imports
from flask import Flask, render_template, send_file
from flask_session import Session
from dotenv import load_dotenv
from os import getenv as env
import logging
import src.routes.error_handlers
import src.routes.dynamic_routes
# Load env
load_dotenv()
# Create logger
stream_handler = logging.StreamHandler()
stream_handler.setFormatter(logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s'))
stream_handler.setLevel(logging.INFO)
file_handler = logging.FileHandler(filename='app.log')
file_handler.setFormatter(logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s'))
file_handler.setLevel(logging.DEBUG)
# Add handlers to the logger
log = logging.getLogger()
log.setLevel(logging.DEBUG)
log.addHandler(stream_handler)
log.addHandler(file_handler)
log.info("Logging initialized")
# Create flask app
app = Flask(
__name__,
template_folder=env('TEMPLATE_FOLDER', default='../templates'),
static_folder=env('STATIC_FOLDER', default='../static')
)
# Configure sessions
app.config["SESSION_PERMANENT"] = True
app.config["SESSION_TYPE"] = "filesystem"
Session(app)
# Load routes
app.register_blueprint(src.routes.error_handlers.bp, url_prefix='/error')
app.register_blueprint(src.routes.dynamic_routes.bp, url_prefix='/')
# Generic routes
@app.route('/')
def index():
return render_template('index.html')
@app.route('/favicon.ico')
def favicon():
return send_file('../static/content/other/favicon.ico')
@app.route('/robots.txt')
def robots():
return send_file('../static/content/other/robots.txt')
# Route for sitemap.xml
@app.route('/sitemap.xml')
def sitemap():
return send_file('../static/content/other/sitemap.xml')