#768 Create command for updating messages file
This commit is contained in:
parent
700ab5f3e4
commit
755f3df33e
@ -11,6 +11,7 @@ import fr.xephi.authme.command.executable.authme.ForceLoginCommand;
|
|||||||
import fr.xephi.authme.command.executable.authme.GetEmailCommand;
|
import fr.xephi.authme.command.executable.authme.GetEmailCommand;
|
||||||
import fr.xephi.authme.command.executable.authme.GetIpCommand;
|
import fr.xephi.authme.command.executable.authme.GetIpCommand;
|
||||||
import fr.xephi.authme.command.executable.authme.LastLoginCommand;
|
import fr.xephi.authme.command.executable.authme.LastLoginCommand;
|
||||||
|
import fr.xephi.authme.command.executable.authme.MessagesCommand;
|
||||||
import fr.xephi.authme.command.executable.authme.PurgeBannedPlayersCommand;
|
import fr.xephi.authme.command.executable.authme.PurgeBannedPlayersCommand;
|
||||||
import fr.xephi.authme.command.executable.authme.PurgeCommand;
|
import fr.xephi.authme.command.executable.authme.PurgeCommand;
|
||||||
import fr.xephi.authme.command.executable.authme.PurgeLastPositionCommand;
|
import fr.xephi.authme.command.executable.authme.PurgeLastPositionCommand;
|
||||||
@ -288,6 +289,15 @@ public class CommandInitializer {
|
|||||||
.executableCommand(ConverterCommand.class)
|
.executableCommand(ConverterCommand.class)
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
|
CommandDescription.builder()
|
||||||
|
.parent(AUTHME_BASE)
|
||||||
|
.labels("messages")
|
||||||
|
.description("Add missing messages")
|
||||||
|
.detailedDescription("Adds missing messages to the current messages file.")
|
||||||
|
// TODO #768: add permission for command
|
||||||
|
.executableCommand(MessagesCommand.class)
|
||||||
|
.build();
|
||||||
|
|
||||||
// Register the base login command
|
// Register the base login command
|
||||||
final CommandDescription LOGIN_BASE = CommandDescription.builder()
|
final CommandDescription LOGIN_BASE = CommandDescription.builder()
|
||||||
.parent(null)
|
.parent(null)
|
||||||
|
|||||||
@ -0,0 +1,48 @@
|
|||||||
|
package fr.xephi.authme.command.executable.authme;
|
||||||
|
|
||||||
|
import fr.xephi.authme.ConsoleLogger;
|
||||||
|
import fr.xephi.authme.command.ExecutableCommand;
|
||||||
|
import fr.xephi.authme.initialization.DataFolder;
|
||||||
|
import fr.xephi.authme.service.MessageUpdater;
|
||||||
|
import fr.xephi.authme.settings.Settings;
|
||||||
|
import fr.xephi.authme.settings.properties.PluginSettings;
|
||||||
|
import org.bukkit.command.CommandSender;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
import java.io.File;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Messages command, updates the user's messages file with any missing files
|
||||||
|
* from the provided file in the JAR.
|
||||||
|
*/
|
||||||
|
public class MessagesCommand implements ExecutableCommand {
|
||||||
|
|
||||||
|
private static final String DEFAULT_LANGUAGE = "en";
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private Settings settings;
|
||||||
|
@Inject
|
||||||
|
@DataFolder
|
||||||
|
private File dataFolder;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void executeCommand(CommandSender sender, List<String> arguments) {
|
||||||
|
final String language = settings.getProperty(PluginSettings.MESSAGES_LANGUAGE);
|
||||||
|
|
||||||
|
try {
|
||||||
|
new MessageUpdater(
|
||||||
|
new File(dataFolder, getMessagePath(language)),
|
||||||
|
getMessagePath(language),
|
||||||
|
getMessagePath(DEFAULT_LANGUAGE))
|
||||||
|
.executeCopy(sender);
|
||||||
|
} catch (Exception e) {
|
||||||
|
sender.sendMessage("Could not update messages: " + e.getMessage());
|
||||||
|
ConsoleLogger.logException("Could not update messages:", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String getMessagePath(String code) {
|
||||||
|
return "messages/messages_" + code + ".yml";
|
||||||
|
}
|
||||||
|
}
|
||||||
108
src/main/java/fr/xephi/authme/service/MessageUpdater.java
Normal file
108
src/main/java/fr/xephi/authme/service/MessageUpdater.java
Normal file
@ -0,0 +1,108 @@
|
|||||||
|
package fr.xephi.authme.service;
|
||||||
|
|
||||||
|
import fr.xephi.authme.ConsoleLogger;
|
||||||
|
import fr.xephi.authme.message.MessageKey;
|
||||||
|
import fr.xephi.authme.util.FileUtils;
|
||||||
|
import fr.xephi.authme.util.StringUtils;
|
||||||
|
import org.bukkit.command.CommandSender;
|
||||||
|
import org.bukkit.configuration.file.FileConfiguration;
|
||||||
|
import org.bukkit.configuration.file.YamlConfiguration;
|
||||||
|
|
||||||
|
import java.io.Closeable;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates a user's messages file with messages from the JAR files.
|
||||||
|
*/
|
||||||
|
public class MessageUpdater {
|
||||||
|
|
||||||
|
private final File userFile;
|
||||||
|
private final FileConfiguration userConfiguration;
|
||||||
|
private final FileConfiguration localJarConfiguration;
|
||||||
|
private final FileConfiguration defaultJarConfiguration;
|
||||||
|
private boolean hasMissingMessages = false;
|
||||||
|
|
||||||
|
public MessageUpdater(File userFile, String jarFile, String jarDefaultsFile) throws Exception {
|
||||||
|
if (!userFile.exists()) {
|
||||||
|
throw new Exception("Local messages file does not exist");
|
||||||
|
}
|
||||||
|
this.userFile = userFile;
|
||||||
|
this.userConfiguration = YamlConfiguration.loadConfiguration(userFile);
|
||||||
|
|
||||||
|
localJarConfiguration = loadJarFileOrSendError(jarFile);
|
||||||
|
defaultJarConfiguration = jarFile.equals(jarDefaultsFile)
|
||||||
|
? null
|
||||||
|
: loadJarFileOrSendError(jarDefaultsFile);
|
||||||
|
if (localJarConfiguration == null && defaultJarConfiguration == null) {
|
||||||
|
throw new Exception("Could not load any JAR messages file to copy from");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void executeCopy(CommandSender sender) {
|
||||||
|
copyMissingMessages();
|
||||||
|
|
||||||
|
if (!hasMissingMessages) {
|
||||||
|
sender.sendMessage("No new messages to add");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Save user configuration file
|
||||||
|
try {
|
||||||
|
userConfiguration.save(userFile);
|
||||||
|
sender.sendMessage("Message file updated with new messages");
|
||||||
|
} catch (IOException e) {
|
||||||
|
sender.sendMessage("Could not save to messages file");
|
||||||
|
ConsoleLogger.logException("Could not save new messages to file:", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void copyMissingMessages() {
|
||||||
|
for (MessageKey entry : MessageKey.values()) {
|
||||||
|
final String key = entry.getKey();
|
||||||
|
if (!userConfiguration.contains(key)) {
|
||||||
|
String jarMessage = getMessageFromJar(key);
|
||||||
|
if (jarMessage != null) {
|
||||||
|
hasMissingMessages = true;
|
||||||
|
userConfiguration.set(key, jarMessage);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getMessageFromJar(String key) {
|
||||||
|
String message = (localJarConfiguration == null ? null : localJarConfiguration.getString(key));
|
||||||
|
if (message != null) {
|
||||||
|
return message;
|
||||||
|
}
|
||||||
|
return (defaultJarConfiguration == null ? null : defaultJarConfiguration.getString(key));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static FileConfiguration loadJarFileOrSendError(String jarPath) {
|
||||||
|
try (InputStream stream = FileUtils.getResourceFromJar(jarPath)) {
|
||||||
|
if (stream == null) {
|
||||||
|
ConsoleLogger.info("Could not load '" + jarPath + "' from JAR");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
InputStreamReader isr = new InputStreamReader(stream);
|
||||||
|
FileConfiguration configuration = YamlConfiguration.loadConfiguration(isr);
|
||||||
|
close(isr);
|
||||||
|
return configuration;
|
||||||
|
} catch (IOException e) {
|
||||||
|
ConsoleLogger.logException("Exception while handling JAR path '" + jarPath + "'", e);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void close(Closeable closeable) {
|
||||||
|
if (closeable != null) {
|
||||||
|
try {
|
||||||
|
closeable.close();
|
||||||
|
} catch (IOException e) {
|
||||||
|
ConsoleLogger.info("Cannot close '" + closeable + "': " + StringUtils.formatException(e));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -23,7 +23,7 @@ public final class FileUtils {
|
|||||||
* Copy a resource file (from the JAR) to the given file if it doesn't exist.
|
* Copy a resource file (from the JAR) to the given file if it doesn't exist.
|
||||||
*
|
*
|
||||||
* @param destinationFile The file to check and copy to (outside of JAR)
|
* @param destinationFile The file to check and copy to (outside of JAR)
|
||||||
* @param resourcePath Absolute path to the resource file (path to file within JAR)
|
* @param resourcePath Local path to the resource file (path to file within JAR)
|
||||||
*
|
*
|
||||||
* @return False if the file does not exist and could not be copied, true otherwise
|
* @return False if the file does not exist and could not be copied, true otherwise
|
||||||
*/
|
*/
|
||||||
@ -35,9 +35,7 @@ public final class FileUtils {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ClassLoader#getResourceAsStream does not deal with the '\' path separator: replace to '/'
|
try (InputStream is = getResourceFromJar(resourcePath)) {
|
||||||
final String normalizedPath = resourcePath.replace("\\", "/");
|
|
||||||
try (InputStream is = AuthMe.class.getClassLoader().getResourceAsStream(normalizedPath)) {
|
|
||||||
if (is == null) {
|
if (is == null) {
|
||||||
ConsoleLogger.warning(format("Cannot copy resource '%s' to file '%s': cannot load resource",
|
ConsoleLogger.warning(format("Cannot copy resource '%s' to file '%s': cannot load resource",
|
||||||
resourcePath, destinationFile.getPath()));
|
resourcePath, destinationFile.getPath()));
|
||||||
@ -52,6 +50,18 @@ public final class FileUtils {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a JAR file as stream. Returns null if it doesn't exist.
|
||||||
|
*
|
||||||
|
* @param path the local path (starting from resources project, e.g. "config.yml" for 'resources/config.yml')
|
||||||
|
* @return the stream if the file exists, or false otherwise
|
||||||
|
*/
|
||||||
|
public static InputStream getResourceFromJar(String path) {
|
||||||
|
// ClassLoader#getResourceAsStream does not deal with the '\' path separator: replace to '/'
|
||||||
|
final String normalizedPath = path.replace("\\", "/");
|
||||||
|
return AuthMe.class.getClassLoader().getResourceAsStream(normalizedPath);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Delete a given directory and all its content.
|
* Delete a given directory and all its content.
|
||||||
*
|
*
|
||||||
|
|||||||
@ -11,6 +11,8 @@ import java.io.File;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
import static org.hamcrest.Matchers.equalTo;
|
import static org.hamcrest.Matchers.equalTo;
|
||||||
|
import static org.hamcrest.Matchers.not;
|
||||||
|
import static org.hamcrest.Matchers.nullValue;
|
||||||
import static org.junit.Assert.assertThat;
|
import static org.junit.Assert.assertThat;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -119,6 +121,13 @@ public class FileUtilsTest {
|
|||||||
// Nothing happens
|
// Nothing happens
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void shouldGetResourceFromJar() {
|
||||||
|
// given / when / then
|
||||||
|
assertThat(FileUtils.getResourceFromJar("config.yml"), not(nullValue()));
|
||||||
|
assertThat(FileUtils.getResourceFromJar("does-not-exist"), nullValue());
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void shouldConstructPath() {
|
public void shouldConstructPath() {
|
||||||
// given/when
|
// given/when
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user