Menú

Mostrar Mensajes

Esta sección te permite ver todos los mensajes escritos por este usuario. Ten en cuenta que sólo puedes ver los mensajes escritos en zonas a las que tienes acceso en este momento.

Mostrar Mensajes Menú

Mensajes - darkucla

#1
Python / Re:Sencillo cliente FTP
Agosto 07, 2020, 03:57:10 PM
Este es el que hice
tiene una funcion .interactivo()   para navegar por el servidor ftp

Código: python

import os
from ftplib import FTP   # clsFTP


import ftputil
import ftputil.session
import time, datetime

my_session_factory = ftputil.session.session_factory(use_passive_mode=False)
class clsFTP:
   
    def __init__(self, strServidor="", strUsuario="", strPassword=""):
        self.bolConectado = False
        self.intReintentos = 3
        if strServidor and strUsuario and strPassword:
            self.conecta(strServidor, strUsuario, strPassword)
   
    def conecta(self, strServidor, strUsuario, strPassword):
        self.strServidor = strServidor
        self.strUsuario = strUsuario
        self.strPassword = strPassword
        try:
            self.ftp = ftputil.FTPHost(strServidor, strUsuario, strPassword, session_factory=my_session_factory )
        except Exception as error:
            print(error)
            self.bolConectado = False
        else:
            print("conexión...")
            self.bolConectado = True
            self.strDirLocal = os.getcwd()
            self.strDirRemoto = self.ftp.getcwd()
            try:
                self.ftp.synchronize_times()
            except Exception as error:
                print("synchronize_times", error)

        return self.bolConectado

    def desconecta(self):
        self.bolConectado = False
        self.ftp.close()


    def dirLocal(self, strDirLocal):
        if not os.path.isdir(strDirLocal):
            os.makedirs(strDirLocal, exist_ok=True)
        os.chdir(strDirLocal) 

    def interactivo(self):
        if not self.bolConectado:
            self.conecta(self.strServidor, self.strUsuario, self.strPassword)
        while 1:
            self.strDirRemoto = self.ftp.getcwd()
            self.strDirLocal = os.getcwd()
            for intR, strlinea  in  enumerate(self.listaRemoto()):
                print(intR, *strlinea)
            print("\nFTP  by UCLA")
            print("Servidor:", self.strServidor)
            print("Directorio Local:",self.strDirLocal)
            print("Directorio Remoto:",self.strDirRemoto)
       
            strOpcion = input("Opción (H ayuda): ").lower().strip()
            if strOpcion == "q":
                break
            elif strOpcion[0:3] == "dir":
                self.listaLocal()
            elif strOpcion[0] == "d":
                intOpcion = int(strOpcion.replace("d",""))
                self.descarga(self.ftp.path.join(self.lstDirRemoto[intOpcion][4], self.lstDirRemoto[intOpcion][0]),
                    os.path.join(self.strDirLocal, self.lstDirRemoto[intOpcion][0]))
            elif strOpcion[0:2] == "..":
                self.ftp.chdir("..")
            elif strOpcion.isdigit():
                intOpcion = int(strOpcion)
                if self.ftp.path.isdir(self.lstDirRemoto[intOpcion][0]):
                    try:
                        self.ftp.chdir(self.lstDirRemoto[intOpcion][0])
                    except Exception as error:
                        print("Cambio de directorio", error)
            elif strOpcion[0:2] == "cd":
                try:
                    os.chdir(strOpcion[3:])
                except Exception as e:
                    print("error al cambiar directorio local " + str(e))
               

    def descarga(self, strRutaArchivoRemoto, strRutaArchivoLocal):
        if self.ftp.path.isfile(strRutaArchivoRemoto):
            for intTry in range(self.intReintentos):
                try:
                    os.makedirs(os.path.dirname(strRutaArchivoLocal), exist_ok=True)
                    print("DESCARGAR ", strRutaArchivoRemoto, " ==> ", os.path.dirname(strRutaArchivoLocal))
                    bolDescargado = self.ftp.download_if_newer(strRutaArchivoRemoto, strRutaArchivoLocal)
                    print(bolDescargado, self.ftp.path.getsize(strRutaArchivoRemoto), os.path.getsize(strRutaArchivoLocal))
                    if self.ftp.path.getsize(strRutaArchivoRemoto) != os.path.getsize(strRutaArchivoLocal):
                        print("tamanos DIFERENTES",self.ftp.path.getsize(strRutaArchivoRemoto),os.path.getsize(strRutaArchivoLocal))
                        input()
                except Exception as error:
                    bolDescargado = False
                    print("ERROR DE DESCARGA!", error)
                    print(f"Reintentando {intTry + 1} de {self.intReintentos}" )
                else:
                    break
        else:

            for strdf in self.ftp.listdir(strRutaArchivoRemoto):
                bolDescargado = self.descarga(self.ftp.path.join(strRutaArchivoRemoto, strdf),os.path.join(strRutaArchivoLocal, strdf))


    def listaLocal(self):
        for elemento in os.listdir():
            if os.path.isdir(elemento):
                print("\t<DIR>", elemento)
            else:
                print("\t", elemento)

    def listaRemoto(self, strRutaRemota = "" ):
        self.lstDirRemoto = []
        if self.bolConectado:
            if strRutaRemota == "":
                strRutaRemota = self.ftp.getcwd()
           
            for df in self.ftp.listdir(strRutaRemota):
                rdf = self.ftp.path.join(strRutaRemota, df)
                strTipo = "<D>" if self.ftp.path.isdir(rdf) else "<F>"
               
                strTamano = "0" if strTipo == "<D>" else "{0:.2f}".format(self.ftp.path.getsize(rdf) / 1024)

                strFecha = time.strftime('%Y-%m-%d', time.gmtime(self.ftp.path.getmtime(rdf)))
                self.lstDirRemoto.append([df, strTipo, strTamano, strFecha, strRutaRemota])
           
        return self.lstDirRemoto
    def Ayuda(self):
        print("\nUn poco de AYUDA:")
        print("""
<numero> - Cambia Directorio Remoto
D <numero> - Descarga Archivo/Directorio Remoto
CD <Directorio> - Cambia Directorio Local
DIR - Listar Directorio Local Actual.
Q - Termina Interactivo\n
        """)
