diff --git a/script_creator.py b/script_creator.py index a146d5f..7deedb2 100644 --- a/script_creator.py +++ b/script_creator.py @@ -2,31 +2,8 @@ from flask import Flask, request, jsonify import os import subprocess import base64 -import requests import redis -import shutil from threading import Lock -from webdav3.client import Client - -def safe_download_file(self, remote_path, local_path, progress=None, progress_args=()): - url = self.get_url(remote_path) - response = self.session.get(url, stream=True, headers={"Accept-Encoding": "identity"}) - content_length = response.headers.get("Content-Length") - - if content_length is None: - print(f"⚠️ Skipping file without content-length: {remote_path}") - return - - total = int(content_length) - os.makedirs(os.path.dirname(local_path), exist_ok=True) - - with open(local_path, "wb") as f: - for chunk in response.iter_content(chunk_size=1024): - if chunk: - f.write(chunk) - -# 🩹 Patch de la méthode originale -Client.download_file = safe_download_file app = Flask(__name__) @@ -49,25 +26,37 @@ def log_debug(msg): if DEBUG: print(f"🔍 DEBUG: {msg}", flush=True) -def sync_from_nextcloud(website, tmp_path): - remote_path = f"/{NEXTCLOUD_PATH}/@{website}/" - local_path = tmp_path +def write_rclone_config(): + """Write rclone config file dynamically""" + config_dir = "/tmp/rclone" + os.makedirs(config_dir, exist_ok=True) + config_path = os.path.join(config_dir, "rclone.conf") - if os.path.exists(local_path): - shutil.rmtree(local_path) - os.makedirs(local_path, exist_ok=True) + with open(config_path, "w") as f: + f.write(f"""[nextcloud] +type = webdav +url = {NEXTCLOUD_URL_DAV} +vendor = nextcloud +user = {NEXTCLOUD_USER} +pass = {NEXTCLOUD_PASSWORD}""") - options = { - 'webdav_hostname': NEXTCLOUD_URL_DAV, - 'webdav_login': NEXTCLOUD_USER, - 'webdav_password': NEXTCLOUD_PASSWORD - } + return config_path - client = Client(options) +def mount_nextcloud(website, mount_path="/mnt"): + config_file = write_rclone_config() + remote_path = f"nextcloud:{NEXTCLOUD_PATH}/@{website}" - log_debug(f"Starting WebDAV sync from '{remote_path}' to '{local_path}'") - client.download_sync(remote_path=remote_path, local_path=local_path) - log_debug("WebDAV sync completed successfully.") + log_debug(f"Mounting {remote_path} to {mount_path}") + os.makedirs(mount_path, exist_ok=True) + + # Try to unmount first in case of stale mount + subprocess.run(f"fusermount -u {mount_path}", shell=True, stderr=subprocess.DEVNULL) + + cmd = f"rclone --config {config_file} mount {remote_path} {mount_path} --vfs-cache-mode full --daemon" + result = subprocess.run(cmd, shell=True, capture_output=True, text=True) + + if result.returncode != 0: + raise RuntimeError(f"Failed to mount: {result.stderr}") @app.route("/build", methods=["POST"]) def build_mkdocs(): @@ -81,7 +70,7 @@ def build_mkdocs(): return jsonify({"error": "WEBSITE parameter missing"}), 400 lock_key = f"{lock_prefix}{website}" - log_debug(f"Attempting to acquire Redis lock: {lock_key}a") + log_debug(f"Attempting to acquire Redis lock: {lock_key}") try: lock_acquired = redis_client.set(lock_key, "locked", nx=True, ex=60) except redis.exceptions.ConnectionError as e: @@ -92,19 +81,18 @@ def build_mkdocs(): log_debug(f"Build already active for website: {website}") return jsonify({"status": "busy", "message": f"Build already active: {website}"}), 429 - tmp_path = f"/tmp/{website}" - compile_path = f"{tmp_path}#compile" + mount_path = "/mnt" + compile_path = f"/tmp/{website}#compile" final_path = f"/srv/{website}" + src = os.path.join(mount_path, "mkdocs.yml") try: - sync_from_nextcloud(website, tmp_path) - - src = os.path.join(tmp_path, "mkdocs.yml") + mount_nextcloud(website, mount_path) log_debug(f"Checking if mkdocs.yml exists at {src}") if not os.path.exists(src): - log_debug(f"{src} not found after sync") - return jsonify({"error": f"{src} not found after sync"}), 404 + log_debug(f"{src} not found after mount") + return jsonify({"error": f"{src} not found after mount"}), 404 log_debug(f"Running MkDocs build: {src} -> {compile_path}") cmd = f"mkdocs build --quiet --no-strict --config-file {src} --site-dir {compile_path}" @@ -114,7 +102,7 @@ def build_mkdocs(): build_error = base64.b64encode(result.stderr.encode()).decode() json_payload = {"site": website, "error": build_error} log_debug(f"MkDocs build failed: {result.stderr}") - #requests.post(error_callback, json=json_payload, headers={"Content-Type": "application/json"}) + # requests.post(error_callback, json=json_payload, headers={"Content-Type": "application/json"}) return jsonify({"status": "error", "message": "Build failed", "error": result.stderr}), 500 log_debug(f"Performing differential copy from {compile_path} to {final_path}") @@ -125,8 +113,9 @@ def build_mkdocs(): finally: redis_client.delete(lock_key) - log_debug(f"Redis lock released for website: {website}") + subprocess.run(f"fusermount -u {mount_path}", shell=True, stderr=subprocess.DEVNULL) + log_debug(f"Redis lock released and mount cleaned for website: {website}") if __name__ == "__main__": log_debug("Starting Flask server on 0.0.0.0:80") - app.run(host="0.0.0.0", port=80) + app.run(host="0.0.0.0", port=80) \ No newline at end of file