From 155bdfdffbae68f85cc971eb96ea432a6f4a736d Mon Sep 17 00:00:00 2001 From: Matt Kohls Date: Sun, 14 Oct 2018 20:21:26 -0400 Subject: Adding ability for sounds to be added/removed on the fly This adds a watcher to the directory named in localAudio (currently doesn't check anything that may be in a child directory). Whenever a file is created/deleted/renamed, it has the LocalAudioManager update its sounds so they can be played. --- .../java/soundchan/BotListener/BotListener.java | 13 +++++ .../soundchan/BotListener/DirectoryWatcher.java | 62 ++++++++++++++++++++++ src/main/java/soundchan/LocalAudioManager.java | 20 ++++--- 3 files changed, 89 insertions(+), 6 deletions(-) create mode 100644 src/main/java/soundchan/BotListener/DirectoryWatcher.java diff --git a/src/main/java/soundchan/BotListener/BotListener.java b/src/main/java/soundchan/BotListener/BotListener.java index 9bcccfe..9177385 100644 --- a/src/main/java/soundchan/BotListener/BotListener.java +++ b/src/main/java/soundchan/BotListener/BotListener.java @@ -23,6 +23,10 @@ import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Properties; +import java.util.concurrent.Executor; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; public class BotListener extends ListenerAdapter{ @@ -32,6 +36,8 @@ public class BotListener extends ListenerAdapter{ private final AudioPlayerManager playerManager; private final Map musicManagers; private BotListenerHelpers helper = new BotListenerHelpers(); + private ExecutorService executorService; + private Future future; // From configuration file private static String followingUser; @@ -45,6 +51,8 @@ public class BotListener extends ListenerAdapter{ AudioSourceManagers.registerRemoteSources(playerManager); AudioSourceManagers.registerLocalSource(playerManager); + executorService = Executors.newSingleThreadExecutor(); + loadProperties(properties); } @@ -67,6 +75,11 @@ public class BotListener extends ListenerAdapter{ } else localManager = new LocalAudioManager(localFilePath); + + DirectoryWatcher directoryWatcher = new DirectoryWatcher(localManager, localFilePath); + future = executorService.submit(directoryWatcher); + executorService.shutdown(); + } private synchronized GuildMusicManager getGuildAudioPlayer() { diff --git a/src/main/java/soundchan/BotListener/DirectoryWatcher.java b/src/main/java/soundchan/BotListener/DirectoryWatcher.java new file mode 100644 index 0000000..7d63bd1 --- /dev/null +++ b/src/main/java/soundchan/BotListener/DirectoryWatcher.java @@ -0,0 +1,62 @@ +package soundchan.BotListener; + +import soundchan.LocalAudioManager; + +import java.io.File; +import java.io.IOException; +import java.nio.file.*; + +import static java.nio.file.StandardWatchEventKinds.ENTRY_CREATE; +import static java.nio.file.StandardWatchEventKinds.ENTRY_DELETE; +import static java.nio.file.StandardWatchEventKinds.ENTRY_MODIFY; + +public class DirectoryWatcher implements Runnable { + + private LocalAudioManager localAudioManager; + private Path soundDir; + private WatchService watchService; + private WatchKey watchKey; + + @SuppressWarnings("unchecked") + static WatchEvent cast(WatchEvent event) { + return (WatchEvent) event; + } + + public DirectoryWatcher(LocalAudioManager audioManager, String filepath) { + this.localAudioManager = audioManager; + this.soundDir = new File(filepath).toPath(); + try { + this.watchService = FileSystems.getDefault().newWatchService(); + this.watchKey = soundDir.register(watchService, ENTRY_CREATE, ENTRY_DELETE, ENTRY_MODIFY); + } catch(IOException e) { + System.out.println("Error setting up watcher for " + filepath); + } + } + + /** + * Called by an executor, checks for changes in the directory + */ + public void run() { + try { + while(true) { + WatchKey key = watchService.take(); + if(this.watchKey != key) { + System.out.println("Error with WatchKey"); + continue; + } + + for(WatchEvent event : key.pollEvents()) { + WatchEvent pathEvent = cast(event); + //System.out.format("%s: %s\n", pathEvent.kind(), soundDir.resolve(pathEvent.context())); + localAudioManager.UpdateFiles(); + } + + if(!key.reset()) { + break; + } + } + } catch(InterruptedException e) { + return; + } + } +} diff --git a/src/main/java/soundchan/LocalAudioManager.java b/src/main/java/soundchan/LocalAudioManager.java index 4b16850..306b8dd 100644 --- a/src/main/java/soundchan/LocalAudioManager.java +++ b/src/main/java/soundchan/LocalAudioManager.java @@ -20,8 +20,7 @@ public class LocalAudioManager { public LocalAudioManager(String filepath_in){ filepath = filepath_in; - filenameDict = new HashMap<>(); - PopulateFiles(); + filenameDict = PopulateFiles(); } /** @@ -31,9 +30,8 @@ public class LocalAudioManager { */ public LocalAudioManager(String filepath_in, String userSoundFile) { filepath = filepath_in; - filenameDict = new HashMap<>(); + filenameDict = PopulateFiles(); usernameDict = new HashMap<>(); - PopulateFiles(); MapUserAudio(userSoundFile); } @@ -87,16 +85,26 @@ public class LocalAudioManager { channel.sendMessage(toPrint).queue(); } - private void PopulateFiles(){ + /** + * Updates the map of sound files + */ + public void UpdateFiles() { + filenameDict = PopulateFiles(); + } + + private Map PopulateFiles(){ File folder = new File(filepath); File[] listOfFiles = folder.listFiles(); + Map fileDict = new HashMap<>(); + for (File file : listOfFiles) { if (file.isFile()) { String filename = file.getName(); - filenameDict.put(filename.substring(0, filename.indexOf('.')), filename); + fileDict.put(filename.substring(0, filename.indexOf('.')), filename); } } + return fileDict; } /** -- cgit v1.2.3