diff --git a/build.xml b/build.xml index fffa1e0..7b71d76 100644 --- a/build.xml +++ b/build.xml @@ -20,11 +20,11 @@ - + - + diff --git a/lib/commons-httpclient-2.0-final.jar b/lib/commons-httpclient-2.0-final.jar deleted file mode 100644 index 8bd4a24..0000000 Binary files a/lib/commons-httpclient-2.0-final.jar and /dev/null differ diff --git a/lib/commons-httpclient-2.0.1.jar b/lib/commons-httpclient-2.0.1.jar new file mode 100644 index 0000000..65f9e3b Binary files /dev/null and b/lib/commons-httpclient-2.0.1.jar differ diff --git a/mobibot.iml b/mobibot.iml index 9c10d54..5d6c1f0 100644 --- a/mobibot.iml +++ b/mobibot.iml @@ -1,5 +1,5 @@ - + @@ -81,15 +81,6 @@ - - - - - - - - - @@ -117,24 +108,6 @@ - - - - - - - - - - - - - - - - - - @@ -153,6 +126,34 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mobibot.ipr b/mobibot.ipr index f44f2ae..7c5dcf4 100644 --- a/mobibot.ipr +++ b/mobibot.ipr @@ -1,21 +1,26 @@ + - + + + - - - - + + false false false false + false + + false + false - + @@ -38,6 +43,9 @@ + + + @@ -49,12 +57,26 @@ + + @@ -96,19 +118,130 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + + + diff --git a/mobibot.iws b/mobibot.iws index 3b59918..f4db17e 100644 --- a/mobibot.iws +++ b/mobibot.iws @@ -11,6 +11,7 @@ + @@ -88,13 +95,13 @@ + - - + + - - - + - + + + + - + @@ -213,6 +229,7 @@ + @@ -226,24 +243,7 @@ - - - - - - + - + + + + + + + + - - - - localhost - 5050 - false - - - - - + + - + + - + - - + + - + + @@ -349,6 +376,7 @@ + @@ -363,6 +391,7 @@ @@ -420,41 +449,15 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -469,18 +472,32 @@ + + + + + + + - + + + + + + + + - + @@ -489,7 +506,7 @@ - + @@ -498,21 +515,21 @@ - + - + - + @@ -521,7 +538,7 @@ - + @@ -530,7 +547,7 @@ - + @@ -565,7 +582,7 @@ - + diff --git a/src/net/thauvin/erik/mobibot/Mobibot.java b/src/net/thauvin/erik/mobibot/Mobibot.java index 7ada31c..c6f4d64 100644 --- a/src/net/thauvin/erik/mobibot/Mobibot.java +++ b/src/net/thauvin/erik/mobibot/Mobibot.java @@ -47,13 +47,17 @@ import org.apache.commons.net.WhoisClient; import org.apache.log4j.Level; -import org.jibble.pircbot.*; +import org.jibble.pircbot.Colors; +import org.jibble.pircbot.PircBot; +import org.jibble.pircbot.User; import java.io.*; import java.net.InetAddress; import java.net.UnknownHostException; +import java.nio.channels.FileChannel; + import java.text.SimpleDateFormat; import java.util.*; @@ -78,11 +82,8 @@ public class Mobibot extends PircBot /** * The info strings. */ - private static final String[] INFO_STRS = - { - "Mobibot v0.1.3b5 by Erik C. Thauvin (erik@thauvin.net)", - "http://www.thauvin.net/mobitopia/mobibot/" - }; + private static final String[] INFO_STRS = + { "Mobibot v0.1.3b12 by Erik C. Thauvin (erik@thauvin.net)", "http://www.thauvin.net/mobitopia/mobibot/" }; /** * Debug command line argument. @@ -197,7 +198,7 @@ public class Mobibot extends PircBot /** * The link match string. */ - private static final String LINK_MATCH = "http://"; + private static final String LINK_MATCH = "^[hH][tT][tT][pP](|[sS])://.*"; /** * The lookup command. @@ -242,7 +243,8 @@ public class Mobibot extends PircBot /** * 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 '"); + private static final SimpleDateFormat TIME_SDF = + new SimpleDateFormat("'The time is 'HH:mm' on 'EEE, d MMM yyyy' in '"); /** * The beats (Internet Time) keyword. @@ -269,11 +271,6 @@ public class Mobibot extends PircBot */ private static final String VIEW_CMD = "view"; - /** - * The view "all" keyword. - */ - private static final String VIEW_ALL_KEYWORD = "all"; - /** * The weather command. */ @@ -325,6 +322,7 @@ public class Mobibot extends PircBot COUNTRIES_MAP.put("NZ", "Pacific/Auckland"); 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"); @@ -350,6 +348,11 @@ public class Mobibot extends PircBot */ private static final String WHOIS_HOST = "whois.arin.net"; + /** + * The number of milliseconds to delay between consecutive messages. + */ + private static final int MESSAGE_DELAY = 1000; + /** * The logger default level. */ @@ -595,8 +598,9 @@ public class Mobibot extends PircBot try { - stdout = new PrintStream(new FileOutputStream(logsDir + channel.substring(1) + '.' + today() + - ".log", true)); + stdout = + new PrintStream(new FileOutputStream(logsDir + channel.substring(1) + '.' + today() + ".log", + true)); } catch (IOException e) { @@ -630,8 +634,8 @@ public class Mobibot extends PircBot final String googleKey = p.getProperty("google", ""); // Create the bot - final Mobibot bot = new Mobibot(server, channel, line.getOptionValue(DATA_ARG.charAt(0), "./mobibot.ser"), - logsDir); + final Mobibot bot = + new Mobibot(server, channel, line.getOptionValue(DATA_ARG.charAt(0), "./mobibot.ser"), logsDir); // Initialize the bot bot.setVerbose(true); @@ -639,6 +643,7 @@ public class Mobibot extends PircBot bot.setName(nickname); bot.setLogin(login); bot.setVersion(weblogURL); + bot.setMessageDelay(MESSAGE_DELAY); // Set the URLs bot.setWeblogURL(weblogURL); @@ -796,9 +801,7 @@ public class Mobibot extends PircBot else if (lcTopic.endsWith(VIEW_CMD)) { this.sendNotice(sender, "To list or search the current URL posts:"); - this.sendNotice(sender, - DOUBLE_INDENT + bold(getNick() + ": " + VIEW_CMD) + " []"); + this.sendNotice(sender, DOUBLE_INDENT + bold(getNick() + ": " + VIEW_CMD) + " [] []"); } else if (lcTopic.endsWith(_channel.substring(1).toLowerCase())) { @@ -943,6 +946,49 @@ public class Mobibot extends PircBot } } + /** + * Copies a file + * + * @param in The source file. + * @param out The destination file + * + * @throws IOException If the file could not be copied. + */ + public void copyFile(File in, File out) + throws IOException + { + FileChannel inChannel; + FileChannel outChannel; + + inChannel = new FileInputStream(in).getChannel(); + outChannel = new FileOutputStream(out).getChannel(); + + try + { + inChannel.transferTo(0, inChannel.size(), outChannel); + } + finally + { + try + { + inChannel.close(); + } + catch (IOException ignore) + { + ; // Do nothing + } + + try + { + outChannel.close(); + } + catch (IOException ignore) + { + ; // Do nothing + } + } + } + /** * This method is called whenever an ACTION is sent from a user. * @@ -1019,9 +1065,7 @@ public class Mobibot extends PircBot { _logger.debug(">>> " + sender + ": " + message); - final String lcMsg = message.toLowerCase(); - - if ((lcMsg.startsWith(LINK_MATCH)) && (lcMsg.length() > LINK_MATCH.length())) + if (message.matches(LINK_MATCH)) { final String[] cmds = message.split(" ", 2); final String cmd = cmds[0].trim(); @@ -1061,7 +1105,7 @@ public class Mobibot extends PircBot this.sendNotice(sender, "Duplicate >> " + buildLink(dupIndex, entry)); } } - else if (lcMsg.matches(getNick() + ":.*")) + else if (message.matches(getNickPattern() + ":.*")) { final String[] cmds = message.substring(message.indexOf(':') + 1).trim().split(" ", 2); final String cmd = cmds[0].toLowerCase(); @@ -1079,15 +1123,14 @@ public class Mobibot extends PircBot } else if (cmd.equals(PING_CMD)) { - final String[] pings = - { - "is barely alive.", "is trying to stay awake.", "has gone fishing.", - "is somewhere over the rainbow.", "has fallen and can't get up.", - "is running. You better go chase it.", "has just spontantiously combusted.", - "is talking to itself... don't interrupt. That's rude.", - "is bartending at an AA meeting.", "is hibernating.", - "is saving energy: apathetic mode activated.", "is busy. Go away!" - }; + final String[] pings = + { + "is barely alive.", "is trying to stay awake.", "has gone fishing.", + "is somewhere over the rainbow.", "has fallen and can't get up.", + "is running. You better go chase it.", "has just spontantiously combusted.", + "is talking to itself... don't interrupt. That's rude.", "is bartending at an AA meeting.", + "is hibernating.", "is saving energy: apathetic mode activated.", "is busy. Go away!" + }; final Random r = new Random(); @@ -1251,7 +1294,7 @@ public class Mobibot extends PircBot { final String link = cmd.substring(1); - if ((link.length() > (LINK_MATCH.length())) && link.toLowerCase().startsWith(LINK_MATCH)) + if (link.matches(LINK_MATCH)) { entry.setLink(link); this.sendNotice(_channel, buildLink(index, entry)); @@ -2075,6 +2118,15 @@ public class Mobibot extends PircBot _logger.debug("Unable to close the data file stream.", e); } } + + try + { + copyFile(new File(_data), new File(_data + ".bak")); + } + catch (IOException e) + { + _logger.warn("Unable to backup the data file.", e); + } } /** @@ -2084,7 +2136,6 @@ public class Mobibot extends PircBot */ private static void sleep(int secs) { - /* try { Thread.sleep((long) (secs * 1000)); @@ -2093,14 +2144,6 @@ public class Mobibot extends PircBot { ; // Do nothing } - */ - - final long stop = System.currentTimeMillis() + ((long) secs * 1000); - - while (System.currentTimeMillis() <= stop) - { - ; // Do nothing - } } /** @@ -2227,8 +2270,9 @@ public class Mobibot extends PircBot else { TIME_SDF.setTimeZone(TimeZone.getTimeZone(tz)); - response = TIME_SDF.format(Calendar.getInstance().getTime()) + - tz.substring(tz.indexOf('/') + 1).replace('_', ' '); + response = + TIME_SDF.format(Calendar.getInstance().getTime()) + + tz.substring(tz.indexOf('/') + 1).replace('_', ' '); } } else @@ -2264,6 +2308,34 @@ public class Mobibot extends PircBot return ISO_SDF.format(Calendar.getInstance().getTime()); } + /** + * Returns the bot's nickname regexp pattern. + * + * @return The nickname regexp pattern. + */ + private final String getNickPattern() + { + final StringBuffer buff = new StringBuffer(0); + final String nick = getNick(); + char c; + + for (int i = 0; i < nick.length(); i++) + { + c = nick.charAt(i); + + if (Character.isLetter(c)) + { + buff.append('[').append(String.valueOf(c).toLowerCase()).append(String.valueOf(c).toUpperCase()).append(']'); + } + else + { + buff.append(c); + } + } + + return buff.toString(); + } + /** * Responds with the users on a channel. * @@ -2301,36 +2373,89 @@ public class Mobibot extends PircBot */ private void viewResponse(String sender, String args, boolean isPrivate) { - final String lcArgs = args.toLowerCase(); + String lcArgs = args.toLowerCase(); if (!_entries.isEmpty()) { final int max = _entries.size(); int i = 0; - if (!(args.length() > 0) && (max > MAX_ENTRIES)) + if (!(lcArgs.length() > 0) && (max > MAX_ENTRIES)) { i = max - MAX_ENTRIES; } + if (lcArgs.matches("^\\d+(| .*)")) + { + final String[] split = lcArgs.split(" ", 2); + + try + { + i = Integer.parseInt(split[0]); + + if (i > 0) + { + i--; + } + + if (split.length == 2) + { + lcArgs = split[1].trim(); + } + else + { + lcArgs = ""; + } + + if (i > max) + { + i = 0; + } + } + catch (NumberFormatException ignore) + { + ; // Do nothing + } + } + EntryLink entry; + int sent = 0; for (; i < max; i++) { entry = (EntryLink) _entries.get(i); - if ((args.length() > 0) && !(args.equals(VIEW_ALL_KEYWORD))) + if (lcArgs.length() > 0) { if ((entry.getLink().toLowerCase().indexOf(lcArgs) != -1) || (entry.getTitle().toLowerCase().indexOf(lcArgs) != -1) || (entry.getNick().toLowerCase().indexOf(lcArgs) != -1)) { + if (sent > MAX_ENTRIES) + { + send(sender, + "To view more, try: " + + bold(getNick() + ": " + VIEW_CMD + ' ' + (i + 1) + ' ' + lcArgs), isPrivate); + + break; + } + send(sender, buildLink(i, entry, true), isPrivate); + sent++; } } else { + if (sent > MAX_ENTRIES) + { + send(sender, "To view more, try: " + bold(getNick() + ": " + VIEW_CMD + ' ' + (i + 1)), + isPrivate); + + break; + } + send(sender, buildLink(i, entry, true), isPrivate); + sent++; } } }