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" />
</component>
<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" />
</component>
<component name="EclipseCompilerSettings">

View file

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

View file

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

View file

@ -40,7 +40,10 @@ import org.jdom2.input.SAXBuilder;
import java.io.IOException;
import java.net.URL;
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.
@ -54,7 +57,7 @@ class CurrencyConverter implements Runnable
/**
* 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.

View file

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

View file

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

View file

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

View file

@ -59,6 +59,11 @@ class GoogleSearch implements Runnable
*/
private final Mobibot bot;
/**
* The Google Custom Search Engine ID.
*/
private final String cseCx;
/**
* The search query.
*/
@ -73,12 +78,14 @@ class GoogleSearch implements Runnable
* Creates a new {@link GoogleSearch} 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 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.cseCx = cseCx;
this.sender = sender;
this.query = query;
}
@ -93,7 +100,8 @@ class GoogleSearch implements Runnable
final String query = URLEncoder.encode(this.query, "UTF-8");
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 StringBuilder sb = new StringBuilder();
@ -106,13 +114,13 @@ class GoogleSearch implements Runnable
}
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++)
{
final JSONObject j = ja.getJSONObject(i);
bot.send(sender, Utils.unescapeXml(j.getString("titleNoFormatting")));
bot.send(sender, TAB_INDENT + j.getString("url"));
bot.send(sender, Utils.unescapeXml(j.getString("title")));
bot.send(sender, TAB_INDENT + Utils.green(j.getString("link")));
}
reader.close();

View file

