Automate It! - Automação de Tarefas Repetitivas

 




Eu não sou uma pessoa que gosta de ficar tirando fotos, mas minha mulher... nossa, não sei como consegue... tudo é motivo para registrar o momento com uma foto ou gravando um vídeo  🤷‍♂️. Acontece que o espaço em nuvem do Google fotos encheu  e a memoria interna do celular também não seria suficiente, por isso, acessei o Google Takeout e baixei todos as fotos que estavam a anos armazenadas.

Mas teve um pequeno problema, as fotos não estavam organizadas da forma que a gente gostaria, e para localizar por exemplo a foto da nossa filha no aniversário de 3 meses estava muito difícil. 

Então como um bom marido, depois de muito tempo ter deixado ela esperando eu finalmente sentei para organizar isso. Mais de 15mil fotos e vídeos seriam organizados em pastas por ano e mês.

Mas teve outro problema, fazer isso vendo foto 1 a 1 iria levar uma eternidade, então recorri a automação com Python. 


Objetivo da automação: Identificar o ano e mês que o arquivo foi criado, mover para uma pasta organizando por ano e mês.

Complicação: Apesar de terem sido criado em dias diferentes, os arquivos tem a mesma data de criação, que é a data do download, então tive que obter do nome do arquivo, visto que alguns deles tinha o registro data/hora da criação no nome.

Como foi feito: No Python irei utilizar as bibliotecas OS, RE, PANDAS e DATETIME.

Onde OS é usado no código: a biblioteca os do Python está sendo usada para manipular e interagir com o sistema de arquivos. Listar arquivos e pasta, para percorrer um diretório e suas subpastas, retornando informações sobre:

- O caminho da pasta atual.

- As subpastas dentro dela.

- Os arquivos contidos nela.

Obter o caminho completo de um arquivo: A função os.path.join() é usada para construir o caminho completo de um arquivo ao combinar o diretório atual com o nome do arquivo, exemplo:

caminho_completo = os.path.join(diretorio_atual, nome_arquivo)

Isso cria o caminho completo como C:/Users/alyson/Downloads/arquivo.jpg,

E depois realizar a movimentação do arquivo.

Onde re é usado no código: A biblioteca re do Python está sendo utilizada para trabalhar com expressões regulares, que são padrões para pesquisar ou manipular strings de maneira flexível.

Identificar padrões no nome dos arquivos: A função extrair_data_do_nome usa re.search() para buscar uma correspondência no nome do arquivo com os padrões definidos (como IMG_\d{8}_\d{6} ou CYMERA_\d{8}_\d{6}). Esses padrões são expressões regulares que representam datas embutidas nos nomes dos arquivos.

match = re.search(padrao, nome_arquivo)

Decodificar os padrões de data: Após encontrar uma correspondência no nome do arquivo, a expressão regular permite extrair as partes específicas da data (ano, mês e dia) de maneira estruturada, usando grupos definidos nos padrões.

Exemplo de um padrão na planilha:

IMG_(\d{4})(\d{2})(\d{2})_\d{6}

Este padrão procura por strings que começam com IMG_.

Captura um ano (4 dígitos), mês (2 dígitos) e dia (2 dígitos) usando parênteses para definir grupos.

Assim, re é usado para encontrar o padrão no texto (re.search).

Dividir o texto em partes úteis (ano, mês, dia) com base nos grupos.

Por que usar re aqui?

A biblioteca re é essencial para manipular strings com padrões variáveis. No meu caso, como os nomes dos arquivos seguem formatos diferentes, usar expressões regulares facilita a extração automática de informações como datas, em vez de depender de métodos simples como split() ou startswith().

Se houver novos padrões de nome de arquivo, basta adicionar as expressões regulares correspondentes na planilha, sem alterar o código principal. Isso torna o código flexível e escalável.

Onde pandas é usado no código: A biblioteca pandas é usada para trabalhar com a planilha de padrões onde as expressões regulares estão armazenadas. O Pandas é amplamente utilizado para manipular e analisar dados tabulares, como arquivos do tipo Excel ou CSV

O pandas lê o arquivo Excel especificado (padroes.xlsx) e carrega seu conteúdo como um DataFrame (estrutura de dados do Pandas que se parece com uma tabela do Excel).

df = pd.read_excel(caminho_planilha)

Isso permite acessar os padrões (expressões regulares) e seus formatos de data para processar os nomes dos arquivos.

df.iterrows()

 Este método itera sobre as linhas do DataFrame, permitindo que você acesse cada padrão (coluna Expressão Regular) e o formato associado

O Pandas facilita a leitura, escrita e manipulação de dados tabulares. Por isso eu posso adicionar novos padrões diretamente na planilha, editar ou reorganizar os formatos de data sem precisar alterar o código.

Isso torna o processo dinâmico, qualquer mudança na planilha é automaticamente incorporada no código, sem necessidade de ajustá-lo.

Onde é usado datetime no código: A biblioteca datetime no código é usada para trabalhar com datas. Especificamente, ela converte as strings extraídas dos nomes dos arquivos para objetos de data, permitindo manipulação e processamento dessas datas de forma estruturada

O datetime também permite extrair partes específicas da data, como ano, mês, dia, etc., de forma simples e direta.

ano_arquivo = data_arquivo.year

mes_arquivo = data_arquivo.month


Passo a Passo:

* Inicio criando as funções(etapas do processo) necessárias conclusão

- Saber quais os padrões que existem

- Identificar a qual padrão de nome o arquivo está associado e obter a data

- Verificar se já existe pasta com data obtida e cria-la se necessário

- Finalmente a função que varre o diretório obtendo todos os arquivos e chama as funções anteriores para chegar ao objetivo e contar quantas foram movidas.

