mirror of
https://github.com/mitb-archive/filebot
synced 2024-12-24 16:58:51 -05:00
+ Auto-delete left behind empty folders when moving files into a new structure
This commit is contained in:
parent
92b8592652
commit
0a5327691e
@ -220,17 +220,21 @@ public class ReleaseInfo {
|
|||||||
if (volumeRoots == null) {
|
if (volumeRoots == null) {
|
||||||
Set<File> volumes = new HashSet<File>();
|
Set<File> volumes = new HashSet<File>();
|
||||||
|
|
||||||
|
File userHome = ApplicationFolder.UserHome.get();
|
||||||
|
List<File> roots = getFileSystemRoots();
|
||||||
|
|
||||||
// user root folder
|
// user root folder
|
||||||
volumes.add(ApplicationFolder.UserHome.get());
|
volumes.add(userHome);
|
||||||
|
volumes.addAll(getChildren(userHome, FOLDERS));
|
||||||
|
|
||||||
// Windows / Linux / Mac system roots
|
// Windows / Linux / Mac system roots
|
||||||
volumes.addAll(getFileSystemRoots());
|
volumes.addAll(roots);
|
||||||
|
|
||||||
// Linux / Mac
|
// Linux / Mac
|
||||||
if (File.separator.equals("/")) {
|
if (File.separator.equals("/")) {
|
||||||
// Linux and Mac system root folders
|
// Linux and Mac system root folders
|
||||||
for (File userFolder : volumes.toArray(new File[0])) {
|
for (File root : roots) {
|
||||||
volumes.addAll(getChildren(userFolder, FOLDERS));
|
volumes.addAll(getChildren(root, FOLDERS));
|
||||||
}
|
}
|
||||||
|
|
||||||
for (File mediaRoot : getMediaRoots()) {
|
for (File mediaRoot : getMediaRoots()) {
|
||||||
@ -241,12 +245,11 @@ public class ReleaseInfo {
|
|||||||
|
|
||||||
// Mac
|
// Mac
|
||||||
if (isMacSandbox()) {
|
if (isMacSandbox()) {
|
||||||
File realUserHome = ApplicationFolder.UserHome.get();
|
|
||||||
File sandboxUserHome = new File(System.getProperty("user.home"));
|
File sandboxUserHome = new File(System.getProperty("user.home"));
|
||||||
|
|
||||||
// e.g. ignore default Movie folder on Mac
|
// e.g. ignore default Movie folder on Mac
|
||||||
for (File userFolder : getChildren(sandboxUserHome, FOLDERS)) {
|
for (File userFolder : getChildren(sandboxUserHome, FOLDERS)) {
|
||||||
volumes.add(new File(realUserHome, userFolder.getName()));
|
volumes.add(new File(userHome, userFolder.getName()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,9 +1,11 @@
|
|||||||
package net.filebot.ui.rename;
|
package net.filebot.ui.rename;
|
||||||
|
|
||||||
|
import static java.util.Arrays.*;
|
||||||
import static java.util.Collections.*;
|
import static java.util.Collections.*;
|
||||||
import static javax.swing.JOptionPane.*;
|
import static javax.swing.JOptionPane.*;
|
||||||
import static net.filebot.Logging.*;
|
import static net.filebot.Logging.*;
|
||||||
import static net.filebot.Settings.*;
|
import static net.filebot.Settings.*;
|
||||||
|
import static net.filebot.media.MediaDetection.*;
|
||||||
import static net.filebot.media.XattrMetaInfo.*;
|
import static net.filebot.media.XattrMetaInfo.*;
|
||||||
import static net.filebot.util.ExceptionUtilities.*;
|
import static net.filebot.util.ExceptionUtilities.*;
|
||||||
import static net.filebot.util.FileUtilities.*;
|
import static net.filebot.util.FileUtilities.*;
|
||||||
@ -16,12 +18,14 @@ import java.awt.event.ActionEvent;
|
|||||||
import java.beans.PropertyChangeEvent;
|
import java.beans.PropertyChangeEvent;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.nio.file.Files;
|
||||||
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.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
|
import java.util.LinkedHashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Map.Entry;
|
import java.util.Map.Entry;
|
||||||
@ -116,18 +120,12 @@ class RenameAction extends AbstractAction {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// write metadata into xattr if xattr is enabled
|
// store xattr
|
||||||
if (useExtendedFileAttributes() || useCreationDate()) {
|
storeMetaInfo(renameMap, matches);
|
||||||
for (Match<Object, File> match : matches) {
|
|
||||||
File file = match.getCandidate();
|
// delete empty folders
|
||||||
Object meta = match.getValue();
|
if (action == StandardRenameAction.MOVE) {
|
||||||
if (renameMap.containsKey(file) && meta != null) {
|
deleteEmptyFolders(renameMap);
|
||||||
File destination = resolve(file, renameMap.get(file));
|
|
||||||
if (destination.isFile()) {
|
|
||||||
xattr.setMetaInfo(destination, meta, file.getName());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} catch (ExecutionException e) {
|
} catch (ExecutionException e) {
|
||||||
// ignore, handled in rename worker
|
// ignore, handled in rename worker
|
||||||
@ -138,6 +136,52 @@ class RenameAction extends AbstractAction {
|
|||||||
window.setCursor(Cursor.getDefaultCursor());
|
window.setCursor(Cursor.getDefaultCursor());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void storeMetaInfo(Map<File, File> renameMap, List<Match<Object, File>> matches) {
|
||||||
|
// write metadata into xattr if xattr is enabled
|
||||||
|
for (Match<Object, File> match : matches) {
|
||||||
|
File file = match.getCandidate();
|
||||||
|
Object meta = match.getValue();
|
||||||
|
if (renameMap.containsKey(file) && meta != null) {
|
||||||
|
File destination = resolve(file, renameMap.get(file));
|
||||||
|
if (destination.isFile()) {
|
||||||
|
xattr.setMetaInfo(destination, meta, file.getName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void deleteEmptyFolders(Map<File, File> renameMap) {
|
||||||
|
// collect newly empty folders
|
||||||
|
Set<File> deleteSet = new LinkedHashSet<File>();
|
||||||
|
|
||||||
|
renameMap.forEach((s, d) -> {
|
||||||
|
File sourceFolder = s.getParentFile();
|
||||||
|
File destinationFolder = resolve(s, d).getParentFile();
|
||||||
|
|
||||||
|
if (!destinationFolder.getPath().startsWith(sourceFolder.getPath())) {
|
||||||
|
int relativePathSize = listPath(d).size() - 1;
|
||||||
|
for (int i = 0; i < relativePathSize && sourceFolder != null && !isVolumeRoot(sourceFolder); sourceFolder = sourceFolder.getParentFile(), i++) {
|
||||||
|
File[] children = sourceFolder.listFiles();
|
||||||
|
if (children == null || !stream(children).allMatch(f -> f.isHidden() || deleteSet.contains(f))) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
stream(children).forEach(deleteSet::add);
|
||||||
|
deleteSet.add(sourceFolder);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
for (File f : deleteSet) {
|
||||||
|
try {
|
||||||
|
debug.finest(format("Delete empty folder: %s", f));
|
||||||
|
Files.delete(f.toPath());
|
||||||
|
} catch (Exception e) {
|
||||||
|
debug.warning(e::toString);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public boolean isNativeActionSupported(StandardRenameAction action) {
|
public boolean isNativeActionSupported(StandardRenameAction action) {
|
||||||
try {
|
try {
|
||||||
return NativeRenameAction.isSupported() && NativeRenameAction.valueOf(action.name()) != null;
|
return NativeRenameAction.isSupported() && NativeRenameAction.valueOf(action.name()) != null;
|
||||||
@ -337,7 +381,7 @@ class RenameAction extends AbstractAction {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// collect renamed types
|
// collect renamed types
|
||||||
final List<Class<?>> types = new ArrayList<Class<?>>();
|
List<Class<?>> types = new ArrayList<Class<?>>();
|
||||||
|
|
||||||
// remove renamed matches
|
// remove renamed matches
|
||||||
for (File source : renameLog.keySet()) {
|
for (File source : renameLog.keySet()) {
|
||||||
|
Loading…
Reference in New Issue
Block a user