feat: with rclone -PREVIOUS IS GOOD

This commit is contained in:
administrateur 2025-03-30 05:13:09 +02:00
parent 015fcde8ee
commit 85319bebee

View File

@ -2,31 +2,8 @@ from flask import Flask, request, jsonify
import os import os
import subprocess import subprocess
import base64 import base64
import requests
import redis import redis
import shutil
from threading import Lock 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__) app = Flask(__name__)
@ -49,25 +26,37 @@ def log_debug(msg):
if DEBUG: if DEBUG:
print(f"🔍 DEBUG: {msg}", flush=True) print(f"🔍 DEBUG: {msg}", flush=True)
def sync_from_nextcloud(website, tmp_path): def write_rclone_config():
remote_path = f"/{NEXTCLOUD_PATH}/@{website}/" """Write rclone config file dynamically"""
local_path = tmp_path 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): with open(config_path, "w") as f:
shutil.rmtree(local_path) f.write(f"""[nextcloud]
os.makedirs(local_path, exist_ok=True) type = webdav
url = {NEXTCLOUD_URL_DAV}
vendor = nextcloud
user = {NEXTCLOUD_USER}
pass = {NEXTCLOUD_PASSWORD}""")
options = { return config_path
'webdav_hostname': NEXTCLOUD_URL_DAV,
'webdav_login': NEXTCLOUD_USER,
'webdav_password': NEXTCLOUD_PASSWORD
}
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}'") log_debug(f"Mounting {remote_path} to {mount_path}")
client.download_sync(remote_path=remote_path, local_path=local_path) os.makedirs(mount_path, exist_ok=True)
log_debug("WebDAV sync completed successfully.")
# 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"]) @app.route("/build", methods=["POST"])
def build_mkdocs(): def build_mkdocs():
@ -81,7 +70,7 @@ def build_mkdocs():
return jsonify({"error": "WEBSITE parameter missing"}), 400 return jsonify({"error": "WEBSITE parameter missing"}), 400
lock_key = f"{lock_prefix}{website}" 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: try:
lock_acquired = redis_client.set(lock_key, "locked", nx=True, ex=60) lock_acquired = redis_client.set(lock_key, "locked", nx=True, ex=60)
except redis.exceptions.ConnectionError as e: except redis.exceptions.ConnectionError as e:
@ -92,19 +81,18 @@ def build_mkdocs():
log_debug(f"Build already active for website: {website}") log_debug(f"Build already active for website: {website}")
return jsonify({"status": "busy", "message": f"Build already active: {website}"}), 429 return jsonify({"status": "busy", "message": f"Build already active: {website}"}), 429
tmp_path = f"/tmp/{website}" mount_path = "/mnt"
compile_path = f"{tmp_path}#compile" compile_path = f"/tmp/{website}#compile"
final_path = f"/srv/{website}" final_path = f"/srv/{website}"
src = os.path.join(mount_path, "mkdocs.yml")
try: try:
sync_from_nextcloud(website, tmp_path) mount_nextcloud(website, mount_path)
src = os.path.join(tmp_path, "mkdocs.yml")
log_debug(f"Checking if mkdocs.yml exists at {src}") log_debug(f"Checking if mkdocs.yml exists at {src}")
if not os.path.exists(src): if not os.path.exists(src):
log_debug(f"{src} not found after sync") log_debug(f"{src} not found after mount")
return jsonify({"error": f"{src} not found after sync"}), 404 return jsonify({"error": f"{src} not found after mount"}), 404
log_debug(f"Running MkDocs build: {src} -> {compile_path}") log_debug(f"Running MkDocs build: {src} -> {compile_path}")
cmd = f"mkdocs build --quiet --no-strict --config-file {src} --site-dir {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() build_error = base64.b64encode(result.stderr.encode()).decode()
json_payload = {"site": website, "error": build_error} json_payload = {"site": website, "error": build_error}
log_debug(f"MkDocs build failed: {result.stderr}") 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 return jsonify({"status": "error", "message": "Build failed", "error": result.stderr}), 500
log_debug(f"Performing differential copy from {compile_path} to {final_path}") log_debug(f"Performing differential copy from {compile_path} to {final_path}")
@ -125,7 +113,8 @@ def build_mkdocs():
finally: finally:
redis_client.delete(lock_key) 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__": if __name__ == "__main__":
log_debug("Starting Flask server on 0.0.0.0:80") log_debug("Starting Flask server on 0.0.0.0:80")