| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113 |
- import threading
- from flask import (
- Blueprint,
- current_app,
- flash,
- redirect,
- render_template,
- request,
- url_for,
- )
- from db import db, Destination
- bp = Blueprint("dest", __name__)
- @bp.route("/destinations")
- def destinations_list():
- destinations = Destination.query.order_by(Destination.name).all()
- return render_template("destinations.html", destinations=destinations)
- @bp.route("/destinations/new", methods=["GET", "POST"])
- def destination_new():
- if request.method == "POST":
- return _save_destination(None)
- return render_template("destination_form.html", dest=None)
- @bp.route("/destinations/<int:dest_id>/edit", methods=["GET", "POST"])
- def destination_edit(dest_id):
- dest = db.get_or_404(Destination, dest_id)
- if request.method == "POST":
- return _save_destination(dest)
- pub_key = _get_pub_key(dest)
- return render_template("destination_form.html", dest=dest, pub_key=pub_key)
- @bp.route("/destinations/<int:dest_id>/delete", methods=["POST"])
- def destination_delete(dest_id):
- dest = db.get_or_404(Destination, dest_id)
- db.session.delete(dest)
- db.session.commit()
- flash(f"Destination « {dest.name} » supprimée.", "success")
- return redirect(url_for("dest.destinations_list"))
- @bp.route("/destinations/<int:dest_id>/test", methods=["POST"])
- def destination_test(dest_id):
- dest = db.get_or_404(Destination, dest_id)
- from jobs.transfer import test_connection
- ok, msg = test_connection(dest, current_app.config["DATA_DIR"])
- flash(msg, "success" if ok else "error")
- return redirect(url_for("dest.destinations_list"))
- @bp.route("/archives/<path:archive_name>/transfer", methods=["POST"])
- def archive_transfer(archive_name):
- dest_id = request.form.get("destination_id", type=int)
- dest = db.get_or_404(Destination, dest_id)
- app = current_app._get_current_object()
- def _do_transfer():
- with app.app_context():
- try:
- from jobs.transfer import transfer_archive
- transfer_archive(archive_name, dest, app.config["YUNOHOST_BACKUP_DIR"],
- app.config["DATA_DIR"])
- app.logger.info(f"Transfert {archive_name} → {dest.remote_str} OK")
- except Exception as exc:
- app.logger.error(f"Transfert {archive_name} échoué : {exc}")
- threading.Thread(target=_do_transfer, daemon=True).start()
- flash(f"Transfert de « {archive_name} » vers {dest.remote_str} démarré.", "success")
- return redirect(request.referrer or url_for("jobs.index"))
- def _save_destination(dest):
- f = request.form
- name = f.get("name", "").strip()
- host = f.get("host", "").strip()
- if not name or not host:
- flash("Nom et hôte sont requis.", "error")
- return render_template("destination_form.html", dest=dest)
- is_new = dest is None
- if is_new:
- dest = Destination()
- db.session.add(dest)
- dest.name = name
- dest.host = host
- dest.port = int(f.get("port", 22) or 22)
- dest.user = f.get("user", "root").strip() or "root"
- dest.remote_path = f.get("remote_path", "/home/yunohost.backup/archives").strip()
- dest.enabled = f.get("enabled") == "1"
- db.session.flush()
- if not dest.key_name:
- from jobs.transfer import generate_key
- dest.key_name = generate_key(dest.name, current_app.config["DATA_DIR"])
- db.session.commit()
- flash(f"Destination « {dest.name} » enregistrée.", "success")
- return redirect(url_for("dest.destination_edit", dest_id=dest.id))
- def _get_pub_key(dest):
- if not dest.key_name:
- return None
- from jobs.transfer import get_public_key
- return get_public_key(dest.key_name, current_app.config["DATA_DIR"])
|