""" consolidate_knowledge.py - Consolidar 118 ficheiros JSON num único ficheiro Author: Descomplicar® Crescimento Digital Link: https://descomplicar.pt Copyright: 2025 Descomplicar® """ import os import json from pathlib import Path from datetime import datetime from typing import Dict, List import statistics # Configurações INPUT_DIR = "/media/ealmeida/Dados/GDrive/Cloud/Clientes_360/CTF_Carstuff/KB/Scrapper/sites/knowledge_base_final" OUTPUT_FILE = "/media/ealmeida/Dados/GDrive/Cloud/Clientes_360/CTF_Carstuff/KB/Scrapper/sites/knowledge_base_consolidated.json" def load_all_knowledge() -> List[Dict]: """Carrega todos os ficheiros JSON.""" all_knowledge = [] input_path = Path(INPUT_DIR) json_files = sorted(input_path.glob("knowledge_*.json")) print(f"📂 Encontrados {len(json_files)} ficheiros JSON") print("🔄 A carregar...") for idx, json_file in enumerate(json_files, 1): try: with open(json_file, 'r', encoding='utf-8') as f: data = json.load(f) # Adicionar metadata do ficheiro data['_source_file'] = json_file.name data['_id'] = idx all_knowledge.append(data) if idx % 20 == 0: print(f" ⏳ {idx}/{len(json_files)} carregados...") except Exception as e: print(f" ⚠️ Erro em {json_file.name}: {e}") continue print(f"✅ {len(all_knowledge)} ficheiros carregados com sucesso") return all_knowledge def generate_statistics(knowledge_list: List[Dict]) -> Dict: """Gera estatísticas sobre o conhecimento consolidado.""" stats = { 'total_entradas': len(knowledge_list), 'total_casos_completos': 0, 'categorias': {}, 'tipos_conteudo': {}, 'nivel_expertise': {}, 'materiais_principais': {}, 'keywords_tecnicas': {}, 'sites_fonte': {}, 'aplicabilidades': {} } for entry in knowledge_list: # Contar casos completos casos = entry.get('casos_completos', []) stats['total_casos_completos'] += len(casos) # Categorias cat = entry.get('categoria_aplicacao', 'desconhecido') stats['categorias'][cat] = stats['categorias'].get(cat, 0) + 1 # Tipos de conteúdo tipo = entry.get('tipo_conteudo', 'desconhecido') stats['tipos_conteudo'][tipo] = stats['tipos_conteudo'].get(tipo, 0) + 1 # Nível de expertise nivel = entry.get('nivel_expertise', 'desconhecido') stats['nivel_expertise'][nivel] = stats['nivel_expertise'].get(nivel, 0) + 1 # Materiais principais materiais = entry.get('materiais_discutidos', {}).get('principais', []) for mat in materiais: stats['materiais_principais'][mat] = stats['materiais_principais'].get(mat, 0) + 1 # Keywords técnicas keywords = entry.get('keywords_tecnicas', []) for kw in keywords: stats['keywords_tecnicas'][kw] = stats['keywords_tecnicas'].get(kw, 0) + 1 # Sites fonte source = entry.get('_source_file', 'unknown') site = source.split('_')[1] if '_' in source else 'unknown' stats['sites_fonte'][site] = stats['sites_fonte'].get(site, 0) + 1 # Aplicabilidades apps = entry.get('aplicabilidade', []) for app in apps: stats['aplicabilidades'][app] = stats['aplicabilidades'].get(app, 0) + 1 # Ordenar por frequência (top 20) stats['materiais_principais'] = dict(sorted( stats['materiais_principais'].items(), key=lambda x: x[1], reverse=True )[:20]) stats['keywords_tecnicas'] = dict(sorted( stats['keywords_tecnicas'].items(), key=lambda x: x[1], reverse=True )[:30]) return stats def consolidate_knowledge(): """Função principal de consolidação.""" print("═══════════════════════════════════════════════════════════") print(" CTF CARSTUFF - CONSOLIDAÇÃO KNOWLEDGE BASE") print("═══════════════════════════════════════════════════════════") print() # Carregar todos os ficheiros all_knowledge = load_all_knowledge() if not all_knowledge: print("❌ Nenhum conhecimento carregado!") return print() print("📊 A gerar estatísticas...") # Gerar estatísticas statistics_data = generate_statistics(all_knowledge) # Estrutura final consolidada consolidated = { 'metadata': { 'created_at': datetime.now().isoformat(), 'total_entries': len(all_knowledge), 'total_complete_cases': statistics_data['total_casos_completos'], 'source_directory': INPUT_DIR, 'description': 'Knowledge base consolidada de estofamento automotivo, náutico e aeronáutico', 'extraction_criteria': 'Apenas casos completos: Problema → Solução → Resultado' }, 'statistics': statistics_data, 'knowledge_base': all_knowledge } # Guardar ficheiro consolidado print(f"💾 A guardar em: {OUTPUT_FILE}") output_path = Path(OUTPUT_FILE) with open(output_path, 'w', encoding='utf-8') as f: json.dump(consolidated, f, indent=2, ensure_ascii=False) # Verificar tamanho file_size = output_path.stat().st_size / (1024 * 1024) # MB print() print("═══════════════════════════════════════════════════════════") print(" CONSOLIDAÇÃO CONCLUÍDA") print("═══════════════════════════════════════════════════════════") print(f"📊 Total de entradas: {len(all_knowledge)}") print(f"📦 Total de casos completos: {statistics_data['total_casos_completos']}") print(f"📁 Tamanho do ficheiro: {file_size:.2f} MB") print(f"💾 Ficheiro: {OUTPUT_FILE}") print() print("📈 ESTATÍSTICAS TOP:") print() print("🏷️ Categorias:") for cat, count in statistics_data['categorias'].items(): print(f" - {cat}: {count}") print() print("📋 Tipos de conteúdo:") for tipo, count in statistics_data['tipos_conteudo'].items(): print(f" - {tipo}: {count}") print() print("🎓 Nível de expertise:") for nivel, count in statistics_data['nivel_expertise'].items(): print(f" - {nivel}: {count}") print() print("🏢 Sites fonte:") for site, count in statistics_data['sites_fonte'].items(): print(f" - {site}: {count}") print() print("🔝 Top 10 Materiais:") for idx, (mat, count) in enumerate(list(statistics_data['materiais_principais'].items())[:10], 1): print(f" {idx}. {mat}: {count} menções") print() print("═══════════════════════════════════════════════════════════") if __name__ == '__main__': consolidate_knowledge()