Extend stats command.
authorDavid ‘Bombe’ Roden <bombe@pterodactylus.net>
Sat, 18 Oct 2014 12:00:55 +0000 (14:00 +0200)
committerDavid ‘Bombe’ Roden <bombe@pterodactylus.net>
Sat, 18 Oct 2014 12:34:49 +0000 (14:34 +0200)
src/main/java/net/pterodactylus/xdcc/core/Core.java
src/main/java/net/pterodactylus/xdcc/data/ConnectedNetwork.java [new file with mode: 0644]
src/main/java/net/pterodactylus/xdcc/ui/stdin/StatsCommand.java
src/test/java/net/pterodactylus/xdcc/ui/stdin/StatsCommandTest.java [new file with mode: 0644]

index c0a2288..10cb06d 100644 (file)
@@ -18,8 +18,6 @@
 package net.pterodactylus.xdcc.core;
 
 import static java.lang.String.format;
-import static java.lang.System.currentTimeMillis;
-import static java.util.concurrent.TimeUnit.HOURS;
 import static net.pterodactylus.irc.event.ChannelNotJoined.Reason.banned;
 import static net.pterodactylus.irc.event.ChannelNotJoined.Reason.registeredNicknamesOnly;
 import static net.pterodactylus.irc.util.MessageCleaner.getDefaultInstance;
@@ -38,6 +36,7 @@ import java.util.List;
 import java.util.Map;
 import java.util.Map.Entry;
 import java.util.concurrent.TimeUnit;
+import java.util.stream.Collectors;
 
 import net.pterodactylus.irc.Connection;
 import net.pterodactylus.irc.ConnectionBuilder;
@@ -70,12 +69,12 @@ import net.pterodactylus.xdcc.core.event.GenericMessage;
 import net.pterodactylus.xdcc.core.event.MessageReceived;
 import net.pterodactylus.xdcc.data.Bot;
 import net.pterodactylus.xdcc.data.Channel;
+import net.pterodactylus.xdcc.data.ConnectedNetwork;
 import net.pterodactylus.xdcc.data.Download;
 import net.pterodactylus.xdcc.data.Network;
 import net.pterodactylus.xdcc.data.Pack;
 import net.pterodactylus.xdcc.data.Server;
 
-import com.google.common.base.Function;
 import com.google.common.base.Optional;
 import com.google.common.base.Predicate;
 import com.google.common.collect.FluentIterable;
