Moved to gradle build system.

Using exp4j instead of MathEvaluator for calcuation now.
This commit is contained in:
Erik C. Thauvin 2014-04-19 21:16:53 -07:00
parent 3b9c5d6431
commit 5858e12b1a
50 changed files with 3124 additions and 1920 deletions

View file

@ -0,0 +1,224 @@
/*
* @(#)CurrencyConverter.java
*
* Copyright (c) 2004, 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.
*
* $Id$
*
*/
package net.thauvin.erik.mobibot;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.JDOMException;
import org.jdom.Namespace;
import org.jdom.input.SAXBuilder;
import java.io.IOException;
import java.net.URL;
import java.text.NumberFormat;
import java.util.*;
/**
* Converts various currencies.
*
* @author Erik C. Thauvin
* @version $Revision$, $Date$
* @created Feb 11, 2004
* @since 1.0
*/
public class CurrencyConverter implements Runnable
{
/**
* The exchange rates table URL.
*/
private static final String EXCHANGE_TABLE_URL = "http://www.ecb.int/stats/eurofxref/eurofxref-daily.xml";
/**
* The exchange rates.
*/
private static final Map EXCHANGE_RATES = new TreeMap();
/**
* The rates keyword.
*/
private static final String RATES_KEYWORD = "rates";
/**
* The bot.
*/
private final Mobibot _bot;
/**
* The actual currency _query.
*/
private final String _query;
/**
* The nick of the person who sent the message.
*/
private final String _sender;
/**
* The last exchange rates table publication date.
*/
private String s_date = "";
/**
* 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)
{
_bot = bot;
_sender = sender;
_query = query.toLowerCase();
if (!s_date.equals(date))
{
EXCHANGE_RATES.clear();
}
}
// Converts specified currencies.
public final void run()
{
if (EXCHANGE_RATES.isEmpty())
{
try
{
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);
s_date = cubeTime.getAttribute("time").getValue();
final List cubes = cubeTime.getChildren();
Element cube;
for (int i = 0; i < cubes.size(); i++)
{
cube = (Element) cubes.get(i);
EXCHANGE_RATES.put(cube.getAttribute("currency").getValue(), cube.getAttribute("rate").getValue());
}
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-z]{3}+ to [a-z]{3}+"))
{
final String[] cmds = _query.split(" ");
if (cmds.length == 4)
{
if (cmds[3].equals(cmds[1]))
{
_bot.send(_sender, "You're kidding, right?");
}
else
{
try
{
final double amt = Double.parseDouble(cmds[0].replaceAll(",", ""));
final double from = Double.parseDouble((String) EXCHANGE_RATES.get(cmds[1].toUpperCase()));
final double to = Double.parseDouble((String) 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: " + s_date);
final Iterator it = EXCHANGE_RATES.keySet().iterator();
String rate;
final StringBuffer buff = new StringBuffer(0);
while (it.hasNext())
{
rate = (String) it.next();
if (buff.length() > 0)
{
buff.append(", ");
}
buff.append(rate).append(": ").append(EXCHANGE_RATES.get(rate));
}
_bot.send(_sender, buff.toString());
}
else
{
_bot.helpResponse(_sender, Mobibot.CURRENCY_CMD + ' ' + _query);
_bot.send(_sender, "The supported currencies are: " + EXCHANGE_RATES.keySet().toString());
}
}
else
{
_bot.getLogger().debug("The exchange rate table is empty.");
_bot.send(_sender, "Sorry, but the exchange rate table is empty.");
}
}
}

View file

@ -0,0 +1,160 @@
/*
* @(#)DeliciousPoster.java
*
* Copyright (c) 2005, 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.
*
* $Id$
*
*/
package net.thauvin.erik.mobibot;
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
*/
public class DeliciousPoster
{
private final Delicious _delicious;
private final String _ircServer;
/**
* Creates a new DeliciousPoster instance.
*
* @param username The del.icio.us username.
* @param password The del.icio.us password.
* @param ircServer The IRC server.
*/
public DeliciousPoster(String username, String password, String ircServer)
{
_delicious = new Delicious(username, password);
_ircServer = ircServer;
}
/**
* Adds a post to del.icio.us.
*
* @param entry The entry to add.
*/
public final void addPost(final EntryLink entry)
{
final SwingWorker worker = new SwingWorker()
{
public Object construct()
{
return Boolean.valueOf(_delicious.addPost(entry.getLink(),
entry.getTitle(),
postedBy(entry),
entry.getDeliciousTags(),
entry.getDate()));
}
};
worker.start();
}
/**
* Deletes a post to del.icio.us.
*
* @param entry The entry to delete.
*/
public final void deletePost(EntryLink entry)
{
final String link = entry.getLink();
final SwingWorker worker = new SwingWorker()
{
public Object construct()
{
return Boolean.valueOf(_delicious.deletePost(link));
}
};
worker.start();
}
/**
* Updates a post to del.icio.us.
*
* @param oldUrl The old post URL.
* @param entry The entry to add.
*/
public final void updatePost(final String oldUrl, final EntryLink entry)
{
final SwingWorker worker = new SwingWorker()
{
public Object construct()
{
if (!oldUrl.equals(entry.getLink()))
{
_delicious.deletePost(oldUrl);
return Boolean.valueOf(_delicious.addPost(entry.getLink(),
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));
}
}
};
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 + ')';
}
}

View file

@ -0,0 +1,138 @@
/*
* @(#)EntryComment.java
*
* Copyright (c) 2004, 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.
*
* $Id$
*
*/
package net.thauvin.erik.mobibot;
import java.io.Serializable;
import java.util.Calendar;
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
*/
public class EntryComment implements Serializable
{
/**
* The serial version UID.
*/
static final long serialVersionUID = 6957415292233553224L;
/**
* The creation date.
*/
private final Date _date = Calendar.getInstance().getTime();
private String _comment = "";
private String _nick = "";
/**
* Creates a new comment.
*
* @param comment The new comment.
* @param nick The nickname of the comment's author.
*/
public EntryComment(String comment, String nick)
{
_comment = comment;
_nick = nick;
}
/**
* Creates a new comment.
* @noinspection UnusedDeclaration
*/
protected EntryComment()
{
; // Required for serialization.
}
/**
* Returns the comment.
*
* @return The comment.
*/
public final String getComment()
{
return _comment;
}
/**
* Sets the comment.
*
* @param comment The actual comment.
* @noinspection UnusedDeclaration
*/
public final void setComment(String comment)
{
_comment = comment;
}
/**
* Returns the comment's creation date.
*
* @return The date.
*/
public final Date getDate()
{
return _date;
}
/**
* Returns the nickname of the author of the comment.
*
* @return The nickname.
*/
public final String getNick()
{
return _nick;
}
/**
* Sets the nickname of the author of the comment.
*
* @param nick The new nickname.
*/
public final void setNick(String nick)
{
_nick = nick;
}
}

View file

@ -0,0 +1,449 @@
/*
* @(#)EntryLink.java
*
* Copyright (c) 2004, 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.
*
* $Id$
*
*/
package net.thauvin.erik.mobibot;
import com.sun.syndication.feed.synd.SyndCategoryImpl;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
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
*/
public class EntryLink implements Serializable
{
/**
* The serial version UID.
*/
static final long serialVersionUID = 3676245542270899086L;
// The link's comments
private final List _comments = new ArrayList(0);
// The tags/categories
private final List _tags = new ArrayList(0);
// The channel
private String _channel = "";
// The creation date
private Date _date = Calendar.getInstance().getTime();
// The link's URL
private String _link = "";
// The author's login
private String _login = "";
// The author's nickname
private String _nick = "";
// The link's title
private String _title = "";
/**
* Creates a new entry.
*
* @param link The new entry's link.
* @param title The new entry's title.
* @param nick The nickname of the author of the link.
* @param login The login of the author of the link.
* @param channel The channel.
* @param tags The entry's tags/categories.
*/
public EntryLink(String link, String title, String nick, String login, String channel, String tags)
{
_link = link;
_title = title;
_nick = nick;
_login = login;
_channel = channel;
setTags(tags);
}
/**
* Creates a new entry.
*
* @param link The new entry's link.
* @param title The new entry's title.
* @param nick The nickname of the author of the link.
* @param channel The channel.
* @param date The entry date.
* @param tags The entry's tags/categories.
*/
public EntryLink(String link, String title, String nick, String channel, Date date, List tags)
{
_link = link;
_title = title;
_nick = nick;
_channel = channel;
_date = date;
setTags(tags);
}
/**
* Creates a new EntryLink object.
* @noinspection UnusedDeclaration
*/
protected EntryLink()
{
; // Required for serialization.
}
/**
* Adds a new comment.
*
* @param comment The actual comment.
* @param nick The nickname of the author of the comment.
*
* @return The total number of comments for this entry.
*/
public final synchronized int addComment(String comment, String nick)
{
_comments.add(new EntryComment(comment, nick));
return (_comments.size() - 1);
}
/**
* Deletes a specific comment.
*
* @param index The index of the comment to delete.
*/
public final synchronized void deleteComment(int index)
{
if (index < _comments.size())
{
_comments.remove(index);
}
}
/**
* Returns the channel the link was posted on.
*
* @return The channel
*/
public final synchronized String getChannel()
{
return _channel;
}
/**
* Sets the channel.
*
* @param channel The channel.
* @noinspection UnusedDeclaration
*/
public final synchronized void setChannel(String channel)
{
_channel = channel;
}
/**
* Returns a comment.
*
* @param index The comment's index.
*
* @return The specific comment.
*/
public final synchronized EntryComment getComment(int index)
{
return ((EntryComment) _comments.get(index));
}
/**
* Returns all the comments.
*
* @return The comments.
*/
public final synchronized EntryComment[] getComments()
{
return ((EntryComment[]) _comments.toArray(new EntryComment[_comments.size()]));
}
/**
* Returns the total number of comments.
*
* @return The count of comments.
*/
public final synchronized int getCommentsCount()
{
return _comments.size();
}
/**
* Returns the comment's creation date.
*
* @return The date.
*/
public final synchronized Date getDate()
{
return _date;
}
/**
* Returns the tags formatted for del.icio.us.
*
* @return The tags as a comma-delimited string.
*/
public final synchronized String getDeliciousTags()
{
final StringBuffer tags = new StringBuffer(_nick);
for (int i = 0; i < _tags.size(); i++)
{
tags.append(',');
tags.append(((SyndCategoryImpl) _tags.get(i)).getName());
}
return tags.toString();
}
/**
* Returns the comment's link.
*
* @return The link.
*/
public final synchronized String getLink()
{
return _link;
}
/**
* Sets the comment's link.
*
* @param link The new link.
*/
public final synchronized void setLink(String link)
{
_link = link;
}
/**
* Return's the comment's author login.
*
* @return The login;
*/
public final synchronized String getLogin()
{
return _login;
}
/**
* Set the comment's author login.
*
* @param login The new login.
* @noinspection UnusedDeclaration
*/
public final synchronized void setLogin(String login)
{
_login = login;
}
/**
* Returns the comment's author nickname.
*
* @return The nickname.
*/
public final synchronized String getNick()
{
return _nick;
}
/**
* Sets the comment's author nickname.
*
* @param nick The new nickname.
*/
public final synchronized void setNick(String nick)
{
_nick = nick;
}
/**
* Returns the tags.
*
* @return The tags.
*/
public final synchronized List getTags()
{
return _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 (int i = 0; i < parts.length; i++)
{
part = parts[i].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)))
{
_tags.remove(tag);
}
}
else if (mod == '+')
{
if (!_tags.contains(tag))
{
_tags.add(tag);
}
}
else
{
tag.setName(part.trim().toLowerCase());
if (!_tags.contains(tag))
{
_tags.add(tag);
}
}
}
}
}
}
/**
* Returns the comment's title.
*
* @return The title.
*/
public final synchronized String getTitle()
{
return _title;
}
/**
* Sets the comment's title.
*
* @param title The new title.
*/
public final synchronized void setTitle(String title)
{
_title = title;
}
/**
* Returns true if the entry has comments.
*
* @return true if there are comments, false otherwise.
*/
public final synchronized boolean hasComments()
{
return (!_comments.isEmpty());
}
/**
* Returns true if the entry has tags.
*
* @return true if there are tags, false otherwise.
*/
public final synchronized boolean hasTags()
{
return (!_tags.isEmpty());
}
/**
* /** Sets a comment.
*
* @param index The comment's index.
* @param comment The actual comment.
* @param nick The nickname of the author of the comment.
*/
public final synchronized void setComment(int index, String comment, String nick)
{
if (index < _comments.size())
{
_comments.set(index, new EntryComment(comment, nick));
}
}
/**
* Sets the tags.
*
* @param tags The tags.
*/
public final synchronized void setTags(List tags)
{
_tags.addAll(tags);
}
/**
* Returns a string representation of the object.
*
* @return A string representation of the object.
*/
public final String toString()
{
return super.toString() + "[ channel -> '" + _channel + '\'' + ", comments -> " + _comments + ", date -> "
+ _date + ", link -> '" + _link + '\'' + ", login -> '" + _login + '\'' + ", nick -> '" + _nick + '\''
+ ", tags -> " + _tags + ", title -> '" + _title + '\'' + " ]";
}
}

