Files
cbc2027/services/webdav_service.py
renato97 ee8fc183be feat: Sistema CBCFacil completo con cola secuencial
- Implementa ProcessingMonitor singleton para procesamiento secuencial de archivos
- Agrega AI summary service con soporte para MiniMax API
- Agrega PDF generator para resúmenes
- Agrega watchers para monitoreo de carpeta remota
- Mejora sistema de notificaciones Telegram
- Implementa gestión de VRAM para GPU
- Configuración mediante variables de entorno (sin hardcoded secrets)
- .env y transcriptions/ agregados a .gitignore

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-25 15:35:39 +00:00

103 lines
3.5 KiB
Python

"""
Cliente WebDAV para Nextcloud.
Provee métodos para interactuar con Nextcloud via WebDAV.
"""
import logging
from pathlib import Path
from typing import Optional
from webdav3.client import Client
from config import settings
class WebDAVService:
"""Cliente WebDAV para Nextcloud."""
def __init__(self) -> None:
self.logger = logging.getLogger(__name__)
self._client: Optional[Client] = None
def _get_client(self) -> Client:
"""Obtiene o crea el cliente WebDAV."""
if self._client is None:
if not settings.has_webdav_config:
raise RuntimeError("WebDAV configuration missing")
options = {
"webdav_hostname": settings.NEXTCLOUD_URL,
"webdav_login": settings.NEXTCLOUD_USER,
"webdav_password": settings.NEXTCLOUD_PASSWORD,
}
self._client = Client(options)
self._client.verify = True # Verificar SSL
return self._client
def test_connection(self) -> bool:
"""Prueba la conexión con Nextcloud."""
try:
client = self._get_client()
return client.check()
except Exception as e:
self.logger.error(f"WebDAV connection failed: {e}")
return False
def list_files(self, remote_path: str = "/") -> list[str]:
"""Lista archivos en una ruta remota."""
try:
client = self._get_client()
# Asegurar que la ruta empieza con /
if not remote_path.startswith("/"):
remote_path = "/" + remote_path
files = client.list(remote_path)
return files if files else []
except Exception as e:
self.logger.error(f"Failed to list files: {e}")
return []
def download_file(self, remote_path: str, local_path: Path) -> bool:
"""Descarga un archivo desde Nextcloud."""
try:
client = self._get_client()
local_path.parent.mkdir(parents=True, exist_ok=True)
client.download_sync(remote_path=str(remote_path), local_path=str(local_path))
self.logger.info(f"Downloaded: {remote_path} -> {local_path}")
return True
except Exception as e:
self.logger.error(f"Failed to download {remote_path}: {e}")
return False
def get_file_info(self, remote_path: str) -> dict:
"""Obtiene información de un archivo."""
try:
client = self._get_client()
info = client.info(remote_path)
return {
"name": info.get("name", ""),
"size": info.get("size", 0),
"modified": info.get("modified", ""),
}
except Exception as e:
self.logger.error(f"Failed to get file info: {e}")
return {}
def file_exists(self, remote_path: str) -> bool:
"""Verifica si un archivo existe en remoto."""
try:
client = self._get_client()
return client.check(remote_path)
except Exception:
return False
def upload_file(self, local_path: Path, remote_path: str) -> bool:
"""Sube un archivo a Nextcloud."""
try:
client = self._get_client()
client.upload_sync(local_path=str(local_path), remote_path=str(remote_path))
self.logger.info(f"Uploaded: {local_path} -> {remote_path}")
return True
except Exception as e:
self.logger.error(f"Failed to upload {local_path}: {e}")
return False