mirror of
https://github.com/Sheldan/abstracto.git
synced 2026-01-27 23:09:05 +00:00
[AB-333] providing some dates as separate instants instead of relying on the member attributes
truncating date to day when displaying the date for export emote stats fixing wrong message when confirming a command and adding missing exception handling
This commit is contained in:
@@ -313,13 +313,16 @@ public class MuteServiceBean implements MuteService {
|
|||||||
finalFuture.complete(null)
|
finalFuture.complete(null)
|
||||||
).exceptionally(throwable1 -> {
|
).exceptionally(throwable1 -> {
|
||||||
log.error("Unmute log failed to send for mute {} in server {}.", muteId, serverId, throwable1);
|
log.error("Unmute log failed to send for mute {} in server {}.", muteId, serverId, throwable1);
|
||||||
finalFuture.complete(null);
|
finalFuture.completeExceptionally(null);
|
||||||
return null;
|
return null;
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
finalFuture.complete(null);
|
finalFuture.complete(null);
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
|
}).exceptionally(throwable -> {
|
||||||
|
finalFuture.completeExceptionally(throwable);
|
||||||
|
return null;
|
||||||
});
|
});
|
||||||
|
|
||||||
return finalFuture;
|
return finalFuture;
|
||||||
|
|||||||
@@ -269,6 +269,9 @@ public class WarnServiceBean implements WarnService {
|
|||||||
return null;
|
return null;
|
||||||
});
|
});
|
||||||
return null;
|
return null;
|
||||||
|
}).exceptionally(throwable -> {
|
||||||
|
sendingFuture.completeExceptionally(throwable);
|
||||||
|
return null;
|
||||||
});
|
});
|
||||||
|
|
||||||
return sendingFuture;
|
return sendingFuture;
|
||||||
|
|||||||
@@ -425,6 +425,7 @@ public class ModMailThreadServiceBean implements ModMailThreadService {
|
|||||||
.builder()
|
.builder()
|
||||||
.member(member)
|
.member(member)
|
||||||
.latestModMailThread(latestThread)
|
.latestModMailThread(latestThread)
|
||||||
|
.memberJoinDate(member.getTimeJoined().toInstant())
|
||||||
.pastModMailThreadCount((long)oldThreads.size())
|
.pastModMailThreadCount((long)oldThreads.size())
|
||||||
.build();
|
.build();
|
||||||
List<CompletableFuture<Message>> messages = channelService.sendEmbedTemplateInTextChannelList("modmail_thread_header", header, channel);
|
List<CompletableFuture<Message>> messages = channelService.sendEmbedTemplateInTextChannelList("modmail_thread_header", header, channel);
|
||||||
|
|||||||
@@ -6,6 +6,8 @@ import lombok.Getter;
|
|||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
import net.dv8tion.jda.api.entities.Member;
|
import net.dv8tion.jda.api.entities.Member;
|
||||||
|
|
||||||
|
import java.time.Instant;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This is the model used when a new mod mail thread is opened and a message containing some information about the user
|
* This is the model used when a new mod mail thread is opened and a message containing some information about the user
|
||||||
* is displayed for the user handling the mod mail thread.
|
* is displayed for the user handling the mod mail thread.
|
||||||
@@ -23,6 +25,7 @@ public class ModMailThreaderHeader {
|
|||||||
* for the user
|
* for the user
|
||||||
*/
|
*/
|
||||||
private ModMailThread latestModMailThread;
|
private ModMailThread latestModMailThread;
|
||||||
|
private Instant memberJoinDate;
|
||||||
/**
|
/**
|
||||||
* The amount of previous mod mail thread the user has.
|
* The amount of previous mod mail thread the user has.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ import java.io.File;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.time.Duration;
|
import java.time.Duration;
|
||||||
import java.time.Instant;
|
import java.time.Instant;
|
||||||
|
import java.time.temporal.ChronoUnit;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.CompletableFuture;
|
import java.util.concurrent.CompletableFuture;
|
||||||
@@ -71,7 +72,7 @@ public class ExportEmoteStats extends AbstractConditionableCommand {
|
|||||||
if(!parameters.isEmpty()) {
|
if(!parameters.isEmpty()) {
|
||||||
// if a duration is given, subtract this duration from the current point in time
|
// if a duration is given, subtract this duration from the current point in time
|
||||||
Duration duration = (Duration) parameters.get(0);
|
Duration duration = (Duration) parameters.get(0);
|
||||||
statsSince = Instant.now().minus(duration);
|
statsSince = Instant.now().minus(duration).truncatedTo(ChronoUnit.DAYS);
|
||||||
}
|
}
|
||||||
AServer actualServer = serverManagementService.loadServer(commandContext.getGuild().getIdLong());
|
AServer actualServer = serverManagementService.loadServer(commandContext.getGuild().getIdLong());
|
||||||
List<UsedEmote> usedEmotes = usedEmoteManagementService.loadEmoteUsagesForServerSince(actualServer, statsSince);
|
List<UsedEmote> usedEmotes = usedEmoteManagementService.loadEmoteUsagesForServerSince(actualServer, statsSince);
|
||||||
|
|||||||
@@ -50,11 +50,15 @@ public class UserInfo extends AbstractConditionableCommand {
|
|||||||
log.info("Force reloading member {} in guild {} for user info.", memberToShow.getId(), memberToShow.getGuild().getId());
|
log.info("Force reloading member {} in guild {} for user info.", memberToShow.getId(), memberToShow.getGuild().getId());
|
||||||
return memberService.forceReloadMember(memberToShow).thenCompose(member -> {
|
return memberService.forceReloadMember(memberToShow).thenCompose(member -> {
|
||||||
model.setMemberInfo(member);
|
model.setMemberInfo(member);
|
||||||
|
model.setCreationDate(member.getTimeCreated().toInstant());
|
||||||
|
model.setJoinDate(member.getTimeJoined().toInstant());
|
||||||
return self.sendResponse(commandContext, model)
|
return self.sendResponse(commandContext, model)
|
||||||
.thenApply(aVoid -> CommandResult.fromIgnored());
|
.thenApply(aVoid -> CommandResult.fromIgnored());
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
model.setMemberInfo(memberToShow);
|
model.setMemberInfo(memberToShow);
|
||||||
|
model.setCreationDate(memberToShow.getTimeCreated().toInstant());
|
||||||
|
model.setJoinDate(memberToShow.getTimeJoined().toInstant());
|
||||||
return self.sendResponse(commandContext, model)
|
return self.sendResponse(commandContext, model)
|
||||||
.thenApply(aVoid -> CommandResult.fromIgnored());
|
.thenApply(aVoid -> CommandResult.fromIgnored());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,6 +15,8 @@ import org.junit.runner.RunWith;
|
|||||||
import org.mockito.*;
|
import org.mockito.*;
|
||||||
import org.mockito.junit.MockitoJUnitRunner;
|
import org.mockito.junit.MockitoJUnitRunner;
|
||||||
|
|
||||||
|
import java.time.Instant;
|
||||||
|
import java.time.OffsetDateTime;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.concurrent.CompletableFuture;
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
|
||||||
@@ -43,6 +45,8 @@ public class UserInfoTest {
|
|||||||
CommandContext noParameters = CommandTestUtilities.getNoParameters();
|
CommandContext noParameters = CommandTestUtilities.getNoParameters();
|
||||||
when(noParameters.getAuthor().getGuild()).thenReturn(noParameters.getGuild());
|
when(noParameters.getAuthor().getGuild()).thenReturn(noParameters.getGuild());
|
||||||
when(noParameters.getAuthor().hasTimeJoined()).thenReturn(true);
|
when(noParameters.getAuthor().hasTimeJoined()).thenReturn(true);
|
||||||
|
when(noParameters.getAuthor().getTimeJoined()).thenReturn(OffsetDateTime.now());
|
||||||
|
when(noParameters.getAuthor().getTimeCreated()).thenReturn(OffsetDateTime.now());
|
||||||
when(self.sendResponse(eq(noParameters),any(UserInfoModel.class))).thenReturn(CompletableFuture.completedFuture(null));
|
when(self.sendResponse(eq(noParameters),any(UserInfoModel.class))).thenReturn(CompletableFuture.completedFuture(null));
|
||||||
CompletableFuture<CommandResult> result = testUnit.executeAsync(noParameters);
|
CompletableFuture<CommandResult> result = testUnit.executeAsync(noParameters);
|
||||||
verify(self, times(1)).sendResponse(eq(noParameters), modelArgumentCaptor.capture());
|
verify(self, times(1)).sendResponse(eq(noParameters), modelArgumentCaptor.capture());
|
||||||
@@ -56,6 +60,8 @@ public class UserInfoTest {
|
|||||||
CommandContext noParameters = CommandTestUtilities.getNoParameters();
|
CommandContext noParameters = CommandTestUtilities.getNoParameters();
|
||||||
when(noParameters.getAuthor().hasTimeJoined()).thenReturn(false);
|
when(noParameters.getAuthor().hasTimeJoined()).thenReturn(false);
|
||||||
Member loadedAuthor = Mockito.mock(Member.class);
|
Member loadedAuthor = Mockito.mock(Member.class);
|
||||||
|
when(loadedAuthor.getTimeJoined()).thenReturn(OffsetDateTime.now());
|
||||||
|
when(loadedAuthor.getTimeCreated()).thenReturn(OffsetDateTime.now());
|
||||||
when(noParameters.getAuthor().getGuild()).thenReturn(noParameters.getGuild());
|
when(noParameters.getAuthor().getGuild()).thenReturn(noParameters.getGuild());
|
||||||
when(memberService.forceReloadMember(noParameters.getAuthor())).thenReturn(CompletableFuture.completedFuture(loadedAuthor));
|
when(memberService.forceReloadMember(noParameters.getAuthor())).thenReturn(CompletableFuture.completedFuture(loadedAuthor));
|
||||||
when(self.sendResponse(eq(noParameters), modelArgumentCaptor.capture())).thenReturn(CompletableFuture.completedFuture(null));
|
when(self.sendResponse(eq(noParameters), modelArgumentCaptor.capture())).thenReturn(CompletableFuture.completedFuture(null));
|
||||||
@@ -69,6 +75,8 @@ public class UserInfoTest {
|
|||||||
public void executeTestWithParameterLoadedMember() {
|
public void executeTestWithParameterLoadedMember() {
|
||||||
Member member = Mockito.mock(Member.class);
|
Member member = Mockito.mock(Member.class);
|
||||||
when(member.hasTimeJoined()).thenReturn(true);
|
when(member.hasTimeJoined()).thenReturn(true);
|
||||||
|
when(member.getTimeJoined()).thenReturn(OffsetDateTime.now());
|
||||||
|
when(member.getTimeCreated()).thenReturn(OffsetDateTime.now());
|
||||||
CommandContext parameters = CommandTestUtilities.getWithParameters(Arrays.asList(member));
|
CommandContext parameters = CommandTestUtilities.getWithParameters(Arrays.asList(member));
|
||||||
when(member.getGuild()).thenReturn(parameters.getGuild());
|
when(member.getGuild()).thenReturn(parameters.getGuild());
|
||||||
when(self.sendResponse(eq(parameters), modelArgumentCaptor.capture())).thenReturn(CompletableFuture.completedFuture(null));
|
when(self.sendResponse(eq(parameters), modelArgumentCaptor.capture())).thenReturn(CompletableFuture.completedFuture(null));
|
||||||
@@ -85,6 +93,8 @@ public class UserInfoTest {
|
|||||||
CommandContext parameters = CommandTestUtilities.getWithParameters(Arrays.asList(member));
|
CommandContext parameters = CommandTestUtilities.getWithParameters(Arrays.asList(member));
|
||||||
when(member.getGuild()).thenReturn(parameters.getGuild());
|
when(member.getGuild()).thenReturn(parameters.getGuild());
|
||||||
Member loadedAuthor = Mockito.mock(Member.class);
|
Member loadedAuthor = Mockito.mock(Member.class);
|
||||||
|
when(loadedAuthor.getTimeJoined()).thenReturn(OffsetDateTime.now());
|
||||||
|
when(loadedAuthor.getTimeCreated()).thenReturn(OffsetDateTime.now());
|
||||||
when(memberService.forceReloadMember(member)).thenReturn(CompletableFuture.completedFuture(loadedAuthor));
|
when(memberService.forceReloadMember(member)).thenReturn(CompletableFuture.completedFuture(loadedAuthor));
|
||||||
when(self.sendResponse(eq(parameters), modelArgumentCaptor.capture())).thenReturn(CompletableFuture.completedFuture(null));
|
when(self.sendResponse(eq(parameters), modelArgumentCaptor.capture())).thenReturn(CompletableFuture.completedFuture(null));
|
||||||
CompletableFuture<CommandResult> result = testUnit.executeAsync(parameters);
|
CompletableFuture<CommandResult> result = testUnit.executeAsync(parameters);
|
||||||
|
|||||||
@@ -6,9 +6,13 @@ import lombok.Setter;
|
|||||||
import lombok.experimental.SuperBuilder;
|
import lombok.experimental.SuperBuilder;
|
||||||
import net.dv8tion.jda.api.entities.Member;
|
import net.dv8tion.jda.api.entities.Member;
|
||||||
|
|
||||||
|
import java.time.Instant;
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
@Setter
|
@Setter
|
||||||
@SuperBuilder
|
@SuperBuilder
|
||||||
public class UserInfoModel extends SlimUserInitiatedServerContext {
|
public class UserInfoModel extends SlimUserInitiatedServerContext {
|
||||||
private Member memberInfo;
|
private Member memberInfo;
|
||||||
|
private Instant joinDate;
|
||||||
|
private Instant creationDate;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -271,13 +271,13 @@ public class CommandReceivedHandler extends ListenerAdapter {
|
|||||||
List<CompletableFuture<Message>> confirmationMessageFutures = channelService.sendMessageToSendToChannel(message, event.getChannel());
|
List<CompletableFuture<Message>> confirmationMessageFutures = channelService.sendMessageToSendToChannel(message, event.getChannel());
|
||||||
FutureUtils.toSingleFutureGeneric(confirmationMessageFutures)
|
FutureUtils.toSingleFutureGeneric(confirmationMessageFutures)
|
||||||
.thenAccept(unused -> self.persistConfirmationCallbacks(model, confirmationMessageFutures.get(0).join()))
|
.thenAccept(unused -> self.persistConfirmationCallbacks(model, confirmationMessageFutures.get(0).join()))
|
||||||
.exceptionally(throwable -> self.failedCommandHandling(event, foundCommand, parsedParameters, commandContext, throwable));
|
.exceptionally(throwable -> self.handleFailedCommand(foundCommand, commandContext, throwable));
|
||||||
} else if(commandConfiguration.isAsync()) {
|
} else if(commandConfiguration.isAsync()) {
|
||||||
log.info("Executing async command {} for server {} in channel {} based on message {} by user {}.",
|
log.info("Executing async command {} for server {} in channel {} based on message {} by user {}.",
|
||||||
commandConfiguration.getName(), commandContext.getGuild().getId(), commandContext.getChannel().getId(), commandContext.getMessage().getId(), commandContext.getAuthor().getId());
|
commandConfiguration.getName(), commandContext.getGuild().getId(), commandContext.getChannel().getId(), commandContext.getMessage().getId(), commandContext.getAuthor().getId());
|
||||||
|
|
||||||
self.executeAsyncCommand(foundCommand, commandContext)
|
self.executeAsyncCommand(foundCommand, commandContext)
|
||||||
.exceptionally(throwable -> failedCommandHandling(event, foundCommand, parsedParameters, commandContext, throwable));
|
.exceptionally(throwable -> handleFailedCommand(foundCommand, commandContext, throwable));
|
||||||
} else {
|
} else {
|
||||||
commandResult = self.executeCommand(foundCommand, commandContext);
|
commandResult = self.executeCommand(foundCommand, commandContext);
|
||||||
}
|
}
|
||||||
@@ -287,32 +287,25 @@ public class CommandReceivedHandler extends ListenerAdapter {
|
|||||||
if(commandResult != null) {
|
if(commandResult != null) {
|
||||||
self.executePostCommandListener(foundCommand, commandContext, commandResult);
|
self.executePostCommandListener(foundCommand, commandContext, commandResult);
|
||||||
}
|
}
|
||||||
}).exceptionally(throwable -> failedCommandHandling(event, foundCommand, parsedParameters, commandContext, throwable));
|
}).exceptionally(throwable -> handleFailedCommand(foundCommand, commandContext, throwable));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private Void failedCommandHandling(MessageReceivedEvent event, Command foundCommand, Parameters parsedParameters, CommandContext commandContext, Throwable throwable) {
|
private Void handleFailedCommand(Command foundCommand, CommandContext commandContext, Throwable throwable) {
|
||||||
log.error("Asynchronous command {} failed.", foundCommand.getConfiguration().getName(), throwable);
|
log.error("Asynchronous command {} failed.", foundCommand.getConfiguration().getName(), throwable);
|
||||||
UserInitiatedServerContext rebuildUserContext = buildUserInitiatedServerContext(commandContext);
|
|
||||||
CommandContext rebuildContext = CommandContext.builder()
|
|
||||||
.author(event.getMember())
|
|
||||||
.guild(event.getGuild())
|
|
||||||
.channel(event.getTextChannel())
|
|
||||||
.message(event.getMessage())
|
|
||||||
.jda(event.getJDA())
|
|
||||||
.undoActions(commandContext.getUndoActions()) // TODO really do this? it would need to guarantee that its available and usable
|
|
||||||
.userInitiatedContext(rebuildUserContext)
|
|
||||||
.parameters(parsedParameters).build();
|
|
||||||
CommandResult failedResult = CommandResult.fromError(throwable.getMessage(), throwable);
|
CommandResult failedResult = CommandResult.fromError(throwable.getMessage(), throwable);
|
||||||
self.executePostCommandListener(foundCommand, rebuildContext, failedResult);
|
self.executePostCommandListener(foundCommand, commandContext, failedResult);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Transactional(isolation = Isolation.SERIALIZABLE)
|
@Transactional(isolation = Isolation.SERIALIZABLE)
|
||||||
public CompletableFuture<Void> executeAsyncCommand(Command foundCommand, CommandContext commandContext) {
|
public CompletableFuture<Void> executeAsyncCommand(Command foundCommand, CommandContext commandContext) {
|
||||||
return foundCommand.executeAsync(commandContext).thenAccept(result ->
|
return foundCommand.executeAsync(commandContext).thenAccept(result ->
|
||||||
executePostCommandListener(foundCommand, commandContext, result)
|
executePostCommandListener(foundCommand, commandContext, result)
|
||||||
);
|
).exceptionally(throwable -> {
|
||||||
|
handleFailedCommand(foundCommand, commandContext, throwable);
|
||||||
|
return null;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Transactional
|
@Transactional
|
||||||
@@ -391,10 +384,6 @@ public class CommandReceivedHandler extends ListenerAdapter {
|
|||||||
return buildUserInitiatedServerContext(event.getMember(), event.getTextChannel(), event.getGuild());
|
return buildUserInitiatedServerContext(event.getMember(), event.getTextChannel(), event.getGuild());
|
||||||
}
|
}
|
||||||
|
|
||||||
private UserInitiatedServerContext buildUserInitiatedServerContext(CommandContext context) {
|
|
||||||
return buildUserInitiatedServerContext(context.getAuthor(), context.getChannel(), context.getGuild());
|
|
||||||
}
|
|
||||||
|
|
||||||
public CompletableFuture<Parameters> getParsedParameters(UnParsedCommandParameter unParsedCommandParameter, Command command, Message message){
|
public CompletableFuture<Parameters> getParsedParameters(UnParsedCommandParameter unParsedCommandParameter, Command command, Message message){
|
||||||
List<ParseResult> parsedParameters = new ArrayList<>();
|
List<ParseResult> parsedParameters = new ArrayList<>();
|
||||||
List<Parameter> parameters = command.getConfiguration().getParameters();
|
List<Parameter> parameters = command.getConfiguration().getParameters();
|
||||||
|
|||||||
@@ -63,7 +63,12 @@ public class ConfirmationButtonClickedListener implements ButtonClickedListener
|
|||||||
log.info("Denying command {} in server {} from message {} in channel {} with event {}.",
|
log.info("Denying command {} in server {} from message {} in channel {} with event {}.",
|
||||||
commandCtx.getCommandName(), commandCtx.getServerId(), commandCtx.getMessageId(),
|
commandCtx.getCommandName(), commandCtx.getServerId(), commandCtx.getMessageId(),
|
||||||
commandCtx.getChannelId(), model.getEvent().getInteraction().getId());
|
commandCtx.getChannelId(), model.getEvent().getInteraction().getId());
|
||||||
cleanup(model, payload);
|
cleanup(model, payload)
|
||||||
|
.thenAccept(unused -> self.sendAbortNotification(model))
|
||||||
|
.exceptionally(throwable -> {
|
||||||
|
log.warn("Failed to clean up confirmation message {}.", model.getEvent().getMessageId());
|
||||||
|
return null;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
return ButtonClickedListenerResult.ACKNOWLEDGED;
|
return ButtonClickedListenerResult.ACKNOWLEDGED;
|
||||||
}
|
}
|
||||||
@@ -84,16 +89,11 @@ public class ConfirmationButtonClickedListener implements ButtonClickedListener
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void cleanup(ButtonClickedListenerModel model, CommandConfirmationPayload payload) {
|
private CompletableFuture<Void> cleanup(ButtonClickedListenerModel model, CommandConfirmationPayload payload) {
|
||||||
log.debug("Cleaning up component {} and {}.", payload.getOtherButtonComponentId(), model.getEvent().getComponentId());
|
log.debug("Cleaning up component {} and {}.", payload.getOtherButtonComponentId(), model.getEvent().getComponentId());
|
||||||
componentPayloadManagementService.deletePayloads(Arrays.asList(payload.getOtherButtonComponentId(), model.getEvent().getComponentId()));
|
componentPayloadManagementService.deletePayloads(Arrays.asList(payload.getOtherButtonComponentId(), model.getEvent().getComponentId()));
|
||||||
log.debug("Deleting confirmation message {}.", model.getEvent().getMessageId());
|
log.debug("Deleting confirmation message {}.", model.getEvent().getMessageId());
|
||||||
messageService.deleteMessage(model.getEvent().getMessage())
|
return messageService.deleteMessage(model.getEvent().getMessage());
|
||||||
.thenAccept(unused -> self.sendAbortNotification(model))
|
|
||||||
.exceptionally(throwable -> {
|
|
||||||
log.warn("Failed to clean up confirmation message {}.", model.getEvent().getMessageId());
|
|
||||||
return null;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public CompletableFuture<Void> sendAbortNotification(ButtonClickedListenerModel model) {
|
public CompletableFuture<Void> sendAbortNotification(ButtonClickedListenerModel model) {
|
||||||
|
|||||||
Reference in New Issue
Block a user