View file

@ -0,0 +1,129 @@
/*
* @(#)FeedReader.java
*
* Copyright (c) 2004, 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.
*
* $Id$
*
*/
package net.thauvin.erik.mobibot;
import com.sun.syndication.feed.synd.SyndEntry;
import com.sun.syndication.feed.synd.SyndEntryImpl;
import com.sun.syndication.feed.synd.SyndFeed;
import com.sun.syndication.fetcher.FeedFetcher;
import com.sun.syndication.fetcher.impl.HttpURLFeedFetcher;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.List;
/**
* Reads a RSS feed.
*
* @author Erik C. Thauvin
* @version $Revision$, $Date$
* @created Feb 1, 2004
* @since 1.0
*/
public class FeedReader implements Runnable
{
/**
* The maximum number of feed items to display.
*/
private static final int MAX_ITEMS = 5;
/**
* The tab indent (4 spaces).
*/
private static final String TAB_INDENT = " ";
/**
* The bot.
*/
private final Mobibot _bot;
/**
* The nick of the person who sent the message.
*/
private final String _sender;
/**
* The URL to fetch.
*/
private final String _url;
/**
* Creates a new FeedReader object.
*
* @param bot The bot.
* @param sender The nick of the person who sent the message.
* @param url The URL to fetch.
*/
public FeedReader(Mobibot bot, String sender, String url)
{
_bot = bot;
_sender = sender;
_url = url;
}
/**
* Fetches the Feed's items.
*/
public final void run()
{
final FeedFetcher fetcher = new HttpURLFeedFetcher(_bot.getFeedInfoCache());
try
{
final SyndFeed feed = fetcher.retrieveFeed(new URL(_url));
SyndEntry item;
final List items = feed.getEntries();
for (int i = 0; (i < items.size()) && (i < MAX_ITEMS); i++)
{
item = (SyndEntryImpl) items.get(i);
_bot.send(_sender, item.getTitle());
_bot.send(_sender, TAB_INDENT + item.getLink());
}
}
catch (MalformedURLException e)
{
_bot.getLogger().debug("Invalid feed URL.", e);
_bot.send(_sender, "The feed URL is invalid.");
}
catch (Exception e)
{
_bot.getLogger().debug("Unable to fetch the feed.", e);
_bot.send(_sender, "An error has occurred while fetching the feed: " + e.getMessage());
}
}
}

