mirror of
https://github.com/mitb-archive/filebot
synced 2025-03-09 13:59:49 -04:00
Add "Move to Trash" action to Filter Tools and add additional type filters that might come in handy when batch deleting clutter files
This commit is contained in:
parent
c856fc9638
commit
dd95a40d11
@ -85,6 +85,10 @@ public class MediaDetection {
|
|||||||
return releaseInfo.getClutterFileFilter();
|
return releaseInfo.getClutterFileFilter();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static FileFilter getClutterTypeFilter() {
|
||||||
|
return releaseInfo.getClutterTypeFilter();
|
||||||
|
}
|
||||||
|
|
||||||
public static boolean isDiskFolder(File folder) {
|
public static boolean isDiskFolder(File folder) {
|
||||||
return getDiskFolderFilter().accept(folder);
|
return getDiskFolderFilter().accept(folder);
|
||||||
}
|
}
|
||||||
|
@ -44,7 +44,8 @@ import net.filebot.ApplicationFolder;
|
|||||||
import net.filebot.Cache;
|
import net.filebot.Cache;
|
||||||
import net.filebot.CacheType;
|
import net.filebot.CacheType;
|
||||||
import net.filebot.Resource;
|
import net.filebot.Resource;
|
||||||
import net.filebot.util.FileUtilities.RegexFileFilter;
|
import net.filebot.util.FileUtilities.RegexFindFilter;
|
||||||
|
import net.filebot.util.FileUtilities.RegexMatchFilter;
|
||||||
import net.filebot.util.SystemProperty;
|
import net.filebot.util.SystemProperty;
|
||||||
import net.filebot.web.Movie;
|
import net.filebot.web.Movie;
|
||||||
import net.filebot.web.SearchResult;
|
import net.filebot.web.SearchResult;
|
||||||
@ -393,29 +394,38 @@ public class ReleaseInfo {
|
|||||||
return diskFolderFilter;
|
return diskFolderFilter;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static RegexFileFilter diskFolderEntryFilter;
|
private static RegexMatchFilter diskFolderEntryFilter;
|
||||||
|
|
||||||
public FileFilter getDiskFolderEntryFilter() {
|
public FileFilter getDiskFolderEntryFilter() {
|
||||||
if (diskFolderEntryFilter == null) {
|
if (diskFolderEntryFilter == null) {
|
||||||
diskFolderEntryFilter = new RegexFileFilter(compile(getProperty("pattern.diskfolder.entry")));
|
diskFolderEntryFilter = new RegexMatchFilter(compile(getProperty("pattern.diskfolder.entry")));
|
||||||
}
|
}
|
||||||
return diskFolderEntryFilter;
|
return diskFolderEntryFilter;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static ClutterFileFilter clutterTypeFilter;
|
||||||
|
|
||||||
|
public FileFilter getClutterTypeFilter() {
|
||||||
|
if (clutterTypeFilter == null) {
|
||||||
|
clutterTypeFilter = new ClutterFileFilter(new RegexFindFilter(compile(getProperty("pattern.clutter.types"), CASE_INSENSITIVE)), Long.parseLong(getProperty("number.clutter.maxfilesize")));
|
||||||
|
}
|
||||||
|
return clutterTypeFilter;
|
||||||
|
}
|
||||||
|
|
||||||
private static ClutterFileFilter clutterFileFilter;
|
private static ClutterFileFilter clutterFileFilter;
|
||||||
|
|
||||||
public FileFilter getClutterFileFilter() {
|
public FileFilter getClutterFileFilter() {
|
||||||
if (clutterFileFilter == null) {
|
if (clutterFileFilter == null) {
|
||||||
clutterFileFilter = new ClutterFileFilter(getExcludePattern(), Long.parseLong(getProperty("number.clutter.maxfilesize"))); // only files smaller than 250 MB may be considered clutter
|
clutterFileFilter = new ClutterFileFilter(new FileFolderNameFilter(getExcludePattern()), Long.parseLong(getProperty("number.clutter.maxfilesize")));
|
||||||
}
|
}
|
||||||
return clutterFileFilter;
|
return clutterFileFilter;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static RegexFileFilter systemFilesFilter;
|
private static RegexMatchFilter systemFilesFilter;
|
||||||
|
|
||||||
public FileFilter getSystemFilesFilter() {
|
public FileFilter getSystemFilesFilter() {
|
||||||
if (systemFilesFilter == null) {
|
if (systemFilesFilter == null) {
|
||||||
systemFilesFilter = new RegexFileFilter(compile(getProperty("pattern.system.files"), CASE_INSENSITIVE));
|
systemFilesFilter = new RegexMatchFilter(compile(getProperty("pattern.system.files"), CASE_INSENSITIVE));
|
||||||
}
|
}
|
||||||
return systemFilesFilter;
|
return systemFilesFilter;
|
||||||
}
|
}
|
||||||
@ -535,18 +545,19 @@ public class ReleaseInfo {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class ClutterFileFilter extends FileFolderNameFilter {
|
public static class ClutterFileFilter implements FileFilter {
|
||||||
|
|
||||||
|
private FileFilter filter;
|
||||||
private long maxFileSize;
|
private long maxFileSize;
|
||||||
|
|
||||||
public ClutterFileFilter(Pattern namePattern, long maxFileSize) {
|
public ClutterFileFilter(FileFilter filter, long maxFileSize) {
|
||||||
super(namePattern);
|
this.filter = filter;
|
||||||
this.maxFileSize = maxFileSize;
|
this.maxFileSize = maxFileSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean accept(File file) {
|
public boolean accept(File file) {
|
||||||
return super.accept(file) && file.isFile() && file.length() < maxFileSize;
|
return filter.accept(file) && file.isFile() && file.length() < maxFileSize;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -19,6 +19,9 @@ pattern.video.format: DivX[345]?|Xvid|AVC|(x|h)[.]?(264|265)|HEVC|3ivx|PGS|MP[E]
|
|||||||
# clutter file exclude pattern
|
# clutter file exclude pattern
|
||||||
pattern.clutter.excludes: (?<=[!\\-\\(\\[])(Sample|Trailer)|(Sample|Trailer)(?=[\\-\\)\\]])|(?<=[.\\-])(s|t|Sample|Trailer)$|(NCED|NCOP|(OP|ED)\\p{Digit}\\p{Alpha})|(Extras|Trailers|Featurettes|Interviews|Scenes|Shorts)$|Behind.the.Scenes|Deleted.and.Extended.Scenes|Deleted.Scenes
|
pattern.clutter.excludes: (?<=[!\\-\\(\\[])(Sample|Trailer)|(Sample|Trailer)(?=[\\-\\)\\]])|(?<=[.\\-])(s|t|Sample|Trailer)$|(NCED|NCOP|(OP|ED)\\p{Digit}\\p{Alpha})|(Extras|Trailers|Featurettes|Interviews|Scenes|Shorts)$|Behind.the.Scenes|Deleted.and.Extended.Scenes|Deleted.Scenes
|
||||||
|
|
||||||
|
# clutter file types
|
||||||
|
pattern.clutter.types: [.](jpg|jpeg|png|gif|ico|nfo|info|xml|htm|html|log|m3u|cue|srt|sub|idx|smi|sup|md5|sfv|txt|rtf|url|db|dna|log|tgmd|json|data|ignore|srv|srr|nzb|vbs|ini|vsmeta|DS_Store)$
|
||||||
|
|
||||||
# only files smaller than 150 MB may be considered clutter
|
# only files smaller than 150 MB may be considered clutter
|
||||||
number.clutter.maxfilesize: 150000000
|
number.clutter.maxfilesize: 150000000
|
||||||
|
|
||||||
|
@ -2,6 +2,7 @@ package net.filebot.ui.filter;
|
|||||||
|
|
||||||
import static java.util.Collections.*;
|
import static java.util.Collections.*;
|
||||||
import static java.util.stream.Collectors.*;
|
import static java.util.stream.Collectors.*;
|
||||||
|
import static net.filebot.Logging.*;
|
||||||
import static net.filebot.util.ui.SwingUI.*;
|
import static net.filebot.util.ui.SwingUI.*;
|
||||||
|
|
||||||
import java.awt.event.ActionEvent;
|
import java.awt.event.ActionEvent;
|
||||||
@ -14,12 +15,14 @@ import java.util.Iterator;
|
|||||||
import java.util.LinkedHashSet;
|
import java.util.LinkedHashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
|
||||||
import javax.swing.AbstractAction;
|
import javax.swing.AbstractAction;
|
||||||
import javax.swing.JMenu;
|
import javax.swing.JMenu;
|
||||||
import javax.swing.JMenuItem;
|
import javax.swing.JMenuItem;
|
||||||
import javax.swing.JPopupMenu;
|
import javax.swing.JPopupMenu;
|
||||||
import javax.swing.JTree;
|
import javax.swing.JTree;
|
||||||
|
import javax.swing.SwingUtilities;
|
||||||
import javax.swing.tree.DefaultTreeModel;
|
import javax.swing.tree.DefaultTreeModel;
|
||||||
import javax.swing.tree.TreeNode;
|
import javax.swing.tree.TreeNode;
|
||||||
import javax.swing.tree.TreePath;
|
import javax.swing.tree.TreePath;
|
||||||
@ -66,7 +69,7 @@ public class FileTree extends JTree {
|
|||||||
return file.getFile();
|
return file.getFile();
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}).collect(toList());
|
}).filter(f -> f != null && f.exists()).collect(toList());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void clear() {
|
public void clear() {
|
||||||
@ -109,6 +112,9 @@ public class FileTree extends JTree {
|
|||||||
|
|
||||||
add(newAction("Expand all", ResourceManager.getIcon("tree.expand"), evt -> expandAll()));
|
add(newAction("Expand all", ResourceManager.getIcon("tree.expand"), evt -> expandAll()));
|
||||||
add(newAction("Collapse all", ResourceManager.getIcon("tree.collapse"), evt -> collapseAll()));
|
add(newAction("Collapse all", ResourceManager.getIcon("tree.collapse"), evt -> collapseAll()));
|
||||||
|
|
||||||
|
addSeparator();
|
||||||
|
add(new TrashAction(selectedFiles));
|
||||||
}
|
}
|
||||||
|
|
||||||
private Collection<File> getFiles(TreePath[] selection) {
|
private Collection<File> getFiles(TreePath[] selection) {
|
||||||
@ -148,6 +154,31 @@ public class FileTree extends JTree {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private class TrashAction extends AbstractAction {
|
||||||
|
|
||||||
|
private Collection<File> files;
|
||||||
|
|
||||||
|
public TrashAction(Collection<File> files) {
|
||||||
|
super("Move to Trash");
|
||||||
|
this.files = files;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void actionPerformed(ActionEvent event) {
|
||||||
|
try {
|
||||||
|
for (File f : files) {
|
||||||
|
UserFiles.trash(f);
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.log(Level.SEVERE, e, e::toString);
|
||||||
|
}
|
||||||
|
|
||||||
|
// reload file tree after files have been deleted
|
||||||
|
FilterPanel parent = (FilterPanel) SwingUtilities.getAncestorOfClass(FilterPanel.class, FileTree.this);
|
||||||
|
parent.reload();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private class ImportAction extends AbstractAction {
|
private class ImportAction extends AbstractAction {
|
||||||
|
|
||||||
private PanelBuilder panel;
|
private PanelBuilder panel;
|
||||||
|
@ -1,12 +1,16 @@
|
|||||||
package net.filebot.ui.filter;
|
package net.filebot.ui.filter;
|
||||||
|
|
||||||
|
import static net.filebot.Logging.*;
|
||||||
|
|
||||||
import java.awt.datatransfer.Transferable;
|
import java.awt.datatransfer.Transferable;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
|
||||||
import javax.swing.JComponent;
|
import javax.swing.JComponent;
|
||||||
import javax.swing.JTabbedPane;
|
import javax.swing.JTabbedPane;
|
||||||
|
|
||||||
import com.google.common.eventbus.Subscribe;
|
import com.google.common.eventbus.Subscribe;
|
||||||
|
|
||||||
|
import net.filebot.ui.transfer.FileTransferable;
|
||||||
import net.filebot.ui.transfer.TransferablePolicy;
|
import net.filebot.ui.transfer.TransferablePolicy;
|
||||||
import net.filebot.ui.transfer.TransferablePolicy.TransferAction;
|
import net.filebot.ui.transfer.TransferablePolicy.TransferAction;
|
||||||
import net.miginfocom.swing.MigLayout;
|
import net.miginfocom.swing.MigLayout;
|
||||||
@ -34,6 +38,14 @@ public class FilterPanel extends JComponent {
|
|||||||
toolsPanel.addTab(tool.getName(), tool);
|
toolsPanel.addTab(tool.getName(), tool);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void reload() {
|
||||||
|
try {
|
||||||
|
fileTreePanel.getTransferablePolicy().handleTransferable(new FileTransferable(fileTreePanel.getFileTree().getRoot()), TransferAction.PUT);
|
||||||
|
} catch (Exception e) {
|
||||||
|
debug.log(Level.WARNING, e, e::toString);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Subscribe
|
@Subscribe
|
||||||
public void handle(Transferable transferable) throws Exception {
|
public void handle(Transferable transferable) throws Exception {
|
||||||
TransferablePolicy handler = fileTreePanel.getTransferablePolicy();
|
TransferablePolicy handler = fileTreePanel.getTransferablePolicy();
|
||||||
|
@ -85,14 +85,15 @@ class TypeTool extends Tool<TreeModel> {
|
|||||||
|
|
||||||
public Map<String, FileFilter> getMetaTypes() {
|
public Map<String, FileFilter> getMetaTypes() {
|
||||||
Map<String, FileFilter> types = new LinkedHashMap<String, FileFilter>();
|
Map<String, FileFilter> types = new LinkedHashMap<String, FileFilter>();
|
||||||
types.put("Movie", (f) -> MediaDetection.isMovie(f, true));
|
types.put("Movie", f -> MediaDetection.isMovie(f, true));
|
||||||
types.put("Episode", (f) -> MediaDetection.isEpisode(f, true));
|
types.put("Episode", f -> MediaDetection.isEpisode(f, true));
|
||||||
|
types.put("Extras", MediaDetection.getClutterFileFilter());
|
||||||
types.put("Video", MediaTypes.VIDEO_FILES);
|
types.put("Video", MediaTypes.VIDEO_FILES);
|
||||||
types.put("Subtitle", MediaTypes.SUBTITLE_FILES);
|
types.put("Subtitle", MediaTypes.SUBTITLE_FILES);
|
||||||
types.put("Audio", MediaTypes.AUDIO_FILES);
|
types.put("Audio", MediaTypes.AUDIO_FILES);
|
||||||
types.put("Archive", MediaTypes.ARCHIVE_FILES);
|
types.put("Archive", MediaTypes.ARCHIVE_FILES);
|
||||||
types.put("Verification", MediaTypes.VERIFICATION_FILES);
|
types.put("Verification", MediaTypes.VERIFICATION_FILES);
|
||||||
types.put("Clutter", MediaDetection.getClutterFileFilter());
|
types.put("Clutter", MediaDetection.getClutterTypeFilter());
|
||||||
types.put("Disk Folder", MediaDetection.getDiskFolderFilter());
|
types.put("Disk Folder", MediaDetection.getDiskFolderFilter());
|
||||||
return types;
|
return types;
|
||||||
}
|
}
|
||||||
|
@ -853,11 +853,11 @@ public final class FileUtilities {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class RegexFileFilter implements FileFilter, FilenameFilter {
|
public static class RegexMatchFilter implements FileFilter, FilenameFilter {
|
||||||
|
|
||||||
private final Pattern pattern;
|
private final Pattern pattern;
|
||||||
|
|
||||||
public RegexFileFilter(Pattern pattern) {
|
public RegexMatchFilter(Pattern pattern) {
|
||||||
this.pattern = pattern;
|
this.pattern = pattern;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -872,6 +872,25 @@ public final class FileUtilities {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static class RegexFindFilter implements FileFilter, FilenameFilter {
|
||||||
|
|
||||||
|
private final Pattern pattern;
|
||||||
|
|
||||||
|
public RegexFindFilter(Pattern pattern) {
|
||||||
|
this.pattern = pattern;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean accept(File dir, String name) {
|
||||||
|
return pattern.matcher(name).find();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean accept(File file) {
|
||||||
|
return accept(file.getParentFile(), file.getName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static final Comparator<File> CASE_INSENSITIVE_PATH_ORDER = comparing(File::getPath, String.CASE_INSENSITIVE_ORDER);
|
public static final Comparator<File> CASE_INSENSITIVE_PATH_ORDER = comparing(File::getPath, String.CASE_INSENSITIVE_ORDER);
|
||||||
|
|
||||||
public static final Comparator<File> HUMAN_NAME_ORDER = comparing(File::getName, new AlphanumComparator(Locale.ENGLISH));
|
public static final Comparator<File> HUMAN_NAME_ORDER = comparing(File::getName, new AlphanumComparator(Locale.ENGLISH));
|
||||||
|
Loading…
x
Reference in New Issue
Block a user