mirror of https://github.com/micromata/borgbackup-butler.git

Kai Reinhard
09.20.2018 4ba33abd9104d715c6e3f53c1d2b23398cc196d6
web...
6 files added
3 files modified
442 ■■■■■ changed files
borgbutler-core/src/main/java/de/micromata/borgbutler/CoreI18n.java 84 ●●●●● patch | view | raw | blame | history
borgbutler-core/src/main/java/de/micromata/borgbutler/I18n.java 109 ●●●●● patch | view | raw | blame | history
borgbutler-core/src/main/resources/BorgButlerCoreMessagesBundle.properties 1 ●●●● patch | view | raw | blame | history
borgbutler-server/src/main/java/de/micromata/borgbutler/server/I18nClientMessages.java 55 ●●●●● patch | view | raw | blame | history
borgbutler-server/src/main/java/de/micromata/borgbutler/server/ServerConfiguration.java 2 ●●● patch | view | raw | blame | history
borgbutler-server/src/main/java/de/micromata/borgbutler/server/rest/I18nRest.java 7 ●●●● patch | view | raw | blame | history
borgbutler-server/src/main/resources/BorgButlerClientMessagesBundle.properties 88 ●●●●● patch | view | raw | blame | history
borgbutler-server/src/main/resources/BorgButlerClientMessagesBundle_de.properties 88 ●●●●● patch | view | raw | blame | history
borgbutler-webapp/src/components/views/Start.jsx 8 ●●●● patch | view | raw | blame | history
borgbutler-core/src/main/java/de/micromata/borgbutler/CoreI18n.java
New file
@@ -0,0 +1,84 @@
package de.micromata.borgbutler;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.*;
/**
 * For internationalization.
 */
public class CoreI18n extends I18n {
    private static Logger log = LoggerFactory.getLogger(CoreI18n.class);
    private static Locale[] DEFAULT_LOCALES = {Locale.ROOT, Locale.GERMAN};
    private static CoreI18n defaultInstance = new CoreI18n();
    public static final String BUNDLE_NAME = "BorgButlerCoreMessagesBundle";
    private static List<I18n> allResourceBundles = new ArrayList<>();
    public static CoreI18n getDefault() {
        return defaultInstance;
    }
    /**
     * Use this if only one locale is used (in a none multi user system).
     * At default the default message bundle "MessagesBundle" of the class path with the system's default locale is used.
     *
     * @param instance
     */
    public static void setDefault(CoreI18n instance) {
        defaultInstance = instance;
    }
    /**
     * Use this if only one locale is used (in a none multi user system).
     * Uses bundle "MessagesBundle" of the class path with the given locale.
     *
     * @param locale
     * @return new default instance for chaining.
     */
    public static CoreI18n setDefault(Locale locale) {
        defaultInstance = new CoreI18n(locale);
        return defaultInstance;
    }
    public static Set<String> getAllTranslations(String key) {
        Set<String> set = new HashSet<>();
        for (I18n i18n : getAllResourceBundles()) {
            String translation = i18n.getMessage(key);
            if (StringUtils.isNotBlank(translation))
                set.add(translation);
        }
        return set;
    }
    private static List<I18n> getAllResourceBundles() {
        if (!allResourceBundles.isEmpty()) {
            return allResourceBundles;
        }
        synchronized (allResourceBundles) {
            for (Locale locale : DEFAULT_LOCALES) {
                allResourceBundles.add(new CoreI18n(locale));
            }
        }
        return allResourceBundles;
    }
    /**
     * Uses the default message bundle "MessagesBundle" of class path with systems default locale.
     */
    public CoreI18n() {
        super(BUNDLE_NAME);
    }
    public CoreI18n(Locale locale) {
        super(BUNDLE_NAME, locale);
    }
    @Override
    protected I18n create(Locale locale) {
        return new CoreI18n(locale);
    }
}
borgbutler-core/src/main/java/de/micromata/borgbutler/I18n.java
New file
@@ -0,0 +1,109 @@
package de.micromata.borgbutler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.text.MessageFormat;
import java.util.*;
/**
 * For internationalization.
 */
