* support SubtitleNaming options for subtitle file naming

This commit is contained in:
Reinhard Pointner 2014-01-02 19:22:05 +00:00
parent a61fb4e70a
commit 4f3c709d17
7 changed files with 64 additions and 46 deletions

View File

@ -78,9 +78,9 @@ public class ArgumentProcessor {
}
if (args.getSubtitles) {
files.addAll(cli.getSubtitles(files, args.db, args.query, args.lang, args.output, args.encoding, !args.nonStrict));
files.addAll(cli.getSubtitles(files, args.db, args.query, args.lang, args.output, args.encoding, args.format, !args.nonStrict));
} else if (args.getMissingSubtitles) {
files.addAll(cli.getMissingSubtitles(files, args.db, args.query, args.lang, args.output, args.encoding, !args.nonStrict));
files.addAll(cli.getMissingSubtitles(files, args.db, args.query, args.lang, args.output, args.encoding, args.format, !args.nonStrict));
}
if (args.rename) {

View File

@ -1,7 +1,5 @@
package net.sourceforge.filebot.cli;
import java.io.File;
import java.io.FileFilter;
import java.util.Collection;
@ -9,30 +7,22 @@ import java.util.List;
import net.sourceforge.filebot.RenameAction;
public interface CmdlineInterface {
List<File> rename(Collection<File> files, RenameAction action, String conflict, String output, String format, String db, String query, String sortOrder, String filter, String lang, boolean strict) throws Exception;
List<File> getSubtitles(Collection<File> files, String db, String query, String lang, String output, String encoding, boolean strict) throws Exception;
List<File> getMissingSubtitles(Collection<File> files, String db, String query, String lang, String output, String encoding, boolean strict) throws Exception;
List<File> getSubtitles(Collection<File> files, String db, String query, String lang, String output, String encoding, String format, boolean strict) throws Exception;
List<File> getMissingSubtitles(Collection<File> files, String db, String query, String lang, String output, String encoding, String format, boolean strict) throws Exception;
boolean check(Collection<File> files) throws Exception;
File compute(Collection<File> files, String output, String encoding) throws Exception;
List<String> fetchEpisodeList(String query, String format, String db, String sortOrder, String lang) throws Exception;
String getMediaInfo(File file, String format) throws Exception;
List<File> extract(Collection<File> files, String output, String conflict, FileFilter filter, boolean forceExtractAll) throws Exception;
}

View File

@ -58,6 +58,7 @@ import net.sourceforge.filebot.similarity.SeriesNameMatcher;
import net.sourceforge.filebot.similarity.SimilarityComparator;
import net.sourceforge.filebot.similarity.SimilarityMetric;
import net.sourceforge.filebot.subtitle.SubtitleFormat;
import net.sourceforge.filebot.subtitle.SubtitleNaming;
import net.sourceforge.filebot.vfs.MemoryFile;
import net.sourceforge.filebot.web.AudioTrack;
import net.sourceforge.filebot.web.Episode;
@ -641,9 +642,10 @@ public class CmdlineOperations implements CmdlineInterface {
}
@Override
public List<File> getSubtitles(Collection<File> files, String db, String query, String languageName, String output, String csn, boolean strict) throws Exception {
public List<File> getSubtitles(Collection<File> files, String db, String query, String languageName, String output, String csn, String format, boolean strict) throws Exception {
final Language language = getLanguage(languageName);
final Pattern databaseFilter = (db != null) ? Pattern.compile(db, Pattern.CASE_INSENSITIVE) : null;
final SubtitleNaming naming = getSubtitleNaming(format);
CLILogger.finest(String.format("Get [%s] subtitles for %d files", language.getName(), files.size()));
// when rewriting subtitles to target format an encoding must be defined, default to UTF-8
@ -669,7 +671,7 @@ public class CmdlineOperations implements CmdlineInterface {
try {
CLILogger.fine("Looking up subtitles by filehash via " + service.getName());
Map<File, SubtitleDescriptor> subtitles = lookupSubtitleByHash(service, language, remainingVideos);
Map<File, File> downloads = downloadSubtitleBatch(service.getName(), subtitles, outputFormat, outputEncoding);
Map<File, File> downloads = downloadSubtitleBatch(service.getName(), subtitles, outputFormat, outputEncoding, naming);
remainingVideos.removeAll(downloads.keySet());
subtitleFiles.addAll(downloads.values());
} catch (Exception e) {
@ -714,7 +716,7 @@ public class CmdlineOperations implements CmdlineInterface {
try {
CLILogger.fine(format("Searching for %s at [%s]", querySet, service.getName()));
Map<File, SubtitleDescriptor> subtitles = lookupSubtitleByFileName(service, querySet, language, remainingVideos, strict);
Map<File, File> downloads = downloadSubtitleBatch(service.getName(), subtitles, outputFormat, outputEncoding);
Map<File, File> downloads = downloadSubtitleBatch(service.getName(), subtitles, outputFormat, outputEncoding, naming);
remainingVideos.removeAll(downloads.keySet());
subtitleFiles.addAll(downloads.values());
} catch (Exception e) {
@ -734,12 +736,14 @@ public class CmdlineOperations implements CmdlineInterface {
}
@Override
public List<File> getMissingSubtitles(Collection<File> files, String db, String query, final String languageName, String output, String csn, boolean strict) throws Exception {
public List<File> getMissingSubtitles(Collection<File> files, String db, String query, final String languageName, String output, String csn, final String format, boolean strict) throws Exception {
List<File> videoFiles = filter(filter(files, VIDEO_FILES), new FileFilter() {
// save time on repeating filesystem calls
private final Map<File, File[]> cache = new HashMap<File, File[]>();
private final SubtitleNaming naming = getSubtitleNaming(format);
// get language code suffix for given language (.eng)
private final String languageCodeSuffix = "." + Language.getISO3LanguageCodeByName(getLanguage(languageName).getName());
@ -752,10 +756,17 @@ public class CmdlineOperations implements CmdlineInterface {
}
for (File subtitle : subtitlesByFolder) {
if (isDerived(subtitle, video) && (subtitle.getName().contains(languageCodeSuffix)))
// can't tell which subtitle belongs to which file -> if any subtitles exist skip the whole folder
if (naming == SubtitleNaming.ORIGINAL) {
return false;
} else if (isDerived(subtitle, video)) {
if (naming == SubtitleNaming.MATCH_VIDEO) {
return false;
} else if (subtitle.getName().contains(languageCodeSuffix)) {
return false;
}
}
}
return true;
}
});
@ -765,16 +776,25 @@ public class CmdlineOperations implements CmdlineInterface {
return emptyList();
}
return getSubtitles(videoFiles, db, query, languageName, output, csn, strict);
return getSubtitles(videoFiles, db, query, languageName, output, csn, format, strict);
}
private Map<File, File> downloadSubtitleBatch(String service, Map<File, SubtitleDescriptor> subtitles, SubtitleFormat outputFormat, Charset outputEncoding) {
private SubtitleNaming getSubtitleNaming(String format) {
SubtitleNaming naming = SubtitleNaming.forName(format);
if (naming != null) {
return naming;
} else {
return SubtitleNaming.MATCH_VIDEO_ADD_LANGUAGE_TAG;
}
}
private Map<File, File> downloadSubtitleBatch(String service, Map<File, SubtitleDescriptor> subtitles, SubtitleFormat outputFormat, Charset outputEncoding, SubtitleNaming naming) {
Map<File, File> downloads = new HashMap<File, File>();
// fetch subtitle
for (Entry<File, SubtitleDescriptor> it : subtitles.entrySet()) {
try {
downloads.put(it.getKey(), downloadSubtitle(it.getValue(), it.getKey(), outputFormat, outputEncoding));
downloads.put(it.getKey(), downloadSubtitle(it.getValue(), it.getKey(), outputFormat, outputEncoding, naming));
Analytics.trackEvent(service, "DownloadSubtitle", it.getValue().getLanguageName(), 1);
} catch (Exception e) {
CLILogger.warning(format("Failed to download %s: %s", it.getValue().getPath(), e.getMessage()));
@ -784,13 +804,12 @@ public class CmdlineOperations implements CmdlineInterface {
return downloads;
}
private File downloadSubtitle(SubtitleDescriptor descriptor, File movieFile, SubtitleFormat outputFormat, Charset outputEncoding) throws Exception {
private File downloadSubtitle(SubtitleDescriptor descriptor, File movieFile, SubtitleFormat outputFormat, Charset outputEncoding, SubtitleNaming naming) throws Exception {
// fetch subtitle archive
CLILogger.config(format("Fetching [%s]", descriptor.getPath()));
MemoryFile subtitleFile = fetchSubtitle(descriptor);
// subtitle filename is based on movie filename
String base = getName(movieFile);
String ext = getExtension(subtitleFile.getName());
ByteBuffer data = subtitleFile.getData();
@ -803,7 +822,7 @@ public class CmdlineOperations implements CmdlineInterface {
data = exportSubtitles(subtitleFile, outputFormat, 0, outputEncoding);
}
File destination = new File(movieFile.getParentFile(), formatSubtitle(base, descriptor.getLanguageName(), ext));
File destination = new File(movieFile.getParentFile(), naming.format(movieFile, descriptor, ext));
CLILogger.info(format("Writing [%s] to [%s]", subtitleFile.getName(), destination.getName()));
writeFile(data, destination);

View File

@ -283,13 +283,13 @@ def rename(args) { args = _defaults(args)
def getSubtitles(args) { args = _defaults(args)
synchronized (_cli) {
_guarded { _cli.getSubtitles(_files(args), args.db as String, args.query as String, args.lang as String, args.output as String, args.encoding as String, args.strict as Boolean) }
_guarded { _cli.getSubtitles(_files(args), args.db as String, args.query as String, args.lang as String, args.output as String, args.encoding as String, args.format as String, args.strict as Boolean) }
}
}
def getMissingSubtitles(args) { args = _defaults(args)
synchronized (_cli) {
_guarded { _cli.getMissingSubtitles(_files(args), args.db as String, args.query as String, args.lang as String, args.output as String, args.encoding as String, args.strict as Boolean) }
_guarded { _cli.getMissingSubtitles(_files(args), args.db as String, args.query as String, args.lang as String, args.output as String, args.encoding as String, args.format as String, args.strict as Boolean) }
}
}

View File

@ -220,7 +220,7 @@ def csv(path, delim = ';', keyIndex = 0, valueIndex = 1) {
def f = path as File
def values = [:]
if (f.isFile()) {
f.splitEachLine(delim) { line ->
f.splitEachLine(delim, 'UTF-8') { line ->
values.put(line[keyIndex], c{ line[valueIndex] })
}
}

View File

@ -11,8 +11,8 @@ public enum SubtitleNaming {
ORIGINAL {
@Override
public String format(File video, SubtitleDescriptor subtitle) {
return String.format("%s.%s", getName(video), subtitle.getType());
public String format(File video, SubtitleDescriptor subtitle, String ext) {
return String.format("%s.%s", subtitle.getName(), ext);
}
@Override
@ -24,8 +24,8 @@ public enum SubtitleNaming {
MATCH_VIDEO {
@Override
public String format(File video, SubtitleDescriptor subtitle) {
return SubtitleUtilities.formatSubtitle(getName(video), null, subtitle.getType());
public String format(File video, SubtitleDescriptor subtitle, String ext) {
return SubtitleUtilities.formatSubtitle(getName(video), null, ext);
}
@Override
@ -37,8 +37,8 @@ public enum SubtitleNaming {
MATCH_VIDEO_ADD_LANGUAGE_TAG {
@Override
public String format(File video, SubtitleDescriptor subtitle) {
return SubtitleUtilities.formatSubtitle(getName(video), subtitle.getLanguageName(), subtitle.getType());
public String format(File video, SubtitleDescriptor subtitle, String ext) {
return SubtitleUtilities.formatSubtitle(getName(video), subtitle.getLanguageName(), ext);
}
@Override
@ -47,6 +47,15 @@ public enum SubtitleNaming {
}
};
public abstract String format(File video, SubtitleDescriptor subtitle);
public abstract String format(File video, SubtitleDescriptor subtitle, String ext);
public static SubtitleNaming forName(String s) {
for (SubtitleNaming it : values()) {
if (it.name().equalsIgnoreCase(s) || it.toString().equalsIgnoreCase(s)) {
return it;
}
}
return null;
}
}

View File

@ -794,7 +794,7 @@ class SubtitleAutoMatchDialog extends JDialog {
return null;
// prefer type from descriptor because we need to know before we download the actual subtitle file
String name = naming.format(video, descriptor.getDescriptor());
String name = naming.format(video, descriptor.getDescriptor(), descriptor.getType());
return new File(video.getParentFile(), name);
}