agirbot/src/main/java/fr/imirhil/april/hebdobot/irc/Bot.java
2017-12-14 11:12:15 +01:00

321 lines
9.1 KiB
Java
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package fr.imirhil.april.hebdobot.irc;
import java.util.Collection;
import java.util.LinkedList;
import java.util.List;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.jibble.pircbot.PircBot;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import fr.imirhil.april.hebdobot.Context;
import fr.imirhil.april.hebdobot.review.CollectiveTopic;
import fr.imirhil.april.hebdobot.review.IndividualTopic;
import fr.imirhil.april.hebdobot.review.Message;
import fr.imirhil.april.hebdobot.review.Review;
import fr.imirhil.april.hebdobot.review.Topic;
public class Bot extends PircBot {
private abstract class Handler {
public abstract boolean handle(String sender, String message);
}
private static final Logger LOGGER = LoggerFactory.getLogger(Bot.class);
private final String host;
private final int port;
private final String channel;
private Review review = null;
private final Collection<ReviewListener> listeners = new LinkedList<ReviewListener>();
private final List<Handler> handlers = new LinkedList<Handler>();
public Bot(final String host, final int port, final String name,
final String channel) {
this.host = host;
this.port = port;
this.channel = channel;
this.setName(name);
}
public void init() throws Exception {
this.connect(this.host, this.port);
this.joinChannel(this.channel);
this.registerHandlers();
}
private void registerHandlers() {
// Help
this.handlers.add(new Handler() {
@Override
public boolean handle(final String sender, final String message) {
if (!"!help".equalsIgnoreCase(message)) {
return false;
}
Bot.this.sendMessage(sender, "Bienvenue " + sender);
Bot.this.sendMessage(
sender,
"Je suis "
+ Bot.this.getName()
+ ", le robot de gestion des revues hebdomadaires de l'APRIL");
Bot.this.sendMessage(sender,
"Voici les commandes que je comprend :");
Bot.this.sendMessage(sender, " ");
Bot.this.sendMessage(sender,
"— !debut : commencer une nouvelle revue");
Bot.this.sendMessage(sender,
"— !fin : terminer la revue en cours");
Bot.this.sendMessage(sender,
"— # titre : démarrer un sujet individuel");
Bot.this.sendMessage(sender,
"— ## titre : démarrer un sujet collectif");
Bot.this.sendMessage(sender,
"— !courant : affiche le sujet en cours");
Bot.this.sendMessage(
sender,
"— !manquants : affiche les participants qui n'ont pas répondu sur le dernier sujet");
Bot.this.sendMessage(sender, "— % message : un commentaire");
return true;
}
});
// Die
this.handlers.add(new Handler() {
@Override
public boolean handle(final String sender, final String message) {
if (!"!stop".equalsIgnoreCase(message)) {
return false;
}
if (Bot.this.review != null) {
Bot.this.sendMessage("% Une revue est en cours, arrêt impossible");
return false;
}
Context.close();
return true;
}
});
// Start
this.handlers.add(new Handler() {
@Override
public boolean handle(final String sender, final String message) {
if (!"!debut".equalsIgnoreCase(message)) {
return false;
}
Bot.this.review = new Review(sender);
Bot.this.sendMessage(sender,
"Vous êtes le conducteur de réunion");
Bot.this.sendMessage(sender,
"Pour terminer la réunion, tapez \"!fin\"");
Bot.this.sendMessage("% Début de la réunion hebdomadaire");
Bot.this.sendMessage("% rappel : toute ligne commençant par % sera considérée comme un commentaire et non prise en compte dans la synthèse");
return true;
}
});
// Stop
this.handlers.add(new Handler() {
@Override
public boolean handle(final String sender, final String message) {
if (Bot.this.review == null
|| !"!fin".equalsIgnoreCase(message)) {
return false;
}
if (!Bot.this.review.isOwner(sender)) {
Bot.this.sendMessage(sender
+ ", vous n'êtes pas le conducteur de la réunion");
return false;
}
for (final ReviewListener listener : Bot.this.listeners) {
listener.onEnd(Bot.this.review);
}
Bot.this.sendMessage("% "
+ Bot.this.review.getOwner()
+ ", ne pas oublier d'ajouter le compte-rendu de la revue sur https://agir.april.org/issues/135");
final String participants = StringUtils.join(
Bot.this.review.getParticipants(), " ");
Bot.this.sendMessage("% "
+ participants
+ ", pensez à noter votre bénévalo : http://www.april.org/my?action=benevalo");
Bot.this.sendMessage("% Fin de la revue hebdomadaire");
Bot.this.review = null;
return true;
}
});
// Collective topic, must be before individual topic
this.handlers.add(new Handler() {
@Override
public boolean handle(final String sender, final String message) {
if (Bot.this.review == null || !message.matches("\\s*##.*")) {
return false;
}
if (!Bot.this.review.isOwner(sender)) {
Bot.this.sendMessage(sender
+ ", vous n'êtes pas le conducteur de la réunion");
return false;
}
final CollectiveTopic topic = new CollectiveTopic(message
.replaceFirst("##", "").trim());
Bot.this.review.begin(topic);
Bot.this.sendMessage("Sujet collectif : " + topic.getTitle());
if (topic.getTitle().toLowerCase().contains("bloquage")) {
Bot.this.sendMessage("% si rien à dire vous pouvez dire %ras");
} else {
Bot.this.sendMessage("% 1 minute max");
}
return true;
}
});
// Individual topic
this.handlers.add(new Handler() {
@Override
public boolean handle(final String sender, final String message) {
if (Bot.this.review == null || !message.matches("\\s*#[^#].*")) {
return false;
}
if (!Bot.this.review.isOwner(sender)) {
Bot.this.sendMessage(sender
+ ", vous n'êtes pas le conducteur de la réunion");
return false;
}
final IndividualTopic topic = new IndividualTopic(message
.replaceFirst("#", "").trim());
Bot.this.review.begin(topic);
Bot.this.sendMessage("Sujet individuel : " + topic.getTitle());
Bot.this.sendMessage("% quand vous avez fini vous le dites par % fini");
return true;
}
});
// Missing
this.handlers.add(new Handler() {
@Override
public boolean handle(final String sender, final String message) {
if (Bot.this.review == null
|| !"!manquants".equalsIgnoreCase(message)) {
return false;
}
final Topic topic = Bot.this.review.getCurrentTopic();
if (topic == null) {
Bot.this.sendMessage("Aucun sujet traité");
return true;
}
final Collection<String> participants = Bot.this.review
.getParticipants();
final Collection<String> currentParticipants = topic
.getParticipants();
@SuppressWarnings("unchecked")
final Collection<String> missing = CollectionUtils.subtract(
participants, currentParticipants);
if (missing.isEmpty()) {
Bot.this.sendMessage("Aucun participant manquant \\o/");
return true;
}
Bot.this.sendMessage(String.format(
"Les participants suivants sont manquants : %1s",
StringUtils.join(missing, ", ")));
return true;
}
});
// Current
this.handlers.add(new Handler() {
@Override
public boolean handle(final String sender, final String message) {
if (Bot.this.review == null
|| !"!courant".equalsIgnoreCase(message)) {
return false;
}
final Topic current = Bot.this.review.getCurrentTopic();
if (current == null) {
Bot.this.sendMessage("% Pas de sujet en cours");
} else if (current instanceof IndividualTopic) {
Bot.this.sendMessage("% Sujet individuel en cours : "
+ current.getTitle());
} else if (current instanceof CollectiveTopic) {
Bot.this.sendMessage("% Sujet collectif en cours : "
+ current.getTitle());
}
return true;
}
});
// Topic message
this.handlers.add(new Handler() {
@Override
public boolean handle(final String sender, final String message) {
if (Bot.this.review == null || message.startsWith("%")) {
return false;
}
Bot.this.review.add(new Message(sender, message));
return true;
}
});
// All the other
this.handlers.add(new Handler() {
@Override
public boolean handle(final String sender, final String message) {
if (Bot.this.review == null) {
return false;
}
Bot.this.review.addRaw(new Message(sender, message));
return true;
}
});
}
public void close() {
this.disconnect();
this.dispose();
}
public void add(final ReviewListener listener) {
this.listeners.add(listener);
}
@Override
protected void onMessage(final String channel, final String sender,
final String login, final String hostname, String message) {
LOGGER.debug(
"Message received - channel : {}, sender : {}, message : {}",
new Object[] { channel, sender, message });
if (!channel.equalsIgnoreCase(this.channel)) {
return;
}
message = message.trim();
for (final Handler handler : this.handlers) {
if (handler.handle(sender, message)) {
break;
}
}
}
public void sendMessage(final String message) {
LOGGER.debug("Send message : {}", message);
this.sendMessage(this.channel, message);
}
}