using System.Runtime.InteropServices;
using Sunfish.Shares;
namespace Sunfish;
/// <summary>Textos de usuario en espanol e ingles.</summary>
public static partial class Strings
{
public static bool Spanish { get; private set; }
static Strings() => Detect();
/// <summary>SUNFISH_LANG manda; si no, el locale (LC_ALL, LC_MESSAGES, LANG) o el idioma de Windows.</summary>
public static void Detect()
{
string? lang = FirstNonEmpty("SUNFISH_LANG", "LC_ALL", "LC_MESSAGES", "LANG");
if (lang is null && OperatingSystem.IsWindows())
lang = (GetUserDefaultUILanguage() & 0x3FF) == 0x0A ? "es" : "en";
Spanish = lang is not null && lang.StartsWith("es", StringComparison.OrdinalIgnoreCase);
}
/// <summary>Fuerza el idioma ("es" o "en"), p. ej. desde --lang.</summary>
public static void Force(string lang) =>
Spanish = lang.StartsWith("es", StringComparison.OrdinalIgnoreCase);
[LibraryImport("kernel32.dll")]
private static partial ushort GetUserDefaultUILanguage();
private static string? FirstNonEmpty(params string[] variables)
{
foreach (var name in variables)
{
var value = Environment.GetEnvironmentVariable(name);
if (!string.IsNullOrWhiteSpace(value))
return value;
}
return null;
}
private static string T(string english, string spanish) => Spanish ? spanish : english;
// Web: navegador de directorios
public static string ColName => T("Name", "Nombre");
public static string ColSize => T("Size", "Tamaño");
public static string ColDate => T("Date", "Fecha");
public static string ParentFolder => T("Parent folder", "Carpeta superior");
public static string EmptyFolder => T("(empty folder)", "(carpeta vacía)");
public static string Shares => T("Shares", "Carpetas compartidas");
public static string FolderContents => T("contents", "contenido");
// Web: errores
public static string ErrorTitle(int status) => status switch
{
400 => T("Bad request", "Petición incorrecta"),
403 => T("Forbidden", "Prohibido"),
404 => T("Not found", "No encontrado"),
405 => T("Method not allowed", "Método no permitido"),
416 => T("Range not satisfiable", "Rango no válido"),
401 => T("Authentication required", "Hace falta identificarse"),
409 => T("Conflict", "Conflicto"),
413 => T("Too large", "Demasiado grande"),
429 => T("Too many attempts", "Demasiados intentos"),
507 => T("Not enough space", "No hay espacio suficiente"),
_ => T("Server error", "Error del servidor"),
};
public static string ErrorText(int status) => status switch
{
401 => T("Enter a valid user name and password.", "Escribe un usuario y una contraseña válidos."),
403 => T("This action is not allowed here.", "Esta acción no está permitida aquí."),
404 => T("The requested address does not exist.", "La dirección pedida no existe."),
429 => T("Too many failed attempts. Wait a minute and try again.", "Demasiados intentos fallidos. Espera un minuto y vuelve a probar."),
_ => "",
};
// Web: acciones
public static string Upload => T("Upload", "Subir");
public static string UploadHint => T("Upload files (or drop them on the page)", "Subir ficheros (o suéltalos en la página)");
public static string Uploading => T("Uploading", "Subiendo");
public static string UploadDone => T("Upload finished", "Subida terminada");
public static string NewFolder => T("New folder", "Nueva carpeta");
public static string Create => T("Create", "Crear");
public static string Rename => T("Rename", "Renombrar");
public static string RenameShort => T("ren", "ren");
public static string Delete => T("Delete", "Borrar");
public static string DeleteShort => T("del", "borrar");
public static string Cancel => T("Cancel", "Cancelar");
public static string DownloadZip => T("Download folder as ZIP", "Descargar la carpeta en ZIP");
public static string RenameTitle(string name) => T($"Rename {name}", $"Renombrar {name}");
public static string NewName => T("New name:", "Nombre nuevo:");
public static string DeleteFileQuestion(string name) =>
T($"Delete the file {name}? This cannot be undone.", $"¿Borrar el fichero {name}? No se puede deshacer.");
public static string DeleteFolderQuestion(string name) =>
T($"Delete the folder {name} and everything inside it? This cannot be undone.",
$"¿Borrar la carpeta {name} y todo su contenido? No se puede deshacer.");
public static string BadToken => T("The form has expired. Go back, reload the page and try again.",
"El formulario ha caducado. Vuelve atrás, recarga la página y prueba otra vez.");
public static string ZipTooLarge => T("The folder is too large for a ZIP file (4 GB or 65535 entries).",
"La carpeta es demasiado grande para un ZIP (4 GB o 65535 entradas).");
public static string OpResult(FileOpResult result, string name) => result switch
{
FileOpResult.InvalidName => T($"'{name}' is not a valid name.", $"'{name}' no es un nombre válido."),
FileOpResult.NotFound => T($"'{name}' does not exist.", $"'{name}' no existe."),
FileOpResult.Exists => T($"'{name}' already exists.", $"'{name}' ya existe."),
FileOpResult.NoSpace => T("There is not enough free space.", "No hay espacio libre suficiente."),
FileOpResult.Conflict => T($"The upload of '{name}' got out of step; start it again.", $"La subida de '{name}' se ha desincronizado; empiézala de nuevo."),
_ => T($"'{name}' could not be changed.", $"No se ha podido modificar '{name}'."),
};
// Configuracion
public static string ConfigLine(int line, string message) =>
T($"line {line}: {message}", $"línea {line}: {message}");
public static string ConfigBadLine => T("not a section, comment or key = value", "no es una sección, comentario ni clave = valor");
public static string ConfigBadBool(string key, string value) =>
T($"{key}: '{value}' is not true/false", $"{key}: '{value}' no es true/false");
public static string ConfigBadNumber(string key, string value) =>
T($"{key}: '{value}' is not a valid number", $"{key}: '{value}' no es un número válido");
public static string ConfigBadAddress(string value) =>
T($"Bind: '{value}' is not an IP address", $"Bind: '{value}' no es una dirección IP");
public static string ConfigBadLocation(string share, string location) =>
T($"share '{share}': invalid Location '{location}'", $"share '{share}': Location '{location}' no válida");
public static string ConfigDuplicateLocation(string share, string location) =>
T($"share '{share}': Location '{location}' is already used", $"share '{share}': la Location '{location}' ya está en uso");
public static string ConfigMissingPath(string share) =>
T($"share '{share}': missing Path", $"share '{share}': falta Path");
public static string ConfigUnknownSection(string name) =>
T($"unknown section [{name}]", $"sección desconocida [{name}]");
// Servidor
public static string HttpListening(string endpoint) =>
T($"HTTP listening on {endpoint}", $"HTTP escuchando en {endpoint}");
public static string HttpStopped => T("HTTP stopped", "HTTP detenido");
public static string ConnectionError(string remote, string message) =>
T($"{remote}: connection error: {message}", $"{remote}: error de conexión: {message}");
public static string FtpListening(string endpoint) =>
T($"FTP listening on {endpoint}", $"FTP escuchando en {endpoint}");
public static string FtpStopped => T("FTP stopped", "FTP detenido");
public static string MdnsAnnouncing(string instance) =>
T($"Announced on the LAN as '{instance}'", $"Anunciado en la red local como '{instance}'");
public static string MdnsUnavailable(string message) =>
T($"Cannot announce on the LAN (mDNS port 5353): {message}", $"No se puede anunciar en la red local (puerto mDNS 5353): {message}");
public static string CannotListen(int port, string message) =>
T($"Cannot listen on port {port}: {message}", $"No se puede escuchar en el puerto {port}: {message}");
public static string ConfigReloaded => T("Configuration reloaded", "Configuración recargada");
public static string ConfigReloadError(string error) =>
T($"Configuration: {error}", $"Configuración: {error}");
public static string UnknownShareKey(string key) =>
T($"unknown option '{key}'", $"opción desconocida '{key}'");
// Comunes a las aplicaciones (GUI y TUI)
public static string AppShares => T("Shares", "Shares");
public static string AppUsers => T("Users", "Usuarios");
public static string AppLog => T("Log", "Registro");
public static string AppStatus => T("Status", "Estado");
public static string AppRunning => T("Running", "En marcha");
public static string AppStopped => T("Stopped", "Parado");
public static string AppPort => T("HTTP port", "Puerto HTTP");
public static string AppAddresses => T("Addresses", "Direcciones");
public static string AppNoShares => T("No shares yet. Add a folder to share it.", "Aún no hay shares. Añade una carpeta para compartirla.");
public static string AppQuickShare(string path) =>
T($"Quick share (not saved): {path}", $"Compartido al momento (no se guarda): {path}");
public static string FieldName => T("Name", "Nombre");
public static string FieldLocation => T("Location (URL path)", "Location (ruta en la URL)");
public static string FieldPath => T("Folder", "Carpeta");
public static string FieldIndex => T("Index document (empty: none)", "Documento índice (vacío: ninguno)");
public static string FieldUsers => T("Users (comma separated; empty: public)", "Usuarios (separados por comas; vacío: público)");
public static string FieldPassword => T("Password", "Contraseña");
public static string OptEnabled => T("Enabled", "Activo");
public static string OptListing => T("List folders", "Listar carpetas");
public static string OptUpload => T("Upload and create folders", "Subir y crear carpetas");
public static string OptOverwrite => T("Overwrite existing files", "Sobrescribir ficheros");
public static string OptRename => T("Rename", "Renombrar");
public static string OptDelete => T("Delete", "Borrar");
public static string OptZip => T("Download folders as ZIP", "Descargar carpetas en ZIP");
public static string WarnUploadListing => T(
"Upload + listing: anyone can publish web pages in this share.",
"Subir + listar: cualquiera puede publicar páginas web en este share.");
public static string AskDeleteShare(string name) =>
T($"Remove the share '{name}'? The folder and its files are not touched.",
$"¿Quitar el share '{name}'? La carpeta y sus ficheros no se tocan.");
public static string AskDeleteUser(string name) =>
T($"Delete the user '{name}'?", $"¿Borrar el usuario '{name}'?");
public static string ErrorNameInUse(string name) => T($"'{name}' is already in use.", $"'{name}' ya está en uso.");
public static string ErrorBadName(string name) => T($"Invalid name: '{name}'.", $"Nombre no válido: '{name}'.");
public static string ErrorNotAFolder(string path) => T($"Not a folder: {path}", $"No es una carpeta: {path}");
public static string ErrorPasswordEmpty => T("The password cannot be empty.", "La contraseña no puede estar vacía.");
}