from aiohttp import web
import aiohttp_jinja2
import jinja2
from pathlib import Path
from aiohttp_session import setup as setup_session
from aiohttp_session.cookie_storage import EncryptedCookieStorage
import os
import aiojobs # Import aiojobs
from .routes import setup_routes
from .services.user_service import UserService
from .services.config_service import ConfigService
from .middlewares import user_middleware, error_middleware
from .helpers.env_manager import ensure_env_file_exists
async def setup_services(app: web.Application):
base_path = Path(__file__).parent
data_path = base_path.parent / "data"
app["user_service"] = UserService(data_path / "users.json")
app["config_service"] = ConfigService(data_path / "config.json")
# Setup aiojobs scheduler
app["scheduler"] = await aiojobs.create_scheduler()
yield
# Cleanup aiojobs scheduler
await app["scheduler"].close()
def create_app():
# Ensure .env file exists before loading any configurations
project_root = Path(__file__).parent.parent
ensure_env_file_exists(project_root / ".env")
app = web.Application()
# The order of middleware registration matters.
# They are executed in the order they are added.
app.middlewares.append(error_middleware)
# Setup session
secret_key = os.urandom(32)
setup_session(app, EncryptedCookieStorage(secret_key))
app.middlewares.append(user_middleware)
# Setup paths
base_path = Path(__file__).parent
static_path = base_path / "static"
templates_path = base_path / "templates"
# Setup Jinja2
aiohttp_jinja2.setup(app, loader=jinja2.FileSystemLoader(str(templates_path)))
# Setup services
app.cleanup_ctx.append(setup_services)
# Setup routes
setup_routes(app)
app.router.add_static("/static", path=str(static_path), name="static")
return app
def main():
app = create_app()
web.run_app(app)
if __name__ == "__main__":
main()