Files
2026-05-09 14:00:04 -04:00

134 lines
4.6 KiB
Python

from ftplib import FTP
import os
import time
class FTPManager:
def __init__(self, siteFTP, userFTP, passwordFTP, postFTP):
self.server = siteFTP
self.user = userFTP
self.password = passwordFTP
self.port = postFTP # Puerto por defecto: 21
self.ftp_client = None
self.list_failed_uploads = []
#def __init__(self, **kwargs):
# self.server = kwargs.get('server')
# self.user = kwargs.get('user')
# self.password = kwargs.get('password')
# self.port = kwargs.get('port', 21) # Puerto por defecto: 21
# self.ftp_client = None
# self.list_failed_uploads = []
def connect(self):
"""Conecta al servidor FTP"""
try:
self.ftp_client = FTP()
self.ftp_client.connect(self.server, self.port)
self.ftp_client.login(self.user, self.password)
self.ftp_client.encoding = 'latin-1'
#print(f"Conexión exitosa al servidor FTP: {self.server}")
except Exception as e:
#print(f"Error al conectar al servidor FTP: {e}")
raise
def disconnect(self):
"""Cierra la conexión FTP"""
if self.ftp_client:
self.ftp_client.quit()
#print("Conexión cerrada con éxito")
def upload_photos(self, local_folder, remote_folder, batch_size=100):
"""
Sube archivos en lotes de 100. Si hay un error, omite el archivo y lo guarda para intentarlo al final.
"""
try:
self.ftp_client.cwd(remote_folder)
except:
# if not exit create folder
self.ftp_client.mkd(remote_folder)
self.ftp_client.cwd(remote_folder)
files = [f for f in os.listdir(local_folder) if os.path.isfile(os.path.join(local_folder, f))]
total_files = len(files)
print(f"Total de archivos a subir: {total_files}")
for i in range(0, total_files, batch_size):
batch = files[i:i+batch_size]
print(f"Subiendo lote {i//batch_size + 1}: {len(batch)} archivos")
for file in batch:
local_path = os.path.join(local_folder, file)
try:
with open(local_path, 'rb') as local_file:
self.ftp_client.storbinary(f"STOR {file}", local_file)
print(f"Subido: {file}")
except Exception as e:
print(f"Error al subir {file}: {e}")
self.list_failed_uploads.append(file)
time.sleep(2) # Pequeña pausa entre lotes para estabilidad
# Intentar subir nuevamente los fallidos
if self.list_failed_uploads:
print("Reintentando archivos fallidos...")
for file in self.list_failed_uploads:
local_path = os.path.join(local_folder, file)
try:
with open(local_path, 'rb') as local_file:
self.ftp_client.storbinary(f"STOR {file}", local_file)
print(f"Subido en reintento: {file}")
except Exception as e:
print(f"Fallo definitivo en {file}: {e}")
print("Proceso de subida finalizado.")
def uploadFile(self, remote_folder, local_file_path):
self.connect()
try:
self.ftp_client.cwd("/") # 👈 IMPORTANTE
self.ensure_remote_path(remote_folder)
with open(local_file_path, "rb") as f:
file_name = os.path.basename(local_file_path)
self.ftp_client.storbinary(f"STOR {file_name}", f)
finally:
self.disconnect()
def ensure_remote_path(self, remote_folder):
folders = remote_folder.strip("/").split("/")
# SIEMPRE empezar desde raíz
self.ftp_client.cwd("/")
for folder in folders:
if folder == "":
continue
try:
self.ftp_client.cwd(folder)
except:
self.ftp_client.mkd(folder)
#print(f"Creando/navegando carpeta: {folder}")
self.ftp_client.cwd(folder)
# Ejemplo de uso
if __name__ == "__main__":
config = {
"server": "glmservice.com",
"user": "ftpeleaderuser",
"password": "AdAw#BaAjwQdc4B",
"port": 21
}
ftp_manager = FTPManager(**config)
try:
ftp_manager.connect()
ftp_manager.upload_photos("C:\\Users\\emili\\Downloads\\sfotos", "/imglm/test/glmpg01/")
finally:
ftp_manager.disconnect()