Modificar ecu_ascii_analyzer.py

This commit is contained in:
2025-06-02 10:58:10 +00:00
parent aefa0a6226
commit e8369886b0

View File

@ -2,6 +2,8 @@ import tkinter as tk
from tkinter import filedialog, scrolledtext, ttk, messagebox
import re
import os
import shutil # Nova importação para operações de ficheiro (cópia)
from datetime import datetime # Nova importação para timestamp
from collections import Counter
# Importações dos novos módulos de padrões
@ -16,6 +18,13 @@ from Data.bmw_ecu_group_handler import load_bmw_ecu_list # Nova importação par
# from patterns.bmw_patterns import PATTERNS_BMW
# etc.
def sanitize_name(name):
"""Remove caracteres inválidos de uma string para usar como nome de ficheiro/pasta."""
# Remove ou substitui caracteres que são tipicamente problemáticos em nomes de ficheiro/pasta
name = re.sub(r'[\/*?"<>|:]', '_', name)
name = name.replace('\n', '_').replace('\r', '_')
return name[:100] # Limita o comprimento para evitar nomes excessivamente longos
# --- Constantes Globais ---
BRAND_NAMES = ['VAG', 'LandRover/Jaguar', 'BMW', 'Mercedes', 'Renault/Dacia', 'Peugeot/Citroen', 'Opel', 'Fiat/Lancia/Alfa', 'Ford']
@ -496,9 +505,13 @@ def create_main_window():
global_progress_label = progress_label
brand_buttons_frame = ttk.Frame(root)
brand_buttons_frame.pack(pady=5, padx=10, fill=tk.X)
brand_buttons_frame.pack(pady=5, padx=5, fill=tk.X)
global_brand_buttons_frame = brand_buttons_frame
# Botão Global File Organizer
file_organizer_button = ttk.Button(root, text="File Organizer", command=initiate_bmw_file_organizer)
file_organizer_button.pack(pady=5, padx=10, fill=tk.X)
category_buttons_frame = ttk.Frame(root)
category_buttons_frame.pack(pady=5, padx=10, fill=tk.X)
global_category_buttons_frame = category_buttons_frame
@ -510,5 +523,124 @@ def create_main_window():
clear_ui_state() # Limpa a UI antes de iniciar
root.mainloop()
def process_folder_for_bmw_organization(source_folder, base_destination_folder, progress_callback=None):
"""Processa uma pasta, analisa ficheiros BMW e organiza-os em subpastas nomeadas."""
processed_files = 0
failed_files = 0
total_files = sum([len(files) for r, d, files in os.walk(source_folder)])
current_file_count = 0
if progress_callback:
progress_callback(0, total_files, "Iniciando organização...")
for root, _, files in os.walk(source_folder):
for filename in files:
current_file_count += 1
if progress_callback:
progress_callback(current_file_count, total_files, f"Processando: {filename}")
file_path = os.path.join(root, filename)
try:
ascii_content = read_file_content(file_path)
if not ascii_content:
print(f"Não foi possível ler o conteúdo ASCII de: {filename}")
failed_files += 1
continue
# Realiza uma análise inicial para 'Ecu Family' e 'Possible Software Number'
initial_patterns = {key: PATTERNS_COMMON[key] for key in INITIAL_ANALYSIS_PATTERNS_KEYS if key in PATTERNS_COMMON}
analysis_results = analyze_ascii_patterns_from_file(ascii_content, initial_patterns)
ecu_family_data = analysis_results.get('Ecu Family', {})
sw_number_data = analysis_results.get('Possible Software Number', {})
# Pega o primeiro (ou mais comum) Ecu Family e Software Number
# Pode ser necessário refinar esta lógica para escolher o "melhor" se houver múltiplos
main_ecu_family = next(iter(ecu_family_data.keys()), "UnknownECU")
main_sw_number = next(iter(sw_number_data.keys()), "UnknownSW")
# Sanitiza os nomes para criar nomes de pasta válidos
s_ecu_family = sanitize_name(main_ecu_family)
s_sw_number = sanitize_name(main_sw_number)
s_filename = sanitize_name(os.path.splitext(filename)[0]) # Nome do ficheiro sem extensão
# Cria o nome da pasta da família da ECU
ecu_family_folder_name = s_ecu_family
ecu_family_path = os.path.join(base_destination_folder, ecu_family_folder_name)
os.makedirs(ecu_family_path, exist_ok=True)
# Cria o nome da subpasta de destino final dentro da pasta da família da ECU
# Ex: BMW_EDC17C41_10SW012345_NomeOriginalDoFicheiro
subfolder_name = f"BMW_{s_ecu_family}_{s_sw_number}_{s_filename}"
destination_subfolder = os.path.join(ecu_family_path, subfolder_name)
os.makedirs(destination_subfolder, exist_ok=True)
# Copia o ficheiro original
shutil.copy2(file_path, os.path.join(destination_subfolder, filename))
# Cria o ficheiro de texto com os dados recolhidos
info_file_path = os.path.join(destination_subfolder, f"info_{s_filename}.txt")
with open(info_file_path, 'w', encoding='utf-8') as info_f:
info_f.write(f"Ficheiro Original: {filename}\n")
info_f.write(f"Caminho Original: {file_path}\n")
info_f.write(f"Data da Análise: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}\n\n")
info_f.write(f"Ecu Family Encontrada: {main_ecu_family}\n")
if ecu_family_data:
for ecu, count in ecu_family_data.items():
info_f.write(f" - {ecu} (Contagem: {count})\n")
info_f.write(f"\nSoftware Number Encontrado: {main_sw_number}\n")
if sw_number_data:
for sw, count in sw_number_data.items():
info_f.write(f" - {sw} (Contagem: {count})\n")
# Adicionar mais dados se necessário
processed_files += 1
except PermissionError as e_perm:
print(f"Erro de permissão ao processar o ficheiro {filename}: {e_perm}. O ficheiro pode estar em uso.")
failed_files += 1
except Exception as e:
print(f"Erro geral ao processar o ficheiro {filename}: {e}")
failed_files += 1
# Considerar logar o erro para um ficheiro de log
if progress_callback:
progress_callback(total_files, total_files, "Organização concluída!")
return processed_files, failed_files
def initiate_bmw_file_organizer():
source_dir = filedialog.askdirectory(title="Selecione a Pasta de Origem com Ficheiros BMW")
if not source_dir:
messagebox.showinfo("Cancelado", "Operação de organização cancelada.")
return
dest_dir = filedialog.askdirectory(title="Selecione a Pasta de Destino Base para Organização")
if not dest_dir:
messagebox.showinfo("Cancelado", "Operação de organização cancelada.")
return
if global_progress_bar and global_progress_label:
def progress_update(current, total, message):
global_progress_label.config(text=message)
if total > 0:
percentage = (current / total) * 100
global_progress_bar['value'] = percentage
else:
global_progress_bar['value'] = 0
if global_root_window: global_root_window.update_idletasks()
try:
processed, failed = process_folder_for_bmw_organization(source_dir, dest_dir, progress_update)
summary_message = f"Organização Concluída.\nFicheiros Processados com Sucesso: {processed}\nFicheiros com Falha: {failed}"
messagebox.showinfo("Concluído", summary_message)
except Exception as e:
messagebox.showerror("Erro na Organização", f"Ocorreu um erro: {e}")
if global_progress_label: global_progress_label.config(text="Erro na organização.")
if global_progress_bar: global_progress_bar['value'] = 0
else:
messagebox.showerror("Erro", "Componentes de progresso não inicializados.")
if __name__ == "__main__":
create_main_window()