Organiza tus archivos con un simple script en Python.

Organiza tus archivos con un simple script en Python.

Introducción


Por lo regular intento ser una persona ordenada en muchos ámbitos de mi vida, una de las cosas que más me incomoda, es tener una gran cantidad de archivos de todo tipo en una sola carpeta, o simplemente tener un desorden de archivos.

Hace unos días andaba algo aburrido y decidí investigar un poco en como podría automatizar o crear algo para ayudarme a organizar todos esos archivos de todo tipo, en carpetas exclusivas y separarlos por tipo de archivo. Así es como hice mi organizador de archivos con un simple script en Python, sin librerías extras.

Antes de empezar

Es recomendable que tengas un poco de conocimiento sobre Python y algunos conceptos sobre manejo de archivos, principalmente en la terminal. No los utilizaremos como tal, pero si esa misma lógica directamente aplicada en código Python.

Creando el Script

Para comenzar, necesitamos crear nuestro archivo .py, en mi caso yo lo llamaré file_organizer.py. Para saber de que trata ese script y ser descriptivos.

Éste es un script muy sencillo el cual no tiene dependencias con otras librerías, sólo utilizando módulos del core de Python.

Primero, importamos los módulos que utilizaremos y que nos permitirán hacer el manejo de archivos, ejecutar comando directamente en el sistema y más.

import os
import shutil
import sys

Vamos a explicar muy breve lo de arriba.
os : nos permite utilizar de una manera efectiva y simple, funciones propias del sistema operativo.
shutil : Nos ofrece una serie de operaciones de alto nivel para archivos o colecciones.
sys : Provee acceso a funciones y objetos mantenidos por el interprete.

Ahora ya es tiempo de comenzar directamente con la funcionalidad del script, como pueden notar, son pocos módulos, que incluso podríamos omitir el módulo sys y quedaría en sólo 2 pero, más adelante lo ampliaré y mejoraré el script.

A continuación, vamos a definir una función la cual nos permitirá saber con base a un tipo de extensión dada, retornará el nombre del directorio/folder al que pertenece o debe estar.

def directory(file_extension: str) -> str:
    if not file_extension:
        return

    folders_by_extension = {
        "exe": "Software",
        "txt": "Texts",
        "pdf": "PDF Documents",
        "epub": "Books",
        "jpg": "Images",
        "jpeg": "Images",
        "png": "Images",
        "raw": "Images",
        "mp3": "Music",
        "mp4": "Videos",
        "mkv": "Videos",
        "xlsx": "Excel Files",
        "ppt": "Slides",
        "doc": "Documents",
        "rar": "Compressed Files",
        "zip": "Compressed Files"
    }
    return folders_by_extension.get(file_extension, 'Extras')

Como saben un diccionario se conforma por {key: value}, dónde key es la extensión del archivo y value es el nombre del directorio al que pertenece. Por ende definimos que, si por ejemplo a la función le pasamos una extensión zip, retornará Compressed Files y así consecuentemente con cada extensión definida.

Dado lo anterior, ya tenemos la primera parte de nuestro script, para obtener el nombre del directorio en el cual guardaremos nuestros archivos.

Primera parte función organizer

Y es hora de llegar a la parte interesante, la función principal de nuestro script, para ello definimos una función organizer, iremos por pasos, ya que es un poco largo, y así, explicar cada parte.

def organize(path: str):
    if not os.path.exists(path):
        print(f"ERROR. Not found {path} or not exists.")
        return
    files = os.listdir(path)
    extensions = [os.path.splitext(file)[1].strip(".") for file in    files]

Primero en nuestra función vamos a requerir de un parametro de nombre path y de tipo string. Ésta será la URL/locación de la carpeta en donde organizarás los archivos, por ejemplo C:\Users\user\Downloads.
Seguido, utilizamos el módulo os, para hacer saber si existe la dirección que le hemos indicado, de lo contrario, imprimimos un error y nos salimos del ciclo de ejecución.

Si existe, entonces con en una variable de nombre files, guardamos una lista que va a contener los nombres de las entradas/archivos en el directorio dado por la ruta/path.

Seguido, vamos a definir una variable extensions que contendrá todas las extensiones de los archivos que se encuentren en el directorio, por ejemplo [«exe», «pdf», «epub»] etc.