View file

@ -0,0 +1,135 @@
/*
* @(#)GoogleSearch.java
*
* Copyright (c) 2004, 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.
*
* $Id$
*
*/
package net.thauvin.erik.mobibot;
import org.json.JSONArray;
import org.json.JSONObject;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.URL;
import java.net.URLConnection;
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
*/
public class GoogleSearch implements Runnable
{
/**
* The tab indent (4 spaces).
*/
private static final String TAB_INDENT = " ";
/**
* The bot.
*/
private final Mobibot _bot;
/**
* The search query.
*/
private final String _query;
/**
* The nick of the person who sent the message.
*/
private final String _sender;
/**
* Creates a new GoogleSearch object.
*
* @param bot The bot.
* @param sender The nick of the person who sent the message.
* @param query The Google query
*/
public GoogleSearch(Mobibot bot, String sender, String query)
{
_bot = bot;
_sender = sender;
_query = query;
}
/**
* Main processing method.
*/
public final void run()
{
try
{
final String query = URLEncoder.encode(_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);
final URLConnection conn = url.openConnection();
final StringBuffer sb = new StringBuffer();
final BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
String line;
while ((line = reader.readLine()) != null)
{
sb.append(line);
}
final JSONObject json = new JSONObject(sb.toString());
final JSONArray ja = json.getJSONObject("responseData").getJSONArray("results");
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, TAB_INDENT + j.getString("url"));
}
reader.close();
}
catch (Exception e)
{
_bot.getLogger().warn("Unable to search in Google for: " + _query, e);
_bot.send(_sender, "An error has occurred: " + e.getMessage());
}
}
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,59 @@
/* Created by JReleaseInfo AntTask from Open Source Competence Group */
/* Creation date Sat Apr 19 21:14:33 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 {
/**
* 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 1397967273141L). */
private static final Date buildDate = new Date(1397967273141L);
/**
* Get buildDate (set during build process to Sat Apr 19 21:14:33 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; }
/** version (set during build process to "0.5"). */
private static final String version = "0.5";
/**
* Get version (set during build process to "0.5").
* @return String version
*/
public static String getVersion() { return version; }
/**
* Get buildNumber (set during build process to 40).
* @return int buildNumber
*/
public static int getBuildNumber() { return 40; }
}