@@ -181,13 +180,25 @@ public class Core extends AbstractExecutionThreadService {
         *
         * @return All connected networks
         */
-       public Collection<Network> connectedNetworks() {
-               return Lists.newArrayList(Optional.presentInstances(FluentIterable.from(networkConnections.values()).transform(new Function<Connection, Optional<Network>>() {
-                       @Override
-                       public Optional<Network> apply(Connection connection) {
-                               return getNetwork(connection);
-                       }
-               })));
+       public Collection<ConnectedNetwork> connectedNetworks() {
+               return networkConnections.entrySet().stream().map((entry) -> {
+                       Network network = entry.getKey();
+                       Collection<Bot> bots = networkBots.row(network).values();
+                       int packCount = bots.stream().mapToInt((bot) -> bot.packs().size()).reduce((a, b) -> a + b).getAsInt();
+                       return new ConnectedNetwork(network, entry.getValue().hostname(),
+                                       entry.getValue().port(), entry.getValue().nickname(),
+                                       channels.stream()
+                                                       .filter((channel) -> channel.network()
+                                                                       .equals(network))
+                                                       .map(Channel::name)
+                                                       .collect(Collectors.<String>toList()),
+                                       extraChannels.stream()
+                                                       .filter((channel) -> channel.network()
+                                                                       .equals(network))
+                                                       .map(Channel::name)
+                                                       .collect(Collectors.<String>toList()),
+                                       bots.size(), packCount);
+               }).collect(Collectors.<ConnectedNetwork>toList());
        }
 
        /**
diff --git a/src/main/java/net/pterodactylus/xdcc/data/ConnectedNetwork.java b/src/main/java/net/pterodactylus/xdcc/data/ConnectedNetwork.java
new file mode 100644 (file)
index 0000000..183f1f3
--- /dev/null
@@ -0,0 +1,66 @@
+package net.pterodactylus.xdcc.data;
+
+import java.util.Collection;
+
+/**
+ * Collections information about a connected network.
+ *
+ * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
+ */
+public class ConnectedNetwork {
+
+       private final Network network;
+       private final String hostname;
+       private final int port;
+       private final String nickname;
+       private final Collection<String> channels;
+       private final Collection<String> forcedChannels;
+       private final int botCount;
+       private final int packCount;
+
+       public ConnectedNetwork(Network network, String hostname, int port,
+                       String nickname, Collection<String> channels,
+                       Collection<String> forcedChannels, int botCount, int packCount) {
+               this.network = network;
+               this.hostname = hostname;
+               this.port = port;
+               this.nickname = nickname;
+               this.channels = channels;
+               this.forcedChannels = forcedChannels;
+               this.botCount = botCount;
+               this.packCount = packCount;
+       }
+
+       public Network getNetwork() {
+               return network;
+       }
+
+       public String getHostname() {
+               return hostname;
+       }
+
+       public int getPort() {
+               return port;
+       }
+
+       public String getNickname() {
+               return nickname;
+       }
+
+       public Collection<String> getChannels() {
+               return channels;
+       }
+
+       public Collection<String> getForcedChannels() {
+               return forcedChannels;
+       }
+
+       public int getBotCount() {
+               return botCount;
+       }
+
+       public int getPackCount() {
+               return packCount;
+       }
+
+}
index 85b92d1..07f2288 100644 (file)
 
 package net.pterodactylus.xdcc.ui.stdin;
 
+import static java.lang.String.format;
 import static java.util.Collections.emptyList;
 
 import java.io.IOException;
 import java.io.Writer;
 import java.util.Collection;
 import java.util.List;
-import java.util.Set;
+import java.util.StringJoiner;
 
 import net.pterodactylus.xdcc.core.Core;
-import net.pterodactylus.xdcc.data.Bot;
-import net.pterodactylus.xdcc.data.Pack;
-
-import com.google.common.collect.Sets;
+import net.pterodactylus.xdcc.data.ConnectedNetwork;
 
 /**
  * Command that outputs a short statistic of what is going on.
@@ -38,23 +36,12 @@ import com.google.common.collect.Sets;
  */
 public class StatsCommand implements Command {
 
-       /** The core to operate on. */
        private final Core core;
 
-       /**
-        * Creates a new stats command.
-        *
-        * @param core
-        *              The core to operate on
-        */
        public StatsCommand(Core core) {
                this.core = core;
        }
 
-       //
-       // COMMAND METHODS
-       //
-
        @Override
        public String getName() {
                return "stats";
@@ -67,22 +54,27 @@ public class StatsCommand implements Command {
 
        @Override
        public State execute(State state, List<String> parameters, Writer outputWriter) throws IOException {
-               int configuredChannelsCount = core.channels().size();
-               int joinedChannelsCount = core.joinedChannels().size();
-               int extraChannelsCount = core.extraChannels().size();
-               Collection<Bot> bots = core.bots();
-               Set<String> packNames = Sets.newHashSet();
-               int packsCount = 0;
-               for (Bot bot : bots) {
-                       packsCount += bot.packs().size();
-                       for (Pack pack : bot) {
-                               packNames.add(pack.name());
-                       }
+               int totalBotCount = 0;
+               int totalPackCount = 0;
+               for (ConnectedNetwork network : core.connectedNetworks()) {
+                       dumpNetworkStats(outputWriter, network);
+                       totalBotCount += network.getBotCount();
+                       totalPackCount += network.getPackCount();
                }
+               outputWriter.write(format("Total: %d bots, %d packs.\n", totalBotCount, totalPackCount));
+               return null;
+       }
 
-               outputWriter.write(String.format("%d channels (%d joined, %d extra), %d bots offering %d packs (%d unique).\n", configuredChannelsCount, joinedChannelsCount, extraChannelsCount, bots.size(), packsCount, packNames.size()));
-               outputWriter.flush();
-               return state;
+       private void dumpNetworkStats(Writer outputWriter, ConnectedNetwork network) throws IOException {
+               outputWriter.write(format("Connected to %s via %s:%d.\n", network.getNetwork().name(), network.getHostname(), network.getPort(), network.getNickname()));
+               StringJoiner joinedChannels = new StringJoiner(", ");
+               network.getChannels().stream().forEach(
+                               (channel) -> joinedChannels.add(channel));
+               StringJoiner forceJoinedChannels = new StringJoiner(", ");
+               network.getForcedChannels().stream().forEach((channel) -> forceJoinedChannels.add(channel));
+               outputWriter.write(format("  Joined %s, force-joined %s.\n",
+                               joinedChannels, forceJoinedChannels));
+               outputWriter.write(format("  %d bots serving %d packs.\n", network.getBotCount(), network.getPackCount()));
        }
 
 }
diff --git a/src/test/java/net/pterodactylus/xdcc/ui/stdin/StatsCommandTest.java b/src/test/java/net/pterodactylus/xdcc/ui/stdin/StatsCommandTest.java
new file mode 100644 (file)
index 0000000..338fe27
--- /dev/null
@@ -0,0 +1,72 @@
+package net.pterodactylus.xdcc.ui.stdin;
+
+import static java.util.Arrays.asList;
+import static java.util.Collections.emptyList;
+import static net.pterodactylus.xdcc.data.Network.builder;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.is;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import java.io.IOException;
+import java.io.StringWriter;
+
+import net.pterodactylus.xdcc.core.Core;
+import net.pterodactylus.xdcc.data.ConnectedNetwork;
+
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * TODO
+ *
+ * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
+ */
+public class StatsCommandTest {
+
+       private final Core core = mock(Core.class);
+       private final StatsCommand command =
+                       new StatsCommand(core);
+
+       @Before
+       public void setupCore() {
+               ConnectedNetwork network1 = new ConnectedNetwork(
+                               builder("TestNet").build(),
+                               "irc.test.net",
+                               6667,
+                               "Nickname1",
+                               asList("#channel1", "#channel2"),
+                               asList("#forced"),
+                               17,
+                               445
+               );
+               ConnectedNetwork network2 = new ConnectedNetwork(
+                               builder("DummyNet").build(),
+                               "irc.dummy.net",
+                               6789,
+                               "Nickname2",
+                               asList("#dummy1", "#dummy2"),
+                               asList("#foo", "#bar"),
+                               65,
+                               234
+               );
+               when(core.connectedNetworks()).thenReturn(asList(network1, network2));
+       }
+
+       @Test
+       public void extendedStatsDumpContainsTheCorrectData() throws IOException {
+               StringWriter writer = new StringWriter();
+               command.execute(null, emptyList(), writer);
+               String result = writer.toString();
+               assertThat(result, is(
+                               "Connected to TestNet via irc.test.net:6667.\n" +
+                               "  Joined #channel1, #channel2, force-joined #forced.\n" +
+                               "  17 bots serving 445 packs.\n" +
+                               "Connected to DummyNet via irc.dummy.net:6789.\n" +
+                               "  Joined #dummy1, #dummy2, force-joined #foo, #bar.\n" +
+                               "  65 bots serving 234 packs.\n" +
+                               "Total: 82 bots, 679 packs.\n"
+               ));
+       }
+
+}