Copia de archivos a través de la Python Consola de QGIS con os, shutil y PyQt

En este post se va a considerar, mediante la Python Console de QGIS, la copia de archivos desde una carpeta particular a una sub carpeta que se crea, si no existe previamente, dentro de la primera. Como el script se ejecuta cargando como módulo el archivo donde se encuentra la función, entonces la primera instrucción de copyFiles (correspondiente al full_path) determina automáticamente la ruta desde donde se efectuarán todas las acciones con los archivos.

Como la Python Console de QGIS no admite el uso de raw_input, si queremos pasarle parámetros a la función de modo interactivo tenemos que hacer uso de las clases que pone a la disposición PyQt. Para ello, nos haremos servir de QInputDialog (para la introducción de datos) y de QMessageBox para las advertencias de las excepciones.

Con relación a QInputDialog, se utilizan dos métodos. El primero para introducir texto (el nombre del directorio que va a ser creado) y el segundo es simplemente una prueba de cómo introducir un número en coma flotante (no se usa en el código).

Con respecto a los archivos a copiar es obvio que está debería ser una lista que se pasa como parámetro a la función y aquí está dentro del código por propósito de prueba. Incluye 4 archivos que están en el directorio considerado y uno que no existe. Después de correr el script, éste detecta que el archivo ‘xxx.txt’ no está en el directorio y lo excluye de los archivos a copiar. Por otra parte, si los archivos a copiar existen se pide confirmación de sobre escritura y al final se incluye un recuento de cuales fueron los verdaderamente copiados.

El código completo del módulo (lo llamé qgis_40.py) es el siguiente:

# -*- coding: utf-8 -*-
import os, shutil
from PyQt4.QtGui import QMessageBox, QInputDialog

def copyFiles():
    
    full_path = os.path.realpath(__file__)
    
    # Se muestra el dialogo para pedir el nombre del usuario
    title = u"Dialogo"
    msg = "Por favor, introduzca su Nombre:"
    
    name = QInputDialog.getText(None, title, msg)
    # name es una tupla donde:
    # name[0] retorna el text 
    # name[1] retorna el boton seleccionado    
    
    # Si se ha hecho click en Cancelar se sale de la funcion
    if not name[1]:
        QMessageBox.warning(None, u"Información", u"No se ha intoducido el Nombre") 
        return
    
    msg = u"Introduzca un número en coma flotante"
    
    d = QInputDialog.getDouble(None, title, msg, decimals= 5)
    
    # Si se ha hecho click en Cancelar se sale de la funcion
    if not d[1]:
        QMessageBox.warning(None, u"Información", u"No se ha introducido el valor") 
        return
    
    print "my double = ", d[0]
    
    if os.path.isfile(full_path) == True:
        
        my_path, file = os.path.split(full_path)
        
        new_path = my_path + "/" + name[0]
        
        if os.path.isdir(new_path) is True:
            print "El directorio " + new_path + " ya existe"
            
        else:
            os.mkdir(new_path)
            print "El directorio " + new_path + " ha sido creado"
            
        names = os.listdir(my_path)
        
        print my_path
        
        lista = ['qgis_10.py', 'qgis_20.py', 'qgis_30.py', 'qgis_40.py', 'xxx.txt']
        
        lista_cop = [] #inicializa lista de archivos copiados
        
        for item in lista:
            if item not in names:
                print "el archivo " + item + u" no está en el directorio"
                message = "El archivo \"" + item + u"\" no está en el directorio"
                QMessageBox.information(None, u"Información", message)
        
        names2 = os.listdir(new_path)
        
        for item in lista:
            my_file = os.path.join(my_path, item)   
            
            if item in names2:
                msg = "El archivo " + item + " ya existe. Quiere sobrescribir el resultado(s/n)?"
                reply = QMessageBox.question(None, 'Question', msg, QMessageBox.Yes, QMessageBox.No)
                
                if reply == QMessageBox.Yes:
                    shutil.copy(my_file, new_path)
                    lista_cop.append(item)
            else:
                if item in names:
                    shutil.copy(my_file, new_path)
                    lista_cop.append(item)
        
        if len(lista_cop) != 0:
        
            message = 'Copia finalizada con los siguientes archivos copiados: \n'
            
            for item in lista_cop:
                message += item + ", "
            
            QMessageBox.information(None, "Informacion", message)
            
        else:
            
            message = 'Cero archivos copiados'
            QMessageBox.information(None, "Informacion", message)     

Para ejecutarlo creé un script de prueba, qgis_exec.py, el cual carga el módulo y ejecuta la función. El código es el siguiente:

import qgis_40

qgis_40.copyFiles()

Cuando se ejecuta el código anterior en la Python Console pide, a través del primer cuadro de diálogo, el nombre de la sub carpeta a crear (ver imagen siguiente):

qt1

En la imagen siguiente se observa cuando solicita el número en coma flotante; el cual no se usa en el código (fue simplemente una prueba).

qt2

En la imagen a continuación se observa como la primera QMessageBox advierte sobre la no existencia del archivo a copiar ‘xxx.txt’ (podría haber hecho lo mismo con lo que el directorio a crear ya existía; tal como si se observa en la ventana de la Python Console).

qt3

La segunda QMessageBox de la imagen siguiente es del tipo “question”; en la cual se solicita la sobre escritura de archivos ya existentes en la sub carpeta creada. Como los cuatro archivos a crear ya existían esta QMessageBox apareció 4 veces.

qt4

En la imagen siguiente la QMessageBox hace un recuento de cuales fueron los archivos efectivamente copiados.

qt5

El script, en términos generales, funcionó de manera efectiva en todas las situaciones posibles. Estas incluyeron todas las combinaciones de si el directorio a crear existía o no y si los archivos a copiar existían o no dentro del directorio fuente y el directorio destino.

Nota: Se corrigió un bug detectado. El código no funcionaba para más de un archivo que no estuviese en el directorio considerado.

Esta entrada fue publicada en PyQGIS, Software Libre. Guarda el enlace permanente.

Responder

Por favor, inicia sesión con uno de estos métodos para publicar tu comentario:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s