diff --git a/src/main/java/net/locusworks/discord/eighttrack/database/repos/GuildSongRepository.java b/src/main/java/net/locusworks/discord/eighttrack/database/repos/GuildSongRepository.java index fc6e85d..41efd54 100644 --- a/src/main/java/net/locusworks/discord/eighttrack/database/repos/GuildSongRepository.java +++ b/src/main/java/net/locusworks/discord/eighttrack/database/repos/GuildSongRepository.java @@ -28,6 +28,7 @@ package net.locusworks.discord.eighttrack.database.repos; import java.util.List; +import java.util.Set; import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.CrudRepository; @@ -53,4 +54,9 @@ public interface GuildSongRepository extends CrudRepository { @Query("SELECT gs FROM GuildSong gs WHERE gs.guild.guildId = ?1 ORDER BY RAND()") List findRandomSong(Long guildId); + List findByGuildAndUuidIn(DiscordGuild guild, Set uuid); + + @Query("SELECT gs FROM GuildSong gs WHERE gs.guild.guildId = ?1 AND gs.uuid = ?2") + List findByGuildAndUuidIn(Long guildId, Set uuid); + } diff --git a/src/main/java/net/locusworks/discord/eighttrack/handlers/DiscordEventHandler.java b/src/main/java/net/locusworks/discord/eighttrack/handlers/DiscordEventHandler.java index 462b0b4..9c2e5b1 100644 --- a/src/main/java/net/locusworks/discord/eighttrack/handlers/DiscordEventHandler.java +++ b/src/main/java/net/locusworks/discord/eighttrack/handlers/DiscordEventHandler.java @@ -174,6 +174,10 @@ public class DiscordEventHandler extends ListenerAdapter { return; case "-playlist": gmh.playlist(event, commands); + return; + case "+delete": + gmh.delete(event, commands); + return; default: return; } diff --git a/src/main/java/net/locusworks/discord/eighttrack/handlers/GuildMusicHandler.java b/src/main/java/net/locusworks/discord/eighttrack/handlers/GuildMusicHandler.java index 8bf32f5..aff80e5 100644 --- a/src/main/java/net/locusworks/discord/eighttrack/handlers/GuildMusicHandler.java +++ b/src/main/java/net/locusworks/discord/eighttrack/handlers/GuildMusicHandler.java @@ -116,6 +116,11 @@ public class GuildMusicHandler { public void playlist(GuildMessageReceivedEvent event, List commands) throws Exception { + if (commands == null || commands.isEmpty()) { + event.getChannel().sendMessage("Missing command for -playlist. Valid commands are: add, delete, list, play").queue(); + return; + } + String command = commands.remove(0); switch(command) { @@ -328,6 +333,63 @@ public class GuildMusicHandler { } } + public void list(GuildMessageReceivedEvent event) { + List gsList = guildSongRepoService.getGuildSongRepo().findByGuild(guildId); + + if (gsList == null || gsList.isEmpty()) { + event.getChannel().sendMessage("There is no music for this guild.").queue(); + return; + } + + int longestSong = 0; + int longestArtist = 0; + for(GuildSong gs : gsList) { + if (gs.getSong().getTitle().length() > longestSong) longestSong = gs.getSong().getTitle().length(); + if (gs.getSong().getArtist().length() > longestArtist) longestArtist = gs.getSong().getArtist().length(); + } + + String fmt = "%6s | %-" + longestSong +"s | %-" + longestArtist +"s | %s%n"; + int count = 0; + StringBuilder sb = new StringBuilder(); + sb.append("**" + "Currently available songs for " + event.getGuild().getName() + "**\n\n```"); + sb.append(String.format(fmt, "Track", "Title", "Artist", "id")); + sb.append(StringUtils.repeat("-", 27 + longestSong + longestArtist)).append("\n"); + + for(GuildSong gs : gsList) { + sb.append(String.format(fmt, ++count, gs.getSong().getTitle(), gs.getSong().getArtist(), gs.getUuid())); + } + sb.append("```"); + event.getChannel().sendMessage(sb.toString()).queue(); + } + + public void delete(GuildMessageReceivedEvent event, List commands) { + if (!event.getMessage().getMember().hasPermission(Permission.ADMINISTRATOR, Permission.MANAGE_SERVER)) { + event.getChannel().sendMessage(String.format("Sorry <@%s> i can't do that. *psst: you have to have manage server, or administrator role*", event.getMember().getIdLong())).queue(); + return; + } + + if (commands == null || commands.isEmpty()) { + event.getChannel().sendMessage(event.getAuthor().getAsMention() + " please provide the name of the playlist to play").queue(); + return; + } + + if (commands == null || commands.isEmpty()) { + event.getChannel().sendMessage("Missing command for +delete. Valid commands are: song, playlist").queue(); + return; + } + + String command = commands.remove(0); + + switch(command) { + case "song": + deleteSong(event, commands); + return; + case "playlist": + deleteUserPlayList(event, commands); + return; + } + } + private void playPlayList(GuildMessageReceivedEvent event, List commands) throws Exception { if (commands == null || commands.isEmpty()) { event.getChannel().sendMessage(event.getAuthor().getAsMention() + " please provide the name of the playlist to play").queue(); @@ -379,38 +441,58 @@ public class GuildMusicHandler { throw new IOException("Unable to find guild in database. Please contact administrator"); } - Path output = musicDir; - if (result.getArtist() != null) { - output = output.resolve(result.getArtist()); - if (result.getAlbum() != null) { - output = output.resolve(result.getAlbum()); + String hash = HashUtils.hash("SHA-1", result.getData()); + + GuildSong gs = guildSongRepoService.getGuildSongRepo().findByGuildAndSongHash(event.getGuild().getIdLong(), hash); + if (gs != null) { + MessageEmbed embed = new EmbedBuilder() + .setColor(Color.ORANGE) + .setThumbnail(event.getGuild().getIconUrl()) + .setTitle("Upload Results for " + fileName) + .setDescription(String.format("**%s** by __%s__ already exists. ID: `%s`", gs.getSong().getTitle(), gs.getSong().getArtist(), gs.getUuid())) + .setTimestamp(OffsetDateTime.now()) + .setFooter(event.getGuild().getSelfMember().getEffectiveName(), event.getGuild().getSelfMember().getUser().getAvatarUrl()) + .build(); + return embed; + } + + + Song song = guildSongRepoService.getSongRepo().findByFileHash(hash); + if (song == null) { + + Path output = musicDir; + if (result.getArtist() != null) { + output = output.resolve(result.getArtist()); + if (result.getAlbum() != null) { + output = output.resolve(result.getAlbum()); + } } - } - output = output.resolve(fileName); + output = output.resolve(fileName); - if (!Files.exists(output.toAbsolutePath().getParent())) { - Files.createDirectories(output.toAbsolutePath().getParent()); + if (!Files.exists(output.toAbsolutePath().getParent())) { + Files.createDirectories(output.toAbsolutePath().getParent()); + } + + Files.write(output, result.getData()); + + song = new Song(); + song.setAlbum(result.getAlbum()); + song.setArtist(result.getArtist()); + song.setDateAdded(new Date()); + song.setDiscNumber(result.getDiscNumber()); + if (result.getDuration() != null) + song.setDuration(BigInteger.valueOf(result.getDuration())); + song.setFileHash(hash); + song.setFilePath(output.toAbsolutePath().toString()); + song.setGenre(result.getGenre()); + song.setReleaseYear(result.getReleaseDate()); + song.setTitle(result.getTitle()); + song.setTrackNumber(result.getTrackNumber()); + + guildSongRepoService.getSongRepo().save(song); } - Files.write(output, result.getData()); - - Song song = new Song(); - song.setAlbum(result.getAlbum()); - song.setArtist(result.getArtist()); - song.setDateAdded(new Date()); - song.setDiscNumber(result.getDiscNumber()); - if (result.getDuration() != null) - song.setDuration(BigInteger.valueOf(result.getDuration())); - song.setFileHash(HashUtils.hash("SHA-1", result.getData())); - song.setFilePath(output.toAbsolutePath().toString()); - song.setGenre(result.getGenre()); - song.setReleaseYear(result.getReleaseDate()); - song.setTitle(result.getTitle()); - song.setTrackNumber(result.getTrackNumber()); - - guildSongRepoService.getSongRepo().save(song); - - GuildSong gs = new GuildSong(); + gs = new GuildSong(); gs.setDateAdded(new Date()); gs.setGuild(guild); gs.setSong(song); @@ -440,62 +522,6 @@ public class GuildMusicHandler { return embed; } - public void list(GuildMessageReceivedEvent event) { - List gsList = guildSongRepoService.getGuildSongRepo().findByGuild(guildId); - - if (gsList == null || gsList.isEmpty()) { - event.getChannel().sendMessage("There is no music for this guild.").queue(); - return; - } - - int longestSong = 0; - int longestArtist = 0; - for(GuildSong gs : gsList) { - if (gs.getSong().getTitle().length() > longestSong) longestSong = gs.getSong().getTitle().length(); - if (gs.getSong().getArtist().length() > longestArtist) longestArtist = gs.getSong().getArtist().length(); - } - - String fmt = "%6s | %-" + longestSong +"s | %-" + longestArtist +"s | %s%n"; - int count = 0; - StringBuilder sb = new StringBuilder(); - sb.append("**" + "Currently available songs for " + event.getGuild().getName() + "**\n\n```"); - sb.append(String.format(fmt, "Track", "Title", "Artist", "id")); - sb.append(StringUtils.repeat("-", 27 + longestSong + longestArtist)).append("\n"); - - for(GuildSong gs : gsList) { - sb.append(String.format(fmt, ++count, gs.getSong().getTitle(), gs.getSong().getArtist(), gs.getUuid())); - } - sb.append("```"); - event.getChannel().sendMessage(sb.toString()).queue(); - } - - private void loadRandomSong() throws Exception { - List gsList = null; - - if (currentPlaylist == null) { - gsList = guildSongRepoService.getGuildSongRepo().findByGuild(guildId); - } else { - gsList = guildSongRepoService.getGuildPlaylistSongRepo().findByGuildPlaylist(currentPlaylist).stream().map(gpl -> gpl.getGuildSong()).collect(Collectors.toList()); - } - if (gsList == null || gsList.isEmpty()) return; - - Random random = new Random(System.currentTimeMillis()); - int item = random.nextInt(gsList.size()); - - GuildSong song = gsList.get(item); - - apm.loadItem(song.getSong().getFilePath(), ts).get(); - } - - private boolean findSong(String uuid) throws Exception { - GuildSong gs = guildSongRepoService.getGuildSongRepo().findByUuid(uuid); - if (gs == null) return false; - - apm.loadItem(gs.getSong().getFilePath(), ts).get(); - - return true; - } - private void listPlayList(GuildMessageReceivedEvent event, List commands) { if (commands == null || commands.isEmpty()) { List userPlaylist = guildSongRepoService.getGuildPlaylistRepo().findByGuildAndUserIdFetchSongs(event.getGuild().getIdLong(), event.getMember().getIdLong()); @@ -564,6 +590,61 @@ public class GuildMusicHandler { } + private void deleteSong(GuildMessageReceivedEvent event, List commands) { + if (commands == null || commands.isEmpty()) { + event.getChannel().sendMessage(event.getAuthor().getAsMention() + ", you have to provide the list of uuids for songs to remove").queue(); + return; + } + + List songs = guildSongRepoService.getGuildSongRepo().findByGuildAndUuidIn(event.getGuild().getIdLong(), commands.stream().collect(Collectors.toSet())); + if (songs.isEmpty()) { + event.getChannel().sendMessage(event.getAuthor().getAsMention() + ", there are no songs for this guild").queue(); + return; + } + + StringBuilder sb = new StringBuilder("Are you sure you want to delete the following songs?\n"); + for (GuildSong gs : songs) { + sb.append(String.format("**%s** by __%s__%n", gs.getSong().getTitle(), gs.getSong().getArtist())); + } + + MessageEmbed embed = new EmbedBuilder() + .setColor(Color.RED) + .setTitle("Delete Playlist Songs") + .setDescription(sb.toString()) + .setTimestamp(OffsetDateTime.now()) + .setFooter(event.getGuild().getSelfMember().getEffectiveName(), event.getGuild().getSelfMember().getUser().getAvatarUrl()) + .build(); + + event.getChannel().sendMessage(embed).queue((msg) -> { + + ReactionListener handler = new ReactionListener<>(event.getAuthor().getIdLong(), msg.getId()); + handler.setExpiresIn(TimeUnit.MINUTES, 1); + handler.registerReaction(Reactions.CHECK_MARK_BUTTON, (ret) -> deleteGuildSongsConfirm(songs, event.getMember().getAsMention(), msg)); + handler.registerReaction(Reactions.CROSS_MARK_BUTTON, (ret) -> deleteMessage(msg)); + + reactionHandler.addReactionListener(guildId, msg, handler); + }); + + } + + private void deleteUserPlayList(GuildMessageReceivedEvent event, List commands) { + // TODO Auto-generated method stub + + } + + private void deleteGuildSongsConfirm(List songs, String user, Message msg) { + try { + guildSongRepoService.getGuildSongRepo().deleteAll(songs); + msg.getChannel().sendMessage(user + ", songs were deleted successfully").complete(); + } catch (Exception ex) { + msg.getChannel().sendMessage("Sorry " + user + " I was unable to remove the selected songs. Reason: " + ex.getMessage()).complete(); + logger.error("Unable to delete songs: " + ex.getMessage()); + logger.error(ex); + } finally { + deleteMessage(msg); + } + } + private void deletePlayList(GuildMessageReceivedEvent event, List commands) { if (commands == null || commands.isEmpty()) { event.getChannel().sendMessage(event.getAuthor().getAsMention() + " you have to provide the playlist to create a new playlist (no spaces in name) and optionally a list of uuids for songs to add").queue(); @@ -743,6 +824,33 @@ public class GuildMusicHandler { event.getChannel().sendMessage(embed).queue(); } + private void loadRandomSong() throws Exception { + List gsList = null; + + if (currentPlaylist == null) { + gsList = guildSongRepoService.getGuildSongRepo().findByGuild(guildId); + } else { + gsList = guildSongRepoService.getGuildPlaylistSongRepo().findByGuildPlaylist(currentPlaylist).stream().map(gpl -> gpl.getGuildSong()).collect(Collectors.toList()); + } + if (gsList == null || gsList.isEmpty()) return; + + Random random = new Random(System.currentTimeMillis()); + int item = random.nextInt(gsList.size()); + + GuildSong song = gsList.get(item); + + apm.loadItem(song.getSong().getFilePath(), ts).get(); + } + + private boolean findSong(String uuid) throws Exception { + GuildSong gs = guildSongRepoService.getGuildSongRepo().findByUuid(uuid); + if (gs == null) return false; + + apm.loadItem(gs.getSong().getFilePath(), ts).get(); + + return true; + } + private void deleteMessage(Message msg) { try { msg.delete().complete();