Module: FileTreeVisualizer::I18n

Defined in:
lib/file_tree_visualizer/i18n.rb

Constant Summary collapse

SUPPORTED_LOCALES =
%w[en es].freeze
TRANSLATIONS =
{
  'en' => {
    'cli' => {
      'banner' => 'Usage: file-tree-visualizer [path] [options]',
      'options_header' => 'Options:',
      'output_option' => 'Output HTML file (default: %<default>s)',
      'top_option' => 'Number of largest files in ranking (default: %<default>s)',
      'follow_symlinks_option' => 'Follow symbolic links during scan',
      'no_progress_option' => 'Disable progress bar',
      'exclude_option' => 'Exclude patterns (comma-separated or repeated)',
      'summary_option' => 'Print terminal summary',
      'json_option' => 'Export scan result as JSON',
      'csv_option' => 'Export top files as CSV',
      'lang_option' => 'Language for CLI and report (en|es)',
      'version_option' => 'Print version',
      'help_option' => 'Show this help',
      'messages' => {
        'report_generated' => 'Report generated at: %<path>s',
        'json_generated' => 'JSON exported at: %<path>s',
        'csv_generated' => 'CSV exported at: %<path>s',
        'scanned' => 'Scanned: %<directories>s directories, %<files>s files, %<skipped>s skipped.',
        'total_size' => 'Total size: %<size>s'
      },
      'errors' => {
        'invalid_top' => '--top must be greater than 0',
        'invalid_lang' => "Unsupported language '%<lang>s'. Supported values: %<supported>s",
        'invalid_directory' => 'Path is not a directory: %<path>s',
        'use_help' => 'Use --help to see available options.',
        'unexpected' => 'Unexpected error: %<message>s'
      },
      'progress' => {
        'preparing' => 'Preparing scan %<spinner>s Files:%<files>s Dirs:%<dirs>s',
        'scanning' => 'Scanning [%<bar>s] %<percent>s%% Files:%<pf>s/%<tf>s Dirs:%<pd>s/%<td>s'
      },
      'summary' => {
        'heading' => 'Summary',
        'source' => 'Source: %<path>s',
        'total_size' => 'Total size: %<size>s',
        'files' => 'Files: %<count>s',
        'directories' => 'Directories: %<count>s',
        'skipped' => 'Skipped entries: %<count>s',
        'top_files' => 'Top files:',
        'none' => '(none)'
      }
    },
    'report' => {
      'page_title' => 'File Report',
      'header_title' => 'Disk usage report',
      'meta_source_prefix' => 'Source: ',
      'meta_generated_prefix' => 'Generated: ',
      'stats' => {
        'total_size' => 'Total size',
        'files' => 'Files',
        'directories' => 'Directories',
        'skipped' => 'Skipped entries'
      },
      'filters' => {
        'search_label' => 'Search by name/path',
        'search_placeholder' => 'eg: node_modules, .mp4, backup',
        'min_size_label' => 'Minimum size (MB)',
        'min_size_hint' => 'Filters tree nodes and ranking by minimum size.'
      },
      'panels' => {
        'tree' => 'File tree',
        'top_files' => 'Top largest files'
      },
      'table' => {
        'index' => '#',
        'size' => 'Size',
        'path' => 'Path'
      },
      'empty' => {
        'tree' => 'No results with current filters.',
        'top_files' => 'No files to show with current filters.'
      }
    }
  },
  'es' => {
    'cli' => {
      'banner' => 'Uso: file-tree-visualizer [ruta] [opciones]',
      'options_header' => 'Opciones:',
      'output_option' => 'Archivo HTML de salida (default: %<default>s)',
      'top_option' => 'Cantidad de archivos pesados en ranking (default: %<default>s)',
      'follow_symlinks_option' => 'Sigue enlaces simbólicos durante el escaneo',
      'no_progress_option' => 'Desactiva la barra de progreso',
      'exclude_option' => 'Excluye patrones (separados por coma o repetidos)',
      'summary_option' => 'Imprime resumen en terminal',
      'json_option' => 'Exporta resultado del escaneo como JSON',
      'csv_option' => 'Exporta top de archivos como CSV',
      'lang_option' => 'Idioma para CLI y reporte (en|es)',
      'version_option' => 'Muestra version',
      'help_option' => 'Muestra esta ayuda',
      'messages' => {
        'report_generated' => 'Reporte generado en: %<path>s',
        'json_generated' => 'JSON exportado en: %<path>s',
        'csv_generated' => 'CSV exportado en: %<path>s',
        'scanned' => 'Escaneado: %<directories>s directorios, %<files>s archivos, %<skipped>s omitidos.',
        'total_size' => 'Tamano total: %<size>s'
      },
      'errors' => {
        'invalid_top' => '--top debe ser mayor que 0',
        'invalid_lang' => "Idioma no soportado '%<lang>s'. Valores permitidos: %<supported>s",
        'invalid_directory' => 'La ruta no es un directorio: %<path>s',
        'use_help' => 'Usa --help para ver las opciones disponibles.',
        'unexpected' => 'Error inesperado: %<message>s'
      },
      'progress' => {
        'preparing' => 'Preparando escaneo %<spinner>s Arch:%<files>s Dir:%<dirs>s',
        'scanning' => 'Escaneando [%<bar>s] %<percent>s%% Arch:%<pf>s/%<tf>s Dir:%<pd>s/%<td>s'
      },
      'summary' => {
        'heading' => 'Resumen',
        'source' => 'Origen: %<path>s',
        'total_size' => 'Tamano total: %<size>s',
        'files' => 'Archivos: %<count>s',
        'directories' => 'Directorios: %<count>s',
        'skipped' => 'Entradas omitidas: %<count>s',
        'top_files' => 'Top archivos:',
        'none' => '(ninguno)'
      }
    },
    'report' => {
      'page_title' => 'Reporte de archivos',
      'header_title' => 'Reporte de espacio en disco',
      'meta_source_prefix' => 'Origen: ',
      'meta_generated_prefix' => 'Generado: ',
      'stats' => {
        'total_size' => 'Tamano total',
        'files' => 'Archivos',
        'directories' => 'Directorios',
        'skipped' => 'Entradas omitidas'
      },
      'filters' => {
        'search_label' => 'Buscar por nombre/ruta',
        'search_placeholder' => 'ej: node_modules, .mp4, backup',
        'min_size_label' => 'Tamano minimo (MB)',
        'min_size_hint' => 'Filtra nodos y ranking por tamano minimo.'
      },
      'panels' => {
        'tree' => 'Arbol de archivos',
        'top_files' => 'Top archivos mas pesados'
      },
      'table' => {
        'index' => '#',
        'size' => 'Tamano',
        'path' => 'Ruta'
      },
      'empty' => {
        'tree' => 'Sin resultados con los filtros actuales.',
        'top_files' => 'Sin archivos para mostrar con los filtros actuales.'
      }
    }
  }
}.freeze

