* extract only archives that contain at least one video file

This commit is contained in:
Reinhard Pointner 2012-07-31 16:17:15 +00:00
parent 87cfae4c76
commit 42ecf32100
6 changed files with 72 additions and 29 deletions

View File

@ -95,6 +95,27 @@ public class Archive implements Closeable {
}
public void extract(ExtractOutProvider outputMapper, FileFilter filter) throws SevenZipException {
List<Integer> selection = new ArrayList<Integer>();
for (int i = 0; i < inArchive.getNumberOfItems(); i++) {
boolean isFolder = (Boolean) inArchive.getProperty(i, PropID.IS_FOLDER);
if (!isFolder) {
String path = (String) inArchive.getProperty(i, PropID.PATH);
if (path != null && filter.accept(new File(path))) {
selection.add(i);
}
}
}
int[] indices = new int[selection.size()];
for (int i = 0; i < indices.length; i++) {
indices[i] = selection.get(i);
}
inArchive.extract(indices, false, new ExtractCallback(inArchive, outputMapper));
}
@Override
public void close() throws IOException {
try {
@ -121,7 +142,6 @@ public class Archive implements Closeable {
return extensions;
}
public static final FileFilter VOLUME_ONE_FILTER = new FileFilter() {
private Pattern volume = Pattern.compile("[.]r[0-9]+$|[.]part[0-9]+|[.][0-9]+$", Pattern.CASE_INSENSITIVE);

View File

@ -79,7 +79,7 @@ public class ArgumentProcessor {
Collection<File> files = new LinkedHashSet<File>(args.getFiles(true));
if (args.extract) {
files.addAll(cli.extract(files, args.output, args.conflict));
files.addAll(cli.extract(files, args.output, args.conflict, null, true));
}
if (args.getSubtitles) {

View File

@ -3,6 +3,7 @@ package net.sourceforge.filebot.cli;
import java.io.File;
import java.io.FileFilter;
import java.util.Collection;
import java.util.List;
@ -32,6 +33,6 @@ public interface CmdlineInterface {
String getMediaInfo(File file, String format) throws Exception;
List<File> extract(Collection<File> files, String output, String conflict) throws Exception;
List<File> extract(Collection<File> files, String output, String conflict, FileFilter filter, boolean forceExtractAll) throws Exception;
}

View File

@ -980,7 +980,7 @@ public class CmdlineOperations implements CmdlineInterface {
@Override
public List<File> extract(Collection<File> files, String output, String conflict) throws Exception {
public List<File> extract(Collection<File> files, String output, String conflict, FileFilter filter, boolean forceExtractAll) throws Exception {
ConflictAction conflictAction = ConflictAction.forName(conflict);
// only keep single-volume archives or first part of multi-volume archives
@ -995,22 +995,51 @@ public class CmdlineOperations implements CmdlineInterface {
outputFolder = new File(file.getParentFile(), outputFolder.getPath());
}
CLILogger.info(String.format("Extract archive [%s] to [%s]", file.getName(), outputFolder));
CLILogger.info(String.format("Read archive [%s] to [%s]", file.getName(), outputFolder));
FileMapper outputMapper = new FileMapper(outputFolder, false);
List<File> entries = archive.listFiles();
final List<File> outputMapping = new ArrayList<File>();
for (File entry : archive.listFiles()) {
outputMapping.add(outputMapper.getOutputFile(entry));
}
final Set<File> selection = new TreeSet<File>();
for (File future : outputMapping) {
if (filter == null || filter.accept(future)) {
selection.add(future);
}
}
// check if there is anything to extract at all
if (selection.isEmpty()) {
continue;
}
boolean skip = true;
for (File entry : entries) {
File outputFile = outputMapper.getOutputFile(entry);
skip &= outputFile.exists();
extractedFiles.add(outputFile);
for (File future : filter == null || forceExtractAll ? outputMapping : selection) {
skip &= future.exists();
}
if (!skip || conflictAction == ConflictAction.OVERRIDE) {
CLILogger.finest("Extracting files " + entries);
archive.extract(outputMapper);
if (filter == null || forceExtractAll) {
CLILogger.finest("Extracting files " + outputMapping);
// extract all files
archive.extract(outputMapper);
extractedFiles.addAll(outputMapping);
} else {
CLILogger.finest("Extracting files " + selection);
// extract files selected by the given filter
archive.extract(outputMapper, new FileFilter() {
@Override
public boolean accept(File entry) {
return selection.contains(entry);
}
});
extractedFiles.addAll(selection);
}
} else {
CLILogger.finest("Skipped extracting files " + entries);
CLILogger.finest("Skipped extracting files " + selection);
}
} finally {
archive.close();
@ -1019,5 +1048,4 @@ public class CmdlineOperations implements CmdlineInterface {
return extractedFiles;
}
}

View File

@ -264,7 +264,7 @@ def compute(args) { args = _defaults(args)
def extract(args) { args = _defaults(args)
synchronized (_cli) {
_guarded { _cli.extract(_files(args), args.output as String, args.conflict as String) }
_guarded { _cli.extract(_files(args), args.output as String, args.conflict as String, args.filter instanceof Closure ? args.filter as FileFilter : null, args.forceExtractAll != null ? args.forceExtractAll : false) }
}
}
@ -319,17 +319,10 @@ def _renameFunction(fn) {
* Fill in default values from cmdline arguments
*/
def _defaults(args) {
args.action = args.action ?: _args.action
args.conflict = args.conflict ?: _args.conflict
args.query = args.query ?: _args.query
args.filter = args.filter ?: _args.filter
args.format = args.format ?: _args.format
args.db = args.db ?: _args.db
args.order = args.order ?: _args.order
args.lang = args.lang ?: _args.lang
args.output = args.output ?: _args.output
args.encoding = args.encoding ?: _args.encoding
args.strict = args.strict != null ? args.strict : !_args.nonStrict
['action', 'conflict', 'query', 'filter', 'format', 'db', 'order', 'lang', 'output', 'encoding'].each{ k ->
args[k] = args.containsKey(k) ? args[k] : _args[k]
}
args.strict = args.strict != null ? args.strict : !_args.nonStrict // invert strict/non-strict
return args
}

View File

@ -47,11 +47,12 @@ if (args.empty) {
input += args.getFiles()
}
// extract archives if necessary
input += extract(file:input, output:".", conflict:"override")
// extract archives (zip, rar, etc) that contain at least one video file
input += extract(file: input.findAll{ it.isArchive() }, output: null, conflict: 'override', filter: { it.isVideo() }, forceExtractAll: true)
// process only media files
input = input.findAll{ it.isVideo() || it.isSubtitle() }
input = input.unique().findAll{ it.isVideo() || it.isSubtitle() }
// ignore clutter files
input = input.findAll{ !(it.path =~ /\b(?i:sample|trailer|extras|deleted.scenes|music.video|scrapbook)\b/) }