alpha v0.0971
This commit is contained in:
104
app.py
104
app.py
@@ -1,5 +1,5 @@
|
||||
|
||||
from flask import Flask, render_template, request, redirect, url_for, flash, Response, jsonify, session, send_from_directory
|
||||
from flask import Flask, render_template, request, redirect, url_for, flash, Response, jsonify, session, send_from_directory, send_file
|
||||
try:
|
||||
import psycopg
|
||||
except ModuleNotFoundError:
|
||||
@@ -16,6 +16,13 @@ import re
|
||||
import os
|
||||
import json
|
||||
import sys
|
||||
from database_maintenance import (
|
||||
DatabaseMaintenanceBusy,
|
||||
DatabaseMaintenanceError,
|
||||
DatabaseMaintenanceManager,
|
||||
InvalidBackupFile,
|
||||
PostgreSqlToolNotFound,
|
||||
)
|
||||
from handlers import computers as computers_handlers
|
||||
from handlers import projectors as projectors_handlers
|
||||
from routes.projectors import _normalize_board_fields
|
||||
@@ -79,6 +86,7 @@ APP_PORT = _integer_setting(APPLICATION_SETTINGS, "port", 5050)
|
||||
app = Flask(__name__)
|
||||
app.secret_key = "secret"
|
||||
app.config["DB_INITIALIZED"] = False
|
||||
database_maintenance = DatabaseMaintenanceManager(DB_CONFIG)
|
||||
CLIENT_AGENT_TOKEN = "change-me-client-token"
|
||||
CLIENT_TEST_OFFLINE_AFTER_SECONDS = 35
|
||||
|
||||
@@ -2640,6 +2648,100 @@ def logout():
|
||||
return redirect(url_for("login"))
|
||||
|
||||
|
||||
def database_admin_api(view):
|
||||
@wraps(view)
|
||||
def wrapper(*args, **kwargs):
|
||||
if "user" not in session:
|
||||
return jsonify(ok=False, error="Требуется авторизация."), 401
|
||||
if session.get("role") != "admin":
|
||||
return jsonify(ok=False, error="Требуются права администратора."), 403
|
||||
return view(*args, **kwargs)
|
||||
|
||||
return wrapper
|
||||
|
||||
|
||||
def _database_size_bytes():
|
||||
conn = get_conn()
|
||||
try:
|
||||
cur = conn.cursor()
|
||||
cur.execute("SELECT pg_database_size(current_database())")
|
||||
row = cur.fetchone()
|
||||
return int(row[0] or 0) if row else 0
|
||||
finally:
|
||||
conn.close()
|
||||
|
||||
|
||||
@app.route("/api/database/backup/start", methods=["POST"])
|
||||
@database_admin_api
|
||||
def database_backup_start():
|
||||
try:
|
||||
try:
|
||||
database_size = _database_size_bytes()
|
||||
except Exception:
|
||||
database_size = 0
|
||||
job_id = database_maintenance.start_backup(
|
||||
session.get("user"),
|
||||
estimated_database_size=database_size,
|
||||
)
|
||||
return jsonify(ok=True, job_id=job_id), 202
|
||||
except (DatabaseMaintenanceBusy, PostgreSqlToolNotFound) as exc:
|
||||
return jsonify(ok=False, error=str(exc)), 409
|
||||
except DatabaseMaintenanceError as exc:
|
||||
return jsonify(ok=False, error=str(exc)), 400
|
||||
except Exception:
|
||||
app.logger.exception("Failed to start a database backup")
|
||||
return jsonify(ok=False, error="Не удалось запустить резервное копирование."), 500
|
||||
|
||||
|
||||
@app.route("/api/database/restore/start", methods=["POST"])
|
||||
@database_admin_api
|
||||
def database_restore_start():
|
||||
uploaded_file = request.files.get("backup_file")
|
||||
if not uploaded_file or not uploaded_file.filename:
|
||||
return jsonify(ok=False, error="Выберите файл резервной копии."), 400
|
||||
try:
|
||||
job_id = database_maintenance.start_restore(
|
||||
session.get("user"),
|
||||
uploaded_file,
|
||||
uploaded_file.filename,
|
||||
)
|
||||
return jsonify(ok=True, job_id=job_id), 202
|
||||
except DatabaseMaintenanceBusy as exc:
|
||||
return jsonify(ok=False, error=str(exc)), 409
|
||||
except (InvalidBackupFile, PostgreSqlToolNotFound, DatabaseMaintenanceError) as exc:
|
||||
return jsonify(ok=False, error=str(exc)), 400
|
||||
except Exception:
|
||||
app.logger.exception("Failed to start a database restore")
|
||||
return jsonify(ok=False, error="Не удалось запустить восстановление базы данных."), 500
|
||||
|
||||
|
||||
@app.route("/api/database/jobs/<job_id>")
|
||||
@database_admin_api
|
||||
def database_job_status(job_id):
|
||||
job = database_maintenance.get_job(job_id, session.get("user"))
|
||||
if not job:
|
||||
return jsonify(ok=False, error="Операция не найдена."), 404
|
||||
if job.get("kind") == "restore" and job.get("status") == "success":
|
||||
app.config["DB_INITIALIZED"] = False
|
||||
return jsonify(ok=True, job=job)
|
||||
|
||||
|
||||
@app.route("/api/database/backup/<job_id>/download")
|
||||
@database_admin_api
|
||||
def database_backup_download(job_id):
|
||||
backup = database_maintenance.get_backup_download(job_id, session.get("user"))
|
||||
if not backup:
|
||||
return jsonify(ok=False, error="Файл резервной копии не найден."), 404
|
||||
path, filename = backup
|
||||
return send_file(
|
||||
path,
|
||||
mimetype="application/octet-stream",
|
||||
as_attachment=True,
|
||||
download_name=filename,
|
||||
conditional=True,
|
||||
)
|
||||
|
||||
|
||||
@app.route("/network")
|
||||
@login_required
|
||||
def network():
|
||||
|
||||
Reference in New Issue
Block a user