From 2a25e1368d5be8f18f3cd2d732b7e3d6cb72fbf9 Mon Sep 17 00:00:00 2001
From: Nekojimi <Jim@nekojimi.moe>
Date: Sun, 5 Nov 2023 22:35:35 +0000
Subject: [PATCH] Mega-refactor: change song to track everywhere.

---
 pom.xml.orig                                  | 72 ++++++++++++++
 src/main/java/moe/nekojimi/chords/Chords.java | 60 ++++++------
 .../java/moe/nekojimi/chords/Downloader.java  | 94 ++++++++++---------
 .../moe/nekojimi/chords/MusicHandler.java     | 44 ++++-----
 .../java/moe/nekojimi/chords/Playlist.java    | 42 ++++-----
 .../moe/nekojimi/chords/QueueManager.java     | 48 +++++-----
 .../nekojimi/chords/{Song.java => Track.java} | 28 +++---
 .../java/moe/nekojimi/chords/TrackPlayer.java |  4 +-
 .../{SongRequest.java => TrackRequest.java}   | 35 +++++--
 .../nekojimi/chords/commands/HelpCommand.java |  8 +-
 .../nekojimi/chords/commands/PlayCommand.java |  8 +-
 .../chords/commands/QueueCommand.java         | 20 ++--
 .../chords/commands/RemoveCommand.java        |  6 +-
 .../chords/commands/RestartCommand.java       |  4 +-
 .../nekojimi/chords/commands/SkipCommand.java |  6 +-
 15 files changed, 287 insertions(+), 192 deletions(-)
 create mode 100644 pom.xml.orig
 rename src/main/java/moe/nekojimi/chords/{Song.java => Track.java} (85%)
 rename src/main/java/moe/nekojimi/chords/{SongRequest.java => TrackRequest.java} (78%)

diff --git a/pom.xml.orig b/pom.xml.orig
new file mode 100644
index 0000000..48e4271
--- /dev/null
+++ b/pom.xml.orig
@@ -0,0 +1,72 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <groupId>moe.nekojimi</groupId>
+    <artifactId>Chords</artifactId>
+    <version>1.0</version>
+    <packaging>jar</packaging>
+    <repositories>
+        <repository>
+            <id>dv8tion</id>
+            <name>m2-dv8tion</name>
+            <url>https://m2.dv8tion.net/releases</url>
+        </repository>
+    </repositories>
+        <build>
+            <plugins>
+                <plugin>
+                    <artifactId>maven-assembly-plugin</artifactId>
+                    <configuration>
+                        <archive>
+                            <manifest>
+                                <mainClass>
+                                    moe.nekojimi.chords.Chords
+                                </mainClass>
+                            </manifest>
+                        </archive>
+                        <descriptorRefs>
+                            <descriptorRef>jar-with-dependencies</descriptorRef>
+                        </descriptorRefs>
+                    </configuration>
+                </plugin>
+            </plugins>
+        </build>
+    <dependencies>
+        <dependency>
+            <groupId>net.dv8tion</groupId>
+            <artifactId>JDA</artifactId>
+<<<<<<< HEAD
+            <version>5.0.0-beta.5</version>
+=======
+            <version>5.0.0-beta.6</version>
+>>>>>>> b24453d (Update JDA to v5.0.)
+        </dependency>
+        <dependency>
+            <groupId>commons-io</groupId>
+            <artifactId>commons-io</artifactId>
+            <version>2.11.0</version>
+        </dependency>
+        <dependency>
+            <groupId>moe.nekojimi</groupId>
+            <artifactId>MusicSearcher</artifactId>
+            <version>1.0-SNAPSHOT</version>
+            <type>jar</type>
+        </dependency>
+        <dependency>
+            <groupId>javax.json</groupId>
+            <artifactId>javax.json-api</artifactId>
+            <version>1.1.4</version>
+            <type>jar</type>
+        </dependency>
+        <dependency>
+            <groupId>com.beust</groupId>
+            <artifactId>jcommander</artifactId>
+            <version>1.78</version>
+        </dependency>
+    </dependencies>
+    <properties>
+        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+        <maven.compiler.source>11</maven.compiler.source>
+        <maven.compiler.target>11</maven.compiler.target>
+    </properties>
+</project>
diff --git a/src/main/java/moe/nekojimi/chords/Chords.java b/src/main/java/moe/nekojimi/chords/Chords.java
index d5eedc6..b8a684c 100644
--- a/src/main/java/moe/nekojimi/chords/Chords.java
+++ b/src/main/java/moe/nekojimi/chords/Chords.java
@@ -128,9 +128,9 @@ public final class Chords extends ListenerAdapter
         JDA jda = builder.build();
         listener.setJda(jda);
     }
-    private final Consumer<Song> nowPlayingConsumer = new NowPlayingConsumer();
+    private final Consumer<Track> nowPlayingConsumer = new NowPlayingConsumer();
 
-    private final BiConsumer<SongRequest, Exception> downloaderMessageHandler = new DownloaderMessageHandler();
+    private final BiConsumer<TrackRequest, Exception> downloaderMessageHandler = new DownloaderMessageHandler();
 
     public Chords() throws IOException
     {
@@ -253,12 +253,12 @@ public final class Chords extends ListenerAdapter
         }
     }
 
-    public void queueDownload(SongRequest request)
+    public void queueDownload(TrackRequest request)
     {
-//        Song song;
+//        Track track;
 //        if (request.getUrl() != null)
 //        {
-//            song = new Song(request.getUrl());
+//            track = new Track(request.getUrl());
 //        } else
 //        {
 //            // interpret search result
@@ -268,15 +268,15 @@ public final class Chords extends ListenerAdapter
 //        {
 //
 //        }
-//        song.setNumber(trackNumber);
+//        track.setNumber(trackNumber);
 //        trackNumber++;
-//        request.addSong(song);
+//        request.addTrack(track);
         request.getInvocation().respond("Request pending...");
         downloader.accept(new Downloader.DownloadTask(request, queueManager));
-//        return song;
+//        return track;
     }
 
