refactor: remove convoluted TrackLoader and LoadableSongs abstraction
BREAKING CHANGE: removed TrackLoader amd LoadableSongs
This commit is contained in:
1 parent
0db751af44
commit
2aa75ce0fc
10 files changed
+9
-385
No files matched your search
@@ -19,7 +19,6 @@ import me.bobert.netneutrality.core.LogHandler;
|
||||
import me.bobert.netneutrality.core.context.CommandContext;
|
||||
import me.bobert.netneutrality.db.GSettings;
|
||||
import me.bobert.netneutrality.exceptions.CommandExecutionException;
|
||||
import me.bobert.netneutrality.music.loadable.LoadableSong;
|
||||
import me.bobert.netneutrality.music.source.UdioAudioSourceManager;
|
||||
import me.bobert.netneutrality.thread.MusicPlayerAutoDisconnectThread;
|
||||
import me.bobert.netneutrality.thread.ThreadManager;
|
||||
@@ -30,8 +29,6 @@ import net.dv8tion.jda.api.entities.channel.middleman.MessageChannel;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
@@ -48,7 +45,6 @@ public class MusicManager {
|
||||
private final Guild guild;
|
||||
private final AudioPlayer player;
|
||||
private final TrackScheduler scheduler;
|
||||
private TrackLoader lastTrackLoader;
|
||||
private ScheduledFuture<?> autoDisconnectThread;
|
||||
private final int baseVolume;
|
||||
|
||||
@@ -126,10 +122,6 @@ public class MusicManager {
|
||||
return guild;
|
||||
}
|
||||
|
||||
public void stopLoading() {
|
||||
lastTrackLoader.stopLoading();
|
||||
}
|
||||
|
||||
public synchronized void leave() {
|
||||
if (guild != null && guild.getAudioManager().getConnectedChannel() != null) {
|
||||
logger.debug("Guild {}: leaving voice channel {}", guild.getId(), guild.getAudioManager().getConnectedChannel().getId());
|
||||
@@ -152,16 +144,9 @@ public class MusicManager {
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized void play(String url, CommandContext context, boolean needToBeConnected, boolean silent) {
|
||||
logger.debug("Guild {}: request to play '{}' by user {}", guild.getId(), url, context.getGuildUser().getId());
|
||||
public synchronized void play(String query, CommandContext context, boolean needToBeConnected, boolean silent) {
|
||||
logger.debug("Guild {}: request to play '{}' by user {}", guild.getId(), query, context.getGuildUser().getId());
|
||||
|
||||
List<LoadableSong> toLoad = new ArrayList<>();
|
||||
toLoad.add(new LoadableSong(null, url, null));
|
||||
|
||||
play(toLoad, context, needToBeConnected, silent);
|
||||
}
|
||||
|
||||
public void play(List<LoadableSong> songs, CommandContext context, boolean needToBeConnected, boolean silent) {
|
||||
Member member = context.getGuildUser();
|
||||
MessageChannel channel = context.getChannel();
|
||||
|
||||
@@ -189,10 +174,14 @@ public class MusicManager {
|
||||
scheduler.attachTextChannel(channel);
|
||||
}
|
||||
|
||||
TrackLoader loader = new TrackLoader(this, context, playerManager, silent);
|
||||
lastTrackLoader = loader;
|
||||
SourceFinder.AudioSourceType type = SourceFinder.getSource(query);
|
||||
String identifier = SourceFinder.getIdentifier(query);
|
||||
|
||||
loader.loadAllSongs(songs);
|
||||
if (identifier != null) {
|
||||
TrackLoadingHandler loadingHandler = new TrackLoadingHandler(context, this, identifier, type, silent);
|
||||
|
||||
playerManager.loadItemOrdered(this, identifier, loadingHandler);
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized void stopTrack() {
|
||||
|
||||
@@ -138,7 +138,6 @@ public class QueueManager {
|
||||
}
|
||||
|
||||
public CommandExecutionResult clearQueue() {
|
||||
scheduler.getMusicManager().stopLoading();
|
||||
scheduler.getMusicManager().leave();
|
||||
|
||||
if (queue.isEmpty()) {
|
||||
|
||||
@@ -1,126 +0,0 @@
|
||||
package me.bobert.netneutrality.music;
|
||||
/*
|
||||
* Copyright (c) anthorob
|
||||
*
|
||||
* https://discord.gg/qUa6zNFZsd
|
||||
*/
|
||||
|
||||
import com.sedmelluq.discord.lavaplayer.player.AudioPlayerManager;
|
||||
import me.bobert.netneutrality.core.LogHandler;
|
||||
import me.bobert.netneutrality.core.context.CommandContext;
|
||||
import me.bobert.netneutrality.music.loadable.CachedSource;
|
||||
import me.bobert.netneutrality.music.loadable.LoadableMusicSource;
|
||||
import me.bobert.netneutrality.music.loadable.LoadableSong;
|
||||
import me.bobert.netneutrality.thread.ThreadManager;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class TrackLoader implements Runnable {
|
||||
|
||||
private final Logger logger = LogManager.getLogger(TrackLoader.class);
|
||||
private final CommandContext context;
|
||||
private final MusicManager musicManager;
|
||||
private final AudioPlayerManager audioPlayerManager;
|
||||
private TrackLoadingHandler lastLoadingHandler;
|
||||
private List<LoadableSong> songs;
|
||||
private LoadableMusicSource source;
|
||||
private int numberOfTracksLoaded;
|
||||
private int totalNumberOfTracks;
|
||||
private boolean loadingDisabled = false;
|
||||
private boolean silent;
|
||||
private final Object sync = new Object();
|
||||
|
||||
public TrackLoader(MusicManager musicManager, CommandContext context, AudioPlayerManager playerManager, boolean silent) {
|
||||
this.musicManager = musicManager;
|
||||
this.context = context;
|
||||
this.audioPlayerManager = playerManager;
|
||||
this.silent = silent;
|
||||
}
|
||||
|
||||
public void loadAllSongs(List<LoadableSong> songs) {
|
||||
this.songs = songs;
|
||||
if (songs.size() > 1) {
|
||||
this.silent = true;
|
||||
}
|
||||
|
||||
ThreadManager.getMusicExecutor().submit(this);
|
||||
}
|
||||
|
||||
public void loadAllSongs(CachedSource cachedSource) {
|
||||
this.source = cachedSource.getSource();
|
||||
|
||||
loadAllSongs(cachedSource.getSongs());
|
||||
}
|
||||
|
||||
public void stopLoading() {
|
||||
loadingDisabled = true;
|
||||
|
||||
if (lastLoadingHandler != null) {
|
||||
lastLoadingHandler.stopLoading();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
List<LoadableSong> copy = new ArrayList<>(songs);
|
||||
|
||||
for (LoadableSong song : songs) {
|
||||
if (loadingDisabled) {
|
||||
copy.remove(song);
|
||||
break;
|
||||
}
|
||||
|
||||
SourceFinder.AudioSourceType type = SourceFinder.getSource(song.name());
|
||||
String identifier = SourceFinder.getIdentifier(song.name());
|
||||
|
||||
if (identifier != null) {
|
||||
TrackLoadingHandler loadingHandler = new TrackLoadingHandler(context, musicManager, identifier, type, silent);
|
||||
loadingHandler.useCallbackOnLoad(success -> {
|
||||
|
||||
synchronized (sync) {
|
||||
if (success) {
|
||||
numberOfTracksLoaded++;
|
||||
}
|
||||
|
||||
totalNumberOfTracks++;
|
||||
|
||||
logger.debug("callback notify; total={}, loaded={}", totalNumberOfTracks, numberOfTracksLoaded);
|
||||
sync.notify();
|
||||
}
|
||||
|
||||
});
|
||||
lastLoadingHandler = loadingHandler;
|
||||
|
||||
audioPlayerManager.loadItemOrdered(this, identifier, loadingHandler);
|
||||
} else {
|
||||
copy.remove(song);
|
||||
|
||||
if (songs.size() == 1) {
|
||||
context.replyToMessage("No source found to play the given url");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
synchronized (sync) {
|
||||
while (!(copy.size() == totalNumberOfTracks)) {
|
||||
logger.debug("waiting for load; size={}, total={}, loaded={}", songs.size(), totalNumberOfTracks, numberOfTracksLoaded);
|
||||
sync.wait();
|
||||
}
|
||||
|
||||
//TODO: logic
|
||||
if (copy.size() > 1 && source != null && !loadingDisabled) {
|
||||
context.replyToMessage("Loaded %d of %d tracks from online source", numberOfTracksLoaded, totalNumberOfTracks);
|
||||
}
|
||||
}
|
||||
} catch (InterruptedException exception) {
|
||||
stopLoading();
|
||||
context.replyToMessage("Loading of tracks was interrupted due to an exception");
|
||||
LogHandler.log(exception);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -17,16 +17,12 @@ import net.dv8tion.jda.api.entities.Guild;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public class TrackLoadingHandler implements AudioLoadResultHandler {
|
||||
private final Logger logger = LogManager.getLogger(TrackLoadingHandler.class);
|
||||
|
||||
private final String identifier;
|
||||
private final SourceFinder.AudioSourceType type;
|
||||
private final boolean silent;
|
||||
private Consumer<Boolean> loadConsumer;
|
||||
private boolean loadingDisabled = false;
|
||||
private final Guild guild;
|
||||
private final TrackScheduler scheduler;
|
||||
private final CommandContext context;
|
||||
@@ -40,24 +36,8 @@ public class TrackLoadingHandler implements AudioLoadResultHandler {
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
public synchronized void stopLoading() {
|
||||
logger.debug("Guild {}: stopped loading of new tracks", guild.getId());
|
||||
loadingDisabled = true;
|
||||
}
|
||||
|
||||
public void useCallbackOnLoad(Consumer<Boolean> consumer) {
|
||||
this.loadConsumer = consumer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void trackLoaded(AudioTrack audioTrack) {
|
||||
if (loadConsumer != null) {
|
||||
loadConsumer.accept(true);
|
||||
}
|
||||
|
||||
if (loadingDisabled)
|
||||
return;
|
||||
|
||||
context.deleteMessage();
|
||||
|
||||
logger.debug("Guild {}: track loaded: {}", guild.getId(), audioTrack.getIdentifier());
|
||||
@@ -70,13 +50,6 @@ public class TrackLoadingHandler implements AudioLoadResultHandler {
|
||||
|
||||
@Override
|
||||
public void playlistLoaded(AudioPlaylist playlist) {
|
||||
if (loadConsumer != null) {
|
||||
loadConsumer.accept(true);
|
||||
}
|
||||
|
||||
if (loadingDisabled)
|
||||
return;
|
||||
|
||||
logger.debug("Guild {}: playlist loaded: {}", guild.getId(), identifier);
|
||||
|
||||
if (!playlist.getTracks().isEmpty()) {
|
||||
@@ -96,10 +69,6 @@ public class TrackLoadingHandler implements AudioLoadResultHandler {
|
||||
}
|
||||
|
||||
for (AudioTrack track : playlist.getTracks()) {
|
||||
if (loadingDisabled) {
|
||||
break;
|
||||
}
|
||||
|
||||
scheduler.getQueueManager().queue(track, context.getGuildUser());
|
||||
}
|
||||
}
|
||||
@@ -108,18 +77,12 @@ public class TrackLoadingHandler implements AudioLoadResultHandler {
|
||||
|
||||
@Override
|
||||
public void noMatches() {
|
||||
if (loadConsumer != null)
|
||||
loadConsumer.accept(false);
|
||||
|
||||
if (!silent)
|
||||
context.replyToMessage("No matches found");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadFailed(FriendlyException e) {
|
||||
if (loadConsumer != null)
|
||||
loadConsumer.accept(false);
|
||||
|
||||
logger.debug("Guild {}: load failed for identifier {}", guild.getId(), identifier, e);
|
||||
LogHandler.log(e);
|
||||
|
||||
|
||||
@@ -1,41 +0,0 @@
|
||||
package me.bobert.netneutrality.music.loadable;
|
||||
/*
|
||||
* Copyright (c) anthorob
|
||||
*
|
||||
* https://discord.gg/qUa6zNFZsd
|
||||
*/
|
||||
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class AppleMostPlayed implements LoadableMusicSource {
|
||||
@Override
|
||||
public String url() {
|
||||
return "https://rss.applemarketingtools.com/api/v2/ca/music/most-played/25/songs.json";
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<LoadableSong> parse(JSONObject obj) {
|
||||
List<LoadableSong> songs = new ArrayList<>();
|
||||
JSONArray results = obj.getJSONObject("feed").getJSONArray("results");
|
||||
|
||||
results.forEach(o -> {
|
||||
JSONObject song = (JSONObject) o;
|
||||
String artist = song.getString("artistName");
|
||||
String songName = song.getString("name");
|
||||
String artwork = song.getString("artworkUrl100");
|
||||
|
||||
songs.add(new LoadableSong(artist, songName, artwork));
|
||||
});
|
||||
|
||||
return songs;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getIdentifier() {
|
||||
return "apple";
|
||||
}
|
||||
}
|
||||
@@ -1,39 +0,0 @@
|
||||
package me.bobert.netneutrality.music.loadable;
|
||||
/*
|
||||
* Copyright (c) anthorob
|
||||
*
|
||||
* https://discord.gg/qUa6zNFZsd
|
||||
*/
|
||||
|
||||
|
||||
import java.time.OffsetDateTime;
|
||||
import java.util.List;
|
||||
|
||||
public class CachedSource {
|
||||
private final LoadableMusicSource source;
|
||||
private OffsetDateTime lastAccess;
|
||||
private final List<LoadableSong> songs;
|
||||
|
||||
protected CachedSource(LoadableMusicSource source, List<LoadableSong> songs) {
|
||||
this.source = source;
|
||||
this.lastAccess = OffsetDateTime.now();
|
||||
this.songs = songs;
|
||||
}
|
||||
|
||||
public List<LoadableSong> getSongs() {
|
||||
return songs;
|
||||
}
|
||||
|
||||
public OffsetDateTime getLastAccess() {
|
||||
return lastAccess;
|
||||
}
|
||||
|
||||
public LoadableMusicSource getSource() {
|
||||
return source;
|
||||
}
|
||||
|
||||
public void updateAccessTime() {
|
||||
this.lastAccess = OffsetDateTime.now();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,19 +0,0 @@
|
||||
package me.bobert.netneutrality.music.loadable;
|
||||
|
||||
/*
|
||||
* Copyright (c) anthorob
|
||||
*
|
||||
* https://discord.gg/qUa6zNFZsd
|
||||
*/
|
||||
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface LoadableMusicSource {
|
||||
String url();
|
||||
|
||||
List<LoadableSong> parse(JSONObject obj);
|
||||
|
||||
String getIdentifier();
|
||||
}
|
||||
@@ -1,18 +0,0 @@
|
||||
package me.bobert.netneutrality.music.loadable;
|
||||
/*
|
||||
* Copyright (c) anthorob
|
||||
*
|
||||
* https://discord.gg/qUa6zNFZsd
|
||||
*/
|
||||
|
||||
public record LoadableSong(String artist, String name, String artworkUrl) {
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "LoadableSong{" +
|
||||
"artist='" + artist + '\'' +
|
||||
", name='" + name + '\'' +
|
||||
", artworkUrl='" + artworkUrl + '\'' +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
@@ -1,57 +0,0 @@
|
||||
package me.bobert.netneutrality.music.loadable;
|
||||
/*
|
||||
* Copyright (c) anthorob
|
||||
*
|
||||
* https://discord.gg/qUa6zNFZsd
|
||||
*/
|
||||
|
||||
import me.bobert.netneutrality.http.WebModule;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.time.OffsetDateTime;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class LoadableSourceManager {
|
||||
|
||||
private final Logger logger = LogManager.getLogger(LoadableSourceManager.class);
|
||||
private static final Map<String, CachedSource> cache = new HashMap<>();
|
||||
|
||||
public CachedSource get(LoadableMusicSource source) {
|
||||
|
||||
if (cache.containsKey(source.getIdentifier())) {
|
||||
CachedSource cachedSource = cache.get(source.getIdentifier());
|
||||
|
||||
if (OffsetDateTime.now().isAfter(cachedSource.getLastAccess().plusHours(4))) {
|
||||
cachedSource.getSongs().clear();
|
||||
cachedSource.getSongs().addAll(loadFromUrl(source));
|
||||
cachedSource.updateAccessTime();
|
||||
}
|
||||
|
||||
return cachedSource;
|
||||
}
|
||||
|
||||
List<LoadableSong> songs = loadFromUrl(source);
|
||||
CachedSource newCachedSource = new CachedSource(source, songs);
|
||||
|
||||
cache.put(source.getIdentifier(), newCachedSource);
|
||||
return newCachedSource;
|
||||
}
|
||||
|
||||
private List<LoadableSong> loadFromUrl(LoadableMusicSource source) {
|
||||
WebModule web = new WebModule(source.url());
|
||||
JSONObject obj = web.request().getAsObject();
|
||||
|
||||
if (obj == null)
|
||||
return Collections.emptyList();
|
||||
|
||||
List<LoadableSong> songs = source.parse(obj);
|
||||
Collections.shuffle(songs);
|
||||
|
||||
return songs;
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user