Added support for Google Custom Search Engine.

Optimized for Java 8.
This commit is contained in:
Erik C. Thauvin 2016-06-26 23:50:13 -07:00
parent 62c011234e
commit e5064f0e0e
14 changed files with 152 additions and 80 deletions

View file

@ -94,7 +94,7 @@
<option name="myForwardDirection" value="false" /> <option name="myForwardDirection" value="false" />
</component> </component>
<component name="DependencyValidationManager"> <component name="DependencyValidationManager">
<scope name="Source" pattern="file:src/main/java/net/thauvin/erik/mobibot/*&amp;&amp;!file:src/main/java/net/thauvin/erik/mobibot/SwingWorker.java&amp;&amp;!file:src/main/java/net/thauvin/erik/mobibot/TwitterOAuth.java" /> <scope name="Source" pattern="file[mobibot_annotationProcessor]:java/net/thauvin/erik/mobibot/*||file[mobibot_main]:java/net/thauvin/erik/mobibot/*" />
<option name="SKIP_IMPORT_STATEMENTS" value="false" /> <option name="SKIP_IMPORT_STATEMENTS" value="false" />
</component> </component>
<component name="EclipseCompilerSettings"> <component name="EclipseCompilerSettings">

View file

@ -25,3 +25,6 @@ tell-max-size=50
#twitter-consumerSecret= #twitter-consumerSecret=
#twitter-token= #twitter-token=
#twitter-tokenSecret= #twitter-tokenSecret=
#google-api=
#google-cse-cx=

View file

