Skip to content

Instantly share code, notes, and snippets.

@lucasoal
Last active December 27, 2024 11:28
Show Gist options
  • Select an option

  • Save lucasoal/b16d19f2533c33486de68148e5c3842b to your computer and use it in GitHub Desktop.

Select an option

Save lucasoal/b16d19f2533c33486de68148e5c3842b to your computer and use it in GitHub Desktop.
Renomeia arquivos a partir da data e hora de criação: YYmd_HMS.type -> 20241225_193542

Rename Files by Creation Datetime

rename_by_creation_datetime (Python):

import gc
import os
import subprocess

from dateutil import parser


def format_date(date_str):
    try:
        # Substitui os ":" por "-" para que o formato seja aceito pelo parser
        date_str = date_str.replace(":", "-", 2)

        # Usa o parser do dateutil para lidar com data e fuso horário
        date_obj = parser.isoparse(date_str)

        # Converte a data para o formato desejado 'YYYYMMDD_HHMMSS'
        formatted_date = date_obj.strftime("%Y%m%d_%H%M%S")

        return formatted_date
    except ValueError as e:
        return None


# Função para renomear arquivos sem colidir com arquivos existentes
def get_unique_filename(folder_path, base_name, extension):
    counter = 1
    new_name = base_name + extension
    new_file_path = os.path.join(folder_path, new_name)

    while os.path.exists(new_file_path):
        new_name = f"{base_name}_{counter:02d}{extension}"
        new_file_path = os.path.join(folder_path, new_name)
        counter += 1

    return new_name


# Função auxiliar para obter a data do EXIF usando o exiftool
def get_date_taken(filepath):
    # print(f"{filepath}")
    tags = ["CreationDate", "DateTimeOriginal", "GPSDateTime", "CreateDate"]
    formatted_date = ""

    for t in tags:
        try:
            # Executa o comando exiftool para pegar o valor do tag
            result = subprocess.run(
                ["exiftool", f"-{t}", "-s", "-s", "-s", filepath],
                capture_output=True,
                text=True,
                check=True,
            )

            # Retorna a data formatada se encontrada
            date_taken = result.stdout.strip()
        except:
            continue

        if date_taken != "":
            formatted_date = format_date(date_taken)
            if formatted_date:
                # print(f"{t}: {date_taken} → {formatted_date}")
                break

    # Se nenhuma data foi encontrada, retorna None
    return formatted_date


# Função para renomear arquivos
def rename_files_in_folder(folder_path):
    # Lista todos os arquivos na pasta
    files = os.listdir(folder_path)
    count_img, count_vid, count_extra = 1, 1, 1

    # Inicializa contadores para imagens e vídeos sem data
    # for i, file_name in enumerate(files[:1000]):
    for i, file_name in enumerate(files):
        file_path = os.path.join(folder_path, file_name)

        if os.path.isfile(file_path):
            # Verifica se é um vídeo

            if file_path.lower().endswith(("png", "jpg", "jpeg", "heic", "dng")):
                type, count = "IMG", count_img + 1
            elif file_path.lower().endswith(("mov", "avi", "mp4")):
                type, count = "VID", count_vid + 1
            else:
                type, count = "FILE", count_extra + 1

            date_taken = get_date_taken(file_path)

            if date_taken:
                try:
                    # A data já está no formato desejado 'YYYYMMDD_HHMMSS'
                    new_base_name = date_taken
                except ValueError:
                    # Caso o formato da data não seja válido, usa o contador
                    new_base_name = f"{type}_{count:02d}"
            else:
                # Caso não tenha o atributo "Date Taken", usa o contador
                new_base_name = f"{type}_{count:02d}"
            # Obtemos um nome único
            new_name = get_unique_filename(
                folder_path, new_base_name, os.path.splitext(file_name)[1]
            )

            # Renomeia o arquivo
            new_file_path = os.path.join(folder_path, new_name)
            os.rename(file_path, new_file_path)
            print(f"Hit {i}: {file_name}{new_name} {" " * 80}", flush=True, end="\r")

            # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            # ~~~~~~~~~ Limpeza de memória ~~~~~~~~
            del (file_path, date_taken, new_base_name, new_name, new_file_path)
            gc.collect()
            # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


# Caminho para a pasta onde os arquivos estão localizados
folder_path = r"path"

# Executa a renomeação dos arquivos
rename_files_in_folder(folder_path)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment