Refactor trash/delete
This commit is contained in:
parent
d886f6569f
commit
5244a33fac
|
@ -58,8 +58,10 @@ public class CacheManager {
|
||||||
|
|
||||||
private void clearDiskStore(File cache) {
|
private void clearDiskStore(File cache) {
|
||||||
getChildren(cache).stream().filter(f -> f.isFile() && !f.getName().startsWith(".")).forEach(f -> {
|
getChildren(cache).stream().filter(f -> f.isFile() && !f.getName().startsWith(".")).forEach(f -> {
|
||||||
if (!delete(f)) {
|
try {
|
||||||
debug.warning(format("Failed to delete cache: %s", f.getName()));
|
delete(f);
|
||||||
|
} catch (Exception e) {
|
||||||
|
debug.warning(format("Failed to delete cache: %s => %s", f, e));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -86,11 +86,8 @@ public class Main {
|
||||||
if (args.clearCache()) {
|
if (args.clearCache()) {
|
||||||
System.out.println("Clear cache");
|
System.out.println("Clear cache");
|
||||||
for (File folder : getChildren(ApplicationFolder.Cache.getCanonicalFile(), FOLDERS)) {
|
for (File folder : getChildren(ApplicationFolder.Cache.getCanonicalFile(), FOLDERS)) {
|
||||||
if (delete(folder)) {
|
System.out.println("Delete " + folder);
|
||||||
System.out.println("* Delete " + folder);
|
delete(folder);
|
||||||
} else {
|
|
||||||
System.out.println("* Failed to delete " + folder);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,11 @@
|
||||||
package net.filebot;
|
package net.filebot;
|
||||||
|
|
||||||
import static java.util.Collections.*;
|
import static java.util.Collections.*;
|
||||||
|
import static net.filebot.Logging.*;
|
||||||
import static net.filebot.util.FileUtilities.*;
|
import static net.filebot.util.FileUtilities.*;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Map.Entry;
|
import java.util.Map.Entry;
|
||||||
import java.util.concurrent.CancellationException;
|
import java.util.concurrent.CancellationException;
|
||||||
|
@ -64,4 +66,27 @@ public enum NativeRenameAction implements RenameAction {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void trash(File file) throws IOException {
|
||||||
|
// use system trash if possible
|
||||||
|
try {
|
||||||
|
if (Platform.isMac()) {
|
||||||
|
// use com.apple.eio package on OS X platform
|
||||||
|
if (com.apple.eio.FileManager.moveToTrash(file)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} else if (com.sun.jna.platform.FileUtils.getInstance().hasTrash()) {
|
||||||
|
// use com.sun.jna.platform package on Windows and Linux
|
||||||
|
com.sun.jna.platform.FileUtils.getInstance().moveToTrash(new File[] { file });
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
debug.warning(e::toString);
|
||||||
|
}
|
||||||
|
|
||||||
|
// delete permanently if necessary
|
||||||
|
if (file.exists()) {
|
||||||
|
net.filebot.util.FileUtilities.delete(file);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -149,29 +149,29 @@ public enum StandardRenameAction implements RenameAction {
|
||||||
|
|
||||||
// reverse symlink
|
// reverse symlink
|
||||||
if (currentAttr.isSymbolicLink() && !originalAttr.isSymbolicLink()) {
|
if (currentAttr.isSymbolicLink() && !originalAttr.isSymbolicLink()) {
|
||||||
Files.delete(current.toPath());
|
NativeRenameAction.trash(current);
|
||||||
return original;
|
return original;
|
||||||
}
|
}
|
||||||
|
|
||||||
// reverse keeplink
|
// reverse keeplink
|
||||||
if (!currentAttr.isSymbolicLink() && originalAttr.isSymbolicLink()) {
|
if (!currentAttr.isSymbolicLink() && originalAttr.isSymbolicLink()) {
|
||||||
Files.delete(original.toPath());
|
NativeRenameAction.trash(original);
|
||||||
return FileUtilities.moveRename(current, original);
|
return FileUtilities.moveRename(current, original);
|
||||||
}
|
}
|
||||||
|
|
||||||
// reverse copy / hardlink
|
// reverse copy / hardlink
|
||||||
if (currentAttr.isRegularFile() && originalAttr.isRegularFile()) {
|
if (currentAttr.isRegularFile() && originalAttr.isRegularFile()) {
|
||||||
Files.delete(current.toPath());
|
NativeRenameAction.trash(current);
|
||||||
return original;
|
return original;
|
||||||
}
|
}
|
||||||
|
|
||||||
// reverse folder copy
|
// reverse folder copy
|
||||||
if (currentAttr.isDirectory() && originalAttr.isDirectory()) {
|
if (currentAttr.isDirectory() && originalAttr.isDirectory()) {
|
||||||
FileUtilities.delete(original);
|
NativeRenameAction.trash(original);
|
||||||
return FileUtilities.moveRename(current, original);
|
return FileUtilities.moveRename(current, original);
|
||||||
}
|
}
|
||||||
|
|
||||||
throw new IllegalArgumentException(String.format("Cannot revert files: %s => %s", current, original));
|
throw new IllegalArgumentException(String.format("Cannot revert file: %s => %s", current, original));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,7 +19,6 @@ import java.io.IOException;
|
||||||
import java.util.AbstractList;
|
import java.util.AbstractList;
|
||||||
import java.util.AbstractMap.SimpleEntry;
|
import java.util.AbstractMap.SimpleEntry;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
|
@ -41,8 +40,6 @@ import javax.swing.JList;
|
||||||
import javax.swing.JOptionPane;
|
import javax.swing.JOptionPane;
|
||||||
import javax.swing.JScrollPane;
|
import javax.swing.JScrollPane;
|
||||||
|
|
||||||
import com.sun.jna.platform.FileUtils;
|
|
||||||
|
|
||||||
import net.filebot.HistorySpooler;
|
import net.filebot.HistorySpooler;
|
||||||
import net.filebot.NativeRenameAction;
|
import net.filebot.NativeRenameAction;
|
||||||
import net.filebot.ResourceManager;
|
import net.filebot.ResourceManager;
|
||||||
|
@ -153,7 +150,7 @@ class RenameAction extends AbstractAction {
|
||||||
|
|
||||||
private void deleteEmptyFolders(Map<File, File> renameMap) {
|
private void deleteEmptyFolders(Map<File, File> renameMap) {
|
||||||
// collect empty folders and files in reverse order
|
// collect empty folders and files in reverse order
|
||||||
Set<File> empty = new TreeSet<File>();
|
Set<File> deleteFiles = new TreeSet<File>();
|
||||||
|
|
||||||
renameMap.forEach((s, d) -> {
|
renameMap.forEach((s, d) -> {
|
||||||
File sourceFolder = s.getParentFile();
|
File sourceFolder = s.getParentFile();
|
||||||
|
@ -170,12 +167,12 @@ class RenameAction extends AbstractAction {
|
||||||
|
|
||||||
for (int i = 0; i < tailSize && !isStructureRoot(sourceFolder); sourceFolder = sourceFolder.getParentFile(), i++) {
|
for (int i = 0; i < tailSize && !isStructureRoot(sourceFolder); sourceFolder = sourceFolder.getParentFile(), i++) {
|
||||||
File[] children = sourceFolder.listFiles();
|
File[] children = sourceFolder.listFiles();
|
||||||
if (children == null || !stream(children).allMatch(f -> empty.contains(f) || isThumbnailStore(f))) {
|
if (children == null || !stream(children).allMatch(f -> deleteFiles.contains(f) || isThumbnailStore(f))) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
stream(children).forEach(empty::add);
|
stream(children).forEach(deleteFiles::add);
|
||||||
empty.add(sourceFolder);
|
deleteFiles.add(sourceFolder);
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
debug.warning(e::toString);
|
debug.warning(e::toString);
|
||||||
|
@ -183,22 +180,10 @@ class RenameAction extends AbstractAction {
|
||||||
});
|
});
|
||||||
|
|
||||||
// use system trash to delete left-behind empty folders / hidden files
|
// use system trash to delete left-behind empty folders / hidden files
|
||||||
moveToTrash(empty);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void moveToTrash(Collection<File> files) {
|
|
||||||
try {
|
try {
|
||||||
for (File f : files) {
|
for (File file : deleteFiles) {
|
||||||
if (!f.exists()) {
|
if (file.exists()) {
|
||||||
continue;
|
NativeRenameAction.trash(file);
|
||||||
}
|
|
||||||
|
|
||||||
if (isMacApp()) {
|
|
||||||
// use com.apple.eio package on OS X platform
|
|
||||||
MacAppUtilities.moveToTrash(f);
|
|
||||||
} else {
|
|
||||||
// use com.sun.jna.platform package on Windows and Linux
|
|
||||||
FileUtils.getInstance().moveToTrash(new File[] { f });
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
|
|
|
@ -67,7 +67,7 @@ public final class FileUtilities {
|
||||||
|
|
||||||
// on Windows, use ATOMIC_MOVE which allows us to rename files even if only lower/upper-case changes (without ATOMIC_MOVE the operation would be ignored)
|
// on Windows, use ATOMIC_MOVE which allows us to rename files even if only lower/upper-case changes (without ATOMIC_MOVE the operation would be ignored)
|
||||||
// but ATOMIC_MOVE can only work for files on the same drive, if that is not the case there is no point trying move with ATOMIC_MOVE
|
// but ATOMIC_MOVE can only work for files on the same drive, if that is not the case there is no point trying move with ATOMIC_MOVE
|
||||||
if (File.separator.equals("\\") && source.equals(destination)) {
|
if (isWindows() && source.equals(destination) && !equalsCaseSensitive(source, destination)) {
|
||||||
try {
|
try {
|
||||||
return Files.move(source.toPath(), destination.toPath(), StandardCopyOption.ATOMIC_MOVE).toFile();
|
return Files.move(source.toPath(), destination.toPath(), StandardCopyOption.ATOMIC_MOVE).toFile();
|
||||||
} catch (AtomicMoveNotSupportedException e) {
|
} catch (AtomicMoveNotSupportedException e) {
|
||||||
|
@ -152,9 +152,25 @@ public final class FileUtilities {
|
||||||
return destination.toFile();
|
return destination.toFile();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean delete(File file) {
|
public static void delete(File file) throws IOException {
|
||||||
// delete files or files
|
if (file.isDirectory()) {
|
||||||
return FileUtils.deleteQuietly(file);
|
Files.walkFileTree(file.toPath(), new SimpleFileVisitor<Path>() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FileVisitResult visitFile(Path f, BasicFileAttributes attr) throws IOException {
|
||||||
|
Files.delete(f);
|
||||||
|
return FileVisitResult.CONTINUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FileVisitResult postVisitDirectory(Path f, IOException e) throws IOException {
|
||||||
|
Files.delete(f);
|
||||||
|
return FileVisitResult.CONTINUE;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
Files.delete(file.toPath());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static File createFolders(File folder) throws IOException {
|
public static File createFolders(File folder) throws IOException {
|
||||||
|
@ -225,6 +241,14 @@ public final class FileUtilities {
|
||||||
return UTF_8.decode(data).toString();
|
return UTF_8.decode(data).toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static boolean isWindows() {
|
||||||
|
return '\\' == File.separatorChar;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean equalsCaseSensitive(File a, File b) {
|
||||||
|
return a.getPath().equals(b.getPath());
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Pattern used for matching file extensions.
|
* Pattern used for matching file extensions.
|
||||||
*
|
*
|
||||||
|
|
Loading…
Reference in New Issue