View file

@ -0,0 +1,165 @@
/*
* @(#)StockQuote.java
*
* Copyright (c) 2004, 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.
*
* $Id$
*
*/
package net.thauvin.erik.mobibot;
import com.Ostermiller.util.CSVParser;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.methods.GetMethod;
import java.io.IOException;
/**
* Retrieves a stock quote from Yahoo!.
*
* @author Erik C. Thauvin
* @version $Revision$, $Date$
* @created Feb 7, 2004
* @since 1.0
*/
public class StockQuote implements Runnable
{
/**
* The Yahoo! stock quote URL.
*/
private static final String YAHOO_URL = "http://finance.yahoo.com/d/quotes.csv?&f=snl1d1t1c1oghv&e=.csv&s=";
/**
* The bot.
*/
private final Mobibot _bot;
/**
* The nick of the person who sent the message.
*/
private final String _sender;
/**
* The stock symbol.
*/
private final String _symbol;
/**
* Creates a new StockQuote object.
*
* @param bot The bot.
* @param sender The nick of the person who sent the message.
* @param symbol The stock symbol.
*/
public StockQuote(Mobibot bot, String sender, String symbol)
{
_bot = bot;
_sender = sender;
_symbol = symbol;
}
/**
* Returns the specified stock quote.
*/
public final void run()
{
try
{
final HttpClient client = new HttpClient();
client.getHttpConnectionManager().getParams().setConnectionTimeout(Mobibot.CONNECT_TIMEOUT);
client.getHttpConnectionManager().getParams().setSoTimeout(Mobibot.CONNECT_TIMEOUT);
final GetMethod getMethod = new GetMethod(YAHOO_URL + _symbol.toUpperCase());
client.executeMethod(getMethod);
final String[][] lines = CSVParser.parse(getMethod.getResponseBodyAsString());
if (lines.length > 0)
{
final String[] quote = lines[0];
if (quote.length > 0)
{
if ((quote.length > 3) && (!"N/A".equalsIgnoreCase(quote[3])))
{
_bot.send(_bot.getChannel(), "Symbol: " + quote[0] + " [" + quote[1] + ']');
if (quote.length > 5)
{
_bot.send(_bot.getChannel(), "Last Trade: " + quote[2] + " (" + quote[5] + ')');
}
else
{
_bot.send(_bot.getChannel(), "Last Trade: " + quote[2]);
}
if (quote.length > 4)
{
_bot.send(_sender, "Time: " + quote[3] + ' ' + quote[4]);
}
if (quote.length > 6 && !"N/A".equalsIgnoreCase(quote[6]))
{
_bot.send(_sender, "Open: " + quote[6]);
}
if (quote.length > 7 && !"N/A".equalsIgnoreCase(quote[7]) && !"N/A".equalsIgnoreCase(quote[8]))
{
_bot.send(_sender, "Day's Range: " + quote[7] + " - " + quote[8]);
}
if (quote.length > 9 && !"0".equalsIgnoreCase(quote[9]))
{
_bot.send(_sender, "Volume: " + quote[9]);
}
}
else
{
_bot.send(_sender, "Invalid ticker symbol.");
}
}
else
{
_bot.send(_sender, "No values returned.");
}
}
else
{
_bot.send(_sender, "No data returned.");
}
}
catch (IOException e)
{
_bot.getLogger().debug("Unable to retrieve stock quote for: " + _symbol, e);
_bot.send(_sender, "An error has occurred: " + e.getMessage());
}
}
}

