* support --filter in -rename movie-mode on query-based detection logic
This commit is contained in:
parent
4799476150
commit
3a8d8d22d5
|
@ -1,7 +1,5 @@
|
|||
|
||||
package net.sourceforge.filebot.cli;
|
||||
|
||||
|
||||
import static java.lang.String.format;
|
||||
import static java.util.Arrays.asList;
|
||||
import static java.util.Collections.addAll;
|
||||
|
@ -67,7 +65,6 @@ import java.util.AbstractMap.SimpleImmutableEntry;
|
|||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
|
@ -121,7 +118,6 @@ import net.sourceforge.filebot.web.SubtitleProvider;
|
|||
import net.sourceforge.filebot.web.VideoHashSubtitleService;
|
||||
import net.sourceforge.tuned.FileUtilities.ParentFilter;
|
||||
|
||||
|
||||
public class CmdlineOperations implements CmdlineInterface {
|
||||
|
||||
@Override
|
||||
|
@ -139,7 +135,7 @@ public class CmdlineOperations implements CmdlineInterface {
|
|||
|
||||
if (getMovieIdentificationService(db) != null) {
|
||||
// movie mode
|
||||
return renameMovie(files, action, conflictAction, outputDir, format, getMovieIdentificationService(db), query, locale, strict);
|
||||
return renameMovie(files, action, conflictAction, outputDir, format, getMovieIdentificationService(db), query, filter, locale, strict);
|
||||
}
|
||||
|
||||
if (getMusicIdentificationService(db) != null || containsOnly(files, AUDIO_FILES)) {
|
||||
|
@ -178,11 +174,10 @@ public class CmdlineOperations implements CmdlineInterface {
|
|||
if (sxe > (max * 0.65) || cws > (max * 0.65)) {
|
||||
return renameSeries(files, action, conflictAction, outputDir, format, WebServices.TheTVDB, query, SortOrder.forName(sortOrder), filter, locale, strict); // use default episode db
|
||||
} else {
|
||||
return renameMovie(files, action, conflictAction, outputDir, format, WebServices.TMDb, query, locale, strict); // use default movie db
|
||||
return renameMovie(files, action, conflictAction, outputDir, format, WebServices.TMDb, query, filter, locale, strict); // use default movie db
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public List<File> renameSeries(Collection<File> files, RenameAction renameAction, ConflictAction conflictAction, File outputDir, ExpressionFormat format, EpisodeListProvider db, String query, SortOrder sortOrder, ExpressionFilter filter, Locale locale, boolean strict) throws Exception {
|
||||
CLILogger.config(format("Rename episodes using [%s]", db.getName()));
|
||||
|
||||
|
@ -215,7 +210,7 @@ public class CmdlineOperations implements CmdlineInterface {
|
|||
}
|
||||
|
||||
// fetch episode data
|
||||
Set<Episode> episodes = fetchEpisodeSet(db, seriesNames, sortOrder, locale, strict);
|
||||
Collection<Episode> episodes = fetchEpisodeSet(db, seriesNames, sortOrder, locale, strict);
|
||||
|
||||
if (episodes.size() == 0) {
|
||||
CLILogger.warning("Failed to fetch episode data: " + seriesNames);
|
||||
|
@ -223,17 +218,7 @@ public class CmdlineOperations implements CmdlineInterface {
|
|||
}
|
||||
|
||||
// filter episodes
|
||||
if (filter != null) {
|
||||
CLILogger.fine(String.format("Apply Filter: {%s}", filter.getExpression()));
|
||||
for (Iterator<Episode> itr = episodes.iterator(); itr.hasNext();) {
|
||||
Episode episode = itr.next();
|
||||
if (filter.matches(new MediaBindingBean(episode, null, null))) {
|
||||
CLILogger.finest(String.format("Include [%s]", episode));
|
||||
} else {
|
||||
itr.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
episodes = applyExpressionFilter(episodes, filter);
|
||||
|
||||
matches.addAll(matchEpisodes(filter(batch, VIDEO_FILES), episodes, strict));
|
||||
matches.addAll(matchEpisodes(filter(batch, SUBTITLE_FILES), episodes, strict));
|
||||
|
@ -290,7 +275,6 @@ public class CmdlineOperations implements CmdlineInterface {
|
|||
return renameAll(renameMap, renameAction, conflictAction);
|
||||
}
|
||||
|
||||
|
||||
private List<Match<File, Object>> matchEpisodes(Collection<File> files, Collection<Episode> episodes, boolean strict) throws Exception {
|
||||
// always use strict fail-fast matcher
|
||||
EpisodeMatcher matcher = new EpisodeMatcher(files, episodes, strict);
|
||||
|
@ -303,7 +287,6 @@ public class CmdlineOperations implements CmdlineInterface {
|
|||
return matches;
|
||||
}
|
||||
|
||||
|
||||
private Set<Episode> fetchEpisodeSet(final EpisodeListProvider db, final Collection<String> names, final SortOrder sortOrder, final Locale locale, final boolean strict) throws Exception {
|
||||
Set<SearchResult> shows = new LinkedHashSet<SearchResult>();
|
||||
Set<Episode> episodes = new LinkedHashSet<Episode>();
|
||||
|
@ -335,8 +318,7 @@ public class CmdlineOperations implements CmdlineInterface {
|
|||
return episodes;
|
||||
}
|
||||
|
||||
|
||||
public List<File> renameMovie(Collection<File> files, RenameAction renameAction, ConflictAction conflictAction, File outputDir, ExpressionFormat format, MovieIdentificationService service, String query, Locale locale, boolean strict) throws Exception {
|
||||
public List<File> renameMovie(Collection<File> files, RenameAction renameAction, ConflictAction conflictAction, File outputDir, ExpressionFormat format, MovieIdentificationService service, String query, ExpressionFilter filter, Locale locale, boolean strict) throws Exception {
|
||||
CLILogger.config(format("Rename movies using [%s]", service.getName()));
|
||||
|
||||
// ignore sample files
|
||||
|
@ -379,7 +361,7 @@ public class CmdlineOperations implements CmdlineInterface {
|
|||
}
|
||||
Analytics.trackEvent(service.getName(), "HashLookup", "Movie", hashLookup.size()); // number of positive hash lookups
|
||||
} catch (UnsupportedOperationException e) {
|
||||
|
||||
// ignore logging => hash lookup only supported by OpenSubtitles
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -429,8 +411,15 @@ public class CmdlineOperations implements CmdlineInterface {
|
|||
}
|
||||
} else {
|
||||
CLILogger.fine(format("Looking up movie by query [%s]", query));
|
||||
Movie result = (Movie) selectSearchResult(query, service.searchMovie(query, locale), strict).get(0);
|
||||
List<Movie> results = service.searchMovie(query, locale);
|
||||
results = applyExpressionFilter(results, filter);
|
||||
|
||||
if (results.isEmpty()) {
|
||||
throw new Exception(format("Failed to look up movie by query [%s]", query));
|
||||
}
|
||||
|
||||
// force all mappings
|
||||
Movie result = (Movie) selectSearchResult(query, results, strict).get(0);
|
||||
for (File file : files) {
|
||||
movieByFile.put(file, result);
|
||||
}
|
||||
|
@ -459,6 +448,7 @@ public class CmdlineOperations implements CmdlineInterface {
|
|||
if (movie == null) {
|
||||
CLILogger.fine(format("Auto-detect movie from context: [%s]", file));
|
||||
Collection<Movie> results = detectMovie(file, null, service, locale, strict);
|
||||
results = applyExpressionFilter(results, filter);
|
||||
try {
|
||||
movie = (Movie) selectSearchResult(query, results, strict).get(0);
|
||||
} catch (Exception e) {
|
||||
|
@ -538,7 +528,6 @@ public class CmdlineOperations implements CmdlineInterface {
|
|||
return renameAll(renameMap, renameAction, conflictAction);
|
||||
}
|
||||
|
||||
|
||||
public List<File> renameMusic(Collection<File> files, RenameAction renameAction, ConflictAction conflictAction, File outputDir, ExpressionFormat format, MusicIdentificationService service) throws Exception {
|
||||
CLILogger.config(format("Rename music using [%s]", service.getName()));
|
||||
List<File> audioFiles = filter(files, AUDIO_FILES);
|
||||
|
@ -576,7 +565,6 @@ public class CmdlineOperations implements CmdlineInterface {
|
|||
return renameAll(renameMap, renameAction, conflictAction);
|
||||
}
|
||||
|
||||
|
||||
private Map<File, Object> getContext(final Collection<Match<File, ?>> matches) {
|
||||
return new AbstractMap<File, Object>() {
|
||||
|
||||
|
@ -593,7 +581,6 @@ public class CmdlineOperations implements CmdlineInterface {
|
|||
};
|
||||
}
|
||||
|
||||
|
||||
private File getDestinationFile(File original, String newName, File outputDir) {
|
||||
String extension = getExtension(original);
|
||||
File newFile = new File(extension != null ? newName + '.' + extension : newName);
|
||||
|
@ -611,7 +598,6 @@ public class CmdlineOperations implements CmdlineInterface {
|
|||
return newFile;
|
||||
}
|
||||
|
||||
|
||||
public List<File> renameAll(Map<File, File> renameMap, RenameAction renameAction, ConflictAction conflictAction) throws Exception {
|
||||
// rename files
|
||||
final List<Entry<File, File>> renameLog = new ArrayList<Entry<File, File>>();
|
||||
|
@ -674,7 +660,6 @@ public class CmdlineOperations implements CmdlineInterface {
|
|||
return destinationList;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public List<File> getSubtitles(Collection<File> files, String db, String query, String languageName, String output, String csn, boolean strict) throws Exception {
|
||||
final Language language = getLanguage(languageName);
|
||||
|
@ -768,7 +753,6 @@ public class CmdlineOperations implements CmdlineInterface {
|
|||
return subtitleFiles;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public List<File> getMissingSubtitles(Collection<File> files, String db, String query, final String languageName, String output, String csn, boolean strict) throws Exception {
|
||||
List<File> videoFiles = filter(filter(files, VIDEO_FILES), new FileFilter() {
|
||||
|
@ -779,7 +763,6 @@ public class CmdlineOperations implements CmdlineInterface {
|
|||
// get language code suffix for given language (.eng)
|
||||
private final String languageCodeSuffix = "." + Language.getISO3LanguageCodeByName(getLanguage(languageName).getName());
|
||||
|
||||
|
||||
@Override
|
||||
public boolean accept(File video) {
|
||||
File[] subtitlesByFolder = cache.get(video.getParentFile());
|
||||
|
@ -805,7 +788,6 @@ public class CmdlineOperations implements CmdlineInterface {
|
|||
return getSubtitles(videoFiles, db, query, languageName, output, csn, strict);
|
||||
}
|
||||
|
||||
|
||||
private Map<File, File> downloadSubtitleBatch(String service, Map<File, SubtitleDescriptor> subtitles, SubtitleFormat outputFormat, Charset outputEncoding) {
|
||||
Map<File, File> downloads = new HashMap<File, File>();
|
||||
|
||||
|
@ -822,7 +804,6 @@ public class CmdlineOperations implements CmdlineInterface {
|
|||
return downloads;
|
||||
}
|
||||
|
||||
|
||||
private File downloadSubtitle(SubtitleDescriptor descriptor, File movieFile, SubtitleFormat outputFormat, Charset outputEncoding) throws Exception {
|
||||
// fetch subtitle archive
|
||||
CLILogger.config(format("Fetching [%s]", descriptor.getPath()));
|
||||
|
@ -849,7 +830,6 @@ public class CmdlineOperations implements CmdlineInterface {
|
|||
return destination;
|
||||
}
|
||||
|
||||
|
||||
private Map<File, SubtitleDescriptor> lookupSubtitleByHash(VideoHashSubtitleService service, Language language, Collection<File> videoFiles) throws Exception {
|
||||
Map<File, SubtitleDescriptor> subtitleByVideo = new HashMap<File, SubtitleDescriptor>(videoFiles.size());
|
||||
|
||||
|
@ -863,7 +843,6 @@ public class CmdlineOperations implements CmdlineInterface {
|
|||
return subtitleByVideo;
|
||||
}
|
||||
|
||||
|
||||
private Map<File, SubtitleDescriptor> lookupSubtitleByFileName(SubtitleProvider service, Collection<String> querySet, Language language, Collection<File> videoFiles, boolean strict) throws Exception {
|
||||
// search for subtitles
|
||||
List<SubtitleDescriptor> subtitles = findSubtitles(service, querySet, language.getName());
|
||||
|
@ -880,7 +859,6 @@ public class CmdlineOperations implements CmdlineInterface {
|
|||
return emptyMap();
|
||||
}
|
||||
|
||||
|
||||
private List<String> detectSeriesQuery(Collection<File> mediaFiles, Locale locale) throws Exception {
|
||||
// detect series name by common word sequence
|
||||
List<String> names = detectSeriesNames(mediaFiles, locale);
|
||||
|
@ -893,6 +871,21 @@ public class CmdlineOperations implements CmdlineInterface {
|
|||
return names;
|
||||
}
|
||||
|
||||
private <T> List<T> applyExpressionFilter(Collection<T> input, ExpressionFilter filter) throws Exception {
|
||||
if (filter == null) {
|
||||
return new ArrayList<T>(input);
|
||||
}
|
||||
|
||||
CLILogger.fine(String.format("Apply Filter: {%s}", filter.getExpression()));
|
||||
List<T> output = new ArrayList<T>(input.size());
|
||||
for (T it : input) {
|
||||
if (filter.matches(new MediaBindingBean(it, null, null))) {
|
||||
CLILogger.finest(String.format("Include [%s]", it));
|
||||
output.add(it);
|
||||
}
|
||||
}
|
||||
return output;
|
||||
}
|
||||
|
||||
public List<SearchResult> findProbableMatches(final String query, Collection<? extends SearchResult> searchResults, boolean strict) {
|
||||
// auto-select most probable search result
|
||||
|
@ -918,7 +911,6 @@ public class CmdlineOperations implements CmdlineInterface {
|
|||
return probableMatches;
|
||||
}
|
||||
|
||||
|
||||
public List<SearchResult> selectSearchResult(String query, Collection<? extends SearchResult> searchResults, boolean strict) throws Exception {
|
||||
List<SearchResult> probableMatches = findProbableMatches(query, searchResults, strict);
|
||||
|
||||
|
@ -943,7 +935,6 @@ public class CmdlineOperations implements CmdlineInterface {
|
|||
return probableMatches.size() <= 5 ? probableMatches : probableMatches.subList(0, 5); // trust that the correct match is in the Top 3
|
||||
}
|
||||
|
||||
|
||||
private Language getLanguage(String lang) throws Exception {
|
||||
// try to look up by language code
|
||||
Language language = Language.getLanguage(lang);
|
||||
|
@ -961,7 +952,6 @@ public class CmdlineOperations implements CmdlineInterface {
|
|||
return language;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean check(Collection<File> files) throws Exception {
|
||||
// only check existing hashes
|
||||
|
@ -974,7 +964,6 @@ public class CmdlineOperations implements CmdlineInterface {
|
|||
return result;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public File compute(Collection<File> files, String output, String csn) throws Exception {
|
||||
// check common parent for all given files
|
||||
|
@ -1011,7 +1000,6 @@ public class CmdlineOperations implements CmdlineInterface {
|
|||
return outputFile;
|
||||
}
|
||||
|
||||
|
||||
private boolean check(File verificationFile, File root) throws Exception {
|
||||
HashType type = getHashType(verificationFile);
|
||||
|
||||
|
@ -1049,7 +1037,6 @@ public class CmdlineOperations implements CmdlineInterface {
|
|||
return status;
|
||||
}
|
||||
|
||||
|
||||
private void compute(String root, Collection<File> files, File outputFile, HashType hashType, String csn) throws IOException, Exception {
|
||||
// compute hashes recursively and write to file
|
||||
VerificationFileWriter out = new VerificationFileWriter(outputFile, hashType.getFormat(), csn != null ? csn : "UTF-8");
|
||||
|
@ -1074,7 +1061,6 @@ public class CmdlineOperations implements CmdlineInterface {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public List<String> fetchEpisodeList(String query, String expression, String db, String sortOrderName, String languageName) throws Exception {
|
||||
if (query == null || query.isEmpty())
|
||||
|
@ -1097,14 +1083,12 @@ public class CmdlineOperations implements CmdlineInterface {
|
|||
return episodes;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String getMediaInfo(File file, String expression) throws Exception {
|
||||
ExpressionFormat format = new ExpressionFormat(expression != null ? expression : "{fn} [{resolution} {af} {vc} {ac}]");
|
||||
return format.format(new MediaBindingBean(file, file, null));
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public List<File> extract(Collection<File> files, String output, String conflict, FileFilter filter, boolean forceExtractAll) throws Exception {
|
||||
ConflictAction conflictAction = ConflictAction.forName(conflict);
|
||||
|
|
Loading…
Reference in New Issue