docs: armonización masiva de bitácoras, categorización de nodos y diagnóstico srv-dasu
This commit is contained in:
@@ -0,0 +1,174 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
# ==========================================================
|
||||
# dtic-BKPs/lib/menu.rb — Menú TUI interactivo + editor CRUD
|
||||
# ==========================================================
|
||||
|
||||
module DTICBKPs
|
||||
class Menu
|
||||
def initialize(config, dispatcher, log)
|
||||
@config = config
|
||||
@dispatcher = dispatcher
|
||||
@log = log
|
||||
end
|
||||
|
||||
def ejecutar
|
||||
loop do
|
||||
system('clear') || system('cls')
|
||||
mostrar_encabezado
|
||||
opciones = construir_opciones
|
||||
|
||||
opciones.each { |op| puts op[:linea] }
|
||||
puts "#{C::CYAN}────────────────────────#{C::RESET}"
|
||||
|
||||
print "\n#{C::YELLOW}Selecciona > #{C::RESET}"
|
||||
$stdout.flush
|
||||
entrada = $stdin.gets&.chomp&.strip&.upcase
|
||||
next if entrada.nil? || entrada.empty?
|
||||
|
||||
op = opciones.find { |o| o[:id] == entrada }
|
||||
unless op
|
||||
@log.error("Opción no válida: #{entrada}")
|
||||
sleep 1
|
||||
next
|
||||
end
|
||||
|
||||
case op[:tipo]
|
||||
when :tarea
|
||||
@dispatcher.ejecutar_tarea(op[:config])
|
||||
when :comando
|
||||
@dispatcher.ejecutar_comando(op[:config])
|
||||
when :editor
|
||||
editor_interactivo
|
||||
@config.reload!
|
||||
when :salir
|
||||
puts "Saliendo..."
|
||||
exit 0
|
||||
end
|
||||
|
||||
unless [:editor, :salir].include?(op[:tipo]) || @config.auto_avanzar
|
||||
print "\nPresiona Enter para continuar..."
|
||||
$stdin.gets
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def mostrar_encabezado
|
||||
puts "#{C::BOLD}#{C::CYAN}╔══════════════════════════════════════════╗#{C::RESET}"
|
||||
puts "#{C::BOLD}#{C::CYAN}║ dtic-BKPs — Procesador de Backups v6.0 ║#{C::RESET}"
|
||||
puts "#{C::BOLD}#{C::CYAN}╚══════════════════════════════════════════╝#{C::RESET}"
|
||||
end
|
||||
|
||||
def construir_opciones
|
||||
opciones = []
|
||||
|
||||
puts "\n#{C::BOLD}Tareas Individuales:#{C::RESET}"
|
||||
@config.tareas.each_with_index do |t, i|
|
||||
id = "T#{i + 1}"
|
||||
opciones << { id: id, tipo: :tarea, config: t, linea: " #{C::YELLOW}#{id}.#{C::RESET} #{t[:texto]}" }
|
||||
end
|
||||
|
||||
puts "\n#{C::BOLD}Comandos (Secuencias):#{C::RESET}"
|
||||
@config.comandos.each_with_index do |c, i|
|
||||
id = "C#{i + 1}"
|
||||
opciones << { id: id, tipo: :comando, config: c, linea: " #{C::YELLOW}#{id}.#{C::RESET} #{c[:texto]}" }
|
||||
end
|
||||
|
||||
puts "\n#{C::CYAN}────────────────────────#{C::RESET}"
|
||||
opciones << { id: 'E', tipo: :editor, linea: " #{C::YELLOW}E.#{C::RESET} Editar tareas y comandos" }
|
||||
opciones << { id: 'S', tipo: :salir, linea: " #{C::YELLOW}S.#{C::RESET} Salir" }
|
||||
|
||||
opciones.each { |op| puts op[:linea] if op[:tipo].is_a?(Symbol) && [:editor, :salir].include?(op[:tipo]) }
|
||||
opciones
|
||||
end
|
||||
|
||||
# ─── Editor CRUD ──────────────────────────────────────────────
|
||||
|
||||
def editor_interactivo
|
||||
loop do
|
||||
system('clear') || system('cls')
|
||||
puts "#{C::BOLD}#{C::CYAN}--- Editor de Tareas y Comandos ---#{C::RESET}\n\n"
|
||||
|
||||
puts "#{C::BOLD}Tareas:#{C::RESET}"
|
||||
@config.tareas.each_with_index do |t, i|
|
||||
puts " #{C::YELLOW}T#{i+1}.#{C::RESET} #{t[:texto]} #{C::DIM}(#{t[:id]})#{C::RESET}"
|
||||
end
|
||||
|
||||
puts "\n#{C::BOLD}Comandos:#{C::RESET}"
|
||||
@config.comandos.each_with_index do |c, i|
|
||||
puts " #{C::YELLOW}C#{i+1}.#{C::RESET} #{c[:texto]} #{C::DIM}(#{c[:id]}, tareas: #{c[:tareas]&.join(', ')})#{C::RESET}"
|
||||
end
|
||||
|
||||
puts "\n#{C::CYAN}[Tx]=Editar, [NT]=Nueva Tarea, [BT]=Borrar Tarea, [G]=Guardar y Volver#{C::RESET}"
|
||||
print "> "
|
||||
$stdout.flush
|
||||
op = $stdin.gets&.chomp&.strip&.downcase
|
||||
return if op.nil?
|
||||
|
||||
case op
|
||||
when /^t(\d+)$/
|
||||
idx = $1.to_i - 1
|
||||
editar_tarea(idx) if @config.tareas[idx]
|
||||
when 'nt'
|
||||
nueva_tarea
|
||||
when 'bt'
|
||||
print "Número a borrar (ej: 1): "
|
||||
idx = $stdin.gets&.chomp.to_i - 1
|
||||
@config.remove_tarea(idx) if idx >= 0 && @config.tareas[idx]
|
||||
when 'g'
|
||||
@config.save!
|
||||
@log.ok("Configuración guardada.")
|
||||
sleep 1
|
||||
return
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def editar_tarea(idx)
|
||||
tarea = @config.tareas[idx]
|
||||
puts "\n#{C::CYAN}Editando: #{tarea[:texto]}#{C::RESET}"
|
||||
puts "#{C::DIM}(Dejar vacío = mantener valor actual)#{C::RESET}\n"
|
||||
|
||||
tarea.each do |k, v|
|
||||
next if k == :id
|
||||
tipo_hint = [true, false].include?(v) ? " (true/false)" : ""
|
||||
print " #{C::YELLOW}#{k}#{C::RESET}#{tipo_hint} [#{v}]: "
|
||||
$stdout.flush
|
||||
nuevo = $stdin.gets&.chomp&.strip
|
||||
next if nuevo.nil? || nuevo.empty?
|
||||
|
||||
tarea[k] = case v
|
||||
when Symbol then nuevo.to_sym
|
||||
when TrueClass, FalseClass then nuevo.downcase == 'true'
|
||||
else nuevo
|
||||
end
|
||||
end
|
||||
@log.ok("Tarea actualizada.")
|
||||
end
|
||||
|
||||
def nueva_tarea
|
||||
tarea = {
|
||||
id: "tarea_#{Time.now.to_i}",
|
||||
texto: "Nueva Tarea",
|
||||
tipo: "rclone",
|
||||
origen: "",
|
||||
destino: "",
|
||||
eliminar_origen: false,
|
||||
sobrescribir: false
|
||||
}
|
||||
editar_tarea_hash(tarea)
|
||||
@config.add_tarea(tarea)
|
||||
end
|
||||
|
||||
def editar_tarea_hash(tarea)
|
||||
tarea.each do |k, v|
|
||||
print " #{C::YELLOW}#{k}#{C::RESET} [#{v}]: "
|
||||
$stdout.flush
|
||||
nuevo = $stdin.gets&.chomp&.strip
|
||||
tarea[k] = nuevo unless nuevo.nil? || nuevo.empty?
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user