Class Method Summary collapse

Class Method Details

.lookup(locale, key) ⇒ Object



195
196
197
198
199
200
201
202
203
204
205
# File 'lib/file_tree_visualizer/i18n.rb', line 195

def lookup(locale, key)
  current = TRANSLATIONS[locale]
  return nil unless current

  key.to_s.split('.').each do |part|
    return nil unless current.is_a?(Hash)

    current = current[part]
  end
  current
end

.normalize_locale(value) ⇒ Object



172
173
174
175
176
177
178
179
180
181
182
# File 'lib/file_tree_visualizer/i18n.rb', line 172

def normalize_locale(value)
  return nil if value.nil?

  normalized = value.to_s.strip.downcase
  return nil if normalized.empty?

  return 'es' if normalized.start_with?('es')
  return 'en' if normalized.start_with?('en')

  nil
end

.resolve_locale(cli_value: nil, env_lang: nil) ⇒ Object



168
169
170
# File 'lib/file_tree_visualizer/i18n.rb', line 168

def resolve_locale(cli_value: nil, env_lang: nil)
  normalize_locale(cli_value) || normalize_locale(env_lang) || 'en'
end

.supported_locale?(value) ⇒ Boolean

Returns:

  • (Boolean)


164
165
166
# File 'lib/file_tree_visualizer/i18n.rb', line 164

def supported_locale?(value)
  SUPPORTED_LOCALES.include?(normalize_locale(value))
end

.t(locale, key, **vars) ⇒ Object



184
185
186
187
188
189
190
191
192
193
# File 'lib/file_tree_visualizer/i18n.rb', line 184

def t(locale, key, **vars)
  template = lookup(locale, key) || lookup('en', key)
  return key unless template.is_a?(String)

  return template if vars.empty?

  template % vars.transform_keys(&:to_sym)
rescue KeyError
  template
end