Segunda parte función organizer

Ya tenemos la primera parte, ahora toca la segunda parte.
Para esto, haremos dos iteraciones a las extensiones que obtuvimos arriba.

 for ext in extensions:
    dir = directory(ext) or ""
    new_directory = os.path.join(path, dir)
    if dir and not os.path.exists(new_directory):
        os.makedirs(new_directory)

for file in files:
    ext = os.path.splitext(file)[1].strip(".")
    _dir = directory(ext)
    if not _dir:
        continue

    source_filepath = os.path.join(path, file)
    destination_filepath = os.path.join(path, _dir, file)

    if not os.path.exists(destination_filepath):
        shutil.move(source_filepath, destination_filepath)
        print(f"Was moved {file} into {_dir} directory. \n")
print(f"All the files was organized successfully in {path}")

En la primera iteración, recorremos la lista de las extensiones y, por cada extensión, se la pasaremos a nuestra función directory, para así con la extensión dada, obtener el nombre del directorio al que pertenece.
Después, entramos a la dirección que proporcionamos a path, y pasamos también, el nombre del directorio que nos regresó nuestra función directory, si existe no hace nada, de lo contrario, creamos el directorio con os.makedirs(nombre_directorio).

En la segunda iteración, recorremos los archivos que se encuentran en el directorio, hacemos un split para obtener la extensión de cada archivo en el ciclo y obtenemos el nombre de su respectiva carpeta de destino.
Si la función no devuelve nada, damos un continue.

Seguido, declaramos dos variables, una con el nombre de source_filepath, la cual es la dirección/path en donde se encuentra actualmente el archivo.
La otra variable es destination_filepath, ésta es la dirección de destino de nuestro archivo, con os.path.join, podemos entrar de manera inteligente a directorios y pasar varios argumentos.

Un ejemplo de como se vería cada variable es de la siguiente forma:

# en representación cada variable tendría un valor similar a:
source_filepath = "C:/users/usuario1/Descargas/clean_code.pdf"

destination_filepath = "C:/users/usuario1/Descargas/PDF Documents/clean_code.pdf"

Como pueden observar, en source, se define la ruta donde se encuentra el archivo, y en destination, la ruta final o a la cual tendrá como destino.

Por último, en la parte final de la función, lo que hacemos es utilizar el módulo shutil para mover de un directorio a otro. Lo cual sería un equivalente en la terminal a escribir:

# shutil.move(source_filepath, destination_filepath)
mv ruta/del/archivo.txt ruta/final/del/archivo.txt

Por último sólo hacemos un print de que se ha movido X archivo a X ruta.

Tercera parte y final

Ahora para que nuestro script pueda correr y recibir parametros desde la terminal, vamos a escribir lo siguiente:

if __name__ == "__main__":
    try:
        directory_location = sys.argv[1]
        organize(directory_location)
    except Exception as e:
        print(f"There was an error: {str(e)}")

Con sys.argv, es una lista de argumentos con la cual se invocó al interprete.
pasamos el directory_location a nuestra función organize y listo, verás la magia funcionar!
Para correr el script, lo ejecutamos de la siguiente manera.

# $ python file_organizer.py <ruta_a_tu_carpeta>
$ python file_organizer.py C:/users/usuario1/Descargas
imagen antes de correr el script
Directorio antes de correr el script
resultado de carpetas después de correr el script
Directorio después de ejecutar el script.

Conclusión


Como pudieron observar, es un script muy sencillo que nos permite automatizar tareas tal vez no complicadas, pero si que nos podría quitar algo de tiempo, y nos ayuda a tener nuestro espacio de trabajo/ordenador, más limpio y accesible para cuando busques cualquier archivo, canción, documento, libro, etc.

Espero que les haya gustado, y me gustaría ver como mejoran éste script, pueden meter aún más tipos de archivos, yo sólo ingresé algunos, pero echando a volar su imaginación pueden lograr muchas cosas. Me gustaría que me compartieran sus resultados de éste script y sus mejoras en mis redes sociales:

Twitter: @migantoju0
Instagram: @migantoju
Facebook: codingtaco

Repositorio: https://github.com/migantoju/scripts-no-dependencies

DigitalOcean Referral Badge