public Task <IEnumerable <ImdbAdvancedInfoSearchResult> > AdvancedSearch( string query, MediaTypes mediaTypes = MediaTypes.All, int?releaseYearStart = null, int?releaseYearEnd = null, float?ratingMin = null, float?ratingMax = null, int?voteCountMin = null, int?voteCountMax = null, int?runtimeMin = null, int?runtimeMax = null, IEnumerable <string> genres = null, Language language = Language.English) { return(Task.Run(async() => { query = HttpUtility.UrlEncode(query, Encoding.GetEncoding("ISO-8859-1")); var searchParams = new List <string>(); searchParams.Add("title=" + query); var types = new List <string>(); if ((mediaTypes & MediaTypes.Movie) == MediaTypes.Movie) { types.AddRange(new[] { "feature", "tv_movie" }); } if ((mediaTypes & MediaTypes.TvShow) == MediaTypes.TvShow) { types.AddRange(new[] { "tv_series", "mini_series" }); } if ((mediaTypes & MediaTypes.Documentary) == MediaTypes.Documentary) { types.AddRange(new[] { "documentary" }); } searchParams.Add("title_type=" + string.Join(",", types)); AddLimitParameter(searchParams, "release_date", releaseYearStart, releaseYearEnd); AddLimitParameter(searchParams, "user_rating", ratingMin, ratingMax); AddLimitParameter(searchParams, "num_votes", voteCountMin, voteCountMax); AddLimitParameter(searchParams, "runtime", runtimeMin, runtimeMax); if (genres != null) { searchParams.Add("genres=" + string.Join(",", genres.Select(g => g.ToLowerInvariant()))); } var queryString = string.Join("&", searchParams); var urlStr = string.Format(ADVANCED_SEARCH_URL, Settings.AdvancedSearchResultCount, queryString); var url = new Uri(urlStr); string documentStr; using (var client = new NovaromaWebClient()) { if (!Settings.UseLocalTitles) { client.Headers.Add("X-FORWARDED-FOR", "199.254.254.254"); } documentStr = await client.DownloadStringTaskAsync(url); } var document = new HtmlParser(documentStr).Parse(); var items = document.All.Where(n => n.ClassName == "lister-item mode-advanced"); var results = new List <ImdbAdvancedInfoSearchResult>(); foreach (var item in items) { var linkNode = item.QuerySelector("div[class='lister-item-image float-left'] a"); var link = linkNode.Attributes.First(a => a.Name == "href").Value; var resultUrl = Helper.CombineUrls(BASE_URL, link); var imdbId = Regex.Match(link, @"\/.*\/(.*)\/").Groups[1].Value; var posterUrl = linkNode.QuerySelector("img").Attributes.First(a => a.Name == "loadlate").Value; var contentNode = item.QuerySelector("div[class='lister-item-content']"); var titleNode = contentNode.QuerySelector("h3[class='lister-item-header']"); var title = titleNode.QuerySelector("a").TextContent.Trim(); var yearType = titleNode.QuerySelector("span[class='lister-item-year text-muted unbold']").TextContent.Trim(); int?year = null; var isTvShow = false; if (yearType.Length > 4) { isTvShow = yearType.Contains("–"); int yearTmp; if (int.TryParse(yearType.Substring(1, 4), out yearTmp)) { year = yearTmp; } } var textNodes = contentNode.QuerySelectorAll("p"); var textNodesTextMuted = textNodes.Where(x => x.ClassName == "text-muted" || x.ClassName == "text-muted ").ToArray(); var genreStr = string.Empty; var outline = string.Empty; int?runtime = null; if (textNodesTextMuted.Length > 0) { var genreNode = textNodesTextMuted[0].QuerySelector("span[class='genre']"); if (genreNode != null) { genreStr = genreNode.TextContent.Trim(); } var runtimeNode = textNodesTextMuted[0].QuerySelector("span[class='runtime']"); if (runtimeNode != null) { var runtimeStr = runtimeNode.TextContent.Trim(); var match = Regex.Match(runtimeStr, @"(\d.*?) "); if (match.Groups.Count == 2) { int runtimeTmp; if (int.TryParse(match.Groups[1].Value, out runtimeTmp)) { runtime = runtimeTmp; } } } if (textNodesTextMuted.Length > 1) { var outlineNode = textNodesTextMuted[1]; outline = outlineNode.TextContent.Trim(); } } var textNodesOther = textNodes.Where(x => x.ClassName != "text-muted").ToArray(); var credits = string.Empty; if (textNodesOther.Length > 1) { credits = textNodesOther[1].TextContent.Replace("\r", "").Replace("\n", "").Replace(" ", ""); } int?voteCount = null; var voteNode = textNodes.FirstOrDefault(x => x.ClassName == "sort-num_votes-visible"); if (voteNode != null) { var voteStr = voteNode.QuerySelector("span[name='nv']").Attributes.First(x => x.Name == "data-value").Value; voteCount = int.Parse(voteStr); } float?rating = null; var ratingNode = contentNode.QuerySelector("div[class='ratings-bar'] strong"); if (ratingNode != null) { rating = float.Parse(ratingNode.TextContent.Trim(), new NumberFormatInfo { CurrencyDecimalSeparator = "." }); } byte[] poster = null; using (var client = new NovaromaWebClient()) { if (posterUrl != DEFAULT_POSTER_URL) { poster = await client.DownloadDataTaskAsync(posterUrl); } } var result = new ImdbAdvancedInfoSearchResult(this, imdbId, resultUrl, title, poster, year, isTvShow, outline, credits, rating, voteCount, runtime, genreStr); results.Add(result); } return results.AsEnumerable(); })); }
public Task <IEnumerable <ImdbAdvancedInfoSearchResult> > AdvancedSearch( string query, MediaTypes mediaTypes = MediaTypes.All, int?releaseYearStart = null, int?releaseYearEnd = null, float?ratingMin = null, float?ratingMax = null, int?voteCountMin = null, int?voteCountMax = null, int?runtimeMin = null, int?runtimeMax = null, IEnumerable <string> genres = null, Language language = Language.English) { return(Task.Run(async() => { query = HttpUtility.UrlEncode(query, Encoding.GetEncoding("ISO-8859-1")); var searchParams = new List <string>(); searchParams.Add("title=" + query); var types = new List <string>(); if ((mediaTypes & MediaTypes.Movie) == MediaTypes.Movie) { types.AddRange(new[] { "feature", "tv_movie" }); } if ((mediaTypes & MediaTypes.TvShow) == MediaTypes.TvShow) { types.AddRange(new[] { "tv_series", "mini_series" }); } if ((mediaTypes & MediaTypes.Documentary) == MediaTypes.Documentary) { types.AddRange(new[] { "documentary" }); } searchParams.Add("title_type=" + string.Join(",", types)); AddLimitParameter(searchParams, "release_date", releaseYearStart, releaseYearEnd); AddLimitParameter(searchParams, "user_rating", ratingMin, ratingMax); AddLimitParameter(searchParams, "num_votes", voteCountMin, voteCountMax); AddLimitParameter(searchParams, "runtime", runtimeMin, runtimeMax); if (genres != null) { searchParams.Add("genres=" + string.Join(",", genres.Select(g => g.ToLowerInvariant()))); } var queryString = string.Join("&", searchParams); var urlStr = string.Format(ADVANCED_SEARCH_URL, Settings.AdvancedSearchResultCount, queryString); var url = new Uri(urlStr); string documentStr; using (var client = new NovaromaWebClient()) { if (!Settings.UseLocalTitles) { client.Headers.Add("X-FORWARDED-FOR", "199.254.254.254"); } documentStr = await client.DownloadStringTaskAsync(url); } var document = DocumentBuilder.Html(documentStr); var items = document.All .Where(n => n.TagName == "TR" && (n.ClassName == "even detailed" || n.ClassName == "odd detailed")); var results = new List <ImdbAdvancedInfoSearchResult>(); foreach (var item in items) { var linkNode = item.QuerySelector("td[class='image'] a"); var link = linkNode.Attributes.First(a => a.Name == "href").Value; var resultUrl = Helper.CombineUrls(BASE_URL, link); var imdbId = Regex.Match(link, @"\/.*\/(.*)\/").Groups[1].Value; var posterUrl = linkNode.QuerySelector("td[class='image'] a img").Attributes.First(a => a.Name == "src").Value; var titleNode = item.QuerySelector("td[class='title']"); var title = titleNode.QuerySelector("a").TextContent.Trim(); var yearType = titleNode.QuerySelector("span[class='year_type']").TextContent.Trim(); var isTvShow = yearType.Contains(" Series)") || yearType.Contains("Mini-Series)"); int?year = null; if (yearType.Length > 4) { int yearTmp; if (int.TryParse(yearType.Substring(1, 4), out yearTmp)) { year = yearTmp; } } var outlineNode = titleNode.QuerySelector("span[class='outline']"); var outline = string.Empty; if (outlineNode != null) { outline = outlineNode.TextContent.Trim(); } var creditNode = titleNode.QuerySelector("span[class='credit']"); var credits = string.Empty; if (creditNode != null) { credits = creditNode.TextContent.Trim(); } var genreNode = titleNode.QuerySelector("span[class='genre']"); var genreStr = string.Empty; if (genreNode != null) { genreStr = genreNode.TextContent.Trim(); } float?rating = null; int?voteCount = null; var ratingNode = titleNode.QuerySelector("div[class='rating rating-list']"); if (ratingNode != null) { var ratingInfoStr = ratingNode.Attributes.First(a => a.Name == "title").Value; var match = Regex.Match(ratingInfoStr, @"(\d.*?)/\d{2} \((.*?) "); if (match.Groups.Count == 3) { var ratingStr = match.Groups[1].Value.Replace(",", "."); rating = float.Parse(ratingStr, new NumberFormatInfo { CurrencyDecimalSeparator = "." }); var voteCountStr = match.Groups[2].Value.Replace(",", "").Replace(".", ""); voteCount = int.Parse(voteCountStr); } } int?runtime = null; var runtimeNode = titleNode.QuerySelector("span[class='runtime']"); if (runtimeNode != null) { var runtimeStr = runtimeNode.TextContent; var match = Regex.Match(runtimeStr, @"(\d.*?) "); if (match.Groups.Count == 2) { int runtimeTmp; if (int.TryParse(match.Groups[1].Value, out runtimeTmp)) { runtime = runtimeTmp; } } } byte[] poster = null; using (var client = new NovaromaWebClient()) { if (posterUrl != DEFAULT_POSTER_URL) { poster = await client.DownloadDataTaskAsync(posterUrl); } } var result = new ImdbAdvancedInfoSearchResult(this, imdbId, resultUrl, title, poster, year, isTvShow, outline, credits, rating, voteCount, runtime, genreStr); results.Add(result); } return results.AsEnumerable(); })); }