Restructured how events were being handled to clean up the mess

This commit is contained in:
Isaac Parenteau
2020-01-01 00:22:02 -06:00
parent 52c8253aa0
commit c8260444bb
10 changed files with 540 additions and 217 deletions

View File

@ -35,11 +35,8 @@ import java.nio.file.Path;
import java.nio.file.Paths; import java.nio.file.Paths;
import java.util.UUID; import java.util.UUID;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import org.xml.sax.SAXException;
import com.mpatric.mp3agic.ID3v2; import com.mpatric.mp3agic.ID3v2;
import com.mpatric.mp3agic.InvalidDataException;
import com.mpatric.mp3agic.Mp3File; import com.mpatric.mp3agic.Mp3File;
import com.mpatric.mp3agic.UnsupportedTagException;
@Component @Component
public class Mp3UploadHandler { 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));
}
} }

View File

@ -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<String> 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<String> commands, String msg) {
return checkCommands(event, commands, 0, msg);
}
protected boolean checkCommands(GuildMessageReceivedEvent event, List<String> 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;
}
}
}

View File

@ -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<String> 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 <id of song to play> (will stop song if one already playing)";
}
}

View File

@ -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<String> 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 <id of song to play> (will not play song if a song is already playing)";
}
}

View File

@ -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<String> 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)";
}
}

View File

@ -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<String> 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)";
}
}

View File

@ -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<String> 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)";
}
}

View File

@ -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<String> 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";
}
}

View File