#2
que loco!.. revivieron un post de hace 9 años... y yo creyéndolo reciente :/
#3
Muy bien, quisiera recomendarte el uso de .isdigt()  en un string te da True si son solo números
Claro que si deseas introducir "12.34".isdigit() por ejemplo, será False.. pero para eso podemos usar "12.34".count(".")  que retornará 1 y sabremos que tiene decimal

Código: python

strNumero = input("Numero: ")
if strNumero.count(".") == 1:  # Busca que tenga un punto
if strNumero.replace(".", "").isdigit():  # quitamos el punto y preguntamos si son solo numeros
fltNumero = float(strNumero)
print(fltNumero, "no es entero, tiene decimal")
else:
print("no es entero")
elif strNumero.isdigit():      # Si la cadena tiene solo números...
intNumero = int(strNumero)
print(intNumero, "es entero ", end="")
if intNumero % 2 == 0:
print("par")
else:
print("impar")
else:
print("no es entero")


Hay algo que no domino aun que son las regex... expresiones regulares... las cuales disminuyen el código.. saludos
#4
Qué tal amiguitos....
He tratado de "mejorar"el código del cifrado de César (desplazamiento)  y pues seguí leyendo y ví eso de la decimación y afín...
Así que me hice un poco bolas, pero para empezar les traigo lo que llevo...está bien que lo ponga tan silvestre?.. o necesitaba detallarlo más?
Luego lo termino... o me pueden aconsejar ...voy bien?... algún otro tipo de encriptación que deba agregar?  saludos

Código: python

def Cifrado(bolCifrar=True):
# strTexto, intROT=0, strTipoDeCifrado="desplazamiento", intMod=27, intAfin=1, bolCifrar=True):
# M = Mensaje a Cifrar
# C = Mensaje Cifrado
# n = Longitud del Alfabeto, default 27
# (Des)Cifrado por Desplazamiento (Cesar) a = 1, b = ROT
# (Des)Cifrado por Decimación  a = salto o 'decimación',  b = 0
# (Des)Cifrado Afín   a = salto o 'decimación',  b = ROT
strTexto = input("Mensaje: ").upper()
if not bolCifrar:
strOpcion = int(input("(1) Tengo los datos.... (2) Letra mas frecuente es E.... (3) Fuerza Bruta: "))
else:
strOpcion = 1

lstABC = list(chr(x) for x in range(65,91))
lstABC.insert(14,"Ñ")
if strOpcion == 3:
for b in range(len(lstABC) + 1):
for a in range(len(lstABC)):
Cifrado2(strTexto, b, a, 27, False)

