1
0
mirror of https://github.com/mitb-archive/filebot synced 2025-03-09 22:09:47 -04:00

* full support for watching a filetree

This commit is contained in:
Reinhard Pointner 2011-12-20 13:03:28 +00:00
parent 1a43b7c5fd
commit cd577da79c
3 changed files with 74 additions and 13 deletions

View File

@ -3,17 +3,24 @@ package net.sourceforge.filebot.cli;
import static java.nio.file.StandardWatchEventKinds.*; import static java.nio.file.StandardWatchEventKinds.*;
import static java.util.Collections.*;
import static net.sourceforge.tuned.FileUtilities.*;
import java.io.Closeable; import java.io.Closeable;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.nio.file.FileVisitResult;
import java.nio.file.Files;
import java.nio.file.Path; import java.nio.file.Path;
import java.nio.file.SimpleFileVisitor;
import java.nio.file.WatchEvent; import java.nio.file.WatchEvent;
import java.nio.file.WatchKey; import java.nio.file.WatchKey;
import java.nio.file.WatchService; import java.nio.file.WatchService;
import java.util.Collection; import java.util.Collection;
import java.util.HashSet; import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.SortedSet; import java.util.SortedSet;
import java.util.TreeSet; import java.util.TreeSet;
import java.util.concurrent.ExecutorService; import java.util.concurrent.ExecutorService;
@ -31,9 +38,10 @@ public abstract class FolderWatchService implements Closeable {
private final Collection<File> commitSet = new HashSet<File>(); private final Collection<File> commitSet = new HashSet<File>();
private final ExecutorService processor = Executors.newSingleThreadExecutor(); private final ExecutorService processor = Executors.newSingleThreadExecutor();
private final ExecutorService watchers = Executors.newCachedThreadPool(new DefaultThreadFactory("FolderWatchService", Thread.MIN_PRIORITY, true)); private final ExecutorService watchers = Executors.newCachedThreadPool(new DefaultThreadFactory("FolderWatchService"));
private long commitDelay = 500; // 0.5 s private long commitDelay = 500; // 0.5 s
private boolean commitPerFolder = true;
private final Timer commitTimer = new Timer() { private final Timer commitTimer = new Timer() {
@Override @Override
@ -44,6 +52,18 @@ public abstract class FolderWatchService implements Closeable {
} }
}; };
private final boolean watchTree;
public FolderWatchService(boolean watchTree) {
this.watchTree = watchTree;
}
public synchronized void setCommitPerFolder(boolean enabled) {
this.commitPerFolder = enabled;
}
public synchronized void setCommitDelay(long commitDelay) { public synchronized void setCommitDelay(long commitDelay) {
if (commitDelay < 0) if (commitDelay < 0)
@ -71,22 +91,45 @@ public abstract class FolderWatchService implements Closeable {
return; return;
} }
// divide into commit batches per folder if required
final Map<File, ? extends Collection<File>> commitBatches = commitPerFolder ? mapByFolder(files) : singletonMap((File) null, files);
processor.submit(new Runnable() { processor.submit(new Runnable() {
@Override @Override
public void run() { public void run() {
synchronized (processor) { synchronized (processor) {
processCommitSet(files.toArray(new File[0])); for (Entry<File, ? extends Collection<File>> it : commitBatches.entrySet()) {
processCommitSet(it.getValue().toArray(new File[0]), it.getKey());
}
} }
} }
}); });
} }
public abstract void processCommitSet(File[] files); public abstract void processCommitSet(File[] files, File dir);
public synchronized void watch(File node) throws IOException { public synchronized void watchFolder(File folder) throws IOException {
if (!watchTree) {
startWatch(folder);
return;
}
// start watching all folders in the tree
Files.walkFileTree(folder.toPath(), new SimpleFileVisitor<Path>() {
@Override
public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException {
startWatch(dir.toFile());
return FileVisitResult.CONTINUE;
}
});
}
private synchronized void startWatch(File node) throws IOException {
if (!node.isDirectory()) { if (!node.isDirectory()) {
throw new IllegalArgumentException("Must be a folder: " + node); throw new IllegalArgumentException("Must be a folder: " + node);
} }
@ -104,19 +147,39 @@ public abstract class FolderWatchService implements Closeable {
@Override @Override
protected void created(File file) { protected void created(File file) {
commitSet.add(file); synchronized (commitSet) {
if (!file.isDirectory()) {
commitSet.add(file);
return;
}
// start watching newly created folder
if (watchTree) {
try {
watchFolder(file);
} catch (IOException e) {
Logger.getLogger(getClass().getName()).log(Level.SEVERE, e.getMessage(), e);
}
}
}
} }
@Override @Override
protected void modified(File file) { protected void modified(File file) {
commitSet.add(file); synchronized (commitSet) {
if (!file.isDirectory()) {
commitSet.add(file);
}
}
} }
@Override @Override
protected void deleted(File file) { protected void deleted(File file) {
commitSet.remove(file); synchronized (commitSet) {
commitSet.remove(file);
}
} }
}); });
} }
@ -157,10 +220,11 @@ public abstract class FolderWatchService implements Closeable {
public void watch() throws IOException, InterruptedException { public void watch() throws IOException, InterruptedException {
try { try {
while (true) { boolean valid = true;
while (valid) {
WatchKey key = watchService.take(); WatchKey key = watchService.take();
processEvents(key.pollEvents()); processEvents(key.pollEvents());
key.reset(); valid = key.reset();
} }
} finally { } finally {
this.close(); this.close();

View File

@ -1,6 +1,5 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<media-types> <media-types>
<!-- Application --> <!-- Application -->
<type name="application/torrent"> <type name="application/torrent">
<extension>torrent</extension> <extension>torrent</extension>
@ -101,7 +100,6 @@
<extension>wtv</extension> <extension>wtv</extension>
</type> </type>
<!-- Subtitles --> <!-- Subtitles -->
<type name="subtitle/SubRip"> <type name="subtitle/SubRip">
<extension>srt</extension> <extension>srt</extension>
@ -124,5 +122,4 @@
<extension>sub</extension> <extension>sub</extension>
<extension>idx</extension> <extension>idx</extension>
</type> </type>
</media-types> </media-types>

View File

@ -1,5 +1,5 @@
// watch folders and print files that were added/modified (requires Java 7) // watch folders and print files that were added/modified (requires Java 7)
def watchman = args.getFolders().watch { changes -> def watchman = args.watch { changes ->
println "Processing $changes" println "Processing $changes"
rename(file:changes, format:"/media/storage/files/tv/{n}{'/Season '+s}/{episode}") rename(file:changes, format:"/media/storage/files/tv/{n}{'/Season '+s}/{episode}")
} }