Moved to gradle build system.
Using exp4j instead of MathEvaluator for calcuation now.
This commit is contained in:
parent
3b9c5d6431
commit
5858e12b1a
50 changed files with 3124 additions and 1920 deletions
224
src/main/java/net/thauvin/erik/mobibot/CurrencyConverter.java
Normal file
224
src/main/java/net/thauvin/erik/mobibot/CurrencyConverter.java
Normal 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.");
|
||||
}
|
||||
}
|
||||
}
|
160
src/main/java/net/thauvin/erik/mobibot/DeliciousPoster.java
Normal file
160
src/main/java/net/thauvin/erik/mobibot/DeliciousPoster.java
Normal 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 + ')';
|
||||
}
|
||||
}
|
138
src/main/java/net/thauvin/erik/mobibot/EntryComment.java
Normal file
138
src/main/java/net/thauvin/erik/mobibot/EntryComment.java
Normal 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;
|
||||
}
|
||||
}
|
449
src/main/java/net/thauvin/erik/mobibot/EntryLink.java
Normal file
449
src/main/java/net/thauvin/erik/mobibot/EntryLink.java
Normal 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 + '\'' + " ]";
|
||||
}
|
||||
}
|
129
src/main/java/net/thauvin/erik/mobibot/FeedReader.java
Normal file
129
src/main/java/net/thauvin/erik/mobibot/FeedReader.java
Normal 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());
|
||||
}
|
||||
}
|
||||
}
|
135
src/main/java/net/thauvin/erik/mobibot/GoogleSearch.java
Normal file
135
src/main/java/net/thauvin/erik/mobibot/GoogleSearch.java
Normal 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());
|
||||
}
|
||||
}
|
||||
}
|
3310
src/main/java/net/thauvin/erik/mobibot/Mobibot.java
Normal file
3310
src/main/java/net/thauvin/erik/mobibot/Mobibot.java
Normal file
File diff suppressed because it is too large
Load diff
59
src/main/java/net/thauvin/erik/mobibot/ReleaseInfo.java
Normal file
59
src/main/java/net/thauvin/erik/mobibot/ReleaseInfo.java
Normal 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; }
|
||||
|
||||
}
|
165
src/main/java/net/thauvin/erik/mobibot/StockQuote.java
Normal file
165
src/main/java/net/thauvin/erik/mobibot/StockQuote.java
Normal 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());
|
||||
}
|
||||
}
|
||||
}
|
133
src/main/java/net/thauvin/erik/mobibot/SwingWorker.java
Normal file
133
src/main/java/net/thauvin/erik/mobibot/SwingWorker.java
Normal 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();
|
||||
}
|
||||
}
|
||||
}
|
134
src/main/java/net/thauvin/erik/mobibot/Twitter.java
Normal file
134
src/main/java/net/thauvin/erik/mobibot/Twitter.java
Normal 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());
|
||||
}
|
||||
}
|
||||
}
|
82
src/main/java/net/thauvin/erik/mobibot/TwitterOAuth.java
Normal file
82
src/main/java/net/thauvin/erik/mobibot/TwitterOAuth.java
Normal 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);
|
||||
}
|
||||
}
|
197
src/main/java/net/thauvin/erik/mobibot/Weather.java
Normal file
197
src/main/java/net/thauvin/erik/mobibot/Weather.java
Normal 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);
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue