From 8cc465e53d80833adb2edc173c1955c0d3074abe Mon Sep 17 00:00:00 2001 From: Liam Date: Fri, 5 Jul 2024 23:59:27 +0100 Subject: [PATCH] clean spotify commands --- .../bat/exception/BatException.java | 10 --- .../bat/features/spotify/SpotifyFeature.java | 87 +++++++++++-------- .../spotify/command/CurrentSubCommand.java | 70 +-------------- .../spotify/command/LinkSubCommand.java | 23 +++-- .../spotify/command/UnlinkSubCommand.java | 16 +++- .../bat/service/SpotifyService.java | 11 +-- 6 files changed, 89 insertions(+), 128 deletions(-) delete mode 100644 src/main/java/cc/fascinated/bat/exception/BatException.java diff --git a/src/main/java/cc/fascinated/bat/exception/BatException.java b/src/main/java/cc/fascinated/bat/exception/BatException.java deleted file mode 100644 index 7c9cf21..0000000 --- a/src/main/java/cc/fascinated/bat/exception/BatException.java +++ /dev/null @@ -1,10 +0,0 @@ -package cc.fascinated.bat.exception; - -/** - * @author Fascinated (fascinated7) - */ -public class BatException extends Exception { - public BatException(String message) { - super(message); - } -} diff --git a/src/main/java/cc/fascinated/bat/features/spotify/SpotifyFeature.java b/src/main/java/cc/fascinated/bat/features/spotify/SpotifyFeature.java index 0673d06..bf04dc8 100644 --- a/src/main/java/cc/fascinated/bat/features/spotify/SpotifyFeature.java +++ b/src/main/java/cc/fascinated/bat/features/spotify/SpotifyFeature.java @@ -3,7 +3,6 @@ package cc.fascinated.bat.features.spotify; import cc.fascinated.bat.Emojis; import cc.fascinated.bat.common.EmbedUtils; import cc.fascinated.bat.common.SpotifyUtils; -import cc.fascinated.bat.exception.BatException; import cc.fascinated.bat.features.Feature; import cc.fascinated.bat.features.FeatureProfile; import cc.fascinated.bat.features.spotify.command.SpotifyCommand; @@ -17,6 +16,7 @@ import net.dv8tion.jda.api.EmbedBuilder; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.ApplicationContext; import org.springframework.stereotype.Component; +import se.michaelthelin.spotify.enums.Action; import se.michaelthelin.spotify.model_objects.miscellaneous.CurrentlyPlaying; import se.michaelthelin.spotify.model_objects.specification.AlbumSimplified; import se.michaelthelin.spotify.model_objects.specification.Image; @@ -34,6 +34,25 @@ public class SpotifyFeature extends Feature { super.registerCommand(commandService, context.getBean(SpotifyCommand.class)); } + /** + * Pre-checks for Spotify commands. + * + * @param spotifyService The Spotify service. + * @param user The user. + */ + public static EmbedBuilder checkSpotify(@NonNull SpotifyService spotifyService, @NonNull BatUser user) { + SpotifyProfile profile = user.getProfile(SpotifyProfile.class); + if (!profile.hasLinkedAccount()) { + return EmbedUtils.errorEmbed() + .setDescription("%s You need to link your Spotify account before you can use this command.".formatted(Emojis.CROSS_MARK_EMOJI)); + } + if (!spotifyService.hasTrackPlaying(user)) { + return EmbedUtils.errorEmbed() + .setDescription("%s You need to have Spotify Premium to use this command.".formatted(Emojis.CROSS_MARK_EMOJI)); + } + return null; + } + /** * Gets the currently playing song. * @@ -43,12 +62,8 @@ public class SpotifyFeature extends Feature { @SneakyThrows public static EmbedBuilder currentSong(@NonNull SpotifyService spotifyService, @NonNull BatUser user) { SpotifyProfile profile = user.getProfile(SpotifyProfile.class); - if (!profile.hasLinkedAccount()) { - throw new BatException("%s You need to link your Spotify account before you can use this command.".formatted(Emojis.CROSS_MARK_EMOJI)); - } - - if (!spotifyService.hasTrackPlaying(user)) { - throw new BatException("%s You are not currently playing a track.".formatted(Emojis.CROSS_MARK_EMOJI)); + if (!profile.hasLinkedAccount() || !spotifyService.hasTrackPlaying(user)) { + return checkSpotify(spotifyService, user); } CurrentlyPlaying currentlyPlaying = spotifyService.getCurrentlyPlayingTrack(user); @@ -92,12 +107,8 @@ public class SpotifyFeature extends Feature { @SneakyThrows public static EmbedBuilder skipSong(@NonNull SpotifyService spotifyService, @NonNull BatUser user) { SpotifyProfile profile = user.getProfile(SpotifyProfile.class); - if (!profile.hasLinkedAccount()) { - throw new BatException("%s You need to link your Spotify account before you can use this command.".formatted(Emojis.CROSS_MARK_EMOJI)); - } - - if (!spotifyService.hasTrackPlaying(user)) { - throw new BatException("%s You are not currently playing a track.".formatted(Emojis.CROSS_MARK_EMOJI)); + if (!profile.hasLinkedAccount() || !spotifyService.hasTrackPlaying(user)) { + return checkSpotify(spotifyService, user); } CurrentlyPlaying currentlyPlaying = spotifyService.getCurrentlyPlayingTrack(user); @@ -131,23 +142,26 @@ public class SpotifyFeature extends Feature { @SneakyThrows public static EmbedBuilder pauseSong(@NonNull SpotifyService spotifyService, @NonNull BatUser user) { SpotifyProfile profile = user.getProfile(SpotifyProfile.class); - if (!profile.hasLinkedAccount()) { - throw new BatException("%s You need to link your Spotify account before you can use this command.".formatted(Emojis.CROSS_MARK_EMOJI)); + if (!profile.hasLinkedAccount() || !spotifyService.hasTrackPlaying(user)) { + return checkSpotify(spotifyService, user); } - - if (!spotifyService.hasTrackPlaying(user)) { - throw new BatException("%s You are not currently playing a track.".formatted(Emojis.CROSS_MARK_EMOJI)); - } - - boolean didPause = spotifyService.pausePlayback(user); CurrentlyPlaying currentlyPlaying = spotifyService.getCurrentlyPlayingTrack(user); + for (Action action : currentlyPlaying.getActions().getDisallows().getDisallowedActions()) { + if (action.equals(Action.PAUSING)) { + return EmbedUtils.errorEmbed() + .setDescription("%s This track is already paused.".formatted(Emojis.CROSS_MARK_EMOJI)); + } + } + + spotifyService.pausePlayback(user); Track track = (Track) currentlyPlaying.getItem(); return EmbedUtils.successEmbed() - .setDescription(didPause ? ":pause_button: Paused the track **[%s | %s](%s)**".formatted( + .setDescription("%s Paused the track **[%s | %s](%s)**".formatted( + Emojis.CHECK_MARK_EMOJI, track.getName(), track.getArtists()[0].getName(), - SpotifyUtils.getTrackUrl(currentlyPlaying)) - : "%s The current track is already paused.".formatted(Emojis.CROSS_MARK_EMOJI)); + SpotifyUtils.getTrackUrl(currentlyPlaying) + )); } /** @@ -159,22 +173,25 @@ public class SpotifyFeature extends Feature { @SneakyThrows public static EmbedBuilder resumeSong(@NonNull SpotifyService spotifyService, @NonNull BatUser user) { SpotifyProfile profile = user.getProfile(SpotifyProfile.class); - if (!profile.hasLinkedAccount()) { - throw new BatException("%s You need to link your Spotify account before you can use this command.".formatted(Emojis.CROSS_MARK_EMOJI)); + if (!profile.hasLinkedAccount() || !spotifyService.hasTrackPlaying(user)) { + return checkSpotify(spotifyService, user); } - - if (!spotifyService.hasTrackPlaying(user)) { - throw new BatException("%s You are not currently playing a track.".formatted(Emojis.CROSS_MARK_EMOJI)); - } - - boolean didResume = spotifyService.resumePlayback(user); CurrentlyPlaying currentlyPlaying = spotifyService.getCurrentlyPlayingTrack(user); + for (Action action : currentlyPlaying.getActions().getDisallows().getDisallowedActions()) { + if (action.equals(Action.RESUMING)) { + return EmbedUtils.errorEmbed() + .setDescription("%s This track is already playing.".formatted(Emojis.CROSS_MARK_EMOJI)); + } + } + + spotifyService.resumePlayback(user); Track track = (Track) currentlyPlaying.getItem(); return EmbedUtils.successEmbed() - .setDescription(didResume ? ":play_pause: Resumed the track **[%s | %s](%s)**".formatted( + .setDescription("%s Resumed the track **[%s | %s](%s)**".formatted( + Emojis.CHECK_MARK_EMOJI, track.getName(), track.getArtists()[0].getName(), - SpotifyUtils.getTrackUrl(currentlyPlaying)) - : "%s The current track is already playing.".formatted(Emojis.CROSS_MARK_EMOJI)); + SpotifyUtils.getTrackUrl(currentlyPlaying) + )); } } diff --git a/src/main/java/cc/fascinated/bat/features/spotify/command/CurrentSubCommand.java b/src/main/java/cc/fascinated/bat/features/spotify/command/CurrentSubCommand.java index c3520c9..7802012 100644 --- a/src/main/java/cc/fascinated/bat/features/spotify/command/CurrentSubCommand.java +++ b/src/main/java/cc/fascinated/bat/features/spotify/command/CurrentSubCommand.java @@ -1,30 +1,20 @@ package cc.fascinated.bat.features.spotify.command; -import cc.fascinated.bat.Emojis; import cc.fascinated.bat.command.BatCommand; import cc.fascinated.bat.command.CommandInfo; import cc.fascinated.bat.event.EventListener; -import cc.fascinated.bat.exception.BatException; import cc.fascinated.bat.features.spotify.SpotifyFeature; import cc.fascinated.bat.model.BatGuild; import cc.fascinated.bat.model.BatUser; import cc.fascinated.bat.service.SpotifyService; import lombok.NonNull; -import lombok.SneakyThrows; import lombok.extern.log4j.Log4j2; import net.dv8tion.jda.api.entities.Member; import net.dv8tion.jda.api.entities.channel.middleman.MessageChannel; -import net.dv8tion.jda.api.events.interaction.component.ButtonInteractionEvent; import net.dv8tion.jda.api.interactions.commands.SlashCommandInteraction; -import net.dv8tion.jda.api.interactions.components.ActionRow; -import net.dv8tion.jda.api.interactions.components.LayoutComponent; -import net.dv8tion.jda.api.interactions.components.buttons.Button; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; -import java.util.ArrayList; -import java.util.concurrent.TimeUnit; - /** * @author Fascinated (fascinated7) */ @@ -41,64 +31,6 @@ public class CurrentSubCommand extends BatCommand implements EventListener { @Override public void execute(BatGuild guild, @NonNull BatUser user, @NonNull MessageChannel channel, Member member, @NonNull SlashCommandInteraction event) { - event.replyEmbeds(SpotifyFeature.currentSong(spotifyService, user).build()).addComponents(createActions()).queue(message -> { - message.editOriginalComponents(new ArrayList<>()).queueAfter(5, TimeUnit.MINUTES); // Remove the buttons after 5 minutes - }); - } - - @Override @SneakyThrows - public void onButtonInteraction(BatGuild guild, @NonNull BatUser user, @NonNull ButtonInteractionEvent event) { - if (guild == null) { - return; - } - if (!event.getUser().getId().equals(user.getId())) { - throw new BatException("%s You cannot interact with this message.".formatted(Emojis.CROSS_MARK_EMOJI)); - } - - if (!event.getComponentId().equals("pause") - && !event.getComponentId().equals("resume") - && !event.getComponentId().equals("skip")) { - return; - } - - switch (event.getComponentId()) { - case "pause" -> { - event.replyEmbeds(SpotifyFeature.pauseSong(spotifyService, user) - .appendDescription("\nThis message will disappear ".formatted(System.currentTimeMillis() / 1000 + 15)).build()) - .queue(message -> { - message.deleteOriginal().queueAfter(15, TimeUnit.SECONDS); - }); - } - case "resume" -> { - event.replyEmbeds(SpotifyFeature.resumeSong(spotifyService, user) - .appendDescription("\nThis message will disappear ".formatted(System.currentTimeMillis() / 1000 + 15)).build()) - .queue(message -> { - message.deleteOriginal().queueAfter(15, TimeUnit.SECONDS); - }); - } - case "skip" -> { - event.replyEmbeds(SpotifyFeature.skipSong(spotifyService, user) - .appendDescription("\nThis message will disappear ".formatted(System.currentTimeMillis() / 1000 + 15)).build()) - .queue(then -> { - then.deleteOriginal().queueAfter(15, TimeUnit.SECONDS); - event.getInteraction().getMessage().editMessageEmbeds(SpotifyFeature.currentSong(spotifyService, user).build()).queue(); - }); - } - } - } - - /** - * Creates the action buttons for the currently playing track - * - * @return The action buttons - */ - private LayoutComponent[] createActions() { - return new LayoutComponent[]{ - ActionRow.of( - Button.primary("pause", "Pause").withEmoji(Emojis.PAUSE_EMOJI), - Button.primary("resume", "Resume").withEmoji(Emojis.PLAY_EMOJI), - Button.primary("skip", "Skip").withEmoji(Emojis.SKIP_EMOJI) - ) - }; + event.replyEmbeds(SpotifyFeature.currentSong(spotifyService, user).build()).queue(); } } diff --git a/src/main/java/cc/fascinated/bat/features/spotify/command/LinkSubCommand.java b/src/main/java/cc/fascinated/bat/features/spotify/command/LinkSubCommand.java index 6c90391..682107b 100644 --- a/src/main/java/cc/fascinated/bat/features/spotify/command/LinkSubCommand.java +++ b/src/main/java/cc/fascinated/bat/features/spotify/command/LinkSubCommand.java @@ -6,7 +6,7 @@ import cc.fascinated.bat.command.BatCommand; import cc.fascinated.bat.command.CommandInfo; import cc.fascinated.bat.common.EmbedUtils; import cc.fascinated.bat.event.EventListener; -import cc.fascinated.bat.exception.BatException; +import cc.fascinated.bat.features.spotify.SpotifyFeature; import cc.fascinated.bat.features.spotify.profile.SpotifyProfile; import cc.fascinated.bat.model.BatGuild; import cc.fascinated.bat.model.BatUser; @@ -43,14 +43,20 @@ public class LinkSubCommand extends BatCommand implements EventListener { @Override @SneakyThrows public void execute(BatGuild guild, @NonNull BatUser user, @NonNull MessageChannel channel, Member member, @NonNull SlashCommandInteraction event) { if (!user.getId().equals(Consts.BOT_OWNER)) { - throw new BatException(""" + event.replyEmbeds(EmbedUtils.errorEmbed() + .setDescription(""" %s We are currently awaiting Spotify's approval for our application. Please check back later. Submitted on: - """.formatted(Emojis.CROSS_MARK_EMOJI)); + """.formatted(Emojis.CROSS_MARK_EMOJI)) + .build()) + .setEphemeral(true) + .queue(); + return; } SpotifyProfile profile = user.getProfile(SpotifyProfile.class); - if (profile.hasLinkedAccount()) { - throw new BatException("%s You have already linked your Spotify account.".formatted(Emojis.CROSS_MARK_EMOJI)); + if (!profile.hasLinkedAccount() || !spotifyService.hasTrackPlaying(user)) { + event.replyEmbeds(SpotifyFeature.checkSpotify(spotifyService, user).build()).queue(); + return; } event.replyEmbeds(EmbedUtils.genericEmbed() @@ -97,7 +103,12 @@ public class LinkSubCommand extends BatCommand implements EventListener { } String code = codeMapping.getAsString(); if (!spotifyService.isValidLinkCode(code)) { - throw new BatException("%s The link code you provided is invalid.".formatted(Emojis.CROSS_MARK_EMOJI)); + event.replyEmbeds(EmbedUtils.errorEmbed() + .setDescription("%s The link code you provided is invalid.".formatted(Emojis.CROSS_MARK_EMOJI)) + .build()) + .setEphemeral(true) + .queue(); + return; } spotifyService.linkAccount(user, code); diff --git a/src/main/java/cc/fascinated/bat/features/spotify/command/UnlinkSubCommand.java b/src/main/java/cc/fascinated/bat/features/spotify/command/UnlinkSubCommand.java index 758e499..d26637b 100644 --- a/src/main/java/cc/fascinated/bat/features/spotify/command/UnlinkSubCommand.java +++ b/src/main/java/cc/fascinated/bat/features/spotify/command/UnlinkSubCommand.java @@ -5,15 +5,17 @@ import cc.fascinated.bat.command.BatCommand; import cc.fascinated.bat.command.CommandInfo; import cc.fascinated.bat.common.EmbedUtils; import cc.fascinated.bat.event.EventListener; -import cc.fascinated.bat.exception.BatException; +import cc.fascinated.bat.features.spotify.SpotifyFeature; import cc.fascinated.bat.features.spotify.profile.SpotifyProfile; import cc.fascinated.bat.model.BatGuild; import cc.fascinated.bat.model.BatUser; +import cc.fascinated.bat.service.SpotifyService; import lombok.NonNull; import lombok.SneakyThrows; import net.dv8tion.jda.api.entities.Member; import net.dv8tion.jda.api.entities.channel.middleman.MessageChannel; import net.dv8tion.jda.api.interactions.commands.SlashCommandInteraction; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; /** @@ -22,11 +24,19 @@ import org.springframework.stereotype.Component; @Component @CommandInfo(name = "unlink", description = "Unlink your Spotify account") public class UnlinkSubCommand extends BatCommand implements EventListener { + private final SpotifyService spotifyService; + + @Autowired + public UnlinkSubCommand(@NonNull SpotifyService spotifyService) { + this.spotifyService = spotifyService; + } + @Override @SneakyThrows public void execute(BatGuild guild, @NonNull BatUser user, @NonNull MessageChannel channel, Member member, @NonNull SlashCommandInteraction event) { SpotifyProfile profile = user.getProfile(SpotifyProfile.class); - if (!profile.hasLinkedAccount()) { - throw new BatException("%s You do not have a linked Spotify account.".formatted(Emojis.CROSS_MARK_EMOJI)); + if (!profile.hasLinkedAccount() || !spotifyService.hasTrackPlaying(user)) { + event.replyEmbeds(SpotifyFeature.checkSpotify(spotifyService, user).build()).queue(); + return; } profile.reset(); diff --git a/src/main/java/cc/fascinated/bat/service/SpotifyService.java b/src/main/java/cc/fascinated/bat/service/SpotifyService.java index f0d2431..6f8d998 100644 --- a/src/main/java/cc/fascinated/bat/service/SpotifyService.java +++ b/src/main/java/cc/fascinated/bat/service/SpotifyService.java @@ -119,9 +119,8 @@ public class SpotifyService { * @return if the playback was paused */ @SneakyThrows - public boolean pausePlayback(BatUser user) { + public void pausePlayback(BatUser user) { getSpotifyApi(user).pauseUsersPlayback().build().execute(); - return true; } /** @@ -131,9 +130,8 @@ public class SpotifyService { * @return if the playback was paused */ @SneakyThrows - public boolean resumePlayback(BatUser user) { + public void resumePlayback(BatUser user) { getSpotifyApi(user).startResumeUsersPlayback().build().execute(); - return true; } /** @@ -173,12 +171,15 @@ public class SpotifyService { /** * Ensures the user has a valid Spotify access token. + *

+ * If the token is expired, it will be refreshed. + *

* * @param user the user to get the token for */ @SneakyThrows public void ensureValidToken(SpotifyProfile profile, BatUser user) { - if (profile.getExpiresAt() == null || profile.getExpiresAt() > System.currentTimeMillis()) { + if (profile.getExpiresAt() == null || profile.getExpiresAt() < System.currentTimeMillis()) { return; } SpotifyApi api = new SpotifyApi.Builder()