From 571139a59cedf48b30ad13dc868a9c9fb5a8d043 Mon Sep 17 00:00:00 2001 From: Nekojimi Date: Sun, 24 Mar 2024 17:29:23 +0000 Subject: [PATCH] Screw it, more changes --- src/main/java/moe/nekojimi/chords/Chords.java | 105 ++++++++++++------ .../java/moe/nekojimi/chords/Downloader.java | 22 +++- .../java/moe/nekojimi/chords/QueueThing.java | 17 +-- .../moe/nekojimi/chords/TrackRequest.java | 14 +-- src/main/java/moe/nekojimi/chords/Util.java | 15 +++ .../moe/nekojimi/chords/commands/Command.java | 15 ++- .../nekojimi/chords/commands/JoinCommand.java | 34 ++---- .../chords/commands/QueueCommand.java | 1 - 8 files changed, 137 insertions(+), 86 deletions(-) diff --git a/src/main/java/moe/nekojimi/chords/Chords.java b/src/main/java/moe/nekojimi/chords/Chords.java index a9273c0..b37fead 100644 --- a/src/main/java/moe/nekojimi/chords/Chords.java +++ b/src/main/java/moe/nekojimi/chords/Chords.java @@ -56,6 +56,7 @@ public final class Chords extends ListenerAdapter private final Downloader downloader; private final Searcher searcher; private final QueueManager queueManager; + private Recommender recommender; private JDA jda; private final Map commands = new HashMap<>(); @@ -149,6 +150,7 @@ public final class Chords extends ListenerAdapter // init queue manager queueManager = new QueueManager(); + queueManager.addSource(downloader); // init commands addCommand(new JoinCommand(this)); @@ -211,18 +213,29 @@ public final class Chords extends ListenerAdapter log("MESG", "G:" + guild.getName() + " A:" + author.getName() + " C:" + content); - try - { - URL parseURL = new URL(content.trim()); - playCommand.call(null); - } catch (MalformedURLException ex) - { - // not a URL, then - } + Invocation invocation = null; try { + try + { + URL parseURL = new URL(content.trim()); + invocation = new Invocation(event, List.of(parseURL.toExternalForm())); + playCommand.call(invocation); + return; + } catch (MalformedURLException ex) + { + // not a URL, then + } + String[] split = content.split("\\s+"); + List args = new ArrayList<>(); + Collections.addAll(args, split); + args.remove(0); + + invocation = new Invocation(event, args); + invocation.setRequestMessage(message); + String cmd = split[0].toLowerCase(); if (!cmd.startsWith("!")) @@ -231,12 +244,6 @@ public final class Chords extends ListenerAdapter cmd = cmd.substring(1); // strip prefix char // String arg = ""; - List args = new ArrayList<>(); - Collections.addAll(args, split); - args.remove(0); - - Invocation invocation = new Invocation(event, args); - invocation.setRequestMessage(message); if (commands.containsKey(cmd)) { @@ -248,32 +255,18 @@ public final class Chords extends ListenerAdapter } } catch (Exception ex) { - event.getChannel().sendMessage("Error in command! " + ex.getMessage()).queue(); + if (invocation != null) + invocation.respond("Error: " + ex.getMessage()); + else + event.getChannel().sendMessage("Error: " + ex.getMessage()).queue(); log("UERR", "Command error:" + ex.getMessage()); } } public void queueDownload(TrackRequest request) { -// Track track; -// if (request.getUrl() != null) -// { -// track = new Track(request.getUrl()); -// } else -// { -// // interpret search result -// throw new UnsupportedOperationException("Not supported yet."); -// } -// if (request.getInvocation().getRequestMessage() != null) -// { -// -// } -// track.setNumber(trackNumber); -// trackNumber++; -// request.addTrack(track); request.getInvocation().respond("Request pending..."); - downloader.accept(new Downloader.DownloadTask(request, queueManager)); -// return track; + downloader.accept(request); } public void setStatus(Track nowPlaying) @@ -361,6 +354,19 @@ public final class Chords extends ListenerAdapter } } + public void setRecommenderEnabled(boolean enabled) + { + if (recommender == null && enabled) + { + recommender = new Recommender(); + downloader.addSource(recommender); + } else if (recommender != null && !enabled) + { + downloader.removeSource(recommender); + recommender = null; + } + } + public MusicHandler getMusicHandler() { return musicHandler; @@ -396,6 +402,36 @@ public final class Chords extends ListenerAdapter return settings; } + public static CommandOptions getOptions() + { + return options; + } + + public File getDataDirectory() + { + return dataDirectory; + } + + public File getPlaylistsDirectory() + { + return playlistsDirectory; + } + + public Map getCommands() + { + return commands; + } + + public Map getPlaylists() + { + return playlists; + } + + public Recommender getRecommender() + { + return recommender; + } + private class DownloaderMessageHandler implements BiConsumer { @@ -477,6 +513,9 @@ public final class Chords extends ListenerAdapter jda.getPresence().setActivity(Activity.of(Activity.ActivityType.LISTENING, track.toString())); else jda.getPresence().setActivity(null); + + if (recommender != null) + recommender.addSeed(track); } } diff --git a/src/main/java/moe/nekojimi/chords/Downloader.java b/src/main/java/moe/nekojimi/chords/Downloader.java index b531fb5..f9baa76 100644 --- a/src/main/java/moe/nekojimi/chords/Downloader.java +++ b/src/main/java/moe/nekojimi/chords/Downloader.java @@ -23,6 +23,7 @@ import javax.json.Json; import javax.json.JsonArray; import javax.json.JsonObject; import javax.json.JsonReader; +import moe.nekojimi.musicsearcher.Result; import net.dv8tion.jda.api.audio.AudioSendHandler; /** @@ -87,6 +88,8 @@ public class Downloader extends QueueThing protected boolean completePromise(Promise promise) { TrackRequest request = promise.getInput(); + if (request == null) + return false; executor.submit(() -> { @@ -244,9 +247,13 @@ public class Downloader extends QueueThing JsonReader reader = Json.createReader(new StringReader(line)); JsonObject object = reader.readObject(); + Result result = request.getResult(); + // look for metadata if (track.getTitle() == null) { + if (result != null && !result.getTitle().isBlank()) + track.setTitle(result.getTitle()); for (String key : INFO_TITLE_KEYS) { if (object.containsKey(key) && !object.getString(key).isBlank()) @@ -258,6 +265,8 @@ public class Downloader extends QueueThing } if (track.getArtist() == null) { + if (result != null && !result.getArtist().isBlank()) + track.setArtist(result.getArtist()); for (String key : INFO_ARTIST_KEYS) { if (object.containsKey(key) && !object.getString(key).isBlank()) @@ -393,10 +402,17 @@ public class Downloader extends QueueThing } } - String error = new String(exec.getErrorStream().readAllBytes(), Charset.defaultCharset()); + boolean exited = exec.waitFor(DOWNLOAD_TIMEOUT, TimeUnit.SECONDS); + if (exited) + { + String error = new String(exec.getErrorStream().readAllBytes(), Charset.defaultCharset()); - if (exec.exitValue() != 0) - throw new RuntimeException("youtube-dl failed with error " + exec.exitValue() + ", output:\n" + error); + if (exec.exitValue() != 0) + throw new RuntimeException("youtube-dl failed with error " + exec.exitValue() + ", output:\n" + error); + } else + { + throw new RuntimeException("youtube-dl failed to exit."); + } messageHandler.accept(request, null); } catch (Exception ex) diff --git a/src/main/java/moe/nekojimi/chords/QueueThing.java b/src/main/java/moe/nekojimi/chords/QueueThing.java index 24f9ca2..21ea53a 100644 --- a/src/main/java/moe/nekojimi/chords/QueueThing.java +++ b/src/main/java/moe/nekojimi/chords/QueueThing.java @@ -44,7 +44,7 @@ public abstract class QueueThing implements Consumer @Override public void accept(I t) { - + // FIXME: this causes queue-jumping // if we've got pending promises, fullfill them, otherwise just put it in the queue and notify the sinks if (pendingPromises.isEmpty()) { @@ -53,6 +53,7 @@ public abstract class QueueThing implements Consumer } else { Promise promise = pendingPromises.poll(); + System.out.println(this.getClass().getSimpleName() + " now has " + pendingPromises + " promises."); promise.setInput(t); handlePromise(promise); } @@ -76,7 +77,7 @@ public abstract class QueueThing implements Consumer public List> request(int count, Consumer destination) { List> ret = new ArrayList<>(); - int demands = 0; + int demandsForClient = 0; for (int i = 0; i < count; i++) { I input = null; @@ -96,21 +97,23 @@ public abstract class QueueThing implements Consumer } else { // we need to get more input from sources - demands++; + demandsForClient++; } } - demands += queueTargetSize - inputQueue.size(); + int demandsForMe = queueTargetSize - inputQueue.size(); + int demandsTotal = demandsForMe + demandsForClient; - if (demands > 0) + if (demandsTotal > 0) { // try to get more input from sources - int sourcePromises = demandInput(demands); + int sourcePromises = demandInput(demandsForClient); // each promise of input we get represents a promise of output we can give - for (int i = 0; i < sourcePromises; i++) + for (int i = 0; i < sourcePromises && i < demandsForClient; i++) { Promise myPromise = new Promise<>(destination); pendingPromises.add(myPromise); + System.out.println(this.getClass().getSimpleName() + " has made " + pendingPromises + " promises."); ret.add(myPromise); } } diff --git a/src/main/java/moe/nekojimi/chords/TrackRequest.java b/src/main/java/moe/nekojimi/chords/TrackRequest.java index 07a4bfb..572de1a 100644 --- a/src/main/java/moe/nekojimi/chords/TrackRequest.java +++ b/src/main/java/moe/nekojimi/chords/TrackRequest.java @@ -35,8 +35,6 @@ public class TrackRequest implements Comparable private String query; private URL url; - private List searchResults; - private Result result; private final List tracks = new ArrayList<>(); @@ -58,16 +56,6 @@ public class TrackRequest implements Comparable return ret; } - public List getSearchResults() - { - return searchResults; - } - - public void setSearchResults(List searchResults) - { - this.searchResults = searchResults; - } - public Result getResult() { return result; @@ -162,7 +150,7 @@ public class TrackRequest implements Comparable trackName = "Request"; else { - trackName = tracks.get(1).toString(); + trackName = tracks.get(0).toString(); if (tracks.size() > 1) trackName += " & " + (tracks.size() - 1) + " more tracks"; } diff --git a/src/main/java/moe/nekojimi/chords/Util.java b/src/main/java/moe/nekojimi/chords/Util.java index 631d837..9966140 100644 --- a/src/main/java/moe/nekojimi/chords/Util.java +++ b/src/main/java/moe/nekojimi/chords/Util.java @@ -77,4 +77,19 @@ public class Util } return -1L; } + + public static String formatProgressBar(double progressPercent, String[] symbols, int barLength) + { + String ret = ""; + double filledSegments = (progressPercent / 100.0) * barLength; + + for (int i = 0; i < barLength; i++) + { + double thisSegment = Math.min(1, Math.max(0, filledSegments - i)); + int symbolIdx = (int) Math.floor(thisSegment * symbols.length); + String symbol = symbols[symbolIdx]; + ret += symbol; + } + return ret; + } } diff --git a/src/main/java/moe/nekojimi/chords/commands/Command.java b/src/main/java/moe/nekojimi/chords/commands/Command.java index 239abf8..d8da30f 100644 --- a/src/main/java/moe/nekojimi/chords/commands/Command.java +++ b/src/main/java/moe/nekojimi/chords/commands/Command.java @@ -30,8 +30,19 @@ public abstract class Command return keyword; } -// public abstract String synopsis(); + public String argumentDescription() + { + return ""; // most commands take no arguments + } + + public String synopsis() + { + throw new UnsupportedOperationException("Not supported yet."); + } // -// public abstract String help(); + public String help() + { + throw new UnsupportedOperationException("Not supported yet."); + } } diff --git a/src/main/java/moe/nekojimi/chords/commands/JoinCommand.java b/src/main/java/moe/nekojimi/chords/commands/JoinCommand.java index 0a4aa47..ff9512a 100644 --- a/src/main/java/moe/nekojimi/chords/commands/JoinCommand.java +++ b/src/main/java/moe/nekojimi/chords/commands/JoinCommand.java @@ -67,40 +67,20 @@ public class JoinCommand extends Command if (channel == null) // I have no idea what you want mr user { - onUnknownChannel(textChannel, arg0); // Let the user know about our failure - return; +// onUnknownChannel(textChannel, arg0); // Let the user know about our failure + throw new RuntimeException("Unable to connect to \"" + channel.getName() + "\", no such channel!"); } } bot.connectTo(channel); // We found a channel to connect to! - onConnecting(channel, textChannel); // Let the user know, we were successful! + invocation.respond("Connecting to " + channel.getName() + "..."); +// onConnecting(channel, textChannel); // Let the user know, we were successful! } - /** - * Inform user about successful connection. - * - * @param channel - * The voice channel we connected to - * @param textChannel - * The text channel to send the message in - */ - public void onConnecting(VoiceChannel channel, MessageChannel textChannel) - { - textChannel.sendMessage("Connecting to " + channel.getName()).queue(); // never forget to queue()! - } - - /** - * The channel to connect to is not known to us. - * - * @param channel - * The message channel (text channel abstraction) to send failure - * information to - * @param comment - * The information of this channel - */ - public void onUnknownChannel(MessageChannel channel, String comment) + @Override + public String argumentDescription() { - channel.sendMessage("Unable to connect to ``" + comment + "``, no such channel!").queue(); // never forget to queue()! + return ""; } } diff --git a/src/main/java/moe/nekojimi/chords/commands/QueueCommand.java b/src/main/java/moe/nekojimi/chords/commands/QueueCommand.java index e5b177d..f1cd90f 100644 --- a/src/main/java/moe/nekojimi/chords/commands/QueueCommand.java +++ b/src/main/java/moe/nekojimi/chords/commands/QueueCommand.java @@ -18,7 +18,6 @@ package moe.nekojimi.chords.commands; import java.util.List; import java.util.Queue; -import moe.nekojimi.chords.Downloader; import moe.nekojimi.chords.Chords; import moe.nekojimi.chords.Track; import moe.nekojimi.chords.TrackRequest;