Modificar ecu_ascii_analyzer.py
This commit is contained in:
@ -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()
|
||||
Reference in New Issue
Block a user