-    public void setStatus(Song nowPlaying)
+    public void setStatus(Track nowPlaying)
     {
         jda.getPresence().setActivity(Activity.listening(nowPlaying.toString()));
     }
@@ -396,7 +396,7 @@ public final class Chords extends ListenerAdapter
         return settings;
     }
 
-    private class DownloaderMessageHandler implements BiConsumer<SongRequest, Exception>
+    private class DownloaderMessageHandler implements BiConsumer<TrackRequest, Exception>
     {
 
         private static final String PROGRESS_SYMBOLS = " ▏▎▍▌▋▊▉█";
@@ -407,23 +407,23 @@ public final class Chords extends ListenerAdapter
         }
 
         @Override
-        public void accept(SongRequest request, Exception ex)
+        public void accept(TrackRequest request, Exception ex)
         {
             String response = "";
-            if (request.getSongs().size() > 1)
-                response += "Downloading " + request.getSongs().size() + " tracks:\n";
-            for (Song song : request.getSongs())
+            if (request.getTracks().size() > 1)
+                response += "Downloading " + request.getTracks().size() + " tracks:\n";
+            for (Track track : request.getTracks())
             {
-//            TextChannel channel = jda.getTextChannelById(song.getRequestedIn());
-//            String bracketNo = "[" + song.getNumber() + "] ";
+//            TextChannel channel = jda.getTextChannelById(track.getRequestedIn());
+//            String bracketNo = "[" + track.getNumber() + "] ";
                 if (ex == null)
-                    if (song.getLocation() != null && song.getProgress() >= 100)
+                    if (track.getLocation() != null && track.getProgress() >= 100)
                     {
-                        response += ("Finished downloading " + song + ", added to queue!");
-                        log("DOWN", "Downloaded " + song);
+                        response += ("Finished downloading " + track + "!");
+                        log("DOWN", "Downloaded " + track);
                     } else
                     {
-                        Format format = song.getBestFormat();
+                        Format format = track.getBestFormat();
                         String formatDetails = "";
                         if (format != null)
                         {
@@ -435,16 +435,16 @@ public final class Chords extends ListenerAdapter
                         }
 
                         String progressDetails = "";
-                        if (song.getProgress() >= 0)
-                            progressDetails = " [" + String.format("%.1f", song.getProgress()) + "%]";
+                        if (track.getProgress() >= 0)
+                            progressDetails = " [" + String.format("%.1f", track.getProgress()) + "%]";
 
-                        response += ("Now downloading " + song + formatDetails + progressDetails + " ...");
-                        log("DOWN", "Downloading " + song + "...");
+                        response += ("Now downloading " + track + formatDetails + progressDetails + " ...");
+                        log("DOWN", "Downloading " + track + "...");
                     }
                 else
                 {
-                    response += ("Failed to download " + song + "! Reason: " + ex.getMessage());
-                    log("DOWN", "Failed to download " + song + "! Reason: " + ex.getMessage());
+                    response += ("Failed to download " + track + "! Reason: " + ex.getMessage());
+                    log("DOWN", "Failed to download " + track + "! Reason: " + ex.getMessage());
                 }
                 response += "\n";
             }
@@ -453,7 +453,7 @@ public final class Chords extends ListenerAdapter
         }
     }
 
-    private class NowPlayingConsumer implements Consumer<Song>
+    private class NowPlayingConsumer implements Consumer<Track>
     {
 
         public NowPlayingConsumer()
@@ -461,10 +461,10 @@ public final class Chords extends ListenerAdapter
         }
 
         @Override
-        public void accept(Song song)
+        public void accept(Track track)
         {
-            if (song != null)
-                jda.getPresence().setActivity(Activity.of(Activity.ActivityType.LISTENING, song.toString()));
+            if (track != null)
+                jda.getPresence().setActivity(Activity.of(Activity.ActivityType.LISTENING, track.toString()));
             else
                 jda.getPresence().setActivity(null);
         }
diff --git a/src/main/java/moe/nekojimi/chords/Downloader.java b/src/main/java/moe/nekojimi/chords/Downloader.java
index 65db535..dc3fb3a 100644
--- a/src/main/java/moe/nekojimi/chords/Downloader.java
+++ b/src/main/java/moe/nekojimi/chords/Downloader.java
@@ -49,8 +49,8 @@ public class Downloader implements Consumer<DownloadTask>
     private final LinkedBlockingDeque<Runnable> workQueue = new LinkedBlockingDeque<>();
     private final ThreadPoolExecutor executor = new ThreadPoolExecutor(2, 4, 30, TimeUnit.SECONDS, workQueue);
     private final ScheduledExecutorService scheduler = new ScheduledThreadPoolExecutor(1);
-//    private Consumer<Song> next;
-    private BiConsumer<SongRequest, Exception> messageHandler;
+//    private Consumer<Track> next;
+    private BiConsumer<TrackRequest, Exception> messageHandler;
 
     private File downloadDir = null;
 
