Nicolas Vinot avatar Nicolas Vinot committed a937308

Send review to pastebin

Comments (0)

Files changed (28)

 	<classpathentry excluding="**" kind="src" output="target/classes" path="src/main/resources"/>
 	<classpathentry kind="src" output="target/test-classes" path="src/test/java"/>
 	<classpathentry excluding="**" kind="src" output="target/test-classes" path="src/test/resources"/>
-	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6"/>
 	<classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER"/>
 	<classpathentry kind="src" output="target/classes" path="target/generated-sources/jaxb">
 		<attributes>
 syntax:glob
-
+conf.properties
+users.xml
 target
 *.log
-
-syntax: regexp
-^users\.xml$

.settings/org.eclipse.jdt.core.prefs

-#Fri Sep 02 19:35:13 CEST 2011
+#Wed Sep 28 23:04:47 CEST 2011
 eclipse.preferences.version=1
-org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
-org.eclipse.jdt.core.compiler.compliance=1.5
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
+org.eclipse.jdt.core.compiler.compliance=1.6
 org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
-org.eclipse.jdt.core.compiler.source=1.5
+org.eclipse.jdt.core.compiler.source=1.6

conf.properties

-irc.host = irc.freenode.org
-irc.port = 6667
-irc.chan = #april
-irc.nick = Hebdobot
-
-log.output = reunion.log
 #!/bin/sh
-java -cp '*:lib/*' fr.imirhil.april.hebdobot.Bot
+java -cp '*:lib/*' fr.imirhil.april.hebdobot.Application
 	<scm>
 		<connection>scm:hg:file://${basedir}</connection>
 	</scm>
+	<properties>
+		<maven.compiler.source>1.6</maven.compiler.source>
+		<maven.compiler.target>${maven.compiler.source}</maven.compiler.target>
+		<project.build.sourceEncoding>UTF8</project.build.sourceEncoding>
+	</properties>
 	<build>
 		<plugins>
 			<plugin>
 			<artifactId>jaxb-api</artifactId>
 			<version>2.1</version>
 		</dependency>
+		<dependency>
+			<groupId>org.quartz-scheduler</groupId>
+			<artifactId>quartz</artifactId>
+			<version>2.0.2</version>
+		</dependency>
+		<dependency>
+			<groupId>org.apache.httpcomponents</groupId>
+			<artifactId>httpclient</artifactId>
+			<version>4.1.2</version>
+		</dependency>
+		<dependency>
+			<groupId>junit</groupId>
+			<artifactId>junit</artifactId>
+			<version>4.8.2</version>
+			<scope>test</scope>
+		</dependency>
+		<dependency>
+			<groupId>org.slf4j</groupId>
+			<artifactId>slf4j-api</artifactId>
+			<version>1.6.1</version>
+		</dependency>
+		<dependency>
+			<groupId>org.slf4j</groupId>
+			<artifactId>slf4j-log4j12</artifactId>
+			<version>1.6.1</version>
+			<scope>runtime</scope>
+		</dependency>
 	</dependencies>
 </project>

src/main/java/fr/imirhil/april/hebdobot/Application.java

+package fr.imirhil.april.hebdobot;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileReader;
+import java.util.Properties;
+
+import org.apache.commons.io.FileUtils;
+import org.joda.time.DateTime;
+import org.joda.time.format.ISODateTimeFormat;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import fr.imirhil.april.hebdobot.irc.Bot;
+import fr.imirhil.april.hebdobot.irc.ReviewListener;
+import fr.imirhil.april.hebdobot.pastebin.PastebinClient;
+import fr.imirhil.april.hebdobot.review.Review;
+import fr.imirhil.april.hebdobot.xml.UserAlias;
+
+public class Application implements ReviewListener {
+	private static final String USERS_FILE = "users.xml";
+
+	private static final Logger LOGGER = LoggerFactory
+			.getLogger(Application.class);
+
+	private static final String CONF_PROPERTIES = "conf.properties";
+	private static final String IRC_HOST = "irc.host";
+	private static final String IRC_PORT = "irc.port";
+	private static final String IRC_NICK = "irc.nick";
+	private static final String IRC_CHAN = "irc.chan";
+	private static final String PASTEBIN_KEY = "pastebin.key";
+	private static final String FILE_SUFFIX = "file.suffix";
+
+	private final Properties properties = new Properties();
+	private final Bot bot;
+	private final UserAlias userAlias;
+	private final String channel;
+
+	private Application() throws Exception {
+		this.userAlias = new UserAlias(new FileInputStream(USERS_FILE));
+
+		this.properties.load(new FileReader(CONF_PROPERTIES));
+		final String name = this.properties.getProperty(IRC_NICK);
+		this.channel = this.properties.getProperty(IRC_CHAN);
+
+		this.bot = new Bot(name, this.channel);
+		this.bot.add(this);
+	}
+
+	public void start() throws Exception {
+		this.bot.connect(this.properties.getProperty(IRC_HOST),
+				Integer.valueOf(this.properties.getProperty(IRC_PORT)));
+		this.bot.joinChannel(this.channel);
+	}
+
+	@Override
+	public void onEnd(final Review review) {
+		final String date = ISODateTimeFormat.basicDate().print(new DateTime());
+		final String text = review.toString(this.userAlias);
+		if (this.properties.containsKey(PASTEBIN_KEY)) {
+			try {
+				this.bot.sendMessage("Compte-rendu de la revue : "
+						+ new PastebinClient(this.properties
+								.getProperty(PASTEBIN_KEY)).paste(text,
+								"Revue APRIL " + date));
+			} catch (final Exception e) {
+				LOGGER.error("Error during Pastebin submit", e);
+			}
+		}
+
+		if (this.properties.containsKey(FILE_SUFFIX)) {
+			try {
+				final File file =
+						new File(date + "_"
+								+ this.properties.getProperty(FILE_SUFFIX));
+				FileUtils.writeStringToFile(file, text);
+				this.bot.sendMessage("Compte-rendu de la revue : "
+						+ file.getName());
+			} catch (final Exception e) {
+				LOGGER.error("Error during file generation", e);
+			}
+		}
+	}
+
+	public static void main(final String[] args) throws Exception {
+		new Application().start();
+	}
+}

src/main/java/fr/imirhil/april/hebdobot/Bot.java

-package fr.imirhil.april.hebdobot;
-
-import java.io.File;
-import java.io.FileReader;
-import java.io.IOException;
-import java.util.Properties;
-
-import org.apache.commons.io.FileUtils;
-import org.jibble.pircbot.PircBot;
-
-import fr.imirhil.april.hebdobot.xml.UserService;
-
-public class Bot extends PircBot {
-	private Meeting meeting = null;
-	private Topic currentTopic = null;
-	private final String channel;
-	private final File output;
-	private String owner;
-
-	public Bot(final String channel, final File output) {
-		this.channel = channel;
-		this.output = output;
-	}
-
-	@Override
-	protected void onMessage(final String channel, final String sender,
-			final String login, final String hostname, String message) {
-		try {
-			if (!channel.equalsIgnoreCase(this.channel)) {
-				return;
-			}
-
-			message = message.trim();
-			final Message raw =
-					new Message(sender, message.replaceFirst("\\s*[#%]*\\s*",
-							""));
-			if (this.meeting == null) {
-				if (message.startsWith("!debut")) {
-					this.start(sender);
-				}
-			} else {
-				if (message.startsWith("!fin")) {
-					this.end(sender);
-				} else if (message.startsWith("##")) {
-					this.startCollectiveTopic(sender, message);
-				} else if (message.startsWith("#")) {
-					this.startIndividualTopic(sender, message);
-				} else if (message.startsWith("!")) {
-					this.handleCommand(message);
-				} else if (!message.startsWith("%")) {
-					this.addToCurrentTopic(raw);
-				}
-			}
-
-			this.log(new Message(sender, message));
-		} catch (final Exception e) {
-			e.printStackTrace();
-		}
-	}
-
-	private void handleCommand(String message) {
-		message = message.replaceFirst("!", "");
-		if (message.startsWith("courant")) {
-			if (this.currentTopic != null) {
-				this.sendMessage(this.channel, "Topic courant : "
-						+ this.currentTopic.getTitle());
-			} else {
-				this.sendMessage(this.channel, "Pas de topic en cours");
-			}
-		}
-	}
-
-	private void log(final Message message) {
-		if (this.meeting != null) {
-			this.meeting.add(message);
-		}
-	}
-
-	private void start(final String sender) {
-		this.owner = sender;
-		this.meeting = new Meeting();
-		this.sendMessage(this.channel, "Début de la réunion hebdo");
-	}
-
-	private void end(final String sender) {
-		if (!this.owner.equalsIgnoreCase(sender)) {
-			return;
-		}
-
-		this.sendMessage(this.channel, "Fin de la réunion hebdo");
-		try {
-			FileUtils.writeStringToFile(this.output, this.meeting.toString());
-		} catch (final IOException e) {
-		}
-		this.meeting = null;
-	}
-
-	private void
-			startIndividualTopic(final String sender, final String message) {
-		if (!this.owner.equalsIgnoreCase(sender)) {
-			return;
-		}
-
-		this.currentTopic =
-				new IndividualTopic(message.replaceFirst("^\\s*#\\s*", ""));
-		this.meeting.add(this.currentTopic);
-		this.sendMessage(this.channel, "Début topic individuel : "
-				+ this.currentTopic.getTitle());
-	}
-
-	private void
-			startCollectiveTopic(final String sender, final String message) {
-		if (!this.owner.equalsIgnoreCase(sender)) {
-			return;
-		}
-
-		this.currentTopic =
-				new CollectiveTopic(message.replaceFirst("^\\s*##\\s*", ""));
-		this.meeting.add(this.currentTopic);
-		this.sendMessage(this.channel, "Début topic collectif : "
-				+ this.currentTopic.getTitle());
-	}
-
-	private void addToCurrentTopic(final Message message) {
-		if (this.currentTopic != null) {
-			this.currentTopic.add(message);
-		}
-	}
-
-	public static void main(final String[] args) throws Exception {
-		new UserService();
-
-		final Properties properties = new Properties();
-		properties.load(new FileReader("conf.properties"));
-		final String channel = properties.getProperty("irc.chan");
-
-		final Bot bot =
-				new Bot(channel, new File(properties.getProperty("log.output")));
-		bot.setName(properties.getProperty("irc.nick"));
-		bot.connect(properties.getProperty("irc.host"),
-				Integer.valueOf(properties.getProperty("irc.port")));
-		bot.joinChannel(channel);
-	}
-}

src/main/java/fr/imirhil/april/hebdobot/CollectiveTopic.java

-package fr.imirhil.april.hebdobot;
-
-import java.util.HashSet;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Set;
-
-public class CollectiveTopic extends Topic {
-	private final List<Message> messages = new LinkedList<Message>();
-
-	public CollectiveTopic(final String title) {
-		super(title);
-	}
-
-	@Override
-	public void add(final Message message) {
-		this.messages.add(message);
-	}
-
-	@Override
-	public Set<String> getParticipants() {
-		final Set<String> participants = new HashSet<String>();
-		for (final Message message : this.messages) {
-			participants.add(message.getAuthor());
-		}
-		return participants;
-	}
-
-	public List<Message> getMessages() {
-		return this.messages;
-	}
-}

src/main/java/fr/imirhil/april/hebdobot/IndividualTopic.java

-package fr.imirhil.april.hebdobot;
-
-import java.util.HashMap;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-public class IndividualTopic extends Topic {
-	private final Map<String, List<Message>> messages =
-			new HashMap<String, List<Message>>();
-
-	public IndividualTopic(final String title) {
-		super(title);
-	}
-
-	@Override
-	public void add(final Message message) {
-		final String author = message.getAuthor();
-		if (!this.messages.containsKey(author)) {
-			this.messages.put(author, new LinkedList<Message>());
-		}
-		this.messages.get(author).add(message);
-	}
-
-	@Override
-	public Set<String> getParticipants() {
-		return this.messages.keySet();
-	}
-
-	public List<Message> getMessages(final String author) {
-		return this.messages.get(author);
-	}
-
-	public boolean hasParticipant(final String participant) {
-		return this.messages.containsKey(participant);
-	}
-}

src/main/java/fr/imirhil/april/hebdobot/Meeting.java

-package fr.imirhil.april.hebdobot;
-
-import java.util.HashSet;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Set;
-
-import org.apache.commons.lang.StringUtils;
-
-import fr.imirhil.april.hebdobot.xml.UserService;
-
-public class Meeting {
-	private static final UserService USER_SERVICE = new UserService();
-	private static final int LENGTH = 74;
-
-	private final Set<String> participants = new HashSet<String>();
-	private final List<IndividualTopic> individualTopics =
-			new LinkedList<IndividualTopic>();
-	private final List<CollectiveTopic> collectiveTopics =
-			new LinkedList<CollectiveTopic>();
-	private final List<Message> messages = new LinkedList<Message>();
-
-	public void add(final Topic topic) {
-		if (topic instanceof IndividualTopic) {
-			this.individualTopics.add((IndividualTopic) topic);
-		} else if (topic instanceof CollectiveTopic) {
-			this.collectiveTopics.add((CollectiveTopic) topic);
-		}
-	}
-
-	public void add(final Message message) {
-		this.messages.add(message);
-		this.participants.add(message.getAuthor());
-	}
-
-	@Override
-	public String toString() {
-		final StringBuffer buffer = new StringBuffer();
-		addBox(buffer, "Revue de la semaine en cours", '#');
-		buffer.append("\n");
-
-		buffer.append("\n");
-		addBox(buffer, "Participants", '=');
-		buffer.append("\n");
-		for (final String participant : this.participants) {
-			buffer.append("* " + Meeting.USER_SERVICE.getRealName(participant)
-					+ "\n");
-		}
-		buffer.append("\n");
-
-		if (!this.individualTopics.isEmpty()) {
-			buffer.append("\n");
-			addBox(buffer, "Sujets individuels", '=');
-			for (final String participant : this.participants) {
-				buffer.append("\n");
-				buffer.append(getLine(
-						Meeting.USER_SERVICE.getRealName(participant), '-'));
-				for (final IndividualTopic topic : this.individualTopics) {
-					if (topic.hasParticipant(participant)) {
-						buffer.append("\n");
-						buffer.append(getTopic(topic));
-						buffer.append("\n");
-						for (final Message message : topic
-								.getMessages(participant)) {
-							buffer.append("* " + message.getContent() + "\n");
-						}
-					}
-				}
-			}
-			buffer.append("\n");
-		}
-
-		if (!this.collectiveTopics.isEmpty()) {
-			buffer.append("\n");
-			addBox(buffer, "Sujets collectifs", '=');
-			for (final CollectiveTopic topic : this.collectiveTopics) {
-				buffer.append("\n");
-				addBox(buffer, topic.getTitle(), '-');
-				for (final Message message : topic.getMessages()) {
-					buffer.append("* " + message.getAuthor() + " : "
-							+ message.getContent() + "\n");
-				}
-			}
-			buffer.append("\n");
-		}
-
-		buffer.append("\n");
-		addBox(buffer, "Log complet", '=');
-		buffer.append("\n");
-		for (final Message message : this.messages) {
-			buffer.append("* " + message.getAuthor() + " : "
-					+ message.getContent() + "\n");
-		}
-
-		return buffer.toString();
-	}
-
-	private static String getLine(final Character c) {
-		return StringUtils.repeat(c.toString(), LENGTH) + "\n";
-	}
-
-	private static String getLine(final String content, final Character c) {
-		return StringUtils.center(" " + content + " ", LENGTH, c) + "\n";
-	}
-
-	private static String getTopic(final Topic topic) {
-		return "===  " + topic.getTitle() + "  ===";
-	}
-
-	private static void addBox(final StringBuffer buffer, final String title,
-			final Character c) {
-		buffer.append(getLine(c));
-		buffer.append(getLine(title, ' '));
-		buffer.append(getLine(c));
-	}
-}

src/main/java/fr/imirhil/april/hebdobot/Message.java

-package fr.imirhil.april.hebdobot;
-
-import org.joda.time.DateTime;
-
-public class Message {
-	private final DateTime date = new DateTime();
-	private final String author;
-	private final String content;
-
-	public Message(final String author, final String content) {
-		this.author = author;
-		this.content = content;
-	}
-
-	public DateTime getDate() {
-		return this.date;
-	}
-
-	public String getAuthor() {
-		return this.author;
-	}
-
-	public String getContent() {
-		return this.content;
-	}
-}

src/main/java/fr/imirhil/april/hebdobot/Topic.java

-package fr.imirhil.april.hebdobot;
-
-import java.util.Set;
-
-public abstract class Topic {
-	private final String title;
-
-	protected Topic(final String title) {
-		this.title = title;
-	}
-
-	public String getTitle() {
-		return this.title;
-	}
-
-	public abstract void add(Message message);
-
-	public abstract Set<String> getParticipants();
-}

src/main/java/fr/imirhil/april/hebdobot/irc/Bot.java

+package fr.imirhil.april.hebdobot.irc;
+
+import java.util.Collection;
+import java.util.LinkedList;
+
+import org.jibble.pircbot.PircBot;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+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 static final Logger LOGGER = LoggerFactory.getLogger(Bot.class);
+
+	private Review review = null;
+	private final String channel;
+	private final Collection<ReviewListener> listeners =
+			new LinkedList<ReviewListener>();
+
+	public Bot(final String name, final String channel) {
+		this.setName(name);
+		this.channel = channel;
+	}
+
+	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) {
+		if (!channel.equalsIgnoreCase(this.channel)) {
+			return;
+		}
+
+		message = message.trim();
+
+		this.handleDie(sender, message);
+		this.handleStartReview(sender, message);
+		this.handleStopReview(sender, message);
+		this.handleStartIndividualTopic(sender, message);
+		this.handleStartCollectiveTopic(sender, message);
+		this.handleComment(sender, message);
+		this.handleMessage(sender, message);
+		this.handleDisplayCurrent(sender, message);
+		this.handleHelp(sender, message);
+	}
+
+	private void handleHelp(final String sender, final String message) {
+		if (!"!help".equalsIgnoreCase(message)) {
+			return;
+		}
+
+		this.sendMessage(sender, "Bienvenue " + sender);
+		this.sendMessage(sender, "Je suis " + this.getName()
+				+ ", le robot de gestion des revues hebdomadaires de l'APRIL");
+		this.sendMessage(sender, "Voici les commandes que je comprend :");
+		this.sendMessage(sender, " ");
+		this.sendMessage(sender, "— !debut : commencer une nouvelle revue");
+		this.sendMessage(sender, "— !fin : terminer la revue en cours");
+		this.sendMessage(sender, "— # titre : démarrer un sujet individuel");
+		this.sendMessage(sender, "— ## titre : démarrer un sujet collectif");
+		this.sendMessage(sender, "— !courant : affiche le sujet en cours");
+		this.sendMessage(sender, "— % message : un commentaire");
+	}
+
+	private void handleMessage(final String sender, final String message) {
+		if (this.review == null || message.startsWith("%")) {
+			return;
+		}
+		this.review.add(new Message(sender, message));
+	}
+
+	private void handleComment(final String sender, final String message) {
+		if (this.review == null) {
+			return;
+		}
+		this.review.addRaw(new Message(sender, message));
+	}
+
+	private void handleDie(final String sender, final String message) {
+		if (!"!stop".equalsIgnoreCase(message)) {
+			return;
+		}
+
+		this.disconnect();
+		this.dispose();
+	}
+
+	private void handleStartReview(final String sender, final String message) {
+		if (!"!debut".equalsIgnoreCase(message)) {
+			return;
+		}
+
+		this.review = new Review(sender);
+		this.sendMessage(sender, "Vous êtes le conducteur de réunion");
+		this.sendMessage(sender, "Pour terminer la réunion, tapez \"!fin\"");
+		this.sendMessage("Début de la réunion hebdomadaire");
+	}
+
+	private void handleStopReview(final String sender, final String message) {
+		if (this.review == null || !"!fin".equalsIgnoreCase(message)) {
+			return;
+		}
+
+		if (!this.review.isOwner(sender)) {
+			this.sendMessage(sender
+					+ ", vous n'êtes pas le conducteur de la réunion");
+			return;
+		}
+
+		for (final ReviewListener listener : this.listeners) {
+			listener.onEnd(this.review);
+		}
+
+		this.review = null;
+		this.sendMessage("Fin de la revue hebdomadaire");
+	}
+
+	private void handleStartIndividualTopic(final String sender,
+			final String message) {
+		if (this.review == null || !message.matches("\\s*#[^#].*")) {
+			return;
+		}
+
+		if (!this.review.isOwner(sender)) {
+			this.sendMessage(sender
+					+ ", vous n'êtes pas le conducteur de la réunion");
+			return;
+		}
+
+		final IndividualTopic topic =
+				new IndividualTopic(message.replaceFirst("#", "").trim());
+		this.review.begin(topic);
+		this.sendMessage("Sujet individuel : " + topic.getTitle());
+	}
+
+	private void handleStartCollectiveTopic(final String sender,
+			final String message) {
+		if (this.review == null || !message.matches("\\s*##.*")) {
+			return;
+		}
+
+		if (!this.review.isOwner(sender)) {
+			this.sendMessage(sender
+					+ ", vous n'êtes pas le conducteur de la réunion");
+			return;
+		}
+
+		final CollectiveTopic topic =
+				new CollectiveTopic(message.replaceFirst("##", "").trim());
+		this.review.begin(topic);
+		this.sendMessage("Sujet collectif : " + topic.getTitle());
+	}
+
+	private void
+			handleDisplayCurrent(final String sender, final String message) {
+		if (this.review == null || !"!courant".equalsIgnoreCase(message)) {
+			return;
+		}
+
+		final Topic current = this.review.getCurrentTopic();
+		if (current == null) {
+			this.sendMessage("Pas de sujet en cours");
+		} else if (current instanceof IndividualTopic) {
+			this.sendMessage("Sujet individuel en cours : "
+					+ current.getTitle());
+		} else if (current instanceof CollectiveTopic) {
+			this.sendMessage("Sujet collectif en cours : " + current.getTitle());
+		}
+	}
+
+	public void sendMessage(final String message) {
+		this.sendMessage(this.channel, message);
+	}
+}

