150 lines
4.4 KiB
Python
150 lines
4.4 KiB
Python
import os
|
|
|
|
import click
|
|
from flask import Flask
|
|
from flask.cli import with_appcontext
|
|
|
|
from app.config import Config
|
|
from app.extensions import db, login_manager
|
|
from app.models import AdminUser
|
|
from app.routes.apply import apply_bp, restore_bp, settings_bp
|
|
from app.routes.auth import auth_bp
|
|
from app.routes.main import main_bp
|
|
from app.routes.mirrors import mirrors_bp
|
|
from app.routes.profiles import profiles_bp
|
|
from app.seed import seed_all
|
|
from app.services.applier import ensure_initial_backup, restore_initial
|
|
from app.services.backup import restore_backup
|
|
from app.services.scheduler import init_scheduler
|
|
|
|
|
|
def create_app(config_class=Config) -> Flask:
|
|
app = Flask(__name__)
|
|
app.config.from_object(config_class)
|
|
Config.ensure_dirs()
|
|
|
|
db.init_app(app)
|
|
login_manager.init_app(app)
|
|
|
|
app.register_blueprint(auth_bp)
|
|
app.register_blueprint(main_bp)
|
|
app.register_blueprint(mirrors_bp)
|
|
app.register_blueprint(profiles_bp)
|
|
app.register_blueprint(apply_bp)
|
|
app.register_blueprint(restore_bp)
|
|
app.register_blueprint(settings_bp)
|
|
|
|
with app.app_context():
|
|
db.create_all()
|
|
seed_all()
|
|
_ensure_admin_user()
|
|
ensure_initial_backup()
|
|
|
|
if not app.config.get("TESTING") and not os.environ.get("DISABLE_SCHEDULER"):
|
|
init_scheduler(app)
|
|
|
|
_register_cli(app)
|
|
return app
|
|
|
|
|
|
def _ensure_admin_user() -> None:
|
|
if AdminUser.query.first():
|
|
return
|
|
user = AdminUser(username=Config.ADMIN_USERNAME)
|
|
user.set_password(Config.ADMIN_PASSWORD)
|
|
db.session.add(user)
|
|
db.session.commit()
|
|
|
|
|
|
def _register_cli(app: Flask) -> None:
|
|
@app.cli.command("init-db")
|
|
@with_appcontext
|
|
def init_db():
|
|
db.create_all()
|
|
seed_all()
|
|
_ensure_admin_user()
|
|
ensure_initial_backup()
|
|
click.echo("Database initialized.")
|
|
|
|
@app.cli.command("create-admin")
|
|
@click.argument("username")
|
|
@click.argument("password")
|
|
@with_appcontext
|
|
def create_admin(username, password):
|
|
user = AdminUser.query.filter_by(username=username).first()
|
|
if not user:
|
|
user = AdminUser(username=username)
|
|
db.session.add(user)
|
|
user.set_password(password)
|
|
db.session.commit()
|
|
click.echo(f"Admin user '{username}' ready.")
|
|
|
|
|
|
@click.group()
|
|
def cli():
|
|
"""Mirror Manager CLI — قابل استفاده از SSH"""
|
|
|
|
|
|
@cli.command()
|
|
@click.option("--initial", is_flag=True, help="بازگردانی تنظیمات اولیه")
|
|
@click.option("--backup", default=None, help="مسیر backup مشخص")
|
|
def restore(initial, backup):
|
|
os.environ["DISABLE_SCHEDULER"] = "1"
|
|
app = create_app()
|
|
with app.app_context():
|
|
if initial:
|
|
result = restore_initial()
|
|
elif backup:
|
|
result = restore_backup(backup)
|
|
else:
|
|
click.echo("یکی از --initial یا --backup را مشخص کنید.")
|
|
return
|
|
if result.get("success"):
|
|
click.echo("بازگردانی موفق:")
|
|
for item in result.get("restored", []):
|
|
click.echo(f" - {item}")
|
|
else:
|
|
click.echo(f"خطا: {result.get('error')}")
|
|
|
|
|
|
@cli.command()
|
|
def disable():
|
|
container = os.environ.get("MIRROR_CONTAINER_NAME", "mirror-manager")
|
|
import subprocess
|
|
|
|
result = subprocess.run(["docker", "stop", container], capture_output=True, text=True)
|
|
if result.returncode == 0:
|
|
click.echo(f"سرویس {container} متوقف شد.")
|
|
else:
|
|
click.echo(f"خطا: {result.stderr or result.stdout}")
|
|
click.echo("دستی: docker stop mirror-manager")
|
|
|
|
|
|
@cli.command()
|
|
def enable():
|
|
container = os.environ.get("MIRROR_CONTAINER_NAME", "mirror-manager")
|
|
import subprocess
|
|
|
|
result = subprocess.run(["docker", "start", container], capture_output=True, text=True)
|
|
if result.returncode == 0:
|
|
click.echo(f"سرویس {container} راهاندازی شد.")
|
|
else:
|
|
click.echo(f"خطا: {result.stderr or result.stdout}")
|
|
click.echo("دستی: docker compose up -d")
|
|
|
|
|
|
@cli.command()
|
|
def status():
|
|
os.environ["DISABLE_SCHEDULER"] = "1"
|
|
app = create_app()
|
|
with app.app_context():
|
|
from app.services.applier import get_system_status
|
|
|
|
info = get_system_status()
|
|
click.echo(f"Ubuntu: {info.get('ubuntu_description')}")
|
|
click.echo(f"Host root: {info.get('host_root')}")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
cli()
|