Refactor CmdlineOperations
This commit is contained in:
parent
2f7ee58707
commit
ec44c7c38d
|
@ -69,10 +69,8 @@ import net.filebot.vfs.SimpleFileInfo;
|
||||||
import net.filebot.web.AudioTrack;
|
import net.filebot.web.AudioTrack;
|
||||||
import net.filebot.web.Datasource;
|
import net.filebot.web.Datasource;
|
||||||
import net.filebot.web.Episode;
|
import net.filebot.web.Episode;
|
||||||
import net.filebot.web.EpisodeFormat;
|
|
||||||
import net.filebot.web.EpisodeListProvider;
|
import net.filebot.web.EpisodeListProvider;
|
||||||
import net.filebot.web.Movie;
|
import net.filebot.web.Movie;
|
||||||
import net.filebot.web.MovieFormat;
|
|
||||||
import net.filebot.web.MovieIdentificationService;
|
import net.filebot.web.MovieIdentificationService;
|
||||||
import net.filebot.web.MoviePart;
|
import net.filebot.web.MoviePart;
|
||||||
import net.filebot.web.MusicIdentificationService;
|
import net.filebot.web.MusicIdentificationService;
|
||||||
|
@ -142,7 +140,7 @@ public class CmdlineOperations implements CmdlineInterface {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<File> rename(EpisodeListProvider db, String query, ExpressionFileFormat format, ExpressionFilter filter, SortOrder order, Locale locale, boolean strict, List<File> files, RenameAction action, ConflictAction conflict, File output) throws Exception {
|
public List<File> rename(EpisodeListProvider db, String query, ExpressionFileFormat format, ExpressionFilter filter, SortOrder order, Locale locale, boolean strict, List<File> files, RenameAction action, ConflictAction conflict, File outputDir) throws Exception {
|
||||||
// match files and episodes in linear order
|
// match files and episodes in linear order
|
||||||
List<Episode> episodes = fetchEpisodeList(db, query, filter, order, locale, strict);
|
List<Episode> episodes = fetchEpisodeList(db, query, filter, order, locale, strict);
|
||||||
|
|
||||||
|
@ -151,19 +149,8 @@ public class CmdlineOperations implements CmdlineInterface {
|
||||||
matches.add(new Match<File, Episode>(files.get(i), episodes.get(i)));
|
matches.add(new Match<File, Episode>(files.get(i), episodes.get(i)));
|
||||||
}
|
}
|
||||||
|
|
||||||
// map old files to new paths by applying formatting and validating filenames
|
|
||||||
Map<File, File> renameMap = new LinkedHashMap<File, File>();
|
|
||||||
|
|
||||||
for (Match<File, ?> match : matches) {
|
|
||||||
File file = match.getValue();
|
|
||||||
Object episode = match.getCandidate();
|
|
||||||
String newName = format != null ? format.format(new MediaBindingBean(episode, file, getContext(matches))) : validateFileName(EpisodeFormat.SeasonEpisode.format(episode));
|
|
||||||
|
|
||||||
renameMap.put(file, getDestinationFile(file, newName, output));
|
|
||||||
}
|
|
||||||
|
|
||||||
// rename episodes
|
// rename episodes
|
||||||
return renameAll(renameMap, action, conflict, matches);
|
return renameAll(formatMatches(matches, format, outputDir), action, conflict, matches);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -254,19 +241,8 @@ public class CmdlineOperations implements CmdlineInterface {
|
||||||
// add matches from other files that are linked via filenames
|
// add matches from other files that are linked via filenames
|
||||||
matches.addAll(derivateMatches);
|
matches.addAll(derivateMatches);
|
||||||
|
|
||||||
// map old files to new paths by applying formatting and validating filenames
|
|
||||||
Map<File, File> renameMap = new LinkedHashMap<File, File>();
|
|
||||||
|
|
||||||
for (Match<File, ?> match : matches) {
|
|
||||||
File file = match.getValue();
|
|
||||||
Object episode = match.getCandidate();
|
|
||||||
String newName = (format != null) ? format.format(new MediaBindingBean(episode, file, getContext(matches))) : validateFileName(EpisodeFormat.SeasonEpisode.format(episode));
|
|
||||||
|
|
||||||
renameMap.put(file, getDestinationFile(file, newName, outputDir));
|
|
||||||
}
|
|
||||||
|
|
||||||
// rename episodes
|
// rename episodes
|
||||||
return renameAll(renameMap, renameAction, conflictAction, matches);
|
return renameAll(formatMatches(matches, format, outputDir), renameAction, conflictAction, matches);
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<Match<File, Object>> matchEpisodes(Collection<File> files, Collection<Episode> episodes, boolean strict) throws Exception {
|
private List<Match<File, Object>> matchEpisodes(Collection<File> files, Collection<Episode> episodes, boolean strict) throws Exception {
|
||||||
|
@ -503,19 +479,8 @@ public class CmdlineOperations implements CmdlineInterface {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
// map old files to new paths by applying formatting and validating filenames
|
|
||||||
Map<File, File> renameMap = new LinkedHashMap<File, File>();
|
|
||||||
|
|
||||||
for (Match<File, ?> match : matches) {
|
|
||||||
File file = match.getValue();
|
|
||||||
Object movie = match.getCandidate();
|
|
||||||
String newName = (format != null) ? format.format(new MediaBindingBean(movie, file, getContext(matches))) : validateFileName(MovieFormat.NameYear.format(movie));
|
|
||||||
|
|
||||||
renameMap.put(file, getDestinationFile(file, newName, outputDir));
|
|
||||||
}
|
|
||||||
|
|
||||||
// rename movies
|
// rename movies
|
||||||
return renameAll(renameMap, renameAction, conflictAction, matches);
|
return renameAll(formatMatches(matches, format, outputDir), renameAction, conflictAction, matches);
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<File> renameMusic(Collection<File> files, RenameAction renameAction, ConflictAction conflictAction, File outputDir, ExpressionFileFormat format, MusicIdentificationService... services) throws Exception {
|
public List<File> renameMusic(Collection<File> files, RenameAction renameAction, ConflictAction conflictAction, File outputDir, ExpressionFileFormat format, MusicIdentificationService... services) throws Exception {
|
||||||
|
@ -536,40 +501,29 @@ public class CmdlineOperations implements CmdlineInterface {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// map old files to new paths by applying formatting and validating filenames
|
|
||||||
Map<File, File> renameMap = new LinkedHashMap<File, File>();
|
|
||||||
|
|
||||||
for (Match<File, ?> it : matches) {
|
|
||||||
File file = it.getValue();
|
|
||||||
Object music = it.getCandidate();
|
|
||||||
String path = format != null ? format.format(new MediaBindingBean(music, file, getContext(matches))) : validateFileName(music.toString());
|
|
||||||
|
|
||||||
renameMap.put(file, getDestinationFile(file, path, outputDir));
|
|
||||||
}
|
|
||||||
|
|
||||||
// error logging
|
// error logging
|
||||||
remaining.forEach(f -> log.warning(format("Failed to process music file: %s", f)));
|
remaining.forEach(f -> log.warning(format("Failed to process music file: %s", f)));
|
||||||
|
|
||||||
// rename movies
|
// rename movies
|
||||||
return renameAll(renameMap, renameAction, conflictAction, null);
|
return renameAll(formatMatches(matches, format, outputDir), renameAction, conflictAction, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<File> renameFiles(Collection<File> files, RenameAction renameAction, ConflictAction conflictAction, File outputDir, ExpressionFileFormat format, XattrMetaInfoProvider service, ExpressionFilter filter, boolean strict) throws Exception {
|
public List<File> renameFiles(Collection<File> files, RenameAction renameAction, ConflictAction conflictAction, File outputDir, ExpressionFileFormat format, XattrMetaInfoProvider service, ExpressionFilter filter, boolean strict) throws Exception {
|
||||||
log.config(format("Rename files using [%s]", service.getName()));
|
log.config(format("Rename files using [%s]", service.getName()));
|
||||||
|
|
||||||
|
Map<File, File> renameMap = new LinkedHashMap<File, File>();
|
||||||
|
|
||||||
// match to xattr metadata object or the file itself
|
// match to xattr metadata object or the file itself
|
||||||
Map<File, Object> matches = service.match(files, strict);
|
Map<File, Object> matches = service.match(files, strict);
|
||||||
|
|
||||||
Map<File, File> renameMap = new LinkedHashMap<File, File>();
|
service.match(files, strict).forEach((k, v) -> {
|
||||||
|
MediaBindingBean bindingBean = new MediaBindingBean(v, k, matches);
|
||||||
for (Entry<File, Object> it : matches.entrySet()) {
|
|
||||||
MediaBindingBean bindingBean = new MediaBindingBean(it.getValue(), it.getKey(), matches);
|
|
||||||
|
|
||||||
if (filter == null || filter.matches(bindingBean)) {
|
if (filter == null || filter.matches(bindingBean)) {
|
||||||
String newName = format != null ? format.format(bindingBean) : bindingBean.getInfoObject() instanceof File ? bindingBean.getInfoObject().toString() : validateFileName(bindingBean.getInfoObject().toString());
|
String destinationPath = format != null ? format.format(bindingBean) : v instanceof File ? v.toString() : validateFileName(v.toString());
|
||||||
renameMap.put(it.getKey(), getDestinationFile(it.getKey(), newName, outputDir));
|
renameMap.put(k, getDestinationFile(k, destinationPath, outputDir));
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
|
|
||||||
return renameAll(renameMap, renameAction, conflictAction, null);
|
return renameAll(renameMap, renameAction, conflictAction, null);
|
||||||
}
|
}
|
||||||
|
@ -601,7 +555,22 @@ public class CmdlineOperations implements CmdlineInterface {
|
||||||
return newFile;
|
return newFile;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<File> renameAll(Map<File, File> renameMap, RenameAction renameAction, ConflictAction conflictAction, List<Match<File, ?>> matches) throws Exception {
|
private Map<File, File> formatMatches(List<Match<File, ?>> matches, ExpressionFormat format, File outputDir) throws Exception {
|
||||||
|
// map old files to new paths by applying formatting and validating filenames
|
||||||
|
Map<File, File> renameMap = new LinkedHashMap<File, File>();
|
||||||
|
|
||||||
|
for (Match<File, ?> match : matches) {
|
||||||
|
File file = match.getValue();
|
||||||
|
Object object = match.getCandidate();
|
||||||
|
String destinationPath = format != null ? format.format(new MediaBindingBean(object, file, getContext(matches))) : validateFileName(object.toString());
|
||||||
|
|
||||||
|
renameMap.put(file, getDestinationFile(file, destinationPath, outputDir));
|
||||||
|
}
|
||||||
|
|
||||||
|
return renameMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected List<File> renameAll(Map<File, File> renameMap, RenameAction renameAction, ConflictAction conflictAction, List<Match<File, ?>> matches) throws Exception {
|
||||||
if (renameMap.isEmpty()) {
|
if (renameMap.isEmpty()) {
|
||||||
throw new CmdlineException("Failed to identify or process any files");
|
throw new CmdlineException("Failed to identify or process any files");
|
||||||
}
|
}
|
||||||
|
@ -854,21 +823,20 @@ public class CmdlineOperations implements CmdlineInterface {
|
||||||
return destination;
|
return destination;
|
||||||
}
|
}
|
||||||
|
|
||||||
private <T> List<T> applyExpressionFilter(List<T> input, ExpressionFilter filter) throws Exception {
|
protected <T> List<T> applyExpressionFilter(List<T> input, ExpressionFilter filter) {
|
||||||
if (filter == null) {
|
if (filter == null) {
|
||||||
return input;
|
return input;
|
||||||
}
|
}
|
||||||
|
|
||||||
log.fine(format("Apply filter [%s] on [%d] items", filter.getExpression(), input.size()));
|
log.fine(format("Apply filter [%s] on [%d] items", filter.getExpression(), input.size()));
|
||||||
Map<File, T> context = new EntryList<File, T>(null, input);
|
|
||||||
List<T> output = new ArrayList<T>(input.size());
|
return input.stream().filter(it -> {
|
||||||
for (T it : input) {
|
if (filter.matches(new MediaBindingBean(it, null, new EntryList<File, T>(null, input)))) {
|
||||||
if (filter.matches(new MediaBindingBean(it, null, context))) {
|
|
||||||
log.finest(format("Include [%s]", it));
|
log.finest(format("Include [%s]", it));
|
||||||
output.add(it);
|
return true;
|
||||||
}
|
}
|
||||||
}
|
return false;
|
||||||
return output;
|
}).collect(toList());
|
||||||
}
|
}
|
||||||
|
|
||||||
protected <T extends SearchResult> T selectSearchResult(String query, Collection<T> options) throws Exception {
|
protected <T extends SearchResult> T selectSearchResult(String query, Collection<T> options) throws Exception {
|
||||||
|
@ -1043,20 +1011,18 @@ public class CmdlineOperations implements CmdlineInterface {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Stream<String> fetchEpisodeList(EpisodeListProvider 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 {
|
||||||
// default episode format
|
|
||||||
if (format == null) {
|
|
||||||
return fetchEpisodeList(db, query, new ExpressionFormat("{episode}"), filter, order, locale, strict);
|
|
||||||
}
|
|
||||||
|
|
||||||
// collect all episode objects first
|
// collect all episode objects first
|
||||||
List<Episode> episodes = fetchEpisodeList(db, query, filter, order, locale, strict);
|
List<Episode> episodes = fetchEpisodeList(db, query, filter, order, locale, strict);
|
||||||
|
|
||||||
// lazy format
|
// instant format
|
||||||
Map<File, Episode> context = new EntryList<File, Episode>(null, episodes);
|
if (format == null) {
|
||||||
|
return episodes.stream().map(Episode::toString);
|
||||||
|
}
|
||||||
|
|
||||||
|
// lazy format
|
||||||
return episodes.stream().map(episode -> {
|
return episodes.stream().map(episode -> {
|
||||||
try {
|
try {
|
||||||
return format.format(new MediaBindingBean(episode, null, context));
|
return format.format(new MediaBindingBean(episode, null, new EntryList<File, Episode>(null, episodes)));
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
debug.warning(e::getMessage);
|
debug.warning(e::getMessage);
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,11 +32,11 @@ public class ExpressionFilter {
|
||||||
return lastException;
|
return lastException;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean matches(Object value) throws ScriptException {
|
public boolean matches(Object value) {
|
||||||
return matches(new ExpressionBindings(value));
|
return matches(new ExpressionBindings(value));
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean matches(Bindings bindings) throws ScriptException {
|
public boolean matches(Bindings bindings) {
|
||||||
this.lastException = null;
|
this.lastException = null;
|
||||||
|
|
||||||
// use privileged bindings so we are not restricted by the script sandbox
|
// use privileged bindings so we are not restricted by the script sandbox
|
||||||
|
|
Loading…
Reference in New Issue