package addon.rss;
import bashoid.Addon;
import bashoid.Message;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.ListIterator;
import org.joox.Match;
import static utils.Constants.*;
public class RSS extends Addon {
private enum Cmds {
INVALID, LIST, RELOAD, SHOW;
}
private static final String configKeyCount = "showMsgsCount";
private static final int MESSAGE_MAX_LENGTH = 450;
private List<Feed> feeds = new ArrayList<>();
private byte showMsgsCount;
private boolean firstRun = true;
public RSS() {
try {
showMsgsCount = Integer.valueOf( config.getValue(configKeyCount) ).byteValue();
} catch(NumberFormatException e) {
showMsgsCount = 5;
}
addFeeds();
checkFeeds();
setPeriodicUpdate(60000);
}
private void addFeeds() {
Match configFeeds = config.getMatch("feeds feed");
for ( Match feed : configFeeds.each() ) {
String name = feed.find("name").text();
String url = feed.find("url").text();
feeds.add( new Feed(name, url) );
}
feeds.add( new EzFeed() );
}
private void removeFeeds() {
feeds.clear();
}
private void reloadFeeds() {
removeFeeds();
reloadConfig();
firstRun = true;
addFeeds();
}
private void checkFeeds() {
for(Feed f : feeds) {
try {
List<String> msgs = f.check(showMsgsCount);
if( !msgs.isEmpty() && !firstRun )
sendChainedMessages(f, msgs);
} catch(IOException e) {
setError(e);
}
}
firstRun = false;
}
private String executeCmd(Cmds cmd, String message, String author) {
if(feeds.isEmpty())
return "No channels available";
switch(cmd) {
case LIST:
{
String msg = "";
for(Feed f : feeds)
msg += f.getName() + " ";
return msg;
}
case SHOW:
{
int index = message.indexOf(" ", message.indexOf("show"));
String channel = message.substring(index+1);
for(Feed f : feeds) {
if(channel.equalsIgnoreCase(f.getName())) {
List<String> messages = f.getLastMessages(showMsgsCount);
sendMessage(author, "Last " + showMsgsCount + " messages for rss channel \"" + f.getName() + "\":");
for(String s : messages)
sendMessage(author, s);
break;
}
}
return null;
}
case RELOAD:
{
reloadFeeds();
sendMessageToChannels("Feeds have been reloaded.");
}
}
return null;
}
private Cmds getCommand(String message) {
int begin = message.indexOf(' ') + 1;
int end = message.indexOf(' ', begin);
if(end == NOT_FOUND)
end = message.length();
String cmd = message.substring(begin, end).toUpperCase();
try {
return Cmds.valueOf(cmd);
} catch (IllegalArgumentException iae) {
return Cmds.INVALID;
}
}
private void sendChainedMessages(Feed feed, List<String> messages) {
String chain = feed.getName() + ": ";
final String SEPARATOR = " | ";
boolean isFirstMessageInChain = true;
ListIterator<String> iterator = messages.listIterator( messages.size() );
while ( iterator.hasPrevious() ) {
String message = iterator.previous();
if ( message.length() > MESSAGE_MAX_LENGTH ) {
sendMessageToChannels(chain);
sendMessageToChannels(message);
chain = "";
isFirstMessageInChain = true;
} else if ( message.length() + chain.length() > MESSAGE_MAX_LENGTH ) {
sendMessageToChannels(chain);
chain = message;
isFirstMessageInChain = false;
} else {
if (!isFirstMessageInChain)
chain += SEPARATOR;
chain += message;
isFirstMessageInChain = false;
}
}
if ( chain.length() > 0 )
sendMessageToChannels(chain);
}
@Override
public boolean shouldReact(Message message) {
return message.text.startsWith("rss") && getCommand(message.text) != Cmds.INVALID;
}
@Override
protected void setReaction(Message message) {
Cmds cmd = getCommand(message.text);
if(cmd == Cmds.INVALID)
return;
String result = executeCmd(cmd, message.text, message.author);
if(result != null)
reaction.add(result);
}
@Override
public void periodicAddonUpdate() {
checkFeeds();
}
}