102 lines
3.8 KiB
Python
102 lines
3.8 KiB
Python
from flask import Flask
|
|
from flask_sqlalchemy import SQLAlchemy
|
|
from flask_login import LoginManager
|
|
import os
|
|
import threading
|
|
import time
|
|
import requests
|
|
import json
|
|
|
|
db = SQLAlchemy()
|
|
login_manager = LoginManager()
|
|
|
|
def create_app():
|
|
app = Flask(__name__)
|
|
|
|
app.config['SECRET_KEY'] = os.environ.get('SECRET_KEY', 'dev-secret-key-change-in-production')
|
|
app.config['SQLALCHEMY_DATABASE_URI'] = os.environ.get('DATABASE_URL', 'sqlite:///testarena.db')
|
|
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
|
|
|
|
db.init_app(app)
|
|
login_manager.init_app(app)
|
|
login_manager.login_view = 'auth.login'
|
|
|
|
from app.models import User
|
|
|
|
@login_manager.user_loader
|
|
def load_user(user_id):
|
|
return User.query.get(int(user_id))
|
|
|
|
# Register blueprints
|
|
from app.routes.auth import auth_bp
|
|
from app.routes.admin import admin_bp
|
|
from app.routes.dashboard import dashboard_bp
|
|
from app.routes.jobs import jobs_bp
|
|
from app.routes.api import api_bp
|
|
|
|
app.register_blueprint(auth_bp)
|
|
app.register_blueprint(admin_bp)
|
|
app.register_blueprint(dashboard_bp)
|
|
app.register_blueprint(jobs_bp)
|
|
app.register_blueprint(api_bp)
|
|
|
|
with app.app_context():
|
|
db.create_all()
|
|
|
|
# Simple migration for Phase 2 columns with retry
|
|
import time
|
|
max_retries = 5
|
|
for i in range(max_retries):
|
|
try:
|
|
from sqlalchemy import text
|
|
with db.engine.connect() as conn:
|
|
# Check if remote_queue_id exists
|
|
result = conn.execute(text("SELECT column_name FROM information_schema.columns WHERE table_name='jobs' AND column_name='remote_queue_id'"))
|
|
if not result.fetchone():
|
|
print("Running Phase 2 migrations...")
|
|
conn.execute(text("ALTER TABLE jobs ADD COLUMN remote_queue_id VARCHAR(50)"))
|
|
conn.execute(text("ALTER TABLE jobs ADD COLUMN remote_task_ids TEXT"))
|
|
conn.execute(text("ALTER TABLE jobs ADD COLUMN remote_results TEXT"))
|
|
conn.execute(text("ALTER TABLE jobs ADD COLUMN queue_log TEXT"))
|
|
conn.commit()
|
|
print("Phase 2 migrations completed.")
|
|
break # Success
|
|
except Exception as e:
|
|
print(f"Migration attempt {i+1} failed: {e}")
|
|
if i < max_retries - 1:
|
|
time.sleep(2)
|
|
else:
|
|
print("Migration failed after all retries.")
|
|
|
|
# Create default admin user if not exists
|
|
try:
|
|
from app.models import User
|
|
if not User.query.filter_by(username='admin').first():
|
|
admin = User(username='admin', is_admin=True)
|
|
admin.set_password('admin123')
|
|
db.session.add(admin)
|
|
db.session.commit()
|
|
except Exception as e:
|
|
# Admin user might already exist, rollback and continue
|
|
db.session.rollback()
|
|
|
|
# Start background polling thread
|
|
def poll_jobs():
|
|
with app.app_context():
|
|
from app.models import Job
|
|
from app.routes.jobs import update_job_status_internal
|
|
while True:
|
|
try:
|
|
# Poll all jobs that are not finished
|
|
unfinished_jobs = Job.query.filter(Job.status.in_(['waiting', 'in_progress'])).all()
|
|
for job in unfinished_jobs:
|
|
update_job_status_internal(job)
|
|
except Exception as e:
|
|
print(f"[ERROR] Background polling error: {e}")
|
|
time.sleep(20)
|
|
|
|
polling_thread = threading.Thread(target=poll_jobs, daemon=True)
|
|
polling_thread.start()
|
|
|
|
return app
|