From b0e9a7d9c4987c1f888f85619122f5d3bb31517d Mon Sep 17 00:00:00 2001 From: Michael gasche Date: Sun, 29 Sep 2024 17:39:10 +0200 Subject: [PATCH] Changes: - Log-buffer for messages before logging initialization (fix) - Correct encodings language files (again) --- .../BeetRootConfigurationManager.java | 30 +++-- .../ch/autumo/beetroot/logging/LogBuffer.java | 107 +++++++++++++++ .../ch/autumo/beetroot/server/BaseServer.java | 6 + web/lang/app/lang_es.properties | 126 +++++++++--------- web/lang/app/lang_it.properties | 28 ++-- web/lang/pw/lang_es.properties | 58 ++++---- web/lang/pw/lang_it.properties | 16 +-- web/lang/pw/lang_pt.properties | 46 +++---- web/lang/tmpl/lang_it.properties | 32 ++--- 9 files changed, 285 insertions(+), 164 deletions(-) create mode 100644 src/main/java/ch/autumo/beetroot/logging/LogBuffer.java diff --git a/src/main/java/ch/autumo/beetroot/BeetRootConfigurationManager.java b/src/main/java/ch/autumo/beetroot/BeetRootConfigurationManager.java index adda3a64..ecc93f60 100644 --- a/src/main/java/ch/autumo/beetroot/BeetRootConfigurationManager.java +++ b/src/main/java/ch/autumo/beetroot/BeetRootConfigurationManager.java @@ -19,7 +19,9 @@ import java.io.File; import java.io.FileInputStream; +import java.io.FileNotFoundException; import java.io.IOException; +import java.io.InputStream; import java.io.InputStreamReader; import java.nio.charset.StandardCharsets; import java.util.ArrayList; @@ -39,6 +41,8 @@ import org.slf4j.LoggerFactory; import org.w3c.dom.Document; +import ch.autumo.beetroot.logging.LogBuffer; +import ch.autumo.beetroot.logging.LogBuffer.LogLevel; import ch.autumo.beetroot.security.SecureApplication; import ch.autumo.beetroot.utils.Helper; import ch.autumo.beetroot.utils.security.Security; @@ -204,8 +208,7 @@ public synchronized void initializeWithFullPath(String configFilePath) throws Ex if (servletContext == null) { if (rootPath == null || rootPath.length() == 0) { - - LOG.error("Specified '-DROOTPATH' is non-existant! Check starting script of java process."); + LogBuffer.log(LogLevel.ERROR, "Specified '-DROOTPATH' is non-existant! Check starting script of java process."); throw new Exception("Specified '-DROOTPATH' is non-existant! Check starting script of java process."); } @@ -215,8 +218,7 @@ public synchronized void initializeWithFullPath(String configFilePath) throws Ex final File dir = new File(rootPath); if (!dir.exists() || !dir.isDirectory()) { - - LOG.error("Specified '-DROOTPATH' is invalid! Check starting script of java process."); + LogBuffer.log(LogLevel.ERROR, "Specified '-DROOTPATH' is invalid! Check starting script of java process."); throw new Exception("Specified '-DROOTPATH' is non-existant! Check starting script of java process."); } } @@ -247,7 +249,7 @@ public synchronized void initializeWithFullPath(String configFilePath) throws Ex generalProps.load(BeetRootConfigurationManager.class.getResourceAsStream(file)); } catch (IOException e) { - LOG.error("Couldn't read general server configuration '" + file + "' !", e); + LogBuffer.log(LogLevel.ERROR, "Couldn't read general server configuration '{}' !", file, e); throw new Exception("Couldn't read general server configuration '" + file + "' !"); } finally { if (fis != null) @@ -258,12 +260,12 @@ public synchronized void initializeWithFullPath(String configFilePath) throws Ex // load some main props separately this.csrf = getYesOrNo(Constants.KEY_WS_USE_CSRF_TOKENS, Constants.YES); if (this.csrf) - LOG.info("CSRF activated!"); + LogBuffer.log(LogLevel.INFO, "CSRF activated!"); this.extendedRoles = getYesOrNo(Constants.KEY_WS_USE_EXT_ROLES, Constants.YES); this.translateTemplates = getYesOrNo(Constants.KEY_WEB_TRANSLATIONS, Constants.NO); if (this.translateTemplates) - LOG.info("Web templates are translated."); + LogBuffer.log(LogLevel.INFO, "Web templates are translated."); // HTML Input map @@ -277,11 +279,14 @@ public synchronized void initializeWithFullPath(String configFilePath) throws Ex fis = new FileInputStream(mapFile); this.htmlInputMap.load(fis); } else { - this.htmlInputMap.load(BeetRootConfigurationManager.class.getResourceAsStream(htmlMap)); + final InputStream is = BeetRootConfigurationManager.class.getResourceAsStream(htmlMap); + this.htmlInputMap.load(is); + if (is == null) + throw new FileNotFoundException("The HTML input map file could not be loaded during the streaming attempt."); } } catch (IOException e) { htmlInputMap = null; - LOG.error("Couldn't read additionl HTML input mapping file '" + htmlMap + "' !", e); + LogBuffer.log(LogLevel.ERROR, "Couldn't read additionl HTML input mapping file '{}' !", htmlMap, e); throw new Exception("Couldn't read additionl HTML input mapping file '" + htmlMap + "' !"); } finally { if (fis != null) @@ -300,12 +305,15 @@ public synchronized void initializeWithFullPath(String configFilePath) throws Ex isr = new InputStreamReader(new FileInputStream(f), StandardCharsets.UTF_8); this.languageMap.load(isr); } else { - isr = new InputStreamReader(BeetRootConfigurationManager.class.getResourceAsStream(file), StandardCharsets.UTF_8); + final InputStream is = BeetRootConfigurationManager.class.getResourceAsStream(file); + if (is == null) + throw new FileNotFoundException("Language file could not be loaded during the streaming attempt."); + isr = new InputStreamReader(is, StandardCharsets.UTF_8); this.languageMap.load(isr); } } catch (IOException e) { this.languageMap = null; - LOG.warn("Couldn't read languages file '" + file + "' !", e); + LogBuffer.log(LogLevel.WARN, "Couldn't read languages file '{}' !", file, e); } finally { if (isr != null) isr.close(); diff --git a/src/main/java/ch/autumo/beetroot/logging/LogBuffer.java b/src/main/java/ch/autumo/beetroot/logging/LogBuffer.java new file mode 100644 index 00000000..5c0b8393 --- /dev/null +++ b/src/main/java/ch/autumo/beetroot/logging/LogBuffer.java @@ -0,0 +1,107 @@ +/** + * + * Copyright (c) 2024 autumo Ltd. Switzerland, Michael Gasche + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +package ch.autumo.beetroot.logging; + +import java.util.ArrayList; +import java.util.List; + +import org.slf4j.Logger; + + +/** + * Log-buffer; used before the logging system is initialized. + */ +public class LogBuffer { + + /** List to buffer logs. */ + private static final List logBuffer = new ArrayList<>(); + + /** Enum for logging severity levels. */ + public enum LogLevel { + INFO, DEBUG, ERROR, WARN, TRACE + } + + /** Inner class to hold log entry data (message, severity level). */ + private static class LogEntry { + LogLevel level; + String message; + Object arguments[]; + LogEntry(LogLevel level, String message) { + this.level = level; + this.message = message; + } + LogEntry(LogLevel level, String message, Object... arguments) { + this.level = level; + this.message = message; + this.arguments = arguments; + } + } + + /** + * Log message to log buffer. + * + * @param level level + * @param message message + * @param arguments arguments + */ + public static void log(LogLevel level, String message) { + logBuffer.add(new LogEntry(level, message)); + } + + /** + * Log message to log buffer. + * + * @param level level + * @param message message + * @param arguments arguments + */ + public static void log(LogLevel level, String message, Object... arguments) { + logBuffer.add(new LogEntry(level, message, arguments)); + } + + /** + * Flush the buffered logs to the actual SLF4J logger + * + * @param logger the logger + */ + public static void flushToLogger(Logger logger) { + for (LogEntry entry : logBuffer) { + switch (entry.level) { + case INFO: + logger.info(entry.message, entry.arguments); + break; + case DEBUG: + logger.debug(entry.message, entry.arguments); + break; + case ERROR: + logger.error(entry.message, entry.arguments); + break; + case WARN: + logger.warn(entry.message, entry.arguments); + break; + case TRACE: + logger.trace(entry.message, entry.arguments); + break; + default: + logger.info(entry.message, entry.arguments); + } + } + logBuffer.clear(); // Clear buffer after flushing + } + +} diff --git a/src/main/java/ch/autumo/beetroot/server/BaseServer.java b/src/main/java/ch/autumo/beetroot/server/BaseServer.java index 9135d85f..8a398390 100644 --- a/src/main/java/ch/autumo/beetroot/server/BaseServer.java +++ b/src/main/java/ch/autumo/beetroot/server/BaseServer.java @@ -43,6 +43,7 @@ import ch.autumo.beetroot.BeetRootDatabaseManager; import ch.autumo.beetroot.BeetRootWebServer; import ch.autumo.beetroot.Constants; +import ch.autumo.beetroot.logging.LogBuffer; import ch.autumo.beetroot.logging.LogEventAppender; import ch.autumo.beetroot.logging.LoggingFactory; import ch.autumo.beetroot.server.action.Download; @@ -262,6 +263,11 @@ public BaseServer(String params[]) { //------------------------------------------------------------------------------ + // Flush the messages that have been collected before log-system initialization + LogBuffer.flushToLogger(LOG); + + //------------------------------------------------------------------------------ + // DB manager initialization if not yet done! try { diff --git a/web/lang/app/lang_es.properties b/web/lang/app/lang_es.properties index baa5a236..60abab42 100644 --- a/web/lang/app/lang_es.properties +++ b/web/lang/app/lang_es.properties @@ -1,72 +1,72 @@ # -# Traducciones de la aplicación base +# Traducciones de la aplicación base # -# Generalmente, no necesitas cambiar las traducciones aquí. Estas +# Generalmente, no necesitas cambiar las traducciones aquí. Estas # traducciones son utilizadas por beetRoot, pero por supuesto puedes # ajustar el texto. # -# Agrega un archivo de traducción para cada idioma, por ejemplo: +# Agrega un archivo de traducción para cada idioma, por ejemplo: # - lang_en.properties # - lang_es.properties # # Tienes que escapar las comillas simples con una segunda comilla simple; -# escribe "¡Serás feliz y tendrás todo!". +# escribe "¡Serás feliz y tendrás todo!". # -base.err.lang.title=Error de configuración del idioma -base.err.lang.msg=El(los) idioma(s) ''{0}'' ha(n) sido configurado(s), ¡pero faltan las traducciones! -base.err.resource.title=¡Recurso no encontrado! -base.err.resource.msg=¡Recurso web ''{0}'' no encontrado en el servidor! -base.err.resource.mime.title=¡Tipo MIME para el recurso no implementado! -base.err.resource.mime.msg=¡El tipo MIME no está implementado para el recurso web solicitado ''{0}''! +base.err.lang.title=Error de configuración del idioma +base.err.lang.msg=El(los) idioma(s) ''{0}'' ha(n) sido configurado(s), ¡pero faltan las traducciones! +base.err.resource.title=¡Recurso no encontrado! +base.err.resource.msg=¡Recurso web ''{0}'' no encontrado en el servidor! +base.err.resource.mime.title=¡Tipo MIME para el recurso no implementado! +base.err.resource.mime.msg=¡El tipo MIME no está implementado para el recurso web solicitado ''{0}''! -base.err.srv.404.title=La página solicitada no existe. (Error HTTP 404) -base.err.srv.501.title=No hay implementación para esta solicitud. (Error HTTP 501) +base.err.srv.404.title=La página solicitada no existe. (Error HTTP 404) +base.err.srv.501.title=No hay implementación para esta solicitud. (Error HTTP 501) base.err.srv.io.title=Error interno del servidor -base.err.srv.io.msg=Excepción de E/S:
{0} +base.err.srv.io.msg=Excepción de E/S:
{0} base.err.srv.re.title=Error interno del servidor -base.err.srv.re.msg=Excepción de respuesta (Estado: {0}): Excepción
{1} +base.err.srv.re.msg=Excepción de respuesta (Estado: {0}): Excepción
{1} base.err.srv.db.title=Error interno del servidor -base.err.srv.db.msg=Excepción de BD:
{0} +base.err.srv.db.msg=Excepción de BD:
{0} base.err.srv.ex.title=Error interno del servidor -base.err.srv.ex.msg=Excepción:
{0} +base.err.srv.ex.msg=Excepción:
{0} base.err.srv.mail.title=Error interno del servidor base.err.srv.mail.msg=No se pudo enviar el correo:
{0} base.err.srv.sms.title=Error interno del servidor base.err.srv.sms.msg=No se pudo enviar el SMS:
{0} -base.err.csrf.inv.title=¡El token CSRF es inválido! -base.err.csrf.inv.msg=¡Alguien debe estar haciendo trampa o presionaste "ATRÁS" en el navegador y, por lo tanto, usaste un formulario antiguo/inválido para modificar datos! ¡Regresa y recarga la página o usa el menú! -base.err.csrf.gen.title=¡No se pudo generar el token CSRF! -base.err.csrf.gen.msg=Excepción:
{0} +base.err.csrf.inv.title=¡El token CSRF es inválido! +base.err.csrf.inv.msg=¡Alguien debe estar haciendo trampa o presionaste "ATRÃS" en el navegador y, por lo tanto, usaste un formulario antiguo/inválido para modificar datos! ¡Regresa y recarga la página o usa el menú! +base.err.csrf.gen.title=¡No se pudo generar el token CSRF! +base.err.csrf.gen.msg=Excepción:
{0} -base.err.handler.construct.title=¡Error en el constructor del manejador! -base.err.handler.construct.msg=No se encontró implementación para la clase de manejador ''{0}'' con {1} parámetros.
Excepción:
{2} -base.err.handler.impl.title=¡Error del manejador! -base.err.handler.impl.msge=¡No se encontró implementación para la clase de manejador ''{0}''!
Excepción:
{1} +base.err.handler.construct.title=¡Error en el constructor del manejador! +base.err.handler.construct.msg=No se encontró implementación para la clase de manejador ''{0}'' con {1} parámetros.
Excepción:
{2} +base.err.handler.impl.title=¡Error del manejador! +base.err.handler.impl.msge=¡No se encontró implementación para la clase de manejador ''{0}''!
Excepción:
{1} base.err.template.title=Error del motor de plantillas -base.err.template.msg=Contacta a tu personal técnico. -base.err.template.parsing.title=¡Error al analizar la plantilla! +base.err.template.msg=Contacta a tu personal técnico. +base.err.template.parsing.title=¡Error al analizar la plantilla! base.err.template.parsing.msg=Plantilla:
''{0}'' -base.err.template.execute.title=¡No se pudo ejecutar la plantilla ''{0}''! +base.err.template.execute.title=¡No se pudo ejecutar la plantilla ''{0}''! -base.err.login.msg=Inicio de sesión inválido, ¡inténtalo de nuevo! +base.err.login.msg=Inicio de sesión inválido, ¡inténtalo de nuevo! -base.error.noaccess.msg=Lo siento, no tienes acceso aquí. +base.error.noaccess.msg=Lo siento, no tienes acceso aquí. -base.error.handler.unique=Ya se encontró ''{0}'' con valor(es) {1}, ¡especifica otro(s)! -base.error.handler.savedid=No se pudo obtener el ID del registro a guardar; ¡el almacenamiento falló! -base.error.handler.savedid.rel=No se pudo obtener el ID del registro de muchos a muchos a guardar; ¡el almacenamiento falló! -base.error.handler.delete.integrity=¡El registro que intentas eliminar está asociado a otro registro! -base.error.handler.delete.abort=¡La eliminación de ''{0}'' con ID {1} ha sido abortada! -base.error.handler.update.abort=¡La actualización de ''{0}'' con ID {1} ha sido abortada! +base.error.handler.unique=Ya se encontró ''{0}'' con valor(es) {1}, ¡especifica otro(s)! +base.error.handler.savedid=No se pudo obtener el ID del registro a guardar; ¡el almacenamiento falló! +base.error.handler.savedid.rel=No se pudo obtener el ID del registro de muchos a muchos a guardar; ¡el almacenamiento falló! +base.error.handler.delete.integrity=¡El registro que intentas eliminar está asociado a otro registro! +base.error.handler.delete.abort=¡La eliminación de ''{0}'' con ID {1} ha sido abortada! +base.error.handler.update.abort=¡La actualización de ''{0}'' con ID {1} ha sido abortada! -base.info.tasks.crondesc=Descripción -base.error.tasks.crondesc=¡No se pudo determinar la descripción del cron de quartz! +base.info.tasks.crondesc=Descripción +base.error.tasks.crondesc=¡No se pudo determinar la descripción del cron de quartz! -base.info.logout.msg=Ahora has cerrado sesión. -base.info.welcome.msg=¡Bienvenido {0}! +base.info.logout.msg=Ahora has cerrado sesión. +base.info.welcome.msg=¡Bienvenido {0}! base.info.updated=Registro actualizado en {0}. base.info.saved=Registro guardado en {0}. @@ -74,13 +74,13 @@ base.info.deleted=Registro eliminado de {0}. base.info.stored0=Archivo guardado. base.info.stored1=Archivo ''{0}'' guardado. -base.info.session.timeout=Tu sesión ha expirado, inicia sesión de nuevo. -base.info.session.inv=¡Esta llamada ha sido invalidada! Haz una nueva selección. -base.info.session.inv.refresh=¡Esta llamada ha sido invalidada, la página ha sido actualizada! +base.info.session.timeout=Tu sesión ha expirado, inicia sesión de nuevo. +base.info.session.inv=¡Esta llamada ha sido invalidada! Haz una nueva selección. +base.info.session.inv.refresh=¡Esta llamada ha sido invalidada, la página ha sido actualizada! -base.operation.delete.ask=¿Estás seguro de que quieres eliminar ''{0}''? +base.operation.delete.ask=¿Estás seguro de que quieres eliminar ''{0}''? -base.name.page=Página +base.name.page=Página base.name.of=de base.name.showing=mostrando base.name.recordsoutof=registro(s) de @@ -88,8 +88,8 @@ base.name.total=total base.name.refresh=Actualizar -base.name.login=Iniciar sesión -base.name.logout=Cerrar sesión +base.name.login=Iniciar sesión +base.name.logout=Cerrar sesión base.name.user=Usuario base.name.users=Usuarios @@ -98,19 +98,19 @@ base.name.edit=Editar base.name.add=Agregar base.name.delete=Eliminar -base.mail.reset.title=autumo beetRoot - Restablecer contraseña -base.mail.reset.subtitle=Restablecer contraseña -base.mail.reset.msg=Aquí tienes tu enlace para restablecer tu contraseña. +base.mail.reset.title=autumo beetRoot - Restablecer contraseña +base.mail.reset.subtitle=Restablecer contraseña +base.mail.reset.msg=Aquí tienes tu enlace para restablecer tu contraseña. -base.mail.code.title=autumo beetRoot - Código de inicio de sesión -base.mail.code.subtitle=Código de inicio de sesión -base.mail.code.msg=Ten en cuenta que el código es válido solo por un máximo de 5 minutos y sigue los ciclos de renovación fijos del Google Authenticator, es decir, el código puede estar a punto de expirar y tendrás que iniciar sesión nuevamente para obtener un nuevo código si no funciona. -base.sms.code.info=autumo beetRoot - Código de inicio de sesión -base.sms.code.note=válido por 5 minutos +base.mail.code.title=autumo beetRoot - Código de inicio de sesión +base.mail.code.subtitle=Código de inicio de sesión +base.mail.code.msg=Ten en cuenta que el código es válido solo por un máximo de 5 minutos y sigue los ciclos de renovación fijos del Google Authenticator, es decir, el código puede estar a punto de expirar y tendrás que iniciar sesión nuevamente para obtener un nuevo código si no funciona. +base.sms.code.info=autumo beetRoot - Código de inicio de sesión +base.sms.code.note=válido por 5 minutos -base.2fa.title.text=Código QR para la aplicación Google Authenticator +base.2fa.title.text=Código QR para la aplicación Google Authenticator -base.switch.yes=Sí +base.switch.yes=Sí base.switch.no=No role.Administrator=Administrador @@ -119,16 +119,16 @@ role.Controller=Controlador system.log.nobackend=No hay registro de servidor back-end disponible. -pw.info=La contraseña debe incluir: -pw.hide=Ocultar contraseña -pw.show=Mostrar contraseña +pw.info=La contraseña debe incluir: +pw.hide=Ocultar contraseña +pw.show=Mostrar contraseña pw.chars=Caracteres -pw.capital=Al menos una letra mayúscula -pw.number=Al menos un número -pw.special=Al menos un carácter especial +pw.capital=Al menos una letra mayúscula +pw.number=Al menos un número +pw.special=Al menos un carácter especial pw.letter=Sin espacios # -# Traducciones de la aplicación de usuario +# Traducciones de la aplicación de usuario # diff --git a/web/lang/app/lang_it.properties b/web/lang/app/lang_it.properties index a4571f1f..ddc896e7 100644 --- a/web/lang/app/lang_it.properties +++ b/web/lang/app/lang_it.properties @@ -1,7 +1,7 @@ # # Traduzioni dell'app di base # -# Di solito non è necessario modificare le traduzioni qui. Queste +# Di solito non è necessario modificare le traduzioni qui. Queste # traduzioni sono utilizzate da beetRoot, ma ovviamente puoi # modificare il testo. # @@ -14,14 +14,14 @@ # base.err.lang.title=Errore di Configurazione della Lingua -base.err.lang.msg=La lingua/e ''{0}'' è/sono stata/e configurata/e, ma le traduzioni mancano! +base.err.lang.msg=La lingua/e ''{0}'' è/sono stata/e configurata/e, ma le traduzioni mancano! base.err.resource.title=Risorsa Non Trovata! base.err.resource.msg=Risorsa web ''{0}'' non trovata sul server! base.err.resource.mime.title=Tipo MIME per Risorsa Non Implementato! -base.err.resource.mime.msg=Il tipo MIME non è implementato per la risorsa web richiesta ''{0}''! +base.err.resource.mime.msg=Il tipo MIME non è implementato per la risorsa web richiesta ''{0}''! base.err.srv.404.title=La pagina richiesta non esiste. (Errore HTTP 404) -base.err.srv.501.title=Non c'è implementazione per questa richiesta. (Errore HTTP 501) +base.err.srv.501.title=Non c'è implementazione per questa richiesta. (Errore HTTP 501) base.err.srv.io.title=Errore Interno del Server base.err.srv.io.msg=Eccezione I/O:
{0} base.err.srv.re.title=Errore Interno del Server @@ -35,7 +35,7 @@ base.err.srv.mail.msg=Impossibile inviare la mail:
{0} base.err.srv.sms.title=Errore Interno del Server base.err.srv.sms.msg=Impossibile inviare SMS:
{0} -base.err.csrf.inv.title=Il token CSRF è non valido! +base.err.csrf.inv.title=Il token CSRF è non valido! base.err.csrf.inv.msg=Qualcuno deve aver imbrogliato o hai premuto "INDIETRO" nel browser e quindi hai usato un vecchio/modificato modulo per modificare i dati! Torna indietro e ricarica la pagina o usa il menu! base.err.csrf.gen.title=Impossibile generare il token CSRF! base.err.csrf.gen.msg=Eccezione:
{0} @@ -55,12 +55,12 @@ base.err.login.msg=Login non valido, riprova! base.error.noaccess.msg=Spiacenti, non hai accesso qui. -base.error.handler.unique=Trovato già ''{0}'' con valore/i {1}, specifica altri! +base.error.handler.unique=Trovato già ''{0}'' con valore/i {1}, specifica altri! base.error.handler.savedid=Impossibile ottenere l'ID dal record da salvare; salvataggio fallito! base.error.handler.savedid.rel=Impossibile ottenere l'ID dal record molti-a-molti da salvare; salvataggio fallito! -base.error.handler.delete.integrity=Il record che stai cercando di eliminare è associato a un altro record! -base.error.handler.delete.abort=Eliminazione di ''{0}'' con ID {1} è stata annullata! -base.error.handler.update.abort=Aggiornamento di ''{0}'' con ID {1} è stato annullato! +base.error.handler.delete.integrity=Il record che stai cercando di eliminare è associato a un altro record! +base.error.handler.delete.abort=Eliminazione di ''{0}'' con ID {1} è stata annullata! +base.error.handler.update.abort=Aggiornamento di ''{0}'' con ID {1} è stato annullato! base.info.tasks.crondesc=Descrizione base.error.tasks.crondesc=Impossibile determinare la descrizione cron di quartz! @@ -74,9 +74,9 @@ base.info.deleted=Record eliminato da {0}. base.info.stored0=File salvato. base.info.stored1=File ''{0}'' salvato. -base.info.session.timeout=La tua sessione è scaduta, accedi di nuovo. -base.info.session.inv=Questa chiamata è stata invalidata! Fai una nuova selezione. -base.info.session.inv.refresh=Questa chiamata è stata invalidata, la pagina è stata aggiornata! +base.info.session.timeout=La tua sessione è scaduta, accedi di nuovo. +base.info.session.inv=Questa chiamata è stata invalidata! Fai una nuova selezione. +base.info.session.inv.refresh=Questa chiamata è stata invalidata, la pagina è stata aggiornata! base.operation.delete.ask=Sei sicuro di voler eliminare ''{0}''? @@ -104,13 +104,13 @@ base.mail.reset.msg=Ecco il tuo link per reimpostare la tua password. base.mail.code.title=autumo beetRoot - Codice di Accesso base.mail.code.subtitle=Codice di Accesso -base.mail.code.msg=Nota che il codice è valido solo per un massimo di 5 minuti e segue i cicli di rinnovo fissi del Google Authenticator, cioè il codice potrebbe essere in procinto di scadere e dovrai accedere di nuovo per ottenere un nuovo codice se non funziona. +base.mail.code.msg=Nota che il codice è valido solo per un massimo di 5 minuti e segue i cicli di rinnovo fissi del Google Authenticator, cioè il codice potrebbe essere in procinto di scadere e dovrai accedere di nuovo per ottenere un nuovo codice se non funziona. base.sms.code.info=autumo beetRoot - Codice di Accesso base.sms.code.note=valido per 5 minuti base.2fa.title.text=Codice QR per l'App Google Authenticator -base.switch.yes=Sì +base.switch.yes=Sì base.switch.no=No role.Administrator=Amministratore diff --git a/web/lang/pw/lang_es.properties b/web/lang/pw/lang_es.properties index 9e57e8ef..bef0475a 100644 --- a/web/lang/pw/lang_es.properties +++ b/web/lang/pw/lang_es.properties @@ -1,29 +1,29 @@ -HISTORY_VIOLATION=La contraseña coincide con una de las %1$s contraseñas anteriores. -ILLEGAL_WORD=La contraseña contiene la palabra del diccionario '%1$s'. -ILLEGAL_WORD_REVERSED=La contraseña contiene la palabra del diccionario '%1$s' al revés. -ILLEGAL_DIGEST_WORD=La contraseña contiene una palabra del diccionario. -ILLEGAL_DIGEST_WORD_REVERSED=La contraseña contiene una palabra del diccionario al revés. -ILLEGAL_MATCH=La contraseña coincide con el patrón ilegal '%1$s'. -ALLOWED_MATCH=La contraseña debe coincidir con el patrón '%1$s'. -ILLEGAL_CHAR=La contraseña %2$s el carácter ilegal '%1$s'. -ALLOWED_CHAR=La contraseña %2$s el carácter ilegal '%1$s'. -ILLEGAL_QWERTY_SEQUENCE=La contraseña contiene la secuencia QWERTY ilegal '%1$s'. -ILLEGAL_ALPHABETICAL_SEQUENCE=La contraseña contiene la secuencia alfabética ilegal '%1$s'. -ILLEGAL_NUMERICAL_SEQUENCE=La contraseña contiene la secuencia numérica ilegal '%1$s'. -ILLEGAL_USERNAME=La contraseña %2$s el id de usuario '%1$s'. -ILLEGAL_USERNAME_REVERSED=La contraseña %2$s el id de usuario '%1$s' al revés. -ILLEGAL_WHITESPACE=La contraseña %2$s un carácter de espacio en blanco. -ILLEGAL_NUMBER_RANGE=La contraseña %2$s el número '%1$s'. -ILLEGAL_REPEATED_CHARS=La contraseña contiene %3$s secuencias de %1$s o más caracteres repetidos, pero solo se permiten %2$s: %4$s. -INSUFFICIENT_UPPERCASE=La contraseña debe contener %1$s o más caracteres en mayúsculas. -INSUFFICIENT_LOWERCASE=La contraseña debe contener %1$s o más caracteres en minúsculas. -INSUFFICIENT_ALPHABETICAL=La contraseña debe contener %1$s o más caracteres alfabéticos. -INSUFFICIENT_DIGIT=La contraseña debe contener %1$s o más caracteres numéricos. -INSUFFICIENT_SPECIAL=La contraseña debe contener %1$s o más caracteres especiales. -INSUFFICIENT_CHARACTERISTICS=La contraseña coincide con %1$s de las %3$s reglas de carácter, pero se requieren %2$s. -INSUFFICIENT_COMPLEXITY=La contraseña cumple con %2$s reglas de complejidad, pero se requieren %3$s. -INSUFFICIENT_COMPLEXITY_RULES=No se han configurado reglas para una contraseña de longitud %1$s. -SOURCE_VIOLATION=La contraseña no puede ser la misma que su contraseña de %1$s. -TOO_LONG=La contraseña no debe tener más de %2$s caracteres de longitud. -TOO_SHORT=La contraseña debe tener %1$s o más caracteres de longitud. -TOO_MANY_OCCURRENCES=La contraseña contiene %2$s ocurrencias del carácter '%1$s', pero se permiten como máximo %3$s. +HISTORY_VIOLATION=La contraseña coincide con una de las %1$s contraseñas anteriores. +ILLEGAL_WORD=La contraseña contiene la palabra del diccionario '%1$s'. +ILLEGAL_WORD_REVERSED=La contraseña contiene la palabra del diccionario '%1$s' al revés. +ILLEGAL_DIGEST_WORD=La contraseña contiene una palabra del diccionario. +ILLEGAL_DIGEST_WORD_REVERSED=La contraseña contiene una palabra del diccionario al revés. +ILLEGAL_MATCH=La contraseña coincide con el patrón ilegal '%1$s'. +ALLOWED_MATCH=La contraseña debe coincidir con el patrón '%1$s'. +ILLEGAL_CHAR=La contraseña %2$s el carácter ilegal '%1$s'. +ALLOWED_CHAR=La contraseña %2$s el carácter ilegal '%1$s'. +ILLEGAL_QWERTY_SEQUENCE=La contraseña contiene la secuencia QWERTY ilegal '%1$s'. +ILLEGAL_ALPHABETICAL_SEQUENCE=La contraseña contiene la secuencia alfabética ilegal '%1$s'. +ILLEGAL_NUMERICAL_SEQUENCE=La contraseña contiene la secuencia numérica ilegal '%1$s'. +ILLEGAL_USERNAME=La contraseña %2$s el id de usuario '%1$s'. +ILLEGAL_USERNAME_REVERSED=La contraseña %2$s el id de usuario '%1$s' al revés. +ILLEGAL_WHITESPACE=La contraseña %2$s un carácter de espacio en blanco. +ILLEGAL_NUMBER_RANGE=La contraseña %2$s el número '%1$s'. +ILLEGAL_REPEATED_CHARS=La contraseña contiene %3$s secuencias de %1$s o más caracteres repetidos, pero solo se permiten %2$s: %4$s. +INSUFFICIENT_UPPERCASE=La contraseña debe contener %1$s o más caracteres en mayúsculas. +INSUFFICIENT_LOWERCASE=La contraseña debe contener %1$s o más caracteres en minúsculas. +INSUFFICIENT_ALPHABETICAL=La contraseña debe contener %1$s o más caracteres alfabéticos. +INSUFFICIENT_DIGIT=La contraseña debe contener %1$s o más caracteres numéricos. +INSUFFICIENT_SPECIAL=La contraseña debe contener %1$s o más caracteres especiales. +INSUFFICIENT_CHARACTERISTICS=La contraseña coincide con %1$s de las %3$s reglas de carácter, pero se requieren %2$s. +INSUFFICIENT_COMPLEXITY=La contraseña cumple con %2$s reglas de complejidad, pero se requieren %3$s. +INSUFFICIENT_COMPLEXITY_RULES=No se han configurado reglas para una contraseña de longitud %1$s. +SOURCE_VIOLATION=La contraseña no puede ser la misma que su contraseña de %1$s. +TOO_LONG=La contraseña no debe tener más de %2$s caracteres de longitud. +TOO_SHORT=La contraseña debe tener %1$s o más caracteres de longitud. +TOO_MANY_OCCURRENCES=La contraseña contiene %2$s ocurrencias del carácter '%1$s', pero se permiten como máximo %3$s. diff --git a/web/lang/pw/lang_it.properties b/web/lang/pw/lang_it.properties index ea3139b4..564f7678 100644 --- a/web/lang/pw/lang_it.properties +++ b/web/lang/pw/lang_it.properties @@ -14,16 +14,16 @@ ILLEGAL_USERNAME=La password %2$s l'ID utente '%1$s'. ILLEGAL_USERNAME_REVERSED=La password %2$s l'ID utente '%1$s' al contrario. ILLEGAL_WHITESPACE=La password %2$s un carattere di spazio. ILLEGAL_NUMBER_RANGE=La password %2$s il numero '%1$s'. -ILLEGAL_REPEATED_CHARS=La password contiene %3$s sequenze di %1$s o più caratteri ripetuti, ma solo %2$s sono consentiti: %4$s. -INSUFFICIENT_UPPERCASE=La password deve contenere %1$s o più caratteri maiuscoli. -INSUFFICIENT_LOWERCASE=La password deve contenere %1$s o più caratteri minuscoli. -INSUFFICIENT_ALPHABETICAL=La password deve contenere %1$s o più caratteri alfabetici. -INSUFFICIENT_DIGIT=La password deve contenere %1$s o più caratteri numerici. -INSUFFICIENT_SPECIAL=La password deve contenere %1$s o più caratteri speciali. +ILLEGAL_REPEATED_CHARS=La password contiene %3$s sequenze di %1$s o più caratteri ripetuti, ma solo %2$s sono consentiti: %4$s. +INSUFFICIENT_UPPERCASE=La password deve contenere %1$s o più caratteri maiuscoli. +INSUFFICIENT_LOWERCASE=La password deve contenere %1$s o più caratteri minuscoli. +INSUFFICIENT_ALPHABETICAL=La password deve contenere %1$s o più caratteri alfabetici. +INSUFFICIENT_DIGIT=La password deve contenere %1$s o più caratteri numerici. +INSUFFICIENT_SPECIAL=La password deve contenere %1$s o più caratteri speciali. INSUFFICIENT_CHARACTERISTICS=La password corrisponde a %1$s delle %3$s regole sui caratteri, ma sono richieste %2$s. -INSUFFICIENT_COMPLEXITY=La password soddisfa %2$s regole di complessità, ma sono richieste %3$s. +INSUFFICIENT_COMPLEXITY=La password soddisfa %2$s regole di complessità, ma sono richieste %3$s. INSUFFICIENT_COMPLEXITY_RULES=Non sono state configurate regole per una password di lunghezza %1$s. -SOURCE_VIOLATION=La password non può essere la stessa della tua password di %1$s. +SOURCE_VIOLATION=La password non può essere la stessa della tua password di %1$s. TOO_LONG=La password non deve superare i %2$s caratteri di lunghezza. TOO_SHORT=La password deve essere lunga almeno %1$s caratteri. TOO_MANY_OCCURRENCES=La password contiene %2$s occorrenze del carattere '%1$s', ma al massimo %3$s sono consentite. diff --git a/web/lang/pw/lang_pt.properties b/web/lang/pw/lang_pt.properties index 8d6dd1b0..c0232acd 100644 --- a/web/lang/pw/lang_pt.properties +++ b/web/lang/pw/lang_pt.properties @@ -1,29 +1,29 @@ HISTORY_VIOLATION=A senha corresponde a uma das %1$s senhas anteriores. -ILLEGAL_WORD=A senha contém a palavra do dicionário '%1$s'. -ILLEGAL_WORD_REVERSED=A senha contém a palavra do dicionário '%1$s' ao contrário. -ILLEGAL_DIGEST_WORD=A senha contém uma palavra do dicionário. -ILLEGAL_DIGEST_WORD_REVERSED=A senha contém uma palavra do dicionário ao contrário. -ILLEGAL_MATCH=A senha corresponde ao padrão ilegal '%1$s'. -ALLOWED_MATCH=A senha deve corresponder ao padrão '%1$s'. +ILLEGAL_WORD=A senha contém a palavra do dicionário '%1$s'. +ILLEGAL_WORD_REVERSED=A senha contém a palavra do dicionário '%1$s' ao contrário. +ILLEGAL_DIGEST_WORD=A senha contém uma palavra do dicionário. +ILLEGAL_DIGEST_WORD_REVERSED=A senha contém uma palavra do dicionário ao contrário. +ILLEGAL_MATCH=A senha corresponde ao padrão ilegal '%1$s'. +ALLOWED_MATCH=A senha deve corresponder ao padrão '%1$s'. ILLEGAL_CHAR=A senha %2$s o caractere ilegal '%1$s'. ALLOWED_CHAR=A senha %2$s o caractere ilegal '%1$s'. -ILLEGAL_QWERTY_SEQUENCE=A senha contém a sequência QWERTY ilegal '%1$s'. -ILLEGAL_ALPHABETICAL_SEQUENCE=A senha contém a sequência alfabética ilegal '%1$s'. -ILLEGAL_NUMERICAL_SEQUENCE=A senha contém a sequência numérica ilegal '%1$s'. -ILLEGAL_USERNAME=A senha %2$s o ID do usuário '%1$s'. -ILLEGAL_USERNAME_REVERSED=A senha %2$s o ID do usuário '%1$s' ao contrário. -ILLEGAL_WHITESPACE=A senha %2$s um caractere de espaço em branco. -ILLEGAL_NUMBER_RANGE=A senha %2$s o número '%1$s'. -ILLEGAL_REPEATED_CHARS=A senha contém %3$s sequências de %1$s ou mais caracteres repetidos, mas apenas %2$s são permitidos: %4$s. -INSUFFICIENT_UPPERCASE=A senha deve conter %1$s ou mais caracteres maiúsculos. -INSUFFICIENT_LOWERCASE=A senha deve conter %1$s ou mais caracteres minúsculos. -INSUFFICIENT_ALPHABETICAL=A senha deve conter %1$s ou mais caracteres alfabéticos. -INSUFFICIENT_DIGIT=A senha deve conter %1$s ou mais caracteres numéricos. +ILLEGAL_QWERTY_SEQUENCE=A senha contém a sequência QWERTY ilegal '%1$s'. +ILLEGAL_ALPHABETICAL_SEQUENCE=A senha contém a sequência alfabética ilegal '%1$s'. +ILLEGAL_NUMERICAL_SEQUENCE=A senha contém a sequência numérica ilegal '%1$s'. +ILLEGAL_USERNAME=A senha %2$s o ID do usuário '%1$s'. +ILLEGAL_USERNAME_REVERSED=A senha %2$s o ID do usuário '%1$s' ao contrário. +ILLEGAL_WHITESPACE=A senha %2$s um caractere de espaço em branco. +ILLEGAL_NUMBER_RANGE=A senha %2$s o número '%1$s'. +ILLEGAL_REPEATED_CHARS=A senha contém %3$s sequências de %1$s ou mais caracteres repetidos, mas apenas %2$s são permitidos: %4$s. +INSUFFICIENT_UPPERCASE=A senha deve conter %1$s ou mais caracteres maiúsculos. +INSUFFICIENT_LOWERCASE=A senha deve conter %1$s ou mais caracteres minúsculos. +INSUFFICIENT_ALPHABETICAL=A senha deve conter %1$s ou mais caracteres alfabéticos. +INSUFFICIENT_DIGIT=A senha deve conter %1$s ou mais caracteres numéricos. INSUFFICIENT_SPECIAL=A senha deve conter %1$s ou mais caracteres especiais. -INSUFFICIENT_CHARACTERISTICS=A senha corresponde a %1$s das %3$s regras de caracteres, mas %2$s são necessárias. -INSUFFICIENT_COMPLEXITY=A senha atende a %2$s regras de complexidade, mas %3$s são necessárias. +INSUFFICIENT_CHARACTERISTICS=A senha corresponde a %1$s das %3$s regras de caracteres, mas %2$s são necessárias. +INSUFFICIENT_COMPLEXITY=A senha atende a %2$s regras de complexidade, mas %3$s são necessárias. INSUFFICIENT_COMPLEXITY_RULES=Nenhuma regra foi configurada para uma senha de comprimento %1$s. -SOURCE_VIOLATION=A senha não pode ser a mesma que a sua senha %1$s. -TOO_LONG=A senha deve ter no máximo %2$s caracteres de comprimento. +SOURCE_VIOLATION=A senha não pode ser a mesma que a sua senha %1$s. +TOO_LONG=A senha deve ter no máximo %2$s caracteres de comprimento. TOO_SHORT=A senha deve ter %1$s ou mais caracteres de comprimento. -TOO_MANY_OCCURRENCES=A senha contém %2$s ocorrências do caractere '%1$s', mas no máximo %3$s são permitidas. +TOO_MANY_OCCURRENCES=A senha contém %2$s ocorrências do caractere '%1$s', mas no máximo %3$s são permitidas. diff --git a/web/lang/tmpl/lang_it.properties b/web/lang/tmpl/lang_it.properties index 11e5a8d2..9e0817e0 100644 --- a/web/lang/tmpl/lang_it.properties +++ b/web/lang/tmpl/lang_it.properties @@ -1,34 +1,34 @@ # -# Prima di poter utilizzare questo file di lingua, � necessario attivare -# 'web_translations' nella configurazione (ad es. 'beetroot.cfg'). +# Prima di poter utilizzare questo file di lingua, devi attivare +# 'web_translations' nella tua configurazione (ad es. 'beetroot.cfg'). # # Le traduzioni web possono sempre essere utilizzate, ma possono essere -# utilizzate esplicitamente per eliminare i file di template web tradotti nelle -# sottodirectory di lingua 'web/html/**'. +# utilizzate esplicitamente per eliminare i file dei template web tradotti +# nelle sottodirectory di lingua 'web/html/**'. # # Tuttavia, i concetti possono essere combinati! # -# L'attivazione delle traduzioni web richiede un po' pi� di performance dal -# motore dei template. Per le massime prestazioni, utilizza solo i template web -# tradotti! +# Attivare le traduzioni web richiede un po' più di prestazioni dal +# motore dei template. Per le massime prestazioni, usa solo i template +# web tradotti! # -# NOTA: Le etichette di traduzione iniziano con '$l.', quindi un'etichetta di traduzione -# valida sarebbe '{$l.translation1}' o -# '{$l.message1,{$var1}{$var1}}'. -# {$var1} e {$var2} verranno pre-analizzati prima -# che avvenga la traduzione linguistica e i valori pre-analizzati -# verranno mostrati nei luoghi definiti -# nel messaggio. Ovviamente, queste variabili devono +# NOTA: I tag di traduzione iniziano con '$l.', quindi un tag di traduzione valido +# sarebbe '{$l.translation1}' o +# '{$l.message1,{$var1}{$var2}}'. +# {$var1} e {$var2} verranno pre-parsati prima +# che avvenga la traduzione della lingua e i valori pre-parsati +# verranno mostrati nelle posizioni definite +# nel messaggio. Naturalmente, queste variabili devono # essere impostate in un gestore! # # Aggiungi un file di traduzione per ogni lingua, ad es.: # - tmpl/lang_en.properties # - tmpl/lang_de.properties # -# Devi scappare gli apostrofi con un secondo apostrofo; +# Devi sfuggire gli apostrofi con un secondo apostrofo; # scrivi "You''ll be happy a have everything!". # -message=Ciao {0}! � una bella giornata, sono {1} gradi Celsius! +message=Ciao {0}! È una bella giornata, sono {1} gradi Celsius! # Colonne: properties/columns.cfg properties.list.name=Nome