src/main/java/fr/imirhil/april/hebdobot/irc/ReviewListener.java

+package fr.imirhil.april.hebdobot.irc;
+
+import fr.imirhil.april.hebdobot.review.Review;
+
+public interface ReviewListener {
+	void onEnd(Review review);
+}

src/main/java/fr/imirhil/april/hebdobot/pastebin/Expiration.java

+package fr.imirhil.april.hebdobot.pastebin;
+
+public enum Expiration {
+	NEVER(null), MINUTE_10("10M"), HOUR_1("1H"), DAY_1("1D"), MONTH_1("1M");
+
+	private final String value;
+
+	private Expiration(final String value) {
+		this.value = value;
+	}
+
+	public String getValue() {
+		return this.value;
+	}
+}

src/main/java/fr/imirhil/april/hebdobot/pastebin/Format.java

+package fr.imirhil.april.hebdobot.pastebin;
+
+public enum Format {
+	NONE(null), C("c"), CPP("cpp"), JAVA("java"), JAVA_5("java5");
+
+	private final String value;
+
+	private Format(final String value) {
+		this.value = value;
+	}
+
+	public String getValue() {
+		return this.value;
+	}
+}

src/main/java/fr/imirhil/april/hebdobot/pastebin/Option.java

+package fr.imirhil.april.hebdobot.pastebin;
+
+public enum Option {
+	PASTE("paste");
+
+	private final String value;
+
+	private Option(final String value) {
+		this.value = value;
+	}
+
+	public String getValue() {
+		return this.value;
+	}
+}