@@ -64,11 +64,11 @@ public class Downloader implements Consumer<DownloadTask>
     @Override
     public void accept(DownloadTask task)
     {
-        // if all songs of the request are already downloaded, just skip
-        if (!task.request.getSongs().isEmpty() && task.request.getSongs().stream().allMatch((t) -> t.isDownloaded()))
+        // if all tracks of the request are already downloaded, just skip
+        if (!task.request.getTracks().isEmpty() && task.request.getTracks().stream().allMatch((t) -> t.isDownloaded()))
         {
-            for (Song song : task.request.getSongs())
-                task.getDestination().accept(song);
+            for (Track track : task.request.getTracks())
+                task.getDestination().accept(track);
             return;
         }
 
@@ -79,7 +79,7 @@ public class Downloader implements Consumer<DownloadTask>
         {
             try
             {
-//                getFormats(song);
+//                getFormats(track);
                 download(task);
             } catch (Exception ex)
             {
@@ -129,13 +129,13 @@ public class Downloader implements Consumer<DownloadTask>
         return formats;
     }
 
-    private void getFormats(Song song)
+    private void getFormats(Track track)
     {
-        if (!song.getFormats().isEmpty())
+        if (!track.getFormats().isEmpty())
             return;
         try
         {
-            String cmd = Chords.getSettings().getYtdlCommand() + " --skip-download -F " + song.getUrl().toString();
+            String cmd = Chords.getSettings().getYtdlCommand() + " --skip-download -F " + track.getUrl().toString();
             Process exec = runCommand(cmd, FORMAT_TIMEOUT);
             InputStream input = exec.getInputStream();
             String output = new String(input.readAllBytes(), Charset.defaultCharset());
@@ -195,7 +195,7 @@ public class Downloader implements Consumer<DownloadTask>
                     format.setSampleRate(Util.parseSampleRate(split[bitrateCol]));
                 formats.add(format);
             }
-            song.setFormats(formats);
+            track.setFormats(formats);
 
         } catch (Exception ex)
         {
@@ -204,31 +204,31 @@ public class Downloader implements Consumer<DownloadTask>
         }
     }
 
-    private List<Song> getInfo(SongRequest request)
+    private List<Track> getInfo(TrackRequest request)
     {
-        List<Song> ret = new ArrayList<>();
+        List<Track> ret = new ArrayList<>();
         try
         {
             String cmd = Chords.getSettings().getYtdlCommand() + " --skip-download --print-json " + request.getUrl().toString();
             Process exec = runCommand(cmd, INFO_TIMEOUT);
             InputStream input = exec.getInputStream();
 
-            // read each line as JSON, turn each into a song object
+            // read each line as JSON, turn each into a track object
             Scanner sc = new Scanner(input);
             while (sc.hasNextLine())
             {
-                Song song = new Song(request.getUrl());
-                song.setNumber(trackNumber);
+                Track track = new Track(request.getUrl());
+                track.setNumber(trackNumber);
                 trackNumber++;
-                request.addSong(song);
+                request.addTrack(track);
 
                 String line = sc.nextLine();
                 JsonReader reader = Json.createReader(new StringReader(line));
                 JsonObject object = reader.readObject();
-                if (song.getTitle() == null)
-                    song.setTitle(object.getString("title", null));
-                if (song.getArtist() == null)
-                    song.setArtist(object.getString("uploader", null));
+                if (track.getTitle() == null)
+                    track.setTitle(object.getString("title", null));
+                if (track.getArtist() == null)
+                    track.setArtist(object.getString("uploader", null));
 
                 JsonArray formatsJSON = object.getJsonArray("formats");
                 if (formatsJSON != null)
@@ -240,10 +240,10 @@ public class Downloader implements Consumer<DownloadTask>
                         if (format != null)
                             formats.add(format);
                     }
-                    song.setFormats(formats);
+                    track.setFormats(formats);
                 }
 
-                ret.add(song);
+                ret.add(track);
             }
         } catch (Exception ex)
         {
@@ -259,25 +259,25 @@ public class Downloader implements Consumer<DownloadTask>
         return downloadDir;
     }
 
-    private Song getSongFromRequest(SongRequest request, int idx)
+    private Track getTrackFromRequest(TrackRequest request, int idx)
     {
-        // if there's less songs in the request than expected, fill the array
-        while (idx >= request.getSongs().size())
+        // if there's less tracks in the request than expected, fill the array
+        while (idx >= request.getTracks().size())
         {
-            Song song = new Song(request.getUrl());
-            song.setNumber(trackNumber);
+            Track track = new Track(request.getUrl());
+            track.setNumber(trackNumber);
             trackNumber++;
-            request.addSong(song);
+            request.addTrack(track);
         }
-        return request.getSongs().get(idx);
+        return request.getTracks().get(idx);
     }
 
     private void download(DownloadTask task)
     {
         Set<Format> uniqueFormats = new HashSet<>();
-        for (Song song : task.request.getSongs())
+        for (Track track : task.request.getTracks())
         {
-            uniqueFormats.addAll(song.getFormats());
+            uniqueFormats.addAll(track.getFormats());
         }
 
         List<Format> sortedFormats = sortFormats(uniqueFormats);
@@ -313,7 +313,7 @@ public class Downloader implements Consumer<DownloadTask>
                 if (itemMatcher.find())
                 {
                     int idx = Integer.parseInt(itemMatcher.group(1)) - 1;
-                    int total = Integer.parseInt(cmd);
+//                    int total = Integer.parseInt(itemMatcher.group(2));
 
                     downloadIdx = idx;
                 }
@@ -321,20 +321,24 @@ public class Downloader implements Consumer<DownloadTask>
                 Matcher progMatcher = PROGRESS_PATTERN.matcher(line);
                 if (progMatcher.find())
                 {
-                    getSongFromRequest(task.request, downloadIdx).setProgress(Double.parseDouble(progMatcher.group(1)));
+                    getTrackFromRequest(task.request, downloadIdx).setProgress(Double.parseDouble(progMatcher.group(1)));
                     messageHandler.accept(task.request, null);
                 }
 
                 Matcher destMatcher = DESTINATION_PATTERN.matcher(line);
                 if (destMatcher.find())
                 {
-                    Song song = getSongFromRequest(task.request, downloadIdx);
+                    Track track = getTrackFromRequest(task.request, downloadIdx);
 
-                    song.setLocation(new File(destMatcher.group(1)));
+                    track.setLocation(new File(destMatcher.group(1)));
 
-                    // this is currently our criteria for completion; submit the song and move on
+                    // this is currently our criteria for completion; submit the track and move on
                     if (task.getDestination() != null)
-                        task.getDestination().accept(song);
+                        task.getDestination().accept(track);
+
+                    track.setProgress(100.0);
+
+                    messageHandler.accept(task.request, null);
 
                     downloadIdx++;
                 }
@@ -383,12 +387,12 @@ public class Downloader implements Consumer<DownloadTask>
         return exec;
     }
 
