Fixed many things, and now you can use youtube to add to playlists.
This commit is contained in:
parent
8177ad8669
commit
fde75385bd
2
pom.xml
2
pom.xml
|
@ -6,7 +6,7 @@
|
|||
|
||||
<groupId>com.github.andrewlalis</groupId>
|
||||
<artifactId>HandieBot</artifactId>
|
||||
<version>1.4.0</version>
|
||||
<version>1.4.1</version>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
|
|
|
@ -52,7 +52,8 @@ public class Commands {
|
|||
public static void executeCommand(String command, CommandContext context){
|
||||
for (Command cmd : commands) {
|
||||
if (cmd.getName().equals(command)){
|
||||
if (cmd instanceof StaticCommand){
|
||||
if (cmd instanceof StaticCommand &&
|
||||
((context != null && cmd.canUserExecute(context.getUser(), context.getGuild())) || context == null)){
|
||||
log.log(BotLog.TYPE.COMMAND, command+" has been issued.");
|
||||
((StaticCommand)cmd).execute();
|
||||
return;
|
||||
|
|
|
@ -4,13 +4,11 @@ import com.google.api.services.youtube.model.Video;
|
|||
import handiebot.HandieBot;
|
||||
import handiebot.command.CommandContext;
|
||||
import handiebot.command.ReactionHandler;
|
||||
import handiebot.command.reactionListeners.YoutubeChoiceListener;
|
||||
import handiebot.command.reactionListeners.YoutubePlayListener;
|
||||
import handiebot.command.types.ContextCommand;
|
||||
import handiebot.lavaplayer.playlist.UnloadedTrack;
|
||||
import handiebot.utils.YoutubeSearch;
|
||||
import sx.blah.discord.api.internal.json.objects.EmbedObject;
|
||||
import sx.blah.discord.handle.obj.IMessage;
|
||||
import sx.blah.discord.util.RequestBuffer;
|
||||
|
||||
import java.text.MessageFormat;
|
||||
import java.util.ArrayList;
|
||||
|
@ -46,24 +44,17 @@ public class PlayCommand extends ContextCommand {
|
|||
e.printStackTrace();
|
||||
}
|
||||
} else {
|
||||
//Construct a Youtube song.
|
||||
//Construct a Youtube song choice.
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (int i = 0; i < context.getArgs().length; i++){
|
||||
sb.append(context.getArgs()[i]).append(' ');
|
||||
}
|
||||
List<Video> videos = YoutubeSearch.query(sb.toString().trim());
|
||||
if (videos != null) {
|
||||
EmbedObject e = YoutubeSearch.createEmbed(videos);
|
||||
IMessage message = context.getChannel().sendMessage(e);
|
||||
List<String> urls = new ArrayList<>(videos.size());
|
||||
videos.forEach((video) -> urls.add(WATCH_URL+video.getId()));
|
||||
RequestBuffer.request(() -> message.addReaction(":one:")).get();
|
||||
RequestBuffer.request(() -> message.addReaction(":two:")).get();
|
||||
RequestBuffer.request(() -> message.addReaction(":three:")).get();
|
||||
RequestBuffer.request(() -> message.addReaction(":four:")).get();
|
||||
RequestBuffer.request(() -> message.addReaction(":five:")).get();
|
||||
RequestBuffer.request(() -> message.addReaction(":x:")).get();
|
||||
ReactionHandler.addListener(new YoutubeChoiceListener(message, context.getUser(), urls));
|
||||
IMessage message = YoutubeSearch.displayChoicesDialog(videos, context.getChannel());
|
||||
ReactionHandler.addListener(new YoutubePlayListener(message, context.getUser(), urls));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,12 +1,16 @@
|
|||
package handiebot.command.commands.music;
|
||||
|
||||
import com.google.api.services.youtube.model.Video;
|
||||
import handiebot.HandieBot;
|
||||
import handiebot.command.CommandContext;
|
||||
import handiebot.command.CommandHandler;
|
||||
import handiebot.command.ReactionHandler;
|
||||
import handiebot.command.reactionListeners.YoutubePlaylistAddListener;
|
||||
import handiebot.command.types.ContextCommand;
|
||||
import handiebot.lavaplayer.playlist.Playlist;
|
||||
import handiebot.lavaplayer.playlist.UnloadedTrack;
|
||||
import handiebot.utils.MessageUtils;
|
||||
import handiebot.utils.YoutubeSearch;
|
||||
import handiebot.view.BotLog;
|
||||
import sx.blah.discord.handle.obj.IChannel;
|
||||
import sx.blah.discord.handle.obj.IMessage;
|
||||
|
@ -14,10 +18,12 @@ import sx.blah.discord.util.RequestBuffer;
|
|||
|
||||
import java.io.File;
|
||||
import java.text.MessageFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static handiebot.HandieBot.log;
|
||||
import static handiebot.HandieBot.resourceBundle;
|
||||
import static handiebot.utils.YoutubeSearch.WATCH_URL;
|
||||
|
||||
/**
|
||||
* @author Andrew Lalis
|
||||
|
@ -32,7 +38,7 @@ public class PlaylistCommand extends ContextCommand {
|
|||
"\t`create <PLAYLIST>` - "+resourceBundle.getString("commands.command.playlist.description.create")+"\n" +
|
||||
"\t`delete <PLAYLIST>` - "+resourceBundle.getString("commands.command.playlist.description.delete")+"\n" +
|
||||
"\t`show [PLAYLIST]` - "+resourceBundle.getString("commands.command.playlist.description.show")+"\n" +
|
||||
"\t`add <PLAYLIST> <URL> [URL]...` - "+resourceBundle.getString("commands.command.playlist.description.add")+"\n" +
|
||||
"\t`add <PLAYLIST> <URL URL...|SEARCHTEXT, SEARCHTEXT...>` - "+resourceBundle.getString("commands.command.playlist.description.add")+"\n" +
|
||||
"\t`remove <PLAYLIST> <SONGINDEX>` - "+resourceBundle.getString("commands.command.playlist.description.remove")+"\n" +
|
||||
"\t`rename <PLAYLIST> <NEWNAME>` - "+resourceBundle.getString("commands.command.playlist.description.rename")+"\n" +
|
||||
"\t`move <PLAYLIST> <OLDINDEX> <NEWINDEX>` - "+resourceBundle.getString("commands.command.playlist.description.move")+"\n" +
|
||||
|
@ -160,6 +166,8 @@ public class PlaylistCommand extends ContextCommand {
|
|||
return;
|
||||
Playlist playlist = new Playlist(context.getArgs()[1]);
|
||||
playlist.load();
|
||||
if (context.getArgs()[2].startsWith("http")){
|
||||
//These are songs, so add them immediately.
|
||||
for (int i = 2; i < context.getArgs().length; i++){
|
||||
playlist.loadTrack(context.getArgs()[i]);
|
||||
RequestBuffer.request(() -> context.getChannel().sendMessage(MessageFormat.format(resourceBundle.getString("commands.command.playlist.add.message"), playlist.getName()))).get();
|
||||
|
@ -167,6 +175,20 @@ public class PlaylistCommand extends ContextCommand {
|
|||
playlist.save();
|
||||
context.getChannel().sendMessage(playlist.toString());
|
||||
log.log(BotLog.TYPE.INFO, MessageFormat.format(resourceBundle.getString("commands.command.playlist.add.log"), playlist.getName()));
|
||||
} else {
|
||||
//This is a youtube search query.
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (int i = 2; i < context.getArgs().length; i++){
|
||||
sb.append(context.getArgs()[i]).append(' ');
|
||||
}
|
||||
List<Video> videos = YoutubeSearch.query(sb.toString().trim());
|
||||
if (videos != null) {
|
||||
List<String> urls = new ArrayList<>(videos.size());
|
||||
videos.forEach((video) -> urls.add(WATCH_URL+video.getId()));
|
||||
IMessage message = YoutubeSearch.displayChoicesDialog(videos, context.getChannel());
|
||||
ReactionHandler.addListener(new YoutubePlaylistAddListener(message, context.getUser(), urls, playlist));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (context.getArgs().length == 1){
|
||||
context.getChannel().sendMessage(MessageFormat.format(resourceBundle.getString("commands.command.playlist.error.addNameNeeded"), getPlaylistShowString(context)));
|
||||
|
|
|
@ -1,9 +1,7 @@
|
|||
package handiebot.command.reactionListeners;
|
||||
|
||||
import handiebot.HandieBot;
|
||||
import handiebot.command.ReactionHandler;
|
||||
import handiebot.command.types.ReactionListener;
|
||||
import handiebot.lavaplayer.playlist.UnloadedTrack;
|
||||
import handiebot.view.BotLog;
|
||||
import sx.blah.discord.handle.impl.events.guild.channel.message.reaction.ReactionEvent;
|
||||
import sx.blah.discord.handle.obj.IMessage;
|
||||
|
@ -20,14 +18,14 @@ import static java.lang.Thread.sleep;
|
|||
* Interface for youtube search results choices. A new instance of this listener is created every time a youtube
|
||||
* query is shown, and is unique for each user.
|
||||
*/
|
||||
public class YoutubeChoiceListener implements ReactionListener {
|
||||
public abstract class YoutubeChoiceListener implements ReactionListener {
|
||||
|
||||
private final IMessage message;
|
||||
private final IUser user;
|
||||
private final List<String> urls;
|
||||
private static final long timeout = 30000;//Time until the choice times out and deletes itself.
|
||||
protected final IMessage message;
|
||||
protected final IUser user;
|
||||
protected final List<String> urls;
|
||||
protected static final long timeout = 30000;//Time until the choice times out and deletes itself.
|
||||
|
||||
private String[] choices = {
|
||||
private static final String[] choices = {
|
||||
"1⃣",
|
||||
"2⃣",
|
||||
"3⃣",
|
||||
|
@ -39,7 +37,6 @@ public class YoutubeChoiceListener implements ReactionListener {
|
|||
this.message = message;
|
||||
this.user = user;
|
||||
this.urls = urls;
|
||||
YoutubeChoiceListener instance = this;
|
||||
new Thread(() -> {
|
||||
try {
|
||||
sleep(timeout);
|
||||
|
@ -59,12 +56,7 @@ public class YoutubeChoiceListener implements ReactionListener {
|
|||
(this.user.getLongID() == event.getUser().getLongID())){
|
||||
for (int i = 0; i < choices.length; i++){
|
||||
if (event.getReaction().toString().equals(choices[i])){
|
||||
try {
|
||||
HandieBot.musicPlayer.addToQueue(message.getGuild(), new UnloadedTrack(urls.get(i)), this.user);
|
||||
log.log(BotLog.TYPE.MUSIC, message.getGuild(), this.user.getName()+" chose item "+(i+1)+" from the Youtube query.");
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
onChoice(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -72,8 +64,17 @@ public class YoutubeChoiceListener implements ReactionListener {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to delete the large, unwieldy message and remove the listener for this set of videos.
|
||||
*/
|
||||
private void cleanup(){
|
||||
RequestBuffer.request(message::delete);
|
||||
ReactionHandler.removeListener(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* What to do when a choice is made.
|
||||
* @param choice An integer value from 0 to 4, describing which choice the player has chosen.
|
||||
*/
|
||||
protected abstract void onChoice(int choice);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,33 @@
|
|||
package handiebot.command.reactionListeners;
|
||||
|
||||
import handiebot.HandieBot;
|
||||
import handiebot.lavaplayer.playlist.UnloadedTrack;
|
||||
import handiebot.view.BotLog;
|
||||
import sx.blah.discord.handle.obj.IMessage;
|
||||
import sx.blah.discord.handle.obj.IUser;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static handiebot.HandieBot.log;
|
||||
|
||||
/**
|
||||
* @author Andrew Lalis
|
||||
* Specific Listener for choices in the Play command, where songs chosen are added to the active queue.
|
||||
*/
|
||||
public class YoutubePlayListener extends YoutubeChoiceListener {
|
||||
|
||||
public YoutubePlayListener(IMessage message, IUser user, List<String> urls) {
|
||||
super(message, user, urls);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onChoice(int choice) {
|
||||
try {
|
||||
HandieBot.musicPlayer.addToQueue(message.getGuild(), new UnloadedTrack(urls.get(choice)), this.user);
|
||||
log.log(BotLog.TYPE.MUSIC, message.getGuild(), this.user.getName()+" chose item "+(choice+1)+" from the Youtube query.");
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
package handiebot.command.reactionListeners;
|
||||
|
||||
import handiebot.lavaplayer.playlist.Playlist;
|
||||
import handiebot.utils.MessageUtils;
|
||||
import sx.blah.discord.handle.obj.IMessage;
|
||||
import sx.blah.discord.handle.obj.IUser;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Andrew Lalis
|
||||
* Specific Listener for adding songs to a playlist that must be saved.
|
||||
*/
|
||||
public class YoutubePlaylistAddListener extends YoutubeChoiceListener {
|
||||
|
||||
private Playlist playlist;
|
||||
|
||||
public YoutubePlaylistAddListener(IMessage message, IUser user, List<String> urls, Playlist playlist) {
|
||||
super(message, user, urls);
|
||||
this.playlist = playlist;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onChoice(int choice) {
|
||||
this.playlist.loadTrack(this.urls.get(choice));
|
||||
this.playlist.save();
|
||||
MessageUtils.sendMessage("Added song to *"+this.playlist.getName()+"*.", message.getChannel());
|
||||
}
|
||||
}
|
|
@ -218,10 +218,7 @@ public class MusicPlayer {
|
|||
StringBuilder sb = new StringBuilder();
|
||||
if (timeUntilPlay > 0) {
|
||||
sb.append(MessageFormat.format(resourceBundle.getString("player.addedToQueue"), user.getName(), track.getTitle()));
|
||||
}
|
||||
//If there's some tracks in the queue, get the time until this one plays.
|
||||
if (timeUntilPlay > 0){
|
||||
sb.append(String.format("\nTime until play: %d min, %d sec",
|
||||
sb.append(String.format("\nTime until play: %d min, %02d sec",
|
||||
TimeUnit.MILLISECONDS.toMinutes(timeUntilPlay),
|
||||
TimeUnit.MILLISECONDS.toSeconds(timeUntilPlay) - TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(timeUntilPlay))
|
||||
));
|
||||
|
|
|
@ -2,6 +2,8 @@ package handiebot.utils;
|
|||
|
||||
import handiebot.HandieBot;
|
||||
import handiebot.view.BotLog;
|
||||
import sx.blah.discord.api.internal.json.objects.EmbedObject;
|
||||
import sx.blah.discord.handle.obj.IChannel;
|
||||
import sx.blah.discord.handle.obj.IMessage;
|
||||
import sx.blah.discord.handle.obj.Permissions;
|
||||
import sx.blah.discord.util.RequestBuffer;
|
||||
|
@ -16,6 +18,26 @@ import static handiebot.HandieBot.resourceBundle;
|
|||
public class MessageUtils extends Thread implements Runnable {
|
||||
|
||||
private MessageUtils(){}
|
||||
//TODO: Replace all 'sendMessage' calls with the new rate-limited calls.
|
||||
/**
|
||||
* Sends a message to a channel safely, using a request buffer.
|
||||
* @param content The string content of the message.
|
||||
* @param channel The channel to send the message on.
|
||||
* @return The message object that was sent.
|
||||
*/
|
||||
public static IMessage sendMessage(String content, IChannel channel){
|
||||
return RequestBuffer.request(() -> (IMessage)channel.sendMessage(content)).get();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends an embed object to a channel safely, using a request buffer.
|
||||
* @param embed The content of the message.
|
||||
* @param channel The channel to send the message on.
|
||||
* @return The message object that was sent.
|
||||
*/
|
||||
public static IMessage sendMessage(EmbedObject embed, IChannel channel){
|
||||
return RequestBuffer.request(() -> (IMessage)channel.sendMessage(embed)).get();
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes a message after a set amount of time.
|
||||
|
|
|
@ -19,7 +19,10 @@ import com.google.api.services.youtube.model.Video;
|
|||
import com.google.api.services.youtube.model.VideoListResponse;
|
||||
import com.google.common.base.Joiner;
|
||||
import sx.blah.discord.api.internal.json.objects.EmbedObject;
|
||||
import sx.blah.discord.handle.obj.IChannel;
|
||||
import sx.blah.discord.handle.obj.IMessage;
|
||||
import sx.blah.discord.util.EmbedBuilder;
|
||||
import sx.blah.discord.util.RequestBuffer;
|
||||
|
||||
import java.awt.*;
|
||||
import java.io.File;
|
||||
|
@ -188,4 +191,23 @@ public class YoutubeSearch {
|
|||
return builder.build();
|
||||
}
|
||||
|
||||
/**
|
||||
* Displays the first five results from a youtube search, and adds reactions so that a user may choose an option.
|
||||
* @param videos The list of videos, returned from calling {@code query}.
|
||||
* @param channel The channel to display the dialog in.
|
||||
*/
|
||||
public static IMessage displayChoicesDialog(List<Video> videos, IChannel channel){
|
||||
EmbedObject e = YoutubeSearch.createEmbed(videos);
|
||||
IMessage message = channel.sendMessage(e);
|
||||
List<String> urls = new ArrayList<>(videos.size());
|
||||
videos.forEach((video) -> urls.add(WATCH_URL + video.getId()));
|
||||
RequestBuffer.request(() -> message.addReaction(":one:")).get();
|
||||
RequestBuffer.request(() -> message.addReaction(":two:")).get();
|
||||
RequestBuffer.request(() -> message.addReaction(":three:")).get();
|
||||
RequestBuffer.request(() -> message.addReaction(":four:")).get();
|
||||
RequestBuffer.request(() -> message.addReaction(":five:")).get();
|
||||
RequestBuffer.request(() -> message.addReaction(":x:")).get();
|
||||
return message;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue