Fixed youtube query issue, updated profile image.

This commit is contained in:
Andrew Lalis 2017-12-23 12:51:52 +01:00 committed by Andrew Lalis
parent 4506edb794
commit 0ea54a5333
10 changed files with 103 additions and 54 deletions

BIN
avatarIcon.psd Normal file

Binary file not shown.

View File

@ -17,10 +17,6 @@ import sx.blah.discord.handle.obj.Permissions;
import sx.blah.discord.util.DiscordException; import sx.blah.discord.util.DiscordException;
import sx.blah.discord.util.RateLimitException; import sx.blah.discord.util.RateLimitException;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileReader;
import java.io.IOException;
import java.util.*; import java.util.*;
/** /**
@ -35,35 +31,16 @@ public class HandieBot {
public static final String APPLICATION_NAME = "HandieBot"; public static final String APPLICATION_NAME = "HandieBot";
//The token required for logging into Discord. This is secure and must not be in the source code on GitHub. //The token required for logging into Discord. This is secure and must not be in the source code on GitHub.
private static final String TOKEN; private static String TOKEN;
static {
TOKEN = readToken();
if (TOKEN.isEmpty()){
System.out.println("You do not have the token required to start the bot. Shutting down.");
System.exit(-1);
}
}
//Variable to enable or disable GUI. //Variable to enable or disable GUI.
private static boolean USE_GUI = true; private static boolean USE_GUI = true;
//Settings for the bot. Tries to load the settings, or if that doesn't work, it will load defaults. //Settings for the bot. Tries to load the settings, or if that doesn't work, it will load defaults.
public static Properties settings; public static Properties settings;
static{
try {
Properties defaultSettings = new Properties();
defaultSettings.load(HandieBot.class.getClassLoader().getResourceAsStream("default_settings"));
settings = new Properties(defaultSettings);
settings.load(new FileInputStream(FileUtil.getDataDirectory()+"settings"));
} catch (IOException e) {
e.printStackTrace();
}
}
//Resource bundle for localized strings. //Resource bundle for localized strings.
public static ResourceBundle resourceBundle = ResourceBundle.getBundle("Strings", Locale.forLanguageTag(settings.getProperty("language"))); public static ResourceBundle resourceBundle;
//Discord client object. //Discord client object.
public static IDiscordClient client; public static IDiscordClient client;
@ -91,8 +68,25 @@ public class HandieBot {
//client.changeAvatar(Image.forStream("png", getClass().getClassLoader().getResourceAsStream("avatarIcon.png"))); //client.changeAvatar(Image.forStream("png", getClass().getClassLoader().getResourceAsStream("avatarIcon.png")));
} }
/**
* Set up the basic functions of the bot.
*/
private static void init(){
TOKEN = FileUtil.readToken();
if (TOKEN.isEmpty()){
System.out.println("You do not have the token required to start the bot. Shutting down.");
System.exit(-1);
}
settings = FileUtil.loadSettings();
resourceBundle = ResourceBundle.getBundle("Strings", Locale.forLanguageTag(settings.getProperty("language")));
}
public static void main(String[] args) throws DiscordException, RateLimitException { public static void main(String[] args) throws DiscordException, RateLimitException {
init();
musicPlayer = new MusicPlayer(); musicPlayer = new MusicPlayer();
List<String> argsList = Arrays.asList(args); List<String> argsList = Arrays.asList(args);
@ -124,21 +118,6 @@ public class HandieBot {
return channel.getModifiedPermissions(client.getOurUser()).contains(permission); return channel.getModifiedPermissions(client.getOurUser()).contains(permission);
} }
/**
* Reads the private discord token necessary to start the bot. If this fails, the bot will shut down.
* @return The string token needed to log in.
*/
private static String readToken(){
String path = FileUtil.getDataDirectory()+"token.txt";
String result = "";
try(BufferedReader reader = new BufferedReader(new FileReader(path))){
result = reader.readLine();
} catch (IOException e) {
System.err.println("Unable to find the token file. You are unable to start the bot without this.");
}
return result;
}
/** /**
* Safely shuts down the bot on all guilds. * Safely shuts down the bot on all guilds.
*/ */
@ -147,7 +126,7 @@ public class HandieBot {
musicPlayer.quitAll(); musicPlayer.quitAll();
client.logout(); client.logout();
window.dispose(); window.dispose();
FileUtil.saveSettings(); FileUtil.saveSettings(settings);
System.exit(0); System.exit(0);
} }

View File

@ -2,6 +2,7 @@ package handiebot.command;
import handiebot.command.types.ReactionListener; import handiebot.command.types.ReactionListener;
import sx.blah.discord.handle.impl.events.guild.channel.message.reaction.ReactionEvent; import sx.blah.discord.handle.impl.events.guild.channel.message.reaction.ReactionEvent;
import sx.blah.discord.util.RequestBuffer;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@ -13,8 +14,12 @@ import java.util.List;
public class ReactionHandler { public class ReactionHandler {
private static List<ReactionListener> listeners = new ArrayList<>(); private static List<ReactionListener> listeners = new ArrayList<>();
//Flag to tell if the handler is iterating over the listeners.
private static boolean iterating = false; private static boolean iterating = false;
//Queue of listeners to remove after an iteration.
private static List<ReactionListener> listenersToRemove = new ArrayList<>(); private static List<ReactionListener> listenersToRemove = new ArrayList<>();
//Flag that individual listeners can set to request the message be deleted after processing.
private static boolean deleteRequested = false;
/** /**
* Adds a listener, so that it is notified when reaction events are received. * Adds a listener, so that it is notified when reaction events are received.
* @param listener The listener to add. * @param listener The listener to add.
@ -35,6 +40,13 @@ public class ReactionHandler {
} }
} }
/**
* Requests that the currently processing message should be deleted after the iteration.
*/
public static void requestMessageDeletion(){
deleteRequested = true;
}
/** /**
* Notifies all listeners that a ReactionEvent has occurred, and calls each one's function. * Notifies all listeners that a ReactionEvent has occurred, and calls each one's function.
* @param event The event that occurred. * @param event The event that occurred.
@ -45,6 +57,10 @@ public class ReactionHandler {
listener.onReactionEvent(event); listener.onReactionEvent(event);
} }
iterating = false; iterating = false;
if (deleteRequested) {
RequestBuffer.request(event.getMessage()::delete);
}
deleteRequested = false;
listeners.removeAll(listenersToRemove); listeners.removeAll(listenersToRemove);
listenersToRemove.clear(); listenersToRemove.clear();
} }

View File

@ -22,6 +22,7 @@ import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutionException;
import static handiebot.HandieBot.log;
import static handiebot.HandieBot.resourceBundle; import static handiebot.HandieBot.resourceBundle;
import static handiebot.utils.MessageUtils.sendMessage; import static handiebot.utils.MessageUtils.sendMessage;
import static handiebot.utils.YoutubeSearch.WATCH_URL; import static handiebot.utils.YoutubeSearch.WATCH_URL;
@ -99,6 +100,8 @@ public class PlayCommand extends ContextCommand {
videos.forEach((video) -> urls.add(WATCH_URL+video.getId())); videos.forEach((video) -> urls.add(WATCH_URL+video.getId()));
IMessage message = YoutubeSearch.displayChoicesDialog(videos, context.getChannel()); IMessage message = YoutubeSearch.displayChoicesDialog(videos, context.getChannel());
ReactionHandler.addListener(new YoutubePlayListener(message, context.getUser(), urls)); ReactionHandler.addListener(new YoutubePlayListener(message, context.getUser(), urls));
} else {
log.log(BotLog.TYPE.ERROR, "YouTube query returned a null list of videos.");
} }
} }
} }

View File

@ -9,6 +9,7 @@ import handiebot.utils.FileUtil;
import java.text.MessageFormat; import java.text.MessageFormat;
import static handiebot.HandieBot.resourceBundle; import static handiebot.HandieBot.resourceBundle;
import static handiebot.HandieBot.settings;
import static handiebot.utils.MessageUtils.sendMessage; import static handiebot.utils.MessageUtils.sendMessage;
/** /**
@ -30,7 +31,7 @@ public class RepeatCommand extends ContextCommand {
boolean shouldRepeat = (context.getArgs()[0].toLowerCase().equals("true")); boolean shouldRepeat = (context.getArgs()[0].toLowerCase().equals("true"));
HandieBot.musicPlayer.setRepeat(context.getGuild(), shouldRepeat); HandieBot.musicPlayer.setRepeat(context.getGuild(), shouldRepeat);
HandieBot.settings.setProperty(context.getGuild().getName()+"_repeat", Boolean.toString(shouldRepeat)); HandieBot.settings.setProperty(context.getGuild().getName()+"_repeat", Boolean.toString(shouldRepeat));
FileUtil.saveSettings(); FileUtil.saveSettings(settings);
} else { } else {
sendMessage(MessageFormat.format(resourceBundle.getString("player.getRepeat"), HandieBot.musicPlayer.isRepeating(context.getGuild())), context.getChannel()); sendMessage(MessageFormat.format(resourceBundle.getString("player.getRepeat"), HandieBot.musicPlayer.isRepeating(context.getGuild())), context.getChannel());
} }

View File

@ -9,6 +9,7 @@ import handiebot.utils.FileUtil;
import java.text.MessageFormat; import java.text.MessageFormat;
import static handiebot.HandieBot.resourceBundle; import static handiebot.HandieBot.resourceBundle;
import static handiebot.HandieBot.settings;
import static handiebot.utils.MessageUtils.sendMessage; import static handiebot.utils.MessageUtils.sendMessage;
/** /**
@ -31,7 +32,7 @@ public class ShuffleCommand extends ContextCommand {
HandieBot.musicPlayer.setShuffle(context.getGuild(), shouldShuffle); HandieBot.musicPlayer.setShuffle(context.getGuild(), shouldShuffle);
//Save the settings for this guild to the settings file. //Save the settings for this guild to the settings file.
HandieBot.settings.setProperty(context.getGuild().getName()+"_shuffle", Boolean.toString(shouldShuffle)); HandieBot.settings.setProperty(context.getGuild().getName()+"_shuffle", Boolean.toString(shouldShuffle));
FileUtil.saveSettings(); FileUtil.saveSettings(settings);
} else { } else {
sendMessage(MessageFormat.format(resourceBundle.getString("player.getShuffle"), HandieBot.musicPlayer.isShuffling(context.getGuild())), context.getChannel()); sendMessage(MessageFormat.format(resourceBundle.getString("player.getShuffle"), HandieBot.musicPlayer.isShuffling(context.getGuild())), context.getChannel());
} }

View File

@ -6,7 +6,6 @@ import handiebot.view.BotLog;
import sx.blah.discord.handle.impl.events.guild.channel.message.reaction.ReactionEvent; import sx.blah.discord.handle.impl.events.guild.channel.message.reaction.ReactionEvent;
import sx.blah.discord.handle.obj.IMessage; import sx.blah.discord.handle.obj.IMessage;
import sx.blah.discord.handle.obj.IUser; import sx.blah.discord.handle.obj.IUser;
import sx.blah.discord.util.RequestBuffer;
import java.util.List; import java.util.List;
@ -56,7 +55,7 @@ public abstract class YoutubeChoiceListener implements ReactionListener {
if ((event.getMessage().getLongID() == this.message.getLongID()) && if ((event.getMessage().getLongID() == this.message.getLongID()) &&
(this.user.getLongID() == event.getUser().getLongID())){ (this.user.getLongID() == event.getUser().getLongID())){
for (int i = 0; i < choices.length; i++){ for (int i = 0; i < choices.length; i++){
if (event.getReaction().toString().equals(choices[i])){ if (event.getReaction().getEmoji().getName().equals(choices[i])){
onChoice(i); onChoice(i);
break; break;
} }
@ -69,7 +68,7 @@ public abstract class YoutubeChoiceListener implements ReactionListener {
* Method to delete the large, unwieldy message and remove the listener for this set of videos. * Method to delete the large, unwieldy message and remove the listener for this set of videos.
*/ */
private void cleanup(){ private void cleanup(){
RequestBuffer.request(message::delete); ReactionHandler.requestMessageDeletion();
ReactionHandler.removeListener(this); ReactionHandler.removeListener(this);
} }

View File

@ -1,5 +1,6 @@
package handiebot.utils; package handiebot.utils;
import handiebot.HandieBot;
import handiebot.view.BotLog; import handiebot.view.BotLog;
import java.io.*; import java.io.*;
@ -7,8 +8,10 @@ import java.nio.file.Files;
import java.text.MessageFormat; import java.text.MessageFormat;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Properties;
import static handiebot.HandieBot.*; import static handiebot.HandieBot.log;
import static handiebot.HandieBot.resourceBundle;
/** /**
* @author Andrew Lalis * @author Andrew Lalis
@ -16,10 +19,19 @@ import static handiebot.HandieBot.*;
*/ */
public class FileUtil { public class FileUtil {
/**
* Gets the directory where handiebot's data is stored.
* @return The directory leading to 'user.home'.
*/
public static String getDataDirectory(){ public static String getDataDirectory(){
return System.getProperty("user.home")+"/.handiebot/"; return System.getProperty("user.home")+"/.handiebot/";
} }
/**
* Reads a file, and returns a list of lines in the file.
* @param file The file to read.
* @return A list of lines from the file.
*/
public static List<String> getLinesFromFile(File file){ public static List<String> getLinesFromFile(File file){
try { try {
return Files.readAllLines(file.toPath()); return Files.readAllLines(file.toPath());
@ -29,6 +41,11 @@ public class FileUtil {
} }
} }
/**
* Writes a list of strings to a file, separated by newlines.
* @param lines The list of lines.
* @param file The file to write to.
*/
public static void writeLinesToFile(List<String> lines, File file){ public static void writeLinesToFile(List<String> lines, File file){
if (lines.size() == 0){ if (lines.size() == 0){
return; return;
@ -56,7 +73,11 @@ public class FileUtil {
} }
} }
public static void saveSettings(){ /**
* Saves the global set of settings.
* @param settings The settings to save.
*/
public static void saveSettings(Properties settings){
try { try {
settings.store(new FileWriter(FileUtil.getDataDirectory()+"settings"), "Settings for HandieBot"); settings.store(new FileWriter(FileUtil.getDataDirectory()+"settings"), "Settings for HandieBot");
} catch (IOException e) { } catch (IOException e) {
@ -64,4 +85,34 @@ public class FileUtil {
} }
} }
/**
* Loads a properties file.
* @return The settings saved locally for HandieBot.
*/
public static Properties loadSettings(){
Properties settings = new Properties();
try {
settings.load(HandieBot.class.getClassLoader().getResourceAsStream("default_settings"));
settings.load(new FileInputStream(FileUtil.getDataDirectory()+"settings"));
} catch (IOException e){
e.printStackTrace();
}
return settings;
}
/**
* Reads the private discord token necessary to start the bot. If this fails, the bot will shut down.
* @return The string token needed to log in.
*/
public static String readToken(){
String path = FileUtil.getDataDirectory()+"token.txt";
String result = "";
try(BufferedReader reader = new BufferedReader(new FileReader(path))){
result = reader.readLine();
} catch (IOException e) {
System.err.println("Unable to find the token file. You are unable to start the bot without this.");
}
return result;
}
} }

View File

@ -25,8 +25,8 @@ import sx.blah.discord.util.EmbedBuilder;
import java.awt.*; import java.awt.*;
import java.io.File; import java.io.File;
import java.io.FileInputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader; import java.io.InputStreamReader;
import java.security.GeneralSecurityException; import java.security.GeneralSecurityException;
import java.text.MessageFormat; import java.text.MessageFormat;
@ -76,14 +76,13 @@ public class YoutubeSearch {
* @throws IOException * @throws IOException
*/ */
public static Credential authorize() throws IOException { public static Credential authorize() throws IOException {
// Load client secrets. // Load client secrets.
InputStream in = YoutubeSearch.class.getClassLoader().getResourceAsStream("client_secret.json"); GoogleClientSecrets clientSecrets = GoogleClientSecrets.load(JSON_FACTORY,
GoogleClientSecrets clientSecrets = GoogleClientSecrets.load(JSON_FACTORY, new InputStreamReader(in)); new InputStreamReader(new FileInputStream(FileUtil.getDataDirectory()+"googleData/client_secret.json")));
// Build flow and trigger user authorization request. // Build flow and trigger user authorization request.
GoogleAuthorizationCodeFlow flow = GoogleAuthorizationCodeFlow flow = new GoogleAuthorizationCodeFlow.Builder(HTTP_TRANSPORT, JSON_FACTORY, clientSecrets, SCOPES)
new GoogleAuthorizationCodeFlow.Builder(
HTTP_TRANSPORT, JSON_FACTORY, clientSecrets, SCOPES)
.setDataStoreFactory(DATA_STORE_FACTORY) .setDataStoreFactory(DATA_STORE_FACTORY)
.setAccessType("offline") .setAccessType("offline")
.build(); .build();

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.4 KiB

After

Width:  |  Height:  |  Size: 74 KiB