elif strOpcion == 2:
lstRepetidas = []
for strLetra in lstABC:
lstRepetidas.append(strTexto.count(strLetra))
intNumMax = max(lstRepetidas)
b = lstRepetidas.index(intNumMax)
a = 1
n = 27
Cifrado2(strTexto, b-4, a, n, False)
Cifrado2(strTexto, b, a, n, False)
else:
b = int(input("Desplazamiento (b): "))
a = int(input("Decimación (a=1): "))
n = int(input("Alfabeto (n=27 con ñ): "))
Cifrado2(strTexto, b, a, n, True)



def Cifrado2(strTexto, b=0, a=1, n=27, bolCifrar=True):
lstABC = list(chr(x) for x in range(65,91))
if n == 27:
lstABC.insert(14,"Ñ")
strCadena = ""

for strLetra in strTexto:
if strLetra in lstABC:
intMC = lstABC.index(strLetra)
if bolCifrar:
intIndexCodificado = (( a * intMC) + b ) % len(lstABC)
else:
intIndexCodificado = ((intMC - b) * modInv( a, len(lstABC))) % len(lstABC)
strLetra = lstABC[intIndexCodificado]
strCadena += strLetra
#return strCadena
print("\nConversión: ",strCadena)




def xgcd(a, b):
    """Calcula el greater common divisor (gcd)/ máximo común divisor de a y b.
        Utiliza el algoritmo extendido de Euclides.

    Args:
        a: mcd(a,b)=resultado
        b: mcd(a,b)=resultado
    Returns:
        Returns mcd(a,b) and (u0,v0)

    """
    if b == 0:
        return 0,1,0

    u0 = 1
    u1 = 0
    v0 = 0
    v1 = 1

    while b != 0:
        q = a//b
        r = a - b * q
        u = u0 - q * u1
        v = v0 - q * v1
        #Update a,b
        a = b
        b = r
        #Update for next iteration
        u0 = u1
        u1 = u
        v0 = v1
        v1 = v

    return  a, u0, v0
def modInv(n, a):
    """Calcula el inverso de a módulo n.
       Utiliza el algoritmo extendido de Euclides para ello.

    Args:
        a: número del que se calcula el módulo
        n: módulo del inverso
     
    Returns:
        inverso de a módulo n

    """
    mcd , u , v = xgcd(n,a)
    if mcd != 1:
       # print("No existe inverso")
        return 0
     
    return u%a



Este es el programa principal....
Código: python

while 1:
print("Menú Cifrado")
print("1.- Cifrar Mensaje\tC = ( ( a * M ) + b ) mod n")
print("2.- Descifrar Mensaje\tM = ( ( C - b ) * inv( a, n ) ) mod n")
print("3.- Salir")
print("""
M = Mensaje a Cifrar
C = Mensaje Cifrado
n = Longitud del Alfabeto, default 27
(Des)Cifrado por Desplazamiento (Cesar) a = 1, b = ROT
(Des)Cifrado por Decimación  a = salto o 'decimación',  b = 0
(Des)Cifrado Afín   a = salto o 'decimación',  b = ROT""")
strOpcion = input("Opción: ").strip()
if strOpcion == "3":
break
if strOpcion == "1":
Cifrado(True)

if strOpcion == "2":
Cifrado(False)



Y el ejemplo...
#5
Python / Re:Cifrado Cesar ... 3 Funciones
Enero 16, 2020, 12:42:18 AM
Nuevamente hay cambios.... ahora una función VoyATenerSuerte()
la cual muestra las 2 posibles soluciones basado en el numero máximo de leras repetidas, podrían ser la A o la E

Código: python

def CifradoCesar(strTexto, intROT, intMod = 27):
return CodigoCesar(strTexto, intROT, intMod, True)

def DescifradoCesar(strCifrado, intROT, intMod = 27):
return CodigoCesar(strCifrado, intROT, intMod, False)

def CodigoCesar(strTexto, intROT, intMod = 27, bolCifrar=True):
lstABC = list(chr(x) for x in range(65,91))
if intMod == 27:
lstABC.insert(14,"Ñ")
strCifrado = ""
for strLetra in strTexto:
strLetra = strLetra.upper()
if strLetra in lstABC:
intIndex = lstABC.index(strLetra)
if bolCifrar:
intIndexCodificado = (intIndex + intROT) % len(lstABC)
else:
intIndexCodificado = (intIndex - intROT) % len(lstABC)
strLetra = lstABC[intIndexCodificado]
strCifrado += strLetra
return strCifrado

def EncuentraCifradoCesar(strCifrado):
lstABC = list(chr(x) for x in range(65,91))
VoyATenerSuerteCesar(strCifrado, lstABC)
for intROT in range(len(lstABC)+1):
print(intROT, DescifradoCesar(strCifrado, intROT, len(lstABC)), len(lstABC))
print("")
lstABC.insert(14,"Ñ")
VoyATenerSuerteCesar(strCifrado, lstABC)
for intROT in range(len(lstABC)+1):
print(intROT, DescifradoCesar(strCifrado, intROT, len(lstABC)), len(lstABC))


def VoyATenerSuerteCesar(strTexto, lstABC):
lstRepetidas = []
for strLetra in lstABC:
strLetra = strLetra.upper()
lstRepetidas.append(strTexto.count(strLetra))

intNumMax = max(lstRepetidas)
print("Voy a tener suerte....")
# Posible A
intIndex = lstRepetidas.index(intNumMax)
print(intIndex, DescifradoCesar(strTexto, intIndex))
# Posible E
intIndex = lstRepetidas.index(intNumMax)-4
print(intIndex, DescifradoCesar(strTexto, intIndex))
input("presiona enter....")
#6
Python / Re:Cifrado Cesar ... 3 Funciones
Enero 15, 2020, 11:46:18 PM
Plebes, ya se los cambié...
Código: python


def CifradoCesar(strTexto, intROT, intMod = 27):
return CodigoCesar(strTexto, intROT, intMod, True)

def DescifradoCesar(strCifrado, intROT, intMod = 27):
return CodigoCesar(strCifrado, intROT, intMod, False)

def CodigoCesar(strTexto, intROT, intMod = 27, bolCifrar=True):
lstABC = list(chr(x) for x in range(65,91))
if intMod == 27:
lstABC.insert(14,"Ñ")
strCifrado = ""
for strLetra in strTexto:
strLetra = strLetra.upper()
if strLetra in lstABC:
intIndex = lstABC.index(strLetra)
if bolCifrar:
intIndexCodificado = (intIndex + intROT) % len(lstABC)
else:
intIndexCodificado = (intIndex - intROT) % len(lstABC)
strLetra = lstABC[intIndexCodificado]
strCifrado += strLetra
return strCifrado

def EncuentraCifradoCesar(strCifrado):
lstABC = list(chr(x) for x in range(65,91))
for intROT in range(len(lstABC)+1):
print(intROT, DescifradoCesar(strCifrado, intROT, len(lstABC)), len(lstABC))
print("")
lstABC.insert(14,"Ñ")
for intROT in range(len(lstABC)+1):
print(intROT, DescifradoCesar(strCifrado, intROT, len(lstABC)), len(lstABC))

#7
Python / Cifrado Cesar ... 3 Funciones
Enero 15, 2020, 10:59:28 PM
CHQF ÑUQZ, NTBEN XQF YHQFGEB YU OBPUSB PQX OURENPB OQFNE FBZ 3 RHZOUBZQF, HZN OUREN QX GQKGB, BGEN XB PQFOUREN L BGEN YHQFGEN XNF OBYÑUZNOUBZQF PQ CBFUÑXQF PQFOURENPBF QFCQEB XQF CHQPN FQEIUE L FU NXSHUQZ XB CHQPQ YQVBENE, CBE RNIBE, OBYCNEGUEXB

Código: python

def CifradoCesar(strTexto, intROT, intMod = 27):
lstABC = list(chr(x) for x in range(65,91))
if intMod == 27:
lstABC.insert(14,"Ñ")
strCifrado = ""
for strLetra in strTexto:
strLetra = strLetra.upper()
if strLetra in lstABC:
intIndex = lstABC.index(strLetra)
intIndexCodificado = (intIndex + intROT) % len(lstABC)
strLetra = lstABC[intIndexCodificado]
strCifrado += strLetra
return strCifrado

def DescifradoCesar(strCifrado, intROT, intMod = 27):
lstABC = list(chr(x) for x in range(65,91))
if intMod == 27:
lstABC.insert(14,"Ñ")
strDescifrado = ""
for strLetra in strCifrado:
if strLetra in lstABC:
intIndex = lstABC.index(strLetra)
intIndexDecodificado = (intIndex - intROT) % len(lstABC)
strLetra = lstABC[intIndexDecodificado]
strDescifrado += strLetra
return strDescifrado

