+ support for smart-skip/override for keeping the higher-quality video via --conflict auto
This commit is contained in:
parent
66a6278611
commit
c45abb7291
|
@ -60,6 +60,7 @@ import net.sourceforge.filebot.subtitle.SubtitleFormat;
|
||||||
import net.sourceforge.filebot.subtitle.SubtitleNaming;
|
import net.sourceforge.filebot.subtitle.SubtitleNaming;
|
||||||
import net.sourceforge.filebot.vfs.FileInfo;
|
import net.sourceforge.filebot.vfs.FileInfo;
|
||||||
import net.sourceforge.filebot.vfs.MemoryFile;
|
import net.sourceforge.filebot.vfs.MemoryFile;
|
||||||
|
import net.sourceforge.filebot.vfs.SimpleFileInfo;
|
||||||
import net.sourceforge.filebot.web.AudioTrack;
|
import net.sourceforge.filebot.web.AudioTrack;
|
||||||
import net.sourceforge.filebot.web.Episode;
|
import net.sourceforge.filebot.web.Episode;
|
||||||
import net.sourceforge.filebot.web.EpisodeFormat;
|
import net.sourceforge.filebot.web.EpisodeFormat;
|
||||||
|
@ -574,7 +575,7 @@ public class CmdlineOperations implements CmdlineInterface {
|
||||||
throw new Exception("File already exists: " + destination);
|
throw new Exception("File already exists: " + destination);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (conflictAction == ConflictAction.OVERRIDE) {
|
if (conflictAction == ConflictAction.OVERRIDE || (conflictAction == ConflictAction.AUTO && VIDEO_SIZE_ORDER.compare(source, destination) > 0)) {
|
||||||
if (!destination.delete()) {
|
if (!destination.delete()) {
|
||||||
CLILogger.log(Level.SEVERE, "Failed to override file: " + destination);
|
CLILogger.log(Level.SEVERE, "Failed to override file: " + destination);
|
||||||
}
|
}
|
||||||
|
@ -1085,14 +1086,15 @@ public class CmdlineOperations implements CmdlineInterface {
|
||||||
CLILogger.info(String.format("Read archive [%s] and extract to [%s]", file.getName(), outputFolder));
|
CLILogger.info(String.format("Read archive [%s] and extract to [%s]", file.getName(), outputFolder));
|
||||||
final FileMapper outputMapper = new FileMapper(outputFolder, false);
|
final FileMapper outputMapper = new FileMapper(outputFolder, false);
|
||||||
|
|
||||||
final List<File> outputMapping = new ArrayList<File>();
|
final List<FileInfo> outputMapping = new ArrayList<FileInfo>();
|
||||||
for (FileInfo entry : archive.listFiles()) {
|
for (FileInfo it : archive.listFiles()) {
|
||||||
outputMapping.add(outputMapper.getOutputFile(new File(entry.getPath())));
|
File outputPath = outputMapper.getOutputFile(it.toFile());
|
||||||
|
outputMapping.add(new SimpleFileInfo(outputPath.getPath(), it.getLength()));
|
||||||
}
|
}
|
||||||
|
|
||||||
final Set<File> selection = new TreeSet<File>();
|
final Set<FileInfo> selection = new TreeSet<FileInfo>();
|
||||||
for (File future : outputMapping) {
|
for (FileInfo future : outputMapping) {
|
||||||
if (filter == null || filter.accept(future)) {
|
if (filter == null || filter.accept(future.toFile())) {
|
||||||
selection.add(future);
|
selection.add(future);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1103,18 +1105,27 @@ public class CmdlineOperations implements CmdlineInterface {
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean skip = true;
|
boolean skip = true;
|
||||||
for (File future : filter == null || forceExtractAll ? outputMapping : selection) {
|
for (FileInfo future : filter == null || forceExtractAll ? outputMapping : selection) {
|
||||||
skip &= future.exists();
|
if (conflictAction == ConflictAction.AUTO) {
|
||||||
|
skip &= (future.toFile().exists() && future.getLength() == future.toFile().length());
|
||||||
|
} else {
|
||||||
|
skip &= (future.toFile().exists());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!skip || conflictAction == ConflictAction.OVERRIDE) {
|
if (!skip || conflictAction == ConflictAction.OVERRIDE) {
|
||||||
if (filter == null || forceExtractAll) {
|
if (filter == null || forceExtractAll) {
|
||||||
CLILogger.finest("Extracting files " + outputMapping);
|
CLILogger.finest("Extracting files " + outputMapping);
|
||||||
|
|
||||||
// extract all files
|
// extract all files
|
||||||
archive.extract(outputMapper);
|
archive.extract(outputMapper);
|
||||||
extractedFiles.addAll(outputMapping);
|
|
||||||
|
for (FileInfo it : outputMapping) {
|
||||||
|
extractedFiles.add(it.toFile());
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
CLILogger.finest("Extracting files " + selection);
|
CLILogger.finest("Extracting files " + selection);
|
||||||
|
|
||||||
// extract files selected by the given filter
|
// extract files selected by the given filter
|
||||||
archive.extract(outputMapper, new FileFilter() {
|
archive.extract(outputMapper, new FileFilter() {
|
||||||
|
|
||||||
|
@ -1123,7 +1134,10 @@ public class CmdlineOperations implements CmdlineInterface {
|
||||||
return selection.contains(outputMapper.getOutputFile(entry));
|
return selection.contains(outputMapper.getOutputFile(entry));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
extractedFiles.addAll(selection);
|
|
||||||
|
for (FileInfo it : selection) {
|
||||||
|
extractedFiles.add(it.toFile());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
CLILogger.finest("Skipped extracting files " + selection);
|
CLILogger.finest("Skipped extracting files " + selection);
|
||||||
|
|
|
@ -707,7 +707,7 @@ public class MediaBindingBean {
|
||||||
return JsonWriter.objectToJson(infoObject);
|
return JsonWriter.objectToJson(infoObject);
|
||||||
}
|
}
|
||||||
|
|
||||||
private File getInferredMediaFile() {
|
public File getInferredMediaFile() {
|
||||||
// make sure media file is defined
|
// make sure media file is defined
|
||||||
checkMediaFile();
|
checkMediaFile();
|
||||||
|
|
||||||
|
@ -717,7 +717,7 @@ public class MediaBindingBean {
|
||||||
if (videos.size() > 0) {
|
if (videos.size() > 0) {
|
||||||
return videos.iterator().next();
|
return videos.iterator().next();
|
||||||
}
|
}
|
||||||
} else if ((infoObject instanceof Episode || infoObject instanceof Movie) && !VIDEO_FILES.accept(mediaFile)) {
|
} else if (SUBTITLE_FILES.accept(mediaFile) || ((infoObject instanceof Episode || infoObject instanceof Movie) && !VIDEO_FILES.accept(mediaFile))) {
|
||||||
// prefer equal match from current context if possible
|
// prefer equal match from current context if possible
|
||||||
if (getContext() != null) {
|
if (getContext() != null) {
|
||||||
for (Entry<File, Object> it : getContext().entrySet()) {
|
for (Entry<File, Object> it : getContext().entrySet()) {
|
||||||
|
|
|
@ -17,6 +17,7 @@ import java.net.URL;
|
||||||
import java.text.CollationKey;
|
import java.text.CollationKey;
|
||||||
import java.text.Collator;
|
import java.text.Collator;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
|
@ -40,6 +41,7 @@ import java.util.regex.Pattern;
|
||||||
|
|
||||||
import net.sourceforge.filebot.WebServices;
|
import net.sourceforge.filebot.WebServices;
|
||||||
import net.sourceforge.filebot.archive.Archive;
|
import net.sourceforge.filebot.archive.Archive;
|
||||||
|
import net.sourceforge.filebot.format.MediaBindingBean;
|
||||||
import net.sourceforge.filebot.similarity.CommonSequenceMatcher;
|
import net.sourceforge.filebot.similarity.CommonSequenceMatcher;
|
||||||
import net.sourceforge.filebot.similarity.DateMatcher;
|
import net.sourceforge.filebot.similarity.DateMatcher;
|
||||||
import net.sourceforge.filebot.similarity.DateMetric;
|
import net.sourceforge.filebot.similarity.DateMetric;
|
||||||
|
@ -97,7 +99,7 @@ public class MediaDetection {
|
||||||
Archive iso = new Archive(file);
|
Archive iso = new Archive(file);
|
||||||
try {
|
try {
|
||||||
for (FileInfo it : iso.listFiles()) {
|
for (FileInfo it : iso.listFiles()) {
|
||||||
for (File entry : listPath(new File(it.getPath()))) {
|
for (File entry : listPath(it.toFile())) {
|
||||||
if (diskFolderEntryFilter.accept(entry)) {
|
if (diskFolderEntryFilter.accept(entry)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -1251,6 +1253,55 @@ public class MediaDetection {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Comparator<File> VIDEO_SIZE_ORDER = new Comparator<File>() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int compare(File f1, File f2) {
|
||||||
|
long[] v1 = getSizeValues(f1);
|
||||||
|
long[] v2 = getSizeValues(f2);
|
||||||
|
|
||||||
|
for (int i = 0; i < v1.length; i++) {
|
||||||
|
// best to worst
|
||||||
|
int d = new Long(v1[i]).compareTo(new Long(v2[i]));
|
||||||
|
if (d != 0) {
|
||||||
|
return d;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long[] getSizeValues(File f) {
|
||||||
|
long[] v = new long[] { 0, 0 };
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (VIDEO_FILES.accept(f) || SUBTITLE_FILES.accept(f)) {
|
||||||
|
MediaBindingBean media = new MediaBindingBean(null, f, null);
|
||||||
|
|
||||||
|
// 1. Video Resolution
|
||||||
|
List<Integer> dim = media.getDimension();
|
||||||
|
v[0] = dim.get(0).longValue() * dim.get(1).longValue();
|
||||||
|
|
||||||
|
// 2. File Size
|
||||||
|
v[1] = media.getInferredMediaFile().length();
|
||||||
|
} else if (AUDIO_FILES.accept(f)) {
|
||||||
|
// 1. Audio BitRate
|
||||||
|
v[0] = 0;
|
||||||
|
|
||||||
|
// 2. File Size
|
||||||
|
v[1] = f.length();
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
// negative values for invalid files
|
||||||
|
Logger.getLogger(MediaDetection.class.getClass().getName()).warning(String.format("Unable to read media info: %s [%s]", e.getMessage(), f.getName()));
|
||||||
|
|
||||||
|
Arrays.fill(v, -1);
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
public static void storeMetaInfo(File file, Object model, String original) {
|
public static void storeMetaInfo(File file, Object model, String original) {
|
||||||
// only for Episode / Movie objects
|
// only for Episode / Movie objects
|
||||||
if ((model instanceof Episode || model instanceof Movie) && file.exists()) {
|
if ((model instanceof Episode || model instanceof Movie) && file.exists()) {
|
||||||
|
|
|
@ -217,7 +217,7 @@ class ExtractTool extends Tool<TableModel> {
|
||||||
return data[row].entry.getName();
|
return data[row].entry.getName();
|
||||||
case 1:
|
case 1:
|
||||||
File root = new File(data[row].archive.getName());
|
File root = new File(data[row].archive.getName());
|
||||||
File prefix = new File(data[row].entry.getPath()).getParentFile();
|
File prefix = data[row].entry.toFile().getParentFile();
|
||||||
File path = (prefix == null) ? root : new File(root, prefix.getPath());
|
File path = (prefix == null) ? root : new File(root, prefix.getPath());
|
||||||
return normalizePathSeparators(path.getPath());
|
return normalizePathSeparators(path.getPath());
|
||||||
case 2:
|
case 2:
|
||||||
|
|
|
@ -1,18 +1,17 @@
|
||||||
|
|
||||||
package net.sourceforge.filebot.vfs;
|
package net.sourceforge.filebot.vfs;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
|
||||||
public interface FileInfo {
|
public interface FileInfo {
|
||||||
|
|
||||||
public String getPath();
|
public String getPath();
|
||||||
|
|
||||||
|
|
||||||
public String getName();
|
public String getName();
|
||||||
|
|
||||||
|
|
||||||
public String getType();
|
public String getType();
|
||||||
|
|
||||||
|
|
||||||
public long getLength();
|
public long getLength();
|
||||||
|
|
||||||
|
public File toFile();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,45 +1,42 @@
|
||||||
|
|
||||||
package net.sourceforge.filebot.vfs;
|
package net.sourceforge.filebot.vfs;
|
||||||
|
|
||||||
|
|
||||||
import static net.sourceforge.tuned.FileUtilities.*;
|
import static net.sourceforge.tuned.FileUtilities.*;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
public class SimpleFileInfo implements FileInfo, Comparable<FileInfo> {
|
||||||
|
|
||||||
public class SimpleFileInfo implements FileInfo {
|
|
||||||
|
|
||||||
private final String path;
|
private final String path;
|
||||||
private final long length;
|
private final long length;
|
||||||
|
|
||||||
|
|
||||||
public SimpleFileInfo(String path, long length) {
|
public SimpleFileInfo(String path, long length) {
|
||||||
this.path = path;
|
this.path = path;
|
||||||
this.length = length;
|
this.length = length;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getPath() {
|
public String getPath() {
|
||||||
return path;
|
return path;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public String getName() {
|
public String getName() {
|
||||||
return getNameWithoutExtension(path);
|
return getNameWithoutExtension(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getType() {
|
public String getType() {
|
||||||
return getExtension(path);
|
return getExtension(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public long getLength() {
|
public long getLength() {
|
||||||
return length;
|
return length;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return Arrays.hashCode(new Object[] { getPath(), getLength() });
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(Object obj) {
|
public boolean equals(Object obj) {
|
||||||
|
@ -47,20 +44,23 @@ public class SimpleFileInfo implements FileInfo {
|
||||||
FileInfo other = (FileInfo) obj;
|
FileInfo other = (FileInfo) obj;
|
||||||
return other.getLength() == getLength() && other.getPath().equals(getPath());
|
return other.getLength() == getLength() && other.getPath().equals(getPath());
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
public int compareTo(FileInfo other) {
|
||||||
return Arrays.hashCode(new Object[] { getPath(), getLength() });
|
return getPath().compareTo(other.getPath());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return getPath();
|
return getPath();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public File toFile() {
|
||||||
|
return new File(path);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
|
|
||||||
package net.sourceforge.filebot.web;
|
package net.sourceforge.filebot.web;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
|
@ -16,62 +15,19 @@ import java.util.zip.ZipException;
|
||||||
import net.sourceforge.tuned.ByteBufferOutputStream;
|
import net.sourceforge.tuned.ByteBufferOutputStream;
|
||||||
import net.sourceforge.tuned.FileUtilities;
|
import net.sourceforge.tuned.FileUtilities;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Describes a subtitle on OpenSubtitles.
|
* Describes a subtitle on OpenSubtitles.
|
||||||
*
|
*
|
||||||
* @see OpenSubtitlesXmlRpc
|
* @see OpenSubtitlesXmlRpc
|
||||||
*/
|
*/
|
||||||
public class OpenSubtitlesSubtitleDescriptor implements SubtitleDescriptor, Serializable {
|
public class OpenSubtitlesSubtitleDescriptor implements SubtitleDescriptor, Serializable {
|
||||||
|
|
||||||
public static enum Property {
|
public static enum Property {
|
||||||
IDSubtitle,
|
IDSubtitle, IDSubtitleFile, IDSubMovieFile, IDMovie, IDMovieImdb, SubFileName, SubFormat, SubHash, SubSize, MovieHash, MovieByteSize, MovieName, MovieNameEng, MovieYear, MovieReleaseName, MovieTimeMS, MovieFPS, MovieImdbRating, MovieKind, SeriesSeason, SeriesEpisode, SeriesIMDBParent, SubLanguageID, ISO639, LanguageName, UserID, UserRank, UserNickName, SubAddDate, SubAuthorComment, SubFeatured, SubComments, SubDownloadsCnt, SubHearingImpaired, SubRating, SubHD, SubBad, SubActualCD, SubSumCD, MatchedBy, SubtitlesLink, SubDownloadLink, ZipDownloadLink;
|
||||||
IDSubtitleFile,
|
|
||||||
IDSubMovieFile,
|
|
||||||
IDMovie,
|
|
||||||
IDMovieImdb,
|
|
||||||
SubFileName,
|
|
||||||
SubFormat,
|
|
||||||
SubHash,
|
|
||||||
SubSize,
|
|
||||||
MovieHash,
|
|
||||||
MovieByteSize,
|
|
||||||
MovieName,
|
|
||||||
MovieNameEng,
|
|
||||||
MovieYear,
|
|
||||||
MovieReleaseName,
|
|
||||||
MovieTimeMS,
|
|
||||||
MovieFPS,
|
|
||||||
MovieImdbRating,
|
|
||||||
MovieKind,
|
|
||||||
SeriesSeason,
|
|
||||||
SeriesEpisode,
|
|
||||||
SeriesIMDBParent,
|
|
||||||
SubLanguageID,
|
|
||||||
ISO639,
|
|
||||||
LanguageName,
|
|
||||||
UserID,
|
|
||||||
UserRank,
|
|
||||||
UserNickName,
|
|
||||||
SubAddDate,
|
|
||||||
SubAuthorComment,
|
|
||||||
SubFeatured,
|
|
||||||
SubComments,
|
|
||||||
SubDownloadsCnt,
|
|
||||||
SubHearingImpaired,
|
|
||||||
SubRating,
|
|
||||||
SubHD,
|
|
||||||
SubBad,
|
|
||||||
SubActualCD,
|
|
||||||
SubSumCD,
|
|
||||||
MatchedBy,
|
|
||||||
SubtitlesLink,
|
|
||||||
SubDownloadLink,
|
|
||||||
ZipDownloadLink;
|
|
||||||
|
|
||||||
public static <V> EnumMap<Property, V> asEnumMap(Map<String, V> stringMap) {
|
public static <V> EnumMap<Property, V> asEnumMap(Map<String, V> stringMap) {
|
||||||
EnumMap<Property, V> enumMap = new EnumMap<Property, V>(Property.class);
|
EnumMap<Property, V> enumMap = new EnumMap<Property, V>(Property.class);
|
||||||
|
|
||||||
// copy entry set to enum map
|
// copy entry set to enum map
|
||||||
for (Entry<String, V> entry : stringMap.entrySet()) {
|
for (Entry<String, V> entry : stringMap.entrySet()) {
|
||||||
try {
|
try {
|
||||||
|
@ -80,109 +36,101 @@ public class OpenSubtitlesSubtitleDescriptor implements SubtitleDescriptor, Seri
|
||||||
// illegal enum constant, just ignore
|
// illegal enum constant, just ignore
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return enumMap;
|
return enumMap;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private final Map<Property, String> properties;
|
private final Map<Property, String> properties;
|
||||||
|
|
||||||
|
|
||||||
public OpenSubtitlesSubtitleDescriptor(Map<Property, String> properties) {
|
public OpenSubtitlesSubtitleDescriptor(Map<Property, String> properties) {
|
||||||
this.properties = properties;
|
this.properties = properties;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public String getProperty(Property key) {
|
public String getProperty(Property key) {
|
||||||
return properties.get(key);
|
return properties.get(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getPath() {
|
public String getPath() {
|
||||||
return getProperty(Property.SubFileName);
|
return getProperty(Property.SubFileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getName() {
|
public String getName() {
|
||||||
return FileUtilities.getNameWithoutExtension(getProperty(Property.SubFileName));
|
return FileUtilities.getNameWithoutExtension(getProperty(Property.SubFileName));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getLanguageName() {
|
public String getLanguageName() {
|
||||||
return getProperty(Property.LanguageName);
|
return getProperty(Property.LanguageName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getType() {
|
public String getType() {
|
||||||
return getProperty(Property.SubFormat);
|
return getProperty(Property.SubFormat);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public long getLength() {
|
public long getLength() {
|
||||||
return Long.parseLong(getProperty(Property.SubSize));
|
return Long.parseLong(getProperty(Property.SubSize));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public String getMovieHash() {
|
public String getMovieHash() {
|
||||||
return getProperty(Property.MovieHash);
|
return getProperty(Property.MovieHash);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public long getMovieByteSize() {
|
public long getMovieByteSize() {
|
||||||
return Long.parseLong(getProperty(Property.MovieByteSize));
|
return Long.parseLong(getProperty(Property.MovieByteSize));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ByteBuffer fetch() throws Exception {
|
public ByteBuffer fetch() throws Exception {
|
||||||
URL resource = new URL(getProperty(Property.SubDownloadLink));
|
URL resource = new URL(getProperty(Property.SubDownloadLink));
|
||||||
InputStream stream = resource.openStream();
|
InputStream stream = resource.openStream();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
ByteBufferOutputStream buffer = new ByteBufferOutputStream(getLength());
|
ByteBufferOutputStream buffer = new ByteBufferOutputStream(getLength());
|
||||||
|
|
||||||
// extract gzipped subtitle on-the-fly
|
// extract gzipped subtitle on-the-fly
|
||||||
try {
|
try {
|
||||||
stream = new GZIPInputStream(stream);
|
stream = new GZIPInputStream(stream);
|
||||||
} catch (ZipException e) {
|
} catch (ZipException e) {
|
||||||
throw new IOException(String.format("%s: anti-leech limit may have been reached", e.getMessage()));
|
throw new IOException(String.format("%s: anti-leech limit may have been reached", e.getMessage()));
|
||||||
}
|
}
|
||||||
|
|
||||||
// fully download
|
// fully download
|
||||||
buffer.transferFully(stream);
|
buffer.transferFully(stream);
|
||||||
|
|
||||||
return buffer.getByteBuffer();
|
return buffer.getByteBuffer();
|
||||||
} finally {
|
} finally {
|
||||||
stream.close();
|
stream.close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
return getProperty(Property.IDSubtitle).hashCode();
|
return getProperty(Property.IDSubtitle).hashCode();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(Object object) {
|
public boolean equals(Object object) {
|
||||||
if (object instanceof OpenSubtitlesSubtitleDescriptor) {
|
if (object instanceof OpenSubtitlesSubtitleDescriptor) {
|
||||||
OpenSubtitlesSubtitleDescriptor other = (OpenSubtitlesSubtitleDescriptor) object;
|
OpenSubtitlesSubtitleDescriptor other = (OpenSubtitlesSubtitleDescriptor) object;
|
||||||
return getProperty(Property.IDSubtitle).equals(other.getProperty(Property.IDSubtitle));
|
return getProperty(Property.IDSubtitle).equals(other.getProperty(Property.IDSubtitle));
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return String.format("%s [%s]", getName(), getLanguageName());
|
return String.format("%s [%s]", getName(), getLanguageName());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public File toFile() {
|
||||||
|
return new File(getPath());
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue