diff --git a/AreaShop/src/main/java/me/wiefferink/areashop/messages/LanguageManager.java b/AreaShop/src/main/java/me/wiefferink/areashop/messages/LanguageManager.java index 5d8161e4..4008ebc9 100644 --- a/AreaShop/src/main/java/me/wiefferink/areashop/messages/LanguageManager.java +++ b/AreaShop/src/main/java/me/wiefferink/areashop/messages/LanguageManager.java @@ -47,9 +47,7 @@ public void saveDefaults() { } // Create the language files, overwrites if a file already exists - // Overriding is necessary because otherwise with an update the new lang - // files would not be used, when translating your own use another - // file name as the default + // Overriding is necessary because otherwise with an update the new lang files would not be used File langFile; for(String language : languages) { langFile = new File(plugin.getDataFolder()+File.separator+AreaShop.languageFolder+File.separator+language+".yml"); @@ -81,28 +79,58 @@ public void saveDefaults() { * @return Map with the messages loaded from the file */ public Map> loadLanguage(String key) { + return loadLanguage(key, true); + } + + /** + * Loads the specified language + * @param key The language to load + * @param convert try conversion or not + * @return Map with the messages loaded from the file + */ + private Map> loadLanguage(String key, boolean convert) { Map> result = new HashMap<>(); // Load the strings + boolean isTransifexFile = false; File file = new File(plugin.getDataFolder()+File.separator+AreaShop.languageFolder+File.separator+key+".yml"); try( InputStreamReader reader = new InputStreamReader(new FileInputStream(file), Charsets.UTF_8) ) { YamlConfiguration ymlFile = YamlConfiguration.loadConfiguration(reader); + // Detect empty language files, happens when the YAML parser prints an exception (it does return an empty YamlConfiguration though) if(ymlFile.getKeys(false).isEmpty()) { AreaShop.warn("Language file "+key+".yml has zero messages."); return result; } - for(String messageKey : ymlFile.getKeys(false)) { - if(ymlFile.isList(messageKey)) { - result.put(messageKey, new ArrayList<>(ymlFile.getStringList(messageKey))); - } else { - result.put(messageKey, new ArrayList<>(Collections.singletonList(ymlFile.getString(messageKey)))); + // Detect language files downloaded from Transifex and convert them + if(ymlFile.getKeys(false).size() == 1) { + for(String languageKey : ymlFile.getKeys(false)) { + if(ymlFile.isConfigurationSection(languageKey)) { + isTransifexFile = convert; + } + } + } + // Retrieve the messages from the YAML file and create the result + if(!isTransifexFile) { + for(String messageKey : ymlFile.getKeys(false)) { + if(ymlFile.isList(messageKey)) { + result.put(messageKey, new ArrayList<>(ymlFile.getStringList(messageKey))); + } else { + result.put(messageKey, new ArrayList<>(Collections.singletonList(ymlFile.getString(messageKey)))); + } } } } catch(IOException e) { AreaShop.warn("Could not load set language file: "+file.getAbsolutePath()); } + + if(isTransifexFile) { + if(!Transifex.convertFrom(file)) { + AreaShop.warn("Failed to convert "+file.getName()+" from the Transifex layout to the AreaShop layout, check the errors above"); + } + return loadLanguage(key, false); + } return result; } diff --git a/AreaShop/src/main/java/me/wiefferink/areashop/messages/Transifex.java b/AreaShop/src/main/java/me/wiefferink/areashop/messages/Transifex.java new file mode 100644 index 00000000..9a206195 --- /dev/null +++ b/AreaShop/src/main/java/me/wiefferink/areashop/messages/Transifex.java @@ -0,0 +1,120 @@ +package me.wiefferink.areashop.messages; + +import me.wiefferink.areashop.AreaShop; +import org.apache.commons.lang.StringUtils; +import org.apache.commons.lang.exception.ExceptionUtils; + +import java.io.*; + +public class Transifex { + public static boolean convertFrom(File inputFile) { + if(inputFile == null || !inputFile.exists() || !inputFile.isFile()) { + warn("Could not convert Transifix file, it does not exist"); + return false; + } + AreaShop.debug("Transifex conversion of", inputFile.getAbsolutePath()); + + File newFile = new File(inputFile.getAbsolutePath()+".new"); + try( + BufferedReader reader = new BufferedReader(new FileReader(inputFile)); + BufferedWriter writer = new BufferedWriter(new FileWriter(newFile)) + ) { + // Create target file + newFile.createNewFile(); + + // Add translation strings + String line = reader.readLine(); + boolean first = true; + String lastLineStart = null; + while(line != null) { + // Skip line with the language on it + if(first) { + first = false; + line = reader.readLine(); + continue; + } + // Skip comment lines (normally there are none) + if(line.startsWith("#")) { + line = reader.readLine(); + continue; + } + // Strip whitespace at the front + if(line.length() > 2) { + line = line.substring(2); + } + // Add empty lines between messages of a different type (the part before - decides the type) + if(lastLineStart != null && !line.trim().isEmpty() && !line.startsWith(lastLineStart) && !line.trim().startsWith("-")) { + writer.newLine(); + } + // Write line to the new file + if(!line.trim().isEmpty()) { + // Detect special fancyformat lines + if(line.contains("\\n")) { + String[] specials = line.split("\\\\n"); + //print("Contains newline: "+line+", split into "+specials.length+" parts"); + // Write identifier + writer.write(specials[0].substring(0, specials[0].indexOf(":")+1)); + writer.newLine(); + // Strip identifier from first part + specials[0] = specials[0].substring(specials[0].indexOf(":")+3); + // Write special lines + for(String special : specials) { + writer.write(" - \""); + if(special.startsWith("\\t")) { + special = special.substring(2); + writer.write(" "); + } + writer.write(special); + if(!special.endsWith("\"")) { + writer.write("\""); + } + writer.newLine(); + } + } else { + // Simply copy the line + writer.write(line); + writer.newLine(); + } + } + // Update last line start + String[] splittedLine = line.split("-"); + if(splittedLine.length > 0 && !line.trim().isEmpty()) { + lastLineStart = splittedLine[0]; + } + line = reader.readLine(); + } + } catch(IOException e) { + warn("Could not convert Transifix file:", ExceptionUtils.getStackTrace(e)); + newFile.delete(); + return false; + } + + // Move current file to .old, move new file to original location + File oldFile = new File(inputFile.getAbsolutePath()+".transifex"); + if(oldFile.exists() && oldFile.isFile()) { + if(!oldFile.delete()) { + warn("Could not remove existing old file:", oldFile.getAbsolutePath()); + return false; + } + } + if(!inputFile.renameTo(oldFile)) { + warn("Could not move input file to .old, from", inputFile.getAbsolutePath(), "to", oldFile.getAbsolutePath()); + return false; + } + if(!newFile.renameTo(inputFile)) { + warn("Could not move new file to original file location, from", newFile.getAbsolutePath(), "to", inputFile.getAbsolutePath()); + oldFile.renameTo(inputFile); // Try to recover original file + return false; + } + AreaShop.info("Converted "+inputFile.getName()+" from the Transifex layout to the AreaShop layout, original saved in "+oldFile.getName()); + return true; + } + + /** + * Print a warning to the console + * @param message The message to print + */ + private static void warn(String... message) { + AreaShop.warn("[Transifex language file conversion]", StringUtils.join(message, " ")); + } +}