From 533e2d1486a76f218797e5d243017d89c9de381b Mon Sep 17 00:00:00 2001 From: "Christian P. MOMON" Date: Mon, 25 Dec 2017 00:29:57 +0100 Subject: [PATCH] Added user aliases management. --- CHANGES | 7 +- resources/scripts/daemon.sh | 2 +- resources/scripts/hebdobot.sh | 2 +- resources/users-sample.conf | 5 + src/org/april/hebdobot/cli/HebdobotCLI.java | 14 ++ src/org/april/hebdobot/model/Hebdobot.java | 185 +++++++++++------- src/org/april/hebdobot/model/UserAliases.java | 140 +++++++++++++ .../hebdobot/pastebin/PastebinSettings.java | 24 +++ src/org/april/hebdobot/review/Review.java | 21 +- .../april/hebdobot/util/HebdobotUtils.java | 2 +- src/org/april/hebdobot/xml/UserAlias.java | 97 --------- test/users.conf | 9 + 12 files changed, 321 insertions(+), 187 deletions(-) create mode 100644 resources/users-sample.conf create mode 100644 src/org/april/hebdobot/model/UserAliases.java delete mode 100644 src/org/april/hebdobot/xml/UserAlias.java create mode 100644 test/users.conf diff --git a/CHANGES b/CHANGES index 364aabc..c8282bd 100644 --- a/CHANGES +++ b/CHANGES @@ -5,9 +5,10 @@ * Set formatter and save actions settings and applied it. * Made a code review. * Place internal classes in their own file. +* Renamed package from fr.imirhil.april to org.april +* Splitted launcher and CLI. + * anonymized Twitter API key - -* renamed package from fr.imirhil.april to org.april -* replaced Maven with Ant +* eplaced Maven with Ant * no more code injection \ No newline at end of file diff --git a/resources/scripts/daemon.sh b/resources/scripts/daemon.sh index ccf20ca..66af092 100644 --- a/resources/scripts/daemon.sh +++ b/resources/scripts/daemon.sh @@ -4,7 +4,7 @@ NAME=hebdobot BASE_DIR=$HOME/$NAME PID_FILE=$BASE_DIR/$NAME.pid DAEMON=java -DAEMON_ARGS="-cp *:lib/* org.april.hebdobot.Application" +DAEMON_ARGS="-cp *:lib/* org.april.hebdobot" CMD="/sbin/start-stop-daemon --chdir $BASE_DIR --quiet --make-pidfile --pidfile $PID_FILE --exec $DAEMON" case "$1" in diff --git a/resources/scripts/hebdobot.sh b/resources/scripts/hebdobot.sh index 5dd19ce..810e734 100755 --- a/resources/scripts/hebdobot.sh +++ b/resources/scripts/hebdobot.sh @@ -1,2 +1,2 @@ #!/bin/sh -java -cp '*:lib/*' org.april.hebdobot.Application +java -cp '*:lib/*' org.april.hebdobot diff --git a/resources/users-sample.conf b/resources/users-sample.conf new file mode 100644 index 0000000..af89070 --- /dev/null +++ b/resources/users-sample.conf @@ -0,0 +1,5 @@ +# +# Sample Hebdobot user file +# + +Christian P. MOMON=cpm__,cpm_screen \ No newline at end of file diff --git a/src/org/april/hebdobot/cli/HebdobotCLI.java b/src/org/april/hebdobot/cli/HebdobotCLI.java index df49847..1265b5d 100644 --- a/src/org/april/hebdobot/cli/HebdobotCLI.java +++ b/src/org/april/hebdobot/cli/HebdobotCLI.java @@ -30,6 +30,7 @@ import org.apache.commons.cli.ParseException; import org.apache.commons.lang3.StringUtils; import org.april.hebdobot.HebdobotException; import org.april.hebdobot.model.Hebdobot; +import org.april.hebdobot.model.UserAliases; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -44,6 +45,7 @@ public class HebdobotCLI public static final String HEBDOBOT_VERSION = "v2.0"; private static final String DEFAULT_CONFIG_FILE = "hebdobot.conf"; + private static final String DEFAULT_ALIAS_FILE = "users.conf"; /** * Instantiates a new hebdobot launcher. @@ -124,11 +126,21 @@ public class HebdobotCLI if (configFile.exists()) { + // Load configuration file. + logger.info("Config file loading… ({}).", configFile.getAbsolutePath()); HebdobotConfigFile config = new HebdobotConfigFile(configFile); + logger.info("Config file loaded."); + + // Load user aliases file. + File aliasFile = new File(configFile.getParentFile(), DEFAULT_ALIAS_FILE); + logger.info("Aliases file loading… ({}).", aliasFile.getAbsolutePath()); + UserAliases aliases = new UserAliases(aliasFile); + logger.info("Aliases file loaded."); if (config.isValid()) { + logger.info("Bot configuring…"); Hebdobot bot = new Hebdobot(config.getIrcHost(), config.getIrcPort(), config.getIrcName(), config.getIrcChannel(), config.getReviewFileSuffix()); @@ -137,6 +149,8 @@ public class HebdobotCLI bot.getIdenticaSettings().setApiSecret(config.getIdenticaApiSecret()); bot.getTwitterSettings().setConsumerKey(config.getTwitterConsumerKey()); bot.getTwitterSettings().setConsumerSecret(config.getTwitterConsumerSecret()); + bot.getAliases().putAll(aliases); + logger.info("Bot configured."); bot.run(); } diff --git a/src/org/april/hebdobot/model/Hebdobot.java b/src/org/april/hebdobot/model/Hebdobot.java index a63d3da..07aa1d4 100644 --- a/src/org/april/hebdobot/model/Hebdobot.java +++ b/src/org/april/hebdobot/model/Hebdobot.java @@ -61,6 +61,7 @@ public class Hebdobot extends PircBot private IdenticaSettings identicaSettings; private PastebinSettings pastebinSettings; private TwitterSettings twitterSettings; + private UserAliases aliases; /** * Instantiates a new bot. @@ -86,6 +87,7 @@ public class Hebdobot extends PircBot this.identicaSettings = new IdenticaSettings(); this.pastebinSettings = new PastebinSettings(); this.twitterSettings = new TwitterSettings(); + this.aliases = new UserAliases(); } /** @@ -97,6 +99,11 @@ public class Hebdobot extends PircBot this.dispose(); } + public UserAliases getAliases() + { + return this.aliases; + } + public IdenticaSettings getIdenticaSettings() { return this.identicaSettings; @@ -148,6 +155,8 @@ public class Hebdobot extends PircBot if (StringUtils.equalsIgnoreCase(text, "!help")) { + logger.info("!help caught."); + // Help. sendMessage(sender, "Bienvenue " + sender); sendMessage(sender, "Je suis " + getName() + ", le robot de gestion des revues hebdomadaires de l'APRIL"); @@ -163,6 +172,8 @@ public class Hebdobot extends PircBot } else if (StringUtils.equalsIgnoreCase(text, "!stop")) { + logger.info("!stop caught."); + // Die. if (this.review == null) { @@ -176,8 +187,10 @@ public class Hebdobot extends PircBot } else if ((StringUtils.equalsIgnoreCase(text, "!debut")) || (StringUtils.equalsIgnoreCase(text, "!début"))) { + logger.info("!debut caught."); + // Start. - this.review = new Review(sender); + this.review = new Review(sender, this.aliases); sendMessage(sender, "Vous êtes le conducteur de réunion"); sendMessage(sender, "Pour terminer la réunion, tapez \"!fin\""); sendMessage("% Début de la réunion hebdomadaire"); @@ -185,6 +198,8 @@ public class Hebdobot extends PircBot } else if (StringUtils.equalsIgnoreCase(text, "!fin")) { + logger.info("!fin caught."); + // Stop. if (this.review != null) { @@ -199,17 +214,20 @@ public class Hebdobot extends PircBot { String date = ISODateTimeFormat.basicDate().print(new DateTime()); String textReview = this.review.toString(); - try + if (this.pastebinSettings.isValid()) { - PastebinClient pastebinClient = new PastebinClient(this.pastebinSettings.getApiKey()); + try + { + PastebinClient pastebinClient = new PastebinClient(this.pastebinSettings.getApiKey()); - String returnValue = pastebinClient.paste(textReview, "Revue APRIL " + date, Private.UNLISTED); + String returnValue = pastebinClient.paste(textReview, "Revue APRIL " + date, Private.UNLISTED); - sendMessage("% Compte-rendu de la revue : " + returnValue); - } - catch (final Exception exception) - { - logger.error("Error during Pastebin submit.", exception); + sendMessage("% Compte-rendu de la revue : " + returnValue); + } + catch (final Exception exception) + { + logger.error("Error during Pastebin submit.", exception); + } } if (this.reviewFileSuffix != null) @@ -238,6 +256,8 @@ public class Hebdobot extends PircBot } else if (text.matches("\\s*##.*")) { + logger.info("\\s*##.* caught."); + // Collective topic, must be before individual topic. if (this.review != null) { @@ -263,6 +283,8 @@ public class Hebdobot extends PircBot } else if (text.matches("\\s*#[^#].*")) { + logger.info("\\s*#[^#].* caught."); + // Individual topic. if (this.review == null) { @@ -278,80 +300,88 @@ public class Hebdobot extends PircBot sendMessage("% quand vous avez fini vous le dites par % fini"); } } - else if (StringUtils.equalsIgnoreCase(text, "!manquants")) - { - // Missing. - if (this.review == null) - { - sendMessage("Pas de revue en cours."); - } - else - { - Topic topic = this.review.getCurrentTopic(); - if (topic == null) - { - sendMessage("Aucun sujet traité"); - } - else - { - Collection participants = this.review.getParticipants(); - Collection currentParticipants = topic.getParticipants(); + } + else if (StringUtils.equalsIgnoreCase(text, "!manquants")) + { + logger.info("!manquants caught."); - Collection missing = CollectionUtils.subtract(participants, currentParticipants); - if (missing.isEmpty()) - { - sendMessage("Aucun participant manquant \\o/"); - } - else - { - sendMessage(String.format("Les participants suivants sont manquants : %1s", StringUtils.join(missing, ", "))); - } - } - } - } - else if (StringUtils.equalsIgnoreCase(text, "!courant")) + // Missing. + if (this.review == null) { - // Current. - if (this.review == null) - { - sendMessage("Pas de revue en cours."); - } - else - { - Topic current = this.review.getCurrentTopic(); - if (current == null) - { - sendMessage("% Pas de sujet en cours"); - } - else if (current instanceof IndividualTopic) - { - sendMessage("% Sujet individuel en cours : " + current.getTitle()); - } - else if (current instanceof CollectiveTopic) - { - sendMessage("% Sujet collectif en cours : " + current.getTitle()); - } - } - } - else if (text.startsWith("%")) - { - // Topic message. - if (this.review == null) - { - sendMessage("Pas de revue en cours."); - } - else - { - this.review.add(new Message(sender, text)); - } + sendMessage("Pas de revue en cours."); } else { - // All the other. - if (this.review != null) + Topic topic = this.review.getCurrentTopic(); + if (topic == null) { - this.review.addRaw(new Message(sender, text)); + sendMessage("Aucun sujet traité"); } + else + { + Collection participants = this.review.getParticipants(); + Collection currentParticipants = topic.getParticipants(); + + Collection missing = CollectionUtils.subtract(participants, currentParticipants); + if (missing.isEmpty()) + { + sendMessage("Aucun participant manquant \\o/"); + } + else + { + sendMessage(String.format("Les participants suivants sont manquants : %1s", StringUtils.join(missing, ", "))); + } + } + } + } + else if (StringUtils.equalsIgnoreCase(text, "!courant")) + { + logger.info("!courant caught."); + + // Current. + if (this.review == null) + { + sendMessage("Pas de revue en cours."); + } + else + { + Topic current = this.review.getCurrentTopic(); + if (current == null) + { + sendMessage("% Pas de sujet en cours"); + } + else if (current instanceof IndividualTopic) + { + sendMessage("% Sujet individuel en cours : " + current.getTitle()); + } + else if (current instanceof CollectiveTopic) + { + sendMessage("% Sujet collectif en cours : " + current.getTitle()); + } + } + } + else if (text.startsWith("%")) + { + logger.info("% caught."); + + // Topic message. + if (this.review == null) + { + sendMessage("Pas de revue en cours."); + } + else + { + this.review.add(new Message(sender, text)); + } + } + else + { + logger.info("Else caught."); + + // All the other. + if (this.review != null) + { + this.review.addRaw(new Message(sender, text)); } } } @@ -368,8 +398,11 @@ public class Hebdobot extends PircBot { try { + logger.info("Bot connection."); this.connect(this.host, this.port); + logger.info("Bot joining channel ({}).", this.channel); this.joinChannel(this.channel); + logger.info("Bot ready."); } catch (NickAlreadyInUseException exception) { diff --git a/src/org/april/hebdobot/model/UserAliases.java b/src/org/april/hebdobot/model/UserAliases.java new file mode 100644 index 0000000..035cecc --- /dev/null +++ b/src/org/april/hebdobot/model/UserAliases.java @@ -0,0 +1,140 @@ +/** + * Copyright (C) 2011-2013 Nicolas Vinot + * Copyright (C) 2017 Christian Pierre MOMON + * + * This file is part of (April) Hebdobot. + * + * Hebdobot is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Hebdobot is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with Hebdobot. If not, see + */ +package org.april.hebdobot.model; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; +import java.util.Properties; + +import org.april.hebdobot.HebdobotException; +import org.april.hebdobot.util.HebdobotUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * The Class UserAliases. + */ +public class UserAliases +{ + private static final Logger logger = LoggerFactory.getLogger(UserAliases.class); + + private final Map aliases; + + /** + * Instantiates a new user aliases. + */ + public UserAliases() + { + this.aliases = new HashMap(); + } + + /** + * Instantiates a new user aliases. + * + * @param source + * the source + * @throws HebdobotException + * the hebdobot exception + */ + public UserAliases(final File source) throws HebdobotException + { + this.aliases = new HashMap(); + + try + { + + Properties users = HebdobotUtils.loadProperties(source); + + for (String realName : users.stringPropertyNames()) + { + String[] nicks = users.getProperty(realName).split(","); + + for (String nick : nicks) + { + this.aliases.put(nick, realName); + } + } + } + catch (FileNotFoundException exception) + { + logger.warn("File not found."); + } + catch (IOException exception) + { + throw new HebdobotException("IO error.", exception); + } + } + + /** + * Gets the real name. + * + * @param nick + * the nick + * @return the real name + */ + public String getRealName(final String nick) + { + String result; + + result = this.aliases.get(nick); + + if (result == null) + { + boolean ended = false; + Iterator iterator = this.aliases.keySet().iterator(); + while (!ended) + { + if (iterator.hasNext()) + { + String currentNick = iterator.next(); + + if (nick.toLowerCase().contains(currentNick.toLowerCase())) + { + ended = true; + result = this.aliases.get(currentNick) + " ( " + nick + " )"; + } + } + else + { + result = nick; + ended = true; + } + } + } + + // + return result; + } + + /** + * Put all. + * + * @param source + * the source + */ + public void putAll(final UserAliases source) + { + this.aliases.putAll(source.aliases); + } +} diff --git a/src/org/april/hebdobot/pastebin/PastebinSettings.java b/src/org/april/hebdobot/pastebin/PastebinSettings.java index 2e814be..8900aed 100644 --- a/src/org/april/hebdobot/pastebin/PastebinSettings.java +++ b/src/org/april/hebdobot/pastebin/PastebinSettings.java @@ -18,6 +18,8 @@ */ package org.april.hebdobot.pastebin; +import org.apache.commons.lang3.StringUtils; + /** * The Class IdenticaSettings. */ @@ -49,6 +51,28 @@ public class PastebinSettings return this.apiKey; } + /** + * Checks if is valid. + * + * @return true, if is valid + */ + public boolean isValid() + { + boolean result; + + if (StringUtils.isBlank(this.apiKey)) + { + result = false; + } + else + { + result = true; + } + + // + return result; + } + public void setApiKey(final String apiKey) { this.apiKey = apiKey; diff --git a/src/org/april/hebdobot/review/Review.java b/src/org/april/hebdobot/review/Review.java index abd7ad0..9c81661 100644 --- a/src/org/april/hebdobot/review/Review.java +++ b/src/org/april/hebdobot/review/Review.java @@ -26,8 +26,7 @@ import java.util.List; import java.util.Set; import org.apache.commons.lang3.StringUtils; -import org.april.hebdobot.Context; -import org.april.hebdobot.xml.UserAlias; +import org.april.hebdobot.model.UserAliases; import org.joda.time.DateTime; import org.joda.time.format.DateTimeFormat; @@ -38,13 +37,13 @@ public class Review { private static final int LENGTH = 80; - private static final UserAlias USER_ALIAS = Context.getBean(UserAlias.class); private final Set participants; private final List individualTopics; private final List collectiveTopics; private Topic currentTopic; private final List messages; private final String owner; + private final UserAliases aliases; /** * Instantiates a new review. @@ -52,7 +51,7 @@ public class Review * @param owner * the owner */ - public Review(final String owner) + public Review(final String owner, final UserAliases aliases) { this.participants = new HashSet(); this.individualTopics = new LinkedList(); @@ -60,6 +59,7 @@ public class Review this.messages = new Messages(); this.owner = owner; + this.aliases = aliases; } /** @@ -154,6 +154,7 @@ public class Review result.addAll(topic.getParticipants()); } + // return result; } @@ -166,7 +167,12 @@ public class Review */ public boolean isOwner(final String name) { - return this.owner.equalsIgnoreCase(name); + boolean result; + + result = this.owner.equalsIgnoreCase(name); + + // + return result; } /* (non-Javadoc) @@ -191,7 +197,7 @@ public class Review addCenter(buffer, "Participants", '-'); for (final String participant : this.participants) { - addChunk(buffer, "* " + USER_ALIAS.getRealName(participant) + "\n"); + addChunk(buffer, "* " + this.aliases.getRealName(participant) + "\n"); } if (!this.individualTopics.isEmpty()) @@ -201,7 +207,7 @@ public class Review addEmpty(buffer); addLine(buffer, '='); addEmpty(buffer); - addCenter(buffer, USER_ALIAS.getRealName(participant), '-'); + addCenter(buffer, this.aliases.getRealName(participant), '-'); for (final IndividualTopic topic : this.individualTopics) { if (topic.hasParticipant(participant)) @@ -443,5 +449,4 @@ public class Review // return result; } - } diff --git a/src/org/april/hebdobot/util/HebdobotUtils.java b/src/org/april/hebdobot/util/HebdobotUtils.java index f08c688..c1ae771 100644 --- a/src/org/april/hebdobot/util/HebdobotUtils.java +++ b/src/org/april/hebdobot/util/HebdobotUtils.java @@ -53,7 +53,7 @@ public class HebdobotUtils * the hebdobot exception * @throws IOException */ - public static Properties loadProperties(final File source) throws HebdobotException, IOException + public static Properties loadProperties(final File source) throws IOException { Properties result; diff --git a/src/org/april/hebdobot/xml/UserAlias.java b/src/org/april/hebdobot/xml/UserAlias.java deleted file mode 100644 index 9bcc449..0000000 --- a/src/org/april/hebdobot/xml/UserAlias.java +++ /dev/null @@ -1,97 +0,0 @@ -/** - * Copyright (C) 2011-2013 Nicolas Vinot - * Copyright (C) 2017 Christian Pierre MOMON - * - * This file is part of (April) Hebdobot. - * - * Hebdobot is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Hebdobot is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with Hebdobot. If not, see - */ -package org.april.hebdobot.xml; - -import java.io.InputStream; -import java.util.HashMap; -import java.util.Map; -import java.util.Map.Entry; - -import javax.xml.XMLConstants; -import javax.xml.bind.JAXBContext; -import javax.xml.bind.JAXBException; -import javax.xml.bind.Unmarshaller; -import javax.xml.transform.stream.StreamSource; -import javax.xml.validation.SchemaFactory; - -import org.jibble.pircbot.User; -import org.xml.sax.SAXException; - -/** - * The Class UserAlias. - */ -public class UserAlias -{ - private final Map aliases = new HashMap(); - - /** - * Instantiates a new user alias. - * - * @param source - * the source - */ - public UserAlias(final InputStream source) - { - try - { - final Unmarshaller unmarshaller = JAXBContext.newInstance(Users.class).createUnmarshaller(); - unmarshaller.setSchema(SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI) - .newSchema(UserAlias.class.getResource("/org/april/hebdobot/users.xsd"))); - - for (final User user : unmarshaller.unmarshal(new StreamSource(source), Users.class).getValue().getUser()) - { - final String realName = user.getRealName(); - for (final String nick : user.getNick()) - { - this.aliases.put(nick, realName); - } - } - } - catch (final SAXException exception) - { - exception.printStackTrace(); - throw new RuntimeException(exception); - } - catch (final JAXBException exception) - { - exception.printStackTrace(); - throw new RuntimeException(exception); - } - } - - /** - * Gets the real name. - * - * @param nick - * the nick - * @return the real name - */ - public String getRealName(final String nick) - { - for (final Entry entry : this.aliases.entrySet()) - { - if (nick.toLowerCase().contains(entry.getKey().toLowerCase())) - { - return entry.getValue() + " ( " + nick + " )"; - } - } - return nick; - } -} diff --git a/test/users.conf b/test/users.conf new file mode 100644 index 0000000..7ab8635 --- /dev/null +++ b/test/users.conf @@ -0,0 +1,9 @@ +# +# Sample Hebdobot user file +# + +Christian P. MOMON=cpm__,cpm_screen +Lionel Allorge=liot,liot_ +Frédéric Couchet=madix +François Poulain=Polux[2] +Étienne Gonnu=lonugem