Reworked.
This commit is contained in:
parent
89eac6b025
commit
0fda50b4e1
1 changed files with 97 additions and 91 deletions
|
@ -38,7 +38,6 @@ import net.thauvin.erik.mobibot.Mobibot;
|
||||||
import net.thauvin.erik.mobibot.Utils;
|
import net.thauvin.erik.mobibot.Utils;
|
||||||
import net.thauvin.erik.mobibot.msg.ErrorMessage;
|
import net.thauvin.erik.mobibot.msg.ErrorMessage;
|
||||||
import net.thauvin.erik.mobibot.msg.Message;
|
import net.thauvin.erik.mobibot.msg.Message;
|
||||||
import net.thauvin.erik.mobibot.msg.NoticeMessage;
|
|
||||||
import net.thauvin.erik.mobibot.msg.PublicMessage;
|
import net.thauvin.erik.mobibot.msg.PublicMessage;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.jdom2.Document;
|
import org.jdom2.Document;
|
||||||
|
@ -51,13 +50,11 @@ import javax.xml.XMLConstants;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.text.NumberFormat;
|
import java.text.NumberFormat;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Locale;
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.TreeMap;
|
import java.util.TreeMap;
|
||||||
|
|
||||||
import static net.thauvin.erik.mobibot.Utils.bold;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The CurrentConverter module.
|
* The CurrentConverter module.
|
||||||
*
|
*
|
||||||
|
@ -67,13 +64,12 @@ import static net.thauvin.erik.mobibot.Utils.bold;
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("PMD.UseConcurrentHashMap")
|
@SuppressWarnings("PMD.UseConcurrentHashMap")
|
||||||
public final class CurrencyConverter extends ThreadedModule {
|
public final class CurrencyConverter extends ThreadedModule {
|
||||||
/**
|
|
||||||
* The rates keyword.
|
|
||||||
*/
|
|
||||||
static final String CURRENCY_RATES_KEYWORD = "rates";
|
|
||||||
|
|
||||||
// Currency command
|
// Currency command
|
||||||
private static final String CURRENCY_CMD = "currency";
|
private static final String CURRENCY_CMD = "currency";
|
||||||
|
// Rates keyword
|
||||||
|
private static final String CURRENCY_RATES_KEYWORD = "rates";
|
||||||
|
// Empty rate table.
|
||||||
|
private static final String EMPTY_RATE_TABLE = "Sorry, but the exchange rate table is empty.";
|
||||||
// Exchange rates
|
// Exchange rates
|
||||||
private static final Map<String, String> EXCHANGE_RATES = new TreeMap<>();
|
private static final Map<String, String> EXCHANGE_RATES = new TreeMap<>();
|
||||||
// Exchange rates table URL
|
// Exchange rates table URL
|
||||||
|
@ -96,9 +92,54 @@ public final class CurrencyConverter extends ThreadedModule {
|
||||||
*
|
*
|
||||||
* @param query The query.
|
* @param query The query.
|
||||||
* @return The {@link Message} contained the converted currency.
|
* @return The {@link Message} contained the converted currency.
|
||||||
* @throws ModuleException If an error occurs while converting.
|
|
||||||
*/
|
*/
|
||||||
static Message convertCurrency(final String query) throws ModuleException {
|
static Message convertCurrency(final String query) {
|
||||||
|
final String[] cmds = query.split(" ");
|
||||||
|
|
||||||
|
if (cmds.length == 4) {
|
||||||
|
if (cmds[3].equals(cmds[1]) || "0".equals(cmds[0])) {
|
||||||
|
return new PublicMessage("You're kidding, right?");
|
||||||
|
} else {
|
||||||
|
final String to = cmds[1].toUpperCase(Constants.LOCALE);
|
||||||
|
final String from = cmds[3].toUpperCase(Constants.LOCALE);
|
||||||
|
|
||||||
|
if (EXCHANGE_RATES.containsKey(to) && EXCHANGE_RATES.containsKey(from)) {
|
||||||
|
try {
|
||||||
|
final double amt = Double.parseDouble(cmds[0].replace(",", ""));
|
||||||
|
final double doubleFrom = Double.parseDouble(EXCHANGE_RATES.get(to));
|
||||||
|
final double doubleTo = Double.parseDouble(EXCHANGE_RATES.get(from));
|
||||||
|
|
||||||
|
return new PublicMessage(
|
||||||
|
NumberFormat.getCurrencyInstance(Constants.LOCALE).format(amt).substring(1)
|
||||||
|
+ ' '
|
||||||
|
+ cmds[1].toUpperCase(Constants.LOCALE)
|
||||||
|
+ " = "
|
||||||
|
+ NumberFormat.getCurrencyInstance(Constants.LOCALE)
|
||||||
|
.format((amt * doubleTo) / doubleFrom)
|
||||||
|
.substring(1)
|
||||||
|
+ ' '
|
||||||
|
+ cmds[3].toUpperCase(Constants.LOCALE));
|
||||||
|
} catch (NumberFormatException e) {
|
||||||
|
return new ErrorMessage("Let's try with some real numbers next time, okay?");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return new ErrorMessage("Sounds like monopoly money to me!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return new ErrorMessage("Invalid query. Let's try again.");
|
||||||
|
}
|
||||||
|
|
||||||
|
static List<String> currencyRates() {
|
||||||
|
final List<String> rates = new ArrayList<>(33);
|
||||||
|
for (final Map.Entry<String, String> rate : EXCHANGE_RATES.entrySet()) {
|
||||||
|
rates.add(" " + rate.getKey() + ": " + StringUtils.leftPad(rate.getValue(), 8));
|
||||||
|
}
|
||||||
|
|
||||||
|
return rates;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void loadRates() throws ModuleException {
|
||||||
if (EXCHANGE_RATES.isEmpty()) {
|
if (EXCHANGE_RATES.isEmpty()) {
|
||||||
try {
|
try {
|
||||||
final SAXBuilder builder = new SAXBuilder();
|
final SAXBuilder builder = new SAXBuilder();
|
||||||
|
@ -116,71 +157,20 @@ public final class CurrencyConverter extends ThreadedModule {
|
||||||
pubDate = cubeTime.getAttribute("time").getValue();
|
pubDate = cubeTime.getAttribute("time").getValue();
|
||||||
|
|
||||||
final List<Element> cubes = cubeTime.getChildren();
|
final List<Element> cubes = cubeTime.getChildren();
|
||||||
Element cube;
|
|
||||||
|
|
||||||
for (final Element rawCube : cubes) {
|
for (final Element cube : cubes) {
|
||||||
cube = rawCube;
|
|
||||||
EXCHANGE_RATES.put(
|
EXCHANGE_RATES.put(
|
||||||
cube.getAttribute("currency").getValue(),
|
cube.getAttribute("currency").getValue(),
|
||||||
cube.getAttribute("rate").getValue());
|
cube.getAttribute("rate").getValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
EXCHANGE_RATES.put("EUR", "1");
|
EXCHANGE_RATES.put("EUR", "1");
|
||||||
} catch (JDOMException e) {
|
} catch (JDOMException | IOException e) {
|
||||||
throw new ModuleException(query, "An error has occurred while parsing the exchange rates table.", e);
|
throw new ModuleException(e.getMessage(),
|
||||||
} catch (IOException e) {
|
"An error has occurred while parsing the exchange rates table.",
|
||||||
throw new ModuleException(
|
e);
|
||||||
query, "An error has occurred while fetching the exchange rates table.", e);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (EXCHANGE_RATES.isEmpty()) {
|
|
||||||
return new ErrorMessage("Sorry, but the exchange rate table is empty.");
|
|
||||||
} else {
|
|
||||||
final String[] cmds = query.split(" ");
|
|
||||||
|
|
||||||
if (cmds.length == 4) {
|
|
||||||
if (cmds[3].equals(cmds[1]) || "0".equals(cmds[0])) {
|
|
||||||
return new ErrorMessage("You're kidding, right?");
|
|
||||||
} else {
|
|
||||||
try {
|
|
||||||
final double amt = Double.parseDouble(cmds[0].replace(",", ""));
|
|
||||||
final double from =
|
|
||||||
Double.parseDouble(EXCHANGE_RATES.get(cmds[1].toUpperCase(Constants.LOCALE)));
|
|
||||||
final double to = Double.parseDouble(EXCHANGE_RATES.get(cmds[3].toUpperCase(Constants.LOCALE)));
|
|
||||||
|
|
||||||
return new PublicMessage(
|
|
||||||
NumberFormat.getCurrencyInstance(Locale.US).format(amt).substring(1)
|
|
||||||
+ ' '
|
|
||||||
+ cmds[1].toUpperCase(Constants.LOCALE)
|
|
||||||
+ " = "
|
|
||||||
+ NumberFormat.getCurrencyInstance(Locale.US)
|
|
||||||
.format((amt * to) / from)
|
|
||||||
.substring(1)
|
|
||||||
+ ' '
|
|
||||||
+ cmds[3].toUpperCase(Constants.LOCALE));
|
|
||||||
} catch (Exception e) {
|
|
||||||
throw new ModuleException("convertCurrency(" + query + ')',
|
|
||||||
"The supported currencies are: " + EXCHANGE_RATES.keySet(), e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (CURRENCY_RATES_KEYWORD.equals(query)) {
|
|
||||||
|
|
||||||
final StringBuilder buff = new StringBuilder().append('[').append(pubDate).append("]: ");
|
|
||||||
|
|
||||||
int i = 0;
|
|
||||||
for (final Map.Entry<String, String> rate : EXCHANGE_RATES.entrySet()) {
|
|
||||||
if (i > 0) {
|
|
||||||
buff.append(", ");
|
|
||||||
}
|
|
||||||
buff.append(rate.getKey()).append(": ").append(rate.getValue());
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
|
|
||||||
return new NoticeMessage(buff.toString());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return new ErrorMessage("The supported currencies are: " + EXCHANGE_RATES.keySet());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -206,22 +196,28 @@ public final class CurrencyConverter extends ThreadedModule {
|
||||||
*/
|
*/
|
||||||
@SuppressFBWarnings("REDOS")
|
@SuppressFBWarnings("REDOS")
|
||||||
@Override
|
@Override
|
||||||
void run(final Mobibot bot, final String sender, final String cmd, final String query) {
|
void run(final Mobibot bot, final String sender, final String cmd, final String query, final boolean isPrivate) {
|
||||||
if (StringUtils.isNotBlank(sender) && StringUtils.isNotBlank(query)) {
|
if (EXCHANGE_RATES.isEmpty()) {
|
||||||
if (query.matches("\\d+([,\\d]+)?(\\.\\d+)? [a-zA-Z]{3}+ to [a-zA-Z]{3}+")) {
|
|
||||||
try {
|
try {
|
||||||
final Message msg = convertCurrency(query);
|
loadRates();
|
||||||
if (msg.isError()) {
|
|
||||||
helpResponse(bot, sender, CURRENCY_CMD + ' ' + query, false);
|
|
||||||
}
|
|
||||||
bot.send(sender, msg);
|
|
||||||
} catch (ModuleException e) {
|
} catch (ModuleException e) {
|
||||||
bot.getLogger().warn(e.getDebugMessage(), e);
|
bot.getLogger().warn(e.getDebugMessage(), e);
|
||||||
bot.send(sender, e.getMessage());
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (EXCHANGE_RATES.isEmpty()) {
|
||||||
|
bot.send(sender, EMPTY_RATE_TABLE, true);
|
||||||
|
} else if (query.matches("\\d+([,\\d]+)?(\\.\\d+)? [a-zA-Z]{3}+ to [a-zA-Z]{3}+")) {
|
||||||
|
final Message msg = convertCurrency(query);
|
||||||
|
bot.send(sender, msg);
|
||||||
|
if (msg.isError()) {
|
||||||
|
helpResponse(bot, sender, isPrivate);
|
||||||
|
}
|
||||||
|
} else if (query.contains(CURRENCY_RATES_KEYWORD)) {
|
||||||
|
bot.send(sender, "The currency rates for " + Utils.bold(pubDate) + " are:", isPrivate);
|
||||||
|
bot.sendCommandsList(sender, currencyRates(), 3, isPrivate, false);
|
||||||
} else {
|
} else {
|
||||||
helpResponse(bot, sender, CURRENCY_CMD + ' ' + query, true);
|
helpResponse(bot, sender, isPrivate);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -229,15 +225,25 @@ public final class CurrencyConverter extends ThreadedModule {
|
||||||
* {@inheritDoc}
|
* {@inheritDoc}
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void helpResponse(final Mobibot bot, final String sender, final String args, final boolean isPrivate) {
|
public void helpResponse(final Mobibot bot, final String sender, final boolean isPrivate) {
|
||||||
bot.send(sender, bold("To convert from one currency to another:"));
|
if (EXCHANGE_RATES.isEmpty()) {
|
||||||
bot.send(sender, Utils.helpIndent(bot.getNick() + ": " + CURRENCY_CMD + " [100 USD to EUR]"));
|
try {
|
||||||
|
loadRates();
|
||||||
if (args.endsWith(CURRENCY_CMD)) {
|
} catch (ModuleException e) {
|
||||||
bot.send(sender, bold("For a listing of currency rates:"));
|
bot.getLogger().debug(e.getDebugMessage(), e);
|
||||||
bot.send(sender, Utils.helpIndent(bot.getNick() + ": " + CURRENCY_CMD) + ' ' + CURRENCY_RATES_KEYWORD);
|
}
|
||||||
bot.send(sender, bold("For a listing of supported currencies:"));
|
}
|
||||||
bot.send(sender, Utils.helpIndent(bot.getNick() + ": " + CURRENCY_CMD));
|
if (EXCHANGE_RATES.isEmpty()) {
|
||||||
|
bot.send(sender, EMPTY_RATE_TABLE, isPrivate);
|
||||||
|
} else {
|
||||||
|
bot.send(sender, "To convert from one currency to another:", isPrivate);
|
||||||
|
bot.send(sender, Utils.helpIndent(bot.getNick() + ": " + CURRENCY_CMD + " 100 USD to EUR"), isPrivate);
|
||||||
|
bot.send(sender, "For a listing of current rates:", isPrivate);
|
||||||
|
bot.send(sender,
|
||||||
|
Utils.helpIndent(bot.getNick() + ": " + CURRENCY_CMD) + ' ' + CURRENCY_RATES_KEYWORD,
|
||||||
|
isPrivate);
|
||||||
|
bot.send(sender, "The supported currencies are: ", isPrivate);
|
||||||
|
bot.sendCommandsList(sender, new ArrayList<>(EXCHANGE_RATES.keySet()), 11, isPrivate, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue