From c8260444bbc2d8d761842aeae21de28d02238dc8 Mon Sep 17 00:00:00 2001 From: Isaac Parenteau Date: Wed, 1 Jan 2020 00:22:02 -0600 Subject: [PATCH] Restructured how events were being handled to clean up the mess --- .../eighttrack/audio/Mp3UploadHandler.java | 12 -- .../events/AbstractEventHandler.java | 68 ++++++ .../events/handlers/NextSongHandler.java | 42 ++++ .../events/handlers/PlaySongHandler.java | 43 ++++ .../events/handlers/RepeatSongHandler.java | 43 ++++ .../events/handlers/StopSongHandler.java | 44 ++++ .../events/handlers/UpNextSongHandler.java | 43 ++++ .../events/handlers/UploadHandler.java | 204 ++++++++++++++++++ .../handlers/DiscordEventHandler.java | 82 +++---- .../handlers/GuildMusicHandler.java | 176 +-------------- 10 files changed, 540 insertions(+), 217 deletions(-) create mode 100644 src/main/java/net/locusworks/discord/eighttrack/events/AbstractEventHandler.java create mode 100644 src/main/java/net/locusworks/discord/eighttrack/events/handlers/NextSongHandler.java create mode 100644 src/main/java/net/locusworks/discord/eighttrack/events/handlers/PlaySongHandler.java create mode 100644 src/main/java/net/locusworks/discord/eighttrack/events/handlers/RepeatSongHandler.java create mode 100644 src/main/java/net/locusworks/discord/eighttrack/events/handlers/StopSongHandler.java create mode 100644 src/main/java/net/locusworks/discord/eighttrack/events/handlers/UpNextSongHandler.java create mode 100644 src/main/java/net/locusworks/discord/eighttrack/events/handlers/UploadHandler.java diff --git a/src/main/java/net/locusworks/discord/eighttrack/audio/Mp3UploadHandler.java b/src/main/java/net/locusworks/discord/eighttrack/audio/Mp3UploadHandler.java index e4ca354..bb6876d 100644 --- a/src/main/java/net/locusworks/discord/eighttrack/audio/Mp3UploadHandler.java +++ b/src/main/java/net/locusworks/discord/eighttrack/audio/Mp3UploadHandler.java @@ -35,11 +35,8 @@ import java.nio.file.Path; import java.nio.file.Paths; import java.util.UUID; import org.springframework.stereotype.Component; -import org.xml.sax.SAXException; import com.mpatric.mp3agic.ID3v2; -import com.mpatric.mp3agic.InvalidDataException; import com.mpatric.mp3agic.Mp3File; -import com.mpatric.mp3agic.UnsupportedTagException; @Component public class Mp3UploadHandler { @@ -74,13 +71,4 @@ public class Mp3UploadHandler { } } } - - public static void main(String args[]) throws IOException, SAXException, UnsupportedTagException, InvalidDataException { - String file = "E:\\Music2\\AronChupa\\01 I'm an Albatraoz.mp3"; - Path path = Paths.get(file); - - Mp3UploadHandler fuh = new Mp3UploadHandler(); - System.out.println(fuh.parse(path)); - } - } diff --git a/src/main/java/net/locusworks/discord/eighttrack/events/AbstractEventHandler.java b/src/main/java/net/locusworks/discord/eighttrack/events/AbstractEventHandler.java new file mode 100644 index 0000000..0e093cc --- /dev/null +++ b/src/main/java/net/locusworks/discord/eighttrack/events/AbstractEventHandler.java @@ -0,0 +1,68 @@ +package net.locusworks.discord.eighttrack.events; + +import java.util.List; +import net.dv8tion.jda.api.Permission; +import net.dv8tion.jda.api.entities.Message; +import net.dv8tion.jda.api.events.message.guild.GuildMessageReceivedEvent; +import net.dv8tion.jda.api.exceptions.ErrorResponseException; +import net.dv8tion.jda.api.requests.ErrorResponse; +import net.locusworks.discord.eighttrack.handlers.GuildMusicHandler; +import net.locusworks.discord.eighttrack.handlers.ReactionHandler; + +public abstract class AbstractEventHandler { + + private String command; + + public AbstractEventHandler(String command) { + this.command = command; + } + + public String getCommand() { + return this.command; + } + + public abstract void executeEvent(GuildMusicHandler musicHandler, GuildMessageReceivedEvent event, List commands); + + + public abstract String help(); + + protected boolean isAdmin(GuildMessageReceivedEvent event) { + 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 false; + } + return true; + } + + protected boolean checkCommands(GuildMessageReceivedEvent event, List commands, String msg) { + return checkCommands(event, commands, 0, msg); + } + + protected boolean checkCommands(GuildMessageReceivedEvent event, List commands, int minParams, String msg) { + if (commands == null || commands.isEmpty() || commands.size() < minParams) { + event.getChannel().sendMessage(msg).queue(); + return false; + } + return true; + } + + protected void sendMessage(GuildMessageReceivedEvent event, String msg) { + event.getChannel().sendMessage(msg).queue(); + } + + protected void sendMessage(GuildMessageReceivedEvent event, String msgFmt, Object... args) { + sendMessage(event, String.format(msgFmt, args)); + } + + protected void deleteMessage(Message msg, ReactionHandler reactionHandler, Long guildId) { + try { + msg.delete().complete(); + if (reactionHandler != null) { + reactionHandler.removeReactionListener(guildId, msg.getIdLong()); + } + } catch (ErrorResponseException ex) { + if (ex.getErrorResponse() != ErrorResponse.UNKNOWN_MESSAGE) throw ex; + } + } + +} diff --git a/src/main/java/net/locusworks/discord/eighttrack/events/handlers/NextSongHandler.java b/src/main/java/net/locusworks/discord/eighttrack/events/handlers/NextSongHandler.java new file mode 100644 index 0000000..ae32c7d --- /dev/null +++ b/src/main/java/net/locusworks/discord/eighttrack/events/handlers/NextSongHandler.java @@ -0,0 +1,42 @@ +package net.locusworks.discord.eighttrack.events.handlers; + +import java.util.List; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; +import net.dv8tion.jda.api.events.message.guild.GuildMessageReceivedEvent; +import net.locusworks.discord.eighttrack.events.AbstractEventHandler; +import net.locusworks.discord.eighttrack.handlers.GuildMusicHandler; +import net.locusworks.discord.eighttrack.services.RepositoryService; +import net.locusworks.logger.ApplicationLogger; +import net.locusworks.logger.ApplicationLoggerFactory; + +@Component +public class NextSongHandler extends AbstractEventHandler { + + private ApplicationLogger logger; + + @Autowired + private RepositoryService guildRepoService; + + public NextSongHandler() { + super("-next"); + logger = ApplicationLoggerFactory.getLogger(NextSongHandler.class); + } + + @Override + public void executeEvent(GuildMusicHandler musicHandler, GuildMessageReceivedEvent event, List commands) { + try { + musicHandler.next(event, commands); + } catch (Exception ex) { + logger.error("Unable to play next song: " + ex.getMessage(), ex); + guildRepoService.logEntry(event.getGuild().getIdLong(), ex, "Unable to play next song: %s", ex.getMessage()); + sendMessage(event, "Sorry I am unable to play next song: " + ex.getMessage()); + } + } + + @Override + public String help() { + return "-next (will stop song if one already playing)"; + } + +} diff --git a/src/main/java/net/locusworks/discord/eighttrack/events/handlers/PlaySongHandler.java b/src/main/java/net/locusworks/discord/eighttrack/events/handlers/PlaySongHandler.java new file mode 100644 index 0000000..4d278f0 --- /dev/null +++ b/src/main/java/net/locusworks/discord/eighttrack/events/handlers/PlaySongHandler.java @@ -0,0 +1,43 @@ +package net.locusworks.discord.eighttrack.events.handlers; + +import java.util.List; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; +import net.dv8tion.jda.api.events.message.guild.GuildMessageReceivedEvent; +import net.locusworks.discord.eighttrack.events.AbstractEventHandler; +import net.locusworks.discord.eighttrack.handlers.GuildMusicHandler; +import net.locusworks.discord.eighttrack.services.RepositoryService; +import net.locusworks.logger.ApplicationLogger; +import net.locusworks.logger.ApplicationLoggerFactory; + +@Component +public class PlaySongHandler extends AbstractEventHandler { + + private ApplicationLogger logger; + + @Autowired + private RepositoryService guildRepoService; + + public PlaySongHandler() { + super("-play"); + logger = ApplicationLoggerFactory.getLogger(PlaySongHandler.class); + } + + @Override + public void executeEvent(GuildMusicHandler musicHandler, GuildMessageReceivedEvent event, List commands) { + try { + musicHandler.play(event, commands); + musicHandler.isPlaying(true); + } catch (Exception ex) { + logger.error("Unable to play song: " + ex.getMessage(), ex); + guildRepoService.logEntry(event.getGuild().getIdLong(), ex, "Unable to play song: %s", ex.getMessage()); + sendMessage(event, "Sorry I am unable to play requested song: " + ex.getMessage()); + } + } + + @Override + public String help() { + return "-play (will not play song if a song is already playing)"; + } + +} diff --git a/src/main/java/net/locusworks/discord/eighttrack/events/handlers/RepeatSongHandler.java b/src/main/java/net/locusworks/discord/eighttrack/events/handlers/RepeatSongHandler.java new file mode 100644 index 0000000..475b73b --- /dev/null +++ b/src/main/java/net/locusworks/discord/eighttrack/events/handlers/RepeatSongHandler.java @@ -0,0 +1,43 @@ +package net.locusworks.discord.eighttrack.events.handlers; + +import java.util.List; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; +import net.dv8tion.jda.api.events.message.guild.GuildMessageReceivedEvent; +import net.locusworks.discord.eighttrack.events.AbstractEventHandler; +import net.locusworks.discord.eighttrack.handlers.GuildMusicHandler; +import net.locusworks.discord.eighttrack.services.RepositoryService; +import net.locusworks.logger.ApplicationLogger; +import net.locusworks.logger.ApplicationLoggerFactory; + +@Component +public class RepeatSongHandler extends AbstractEventHandler { + + private ApplicationLogger logger; + + @Autowired + private RepositoryService guildRepoService; + + public RepeatSongHandler() { + super("-repeat"); + logger = ApplicationLoggerFactory.getLogger(RepeatSongHandler.class); + } + + @Override + public void executeEvent(GuildMusicHandler musicHandler, GuildMessageReceivedEvent event, List commands) { + try { + musicHandler.repeat(event); + musicHandler.isPlaying(true); + } catch (Exception ex) { + logger.error("Unable to repeat songs: " + ex.getMessage(), ex); + guildRepoService.logEntry(event.getGuild().getIdLong(), ex, "Unable to repeat song: %s", ex.getMessage()); + sendMessage(event, "Sorry I am unable to repeat songs: " + ex.getMessage()); + } + } + + @Override + public String help() { + return "-repeat (repeats the current song list)"; + } + +} diff --git a/src/main/java/net/locusworks/discord/eighttrack/events/handlers/StopSongHandler.java b/src/main/java/net/locusworks/discord/eighttrack/events/handlers/StopSongHandler.java new file mode 100644 index 0000000..ecce361 --- /dev/null +++ b/src/main/java/net/locusworks/discord/eighttrack/events/handlers/StopSongHandler.java @@ -0,0 +1,44 @@ +package net.locusworks.discord.eighttrack.events.handlers; + +import java.util.List; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; +import net.dv8tion.jda.api.events.message.guild.GuildMessageReceivedEvent; +import net.locusworks.discord.eighttrack.events.AbstractEventHandler; +import net.locusworks.discord.eighttrack.handlers.GuildMusicHandler; +import net.locusworks.discord.eighttrack.services.RepositoryService; +import net.locusworks.logger.ApplicationLogger; +import net.locusworks.logger.ApplicationLoggerFactory; + +@Component +public class StopSongHandler extends AbstractEventHandler { + + private ApplicationLogger logger; + + @Autowired + private RepositoryService guildRepoService; + + public StopSongHandler() { + super("-stop"); + logger = ApplicationLoggerFactory.getLogger(StopSongHandler.class); + } + + @Override + public void executeEvent(GuildMusicHandler musicHandler, GuildMessageReceivedEvent event, List commands) { + try { + musicHandler.isPlaying(false); + musicHandler.stop(event); + event.getGuild().getAudioManager().closeAudioConnection(); + } catch (Exception ex) { + logger.error("Unable to stop song: " + ex.getMessage(), ex); + guildRepoService.logEntry(event.getGuild().getIdLong(), ex, "Unable to stop song: %s", ex.getMessage()); + sendMessage(event, "Sorry I am unable to stop current song: " + ex.getMessage()); + } + } + + @Override + public String help() { + return "-stop (stops the current song)"; + } + +} diff --git a/src/main/java/net/locusworks/discord/eighttrack/events/handlers/UpNextSongHandler.java b/src/main/java/net/locusworks/discord/eighttrack/events/handlers/UpNextSongHandler.java new file mode 100644 index 0000000..d4b7def --- /dev/null +++ b/src/main/java/net/locusworks/discord/eighttrack/events/handlers/UpNextSongHandler.java @@ -0,0 +1,43 @@ +package net.locusworks.discord.eighttrack.events.handlers; + +import java.util.List; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; +import net.dv8tion.jda.api.events.message.guild.GuildMessageReceivedEvent; +import net.locusworks.discord.eighttrack.events.AbstractEventHandler; +import net.locusworks.discord.eighttrack.handlers.GuildMusicHandler; +import net.locusworks.discord.eighttrack.services.RepositoryService; +import net.locusworks.logger.ApplicationLogger; +import net.locusworks.logger.ApplicationLoggerFactory; + +@Component +public class UpNextSongHandler extends AbstractEventHandler { + + private ApplicationLogger logger; + + @Autowired + private RepositoryService guildRepoService; + + public UpNextSongHandler() { + super("-upnext"); + logger = ApplicationLoggerFactory.getLogger(UpNextSongHandler.class); + } + + @Override + public void executeEvent(GuildMusicHandler musicHandler, GuildMessageReceivedEvent event, List commands) { + try { + musicHandler.repeat(event); + musicHandler.isPlaying(true); + } catch (Exception ex) { + logger.error("Unable to show the next songs: " + ex.getMessage(), ex); + guildRepoService.logEntry(event.getGuild().getIdLong(), ex, "Unable to show next song: %s", ex.getMessage()); + sendMessage(event, "Sorry I am unable to show next songs: " + ex.getMessage()); + } + } + + @Override + public String help() { + return "-upnext (shows which song is up next)"; + } + +} diff --git a/src/main/java/net/locusworks/discord/eighttrack/events/handlers/UploadHandler.java b/src/main/java/net/locusworks/discord/eighttrack/events/handlers/UploadHandler.java new file mode 100644 index 0000000..d99559c --- /dev/null +++ b/src/main/java/net/locusworks/discord/eighttrack/events/handlers/UploadHandler.java @@ -0,0 +1,204 @@ +package net.locusworks.discord.eighttrack.events.handlers; + +import java.awt.Color; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.time.OffsetDateTime; +import java.util.Date; +import java.util.List; +import java.util.UUID; +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; +import net.dv8tion.jda.api.EmbedBuilder; +import net.dv8tion.jda.api.entities.MessageEmbed; +import net.dv8tion.jda.api.entities.Message.Attachment; +import net.dv8tion.jda.api.events.message.guild.GuildMessageReceivedEvent; +import net.locusworks.crypto.utils.HashUtils; +import net.locusworks.discord.eighttrack.audio.Mp3UploadHandler; +import net.locusworks.discord.eighttrack.audio.Mp3UploadResults; +import net.locusworks.discord.eighttrack.database.entities.DiscordGuild; +import net.locusworks.discord.eighttrack.database.entities.GuildSong; +import net.locusworks.discord.eighttrack.database.entities.Song; +import net.locusworks.discord.eighttrack.events.AbstractEventHandler; +import net.locusworks.discord.eighttrack.handlers.GuildMusicHandler; +import net.locusworks.discord.eighttrack.services.ConfigurationService; +import net.locusworks.discord.eighttrack.services.RepositoryService; +import net.locusworks.logger.ApplicationLogger; +import net.locusworks.logger.ApplicationLoggerFactory; + +@Component +public class UploadHandler extends AbstractEventHandler { + + private ApplicationLogger logger; + + @Autowired + private Mp3UploadHandler uploadHandler; + + @Autowired + private RepositoryService guildSongRepoService; + + @Autowired + private ConfigurationService confService; + + public UploadHandler() { + super("+upload"); + logger = ApplicationLoggerFactory.getLogger(UploadHandler.class); + } + + @Override + public void executeEvent(GuildMusicHandler musicHandler, GuildMessageReceivedEvent event, List commands) { + if (!isAdmin(event)) return; + + for(Attachment attachment : event.getMessage().getAttachments()) { + attachment.retrieveInputStream().thenAccept((in) -> { + Mp3UploadResults res = null; + MessageEmbed embed = null; + try { + + res = uploadHandler.parse(in); + if (res.validFile()) { + embed = persistSong(res, event, attachment.getFileName()); + } else { + embed = wrongFile(event, attachment.getFileName()); + } + + } catch (Exception ex) { + logger.error("Unable to get file information: %s", ex.getMessage()); + logger.error(ex); + embed = error(event, ex, attachment.getFileName()); + } finally { + event.getMessage().delete().queue(); + if (res != null) res.clear(); + + if (embed != null) event.getChannel().sendMessage(embed).queue(); + } + + }).exceptionally((err) -> { + event.getMessage().delete().queue(); + MessageEmbed embed = error(event, err, attachment.getFileName()); + if (embed != null) event.getChannel().sendMessage(embed).queue(); + return null; + }); + } + } + + private MessageEmbed error(GuildMessageReceivedEvent event, Throwable ex, String fileName) { + return new EmbedBuilder() + .setTitle("Unable to upload file: " + fileName) + .setDescription("There was an error uploading your file: " + ex.getMessage() + ". Please contact admin") + .setColor(Color.RED) + .setTimestamp(OffsetDateTime.now()) + .setFooter(event.getGuild().getSelfMember().getEffectiveName(), event.getGuild().getSelfMember().getUser().getAvatarUrl()) + .build(); + } + + private MessageEmbed wrongFile(GuildMessageReceivedEvent event, String fileName) { + return new EmbedBuilder() + .setTitle("Invalid File: " + fileName) + .setDescription("Only music type files are allowed to be uploaded") + .setColor(Color.RED) + .setTimestamp(OffsetDateTime.now()) + .setFooter(event.getGuild().getSelfMember().getEffectiveName(), event.getGuild().getSelfMember().getUser().getAvatarUrl()) + .build(); + } + + private MessageEmbed persistSong(Mp3UploadResults result, GuildMessageReceivedEvent event, String fileName) throws Exception { + + DiscordGuild guild = guildSongRepoService.getGuildRepo().findByGuildId(event.getGuild().getIdLong()); + if(guild == null) { + throw new IOException("Unable to find guild in database. Please contact administrator"); + } + + 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 = confService.getMusicDirectory(); + if (result.getArtist() != null) { + output = output.resolve(result.getArtist()); + if (result.getAlbum() != null) { + output = output.resolve(result.getAlbum()); + } + } + output = output.resolve(fileName); + + 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()); + 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); + } + + gs = new GuildSong(); + gs.setDateAdded(new Date()); + gs.setGuild(guild); + gs.setSong(song); + + String[] uuidArray = UUID.randomUUID().toString().split("-"); + + gs.setUuid(uuidArray[uuidArray.length - 1]); + + guildSongRepoService.getGuildSongRepo().save(gs); + + EmbedBuilder builder = new EmbedBuilder() + .setColor(Color.GREEN) + .setThumbnail(event.getGuild().getIconUrl()) + .setTitle("Upload Results for " + fileName) + .setTimestamp(OffsetDateTime.now()) + .setFooter(event.getGuild().getSelfMember().getEffectiveName(), event.getGuild().getSelfMember().getUser().getAvatarUrl()) + .addField("Title", result.getTitle(), true); + + if (!StringUtils.isBlank(result.getArtist())) builder.addField("Artist", result.getArtist(), true); + if (!StringUtils.isBlank(result.getAlbum())) builder.addField("Album", result.getAlbum(), true); + if (!StringUtils.isBlank(result.getTrackNumber())) builder.addField("Track", result.getTrackNumber(), true); + if (!StringUtils.isBlank(result.getDiscNumber())) builder.addField("Disc", result.getDiscNumber(), true); + if (!StringUtils.isBlank(result.getReleaseDate())) builder.addField("Year", result.getReleaseDate(), true); + + builder.addField("ID", gs.getUuid(), true); + + MessageEmbed embed = builder.build(); + + try { + guildSongRepoService.logEntry(event.getGuild().getIdLong(), "%s uploaded", result); + } catch (Exception ex) {} + + return embed; + } + + @Override + public String help() { + return "upload song"; + } + +} 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 8a9e215..730e347 100644 --- a/src/main/java/net/locusworks/discord/eighttrack/handlers/DiscordEventHandler.java +++ b/src/main/java/net/locusworks/discord/eighttrack/handlers/DiscordEventHandler.java @@ -27,20 +27,22 @@ */ package net.locusworks.discord.eighttrack.handlers; +import java.awt.Color; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; +import java.time.OffsetDateTime; import java.util.ArrayList; import java.util.Arrays; import java.util.Date; import java.util.List; - -import javax.annotation.PostConstruct; - +import java.util.Map; +import java.util.Map.Entry; +import java.util.TreeMap; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Service; - +import net.dv8tion.jda.api.EmbedBuilder; import net.dv8tion.jda.api.entities.ChannelType; import net.dv8tion.jda.api.entities.TextChannel; import net.dv8tion.jda.api.events.ExceptionEvent; @@ -48,8 +50,8 @@ import net.dv8tion.jda.api.events.guild.GuildJoinEvent; import net.dv8tion.jda.api.events.message.guild.GuildMessageReceivedEvent; import net.dv8tion.jda.api.events.message.react.MessageReactionAddEvent; import net.dv8tion.jda.api.hooks.ListenerAdapter; -import net.locusworks.discord.eighttrack.audio.Mp3UploadHandler; import net.locusworks.discord.eighttrack.database.entities.DiscordGuild; +import net.locusworks.discord.eighttrack.events.AbstractEventHandler; import net.locusworks.discord.eighttrack.services.ConfigurationService; import net.locusworks.discord.eighttrack.services.GuildMusicService; import net.locusworks.discord.eighttrack.services.RepositoryService; @@ -63,24 +65,26 @@ public class DiscordEventHandler extends ListenerAdapter { private ApplicationLogger logger = ApplicationLoggerFactory.getLogger(DiscordEventHandler.class); - @Autowired - private ConfigurationService confService; - - @Autowired - private Mp3UploadHandler uploadHandler; - @Autowired private RepositoryService guildSongRepoService; @Autowired private ReactionHandler reactionHandler; - @PostConstruct - private void init() throws IOException { - this.musicDir = confService.getMusicDirectory(); + private Map events; + + @Autowired + private void setup(ConfigurationService cService, List eventHandlers) throws IOException { + this.musicDir = cService.getMusicDirectory(); if (!Files.exists(this.musicDir.toAbsolutePath())) { Files.createDirectories(this.musicDir.toAbsolutePath()); } + + events = new TreeMap<>(); + + for(AbstractEventHandler handler : eventHandlers) { + events.put(handler.getCommand(), handler); + } } @Scheduled(fixedRate = 300000L, initialDelay=300000L) @@ -151,7 +155,7 @@ public class DiscordEventHandler extends ListenerAdapter { if (!GuildMusicService.getMap().containsKey(event.getGuild().getIdLong())) { GuildMusicService.getMap().put(event.getGuild().getIdLong(), - new GuildMusicHandler(musicDir, event.getGuild().getIdLong(), uploadHandler, reactionHandler, guildSongRepoService)); + new GuildMusicHandler(event.getGuild().getIdLong(), reactionHandler, guildSongRepoService)); } GuildMusicHandler gmh = GuildMusicService.getMap().get(event.getGuild().getIdLong()); @@ -161,29 +165,13 @@ public class DiscordEventHandler extends ListenerAdapter { String command = commands.remove(0); + AbstractEventHandler aeh = events.get(command.toLowerCase()); + if (aeh != null) { + aeh.executeEvent(gmh, event, commands); + return; + } + switch(command) { - case "+upload": - gmh.upload(event); - return; - case "-play": - gmh.play(event, commands); - gmh.isPlaying(true); - return; - case "-stop": - gmh.isPlaying(false); - gmh.stop(event); - event.getGuild().getAudioManager().closeAudioConnection(); - return; - case "-next": - gmh.next(event, commands); - return; - case "-repeat": - gmh.repeat(event); - gmh.isPlaying(true); - return; - case "-upnext": - gmh.upNext(event, commands); - return; case "-list": gmh.list(event); return; @@ -196,8 +184,24 @@ public class DiscordEventHandler extends ListenerAdapter { case "+delete": gmh.delete(event, commands); return; - default: - return; } + + if (!command.equalsIgnoreCase("-help")) return; + + StringBuilder sb = new StringBuilder(); + for (Entry entry : events.entrySet()) { + sb.append(String.format("%s | %s%n", entry.getKey(), entry.getValue().help())); + } + + EmbedBuilder builder = new EmbedBuilder() + .setColor(Color.GREEN) + .setThumbnail(event.getGuild().getIconUrl()) + .setTitle("Eight Track Help Menu") + .setDescription(sb.toString()) + .setTimestamp(OffsetDateTime.now()) + .setFooter(event.getGuild().getSelfMember().getEffectiveName(), event.getGuild().getSelfMember().getUser().getAvatarUrl()); + + event.getChannel().sendMessage(builder.build()).queue(); } + } 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 b9c11e3..694c75b 100644 --- a/src/main/java/net/locusworks/discord/eighttrack/handlers/GuildMusicHandler.java +++ b/src/main/java/net/locusworks/discord/eighttrack/handlers/GuildMusicHandler.java @@ -29,8 +29,6 @@ package net.locusworks.discord.eighttrack.handlers; import java.awt.Color; import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; import java.time.OffsetDateTime; import java.util.ArrayList; import java.util.Date; @@ -39,7 +37,6 @@ import java.util.List; import java.util.Map; import java.util.Random; import java.util.Set; -import java.util.UUID; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicBoolean; import java.util.function.Consumer; @@ -54,17 +51,13 @@ import net.dv8tion.jda.api.entities.ChannelType; import net.dv8tion.jda.api.entities.GuildChannel; import net.dv8tion.jda.api.entities.Member; import net.dv8tion.jda.api.entities.Message; -import net.dv8tion.jda.api.entities.Message.Attachment; import net.dv8tion.jda.api.entities.MessageEmbed; import net.dv8tion.jda.api.entities.VoiceChannel; import net.dv8tion.jda.api.events.message.guild.GuildMessageReceivedEvent; import net.dv8tion.jda.api.exceptions.ErrorResponseException; import net.dv8tion.jda.api.managers.AudioManager; import net.dv8tion.jda.api.requests.ErrorResponse; -import net.locusworks.crypto.utils.HashUtils; import net.locusworks.discord.eighttrack.audio.EightTrackAudioSendHandler; -import net.locusworks.discord.eighttrack.audio.Mp3UploadHandler; -import net.locusworks.discord.eighttrack.audio.Mp3UploadResults; import net.locusworks.discord.eighttrack.audio.TrackManager; import net.locusworks.discord.eighttrack.database.entities.DiscordGuild; import net.locusworks.discord.eighttrack.database.entities.GuildPlaylist; @@ -79,7 +72,6 @@ import net.locusworks.logger.ApplicationLoggerFactory; public class GuildMusicHandler { - private Path musicDir; private ApplicationLogger logger; private AtomicBoolean playing; private Long voiceChannelId; @@ -87,7 +79,6 @@ public class GuildMusicHandler { private OffsetDateTime lastPlayed; private Consumer callback; - private Mp3UploadHandler uploadHandler; private RepositoryService guildSongRepoService; private ReactionHandler reactionHandler; private long guildId; @@ -96,12 +87,10 @@ public class GuildMusicHandler { private TrackManager trackManager; - public GuildMusicHandler(Path musicDir, long guildId, Mp3UploadHandler uploadHandler, ReactionHandler reactionHandler, RepositoryService guildSongRepoService) throws IOException { + public GuildMusicHandler(long guildId, ReactionHandler reactionHandler, RepositoryService guildSongRepoService) throws IOException { this.logger = ApplicationLoggerFactory.getLogger(GuildMusicHandler.class); this.playing = new AtomicBoolean(false); - this.musicDir = musicDir; this.lastPlayed = OffsetDateTime.now(); - this.uploadHandler = uploadHandler; this.guildSongRepoService = guildSongRepoService; this.guildId = guildId; this.reactionHandler = reactionHandler; @@ -197,6 +186,7 @@ public class GuildMusicHandler { playing.set(true); return; } + GuildChannel gc = event.getGuild().getGuildChannelById(ChannelType.VOICE, voiceChannelId); if (gc != null && gc.getMembers().size() == 1) { event.getChannel().sendMessage("Going silent since no one is currently listening to the channel").queue(); @@ -206,18 +196,20 @@ public class GuildMusicHandler { } playing.set(false); - stop(event, true); + stop(event, true, true); play(event, commands); playing.set(true); } public void stop(GuildMessageReceivedEvent event) { - stop(event, false); + stop(event, false, false); } - public void stop(GuildMessageReceivedEvent event, boolean stoppedFromRepeat) { + public void stop(GuildMessageReceivedEvent event, boolean stoppedFromRepeat, boolean stoppedFromNext) { trackManager.stopTrack(); - voiceChannelId = null; + if (!stoppedFromNext) { + voiceChannelId = null; + } if (!stoppedFromRepeat) { currentPlaylist = null; } @@ -264,7 +256,7 @@ public class GuildMusicHandler { event.getChannel().sendMessageFormat("Unable to find song with identifier: %s", uuid).queue(); return; } - stop(event, true); + stop(event, true, true); } if (!trackManager.hasTracks()) { @@ -292,42 +284,6 @@ public class GuildMusicHandler { } } - public void upload(GuildMessageReceivedEvent event) { - isAdmin(event); - - for(Attachment attachment : event.getMessage().getAttachments()) { - attachment.retrieveInputStream().thenAccept((in) -> { - Mp3UploadResults res = null; - MessageEmbed embed = null; - try { - - res = uploadHandler.parse(in); - if (res.validFile()) { - embed = persistSong(res, event, attachment.getFileName()); - } else { - embed = wrongFile(event, attachment.getFileName()); - } - - } catch (Exception ex) { - logger.error("Unable to get file information: %s", ex.getMessage()); - logger.error(ex); - embed = error(event, ex, attachment.getFileName()); - } finally { - event.getMessage().delete().queue(); - if (res != null) res.clear(); - - if (embed != null) event.getChannel().sendMessage(embed).queue(); - } - - }).exceptionally((err) -> { - event.getMessage().delete().queue(); - MessageEmbed embed = error(event, err, attachment.getFileName()); - if (embed != null) event.getChannel().sendMessage(embed).queue(); - return null; - }); - } - } - public void list(GuildMessageReceivedEvent event) { List gsList = guildSongRepoService.getGuildSongRepo().findByGuild(guildId); @@ -421,118 +377,6 @@ public class GuildMusicHandler { playing.set(true); } - private MessageEmbed error(GuildMessageReceivedEvent event, Throwable ex, String fileName) { - return new EmbedBuilder() - .setTitle("Unable to upload file: " + fileName) - .setDescription("There was an error uploading your file: " + ex.getMessage() + ". Please contact admin") - .setColor(Color.RED) - .setTimestamp(OffsetDateTime.now()) - .setFooter(event.getGuild().getSelfMember().getEffectiveName(), event.getGuild().getSelfMember().getUser().getAvatarUrl()) - .build(); - } - - private MessageEmbed wrongFile(GuildMessageReceivedEvent event, String fileName) { - return new EmbedBuilder() - .setTitle("Invalid File: " + fileName) - .setDescription("Only music type files are allowed to be uploaded") - .setColor(Color.RED) - .setTimestamp(OffsetDateTime.now()) - .setFooter(event.getGuild().getSelfMember().getEffectiveName(), event.getGuild().getSelfMember().getUser().getAvatarUrl()) - .build(); - } - - private MessageEmbed persistSong(Mp3UploadResults result, GuildMessageReceivedEvent event, String fileName) throws Exception { - - DiscordGuild guild = guildSongRepoService.getGuildRepo().findByGuildId(event.getGuild().getIdLong()); - if(guild == null) { - throw new IOException("Unable to find guild in database. Please contact administrator"); - } - - 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); - - 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()); - 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); - } - - gs = new GuildSong(); - gs.setDateAdded(new Date()); - gs.setGuild(guild); - gs.setSong(song); - - String[] uuidArray = UUID.randomUUID().toString().split("-"); - - gs.setUuid(uuidArray[uuidArray.length - 1]); - - guildSongRepoService.getGuildSongRepo().save(gs); - - EmbedBuilder builder = new EmbedBuilder() - .setColor(Color.GREEN) - .setThumbnail(event.getGuild().getIconUrl()) - .setTitle("Upload Results for " + fileName) - .setTimestamp(OffsetDateTime.now()) - .setFooter(event.getGuild().getSelfMember().getEffectiveName(), event.getGuild().getSelfMember().getUser().getAvatarUrl()) - .addField("Title", result.getTitle(), true); - - if (!StringUtils.isBlank(result.getArtist())) builder.addField("Artist", result.getArtist(), true); - if (!StringUtils.isBlank(result.getAlbum())) builder.addField("Album", result.getAlbum(), true); - if (!StringUtils.isBlank(result.getTrackNumber())) builder.addField("Track", result.getTrackNumber(), true); - if (!StringUtils.isBlank(result.getDiscNumber())) builder.addField("Disc", result.getDiscNumber(), true); - if (!StringUtils.isBlank(result.getReleaseDate())) builder.addField("Year", result.getReleaseDate(), true); - - builder.addField("ID", gs.getUuid(), true); - - MessageEmbed embed = builder.build(); - - try { - guildSongRepoService.logEntry(event.getGuild().getIdLong(), "%s uploaded", result); - } catch (Exception ex) {} - - return embed; - } - private void listPlayList(GuildMessageReceivedEvent event, List commands) { if (commands == null || commands.isEmpty()) { List userPlaylist = guildSongRepoService.getGuildPlaylistRepo().findByGuildAndUserIdFetchSongs(event.getGuild().getIdLong(), event.getMember().getIdLong()); @@ -947,7 +791,7 @@ public class GuildMusicHandler { private void sendMessage(GuildMessageReceivedEvent event, String msg) { event.getChannel().sendMessage(msg).queue(); } - + private void deleteMessage(Message msg) { try { msg.delete().complete();