View file

@ -0,0 +1,133 @@
package net.thauvin.erik.mobibot;
import javax.swing.SwingUtilities;
/**
* 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.
*
* @noinspection ALL
*/
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;
/**
* Get the value produced by the worker thread, or null if it
* hasn't been constructed yet.
*/
protected synchronized Object getValue() {
return value;
}
/**
* Set the value produced by worker thread
*/
private synchronized void setValue(Object x) {
value = x;
}
/**
* Compute the value to be returned by the <code>get</code> method.
*/
public abstract Object construct();
/**
* Called on the event dispatching thread (not on the worker thread)
* after the <code>construct</code> 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();
}
/**
* Return the value created by the <code>construct</code> 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 <code>construct</code> 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 <code>construct</code> method
* and then exit.
*/
public SwingWorker() {
final Runnable doFinished = new Runnable() {
public void run() { finished(); }
};
Runnable doConstruct = new Runnable() {
public void run() {
try {
setValue(construct());
}
finally {
threadVar.clear();
}
SwingUtilities.invokeLater(doFinished);
}
};
Thread t = new Thread(doConstruct);
threadVar = new ThreadVar(t);
}
/**
* Start the worker thread.
*/
public void start() {
Thread t = threadVar.get();
if (t != null) {
t.start();
}
}
}