src/main/java/fr/imirhil/april/hebdobot/pastebin/PastebinClient.java

+package fr.imirhil.april.hebdobot.pastebin;
+
+import java.util.LinkedList;
+import java.util.List;
+
+import org.apache.commons.io.IOUtils;
+import org.apache.http.HttpResponse;
+import org.apache.http.NameValuePair;
+import org.apache.http.client.HttpClient;
+import org.apache.http.client.entity.UrlEncodedFormEntity;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.impl.client.DefaultHttpClient;
+import org.apache.http.message.BasicNameValuePair;
+import org.apache.http.params.HttpParams;
+
+public class PastebinClient {
+	private static final String API_DEV_KEY = "api_dev_key";
+	private static final String API_USER_KEY = "api_user_key";
+	private static final String API_USER_NAME = "api_user_name";
+	private static final String API_USER_PASSWORD = "api_user_password";
+	private static final String API_OPTION = "api_option";
+	private static final String API_PASTE_PRIVATE = "api_paste_private";
+	private static final String API_PASTE_NAME = "api_paste_name";
+	private static final String API_PASTE_EXPIRATION = "api_paste_expire_date";
+	private static final String API_PASTE_FORMAT = "api_paste_format";
+	private static final String API_PASTE_CODE = "api_paste_code";
+
+	private static final String API_ERROR = "Bad API request,";
+
+	public static class APIException extends Exception {
+		private APIException(final String message) {
+			super(message);
+		}
+
+		private static void throwIfError(final String content)
+				throws APIException {
+			if (content.contains(API_ERROR)) {
+				throw new APIException(content.replaceFirst(API_ERROR, ""));
+			}
+		}
+	}
+
+	private final String apiDevKey;
+	private String apiUserKey = null;
+	HttpClient httpClient = new DefaultHttpClient();
+
+	public PastebinClient(final String apiDevKey) {
+		this.apiDevKey = apiDevKey;
+	}
+
+	public String paste(final String code) throws Exception {
+		return this.paste(code, null);
+	}
+
+	public String paste(final String code, final String name) throws Exception {
+		return this.paste(code, name, Format.NONE, false, Expiration.DAY_1);
+	}
+
+	public void login(final String name, final String password)
+			throws Exception {
+		final List<NameValuePair> params = new LinkedList<NameValuePair>();
+		setParameter(params, API_DEV_KEY, this.apiDevKey);
+		setParameter(params, API_USER_NAME, name);
+		setParameter(params, API_USER_PASSWORD, password);
+
+		final HttpPost request =
+				new HttpPost("http://pastebin.com/api/api_login.php");
+		request.setEntity(new UrlEncodedFormEntity(params));
+
+		final HttpResponse response = this.httpClient.execute(request);
+		final String content =
+				IOUtils.toString(response.getEntity().getContent());
+		APIException.throwIfError(content);
+		this.apiUserKey = content;
+	}
+
+	public String paste(final String code, final String name,
+			final Format format, final boolean privat,
+			final Expiration expiration) throws Exception {
+		final List<NameValuePair> params = new LinkedList<NameValuePair>();
+		setParameter(params, API_DEV_KEY, this.apiDevKey);
+		setParameter(params, API_USER_KEY, this.apiUserKey);
+		setParameter(params, API_OPTION, Option.PASTE.getValue());
+		setParameter(params, API_PASTE_PRIVATE, privat ? "1" : "0");
+		setParameter(params, API_PASTE_NAME, name);
+		setParameter(params, API_PASTE_EXPIRATION, expiration.getValue());
+		setParameter(params, API_PASTE_FORMAT, format.getValue());
+		setParameter(params, API_PASTE_CODE, code);
+
+		final HttpPost request =
+				new HttpPost("http://pastebin.com/api/api_post.php");
+		request.setEntity(new UrlEncodedFormEntity(params));
+
+		final HttpResponse response = this.httpClient.execute(request);
+		final String content =
+				IOUtils.toString(response.getEntity().getContent());
+		APIException.throwIfError(content);
+		return content;
+	}
+
+	private static void setParameter(final HttpParams params,
+			final String name, final Object value) {
+		if (value == null) {
+			return;
+		}
+		params.setParameter(name, value);
+	}
+
+	private static void setParameter(final List<NameValuePair> params,
+			final String name, final String value) {
+		if (value == null) {
+			return;
+		}
+		params.add(new BasicNameValuePair(name, value));
+	}
+}

src/main/java/fr/imirhil/april/hebdobot/review/CollectiveTopic.java

+package fr.imirhil.april.hebdobot.review;
+
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Set;
+
+public class CollectiveTopic extends Topic {
+	private final List<Message> messages = new LinkedList<Message>();
+
+	public CollectiveTopic(final String title) {
+		super(title);
+	}
+
+	@Override
+	public void add(final Message message) {
+		this.messages.add(message);
+	}
+
+	@Override
+	public Set<String> getParticipants() {
+		final Set<String> participants = new HashSet<String>();
+		for (final Message message : this.messages) {
+			participants.add(message.getAuthor());
+		}
+		return participants;
+	}
+
+	public List<Message> getMessages() {
+		return this.messages;
+	}
+}