def EncuentraCifradoCesar(strCifrado):
lstABC = list(chr(x) for x in range(65,91))
for intROT in range(len(lstABC)+1):
print(intROT, DescifradoCesar(strCifrado, intROT, len(lstABC)), len(lstABC))
print("")
lstABC.insert(14,"Ñ")
for intROT in range(len(lstABC)+1):
print(intROT, DescifradoCesar(strCifrado, intROT, len(lstABC)), len(lstABC))


Código: python

strTexto = input("Introduzca el texto a Descifrar: ")
intROT = int(input("Desplazamiento? (0 Muestra Todos): "))
if intROT == 0:
EncuentraCifradoCesar(strTexto)
else:
print("Descifrado:", DescifradoCesar(strTexto, intROT))
#8
@No tienes permitido ver los links. Registrarse o Entrar a mi cuenta
Gracias por tu ayuda... espero haber entendido
tengo la aplicación ksnip....


este sería el código en github
No tienes permitido ver los links. Registrarse o Entrar a mi cuenta

saludos
#9
Hola, soy Elfo!

Ahora les comparto este código el cuál utilizo para descargar archivos o directorios completos por ftp..
En la página para principiantes de facebook he estado compartiendo  este y otros códigos
Le faltan detalles.. espero alguien aquí le pueda servir y/o pueda ayudarme a mejorarlo

En la función interactivo() acepta comandos como
dir --> muestra listado directorio local actual
cd --> cambia directorio local
..  --> regresa al directorio padre remoto
<numero>   --> en el listado remoto slecciona el numero para acceder al directorio
d <numero> --> descarga el archivo o directorio enumerado al directorio local actual
q   --> termina interactivo

Código: python

import os  # clsFTP, copia(), clsUAC
# import sys  # clsUAC
# import ctypes   # clsUAC

# import shutil      # copia()
# from distutils.dir_util import copy_tree   # copia()

from ftplib import FTP   # clsFTP

class clsFTP():
    def __init__(self):
        self.DirLocal = os.getcwd()
        self.Servidor = ""
        self.Usuario = ""
        self.Password = ""
        self.DirRemoto = ""
        self.bolConectado = False
   
    def conecta(self, strServidor, strUsuario, strPassword):
        try:
            self.Servidor = strServidor
            self.strUsuario = strUsuario
            self.Password = strPassword
            self.ftp =  FTP(strServidor,strUsuario,strPassword)
            self.DirRemoto = self.ftp.pwd()
            self.bolConectado = True
            print(self.ftp.getwelcome())
        except Exception as err:
            self.bolConectado = False
            print("ERROR DE CONEXION")
            print(err)

    def desconecta(self):
        self.ftp.quit()
        self.bolConectado = False

    def dirLocal(self, strDirLocal):
        if not os.path.isdir(strDirLocal):
            os.makedirs(strDirLocal, exist_ok=True)
        os.chdir(strDirLocal)       
    def descarga(self, ruta, filename):
        print("DESCARGAR ", ruta + "/" + filename, " a ", os.getcwd())
        try:
            with open(filename, "wb") as fp:
                self.ftp.retrbinary("RETR " + ruta + "/" + filename, fp.write)
            # print(self.ftp.size(filename))
            # print(os.path.getsize(filename))

        except Exception as e:
            print("Error " + str(e))
            try:
                self.ftp.cwd(ruta + "/" + filename)
                fp.close()
                os.remove(filename)
                os.mkdir(filename)
                os.chdir(filename)
                listaD = self.ftp.nlst()
                for i in range(len(listaD)):
                    self.descarga(self.ftp.pwd(), listaD[i])
                self.ftp.cwd("..")
                os.chdir("..")
            except Exception as e:
                print("Error Download" + str(e))
    def interactivo(self):
        while 1:
            self.listarRemoto()
            self.DirRemoto = self.ftp.pwd()
            self.DirLocal = os.getcwd()
            print("\nFTP  by UCLA")
            print("Servidor:",self.Servidor)
            print("Directorio Local:",self.DirLocal)
            print("Directorio Remoto:",self.DirRemoto)
            #print("\n")
            strOpcion = input("Opción (H ayuda): ")
            if strOpcion.lower() == "q":
                break
            self.evaluaOpcion(strOpcion)
    def evaluaOpcion(self, strOpcion):
        strOpcion = strOpcion.lower().strip()
        dicOpciones = {"ll" : "self.listarLocal()", "lr" : "self.listarRemoto()",
                       "cr" : "self.cdRemoto()",
                       "h" : "self.Ayuda()"
                        }
        if strOpcion[0] == "d":
            if strOpcion[0:3] == "dir":
                self.listarLocal()
            else:
                intOpcion = int(strOpcion.replace("d",""))
                self.descarga(self.ftp.pwd(), self.lstDirectorio[intOpcion][1])
        if strOpcion[0:2] == "..":
            self.ftp.cwd("..")
        if strOpcion.isdigit():
            intOpcion = int(strOpcion)
            try:
                self.ftp.cwd(self.lstDirectorio[intOpcion][1])
            except Exception as e:
                print("Error al cambiar directorio remoto: " + str(e))
        if strOpcion[0:2] == "cd":
            try:
                os.chdir(strOpcion[3:])
            except Exception as e:
                print("error al cambiar directorio local " + str(e))
       
        if strOpcion in dicOpciones.keys():
            eval(dicOpciones[strOpcion])
       
           
    def Ayuda(self):
        print("\nUn poco de AYUDA:")
        print("""
<numero> - Cambia Directorio Remoto
D <numero> - Descarga Archivo/Directorio Remoto
CD <Directorio> - Cambia Directorio Local
DIR - Listar Directorio Local Actual.
Q - Termina Interactivo\n
        """)

    def listarLocal(self):
        for elemento in os.listdir():
            if os.path.isdir(elemento):
                print("\t<DIR>", elemento)
            else:
                print("\t", elemento)

    def listarRemoto(self):
        if self.bolConectado:
            self.lstDir = []
            self.lstDirectorio = []
            self.lstnlst = self.ftp.nlst()
            self.ftp.dir(self.ftp.pwd(), self.lstDir.append)
            for i in range(len(self.lstDir)):
                try:
                    intSize = self.ftp.size(self.lstnlst[i])
                    strType = "F"
                except:
                    intSize = 0
                    strType = "D"
                self.lstDirectorio.append([self.lstDir[i], self.lstnlst[i], strType, intSize])
                print(i,self.lstDirectorio[i][0])
   
    def cdRemoto(self):
        pass