@ -27,20 +27,22 @@
*/ */
package net.locusworks.discord.eighttrack.handlers; package net.locusworks.discord.eighttrack.handlers;
import java.awt.Color;
import java.io.IOException; import java.io.IOException;
import java.nio.file.Files; import java.nio.file.Files;
import java.nio.file.Path; import java.nio.file.Path;
import java.time.OffsetDateTime;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Date; import java.util.Date;
import java.util.List; import java.util.List;
import java.util.Map;
import javax.annotation.PostConstruct; import java.util.Map.Entry;
import java.util.TreeMap;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled; import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import net.dv8tion.jda.api.EmbedBuilder;
import net.dv8tion.jda.api.entities.ChannelType; import net.dv8tion.jda.api.entities.ChannelType;
import net.dv8tion.jda.api.entities.TextChannel; import net.dv8tion.jda.api.entities.TextChannel;
import net.dv8tion.jda.api.events.ExceptionEvent; 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.guild.GuildMessageReceivedEvent;
import net.dv8tion.jda.api.events.message.react.MessageReactionAddEvent; import net.dv8tion.jda.api.events.message.react.MessageReactionAddEvent;
import net.dv8tion.jda.api.hooks.ListenerAdapter; 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.database.entities.DiscordGuild;
import net.locusworks.discord.eighttrack.events.AbstractEventHandler;
import net.locusworks.discord.eighttrack.services.ConfigurationService; import net.locusworks.discord.eighttrack.services.ConfigurationService;
import net.locusworks.discord.eighttrack.services.GuildMusicService; import net.locusworks.discord.eighttrack.services.GuildMusicService;
import net.locusworks.discord.eighttrack.services.RepositoryService; import net.locusworks.discord.eighttrack.services.RepositoryService;
@ -63,24 +65,26 @@ public class DiscordEventHandler extends ListenerAdapter {
private ApplicationLogger logger = ApplicationLoggerFactory.getLogger(DiscordEventHandler.class); private ApplicationLogger logger = ApplicationLoggerFactory.getLogger(DiscordEventHandler.class);
@Autowired
private ConfigurationService confService;
@Autowired
private Mp3UploadHandler uploadHandler;
@Autowired @Autowired
private RepositoryService guildSongRepoService; private RepositoryService guildSongRepoService;
@Autowired @Autowired
private ReactionHandler reactionHandler; private ReactionHandler reactionHandler;
@PostConstruct private Map<String, AbstractEventHandler> events;
private void init() throws IOException {
this.musicDir = confService.getMusicDirectory(); @Autowired
private void setup(ConfigurationService cService, List<AbstractEventHandler> eventHandlers) throws IOException {
this.musicDir = cService.getMusicDirectory();
if (!Files.exists(this.musicDir.toAbsolutePath())) { if (!Files.exists(this.musicDir.toAbsolutePath())) {
Files.createDirectories(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) @Scheduled(fixedRate = 300000L, initialDelay=300000L)
@ -151,7 +155,7 @@ public class DiscordEventHandler extends ListenerAdapter {
if (!GuildMusicService.getMap().containsKey(event.getGuild().getIdLong())) { if (!GuildMusicService.getMap().containsKey(event.getGuild().getIdLong())) {
GuildMusicService.getMap().put(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()); GuildMusicHandler gmh = GuildMusicService.getMap().get(event.getGuild().getIdLong());
@ -161,29 +165,13 @@ public class DiscordEventHandler extends ListenerAdapter {
String command = commands.remove(0); String command = commands.remove(0);
AbstractEventHandler aeh = events.get(command.toLowerCase());
if (aeh != null) {
aeh.executeEvent(gmh, event, commands);
return;
}
switch(command) { 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": case "-list":
gmh.list(event); gmh.list(event);
return; return;
@ -196,8 +184,24 @@ public class DiscordEventHandler extends ListenerAdapter {
case "+delete": case "+delete":
gmh.delete(event, commands); gmh.delete(event, commands);
return; return;
default:
return;
} }
if (!command.equalsIgnoreCase("-help")) return;
StringBuilder sb = new StringBuilder();
for (Entry<String, AbstractEventHandler> 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();
} }
} }

View File

@ -29,8 +29,6 @@ package net.locusworks.discord.eighttrack.handlers;
import java.awt.Color; import java.awt.Color;
import java.io.IOException; import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.time.OffsetDateTime; import java.time.OffsetDateTime;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Date; import java.util.Date;
@ -39,7 +37,6 @@ import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Random; import java.util.Random;
import java.util.Set; import java.util.Set;
import java.util.UUID;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.Consumer; 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.GuildChannel;
import net.dv8tion.jda.api.entities.Member; import net.dv8tion.jda.api.entities.Member;
import net.dv8tion.jda.api.entities.Message; 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.MessageEmbed;
import net.dv8tion.jda.api.entities.VoiceChannel; import net.dv8tion.jda.api.entities.VoiceChannel;
import net.dv8tion.jda.api.events.message.guild.GuildMessageReceivedEvent; import net.dv8tion.jda.api.events.message.guild.GuildMessageReceivedEvent;
import net.dv8tion.jda.api.exceptions.ErrorResponseException; import net.dv8tion.jda.api.exceptions.ErrorResponseException;
import net.dv8tion.jda.api.managers.AudioManager; import net.dv8tion.jda.api.managers.AudioManager;
import net.dv8tion.jda.api.requests.ErrorResponse; 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.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.audio.TrackManager;
import net.locusworks.discord.eighttrack.database.entities.DiscordGuild; import net.locusworks.discord.eighttrack.database.entities.DiscordGuild;
import net.locusworks.discord.eighttrack.database.entities.GuildPlaylist; import net.locusworks.discord.eighttrack.database.entities.GuildPlaylist;
@ -79,7 +72,6 @@ import net.locusworks.logger.ApplicationLoggerFactory;
public class GuildMusicHandler { public class GuildMusicHandler {
private Path musicDir;
private ApplicationLogger logger; private ApplicationLogger logger;
private AtomicBoolean playing; private AtomicBoolean playing;
private Long voiceChannelId; private Long voiceChannelId;
@ -87,7 +79,6 @@ public class GuildMusicHandler {
private OffsetDateTime lastPlayed; private OffsetDateTime lastPlayed;
private Consumer<Long> callback; private Consumer<Long> callback;
private Mp3UploadHandler uploadHandler;
private RepositoryService guildSongRepoService; private RepositoryService guildSongRepoService;
private ReactionHandler reactionHandler; private ReactionHandler reactionHandler;
private long guildId; private long guildId;
@ -96,12 +87,10 @@ public class GuildMusicHandler {
private TrackManager trackManager; 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.logger = ApplicationLoggerFactory.getLogger(GuildMusicHandler.class);
this.playing = new AtomicBoolean(false); this.playing = new AtomicBoolean(false);
this.musicDir = musicDir;
this.lastPlayed = OffsetDateTime.now(); this.lastPlayed = OffsetDateTime.now();
this.uploadHandler = uploadHandler;
this.guildSongRepoService = guildSongRepoService; this.guildSongRepoService = guildSongRepoService;
this.guildId = guildId; this.guildId = guildId;
this.reactionHandler = reactionHandler; this.reactionHandler = reactionHandler;
@ -197,6 +186,7 @@ public class GuildMusicHandler {
playing.set(true); playing.set(true);
return; return;
} }
GuildChannel gc = event.getGuild().getGuildChannelById(ChannelType.VOICE, voiceChannelId); GuildChannel gc = event.getGuild().getGuildChannelById(ChannelType.VOICE, voiceChannelId);
if (gc != null && gc.getMembers().size() == 1) { if (gc != null && gc.getMembers().size() == 1) {
event.getChannel().sendMessage("Going silent since no one is currently listening to the channel").queue(); 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); playing.set(false);
stop(event, true); stop(event, true, true);
play(event, commands); play(event, commands);
playing.set(true); playing.set(true);
} }
public void stop(GuildMessageReceivedEvent event) { 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(); trackManager.stopTrack();
voiceChannelId = null; if (!stoppedFromNext) {
voiceChannelId = null;
}
if (!stoppedFromRepeat) { if (!stoppedFromRepeat) {
currentPlaylist = null; currentPlaylist = null;
} }
@ -264,7 +256,7 @@ public class GuildMusicHandler {
event.getChannel().sendMessageFormat("Unable to find song with identifier: %s", uuid).queue(); event.getChannel().sendMessageFormat("Unable to find song with identifier: %s", uuid).queue();
return; return;
} }
stop(event, true); stop(event, true, true);
} }
if (!trackManager.hasTracks()) { 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) { public void list(GuildMessageReceivedEvent event) {
List<GuildSong> gsList = guildSongRepoService.getGuildSongRepo().findByGuild(guildId); List<GuildSong> gsList = guildSongRepoService.getGuildSongRepo().findByGuild(guildId);
@ -421,118 +377,6 @@ public class GuildMusicHandler {
playing.set(true); 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<String> commands) { private void listPlayList(GuildMessageReceivedEvent event, List<String> commands) {
if (commands == null || commands.isEmpty()) { if (commands == null || commands.isEmpty()) {
List<GuildPlaylist> userPlaylist = guildSongRepoService.getGuildPlaylistRepo().findByGuildAndUserIdFetchSongs(event.getGuild().getIdLong(), event.getMember().getIdLong()); List<GuildPlaylist> userPlaylist = guildSongRepoService.getGuildPlaylistRepo().findByGuildAndUserIdFetchSongs(event.getGuild().getIdLong(), event.getMember().getIdLong());