src/main/java/fr/imirhil/april/hebdobot/review/IndividualTopic.java

+package fr.imirhil.april.hebdobot.review;
+
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+public class IndividualTopic extends Topic {
+	private final Map<String, List<Message>> messages =
+			new HashMap<String, List<Message>>();
+
+	public IndividualTopic(final String title) {
+		super(title);
+	}
+
+	@Override
+	public void add(final Message message) {
+		final String author = message.getAuthor();
+		if (!this.messages.containsKey(author)) {
+			this.messages.put(author, new LinkedList<Message>());
+		}
+		this.messages.get(author).add(message);
+	}
+
+	@Override
+	public Set<String> getParticipants() {
+		return this.messages.keySet();
+	}
+
+	public List<Message> getMessages(final String author) {
+		return this.messages.get(author);
+	}
+
+	public boolean hasParticipant(final String participant) {
+		return this.messages.containsKey(participant);
+	}
+}

src/main/java/fr/imirhil/april/hebdobot/review/Message.java

+package fr.imirhil.april.hebdobot.review;
+
+import org.joda.time.DateTime;
+
+public class Message {
+	private final DateTime date = new DateTime();
+	private final String author;
+	private final String content;
+
+	public Message(final String author, final String content) {
+		this.author = author;
+		this.content = content;
+	}
+
+	public DateTime getDate() {
+		return this.date;
+	}
+
+	public String getAuthor() {
+		return this.author;
+	}
+
+	public String getContent() {
+		return this.content;
+	}
+}

src/main/java/fr/imirhil/april/hebdobot/review/Review.java

+package fr.imirhil.april.hebdobot.review;
+
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Set;
+
+import org.apache.commons.lang.StringUtils;
+
+import fr.imirhil.april.hebdobot.xml.UserAlias;
+
+public class Review {
+	private static final int LENGTH = 74;
+
+	private final Set<String> participants = new HashSet<String>();
+	private final List<IndividualTopic> individualTopics =
+			new LinkedList<IndividualTopic>();
+	private final List<CollectiveTopic> collectiveTopics =
+			new LinkedList<CollectiveTopic>();
+	private Topic currentTopic;
+	private final List<Message> messages = new LinkedList<Message>();
+	private final String owner;
+
+	public String getOwner() {
+		return this.owner;
+	}
+
+	public boolean isOwner(final String name) {
+		return this.owner.equalsIgnoreCase(name);
+	}
+
+	public Review(final String owner) {
+		this.owner = owner;
+	}
+
+	public Topic getCurrentTopic() {
+		return this.currentTopic;
+	}
+
+	public void begin(final IndividualTopic topic) {
+		this.individualTopics.add(topic);
+		this.currentTopic = topic;
+	}
+
+	public void begin(final CollectiveTopic topic) {
+		this.collectiveTopics.add(topic);
+		this.currentTopic = topic;
+	}
+
+	public void add(final Message message) {
+		if (this.currentTopic != null) {
+			this.participants.add(message.getAuthor());
+			this.currentTopic.add(message);
+		}
+	}
+
+	public void addRaw(final Message message) {
+		this.messages.add(message);
+	}
+
+	public String toString(final UserAlias userService) {
+		final StringBuffer buffer = new StringBuffer();
+		addBox(buffer, "Revue de la semaine en cours", '#');
+		buffer.append("\n");
+
+		buffer.append("\n");
+		addBox(buffer, "Participants", '=');
+		buffer.append("\n");
+		for (final String participant : this.participants) {
+			buffer.append("* " + userService.getRealName(participant) + "\n");
+		}
+		buffer.append("\n");
+
+		if (!this.individualTopics.isEmpty()) {
+			buffer.append("\n");
+			addBox(buffer, "Sujets individuels", '=');
+			for (final String participant : this.participants) {
+				buffer.append("\n");
+				buffer.append(getLine(userService.getRealName(participant), '-'));
+				for (final IndividualTopic topic : this.individualTopics) {
+					if (topic.hasParticipant(participant)) {
+						buffer.append("\n");
+						buffer.append(getTopic(topic));
+						buffer.append("\n");
+						for (final Message message : topic
+								.getMessages(participant)) {
+							buffer.append("* " + message.getContent() + "\n");
+						}
+					}
+				}
+			}
+			buffer.append("\n");
+		}
+
+		if (!this.collectiveTopics.isEmpty()) {
+			buffer.append("\n");
+			addBox(buffer, "Sujets collectifs", '=');
+			for (final CollectiveTopic topic : this.collectiveTopics) {
+				buffer.append("\n");
+				addBox(buffer, topic.getTitle(), '-');
+				for (final Message message : topic.getMessages()) {
+					buffer.append("* " + message.getAuthor() + " : "
+							+ message.getContent() + "\n");
+				}
+			}
+			buffer.append("\n");
+		}
+
+		buffer.append("\n");
+		addBox(buffer, "Log complet", '=');
+		buffer.append("\n");
+		for (final Message message : this.messages) {
+			buffer.append("* " + message.getAuthor() + " : "
+					+ message.getContent() + "\n");
+		}
+
+		return buffer.toString();
+	}
+
+	private static String getLine(final Character c) {
+		return StringUtils.repeat(c.toString(), LENGTH) + "\n";
+	}
+
+	private static String getLine(final String content, final Character c) {
+		return StringUtils.center(" " + content + " ", LENGTH, c) + "\n";
+	}
+
+	private static String getTopic(final Topic topic) {
+		return "===  " + topic.getTitle() + "  ===";
+	}
+
+	private static void addBox(final StringBuffer buffer, final String title,
+			final Character c) {
+		buffer.append(getLine(c));
+		buffer.append(getLine(title, ' '));
+		buffer.append(getLine(c));
+	}
+}

