@@ -0,0 +1,2458 @@
+package peergos.server;%0A%0Aimport peergos.shared.*;%0Aimport peergos.shared.corenode.*;%0Aimport peergos.shared.crypto.hash.*;%0Aimport peergos.shared.merklebtree.*;%0Aimport peergos.shared.user.*;%0A%0Aimport java.net.*;%0Aimport java.time.*;%0Aimport java.util.*;%0Aimport java.util.stream.*;%0A%0Apublic class UserStats %7B%0A%0A    public static void main(String%5B%5D args) throws Exception %7B%0A        Crypto crypto = Crypto.initJava();%0A        NetworkAccess network = NetworkAccess.buildJava(new URL(%22https://demo.peergos.net%22)).get();%0A        List%3CString%3E usernames = network.coreNode.getUsernames(%22%22).get();%0A        List%3CSummary%3E summaries = usernames.stream().parallel().flatMap(username -%3E %7B%0A            try %7B%0A                List%3CUserPublicKeyLink%3E chain = network.coreNode.getChain(username).get();%0A                UserPublicKeyLink last = chain.get(chain.size() - 1);%0A                LocalDate expiry = last.claim.expiry;%0A                Set%3CPublicKeyHash%3E ownedKeysRecursive = WriterData.getOwnedKeysRecursive(username, network.coreNode, network.mutable, network.dhtClient);%0A                long total = 0;%0A                for (PublicKeyHash writer : ownedKeysRecursive) %7B%0A                    MaybeMultihash target = network.mutable.getPointerTarget(writer, network.dhtClient).get();%0A                    if (target.isPresent())%0A                        total += network.dhtClient.getRecursiveBlockSize(target.get()).get();%0A                %7D%0A                String summary = %22User: %22 + username + %22, expiry: %22 + expiry + %22 usage: %22 + total + %22%5Cn%22;%0A                System.out.println(summary);%0A                return Stream.of(new Summary(username, expiry, total));%0A            %7D catch (Exception e) %7B%0A                System.err.println(%22Error for %22 + username);%0A                e.printStackTrace();%0A                return Stream.empty();%0A            %7D%0A        %7D).collect(Collectors.toList());%0A%0A        summaries.sort((a, b) -%3E (int) (b.usage - a.usage));%0A        summaries.forEach(System.out::println);%0A    %7D%0A%0A    private static class Summary %7B%0A        public final String username;%0A        public final LocalDate expiry;%0A        public final long usage;%0A%0A        public Summary(String username, LocalDate expiry, long usage) %7B%0A            this.username = username;%0A            this.expiry = expiry;%0A            this.usage = usage;%0A        %7D%0A%0A        public String toString() %7B%0A            return %22User: %22 + username + %22, expiry: %22 + expiry + %22 usage: %22 + usage;%0A        %7D%0A    %7D%0A%7D%0A

Add util for calculating global public stats