diff --git a/source/net/sourceforge/filebot/cli/ArgumentBean.java b/source/net/sourceforge/filebot/cli/ArgumentBean.java index 4d7fa8bc..7016b253 100644 --- a/source/net/sourceforge/filebot/cli/ArgumentBean.java +++ b/source/net/sourceforge/filebot/cli/ArgumentBean.java @@ -37,6 +37,9 @@ public class ArgumentBean { @Option(name = "-get-subtitles", usage = "Fetch subtitles", metaVar = "fileset") public boolean getSubtitles; + @Option(name = "-get-missing-subtitles", usage = "Fetch missing subtitles", metaVar = "fileset") + public boolean getMissingSubtitles; + @Option(name = "--q", usage = "Search query", metaVar = "title") public String query; @@ -84,7 +87,7 @@ public class ArgumentBean { public boolean runCLI() { - return rename || getSubtitles || check || list || mediaInfo || script != null; + return rename || getSubtitles || getMissingSubtitles || check || list || mediaInfo || script != null; } diff --git a/source/net/sourceforge/filebot/cli/ArgumentProcessor.java b/source/net/sourceforge/filebot/cli/ArgumentProcessor.java index e1e64cc7..7b7d3399 100644 --- a/source/net/sourceforge/filebot/cli/ArgumentProcessor.java +++ b/source/net/sourceforge/filebot/cli/ArgumentProcessor.java @@ -9,7 +9,6 @@ import java.io.File; import java.io.InputStreamReader; import java.security.AccessController; import java.util.LinkedHashSet; -import java.util.List; import java.util.Set; import javax.script.Bindings; @@ -63,8 +62,9 @@ public class ArgumentProcessor { Set files = new LinkedHashSet(args.getFiles(true)); if (args.getSubtitles) { - List subtitles = cli.getSubtitles(files, args.query, args.lang, args.output, args.encoding, !args.nonStrict); - files.addAll(subtitles); + files.addAll(cli.getSubtitles(files, args.query, args.lang, args.output, args.encoding, !args.nonStrict)); + } else if (args.getMissingSubtitles) { + files.addAll(cli.getMissingSubtitles(files, args.query, args.lang, args.output, args.encoding, !args.nonStrict)); } if (args.rename) { diff --git a/source/net/sourceforge/filebot/cli/CmdlineInterface.java b/source/net/sourceforge/filebot/cli/CmdlineInterface.java index d7fad084..84757090 100644 --- a/source/net/sourceforge/filebot/cli/CmdlineInterface.java +++ b/source/net/sourceforge/filebot/cli/CmdlineInterface.java @@ -15,6 +15,9 @@ public interface CmdlineInterface { List getSubtitles(Collection files, String query, String lang, String output, String encoding, boolean strict) throws Exception; + List getMissingSubtitles(Collection files, String query, String lang, String output, String encoding, boolean strict) throws Exception; + + boolean check(Collection files) throws Exception; diff --git a/source/net/sourceforge/filebot/cli/CmdlineOperations.java b/source/net/sourceforge/filebot/cli/CmdlineOperations.java index 8d7fc56e..7e53b5d7 100644 --- a/source/net/sourceforge/filebot/cli/CmdlineOperations.java +++ b/source/net/sourceforge/filebot/cli/CmdlineOperations.java @@ -13,6 +13,7 @@ import static net.sourceforge.filebot.subtitle.SubtitleUtilities.*; import static net.sourceforge.tuned.FileUtilities.*; import java.io.File; +import java.io.FileFilter; import java.io.IOException; import java.nio.ByteBuffer; import java.nio.charset.Charset; @@ -451,6 +452,40 @@ public class CmdlineOperations implements CmdlineInterface { } + public List getMissingSubtitles(Collection files, String query, String languageName, String output, String csn, boolean strict) throws Exception { + List videoFiles = filter(filter(files, VIDEO_FILES), new FileFilter() { + + // save time on repeating filesystem calls + private final Map cache = new HashMap(); + + + @Override + public boolean accept(File video) { + File[] subtitlesByFolder = cache.get(video.getParentFile()); + if (subtitlesByFolder == null) { + subtitlesByFolder = video.getParentFile().listFiles(SUBTITLE_FILES); + cache.put(video.getParentFile(), subtitlesByFolder); + } + + for (File subtitle : subtitlesByFolder) { + if (isDerived(subtitle, video)) + return false; + } + + return true; + } + }); + + if (videoFiles.isEmpty()) { + CLILogger.info("No missing subtitles"); + return emptyList(); + } + + CLILogger.finest(format("Missing subtitles for %d video files", videoFiles.size())); + return getSubtitles(videoFiles, query, languageName, output, csn, strict); + } + + private File downloadSubtitle(SubtitleDescriptor descriptor, File movieFile, SubtitleFormat outputFormat, Charset outputEncoding) throws Exception { // fetch subtitle archive CLILogger.info(format("Fetching [%s]", descriptor.getPath()));