public class I18n {
    private Logger log = LoggerFactory.getLogger(I18n.class);
    private ResourceBundle resourceBundle;
    private Map<Locale, I18n> i18nMap;
    public I18n get(Locale locale) {
        if (i18nMap == null) {
            i18nMap = new HashMap<>();
        }
        I18n i18n = i18nMap.get(locale);
        if (i18n == null) {
            i18n = create(locale);
            i18nMap.put(locale, i18n);
        }
        return i18n;
    }
    protected I18n create(Locale locale) {
        return new I18n(this.resourceBundle.getBaseBundleName(), locale);
    }
    /**
     * Uses the default message bundle "MessagesBundle" of class path with systems default locale.
     */
    public I18n(String bundleName) {
        this.resourceBundle = I18n.getBundle(bundleName);
    }
    public I18n(String bundleName, Locale locale) {
        this.resourceBundle = I18n.getBundle(bundleName, locale);
    }
    /**
     * Throws an error if messageId not found.
     *
     * @param messageId
     * @return localized message.
     */
    public String getMessage(String messageId) {
        return resourceBundle.getString(messageId);
    }
    /**
     * @param messageId
     * @return true, if the messageId is found in the bundle, otherwise false.
     */
    public boolean containsMessage(String messageId) {
        return resourceBundle.containsKey(messageId);
    }
    /**
     * @param messageId
     * @param params    Message parameter to replace in message.
     * @return localized message.
     * @see MessageFormat#format(String, Object...)
     */
    public String formatMessage(String messageId, Object... params) {
        if (params == null || params.length == 0) {
            return getMessage(messageId);
        }
        try {
            return MessageFormat.format(resourceBundle.getString(messageId), params);
        } catch (MissingResourceException ex) {
            log.error("Missing resource '" + messageId + "': " + ex.getMessage(), ex);
            return messageId;
        }
    }
    public ResourceBundle getResourceBundle() {
        return resourceBundle;
    }
    /**
     *
     * @param bundleName
     * @param locale
     * @return The root bundle if the given locale's language is "en" or language not found, otherwise the desired bundle for the given locale.
     */
    public static ResourceBundle getBundle(String bundleName, Locale locale) {
        if ("en".equals(locale.getLanguage())) {
            return ResourceBundle.getBundle(bundleName, Locale.ROOT);
        }
        return ResourceBundle.getBundle(bundleName, locale);
        //return ResourceBundle.getBundle(bundleName, locale,
        //        ResourceBundle.Control.getNoFallbackControl(ResourceBundle.Control.FORMAT_PROPERTIES));
    }
    /**
     * Simply calls {@link ResourceBundle#getBundle(String)}.
     * @param bundleName
     * @return The bundle for {@link Locale#getDefault()} or root bundle if not found..
     */
    public static ResourceBundle getBundle(String bundleName) {
        return ResourceBundle.getBundle(bundleName);
        //return ResourceBundle.getBundle(bundleName, locale,
        //        ResourceBundle.Control.getNoFallbackControl(ResourceBundle.Control.FORMAT_PROPERTIES));
    }
}
borgbutler-core/src/main/resources/BorgButlerCoreMessagesBundle.properties
New file
@@ -0,0 +1 @@
# Prepared for i18n.
borgbutler-server/src/main/java/de/micromata/borgbutler/server/I18nClientMessages.java
New file
@@ -0,0 +1,55 @@
package de.micromata.borgbutler.server;
import de.micromata.borgbutler.CoreI18n;
import de.micromata.borgbutler.I18n;
import java.text.MessageFormat;
import java.util.*;
/**
 * For internationalization.
 */
