([^<]+)<\/div>/)
next unless id_match && titulo_match
hitos << {
id: id_match[1],
titulo: titulo_match[1],
estado: estado_match ? estado_match[1] : 'pending',
fecha: fecha_match ? fecha_match[1] : 'Sin fecha',
descripcion: descripcion_match ? descripcion_match[1] : nil,
tags: hito.scan(/
([^<]+)<\/span>/).flatten
}
end
# Eliminar duplicados por ID
hitos.uniq { |h| h[:id] }
end
def contar_estados_hitos(content)
estados = Hash.new(0)
content.scan(/<\/div>/) do |estado|
estados[estado[0]] += 1
end
estados
end
def extraer_metricas_clave(content)
metricas = {}
# Buscar porcentaje de progreso
if match = content.match(/id="progressPct">([^<]+))
metricas['Progreso'] = match[1]
end
# Buscar hitos completados
if match = content.match(/Hitos Completados[^<]*<[^>]*>([^<]+))
metricas['Hitos Completados'] = match[1]
end
# Buscar hitos pendientes
if match = content.match(/Hitos Pendientes[^<]*<[^>]*>([^<]+))
metricas['Hitos Pendientes'] = match[1]
end
metricas
end
def extraer_valores_metricas(content)
metricas = {}
# Buscar porcentaje de progreso
if match = content.match(/id="progressPct">([^<]+))
metricas['Progreso'] = match[1]
end
# Buscar hitos completados
if match = content.match(/Hitos Completados[^<]*<[^>]*>([^<]+))
metricas['Hitos Completados'] = match[1]
end
# Buscar hitos pendientes
if match = content.match(/Hitos Pendientes[^<]*<[^>]*>([^<]+))
metricas['Hitos Pendientes'] = match[1]
end
# Buscar esfuerzo total
if match = content.match(/Esfuerzo Total[^<]*<[^>]*>([^<]+))
metricas['Esfuerzo Total'] = match[1]
end
# Buscar horas físicas
if match = content.match(/Horas Físicas[^<]*<[^>]*>([^<]+))
metricas['Horas Físicas'] = match[1]
end
metricas
end
end
# Interfaz de línea de comandos
if __FILE__ == $0
begin
preview = DashboardPreview.new
# Parsear argumentos
modo = 'resumen'
dashboard_path = nil
ARGV.each_with_index do |arg, i|
if arg == '--dashboard' && ARGV[i + 1]
dashboard_path = ARGV[i + 1]
elsif i == 0 && !arg.start_with?('--')
modo = arg
end
end
preview = DashboardPreview.new(dashboard_path)
case modo
when 'resumen', 'summary'
success = preview.mostrar_vista_previa('resumen')
when 'hitos', 'milestones'
success = preview.mostrar_vista_previa('hitos')
when 'estructura', 'structure'
success = preview.mostrar_vista_previa('estructura')
when 'estadisticas', 'stats', 'statistics'
success = preview.mostrar_vista_previa('estadisticas')
when 'rapido', 'quick', 'fast'
success = preview.mostrar_resumen_rapido
when 'help', '--help', '-h'
puts "📖 USO:"
puts " #{$0} [modo] [--dashboard RUTA]"
puts
puts "MODOS:"
puts " resumen, summary - Resumen completo (predeterminado)"
puts " hitos, milestones - Hitos detallados"
puts " estructura, structure - Estructura del dashboard"
puts " estadisticas, stats - Estadísticas detalladas"
puts " rapido, quick - Resumen rápido"
puts " help - Mostrar esta ayuda"
puts
puts "OPCIONES:"
puts " --dashboard RUTA - Ruta personalizada al archivo dashboard"
puts
puts "EJEMPLOS:"
puts " #{$0} resumen"
puts " #{$0} hitos"
puts " #{$0} rapido"
puts " #{$0} --dashboard /ruta/al/dashboard.html estructura"
puts
success = true
else
puts "❌ Modo '#{modo}' no reconocido"
puts " Use '#{$0} help' para ver la ayuda"
success = false
end
if success
puts "\n🚀 HERRAMIENTAS RELACIONADAS:"
puts " 1. limpiar.rb - Limpiar hitos duplicados"
puts " 2. agregar_hitos.rb - Agregar nuevos hitos"
puts " 3. actualizar_estados.rb - Actualizar estados de hitos"
puts " 4. verificar.rb - Verificar estructura del dashboard"
puts
puts "🔗 Dashboard: https://ns8.frlr.utn.edu.ar/bitacoras/p2601"
puts "📅 #{Time.now.strftime('%Y-%m-%d %H:%M:%S')}"
puts "=" * 60
else
exit 1
end
rescue => e
puts "❌ Error: #{e.message}"
puts e.backtrace if ENV['DEBUG']
exit 1
end
end