# app/__init__.py import click from flask import Flask from flask.cli import with_appcontext from flask_sqlalchemy import SQLAlchemy from flask_migrate import Migrate from werkzeug.middleware.proxy_fix import ProxyFix from sqlalchemy import event from sqlalchemy.engine import Engine import sqlite3 db = SQLAlchemy() migrate = Migrate() # Celery instance - will be configured with app context in create_app celery = None # ============================================================================= # CLI Commands # ============================================================================= @click.command("version-check") @with_appcontext def version_check_command(): """Check app version and run data migrations if needed (e.g., phash recomputation).""" from app.utils.version_migration import check_and_run_migrations check_and_run_migrations() @click.command("celery-worker") @click.option('--queues', '-Q', default='scan,import,thumbnail,sidecar,default', help='Comma-separated list of queues to consume') @click.option('--concurrency', '-c', default=2, type=int, help='Number of worker processes') @with_appcontext def celery_worker_command(queues, concurrency): """Start a Celery worker for processing import tasks.""" from app.celery_app import celery as celery_app celery_app.worker_main([ 'worker', f'--queues={queues}', f'--concurrency={concurrency}', '--loglevel=info' ]) @click.command("celery-beat") @with_appcontext def celery_beat_command(): """Start Celery Beat scheduler for periodic tasks.""" from app.celery_app import celery as celery_app celery_app.worker_main([ 'beat', '--loglevel=info' ]) @event.listens_for(Engine, "connect") def set_sqlite_pragma(dbapi_connection, connection_record): # Only apply to SQLite connections if isinstance(dbapi_connection, sqlite3.Connection): cursor = dbapi_connection.cursor() cursor.execute("PRAGMA foreign_keys = ON") cursor.close() def create_app(config_class='config.Config'): app = Flask(__name__) app.config.from_object(config_class) app.config['SQLALCHEMY_ENGINE_OPTIONS'] = { "pool_pre_ping": True } db.init_app(app) migrate.init_app(app, db) app.wsgi_app = ProxyFix(app.wsgi_app, x_for=1, x_proto=1, x_host=1, x_port=1) from app.main import main app.register_blueprint(main) @app.template_filter('datetimeformat') def datetimeformat(value, format="%Y-%m-%d"): return value.strftime(format) if value else "" # Register CLI commands app.cli.add_command(version_check_command) app.cli.add_command(celery_worker_command) app.cli.add_command(celery_beat_command) # Initialize Celery with Flask app context from app.celery_app import make_celery global celery celery = make_celery(app) app.celery = celery return app