Streamify -mediainfo and -list commands to make them more responsive when used on the command-line on large datasets

This commit is contained in:
Reinhard Pointner 2017-02-23 20:10:12 +08:00
parent bc910571ac
commit 9e13e1928e
5 changed files with 56 additions and 44 deletions

View File

@ -37,6 +37,7 @@ import net.filebot.hash.HashType;
import net.filebot.subtitle.SubtitleFormat; import net.filebot.subtitle.SubtitleFormat;
import net.filebot.subtitle.SubtitleNaming; import net.filebot.subtitle.SubtitleNaming;
import net.filebot.web.Datasource; import net.filebot.web.Datasource;
import net.filebot.web.EpisodeListProvider;
import net.filebot.web.SortOrder; import net.filebot.web.SortOrder;
public class ArgumentBean { public class ArgumentBean {
@ -227,6 +228,10 @@ public class ArgumentBean {
return db == null ? null : WebServices.getService(db); return db == null ? null : WebServices.getService(db);
} }
public EpisodeListProvider getEpisodeListProvider() {
return db == null ? WebServices.TheTVDB : WebServices.getEpisodeListProvider(db); // default to TheTVDB if --db is not set
}
public String getSearchQuery() { public String getSearchQuery() {
return query == null || query.isEmpty() ? null : query; return query == null || query.isEmpty() ? null : query;
} }

View File

@ -7,9 +7,9 @@ import static net.filebot.util.FileUtilities.*;
import java.io.File; import java.io.File;
import java.util.LinkedHashSet; import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set; import java.util.Set;
import java.util.logging.Level; import java.util.logging.Level;
import java.util.stream.Stream;
import javax.script.Bindings; import javax.script.Bindings;
import javax.script.SimpleBindings; import javax.script.SimpleBindings;
@ -55,7 +55,7 @@ public class ArgumentProcessor {
// print episode info // print episode info
if (args.list) { if (args.list) {
return print(cli.fetchEpisodeList(args.getDatasource(), args.getSearchQuery(), args.getExpressionFormat(), args.getExpressionFilter(), args.getSortOrder(), args.getLanguage().getLocale(), args.isStrict())); return print(cli.fetchEpisodeList(args.getEpisodeListProvider(), args.getSearchQuery(), args.getExpressionFormat(), args.getExpressionFilter(), args.getSortOrder(), args.getLanguage().getLocale(), args.isStrict()));
} }
// print media info // print media info
@ -97,19 +97,11 @@ public class ArgumentProcessor {
return 0; return 0;
} }
private int print(List<?> values) { private int print(Stream<?> values) {
int lines = 0; return values.mapToInt(v -> {
System.out.println(v);
for (int i = 0; i < values.size(); i++) { return 1;
try { }).sum() == 0 ? 1 : 0;
System.out.println(values.get(i));
lines++;
} catch (Exception e) {
debug.warning(e::getMessage);
}
}
return lines == 0 ? 1 : 0;
} }
public void runScript(CmdlineInterface cli, ArgumentBean args) throws Throwable { public void runScript(CmdlineInterface cli, ArgumentBean args) throws Throwable {

View File

@ -7,6 +7,7 @@ import java.util.Collection;
import java.util.List; import java.util.List;
import java.util.Locale; import java.util.Locale;
import java.util.Map; import java.util.Map;
import java.util.stream.Stream;
import net.filebot.Language; import net.filebot.Language;
import net.filebot.RenameAction; import net.filebot.RenameAction;
@ -16,6 +17,7 @@ import net.filebot.hash.HashType;
import net.filebot.subtitle.SubtitleFormat; import net.filebot.subtitle.SubtitleFormat;
import net.filebot.subtitle.SubtitleNaming; import net.filebot.subtitle.SubtitleNaming;
import net.filebot.web.Datasource; import net.filebot.web.Datasource;
import net.filebot.web.EpisodeListProvider;
import net.filebot.web.SortOrder; import net.filebot.web.SortOrder;
public interface CmdlineInterface { public interface CmdlineInterface {
@ -34,9 +36,9 @@ public interface CmdlineInterface {
File compute(Collection<File> files, File output, HashType hash, Charset encoding) throws Exception; File compute(Collection<File> files, File output, HashType hash, Charset encoding) throws Exception;
List<String> fetchEpisodeList(Datasource db, String query, ExpressionFormat format, ExpressionFilter filter, SortOrder order, Locale locale, boolean strict) throws Exception; Stream<String> fetchEpisodeList(EpisodeListProvider db, String query, ExpressionFormat format, ExpressionFilter filter, SortOrder order, Locale locale, boolean strict) throws Exception;
List<String> getMediaInfo(Collection<File> files, FileFilter filter, ExpressionFormat format) throws Exception; Stream<String> getMediaInfo(Collection<File> files, FileFilter filter, ExpressionFormat format) throws Exception;
List<File> extract(Collection<File> files, File output, ConflictAction conflict, FileFilter filter, boolean forceExtractAll) throws Exception; List<File> extract(Collection<File> files, File output, ConflictAction conflict, FileFilter filter, boolean forceExtractAll) throws Exception;

View File

@ -62,7 +62,6 @@ import net.filebot.subtitle.SubtitleFormat;
import net.filebot.subtitle.SubtitleNaming; import net.filebot.subtitle.SubtitleNaming;
import net.filebot.util.EntryList; import net.filebot.util.EntryList;
import net.filebot.util.FileUtilities.ParentFilter; import net.filebot.util.FileUtilities.ParentFilter;
import net.filebot.util.FunctionList;
import net.filebot.vfs.FileInfo; import net.filebot.vfs.FileInfo;
import net.filebot.vfs.MemoryFile; import net.filebot.vfs.MemoryFile;
import net.filebot.vfs.SimpleFileInfo; import net.filebot.vfs.SimpleFileInfo;
@ -986,55 +985,69 @@ public class CmdlineOperations implements CmdlineInterface {
} }
@Override @Override
public List<String> fetchEpisodeList(Datasource db, String query, ExpressionFormat format, ExpressionFilter filter, SortOrder order, Locale locale, boolean strict) throws Exception { public Stream<String> fetchEpisodeList(EpisodeListProvider db, String query, ExpressionFormat format, ExpressionFilter filter, SortOrder order, Locale locale, boolean strict) throws Exception {
if (query == null) { // default episode format
throw new IllegalArgumentException("query is not defined"); if (format == null) {
return fetchEpisodeList(db, query, new ExpressionFormat("{episode}"), filter, order, locale, strict);
} }
// find series on the web and fetch episode list // sanity check
EpisodeListProvider service = db instanceof EpisodeListProvider ? (EpisodeListProvider) db : TheTVDB; if (query == null) {
throw new CmdlineException(String.format("%s: query parameter is required", db.getName()));
}
// search and select search result // search and select search result
List<SearchResult> results = service.search(query, locale); List<SearchResult> results = db.search(query, locale);
// sanity check
if (results.isEmpty()) { if (results.isEmpty()) {
throw new CmdlineException(String.format("%s: no results", service.getName())); throw new CmdlineException(String.format("%s: no results", db.getName()));
} }
List<SearchResult> options = selectSearchResult(query, results, false, false, false, strict ? 1 : 5); List<SearchResult> options = selectSearchResult(query, results, false, false, false, strict ? 1 : 5);
List<Episode> episodes = new ArrayList<Episode>();
// fetch episodes // fetch episodes
List<Episode> episodes = new ArrayList<Episode>();
for (SearchResult option : options) { for (SearchResult option : options) {
episodes.addAll(service.getEpisodeList(option, order, locale)); episodes.addAll(db.getEpisodeList(option, order, locale));
} }
// apply filter // apply filter
episodes = applyExpressionFilter(episodes, filter); episodes = applyExpressionFilter(episodes, filter);
// lazy format
Map<File, Episode> context = new EntryList<File, Episode>(null, episodes); Map<File, Episode> context = new EntryList<File, Episode>(null, episodes);
// lazy format return episodes.stream().map(episode -> {
return new FunctionList<Episode, String>(episodes, e -> { try {
return format != null ? format.format(new MediaBindingBean(e, null, context)) : EpisodeFormat.SeasonEpisode.format(e); return format.format(new MediaBindingBean(episode, null, context));
}); } catch (Exception e) {
debug.warning(e::getMessage);
}
return null;
}).filter(Objects::nonNull);
} }
@Override @Override
public List<String> getMediaInfo(Collection<File> files, FileFilter filter, ExpressionFormat format) throws Exception { public Stream<String> getMediaInfo(Collection<File> files, FileFilter filter, ExpressionFormat format) throws Exception {
List<File> selection = filter(files, FILES); // use default file filter
if (filter == null) {
// apply custom filter return getMediaInfo(files, FILES, format);
if (filter != null) {
selection = filter(selection, filter);
} }
// default expression format if not set // use default expression format if not set
ExpressionFormat formatter = format != null ? format : new ExpressionFormat("{fn} [{resolution} {vc} {channels} {ac} {minutes}m]"); if (format == null) {
return getMediaInfo(files, filter, new ExpressionFormat("{fn} [{resolution} {vc} {channels} {ac} {minutes}m]"));
}
// lazy format return files.stream().filter(filter::accept).map(f -> {
return new FunctionList<File, String>(selection, f -> { try {
return formatter.format(new MediaBindingBean(xattr.getMetaInfo(f), f)); return format.format(new MediaBindingBean(xattr.getMetaInfo(f), f));
}); } catch (Exception e) {
debug.warning(e::getMessage);
}
return null;
}).filter(Objects::nonNull);
} }
@Override @Override

View File

@ -424,7 +424,7 @@ public abstract class ScriptShellBaseClass extends Script {
ArgumentBean args = getArgumentBean(parameters); ArgumentBean args = getArgumentBean(parameters);
try { try {
return getCLI().fetchEpisodeList(args.getDatasource(), args.getSearchQuery(), args.getExpressionFormat(), args.getExpressionFilter(), args.getSortOrder(), args.getLanguage().getLocale(), args.isStrict()); return getCLI().fetchEpisodeList(args.getEpisodeListProvider(), args.getSearchQuery(), args.getExpressionFormat(), args.getExpressionFilter(), args.getSortOrder(), args.getLanguage().getLocale(), args.isStrict()).collect(toList());
} catch (Exception e) { } catch (Exception e) {
printException(e); printException(e);
} }