diff --git a/src/NzbDrone.Core/MetadataSource/SkyHook/Resource/TMDBResources.cs b/src/NzbDrone.Core/MetadataSource/SkyHook/Resource/TMDBResources.cs index 9c346057a..80e1b42cf 100644 --- a/src/NzbDrone.Core/MetadataSource/SkyHook/Resource/TMDBResources.cs +++ b/src/NzbDrone.Core/MetadataSource/SkyHook/Resource/TMDBResources.cs @@ -6,6 +6,10 @@ using System.Text; namespace NzbDrone.Core.MetadataSource.SkyHook.Resource { + public class FindRoot + { + public MovieResult[] movie_results { get; set; } + } public class MovieSearchRoot { public int page { get; set; } diff --git a/src/NzbDrone.Core/MetadataSource/SkyHook/SkyHookProxy.cs b/src/NzbDrone.Core/MetadataSource/SkyHook/SkyHookProxy.cs index af4c8dcf2..650bd0cc4 100644 --- a/src/NzbDrone.Core/MetadataSource/SkyHook/SkyHookProxy.cs +++ b/src/NzbDrone.Core/MetadataSource/SkyHook/SkyHookProxy.cs @@ -146,69 +146,19 @@ namespace NzbDrone.Core.MetadataSource.SkyHook public Movie GetMovieInfo(string ImdbId) { - var imdbRequest = new HttpRequest("http://www.omdbapi.com/?i=" + ImdbId + "&plot=full&r=json"); + var request = _movieBuilder.Create() + .SetSegment("route", "find") + .SetSegment("id", ImdbId) + .SetSegment("secondaryRoute", "") + .AddQueryParam("external_source", "imdb_id") + .Build(); - var httpResponse = _httpClient.Get(imdbRequest); + request.AllowAutoRedirect = true; + request.SuppressHttpError = true; - if (httpResponse.HasHttpError) - { - if (httpResponse.StatusCode == HttpStatusCode.NotFound) - { - throw new MovieNotFoundException(ImdbId); - } - else - { - throw new HttpException(imdbRequest, httpResponse); - } - } + var resources = _httpClient.Get(request).Resource; - var response = httpResponse.Content; - - dynamic json = JsonConvert.DeserializeObject(response); - - var movie = new Movie(); - - movie.Title = json.Title; - movie.TitleSlug = movie.Title.ToLower().Replace(" ", "-"); - movie.Overview = json.Plot; - movie.CleanTitle = Parser.Parser.CleanSeriesTitle(movie.Title); - string airDateStr = json.Released; - DateTime airDate = DateTime.Parse(airDateStr); - movie.InCinemas = airDate; - movie.Year = airDate.Year; - movie.ImdbId = ImdbId; - string imdbRating = json.imdbVotes; - if (imdbRating == "N/A") - { - movie.Status = MovieStatusType.Announced; - } - else - { - movie.Status = MovieStatusType.Released; - } - string url = json.Poster; - var imdbPoster = new MediaCover.MediaCover(MediaCoverTypes.Poster, url); - movie.Images.Add(imdbPoster); - string runtime = json.Runtime; - int runtimeNum = 0; - int.TryParse(runtime.Replace("min", "").Trim(), out runtimeNum); - movie.Runtime = runtimeNum; - - return movie; - } - - private string[] SeparateYearFromTitle(string title) - { - var yearPattern = @"((?:19|20)\d{2})"; - var newTitle = title; - var substrings = Regex.Split(title, yearPattern); - var year = ""; - if (substrings.Length > 1) { - newTitle = substrings[0].TrimEnd("("); - year = substrings[1]; - } - - return new[] { newTitle.Trim(), year.Trim() }; + return resources.movie_results.SelectList(MapMovie).FirstOrDefault(); } private string StripTrailingTheFromTitle(string title) @@ -226,10 +176,25 @@ namespace NzbDrone.Core.MetadataSource.SkyHook public List SearchForNewMovie(string title) { var lowerTitle = title.ToLower(); - var yearCheck = SeparateYearFromTitle(lowerTitle); // TODO: Make this much less hacky! - lowerTitle = yearCheck[0]; - var yearTerm = yearCheck[1]; + var parserResult = Parser.Parser.ParseMovieTitle(title); + + var yearTerm = ""; + + if (parserResult != null && parserResult.MovieTitle != title) + { + //Parser found something interesting! + lowerTitle = parserResult.MovieTitle.ToLower(); + if (parserResult.Year > 1800) + { + yearTerm = parserResult.Year.ToString(); + } + + if (parserResult.ImdbId.IsNotNullOrWhiteSpace()) + { + return new List { GetMovieInfo(parserResult.ImdbId) }; + } + } lowerTitle = StripTrailingTheFromTitle(lowerTitle); @@ -254,7 +219,7 @@ namespace NzbDrone.Core.MetadataSource.SkyHook } } - var searchTerm = lowerTitle.Replace("_", "+").Replace(" ", "+"); + var searchTerm = lowerTitle.Replace("_", "+").Replace(" ", "+").Replace(".", "+"); var firstChar = searchTerm.First(); @@ -290,43 +255,7 @@ namespace NzbDrone.Core.MetadataSource.SkyHook var movieResults = response.Resource.results; - var imdbMovies = new List(); - - foreach (MovieResult result in movieResults) - { - var imdbMovie = new Movie(); - imdbMovie.TmdbId = result.id; - try - { - imdbMovie.SortTitle = result.title; - imdbMovie.Title = result.title; - string titleSlug = result.title; - imdbMovie.TitleSlug = titleSlug.ToLower().Replace(" ", "-"); - imdbMovie.Year = DateTime.Parse(result.release_date).Year; - imdbMovie.Images = new List(); - imdbMovie.Overview = result.overview; - try - { - string url = result.poster_path; - var imdbPoster = _configService.GetCoverForURL(result.poster_path, MediaCoverTypes.Poster); - imdbMovie.Images.Add(imdbPoster); - } - catch (Exception e) - { - _logger.Debug(result); - continue; - } - - imdbMovies.Add(imdbMovie); - } - catch (Exception e) - { - _logger.Error(e, "Error occured while searching for new movies."); - } - - } - - return imdbMovies; + return movieResults.SelectList(MapMovie); } public List SearchForNewSeries(string title) @@ -380,6 +309,40 @@ namespace NzbDrone.Core.MetadataSource.SkyHook } } + private Movie MapMovie(MovieResult result) + { + var imdbMovie = new Movie(); + imdbMovie.TmdbId = result.id; + try + { + imdbMovie.SortTitle = result.title; + imdbMovie.Title = result.title; + string titleSlug = result.title; + imdbMovie.TitleSlug = titleSlug.ToLower().Replace(" ", "-"); + imdbMovie.Year = DateTime.Parse(result.release_date).Year; + imdbMovie.Images = new List(); + imdbMovie.Overview = result.overview; + try + { + string url = result.poster_path; + var imdbPoster = _configService.GetCoverForURL(result.poster_path, MediaCoverTypes.Poster); + imdbMovie.Images.Add(imdbPoster); + } + catch (Exception e) + { + _logger.Debug(result); + } + + return imdbMovie; + } + catch (Exception e) + { + _logger.Error(e, "Error occured while searching for new movies."); + } + + return null; + } + private static Series MapSeries(ShowResource show) { var series = new Series(); diff --git a/src/NzbDrone.Core/Parser/Model/ParsedMovieInfo.cs b/src/NzbDrone.Core/Parser/Model/ParsedMovieInfo.cs index ff1f87cfd..4b9bc7526 100644 --- a/src/NzbDrone.Core/Parser/Model/ParsedMovieInfo.cs +++ b/src/NzbDrone.Core/Parser/Model/ParsedMovieInfo.cs @@ -17,6 +17,7 @@ namespace NzbDrone.Core.Parser.Model public string ReleaseHash { get; set; } public string Edition { get; set;} public int Year { get; set; } + public string ImdbId { get; set; } public ParsedMovieInfo() { diff --git a/src/NzbDrone.Core/Parser/Parser.cs b/src/NzbDrone.Core/Parser/Parser.cs index a48204a28..b05f30799 100644 --- a/src/NzbDrone.Core/Parser/Parser.cs +++ b/src/NzbDrone.Core/Parser/Parser.cs @@ -18,20 +18,20 @@ namespace NzbDrone.Core.Parser private static readonly Regex[] ReportMovieTitleRegex = new[] { //Special, Despecialized, etc. Edition Movies, e.g: Mission.Impossible.3.Special.Edition.2011 - new Regex(@"^(?.+?)?(?:(?:[-_\W](?<![()\[!]))*(?<edition>(\w+\.?edition))\.(?<year>(?<!e|x)\d{4}(?!p|i|\d+|\)|\]|\W\d+)))+(\W+|_|$)(?!\\)", + new Regex(@"^(?<title>.+?)?(?:(?:[-_\W](?<![)\[!]))*(?<edition>(\w+\.?edition))\.(?<year>(19|20)\d{2}(?!p|i|\d+|\]|\W\d+)))+(\W+|_|$)(?!\\)", RegexOptions.IgnoreCase | RegexOptions.Compiled), //Special, Despecialized, etc. Edition Movies, e.g: Mission.Impossible.3.2011.Special.Edition //TODO: Seems to slow down parsing heavily! - new Regex(@"^(?<title>.+?)?(?:(?:[-_\W](?<![()\[!]))*(?<year>(?<!e|x)\d{4}(?!p|i|\d+|\)|\]|\W\d+)))+(\W+|_|$)(?!\\)(?<edition>((\w+\.?){1,3}edition))", + new Regex(@"^(?<title>.+?)?(?:(?:[-_\W](?<![)\[!]))*(?<year>(19|20)\d{2}(?!p|i|\d+|\]|\W\d+)))+(\W+|_|$)(?!\\)(?<edition>((\w+\.?){1,3}edition))", RegexOptions.IgnoreCase | RegexOptions.Compiled), //Cut Movies, e.g: Mission.Impossible.3.Directors.Cut.2011 - new Regex(@"^(?<title>.+?)?(?:(?:[-_\W](?<![()\[!]))*(?<edition>(\w+\.?cut))\.(?<year>(?<!e|x)\d{4}(?!p|i|\d+|\)|\]|\W\d+)))+(\W+|_|$)(?!\\)", + new Regex(@"^(?<title>.+?)?(?:(?:[-_\W](?<![)\[!]))*(?<edition>(\w+\.?cut))\.(?<year>(19|20)\d{2}(?!p|i|\d+|\]|\W\d+)))+(\W+|_|$)(?!\\)", RegexOptions.IgnoreCase | RegexOptions.Compiled), //Cut Movies, e.g: Mission.Impossible.3.2011.Directors.Cut - new Regex(@"^(?<title>.+?)?(?:(?:[-_\W](?<![()\[!]))*(?<year>(?<!e|x)\d{4}(?!p|i|\d+|\)|\]|\W\d+)))+(\W+|_|$)(?!\\)(?<edition>((\w+\.?){1,3}cut))", + new Regex(@"^(?<title>.+?)?(?:(?:[-_\W](?<![)\[!]))*(?<year>(19|20)\d{2}(?!p|i|\d+|\]|\W\d+)))+(\W+|_|$)(?!\\)(?<edition>((\w+\.?){1,3}cut))", RegexOptions.IgnoreCase | RegexOptions.Compiled), //Normal movie format, e.g: Mission.Impossible.3.2011 - new Regex(@"^(?<title>.+?)?(?:(?:[-_\W](?<![()\[!]))*(?<year>(?<!e|x)\d{4}(?!p|i|\d+|\)|\]|\W\d+)))+(\W+|_|$)(?!\\)", + new Regex(@"^(?<title>.+?)?(?:(?:[-_\W](?<![)\[!]))*(?<year>(19|20)\d{2}(?!p|i|\d+|\]|\W\d+)))+(\W+|_|$)(?!\\)", RegexOptions.IgnoreCase | RegexOptions.Compiled), //PassThePopcorn Torrent names: Star.Wars[PassThePopcorn] new Regex(@"^(?<title>.+?)?(?:(?:[-_\W](?<![()\[!]))*(?<year>(\[\w *\])))+(\W+|_|$)(?!\\)", @@ -263,6 +263,8 @@ namespace NzbDrone.Core.Parser private static readonly Regex FileExtensionRegex = new Regex(@"\.[a-z0-9]{2,4}$", RegexOptions.IgnoreCase | RegexOptions.Compiled); + private static readonly Regex ReportImdbId = new Regex(@"(?<imdbid>tt\d{9})", RegexOptions.IgnoreCase | RegexOptions.Compiled); + private static readonly Regex SimpleTitleRegex = new Regex(@"(?:480[ip]|720[ip]|1080[ip]|[xh][\W_]?26[45]|DD\W?5\W1|[<>?*:|]|848x480|1280x720|1920x1080|(8|10)b(it)?)\s*", RegexOptions.IgnoreCase | RegexOptions.Compiled); @@ -374,6 +376,8 @@ namespace NzbDrone.Core.Parser result.ReleaseGroup = ParseReleaseGroup(title); + result.ImdbId = ParseImdbId(title); + var subGroup = GetSubGroup(match); if (!subGroup.IsNullOrWhiteSpace()) { @@ -411,6 +415,23 @@ namespace NzbDrone.Core.Parser return realResult; } + public static string ParseImdbId(string title) + { + var match = ReportImdbId.Match(title); + if (match.Success) + { + if (match.Groups["imdbid"].Value != null) + { + if (match.Groups["imdbid"].Length == 11) + { + return match.Groups["imdbid"].Value; + } + } + } + + return ""; + } + public static ParsedEpisodeInfo ParseTitle(string title) {