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
import dotenv # Import dotenv
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, get_or_create_session_secret_key # Import new function
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
env_file_path = project_root / ".env" # Define env_file_path
ensure_env_file_exists(env_file_path)
dotenv.load_dotenv(dotenv_path=env_file_path) # Load environment variables after ensuring .env exists
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 = get_or_create_session_secret_key(env_file_path) # Use the new helper function
setup_session(app, EncryptedCookieStorage(secret_key.decode("utf-8")))
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()