diff --git a/source/net/sourceforge/filebot/cli/CmdlineOperations.java b/source/net/sourceforge/filebot/cli/CmdlineOperations.java index a97066cc..b48a0e68 100644 --- a/source/net/sourceforge/filebot/cli/CmdlineOperations.java +++ b/source/net/sourceforge/filebot/cli/CmdlineOperations.java @@ -92,11 +92,6 @@ public class CmdlineOperations implements CmdlineInterface { Locale locale = getLanguage(lang).toLocale(); ConflictAction conflictAction = ConflictAction.forName(conflict); - List mediaFiles = filter(files, VIDEO_FILES, SUBTITLE_FILES); - if (mediaFiles.isEmpty()) { - throw new Exception("No media files: " + files); - } - if (getEpisodeListProvider(db) != null) { // tv series mode return renameSeries(files, action, conflictAction, outputDir, format, getEpisodeListProvider(db), query, SortOrder.forName(sortOrder), filter, locale, strict); @@ -108,9 +103,10 @@ public class CmdlineOperations implements CmdlineInterface { } // auto-determine mode + List mediaFiles = filter(files, VIDEO_FILES, SUBTITLE_FILES); + double max = mediaFiles.size(); int sxe = 0; // SxE int cws = 0; // common word sequence - double max = mediaFiles.size(); SeriesNameMatcher nameMatcher = new SeriesNameMatcher(locale); Collection cwsList = emptySet(); @@ -144,7 +140,11 @@ public class CmdlineOperations implements CmdlineInterface { public List renameSeries(Collection 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())); + List mediaFiles = filter(files, VIDEO_FILES, SUBTITLE_FILES); + if (mediaFiles.isEmpty()) { + throw new Exception("No media files: " + files); + } // similarity metrics for matching List> matches = new ArrayList>(); @@ -296,7 +296,7 @@ public class CmdlineOperations implements CmdlineInterface { // handle movie files Set movieFiles = new TreeSet(filter(fileset, VIDEO_FILES)); - Set nfoFiles = new TreeSet(filter(fileset, MediaTypes.getDefaultFilter("application/nfo"))); + Set nfoFiles = new TreeSet(filter(fileset, NFO_FILES)); List orphanedFiles = new ArrayList(filter(fileset, FILES)); orphanedFiles.removeAll(movieFiles); @@ -336,7 +336,7 @@ public class CmdlineOperations implements CmdlineInterface { // collect useful nfo files even if they are not part of the selected fileset Set effectiveNfoFileSet = new TreeSet(nfoFiles); for (File dir : mapByFolder(movieFiles).keySet()) { - addAll(effectiveNfoFileSet, dir.listFiles(MediaTypes.getDefaultFilter("application/nfo"))); + addAll(effectiveNfoFileSet, dir.listFiles(NFO_FILES)); } for (File nfo : effectiveNfoFileSet) { try { @@ -372,9 +372,14 @@ public class CmdlineOperations implements CmdlineInterface { List movieMatchFiles = new ArrayList(); movieMatchFiles.addAll(movieFiles); movieMatchFiles.addAll(nfoFiles); - movieMatchFiles.addAll(filter(files, DISK_FOLDERS)); + movieMatchFiles.addAll(filter(files, FOLDERS)); movieMatchFiles.addAll(filter(orphanedFiles, SUBTITLE_FILES)); // run movie detection only on orphaned subtitle files + // sanity check that we have something to do + if (fileset.isEmpty() || movieMatchFiles.isEmpty()) { + throw new Exception("No media files: " + files); + } + // map movies to (possibly multiple) files (in natural order) Map> filesByMovie = new HashMap>(); @@ -454,7 +459,8 @@ public class CmdlineOperations implements CmdlineInterface { private File getDestinationFile(File original, String newName, File outputDir) { - File newFile = new File(newName + "." + getExtension(original)); + String extension = getExtension(original); + File newFile = new File(extension != null ? newName + '.' + extension : newName); // resolve against output dir if (outputDir != null && !newFile.isAbsolute()) { diff --git a/source/net/sourceforge/filebot/format/MediaBindingBean.java b/source/net/sourceforge/filebot/format/MediaBindingBean.java index b612e629..114f2ad3 100644 --- a/source/net/sourceforge/filebot/format/MediaBindingBean.java +++ b/source/net/sourceforge/filebot/format/MediaBindingBean.java @@ -515,7 +515,7 @@ public class MediaBindingBean { // make sure media file is defined checkMediaFile(); - if (SUBTITLE_FILES.accept(mediaFile) || getDefaultFilter("application/nfo").accept(mediaFile)) { + if (SUBTITLE_FILES.accept(mediaFile) || NFO_FILES.accept(mediaFile)) { // file is a subtitle String baseName = stripReleaseInfo(FileUtilities.getName(mediaFile)).toLowerCase(); diff --git a/source/net/sourceforge/filebot/media/MediaDetection.java b/source/net/sourceforge/filebot/media/MediaDetection.java index ae80782b..076eaba6 100644 --- a/source/net/sourceforge/filebot/media/MediaDetection.java +++ b/source/net/sourceforge/filebot/media/MediaDetection.java @@ -568,15 +568,19 @@ public class MediaDetection { Set collection = new LinkedHashSet(); List nfoFiles = new ArrayList(); if (file.isDirectory()) { - nfoFiles.addAll(listFiles(singleton(file), 10, false)); + nfoFiles.addAll(filter(listFiles(singleton(file), 10, false), NFO_FILES)); } else { addAll(nfoFiles, file.getParentFile().listFiles(NFO_FILES)); } // parse ids from nfo files for (File nfo : nfoFiles) { - String text = new String(readFile(nfo), "UTF-8"); - collection.addAll(grepImdbId(text)); + try { + String text = new String(readFile(nfo), "UTF-8"); + collection.addAll(grepImdbId(text)); + } catch (Exception e) { + Logger.getLogger(MediaDetection.class.getClass().getName()).log(Level.WARNING, "Failed to read nfo: " + e.getMessage()); + } } return collection; diff --git a/source/net/sourceforge/filebot/ui/rename/MovieHashMatcher.java b/source/net/sourceforge/filebot/ui/rename/MovieHashMatcher.java index 1f934885..f652519a 100644 --- a/source/net/sourceforge/filebot/ui/rename/MovieHashMatcher.java +++ b/source/net/sourceforge/filebot/ui/rename/MovieHashMatcher.java @@ -144,7 +144,7 @@ class MovieHashMatcher implements AutoCompleteMatcher { List movieMatchFiles = new ArrayList(); movieMatchFiles.addAll(movieFiles); movieMatchFiles.addAll(nfoFiles); - movieMatchFiles.addAll(filter(files, DISK_FOLDERS)); + movieMatchFiles.addAll(filter(files, FOLDERS)); movieMatchFiles.addAll(filter(orphanedFiles, SUBTITLE_FILES)); // run movie detection only on orphaned subtitle files // match remaining movies file by file in parallel diff --git a/source/net/sourceforge/tuned/FileUtilities.java b/source/net/sourceforge/tuned/FileUtilities.java index b5c1eba6..49f2d928 100644 --- a/source/net/sourceforge/tuned/FileUtilities.java +++ b/source/net/sourceforge/tuned/FileUtilities.java @@ -105,7 +105,12 @@ public final class FileUtilities { InputStream in = new FileInputStream(source); try { - byte[] data = new byte[(int) source.length()]; + long size = source.length(); + if (size < 0 || size > Integer.MAX_VALUE) { + throw new IllegalArgumentException("Unable to read file: " + source); + } + + byte[] data = new byte[(int) size]; int position = 0; int read = 0; @@ -177,7 +182,6 @@ public final class FileUtilities { return Charset.forName("UTF-8").decode(data).toString(); } - /** * Pattern used for matching file extensions. * @@ -421,7 +425,6 @@ public final class FileUtilities { return map; } - /** * Invalid file name characters: \, /, :, *, ?, ", <, >, |, \r and \n */ @@ -508,7 +511,6 @@ public final class FileUtilities { return buffer.toString(); } - public static final long KILO = 1024; public static final long MEGA = KILO * 1024; public static final long GIGA = MEGA * 1024; @@ -523,7 +525,6 @@ public final class FileUtilities { return String.format("%,d Byte", size); } - public static final FileFilter FOLDERS = new FileFilter() { @Override @@ -532,7 +533,6 @@ public final class FileUtilities { } }; - public static final FileFilter FILES = new FileFilter() { @Override @@ -541,7 +541,6 @@ public final class FileUtilities { } }; - public static final FileFilter TEMPORARY = new FileFilter() { private final String tmpdir = System.getProperty("java.io.tmpdir");