@ -13,8 +13,8 @@ import java.util.Date;
* Annotation Processor</a> * Annotation Processor</a>
*/ */
public final class ReleaseInfo { public final class ReleaseInfo {
private final static String buildmeta = "005"; private final static String buildmeta = "006";
private final static Date date = new Date(1466989732969L); private final static Date date = new Date(1467010048201L);
private final static int major = 0; private final static int major = 0;
private final static int minor = 6; private final static int minor = 6;
private final static int patch = 1; private final static int patch = 1;

View file

@ -40,7 +40,10 @@ import org.jdom2.input.SAXBuilder;
import java.io.IOException; import java.io.IOException;
import java.net.URL; import java.net.URL;
import java.text.NumberFormat; import java.text.NumberFormat;
import java.util.*; import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.TreeMap;
/** /**
* Processes the {@link Commands#CURRENCY_CMD} command. * Processes the {@link Commands#CURRENCY_CMD} command.
@ -54,7 +57,7 @@ class CurrencyConverter implements Runnable
/** /**
* The exchange rates. * The exchange rates.
*/ */
private static final Map<String, String> EXCHANGE_RATES = new TreeMap<String, String>(); private static final Map<String, String> EXCHANGE_RATES = new TreeMap<>();
/** /**
* The exchange rates table URL. * The exchange rates table URL.

View file

@ -249,7 +249,7 @@ final class EntriesMgr
EntryLink entry; EntryLink entry;
StringBuffer buff; StringBuffer buff;
EntryComment comment; EntryComment comment;
final List<SyndEntry> items = new ArrayList<SyndEntry>(0); final List<SyndEntry> items = new ArrayList<>(0);
SyndEntry item; SyndEntry item;
SyndContent description; SyndContent description;

View file

@ -55,10 +55,10 @@ public class EntryLink implements Serializable
static final long serialVersionUID = 3676245542270899086L; static final long serialVersionUID = 3676245542270899086L;
// The link's comments // The link's comments
private final List<EntryComment> comments = new CopyOnWriteArrayList<EntryComment>(); private final List<EntryComment> comments = new CopyOnWriteArrayList<>();
// The tags/categories // The tags/categories
private final List<SyndCategory> tags = new CopyOnWriteArrayList<SyndCategory>(); private final List<SyndCategory> tags = new CopyOnWriteArrayList<>();
// The channel // The channel
private String channel = ""; private String channel = "";

View file

@ -106,7 +106,7 @@ class FeedReader implements Runnable
{ {
item = (SyndEntryImpl) items.get(i); item = (SyndEntryImpl) items.get(i);
bot.send(sender, item.getTitle()); bot.send(sender, item.getTitle());
bot.send(sender, TAB_INDENT + item.getLink()); bot.send(sender, TAB_INDENT + Utils.green(item.getLink()));
} }
} }
catch (MalformedURLException e) catch (MalformedURLException e)

View file

@ -59,6 +59,11 @@ class GoogleSearch implements Runnable
*/ */
private final Mobibot bot; private final Mobibot bot;
/**
* The Google Custom Search Engine ID.
*/
private final String cseCx;
/** /**
* The search query. * The search query.
*/ */
@ -73,12 +78,14 @@ class GoogleSearch implements Runnable
* Creates a new {@link GoogleSearch} instance. * Creates a new {@link GoogleSearch} instance.
* *
* @param bot The bot's instance. * @param bot The bot's instance.
* @param cseCx The Google Custom Search Engine ID.
* @param sender The nick of the person who sent the message. * @param sender The nick of the person who sent the message.
* @param query The Google query * @param query The Google query
*/ */
public GoogleSearch(final Mobibot bot, final String sender, final String query) public GoogleSearch(final Mobibot bot, final String cseCx, final String sender, final String query)
{ {
this.bot = bot; this.bot = bot;
this.cseCx = cseCx;
this.sender = sender; this.sender = sender;
this.query = query; this.query = query;
} }
@ -93,7 +100,8 @@ class GoogleSearch implements Runnable
final String query = URLEncoder.encode(this.query, "UTF-8"); final String query = URLEncoder.encode(this.query, "UTF-8");
final URL url = final URL url =
new URL("http://ajax.googleapis.com/ajax/services/search/web?start=0&rsz=small&v=1.0&q=" + query); new URL("https://www.googleapis.com/customsearch/v1?key=" + bot.getGoogleApiKey() + "&cx=" + cseCx
+ "&q=" + query + "&filter=1&num=5&alt=json");
final URLConnection conn = url.openConnection(); final URLConnection conn = url.openConnection();
final StringBuilder sb = new StringBuilder(); final StringBuilder sb = new StringBuilder();
@ -106,13 +114,13 @@ class GoogleSearch implements Runnable
} }
final JSONObject json = new JSONObject(sb.toString()); final JSONObject json = new JSONObject(sb.toString());
final JSONArray ja = json.getJSONObject("responseData").getJSONArray("results"); final JSONArray ja = json.getJSONArray("items");
for (int i = 0; i < ja.length(); i++) for (int i = 0; i < ja.length(); i++)
{ {
final JSONObject j = ja.getJSONObject(i); final JSONObject j = ja.getJSONObject(i);
bot.send(sender, Utils.unescapeXml(j.getString("titleNoFormatting"))); bot.send(sender, Utils.unescapeXml(j.getString("title")));
bot.send(sender, TAB_INDENT + j.getString("url")); bot.send(sender, TAB_INDENT + Utils.green(j.getString("link")));
} }
reader.close(); reader.close();

View file

