2023-02-15 16:00:30 +04:00
|
|
|
"""Flask web application main script"""
|
2023-02-14 19:53:57 +04:00
|
|
|
|
2023-02-15 16:00:30 +04:00
|
|
|
import os
|
|
|
|
import secrets
|
2023-02-15 19:55:06 +04:00
|
|
|
from typing import Optional
|
|
|
|
from typing import Type, List
|
2023-02-14 19:53:57 +04:00
|
|
|
|
2023-02-16 18:19:58 +04:00
|
|
|
from pathlib import Path
|
|
|
|
from dotenv import load_dotenv
|
|
|
|
|
2023-02-14 19:53:57 +04:00
|
|
|
from flask import Flask
|
|
|
|
|
2023-02-16 18:19:58 +04:00
|
|
|
from . import exts
|
2023-02-15 19:55:06 +04:00
|
|
|
from .routes import Routes
|
|
|
|
from . import pages
|
2023-02-16 18:19:58 +04:00
|
|
|
from . import admin
|
2023-02-15 17:34:49 +04:00
|
|
|
from . import errors
|
2023-02-15 19:55:06 +04:00
|
|
|
from . import db
|
|
|
|
|
|
|
|
routes: List[Type[Routes]] = [
|
|
|
|
pages.RoutePages,
|
2023-02-16 18:19:58 +04:00
|
|
|
admin.RouteAdmin,
|
2023-02-15 19:55:06 +04:00
|
|
|
errors.RouteErrors,
|
|
|
|
]
|
2023-02-15 17:34:49 +04:00
|
|
|
|
2023-02-14 19:53:57 +04:00
|
|
|
|
2023-02-15 16:00:30 +04:00
|
|
|
def create_app() -> Flask:
|
|
|
|
"""Flask app factory function"""
|
2023-02-14 19:53:57 +04:00
|
|
|
|
2023-02-15 17:34:49 +04:00
|
|
|
# Create an app object
|
2023-02-15 16:00:30 +04:00
|
|
|
app = Flask(
|
|
|
|
__name__,
|
2023-02-15 17:34:49 +04:00
|
|
|
static_folder='../static',
|
|
|
|
template_folder='../templates',
|
2023-02-15 16:00:30 +04:00
|
|
|
instance_relative_config=True,
|
|
|
|
)
|
2023-02-16 18:19:58 +04:00
|
|
|
# Load sample configuation
|
|
|
|
if app.debug:
|
|
|
|
load_dotenv(
|
|
|
|
Path(__file__).parent.parent / '.env'
|
|
|
|
)
|
2023-02-15 17:34:49 +04:00
|
|
|
# Get the token from environment
|
|
|
|
# or generate it using secrets
|
2023-02-15 16:00:30 +04:00
|
|
|
app.config['SECRET_KEY'] = os.getenv(
|
|
|
|
'SECRET_KEY',
|
|
|
|
secrets.token_hex(32),
|
|
|
|
)
|
|
|
|
|
2023-02-16 18:19:58 +04:00
|
|
|
# Configurate MySQL database
|
|
|
|
db_name = os.getenv('MYSQL_DATABASE', '${REPO_NAME_SNAKE}')
|
2023-02-15 19:55:06 +04:00
|
|
|
app.config.update({
|
2023-02-16 18:19:58 +04:00
|
|
|
'MYSQL_DATABASE_HOST': os.getenv('MYSQL_HOST', 'localhost'),
|
|
|
|
'MYSQL_DATABASE_PORT': parseint(os.getenv('MYSQL_PORT'), 3306),
|
|
|
|
'MYSQL_DATABASE_USER': os.getenv('MYSQL_USER', 'root'),
|
|
|
|
'MYSQL_DATABASE_PASSWORD': os.getenv('MYSQL_PASSWORD', ''),
|
2023-02-15 19:55:06 +04:00
|
|
|
})
|
2023-02-16 18:19:58 +04:00
|
|
|
|
|
|
|
# Load extensions
|
|
|
|
for ext in exts.exts:
|
|
|
|
ext.init_app(app)
|
|
|
|
|
|
|
|
db.create_db(db_name)
|
|
|
|
with app.app_context():
|
|
|
|
db.init_db()
|
2023-02-15 19:55:06 +04:00
|
|
|
|
2023-02-15 17:34:49 +04:00
|
|
|
# Create instance/ directory
|
2023-02-15 16:00:30 +04:00
|
|
|
try:
|
|
|
|
os.makedirs(app.instance_path)
|
|
|
|
except OSError:
|
|
|
|
pass
|
|
|
|
|
2023-02-15 19:55:06 +04:00
|
|
|
# Add all routes
|
|
|
|
for r in routes:
|
|
|
|
r(app).add_routes()
|
2023-02-15 17:34:49 +04:00
|
|
|
|
2023-02-15 16:00:30 +04:00
|
|
|
return app
|
2023-02-15 19:55:06 +04:00
|
|
|
|
|
|
|
|
|
|
|
def parseint(
|
|
|
|
value: Optional[str],
|
|
|
|
default: int) -> Optional[int]:
|
|
|
|
"""Parses integer from the string,
|
|
|
|
returns default value on error
|
|
|
|
|
|
|
|
Args:
|
|
|
|
value (Optional[str]): String or None
|
|
|
|
default (int): Default value
|
|
|
|
|
|
|
|
Returns:
|
|
|
|
Integer or None
|
|
|
|
"""
|
|
|
|
|
|
|
|
try:
|
|
|
|
return int(value or default)
|
|
|
|
except ValueError:
|
|
|
|
return default
|