View file

@ -0,0 +1,134 @@
/*
* @(#)Twitter.java
*
* Copyright (C) 2007 Erik C. Thauvin
* 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.
*
* $Id$
*
*/
package net.thauvin.erik.mobibot;
import twitter4j.Status;
import twitter4j.TwitterFactory;
import twitter4j.conf.ConfigurationBuilder;
/**
* Inserts presence information into Twitter.
*
* @author <a href="mailto:erik@thauvin.net">Erik C. Thauvin</a>
* @version $Revision$, $Date$
* @created Sept 10, 2008
* @since 1.0
*/
public class Twitter implements Runnable
{
/**
* The bot.
*/
private final Mobibot _bot;
/**
* The Twitter consumer secret.
*/
private final String _consumerSecret;
/**
* The Twitter consumer key.
*/
private final String _consumerKey;
/**
* The Twitter message.
*/
private final String _message;
/**
* The Twitter access token.
*/
private final String _accessToken;
/**
* The Twitter access token secret.
*/
private final String _accessTokenSecret;
/**
* The nick of the person who sent the message.
*/
private final String _sender;
/**
* Creates a new Twitter object.
*
* @param bot The bot.
* @param sender The nick of the person who sent the message.
* @param consumerKey The Twitter consumer key.
* @param consumerSecret The Twitter consumer secret.
* @param accessToken The Twitter access token.
* @param accessTokenSecret The Twitter access token secret.
* @param message The Twitter message.
*/
public Twitter(Mobibot bot, String sender, String consumerKey, String consumerSecret, String accessToken,
String accessTokenSecret, String message)
{
_bot = bot;
_consumerKey = consumerKey;
_consumerSecret = consumerSecret;
_accessToken = accessToken;
_accessTokenSecret = accessTokenSecret;
_message = message;
_sender = sender;
}
public final void run()
{
try
{
final ConfigurationBuilder cb = new ConfigurationBuilder();
cb.setDebugEnabled(true).setOAuthConsumerKey(_consumerKey).setOAuthConsumerSecret(_consumerSecret)
.setOAuthAccessToken(_accessToken).setOAuthAccessTokenSecret(_accessTokenSecret);
final TwitterFactory tf = new TwitterFactory(cb.build());
final twitter4j.Twitter twitter = tf.getInstance();
final Status status = twitter.updateStatus(_message + " (" + _sender + ')');
_bot.send(_sender,
"You message was posted to http://twitter.com/" + twitter.getScreenName() + "/statuses/" + status
.getId()
);
}
catch (Exception e)
{
_bot.getLogger().warn("Unable to post to Twitter: " + _message, e);
_bot.send(_sender, "An error has occurred: " + e.getMessage());
}
}
}

View file

