2009-04-04 19:36:12 +00:00
|
|
|
|
|
|
|
package net.sourceforge.filebot.format;
|
|
|
|
|
|
|
|
|
2012-03-17 19:02:04 +00:00
|
|
|
import static java.util.Arrays.*;
|
2009-08-10 11:46:24 +00:00
|
|
|
import static net.sourceforge.filebot.MediaTypes.*;
|
2009-05-17 17:22:44 +00:00
|
|
|
import static net.sourceforge.filebot.format.Define.*;
|
2009-08-10 11:46:24 +00:00
|
|
|
import static net.sourceforge.filebot.hash.VerificationUtilities.*;
|
2012-07-06 03:10:26 +00:00
|
|
|
import static net.sourceforge.filebot.media.MediaDetection.*;
|
2012-03-17 19:02:04 +00:00
|
|
|
import static net.sourceforge.filebot.similarity.Normalization.*;
|
2011-11-20 18:38:49 +00:00
|
|
|
import static net.sourceforge.filebot.web.EpisodeFormat.*;
|
2011-11-21 12:24:51 +00:00
|
|
|
import static net.sourceforge.tuned.FileUtilities.*;
|
2012-03-17 19:02:04 +00:00
|
|
|
import static net.sourceforge.tuned.StringUtilities.*;
|
2009-04-04 19:36:12 +00:00
|
|
|
|
|
|
|
import java.io.File;
|
|
|
|
import java.io.IOException;
|
2012-07-10 06:20:01 +00:00
|
|
|
import java.util.Arrays;
|
2012-03-17 19:02:04 +00:00
|
|
|
import java.util.LinkedHashSet;
|
|
|
|
import java.util.List;
|
2011-11-21 12:24:51 +00:00
|
|
|
import java.util.Locale;
|
2012-07-08 03:09:42 +00:00
|
|
|
import java.util.Map;
|
2009-04-25 07:59:08 +00:00
|
|
|
import java.util.Scanner;
|
2012-03-17 19:02:04 +00:00
|
|
|
import java.util.Set;
|
2009-04-04 19:36:12 +00:00
|
|
|
|
2012-07-25 04:34:20 +00:00
|
|
|
import net.sourceforge.filebot.Cache;
|
2011-11-21 12:24:51 +00:00
|
|
|
import net.sourceforge.filebot.WebServices;
|
2009-08-10 11:46:24 +00:00
|
|
|
import net.sourceforge.filebot.hash.HashType;
|
2009-04-04 19:36:12 +00:00
|
|
|
import net.sourceforge.filebot.mediainfo.MediaInfo;
|
|
|
|
import net.sourceforge.filebot.mediainfo.MediaInfo.StreamKind;
|
2010-10-23 12:47:43 +00:00
|
|
|
import net.sourceforge.filebot.web.Date;
|
2009-04-04 19:36:12 +00:00
|
|
|
import net.sourceforge.filebot.web.Episode;
|
2011-09-22 12:55:04 +00:00
|
|
|
import net.sourceforge.filebot.web.Movie;
|
2011-09-18 19:08:03 +00:00
|
|
|
import net.sourceforge.filebot.web.MoviePart;
|
2012-03-17 19:02:04 +00:00
|
|
|
import net.sourceforge.filebot.web.MultiEpisode;
|
2012-02-13 10:18:00 +00:00
|
|
|
import net.sourceforge.filebot.web.SortOrder;
|
2009-05-02 23:34:04 +00:00
|
|
|
import net.sourceforge.tuned.FileUtilities;
|
2009-04-04 19:36:12 +00:00
|
|
|
|
|
|
|
|
2011-09-18 19:08:03 +00:00
|
|
|
public class MediaBindingBean {
|
2009-04-04 19:36:12 +00:00
|
|
|
|
2011-09-18 19:08:03 +00:00
|
|
|
private final Object infoObject;
|
2009-04-04 19:36:12 +00:00
|
|
|
private final File mediaFile;
|
|
|
|
private MediaInfo mediaInfo;
|
2012-02-08 12:24:36 +00:00
|
|
|
private Object metaInfo;
|
2009-04-04 19:36:12 +00:00
|
|
|
|
2011-12-19 06:31:48 +00:00
|
|
|
|
2011-09-18 19:08:03 +00:00
|
|
|
public MediaBindingBean(Object infoObject, File mediaFile) {
|
|
|
|
this.infoObject = infoObject;
|
2009-04-04 19:36:12 +00:00
|
|
|
this.mediaFile = mediaFile;
|
|
|
|
}
|
|
|
|
|
2011-12-19 06:31:48 +00:00
|
|
|
|
2009-04-04 19:36:12 +00:00
|
|
|
@Define(undefined)
|
2011-09-18 19:08:03 +00:00
|
|
|
public <T> T undefined() {
|
2009-04-04 19:36:12 +00:00
|
|
|
// omit expressions that depend on undefined values
|
|
|
|
throw new RuntimeException("undefined");
|
|
|
|
}
|
|
|
|
|
2011-12-19 06:31:48 +00:00
|
|
|
|
2009-04-04 19:36:12 +00:00
|
|
|
@Define("n")
|
2011-09-18 19:08:03 +00:00
|
|
|
public String getName() {
|
|
|
|
if (infoObject instanceof Episode)
|
|
|
|
return getEpisode().getSeriesName();
|
2011-09-22 12:55:04 +00:00
|
|
|
if (infoObject instanceof Movie)
|
2011-09-18 19:08:03 +00:00
|
|
|
return getMovie().getName();
|
|
|
|
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
2011-12-19 06:31:48 +00:00
|
|
|
|
2011-09-18 19:08:03 +00:00
|
|
|
@Define("y")
|
|
|
|
public Integer getYear() {
|
|
|
|
if (infoObject instanceof Episode)
|
2011-10-01 04:08:46 +00:00
|
|
|
return getEpisode().getSeriesStartDate().getYear();
|
2011-09-22 12:55:04 +00:00
|
|
|
if (infoObject instanceof Movie)
|
2011-09-18 19:08:03 +00:00
|
|
|
return getMovie().getYear();
|
|
|
|
|
|
|
|
return null;
|
2009-04-04 19:36:12 +00:00
|
|
|
}
|
|
|
|
|
2011-12-19 06:31:48 +00:00
|
|
|
|
2009-04-04 19:36:12 +00:00
|
|
|
@Define("s")
|
2010-10-24 12:10:30 +00:00
|
|
|
public Integer getSeasonNumber() {
|
2011-09-18 19:08:03 +00:00
|
|
|
return getEpisode().getSeason();
|
2009-04-04 19:36:12 +00:00
|
|
|
}
|
|
|
|
|
2011-12-19 06:31:48 +00:00
|
|
|
|
2009-04-04 19:36:12 +00:00
|
|
|
@Define("e")
|
2010-10-24 12:10:30 +00:00
|
|
|
public Integer getEpisodeNumber() {
|
2011-09-18 19:08:03 +00:00
|
|
|
return getEpisode().getEpisode();
|
2009-04-04 19:36:12 +00:00
|
|
|
}
|
|
|
|
|
2011-12-19 06:31:48 +00:00
|
|
|
|
2011-11-27 17:04:32 +00:00
|
|
|
@Define("sxe")
|
2011-11-20 18:38:49 +00:00
|
|
|
public String getSxE() {
|
|
|
|
return SeasonEpisode.formatSxE(getEpisode());
|
|
|
|
}
|
|
|
|
|
2011-12-19 06:31:48 +00:00
|
|
|
|
2011-11-27 17:04:32 +00:00
|
|
|
@Define("s00e00")
|
2011-11-20 18:38:49 +00:00
|
|
|
public String getS00E00() {
|
|
|
|
return SeasonEpisode.formatS00E00(getEpisode());
|
|
|
|
}
|
|
|
|
|
2011-12-19 06:31:48 +00:00
|
|
|
|
2009-04-04 19:36:12 +00:00
|
|
|
@Define("t")
|
|
|
|
public String getTitle() {
|
2012-04-10 01:19:34 +00:00
|
|
|
// single episode format
|
|
|
|
if (getEpisodes().size() == 1) {
|
|
|
|
return getEpisode().getTitle();
|
|
|
|
}
|
|
|
|
|
|
|
|
// multi-episode format
|
2012-03-17 19:02:04 +00:00
|
|
|
Set<String> title = new LinkedHashSet<String>();
|
|
|
|
for (Episode it : getEpisodes()) {
|
|
|
|
title.add(removeTrailingBrackets(it.getTitle()));
|
|
|
|
}
|
|
|
|
return join(title, " & ");
|
2009-04-04 19:36:12 +00:00
|
|
|
}
|
|
|
|
|
2011-12-19 06:31:48 +00:00
|
|
|
|
2010-11-09 08:04:12 +00:00
|
|
|
@Define("airdate")
|
2010-10-23 12:47:43 +00:00
|
|
|
public Date airdate() {
|
2011-09-18 19:08:03 +00:00
|
|
|
return getEpisode().airdate();
|
2010-10-23 12:47:43 +00:00
|
|
|
}
|
|
|
|
|
2011-12-19 06:31:48 +00:00
|
|
|
|
2011-10-01 04:08:46 +00:00
|
|
|
@Define("startdate")
|
|
|
|
public Date startdate() {
|
|
|
|
return getEpisode().getSeriesStartDate();
|
|
|
|
}
|
|
|
|
|
2011-12-19 06:31:48 +00:00
|
|
|
|
2010-11-09 08:04:12 +00:00
|
|
|
@Define("absolute")
|
|
|
|
public Integer getAbsoluteEpisodeNumber() {
|
2011-09-18 19:08:03 +00:00
|
|
|
return getEpisode().getAbsolute();
|
2010-11-09 08:04:12 +00:00
|
|
|
}
|
|
|
|
|
2011-12-19 06:31:48 +00:00
|
|
|
|
2010-11-09 08:04:12 +00:00
|
|
|
@Define("special")
|
|
|
|
public Integer getSpecialNumber() {
|
2011-09-18 19:08:03 +00:00
|
|
|
return getEpisode().getSpecial();
|
|
|
|
}
|
|
|
|
|
2011-12-19 06:31:48 +00:00
|
|
|
|
2012-07-22 11:54:49 +00:00
|
|
|
@Define("imdbid")
|
2012-07-24 17:44:54 +00:00
|
|
|
public String getImdbId() throws Exception {
|
|
|
|
int imdbid = getMovie().getImdbId();
|
2011-09-19 14:21:21 +00:00
|
|
|
|
2012-07-24 17:44:54 +00:00
|
|
|
if (imdbid <= 0) {
|
|
|
|
if (getMovie().getTmdbId() <= 0) {
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
|
|
|
// lookup IMDbID for TMDbID
|
|
|
|
imdbid = WebServices.TMDb.getMovieInfo(getMovie(), null).getImdbId();
|
|
|
|
}
|
2011-09-19 14:21:21 +00:00
|
|
|
|
2012-07-24 17:44:54 +00:00
|
|
|
return String.format("%07d", imdbid);
|
2010-11-09 08:04:12 +00:00
|
|
|
}
|
|
|
|
|
2011-12-19 06:31:48 +00:00
|
|
|
|
2009-04-04 19:36:12 +00:00
|
|
|
@Define("vc")
|
|
|
|
public String getVideoCodec() {
|
2009-08-23 15:17:32 +00:00
|
|
|
// e.g. XviD, x264, DivX 5, MPEG-4 Visual, AVC, etc.
|
|
|
|
String codec = getMediaInfo(StreamKind.Video, 0, "Encoded_Library/Name", "CodecID/Hint", "Format");
|
|
|
|
|
|
|
|
// get first token (e.g. DivX 5 => DivX)
|
|
|
|
return new Scanner(codec).next();
|
2009-04-04 19:36:12 +00:00
|
|
|
}
|
|
|
|
|
2011-12-19 06:31:48 +00:00
|
|
|
|
2009-04-04 19:36:12 +00:00
|
|
|
@Define("ac")
|
|
|
|
public String getAudioCodec() {
|
2009-08-23 15:17:32 +00:00
|
|
|
// e.g. AC-3, DTS, AAC, Vorbis, MP3, etc.
|
|
|
|
String codec = getMediaInfo(StreamKind.Audio, 0, "CodecID/Hint", "Format");
|
|
|
|
|
|
|
|
// remove punctuation (e.g. AC-3 => AC3)
|
|
|
|
return codec.replaceAll("\\p{Punct}", "");
|
2009-04-04 19:36:12 +00:00
|
|
|
}
|
|
|
|
|
2011-12-19 06:31:48 +00:00
|
|
|
|
2009-05-02 23:34:04 +00:00
|
|
|
@Define("cf")
|
|
|
|
public String getContainerFormat() {
|
2009-08-23 15:17:32 +00:00
|
|
|
// container format extensions (e.g. avi, mkv mka mks, OGG, etc.)
|
|
|
|
String extensions = getMediaInfo(StreamKind.General, 0, "Codec/Extensions", "Format");
|
2009-05-02 23:34:04 +00:00
|
|
|
|
2009-08-23 15:17:32 +00:00
|
|
|
// get first extension
|
|
|
|
return new Scanner(extensions).next().toLowerCase();
|
2009-05-02 23:34:04 +00:00
|
|
|
}
|
|
|
|
|
2011-12-19 06:31:48 +00:00
|
|
|
|
2009-08-23 15:17:32 +00:00
|
|
|
@Define("vf")
|
|
|
|
public String getVideoFormat() {
|
2012-07-08 12:38:34 +00:00
|
|
|
int height = Integer.parseInt(getMediaInfo(StreamKind.Video, 0, "Height"));
|
|
|
|
|
2012-07-16 11:43:14 +00:00
|
|
|
int ns = 0;
|
|
|
|
int[] hs = new int[] { 1080, 720, 480, 360, 240, 120 };
|
|
|
|
for (int i = 0; i < hs.length - 1; i++) {
|
|
|
|
if (height > hs[i + 1]) {
|
|
|
|
ns = hs[i];
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (ns > 0) {
|
|
|
|
// e.g. 720p, nobody actually wants files to be tagged as interlaced, e.g. 720i
|
|
|
|
return String.format("%dp", ns);
|
|
|
|
}
|
|
|
|
|
|
|
|
return null; // video too small
|
2012-07-08 12:38:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@Define("hpi")
|
|
|
|
public String getExactVideoFormat() {
|
2009-04-04 19:36:12 +00:00
|
|
|
String height = getMediaInfo(StreamKind.Video, 0, "Height");
|
2009-08-23 15:17:32 +00:00
|
|
|
String scanType = getMediaInfo(StreamKind.Video, 0, "ScanType");
|
2009-04-04 19:36:12 +00:00
|
|
|
|
2009-08-23 15:17:32 +00:00
|
|
|
if (height == null || scanType == null)
|
2009-04-04 19:36:12 +00:00
|
|
|
return null;
|
|
|
|
|
|
|
|
// e.g. 720p
|
2009-08-23 15:17:32 +00:00
|
|
|
return height + Character.toLowerCase(scanType.charAt(0));
|
2009-04-04 19:36:12 +00:00
|
|
|
}
|
|
|
|
|
2011-12-19 06:31:48 +00:00
|
|
|
|
2011-09-18 19:08:03 +00:00
|
|
|
@Define("af")
|
|
|
|
public String getAudioChannels() {
|
|
|
|
String channels = getMediaInfo(StreamKind.Audio, 0, "Channel(s)");
|
|
|
|
|
|
|
|
if (channels == null)
|
|
|
|
return null;
|
|
|
|
|
|
|
|
// e.g. 6ch
|
|
|
|
return channels + "ch";
|
|
|
|
}
|
|
|
|
|
2011-12-19 06:31:48 +00:00
|
|
|
|
2009-04-04 19:36:12 +00:00
|
|
|
@Define("resolution")
|
|
|
|
public String getVideoResolution() {
|
2012-07-10 06:20:01 +00:00
|
|
|
List<Integer> dim = getDimension();
|
2009-04-04 19:36:12 +00:00
|
|
|
|
2012-07-10 06:20:01 +00:00
|
|
|
if (dim.contains(null))
|
2009-04-04 19:36:12 +00:00
|
|
|
return null;
|
|
|
|
|
|
|
|
// e.g. 1280x720
|
2012-07-10 06:20:01 +00:00
|
|
|
return join(dim, "x");
|
2009-04-04 19:36:12 +00:00
|
|
|
}
|
|
|
|
|
2011-12-19 06:31:48 +00:00
|
|
|
|
2011-11-20 18:38:49 +00:00
|
|
|
@Define("ws")
|
|
|
|
public String getWidescreen() {
|
2012-07-10 06:20:01 +00:00
|
|
|
List<Integer> dim = getDimension();
|
2011-11-20 18:38:49 +00:00
|
|
|
|
|
|
|
// width-to-height aspect ratio greater than 1.37:1
|
2012-07-10 06:20:01 +00:00
|
|
|
return (float) dim.get(0) / dim.get(1) > 1.37f ? "ws" : null;
|
2011-11-20 18:38:49 +00:00
|
|
|
}
|
|
|
|
|
2011-12-19 06:31:48 +00:00
|
|
|
|
2011-11-02 14:48:23 +00:00
|
|
|
@Define("sdhd")
|
|
|
|
public String getVideoDefinitionCategory() {
|
2012-07-10 06:20:01 +00:00
|
|
|
List<Integer> dim = getDimension();
|
2011-11-02 14:48:23 +00:00
|
|
|
|
|
|
|
// SD (less than 720 lines) or HD (more than 720 lines)
|
2012-07-10 06:20:01 +00:00
|
|
|
return dim.get(0) >= 1280 || dim.get(1) >= 720 ? "HD" : "SD";
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@Define("dim")
|
|
|
|
public List<Integer> getDimension() {
|
|
|
|
String width = getMediaInfo(StreamKind.Video, 0, "Width");
|
|
|
|
String height = getMediaInfo(StreamKind.Video, 0, "Height");
|
|
|
|
|
|
|
|
return Arrays.asList(width != null ? Integer.parseInt(width) : null, height != null ? Integer.parseInt(height) : null);
|
2011-11-02 14:48:23 +00:00
|
|
|
}
|
|
|
|
|
2011-12-19 06:31:48 +00:00
|
|
|
|
2009-04-04 19:36:12 +00:00
|
|
|
@Define("crc32")
|
2009-04-26 13:34:22 +00:00
|
|
|
public String getCRC32() throws IOException, InterruptedException {
|
2009-05-26 17:05:05 +00:00
|
|
|
// use inferred media file
|
|
|
|
File inferredMediaFile = getInferredMediaFile();
|
|
|
|
|
2009-05-03 15:21:04 +00:00
|
|
|
// try to get checksum from file name
|
2009-08-10 11:46:24 +00:00
|
|
|
String checksum = getEmbeddedChecksum(inferredMediaFile.getName());
|
2009-05-03 15:21:04 +00:00
|
|
|
|
|
|
|
if (checksum != null)
|
|
|
|
return checksum;
|
|
|
|
|
|
|
|
// try to get checksum from sfv file
|
2009-08-10 11:46:24 +00:00
|
|
|
checksum = getHashFromVerificationFile(inferredMediaFile, HashType.SFV, 3);
|
2009-05-03 15:21:04 +00:00
|
|
|
|
|
|
|
if (checksum != null)
|
|
|
|
return checksum;
|
|
|
|
|
|
|
|
// calculate checksum from file
|
2009-05-26 17:05:05 +00:00
|
|
|
return crc32(inferredMediaFile);
|
2009-04-04 19:36:12 +00:00
|
|
|
}
|
|
|
|
|
2011-12-19 06:31:48 +00:00
|
|
|
|
2010-10-24 12:10:30 +00:00
|
|
|
@Define("fn")
|
|
|
|
public String getFileName() {
|
|
|
|
// make sure media file is defined
|
|
|
|
checkMediaFile();
|
|
|
|
|
|
|
|
// file extension
|
|
|
|
return FileUtilities.getName(mediaFile);
|
|
|
|
}
|
|
|
|
|
2011-12-19 06:31:48 +00:00
|
|
|
|
2009-05-02 23:34:04 +00:00
|
|
|
@Define("ext")
|
2009-05-03 16:28:39 +00:00
|
|
|
public String getExtension() {
|
2009-05-03 15:21:04 +00:00
|
|
|
// make sure media file is defined
|
|
|
|
checkMediaFile();
|
|
|
|
|
2009-05-02 23:34:04 +00:00
|
|
|
// file extension
|
|
|
|
return FileUtilities.getExtension(mediaFile);
|
|
|
|
}
|
|
|
|
|
2011-12-19 06:31:48 +00:00
|
|
|
|
2011-09-18 19:08:03 +00:00
|
|
|
@Define("source")
|
|
|
|
public String getVideoSource() {
|
|
|
|
// use inferred media file
|
|
|
|
File inferredMediaFile = getInferredMediaFile();
|
|
|
|
|
|
|
|
// look for video source patterns in media file and it's parent folder
|
2011-11-14 11:43:22 +00:00
|
|
|
return releaseInfo.getVideoSource(inferredMediaFile);
|
2011-09-18 19:08:03 +00:00
|
|
|
}
|
|
|
|
|
2011-12-19 06:31:48 +00:00
|
|
|
|
2011-09-18 19:08:03 +00:00
|
|
|
@Define("group")
|
|
|
|
public String getReleaseGroup() throws IOException {
|
|
|
|
// use inferred media file
|
|
|
|
File inferredMediaFile = getInferredMediaFile();
|
|
|
|
|
|
|
|
// look for release group names in media file and it's parent folder
|
2011-11-14 11:43:22 +00:00
|
|
|
return releaseInfo.getReleaseGroup(inferredMediaFile);
|
2011-09-18 19:08:03 +00:00
|
|
|
}
|
|
|
|
|
2011-12-19 06:31:48 +00:00
|
|
|
|
2011-11-21 12:24:51 +00:00
|
|
|
@Define("lang")
|
|
|
|
public Locale detectSubtitleLanguage() throws Exception {
|
2012-01-02 16:59:37 +00:00
|
|
|
// make sure media file is defined
|
|
|
|
checkMediaFile();
|
|
|
|
|
2012-07-06 03:10:26 +00:00
|
|
|
Locale languageSuffix = releaseInfo.getLanguageSuffix(FileUtilities.getName(mediaFile));
|
2012-01-02 16:59:37 +00:00
|
|
|
if (languageSuffix != null)
|
2012-02-15 06:16:32 +00:00
|
|
|
return new Locale(languageSuffix.getISO3Language()); // force ISO3 letter-code
|
|
|
|
|
2011-11-21 12:24:51 +00:00
|
|
|
// require subtitle file
|
|
|
|
if (!SUBTITLE_FILES.accept(mediaFile))
|
|
|
|
return null;
|
|
|
|
|
|
|
|
return WebServices.OpenSubtitles.detectLanguage(readFile(mediaFile));
|
|
|
|
}
|
|
|
|
|
2011-12-19 06:31:48 +00:00
|
|
|
|
2012-02-20 07:07:06 +00:00
|
|
|
@Define("actors")
|
|
|
|
public Object getActors() {
|
|
|
|
return getMetaInfo().getProperty("actors");
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@Define("genres")
|
|
|
|
public Object getGenres() {
|
|
|
|
return getMetaInfo().getProperty("genres");
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@Define("director")
|
|
|
|
public Object getDirector() {
|
|
|
|
return getMetaInfo().getProperty("director");
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@Define("certification")
|
|
|
|
public Object getCertification() {
|
|
|
|
return getMetaInfo().getProperty("certification");
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@Define("rating")
|
|
|
|
public Object getRating() {
|
|
|
|
return getMetaInfo().getProperty("rating");
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2012-07-24 17:44:54 +00:00
|
|
|
@Define("collection")
|
|
|
|
public Object getCollection() {
|
|
|
|
return getMetaInfo().getProperty("collection");
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2012-02-09 13:42:14 +00:00
|
|
|
@Define("info")
|
2012-02-20 07:07:06 +00:00
|
|
|
public synchronized AssociativeScriptObject getMetaInfo() {
|
2012-02-08 12:24:36 +00:00
|
|
|
if (metaInfo == null) {
|
2012-02-20 07:07:06 +00:00
|
|
|
try {
|
|
|
|
if (infoObject instanceof Episode)
|
|
|
|
metaInfo = WebServices.TheTVDB.getSeriesInfoByName(((Episode) infoObject).getSeriesName(), Locale.ENGLISH);
|
|
|
|
if (infoObject instanceof Movie)
|
2012-07-24 17:44:54 +00:00
|
|
|
metaInfo = WebServices.TMDb.getMovieInfo(getMovie(), Locale.ENGLISH);
|
2012-02-20 07:07:06 +00:00
|
|
|
} catch (Exception e) {
|
|
|
|
throw new RuntimeException("Failed to retrieve metadata: " + infoObject, e);
|
|
|
|
}
|
2012-02-08 12:24:36 +00:00
|
|
|
}
|
|
|
|
|
2012-07-08 03:09:42 +00:00
|
|
|
return createMapBindings(new PropertyBindings(metaInfo, null));
|
2012-02-08 12:24:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2012-07-22 11:54:49 +00:00
|
|
|
@Define("imdb")
|
2012-07-22 09:44:08 +00:00
|
|
|
public synchronized AssociativeScriptObject getImdbApiInfo() {
|
|
|
|
Object data = null;
|
|
|
|
|
|
|
|
try {
|
2012-07-24 17:44:54 +00:00
|
|
|
if (infoObject instanceof Episode) {
|
|
|
|
data = WebServices.IMDb.getImdbApiMovieInfo(new Movie(getEpisode().getSeriesName(), getEpisode().getSeriesStartDate().getYear(), -1, -1));
|
|
|
|
}
|
|
|
|
if (infoObject instanceof Movie) {
|
|
|
|
Movie m = getMovie();
|
|
|
|
data = WebServices.IMDb.getImdbApiMovieInfo(m.getImdbId() > 0 ? m : new Movie(null, -1, WebServices.TMDb.getMovieInfo(getMovie(), Locale.ENGLISH).getId(), -1));
|
|
|
|
}
|
2012-07-22 09:44:08 +00:00
|
|
|
} catch (Exception e) {
|
|
|
|
throw new RuntimeException("Failed to retrieve metadata: " + infoObject, e);
|
|
|
|
}
|
|
|
|
|
|
|
|
return createMapBindings(new PropertyBindings(data, null));
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2012-03-17 19:02:04 +00:00
|
|
|
@Define("episodelist")
|
2012-02-13 10:18:00 +00:00
|
|
|
public Object getEpisodeList() throws Exception {
|
|
|
|
return WebServices.TheTVDB.getEpisodeList(WebServices.TheTVDB.search(getEpisode().getSeriesName()).get(0), SortOrder.Airdate, Locale.ENGLISH);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2009-05-03 16:28:39 +00:00
|
|
|
@Define("media")
|
2012-02-20 07:07:06 +00:00
|
|
|
public AssociativeScriptObject getGeneralMediaInfo() {
|
2012-07-08 03:09:42 +00:00
|
|
|
return createMapBindings(getMediaInfo().snapshot(StreamKind.General, 0));
|
2009-04-05 21:03:40 +00:00
|
|
|
}
|
|
|
|
|
2011-12-19 06:31:48 +00:00
|
|
|
|
2009-04-04 19:36:12 +00:00
|
|
|
@Define("video")
|
2012-02-20 07:07:06 +00:00
|
|
|
public AssociativeScriptObject getVideoInfo() {
|
2012-07-08 03:09:42 +00:00
|
|
|
return createMapBindings(getMediaInfo().snapshot(StreamKind.Video, 0));
|
2009-04-04 19:36:12 +00:00
|
|
|
}
|
|
|
|
|
2011-12-19 06:31:48 +00:00
|
|
|
|
2009-04-04 19:36:12 +00:00
|
|
|
@Define("audio")
|
2012-02-20 07:07:06 +00:00
|
|
|
public AssociativeScriptObject getAudioInfo() {
|
2012-07-08 03:09:42 +00:00
|
|
|
return createMapBindings(getMediaInfo().snapshot(StreamKind.Audio, 0));
|
2009-04-04 19:36:12 +00:00
|
|
|
}
|
|
|
|
|
2011-12-19 06:31:48 +00:00
|
|
|
|
2009-04-05 21:03:40 +00:00
|
|
|
@Define("text")
|
2012-02-20 07:07:06 +00:00
|
|
|
public AssociativeScriptObject getTextInfo() {
|
2012-07-08 03:09:42 +00:00
|
|
|
return createMapBindings(getMediaInfo().snapshot(StreamKind.Text, 0));
|
2009-04-04 19:36:12 +00:00
|
|
|
}
|
|
|
|
|
2011-12-19 06:31:48 +00:00
|
|
|
|
2009-05-02 23:34:04 +00:00
|
|
|
@Define("episode")
|
2009-04-25 07:59:08 +00:00
|
|
|
public Episode getEpisode() {
|
2011-09-18 19:08:03 +00:00
|
|
|
return (Episode) infoObject;
|
|
|
|
}
|
|
|
|
|
2011-12-19 06:31:48 +00:00
|
|
|
|
2012-03-17 19:02:04 +00:00
|
|
|
@Define("episodes")
|
|
|
|
public List<Episode> getEpisodes() {
|
|
|
|
return infoObject instanceof MultiEpisode ? ((MultiEpisode) infoObject).getEpisodes() : asList(getEpisode());
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2011-09-18 19:08:03 +00:00
|
|
|
@Define("movie")
|
2011-09-22 12:55:04 +00:00
|
|
|
public Movie getMovie() {
|
|
|
|
return (Movie) infoObject;
|
2009-04-25 07:59:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2011-09-18 19:08:03 +00:00
|
|
|
@Define("pi")
|
|
|
|
public Integer getPart() {
|
2011-09-19 14:21:21 +00:00
|
|
|
return ((MoviePart) infoObject).getPartIndex();
|
2011-09-18 19:08:03 +00:00
|
|
|
}
|
|
|
|
|
2011-12-19 06:31:48 +00:00
|
|
|
|
2011-09-18 19:08:03 +00:00
|
|
|
@Define("pn")
|
|
|
|
public Integer getPartCount() {
|
2011-09-19 14:21:21 +00:00
|
|
|
return ((MoviePart) infoObject).getPartCount();
|
2011-09-18 19:08:03 +00:00
|
|
|
}
|
|
|
|
|
2011-12-19 06:31:48 +00:00
|
|
|
|
|
|
|
@Define("file")
|
|
|
|
public File getMediaFile() {
|
|
|
|
return mediaFile;
|
2012-02-14 14:16:13 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@Define("folder")
|
|
|
|
public File getMediaParentFolder() {
|
|
|
|
return mediaFile.getParentFile();
|
2011-12-19 06:31:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@Define("home")
|
|
|
|
public File getUserHome() throws IOException {
|
|
|
|
return new File(System.getProperty("user.home"));
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2011-09-18 19:08:03 +00:00
|
|
|
public Object getInfoObject() {
|
|
|
|
return infoObject;
|
|
|
|
}
|
|
|
|
|
2011-12-19 06:31:48 +00:00
|
|
|
|
2009-07-29 20:31:08 +00:00
|
|
|
private File getInferredMediaFile() {
|
2009-05-03 17:38:22 +00:00
|
|
|
// make sure media file is defined
|
|
|
|
checkMediaFile();
|
|
|
|
|
2012-07-21 15:54:39 +00:00
|
|
|
if (SUBTITLE_FILES.accept(mediaFile) || getDefaultFilter("application/nfo").accept(mediaFile)) {
|
2009-05-03 16:28:39 +00:00
|
|
|
// file is a subtitle
|
2012-07-21 15:54:39 +00:00
|
|
|
String baseName = stripReleaseInfo(FileUtilities.getName(mediaFile).toLowerCase());
|
2009-05-03 16:28:39 +00:00
|
|
|
|
|
|
|
// find corresponding movie file
|
2012-07-21 15:54:39 +00:00
|
|
|
for (File movieFile : mediaFile.getParentFile().listFiles(VIDEO_FILES)) {
|
|
|
|
if (baseName.startsWith(stripReleaseInfo(FileUtilities.getName(movieFile)).toLowerCase())) {
|
|
|
|
return movieFile;
|
2009-05-03 16:28:39 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return mediaFile;
|
|
|
|
}
|
|
|
|
|
2011-12-19 06:31:48 +00:00
|
|
|
|
2009-07-29 20:31:08 +00:00
|
|
|
private void checkMediaFile() throws RuntimeException {
|
|
|
|
// make sure file is not null, and that it is an existing file
|
|
|
|
if (mediaFile == null || !mediaFile.isFile())
|
2011-09-13 01:44:54 +00:00
|
|
|
throw new RuntimeException("Invalid media file: " + mediaFile);
|
2009-05-03 15:21:04 +00:00
|
|
|
}
|
|
|
|
|
2011-12-19 06:31:48 +00:00
|
|
|
|
2009-08-02 11:48:45 +00:00
|
|
|
private synchronized MediaInfo getMediaInfo() {
|
2009-04-04 19:36:12 +00:00
|
|
|
if (mediaInfo == null) {
|
2009-05-03 15:21:04 +00:00
|
|
|
// make sure media file is defined
|
|
|
|
checkMediaFile();
|
|
|
|
|
2009-05-03 16:28:39 +00:00
|
|
|
MediaInfo newMediaInfo = new MediaInfo();
|
2009-04-05 17:43:32 +00:00
|
|
|
|
2009-05-03 17:38:22 +00:00
|
|
|
// use inferred media file (e.g. actual movie file instead of subtitle file)
|
2009-05-03 16:28:39 +00:00
|
|
|
if (!newMediaInfo.open(getInferredMediaFile())) {
|
2011-09-13 01:44:54 +00:00
|
|
|
throw new RuntimeException("Cannot open media file: " + mediaFile);
|
2009-04-04 19:36:12 +00:00
|
|
|
}
|
2009-05-03 16:28:39 +00:00
|
|
|
|
|
|
|
mediaInfo = newMediaInfo;
|
2009-04-04 19:36:12 +00:00
|
|
|
}
|
|
|
|
|
2012-07-21 15:54:39 +00:00
|
|
|
return mediaInfo;
|
2009-04-04 19:36:12 +00:00
|
|
|
}
|
|
|
|
|
2011-12-19 06:31:48 +00:00
|
|
|
|
2009-04-04 19:36:12 +00:00
|
|
|
private String getMediaInfo(StreamKind streamKind, int streamNumber, String... keys) {
|
2009-04-04 20:19:03 +00:00
|
|
|
for (String key : keys) {
|
|
|
|
String value = getMediaInfo().get(streamKind, streamNumber, key);
|
|
|
|
|
2011-09-13 01:44:54 +00:00
|
|
|
if (value.length() > 0)
|
2009-04-04 20:19:03 +00:00
|
|
|
return value;
|
2009-04-04 19:36:12 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
2011-12-19 06:31:48 +00:00
|
|
|
|
2012-07-08 03:09:42 +00:00
|
|
|
private AssociativeScriptObject createMapBindings(Map<?, ?> map) {
|
|
|
|
return new AssociativeScriptObject(map) {
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public Object getProperty(String name) {
|
|
|
|
Object value = super.getProperty(name);
|
|
|
|
|
|
|
|
if (value == null)
|
|
|
|
throw new BindingException(name, "undefined");
|
|
|
|
|
|
|
|
return value;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2009-04-26 13:34:22 +00:00
|
|
|
private String crc32(File file) throws IOException, InterruptedException {
|
2009-04-04 19:36:12 +00:00
|
|
|
// try to get checksum from cache
|
2012-07-25 04:34:20 +00:00
|
|
|
Cache cache = Cache.getCache("checksum");
|
|
|
|
|
|
|
|
String hash = cache.get(file, String.class);
|
|
|
|
if (hash != null) {
|
|
|
|
return hash;
|
|
|
|
}
|
2009-04-26 18:57:27 +00:00
|
|
|
|
2011-09-13 01:44:54 +00:00
|
|
|
// compute and cache checksum
|
2012-07-25 04:34:20 +00:00
|
|
|
hash = computeHash(file, HashType.SFV);
|
|
|
|
cache.put(file, hash);
|
2011-09-13 01:44:54 +00:00
|
|
|
return hash;
|
2009-04-04 19:36:12 +00:00
|
|
|
}
|
|
|
|
}
|