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:
Reinhard Pointner 2018-12-20 18:22:53 +07:00
parent c856fc9638
commit dd95a40d11
7 changed files with 97 additions and 16 deletions

View File

@ -85,6 +85,10 @@ public class MediaDetection {
return releaseInfo.getClutterFileFilter();
}
public static FileFilter getClutterTypeFilter() {
return releaseInfo.getClutterTypeFilter();
}
public static boolean isDiskFolder(File folder) {
return getDiskFolderFilter().accept(folder);
}

View File

@ -44,7 +44,8 @@ import net.filebot.ApplicationFolder;
import net.filebot.Cache;
import net.filebot.CacheType;
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.web.Movie;
import net.filebot.web.SearchResult;
@ -393,29 +394,38 @@ public class ReleaseInfo {
return diskFolderFilter;
}
private static RegexFileFilter diskFolderEntryFilter;
private static RegexMatchFilter diskFolderEntryFilter;
public FileFilter getDiskFolderEntryFilter() {
if (diskFolderEntryFilter == null) {
diskFolderEntryFilter = new RegexFileFilter(compile(getProperty("pattern.diskfolder.entry")));
diskFolderEntryFilter = new RegexMatchFilter(compile(getProperty("pattern.diskfolder.entry")));
}
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;
public FileFilter getClutterFileFilter() {
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;
}
private static RegexFileFilter systemFilesFilter;
private static RegexMatchFilter systemFilesFilter;
public FileFilter getSystemFilesFilter() {
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;
}
@ -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;
public ClutterFileFilter(Pattern namePattern, long maxFileSize) {
super(namePattern);
public ClutterFileFilter(FileFilter filter, long maxFileSize) {
this.filter = filter;
this.maxFileSize = maxFileSize;
}
@Override
public boolean accept(File file) {
return super.accept(file) && file.isFile() && file.length() < maxFileSize;
return filter.accept(file) && file.isFile() && file.length() < maxFileSize;
}
}

View File

@ -19,6 +19,9 @@ pattern.video.format: DivX[345]?|Xvid|AVC|(x|h)[.]?(264|265)|HEVC|3ivx|PGS|MP[E]
# 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
# 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
number.clutter.maxfilesize: 150000000

View File

@ -2,6 +2,7 @@ package net.filebot.ui.filter;
import static java.util.Collections.*;
import static java.util.stream.Collectors.*;
import static net.filebot.Logging.*;
import static net.filebot.util.ui.SwingUI.*;
import java.awt.event.ActionEvent;
@ -14,12 +15,14 @@ import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
import java.util.logging.Level;
import javax.swing.AbstractAction;
import javax.swing.JMenu;
import javax.swing.JMenuItem;
import javax.swing.JPopupMenu;
import javax.swing.JTree;
import javax.swing.SwingUtilities;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreeNode;
import javax.swing.tree.TreePath;
@ -66,7 +69,7 @@ public class FileTree extends JTree {
return file.getFile();
}
return null;
}).collect(toList());
}).filter(f -> f != null && f.exists()).collect(toList());
}
public void clear() {
@ -109,6 +112,9 @@ public class FileTree extends JTree {
add(newAction("Expand all", ResourceManager.getIcon("tree.expand"), evt -> expandAll()));
add(newAction("Collapse all", ResourceManager.getIcon("tree.collapse"), evt -> collapseAll()));
addSeparator();
add(new TrashAction(selectedFiles));
}
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 PanelBuilder panel;

View File

@ -1,12 +1,16 @@
package net.filebot.ui.filter;
import static net.filebot.Logging.*;
import java.awt.datatransfer.Transferable;
import java.util.logging.Level;
import javax.swing.JComponent;
import javax.swing.JTabbedPane;
import com.google.common.eventbus.Subscribe;
import net.filebot.ui.transfer.FileTransferable;
import net.filebot.ui.transfer.TransferablePolicy;
import net.filebot.ui.transfer.TransferablePolicy.TransferAction;
import net.miginfocom.swing.MigLayout;
@ -34,6 +38,14 @@ public class FilterPanel extends JComponent {
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
public void handle(Transferable transferable) throws Exception {
TransferablePolicy handler = fileTreePanel.getTransferablePolicy();

View File

@ -85,14 +85,15 @@ class TypeTool extends Tool<TreeModel> {
public Map<String, FileFilter> getMetaTypes() {
Map<String, FileFilter> types = new LinkedHashMap<String, FileFilter>();
types.put("Movie", (f) -> MediaDetection.isMovie(f, true));
types.put("Episode", (f) -> MediaDetection.isEpisode(f, true));
types.put("Movie", f -> MediaDetection.isMovie(f, true));
types.put("Episode", f -> MediaDetection.isEpisode(f, true));
types.put("Extras", MediaDetection.getClutterFileFilter());
types.put("Video", MediaTypes.VIDEO_FILES);
types.put("Subtitle", MediaTypes.SUBTITLE_FILES);
types.put("Audio", MediaTypes.AUDIO_FILES);
types.put("Archive", MediaTypes.ARCHIVE_FILES);
types.put("Verification", MediaTypes.VERIFICATION_FILES);
types.put("Clutter", MediaDetection.getClutterFileFilter());
types.put("Clutter", MediaDetection.getClutterTypeFilter());
types.put("Disk Folder", MediaDetection.getDiskFolderFilter());
return types;
}

View File

@ -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;
public RegexFileFilter(Pattern pattern) {
public RegexMatchFilter(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> HUMAN_NAME_ORDER = comparing(File::getName, new AlphanumComparator(Locale.ENGLISH));