@ -160,7 +160,7 @@ public class Mobibot extends PircBot
/**
* The commands list.
*/
private final List<String> commandsList = new ArrayList<String>();
private final List<String> commandsList = new ArrayList<>();
/**
* The currency converter.
@ -170,18 +170,17 @@ public class Mobibot extends PircBot
/**
* The entries array.
*/
private final List<EntryLink> entries = new ArrayList<EntryLink>(0);
private final List<EntryLink> entries = new ArrayList<>(0);
/**
* 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.
*/
private final List<String> ignoredNicks = new ArrayList<String>(0);
private final List<String> ignoredNicks = new ArrayList<>(0);
/**
* The IRC port.
@ -211,7 +210,7 @@ public class Mobibot extends PircBot
/**
* The recap array.
*/
private final List<String> recap = new ArrayList<String>(0);
private final List<String> recap = new ArrayList<>(0);
/**
* The serialized object file.
@ -221,7 +220,7 @@ public class Mobibot extends PircBot
/**
* 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.
@ -248,6 +247,16 @@ public class Mobibot extends PircBot
*/
private String feedURL = "";
/**
* The Google API Key.
*/
private String googleApiKey = "";
/**
* The Google Custom Search Engine ID.
*/
private String googleCseCx = "";
/**
* The NickServ ident password.
*/
@ -521,6 +530,10 @@ public class Mobibot extends PircBot
final String ttoken = p.getProperty("twitter-token", "");
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
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);
@ -560,6 +573,14 @@ public class Mobibot extends PircBot
bot.setTwitterAuth(tconsumerKey, tconsumerSecret, ttoken, ttokenSecret);
}
if (Utils.isValidString(googleApiKey))
{
if (Utils.isValidString(googleCseCx))
{
bot.setGoogleAuth(googleApiKey, googleCseCx);
}
}
// Set the tags
bot.setTags(tags);
@ -695,6 +716,15 @@ public class Mobibot extends PircBot
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.
*
@ -937,6 +967,15 @@ public class Mobibot extends PircBot
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.
@ -1025,13 +1064,20 @@ public class Mobibot extends PircBot
*/
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
{
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, 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, helpIndent(getNick() + ": " + Commands.GOOGLE_CMD + " <query>"));
@ -1255,7 +1301,6 @@ public class Mobibot extends PircBot
commandsList.add(Commands.CALC_CMD);
commandsList.add(Commands.CURRENCY_CMD);
commandsList.add(Commands.DICE_CMD);
commandsList.add(Commands.GOOGLE_CMD);
commandsList.add(Commands.IGNORE_CMD);
commandsList.add(Commands.INFO_CMD);
commandsList.add(Commands.JOKE_CMD);
@ -1281,6 +1326,11 @@ public class Mobibot extends PircBot
commandsList.add(Commands.TWITTER_CMD);
}
if (isGseEnabled())
{
commandsList.add(Commands.GOOGLE_CMD);
}
Collections.sort(commandsList);
}
@ -1412,6 +1462,16 @@ public class Mobibot extends PircBot
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.
*
@ -1787,7 +1847,7 @@ public class Mobibot extends PircBot
viewResponse(sender, args, false);
}
// mobibot: google
else if (cmd.startsWith(Commands.GOOGLE_CMD))
else if (cmd.startsWith(Commands.GOOGLE_CMD) && isGseEnabled())
{
googleResponse(sender, args);
}
@ -2316,53 +2376,49 @@ public class Mobibot extends PircBot
{
if (!nickname.equals(getNick()) && isTellEnabled())
{
for (final TellMessage message : tellMessages)
{
if (message.isMatch(nickname))
tellMessages.stream().filter(message -> message.isMatch(nickname)).forEach(message -> {
if (message.getRecipient().equalsIgnoreCase(nickname) && !message.isReceived())
{
if (message.getRecipient().equalsIgnoreCase(nickname) && !message.isReceived())
if (message.getSender().equals(nickname))
{
if (message.getSender().equals(nickname))
{
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
if (!isMessage)
{
send(nickname,
message.getSender() + " wanted me to tell you: " + Colors.REVERSE + message
.getMessage() + Colors.REVERSE,
true);
Utils.bold("You") + " wanted me to remind you: " + Colors.REVERSE + message
.getMessage() + Colors.NORMAL, true);
message.setIsReceived();
message.setIsNotified();
saveTellMessages();
}
}
else if (message.getSender().equalsIgnoreCase(nickname) && message.isReceived() && !message
.isNotified())
else
{
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()),
message.getSender() + " wanted me to tell you: " + Colors.REVERSE + message.getMessage()
+ Colors.NORMAL,
true);
message.setIsNotified();
message.setIsReceived();
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
{
final ObjectInput input = new ObjectInputStream(new BufferedInputStream(new FileInputStream(file)));
try
try (ObjectInput input = new ObjectInputStream(new BufferedInputStream(new FileInputStream(file))))
{
if (logger.isDebugEnabled())
{
@ -112,10 +111,6 @@ final class TellMessagesMgr
return ((List<TellMessage>) input.readObject());
}
finally
{
input.close();
}
}
catch (FileNotFoundException ignore)
{
@ -130,7 +125,7 @@ final class TellMessagesMgr
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
{
final ObjectOutput output = new ObjectOutputStream(new BufferedOutputStream(new FileOutputStream(file)));
try
try (ObjectOutput output = new ObjectOutputStream(new BufferedOutputStream(new FileOutputStream(file))))
{
if (logger.isDebugEnabled())
{
@ -155,10 +149,6 @@ final class TellMessagesMgr
output.writeObject(messages);
}
finally
{
output.close();
}
}
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>
* 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.
*
* @author <a href="mailto:erik@thauvin.net">Erik C. Thauvin</a>
@ -18,9 +19,9 @@ import java.io.InputStreamReader;
* @created Sep 13, 2010
* @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
{
if (args.length == 2)
@ -50,8 +51,7 @@ public class TwitterOAuth
System.out.println(
"Please add the following to the bot's property file:" + "\n\n" + "twitter-consumerKey="
+ 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)
{

View file

@ -142,14 +142,14 @@ final class Utils
if (Mobibot.NO_TITLE.equals(entry.getTitle()))
{
buff.append(bold(entry.getTitle()));
buff.append(entry.getTitle());
}
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();
}
@ -163,7 +163,19 @@ final class Utils
*/
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.
*/
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.

View file

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