+
+
+ No facets are configured
@@ -2752,7 +3047,21 @@
-
+
+
+ Source
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/properties/mobibot.properties b/properties/mobibot.properties
index d3ae51c..3acc8ab 100644
--- a/properties/mobibot.properties
+++ b/properties/mobibot.properties
@@ -15,6 +15,9 @@ weblog=http://www.mobitopia.org/
feed=http://www.mobitopia.org/rss.xml
backlogs=http://www.mobitopia.org/mobibot/logs
+tell-max-days=5
+tell-max-size=50
+
#delicious-user=
#delicious-pwd=
diff --git a/src/main/java/net/thauvin/erik/mobibot/Commands.java b/src/main/java/net/thauvin/erik/mobibot/Commands.java
new file mode 100644
index 0000000..47dbedf
--- /dev/null
+++ b/src/main/java/net/thauvin/erik/mobibot/Commands.java
@@ -0,0 +1,256 @@
+/*
+ * @(#)Commands.java
+ *
+ * Copyright (c) 2004-2014, Erik C. Thauvin (erik@thauvin.net)
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the author nor the names of its contributors may be
+ * used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package net.thauvin.erik.mobibot;
+
+/**
+ * The commands, keywords and arguments.
+ *
+ * @author Erik C. Thauvin
+ * @created 2014-04-26
+ * @since 1.0
+ */
+public class Commands
+{
+ /**
+ * The currency command.
+ */
+ public static final String CURRENCY_CMD = "currency";
+
+ /**
+ * The rates keyword.
+ */
+ public static final String CURRENCY_RATES_KEYWORD = "rates";
+
+ /**
+ * The weather command.
+ */
+ public static final String WEATHER_CMD = "weather";
+
+ /**
+ * Debug command line argument.
+ */
+ public static final String DEBUG_ARG = "debug";
+
+ /**
+ * Help command line argument.
+ */
+ public static final String HELP_ARG = "help";
+
+ /**
+ * Properties command line argument.
+ */
+ public static final String PROPS_ARG = "properties";
+
+ /**
+ * Properties version line argument.
+ */
+ public static final String VERSION_ARG = "version";
+
+ /**
+ * The add (back)log command.
+ */
+ public static final String ADDLOG_CMD = "addlog";
+
+ /**
+ * The debug command.
+ */
+ public static final String DEBUG_CMD = "debug";
+
+ /**
+ * The dices command.
+ */
+ public static final String DICE_CMD = "dice";
+
+ /**
+ * The say command.
+ */
+ public static final String SAY_CMD = "say";
+
+ /**
+ * The die command.
+ */
+ public static final String DIE_CMD = "die";
+
+ /**
+ * The cycle command.
+ */
+ public static final String CYCLE_CMD = "cycle";
+
+ /**
+ * The msg command.
+ */
+ public static final String MSG_CMD = "msg";
+
+ /**
+ * The ignore command.
+ */
+ public static final String IGNORE_CMD = "ignore";
+
+ /**
+ * The ignore me keyword.
+ */
+ public static final String IGNORE_ME_KEYWORD = "me";
+
+ /**
+ * The help command.
+ */
+ public static final String HELP_CMD = "help";
+
+ /**
+ * The help on posting keyword.
+ */
+ public static final String HELP_POSTING_KEYWORD = "posting";
+
+ /**
+ * The help on tags keyword.
+ */
+ public static final String HELP_TAGS_KEYWORD = "tags";
+
+ /**
+ * The Google command.
+ */
+ public static final String GOOGLE_CMD = "google";
+
+ /**
+ * The Twitter command.
+ */
+ public static final String TWITTER_CMD = "twitter";
+
+ /**
+ * The math command.
+ */
+ public static final String CALC_CMD = "calc";
+
+ /**
+ * The me command.
+ */
+ public static final String ME_CMD = "me";
+
+ /**
+ * The nick command.
+ */
+ public static final String NICK_CMD = "nick";
+
+ /**
+ * The link command.
+ */
+ public static final String LINK_CMD = "L";
+
+ /**
+ * The lookup command.
+ */
+ public static final String LOOKUP_CMD = "lookup";
+
+ /**
+ * The ping command.
+ */
+ public static final String PING_CMD = "ping";
+
+ /**
+ * The pong command.
+ */
+ public static final String PONG_CMD = "pong";
+
+ /**
+ * The quote command.
+ */
+ public static final String QUOTE_CMD = "quote";
+
+ /**
+ * The recap command.
+ */
+ public static final String RECAP_CMD = "recap";
+
+ /**
+ * The stock command.
+ */
+ public static final String STOCK_CMD = "stock";
+
+ /**
+ * The time command.
+ */
+ public static final String TIME_CMD = "time";
+
+ /**
+ * The tell command.
+ */
+ public static final String TELL_CMD = "tell";
+
+ /**
+ * The {@link #TELL_CMD} delete command.
+ */
+ public static final String TELL_DEL_CMD = "del";
+
+ /**
+ * The {@link #TELL_CMD} all command.
+ */
+ public static final String TELL_ALL_CMD = "all";
+
+ /**
+ * The war command.
+ */
+ public static final String WAR_CMD = "war";
+
+ /**
+ * The users command.
+ */
+ public static final String USERS_CMD = "users";
+
+ /**
+ * The info command.
+ */
+ public static final String INFO_CMD = "info";
+
+ /**
+ * The version command.
+ */
+ public static final String VERSION_CMD = "version";
+
+ /**
+ * The view command.
+ */
+ public static final String VIEW_CMD = "view";
+
+ /**
+ * Disables the default constructor.
+ *
+ * @throws UnsupportedOperationException if an error occurred. if the constructor is called.
+ */
+ private Commands()
+ throws UnsupportedOperationException
+ {
+ throw new UnsupportedOperationException("Illegal constructor call.");
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/net/thauvin/erik/mobibot/CurrencyConverter.java b/src/main/java/net/thauvin/erik/mobibot/CurrencyConverter.java
index 8bcb522..4822fb0 100644
--- a/src/main/java/net/thauvin/erik/mobibot/CurrencyConverter.java
+++ b/src/main/java/net/thauvin/erik/mobibot/CurrencyConverter.java
@@ -1,7 +1,7 @@
/*
* @(#)CurrencyConverter.java
*
- * Copyright (c) 2004, Erik C. Thauvin (erik@thauvin.net)
+ * Copyright (c) 2004-2014, Erik C. Thauvin (erik@thauvin.net)
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -30,10 +30,8 @@
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * $Id$
- *
*/
+
package net.thauvin.erik.mobibot;
import org.jdom.Document;
@@ -51,7 +49,6 @@ import java.util.*;
* Converts various currencies.
*
* @author Erik C. Thauvin
- * @version $Revision$, $Date$
* @created Feb 11, 2004
* @since 1.0
*/
@@ -67,11 +64,6 @@ public class CurrencyConverter implements Runnable
*/
private static final Map EXCHANGE_RATES = new TreeMap();
- /**
- * The rates keyword.
- */
- private static final String RATES_KEYWORD = "rates";
-
/**
* The bot.
*/
@@ -80,12 +72,12 @@ public class CurrencyConverter implements Runnable
/**
* The actual currency query.
*/
- private final String query;
+ private String query;
/**
* The nick of the person who sent the message.
*/
- private final String sender;
+ private String sender;
/**
* The last exchange rates table publication date.
@@ -96,17 +88,24 @@ public class CurrencyConverter implements Runnable
* Creates a new CurrencyConverter object.
*
* @param bot The bot.
- * @param sender The nick of the person who sent the message.
- * @param query The currency query.
- * @param date The current date.
*/
- public CurrencyConverter(Mobibot bot, String sender, String query, String date)
+ public CurrencyConverter(Mobibot bot)
{
this.bot = bot;
- this.sender = sender;
- this.query = query.toLowerCase();
+ }
- if (!pubDate.equals(date))
+ /**
+ * Sets the query.
+ *
+ * @param sender The nick of the person who sent the message.
+ * @param query The currency query.
+ */
+ public void setQuery(String sender, String query)
+ {
+ this.query = query;
+ this.sender = sender;
+
+ if (!pubDate.equals(Utils.today()))
{
EXCHANGE_RATES.clear();
}
@@ -115,110 +114,115 @@ public class CurrencyConverter implements Runnable
// Converts specified currencies.
public final void run()
{
- if (EXCHANGE_RATES.isEmpty())
+ if (Utils.isValidString(sender) && Utils.isValidString(query))
{
- try
+ if (EXCHANGE_RATES.isEmpty())
{
- final SAXBuilder builder = new SAXBuilder();
- builder.setIgnoringElementContentWhitespace(true);
-
- final Document doc = builder.build(new URL(EXCHANGE_TABLE_URL));
- final Element root = doc.getRootElement();
- final Namespace ns = root.getNamespace("");
- final Element cubeRoot = root.getChild("Cube", ns);
- final Element cubeTime = cubeRoot.getChild("Cube", ns);
-
- pubDate = cubeTime.getAttribute("time").getValue();
-
- final List cubes = cubeTime.getChildren();
- Element cube;
-
- for (final Object rawCube : cubes)
+ try
{
- cube = (Element) rawCube;
- EXCHANGE_RATES.put(cube.getAttribute("currency").getValue(), cube.getAttribute("rate").getValue());
- }
+ final SAXBuilder builder = new SAXBuilder();
+ builder.setIgnoringElementContentWhitespace(true);
- EXCHANGE_RATES.put("EUR", "1");
- }
- catch (JDOMException e)
- {
- bot.getLogger().debug("Unable to parse the exchange rates table.", e);
- bot.send(sender, "An error has occurred while parsing the exchange rates table.");
- }
- catch (IOException e)
- {
- bot.getLogger().debug("Unable to fetch the exchange rates table.", e);
- bot.send(sender, "An error has occurred while fetching the exchange rates table: " + e.getMessage());
- }
- }
+ final Document doc = builder.build(new URL(EXCHANGE_TABLE_URL));
+ final Element root = doc.getRootElement();
+ final Namespace ns = root.getNamespace("");
+ final Element cubeRoot = root.getChild("Cube", ns);
+ final Element cubeTime = cubeRoot.getChild("Cube", ns);
- if (!EXCHANGE_RATES.isEmpty())
- {
- if (query.matches("\\d+([,\\d]+)?(\\.\\d+)? [a-z]{3}+ to [a-z]{3}+"))
- {
- final String[] cmds = query.split(" ");
+ pubDate = cubeTime.getAttribute("time").getValue();
- if (cmds.length == 4)
- {
- if (cmds[3].equals(cmds[1]))
+ final List cubes = cubeTime.getChildren();
+ Element cube;
+
+ for (final Object rawCube : cubes)
{
- bot.send(sender, "You're kidding, right?");
+ cube = (Element) rawCube;
+ EXCHANGE_RATES
+ .put(cube.getAttribute("currency").getValue(), cube.getAttribute("rate").getValue());
}
- else
- {
- try
- {
- final double amt = Double.parseDouble(cmds[0].replaceAll(",", ""));
- final double from = Double.parseDouble(EXCHANGE_RATES.get(cmds[1].toUpperCase()));
- final double to = Double.parseDouble(EXCHANGE_RATES.get(cmds[3].toUpperCase()));
- bot.send(bot.getChannel(),
- NumberFormat.getCurrencyInstance(Locale.US).format(amt).substring(1) + ' ' +
- cmds[1].toUpperCase() + " = " +
- NumberFormat.getCurrencyInstance(Locale.US).format((amt * to) / from).substring(1)
- + ' ' + cmds[3].toUpperCase()
- );
- }
- catch (NullPointerException ignored)
+ EXCHANGE_RATES.put("EUR", "1");
+ }
+ catch (JDOMException e)
+ {
+ bot.getLogger().debug("Unable to parse the exchange rates table.", e);
+ bot.send(sender, "An error has occurred while parsing the exchange rates table.");
+ }
+ catch (IOException e)
+ {
+ bot.getLogger().debug("Unable to fetch the exchange rates table.", e);
+ bot.send(sender,
+ "An error has occurred while fetching the exchange rates table: " + e.getMessage());
+ }
+ }
+
+ if (!EXCHANGE_RATES.isEmpty())
+ {
+ if (query.matches("\\d+([,\\d]+)?(\\.\\d+)? [a-zA-Z]{3}+ to [a-zA-Z]{3}+"))
+ {
+ final String[] cmds = query.split(" ");
+
+ if (cmds.length == 4)
+ {
+ if (cmds[3].equals(cmds[1]) || cmds[0].equals("0"))
{
- bot.send(sender, "The supported currencies are: " + EXCHANGE_RATES.keySet().toString());
+ bot.send(sender, "You're kidding, right?");
+ }
+ else
+ {
+ try
+ {
+ final double amt = Double.parseDouble(cmds[0].replaceAll(",", ""));
+ final double from = Double.parseDouble(EXCHANGE_RATES.get(cmds[1].toUpperCase()));
+ final double to = Double.parseDouble(EXCHANGE_RATES.get(cmds[3].toUpperCase()));
+
+ bot.send(bot.getChannel(),
+ NumberFormat.getCurrencyInstance(Locale.US).format(amt).substring(1) + ' ' +
+ cmds[1].toUpperCase() + " = " +
+ NumberFormat.getCurrencyInstance(Locale.US).format((amt * to) / from)
+ .substring(1) + ' ' + cmds[3].toUpperCase()
+ );
+ }
+ catch (NullPointerException ignored)
+ {
+ bot.send(sender, "The supported currencies are: " + EXCHANGE_RATES.keySet().toString());
+ }
}
}
}
- }
- else if (query.equals(RATES_KEYWORD))
- {
- bot.send(sender, "Last Update: " + pubDate);
-
- final Iterator it = EXCHANGE_RATES.keySet().iterator();
- String rate;
-
- final StringBuilder buff = new StringBuilder(0);
-
- while (it.hasNext())
+ else if (query.equals(Commands.CURRENCY_RATES_KEYWORD))
{
- rate = it.next();
- if (buff.length() > 0)
+ bot.send(sender, "Last Update: " + pubDate);
+
+ final Iterator it = EXCHANGE_RATES.keySet().iterator();
+ String rate;
+
+ final StringBuilder buff = new StringBuilder(0);
+
+ while (it.hasNext())
{
- buff.append(", ");
+ rate = it.next();
+ if (buff.length() > 0)
+ {
+ buff.append(", ");
+ }
+ buff.append(rate).append(": ").append(EXCHANGE_RATES.get(rate));
}
- buff.append(rate).append(": ").append(EXCHANGE_RATES.get(rate));
+
+ bot.send(sender, buff.toString());
+
+ }
+ else
+ {
+ bot.helpResponse(sender, Commands.CURRENCY_CMD + ' ' + query);
+ bot.send(sender, "The supported currencies are: " + EXCHANGE_RATES.keySet().toString());
}
-
- bot.send(sender, buff.toString());
-
}
else
{
- bot.helpResponse(sender, Mobibot.CURRENCY_CMD + ' ' + query);
- bot.send(sender, "The supported currencies are: " + EXCHANGE_RATES.keySet().toString());
+ bot.getLogger().debug("The exchange rate table is empty.");
+ bot.send(sender, "Sorry, but the exchange rate table is empty.");
}
}
- else
- {
- bot.getLogger().debug("The exchange rate table is empty.");
- bot.send(sender, "Sorry, but the exchange rate table is empty.");
- }
}
}
diff --git a/src/main/java/net/thauvin/erik/mobibot/DeliciousPoster.java b/src/main/java/net/thauvin/erik/mobibot/DeliciousPoster.java
index 036f2e8..8f60136 100644
--- a/src/main/java/net/thauvin/erik/mobibot/DeliciousPoster.java
+++ b/src/main/java/net/thauvin/erik/mobibot/DeliciousPoster.java
@@ -1,7 +1,7 @@
/*
* @(#)DeliciousPoster.java
*
- * Copyright (c) 2005, Erik C. Thauvin (erik@thauvin.net)
+ * Copyright (c) 2004-2014, Erik C. Thauvin (erik@thauvin.net)
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -30,10 +30,8 @@
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * $Id$
- *
*/
+
package net.thauvin.erik.mobibot;
import del.icio.us.Delicious;
@@ -42,11 +40,10 @@ import del.icio.us.Delicious;
* The class to handle posts to del.icio.us.
*
* @author Erik C. Thauvin
- * @version $Revision$, $Date$
* @created Mar 5, 2005
- * @noinspection UnnecessaryBoxing
* @since 1.0
*/
+@SuppressWarnings("UnnecessaryBoxing")
public class DeliciousPoster
{
private final Delicious delicious;
@@ -78,16 +75,28 @@ public class DeliciousPoster
public Object construct()
{
return Boolean.valueOf(delicious.addPost(entry.getLink(),
- entry.getTitle(),
- postedBy(entry),
- entry.getDeliciousTags(),
- entry.getDate()));
+ entry.getTitle(),
+ postedBy(entry),
+ entry.getDeliciousTags(),
+ entry.getDate()));
}
};
worker.start();
}
+ /**
+ * Returns he del.icio.us extended attribution line.
+ *
+ * @param entry The entry.
+ *
+ * @return The extended attribution line.
+ */
+ private String postedBy(EntryLink entry)
+ {
+ return "Posted by " + entry.getNick() + " on " + entry.getChannel() + " (" + ircServer + ')';
+ }
+
/**
* Deletes a post to del.icio.us.
*
@@ -125,36 +134,24 @@ public class DeliciousPoster
delicious.deletePost(oldUrl);
return Boolean.valueOf(delicious.addPost(entry.getLink(),
- entry.getTitle(),
- postedBy(entry),
- entry.getDeliciousTags(),
- entry.getDate()));
+ entry.getTitle(),
+ postedBy(entry),
+ entry.getDeliciousTags(),
+ entry.getDate()));
}
else
{
return Boolean.valueOf(delicious.addPost(entry.getLink(),
- entry.getTitle(),
- postedBy(entry),
- entry.getDeliciousTags(),
- entry.getDate(),
- true,
- true));
+ entry.getTitle(),
+ postedBy(entry),
+ entry.getDeliciousTags(),
+ entry.getDate(),
+ true,
+ true));
}
}
};
worker.start();
}
-
- /**
- * Returns he del.icio.us extended attribution line.
- *
- * @param entry The entry.
- *
- * @return The extended attribution line.
- */
- private String postedBy(EntryLink entry)
- {
- return "Posted by " + entry.getNick() + " on " + entry.getChannel() + " (" + ircServer + ')';
- }
}
diff --git a/src/main/java/net/thauvin/erik/mobibot/Dice.java b/src/main/java/net/thauvin/erik/mobibot/Dice.java
new file mode 100644
index 0000000..f5f63d2
--- /dev/null
+++ b/src/main/java/net/thauvin/erik/mobibot/Dice.java
@@ -0,0 +1,97 @@
+/*
+ * @(#)Dice.java
+ *
+ * Copyright (c) 2004-2014, Erik C. Thauvin (erik@thauvin.net)
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the author nor the names of its contributors may be
+ * used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package net.thauvin.erik.mobibot;
+
+import java.util.Random;
+
+/**
+ * The {@link net.thauvin.erik.mobibot.Commands#DICE_CMD} command
+ *
+ * @author Erik C. Thauvin
+ * @created 2014-04-28
+ * @since 1.0
+ */
+public class Dice
+{
+ /**
+ * Disables the default constructor.
+ *
+ * @throws UnsupportedOperationException if an error occurred. if the constructor is called.
+ */
+ private Dice()
+ throws UnsupportedOperationException
+ {
+ throw new UnsupportedOperationException("Illegal constructor call.");
+ }
+
+ /**
+ * Rolls the dice
+ *
+ * @param bot The bot.
+ * @param sender The sender's nickname.
+ */
+ public static void roll(Mobibot bot, String sender)
+ {
+ final Random r = new Random();
+
+ int i = r.nextInt(6) + 1;
+ int y = r.nextInt(6) + 1;
+ final int playerTotal = i + y;
+
+ bot.send(bot.getChannel(),
+ sender + " rolled two dice: " + Utils.bold(i) + " and " + Utils.bold(y) + " for a total of " + Utils
+ .bold(playerTotal)
+ );
+
+ i = r.nextInt(6) + 1;
+ y = r.nextInt(6) + 1;
+ final int total = i + y;
+
+ bot.action(
+ "rolled two dice: " + Utils.bold(i) + " and " + Utils.bold(y) + " for a total of " + Utils.bold(total));
+
+ if (playerTotal < total)
+ {
+ bot.action("wins.");
+ }
+ else if (playerTotal > total)
+ {
+ bot.action("lost.");
+ }
+ else
+ {
+ bot.action("tied.");
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/net/thauvin/erik/mobibot/EntriesMgr.java b/src/main/java/net/thauvin/erik/mobibot/EntriesMgr.java
new file mode 100644
index 0000000..a3add76
--- /dev/null
+++ b/src/main/java/net/thauvin/erik/mobibot/EntriesMgr.java
@@ -0,0 +1,384 @@
+/*
+ * @(#)EntriesMgr.java
+ *
+ * Copyright (c) 2004-2014, Erik C. Thauvin (erik@thauvin.net)
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the author nor the names of its contributors may be
+ * used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package net.thauvin.erik.mobibot;
+
+import com.sun.syndication.feed.synd.*;
+import com.sun.syndication.io.FeedException;
+import com.sun.syndication.io.SyndFeedInput;
+import com.sun.syndication.io.SyndFeedOutput;
+
+import java.io.*;
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.List;
+
+/**
+ * Manages the feed entries.
+ *
+ * @author Erik C. Thauvin
+ * @created 2014-04-28
+ * @since 1.0
+ */
+public class EntriesMgr
+{
+ /**
+ * The name of the file containing the current entries.
+ */
+ public static final String CURRENT_XML = "current.xml";
+
+ /**
+ * The name of the file containing the backlog entries.
+ */
+ public static final String NAV_XML = "nav.xml";
+
+ /**
+ * The maximum number of backlogs to keep.
+ */
+ private static final int MAX_BACKLOGS = 10;
+
+ /**
+ * Disables the default constructor.
+ *
+ * @throws UnsupportedOperationException if an error occurred. if the constructor is called.
+ */
+ private EntriesMgr()
+ throws UnsupportedOperationException
+ {
+ throw new UnsupportedOperationException("Illegal constructor call.");
+ }
+
+ /**
+ * Loads the current entries.
+ *
+ * @param file The file containing the current entries.
+ * @param channel The channel
+ * @param entries The entries.
+ *
+ * @return The feed's last published date.
+ *
+ * @throws java.io.FileNotFoundException If the file was not found.
+ * @throws com.sun.syndication.io.FeedException If an error occurred while reading the feed.
+ */
+ @SuppressWarnings("unchecked")
+ public static String loadEntries(String file, String channel, List entries)
+ throws FileNotFoundException, FeedException
+ {
+ entries.clear();
+
+ final SyndFeedInput input = new SyndFeedInput();
+
+ String today;
+ InputStreamReader reader = null;
+
+ try
+ {
+ reader = new InputStreamReader(new FileInputStream(new File(file)));
+
+ final SyndFeed feed = input.build(reader);
+
+ today = Utils.ISO_SDF.format(feed.getPublishedDate());
+
+ final List items = feed.getEntries();
+ SyndEntry item;
+ SyndContent description;
+ String[] comments;
+ String author;
+ EntryLink entry;
+
+ for (int i = items.size() - 1; i >= 0; i--)
+ {
+ item = (SyndEntryImpl) items.get(i);
+ author = item.getAuthor()
+ .substring(item.getAuthor().lastIndexOf('(') + 1, item.getAuthor().length() - 1);
+ entry = new EntryLink(item.getLink(),
+ item.getTitle(),
+ author,
+ channel,
+ item.getPublishedDate(),
+ item.getCategories());
+ description = item.getDescription();
+ comments = description.getValue().split(" ");
+
+ int split;
+ for (final String comment : comments)
+ {
+ split = comment.indexOf(": ");
+
+ if (split != -1)
+ {
+ entry.addComment(comment.substring(split + 2).trim(), comment.substring(0, split).trim());
+ }
+ }
+
+ entries.add(entry);
+ }
+ }
+ finally
+ {
+ if (reader != null)
+ {
+ try
+ {
+ reader.close();
+ }
+ catch (IOException ignore)
+ {
+ ; // Do nothing
+ }
+ }
+ }
+
+ return today;
+ }
+
+ /**
+ * Loads the backlogs.
+ *
+ * @param file The file containing the backlogs.
+ * @param history The history list.
+ *
+ * @throws FileNotFoundException If the file was not found.
+ * @throws FeedException If an error occurred while reading the feed.
+ */
+ public static void loadBacklogs(String file, List history)
+ throws FileNotFoundException, FeedException
+ {
+ history.clear();
+
+ final SyndFeedInput input = new SyndFeedInput();
+
+ InputStreamReader reader = null;
+
+ try
+ {
+ reader = new InputStreamReader(new FileInputStream(new File(file)));
+
+ final SyndFeed feed = input.build(reader);
+
+ final List items = feed.getEntries();
+ SyndEntry item;
+
+ for (int i = items.size() - 1; i >= 0; i--)
+ {
+ item = (SyndEntryImpl) items.get(i);
+ history.add(item.getTitle());
+ }
+ }
+ finally
+ {
+ if (reader != null)
+ {
+ try
+ {
+ reader.close();
+ }
+ catch (IOException ignore)
+ {
+ ; // Do nothing
+ }
+ }
+ }
+ }
+
+ /**
+ * Saves the entries.
+ *
+ * @param isDayBackup Set the true if the daily backup file should also be created.
+ */
+ public static void saveEntries(Mobibot bot, List entries, List history, boolean isDayBackup)
+ {
+ if (bot.getLogger().isDebugEnabled())
+ {
+ bot.getLogger().debug("Saving...");
+ }
+
+ if (Utils.isValidString(bot.getLogsDir()) && Utils.isValidString(bot.getWeblogUrl()))
+ {
+ FileWriter fw = null;
+
+ try
+ {
+ fw = new FileWriter(new File(bot.getLogsDir() + CURRENT_XML));
+
+ SyndFeed rss = new SyndFeedImpl();
+ rss.setFeedType("rss_2.0");
+ rss.setTitle(bot.getChannel() + " IRC Links");
+ rss.setDescription("Links from " + bot.getIrcServer() + " on " + bot.getChannel());
+ rss.setLink(bot.getWeblogUrl());
+ rss.setPublishedDate(Calendar.getInstance().getTime());
+ rss.setLanguage("en");
+
+ EntryLink entry;
+ StringBuffer buff;
+ EntryComment comment;
+ final List items = new ArrayList(0);
+ SyndEntry item;
+ SyndContent description;
+
+ for (int i = (entries.size() - 1); i >= 0; --i)
+ {
+ entry = entries.get(i);
+
+ buff = new StringBuffer(
+ "Posted by " + entry.getNick() + " on " + entry.getChannel() + ""
+ );
+
+ if (entry.getCommentsCount() > 0)
+ {
+ buff.append("
");
+
+ final EntryComment[] comments = entry.getComments();
+
+ for (int j = 0; j < comments.length; j++)
+ {
+ comment = comments[j];
+
+ if (j > 0)
+ {
+ buff.append(" ");
+ }
+
+ buff.append(comment.getNick()).append(": ").append(comment.getComment());
+ }
+ }
+
+ item = new SyndEntryImpl();
+ item.setLink(entry.getLink());
+ description = new SyndContentImpl();
+ description.setValue(buff.toString());
+ item.setDescription(description);
+ item.setTitle(entry.getTitle());
+ item.setPublishedDate(entry.getDate());
+ item.setAuthor(
+ bot.getChannel().substring(1) + '@' + bot.getIrcServer() + " (" + entry.getNick() + ')');
+ item.setCategories(entry.getTags());
+
+ items.add(item);
+ }
+
+ rss.setEntries(items);
+
+ if (bot.getLogger().isDebugEnabled())
+ {
+ bot.getLogger().debug("Writing the entries feed.");
+ }
+
+ final SyndFeedOutput output = new SyndFeedOutput();
+ output.output(rss, fw);
+ fw.close();
+
+ fw = new FileWriter(new File(bot.getLogsDir() + bot.getToday() + ".xml"));
+ output.output(rss, fw);
+
+ if (isDayBackup)
+ {
+ if (Utils.isValidString(bot.getBacklogsUrl()))
+ {
+ if (history.indexOf(bot.getToday()) == -1)
+ {
+ history.add(bot.getToday());
+
+ while (history.size() > MAX_BACKLOGS)
+ {
+ history.remove(0);
+ }
+ }
+
+ fw.close();
+ fw = new FileWriter(new File(bot.getLogsDir() + NAV_XML));
+ rss = new SyndFeedImpl();
+ rss.setFeedType("rss_2.0");
+ rss.setTitle(bot.getChannel() + " IRC Links Backlogs");
+ rss.setDescription("Backlogs of Links from " + bot.getIrcServer() + " on " + bot.getChannel());
+ rss.setLink(bot.getBacklogsUrl());
+ rss.setPublishedDate(Calendar.getInstance().getTime());
+
+ String date;
+ items.clear();
+
+ for (int i = (history.size() - 1); i >= 0; --i)
+ {
+ date = history.get(i);
+
+ item = new SyndEntryImpl();
+ item.setLink(bot.getBacklogsUrl() + date + ".xml");
+ item.setTitle(date);
+ description = new SyndContentImpl();
+ description.setValue("Links for " + date);
+ item.setDescription(description);
+
+ items.add(item);
+ }
+
+ rss.setEntries(items);
+
+ if (bot.getLogger().isDebugEnabled())
+ {
+ bot.getLogger().debug("Writing the backlog feed.");
+ }
+
+ output.output(rss, fw);
+ }
+ else
+ {
+ bot.getLogger().warn("Unable to generate the backlogs feed. No property configured.");
+ }
+ }
+ }
+ catch (Exception e)
+ {
+ bot.getLogger().warn("Unable to generate the feed.", e);
+ }
+ finally
+ {
+ try
+ {
+ if (fw != null)
+ {
+ fw.close();
+ }
+ }
+ catch (Exception ignore)
+ {
+ ; // Do nothing
+ }
+ }
+ }
+ else
+ {
+ bot.getLogger().warn("Unable to generate the feed. At least one of the required property is missing.");
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/net/thauvin/erik/mobibot/EntryComment.java b/src/main/java/net/thauvin/erik/mobibot/EntryComment.java
index c071e74..4c12789 100644
--- a/src/main/java/net/thauvin/erik/mobibot/EntryComment.java
+++ b/src/main/java/net/thauvin/erik/mobibot/EntryComment.java
@@ -1,7 +1,7 @@
/*
* @(#)EntryComment.java
*
- * Copyright (c) 2004, Erik C. Thauvin (erik@thauvin.net)
+ * Copyright (c) 2004-2014, Erik C. Thauvin (erik@thauvin.net)
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -30,10 +30,8 @@
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * $Id$
- *
*/
+
package net.thauvin.erik.mobibot;
import java.io.Serializable;
@@ -44,7 +42,6 @@ import java.util.Date;
* The class used to store comments associated to a specific entry.
*
* @author Erik C. Thauvin
- * @version $Revision$, $Date$
* @created Jan 31, 2004
* @since 1.0
*/
@@ -80,6 +77,7 @@ public class EntryComment implements Serializable
/**
* Creates a new comment.
+ *
* @noinspection UnusedDeclaration
*/
protected EntryComment()
@@ -101,6 +99,7 @@ public class EntryComment implements Serializable
* Sets the comment.
*
* @param comment The actual comment.
+ *
* @noinspection UnusedDeclaration
*/
public final void setComment(String comment)
diff --git a/src/main/java/net/thauvin/erik/mobibot/EntryLink.java b/src/main/java/net/thauvin/erik/mobibot/EntryLink.java
index 5afd312..2b737cf 100644
--- a/src/main/java/net/thauvin/erik/mobibot/EntryLink.java
+++ b/src/main/java/net/thauvin/erik/mobibot/EntryLink.java
@@ -1,7 +1,7 @@
/*
* @(#)EntryLink.java
*
- * Copyright (c) 2004, Erik C. Thauvin (erik@thauvin.net)
+ * Copyright (c) 2004-2014, Erik C. Thauvin (erik@thauvin.net)
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -30,10 +30,8 @@
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * $Id$
- *
*/
+
package net.thauvin.erik.mobibot;
import com.sun.syndication.feed.synd.SyndCategoryImpl;
@@ -48,7 +46,6 @@ import java.util.List;
* The class used to store link entries.
*
* @author Erik C. Thauvin
- * @version $Revision$, $Date$
* @created Jan 31, 2004
* @since 1.0
*/
@@ -106,6 +103,61 @@ public class EntryLink implements Serializable
setTags(tags);
}
+ /**
+ * Sets the tags.
+ *
+ * @param tags The space-delimited tags.
+ */
+ public final synchronized void setTags(String tags)
+ {
+ if (tags != null)
+ {
+ final String[] parts = tags.replaceAll(", ", " ").replaceAll(",", " ").split(" ");
+
+ SyndCategoryImpl tag;
+ String part;
+ char mod;
+
+ for (final String rawPart : parts)
+ {
+ part = rawPart.trim();
+
+ if (part.length() >= 2)
+ {
+ tag = new SyndCategoryImpl();
+ tag.setName(part.substring(1).toLowerCase());
+
+ mod = part.charAt(0);
+
+ if (mod == '-')
+ {
+ // Don't remove the channel tag, if any.
+ if (!tag.getName().equals(channel.substring(1)))
+ {
+ this.tags.remove(tag);
+ }
+ }
+ else if (mod == '+')
+ {
+ if (!this.tags.contains(tag))
+ {
+ this.tags.add(tag);
+ }
+ }
+ else
+ {
+ tag.setName(part.trim().toLowerCase());
+
+ if (!this.tags.contains(tag))
+ {
+ this.tags.add(tag);
+ }
+ }
+ }
+ }
+ }
+ }
+
/**
* Creates a new entry.
*
@@ -129,6 +181,7 @@ public class EntryLink implements Serializable
/**
* Creates a new EntryLink object.
+ *
* @noinspection UnusedDeclaration
*/
protected EntryLink()
@@ -178,6 +231,7 @@ public class EntryLink implements Serializable
* Sets the channel.
*
* @param channel The channel.
+ *
* @noinspection UnusedDeclaration
*/
public final synchronized void setChannel(String channel)
@@ -279,6 +333,7 @@ public class EntryLink implements Serializable
* Set the comment's author login.
*
* @param login The new login.
+ *
* @noinspection UnusedDeclaration
*/
public final synchronized void setLogin(String login)
@@ -319,56 +374,11 @@ public class EntryLink implements Serializable
/**
* Sets the tags.
*
- * @param tags The space-delimited tags.
+ * @param tags The tags.
*/
- public final synchronized void setTags(String tags)
+ final synchronized void setTags(List tags)
{
- if (tags != null)
- {
- final String[] parts = tags.replaceAll(", ", " ").replaceAll(",", " ").split(" ");
-
- SyndCategoryImpl tag;
- String part;
- char mod;
-
- for (final String rawPart : parts)
- {
- part = rawPart.trim();
-
- if (part.length() >= 2)
- {
- tag = new SyndCategoryImpl();
- tag.setName(part.substring(1).toLowerCase());
-
- mod = part.charAt(0);
-
- if (mod == '-')
- {
- // Don't remove the channel tag, if any.
- if (!tag.getName().equals(channel.substring(1)))
- {
- this.tags.remove(tag);
- }
- }
- else if (mod == '+')
- {
- if (!this.tags.contains(tag))
- {
- this.tags.add(tag);
- }
- }
- else
- {
- tag.setName(part.trim().toLowerCase());
-
- if (!this.tags.contains(tag))
- {
- this.tags.add(tag);
- }
- }
- }
- }
- }
+ this.tags.addAll(tags);
}
/**
@@ -426,16 +436,6 @@ public class EntryLink implements Serializable
}
}
- /**
- * Sets the tags.
- *
- * @param tags The tags.
- */
- public final synchronized void setTags(List tags)
- {
- this.tags.addAll(tags);
- }
-
/**
* Returns a string representation of the object.
*
@@ -444,8 +444,8 @@ public class EntryLink implements Serializable
public final String toString()
{
- return super.toString() + "[ channel -> '" + channel + '\'' + ", comments -> " + comments + ", date -> "
- + date + ", link -> '" + link + '\'' + ", login -> '" + login + '\'' + ", nick -> '" + nick + '\''
+ return super.toString() + "[ channel -> '" + channel + '\'' + ", comments -> " + comments + ", date -> " + date
+ + ", link -> '" + link + '\'' + ", login -> '" + login + '\'' + ", nick -> '" + nick + '\''
+ ", tags -> " + tags + ", title -> '" + title + '\'' + " ]";
}
}
diff --git a/src/main/java/net/thauvin/erik/mobibot/FeedReader.java b/src/main/java/net/thauvin/erik/mobibot/FeedReader.java
index bfd3197..adbcdda 100644
--- a/src/main/java/net/thauvin/erik/mobibot/FeedReader.java
+++ b/src/main/java/net/thauvin/erik/mobibot/FeedReader.java
@@ -1,7 +1,7 @@
/*
* @(#)FeedReader.java
*
- * Copyright (c) 2004, Erik C. Thauvin (erik@thauvin.net)
+ * Copyright (c) 2004-2014, Erik C. Thauvin (erik@thauvin.net)
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -30,10 +30,8 @@
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * $Id$
- *
*/
+
package net.thauvin.erik.mobibot;
import com.sun.syndication.feed.synd.SyndEntry;
@@ -50,7 +48,6 @@ import java.util.List;
* Reads a RSS feed.
*
* @author Erik C. Thauvin
- * @version $Revision$, $Date$
* @created Feb 1, 2004
* @since 1.0
*/
diff --git a/src/main/java/net/thauvin/erik/mobibot/GoogleSearch.java b/src/main/java/net/thauvin/erik/mobibot/GoogleSearch.java
index ad73726..190a232 100644
--- a/src/main/java/net/thauvin/erik/mobibot/GoogleSearch.java
+++ b/src/main/java/net/thauvin/erik/mobibot/GoogleSearch.java
@@ -1,7 +1,7 @@
/*
* @(#)GoogleSearch.java
*
- * Copyright (c) 2004, Erik C. Thauvin (erik@thauvin.net)
+ * Copyright (c) 2004-2014, Erik C. Thauvin (erik@thauvin.net)
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -30,12 +30,9 @@
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * $Id$
- *
*/
-package net.thauvin.erik.mobibot;
+package net.thauvin.erik.mobibot;
import org.json.JSONArray;
import org.json.JSONObject;
@@ -50,7 +47,6 @@ import java.net.URLEncoder;
* Performs a Google search or spell checking query.
*
* @author Erik C. Thauvin
- * @version $Revision$, $Date$
* @created Feb 7, 2004
* @since 1.0
*/
@@ -95,7 +91,6 @@ public class GoogleSearch implements Runnable
*/
public final void run()
{
-
try
{
final String query = URLEncoder.encode(this.query, "UTF-8");
@@ -119,12 +114,11 @@ public class GoogleSearch implements Runnable
for (int i = 0; i < ja.length(); i++)
{
final JSONObject j = ja.getJSONObject(i);
- bot.send(sender, Mobibot.unescapeXml(j.getString("titleNoFormatting")));
+ bot.send(sender, Utils.unescapeXml(j.getString("titleNoFormatting")));
bot.send(sender, TAB_INDENT + j.getString("url"));
}
reader.close();
-
}
catch (Exception e)
{
diff --git a/src/main/java/net/thauvin/erik/mobibot/Lookup.java b/src/main/java/net/thauvin/erik/mobibot/Lookup.java
new file mode 100644
index 0000000..43884ec
--- /dev/null
+++ b/src/main/java/net/thauvin/erik/mobibot/Lookup.java
@@ -0,0 +1,162 @@
+/*
+ * @(#)Lookup.java
+ *
+ * Copyright (c) 2004-2014, Erik C. Thauvin (erik@thauvin.net)
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the author nor the names of its contributors may be
+ * used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package net.thauvin.erik.mobibot;
+
+import org.apache.commons.net.WhoisClient;
+
+import java.io.IOException;
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+
+/**
+ * Performs a DNS lookup query.
+ *
+ * @author Erik C. Thauvin
+ * @created 2014-04-26
+ * @since 1.0
+ */
+public class Lookup
+{
+
+ /**
+ * The whois host.
+ */
+ @SuppressWarnings("WeakerAccess")
+ public static final String WHOIS_HOST = "whois.arin.net";
+
+ /**
+ * Disables the default constructor.
+ *
+ * @throws UnsupportedOperationException if an error occurred. if the constructor is called.
+ */
+ private Lookup()
+ throws UnsupportedOperationException
+ {
+ throw new UnsupportedOperationException("Illegal constructor call.");
+ }
+
+ /**
+ * Performs a DNS lookup on the specified query.
+ *
+ * @param query The IP address or hostname.
+ *
+ * @return The lookup query result string.
+ *
+ * @throws java.net.UnknownHostException If the host is unknown.
+ */
+ public static String lookup(String query)
+ throws UnknownHostException
+ {
+ final StringBuilder buffer = new StringBuilder("");
+
+ final InetAddress[] results = InetAddress.getAllByName(query);
+ String hostInfo;
+
+ for (final InetAddress result : results)
+ {
+ if (result.getHostAddress().equals(query))
+ {
+ hostInfo = result.getHostName();
+
+ if (hostInfo.equals(query))
+ {
+ throw new UnknownHostException();
+ }
+ }
+ else
+ {
+ hostInfo = result.getHostAddress();
+ }
+
+ if (buffer.length() > 0)
+ {
+ buffer.append(", ");
+ }
+
+ buffer.append(hostInfo);
+ }
+
+ return buffer.toString();
+ }
+
+ /**
+ * Performs a whois IP query.
+ *
+ * @param query The IP address.
+ *
+ * @return The IP whois data, if any.
+ *
+ * @throws java.io.IOException If a connection error occurs.
+ */
+ public static String[] whois(String query)
+ throws IOException
+ {
+ return whois(query, WHOIS_HOST);
+ }
+
+ /**
+ * Performs a whois IP query.
+ *
+ * @param query The IP address.
+ * @param host The whois host.
+ *
+ * @return The IP whois data, if any.
+ *
+ * @throws java.io.IOException If a connection error occurs.
+ */
+ @SuppressWarnings("WeakerAccess, SameParameterValue")
+ public static String[] whois(String query, String host)
+ throws IOException
+ {
+ final WhoisClient whois = new WhoisClient();
+ String[] lines;
+
+ try
+ {
+ whois.setDefaultTimeout(Mobibot.CONNECT_TIMEOUT);
+ whois.connect(host);
+ whois.setSoTimeout(Mobibot.CONNECT_TIMEOUT);
+ whois.setSoLinger(false, 0);
+
+ lines = whois.query('-' + query).split("\n");
+ }
+ finally
+ {
+ whois.disconnect();
+ }
+
+ return lines;
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/net/thauvin/erik/mobibot/Mobibot.java b/src/main/java/net/thauvin/erik/mobibot/Mobibot.java
index 4a8a14d..97405a5 100644
--- a/src/main/java/net/thauvin/erik/mobibot/Mobibot.java
+++ b/src/main/java/net/thauvin/erik/mobibot/Mobibot.java
@@ -1,7 +1,7 @@
/*
* @(#)Mobibot.java
*
- * Copyright (c) 2004, Erik C. Thauvin (erik@thauvin.net)
+ * Copyright (c) 2004-2014, Erik C. Thauvin (erik@thauvin.net)
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -30,23 +30,16 @@
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * $Id$
- *
*/
package net.thauvin.erik.mobibot;
-import com.sun.syndication.feed.synd.*;
import com.sun.syndication.fetcher.impl.FeedFetcherCache;
import com.sun.syndication.fetcher.impl.HashMapFeedInfoCache;
import com.sun.syndication.io.FeedException;
-import com.sun.syndication.io.SyndFeedInput;
-import com.sun.syndication.io.SyndFeedOutput;
import de.congrace.exp4j.Calculable;
import de.congrace.exp4j.ExpressionBuilder;
import org.apache.commons.cli.*;
import org.apache.commons.logging.impl.Log4JLogger;
-import org.apache.commons.net.WhoisClient;
import org.apache.log4j.Level;
import org.jibble.pircbot.Colors;
import org.jibble.pircbot.PircBot;
@@ -55,18 +48,14 @@ import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import java.io.*;
-import java.net.InetAddress;
import java.net.UnknownHostException;
-import java.nio.channels.FileChannel;
import java.text.DecimalFormat;
-import java.text.SimpleDateFormat;
import java.util.*;
/**
* Implements the #mobitopia bot.
*
* @author Erik C. Thauvin
- * @version $Revision$, $Date$
* @created Jan 31, 2004
* @since 1.0
*/
@@ -78,32 +67,14 @@ public class Mobibot extends PircBot
public static final int CONNECT_TIMEOUT = 5000;
/**
- * The currency command.
+ * The serialized object file extension.
*/
- public static final String CURRENCY_CMD = "currency";
+ private static final String SER_EXT = ".ser";
/**
- * The weather command.
+ * Shall we play a game?
*/
- public static final String WEATHER_CMD = "weather";
-
- /**
- * The HH:MM timestamp simple date format.
- */
- private static final SimpleDateFormat HHMM_SDF = new SimpleDateFormat("HH:mm z");
-
- /**
- * Initialize {@link #HHMM_SDF timestamp}
- */
- static
- {
- HHMM_SDF.setTimeZone(TimeZone.getTimeZone("UTC"));
- }
-
- /**
- * The ISO (YYYY-MM-DD) simple date format.
- */
- private static final SimpleDateFormat ISO_SDF = new SimpleDateFormat("yyyy-MM-dd");
+ private static final String shall_we_play_a_game = "Shall we play a game?";
/**
* The info strings.
@@ -117,7 +88,7 @@ public class Mobibot extends PircBot
* The version strings.
*/
private static final String[] VERSION_STRS = {
- "Version: " + ReleaseInfo.getVersion() + '.' + ReleaseInfo.getBuildNumber() + " (" + ISO_SDF
+ "Version: " + ReleaseInfo.getVersion() + '.' + ReleaseInfo.getBuildNumber() + " (" + Utils.ISO_SDF
.format(ReleaseInfo.getBuildDate()) + ')',
"Platform: " + System.getProperty("os.name") + " (" + System.getProperty("os.version") + ", " + System
.getProperty("os.arch") + ", " + System.getProperty("user.country") + ')',
@@ -127,26 +98,6 @@ public class Mobibot extends PircBot
+ System.getProperty("java.vm.info") + ')'
};
- /**
- * Debug command line argument.
- */
- private static final String DEBUG_ARG = "debug";
-
- /**
- * Help command line argument.
- */
- private static final String HELP_ARG = "help";
-
- /**
- * Properties command line argument.
- */
- private static final String PROPS_ARG = "properties";
-
- /**
- * Properties version line argument.
- */
- private static final String VERSION_ARG = "version";
-
/**
* The maximum number of times the bot will try to reconnect, if disconnected.
*/
@@ -162,156 +113,16 @@ public class Mobibot extends PircBot
*/
private static final int MAX_RECAP = 10;
- /**
- * The recap array.
- */
- private static final List RECAP_ARRAY = new ArrayList(MAX_RECAP);
-
- /**
- * The maximum number of backlogs to keep.
- */
- private static final int MAX_BACKLOGS = 10;
-
/**
* The double tab indent (8 spaces).
*/
private static final String DOUBLE_INDENT = " ";
- /**
- * The add (back)log command.
- */
- private static final String ADDLOG_CMD = "addlog";
-
- /**
- * The debug command.
- */
- private static final String DEBUG_CMD = "debug";
-
- /**
- * The dices command.
- */
- private static final String DICE_CMD = "dice";
-
- /**
- * The say command.
- */
- private static final String SAY_CMD = "say";
-
- /**
- * The die command.
- */
- private static final String DIE_CMD = "die";
-
- /**
- * The cycle command.
- */
- private static final String CYCLE_CMD = "cycle";
-
- /**
- * The msg command.
- */
- private static final String MSG_CMD = "msg";
-
- /**
- * The ignore command.
- */
- private static final String IGNORE_CMD = "ignore";
-
- /**
- * The ignore me keyword.
- */
- private static final String IGNORE_ME_KEYWORD = "me";
-
- /**
- * The help command.
- */
- private static final String HELP_CMD = "help";
-
- /**
- * The help on posting keyword.
- */
- private static final String HELP_POSTING_KEYWORD = "posting";
-
- /**
- * The help on tags keyword.
- */
- private static final String HELP_TAGS_KEYWORD = "tags";
-
- /**
- * The Google command.
- */
- private static final String GOOGLE_CMD = "google";
-
- /**
- * The Twitter command.
- */
- private static final String TWITTER_CMD = "twitter";
-
- /**
- * The math command.
- */
- private static final String CALC_CMD = "calc";
-
- /**
- * The me command.
- */
- private static final String ME_CMD = "me";
-
- /**
- * The nick command.
- */
- private static final String NICK_CMD = "nick";
-
- /**
- * The link command.
- */
- private static final String LINK_CMD = "L";
-
/**
* The link match string.
*/
private static final String LINK_MATCH = "^[hH][tT][tT][pP](|[sS])://.*";
- /**
- * The lookup command.
- */
- private static final String LOOKUP_CMD = "lookup";
-
- /**
- * The ping command.
- */
- private static final String PING_CMD = "ping";
-
- /**
- * The pong command.
- */
- private static final String PONG_CMD = "pong";
-
- /**
- * The quote command.
- */
- private static final String QUOTE_CMD = "quote";
-
- /**
- * The recap command.
- */
- private static final String RECAP_CMD = "recap";
-
- /**
- * The stock command.
- */
- private static final String STOCK_CMD = "stock";
-
- /**
- * The time command.
- */
- private static final String TIME_CMD = "time";
-
- /**
- * The war command.
- */
- private static final String WAR_CMD = "war";
-
/**
* The empty title string.
*/
@@ -322,53 +133,6 @@ public class Mobibot extends PircBot
*/
private static final String TAGS_MARKER = "tags:";
- /**
- * The countries supported by the {@link #TIME_CMD time} command.
- */
- private static final Map COUNTRIES_MAP = new TreeMap();
-
- /**
- * The deck of card for the {@link #WAR_CMD war} command.
- */
- private static final String[] WAR_DECK =
- new String[]{"Ace", "King", "Queen", "Jack", "10", "9", "8", "7", "6", "5", "4", "3", "2"};
-
- /**
- * The suits for the deck of card for the {@link #WAR_CMD war} command.
- */
- private static final String[] WAR_SUITS = new String[]{"Hearts", "Spades", "Diamonds", "Clubs"};
-
- /**
- * The date/time format for the {@link #TIME_CMD time} command.
- */
- private static final SimpleDateFormat TIME_SDF =
- new SimpleDateFormat("'The time is 'HH:mm' on 'EEE, d MMM yyyy' in '");
-
- /**
- * The beats (Internet Time) keyword.
- */
- private static final String BEATS_KEYWORD = ".beats";
-
- /**
- * The users command.
- */
- private static final String USERS_CMD = "users";
-
- /**
- * The info command.
- */
- private static final String INFO_CMD = "info";
-
- /**
- * The version command.
- */
- private static final String VERSION_CMD = "version";
-
- /**
- * The view command.
- */
- private static final String VIEW_CMD = "view";
-
/**
* The start time.
*/
@@ -379,25 +143,41 @@ public class Mobibot extends PircBot
*/
private static final int DEFAULT_PORT = 6667;
- /**
- * The whois host.
- */
- private static final String WHOIS_HOST = "whois.arin.net";
-
/**
* The number of milliseconds to delay between consecutive messages.
*/
private static final long MESSAGE_DELAY = 1000L;
/**
- * The name of the file containing the current entries.
+ * The default maximum number of days to keep {@link Commands#TELL_CMD} messages.
*/
- private static final String CURRENT_XML = "current.xml";
+
+ private static final int DEFAULT_TELL_MAX_DAYS = 7;
/**
- * The name of the file containing the backlog entries.
+ * The number of days message are kept.
*/
- private static final String NAV_XML = "nav.xml";
+ private int tellMaxDays = DEFAULT_TELL_MAX_DAYS;
+
+ /**
+ * The default {@link Commands#TELL_CMD) message max queue size.
+ */
+ private static final int DEFAULT_TELL_MAX_SIZE = 50;
+
+ /**
+ * The maximum number of {@link Commands#TELL_CMD} messages allowed.
+ */
+ private int tellMaxSize = DEFAULT_TELL_MAX_SIZE;
+
+ /**
+ * The recap array.
+ */
+ private final List recap = new ArrayList(0);
+
+ /**
+ * The {@link Commands#TELL_CMD} messages queue.
+ */
+ private final List tellMessages = new ArrayList(0);
/**
* The main channel.
@@ -434,6 +214,11 @@ public class Mobibot extends PircBot
*/
private final String ircServer;
+ /**
+ * The currency converter.
+ */
+ private final CurrencyConverter currencyConverter;
+
/**
* The logger.
*/
@@ -449,10 +234,20 @@ public class Mobibot extends PircBot
*/
private final String logsDir;
+ /**
+ * The serialized object file.
+ */
+ private final String serializedObject;
+
+ /**
+ * Time command.
+ */
+ private final WorldTime worldTime = new WorldTime();
+
/**
* The backlogs URL.
*/
- private String backlogsURL = "";
+ private String backLogsUrl = "";
/**
* The default tags/categories.
@@ -507,96 +302,52 @@ public class Mobibot extends PircBot
/**
* Today's date.
*/
- private String today = today();
+ private String today = Utils.today();
/**
* The weblog URL.
*/
- private String weblogURL = "";
-
- /**
- * Initialize the countries.
- */
- static
- {
- COUNTRIES_MAP.put("AU", "Australia/Sydney");
- COUNTRIES_MAP.put("BE", "Europe/Brussels");
- COUNTRIES_MAP.put("CA", "America/Montreal");
- COUNTRIES_MAP.put("CH", "Europe/Zurich");
- COUNTRIES_MAP.put("CN", "Asia/Shanghai");
- COUNTRIES_MAP.put("DE", "Europe/Berlin");
- COUNTRIES_MAP.put("DK", "Europe/Copenhagen");
- COUNTRIES_MAP.put("ES", "Europe/Madrid");
- COUNTRIES_MAP.put("FI", "Europe/Helsinki");
- COUNTRIES_MAP.put("FR", "Europe/Paris");
- COUNTRIES_MAP.put("GB", "Europe/London");
- COUNTRIES_MAP.put("HK", "Asia/Hong_Kong");
- COUNTRIES_MAP.put("IE", "Europe/Dublin");
- COUNTRIES_MAP.put("IL", "Israel");
- COUNTRIES_MAP.put("IN", "Asia/Calcutta");
- COUNTRIES_MAP.put("IS", "Iceland");
- COUNTRIES_MAP.put("IT", "Europe/Rome");
- COUNTRIES_MAP.put("JP", "Asia/Tokyo");
- COUNTRIES_MAP.put("MX", "Mexico/Mexico_City");
- COUNTRIES_MAP.put("NL", "Europe/Amsterdam");
- COUNTRIES_MAP.put("NO", "Europe/Oslo");
- COUNTRIES_MAP.put("NZ", "Pacific/Auckland");
- COUNTRIES_MAP.put("PK", "Asia/Karachi");
- COUNTRIES_MAP.put("RU", "Europe/Moscow");
- COUNTRIES_MAP.put("SE", "Europe/Stockholm");
- COUNTRIES_MAP.put("SG", "Asia/Singapore");
- COUNTRIES_MAP.put("SU", "Europe/Moscow");
- COUNTRIES_MAP.put("TH", "Asia/Bangkok");
- COUNTRIES_MAP.put("TW", "Asia/Taipei");
- COUNTRIES_MAP.put("UK", "Europe/London");
- COUNTRIES_MAP.put("US", "America/New_York");
- COUNTRIES_MAP.put("EST", "America/New_York");
- COUNTRIES_MAP.put("CST", "America/Chicago");
- COUNTRIES_MAP.put("MST", "America/Denver");
- COUNTRIES_MAP.put("PST", "America/Los_Angeles");
- COUNTRIES_MAP.put("EDT", "America/New_York");
- COUNTRIES_MAP.put("CDT", "America/Chicago");
- COUNTRIES_MAP.put("MDT", "America/Denver");
- COUNTRIES_MAP.put("PDT", "America/Los_Angeles");
- COUNTRIES_MAP.put("CET", "CET");
- COUNTRIES_MAP.put("GMT", "GMT");
- COUNTRIES_MAP.put("HST", "HST");
- COUNTRIES_MAP.put("UTC", "UTC");
- COUNTRIES_MAP.put("INTERNET", BEATS_KEYWORD);
- COUNTRIES_MAP.put("BEATS", BEATS_KEYWORD);
- }
+ private String weblogUrl = "";
/**
* Creates a new Mobibot object.
*
* @param server The server.
* @param port The port.
+ * @param nickname The nickname.
* @param channel The channel.
* @param logsDir The logs directory.
*/
- public Mobibot(String server, int port, String channel, String logsDir)
+ public Mobibot(String server, int port, String nickname, String channel, String logsDir)
{
System.getProperties().setProperty("sun.net.client.defaultConnectTimeout", String.valueOf(CONNECT_TIMEOUT));
System.getProperties().setProperty("sun.net.client.defaultReadTimeout", String.valueOf(CONNECT_TIMEOUT));
+ setName(nickname);
+
ircServer = server;
ircPort = port;
this.channel = channel;
this.logsDir = logsDir;
+ this.serializedObject = logsDir + getName() + SER_EXT;
// Set the logger
logger = new Log4JLogger(Mobibot.class.getPackage().getName());
loggerLevel = logger.getLogger().getLevel();
+ // Initialization
+ Utils.UTC_SDF.setTimeZone(TimeZone.getTimeZone("UTC"));
+ currencyConverter = new CurrencyConverter(this);
+
// Load the current entries, if any.
try
{
- loadEntries(this.logsDir + CURRENT_XML);
+ today = EntriesMgr.loadEntries(this.logsDir + EntriesMgr.CURRENT_XML, this.channel, entries);
- if (!today().equals(today))
+ if (!Utils.today().equals(today))
{
entries.clear();
- today = today();
+ today = Utils.today();
}
}
catch (FileNotFoundException ignore)
@@ -605,13 +356,13 @@ public class Mobibot extends PircBot
}
catch (FeedException e)
{
- logger.error("An error occurred while parsing the '" + CURRENT_XML + "' file.", e);
+ logger.error("An error occurred while parsing the '" + EntriesMgr.CURRENT_XML + "' file.", e);
}
// Load the backlogs, if any.
try
{
- loadBacklogs(this.logsDir + NAV_XML);
+ EntriesMgr.loadBacklogs(this.logsDir + EntriesMgr.NAV_XML, history);
}
catch (FileNotFoundException ignore)
{
@@ -619,42 +370,30 @@ public class Mobibot extends PircBot
}
catch (FeedException e)
{
- logger.error("An error occurred while parsing the '" + NAV_XML + "' file.", e);
+ logger.error("An error occurred while parsing the '" + EntriesMgr.NAV_XML + "' file.", e);
}
}
- /**
- * Returns true if the given string is valid.
- *
- * @param s The string to validate.
- *
- * @return true if the string is non-empty and not null, false otherwise.
- */
- public static boolean isValidString(String s)
- {
- return (s != null) && (s.trim().length() > 0);
- }
-
/**
* The Truth Is Out There...
*
* @param args The command line arguments.
*
- * @noinspection UseOfSystemOutOrSystemErr, ACCESS_STATIC_VIA_INSTANCE
+ * @noinspection UseOfSystemOutOrSystemErr, ACCESS_STATIC_VIA_INSTANCE, unchecked
*/
public static void main(String[] args)
{
// Setup the command line options
final Options options = new Options();
- options.addOption(HELP_ARG.substring(0, 1), HELP_ARG, false, "print this help message");
- options.addOption(DEBUG_ARG.substring(0, 1),
- DEBUG_ARG,
+ options.addOption(Commands.HELP_ARG.substring(0, 1), Commands.HELP_ARG, false, "print this help message");
+ options.addOption(Commands.DEBUG_ARG.substring(0, 1),
+ Commands.DEBUG_ARG,
false,
"print debug & logging data directly to the console");
//noinspection AccessStaticViaInstance
options.addOption(OptionBuilder.withArgName("file").hasArg().withDescription("use alternate properties file")
- .withLongOpt(PROPS_ARG).create(PROPS_ARG.substring(0, 1)));
- options.addOption(VERSION_ARG.substring(0, 1), VERSION_ARG, false, "print version info");
+ .withLongOpt(Commands.PROPS_ARG).create(Commands.PROPS_ARG.substring(0, 1)));
+ options.addOption(Commands.VERSION_ARG.substring(0, 1), Commands.VERSION_ARG, false, "print version info");
// Parse the command line
final CommandLineParser parser = new PosixParser();
@@ -671,12 +410,12 @@ public class Mobibot extends PircBot
System.exit(1);
}
- if (line.hasOption(HELP_ARG.charAt(0)))
+ if (line.hasOption(Commands.HELP_ARG.charAt(0)))
{
// Output the usage
new HelpFormatter().printHelp(Mobibot.class.getName(), options);
}
- else if (line.hasOption(VERSION_ARG.charAt(0)))
+ else if (line.hasOption(Commands.VERSION_ARG.charAt(0)))
{
for (final String s : INFO_STRS)
{
@@ -690,7 +429,8 @@ public class Mobibot extends PircBot
try
{
- fis = new FileInputStream(new File(line.getOptionValue(PROPS_ARG.charAt(0), "./mobibot.properties")));
+ fis = new FileInputStream(new File(line.getOptionValue(Commands.PROPS_ARG.charAt(0),
+ "./mobibot.properties")));
// Load the properties files
p.load(fis);
@@ -725,11 +465,11 @@ public class Mobibot extends PircBot
// Get the main properties
final String channel = p.getProperty("channel");
final String server = p.getProperty("server");
- final int port = getPort(p.getProperty("port", String.valueOf(DEFAULT_PORT)));
+ final int port = Utils.getIntProperty(p.getProperty("port"), DEFAULT_PORT);
final String nickname = p.getProperty("nick", Mobibot.class.getName().toLowerCase());
- final String logsDir = ensureDir(p.getProperty("logs", "."), false);
+ final String logsDir = Utils.ensureDir(p.getProperty("logs", "."), false);
- if (!line.hasOption(DEBUG_ARG.charAt(0)))
+ if (!line.hasOption(Commands.DEBUG_ARG.charAt(0)))
{
// Redirect the stdout and stderr
PrintStream stdout = null;
@@ -737,7 +477,7 @@ public class Mobibot extends PircBot
try
{
stdout = new PrintStream(new FileOutputStream(
- logsDir + channel.substring(1) + '.' + today() + ".log", true));
+ logsDir + channel.substring(1) + '.' + Utils.today() + ".log", true));
}
catch (IOException e)
{
@@ -767,7 +507,7 @@ public class Mobibot extends PircBot
final String login = p.getProperty("login", nickname);
final String weblogURL = p.getProperty("weblog", "");
final String feedURL = p.getProperty("feed", "");
- final String backlogsURL = ensureDir(p.getProperty("backlogs", weblogURL), true);
+ final String backlogsURL = Utils.ensureDir(p.getProperty("backlogs", weblogURL), true);
final String ignoredNicks = p.getProperty("ignore", "");
final String identNick = p.getProperty("ident-nick", "");
final String identMsg = p.getProperty("ident-msg", "");
@@ -784,13 +524,16 @@ public class Mobibot extends PircBot
final String ttoken = p.getProperty("twitter-token", "");
final String ttokenSecret = p.getProperty("twitter-tokenSecret", "");
+ // Get the tell command settings
+ final int tellMaxDays = Utils.getIntProperty(p.getProperty("tell-max-days"), DEFAULT_TELL_MAX_DAYS);
+ final int tellMaxSize = Utils.getIntProperty(p.getProperty("tell-max-size"), DEFAULT_TELL_MAX_SIZE);
+
// Create the bot
- final Mobibot bot = new Mobibot(server, port, channel, logsDir);
+ final Mobibot bot = new Mobibot(server, port, nickname, channel, logsDir);
// Initialize the bot
bot.setVerbose(true);
bot.setAutoNickChange(true);
- bot.setName(nickname);
bot.setLogin(login);
bot.setVersion(weblogURL);
bot.setMessageDelay(MESSAGE_DELAY);
@@ -803,18 +546,18 @@ public class Mobibot extends PircBot
bot.setIdentMsg(identMsg);
// Set the URLs
- bot.setWeblogURL(weblogURL);
+ bot.setWeblogUrl(weblogURL);
bot.setFeedURL(feedURL);
- bot.setBacklogsURL(backlogsURL);
+ bot.setBacklogsUrl(backlogsURL);
- if (isValidString(dname) && isValidString(dpwd))
+ if (Utils.isValidString(dname) && Utils.isValidString(dpwd))
{
// Set the del.icio.us authentication
bot.setDeliciousAuth(dname, dpwd);
}
- if (isValidString(tconsumerKey) && isValidString(tconsumerSecret) && isValidString(ttoken) && isValidString(
- ttokenSecret))
+ if (Utils.isValidString(tconsumerKey) && Utils.isValidString(tconsumerSecret) && Utils.isValidString(ttoken)
+ && Utils.isValidString(ttokenSecret))
{
// Set the Twitter authentication
bot.setTwitterAuth(tconsumerKey, tconsumerSecret, ttoken, ttokenSecret);
@@ -826,6 +569,9 @@ public class Mobibot extends PircBot
// Set the ignored nicks
bot.setIgnoredNicks(ignoredNicks);
+ // Set the tell command
+ bot.setTell(tellMaxDays, tellMaxSize);
+
// Save the entries
bot.saveEntries(true);
@@ -862,62 +608,186 @@ public class Mobibot extends PircBot
bot.setVersion(INFO_STRS[0]);
// Identify with NickServ
- if (isValidString(ident))
+ if (Utils.isValidString(ident))
{
bot.identify(ident);
}
// Identify with a specified nick
- if (isValidString(identNick) && isValidString(identMsg))
+ if (Utils.isValidString(identNick) && Utils.isValidString(identMsg))
{
bot.sendMessage(identNick, identMsg);
}
+ // Load the messages queue
+ bot.tellMessages.addAll(TellMessagesMgr.load(bot.getSerializedObject(), bot.getLogger()));
+ bot.cleanTellMessages();
+
bot.joinChannel(channel);
}
}
/**
- * Converts XML/XHTML entities to plain text.
+ * Sets the ident password.
*
- * @param str The string to unescape.
- *
- * @return The unescaped string.
+ * @param pwd The password.
*/
- public static String unescapeXml(String str)
+ private void setIdent(String pwd)
{
- String s = str.replaceAll("&", "&");
- s = s.replaceAll("<", "<");
- s = s.replaceAll(">", ">");
- s = s.replaceAll(""", "\"");
- s = s.replaceAll("'", "'");
- s = s.replaceAll("'", "'");
-
- return s;
+ ident = pwd;
}
/**
- * Makes the given int bold.
+ * Sets the ident nickname.
*
- * @param i The int.
- *
- * @return The bold string.
+ * @param nick The nickname.
*/
- private static String bold(int i)
+ private void setIdentNick(String nick)
{
- return Colors.BOLD + i + Colors.BOLD;
+ identNick = nick;
}
/**
- * Makes the given string bold.
+ * Sets the ident message.
*
- * @param s The string.
- *
- * @return The bold string.
+ * @param msg The message.
*/
- private static String bold(String s)
+ private void setIdentMsg(String msg)
{
- return Colors.BOLD + s + Colors.BOLD;
+ identMsg = msg;
+ }
+
+ /**
+ * Sets the feed URL.
+ *
+ * @param feedURL The feed URL.
+ */
+ private void setFeedURL(String feedURL)
+ {
+ this.feedURL = feedURL;
+ }
+
+ /**
+ * Sets the del.icio.us authentication.
+ *
+ * @param username The del.icio.us username.
+ * @param password The del.icio.us password.
+ */
+ private void setDeliciousAuth(String username, String password)
+ {
+ delicious = new DeliciousPoster(username, password, ircServer);
+ }
+
+ /**
+ * Sets the Twitter consumerSecret and password..
+ *
+ * @param consumerKey The Twitter consumer key.
+ * @param consumerSecret The Twitter consumer secret.
+ * @param token The Twitter token.
+ * @param tokenSecret The Twitter token secret.
+ */
+ private void setTwitterAuth(String consumerKey, String consumerSecret, String token, String tokenSecret)
+ {
+ twitterConsumerKey = consumerKey;
+ twitterConsumerSecret = consumerSecret;
+ twitterToken = token;
+ twitterTokenSecret = tokenSecret;
+ }
+
+ /**
+ * Sets the default tags/categories.
+ *
+ * @param tags The tags.
+ */
+ private void setTags(String tags)
+ {
+ defaultTags = tags;
+ }
+
+ /**
+ * Sets the Ignored nicks.
+ *
+ * @param nicks The nicks to ignore
+ */
+ private void setIgnoredNicks(String nicks)
+ {
+ if (Utils.isValidString(nicks))
+ {
+ final StringTokenizer st = new StringTokenizer(nicks, ",");
+
+ while (st.hasMoreTokens())
+ {
+ ignoredNicks.add(st.nextToken().trim().toLowerCase());
+ }
+ }
+ }
+
+ /**
+ * Set the {@link Commands#TELL_CMD} parameters
+ *
+ * @param tellMaxDays The max number of days to hold messages for.
+ * @param tellMaxSize The maximmm number of messages to hold
+ */
+ private void setTell(int tellMaxDays, int tellMaxSize)
+ {
+ this.tellMaxDays = tellMaxDays;
+ this.tellMaxSize = tellMaxSize;
+ }
+
+ /**
+ * Saves the entries.
+ *
+ * @param isDayBackup Set the true if the daily backup file should also be created.
+ */
+ private void saveEntries(boolean isDayBackup)
+ {
+ EntriesMgr.saveEntries(this, entries, history, isDayBackup);
+ }
+
+ /**
+ * Sleeps for the specified number of seconds.
+ *
+ * @param secs The number of seconds to sleep for.
+ */
+ private static void sleep(int secs)
+ {
+ try
+ {
+ Thread.sleep((long) (secs * 1000));
+ }
+ catch (InterruptedException ignore)
+ {
+ ; // Do nothing
+ }
+ }
+
+ /**
+ * Reruns the serialized object file.
+ *
+ * @return The file location.
+ */
+ @SuppressWarnings("WeakerAccess")
+ public String getSerializedObject()
+ {
+ return serializedObject;
+ }
+
+ /**
+ * Returns the bot's logger.
+ *
+ * @return The bot's logger.
+ */
+ public final Log4JLogger getLogger()
+ {
+ return logger;
+ }
+
+ /**
+ * Cleans the {@link #tellMessages} messages queue.
+ */
+ private void cleanTellMessages()
+ {
+ TellMessagesMgr.cleanTellMessages(tellMessages, tellMaxDays);
}
/**
@@ -931,8 +801,8 @@ public class Mobibot extends PircBot
*/
private static String buildComment(int entryIndex, int commentIndex, EntryComment comment)
{
- return (LINK_CMD + (entryIndex + 1) + '.' + (commentIndex + 1) + ": [" + comment.getNick() + "] " + comment
- .getComment());
+ return (Commands.LINK_CMD + (entryIndex + 1) + '.' + (commentIndex + 1) + ": [" + comment.getNick() + "] "
+ + comment.getComment());
}
/**
@@ -961,7 +831,7 @@ public class Mobibot extends PircBot
*/
private static String buildLink(int index, EntryLink entry, boolean isView)
{
- final StringBuilder buff = new StringBuilder(LINK_CMD + (index + 1) + ": ");
+ final StringBuilder buff = new StringBuilder(Commands.LINK_CMD + (index + 1) + ": ");
buff.append('[').append(entry.getNick()).append(']');
@@ -974,7 +844,7 @@ public class Mobibot extends PircBot
if (NO_TITLE.equals(entry.getTitle()))
{
- buff.append(bold(entry.getTitle()));
+ buff.append(Utils.bold(entry.getTitle()));
}
else
{
@@ -996,290 +866,77 @@ public class Mobibot extends PircBot
*/
private static String buildTags(int entryIndex, EntryLink entry)
{
- return (LINK_CMD + (entryIndex + 1) + "T: " + entry.getDeliciousTags().replaceAll(",", ", "));
+ return (Commands.LINK_CMD + (entryIndex + 1) + "T: " + entry.getDeliciousTags().replaceAll(",", ", "));
}
/**
- * Copies a file.
+ * Get today's date for the feed.
*
- * @param in The source file.
- * @param out The destination file.
- *
- * @throws IOException If the file could not be copied.
- * @noinspection UnusedDeclaration
+ * @return Today's date.
*/
- private static void copyFile(File in, File out)
- throws IOException
+ public synchronized String getToday()
{
- FileChannel inChannel = null;
- FileChannel outChannel = null;
- FileInputStream input = null;
- FileOutputStream output = null;
-
- try
- {
- input = new FileInputStream(in);
- output = new FileOutputStream(out);
-
- inChannel = input.getChannel();
- outChannel = output.getChannel();
-
- inChannel.transferTo(0L, inChannel.size(), outChannel);
- }
- finally
- {
- try
- {
- if (inChannel != null)
- {
- inChannel.close();
- }
-
- if (input != null)
- {
- input.close();
- }
- }
- catch (Exception ignore)
- {
- ; // Do nothing
- }
-
- try
- {
- if (outChannel != null)
- {
- outChannel.close();
- }
-
- if (output != null)
- {
- output.close();
- }
- }
- catch (Exception ignore)
- {
- ; // Do nothing
- }
- }
+ return today;
}
/**
- * Ensures that the given location (File/URL) has a trailing slash (/) to indicate a directory.
+ * Returns the backlogs URL.
*
- * @param location The File or URL location.
- * @param isUrl Set to true if the location is a URL
- *
- * @return The location ending with a slash.
+ * @return The backlogs URL.
*/
- private static String ensureDir(String location, boolean isUrl)
+ public final String getBacklogsUrl()
{
- if (isUrl)
- {
- if (location.charAt(location.length() - 1) == '/')
- {
- return location;
- }
- else
- {
- return location + '/';
- }
- }
- else
- {
- if (location.charAt(location.length() - 1) == File.separatorChar)
- {
- return location;
- }
- else
- {
- return location + File.separatorChar;
- }
- }
+ return backLogsUrl;
}
/**
- * Returns the port.
+ * Sets the backlogs URL.
*
- * @param property The port property value.
- *
- * @return The port or default value if invalid.
+ * @param backLogsUrl The backlogs URL.
*/
- private static int getPort(String property)
+ private void setBacklogsUrl(String backLogsUrl)
{
- int port;
-
- try
- {
- port = Integer.parseInt(property);
- }
- catch (NumberFormatException ignore)
- {
- port = Mobibot.DEFAULT_PORT;
- }
-
- return port;
+ this.backLogsUrl = backLogsUrl;
}
/**
- * Returns the current Internet (beat) Time.
+ * Returns the weblog URL.
*
- * @return The Internet Time string.
+ * @return The weblog URL.
*/
- private static String internetTime()
+ public final String getWeblogUrl()
{
- final Calendar gc = Calendar.getInstance();
-
- final int offset = (gc.get(Calendar.ZONE_OFFSET) / (60 * 60 * 1000));
- int hh = gc.get(Calendar.HOUR_OF_DAY);
- final int mm = gc.get(Calendar.MINUTE);
- final int ss = gc.get(Calendar.SECOND);
-
- hh -= offset; // GMT
- hh += 1; // BMT
-
- long beats = Math.round(Math.floor((double) ((((hh * 3600) + (mm * 60) + ss) * 1000) / 86400)));
-
- if (beats >= 1000)
- {
- beats -= (long) 1000;
- }
- else if (beats < 0)
- {
- beats += (long) 1000;
- }
-
- if (beats < 10)
- {
- return ("@00" + String.valueOf(beats));
- }
- else if (beats < 100)
- {
- return ("@0" + String.valueOf(beats));
- }
-
- return ('@' + String.valueOf(beats));
+ return weblogUrl;
}
/**
- * Performs a DNS lookup on the specified query.
+ * Sets the weblog URL.
*
- * @param query The IP address or hostname.
- *
- * @return The lookup query result string.
- *
- * @throws UnknownHostException If the host is unknown.
+ * @param weblogUrl The weblog URL.
*/
- private static String lookup(String query)
- throws UnknownHostException
+ private void setWeblogUrl(String weblogUrl)
{
- final StringBuilder buffer = new StringBuilder("");
-
- final InetAddress[] results = InetAddress.getAllByName(query);
- String hostInfo;
-
- for (final InetAddress result : results)
- {
- if (result.getHostAddress().equals(query))
- {
- hostInfo = result.getHostName();
-
- if (hostInfo.equals(query))
- {
- throw new UnknownHostException();
- }
- }
- else
- {
- hostInfo = result.getHostAddress();
- }
-
- if (buffer.length() > 0)
- {
- buffer.append(", ");
- }
-
- buffer.append(hostInfo);
- }
-
- return buffer.toString();
+ this.weblogUrl = weblogUrl;
}
/**
- * Stores the last 10 public messages and actions.
+ * Returns the log directory.
*
- * @param sender The nick of the person who sent the private message.
- * @param message The actual message sent.
- * @param isAction Set to true if the message is an action.
+ * @return the log directory.
*/
- private static void recap(String sender, String message, boolean isAction)
+ public final String getLogsDir()
{
- RECAP_ARRAY.add(HHMM_SDF.format(Calendar.getInstance().getTime()) + " -> " + sender + (isAction ? " " : ": ")
- + message);
-
- if (RECAP_ARRAY.size() > MAX_RECAP)
- {
- RECAP_ARRAY.remove(0);
- }
+ return logsDir;
}
/**
- * Sleeps for the specified number of seconds.
+ * Returns the irc server.
*
- * @param secs The number of seconds to sleep for.
+ * @return The irc server.
*/
- private static void sleep(int secs)
+ public final String getIrcServer()
{
- try
- {
- Thread.sleep((long) (secs * 1000));
- }
- catch (InterruptedException ignore)
- {
- ; // Do nothing
- }
- }
-
- /**
- * Returns today's date.
- *
- * @return Today's date in {@link #ISO_SDF ISO} format.
- */
- private static String today()
- {
- return ISO_SDF.format(Calendar.getInstance().getTime());
- }
-
- /**
- * Performs a whois IP query.
- *
- * @param query The IP address.
- *
- * @return The IP whois data, if any.
- *
- * @throws IOException If a connection error occurs.
- */
- private static String[] whois(String query)
- throws IOException
- {
- final WhoisClient whois = new WhoisClient();
- String[] lines;
-
- try
- {
- whois.setDefaultTimeout(CONNECT_TIMEOUT);
- whois.connect(WHOIS_HOST);
- whois.setSoTimeout(CONNECT_TIMEOUT);
- whois.setSoLinger(false, 0);
-
- lines = whois.query('-' + query).split("\n");
- }
- finally
- {
- whois.disconnect();
- }
-
- return lines;
+ return ircServer;
}
/**
@@ -1287,7 +944,7 @@ public class Mobibot extends PircBot
*
* @param action The action.
*/
- public final void action(String action)
+ final void action(String action)
{
action(getChannel(), action);
}
@@ -1298,24 +955,14 @@ public class Mobibot extends PircBot
* @param channel The channel.
* @param action The action.
*/
- public final void action(String channel, String action)
+ final void action(String channel, String action)
{
- if (isValidString(channel) && isValidString(action))
+ if (Utils.isValidString(channel) && Utils.isValidString(action))
{
sendAction(channel, action);
}
}
- /**
- * Returns the current channel.
- *
- * @return The current channel.
- */
- public final String getChannel()
- {
- return channel;
- }
-
/**
* Returns the {@link FeedFetcherCache feed info cache}.
*
@@ -1326,16 +973,6 @@ public class Mobibot extends PircBot
return feedInfoCache;
}
- /**
- * Returns the bot's logger.
- *
- * @return The bot's logger.
- */
- public final Log4JLogger getLogger()
- {
- return logger;
- }
-
/**
* Responds with the bot's help.
*
@@ -1346,238 +983,247 @@ public class Mobibot extends PircBot
{
final String lcTopic = topic.toLowerCase();
- if (lcTopic.endsWith(HELP_POSTING_KEYWORD))
+ if (lcTopic.endsWith(Commands.HELP_POSTING_KEYWORD))
{
- send(sender, bold("Post a URL, by saying it on a line on its own:"));
- send(sender, DOUBLE_INDENT + bold(" [] [" + TAGS_MARKER + "<+tag> [...]]"));
- send(sender, "I will reply with a label, for example: " + bold(LINK_CMD + '1'));
+ send(sender, Utils.bold("Post a URL, by saying it on a line on its own:"));
+ send(sender, DOUBLE_INDENT + Utils.bold(" [] [" + TAGS_MARKER + "<+tag> [...]]"));
+ send(sender, "I will reply with a label, for example: " + Utils.bold(Commands.LINK_CMD + '1'));
send(sender, "To add a title, use a its label and a pipe:");
- send(sender, DOUBLE_INDENT + bold(LINK_CMD + "1:|This is the title"));
+ send(sender, DOUBLE_INDENT + Utils.bold(Commands.LINK_CMD + "1:|This is the title"));
send(sender, "To add a comment: ");
- send(sender, DOUBLE_INDENT + bold(LINK_CMD + "1:This is a comment"));
- send(sender, "I will reply with a label, for example: " + bold(LINK_CMD + "1.1"));
+ send(sender, DOUBLE_INDENT + Utils.bold(Commands.LINK_CMD + "1:This is a comment"));
+ send(sender, "I will reply with a label, for example: " + Utils.bold(Commands.LINK_CMD + "1.1"));
send(sender, "To edit a comment, use its label: ");
- send(sender, DOUBLE_INDENT + bold(LINK_CMD + "1.1:This is an edited comment"));
+ send(sender, DOUBLE_INDENT + Utils.bold(Commands.LINK_CMD + "1.1:This is an edited comment"));
send(sender, "To delete a comment, use its label and a minus sign: ");
- send(sender, DOUBLE_INDENT + bold(LINK_CMD + "1.1:-"));
+ send(sender, DOUBLE_INDENT + Utils.bold(Commands.LINK_CMD + "1.1:-"));
send(sender, "You can also view a posting by saying its label.");
}
- else if (lcTopic.endsWith(HELP_TAGS_KEYWORD))
+ else if (lcTopic.endsWith(Commands.HELP_TAGS_KEYWORD))
{
- send(sender, bold("To categorize or tag a URL, use its label and a T:"));
- send(sender, DOUBLE_INDENT + bold(LINK_CMD + "1T:<+tag|-tag> [...]"));
+ send(sender, Utils.bold("To categorize or tag a URL, use its label and a T:"));
+ send(sender, DOUBLE_INDENT + Utils.bold(Commands.LINK_CMD + "1T:<+tag|-tag> [...]"));
}
- else if (lcTopic.endsWith(VIEW_CMD))
+ else if (lcTopic.endsWith(Commands.VIEW_CMD))
{
send(sender, "To list or search the current URL posts:");
- send(sender, DOUBLE_INDENT + bold(getNick() + ": " + VIEW_CMD) + " [] []");
+ send(sender, DOUBLE_INDENT + Utils.bold(getNick() + ": " + Commands.VIEW_CMD) + " [] []");
}
else if (lcTopic.endsWith(getChannel().substring(1).toLowerCase()))
{
send(sender, "To list the last 5 posts from the channel's weblog:");
- send(sender, DOUBLE_INDENT + bold(getNick() + ": " + getChannel().substring(1)));
+ send(sender, DOUBLE_INDENT + Utils.bold(getNick() + ": " + getChannel().substring(1)));
}
- else if (lcTopic.endsWith(GOOGLE_CMD))
+ else if (lcTopic.endsWith(Commands.GOOGLE_CMD))
{
send(sender, "To search Google:");
- send(sender, DOUBLE_INDENT + bold(getNick() + ": " + GOOGLE_CMD + " "));
+ send(sender, DOUBLE_INDENT + Utils.bold(getNick() + ": " + Commands.GOOGLE_CMD + " "));
}
- else if (lcTopic.endsWith(TWITTER_CMD) && isTwitterEnabled())
+ else if (lcTopic.endsWith(Commands.TWITTER_CMD) && isTwitterEnabled())
{
send(sender, "To post to Twitter:");
- send(sender, DOUBLE_INDENT + bold(getNick() + ": " + TWITTER_CMD + " "));
+ send(sender, DOUBLE_INDENT + Utils.bold(getNick() + ": " + Commands.TWITTER_CMD + " "));
}
- else if (lcTopic.endsWith(RECAP_CMD))
+ else if (lcTopic.endsWith(Commands.RECAP_CMD))
{
send(sender, "To list the last 10 public channel messages:");
- send(sender, DOUBLE_INDENT + bold(getNick() + ": " + RECAP_CMD));
+ send(sender, DOUBLE_INDENT + Utils.bold(getNick() + ": " + Commands.RECAP_CMD));
}
- else if (lcTopic.endsWith(CALC_CMD))
+ else if (lcTopic.endsWith(Commands.CALC_CMD))
{
send(sender, "To solve a mathematical calculation:");
- send(sender, DOUBLE_INDENT + bold(getNick() + ": " + CALC_CMD + " "));
+ send(sender, DOUBLE_INDENT + Utils.bold(getNick() + ": " + Commands.CALC_CMD + " "));
}
- else if (lcTopic.endsWith(LOOKUP_CMD))
+ else if (lcTopic.endsWith(Commands.LOOKUP_CMD))
{
send(sender, "To perform a DNS lookup query:");
- send(sender, DOUBLE_INDENT + bold(getNick() + ": " + LOOKUP_CMD + " "));
+ send(sender,
+ DOUBLE_INDENT + Utils.bold(getNick() + ": " + Commands.LOOKUP_CMD + " "));
}
- else if (lcTopic.endsWith(TIME_CMD))
+ else if (lcTopic.endsWith(Commands.TIME_CMD))
{
send(sender, "To display a country's current date/time:");
- send(sender, DOUBLE_INDENT + bold(getNick() + ": " + TIME_CMD) + " []");
+ send(sender, DOUBLE_INDENT + Utils.bold(getNick() + ": " + Commands.TIME_CMD) + " []");
send(sender, "For a listing of the supported countries:");
- send(sender, DOUBLE_INDENT + bold(getNick() + ": " + TIME_CMD));
+ send(sender, DOUBLE_INDENT + Utils.bold(getNick() + ": " + Commands.TIME_CMD));
}
- else if (lcTopic.endsWith(QUOTE_CMD))
+ else if (lcTopic.endsWith(Commands.QUOTE_CMD))
{
send(sender, "To retrieve a random quote:");
- send(sender, DOUBLE_INDENT + bold(getNick() + ": " + QUOTE_CMD));
+ send(sender, DOUBLE_INDENT + Utils.bold(getNick() + ": " + Commands.QUOTE_CMD));
}
- else if (lcTopic.endsWith(STOCK_CMD))
+ else if (lcTopic.endsWith(Commands.STOCK_CMD))
{
send(sender, "To retrieve a stock quote:");
- send(sender, DOUBLE_INDENT + bold(getNick() + ": " + STOCK_CMD + " "));
+ send(sender,
+ DOUBLE_INDENT + Utils.bold(getNick() + ": " + Commands.STOCK_CMD + " "));
}
- else if (lcTopic.endsWith(DICE_CMD))
+ else if (lcTopic.endsWith(Commands.DICE_CMD))
{
send(sender, "To roll the dice:");
- send(sender, DOUBLE_INDENT + bold(getNick() + ": " + DICE_CMD));
+ send(sender, DOUBLE_INDENT + Utils.bold(getNick() + ": " + Commands.DICE_CMD));
}
- else if (lcTopic.endsWith(WAR_CMD))
+ else if (lcTopic.endsWith(Commands.WAR_CMD))
{
send(sender, "To play war:");
- send(sender, DOUBLE_INDENT + bold(getNick() + ": " + WAR_CMD));
+ send(sender, DOUBLE_INDENT + Utils.bold(getNick() + ": " + Commands.WAR_CMD));
}
- else if (lcTopic.endsWith(WEATHER_CMD))
+ else if (lcTopic.endsWith(Commands.WEATHER_CMD))
{
send(sender, "To display weather information:");
- send(sender, DOUBLE_INDENT + bold(getNick() + ": " + WEATHER_CMD + " "));
+ send(sender, DOUBLE_INDENT + Utils.bold(getNick() + ": " + Commands.WEATHER_CMD + " "));
send(sender, "For a listing of the ICAO station IDs, please visit: " + Weather.STATIONS_URL);
}
- else if (lcTopic.endsWith(USERS_CMD))
+ else if (lcTopic.endsWith(Commands.USERS_CMD))
{
send(sender, "To list the users present on the channel:");
- send(sender, DOUBLE_INDENT + bold(getNick() + ": " + USERS_CMD));
+ send(sender, DOUBLE_INDENT + Utils.bold(getNick() + ": " + Commands.USERS_CMD));
}
- else if (lcTopic.endsWith(INFO_CMD))
+ else if (lcTopic.endsWith(Commands.INFO_CMD))
{
send(sender, "To view information about the bot:");
- send(sender, DOUBLE_INDENT + bold(getNick() + ": " + INFO_CMD));
+ send(sender, DOUBLE_INDENT + Utils.bold(getNick() + ": " + Commands.INFO_CMD));
}
- else if (lcTopic.endsWith(CYCLE_CMD))
+ else if (lcTopic.endsWith(Commands.CYCLE_CMD))
{
if (isOp(sender))
{
send(sender, "To have the bot leave the channel and come back:");
- send(sender, DOUBLE_INDENT + bold("/msg " + getNick() + ' ' + CYCLE_CMD));
+ send(sender, DOUBLE_INDENT + Utils.bold("/msg " + getNick() + ' ' + Commands.CYCLE_CMD));
}
}
- else if (lcTopic.endsWith(ME_CMD))
+ else if (lcTopic.endsWith(Commands.ME_CMD))
{
if (isOp(sender))
{
send(sender, "To have the bot perform an action:");
- send(sender, DOUBLE_INDENT + bold("/msg " + getNick() + ' ' + ME_CMD + " "));
+ send(sender, DOUBLE_INDENT + Utils.bold("/msg " + getNick() + ' ' + Commands.ME_CMD + " "));
}
}
- else if (lcTopic.endsWith(SAY_CMD))
+ else if (lcTopic.endsWith(Commands.SAY_CMD))
{
if (isOp(sender))
{
send(sender, "To have the bot say something on the channel:");
- send(sender, DOUBLE_INDENT + bold("/msg " + getNick() + ' ' + SAY_CMD + " "));
+ send(sender, DOUBLE_INDENT + Utils.bold("/msg " + getNick() + ' ' + Commands.SAY_CMD + " "));
}
}
- else if (lcTopic.endsWith(VERSION_CMD))
+ else if (lcTopic.endsWith(Commands.VERSION_CMD))
{
if (isOp(sender))
{
send(sender, "To view the version data (bot, java, etc.):");
- send(sender, DOUBLE_INDENT + bold("/msg " + getNick() + ' ' + VERSION_CMD));
+ send(sender, DOUBLE_INDENT + Utils.bold("/msg " + getNick() + ' ' + Commands.VERSION_CMD));
}
}
- else if (lcTopic.endsWith(MSG_CMD))
+ else if (lcTopic.endsWith(Commands.MSG_CMD))
{
if (isOp(sender))
{
send(sender, "To have the bot send a private message to someone:");
- send(sender, DOUBLE_INDENT + bold("/msg " + getNick() + ' ' + MSG_CMD + " "));
+ send(sender,
+ DOUBLE_INDENT + Utils.bold("/msg " + getNick() + ' ' + Commands.MSG_CMD + " "));
}
}
- else if (lcTopic.startsWith(CURRENCY_CMD))
+ else if (lcTopic.startsWith(Commands.CURRENCY_CMD))
{
send(sender, "To convert from one currency to another:");
- send(sender, DOUBLE_INDENT + bold(getNick() + ": " + CURRENCY_CMD + " [100 USD to EUR]"));
+ send(sender, DOUBLE_INDENT + Utils.bold(getNick() + ": " + Commands.CURRENCY_CMD + " [100 USD to EUR]"));
- if (lcTopic.endsWith(CURRENCY_CMD))
+ if (lcTopic.endsWith(Commands.CURRENCY_CMD))
{
send(sender, "For a listing of supported currencies:");
- send(sender, DOUBLE_INDENT + bold(getNick() + ": " + CURRENCY_CMD));
+ send(sender, DOUBLE_INDENT + Utils.bold(getNick() + ": " + Commands.CURRENCY_CMD));
}
}
- else if (lcTopic.startsWith(IGNORE_CMD))
+ else if (lcTopic.startsWith(Commands.IGNORE_CMD))
{
send(sender, "To check your ignore status:");
- send(sender, DOUBLE_INDENT + bold(getNick() + ": " + IGNORE_CMD));
+ send(sender, DOUBLE_INDENT + Utils.bold(getNick() + ": " + Commands.IGNORE_CMD));
send(sender, "To toggle your ignore status:");
- send(sender, DOUBLE_INDENT + bold(getNick() + ": " + IGNORE_CMD + ' ' + IGNORE_ME_KEYWORD));
+ send(sender,
+ DOUBLE_INDENT + Utils.bold(getNick() + ": " + Commands.IGNORE_CMD + ' ' + Commands.IGNORE_ME_KEYWORD));
+
+ }
+ else if (lcTopic.startsWith(Commands.TELL_CMD))
+ {
+ send(sender, "To send a message to someone when they join the channel:");
+ send(sender, DOUBLE_INDENT + Utils.bold(getNick() + ": " + Commands.TELL_CMD + " "));
+
+ send(sender, "To view queued and sent messages:");
+ send(sender, DOUBLE_INDENT + Utils.bold(getNick() + ": " + Commands.TELL_CMD + ' ' + Commands.VIEW_CMD));
+
+ send(sender, "Messages are kept for about " + Utils.bold(tellMaxDays) + " days.");
}
else
{
- send(sender, bold("Type a URL on " + getChannel() + " to post it."));
+ send(sender, Utils.bold("Type a URL on " + getChannel() + " to post it."));
send(sender, "For more information on specific command, type:");
- send(sender, DOUBLE_INDENT + bold(getNick() + ": " + HELP_CMD + " "));
+ send(sender, DOUBLE_INDENT + Utils.bold(getNick() + ": " + Commands.HELP_CMD + " "));
send(sender, "The commands are:");
- final String[] cmds = {
- CALC_CMD,
- CURRENCY_CMD,
- DICE_CMD,
- GOOGLE_CMD,
- IGNORE_CMD,
- INFO_CMD,
- LOOKUP_CMD,
- getChannel().substring(1),
- HELP_POSTING_KEYWORD,
- QUOTE_CMD,
- RECAP_CMD,
- STOCK_CMD,
- HELP_TAGS_KEYWORD,
- TIME_CMD,
- TWITTER_CMD,
- USERS_CMD,
- VIEW_CMD,
- WAR_CMD,
- WEATHER_CMD
- };
+ final List cmds = new ArrayList();
+ cmds.add(Commands.CALC_CMD);
+ cmds.add(Commands.CURRENCY_CMD);
+ cmds.add(Commands.DICE_CMD);
+ cmds.add(Commands.GOOGLE_CMD);
+ cmds.add(Commands.IGNORE_CMD);
+ cmds.add(Commands.INFO_CMD);
+ cmds.add(Commands.LOOKUP_CMD);
+ cmds.add(getChannel().substring(1));
+ cmds.add(Commands.HELP_POSTING_KEYWORD);
+ cmds.add(Commands.QUOTE_CMD);
+ cmds.add(Commands.RECAP_CMD);
+ cmds.add(Commands.STOCK_CMD);
+ cmds.add(Commands.HELP_TAGS_KEYWORD);
+ cmds.add(Commands.TIME_CMD);
+ cmds.add(Commands.USERS_CMD);
+ cmds.add(Commands.VIEW_CMD);
+ cmds.add(Commands.WAR_CMD);
+ cmds.add(Commands.WEATHER_CMD);
- Arrays.sort(cmds);
+ if (isTellEnabled())
+ {
+ cmds.add(Commands.TELL_CMD);
+ }
+
+ if (isTwitterEnabled())
+ {
+ cmds.add(Commands.TWITTER_CMD);
+ }
+
+ Collections.sort(cmds);
final StringBuilder sb = new StringBuilder(0);
- boolean isValidCmd = true;
- for (int i = 0, cmdCount = 1; i < cmds.length; i++, cmdCount++)
+ for (int i = 0, cmdCount = 1; i < cmds.size(); i++, cmdCount++)
{
- if (cmds[i].equals(TWITTER_CMD))
+ if (sb.length() > 0)
{
- isValidCmd = isTwitterEnabled();
+ sb.append(" ");
}
- if (isValidCmd)
- {
- if (sb.length() > 0)
- {
- sb.append(" ");
- }
-
- sb.append(cmds[i]);
- }
- else
- {
- cmdCount--;
- }
+ sb.append(cmds.get(i));
// 5 commands per line or last command
- if (sb.length() > 0 && (cmdCount == 5 || i == (cmds.length - 1)))
+ if (sb.length() > 0 && (cmdCount == 5 || i == (cmds.size() - 1)))
{
- send(sender, DOUBLE_INDENT + bold(sb.toString()));
+ send(sender, DOUBLE_INDENT + Utils.bold(sb.toString()));
sb.setLength(0);
cmdCount = 0;
}
-
- isValidCmd = true;
}
if (isOp(sender))
{
send(sender, "The op commands are:");
send(sender,
- DOUBLE_INDENT + bold(
- CYCLE_CMD + " " + ME_CMD + " " + MSG_CMD + " " + SAY_CMD + " " + VERSION_CMD)
+ DOUBLE_INDENT + Utils
+ .bold(Commands.CYCLE_CMD + " " + Commands.ME_CMD + " " + Commands.MSG_CMD + " "
+ + Commands.SAY_CMD + " " + Commands.VERSION_CMD)
);
}
}
@@ -1594,65 +1240,12 @@ public class Mobibot extends PircBot
send(sender, message, false);
}
- /**
- * Sends a private message or notice.
- *
- * @param sender The nick of the person who sent the message.
- * @param message The actual message.
- * @param isPrivate Set to true if the response should be a private message, otherwise a notice is sent.
- */
- public final void send(String sender, String message, boolean isPrivate)
- {
- if (isValidString(message) && isValidString(sender))
- {
- if (isPrivate)
- {
- if (logger.isDebugEnabled())
- {
- logger.debug("Sending message to " + sender + ": " + message);
- }
-
- sendMessage(sender, message);
- }
- else
- {
- if (logger.isDebugEnabled())
- {
- logger.debug("Sending notice to " + sender + ": " + message);
- }
-
- sendNotice(sender, message);
- }
- }
- }
-
- /**
- * This method is called whenever an ACTION is sent from a user.
- *
- * @param sender The nick of the person who sent the action.
- * @param login The login of the person who sent the action.
- * @param hostname The hostname of the person who sent the action.
- * @param target The target of the action, be it a channel or our nick.
- * @param action The action carried out by the user.
- */
- protected final void onAction(String sender, String login, String hostname, String target, String action)
- {
- if (target.equals(getChannel()))
- {
- recap(sender, action, true);
- }
- }
-
- /**
- * This method carries out the actions to be performed when the PircBot gets disconnected.
- *
- * @noinspection UseOfSystemOutOrSystemErr
- */
+ @Override
protected final void onDisconnect()
{
- if (isValidString(weblogURL))
+ if (Utils.isValidString(weblogUrl))
{
- setVersion(weblogURL);
+ setVersion(weblogUrl);
}
sleep(5);
@@ -1694,12 +1287,12 @@ public class Mobibot extends PircBot
setVersion(INFO_STRS[0]);
- if (isValidString(ident))
+ if (Utils.isValidString(ident))
{
identify(ident);
}
- if (isValidString(identNick) && isValidString(identMsg))
+ if (Utils.isValidString(identNick) && Utils.isValidString(identMsg))
{
sendMessage(identNick, identMsg);
}
@@ -1708,14 +1301,16 @@ public class Mobibot extends PircBot
}
/**
- * This method is called whenever a message is sent to a channel.
+ * Returns the current channel.
*
- * @param channel The channel to which the message was sent.
- * @param sender The nick of the person who sent the message.
- * @param login The login of the person who sent the message.
- * @param hostname The hostname of the person who sent the message.
- * @param message The actual message sent.
+ * @return The current channel.
*/
+ public final String getChannel()
+ {
+ return channel;
+ }
+
+ @Override
protected final void onMessage(String channel, String sender, String login, String hostname, String message)
{
if (logger.isDebugEnabled())
@@ -1740,13 +1335,13 @@ public class Mobibot extends PircBot
if (dupIndex == -1)
{
- if (!today().equals(getToday()))
+ if (!Utils.today().equals(getToday()))
{
isBackup = true;
saveEntries(true);
entries.clear();
- setToday(today());
+ today = Utils.today();
}
final StringBuilder tags = new StringBuilder(defaultTags);
@@ -1762,7 +1357,7 @@ public class Mobibot extends PircBot
}
else
{
- if (isValidString(data[0]))
+ if (Utils.isValidString(data[0]))
{
title = data[0].trim();
}
@@ -1778,7 +1373,7 @@ public class Mobibot extends PircBot
final Document html = Jsoup.connect(link).get();
final String htmlTitle = html.title();
- if (isValidString(htmlTitle))
+ if (Utils.isValidString(htmlTitle))
{
title = htmlTitle;
}
@@ -1805,7 +1400,9 @@ public class Mobibot extends PircBot
if (NO_TITLE.equals(entry.getTitle()))
{
send(sender, "Please specify a title, by typing:", true);
- send(sender, DOUBLE_INDENT + bold(LINK_CMD + (index + 1) + ":|This is the title"), true);
+ send(sender,
+ DOUBLE_INDENT + Utils.bold(Commands.LINK_CMD + (index + 1) + ":|This is the title"),
+ true);
}
}
else
@@ -1829,11 +1426,11 @@ public class Mobibot extends PircBot
args = cmds[1].trim();
}
- if (cmd.startsWith(HELP_CMD))
+ if (cmd.startsWith(Commands.HELP_CMD))
{
helpResponse(sender, args);
}
- else if (cmd.equals(PING_CMD))
+ else if (cmd.equals(Commands.PING_CMD))
{
final String[] pings = {
"is barely alive.",
@@ -1854,125 +1451,72 @@ public class Mobibot extends PircBot
action(channel, pings[r.nextInt(pings.length)]);
}
- else if (cmd.equals(PONG_CMD))
+ else if (cmd.equals(Commands.PONG_CMD))
{
- send(channel, PING_CMD, true);
+ send(channel, Commands.PING_CMD, true);
}
- else if (cmd.equals(RECAP_CMD))
+ else if (cmd.equals(Commands.RECAP_CMD))
{
recapResponse(sender, false);
}
- else if (cmd.equals(USERS_CMD))
+ else if (cmd.equals(Commands.USERS_CMD))
{
usersResponse(sender, false);
}
- else if (cmd.equals(INFO_CMD))
+ else if (cmd.equals(Commands.INFO_CMD))
{
infoResponse(sender, false);
}
- else if (cmd.equals(VERSION_CMD))
+ else if (cmd.equals(Commands.VERSION_CMD))
{
versionResponse(sender, false);
}
- else if (cmd.equals(DICE_CMD))
+ else if (cmd.equals(Commands.DICE_CMD))
{
- final Random r = new Random();
+ send(getChannel(), shall_we_play_a_game);
- int i = r.nextInt(6) + 1;
- int y = r.nextInt(6) + 1;
- final int playerTotal = i + y;
-
- send(getChannel(),
- sender + " rolled two dice: " + bold(i) + " and " + bold(y) + " for a total of "
- + bold(playerTotal));
-
- i = r.nextInt(6) + 1;
- y = r.nextInt(6) + 1;
- final int total = i + y;
-
- action("rolled two dice: " + bold(i) + " and " + bold(y) + " for a total of " + bold(total));
-
- if (playerTotal < total)
- {
- action("wins.");
- }
- else if (playerTotal > total)
- {
- action("lost.");
- }
- else
- {
- action("tied.");
- }
+ Dice.roll(this, sender);
}
- else if (cmd.equals(WAR_CMD))
+ else if (cmd.equals(Commands.WAR_CMD))
{
- final Random r = new Random();
+ send(getChannel(), shall_we_play_a_game);
- int i;
- int y;
-
- while (true)
- {
- i = r.nextInt(WAR_DECK.length);
- y = r.nextInt(WAR_DECK.length);
-
- send(getChannel(),
- sender + " drew the " + bold(WAR_DECK[i]) + " of " + WAR_SUITS[r.nextInt(WAR_SUITS.length)]);
- action("drew the " + bold(WAR_DECK[y]) + " of " + WAR_SUITS[r.nextInt(WAR_SUITS.length)]);
-
- if (i != y)
- {
- break;
- }
- }
-
- if (i < y)
- {
- action("lost.");
- }
- else if (i > y)
- {
- action("wins.");
- }
- else
- {
- action("tied.");
- }
+ War.play(this, sender);
}
else if (cmd.equalsIgnoreCase(getChannel().substring(1)))
{
feedResponse(sender);
}
- else if (cmd.startsWith(CURRENCY_CMD))
+ else if (cmd.startsWith(Commands.CURRENCY_CMD))
{
- new Thread(new CurrencyConverter(this, sender, args, today())).start();
+ currencyConverter.setQuery(sender, args);
+ new Thread(currencyConverter).start();
}
- else if (cmd.startsWith(LOOKUP_CMD))
+ else if (cmd.startsWith(Commands.LOOKUP_CMD))
{
lookupResponse(sender, args);
}
- else if (cmd.startsWith(VIEW_CMD))
+ else if (cmd.startsWith(Commands.VIEW_CMD))
{
viewResponse(sender, args, false);
}
- else if (cmd.startsWith(GOOGLE_CMD))
+ else if (cmd.startsWith(Commands.GOOGLE_CMD))
{
googleResponse(sender, args);
}
- else if (cmd.startsWith(TWITTER_CMD))
+ else if (cmd.startsWith(Commands.TWITTER_CMD) && isTwitterEnabled())
{
twitterResponse(sender, args);
}
- else if (cmd.startsWith(STOCK_CMD))
+ else if (cmd.startsWith(Commands.STOCK_CMD))
{
stockResponse(sender, args);
}
- else if (cmd.startsWith(QUOTE_CMD))
+ else if (cmd.startsWith(Commands.QUOTE_CMD))
{
new Thread(new Quote(this, sender)).start();
}
- else if (cmd.startsWith(CALC_CMD))
+ else if (cmd.startsWith(Commands.CALC_CMD))
{
if (cmds.length > 1)
{
@@ -1993,23 +1537,27 @@ public class Mobibot extends PircBot
}
else
{
- helpResponse(sender, CALC_CMD);
+ helpResponse(sender, Commands.CALC_CMD);
}
}
- else if (cmd.startsWith(TIME_CMD))
+ else if (cmd.startsWith(Commands.TIME_CMD))
{
- timeResponse(sender, args, false);
+ worldTime.timeResponse(this, sender, args, false);
}
- else if (cmd.startsWith(WEATHER_CMD))
+ else if (cmd.startsWith(Commands.TELL_CMD) && isTellEnabled())
+ {
+ tellResponse(sender, args);
+ }
+ else if (cmd.startsWith(Commands.WEATHER_CMD))
{
weatherResponse(sender, args, false);
}
- else if (cmd.startsWith(IGNORE_CMD))
+ else if (cmd.startsWith(Commands.IGNORE_CMD))
{
if (!isOp(sender))
{
final String nick = sender.toLowerCase();
- final boolean isMe = args.toLowerCase().startsWith(IGNORE_ME_KEYWORD);
+ final boolean isMe = args.toLowerCase().startsWith(Commands.IGNORE_ME_KEYWORD);
if (ignoredNicks.contains(nick))
{
@@ -2046,7 +1594,7 @@ public class Mobibot extends PircBot
for (String nick : nicks)
{
- if (IGNORE_ME_KEYWORD.equals(nick))
+ if (Commands.IGNORE_ME_KEYWORD.equals(nick))
{
nick = sender.toLowerCase();
}
@@ -2066,7 +1614,7 @@ public class Mobibot extends PircBot
}
}
}
- else if (message.matches(LINK_CMD + "[0-9]+:.*"))
+ else if (message.matches(Commands.LINK_CMD + "[0-9]+:.*"))
{
isCommand = true;
@@ -2111,7 +1659,7 @@ public class Mobibot extends PircBot
}
entries.remove(index);
- send(getChannel(), "Entry " + LINK_CMD + (index + 1) + " removed.");
+ send(getChannel(), "Entry " + Commands.LINK_CMD + (index + 1) + " removed.");
saveEntries(false);
}
else
@@ -2192,7 +1740,7 @@ public class Mobibot extends PircBot
}
}
}
- else if (message.matches(LINK_CMD + "[0-9]+T:.*"))
+ else if (message.matches(Commands.LINK_CMD + "[0-9]+T:.*"))
{
isCommand = true;
@@ -2237,7 +1785,7 @@ public class Mobibot extends PircBot
}
}
}
- else if (message.matches(LINK_CMD + "[0-9]+\\.[0-9]+:.*"))
+ else if (message.matches(Commands.LINK_CMD + "[0-9]+\\.[0-9]+:.*"))
{
isCommand = true;
@@ -2261,7 +1809,8 @@ public class Mobibot extends PircBot
else if ("-".equals(cmd))
{
entry.deleteComment(cindex);
- send(getChannel(), "Comment " + LINK_CMD + (index + 1) + '.' + (cindex + 1) + " removed.");
+ send(getChannel(),
+ "Comment " + Commands.LINK_CMD + (index + 1) + '.' + (cindex + 1) + " removed.");
saveEntries(false);
}
else if (cmd.charAt(0) == '?')
@@ -2299,16 +1848,7 @@ public class Mobibot extends PircBot
}
}
- /**
- * This method is called whenever a private message is sent to the bot.
- *
- * @param sender The nick of the person who sent the private message.
- * @param login The login of the person who sent the private message.
- * @param hostname The hostname of the person who sent the private message.
- * @param message The actual message sent.
- *
- * @noinspection UseOfSystemOutOrSystemErr
- */
+ @Override
protected final void onPrivateMessage(String sender, String login, String hostname, String message)
{
if (logger.isDebugEnabled())
@@ -2325,7 +1865,7 @@ public class Mobibot extends PircBot
args = cmds[1].trim();
}
- if (cmd.startsWith(HELP_CMD))
+ if (cmd.startsWith(Commands.HELP_CMD))
{
helpResponse(sender, args);
}
@@ -2337,7 +1877,7 @@ public class Mobibot extends PircBot
System.exit(0);
}
}
- else if (cmd.equals(DIE_CMD))
+ else if (cmd.equals(Commands.DIE_CMD))
{
if (isOp(sender))
{
@@ -2348,23 +1888,23 @@ public class Mobibot extends PircBot
System.exit(0);
}
}
- else if (cmd.equals(CYCLE_CMD))
+ else if (cmd.equals(Commands.CYCLE_CMD))
{
send(getChannel(), sender + " has just asked me to leave. I'll be back!");
sleep(0);
partChannel(getChannel());
- sleep(5);
+ sleep(10);
joinChannel(getChannel());
}
- else if (cmd.equals(RECAP_CMD))
+ else if (cmd.equals(Commands.RECAP_CMD))
{
recapResponse(sender, true);
}
- else if (cmd.equals(USERS_CMD))
+ else if (cmd.equals(Commands.USERS_CMD))
{
usersResponse(sender, true);
}
- else if (cmd.startsWith(ADDLOG_CMD) && (cmds.length > 1))
+ else if (cmd.startsWith(Commands.ADDLOG_CMD) && (cmds.length > 1))
{
if (isOp(sender))
{
@@ -2372,7 +1912,7 @@ public class Mobibot extends PircBot
send(sender, history.toString(), true);
}
}
- else if (cmd.startsWith(ME_CMD))
+ else if (cmd.startsWith(Commands.ME_CMD))
{
if (isOp(sender))
{
@@ -2382,18 +1922,18 @@ public class Mobibot extends PircBot
}
else
{
- helpResponse(sender, ME_CMD);
+ helpResponse(sender, Commands.ME_CMD);
}
}
}
- else if (cmd.startsWith(NICK_CMD) && (cmds.length > 1))
+ else if (cmd.startsWith(Commands.NICK_CMD) && (cmds.length > 1))
{
if (isOp(sender))
{
changeNick(args);
}
}
- else if (cmd.startsWith(SAY_CMD))
+ else if (cmd.startsWith(Commands.SAY_CMD))
{
if (isOp(sender))
{
@@ -2403,11 +1943,11 @@ public class Mobibot extends PircBot
}
else
{
- helpResponse(sender, SAY_CMD);
+ helpResponse(sender, Commands.SAY_CMD);
}
}
}
- else if (cmd.startsWith(MSG_CMD))
+ else if (cmd.startsWith(Commands.MSG_CMD))
{
if (isOp(sender))
{
@@ -2417,41 +1957,44 @@ public class Mobibot extends PircBot
if (args.length() > 2)
{
- System.out.println(msg[0] + ' ' + msg[1]);
send(msg[0], msg[1], true);
}
else
{
- helpResponse(sender, MSG_CMD);
+ helpResponse(sender, Commands.MSG_CMD);
}
}
else
{
- helpResponse(sender, MSG_CMD);
+ helpResponse(sender, Commands.MSG_CMD);
}
}
}
- else if (cmd.startsWith(VIEW_CMD))
+ else if (cmd.startsWith(Commands.VIEW_CMD))
{
viewResponse(sender, args, true);
}
- else if (cmd.startsWith(TIME_CMD))
+ else if (cmd.startsWith(Commands.TIME_CMD))
{
- timeResponse(sender, args, true);
+ worldTime.timeResponse(this, sender, args, true);
}
- else if (cmd.startsWith(WEATHER_CMD))
+ else if (cmd.startsWith(Commands.TELL_CMD) && isTellEnabled())
+ {
+ tellResponse(sender, args);
+ }
+ else if (cmd.startsWith(Commands.WEATHER_CMD))
{
weatherResponse(sender, args, true);
}
- else if (cmd.equals(INFO_CMD))
+ else if (cmd.equals(Commands.INFO_CMD))
{
infoResponse(sender, true);
}
- else if (cmd.equals(VERSION_CMD))
+ else if (cmd.equals(Commands.VERSION_CMD))
{
versionResponse(sender, true);
}
- else if (cmd.equals(DEBUG_CMD))
+ else if (cmd.equals(Commands.DEBUG_CMD))
{
if (isOp(sender))
{
@@ -2473,14 +2016,331 @@ public class Mobibot extends PircBot
}
}
+ @Override
+ protected final void onAction(String sender, String login, String hostname, String target, String action)
+ {
+ if (target.equals(getChannel()))
+ {
+ recap(sender, action, true);
+ }
+ }
+
/**
- * Responds the title and links from the RSS feed.
+ * Stores the last 10 public messages and actions.
+ *
+ * @param sender The nick of the person who sent the private message.
+ * @param message The actual message sent.
+ * @param isAction Set to true if the message is an action.
+ */
+ private void recap(String sender, String message, boolean isAction)
+ {
+ recap.add(Utils.UTC_SDF.format(Calendar.getInstance().getTime()) + " -> " + sender + (isAction ? " " : ": ")
+ + message
+ );
+
+ if (recap.size() > MAX_RECAP)
+ {
+ recap.remove(0);
+ }
+ }
+
+ @Override
+ protected void onJoin(String channel, String sender, String login, String hostname)
+ {
+ tellSendMessages(sender);
+ }
+
+ @Override
+ protected void onNickChange(String oldNick, String login, String hostname, String newNick)
+ {
+ tellSendMessages(newNick);
+ }
+
+ /**
+ * Checks and sends {@link Commands#TELL_CMD} messages.
+ *
+ * @param nickname The user's nickname.
+ */
+ private void tellSendMessages(String nickname)
+ {
+ if (!nickname.equals(getNick()) && isTellEnabled())
+ {
+ synchronized (tellMessages)
+ {
+ for (final TellMessage message : tellMessages)
+ {
+ if (message.isMatch(nickname))
+ {
+ if (message.getRecipient().equalsIgnoreCase(nickname) && !message.isReceived())
+ {
+ if (message.getSender().equals(nickname))
+ {
+ send(nickname,
+ Utils.bold("You") + " wanted me to remind you: " + Colors.REVERSE + message
+ .getMessage() + Colors.REVERSE, true
+ );
+ }
+ else
+ {
+ send(nickname,
+ message.getSender() + " wanted me to tell you: " + Colors.REVERSE + message
+ .getMessage() + Colors.REVERSE,
+ true
+ );
+ }
+
+ message.setReceived();
+
+ saveTellMessages();
+
+ }
+ else if (message.getSender().equalsIgnoreCase(nickname) && message.isReceived() && !message
+ .isNotified())
+ {
+ send(nickname,
+ "Your message " + Colors.REVERSE + "[ID " + message.getId() + ']' + Colors.REVERSE
+ + " was sent to " + Utils.bold(message.getRecipient()) + " on " + Utils.UTC_SDF
+ .format(message.getReceived()),
+ true
+ );
+
+ message.setNotified();
+
+ saveTellMessages();
+ }
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * Returns true if {@link Commands#TELL_CMD} is enabled.
+ *
+ * @return true or false
+ */
+ private boolean isTellEnabled()
+ {
+ return tellMaxSize > 0 && tellMaxDays > 0;
+ }
+
+ /**
+ * Sends a private message or notice.
+ *
+ * @param sender The nick of the person who sent the message.
+ * @param message The actual message.
+ * @param isPrivate Set to true if the response should be a private message, otherwise a notice is sent.
+ */
+ public final void send(String sender, String message, boolean isPrivate)
+ {
+ if (Utils.isValidString(message) && Utils.isValidString(sender))
+ {
+ if (isPrivate)
+ {
+ if (logger.isDebugEnabled())
+ {
+ logger.debug("Sending message to " + sender + ": " + message);
+ }
+
+ sendMessage(sender, message);
+ }
+ else
+ {
+ if (logger.isDebugEnabled())
+ {
+ logger.debug("Sending notice to " + sender + ": " + message);
+ }
+
+ sendNotice(sender, message);
+ }
+ }
+ }
+
+ /**
+ * Saves the {@link #tellMessages} messages queue.
+ */
+ private void saveTellMessages()
+ {
+ TellMessagesMgr.save(getSerializedObject(), tellMessages, logger);
+ }
+
+ /**
+ * Processes the {@link Commands#TELL_CMD} commands.
+ *
+ * @param sender The sender's nick.
+ * @param cmds The commands string.
+ */
+ private void tellResponse(String sender, String cmds)
+ {
+ if (!Utils.isValidString(cmds))
+ {
+ helpResponse(sender, Commands.TELL_CMD);
+ }
+ else if (cmds.startsWith(Commands.VIEW_CMD))
+ {
+ if (isOp(sender) && cmds.equals(Commands.VIEW_CMD + ' ' + Commands.TELL_ALL_CMD))
+ {
+ if (tellMessages.size() > 0)
+ {
+ synchronized (tellMessages)
+ {
+ for (final TellMessage message : tellMessages)
+ {
+ send(sender,
+ Utils.bold(message.getSender()) + " --> " + Utils.bold(message.getRecipient())
+ + " [ID: " + message.getId() + ", " + (message.isReceived() ? "DELIVERED" : "QUEUED")
+ + ']',
+ true
+ );
+ }
+ }
+ }
+ else
+ {
+ send(sender, "There are no messages in the queue.", true);
+ }
+ }
+ else
+ {
+ boolean hasMessage = false;
+
+ synchronized (tellMessages)
+ {
+ for (final TellMessage message : tellMessages)
+ {
+ if (message.isMatch(sender))
+ {
+ if (!hasMessage)
+ {
+ hasMessage = true;
+ send(sender, "Here are your messages: ", true);
+ }
+
+ if (message.isReceived())
+ {
+ send(sender,
+ Utils.bold(message.getSender()) + " --> " + Utils.bold(message.getRecipient())
+ + " [" + Utils.UTC_SDF.format(message.getReceived()) + ", ID: " + message.getId()
+ + ", DELIVERED]",
+ true
+ );
+
+ }
+ else
+ {
+ send(sender,
+ Utils.bold(message.getSender()) + " --> " + Utils.bold(message.getRecipient())
+ + " [" + Utils.UTC_SDF.format(message.getQueued()) + ", ID: " + message.getId()
+ + ", QUEUED]",
+ true
+ );
+ }
+
+ send(sender, DOUBLE_INDENT + message.getMessage(), true);
+ }
+ }
+ }
+
+ if (!hasMessage)
+ {
+ send(sender, "You have no messages in the queue.", true);
+ }
+ else
+ {
+ send(sender, "To delete a message that you sent:");
+ send(sender,
+ DOUBLE_INDENT + Utils
+ .bold(getNick() + ": " + Commands.TELL_CMD + ' ' + Commands.TELL_DEL_CMD + " ")
+ );
+ send(sender, "Messages are kept for about " + Utils.bold(tellMaxDays) + " days.");
+ }
+ }
+ }
+ else if (cmds.startsWith(Commands.TELL_DEL_CMD + ' '))
+ {
+ final String[] split = cmds.split(" ");
+
+ if (split.length == 2)
+ {
+ final String id = split[1];
+ boolean deleted = false;
+ boolean found = false;
+
+ synchronized (tellMessages)
+ {
+ for (final TellMessage message : tellMessages)
+ {
+ found = message.isMatchId(id);
+
+ if (found && (message.getSender().equalsIgnoreCase(sender) || isOp(sender)))
+ {
+ tellMessages.remove(message);
+
+ saveTellMessages();
+ send(sender, "Your message was deleted from the queue.", true);
+ deleted = true;
+ break;
+ }
+ }
+ }
+
+ if (!deleted)
+ {
+ if (found)
+ {
+ send(sender, "Only messages that you sent can be deleted.", true);
+ }
+ else
+ {
+ send(sender, "The specified message [ID " + id + "] could not be found.", true);
+ }
+ }
+ }
+ else
+ {
+ helpResponse(sender, Commands.TELL_CMD);
+ }
+ }
+ else
+ {
+ final String[] split = cmds.split(" ", 2);
+
+ if (split.length == 2 && (Utils.isValidString(split[1]) && split[1].contains(" ")))
+ {
+ if (tellMessages.size() < tellMaxSize)
+ {
+ final TellMessage message = new TellMessage(sender, split[0], split[1].trim());
+
+ tellMessages.add(message);
+
+ saveTellMessages();
+
+ send(sender,
+ "Message [ID " + message.getId() + "] was queued for " + Utils.bold(message.getRecipient()),
+ true);
+ }
+ else
+ {
+ send(sender, "Sorry, the messages queue is currently full.", true);
+ }
+ }
+ else
+ {
+ helpResponse(sender, Commands.TELL_CMD);
+ }
+ }
+
+ cleanTellMessages();
+ }
+
+ /**
+ * Responds with the title and links from the RSS feed.
*
* @param sender The nick of the person who sent the private message.
*/
private void feedResponse(String sender)
{
- if (isValidString(feedURL))
+ if (Utils.isValidString(feedURL))
{
new Thread(new FeedReader(this, sender, feedURL)).start();
}
@@ -2543,26 +2403,6 @@ public class Mobibot extends PircBot
return buff.toString();
}
- /**
- * Get today's date.
- *
- * @return Today's date.
- */
- private synchronized String getToday()
- {
- return today;
- }
-
- /**
- * Set today's date.
- *
- * @param today Today's date.
- */
- private synchronized void setToday(String today)
- {
- this.today = today;
- }
-
/**
* Responds with the Google search results for the specified query.
*
@@ -2571,16 +2411,14 @@ public class Mobibot extends PircBot
*/
private void googleResponse(String sender, String query)
{
-
if (query.length() > 0)
{
new Thread(new GoogleSearch(this, sender, query)).start();
}
else
{
- helpResponse(sender, GOOGLE_CMD);
+ helpResponse(sender, Commands.GOOGLE_CMD);
}
-
}
/**
@@ -2590,8 +2428,8 @@ public class Mobibot extends PircBot
*/
private boolean isTwitterEnabled()
{
- return isValidString(twitterConsumerKey) && isValidString(twitterConsumerSecret) && isValidString(twitterToken)
- && isValidString(twitterTokenSecret);
+ return Utils.isValidString(twitterConsumerKey) && Utils.isValidString(twitterConsumerSecret) && Utils
+ .isValidString(twitterToken) && Utils.isValidString(twitterTokenSecret);
}
/**
@@ -2616,7 +2454,7 @@ public class Mobibot extends PircBot
}
else
{
- helpResponse(sender, TWITTER_CMD);
+ helpResponse(sender, Commands.TWITTER_CMD);
}
}
else
@@ -2649,7 +2487,7 @@ public class Mobibot extends PircBot
final long minutes = timeInSeconds / 60L;
send(sender,
"Uptime: " + days + " day(s) " + hours + " hour(s) " + minutes + " minute(s) [Entries: " + entries.size()
- + ']',
+ + (isTellEnabled() && isOp(sender) ? ", Messages: " + tellMessages.size() : "") + ']',
isPrivate
);
}
@@ -2680,7 +2518,7 @@ public class Mobibot extends PircBot
*/
private boolean isIgnoredNick(String nick)
{
- return isValidString(nick) && ignoredNicks.contains(nick.toLowerCase());
+ return Utils.isValidString(nick) && ignoredNicks.contains(nick.toLowerCase());
}
@@ -2697,7 +2535,6 @@ public class Mobibot extends PircBot
for (final User user : users)
{
-
if (user.getNick().equals(sender))
{
return user.isOp();
@@ -2707,132 +2544,6 @@ public class Mobibot extends PircBot
return false;
}
- /**
- * Loads the backlogs.
- *
- * @param file The file containing the backlogs.
- *
- * @throws FileNotFoundException If the file was not found.
- * @throws FeedException If an error occurred while reading the feed.
- */
- private void loadBacklogs(String file)
- throws FileNotFoundException, FeedException
- {
- history.clear();
-
- final SyndFeedInput input = new SyndFeedInput();
-
- InputStreamReader reader = null;
-
- try
- {
- reader = new InputStreamReader(new FileInputStream(new File(file)));
-
- final SyndFeed feed = input.build(reader);
-
- final List items = feed.getEntries();
- SyndEntry item;
-
- for (int i = items.size() - 1; i >= 0; i--)
- {
- item = (SyndEntryImpl) items.get(i);
- history.add(item.getTitle());
- }
- }
- finally
- {
- if (reader != null)
- {
- try
- {
- reader.close();
- }
- catch (IOException ignore)
- {
- ; // Do nothing
- }
- }
- }
-
- }
-
- /**
- * Loads the current entries.
- *
- * @param file The file containing the current entries.
- *
- * @throws FileNotFoundException If the file was not found.
- * @throws FeedException If an error occurred while reading the feed.
- */
- @SuppressWarnings("unchecked")
- private void loadEntries(String file)
- throws FileNotFoundException, FeedException
- {
- entries.clear();
-
- final SyndFeedInput input = new SyndFeedInput();
-
- InputStreamReader reader = null;
-
- try
- {
- reader = new InputStreamReader(new FileInputStream(new File(file)));
-
- final SyndFeed feed = input.build(reader);
-
- setToday(ISO_SDF.format(feed.getPublishedDate()));
-
- final List items = feed.getEntries();
- SyndEntry item;
- SyndContent description;
- String[] comments;
- String author;
- EntryLink entry;
-
- for (int i = items.size() - 1; i >= 0; i--)
- {
- item = (SyndEntryImpl) items.get(i);
- author = item.getAuthor()
- .substring(item.getAuthor().lastIndexOf('(') + 1, item.getAuthor().length() - 1);
- entry = new EntryLink(item.getLink(),
- item.getTitle(),
- author,
- getChannel(),
- item.getPublishedDate(),
- item.getCategories());
- description = item.getDescription();
- comments = description.getValue().split(" ");
-
- int split;
- for (final String comment : comments)
- {
- split = comment.indexOf(": ");
-
- if (split != -1)
- {
- entry.addComment(comment.substring(split + 2).trim(), comment.substring(0, split).trim());
- }
- }
-
- entries.add(entry);
- }
- }
- finally
- {
- if (reader != null)
- {
- try
- {
- reader.close();
- }
- catch (IOException ignore)
- {
- ; // Do nothing
- }
- }
- }
- }
-
/**
* Responds with the results of a DNS query.
*
@@ -2845,7 +2556,7 @@ public class Mobibot extends PircBot
{
try
{
- send(getChannel(), lookup(query));
+ send(getChannel(), Lookup.lookup(query));
}
catch (UnknownHostException ignore)
{
@@ -2854,7 +2565,7 @@ public class Mobibot extends PircBot
{
try
{
- final String[] lines = whois(query);
+ final String[] lines = Lookup.whois(query);
if ((lines != null) && (lines.length > 0))
{
@@ -2893,7 +2604,7 @@ public class Mobibot extends PircBot
}
else
{
- helpResponse(sender, LOOKUP_CMD);
+ helpResponse(sender, Commands.LOOKUP_CMD);
}
}
@@ -2905,297 +2616,12 @@ public class Mobibot extends PircBot
*/
private void recapResponse(String sender, boolean isPrivate)
{
- for (final String recap : RECAP_ARRAY)
+ for (final String recap : this.recap)
{
send(sender, recap, isPrivate);
}
}
- /**
- * Saves the entries.
- *
- * @param isDayBackup Set the true if the daily backup file should also be created.
- */
- private void saveEntries(boolean isDayBackup)
- {
- if (logger.isDebugEnabled())
- {
- logger.debug("Saving...");
- }
-
- if (isValidString(logsDir) && isValidString(weblogURL))
- {
- FileWriter fw = null;
-
- try
- {
- fw = new FileWriter(new File(logsDir + CURRENT_XML));
-
- SyndFeed rss = new SyndFeedImpl();
- rss.setFeedType("rss_2.0");
- rss.setTitle(getChannel() + " IRC Links");
- rss.setDescription("Links from " + ircServer + " on " + getChannel());
- rss.setLink(weblogURL);
- rss.setPublishedDate(Calendar.getInstance().getTime());
- rss.setLanguage("en");
-
- EntryLink entry;
- StringBuffer buff;
- EntryComment comment;
- final List items = new ArrayList(0);
- SyndEntry item;
- SyndContent description;
-
- for (int i = (entries.size() - 1); i >= 0; --i)
- {
- entry = entries.get(i);
-
- buff = new StringBuffer(
- "Posted by " + entry.getNick() + " on " + entry.getChannel() + ""
- );
-
- if (entry.getCommentsCount() > 0)
- {
- buff.append("
");
-
- final EntryComment[] comments = entry.getComments();
-
- for (int j = 0; j < comments.length; j++)
- {
- comment = comments[j];
-
- if (j > 0)
- {
- buff.append(" ");
- }
-
- buff.append(comment.getNick()).append(": ").append(comment.getComment());
- }
- }
-
- item = new SyndEntryImpl();
- item.setLink(entry.getLink());
- description = new SyndContentImpl();
- description.setValue(buff.toString());
- item.setDescription(description);
- item.setTitle(entry.getTitle());
- item.setPublishedDate(entry.getDate());
- item.setAuthor(getChannel().substring(1) + '@' + ircServer + " (" + entry.getNick() + ')');
- item.setCategories(entry.getTags());
-
- items.add(item);
- }
-
- rss.setEntries(items);
-
- if (logger.isDebugEnabled())
- {
- logger.debug("Writing the entries feed.");
- }
-
- final SyndFeedOutput output = new SyndFeedOutput();
- output.output(rss, fw);
- fw.close();
-
- fw = new FileWriter(new File(logsDir + getToday() + ".xml"));
- output.output(rss, fw);
-
- if (isDayBackup)
- {
- if (isValidString(backlogsURL))
- {
- if (history.indexOf(getToday()) == -1)
- {
- history.add(getToday());
-
- while (history.size() > MAX_BACKLOGS)
- {
- history.remove(0);
- }
- }
-
- fw.close();
- fw = new FileWriter(new File(logsDir + NAV_XML));
- rss = new SyndFeedImpl();
- rss.setFeedType("rss_2.0");
- rss.setTitle(getChannel() + " IRC Links Backlogs");
- rss.setDescription("Backlogs of Links from " + ircServer + " on " + getChannel());
- rss.setLink(backlogsURL);
- rss.setPublishedDate(Calendar.getInstance().getTime());
-
- String date;
- items.clear();
-
- for (int i = (history.size() - 1); i >= 0; --i)
- {
- date = history.get(i);
-
- item = new SyndEntryImpl();
- item.setLink(backlogsURL + date + ".xml");
- item.setTitle(date);
- description = new SyndContentImpl();
- description.setValue("Links for " + date);
- item.setDescription(description);
-
- items.add(item);
- }
-
- rss.setEntries(items);
-
- if (logger.isDebugEnabled())
- {
- logger.debug("Writing the backlog feed.");
- }
-
- output.output(rss, fw);
- }
- else
- {
- logger.warn("Unable to generate the backlogs feed. No property configured.");
- }
- }
- }
- catch (Exception e)
- {
- logger.warn("Unable to generate the feed.", e);
- }
- finally
- {
- try
- {
- if (fw != null)
- {
- fw.close();
- }
- }
- catch (Exception ignore)
- {
- ; // Do nothing
- }
- }
- }
- else
- {
- logger.warn("Unable to generate the feed. At least one of the required property is missing.");
- }
- }
-
- /**
- * Sets the backlogs URL.
- *
- * @param backlogsURL The backlogs URL.
- */
- private void setBacklogsURL(String backlogsURL)
- {
- this.backlogsURL = backlogsURL;
- }
-
- /**
- * Sets the del.icio.us authentication.
- *
- * @param username The del.icio.us username.
- * @param password The del.icio.us password.
- */
- private void setDeliciousAuth(String username, String password)
- {
- delicious = new DeliciousPoster(username, password, ircServer);
- }
-
- /**
- * Sets the feed URL.
- *
- * @param feedURL The feed URL.
- */
- private void setFeedURL(String feedURL)
- {
- this.feedURL = feedURL;
- }
-
- /**
- * Sets the Twitter consumerSecret and password..
- *
- * @param consumerKey The Twitter consumer key.
- * @param consumerSecret The Twitter consumer secret.
- * @param token The Twitter token.
- * @param tokenSecret The Twitter token secret.
- */
- private void setTwitterAuth(String consumerKey, String consumerSecret, String token, String tokenSecret)
- {
- twitterConsumerKey = consumerKey;
- twitterConsumerSecret = consumerSecret;
- twitterToken = token;
- twitterTokenSecret = tokenSecret;
- }
-
- /**
- * Sets the ident password.
- *
- * @param pwd The password.
- */
- private void setIdent(String pwd)
- {
- ident = pwd;
- }
-
- /**
- * Sets the ident message.
- *
- * @param msg The message.
- */
- private void setIdentMsg(String msg)
- {
- identMsg = msg;
- }
-
- /**
- * Sets the ident nickname.
- *
- * @param nick The nickname.
- */
- private void setIdentNick(String nick)
- {
- identNick = nick;
- }
-
- /**
- * Sets the Ignored nicks.
- *
- * @param nicks The nicks to ignore
- */
- private void setIgnoredNicks(String nicks)
- {
- if (isValidString(nicks))
- {
- final StringTokenizer st = new StringTokenizer(nicks, ",");
-
- while (st.hasMoreTokens())
- {
- ignoredNicks.add(st.nextToken().trim().toLowerCase());
- }
- }
- }
-
- /**
- * Sets the default tags/categories.
- *
- * @param tags The tags.
- */
- private void setTags(String tags)
- {
- defaultTags = tags;
- }
-
- /**
- * Sets the weblog URL.
- *
- * @param weblogURL The weblog URL.
- */
- private void setWeblogURL(String weblogURL)
- {
- this.weblogURL = weblogURL;
- }
-
/**
* Responds with the specified stock quote.
*
@@ -3210,56 +2636,7 @@ public class Mobibot extends PircBot
}
else
{
- helpResponse(sender, STOCK_CMD);
- }
- }
-
- /**
- * Responds with the current time.
- *
- * @param sender The nick of the person who sent the message.
- * @param args The time command arguments.
- * @param isPrivate Set to true is the response should be send as a private message.
- */
- private void timeResponse(String sender, String args, boolean isPrivate)
- {
- boolean isInvalidTz = false;
- final String tz = (COUNTRIES_MAP.get((args.substring(args.indexOf(' ') + 1).trim().toUpperCase())));
- final String response;
-
- if (tz != null)
- {
- if (tz.equals(BEATS_KEYWORD))
- {
- response = ("The current Internet Time is: " + internetTime() + ' ' + BEATS_KEYWORD);
- }
- else
- {
- TIME_SDF.setTimeZone(TimeZone.getTimeZone(tz));
- response = TIME_SDF.format(Calendar.getInstance().getTime()) + tz.substring(tz.indexOf('/') + 1)
- .replace('_', ' ');
- }
- }
- else
- {
- isInvalidTz = true;
- response = "The supported time zones/countries are: " + COUNTRIES_MAP.keySet().toString();
- }
-
- if (isPrivate)
- {
- send(sender, response, true);
- }
- else
- {
- if (isInvalidTz)
- {
- send(sender, response);
- }
- else
- {
- send(getChannel(), response);
- }
+ helpResponse(sender, Commands.STOCK_CMD);
}
}
@@ -3366,8 +2743,9 @@ public class Mobibot extends PircBot
if (sent > MAX_ENTRIES)
{
send(sender,
- "To view more, try: " + bold(
- getNick() + ": " + VIEW_CMD + ' ' + (i + 1) + ' ' + lcArgs), isPrivate
+ "To view more, try: " + Utils
+ .bold(getNick() + ": " + Commands.VIEW_CMD + ' ' + (i + 1) + ' ' + lcArgs),
+ isPrivate
);
break;
@@ -3382,7 +2760,7 @@ public class Mobibot extends PircBot
if (sent > MAX_ENTRIES)
{
send(sender,
- "To view more, try: " + bold(getNick() + ": " + VIEW_CMD + ' ' + (i + 1)),
+ "To view more, try: " + Utils.bold(getNick() + ": " + Commands.VIEW_CMD + ' ' + (i + 1)),
isPrivate);
break;
diff --git a/src/main/java/net/thauvin/erik/mobibot/Quote.java b/src/main/java/net/thauvin/erik/mobibot/Quote.java
index a839584..721a384 100644
--- a/src/main/java/net/thauvin/erik/mobibot/Quote.java
+++ b/src/main/java/net/thauvin/erik/mobibot/Quote.java
@@ -1,7 +1,7 @@
/*
* @(#)Quote.java
*
- * Copyright (c) 2014, Erik C. Thauvin (erik@thauvin.net)
+ * Copyright (c) 2004-2014, Erik C. Thauvin (erik@thauvin.net)
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -30,10 +30,8 @@
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * $Id$
- *
*/
+
package net.thauvin.erik.mobibot;
import org.jibble.pircbot.Colors;
@@ -53,6 +51,13 @@ import java.net.URLConnection;
*/
public class Quote implements Runnable
{
+
+ /**
+ * The I Heart Quotes URL.
+ */
+ private static final String QUOTE_URL =
+ "http://www.iheartquotes.com/api/v1/random?format=json&max_lines=1&source=esr+humorix_misc+humorix_stories+joel_on_software+macintosh+math+mav_flame+osp_rules+paul_graham+prog_style+subversion";
+
/**
* The bot.
*/
@@ -82,7 +87,7 @@ public class Quote implements Runnable
{
try
{
- final URL url = new URL("http://www.iheartquotes.com/api/v1/random?format=json&max_lines=1");
+ final URL url = new URL(QUOTE_URL);
final URLConnection conn = url.openConnection();
final StringBuilder sb = new StringBuilder();
@@ -96,7 +101,7 @@ public class Quote implements Runnable
final JSONObject json = new JSONObject(sb.toString());
- bot.send(bot.getChannel(), Colors.BLUE + json.getString("quote") + Colors.BLUE);
+ bot.send(bot.getChannel(), Colors.CYAN + json.getString("quote") + Colors.CYAN);
reader.close();
}
diff --git a/src/main/java/net/thauvin/erik/mobibot/ReleaseInfo.java b/src/main/java/net/thauvin/erik/mobibot/ReleaseInfo.java
index d8ebe4e..7caf1ec 100644
--- a/src/main/java/net/thauvin/erik/mobibot/ReleaseInfo.java
+++ b/src/main/java/net/thauvin/erik/mobibot/ReleaseInfo.java
@@ -1,59 +1,115 @@
+/*
+ * @(#)ReleaseInfo.java
+ *
+ * Copyright (c) 2004-2014, Erik C. Thauvin (erik@thauvin.net)
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the author nor the names of its contributors may be
+ * used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
/* Created by JReleaseInfo AntTask from Open Source Competence Group */
-/* Creation date Sun Apr 20 23:26:28 PDT 2014 */
+/* Creation date Fri Apr 25 18:08:16 PDT 2014 */
package net.thauvin.erik.mobibot;
import java.util.Date;
/**
* This class provides information gathered from the build environment.
- *
+ *
* @author JReleaseInfo AntTask
*/
-public class ReleaseInfo {
+public class ReleaseInfo
+{
- /**
- * Disables the default constructor.
- * @throws UnsupportedOperationException if the constructor is called.
- */
- private ReleaseInfo() throws UnsupportedOperationException {
- throw new UnsupportedOperationException("Illegal constructor call.");
- }
+ /**
+ * buildDate (set during build process to 1398474496363L).
+ */
+ private static final Date buildDate = new Date(1398474496363L);
+ /**
+ * project (set during build process to "mobibot").
+ */
+ private static final String project = "mobibot";
- /** buildDate (set during build process to 1398061588708L). */
- private static final Date buildDate = new Date(1398061588708L);
+ /**
+ * version (set during build process to "0.6").
+ */
+ private static final String version = "0.6";
- /**
- * Get buildDate (set during build process to Sun Apr 20 23:26:28 PDT 2014).
- * @return Date buildDate
- */
- public static Date getBuildDate() { return buildDate; }
+ /**
+ * Disables the default constructor.
+ *
+ * @throws UnsupportedOperationException if the constructor is called.
+ */
+ private ReleaseInfo()
+ throws UnsupportedOperationException
+ {
+ throw new UnsupportedOperationException("Illegal constructor call.");
+ }
+ /**
+ * Get buildDate (set during build process to Fri Apr 25 18:08:16 PDT 2014).
+ *
+ * @return Date buildDate
+ */
+ public static Date getBuildDate()
+ {
+ return buildDate;
+ }
- /** project (set during build process to "mobibot"). */
- private static final String project = "mobibot";
+ /**
+ * Get project (set during build process to "mobibot").
+ *
+ * @return String project
+ */
+ public static String getProject()
+ {
+ return project;
+ }
- /**
- * Get project (set during build process to "mobibot").
- * @return String project
- */
- public static String getProject() { return project; }
+ /**
+ * Get version (set during build process to "0.6").
+ *
+ * @return String version
+ */
+ public static String getVersion()
+ {
+ return version;
+ }
-
- /** version (set during build process to "0.6"). */
- private static final String version = "0.6";
-
- /**
- * Get version (set during build process to "0.6").
- * @return String version
- */
- public static String getVersion() { return version; }
-
-
- /**
- * Get buildNumber (set during build process to 0).
- * @return int buildNumber
- */
- public static int getBuildNumber() { return 0; }
+ /**
+ * Get buildNumber (set during build process to 0).
+ *
+ * @return int buildNumber
+ */
+ public static int getBuildNumber()
+ {
+ return 0;
+ }
}
diff --git a/src/main/java/net/thauvin/erik/mobibot/StockQuote.java b/src/main/java/net/thauvin/erik/mobibot/StockQuote.java
index f453f3c..492c1f5 100644
--- a/src/main/java/net/thauvin/erik/mobibot/StockQuote.java
+++ b/src/main/java/net/thauvin/erik/mobibot/StockQuote.java
@@ -1,7 +1,7 @@
/*
* @(#)StockQuote.java
*
- * Copyright (c) 2004, Erik C. Thauvin (erik@thauvin.net)
+ * Copyright (c) 2004-2014, Erik C. Thauvin (erik@thauvin.net)
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -30,10 +30,8 @@
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * $Id$
- *
*/
+
package net.thauvin.erik.mobibot;
import com.Ostermiller.util.CSVParser;
@@ -46,7 +44,6 @@ import java.io.IOException;
* Retrieves a stock quote from Yahoo!.
*
* @author Erik C. Thauvin
- * @version $Revision$, $Date$
* @created Feb 7, 2004
* @since 1.0
*/
diff --git a/src/main/java/net/thauvin/erik/mobibot/SwingWorker.java b/src/main/java/net/thauvin/erik/mobibot/SwingWorker.java
index 6c49325..2ff6379 100644
--- a/src/main/java/net/thauvin/erik/mobibot/SwingWorker.java
+++ b/src/main/java/net/thauvin/erik/mobibot/SwingWorker.java
@@ -1,133 +1,159 @@
package net.thauvin.erik.mobibot;
-import javax.swing.SwingUtilities;
+import javax.swing.*;
/**
- * This is the 3rd version of SwingWorker (also known as
- * SwingWorker 3), an abstract class that you subclass to
- * perform GUI-related work in a dedicated thread. For
- * instructions on and examples of using this class, see:
- *
+ * This is the 3rd version of SwingWorker (also known as SwingWorker 3), an abstract class that you subclass to perform
+ * GUI-related work in a dedicated thread. For instructions on and examples of using this class, see:
+ *
* http://java.sun.com/docs/books/tutorial/uiswing/misc/threads.html
- *
- * Note that the API changed slightly in the 3rd version:
- * You must now invoke start() on the SwingWorker after
- * creating it.
+ *
+ * Note that the API changed slightly in the 3rd version: You must now invoke start() on the SwingWorker after creating
+ * it.
*
* @noinspection ALL
*/
-public abstract class SwingWorker {
- private Object value; // see getValue(), setValue()
+public abstract class SwingWorker
+{
+ private Object value; // see getValue(), setValue()
- /**
- * Class to maintain reference to current worker thread
- * under separate synchronization control.
- */
- private static class ThreadVar {
- private Thread thread;
- ThreadVar(Thread t) { thread = t; }
- synchronized Thread get() { return thread; }
- synchronized void clear() { thread = null; }
- }
+ private ThreadVar threadVar;
- private ThreadVar threadVar;
+ /**
+ * Start a thread that will call the construct method and then exit.
+ */
+ public SwingWorker()
+ {
+ final Runnable doFinished = new Runnable()
+ {
+ public void run()
+ {
+ finished();
+ }
+ };
- /**
- * Get the value produced by the worker thread, or null if it
- * hasn't been constructed yet.
- */
- protected synchronized Object getValue() {
- return value;
- }
+ Runnable doConstruct = new Runnable()
+ {
+ public void run()
+ {
+ try
+ {
+ setValue(construct());
+ }
+ finally
+ {
+ threadVar.clear();
+ }
- /**
- * Set the value produced by worker thread
- */
- private synchronized void setValue(Object x) {
- value = x;
- }
+ SwingUtilities.invokeLater(doFinished);
+ }
+ };
- /**
- * Compute the value to be returned by the get method.
- */
- public abstract Object construct();
+ Thread t = new Thread(doConstruct);
+ threadVar = new ThreadVar(t);
+ }
- /**
- * Called on the event dispatching thread (not on the worker thread)
- * after the construct method has returned.
- */
- public void finished() {
- }
+ /**
+ * Called on the event dispatching thread (not on the worker thread) after the construct method has
+ * returned.
+ */
+ public void finished()
+ {
+ }
- /**
- * A new method that interrupts the worker thread. Call this method
- * to force the worker to stop what it's doing.
- */
- public void interrupt() {
- Thread t = threadVar.get();
- if (t != null) {
- t.interrupt();
- }
- threadVar.clear();
- }
+ /**
+ * Compute the value to be returned by the get method.
+ */
+ public abstract Object construct();
- /**
- * Return the value created by the construct method.
- * Returns null if either the constructing thread or the current
- * thread was interrupted before a value was produced.
- *
- * @return the value created by the construct method
- */
- public Object get() {
- while (true) {
- Thread t = threadVar.get();
- if (t == null) {
- return getValue();
- }
- try {
- t.join();
- }
- catch (InterruptedException e) {
- Thread.currentThread().interrupt(); // propagate
- return null;
- }
- }
- }
+ /**
+ * A new method that interrupts the worker thread. Call this method to force the worker to stop what it's doing.
+ */
+ public void interrupt()
+ {
+ Thread t = threadVar.get();
+ if (t != null)
+ {
+ t.interrupt();
+ }
+ threadVar.clear();
+ }
+ /**
+ * Return the value created by the construct method. Returns null if either the constructing thread or
+ * the current thread was interrupted before a value was produced.
+ *
+ * @return the value created by the construct method
+ */
+ public Object get()
+ {
+ while (true)
+ {
+ Thread t = threadVar.get();
+ if (t == null)
+ {
+ return getValue();
+ }
+ try
+ {
+ t.join();
+ }
+ catch (InterruptedException e)
+ {
+ Thread.currentThread().interrupt(); // propagate
+ return null;
+ }
+ }
+ }
- /**
- * Start a thread that will call the construct method
- * and then exit.
- */
- public SwingWorker() {
- final Runnable doFinished = new Runnable() {
- public void run() { finished(); }
- };
+ /**
+ * Get the value produced by the worker thread, or null if it hasn't been constructed yet.
+ */
+ protected synchronized Object getValue()
+ {
+ return value;
+ }
- Runnable doConstruct = new Runnable() {
- public void run() {
- try {
- setValue(construct());
- }
- finally {
- threadVar.clear();
- }
+ /**
+ * Set the value produced by worker thread
+ */
+ private synchronized void setValue(Object x)
+ {
+ value = x;
+ }
- SwingUtilities.invokeLater(doFinished);
- }
- };
+ /**
+ * Start the worker thread.
+ */
+ public void start()
+ {
+ Thread t = threadVar.get();
+ if (t != null)
+ {
+ t.start();
+ }
+ }
- Thread t = new Thread(doConstruct);
- threadVar = new ThreadVar(t);
- }
+ /**
+ * Class to maintain reference to current worker thread under separate synchronization control.
+ */
+ private static class ThreadVar
+ {
+ private Thread thread;
- /**
- * Start the worker thread.
- */
- public void start() {
- Thread t = threadVar.get();
- if (t != null) {
- t.start();
- }
- }
+ ThreadVar(Thread t)
+ {
+ thread = t;
+ }
+
+ synchronized Thread get()
+ {
+ return thread;
+ }
+
+ synchronized void clear()
+ {
+ thread = null;
+ }
+ }
}
diff --git a/src/main/java/net/thauvin/erik/mobibot/TellMessage.java b/src/main/java/net/thauvin/erik/mobibot/TellMessage.java
new file mode 100644
index 0000000..1872208
--- /dev/null
+++ b/src/main/java/net/thauvin/erik/mobibot/TellMessage.java
@@ -0,0 +1,146 @@
+/*
+ * @(#)TellMessage.java
+ *
+ * Copyright (c) 2004-2014, Erik C. Thauvin (erik@thauvin.net)
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the author nor the names of its contributors may be
+ * used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package net.thauvin.erik.mobibot;
+
+import java.io.Serializable;
+import java.util.Calendar;
+import java.util.Date;
+
+/**
+ * The TellMessage class.
+ *
+ * @author Erik C. Thauvin
+ * @created 2014-04-24
+ * @since 1.0
+ */
+public class TellMessage implements Serializable
+{
+ private static final long serialVersionUID = 1L;
+
+ private final String sender;
+
+ private final String recipient;
+
+ private final String message;
+
+ private final String id;
+
+ final private Date queued;
+
+ private Date received;
+
+ private boolean isReceived;
+
+ private boolean isNotified;
+
+ /**
+ * Create a new message.
+ *
+ * @param sender The sender's nick.
+ * @param recipient The recipient's nick.
+ * @param message The message.
+ */
+ public TellMessage(String sender, String recipient, String message)
+ {
+ this.sender = sender;
+ this.recipient = recipient;
+ this.message = message;
+
+ this.queued = Calendar.getInstance().getTime();
+ this.id = Utils.TIMESTAMP_SDF.format(this.queued);
+
+ }
+
+ public String getSender()
+ {
+ return sender;
+ }
+
+ public String getRecipient()
+ {
+ return recipient;
+ }
+
+ public String getMessage()
+ {
+ return message;
+ }
+
+ public Date getQueued()
+ {
+ return queued;
+ }
+
+ public Date getReceived()
+ {
+ return received;
+ }
+
+ public void setReceived()
+ {
+ this.received = Calendar.getInstance().getTime();
+ this.isReceived = true;
+ }
+
+ public boolean isNotified()
+ {
+ return this.isNotified;
+ }
+
+ public void setNotified()
+ {
+ this.isNotified = true;
+ }
+
+ public String getId()
+ {
+ return this.id;
+ }
+
+ public boolean isReceived()
+ {
+ return this.isReceived;
+ }
+
+ public boolean isMatchId(String id)
+ {
+ return this.id.equals(id);
+ }
+
+ public boolean isMatch(String nick)
+ {
+ return (sender.equalsIgnoreCase(nick) || recipient.equalsIgnoreCase(nick));
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/net/thauvin/erik/mobibot/TellMessagesMgr.java b/src/main/java/net/thauvin/erik/mobibot/TellMessagesMgr.java
new file mode 100644
index 0000000..c54f636
--- /dev/null
+++ b/src/main/java/net/thauvin/erik/mobibot/TellMessagesMgr.java
@@ -0,0 +1,156 @@
+/*
+ * @(#)TellMessagesMgr.java
+ *
+ * Copyright (c) 2004-2014, Erik C. Thauvin (erik@thauvin.net)
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the author nor the names of its contributors may be
+ * used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package net.thauvin.erik.mobibot;
+
+import org.apache.commons.logging.impl.Log4JLogger;
+
+import java.io.*;
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.List;
+
+/**
+ * Managers the {@link Commands#TELL_CMD} messages.
+ *
+ * @author Erik C. Thauvin
+ * @created 2014-04-26
+ * @since 1.0
+ */
+public class TellMessagesMgr
+{
+ /**
+ * Disables the default constructor.
+ *
+ * @throws UnsupportedOperationException if an error occurred. if the constructor is called.
+ */
+ private TellMessagesMgr()
+ throws UnsupportedOperationException
+ {
+ throw new UnsupportedOperationException("Illegal constructor call.");
+ }
+
+ /**
+ * Loads the messages.
+ *
+ * @param file The serialized objects file.
+ * @param logger The logger.
+ *
+ * @return The {@link net.thauvin.erik.mobibot.TellMessage} array.
+ */
+ @SuppressWarnings("unchecked")
+ public static List load(String file, Log4JLogger logger)
+ {
+ try
+ {
+ final ObjectInput input = new ObjectInputStream(new BufferedInputStream(new FileInputStream(file)));
+
+ try
+ {
+
+ return ((List) input.readObject());
+ }
+ finally
+ {
+ input.close();
+ }
+ }
+ catch (FileNotFoundException ignore)
+ {
+ ; // Do nothing.
+ }
+ catch (IOException e)
+ {
+ logger.error("An IO error occurred loading the messages queue.", e);
+ }
+ catch (Exception e)
+ {
+ logger.getLogger().error("An error occurred loading the messages queue.", e);
+ }
+
+ return (List) new ArrayList();
+ }
+
+ /**
+ * Saves the messages.
+ *
+ * @param file The serialized objects file.
+ * @param messages The {@link net.thauvin.erik.mobibot.TellMessage} array.
+ * @param logger The logger.
+ */
+ public static void save(String file, List messages, Log4JLogger logger)
+ {
+ try
+ {
+ final ObjectOutput output = new ObjectOutputStream(new BufferedOutputStream(new FileOutputStream(file)));
+
+ try
+ {
+ output.writeObject(messages);
+ }
+ finally
+ {
+ output.close();
+ }
+ }
+ catch (IOException e)
+ {
+ logger.error("Unable to save messages queue.", e);
+ }
+ }
+
+ /**
+ * Cleans the messages queue.
+ */
+ public static void cleanTellMessages(List tellMessages, int tellMaxDays)
+ {
+ final Calendar maxDate = Calendar.getInstance();
+ final Date today = new Date();
+
+ synchronized (tellMessages)
+ {
+ for (final TellMessage message : tellMessages)
+ {
+ maxDate.setTime(message.getQueued());
+ maxDate.add(Calendar.DATE, tellMaxDays);
+
+ if (maxDate.getTime().before(today))
+ {
+ tellMessages.remove(message);
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/net/thauvin/erik/mobibot/Twitter.java b/src/main/java/net/thauvin/erik/mobibot/Twitter.java
index 6742092..23fd404 100644
--- a/src/main/java/net/thauvin/erik/mobibot/Twitter.java
+++ b/src/main/java/net/thauvin/erik/mobibot/Twitter.java
@@ -1,7 +1,7 @@
/*
* @(#)Twitter.java
*
- * Copyright (C) 2007 Erik C. Thauvin
+ * Copyright (c) 2004-2014, Erik C. Thauvin (erik@thauvin.net)
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -30,10 +30,8 @@
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * $Id$
- *
*/
+
package net.thauvin.erik.mobibot;
import twitter4j.Status;
@@ -44,7 +42,6 @@ import twitter4j.conf.ConfigurationBuilder;
* Inserts presence information into Twitter.
*
* @author Erik C. Thauvin
- * @version $Revision$, $Date$
* @created Sept 10, 2008
* @since 1.0
*/
@@ -121,8 +118,8 @@ public class Twitter implements Runnable
final Status status = twitter.updateStatus(message + " (" + sender + ')');
bot.send(sender,
- "You message was posted to http://twitter.com/" + twitter.getScreenName() + "/statuses/" + status
- .getId()
+ "You message was posted to http://twitter.com/" + twitter.getScreenName() + "/statuses/" + status
+ .getId()
);
}
catch (Exception e)
diff --git a/src/main/java/net/thauvin/erik/mobibot/TwitterOAuth.java b/src/main/java/net/thauvin/erik/mobibot/TwitterOAuth.java
index 06b8589..1bcb5ba 100644
--- a/src/main/java/net/thauvin/erik/mobibot/TwitterOAuth.java
+++ b/src/main/java/net/thauvin/erik/mobibot/TwitterOAuth.java
@@ -20,7 +20,6 @@ import java.io.InputStreamReader;
*
* @author Erik C. Thauvin
* @author http://twitter4j.org/en/code-examples.html#oauth
- * @version $Revision$, $Date$
* @created Sep 13, 2010
* @since 1.0
*/
diff --git a/src/main/java/net/thauvin/erik/mobibot/Utils.java b/src/main/java/net/thauvin/erik/mobibot/Utils.java
new file mode 100644
index 0000000..3ff10ab
--- /dev/null
+++ b/src/main/java/net/thauvin/erik/mobibot/Utils.java
@@ -0,0 +1,309 @@
+/*
+ * @(#)Utils.java
+ *
+ * Copyright (c) 2004-2014, Erik C. Thauvin (erik@thauvin.net)
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the author nor the names of its contributors may be
+ * used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package net.thauvin.erik.mobibot;
+
+import org.jibble.pircbot.Colors;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.nio.channels.FileChannel;
+import java.text.SimpleDateFormat;
+import java.util.Calendar;
+
+/**
+ * Miscellaneous utilities class.
+ *
+ * @author Erik C. Thauvin
+ * @created 2014-04-26
+ * @since 1.0
+ */
+public class Utils
+{
+ /**
+ * The timestamp simple date format.
+ */
+ public static final SimpleDateFormat TIMESTAMP_SDF = new SimpleDateFormat("yyyyMMddHHmmss");
+
+ /**
+ * The UTC (yyyy-MM-dd HH:mm) simple date format.
+ */
+ static final SimpleDateFormat UTC_SDF = new SimpleDateFormat("yyyy-MM-dd HH:mm");
+
+ /**
+ * The ISO (YYYY-MM-DD) simple date format.
+ */
+ static final SimpleDateFormat ISO_SDF = new SimpleDateFormat("yyyy-MM-dd");
+
+ /**
+ * Disables the default constructor.
+ *
+ * @throws UnsupportedOperationException if an error occurred. if the constructor is called.
+ */
+ private Utils()
+ throws UnsupportedOperationException
+ {
+ throw new UnsupportedOperationException("Illegal constructor call.");
+ }
+
+ /**
+ * Converts XML/XHTML entities to plain text.
+ *
+ * @param str The string to unescape.
+ *
+ * @return The unescaped string.
+ */
+ public static String unescapeXml(String str)
+ {
+ String s = str.replaceAll("&", "&");
+ s = s.replaceAll("<", "<");
+ s = s.replaceAll(">", ">");
+ s = s.replaceAll(""", "\"");
+ s = s.replaceAll("'", "'");
+ s = s.replaceAll("'", "'");
+
+ return s;
+ }
+
+ /**
+ * Copies a file.
+ *
+ * @param in The source file.
+ * @param out The destination file.
+ *
+ * @throws java.io.IOException If the file could not be copied.
+ * @noinspection UnusedDeclaration
+ */
+ public static void copyFile(File in, File out)
+ throws IOException
+ {
+ FileChannel inChannel = null;
+ FileChannel outChannel = null;
+ FileInputStream input = null;
+ FileOutputStream output = null;
+
+ try
+ {
+ input = new FileInputStream(in);
+ output = new FileOutputStream(out);
+
+ inChannel = input.getChannel();
+ outChannel = output.getChannel();
+
+ inChannel.transferTo(0L, inChannel.size(), outChannel);
+ }
+ finally
+ {
+ try
+ {
+ if (inChannel != null)
+ {
+ inChannel.close();
+ }
+
+ if (input != null)
+ {
+ input.close();
+ }
+ }
+ catch (Exception ignore)
+ {
+ ; // Do nothing
+ }
+
+ try
+ {
+ if (outChannel != null)
+ {
+ outChannel.close();
+ }
+
+ if (output != null)
+ {
+ output.close();
+ }
+ }
+ catch (Exception ignore)
+ {
+ ; // Do nothing
+ }
+ }
+ }
+
+ /**
+ * Returns the current Internet (beat) Time.
+ *
+ * @return The Internet Time string.
+ */
+ public static String internetTime()
+ {
+ final Calendar gc = Calendar.getInstance();
+
+ final int offset = (gc.get(Calendar.ZONE_OFFSET) / (60 * 60 * 1000));
+ int hh = gc.get(Calendar.HOUR_OF_DAY);
+ final int mm = gc.get(Calendar.MINUTE);
+ final int ss = gc.get(Calendar.SECOND);
+
+ hh -= offset; // GMT
+ hh += 1; // BMT
+
+ long beats = Math.round(Math.floor((double) ((((hh * 3600) + (mm * 60) + ss) * 1000) / 86400)));
+
+ if (beats >= 1000)
+ {
+ beats -= (long) 1000;
+ }
+ else if (beats < 0)
+ {
+ beats += (long) 1000;
+ }
+
+ if (beats < 10)
+ {
+ return ("@00" + String.valueOf(beats));
+ }
+ else if (beats < 100)
+ {
+ return ("@0" + String.valueOf(beats));
+ }
+
+ return ('@' + String.valueOf(beats));
+ }
+
+ /**
+ * Returns a property as an int.
+ *
+ * @param property The port property value.
+ * @param def The default property value.
+ *
+ * @return The port or default value if invalid.
+ */
+ public static int getIntProperty(String property, int def)
+ {
+ int prop;
+
+ try
+ {
+ prop = Integer.parseInt(property);
+ }
+ catch (NumberFormatException ignore)
+ {
+ prop = def;
+ }
+
+ return prop;
+ }
+
+ /**
+ * Ensures that the given location (File/URL) has a trailing slash (/) to indicate a directory.
+ *
+ * @param location The File or URL location.
+ * @param isUrl Set to true if the location is a URL
+ *
+ * @return The location ending with a slash.
+ */
+ public static String ensureDir(String location, boolean isUrl)
+ {
+ if (isUrl)
+ {
+ if (location.charAt(location.length() - 1) == '/')
+ {
+ return location;
+ }
+ else
+ {
+ return location + '/';
+ }
+ }
+ else
+ {
+ if (location.charAt(location.length() - 1) == File.separatorChar)
+ {
+ return location;
+ }
+ else
+ {
+ return location + File.separatorChar;
+ }
+ }
+ }
+
+ /**
+ * Returns true if the given string is valid.
+ *
+ * @param s The string to validate.
+ *
+ * @return true if the string is non-empty and not null, false otherwise.
+ */
+ public static boolean isValidString(String s)
+ {
+ return (s != null) && (s.trim().length() > 0);
+ }
+
+ /**
+ * Makes the given int bold.
+ *
+ * @param i The int.
+ *
+ * @return The bold string.
+ */
+ public static String bold(int i)
+ {
+ return Colors.BOLD + i + Colors.BOLD;
+ }
+
+ /**
+ * Returns today's date.
+ *
+ * @return Today's date in {@link #ISO_SDF ISO} format.
+ */
+ public static String today()
+ {
+ return ISO_SDF.format(Calendar.getInstance().getTime());
+ }
+
+ /**
+ * Makes the given string bold.
+ *
+ * @param s The string.
+ *
+ * @return The bold string.
+ */
+ public static String bold(String s)
+ {
+ return Colors.BOLD + s + Colors.BOLD;
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/net/thauvin/erik/mobibot/War.java b/src/main/java/net/thauvin/erik/mobibot/War.java
new file mode 100644
index 0000000..6430374
--- /dev/null
+++ b/src/main/java/net/thauvin/erik/mobibot/War.java
@@ -0,0 +1,110 @@
+/*
+ * @(#)War.java
+ *
+ * Copyright (c) 2004-2014, Erik C. Thauvin (erik@thauvin.net)
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the author nor the names of its contributors may be
+ * used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package net.thauvin.erik.mobibot;
+
+import java.util.Random;
+
+/**
+ * The War class.
+ *
+ * @author Erik C. Thauvin
+ * @created 2014-04-28
+ * @since 1.0
+ */
+public class War
+{
+ /**
+ * The deck of card for the {@link net.thauvin.erik.mobibot.Commands#WAR_CMD war} command.
+ */
+ private static final String[] WAR_DECK =
+ new String[]{"Ace", "King", "Queen", "Jack", "10", "9", "8", "7", "6", "5", "4", "3", "2"};
+
+ /**
+ * The suits for the deck of card for the {@link Commands#WAR_CMD war} command.
+ */
+ private static final String[] WAR_SUITS = new String[]{"Hearts", "Spades", "Diamonds", "Clubs"};
+
+ /**
+ * Disables the default constructor.
+ *
+ * @throws UnsupportedOperationException if an error occurred. if the constructor is called.
+ */
+ private War()
+ throws UnsupportedOperationException
+ {
+ throw new UnsupportedOperationException("Illegal constructor call.");
+ }
+
+ /**
+ * Plays war.
+ *
+ * @param bot The bot.
+ * @param sender The sender's nickname.
+ */
+ public static void play(Mobibot bot, String sender)
+ {
+ final Random r = new Random();
+
+ int i;
+ int y;
+
+ while (true)
+ {
+ i = r.nextInt(WAR_DECK.length);
+ y = r.nextInt(WAR_DECK.length);
+
+ bot.send(bot.getChannel(),
+ sender + " drew the " + Utils.bold(WAR_DECK[i]) + " of " + WAR_SUITS[r.nextInt(WAR_SUITS.length)]);
+ bot.action("drew the " + Utils.bold(WAR_DECK[y]) + " of " + WAR_SUITS[r.nextInt(WAR_SUITS.length)]);
+
+ if (i != y)
+ {
+ break;
+ }
+ }
+
+ if (i < y)
+ {
+ bot.action("lost.");
+ }
+ else if (i > y)
+ {
+ bot.action("wins.");
+ }
+ else
+ {
+ bot.action("tied.");
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/net/thauvin/erik/mobibot/Weather.java b/src/main/java/net/thauvin/erik/mobibot/Weather.java
index 9b264ec..8f8442d 100644
--- a/src/main/java/net/thauvin/erik/mobibot/Weather.java
+++ b/src/main/java/net/thauvin/erik/mobibot/Weather.java
@@ -1,7 +1,7 @@
/*
* @(#)Weather.java
*
- * Copyright (c) 2004, Erik C. Thauvin (erik@thauvin.net)
+ * Copyright (c) 2004-2014, Erik C. Thauvin (erik@thauvin.net)
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -30,10 +30,8 @@
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * $Id$
- *
*/
+
package net.thauvin.erik.mobibot;
import net.sf.jweather.metar.Metar;
@@ -48,7 +46,6 @@ import java.util.Iterator;
* Fetches the weather data from a specific station ID.
*
* @author Erik C. Thauvin
- * @version $Revision$, $Date$
* @created Feb 7, 2004
* @since 1.0
*/
@@ -116,9 +113,9 @@ public class Weather implements Runnable
bot.send(sender, "Station ID: " + metar.getStationID(), isPrivate);
bot.send(sender,
- "At: " + metar.getDateString() + " UTC (" + (
- ((new Date()).getTime() - metar.getDate().getTime()) / 1000L / 60L) + " minutes ago)",
- isPrivate
+ "At: " + Utils.UTC_SDF.format(metar.getDate()) + " UTC (" + (
+ ((new Date()).getTime() - metar.getDate().getTime()) / 1000L / 60L) + " minutes ago)",
+ isPrivate
);
result = metar.getWindSpeedInMPH();
@@ -126,28 +123,30 @@ public class Weather implements Runnable
if (result != null)
{
bot.send(sender,
- "Wind Speed: " + result + " mph, " + metar.getWindSpeedInKnots() + " knots", isPrivate);
+ "Wind Speed: " + result + " mph, " + metar.getWindSpeedInKnots() + " knots, " + metar
+ .getWindSpeedInMPS() + " m/s",
+ isPrivate
+ );
}
result = metar.getVisibility();
if (result != null)
{
- if (!metar.getVisibilityLessThan())
- {
- bot.send(sender, "Visibility: " + NUMBER_FORMAT.format(result) + " mile(s)", isPrivate);
- }
- else
- {
- bot.send(sender, "Visibility: < " + NUMBER_FORMAT.format(result) + " mile(s)", isPrivate);
- }
+ bot.send(sender,
+ "Visibility: " + (metar.getVisibilityLessThan() ? "< " : "") + NUMBER_FORMAT.format(result)
+ + " mi, " + metar.getVisibilityInKilometers() + " km",
+ isPrivate
+ );
}
result = metar.getPressure();
if (result != null)
{
- bot.send(sender, "Pressure: " + result + " in Hg", isPrivate);
+ bot.send(sender,
+ "Pressure: " + result + " Hg, " + metar.getPressureInHectoPascals() + " hPa",
+ isPrivate);
}
result = metar.getTemperatureInCelsius();
@@ -155,7 +154,8 @@ public class Weather implements Runnable
if (result != null)
{
bot.send(sender,
- "Temperature: " + result + " C, " + metar.getTemperatureInFahrenheit() + " F", isPrivate);
+ "Temperature: " + result + " \u00B0C, " + metar.getTemperatureInFahrenheit() + " \u00B0F",
+ isPrivate);
}
if (metar.getWeatherConditions() != null)
@@ -192,6 +192,6 @@ public class Weather implements Runnable
}
}
- bot.helpResponse(sender, Mobibot.WEATHER_CMD);
+ bot.helpResponse(sender, Commands.WEATHER_CMD);
}
}
diff --git a/src/main/java/net/thauvin/erik/mobibot/WorldTime.java b/src/main/java/net/thauvin/erik/mobibot/WorldTime.java
new file mode 100644
index 0000000..e22514f
--- /dev/null
+++ b/src/main/java/net/thauvin/erik/mobibot/WorldTime.java
@@ -0,0 +1,190 @@
+/*
+ * @(#)Time.java
+ *
+ * Copyright (c) 2004-2014, Erik C. Thauvin (erik@thauvin.net)
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the author nor the names of its contributors may be
+ * used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package net.thauvin.erik.mobibot;
+
+import java.text.SimpleDateFormat;
+import java.util.Calendar;
+import java.util.Map;
+import java.util.TimeZone;
+import java.util.TreeMap;
+
+/**
+ * Processes the {@link net.thauvin.erik.mobibot.Commands#TIME_CMD} command.
+ *
+ * @author Erik C. Thauvin
+ * @created 2014-04-27
+ * @since 1.0
+ */
+public class WorldTime
+{
+ /**
+ * The countries supported by the {@link net.thauvin.erik.mobibot.Commands#TIME_CMD time} command.
+ */
+ private static final Map COUNTRIES_MAP = new TreeMap();
+
+ /**
+ * The beats (Internet Time) keyword.
+ */
+ private static final String BEATS_KEYWORD = ".beats";
+
+ /**
+ * The date/time format for the {@link net.thauvin.erik.mobibot.Commands#TIME_CMD time} command.
+ */
+ private static final SimpleDateFormat TIME_SDF =
+ new SimpleDateFormat("'The time is 'HH:mm' on 'EEEE, d MMMM yyyy' in '");
+
+ /**
+ * Creates a new time object.
+ */
+ public WorldTime()
+ {
+ // Initialize the countries map
+ COUNTRIES_MAP.put("AU", "Australia/Sydney");
+ COUNTRIES_MAP.put("BE", "Europe/Brussels");
+ COUNTRIES_MAP.put("CA", "America/Montreal");
+ COUNTRIES_MAP.put("CDT", "America/Chicago");
+ COUNTRIES_MAP.put("CET", "CET");
+ COUNTRIES_MAP.put("CH", "Europe/Zurich");
+ COUNTRIES_MAP.put("CN", "Asia/Shanghai");
+ COUNTRIES_MAP.put("CST", "America/Chicago");
+ COUNTRIES_MAP.put("CU", "Cuba");
+ COUNTRIES_MAP.put("DE", "Europe/Berlin");
+ COUNTRIES_MAP.put("DK", "Europe/Copenhagen");
+ COUNTRIES_MAP.put("EDT", "America/New_York");
+ COUNTRIES_MAP.put("EG", "Africa/Cairo");
+ COUNTRIES_MAP.put("ER", "Africa/Asmara");
+ COUNTRIES_MAP.put("ES", "Europe/Madrid");
+ COUNTRIES_MAP.put("EST", "America/New_York");
+ COUNTRIES_MAP.put("FI", "Europe/Helsinki");
+ COUNTRIES_MAP.put("FR", "Europe/Paris");
+ COUNTRIES_MAP.put("GB", "Europe/London");
+ COUNTRIES_MAP.put("GMT", "GMT");
+ COUNTRIES_MAP.put("HK", "Asia/Hong_Kong");
+ COUNTRIES_MAP.put("HST", "HST");
+ COUNTRIES_MAP.put("IE", "Europe/Dublin");
+ COUNTRIES_MAP.put("IL", "Asia/Tel_Aviv");
+ COUNTRIES_MAP.put("IN", "Asia/Calcutta");
+ COUNTRIES_MAP.put("IR", "Asia/Tehran");
+ COUNTRIES_MAP.put("IS", "Atlantic/Reykjavik");
+ COUNTRIES_MAP.put("IT", "Europe/Rome");
+ COUNTRIES_MAP.put("JM", "Jamaica");
+ COUNTRIES_MAP.put("JP", "Asia/Tokyo");
+ COUNTRIES_MAP.put("LY", "Africa/Tripoli");
+ COUNTRIES_MAP.put("MDT", "America/Denver");
+ COUNTRIES_MAP.put("MH", "Kwajalein");
+ COUNTRIES_MAP.put("MST", "America/Denver");
+ COUNTRIES_MAP.put("MX", "America/Mexico_City");
+ COUNTRIES_MAP.put("NL", "Europe/Amsterdam");
+ COUNTRIES_MAP.put("NO", "Europe/Oslo");
+ COUNTRIES_MAP.put("NP", "Asia/Katmandu");
+ COUNTRIES_MAP.put("NZ", "Pacific/Auckland");
+ COUNTRIES_MAP.put("PDT", "America/Los_Angeles");
+ COUNTRIES_MAP.put("PK", "Asia/Karachi");
+ COUNTRIES_MAP.put("PL", "Europe/Warsaw");
+ COUNTRIES_MAP.put("PST", "America/Los_Angeles");
+ COUNTRIES_MAP.put("PT", "Europe/Lisbon");
+ COUNTRIES_MAP.put("RU", "Europe/Moscow");
+ COUNTRIES_MAP.put("SE", "Europe/Stockholm");
+ COUNTRIES_MAP.put("SG", "Asia/Singapore");
+ COUNTRIES_MAP.put("SU", "Europe/Moscow");
+ COUNTRIES_MAP.put("TH", "Asia/Bangkok");
+ COUNTRIES_MAP.put("TM", "Asia/Ashgabat");
+ COUNTRIES_MAP.put("TR", "Europe/Istanbul");
+ COUNTRIES_MAP.put("TW", "Asia/Taipei");
+ COUNTRIES_MAP.put("UK", "Europe/London");
+ COUNTRIES_MAP.put("US", "America/New_York");
+ COUNTRIES_MAP.put("UTC", "UTC");
+ COUNTRIES_MAP.put("VA", "Europe/Vatican");
+ COUNTRIES_MAP.put("VN", "Asia/Ho_Chi_Minh");
+ COUNTRIES_MAP.put("INTERNET", BEATS_KEYWORD);
+ COUNTRIES_MAP.put("BEATS", BEATS_KEYWORD);
+
+ for (final String tz : TimeZone.getAvailableIDs())
+ {
+ if (!tz.contains("/") && tz.length() == 3 & !COUNTRIES_MAP.containsKey(tz))
+ {
+ COUNTRIES_MAP.put(tz, tz);
+ }
+ }
+ }
+
+ /**
+ * Responds with the current time.
+ *
+ * @param sender The nick of the person who sent the message.
+ * @param args The time command arguments.
+ * @param isPrivate Set to true is the response should be send as a private message.
+ */
+ public final void timeResponse(Mobibot bot, String sender, String args, boolean isPrivate)
+ {
+ boolean isInvalidTz = false;
+ final String tz = (COUNTRIES_MAP.get((args.substring(args.indexOf(' ') + 1).trim().toUpperCase())));
+ final String response;
+
+ if (tz != null)
+ {
+ if (tz.equals(BEATS_KEYWORD))
+ {
+ response = ("The current Internet Time is: " + Utils.internetTime() + ' ' + BEATS_KEYWORD);
+ }
+ else
+ {
+ TIME_SDF.setTimeZone(TimeZone.getTimeZone(tz));
+ response = TIME_SDF.format(Calendar.getInstance().getTime()) + tz.substring(tz.indexOf('/') + 1)
+ .replace('_', ' ');
+ }
+ }
+ else
+ {
+ isInvalidTz = true;
+ response = "The supported time zones/countries are: " + COUNTRIES_MAP.keySet().toString();
+ }
+
+ if (isPrivate)
+ {
+ bot.send(sender, response, true);
+ }
+ else
+ {
+ if (isInvalidTz)
+ {
+ bot.send(sender, response);
+ }
+ else
+ {
+ bot.send(bot.getChannel(), response);
+ }
+ }
+ }
+}
\ No newline at end of file