209 lines
6.1 KiB
Ruby
Executable File
209 lines
6.1 KiB
Ruby
Executable File
#!/usr/bin/env ruby
|
|
# frozen_string_literal: true
|
|
|
|
# tools/orquestador/dashboard/limpiar.rb
|
|
# ======================================
|
|
# Herramienta simple para limpiar hitos duplicados del dashboard P2601
|
|
# Filosofía: "Menos es más" - herramienta pequeña, específica y reutilizable
|
|
|
|
require 'fileutils'
|
|
|
|
class DashboardCleaner
|
|
def initialize(dashboard_path = nil)
|
|
@dashboard_path = dashboard_path || default_dashboard_path
|
|
@backup_dir = File.join(File.dirname(@dashboard_path), 'backups')
|
|
end
|
|
|
|
def default_dashboard_path
|
|
File.expand_path('../../../../dashboard/index.html', __FILE__)
|
|
end
|
|
|
|
def run
|
|
puts "🧹 LIMPIANDO DASHBOARD P2601"
|
|
puts "=" * 50
|
|
|
|
unless File.exist?(@dashboard_path)
|
|
puts "❌ Error: No se encuentra el dashboard en #{@dashboard_path}"
|
|
return false
|
|
end
|
|
|
|
# Crear backup
|
|
create_backup
|
|
|
|
# Leer contenido
|
|
puts "📖 Leyendo dashboard..."
|
|
content = File.read(@dashboard_path)
|
|
original_size = content.length
|
|
original_lines = content.lines.count
|
|
|
|
# Limpiar hitos duplicados
|
|
puts "🔍 Buscando hitos duplicados..."
|
|
cleaned_content = remove_duplicate_hitos(content)
|
|
|
|
# Verificar cambios
|
|
if cleaned_content == content
|
|
puts "✅ No se encontraron hitos duplicados"
|
|
return true
|
|
end
|
|
|
|
# Guardar cambios
|
|
puts "💾 Guardando dashboard limpio..."
|
|
File.write(@dashboard_path, cleaned_content)
|
|
|
|
# Mostrar resultados
|
|
show_results(content, cleaned_content)
|
|
|
|
true
|
|
end
|
|
|
|
private
|
|
|
|
def create_backup
|
|
FileUtils.mkdir_p(@backup_dir) unless Dir.exist?(@backup_dir)
|
|
|
|
timestamp = Time.now.strftime('%Y%m%d_%H%M%S')
|
|
backup_file = File.join(@backup_dir, "dashboard_clean_#{timestamp}.html")
|
|
|
|
puts "💾 Creando backup en: #{backup_file}"
|
|
FileUtils.cp(@dashboard_path, backup_file)
|
|
puts "✅ Backup creado"
|
|
end
|
|
|
|
def remove_duplicate_hitos(content)
|
|
# Patrones para identificar hitos duplicados
|
|
# Buscamos hitos que comienzan con el comentario de "Hitos adicionales agregados automáticamente"
|
|
duplicate_pattern = /<!-- Hitos adicionales agregados automáticamente - .*?-->[\s\S]*?(?=<div class="tl-item"|<\/div>\s*<div class="footer">|$)/m
|
|
|
|
# Contar ocurrencias
|
|
matches = content.scan(duplicate_pattern)
|
|
puts "📊 Encontrados #{matches.size} bloques de hitos duplicados"
|
|
|
|
# Eliminar todos los bloques duplicados
|
|
cleaned = content.gsub(duplicate_pattern, '')
|
|
|
|
# También limpiar hitos insertados en lugares incorrectos
|
|
# Buscar hitos que no están dentro de la sección .timeline
|
|
timeline_section = extract_timeline_section(cleaned)
|
|
|
|
if timeline_section
|
|
# Mantener solo los hitos dentro de la sección timeline
|
|
cleaned = restore_proper_structure(cleaned, timeline_section)
|
|
end
|
|
|
|
cleaned
|
|
end
|
|
|
|
def extract_timeline_section(content)
|
|
# Buscar la sección de timeline
|
|
timeline_start = content.index('<div class="timeline">')
|
|
return nil unless timeline_start
|
|
|
|
# Encontrar el cierre de la sección timeline
|
|
# Buscar el cierre del div que contiene la timeline
|
|
depth = 0
|
|
timeline_end = timeline_start
|
|
|
|
content[timeline_start..-1].chars.each_with_index do |char, i|
|
|
if content[timeline_start + i, 4] == '<div'
|
|
depth += 1
|
|
elsif content[timeline_start + i, 5] == '</div'
|
|
depth -= 1
|
|
if depth == 0
|
|
timeline_end = timeline_start + i + 6 # Incluir '</div>'
|
|
break
|
|
end
|
|
end
|
|
end
|
|
|
|
content[timeline_start...timeline_end]
|
|
end
|
|
|
|
def restore_proper_structure(content, timeline_section)
|
|
# Reconstruir el contenido manteniendo solo la timeline correcta
|
|
# Primero, eliminar todas las ocurrencias de hitos fuera de timeline
|
|
tl_item_pattern = /<div class="tl-item">[\s\S]*?<\/div>\s*<\/div>\s*<\/div>/m
|
|
|
|
# Extraer todos los hitos únicos
|
|
all_hitos = content.scan(tl_item_pattern).uniq
|
|
|
|
if all_hitos.any?
|
|
puts "📋 Encontrados #{all_hitos.size} hitos únicos"
|
|
|
|
# Reemplazar la sección timeline completa con una versión limpia
|
|
new_timeline = <<~HTML
|
|
<div class="timeline">
|
|
#{all_hitos.join("\n\n")}
|
|
</div>
|
|
HTML
|
|
|
|
# Reemplazar la timeline antigua con la nueva
|
|
content = content.gsub(/<div class="timeline">[\s\S]*?<\/div>\s*<\/div>\s*<\/div>/m, new_timeline)
|
|
end
|
|
|
|
content
|
|
end
|
|
|
|
def show_results(original, cleaned)
|
|
puts "\n📊 RESULTADOS DE LA LIMPIEZA:"
|
|
puts " • Líneas originales: #{original.lines.count}"
|
|
puts " • Líneas limpias: #{cleaned.lines.count}"
|
|
puts " • Líneas eliminadas: #{original.lines.count - cleaned.lines.count}"
|
|
puts " • Bytes originales: #{original.length}"
|
|
puts " • Bytes limpios: #{cleaned.length}"
|
|
puts " • Bytes ahorrados: #{original.length - cleaned.length}"
|
|
|
|
# Contar hitos únicos
|
|
hitos_count = cleaned.scan(/<div class="tl-item">/).size
|
|
puts " • Hitos únicos encontrados: #{hitos_count}"
|
|
|
|
puts "\n✅ Dashboard limpiado exitosamente"
|
|
end
|
|
end
|
|
|
|
# Ejecución principal
|
|
if __FILE__ == $0
|
|
begin
|
|
# Parsear argumentos
|
|
dashboard_path = nil
|
|
|
|
ARGV.each_with_index do |arg, i|
|
|
if arg == '--dashboard' && ARGV[i + 1]
|
|
dashboard_path = ARGV[i + 1]
|
|
end
|
|
end
|
|
|
|
cleaner = DashboardCleaner.new(dashboard_path)
|
|
success = cleaner.run
|
|
|
|
if success
|
|
puts "\n🚀 PRÓXIMOS PASOS:"
|
|
puts " 1. Verificar dashboard en: https://ns8.frlr.utn.edu.ar/bitacoras/p2601"
|
|
puts " 2. Usar herramientas de orquestador para agregar hitos correctamente"
|
|
puts " 3. Revisar backups en: dashboard/backups/"
|
|
|
|
puts "\n📅 #{Time.now.strftime('%Y-%m-%d %H:%M:%S')}"
|
|
puts "=" * 50
|
|
else
|
|
exit 1
|
|
end
|
|
rescue => e
|
|
puts "❌ Error: #{e.message}"
|
|
puts e.backtrace if ENV['DEBUG']
|
|
exit 1
|
|
end
|
|
end
|
|
|
|
# Mostrar ayuda si se solicita
|
|
if ARGV.include?('--help') || ARGV.include?('-h')
|
|
puts "📖 USO:"
|
|
puts " #{$0} [--dashboard RUTA]"
|
|
puts
|
|
puts "OPCIONES:"
|
|
puts " --dashboard RUTA - Ruta personalizada al archivo dashboard"
|
|
puts " --help, -h - Mostrar esta ayuda"
|
|
puts
|
|
puts "EJEMPLO:"
|
|
puts " #{$0} --dashboard /ruta/al/dashboard/index.html"
|
|
exit 0
|
|
end
|