from flask import Flask, session from dotenv import load_dotenv from .models import Avatars, Users from .auth import digest from .routes.users import is_logged_in, get_active_user from .constants import ( PermissionLevel, InfoboxKind, InfoboxIcons, InfoboxHTMLClass ) from datetime import datetime import os import time import secrets def create_default_avatar(): if Avatars.count() == 0: print("Creating default avatar reference") Avatars.create({ "file_path": "/static/avatars/default.webp", "uploaded_at": int(time.time()) }) def create_admin(): username = "admin" if Users.count({"username": username}) == 0: print("!!!!!Creating admin account!!!!!") password_length = 16 password = secrets.token_urlsafe(password_length) hashed = digest(password) Users.create({ "username": username, "password_hash": hashed, "permission": PermissionLevel.ADMIN.value, }) print(f"!!!!!Administrator account created, use '{username}' as the login and '{password}' as the password. This will only be shown once!!!!!") def create_deleted_user(): username = "DeletedUser" if Users.count({"username": username}) == 0: print("Creating DeletedUser") Users.create({ "username": username, "password_hash": "", "permission": PermissionLevel.SYSTEM.value, }) def create_app(): app = Flask(__name__) if os.getenv("PYROM_PROD") is None: app.static_folder = os.path.join(os.path.dirname(__file__), "../data/static") app.debug = True app.config["DB_PATH"] = "data/db/db.dev.sqlite" load_dotenv() else: app.config["DB_PATH"] = "data/db/db.prod.sqlite" app.config["SECRET_KEY"] = os.getenv("FLASK_SECRET_KEY") app.config['AVATAR_UPLOAD_PATH'] = 'data/static/avatars/' app.config['MAX_CONTENT_LENGTH'] = 1000 * 1000 os.makedirs(os.path.dirname(app.config["DB_PATH"]), exist_ok = True) with app.app_context(): from .schema import create as create_tables from .migrations import run_migrations create_tables() run_migrations() create_default_avatar() create_admin() create_deleted_user() from app.routes.app import bp as app_bp from app.routes.topics import bp as topics_bp from app.routes.threads import bp as threads_bp from app.routes.users import bp as users_bp from app.routes.mod import bp as mod_bp from app.routes.api import bp as api_bp app.register_blueprint(app_bp) app.register_blueprint(topics_bp) app.register_blueprint(threads_bp) app.register_blueprint(users_bp) app.register_blueprint(mod_bp) app.register_blueprint(api_bp) app.config['SESSION_COOKIE_SECURE'] = True @app.before_request def make_session_permanent(): session.permanent = True commit = "" with open('.git/refs/heads/main') as f: commit = f.read().strip() @app.context_processor def inject_constants(): return { "InfoboxIcons": InfoboxIcons, "InfoboxHTMLClass": InfoboxHTMLClass, "InfoboxKind": InfoboxKind, "__commit": commit, } @app.context_processor def inject_auth(): return {"is_logged_in": is_logged_in, "get_active_user": get_active_user, "active_user": get_active_user()} @app.template_filter("ts_datetime") def ts_datetime(ts, format): return datetime.utcfromtimestamp(ts or int(time.time())).strftime(format) @app.template_filter("pluralize") def pluralize(number, singular = "", plural = "s"): if number == 1: return singular return plural return app