* Informo quais as variáveis referente o local onde estão os arquivos e a planilha

* Defino o contador como zero e depois indico que ele é igual ao resultado obtido por chamar a função de varrer, o que acabara acionando todas as outras.

* Concluo com uma mensagem que diz quantos arquivos foram tratados.


import os
import re
import pandas as pd
from datetime import datetime



def carregar_padroes_da_planilha(caminho_planilha):
    #Carrega os padrões de nome de arquivo e expressões regulares de uma planilha Excel.
    #Retorna um dicionário com os padrões de nome como chave e as expressões regulares
    # como valor.
   
    planilha_padrao = pd.read_excel(caminho_planilha)
    padroes_data = {}
   
    for _, linha in planilha_padrao.iterrows():
        padrao = linha['Padrão']
        expressao_regular = linha['Expressao']
        padroes_data[padrao] = expressao_regular
   
    return padroes_data

def extrair_data_do_nome(nome_arquivo, padroes_data):
    """
    Tenta extrair a data do nome do arquivo com base nos padrões definidos na tabela
      carregada.
    Retorna a data como um objeto datetime, ou None se não conseguir identificar.
    """
    for chave, padrao in padroes_data.items():
        match = re.search(padrao, nome_arquivo)
        if match:
            try:
                # Se o padrão for encontrado, tenta construir a data a partir dos grupos
                ano, mes, dia, hora, minuto, segundo = match.groups()
                # Cria a data e hora a partir dos grupos
                return datetime(int(ano), int(mes), int(dia), int(hora), int(minuto),
                                 int(segundo))
            except ValueError:
                pass
    return None


#cria função que cria pasta de ano mÊs
def criar_pastas_ano_mes(ano, mes):
    #defino as variaveis da função para facilitar o manuseio
    pasta_organizar = "D:\\ORGANIZAR"
    pasta_ano = os.path.join(pasta_organizar, str(ano))
    pasta_mes = os.path.join(pasta_ano, str(mes).zfill(2))
    #verifico se já existe a pasta ano, se não existe eu crio
    if not os.path.exists(pasta_ano):
        os.makedirs(pasta_ano)
     #verifico se já existe a pasta mês, se não existe eu crio
    if not os.path.exists(pasta_mes):
        os.makedirs(pasta_mes)

#cria a principal responsavel por organizar
def listar_arquivos(diretorio, contador, padroes_data):
    #vamos tentar, para cada arquivo no diretorio
    try:
        for nome_arquivo in os.listdir(diretorio):
            caminho_completo = os.path.join(diretorio, nome_arquivo)
            #verifico se o item localizado é a pasta ORGANIZAR,
            # então realizo a contagem dos arquivos no diretorio
            if os.path.isdir(caminho_completo):
                if nome_arquivo == "ORGANIZAR":
                    continue
                contador = listar_arquivos(caminho_completo, contador, padroes_data)
            else:
                #verifica se o item é um arquivo
                # obtenho a data do arquivo chamando a função de extração
                data_arquivo = extrair_data_do_nome(nome_arquivo, padroes_data)
                if data_arquivo:
                    #defino as variaveis ano e mês a partir da função utilizada
                    ano_arquivo = data_arquivo.year
                    mes_arquivo = data_arquivo.month
                    #com a variavel em mão eu chamo a função de criar pasta
                    criar_pastas_ano_mes(ano_arquivo, mes_arquivo)

                    # utilizando a variavel ano e mes do arquivo, e tendo criado ou
                    # confirmado que a pasta existe
                    #consigo definir o Caminho da pasta de destino
                    pasta_destino = os.path.join("D:\\ORGANIZAR", str(ano_arquivo),
                                                 str(mes_arquivo).zfill(2))

                    # Mover arquivo para a pasta de destino
                    #crio a variavel novo caminho que é a junção da pasta de destino
                    # com o nome do arquivo
                    novo_caminho = os.path.join(pasta_destino, nome_arquivo)
                    #chamo a função rename alterando o antigo caminho pelo novo caminho
                    os.rename(caminho_completo, novo_caminho)
                    print(f"Arquivo movido: {novo_caminho}")

                    contador += 1
                else:
                    print(f"Data não encontrada no nome: {nome_arquivo}")
    except PermissionError:
        pass
    return contador


#definir variaveis que serão utilizadas
caminho_planilha = r"D:\padroes.xlsx"
# Diretório raiz para começar a varredura
diretorio_raiz = r"D:\ORGANIZAR\bagunça"
# Inicializa o contador
contador = 0
# Carrega os padrões da planilha
padroes_data = carregar_padroes_da_planilha(caminho_planilha)

# Chamando a função para listar os arquivos dentro do diretório raiz
# e no final teremos o numero de arquivos tratados
contador = listar_arquivos(diretorio_raiz, contador, padroes_data)

# Imprime o número de arquivos localizados
print("Número total de arquivos organizados:", contador)


Assista a execução:




Aplicabilidade: Para pessoas físicas, uma solução como essa pode ser utilizada para organizar arquivos pessoais como músicas, vídeos ou documentos, classificando-os por categorias ou datas automaticamente, o que facilita a busca e o gerenciamento. Por exemplo, organizar digitalmente coleções de músicas por gênero e ano ou separar documentos importantes por categorias como impostos, recibos ou contratos.

Para pessoas jurídicas, o princípio da solução pode ser aplicado em diversos cenários, como a gestão de arquivos corporativos, separando relatórios, atas e contratos por departamento e data de criação. Pode também ser usado em ambientes industriais para organizar automaticamente logs de produção ou em empresas de marketing para categorizar imagens e vídeos de campanhas publicitárias por datas e projetos.




Comentários