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 From 266c900d573cc4b70683e290404af663eb3f66d0 Mon Sep 17 00:00:00 2001 From: Matt Kohls Date: Tue, 16 Oct 2018 17:58:38 -0400 Subject: Adding property setting for watching local sounds --- soundchan.properties.example | 16 +++++++++++----- src/main/java/soundchan/BotListener/BotListener.java | 14 +++++++------- 2 files changed, 18 insertions(+), 12 deletions(-) diff --git a/soundchan.properties.example b/soundchan.properties.example index 0655076..8780021 100644 --- a/soundchan.properties.example +++ b/soundchan.properties.example @@ -1,19 +1,25 @@ +// Example properties file for SoundChan +// +// Flag conditions are enabled with any of the following values: +// true, on, enable, yes, 1 +// any other string (or empty) will leave the condition disabled + + //The Bot Token you will have received from the discord developers page botToken=BOT_TOKEN_FROM_DISCORD //The local file path to the directory of your sounds. Don't forget to escape your slashes localFilePath=C:\\PATH\\TO\\SOUNDS\\DIRECTORY +//Flag for watching the sound directory for changes +watchLocalFilePath=FLAG_CONDITION + //The user for the followingUser=USERNAME -//Flag conditions are enabled with any of the following values: -// true, on, enable, yes, 1 -//any other string (or empty) will leave the condition disabled - //If you want SoundChan to play an audio file whit their name when a user joins the channel or have that information come from below file //This is a flag condition -audioOnUserJoin=on/off +audioOnUserJoin=FLAG_CONDITION //The file where users and sound clips are related, see usersound.properties.example for more info //If this is not set, it will default to usersounds.properties diff --git a/src/main/java/soundchan/BotListener/BotListener.java b/src/main/java/soundchan/BotListener/BotListener.java index 9177385..0dad6c0 100644 --- a/src/main/java/soundchan/BotListener/BotListener.java +++ b/src/main/java/soundchan/BotListener/BotListener.java @@ -36,7 +36,6 @@ 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 @@ -51,8 +50,6 @@ public class BotListener extends ListenerAdapter{ AudioSourceManagers.registerRemoteSources(playerManager); AudioSourceManagers.registerLocalSource(playerManager); - executorService = Executors.newSingleThreadExecutor(); - loadProperties(properties); } @@ -75,10 +72,13 @@ public class BotListener extends ListenerAdapter{ } else localManager = new LocalAudioManager(localFilePath); - - DirectoryWatcher directoryWatcher = new DirectoryWatcher(localManager, localFilePath); - future = executorService.submit(directoryWatcher); - executorService.shutdown(); + + if(settingEnableCheck(properties.getProperty("watchLocalFilePath"))) { + ExecutorService executorService = Executors.newSingleThreadExecutor(); + DirectoryWatcher directoryWatcher = new DirectoryWatcher(localManager, localFilePath); + future = executorService.submit(directoryWatcher); + executorService.shutdown(); + } } -- cgit v1.2.3 From 2375afc8d0db70f829288586f5076e7da8684a87 Mon Sep 17 00:00:00 2001 From: Matt Kohls Date: Tue, 16 Oct 2018 18:07:49 -0400 Subject: Adding comment about what PopulateFiles() does now --- src/main/java/soundchan/LocalAudioManager.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/main/java/soundchan/LocalAudioManager.java b/src/main/java/soundchan/LocalAudioManager.java index 306b8dd..036b38d 100644 --- a/src/main/java/soundchan/LocalAudioManager.java +++ b/src/main/java/soundchan/LocalAudioManager.java @@ -92,6 +92,10 @@ public class LocalAudioManager { filenameDict = PopulateFiles(); } + /** + * Creates a map of the sounds in the sound directory + * @return A map with the filename (without extension) is the key for the filename (with extension) + */ private Map PopulateFiles(){ File folder = new File(filepath); File[] listOfFiles = folder.listFiles(); -- cgit v1.2.3 From 5789f36ca27d9082a1266207453d43f4ed87ef6e Mon Sep 17 00:00:00 2001 From: Matt Kohls Date: Tue, 16 Oct 2018 19:09:12 -0400 Subject: Adding in watcher for changes to user sound file --- soundchan.properties.example | 4 ++ .../java/soundchan/BotListener/BotListener.java | 15 +++-- .../soundchan/BotListener/UserSoundWatcher.java | 69 ++++++++++++++++++++++ src/main/java/soundchan/LocalAudioManager.java | 28 ++++++--- 4 files changed, 105 insertions(+), 11 deletions(-) create mode 100644 src/main/java/soundchan/BotListener/UserSoundWatcher.java diff --git a/soundchan.properties.example b/soundchan.properties.example index 8780021..b600032 100644 --- a/soundchan.properties.example +++ b/soundchan.properties.example @@ -24,3 +24,7 @@ audioOnUserJoin=FLAG_CONDITION //The file where users and sound clips are related, see usersound.properties.example for more info //If this is not set, it will default to usersounds.properties userAudioFilePath=C:\\PATH\\TO\\USER\\SOUND\\FILE + +//Flag for watching the user sound file for changes +//If audioOnUserJoin is not enabled, then this will do nothing +watchUserSoundFile=FLAG_CONDITION \ No newline at end of file diff --git a/src/main/java/soundchan/BotListener/BotListener.java b/src/main/java/soundchan/BotListener/BotListener.java index 0dad6c0..02c3acd 100644 --- a/src/main/java/soundchan/BotListener/BotListener.java +++ b/src/main/java/soundchan/BotListener/BotListener.java @@ -64,15 +64,20 @@ public class BotListener extends ListenerAdapter{ if(audioOnUserJoin) { String userAudioPath = properties.getProperty("userAudioFilePath"); if(userAudioPath == null || userAudioPath.contentEquals("")) { - localManager = new LocalAudioManager(localFilePath, "usersound.properties"); + userAudioPath = "usersound.properties"; } - else { - localManager = new LocalAudioManager(localFilePath, userAudioPath); + localManager = new LocalAudioManager(localFilePath, userAudioPath); + + if(settingEnableCheck(properties.getProperty("watchUserSoundFile"))) { + ExecutorService executorService = Executors.newSingleThreadExecutor(); + UserSoundWatcher userSoundWatcher = new UserSoundWatcher(localManager, userAudioPath); + future = executorService.submit(userSoundWatcher); + executorService.shutdown(); } } else localManager = new LocalAudioManager(localFilePath); - + if(settingEnableCheck(properties.getProperty("watchLocalFilePath"))) { ExecutorService executorService = Executors.newSingleThreadExecutor(); DirectoryWatcher directoryWatcher = new DirectoryWatcher(localManager, localFilePath); @@ -379,6 +384,8 @@ public class BotListener extends ListenerAdapter{ * @return True if it matches a value to enable, False otherwise */ private static boolean settingEnableCheck(String value) { + if(value == null) + return false; value = value.toLowerCase(); if(value.contentEquals("true") || value.contentEquals("1") || value.contentEquals("yes") || value.contentEquals("on") || diff --git a/src/main/java/soundchan/BotListener/UserSoundWatcher.java b/src/main/java/soundchan/BotListener/UserSoundWatcher.java new file mode 100644 index 0000000..4c10cef --- /dev/null +++ b/src/main/java/soundchan/BotListener/UserSoundWatcher.java @@ -0,0 +1,69 @@ +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_MODIFY; + +public class UserSoundWatcher implements Runnable { + + private LocalAudioManager localAudioManager; + private String userSoundFile; + private Path soundFileDirectory; + private WatchService watchService; + private WatchKey watchKey; + + @SuppressWarnings("unchecked") + static WatchEvent cast(WatchEvent event) { + return (WatchEvent) event; + } + + public UserSoundWatcher(LocalAudioManager audioManager, String filepath) { + this.localAudioManager = audioManager; + File soundFile = new File(filepath); + this.userSoundFile = soundFile.getName(); + try { + this.soundFileDirectory = soundFile.getCanonicalFile().getParentFile().toPath(); + } catch(IOException e) { + System.out.println("Error getting parent path of " + userSoundFile); + } + try { + this.watchService = FileSystems.getDefault().newWatchService(); + this.watchKey = soundFileDirectory.register(watchService, ENTRY_MODIFY); + } catch(IOException e) { + System.out.println(e.getMessage()); + System.out.println("Error setting up watcher for " + filepath); + } + } + + /** + * Called by an executor, checks for changes of the userSoundFile + */ + 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); + if(pathEvent.context().endsWith(userSoundFile)) { + localAudioManager.UpdateUserAudio(); + } + } + + 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 036b38d..b125e73 100644 --- a/src/main/java/soundchan/LocalAudioManager.java +++ b/src/main/java/soundchan/LocalAudioManager.java @@ -17,9 +17,11 @@ public class LocalAudioManager { public Map filenameDict; public Map usernameDict; private String filepath; + private String userSoundFilepath; public LocalAudioManager(String filepath_in){ filepath = filepath_in; + userSoundFilepath = null; filenameDict = PopulateFiles(); } @@ -30,9 +32,9 @@ public class LocalAudioManager { */ public LocalAudioManager(String filepath_in, String userSoundFile) { filepath = filepath_in; + userSoundFilepath = userSoundFile; filenameDict = PopulateFiles(); - usernameDict = new HashMap<>(); - MapUserAudio(userSoundFile); + usernameDict = MapUserAudio(); } /** @@ -92,6 +94,15 @@ public class LocalAudioManager { filenameDict = PopulateFiles(); } + /** + * Updates the map of usernames to sound files + */ + public void UpdateUserAudio() { + if(userSoundFilepath != null | userSoundFilepath.contentEquals("")) { + usernameDict = MapUserAudio(); + } + } + /** * Creates a map of the sounds in the sound directory * @return A map with the filename (without extension) is the key for the filename (with extension) @@ -114,16 +125,19 @@ public class LocalAudioManager { /** * Reads in users and their respective sounds from file, then builds a map of users to the filenames. This assumes * filenames for the sounds are valid, but doesn't check for them. - * @param userSoundFile The file (with path if required) with listing of users and the sounds to play when they join + * @return A map with the usernames as the keys for the filename of the sound */ - private void MapUserAudio(String userSoundFile) { - Properties userSoundProp = LoadProperties(userSoundFile); + private Map MapUserAudio() { + Properties userSoundProp = LoadProperties(userSoundFilepath); Set users = userSoundProp.stringPropertyNames(); + + Map userDict = new HashMap<>(); + for(String user : users) { String soundFile = userSoundProp.getProperty(user); - usernameDict.put(user, soundFile); + userDict.put(user, soundFile); } - + return userDict; } /** -- cgit v1.2.3 From c674b38d1c2bf15db1ea029aa707609084cb2fb2 Mon Sep 17 00:00:00 2001 From: Matt Kohls Date: Tue, 16 Oct 2018 21:57:36 -0400 Subject: Putting watcher threads in map so they can be accessed later --- src/main/java/soundchan/BotListener/BotListener.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/soundchan/BotListener/BotListener.java b/src/main/java/soundchan/BotListener/BotListener.java index 02c3acd..799b547 100644 --- a/src/main/java/soundchan/BotListener/BotListener.java +++ b/src/main/java/soundchan/BotListener/BotListener.java @@ -36,7 +36,7 @@ public class BotListener extends ListenerAdapter{ private final AudioPlayerManager playerManager; private final Map musicManagers; private BotListenerHelpers helper = new BotListenerHelpers(); - private Future future; + private Map > otherTasks; // From configuration file private static String followingUser; @@ -71,7 +71,7 @@ public class BotListener extends ListenerAdapter{ if(settingEnableCheck(properties.getProperty("watchUserSoundFile"))) { ExecutorService executorService = Executors.newSingleThreadExecutor(); UserSoundWatcher userSoundWatcher = new UserSoundWatcher(localManager, userAudioPath); - future = executorService.submit(userSoundWatcher); + otherTasks.put("watchUserSoundFile", executorService.submit(userSoundWatcher)); executorService.shutdown(); } } @@ -81,7 +81,7 @@ public class BotListener extends ListenerAdapter{ if(settingEnableCheck(properties.getProperty("watchLocalFilePath"))) { ExecutorService executorService = Executors.newSingleThreadExecutor(); DirectoryWatcher directoryWatcher = new DirectoryWatcher(localManager, localFilePath); - future = executorService.submit(directoryWatcher); + otherTasks.put("watchLocalFilePath", executorService.submit(directoryWatcher)); executorService.shutdown(); } -- cgit v1.2.3 From 4db359db8fa95424446f5789a1af3fac7e800bda Mon Sep 17 00:00:00 2001 From: Matt Kohls Date: Mon, 12 Nov 2018 16:41:16 -0500 Subject: Merging Directory and UserSound watchers into one class --- .../java/soundchan/BotListener/MediaWatcher.java | 91 ++++++++++++++++++++++ 1 file changed, 91 insertions(+) create mode 100644 src/main/java/soundchan/BotListener/MediaWatcher.java diff --git a/src/main/java/soundchan/BotListener/MediaWatcher.java b/src/main/java/soundchan/BotListener/MediaWatcher.java new file mode 100644 index 0000000..1f15cc1 --- /dev/null +++ b/src/main/java/soundchan/BotListener/MediaWatcher.java @@ -0,0 +1,91 @@ +package soundchan.BotListener; + +import soundchan.LocalAudioManager; + +import java.io.File; +import java.io.IOException; +import java.nio.file.*; + +import static java.lang.Thread.sleep; +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 MediaWatcher implements Runnable { + + private LocalAudioManager localAudioManager; + private String mediaFilename; + private Path mediaDir; + private WatchService watchService; + private WatchKey watchKey; + private boolean isDirectory; + + @SuppressWarnings("unchecked") + static WatchEvent cast(WatchEvent event) { + return (WatchEvent) event; + } + + /** + * Creates a MediaWatcher, which monitors changes to files either within a directory or for a specific file. + * If the given filepath is name of a directory, it is assumed that we want to monitor changes to the sound files. + * If the given filepath is a single file, it is assumed that we want to monitor changes to the userSoundFile. + * @param audioManager AudioManager for this bot instance + * @param filepath Path to either directory or specific file + */ + public MediaWatcher(LocalAudioManager audioManager, String filepath) { + this.localAudioManager = audioManager; + File mediaFile = new File(filepath); + this.mediaFilename = mediaFile.getName(); + if(mediaFile.isFile()) { + try { + this.mediaDir = mediaFile.getCanonicalFile().getParentFile().toPath(); + } catch (IOException e) { + System.out.println("Error getting parent path of " + mediaFilename); + } + isDirectory = false; + } else if(mediaFile.isDirectory()) { + this.mediaDir = mediaFile.toPath(); + isDirectory = true; + } + try { + this.watchService = FileSystems.getDefault().newWatchService(); + this.watchKey = mediaDir.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); + if(isDirectory) { + localAudioManager.UpdateFiles(); + } else { + if(pathEvent.context().endsWith(mediaFilename)) { + localAudioManager.UpdateUserAudio(); + } + } + } + + if(!key.reset()) { + break; + } + + sleep(5000); + } + } catch(InterruptedException e) { + return; + } + } +} -- cgit v1.2.3 From ede0d1d78371f7980b98beaf94d2dd642077a762 Mon Sep 17 00:00:00 2001 From: Matt Kohls Date: Mon, 12 Nov 2018 16:43:25 -0500 Subject: Cleaning up watcher stuff --- .../soundchan/BotListener/DirectoryWatcher.java | 62 ------------------- .../java/soundchan/BotListener/MediaWatcher.java | 2 +- .../soundchan/BotListener/UserSoundWatcher.java | 69 ---------------------- 3 files changed, 1 insertion(+), 132 deletions(-) delete mode 100644 src/main/java/soundchan/BotListener/DirectoryWatcher.java delete mode 100644 src/main/java/soundchan/BotListener/UserSoundWatcher.java diff --git a/src/main/java/soundchan/BotListener/DirectoryWatcher.java b/src/main/java/soundchan/BotListener/DirectoryWatcher.java deleted file mode 100644 index 7d63bd1..0000000 --- a/src/main/java/soundchan/BotListener/DirectoryWatcher.java +++ /dev/null @@ -1,62 +0,0 @@ -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/BotListener/MediaWatcher.java b/src/main/java/soundchan/BotListener/MediaWatcher.java index 1f15cc1..20f6ee8 100644 --- a/src/main/java/soundchan/BotListener/MediaWatcher.java +++ b/src/main/java/soundchan/BotListener/MediaWatcher.java @@ -56,7 +56,7 @@ public class MediaWatcher implements Runnable { } /** - * Called by an executor, checks for changes in the directory + * Called by an executor, checks for changes to file(s) */ public void run() { try { diff --git a/src/main/java/soundchan/BotListener/UserSoundWatcher.java b/src/main/java/soundchan/BotListener/UserSoundWatcher.java deleted file mode 100644 index 4c10cef..0000000 --- a/src/main/java/soundchan/BotListener/UserSoundWatcher.java +++ /dev/null @@ -1,69 +0,0 @@ -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_MODIFY; - -public class UserSoundWatcher implements Runnable { - - private LocalAudioManager localAudioManager; - private String userSoundFile; - private Path soundFileDirectory; - private WatchService watchService; - private WatchKey watchKey; - - @SuppressWarnings("unchecked") - static WatchEvent cast(WatchEvent event) { - return (WatchEvent) event; - } - - public UserSoundWatcher(LocalAudioManager audioManager, String filepath) { - this.localAudioManager = audioManager; - File soundFile = new File(filepath); - this.userSoundFile = soundFile.getName(); - try { - this.soundFileDirectory = soundFile.getCanonicalFile().getParentFile().toPath(); - } catch(IOException e) { - System.out.println("Error getting parent path of " + userSoundFile); - } - try { - this.watchService = FileSystems.getDefault().newWatchService(); - this.watchKey = soundFileDirectory.register(watchService, ENTRY_MODIFY); - } catch(IOException e) { - System.out.println(e.getMessage()); - System.out.println("Error setting up watcher for " + filepath); - } - } - - /** - * Called by an executor, checks for changes of the userSoundFile - */ - 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); - if(pathEvent.context().endsWith(userSoundFile)) { - localAudioManager.UpdateUserAudio(); - } - } - - if(!key.reset()) { - break; - } - } - } catch(InterruptedException e) { - return; - } - } -} -- cgit v1.2.3 From 2265b16d8b3bcf74a1681838cefc8e81ea6e9eab Mon Sep 17 00:00:00 2001 From: Matt Kohls Date: Mon, 12 Nov 2018 16:52:07 -0500 Subject: Breaking out creation of MediaWatcher tasks to separate function --- .../java/soundchan/BotListener/BotListener.java | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/src/main/java/soundchan/BotListener/BotListener.java b/src/main/java/soundchan/BotListener/BotListener.java index 799b547..c7740c0 100644 --- a/src/main/java/soundchan/BotListener/BotListener.java +++ b/src/main/java/soundchan/BotListener/BotListener.java @@ -69,20 +69,14 @@ public class BotListener extends ListenerAdapter{ localManager = new LocalAudioManager(localFilePath, userAudioPath); if(settingEnableCheck(properties.getProperty("watchUserSoundFile"))) { - ExecutorService executorService = Executors.newSingleThreadExecutor(); - UserSoundWatcher userSoundWatcher = new UserSoundWatcher(localManager, userAudioPath); - otherTasks.put("watchUserSoundFile", executorService.submit(userSoundWatcher)); - executorService.shutdown(); + addWatcherTask(userAudioPath, "watchUserSoundFile"); } } else localManager = new LocalAudioManager(localFilePath); if(settingEnableCheck(properties.getProperty("watchLocalFilePath"))) { - ExecutorService executorService = Executors.newSingleThreadExecutor(); - DirectoryWatcher directoryWatcher = new DirectoryWatcher(localManager, localFilePath); - otherTasks.put("watchLocalFilePath", executorService.submit(directoryWatcher)); - executorService.shutdown(); + addWatcherTask(localFilePath, "watchLocalFilePath"); } } @@ -395,4 +389,16 @@ public class BotListener extends ListenerAdapter{ return false; } + /** + * Adds a new MediaWatcher to the list of running tasks + * @param filepath Path to either directory or file + * @param taskName Thing to name task as + */ + private void addWatcherTask(String filepath, String taskName) { + ExecutorService executorService = Executors.newSingleThreadExecutor(); + MediaWatcher directoryWatcher = new MediaWatcher(localManager, filepath); + otherTasks.put(taskName, executorService.submit(directoryWatcher)); + executorService.shutdown(); + } + } -- cgit v1.2.3 From e3718974166f429524877aaefd3cf1f3b384f27e Mon Sep 17 00:00:00 2001 From: Matt Kohls Date: Mon, 12 Nov 2018 22:25:56 -0500 Subject: Hopefully setting things up to make scanning for media updates easier But things don't actually work yet --- .../java/soundchan/BotListener/BotListener.java | 28 +++++++++++---- .../java/soundchan/BotListener/MediaWatcher.java | 40 ++++++++++++++++------ .../BotListener/MediaWatcherListener.java | 8 +++++ 3 files changed, 59 insertions(+), 17 deletions(-) create mode 100644 src/main/java/soundchan/BotListener/MediaWatcherListener.java diff --git a/src/main/java/soundchan/BotListener/BotListener.java b/src/main/java/soundchan/BotListener/BotListener.java index c7740c0..6350d6d 100644 --- a/src/main/java/soundchan/BotListener/BotListener.java +++ b/src/main/java/soundchan/BotListener/BotListener.java @@ -19,11 +19,12 @@ import net.dv8tion.jda.core.hooks.ListenerAdapter; import net.dv8tion.jda.core.managers.AudioManager; import soundchan.*; +import java.nio.file.WatchEvent; +import java.sql.SQLOutput; 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; @@ -69,14 +70,28 @@ public class BotListener extends ListenerAdapter{ localManager = new LocalAudioManager(localFilePath, userAudioPath); if(settingEnableCheck(properties.getProperty("watchUserSoundFile"))) { - addWatcherTask(userAudioPath, "watchUserSoundFile"); + MediaWatcherListener listener = (event) -> System.out.println("thing"); + addWatcherTask(listener, userAudioPath, "watchUserSoundFile"); + /*addWatcherTask(new MediaWatcherListener() { + @Override + public void runTask(WatchEvent event) { + System.out.println("Aaaa"); + //localManager.UpdateUserAudio(); + } + }, userAudioPath, "watchUserSoundFile");*/ } } else localManager = new LocalAudioManager(localFilePath); if(settingEnableCheck(properties.getProperty("watchLocalFilePath"))) { - addWatcherTask(localFilePath, "watchLocalFilePath"); + addWatcherTask(new MediaWatcherListener() { + @Override + public void runTask(WatchEvent event) { + System.out.println("Oooo"); + //localManager.UpdateFiles(); + } + }, localFilePath, "watchLocalFilePath"); } } @@ -391,13 +406,14 @@ public class BotListener extends ListenerAdapter{ /** * Adds a new MediaWatcher to the list of running tasks + * @param listener Listener that will get callback during watching of media * @param filepath Path to either directory or file * @param taskName Thing to name task as */ - private void addWatcherTask(String filepath, String taskName) { + private void addWatcherTask(@NotNull MediaWatcherListener listener, String filepath, String taskName) { ExecutorService executorService = Executors.newSingleThreadExecutor(); - MediaWatcher directoryWatcher = new MediaWatcher(localManager, filepath); - otherTasks.put(taskName, executorService.submit(directoryWatcher)); + MediaWatcher watcher = new MediaWatcher(listener, filepath); + otherTasks.put(taskName, executorService.submit(watcher)); executorService.shutdown(); } diff --git a/src/main/java/soundchan/BotListener/MediaWatcher.java b/src/main/java/soundchan/BotListener/MediaWatcher.java index 20f6ee8..684be94 100644 --- a/src/main/java/soundchan/BotListener/MediaWatcher.java +++ b/src/main/java/soundchan/BotListener/MediaWatcher.java @@ -1,7 +1,5 @@ package soundchan.BotListener; -import soundchan.LocalAudioManager; - import java.io.File; import java.io.IOException; import java.nio.file.*; @@ -13,12 +11,13 @@ import static java.nio.file.StandardWatchEventKinds.ENTRY_MODIFY; public class MediaWatcher implements Runnable { - private LocalAudioManager localAudioManager; + private MediaWatcherListener listener; private String mediaFilename; private Path mediaDir; private WatchService watchService; private WatchKey watchKey; private boolean isDirectory; + private int sleepTime = 5000; @SuppressWarnings("unchecked") static WatchEvent cast(WatchEvent event) { @@ -27,13 +26,32 @@ public class MediaWatcher implements Runnable { /** * Creates a MediaWatcher, which monitors changes to files either within a directory or for a specific file. - * If the given filepath is name of a directory, it is assumed that we want to monitor changes to the sound files. - * If the given filepath is a single file, it is assumed that we want to monitor changes to the userSoundFile. - * @param audioManager AudioManager for this bot instance + * Defaults to scanning every 5 seconds. + * @param listener Object that will get a callback when there is a watch event * @param filepath Path to either directory or specific file */ - public MediaWatcher(LocalAudioManager audioManager, String filepath) { - this.localAudioManager = audioManager; + public MediaWatcher(MediaWatcherListener listener, String filepath) { + this.listener = listener; + startWatchService(filepath); + } + + /** + * Creates a MediaWatcher, which monitors changes to files either within a directory or for a specific file. + * @param listener Object that will get a callback when there is a watch event + * @param filepath Path to either directory or specific file + * @param sleepTime How long to put the scanner thread to sleep between rescans (time in milliseconds) + */ + public MediaWatcher(MediaWatcherListener listener, String filepath, int sleepTime) { + this.listener = listener; + this.sleepTime = sleepTime; + startWatchService(filepath); + } + + /** + * Sets up watch service for the file/directory + * @param filepath Path to file or directory to be scanned + */ + private void startWatchService(String filepath) { File mediaFile = new File(filepath); this.mediaFilename = mediaFile.getName(); if(mediaFile.isFile()) { @@ -70,10 +88,10 @@ public class MediaWatcher implements Runnable { for(WatchEvent event : key.pollEvents()) { WatchEvent pathEvent = cast(event); if(isDirectory) { - localAudioManager.UpdateFiles(); + listener.runTask(event); } else { if(pathEvent.context().endsWith(mediaFilename)) { - localAudioManager.UpdateUserAudio(); + listener.runTask(event); } } } @@ -82,7 +100,7 @@ public class MediaWatcher implements Runnable { break; } - sleep(5000); + sleep(sleepTime); } } catch(InterruptedException e) { return; diff --git a/src/main/java/soundchan/BotListener/MediaWatcherListener.java b/src/main/java/soundchan/BotListener/MediaWatcherListener.java new file mode 100644 index 0000000..8997a49 --- /dev/null +++ b/src/main/java/soundchan/BotListener/MediaWatcherListener.java @@ -0,0 +1,8 @@ +package soundchan.BotListener; + +import java.nio.file.WatchEvent; + +public interface MediaWatcherListener { + + void runTask(WatchEvent event); +} -- cgit v1.2.3 From 3d2ded8af9e6306f0a3bea331f6354743c8c7a28 Mon Sep 17 00:00:00 2001 From: Matt Kohls Date: Mon, 12 Nov 2018 22:52:26 -0500 Subject: Got MediaWatcher working with MediaWatcherListener --- src/main/java/soundchan/BotListener/BotListener.java | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/src/main/java/soundchan/BotListener/BotListener.java b/src/main/java/soundchan/BotListener/BotListener.java index 6350d6d..77ed890 100644 --- a/src/main/java/soundchan/BotListener/BotListener.java +++ b/src/main/java/soundchan/BotListener/BotListener.java @@ -21,10 +21,7 @@ import soundchan.*; import java.nio.file.WatchEvent; import java.sql.SQLOutput; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Properties; +import java.util.*; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; @@ -62,6 +59,7 @@ public class BotListener extends ListenerAdapter{ localFilePath = properties.getProperty("localFilePath"); followingUser = properties.getProperty("followingUser"); audioOnUserJoin = settingEnableCheck(properties.getProperty("audioOnUserJoin")); + otherTasks = new HashMap<>(); if(audioOnUserJoin) { String userAudioPath = properties.getProperty("userAudioFilePath"); if(userAudioPath == null || userAudioPath.contentEquals("")) { @@ -70,15 +68,12 @@ public class BotListener extends ListenerAdapter{ localManager = new LocalAudioManager(localFilePath, userAudioPath); if(settingEnableCheck(properties.getProperty("watchUserSoundFile"))) { - MediaWatcherListener listener = (event) -> System.out.println("thing"); - addWatcherTask(listener, userAudioPath, "watchUserSoundFile"); - /*addWatcherTask(new MediaWatcherListener() { + addWatcherTask(new MediaWatcherListener() { @Override public void runTask(WatchEvent event) { - System.out.println("Aaaa"); - //localManager.UpdateUserAudio(); + localManager.UpdateUserAudio(); } - }, userAudioPath, "watchUserSoundFile");*/ + }, userAudioPath, "watchUserSoundFile"); } } else @@ -88,8 +83,7 @@ public class BotListener extends ListenerAdapter{ addWatcherTask(new MediaWatcherListener() { @Override public void runTask(WatchEvent event) { - System.out.println("Oooo"); - //localManager.UpdateFiles(); + localManager.UpdateFiles(); } }, localFilePath, "watchLocalFilePath"); } -- cgit v1.2.3 From 9596f2ab16de02e46415dde479a19973b8d43ac8 Mon Sep 17 00:00:00 2001 From: Matt Kohls Date: Mon, 12 Nov 2018 23:02:03 -0500 Subject: Renaming function and adding comment --- src/main/java/soundchan/BotListener/BotListener.java | 4 ++-- src/main/java/soundchan/BotListener/MediaWatcher.java | 4 ++-- src/main/java/soundchan/BotListener/MediaWatcherListener.java | 6 +++++- 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/src/main/java/soundchan/BotListener/BotListener.java b/src/main/java/soundchan/BotListener/BotListener.java index 77ed890..e3ac382 100644 --- a/src/main/java/soundchan/BotListener/BotListener.java +++ b/src/main/java/soundchan/BotListener/BotListener.java @@ -70,7 +70,7 @@ public class BotListener extends ListenerAdapter{ if(settingEnableCheck(properties.getProperty("watchUserSoundFile"))) { addWatcherTask(new MediaWatcherListener() { @Override - public void runTask(WatchEvent event) { + public void onWatchEvent(WatchEvent event) { localManager.UpdateUserAudio(); } }, userAudioPath, "watchUserSoundFile"); @@ -82,7 +82,7 @@ public class BotListener extends ListenerAdapter{ if(settingEnableCheck(properties.getProperty("watchLocalFilePath"))) { addWatcherTask(new MediaWatcherListener() { @Override - public void runTask(WatchEvent event) { + public void onWatchEvent(WatchEvent event) { localManager.UpdateFiles(); } }, localFilePath, "watchLocalFilePath"); diff --git a/src/main/java/soundchan/BotListener/MediaWatcher.java b/src/main/java/soundchan/BotListener/MediaWatcher.java index 684be94..f9c7598 100644 --- a/src/main/java/soundchan/BotListener/MediaWatcher.java +++ b/src/main/java/soundchan/BotListener/MediaWatcher.java @@ -88,10 +88,10 @@ public class MediaWatcher implements Runnable { for(WatchEvent event : key.pollEvents()) { WatchEvent pathEvent = cast(event); if(isDirectory) { - listener.runTask(event); + listener.onWatchEvent(event); } else { if(pathEvent.context().endsWith(mediaFilename)) { - listener.runTask(event); + listener.onWatchEvent(event); } } } diff --git a/src/main/java/soundchan/BotListener/MediaWatcherListener.java b/src/main/java/soundchan/BotListener/MediaWatcherListener.java index 8997a49..8c146f6 100644 --- a/src/main/java/soundchan/BotListener/MediaWatcherListener.java +++ b/src/main/java/soundchan/BotListener/MediaWatcherListener.java @@ -4,5 +4,9 @@ import java.nio.file.WatchEvent; public interface MediaWatcherListener { - void runTask(WatchEvent event); + /** + * Called by MediaWatcher when there is a file event. Any created, deleted, or modified events will be passed for use. + * @param event The type of event that triggered the update. + */ + void onWatchEvent(WatchEvent event); } -- cgit v1.2.3 From 9cf395013daec68ad679e9ea589aaf55074743fd Mon Sep 17 00:00:00 2001 From: Matt Kohls Date: Tue, 13 Nov 2018 15:09:27 -0500 Subject: Adding ability to scan for changes in subdirectories --- .../java/soundchan/BotListener/BotListener.java | 9 ++++---- .../java/soundchan/BotListener/MediaWatcher.java | 27 ++++++++++++++++++---- 2 files changed, 27 insertions(+), 9 deletions(-) diff --git a/src/main/java/soundchan/BotListener/BotListener.java b/src/main/java/soundchan/BotListener/BotListener.java index e3ac382..16ad2fc 100644 --- a/src/main/java/soundchan/BotListener/BotListener.java +++ b/src/main/java/soundchan/BotListener/BotListener.java @@ -73,7 +73,7 @@ public class BotListener extends ListenerAdapter{ public void onWatchEvent(WatchEvent event) { localManager.UpdateUserAudio(); } - }, userAudioPath, "watchUserSoundFile"); + }, userAudioPath, "watchUserSoundFile", false); } } else @@ -85,7 +85,7 @@ public class BotListener extends ListenerAdapter{ public void onWatchEvent(WatchEvent event) { localManager.UpdateFiles(); } - }, localFilePath, "watchLocalFilePath"); + }, localFilePath, "watchLocalFilePath", true); } } @@ -403,10 +403,11 @@ public class BotListener extends ListenerAdapter{ * @param listener Listener that will get callback during watching of media * @param filepath Path to either directory or file * @param taskName Thing to name task as + * @param watchSubDirs Also watch any subdirectories in the given directory (doesn't do anything if watching a file) */ - private void addWatcherTask(@NotNull MediaWatcherListener listener, String filepath, String taskName) { + private void addWatcherTask(@NotNull MediaWatcherListener listener, String filepath, String taskName, boolean watchSubDirs) { ExecutorService executorService = Executors.newSingleThreadExecutor(); - MediaWatcher watcher = new MediaWatcher(listener, filepath); + MediaWatcher watcher = new MediaWatcher(listener, filepath, watchSubDirs); otherTasks.put(taskName, executorService.submit(watcher)); executorService.shutdown(); } diff --git a/src/main/java/soundchan/BotListener/MediaWatcher.java b/src/main/java/soundchan/BotListener/MediaWatcher.java index f9c7598..3e58d3f 100644 --- a/src/main/java/soundchan/BotListener/MediaWatcher.java +++ b/src/main/java/soundchan/BotListener/MediaWatcher.java @@ -3,6 +3,7 @@ package soundchan.BotListener; import java.io.File; import java.io.IOException; import java.nio.file.*; +import java.nio.file.attribute.BasicFileAttributes; import static java.lang.Thread.sleep; import static java.nio.file.StandardWatchEventKinds.ENTRY_CREATE; @@ -29,29 +30,31 @@ public class MediaWatcher implements Runnable { * Defaults to scanning every 5 seconds. * @param listener Object that will get a callback when there is a watch event * @param filepath Path to either directory or specific file + * @param watchSubDirs Also watch any subdirectories in the given directory (doesn't do anything if watching a file) */ - public MediaWatcher(MediaWatcherListener listener, String filepath) { + public MediaWatcher(MediaWatcherListener listener, String filepath, boolean watchSubDirs) { this.listener = listener; - startWatchService(filepath); + startWatchService(filepath, watchSubDirs); } /** * Creates a MediaWatcher, which monitors changes to files either within a directory or for a specific file. * @param listener Object that will get a callback when there is a watch event * @param filepath Path to either directory or specific file + * @param watchSubDirs Also watch any subdirectories in the given directory (doesn't do anything if watching a file) * @param sleepTime How long to put the scanner thread to sleep between rescans (time in milliseconds) */ - public MediaWatcher(MediaWatcherListener listener, String filepath, int sleepTime) { + public MediaWatcher(MediaWatcherListener listener, String filepath, boolean watchSubDirs, int sleepTime) { this.listener = listener; this.sleepTime = sleepTime; - startWatchService(filepath); + startWatchService(filepath, watchSubDirs); } /** * Sets up watch service for the file/directory * @param filepath Path to file or directory to be scanned */ - private void startWatchService(String filepath) { + private void startWatchService(String filepath, boolean watchSubDirs) { File mediaFile = new File(filepath); this.mediaFilename = mediaFile.getName(); if(mediaFile.isFile()) { @@ -68,6 +71,20 @@ public class MediaWatcher implements Runnable { try { this.watchService = FileSystems.getDefault().newWatchService(); this.watchKey = mediaDir.register(watchService, ENTRY_CREATE, ENTRY_DELETE, ENTRY_MODIFY); + if(isDirectory && watchSubDirs) { + Files.walkFileTree(mediaDir, new SimpleFileVisitor() { + @Override + public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) { + try { + dir.register(watchService, ENTRY_CREATE, ENTRY_DELETE, ENTRY_MODIFY); + return FileVisitResult.CONTINUE; + } catch (IOException e) { + System.out.println("Error setting up watch service with sub dirs in " + filepath); + return FileVisitResult.SKIP_SUBTREE; + } + } + }); + } } catch (IOException e) { System.out.println("Error setting up watcher for " + filepath); } -- cgit v1.2.3 From cdb25dd2ac7065b5211364730e5bb03b435a3358 Mon Sep 17 00:00:00 2001 From: Matt Kohls Date: Tue, 13 Nov 2018 15:24:29 -0500 Subject: Adding comments --- src/main/java/soundchan/BotListener/MediaWatcher.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/soundchan/BotListener/MediaWatcher.java b/src/main/java/soundchan/BotListener/MediaWatcher.java index 3e58d3f..80a0c83 100644 --- a/src/main/java/soundchan/BotListener/MediaWatcher.java +++ b/src/main/java/soundchan/BotListener/MediaWatcher.java @@ -53,6 +53,7 @@ public class MediaWatcher implements Runnable { /** * Sets up watch service for the file/directory * @param filepath Path to file or directory to be scanned + * @param watchSubDirs Also watch any subdirectories in the given directory (doesn't do anything if watching a file) */ private void startWatchService(String filepath, boolean watchSubDirs) { File mediaFile = new File(filepath); -- cgit v1.2.3 From 47ebae8b5085b7deed8fc10b69bc0f4be4d4e00d Mon Sep 17 00:00:00 2001 From: Matt Kohls Date: Mon, 19 Nov 2018 23:03:20 -0500 Subject: Handling events from sub-dirs correctly --- .../java/soundchan/BotListener/MediaWatcher.java | 26 +++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/src/main/java/soundchan/BotListener/MediaWatcher.java b/src/main/java/soundchan/BotListener/MediaWatcher.java index 80a0c83..2784eec 100644 --- a/src/main/java/soundchan/BotListener/MediaWatcher.java +++ b/src/main/java/soundchan/BotListener/MediaWatcher.java @@ -4,6 +4,7 @@ import java.io.File; import java.io.IOException; import java.nio.file.*; import java.nio.file.attribute.BasicFileAttributes; +import java.util.ArrayList; import static java.lang.Thread.sleep; import static java.nio.file.StandardWatchEventKinds.ENTRY_CREATE; @@ -17,6 +18,7 @@ public class MediaWatcher implements Runnable { private Path mediaDir; private WatchService watchService; private WatchKey watchKey; + private ArrayList subDirKeys; private boolean isDirectory; private int sleepTime = 5000; @@ -68,6 +70,7 @@ public class MediaWatcher implements Runnable { } else if(mediaFile.isDirectory()) { this.mediaDir = mediaFile.toPath(); isDirectory = true; + subDirKeys = new ArrayList<>(); } try { this.watchService = FileSystems.getDefault().newWatchService(); @@ -77,7 +80,8 @@ public class MediaWatcher implements Runnable { @Override public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) { try { - dir.register(watchService, ENTRY_CREATE, ENTRY_DELETE, ENTRY_MODIFY); + WatchKey temp = dir.register(watchService, ENTRY_CREATE, ENTRY_DELETE, ENTRY_MODIFY); + subDirKeys.add(temp); return FileVisitResult.CONTINUE; } catch (IOException e) { System.out.println("Error setting up watch service with sub dirs in " + filepath); @@ -97,10 +101,26 @@ public class MediaWatcher implements Runnable { public void run() { try { while(true) { - WatchKey key = watchService.take(); - if(this.watchKey != key) { + WatchKey key = watchService.take(); // Wait for an event to happen + + // Check this event happened in a place we are monitoring, otherwise ignore it + if(!isDirectory && this.watchKey != key) { System.out.println("Error with WatchKey"); continue; + } else if(isDirectory) { + if(this.watchKey != key) { // Our event doesn't happen in the root of the sounds directory + boolean noKeyMatch = true; + for(WatchKey subKey : subDirKeys) { // Check if it happened in on of the sub directories + if(subKey == key) { + noKeyMatch = false; + break; + } + } + if(noKeyMatch) { + System.out.println("Error with WatchKey"); + continue; + } + } } for(WatchEvent event : key.pollEvents()) { -- cgit v1.2.3