Todavía no sé como insertar la imagen :(

Mientras un ejemplo:
Código: python

objftp = clsFTP()

objftp.conecta("ftp.rediris.es", "anonymous", "guest")
objftp.interactivo()
#10
Desde antes les digo que no sé como publicar u.u
Soy principiante en underc0de y en python... les comparto una función que he hecho para copiar un archivo o un directorio la cual uso para respaldar archivos en windows

Faltará el return 0 o -1 en caso de error.. yo que sé?!

Hasta ahora funcionó:
copia("archivo.txt", "archivo2.txt)
copia("archivo.txt", "directorio")
copia("archivo.txt", "directorio\archivo3.txt")
copia("archivo.txt") # crea un "archivo_copia.txt"
copia("directorio", "directorio2")
copia("directorio") # crea un "directorio_copia"
copia() # hace una copia del directorio actual_copia

Espero les sea de utilidad o si se puede mejorar me lo hagan saber.. gracias

Código: python

import os  # clsFTP, copia(), clsUAC
# import sys  # clsUAC
# import ctypes   # clsUAC

import shutil      # copia()
from distutils.dir_util import copy_tree   # copia()

def copia(strOrigen="", strDestino=""):
    if strOrigen == "":           # Si no se pasa origen
        strOrigen = os.getcwd()   # se toma el directorio actual
    if os.path.exists(strOrigen):  # Si existe el origen let's play...
        if strDestino == "":   # si no se pasa el destino entonces será origen_copia
            strDestino = os.path.splitext(strOrigen)[0] + "_Copia" + os.path.splitext(strOrigen)[1]
       
        if os.path.splitext(strDestino)[1] == "":  #  posible directorio
            os.makedirs(strDestino, exist_ok=True) # Crea los directorios

        if os.path.isfile(strOrigen):  # si queremos copiar un solo archivo
            os.makedirs(os.path.dirname(os.path.abspath(strDestino)), exist_ok=True)
            shutil.copy(strOrigen, strDestino)
           
        if os.path.isdir(strOrigen):  # si lo que queremos copiar es un directorio
            copy_tree(strOrigen, strDestino)


Si todo va bien, luego les comparto la clase clsFTP y la clsUAC


Ejemplo:
Código: python


lstARespaldar = [r"C:\dir1\dir2", r"C:\dir3\dir4\archivo.txt"]
strRutaRespaldo = r"C:\dirRespaldo"

for strOrigen in lstARespaldar:
    print("Copiando",  strOrigen, " a ", strRutaRespaldo)
    copia(strOrigen, strRutaRespaldo)
               
print("Respaldo Finalizado...")