-    public BiConsumer<SongRequest, Exception> getMessageHandler()
+    public BiConsumer<TrackRequest, Exception> getMessageHandler()
     {
         return messageHandler;
     }
 
-    public void setMessageHandler(BiConsumer<SongRequest, Exception> messageHandler)
+    public void setMessageHandler(BiConsumer<TrackRequest, Exception> messageHandler)
     {
         this.messageHandler = messageHandler;
     }
@@ -401,21 +405,21 @@ public class Downloader implements Consumer<DownloadTask>
     public static class DownloadTask
     {
 
-        private final SongRequest request;
-        private final Consumer<Song> destination;
+        private final TrackRequest request;
+        private final Consumer<Track> destination;
 
-        public DownloadTask(SongRequest request, Consumer<Song> destination)
+        public DownloadTask(TrackRequest request, Consumer<Track> destination)
         {
             this.request = request;
             this.destination = destination;
         }
 
-        public SongRequest getSong()
+        public TrackRequest getTrack()
         {
             return request;
         }
 
-        public Consumer<Song> getDestination()
+        public Consumer<Track> getDestination()
         {
             return destination;
         }
diff --git a/src/main/java/moe/nekojimi/chords/MusicHandler.java b/src/main/java/moe/nekojimi/chords/MusicHandler.java
index 7e28d09..56efc07 100644
--- a/src/main/java/moe/nekojimi/chords/MusicHandler.java
+++ b/src/main/java/moe/nekojimi/chords/MusicHandler.java
@@ -23,21 +23,21 @@ public class MusicHandler implements AudioSendHandler, Closeable
 {
 
     private QueueManager queueManager;
-//    private final LinkedList<Song> songQueue = new LinkedList<>();
+//    private final LinkedList<Track> trackQueue = new LinkedList<>();
 //    private final Queue<byte[]> queue = new ConcurrentLinkedQueue<>();
 //    private final CircularByteBuffer audioBuffer = new CircularByteBuffer(3840 * 1024);
     private boolean shouldPlay = true;
     private int byteCount;
 
     private boolean arrayErr = false;
-    private Consumer<Song> nowPlayingConsumer;
+    private Consumer<Track> nowPlayingConsumer;
 
-    public void setNowPlayingConsumer(Consumer<Song> nowPlayingConsumer)
+    public void setNowPlayingConsumer(Consumer<Track> nowPlayingConsumer)
     {
         this.nowPlayingConsumer = nowPlayingConsumer;
     }
 
-    private Song currentSong;
+    private Track currentTrack;
 //    private TrackPlayer player;
     private final List<TrackPlayer> playingTracks = new ArrayList<>();
 
@@ -66,21 +66,21 @@ public class MusicHandler implements AudioSendHandler, Closeable
 
     public void playNext()
     {
-        nextSong(true);
+        nextTrack(true);
     }
 
-    public void playOver(Song song)
+    public void playOver(Track track)
     {
 
     }
 
 
-    private boolean nextSong()
+    private boolean nextTrack()
     {
-        return nextSong(false);
+        return nextTrack(false);
     }
 
-    public boolean nextSong(boolean immediate)
+    public boolean nextTrack(boolean immediate)
     {
         if (immediate)
         {
@@ -90,25 +90,25 @@ public class MusicHandler implements AudioSendHandler, Closeable
 
         try
         {
-            if (currentSong != null)
+            if (currentTrack != null)
             {
-                if (!currentSong.isKept())
-                    currentSong.delete();
-                currentSong = null;
+                if (!currentTrack.isKept())
+                    currentTrack.delete();
+                currentTrack = null;
             }
-            currentSong = queueManager.nextSongNeeded();
+            currentTrack = queueManager.nextTrackNeeded();
             if (nowPlayingConsumer != null)
-                nowPlayingConsumer.accept(currentSong);
-            if (currentSong == null)
+                nowPlayingConsumer.accept(currentTrack);
+            if (currentTrack == null)
             {
                 System.out.println("End of queue.");
                 debugOut.flush();
                 return false;
             }
-            System.out.println("Playing song " + currentSong.getLocation().getAbsolutePath());
+            System.out.println("Playing track " + currentTrack.getLocation().getAbsolutePath());
             arrayErr = false;
             byteCount = 3840;
-            TrackPlayer player = new TrackPlayer(currentSong);
+            TrackPlayer player = new TrackPlayer(currentTrack);
             playingTracks.add(player);
 //            System.out.println("Queue filled to " + audioBuffer.getCurrentNumberOfBytes());
             return true;
@@ -134,7 +134,7 @@ public class MusicHandler implements AudioSendHandler, Closeable
     public void setShouldPlay(boolean shouldPlay)
     {
         if (!this.shouldPlay && shouldPlay)
-            nextSong();
+            nextTrack();
         this.shouldPlay = shouldPlay;
     }
 
@@ -181,7 +181,7 @@ public class MusicHandler implements AudioSendHandler, Closeable
             ret.put(mixBuffers(mixes));
             if (outOfInput)
             {
-                boolean foundNext = nextSong();
+                boolean foundNext = nextTrack();
                 if (!foundNext)
                     break;
             }
@@ -194,9 +194,9 @@ public class MusicHandler implements AudioSendHandler, Closeable
 
     }
 
-    public Song getCurrentSong()
+    public Track getCurrentTrack()
     {
-        return currentSong;
+        return currentTrack;
     }
 
     @Override
diff --git a/src/main/java/moe/nekojimi/chords/Playlist.java b/src/main/java/moe/nekojimi/chords/Playlist.java
index 2863d35..3f622fa 100644
--- a/src/main/java/moe/nekojimi/chords/Playlist.java
+++ b/src/main/java/moe/nekojimi/chords/Playlist.java
@@ -30,14 +30,14 @@ import java.util.logging.Logger;
  *
  * @author jimj316
  */
-public class Playlist implements Consumer<Song>
+public class Playlist implements Consumer<Track>
 {
 
     private static final int SHUFFLE_DONT_REPEAT_LAST = 3;
 
     private final String name;
-    private final List<Song> songs = new ArrayList<>();
-    private final LinkedList<Song> playHistory = new LinkedList<>();
+    private final List<Track> tracks = new ArrayList<>();
+    private final LinkedList<Track> playHistory = new LinkedList<>();
 
     public Playlist(String name)
     {
@@ -46,25 +46,25 @@ public class Playlist implements Consumer<Song>
 
     public YamlMapping toYaml()
     {
-        YamlSequenceBuilder songList = Yaml.createYamlSequenceBuilder();
-        for (Song song : songs)
-            songList = songList.add(song.toYaml());
+        YamlSequenceBuilder trackList = Yaml.createYamlSequenceBuilder();
+        for (Track track : tracks)
+            trackList = trackList.add(track.toYaml());
 
         return Yaml.createYamlMappingBuilder()
                 .add("name", name)
-                .add("songs", songList.build())
+                .add("tracks", trackList.build())
                 .build();
     }
 
     public static Playlist fromYaml(YamlMapping yaml)
     {
         Playlist ret = new Playlist(yaml.string("name"));
-        YamlSequence songList = yaml.value("songs").asSequence();
-        for (int i = 0; i < songList.size(); i++)
+        YamlSequence trackList = yaml.value("tracks").asSequence();
+        for (int i = 0; i < trackList.size(); i++)
         {
             try
             {
-                ret.addSong(Song.fromYaml(songList.yamlMapping(i)));
+                ret.addTrack(Track.fromYaml(trackList.yamlMapping(i)));
             } catch (MalformedURLException ex)
             {
                 Logger.getLogger(Playlist.class.getName()).log(Level.SEVERE, null, ex);
@@ -73,10 +73,10 @@ public class Playlist implements Consumer<Song>
         return ret;
     }
 
-    public void addSong(Song song)
+    public void addTrack(Track track)
     {
-        song.setKept(true);
-        songs.add(song);
+        track.setKept(true);
+        tracks.add(track);
     }
 
     public String getName()
@@ -84,17 +84,17 @@ public class Playlist implements Consumer<Song>
         return name;
     }
 
-    public List<Song> getSongs()
+    public List<Track> getTracks()
     {
-        return songs;
+        return tracks;
     }
 
-    public Song getNextSong()
+    public Track getNextTrack()
     {
-        Song ret;
+        Track ret;
 
-        // copy the song list
-        List<Song> toShuffle = new LinkedList<>(songs);
+        // copy the track list
+        List<Track> toShuffle = new LinkedList<>(tracks);
 
         // remove play history from candidates, latest first, unless we'd have less than 2 options
         for (int i = playHistory.size() - 1; i >= 0; i--)
@@ -114,9 +114,9 @@ public class Playlist implements Consumer<Song>
     }
 
     @Override
-    public void accept(Song t)
+    public void accept(Track t)
     {
-        addSong(t);
+        addTrack(t);
     }
 
 }
diff --git a/src/main/java/moe/nekojimi/chords/QueueManager.java b/src/main/java/moe/nekojimi/chords/QueueManager.java
index d67d5d5..613a1e6 100644
--- a/src/main/java/moe/nekojimi/chords/QueueManager.java
+++ b/src/main/java/moe/nekojimi/chords/QueueManager.java
@@ -26,11 +26,11 @@ import java.util.function.Consumer;
  *
  * @author jimj316
  */
-public class QueueManager implements Consumer<Song>
+public class QueueManager implements Consumer<Track>
 {
 
-    private Song restartingSong = null;
-    private final PriorityQueue<Song> jukeboxQueue = new PriorityQueue<>();
+    private Track restartingTrack = null;
+    private final PriorityQueue<Track> jukeboxQueue = new PriorityQueue<>();
     private Playlist playlist;
     private MusicHandler handler;
 
@@ -40,30 +40,30 @@ public class QueueManager implements Consumer<Song>
     }
 
     @Override
-    public void accept(Song t)
+    public void accept(Track t)
     {
         jukeboxQueue.add(t);
 
-        if (!handler.isPlaying() || handler.getCurrentSong() == null)
+        if (!handler.isPlaying() || handler.getCurrentTrack() == null)
             handler.playNext();
 
-        if (handler.isPlaying() != (handler.getCurrentSong() == null))
+        if (handler.isPlaying() != (handler.getCurrentTrack() == null))
             System.err.println("WARNING: handler isPlaying violates contract! Something dumb going on!");
     }
 
     /**
-     * Called by the music handler when the current song has ended, or if
+     * Called by the music handler when the current track has ended, or if
      * playNext is called with nothing playing.
      *
      * @return the next track to play, or null to stop playing.
      */
-    public Song nextSongNeeded()
+    public Track nextTrackNeeded()
     {
-        // if we're restarting the current song: store, clear, and return it
-        if (restartingSong != null)
+        // if we're restarting the current track: store, clear, and return it
+        if (restartingTrack != null)
         {
-            Song ret = restartingSong;
-            restartingSong = null;
+            Track ret = restartingTrack;
+            restartingTrack = null;
             return ret;
         }
         // if there's anything in the queue, play that first
@@ -74,7 +74,7 @@ public class QueueManager implements Consumer<Song>
         // otherwise if there's a playlist, shuffle from that
         else if (playlist != null)
         {
-            return playlist.getNextSong();
+            return playlist.getNextTrack();
         }
         // otherwise stop playing
         else
@@ -86,27 +86,27 @@ public class QueueManager implements Consumer<Song>
         return handler;
     }
 
-    public void addSong(Song song)
+    public void addTrack(Track track)
     {
-        System.out.println("Song added to queue: " + song.getLocation().getAbsolutePath());
-        jukeboxQueue.add(song);
+        System.out.println("Track added to queue: " + track.getLocation().getAbsolutePath());
+        jukeboxQueue.add(track);
 
     }
 
-    public boolean removeSong(int i)
+    public boolean removeTrack(int i)
     {
         try
         {
-            return jukeboxQueue.remove((Song) jukeboxQueue.toArray()[i]);
+            return jukeboxQueue.remove((Track) jukeboxQueue.toArray()[i]);
         } catch (ArrayIndexOutOfBoundsException ex)
         {
             return false;
         }
     }
 
-    public boolean removeSong(Song song)
+    public boolean removeTrack(Track track)
     {
-        return jukeboxQueue.remove(song);
+        return jukeboxQueue.remove(track);
     }
 
     public void setHandler(MusicHandler handler)
@@ -115,7 +115,7 @@ public class QueueManager implements Consumer<Song>
         handler.setQueueManager(this);
     }
 
-    public Queue<Song> getJukeboxQueue()
+    public Queue<Track> getJukeboxQueue()
     {
         return jukeboxQueue;
     }
@@ -130,10 +130,10 @@ public class QueueManager implements Consumer<Song>
         this.playlist = playlist;
     }
 
-    public boolean restartSong()
+    public boolean restartTrack()
     {
-        restartingSong = handler.getCurrentSong();
-        if (restartingSong != null)
+        restartingTrack = handler.getCurrentTrack();
+        if (restartingTrack != null)
         {
             handler.playNext();
             return true;
diff --git a/src/main/java/moe/nekojimi/chords/Song.java b/src/main/java/moe/nekojimi/chords/Track.java
similarity index 85%
rename from src/main/java/moe/nekojimi/chords/Song.java
rename to src/main/java/moe/nekojimi/chords/Track.java
index 1733e58..46a7944 100644
--- a/src/main/java/moe/nekojimi/chords/Song.java
+++ b/src/main/java/moe/nekojimi/chords/Track.java
@@ -19,7 +19,7 @@ import java.util.List;
  *
  * @author jimj316
  */
-public class Song implements Comparable<Song>
+public class Track implements Comparable<Track>
 {
     private String title;
     private String artist;
@@ -33,7 +33,7 @@ public class Song implements Comparable<Song>
     private double progress = -1;
     private double eta = -1;
 
-    public Song(URL url)
+    public Track(URL url)
     {
         this.url = url;
     }
@@ -57,24 +57,24 @@ public class Song implements Comparable<Song>
                 .build();
     }
 
-    public static Song fromYaml(YamlMapping map) throws MalformedURLException
+    public static Track fromYaml(YamlMapping map) throws MalformedURLException
     {
-        Song song = new Song(new URL(map.string("url")));
-        song.setArtist(map.string("artist"));
-        song.setTitle(map.string("title"));
-        song.setLocation(new File(map.string("location")));
-        song.setNumber(map.integer("num"));
-        song.setKept(Boolean.parseBoolean(map.string("kept")));
-//        song.setRequestedBy(map.string("requestedBy"));
-//        song.setRequestedIn(map.string("requestedIn"));
+        Track track = new Track(new URL(map.string("url")));
+        track.setArtist(map.string("artist"));
+        track.setTitle(map.string("title"));
+        track.setLocation(new File(map.string("location")));
+        track.setNumber(map.integer("num"));
+        track.setKept(Boolean.parseBoolean(map.string("kept")));
+//        track.setRequestedBy(map.string("requestedBy"));
+//        track.setRequestedIn(map.string("requestedIn"));
 
         List<Format> formats = new ArrayList<>();
         YamlSequence formatSeq = map.yamlSequence("formats");
         for (int i = 0; i < formats.size(); i++)
             formats.add(Format.fromYaml(formatSeq.yamlMapping(i)));
-        song.setFormats(formats);
+        track.setFormats(formats);
 
-        return song;
+        return track;
     }
 
     public boolean isDownloaded()
@@ -199,7 +199,7 @@ public class Song implements Comparable<Song>
     }
 
     @Override
-    public int compareTo(Song o)
+    public int compareTo(Track o)
     {
         return Integer.compare(number, o.number);
     }
diff --git a/src/main/java/moe/nekojimi/chords/TrackPlayer.java b/src/main/java/moe/nekojimi/chords/TrackPlayer.java
index a77b445..e622dd4 100644
--- a/src/main/java/moe/nekojimi/chords/TrackPlayer.java
+++ b/src/main/java/moe/nekojimi/chords/TrackPlayer.java
@@ -31,9 +31,9 @@ public class TrackPlayer implements Closeable
 
     private boolean arrayErr = false; // supresses ArrayIndexOutOfBoundsException after the first time, to prevent spam
 
-    public TrackPlayer(Song song) throws UnsupportedAudioFileException, IOException
+    public TrackPlayer(Track track) throws UnsupportedAudioFileException, IOException
     {
-        AudioInputStream in = AudioSystem.getAudioInputStream(song.getLocation());
+        AudioInputStream in = AudioSystem.getAudioInputStream(track.getLocation());
         AudioFormat decodedFormat = AudioSendHandler.INPUT_FORMAT;
         input = AudioSystem.getAudioInputStream(decodedFormat, in);
         fillBuffer(false);
diff --git a/src/main/java/moe/nekojimi/chords/SongRequest.java b/src/main/java/moe/nekojimi/chords/TrackRequest.java
similarity index 78%
rename from src/main/java/moe/nekojimi/chords/SongRequest.java
rename to src/main/java/moe/nekojimi/chords/TrackRequest.java
index 7979a1e..1ec54db 100644
--- a/src/main/java/moe/nekojimi/chords/SongRequest.java
+++ b/src/main/java/moe/nekojimi/chords/TrackRequest.java
@@ -26,7 +26,7 @@ import moe.nekojimi.musicsearcher.Result;
  *
  * @author jimj316
  */
-public class SongRequest
+public class TrackRequest
 {
     private Invocation invocation;
 
@@ -37,7 +37,7 @@ public class SongRequest
 
     private Result result;
 
-    private final List<Song> songs = new ArrayList<>();
+    private final List<Track> tracks = new ArrayList<>();
 
     private String requestedBy;
     private String requestedIn;
@@ -115,19 +115,19 @@ public class SongRequest
         this.url = url;
     }
 
-    public List<Song> getSongs()
+    public List<Track> getTracks()
     {
-        return songs;
+        return tracks;
     }
 
-    public void addSong(Song song)
+    public void addTrack(Track track)
     {
-        songs.add(song);
+        tracks.add(track);
     }
 
-    public void clearSongs()
+    public void clearTracks()
     {
-        songs.clear();
+        tracks.clear();
     }
 
     public String getRequestedBy()
@@ -140,4 +140,23 @@ public class SongRequest
         return requestedIn;
     }
 
+    public String toString()
+    {
+        String trackName;
+        if (tracks.isEmpty())
+            trackName = "Request";
+        else
+        {
+            trackName = tracks.get(1).toString();
+            if (tracks.size() > 1)
+                trackName += " & " + (tracks.size() - 1) + " more tracks";
+        }
+
+        String requestName = "";
+        if (!requestedBy.isEmpty())
+            requestName = "for " + requestedBy;
+
+        return (trackName + " " + requestName).trim();
+    }
+
 }
diff --git a/src/main/java/moe/nekojimi/chords/commands/HelpCommand.java b/src/main/java/moe/nekojimi/chords/commands/HelpCommand.java
index 9ce2d21..bec4fc9 100644
--- a/src/main/java/moe/nekojimi/chords/commands/HelpCommand.java
+++ b/src/main/java/moe/nekojimi/chords/commands/HelpCommand.java
@@ -34,10 +34,10 @@ public class HelpCommand extends Command
                 + "!leave                - Leaves the current voice channel\n"
                 + "!play <URL>           - Downloads the track at that URL and adds it to the queue.\n"
                 + "!play <Search>        - Searches for a track and displays a selection menu.\n"
-                + "!queue                - Show the songs currently playing and the current queue.\n"
-                + "!remove <Index>       - Remove the song at position <Index> from the queue.\n"
-                + "!skip                 - Skip the current song and play the next one.\n"
-                + "!restart              - Try playing the current song again in case it goes wrong.\n";
+                + "!queue                - Show the tracks currently playing and the current queue.\n"
+                + "!remove <Index>       - Remove the track at position <Index> from the queue.\n"
+                + "!skip                 - Skip the current track and play the next one.\n"
+                + "!restart              - Try playing the current track again in case it goes wrong.\n";
 //        for (String key: commands.keySet())
 //        {
 //            help += "!" + key + ":"
diff --git a/src/main/java/moe/nekojimi/chords/commands/PlayCommand.java b/src/main/java/moe/nekojimi/chords/commands/PlayCommand.java
index f028ffc..cca433b 100644
--- a/src/main/java/moe/nekojimi/chords/commands/PlayCommand.java
+++ b/src/main/java/moe/nekojimi/chords/commands/PlayCommand.java
@@ -22,7 +22,7 @@ import java.util.List;
 import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.TimeUnit;
 import moe.nekojimi.chords.Chords;
-import moe.nekojimi.chords.SongRequest;
+import moe.nekojimi.chords.TrackRequest;
 import moe.nekojimi.musicsearcher.Query;
 import moe.nekojimi.musicsearcher.Result;
 
@@ -45,7 +45,7 @@ public class PlayCommand extends Command
     @Override
     public void call(Invocation invocation)
     {
-        SongRequest request = new SongRequest();
+        TrackRequest request = new TrackRequest();
         request.setInvocation(invocation);
         try
         {
@@ -67,11 +67,11 @@ public class PlayCommand extends Command
                         Result result = request.getSearchResults().get(index - 1);
                         request.setResult(result);
                         bot.queueDownload(request);
-//                        event.getChannel().sendMessage("Song removed.").queue();
+//                        event.getChannel().sendMessage("Track removed.").queue();
                     } else if (size > 1)
                         invocation.respond("That's not a number between 1 and " + size + "!");
                     else if (size == 1)
-                        invocation.respond("There's only one song and that's not one of them!");
+                        invocation.respond("There's only one track and that's not one of them!");
 
                     return;
                 } catch (NumberFormatException nfx)
diff --git a/src/main/java/moe/nekojimi/chords/commands/QueueCommand.java b/src/main/java/moe/nekojimi/chords/commands/QueueCommand.java
index d56dd53..911100e 100644
--- a/src/main/java/moe/nekojimi/chords/commands/QueueCommand.java
+++ b/src/main/java/moe/nekojimi/chords/commands/QueueCommand.java
@@ -20,7 +20,7 @@ import java.util.List;
 import java.util.Queue;
 import moe.nekojimi.chords.Downloader;
 import moe.nekojimi.chords.Chords;
-import moe.nekojimi.chords.Song;
+import moe.nekojimi.chords.Track;
 
 public class QueueCommand extends Command
 {
@@ -36,19 +36,19 @@ public class QueueCommand extends Command
         String message = ">>> ";
         int i = 1;
 
-        final Song currentSong = bot.getMusicHandler().getCurrentSong();
-        if (currentSong != null)
-            message += ":notes: **Now playing: " + currentSong + "**\n";
+        final Track currentTrack = bot.getMusicHandler().getCurrentTrack();
+        if (currentTrack != null)
+            message += ":notes: **Now playing: " + currentTrack + "**\n";
         else
             message += ":mute: **Not playing anything right now.**\n";
 
-        final Queue<Song> songQueue = bot.getQueueManager().getJukeboxQueue();
-        if (!songQueue.isEmpty())
+        final Queue<Track> trackQueue = bot.getQueueManager().getJukeboxQueue();
+        if (!trackQueue.isEmpty())
         {
             message += "__Ready to play:__\n";
-            for (Song song : songQueue)
+            for (Track track : trackQueue)
             {
-                message += ":bread: **" + (i) + ":** " + song + "\n";
+                message += ":bread: **" + (i) + ":** " + track + "\n";
                 i++;
             }
         }
@@ -59,12 +59,12 @@ public class QueueCommand extends Command
             message += "__Downloading:__\n";
             for (Downloader.DownloadTask task : downloadQueue)
             {
-                message += ":inbox_tray: **" + (i) + ":** " + task.getSong() + "\n";
+                message += ":inbox_tray: **" + (i) + ":** " + task.getTrack() + "\n";
                 i++;
             }
         }
 
-        if (downloadQueue.isEmpty() && songQueue.isEmpty())
+        if (downloadQueue.isEmpty() && trackQueue.isEmpty())
             message += ":mailbox_with_no_mail: The track queue is empty.";
         // :inbox_tray:
         invocation.respond(message);
diff --git a/src/main/java/moe/nekojimi/chords/commands/RemoveCommand.java b/src/main/java/moe/nekojimi/chords/commands/RemoveCommand.java
index 7afe6d4..d940988 100644
--- a/src/main/java/moe/nekojimi/chords/commands/RemoveCommand.java
+++ b/src/main/java/moe/nekojimi/chords/commands/RemoveCommand.java
@@ -32,14 +32,14 @@ public class RemoveCommand extends Command
         try
         {
             int i = Integer.parseInt(invocation.getArgs().get(0));
-            boolean removed = bot.getQueueManager().removeSong(i - 1);
+            boolean removed = bot.getQueueManager().removeTrack(i - 1);
             final int size = bot.getQueueManager().getJukeboxQueue().size();
             if (removed)
-                invocation.respond("Song removed.");
+                invocation.respond("Track removed.");
             else if (size > 1)
                 invocation.respond("That's not a number between 1 and " + size + "!");
             else if (size == 1)
-                invocation.respond("There's only one song to remove and that's not one of them!");
+                invocation.respond("There's only one track to remove and that's not one of them!");
 
         } catch (NumberFormatException ex)
         {
diff --git a/src/main/java/moe/nekojimi/chords/commands/RestartCommand.java b/src/main/java/moe/nekojimi/chords/commands/RestartCommand.java
index e55d685..d39c7ac 100644
--- a/src/main/java/moe/nekojimi/chords/commands/RestartCommand.java
+++ b/src/main/java/moe/nekojimi/chords/commands/RestartCommand.java
@@ -30,9 +30,9 @@ public class RestartCommand extends Command
     public void call(Invocation invocation)
     {
         // TODO: this needs to clear the current data queue
-        boolean ok = bot.getQueueManager().restartSong();
+        boolean ok = bot.getQueueManager().restartTrack();
         if (ok)
-            invocation.respond("Restarted current song!");
+            invocation.respond("Restarted current track!");
         else
             invocation.respond("Cannot restart!");
     }
diff --git a/src/main/java/moe/nekojimi/chords/commands/SkipCommand.java b/src/main/java/moe/nekojimi/chords/commands/SkipCommand.java
index 90e69f7..835d8fb 100644
--- a/src/main/java/moe/nekojimi/chords/commands/SkipCommand.java
+++ b/src/main/java/moe/nekojimi/chords/commands/SkipCommand.java
@@ -29,11 +29,11 @@ public class SkipCommand extends Command
     @Override
     public void call(Invocation invocation)
     {
-        boolean ok = bot.getMusicHandler().nextSong(true);
+        boolean ok = bot.getMusicHandler().nextTrack(true);
         if (ok)
-            invocation.respond("Skipped to next song!");
+            invocation.respond("Skipped to next track!");
         else
-            invocation.respond("There's no more songs!");
+            invocation.respond("There's no more tracks!");
     }
 
 }