from flask import Flask, request from flask_migrate import Migrate # Add this line from .config import Config from .db import db from .models import init_schedule_config from .models import ActivityLog, ActivityCategory from .blueprints import register_blueprints from .scheduler import ScraperScheduler def create_app(test_config=None): app = Flask(__name__, instance_relative_config=True) app.config.from_object(Config) # Ensure the instance folder exists import os try: os.makedirs(app.instance_path) except OSError: pass # Set the database URI to use absolute path if it's the default relative path if app.config['SQLALCHEMY_DATABASE_URI'] == "sqlite:///instance/papers.db": db_path = os.path.join(app.instance_path, 'papers.db') app.config['SQLALCHEMY_DATABASE_URI'] = f'sqlite:///{db_path}' if test_config: app.config.update(test_config) db.init_app(app) migrate = Migrate(app, db) with app.app_context(): db.create_all() init_schedule_config() # Initialize APScheduler scheduler = ScraperScheduler(app) # Store scheduler in app config for access from other modules app.config['SCHEDULER'] = scheduler @app.context_processor def inject_app_title(): return {"app_title": app.config["APP_TITLE"]} register_blueprints(app) @app.before_request def before_request(): # Skip logging for static files, health checks, or other frequent requests if request.path.startswith('/static/') or request.path == '/health' or request.path == '/favicon.ico': return # Skip task status checks to avoid log spam if request.path.startswith('/task_status/'): return action = request.endpoint or request.path or "unknown_request" ActivityLog.log_gui_interaction( action=action, description=f"Request to {request.path}", extra={"method": request.method, "url": request.url} ) return app