src/main/java/fr/imirhil/april/hebdobot/review/Topic.java

+package fr.imirhil.april.hebdobot.review;
+
+import java.util.Set;
+
+public abstract class Topic {
+	private final String title;
+
+	protected Topic(final String title) {
+		this.title = title;
+	}
+
+	public String getTitle() {
+		return this.title;
+	}
+
+	public abstract void add(Message message);
+
+	public abstract Set<String> getParticipants();
+}

src/main/java/fr/imirhil/april/hebdobot/statusnet/Client.java

+package fr.imirhil.april.hebdobot.statusnet;
+
+public class Client {
+
+}

src/main/java/fr/imirhil/april/hebdobot/xml/UserAlias.java

+package fr.imirhil.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.xml.sax.SAXException;
+
+public class UserAlias {
+	private final Map<String, String> aliases = new HashMap<String, String>();
+
+	public UserAlias(final InputStream source) {
+		try {
+			final Unmarshaller u =
+					JAXBContext.newInstance(Users.class).createUnmarshaller();
+			u.setSchema(SchemaFactory
+					.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI)
+					.newSchema(
+							UserAlias.class
+									.getResource("/fr/imirhil/april/hebdobot/users.xsd")));
+
+			for (final User user : u
+					.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 e) {
+			e.printStackTrace();
+			throw new RuntimeException(e);
+		} catch (final JAXBException e) {
+			e.printStackTrace();
+			throw new RuntimeException(e);
+		}
+	}
+
+	public String getRealName(final String nick) {
+		for (final Entry<String, String> entry : this.aliases.entrySet()) {
+			if (nick.toLowerCase().contains(entry.getKey().toLowerCase())) {
+				return entry.getValue() + " ( " + nick + " )";
+			}
+		}
+		return nick;
+	}
+}

src/main/java/fr/imirhil/april/hebdobot/xml/UserService.java

-package fr.imirhil.april.hebdobot.xml;
-
-import java.io.File;
-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.xml.sax.SAXException;
-
-public class UserService {
-	private final Map<String, String> aliases = new HashMap<String, String>();
-
-	public UserService() {
-		try {
-			final Unmarshaller u =
-					JAXBContext.newInstance(Users.class).createUnmarshaller();
-			u.setSchema(SchemaFactory
-					.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI)
-					.newSchema(
-							UserService.class
-									.getResource("/fr/imirhil/april/hebdobot/users.xsd")));
-
-			for (final User user : u
-					.unmarshal(new StreamSource(new File("users.xml")),
-							Users.class).getValue().getUser()) {
-				final String realName = user.getRealName();
-				for (final String nick : user.getNick()) {
-					this.aliases.put(nick, realName);
-				}
-			}
-		} catch (final SAXException e) {
-			e.printStackTrace();
-			throw new RuntimeException(e);
-		} catch (final JAXBException e) {
-			e.printStackTrace();
-			throw new RuntimeException(e);
-		}
-	}
-
-	public String getRealName(final String nick) {
-		for (final Entry<String, String> entry : this.aliases.entrySet()) {
-			if (nick.toLowerCase().contains(entry.getKey().toLowerCase())) {
-				return entry.getValue() + " ( " + nick + " )";
-			}
-		}
-		return nick;
-	}
-}

src/main/resources/log4j.properties

+log4j.rootLogger = warn, stdout
+
+log4j.logger.fr.imirhil.april.hebdobot = info
+
+log4j.appender.stdout = org.apache.log4j.ConsoleAppender
+log4j.appender.stdout.layout = org.apache.log4j.PatternLayout
+log4j.appender.stdout.layout.ConversionPattern = %d %-5p %c - %m%n
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.