@ -0,0 +1,82 @@
package net.thauvin.erik.mobibot;
import twitter4j.TwitterException;
import twitter4j.TwitterFactory;
import twitter4j.auth.AccessToken;
import twitter4j.auth.RequestToken;
import java.io.BufferedReader;
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.
* Then execute:
* <p/>
* <code>java -cp "mobibot.jar:lib/*" net.thauvin.erik.mobibot.TwitterOAuth <consumerKey> <consumerSecret></code>
* <p/>
* and follow the prompts/instructions.
*
* @author <a href="mailto:erik@thauvin.net">Erik C. Thauvin</a>
* @author <a href="http://twitter4j.org/en/code-examples.html#oauth">http://twitter4j.org/en/code-examples.html#oauth</a>
* @version $Revision$, $Date$
* @created Sep 13, 2010
* @since 1.0
*/
public class TwitterOAuth
{
public static void main(String args[])
throws Exception
{
if (args.length == 2)
{
final twitter4j.Twitter twitter = new TwitterFactory().getInstance();
twitter.setOAuthConsumer(args[0], args[1]);
final RequestToken requestToken = twitter.getOAuthRequestToken();
AccessToken accessToken = null;
final BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
while (null == accessToken)
{
System.out.println("Open the following URL and grant access to your account:");
System.out.println(requestToken.getAuthorizationURL());
System.out.print("Enter the PIN (if available) or just hit enter.[PIN]:");
final String pin = br.readLine();
try
{
if (pin.length() > 0)
{
accessToken = twitter.getOAuthAccessToken(requestToken, pin);
}
else
{
accessToken = twitter.getOAuthAccessToken();
}
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()
);
}
catch (TwitterException te)
{
if (401 == te.getStatusCode())
{
System.out.println("Unable to get the access token.");
}
else
{
te.printStackTrace();
}
}
}
}
else
{
System.out.println("Usage: " + TwitterOAuth.class.getName() + " <consumerKey> <consumerSecret>");
}
System.exit(0);
}
}

View file

@ -0,0 +1,197 @@
/*
* @(#)Weather.java
*
* Copyright (c) 2004, 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.
*
* $Id$
*
*/
package net.thauvin.erik.mobibot;
import net.sf.jweather.metar.Metar;
import net.sf.jweather.metar.SkyCondition;
import net.sf.jweather.metar.WeatherCondition;
import java.text.DecimalFormat;
import java.util.Date;
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
*/
public class Weather implements Runnable
{
/**
* The URL where the stations are listed.
*/
public static final String STATIONS_URL = "http://www.rap.ucar.edu/weather/surface/stations.txt";
/**
* The decimal number format.
*/
private static final DecimalFormat NUMBER_FORMAT = new DecimalFormat("0.##");
/**
* The bot.
*/
private final Mobibot _bot;
/**
* The nick of the person who sent the message.
*/
private final String _sender;
/**
* The station ID.
*/
private final String _station;
/**
* The private message flag.
*/
private final boolean _isPrivate;
/**
* Creates a new Weather object.
*
* @param bot The bot.
* @param sender The nick of the person who sent the message.
* @param station The station ID.
* @param isPrivate Set to true is the response should be send as a private message.
*/
public Weather(Mobibot bot, String sender, String station, boolean isPrivate)
{
_bot = bot;
_sender = sender;
_station = station.toUpperCase();
_isPrivate = isPrivate;
}
/**
* Main processing method.
*/
public final void run()
{
if (_station.length() == 4)
{
final Metar metar = net.sf.jweather.Weather.getMetar(_station);
if (metar != null)
{
Float result;
_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
);
result = metar.getWindSpeedInMPH();
if (result != null)
{
_bot.send(_sender,
"Wind Speed: " + result + " mph, " + metar.getWindSpeedInKnots() + " knots",
_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);
}
}
result = metar.getPressure();
if (result != null)
{
_bot.send(_sender, "Pressure: " + result + " in Hg", _isPrivate);
}
result = metar.getTemperatureInCelsius();
if (result != null)
{
_bot.send(_sender,
"Temperature: " + result + " C, " + metar.getTemperatureInFahrenheit() + " F",
_isPrivate);
}
if (metar.getWeatherConditions() != null)
{
final Iterator it = metar.getWeatherConditions().iterator();
while (it.hasNext())
{
final WeatherCondition weatherCondition = (WeatherCondition) it.next();
_bot.send(_sender, weatherCondition.getNaturalLanguageString(), _isPrivate);
}
}
if (metar.getSkyConditions() != null)
{
final Iterator it = metar.getSkyConditions().iterator();
while (it.hasNext())
{
final SkyCondition skyCondition = (SkyCondition) it.next();
_bot.send(_sender, skyCondition.getNaturalLanguageString(), _isPrivate);
}
}
return;
}
else
{
_bot.send(_sender, "Invalid Station ID. Please try again.", _isPrivate);
return;
}
}
_bot.helpResponse(_sender, Mobibot.WEATHER_CMD);
}
}