public class I18nClientMessages {
    private static final String BUNDLE_NAME = "BorgButlerClientMessagesBundle";
    private static String[] params = {"{0}", "{1}", "{2}", "{3}", "{4}", "{5}", "{6}", "{7}", "{8}", "{9}"};
    private static final I18nClientMessages instance = new I18nClientMessages();
    public static I18nClientMessages getInstance() {
        return instance;
    }
    private I18nClientMessages() {
    }
    /**
     *
     * @param locale
     * @param keysOnly If true, only the keys will be returned. Default is false.
     * @return
     */
    public Map<String, String> getAllMessages(Locale locale, boolean keysOnly) {
        Map<String, String> map = new HashMap<>();
        //addAllMessages(map, new AppI18n(locale).getResourceBundle(), keysOnly);
        addAllMessages(map, new CoreI18n(locale).getResourceBundle(), keysOnly);
        ResourceBundle bundle = I18n.getBundle(BUNDLE_NAME, locale);
        addAllMessages(map, bundle, keysOnly);
        return new TreeMap<>(map); // Sorted by keys.
    }
    private Map<String, String> addAllMessages(Map<String, String> map, ResourceBundle bundle, boolean keysOnly) {
        for (String key : bundle.keySet()) {
            String value = bundle.getString(key);
            map.put(key, keysOnly ? "" : prepareForReactClient(value));
        }
        return map;
    }
    /**
     * @param str
     * @return
     * @see MessageFormat#format(Object)
     */
    static String prepareForReactClient(String str) {
        return MessageFormat.format(str, (Object[])params);
    }
}
borgbutler-server/src/main/java/de/micromata/borgbutler/server/ServerConfiguration.java
@@ -8,7 +8,7 @@
public class ServerConfiguration {
    private static Logger log = LoggerFactory.getLogger(ServerConfiguration.class);
    private final static String[] SUPPORTED_LANGUAGES = {"en"};
    private final static String[] SUPPORTED_LANGUAGES = {"en", "de"};
    private static String applicationHome;
    private int port;
borgbutler-server/src/main/java/de/micromata/borgbutler/server/rest/I18nRest.java
@@ -1,5 +1,7 @@
package de.micromata.borgbutler.server.rest;
import de.micromata.borgbutler.json.JsonUtils;
import de.micromata.borgbutler.server.I18nClientMessages;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -12,6 +14,7 @@
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import java.util.Locale;
import java.util.Map;
@Path("/i18n")
public class I18nRest {
@@ -36,6 +39,8 @@
        } else {
            localeObject = RestUtils.getUserLocale(requestContext);
        }
        return ""; // i18n not yet supported.
        Map<String, String> translations = I18nClientMessages.getInstance().getAllMessages(localeObject, keysOnly);
        String json = JsonUtils.toJson(translations, prettyPrinter);
        return json;
    }
}
borgbutler-server/src/main/resources/BorgButlerClientMessagesBundle.properties
New file
@@ -0,0 +1,88 @@
common.browse=Browse
common.browse.hint=Browse local filesystem
common.cancel=Cancel
common.comment=Comment
common.common=Common
common.description=Description
common.droparea.title=Select a file or drop one here.
common.droparea.hint=Drop or open your files here, such as serial definition files (Excel).
common.filename=File name
common.fileSize=File size
common.information=Information
common.lastModified=Last modified
common.limitsResultSize=Limits result size.
common.loading=Loading...
common.new=New
common.none=none
common.required=Required
common.path=Path
common.run=Run
common.save=Save
common.unique=Unique
common.update=Update
common.alert.cantLoadData=Can't load data
common.alert.genericRestAPIFailure=Something went wrong with the server call. Is the server available?
common.alert.tryAgain=Try again
configuration=Configuration
configuration.account=Account
configuration.addDirectory=Add directory
configuration.addDirectory.hint=Add new template directory.
configuration.application.dateFormat=Date format
configuration.application.dateFormat.option.auto=Auto
configuration.application.language=Application language
configuration.application.language.option.default=Default (browser)
configuration.cancel.hint=Discard changes and go to Start page.
configuration.expertSettings=Expert settings
configuration.forExpertsOnly=For experts only
configuration.reloadDictionary.hint=Force reloading all translations for this app.
configuration.removeItem=Remove item
configuration.resetAllSettings=Reset all settings
configuration.resetAllSettings.question=Are you sure you want to reset all settings? All settings will be resetted on server. Template files will not be deleted.
configuration.resetAllSettings.hint=Reset factory settings.
configuration.save.hint=Save changes and go to Start page.
configuration.server=Server
configuration.showTestData=Show test data
configuration.templatesDirectory=Directory
configuration.webDevelopmentMode=Web development
configuration.webDevelopmentMode.hint=Activate this checkbox only for web development of BorgButler (with yarn or npm). The CrossOriginFilter will be set. A restart of BorgButler is required.
language.english=English
language.german=German
logviewer=Log viewer
logviewer.filter=Filter
logviewer.filter.level.hint=Minimum displayed log level.
logviewer.filter.location.hint=Show location of message in source code.
logviewer.filter.location.option.short=short
logviewer.filter.location.option.normal=long
logviewer.filter.stacktraces=Stacktraces
logviewer.filter.stacktraces.showHide.hint=Show/hide stack traces.
logviewer.level=Level
logviewer.location=Location in source code
logviewer.message=Message
logviewer.timestamp=Timestamp
startscreen.welcome.title=Welcome to BorgButler
startscreen.welcome.text=Congratulations. With BorgButler you have started a smart assistant for your work with borg backups.
startscreen.welcome.enjoy=Enjoy your work!
startscreen.welcome.documentation=Go to Documentation
update=Update
update.installerUrl=Installer url
update.newVersion=New version
update.newVersionAvailable=The new version {0} is available.
update.newVersion.simplyClickButton=You can start the update process by simply clicking the update button.
update.noUpdateAvailable=No update available.
update.update.button.hint=Download and execute update.
update.description.line1=The update button works only if your browser is running on the same computer as your BorgBackup server.
update.description.line2=If the installer doesn't start after clicking the update button, please proceed manually by downloading the installer from the given url below.
validation.requiredField=Value is required. Please insert a value.
validation.numberExpected=Value must be a number.
validation.numberMustBeLower=The number can't be higher than {0}.
validation.numberMustBeHigher=The number can't be lower than {0}.
version=Version
version.buildDate=Build date
version.updateAvailable=Update available!
borgbutler-server/src/main/resources/BorgButlerClientMessagesBundle_de.properties
New file
@@ -0,0 +1,88 @@
common.browse=Browse
common.browse.hint=Öffne lokales Dateisystem
common.cancel=Abbrechen
common.comment=Kommentar
common.common=Allgemein
common.description=Beschreibung
common.droparea.title=Datei hierhin ziehen oder auswählen.
common.droparea.hint=Ziehen Sie Ihre Dateien hierhin, wie beispielsweise Seriendefinitionen(Excel).
common.filename=Dateiname
common.fileSize=Dateigröße
common.information=Information
common.lastModified=Letzte Änderung
common.limitsResultSize=Ergebnisliste begrenzen.
common.loading=Lädt gerade...
common.new=Neu
common.none=keine
common.required=Erforderlich
common.path=Pfad
common.run=Ausführen
common.save=Speichern
common.unique=Eindeuting
common.update=Aktualisieren
common.alert.cantLoadData=Fehler beim Laden von Daten
common.alert.genericRestAPIFailure=Ein allgemeiner Fehler ist beim Serveraufruf aufgetreten. Ist der Server erreichbar?
common.alert.tryAgain=Erneut probieren
configuration=Konfiguration
configuration.account=Zugang
configuration.addDirectory=Verzeichnis hinzufügen
configuration.addDirectory.hint=Ein neues Template-Verzeichnis hinzufügen.
configuration.application.dateFormat=Datumsformat
configuration.application.dateFormat.option.auto=Automatisch
configuration.application.language=Anwendungssprache
configuration.application.language.option.default=Standard (Browser)
configuration.cancel.hint=Änderungen verwerfen und zur Startseite.
configuration.expertSettings=Experteneinstellungen
configuration.forExpertsOnly=Nur für Experten
configuration.reloadDictionary.hint=Erzwingt das Neuladen aller Übersetzungstexte dieser Anwendung.
configuration.removeItem=Eintrag entfernen
configuration.resetAllSettings=Alles zurücksetzen
configuration.resetAllSettings.question=Sind Sie sich wirklich sicher, dass Sie alle Einstellungen zurücksetzen wollen? Alle Einstellungen werden auf dem Server zurückgesetzt. Templatedateien werden nicht gelöscht.
configuration.resetAllSettings.hint=Alle Einstellungen zurücksetzen.
configuration.save.hint=Änderungen speichern und zur Startseite.
configuration.server=Server
configuration.showTestData=Testdaten anzeigen
configuration.templatesDirectory=Verzeichnis
configuration.webDevelopmentMode=Webentwicklung
configuration.webDevelopmentMode.hint=Aktivieren Sie diese Funktion nur, wenn Sie die Webentwicklung für BorgButler durchführen (yarn oder npm). Der CrossOriginFilter wird hierüber aktiviert. Ein Neustart von BorgButler ist erforderlich.
language.english=Englisch
language.german=Deutsch
logviewer=Protokolldateien
logviewer.filter=Filter
logviewer.filter.level.hint=Zeige nur Meldungen ab diesem Level.
logviewer.filter.location.hint=Zeige den Ort der Meldung im Quellcode.
logviewer.filter.location.option.short=kurz
logviewer.filter.location.option.normal=lang
logviewer.filter.stacktraces=Stacktraces
logviewer.filter.stacktraces.showHide.hint=Zeige/verstecke Stacktraces.
logviewer.level=Level
logviewer.location=Stelle im Quellcode
logviewer.message=Meldung
logviewer.timestamp=Zeitstempel
startscreen.welcome.title=Willkommen zu BorgButler
startscreen.welcome.text=Herzlichen Glückwunsch. Mit BorgButler haben Sie einen smarten Assistenten für Ihre tägliche Arbeit mit Borg-Backups gestartet.
startscreen.welcome.enjoy=Viel Spaß!
startscreen.welcome.documentation=Gehe zur Dokumentation
update=Aktualisierung
update.installerUrl=Webadresse Installation
update.newVersion=Neue Version
update.newVersionAvailable=Die neue Version {0} ist verfügbar.
update.newVersion.simplyClickButton=Sie können die Aktualisierung auf Knopfdruck automatisch starten.
update.noUpdateAvailable=Keine Aktualisierung verfügbar.
update.update.button.hint=Aktualisierung herunterladen und ausführen.
update.description.line1=Der Aktualisierungsknopf funktioniert nur, wenn Ihr Browser auf dem gleichen Computer läuft wie der BorgButler-Server.
update.description.line2=Wenn das Installationsprogramm nicht auf Knopfdruck startet, fahren Sie bitte mit dem manuellen Download von der unten angegebenen Webadresse fort.
validation.requiredField=Der Wert ist erforderlich. Bitte geben Sie einen Wert ein.
validation.numberExpected=Der Wert muss eine Zahl sein.
validation.numberMustBeLower=Die Zahl muss kleiner als {0} sein.
validation.numberMustBeHigher=Die Zahl muss größer als {0} sein.
version=Version
version.buildDate=Erzeugt am
version.updateAvailable=Aktualisierung verfügbar!
borgbutler-webapp/src/components/views/Start.jsx
@@ -7,11 +7,11 @@
        return (
            <React.Fragment>
                <PageHeader>
                    Welcome to BorgButler
                    <I18n name={'startscreen.welcome.title'}/>
                </PageHeader>
                <div className="welcome-intro">BorgButler is the frontend for BorgBackup.</div>
                <div className="welcome-enjoy">Enjoy your work with BorgButler.</div>
                <div className="welcome-documentation-link"><a className={'btn btn-link btn-outline-primary'} href={'https://github.com/micromata/borgbackup-butler'} target="_blank" rel="noopener noreferrer">Documentation</a></div>
                <div className="welcome-intro"><I18n name={'startscreen.welcome.text'}/></div>
                <div className="welcome-enjoy"><I18n name={'startscreen.welcome.enjoy'}/></div>
                <div className="welcome-documentation-link"><a className={'btn btn-link btn-outline-primary'} href={'https://github.com/micromata/borgbackup-butler'} target="_blank" rel="noopener noreferrer"><I18n name={'startscreen.welcome.documentation'}/></a></div>
            </React.Fragment>
        );
    }