@ -160,7 +160,7 @@ public class Mobibot extends PircBot
/** /**
* The commands list. * The commands list.
*/ */
private final List<String> commandsList = new ArrayList<String>(); private final List<String> commandsList = new ArrayList<>();
/** /**
* The currency converter. * The currency converter.
@ -170,18 +170,17 @@ public class Mobibot extends PircBot
/** /**
* The entries array. * The entries array.
*/ */
private final List<EntryLink> entries = new ArrayList<EntryLink>(0); private final List<EntryLink> entries = new ArrayList<>(0);
/** /**
* The history/backlogs array. * The history/backlogs array.
*/ */
private final List<String> history = new ArrayList<String>(0); private final List<String> history = new ArrayList<>(0);
/** /**
* The ignored nicks array. * The ignored nicks array.
*/ */
private final List<String> ignoredNicks = new ArrayList<String>(0); private final List<String> ignoredNicks = new ArrayList<>(0);
/** /**
* The IRC port. * The IRC port.
@ -211,7 +210,7 @@ public class Mobibot extends PircBot
/** /**
* The recap array. * The recap array.
*/ */
private final List<String> recap = new ArrayList<String>(0); private final List<String> recap = new ArrayList<>(0);
/** /**
* The serialized object file. * The serialized object file.
@ -221,7 +220,7 @@ public class Mobibot extends PircBot
/** /**
* Processes the {@link Commands#TELL_CMD} messages queue. * Processes the {@link Commands#TELL_CMD} messages queue.
*/ */
private final List<TellMessage> tellMessages = new CopyOnWriteArrayList<TellMessage>(); private final List<TellMessage> tellMessages = new CopyOnWriteArrayList<>();
/** /**
* Time command. * Time command.
@ -248,6 +247,16 @@ public class Mobibot extends PircBot
*/ */
private String feedURL = ""; private String feedURL = "";
/**
* The Google API Key.
*/
private String googleApiKey = "";
/**
* The Google Custom Search Engine ID.
*/
private String googleCseCx = "";
/** /**
* The NickServ ident password. * The NickServ ident password.
*/ */
@ -521,6 +530,10 @@ public class Mobibot extends PircBot
final String ttoken = p.getProperty("twitter-token", ""); final String ttoken = p.getProperty("twitter-token", "");
final String ttokenSecret = p.getProperty("twitter-tokenSecret", ""); final String ttokenSecret = p.getProperty("twitter-tokenSecret", "");
// Get the Google properties
final String googleApiKey = p.getProperty("google-api-key");
final String googleCseCx = p.getProperty("google-cse-cx");
// Get the tell command settings // Get the tell command settings
final int tellMaxDays = Utils.getIntProperty(p.getProperty("tell-max-days"), DEFAULT_TELL_MAX_DAYS); 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); final int tellMaxSize = Utils.getIntProperty(p.getProperty("tell-max-size"), DEFAULT_TELL_MAX_SIZE);
@ -560,6 +573,14 @@ public class Mobibot extends PircBot
bot.setTwitterAuth(tconsumerKey, tconsumerSecret, ttoken, ttokenSecret); bot.setTwitterAuth(tconsumerKey, tconsumerSecret, ttoken, ttokenSecret);
} }
if (Utils.isValidString(googleApiKey))
{
if (Utils.isValidString(googleCseCx))
{
bot.setGoogleAuth(googleApiKey, googleCseCx);
}
}
// Set the tags // Set the tags
bot.setTags(tags); bot.setTags(tags);
@ -695,6 +716,15 @@ public class Mobibot extends PircBot
twitterTokenSecret = tokenSecret; twitterTokenSecret = tokenSecret;
} }
/**
* Sets the Google authentication.
*/
private void setGoogleAuth(final String apiKey, final String cseCx)
{
this.googleApiKey = apiKey;
this.googleCseCx = cseCx;
}
/** /**
* Sets the default tags/categories. * Sets the default tags/categories.
* *
@ -937,6 +967,15 @@ public class Mobibot extends PircBot
return channel; return channel;
} }
/**
* Returns the Google API Key, if any.
*
* @return The Google API key or <code>empty</code>.
*/
public String getGoogleApiKey()
{
return this.googleApiKey;
}
/** /**
* Returns the irc server. * Returns the irc server.
@ -1025,13 +1064,20 @@ public class Mobibot extends PircBot
*/ */
private void googleResponse(final String sender, final String query) private void googleResponse(final String sender, final String query)
{ {
if (query.length() > 0) if (isGseEnabled())
{ {
new Thread(new GoogleSearch(this, sender, query)).start(); if (query.length() > 0)
{
new Thread(new GoogleSearch(this, googleCseCx, sender, query)).start();
}
else
{
helpResponse(sender, Commands.GOOGLE_CMD);
}
} }
else else
{ {
helpResponse(sender, Commands.GOOGLE_CMD); send(sender, "The Google searching facility is disabled.");
} }
} }
@ -1101,7 +1147,7 @@ public class Mobibot extends PircBot
send(sender, "To list the last 5 posts from the channel's weblog:"); send(sender, "To list the last 5 posts from the channel's weblog:");
send(sender, helpIndent(getNick() + ": " + channel.substring(1))); send(sender, helpIndent(getNick() + ": " + channel.substring(1)));
} }
else if (lcTopic.endsWith(Commands.GOOGLE_CMD)) else if (lcTopic.endsWith(Commands.GOOGLE_CMD) && isGseEnabled())
{ {
send(sender, "To search Google:"); send(sender, "To search Google:");
send(sender, helpIndent(getNick() + ": " + Commands.GOOGLE_CMD + " <query>")); send(sender, helpIndent(getNick() + ": " + Commands.GOOGLE_CMD + " <query>"));
@ -1255,7 +1301,6 @@ public class Mobibot extends PircBot
commandsList.add(Commands.CALC_CMD); commandsList.add(Commands.CALC_CMD);
commandsList.add(Commands.CURRENCY_CMD); commandsList.add(Commands.CURRENCY_CMD);
commandsList.add(Commands.DICE_CMD); commandsList.add(Commands.DICE_CMD);
commandsList.add(Commands.GOOGLE_CMD);
commandsList.add(Commands.IGNORE_CMD); commandsList.add(Commands.IGNORE_CMD);
commandsList.add(Commands.INFO_CMD); commandsList.add(Commands.INFO_CMD);
commandsList.add(Commands.JOKE_CMD); commandsList.add(Commands.JOKE_CMD);
@ -1281,6 +1326,11 @@ public class Mobibot extends PircBot
commandsList.add(Commands.TWITTER_CMD); commandsList.add(Commands.TWITTER_CMD);
} }
if (isGseEnabled())
{
commandsList.add(Commands.GOOGLE_CMD);
}
Collections.sort(commandsList); Collections.sort(commandsList);
} }
@ -1412,6 +1462,16 @@ public class Mobibot extends PircBot
isPrivate); isPrivate);
} }
/**
* Returns <code>true</code> if Google search is enabled.
*
* @return <code>true</code> or <code>false</code>
*/
private boolean isGseEnabled()
{
return Utils.isValidString(googleApiKey) && Utils.isValidString(googleCseCx);
}
/** /**
* Determines whether the specified nick should be ignored. * Determines whether the specified nick should be ignored.
* *
@ -1787,7 +1847,7 @@ public class Mobibot extends PircBot
viewResponse(sender, args, false); viewResponse(sender, args, false);
} }
// mobibot: google // mobibot: google
else if (cmd.startsWith(Commands.GOOGLE_CMD)) else if (cmd.startsWith(Commands.GOOGLE_CMD) && isGseEnabled())
{ {
googleResponse(sender, args); googleResponse(sender, args);
} }
@ -2316,53 +2376,49 @@ public class Mobibot extends PircBot
{ {
if (!nickname.equals(getNick()) && isTellEnabled()) if (!nickname.equals(getNick()) && isTellEnabled())
{ {
for (final TellMessage message : tellMessages) tellMessages.stream().filter(message -> message.isMatch(nickname)).forEach(message -> {
{ if (message.getRecipient().equalsIgnoreCase(nickname) && !message.isReceived())
if (message.isMatch(nickname))
{ {
if (message.getRecipient().equalsIgnoreCase(nickname) && !message.isReceived()) if (message.getSender().equals(nickname))
{ {
if (message.getSender().equals(nickname)) if (!isMessage)
{
if (!isMessage)
{
send(nickname,
Utils.bold("You") + " wanted me to remind you: " + Colors.REVERSE + message
.getMessage() + Colors.REVERSE, true);
message.setIsReceived();
message.setIsNotified();
saveTellMessages();
}
}
else
{ {
send(nickname, send(nickname,
message.getSender() + " wanted me to tell you: " + Colors.REVERSE + message Utils.bold("You") + " wanted me to remind you: " + Colors.REVERSE + message
.getMessage() + Colors.REVERSE, .getMessage() + Colors.NORMAL, true);
true);
message.setIsReceived(); message.setIsReceived();
message.setIsNotified();
saveTellMessages(); saveTellMessages();
} }
} }
else if (message.getSender().equalsIgnoreCase(nickname) && message.isReceived() && !message else
.isNotified())
{ {
send(nickname, send(nickname,
"Your message " + Colors.REVERSE + "[ID " + message.getId() + ']' + Colors.REVERSE message.getSender() + " wanted me to tell you: " + Colors.REVERSE + message.getMessage()
+ " was sent to " + Utils.bold(message.getRecipient()) + " on " + Utils.UTC_SDF + Colors.NORMAL,
.format(message.getReceived()),
true); true);
message.setIsNotified(); message.setIsReceived();
saveTellMessages(); saveTellMessages();
} }
} }
} else if (message.getSender().equalsIgnoreCase(nickname) && message.isReceived() && !message
.isNotified())
{
send(nickname,
"Your message " + Colors.REVERSE + "[ID " + message.getId() + ']' + Colors.NORMAL
+ " was sent to " + Utils.bold(message.getRecipient()) + " on " + Utils.UTC_SDF
.format(message.getReceived()),
true);
message.setIsNotified();
saveTellMessages();
}
});
} }
} }

View file

@ -101,9 +101,8 @@ final class TellMessagesMgr
{ {
try try
{ {
final ObjectInput input = new ObjectInputStream(new BufferedInputStream(new FileInputStream(file)));
try try (ObjectInput input = new ObjectInputStream(new BufferedInputStream(new FileInputStream(file))))
{ {
if (logger.isDebugEnabled()) if (logger.isDebugEnabled())
{ {
@ -112,10 +111,6 @@ final class TellMessagesMgr
return ((List<TellMessage>) input.readObject()); return ((List<TellMessage>) input.readObject());
} }
finally
{
input.close();
}
} }
catch (FileNotFoundException ignore) catch (FileNotFoundException ignore)
{ {
@ -130,7 +125,7 @@ final class TellMessagesMgr
logger.getLogger().error("An error occurred loading the messages queue.", e); logger.getLogger().error("An error occurred loading the messages queue.", e);
} }
return new ArrayList<TellMessage>(); return new ArrayList<>();
} }
/** /**
@ -144,9 +139,8 @@ final class TellMessagesMgr
{ {
try try
{ {
final ObjectOutput output = new ObjectOutputStream(new BufferedOutputStream(new FileOutputStream(file)));
try try (ObjectOutput output = new ObjectOutputStream(new BufferedOutputStream(new FileOutputStream(file))))
{ {
if (logger.isDebugEnabled()) if (logger.isDebugEnabled())
{ {
@ -155,10 +149,6 @@ final class TellMessagesMgr
output.writeObject(messages); output.writeObject(messages);
} }
finally
{
output.close();
}
} }
catch (IOException e) catch (IOException e)
{ {

View file

@ -10,7 +10,8 @@ import java.io.InputStreamReader;
/** /**
* The <code>TwitterOAuth</code> class. <p> Go to <a href="http://twitter.com/oauth_clients/new">http://twitter.com/oauth_clients/new</a> * The <code>TwitterOAuth</code> class. <p> Go to <a href="http://twitter.com/oauth_clients/new">http://twitter.com/oauth_clients/new</a>
* to register your bot. </p> Then execute: <p> <code>java -cp "mobibot.jar:lib/*" net.thauvin.erik.mobibot.TwitterOAuth * to register your bot. </p> Then execute: <p> <code>java -cp "mobibot.jar:lib/*"
* net.thauvin.erik.mobibot.TwitterOAuth
* &lt;consumerKey&gt; &lt;consumerSecret&gt;</code> </p> and follow the prompts/instructions. * &lt;consumerKey&gt; &lt;consumerSecret&gt;</code> </p> and follow the prompts/instructions.
* *
* @author <a href="mailto:erik@thauvin.net">Erik C. Thauvin</a> * @author <a href="mailto:erik@thauvin.net">Erik C. Thauvin</a>
@ -18,9 +19,9 @@ import java.io.InputStreamReader;
* @created Sep 13, 2010 * @created Sep 13, 2010
* @since 1.0 * @since 1.0
*/ */
public class TwitterOAuth public final class TwitterOAuth
{ {
public static void main(String args[]) public static void main(final String[] args)
throws Exception throws Exception
{ {
if (args.length == 2) if (args.length == 2)
@ -50,8 +51,7 @@ public class TwitterOAuth
System.out.println( System.out.println(
"Please add the following to the bot's property file:" + "\n\n" + "twitter-consumerKey=" "Please add the following to the bot's property file:" + "\n\n" + "twitter-consumerKey="
+ args[0] + '\n' + "twitter-consumerSecret=" + args[1] + '\n' + "twitter-token=" + args[0] + '\n' + "twitter-consumerSecret=" + args[1] + '\n' + "twitter-token="
+ accessToken.getToken() + '\n' + "twitter-tokenSecret=" + accessToken.getTokenSecret() + accessToken.getToken() + '\n' + "twitter-tokenSecret=" + accessToken.getTokenSecret());
);
} }
catch (TwitterException te) catch (TwitterException te)
{ {

View file

@ -142,14 +142,14 @@ final class Utils
if (Mobibot.NO_TITLE.equals(entry.getTitle())) if (Mobibot.NO_TITLE.equals(entry.getTitle()))
{ {
buff.append(bold(entry.getTitle())); buff.append(entry.getTitle());
} }
else else
{ {
buff.append(entry.getTitle()); buff.append(bold(entry.getTitle()));
} }
buff.append(" ( ").append(entry.getLink()).append(" )"); buff.append(" ( ").append(Utils.green(entry.getLink())).append(" )");
return buff.toString(); return buff.toString();
} }
@ -163,7 +163,19 @@ final class Utils
*/ */
public static String bold(final String s) public static String bold(final String s)
{ {
return Colors.BOLD + s + Colors.BOLD; return Colors.BOLD + s + Colors.NORMAL;
}
/**
* Makes the given string green.
*
* @param s The string.
*
* @return The bold string.
*/
public static String green(final String s)
{
return Colors.DARK_GREEN + s + Colors.NORMAL;
} }
/** /**

View file

@ -54,7 +54,7 @@ class WorldTime
/** /**
* The countries supported by the {@link net.thauvin.erik.mobibot.Commands#TIME_CMD time} command. * The countries supported by the {@link net.thauvin.erik.mobibot.Commands#TIME_CMD time} command.
*/ */
private static final Map<String, String> COUNTRIES_MAP = new TreeMap<String, String>(); private static final Map<String, String> COUNTRIES_MAP = new TreeMap<>();
/** /**
* The date/time format for the {@link net.thauvin.erik.mobibot.Commands#TIME_CMD time} command. * The date/time format for the {@link net.thauvin.erik.mobibot.Commands#TIME_CMD time} command.

View file

@ -5,4 +5,4 @@ version.major=0
version.minor=6 version.minor=6
version.patch=1 version.patch=1
version.prerelease=beta version.prerelease=beta
version.buildmeta=005 version.buildmeta=006