1
0
mirror of https://github.com/mitb-archive/filebot synced 2024-08-13 17:03:45 -04:00

SFV: auto-detect common root folder from dropped fileset

This commit is contained in:
Reinhard Pointner 2016-03-21 15:29:27 +00:00
parent 6c3895d7bf
commit 47ab6f6b96
2 changed files with 68 additions and 19 deletions

View File

@ -11,6 +11,7 @@ import static net.filebot.util.ui.SwingUI.*;
import java.io.File;
import java.io.IOException;
import java.nio.file.Path;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@ -24,6 +25,7 @@ import net.filebot.hash.VerificationFileReader;
import net.filebot.mac.MacAppUtilities;
import net.filebot.ui.transfer.BackgroundFileTransferablePolicy;
import net.filebot.util.ExceptionUtilities;
import net.filebot.util.FileSet;
class ChecksumTableTransferablePolicy extends BackgroundFileTransferablePolicy<ChecksumCell> {
@ -84,20 +86,42 @@ class ChecksumTableTransferablePolicy extends BackgroundFileTransferablePolicy<C
try {
// handle single verification file drop
if (files.size() == 1 && getHashType(files.get(0)) != null) {
loadVerificationFile(files.get(0), getHashType(files.get(0)));
}
// handle single folder drop
else if (files.size() == 1 && files.get(0).isDirectory()) {
for (File file : getChildren(files.get(0), NOT_HIDDEN, CASE_INSENSITIVE_PATH)) {
load(file, null, files.get(0));
if (containsOnly(files, VERIFICATION_FILES)) {
for (File file : files) {
loadVerificationFile(file, getHashType(file));
}
return;
}
// handle all other drops
else {
// handle single folder drop
if (files.size() == 1 && containsOnly(files, FOLDERS)) {
for (File folder : files) {
for (File file : getChildren(folder, NOT_HIDDEN, CASE_INSENSITIVE_PATH)) {
load(file, null, folder);
}
}
return;
}
// handle files and folders dropped from the same parent folder
if (mapByFolder(files).size() == 1) {
for (File file : files) {
load(file, null, file.getParentFile());
}
return;
}
// handle all other drops and auto-detect common root folder from dropped fileset
FileSet fileset = new FileSet();
files.forEach(fileset::add);
for (Entry<Path, List<Path>> it : fileset.getRoots().entrySet()) {
File root = it.getKey().toFile();
for (Path path : it.getValue()) {
File relativeFile = path.toFile().getParentFile();
File absoluteFile = new File(root, path.toString());
load(absoluteFile, relativeFile, root);
}
}
} catch (InterruptedException e) {
// supposed to happen if background execution is aborted
@ -120,8 +144,9 @@ class ChecksumTableTransferablePolicy extends BackgroundFileTransferablePolicy<C
while (parser.hasNext()) {
// make this possibly long-running operation interruptible
if (Thread.interrupted())
if (Thread.interrupted()) {
throw new InterruptedException();
}
Entry<File, String> entry = parser.next();
@ -140,12 +165,14 @@ class ChecksumTableTransferablePolicy extends BackgroundFileTransferablePolicy<C
}
protected void load(File absoluteFile, File relativeFile, File root) throws IOException, InterruptedException {
if (Thread.interrupted())
if (Thread.interrupted()) {
throw new InterruptedException();
}
// ignore hidden files/folders
if (absoluteFile.isHidden())
if (absoluteFile.isHidden()) {
return;
}
// add next name to relative path
relativeFile = new File(relativeFile, absoluteFile.getName());

View File

@ -1,5 +1,8 @@
package net.filebot.util;
import static java.util.Collections.*;
import static java.util.stream.Collectors.*;
import java.io.File;
import java.nio.file.Path;
import java.nio.file.Paths;
@ -7,33 +10,33 @@ import java.util.AbstractSet;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.Spliterator;
import java.util.stream.Stream;
public class FileSet extends AbstractSet<Path> {
private static final int ROOT_LEVEL = -1;
private final Map<Path, FileSet> folders = new HashMap<Path, FileSet>(4, 2);
private final Set<Path> files = new HashSet<Path>(4, 2);
private boolean add(Path e, int depth) {
// add new leaf element
if (e.getNameCount() - depth == 1) {
if (e.getNameCount() - 1 == depth) {
return files.add(e.getFileName());
}
// add new node element
if (e.getNameCount() - depth > 1) {
folders.computeIfAbsent(e.getName(depth), k -> new FileSet()).add(e, depth + 1);
}
return false;
return folders.computeIfAbsent(depth == ROOT_LEVEL ? e.getRoot() : e.getName(depth), k -> new FileSet()).add(e, depth + 1);
}
@Override
public boolean add(Path e) {
return add(e, 0);
return add(e, ROOT_LEVEL);
}
public boolean add(File e) {
@ -84,6 +87,25 @@ public class FileSet extends AbstractSet<Path> {
return Paths.get(path);
}
public Map<Path, List<Path>> getRoots() {
if (folders.size() != 1 || files.size() > 0) {
return emptyMap();
}
Entry<Path, FileSet> entry = folders.entrySet().iterator().next();
Path parent = entry.getKey();
Map<Path, List<Path>> next = entry.getValue().getRoots();
if (next.size() > 0) {
// resolve children
return next.entrySet().stream().collect(toMap(it -> {
return parent.resolve(it.getKey());
}, it -> it.getValue()));
}
// resolve children
return folders.entrySet().stream().collect(toMap(it -> it.getKey(), it -> it.getValue().stream().collect(toList())));
}
@Override
public int size() {
return folders.values().stream().mapToInt(f -> f.size()).sum() + files.size();