diff --git a/htroot/ConfigBasic.html b/htroot/ConfigBasic.html
index daef4777a..20b7e0832 100644
--- a/htroot/ConfigBasic.html
+++ b/htroot/ConfigBasic.html
@@ -33,14 +33,15 @@
Select a language for the interface:
diff --git a/htroot/ConfigBasic.java b/htroot/ConfigBasic.java
index 378ee2e07..cc382fe23 100644
--- a/htroot/ConfigBasic.java
+++ b/htroot/ConfigBasic.java
@@ -31,11 +31,13 @@
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
+import java.util.List;
import java.util.regex.Pattern;
import net.yacy.cora.protocol.Domains;
import net.yacy.cora.protocol.HeaderFramework;
import net.yacy.cora.protocol.RequestHeader;
+import net.yacy.data.Translator;
import net.yacy.data.WorkTables;
import net.yacy.http.YaCyHttpServer;
import net.yacy.kelondro.workflow.InstantBusyThread;
@@ -63,7 +65,7 @@ public class ConfigBasic {
final Switchboard sb = (Switchboard) env;
final serverObjects prop = new serverObjects();
final File langPath = new File(sb.getAppPath("locale.source", "locales").getAbsolutePath());
- String lang = env.getConfig("locale.language", "default");
+ String lang = env.getConfig("locale.language", "browser");
final int authentication = sb.adminAuthenticated(header);
if (authentication < 2) {
@@ -269,6 +271,7 @@ public class ConfigBasic {
prop.put("defaultPort", env.getLocalPort());
prop.put("withsslenabled", env.getConfigBool("server.https", false) ? 1 : 0);
lang = env.getConfig("locale.language", "default"); // re-assign lang, may have changed
+ prop.put("lang_browser", "0"); // for client browser language dependent
prop.put("lang_de", "0");
prop.put("lang_fr", "0");
prop.put("lang_cn", "0");
@@ -281,6 +284,28 @@ public class ConfigBasic {
} else {
prop.put("lang_" + lang, "1");
}
+ // set label class (green background) for active translation
+ if (lang.equals("browser")) {
+ List l = Translator.activeTranslations();
+ prop.put("active_cn", l.contains("cn") ? "label-success" : "");
+ prop.put("active_de", l.contains("de") ? "label-success" : "");
+ prop.put("active_fr", l.contains("fr") ? "label-success" : "");
+ prop.put("active_hi", l.contains("hi") ? "label-success" : "");
+ prop.put("active_jp", l.contains("jp") ? "label-success" : "");
+ prop.put("active_ru", l.contains("ru") ? "label-success" : "");
+ prop.put("active_uk", l.contains("uk") ? "label-success" : "");
+ prop.put("active_en", "label-success");
+
+ } else {
+ prop.put("active_de", "");
+ prop.put("active_fr", "");
+ prop.put("active_hi", "");
+ prop.put("active_cn", "");
+ prop.put("active_ru", "");
+ prop.put("active_uk", "");
+ prop.put("active_en", "");
+ prop.put("active_jp", "");
+ }
return prop;
}
}
diff --git a/htroot/ConfigLanguage_p.java b/htroot/ConfigLanguage_p.java
index eff442e69..bd08db5c6 100644
--- a/htroot/ConfigLanguage_p.java
+++ b/htroot/ConfigLanguage_p.java
@@ -81,7 +81,7 @@ public class ConfigLanguage_p {
* read from the language directory. This is very important to prevent
* directory traversal attacks!
*/
- if (langFiles.contains(selectedLanguage) || selectedLanguage.startsWith("default")) {
+ if (langFiles.contains(selectedLanguage) || selectedLanguage.startsWith("default") || selectedLanguage.startsWith("browser")) {
new TranslatorXliff().changeLang(env, langPath, selectedLanguage);
}
@@ -142,27 +142,28 @@ public class ConfigLanguage_p {
final Map langNames = Translator.langMap(env);
//virtual entry
- prop.put("langlist_0_file", "default");
- prop.put("langlist_0_name", ((langNames.get("default") == null) ? "default" : langNames.get("default")));
+ prop.put("langlist_0_file", "browser");
+ prop.put("langlist_0_name", ((langNames.get("browser") == null) ? "browser" : langNames.get("browser")));
prop.put("langlist_0_selected", "selected=\"selected\"");
+ prop.put("langlist_1_file", "default");
+ prop.put("langlist_1_name", ((langNames.get("default") == null) ? "default" : langNames.get("default")));
- int count = 0;
- for (final String langFile : langFiles) {
- //+1 because of the virtual entry "default" at top
+ int count = 2; //+2 because of the virtual entry "browser" and "default" at top
+ for (final String langFile : langFiles) {
final String langKey = langFile.substring(0, langFile.length() -4);
final String langName = langNames.get(langKey);
- prop.put("langlist_" + (count + 1) + "_file", langFile);
- prop.put("langlist_" + (count + 1) + "_name", ((langName == null) ? langKey : langName));
+ prop.put("langlist_" + (count) + "_file", langFile);
+ prop.put("langlist_" + (count) + "_name", ((langName == null) ? langKey : langName));
if(env.getConfig("locale.language", "default").equals(langKey)) {
- prop.put("langlist_" + (count + 1) + "_selected", "selected=\"selected\"");
+ prop.put("langlist_" + (count) + "_selected", "selected=\"selected\"");
prop.put("langlist_0_selected", " "); // reset Default
} else {
- prop.put("langlist_" + (count + 1) + "_selected", " ");
+ prop.put("langlist_" + (count) + "_selected", " ");
}
count++;
}
- prop.put("langlist", (count + 1));
+ prop.put("langlist", (count));
//is done by Translationtemplate
//langName = (String) langNames.get(env.getConfig("locale.language", "default"));
diff --git a/source/net/yacy/data/Translator.java b/source/net/yacy/data/Translator.java
index ac14a0f7e..1aa63e57f 100644
--- a/source/net/yacy/data/Translator.java
+++ b/source/net/yacy/data/Translator.java
@@ -40,6 +40,7 @@ import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.nio.charset.StandardCharsets;
+import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
@@ -53,6 +54,7 @@ import net.yacy.document.SentenceReader;
import net.yacy.kelondro.util.FileUtils;
import net.yacy.kelondro.util.Formatter;
import net.yacy.peers.Seed;
+import net.yacy.search.Switchboard;
import net.yacy.search.SwitchboardConstants;
import net.yacy.server.serverSwitch;
import net.yacy.utils.translation.ExtensionsFileFilter;
@@ -274,6 +276,7 @@ public class Translator {
public static Map langMap(@SuppressWarnings("unused") final serverSwitch env) {
final String[] ms = CommonPattern.COMMA.split(
+ "browser/Browser Language," +
"default/English,de/Deutsch,fr/Français,nl/Nederlands,it/Italiano,es/Español,pt/Portugês,fi/Suomi,se/Svenska,dk/Dansk," +
"gr/Eλληvικα,sk/Slovensky,cn/汉语/漢語," +
"ru/Русский,uk/Українська," +
@@ -294,6 +297,9 @@ public class Translator {
if ("default".equals(lang) || "default.lng".equals(lang)) {
env.setConfig("locale.language", "default");
ret = true;
+ } else if ("browser".equals(lang) || "browser.lng".equals(lang)) {
+ env.setConfig("locale.language", "browser");
+ ret = true;
} else {
final String htRootPath = env.getConfig(SwitchboardConstants.HTROOT_PATH, SwitchboardConstants.HTROOT_PATH_DEFAULT);
final File sourceDir = new File(env.getAppPath(), htRootPath);
@@ -319,4 +325,24 @@ public class Translator {
public static List langFiles(File langPath) {
return FileUtils.getDirListing(langPath, Translator.LANG_FILENAME_FILTER);
}
+
+ /**
+ * Helper to collect a list of available translations
+ * This looks in the locale directory for the subdirectories created on translation
+ * @return list of language-codes of available/active translations
+ */
+ public static List activeTranslations() {
+ Switchboard sb = Switchboard.getSwitchboard();
+ File localePath;
+ if (sb != null)
+ localePath = sb.getDataPath("locale.translated_html", "DATA/LOCALE/htroot");
+ else
+ localePath = new File ("DATA/LOCALE/htroot");
+ List dirlist = new ArrayList(); // get list of language subdirectories
+ File[] list = localePath.listFiles();
+ for (File f : list) {
+ if (f.isDirectory()) dirlist.add(f.getName()); // filter directories to add to result
+ }
+ return dirlist;
+ }
}
diff --git a/source/net/yacy/http/servlets/YaCyDefaultServlet.java b/source/net/yacy/http/servlets/YaCyDefaultServlet.java
index 22a06538c..99f592b5f 100644
--- a/source/net/yacy/http/servlets/YaCyDefaultServlet.java
+++ b/source/net/yacy/http/servlets/YaCyDefaultServlet.java
@@ -811,7 +811,15 @@ public class YaCyDefaultServlet extends HttpServlet {
protected void handleTemplate(String target, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
Switchboard sb = Switchboard.getSwitchboard();
- String localeSelection = sb.getConfig("locale.language", "default");
+ String localeSelection = sb.getConfig("locale.language", "browser");
+ if (localeSelection.endsWith("browser")) {
+ String lng = request.getLocale().getLanguage();
+ if (lng.equalsIgnoreCase("en")) { // because en is handled as "default" in localizer
+ localeSelection = "default";
+ } else {
+ localeSelection = lng;
+ }
+ }
File targetFile = getLocalizedFile(target, localeSelection);
File targetClass = rewriteClassFile(_resourceBase.addPath(target).getFile());
String targetExt = target.substring(target.lastIndexOf('.') + 1);
@@ -994,6 +1002,7 @@ public class YaCyDefaultServlet extends HttpServlet {
templatePatterns.put("navigation-advanced_authorized", authorized ? 1 : 0);
templatePatterns.put(SwitchboardConstants.GREETING_HOMEPAGE, sb.getConfig(SwitchboardConstants.GREETING_HOMEPAGE, ""));
templatePatterns.put(SwitchboardConstants.GREETING_SMALL_IMAGE, sb.getConfig(SwitchboardConstants.GREETING_SMALL_IMAGE, ""));
+ templatePatterns.put("clientlanguage", localeSelection);
String mimeType = Classification.ext2mime(targetExt, MimeTypes.Type.TEXT_HTML.asString());
diff --git a/source/net/yacy/server/http/TemplateEngine.java b/source/net/yacy/server/http/TemplateEngine.java
index 5158772b2..863455fb8 100644
--- a/source/net/yacy/server/http/TemplateEngine.java
+++ b/source/net/yacy/server/http/TemplateEngine.java
@@ -213,6 +213,7 @@ public final class TemplateEngine {
byte[] replacement;
int bb;
final ByteBuffer structure = new ByteBuffer();
+ final String clientbrowserlang = pattern.get("clientlanguage"); // preferred language or null (used for include files)
while (transferUntil(pis, out, hashChar)) {
bb = pis.read();
keyStream.reset();
@@ -416,7 +417,7 @@ public final class TemplateEngine {
BufferedReader br = null;
try{
//br = new BufferedReader(new InputStreamReader(new FileInputStream( filename ))); //Simple Include
- br = new BufferedReader( new InputStreamReader(new FileInputStream( HTTPDFileHandler.getLocalizedFile(UTF8.String(filename))), StandardCharsets.UTF_8) ); //YaCy (with Locales)
+ br = new BufferedReader( new InputStreamReader(new FileInputStream( HTTPDFileHandler.getLocalizedFile(UTF8.String(filename), clientbrowserlang)), StandardCharsets.UTF_8) ); //YaCy (with Locales)
//Read the Include
String line = "";
while ((line = br.readLine()) != null) {
diff --git a/source/net/yacy/yacy.java b/source/net/yacy/yacy.java
index 4dcbb98f3..db7bbce51 100644
--- a/source/net/yacy/yacy.java
+++ b/source/net/yacy/yacy.java
@@ -37,6 +37,8 @@ import java.io.PrintWriter;
import java.io.RandomAccessFile;
import java.nio.channels.FileChannel;
import java.nio.channels.FileLock;
+import java.util.ArrayList;
+import java.util.List;
import java.util.Properties;
import java.util.concurrent.Semaphore;
@@ -54,6 +56,7 @@ import net.yacy.cora.protocol.http.HTTPClient;
import net.yacy.cora.sorting.Array;
import net.yacy.cora.util.ConcurrentLog;
import net.yacy.crawler.retrieval.Response;
+import net.yacy.data.Translator;
import net.yacy.document.Document;
import net.yacy.gui.YaCyApp;
import net.yacy.gui.framework.Browser;
@@ -337,29 +340,43 @@ public final class yacy {
//regenerate Locales from Translationlist, if needed
final File locale_source = sb.getAppPath("locale.source", "locales");
final String lang = sb.getConfig("locale.language", "");
- if (!lang.equals("") && !lang.equals("default")) { //locale is used
- String currentRev = null;
- try{
- final BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(new File(sb.getDataPath("locale.translated_html", "DATA/LOCALE/htroot"), lang+"/version" ))));
- currentRev = br.readLine(); // may return null
- br.close();
- }catch(final IOException e){
- //Error
- }
+ // on lang=browser all active translation should be checked (because any could be requested by client)
+ List langlist;
+ if (lang.endsWith("browser"))
+ langlist = Translator.activeTranslations(); // get all translated languages
+ else {
+ langlist = new ArrayList();
+ langlist.add(lang);
+ }
+ for (String tmplang : langlist) {
+ if (!tmplang.equals("") && !tmplang.equals("default") && !tmplang.equals("browser")) { //locale is used
+ String currentRev = null;
+ try {
+ final BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(new File(sb.getDataPath("locale.translated_html", "DATA/LOCALE/htroot"), tmplang + "/version"))));
+ currentRev = br.readLine(); // may return null
+ br.close();
+ } catch (final IOException e) {
+ //Error
+ }
- if (currentRev == null || !currentRev.equals(sb.getConfig(Seed.VERSION, ""))) try { //is this another version?!
- final File sourceDir = new File(sb.getConfig(SwitchboardConstants.HTROOT_PATH, SwitchboardConstants.HTROOT_PATH_DEFAULT));
- final File destDir = new File(sb.getDataPath("locale.translated_html", "DATA/LOCALE/htroot"), lang);
- if (new TranslatorXliff().translateFilesRecursive(sourceDir, destDir, new File(locale_source, lang + ".lng"), "html,template,inc", "locale")){ //translate it
- //write the new Versionnumber
- final BufferedWriter bw = new BufferedWriter(new PrintWriter(new FileWriter(new File(destDir, "version"))));
- bw.write(sb.getConfig(Seed.VERSION, "Error getting Version"));
- bw.close();
+ if (currentRev == null || !currentRev.equals(sb.getConfig(Seed.VERSION, ""))) {
+ try { //is this another version?!
+ final File sourceDir = new File(sb.getConfig(SwitchboardConstants.HTROOT_PATH, SwitchboardConstants.HTROOT_PATH_DEFAULT));
+ final File destDir = new File(sb.getDataPath("locale.translated_html", "DATA/LOCALE/htroot"), tmplang);
+ if (new TranslatorXliff().translateFilesRecursive(sourceDir, destDir, new File(locale_source, tmplang + ".lng"), "html,template,inc", "locale")) { //translate it
+ //write the new Versionnumber
+ final BufferedWriter bw = new BufferedWriter(new PrintWriter(new FileWriter(new File(destDir, "version"))));
+ bw.write(sb.getConfig(Seed.VERSION, "Error getting Version"));
+ bw.close();
+ }
+ } catch (final IOException e) {
+ }
}
- } catch (final IOException e) {}
+ }
}
// initialize number formatter with this locale
- Formatter.setLocale(lang);
+ if (!lang.equals("browser")) // "default" is handled by .setLocale()
+ Formatter.setLocale(lang);
// registering shutdown hook
ConcurrentLog.config("STARTUP", "Registering Shutdown Hook");