diff --git a/source/net/sourceforge/filebot/cli/ArgumentProcessor.java b/source/net/sourceforge/filebot/cli/ArgumentProcessor.java index f435f114..ab8a4489 100644 --- a/source/net/sourceforge/filebot/cli/ArgumentProcessor.java +++ b/source/net/sourceforge/filebot/cli/ArgumentProcessor.java @@ -33,6 +33,7 @@ import org.kohsuke.args4j.CmdLineParser; import net.sourceforge.filebot.Analytics; import net.sourceforge.filebot.MediaTypes; +import net.sourceforge.filebot.StandardRenameAction; import net.sourceforge.filebot.cli.ScriptShell.Script; import net.sourceforge.filebot.cli.ScriptShell.ScriptProvider; import net.sourceforge.filebot.web.CachedResource; @@ -106,7 +107,7 @@ public class ArgumentProcessor { } if (args.rename) { - cli.rename(files, args.action, args.conflict, args.output, args.format, args.db, args.query, args.order, args.filter, args.lang, !args.nonStrict); + cli.rename(files, StandardRenameAction.forName(args.action), args.conflict, args.output, args.format, args.db, args.query, args.order, args.filter, args.lang, !args.nonStrict); } if (args.check) { diff --git a/source/net/sourceforge/filebot/cli/CmdlineInterface.java b/source/net/sourceforge/filebot/cli/CmdlineInterface.java index d80ce2db..59986f3e 100644 --- a/source/net/sourceforge/filebot/cli/CmdlineInterface.java +++ b/source/net/sourceforge/filebot/cli/CmdlineInterface.java @@ -6,10 +6,12 @@ import java.io.File; import java.util.Collection; import java.util.List; +import net.sourceforge.filebot.RenameAction; + public interface CmdlineInterface { - List rename(Collection files, String action, String conflict, String output, String format, String db, String query, String sortOrder, String filter, String lang, boolean strict) throws Exception; + List rename(Collection files, RenameAction action, String conflict, String output, String format, String db, String query, String sortOrder, String filter, String lang, boolean strict) throws Exception; List getSubtitles(Collection files, String db, String query, String lang, String output, String encoding, boolean strict) throws Exception; diff --git a/source/net/sourceforge/filebot/cli/CmdlineOperations.java b/source/net/sourceforge/filebot/cli/CmdlineOperations.java index e8017ea1..f0e85ed3 100644 --- a/source/net/sourceforge/filebot/cli/CmdlineOperations.java +++ b/source/net/sourceforge/filebot/cli/CmdlineOperations.java @@ -47,7 +47,6 @@ import net.sourceforge.filebot.Analytics; import net.sourceforge.filebot.HistorySpooler; import net.sourceforge.filebot.MediaTypes; import net.sourceforge.filebot.RenameAction; -import net.sourceforge.filebot.StandardRenameAction; import net.sourceforge.filebot.WebServices; import net.sourceforge.filebot.archive.Archive; import net.sourceforge.filebot.archive.FileMapper; @@ -85,12 +84,12 @@ import net.sourceforge.tuned.FileUtilities.ParentFilter; public class CmdlineOperations implements CmdlineInterface { @Override - public List rename(Collection files, String action, String conflict, String output, String formatExpression, String db, String query, String sortOrder, String filterExpression, String lang, boolean strict) throws Exception { + public List rename(Collection files, RenameAction action, String conflict, String output, String formatExpression, String db, String query, String sortOrder, String filterExpression, String lang, boolean strict) + throws Exception { ExpressionFormat format = (formatExpression != null) ? new ExpressionFormat(formatExpression) : null; ExpressionFilter filter = (filterExpression != null) ? new ExpressionFilter(filterExpression) : null; File outputDir = (output != null && output.length() > 0) ? new File(output).getAbsoluteFile() : null; Locale locale = getLanguage(lang).toLocale(); - RenameAction renameAction = StandardRenameAction.forName(action); ConflictAction conflictAction = ConflictAction.forName(conflict); List mediaFiles = filter(files, VIDEO_FILES, SUBTITLE_FILES); @@ -100,12 +99,12 @@ public class CmdlineOperations implements CmdlineInterface { if (getEpisodeListProvider(db) != null) { // tv series mode - return renameSeries(files, renameAction, conflictAction, outputDir, format, getEpisodeListProvider(db), query, SortOrder.forName(sortOrder), filter, locale, strict); + return renameSeries(files, action, conflictAction, outputDir, format, getEpisodeListProvider(db), query, SortOrder.forName(sortOrder), filter, locale, strict); } if (getMovieIdentificationService(db) != null) { // movie mode - return renameMovie(files, renameAction, conflictAction, outputDir, format, getMovieIdentificationService(db), query, locale, strict); + return renameMovie(files, action, conflictAction, outputDir, format, getMovieIdentificationService(db), query, locale, strict); } // auto-determine mode @@ -136,9 +135,9 @@ public class CmdlineOperations implements CmdlineInterface { CLILogger.finest(format("Filename pattern: [%.02f] SxE, [%.02f] CWS", sxe / max, cws / max)); if (sxe >= (max * 0.65) || cws >= (max * 0.65)) { - return renameSeries(files, renameAction, conflictAction, outputDir, format, WebServices.TheTVDB, query, SortOrder.forName(sortOrder), filter, locale, strict); // use default episode db + return renameSeries(files, action, conflictAction, outputDir, format, WebServices.TheTVDB, query, SortOrder.forName(sortOrder), filter, locale, strict); // use default episode db } else { - return renameMovie(files, renameAction, conflictAction, outputDir, format, WebServices.TMDb, query, locale, strict); // use default movie db + return renameMovie(files, action, conflictAction, outputDir, format, WebServices.TMDb, query, locale, strict); // use default movie db } } @@ -208,14 +207,8 @@ public class CmdlineOperations implements CmdlineInterface { File file = match.getValue(); Object episode = match.getCandidate(); String newName = (format != null) ? format.format(new MediaBindingBean(episode, file)) : validateFileName(EpisodeFormat.SeasonEpisode.format(episode)); - File newFile = new File(outputDir, newName + "." + getExtension(file)); - if (isInvalidFilePath(newFile) && !isUnixFS()) { - CLILogger.config("Stripping invalid characters from new path: " + newName); - newFile = validateFilePath(newFile); - } - - renameMap.put(file, newFile); + renameMap.put(file, getDestinationFile(file, newName, outputDir)); } // rename episodes @@ -443,14 +436,8 @@ public class CmdlineOperations implements CmdlineInterface { File file = match.getValue(); Object movie = match.getCandidate(); String newName = (format != null) ? format.format(new MediaBindingBean(movie, file)) : validateFileName(MovieFormat.NameYear.format(movie)); - File newFile = new File(outputDir, newName + "." + getExtension(file)); - if (isInvalidFilePath(newFile) && !isUnixFS()) { - CLILogger.config("Stripping invalid characters from new path: " + newName); - newFile = validateFilePath(newFile); - } - - renameMap.put(file, newFile); + renameMap.put(file, getDestinationFile(file, newName, outputDir)); } // rename movies @@ -459,6 +446,23 @@ public class CmdlineOperations implements CmdlineInterface { } + private File getDestinationFile(File original, String newName, File outputDir) { + File newFile = new File(newName + "." + getExtension(original)); + + // resolve against output dir + if (outputDir != null && !newFile.isAbsolute()) { + newFile = new File(outputDir, newFile.getPath()); + } + + if (isInvalidFilePath(newFile) && !isUnixFS()) { + CLILogger.config("Stripping invalid characters from new path: " + newName); + newFile = validateFilePath(newFile); + } + + return newFile; + } + + public List renameAll(Map renameMap, RenameAction renameAction, ConflictAction conflictAction) throws Exception { // rename files final List> renameLog = new ArrayList>(); diff --git a/source/net/sourceforge/filebot/cli/ScriptShell.lib.groovy b/source/net/sourceforge/filebot/cli/ScriptShell.lib.groovy index a32ca561..6e3f6221 100644 --- a/source/net/sourceforge/filebot/cli/ScriptShell.lib.groovy +++ b/source/net/sourceforge/filebot/cli/ScriptShell.lib.groovy @@ -210,7 +210,7 @@ def include(String input, Map parameters = [:], Object... args) { // CLI bindings def rename(args) { args = _defaults(args) synchronized (_cli) { - _guarded { _cli.rename(_files(args), args.action as String, args.conflict as String, args.output as String, args.format as String, args.db as String, args.query as String, args.order as String, args.filter as String, args.lang as String, args.strict as Boolean) } + _guarded { _cli.rename(_files(args), _renameFunction(args.action), args.conflict as String, args.output as String, args.format as String, args.db as String, args.query as String, args.order as String, args.filter as String, args.lang as String, args.strict as Boolean) } } } @@ -275,6 +275,20 @@ def _files(args) { return files } + +// allow Groovy to hook into rename interface +import net.sourceforge.filebot.* + +def _renameFunction(fn) { + if (fn instanceof String) + return StandardRenameAction.forName(fn) + if (fn instanceof Closure) + return [rename:fn as Closure, toString:{'CLOSURE'}] as RenameAction + + return fn as RenameAction +} + + /** * Fill in default values from cmdline arguments */