Search in sources :

Example 1 with MessageSet

use of org.javacord.api.entity.message.MessageSet in project Javacord by BtoBastian.

the class MessageSetImpl method getMessagesAround.

/**
 * Gets up to a given amount of messages in the given channel around a given message in any channel.
 * The given message will be part of the result in addition to the messages around if it was sent in the given
 * channel and does not count towards the limit.
 * Half of the messages will be older than the given message and half of the messages will be newer.
 * If there aren't enough older or newer messages, the actual amount of messages will be less than the given limit.
 * It's also not guaranteed to be perfectly balanced.
 *
 * @param channel The channel of the messages.
 * @param limit The limit of messages to get.
 * @param around Get messages around the message with this id.
 * @return The messages.
 * @see #getMessagesAroundAsStream(TextChannel, long)
 */
public static CompletableFuture<MessageSet> getMessagesAround(TextChannel channel, int limit, long around) {
    CompletableFuture<MessageSet> future = new CompletableFuture<>();
    channel.getApi().getThreadPool().getExecutorService().submit(() -> {
        try {
            // calculate the half limit.
            int halfLimit = limit / 2;
            // get the newer half
            MessageSet newerMessages = getMessagesAfter(channel, halfLimit, around).join();
            // get the older half + around message
            MessageSet olderMessages = getMessagesBefore(channel, halfLimit + 1, around + 1).join();
            // for example because the around message was from a different channel
            if (olderMessages.getNewestMessage().map(DiscordEntity::getId).map(id -> id != around).orElse(false)) {
                olderMessages = olderMessages.tailSet(olderMessages.getOldestMessage().orElseThrow(AssertionError::new), false);
            }
            // combine the messages into one collection
            Collection<Message> messages = Stream.of(olderMessages, newerMessages).flatMap(Collection::stream).collect(toList());
            // we are done
            future.complete(new MessageSetImpl(messages));
        } catch (Throwable t) {
            future.completeExceptionally(t);
        }
    });
    return future;
}
Also used : MessageSet(org.javacord.api.entity.message.MessageSet) MessageSet(org.javacord.api.entity.message.MessageSet) Arrays(java.util.Arrays) Spliterators(java.util.Spliterators) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) CompletableFuture(java.util.concurrent.CompletableFuture) RestMethod(org.javacord.core.util.rest.RestMethod) TreeSet(java.util.TreeSet) ArrayList(java.util.ArrayList) DiscordEntity(org.javacord.api.entity.DiscordEntity) RestRequest(org.javacord.core.util.rest.RestRequest) TextChannel(org.javacord.api.entity.channel.TextChannel) JsonNode(com.fasterxml.jackson.databind.JsonNode) StreamSupport(java.util.stream.StreamSupport) Iterator(java.util.Iterator) Predicate(java.util.function.Predicate) Collections.emptyList(java.util.Collections.emptyList) Collection(java.util.Collection) NavigableSet(java.util.NavigableSet) DiscordApiImpl(org.javacord.core.DiscordApiImpl) Message(org.javacord.api.entity.message.Message) RestEndpoint(org.javacord.core.util.rest.RestEndpoint) List(java.util.List) Collectors.toList(java.util.stream.Collectors.toList) Stream(java.util.stream.Stream) Comparator(java.util.Comparator) Collections(java.util.Collections) Spliterator(java.util.Spliterator) CompletableFuture(java.util.concurrent.CompletableFuture) Message(org.javacord.api.entity.message.Message) RestEndpoint(org.javacord.core.util.rest.RestEndpoint) DiscordEntity(org.javacord.api.entity.DiscordEntity)

Example 2 with MessageSet

use of org.javacord.api.entity.message.MessageSet in project Javacord by BtoBastian.

the class MessageSetImpl method getMessages.

/**
 * Gets up to a given amount of messages in the given channel.
 *
 * @param channel The channel of the messages.
 * @param limit The limit of messages to get.
 * @param before Get messages before the message with this id.
 * @param after Get messages after the message with this id.
 *
 * @return The messages.
 * @see #getMessagesAsStream(TextChannel, long, long)
 */
private static CompletableFuture<MessageSet> getMessages(TextChannel channel, int limit, long before, long after) {
    CompletableFuture<MessageSet> future = new CompletableFuture<>();
    channel.getApi().getThreadPool().getExecutorService().submit(() -> {
        try {
            // get the initial batch with the first <= 100 messages
            int initialBatchSize = ((limit % 100) == 0) ? 100 : limit % 100;
            MessageSet initialMessages = requestAsMessages(channel, initialBatchSize, before, after);
            // initialMessages is empty => READ_MESSAGE_HISTORY permission is denied or no more messages available
            if ((limit <= 100) || initialMessages.isEmpty()) {
                future.complete(initialMessages);
                return;
            }
            // calculate the amount and direction of remaining message to get
            // this will be a multiple of 100 and at least 100
            int remainingMessages = limit - initialBatchSize;
            int steps = remainingMessages / 100;
            // "before" is set or both are not set
            boolean older = (before != -1) || (after == -1);
            boolean newer = after != -1;
            // get remaining messages
            List<MessageSet> messageSets = new ArrayList<>();
            MessageSet lastMessages = initialMessages;
            messageSets.add(lastMessages);
            for (int step = 0; step < steps; ++step) {
                lastMessages = requestAsMessages(channel, 100, lastMessages.getOldestMessage().filter(message -> older).map(DiscordEntity::getId).orElse(-1L), lastMessages.getNewestMessage().filter(message -> newer).map(DiscordEntity::getId).orElse(-1L));
                // no more messages available
                if (lastMessages.isEmpty()) {
                    break;
                }
                messageSets.add(lastMessages);
            }
            // combine the message sets
            future.complete(new MessageSetImpl(messageSets.stream().flatMap(Collection::stream).collect(toList())));
        } catch (Throwable t) {
            future.completeExceptionally(t);
        }
    });
    return future;
}
Also used : MessageSet(org.javacord.api.entity.message.MessageSet) CompletableFuture(java.util.concurrent.CompletableFuture) ArrayList(java.util.ArrayList) RestEndpoint(org.javacord.core.util.rest.RestEndpoint)

Aggregations

ArrayList (java.util.ArrayList)2 CompletableFuture (java.util.concurrent.CompletableFuture)2 MessageSet (org.javacord.api.entity.message.MessageSet)2 RestEndpoint (org.javacord.core.util.rest.RestEndpoint)2 JsonNode (com.fasterxml.jackson.databind.JsonNode)1 Arrays (java.util.Arrays)1 Collection (java.util.Collection)1 Collections (java.util.Collections)1 Collections.emptyList (java.util.Collections.emptyList)1 Comparator (java.util.Comparator)1 Iterator (java.util.Iterator)1 List (java.util.List)1 NavigableSet (java.util.NavigableSet)1 Spliterator (java.util.Spliterator)1 Spliterators (java.util.Spliterators)1 TreeSet (java.util.TreeSet)1 AtomicBoolean (java.util.concurrent.atomic.AtomicBoolean)1 Predicate (java.util.function.Predicate)1 Collectors.toList (java.util.stream.Collectors.toList)1 Stream (java.util.stream.Stream)1