/// <summary> /// Initialize /// </summary> private void Init() { // create an IMDb session if (apiSession == null) { apiSession = IMDbAPI.GetSession(); apiSession.MakeRequest = doWebRequest; } }
/// <summary> /// Searches for titles and names matching the given keywords. /// </summary> /// <param name="session">a session instance.</param> /// <param name="query">the search query keywords.</param> /// <returns></returns> public static SearchResults Search(Session session, string query) { var d = new Dictionary<string, string>(); d.Add("q", query); string uri = string.Format(session.Settings.BaseUriMobile, session.Settings.SearchMobile, "?{0}"); HtmlNode root = GetResponseFromSite(session, uri, d); SearchResults results = new SearchResults(); List<TitleReference> titles = new List<TitleReference>(); HtmlNodeCollection nodes = root.SelectNodes("//div[@class='poster ']"); foreach(HtmlNode node in nodes) { HtmlNode titleNode = node.SelectSingleNode("div[@class='label']/div[@class='title']/a[contains(@href,'title')]"); if (titleNode == null) { continue; } TitleReference title = new TitleReference(); title.session = session; title.ID = titleNode.Attributes["href"].Value.Replace("/title/", "").Replace("/", ""); ParseDisplayStringToTitleBase(title, titleNode.ParentNode.InnerText); HtmlNode detailNode = node.SelectSingleNode("div[@class='label']/div[@class='detail']"); if (detailNode != null) { string[] actors = detailNode.InnerText.Split(new string[] { ", " }, StringSplitOptions.RemoveEmptyEntries); foreach (string actor in actors) { // todo: the name reference is missing an id title.Principals.Add(new NameReference { Name = actor }); } } HtmlNode imageNode = node.DescendantNodes().Where(x => x.Name == "img").FirstOrDefault(); if (imageNode != null) { Match match = imdbImageExpression.Match(imageNode.Attributes["src"].Value); if (match.Success) { title.Image = HttpUtility.UrlDecode(match.Groups["filename"].Value + match.Groups["ext"].Value); } } titles.Add(title); } // todo: this is abuse, need to split the title results using the h1 headers later results.Titles[ResultType.Exact] = titles; return results; }
/// <summary> /// Browse the US weekend box office results. /// </summary> /// <param name="session">The session.</param> /// <returns></returns> public static List<TitleReference> GetBoxOffice(Session session) { return GetList(session, session.Settings.BoxOfficeMobile); }
/// <summary> /// Browse the Best Picture winners /// </summary> /// <param name="session">The session.</param> /// <returns></returns> public static List<TitleReference> GetBestPictureWinners(Session session) { return GetList(session, session.Settings.BestPictureWinners); }
/// <summary> /// Browse the "Coming Soon" listing. /// </summary> /// <param name="session"></param> /// <returns>a collection of titles</returns> public static List<TitleReference> GetComingSoon(Session session) { return GetList(session, session.Settings.ComingSoon); }
/// <summary> /// Browse the movie bottom top 100. /// </summary> /// <param name="session"></param> /// <returns></returns> public static List<TitleReference> GetBottom100(Session session) { return GetList(session, session.Settings.ChartBottom100Mobile); }
internal static HtmlNode GetResponseFromSite(Session session, string url) { return GetResponseFromSite(session, url, null); }
/// <summary> /// Common method to get a list of titles from the IMDb app interface (JSON) /// </summary> /// <param name="session"></param> /// <param name="chart">name of the chart</param> /// <returns>a collection of titles</returns> internal static List<TitleReference> GetChart(Session session, string chart) { List<TitleReference> titles = new List<TitleReference>(); string data = GetResponseFromEndpoint(session, chart); IMDbResponse<IMDbSingleList<IMDbList<IMDbTitle>>> response = JsonConvert.DeserializeObject<IMDbResponse<IMDbSingleList<IMDbList<IMDbTitle>>>>(data); foreach (IMDbTitle item in response.Data.List.Items) { TitleReference title = new TitleReference(); title.session = session; title.FillFrom(item); titles.Add(title); } return titles; }
/// <summary> /// Gets the videos associated with this title (video gallery). /// </summary> /// <param name="session">The session.</param> /// <param name="imdbID">The imdb ID.</param> /// <remarks>uses web scraping</remarks> /// <returns></returns> public static List<VideoReference> GetVideos(Session session, string imdbID) { List<VideoReference> videos = new List<VideoReference>(); string data = session.MakeRequest(string.Format(session.Settings.VideoGallery, imdbID)); HtmlNode root = Utility.ToHtmlNode(data); if (root != null) { var nodes = root.SelectNodes("//div[contains(@class, 'results-item')]"); string movieTitle = root.SelectSingleNode("//h3/a").InnerText; if (nodes != null) { foreach (HtmlNode node in nodes) { HtmlNode imgNode = node.SelectSingleNode("a/img"); if (imgNode == null) continue; string href = node.SelectSingleNode("h2/a").GetAttributeValue("href", ""); if (href.Contains("/imdblink/")) continue; // link to an external trailer string videoTitle = node.SelectSingleNode("h2/a").InnerText; if (videoTitle.ToLower().Trim() == movieTitle.ToLower().Trim()) { // if the title is the same as the movie title try the image's title var title2 = imgNode.GetAttributeValue("title", ""); if (title2 != "") videoTitle = title2; } // clean up the video title int i = videoTitle.IndexOf(" -- "); if (i >= 0) { videoTitle = videoTitle.Substring(i + 4); } videoTitle = videoTitle.Replace(movieTitle + ":", string.Empty).Trim(); VideoReference video = new VideoReference(); video.session = session; video.Image = imgNode.GetAttributeValue("src", ""); video.ID = imgNode.Attributes["viconst"].Value; video.Title = HttpUtility.HtmlDecode(videoTitle); videos.Add(video); } } } return videos; }
/// <summary> /// Browser the top HD movie trailers. /// </summary> /// <param name="session"></param> /// <returns></returns> public static List<TitleReference> GetTrailersTopHD(Session session) { return GetTrailers(session, session.Settings.TrailersTopHD, 0); }
/// <summary> /// Gets the IMDb title /// </summary> /// <param name="session">a session instance.</param> /// <param name="imdbID">IMDb ID</param> /// <returns></returns> public static TitleDetails GetTitle(Session session, string imdbID) { string uri = string.Format(session.Settings.BaseUriMobile, session.Settings.TitleDetailsMobile, "/" + imdbID + "/"); HtmlNode root = GetResponseFromSite(session, uri); TitleDetails title = new TitleDetails(); title.session = session; title.ID = imdbID; // Main Details HtmlNode node = root.SelectSingleNode("//div[@class='media-body']"); string titleInfo = node.SelectSingleNode("h1").InnerText; ParseDisplayStringToTitleBase(title, HttpUtility.HtmlDecode(titleInfo)); // Tagline node = node.SelectSingleNode("p"); if (node != null) { title.Tagline = HttpUtility.HtmlDecode(node.InnerText); } // Release date node = root.SelectSingleNode("//section[h3='Release Date:']/span"); if (node != null) { DateTime value; if (DateTime.TryParse(node.InnerText, out value)) { title.ReleaseDate = value; } } // Summary node = root.SelectSingleNode("//p[@itemprop='description']"); if (node != null) { node = node.FirstChild; if (node != null) { title.Plot = HttpUtility.HtmlDecode(node.InnerText).Trim(); } } // Genres title.Genres = root.SelectNodes("//span[@itemprop='genre']").Select(s => HttpUtility.HtmlDecode(s.InnerText)).ToList(); // Ratings / Votes // todo: fix this node = root.SelectSingleNode("//p[@class='votes']/strong"); if (node != null) { title.Rating = Convert.ToDouble(node.InnerText, CultureInfo.InvariantCulture.NumberFormat); // Votes string votes = node.NextSibling.InnerText; if (votes.Contains("votes")) { votes = Regex.Replace(votes, @".+?([\d\,]+) votes.+", "$1", RegexOptions.Singleline); title.Votes = Convert.ToInt32(votes.Replace(",","")); } } // Certification node = root.SelectSingleNode("//span[@itemprop='contentRating']"); if (node != null) { title.Certificate = HttpUtility.HtmlDecode(node.GetAttributeValue("content", "?")); } //Poster node = root.SelectSingleNode("//div[@class='poster']/a"); if (node != null) { Match match = imdbImageExpression.Match(node.Attributes["href"].Value); if (match.Success) { title.Image = HttpUtility.UrlDecode(match.Groups["filename"].Value + match.Groups["ext"].Value); } } // Cast HtmlNodeCollection nodes = root.SelectNodes("//div[@id='cast-and-crew']/div/ul/li"); if (nodes != null) { foreach (HtmlNode n in nodes) { HtmlNode infoNode = n.SelectSingleNode("div[@class='text-center']/div[@class='ellipse']"); if (infoNode == null) { continue; } // Character info Character character = new Character(); character.Actor = new NameReference(); character.Actor.session = session; character.Actor.Name = HttpUtility.HtmlDecode(infoNode.InnerText).Trim(); infoNode = n.SelectSingleNode("a"); if (infoNode != null) character.Actor.ID = infoNode.Attributes["href"].Value.Replace("http://m.imdb.com/name/", "").Replace("/", ""); infoNode = n.Descendants("small").Last(); if (infoNode != null) character.Name = HttpUtility.HtmlDecode(infoNode.InnerText).Trim(); infoNode = n.SelectSingleNode("a/img"); if (infoNode != null) { Match match = imdbImageExpression.Match(infoNode.Attributes["src"].Value); if (match.Success) { character.Actor.Image = HttpUtility.UrlDecode(match.Groups["filename"].Value + match.Groups["ext"].Value); } } // add character object to the title title.Cast.Add(character); } } nodes = root.SelectNodes("//div[@id='cast-and-crew']"); if (nodes != null) { foreach (HtmlNode n in nodes.Elements("a")) { var itemprop = n.GetAttributeValue("itemprop", ""); if (itemprop == "director" || itemprop == "creator") { NameReference person = new NameReference(); person.session = session; person.ID = n.Attributes["href"].Value.Replace("//m.imdb.com/name/", "").Replace("/", ""); person.ID = person.ID.Substring(0, person.ID.IndexOf("?")); person.Name = HttpUtility.HtmlDecode(n.Descendants("span").First().InnerText).Trim(); if (itemprop == "director") { title.Directors.Add(person); } else if (itemprop == "creator") { title.Writers.Add(person); } } } } HtmlNode trailerNode = root.SelectSingleNode("//span[@data-trailer-id]"); if (trailerNode != null) { string videoId = trailerNode.GetAttributeValue("data-trailer-id", string.Empty); if (videoId != string.Empty) { title.trailer = videoId; } } return title; }
/// <summary> /// Gets the IMDb name /// </summary> /// <param name="session">Session instance.</param> /// <param name="imdbID">IMDb ID</param> /// <returns></returns> public static NameDetails GetName(Session session, string imdbID) { throw new NotImplementedException(); }
internal static string GetResponseFromEndpoint(Session session, string target, Dictionary<string, string> args) { if (session == null) { throw new ArgumentNullException("session", "session object needed"); } // build the querystring string query = CreateQuerystringFromDictionary(args); // format the url //string url = string.Format(session.Settings.BaseApiUri, target, session.Settings.Locale, query); string url = string.Format(session.Settings.BaseUriMobile, target, query); // make and return the request return session.MakeRequest(url); }
internal static string GetResponseFromEndpoint(Session session, string target) { return GetResponseFromEndpoint(session, target, null); }
internal static HtmlNode GetResponseFromSite(Session session, string url, Dictionary<string, string> args) { if (session == null) { throw new ArgumentNullException("session", "session object needed"); } string uri = url; string query = CreateQuerystringFromDictionary(args); // create the uri uri = string.Format(url, query); string data = session.MakeRequest(uri); HtmlNode node = Utility.ToHtmlNode(data); return node; }
/// <summary> /// Browse the MOVIEmeter movies. /// </summary> /// <param name="session">The session.</param> /// <returns></returns> public static List<TitleReference> GetMovieMeter(Session session) { return GetList(session, session.Settings.ChartMovieMeterMobile); }
/// <summary> /// Browse popular movie trailers /// </summary> /// <param name="session"></param> /// <returns></returns> public static List<TitleReference> GetTrailersPopular(Session session, int page) { return GetTrailers(session, session.Settings.TrailersPopular, page); }
/// <summary> /// Browse the popular tv series /// </summary> /// <param name="session"></param> /// <returns></returns> public static List<TitleReference> GetPopularTV(Session session) { return GetList(session, session.Settings.PopularTVSeriesMobile); }
/// <summary> /// Common method to get a list of titles from an IMDb trailer JSON feed /// </summary> /// <param name="session"></param> /// <param name="path">path to JSON feed</param> /// <returns>a collection of titles</returns> internal static List<TitleReference> GetTrailers(Session session, string uri, int token) { string url = (token > 0) ? uri + "&token=" + token : uri; List<TitleReference> titles = new List<TitleReference>(); string response = session.MakeRequest(url); //JObject parsedResults = JObject.Parse(response); var imdbResponse = JsonConvert.DeserializeObject<OnlineVideos.Sites.apondman.IMDb.DTO.IMDbResponse>(response); HashSet<string> duplicateFilter = new HashSet<string>(); foreach (var item in imdbResponse.model.items) { var titleId = item.display.titleId; if (duplicateFilter.Contains(titleId)) { continue; } duplicateFilter.Add(titleId); TitleReference title = new TitleReference(); title.session = session; title.FillFrom(item); titles.Add(title); } return titles; }
/// <summary> /// Gets the IMDb video /// </summary> /// <param name="session">Session instance.</param> /// <param name="imdbID">IMDb ID</param> /// <returns></returns> public static VideoDetails GetVideo(Session session, string imdbID) { VideoDetails details = new VideoDetails(); details.session = session; details.ID = imdbID; string url = string.Format(session.Settings.VideoInfo, imdbID); string data = session.MakeRequest(url); HtmlNode root = Utility.ToHtmlNode(data); if (root == null) { return details; } HtmlNode titleNode = root.SelectSingleNode("//title"); string title = titleNode.InnerText; title = title.Substring(title.IndexOf(':') + 1).Trim(); details.Title = HttpUtility.HtmlDecode(title); HtmlNode descNode = root.SelectSingleNode("//table[@id='video-details']/tr[1]/td[2]"); details.Description = HttpUtility.HtmlDecode(descNode.InnerText); string[] formats = null; MatchCollection matches = videoFormatExpression.Matches(data); foreach (Match m in matches) { string format = m.Groups["format"].Value; string video = m.Groups["video"].Value; if (formats == null) { string videoPlayerHtml = session.MakeRequest(session.Settings.BaseUri + video); var json = GetJsonForVideo(videoPlayerHtml); if (json != null) { formats = json["titleObject"]["encoding"].Select(q => (q as JProperty).Name).Where(q => q != "selected").ToArray(); } } if (formats != null) { switch (format) { case "SD": if (formats.Contains("240p")) details.Files[VideoFormat.SD] = video; break; case "480p": if (formats.Contains("480p")) details.Files[VideoFormat.HD480] = video; break; case "720p": if (formats.Contains("720p")) details.Files[VideoFormat.HD720] = video; break; } } else { details.Files[VideoFormat.SD] = video; break; } } if (details.Files.Count == 0) { details.Files.Add(VideoFormat.SD, "/video/screenplay/" + imdbID + "/player"); } return details; }
internal static string GetSearchResponse(Session session, string query) { var d = new Dictionary<string, string>(); d.Add("q", query); string response = GetResponseFromEndpoint(session, "find", d); return response; }
/// <summary> /// Browse the full length movies in a specific category. /// </summary> /// <param name="session">session to use</param> /// <param name="index">a single character in the range: # and A-Z</param> /// <returns></returns> public static List<TitleReference> GetFullLengthMovies(Session session, string index) { List<TitleReference> titles = new List<TitleReference>(); string uri = string.Format(session.Settings.FullLengthMovies, index); HtmlNode data = GetResponseFromSite(session, uri); HtmlNodeCollection nodes = data.SelectNodes("//a[contains(@href,'title/tt')]"); foreach (HtmlNode node in nodes) { string href = node.Attributes["href"].Value; string tt = ParseTitleConst(href); if (tt != null) { TitleReference title = new TitleReference(); title.Type = TitleType.Movie; title.session = session; title.ID = tt; title.Title = node.InnerText; titles.Add(title); } } return titles; }
/// <summary> /// Gets the IMDB video playback url. /// </summary> /// <param name="session">Session instance.</param> /// <param name="url">The player url.</param> /// <returns></returns> public static string GetVideoFile(Session session, string url) { if (!url.StartsWith("/")) { // we only need to post-process the relative urls return url; } string response = session.MakeRequest(session.Settings.BaseUri + url); Match match = videoPlayerExpression.Match(response); if (match.Success) { string player = match.Groups["player"].Value; switch(player) { case "thunder": match = videoThunderExpression.Match(response); if (match.Success) { string smilURL = match.Groups["video"].Value; HtmlNode node = GetResponseFromSite(session, smilURL); HtmlNode rtmp = node.SelectSingleNode("//ref/@src[contains(.,'rtmp:')]"); if (rtmp != null) { return HttpUtility.UrlDecode(rtmp.Attributes["src"].Value); } } break; // todo add more player types } } match = videoFileExpression.Match(response); if (match.Success) { return match.Groups["video"].Value; } match = videoRTMPExpression.Match(response); if (match.Success) { string value = match.Groups["video"].Value; match = videoRTMPIdExpression.Match(response); string file = match.Groups["video"].Value; return System.Web.HttpUtility.UrlDecode(value + "/" + file); } var json = GetJsonForVideo(response); if (json != null) { return json["videoPlayerObject"]["video"].Value<string>("url"); } return null; }
/// <summary> /// Returns a new configurable session you can use to query the api /// </summary> /// <returns></returns> public static Session GetSession() { Session session = new Session(); session.Settings = new Settings(); return session; }
/// <summary> /// Common method to get a list of titles from an IMDb mobile JSON feed /// </summary> /// <param name="session"></param> /// <param name="path">path to JSON feed</param> /// <returns>a collection of titles</returns> internal static List<TitleReference> GetList(Session session, string path) { List<TitleReference> titles = new List<TitleReference>(); string data = GetResponseFromEndpoint(session, path); IMDbMobileResponse<List<IMDbTitleMobile>> response = JsonConvert.DeserializeObject<IMDbMobileResponse<List<IMDbTitleMobile>>>(data); DateTime releaseDateHeader = DateTime.MinValue; foreach (IMDbTitleMobile item in response.Data) { if (item.URL == null) { if (item.ReleaseDate > DateTime.MinValue) { releaseDateHeader = item.ReleaseDate; } continue; } TitleReference title = new TitleReference(); title.session = session; title.FillFrom(item); title.ReleaseDate = releaseDateHeader; titles.Add(title); } return titles; }