diff --git a/modules/__init__.py b/modules/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/modules/copier.py b/modules/copier.py new file mode 100644 index 0000000..e8be16c --- /dev/null +++ b/modules/copier.py @@ -0,0 +1,50 @@ +# copier.py +# Funções para copiar ficheiros para o destino organizado +from . import organizer +from pathlib import Path +import shutil + + +def copiar_ficheiro(origem: str, destino: str): + """ + Copia o ficheiro da origem para o destino. + Deve lidar com conflitos de nomes (duplicados). + """ + pass + + +def copiar_ficheiros_para_destino( + lista_ficheiros: list[str], + base_destino: str, + categorizar_data: bool = False, + usar_criacao: bool = False, + formato_data: str = "%d-%m-%Y", +) -> None: + """ + Copiar cada ficheiro na lista para o directório base, seguindo as regras de categorização + + argumentos: + lista_ficheiros (list[str]) -> lista com o caminho dos ficheiros a serem copiados + base_destino (str) -> directorio base no qual serão criados os novos directórios com base nas regras de categorização + categorizar_data (bool) -> flag para activar categorização por data (defeito: False) + usar_criacao (bool) -> usar data de criação (defeito: False usar data de modificacao) + formato_data (str) -> formato de data para nome dos subdirectórios (defeito: '%d-%m-%Y') + + retorna: + None + """ + for ficheiro in lista_ficheiros: + if not Path(ficheiro).is_file(): + print(f"Aviso: '{ficheiro}' não existe ou não é um ficheiro.") + continue + categoria = organizer.categorizar_por_tipo(ficheiro) + data = ( + organizer.obter_data_ficheiro(ficheiro, usar_criacao) + if categorizar_data + else None + ) + pasta_destino = organizer.criar_pasta_destino( + base_destino, categoria, data, formato_data + ) + destino_final = pasta_destino / Path(ficheiro).name + shutil.copy2(ficheiro, destino_final) diff --git a/modules/logger.py b/modules/logger.py new file mode 100644 index 0000000..b2ab260 --- /dev/null +++ b/modules/logger.py @@ -0,0 +1,9 @@ +# logger.py +# Função para escrever logs do processo + + +def registar_log(mensagem): + """ + Escreve mensagem no ficheiro de log. + """ + pass diff --git a/modules/organizer.py b/modules/organizer.py new file mode 100644 index 0000000..2b140c5 --- /dev/null +++ b/modules/organizer.py @@ -0,0 +1,69 @@ +# organizer.py +# Funções para categorizar ficheiros e criar estrutura de destino +from pathlib import Path +from datetime import datetime + + +def categorizar_por_tipo(ficheiro: str) -> str: + """ + Devolve o tipo de ficheiro (imagem, documento, vídeo, etc) com base na extensão. + + argumentos: + ficheiro (str) -> caminho do ficheiro + + retorna: + str -> tipo de ficheiro + """ + # TODO: extensões configuraveis externamente pelo utilizador + extensao = Path(ficheiro).suffix.lower() + if extensao in [".jpeg", ".jpg", ".bmp", ".cr2", ".raw"]: + return "imagem" + elif extensao in [".pdf", ".doc", ".docx", ".xls", ".xlsx"]: + return "documento" + elif extensao in [".mp4", ".mpeg", ".mov"]: + return "video" + else: + return "outros" + + +def obter_data_ficheiro(ficheiro: str, usar_criacao: bool = False) -> datetime: + """ + Devolve a data de modificação ou criação do ficheiro. + + argumentos: + ficheiro (str) -> caminho do ficheiro + usar_criacao (bool) -> retornar data de criação de ficheiro (defeito: False) + + retorna: + datetime -> data de modificação ou criação do ficheiro + """ + stats_ficheiro = Path(ficheiro).stat() + timestamp = stats_ficheiro.st_ctime if usar_criacao else stats_ficheiro.st_mtime + return datetime.fromtimestamp(timestamp) + + +def criar_pasta_destino( + base_destino: str, + categoria: str, + data: datetime | None = None, + formato_data: str = "%d-%m-%Y", +) -> Path: + """ + Cria a pasta de destino apropriada, se não existir. + + argumentos: + base_destino (str) -> directorio raiz para criar novo directorio + categoria (str) -> nome do novo directorio a criar + data (datetime | None) -> nome para subdirectorio para categorizar por data (defeito: None, não criar subdirectorio de data) + formato_data (str) -> formato da data ppara o nome da pasta (defeito: '%d-%m-%Y') + + retorna: + Path -> caminho completo para o novo directorio criado + """ + if isinstance(data, datetime): + data_directorio = data.strftime(formato_data) + else: + data_directorio = "" + caminho_novo_directorio = Path(base_destino) / categoria / data_directorio + caminho_novo_directorio.mkdir(parents=True, exist_ok=True) + return caminho_novo_directorio diff --git a/modules/scanner.py b/modules/scanner.py new file mode 100644 index 0000000..5b1713a --- /dev/null +++ b/modules/scanner.py @@ -0,0 +1,23 @@ +# scanner.py +# Funções para ler diretórios e listar ficheiros +from pathlib import Path + + +def listar_ficheiros(origem: str = ".") -> list: + """ + Percorrer recursivamente a pasta de origem e devolver lista de caminhos completos dos ficheiros. + versão Pathlib + """ + lista_caminhos_ficheiros: list = [] + try: + caminho_origem = Path(origem) + for item in caminho_origem.iterdir(): + if item.is_dir(): + lista_caminhos_ficheiros.extend(listar_ficheiros(str(item.resolve()))) + else: + lista_caminhos_ficheiros.append(str(item.resolve())) + except FileNotFoundError: + print(f"Erro: a pasta '{origem}' não existe.") + except PermissionError: + print(f"Erro: sem permissões para aceder a '{origem}'.") + return lista_caminhos_ficheiros diff --git a/modules/utils.py b/modules/utils.py new file mode 100644 index 0000000..dcd98fc --- /dev/null +++ b/modules/utils.py @@ -0,0 +1,9 @@ +# utils.py +# Funções auxiliares diversas + + +def validar_caminho(caminho): + """ + Verifica se o caminho existe e é válido. + """ + pass