private Movie GetMatchingMovie(string movieName, int?movieYear, string targetFolder, FileOrganizationResult result) { var parsedName = _libraryManager.ParseName(movieName); var yearInName = parsedName.Year; var nameWithoutYear = parsedName.Name; if (string.IsNullOrWhiteSpace(nameWithoutYear)) { nameWithoutYear = movieName; } if (!yearInName.HasValue) { yearInName = movieYear; } result.ExtractedName = nameWithoutYear; result.ExtractedYear = yearInName; var movie = _libraryManager.GetItemList(new InternalItemsQuery { IncludeItemTypes = new[] { BaseItemKind.Movie }, Recursive = true, DtoOptions = new DtoOptions(true), }) .Cast <Movie>() .Select(i => NameUtils.GetMatchScore(nameWithoutYear, yearInName, i)) .Where(i => i.Item2 > 0) .OrderByDescending(i => i.Item2) .Select(i => i.Item1) .FirstOrDefault(m => // Check For the right folder AND the right extension (to handle quality upgrade) m.Path.StartsWith(targetFolder, StringComparison.Ordinal) && Path.GetExtension(m.Path) == Path.GetExtension(result.OriginalPath)); return(movie); }
private Series GetMatchingSeries(string seriesName, int?seriesYear, string targetFolder, FileOrganizationResult result) { if (result != null) { result.ExtractedName = seriesName; result.ExtractedYear = seriesYear; } var series = _libraryManager.GetItemList(new InternalItemsQuery { IncludeItemTypes = new[] { BaseItemKind.Series }, Recursive = true, DtoOptions = new DtoOptions(true) }) .Cast <Series>() .Select(i => NameUtils.GetMatchScore(seriesName, seriesYear, i)) .Where(i => i.Item2 > 0) .OrderByDescending(i => i.Item2) .Select(i => i.Item1) .FirstOrDefault(s => s.Path.StartsWith(targetFolder, StringComparison.Ordinal)); if (series == null) { var info = _organizationService.GetSmartMatchInfos().Items.FirstOrDefault(e => e.MatchStrings.Contains(seriesName, StringComparer.OrdinalIgnoreCase)); if (info != null) { series = _libraryManager.GetItemList(new InternalItemsQuery { IncludeItemTypes = new[] { BaseItemKind.Series }, Recursive = true, Name = info.ItemName, DtoOptions = new DtoOptions(true) }).Cast <Series>().FirstOrDefault(s => s.Path.StartsWith(targetFolder, StringComparison.Ordinal)); } } return(series); }
private async Task <Tuple <Movie, RemoteSearchResult> > AutoDetectMovie(string movieName, int?movieYear, FileOrganizationResult result, MovieFileOrganizationOptions options, CancellationToken cancellationToken) { if (options.AutoDetectMovie) { var parsedName = _libraryManager.ParseName(movieName); var yearInName = parsedName.Year; var nameWithoutYear = parsedName.Name; RemoteSearchResult finalResult = null; if (string.IsNullOrWhiteSpace(nameWithoutYear)) { nameWithoutYear = movieName; } if (!yearInName.HasValue) { yearInName = movieYear; } // Perform remote search var movieInfo = new MovieInfo { Name = nameWithoutYear, Year = yearInName, }; var searchResultsTask = await _providerManager.GetRemoteSearchResults <Movie, MovieInfo>( new RemoteSearchQuery <MovieInfo> { SearchInfo = movieInfo }, cancellationToken).ConfigureAwait(false); // Group movies by name and year (if 2 movie with the exact same name, the same year ...) var groupedResult = searchResultsTask.GroupBy( p => new { p.Name, p.ProductionYear }, p => p, (key, g) => new { Key = key, Result = g.ToList() }).ToList(); if (groupedResult.Count == 1) { finalResult = groupedResult.First().Result.First(); } else if (groupedResult.Count > 1) { var filtredResult = groupedResult .Select(i => new { Ref = i, Score = NameUtils.GetMatchScore(nameWithoutYear, yearInName, i.Key.Name, i.Key.ProductionYear) }) .Where(i => i.Score > 0) .OrderByDescending(i => i.Score) .Select(i => i.Ref) .FirstOrDefault(); finalResult = filtredResult?.Result.First(); } if (finalResult != null) { // We are in the good position, we can create the item var organizationRequest = new MovieFileOrganizationRequest { NewMovieName = finalResult.Name, NewMovieProviderIds = finalResult.ProviderIds, NewMovieYear = finalResult.ProductionYear, TargetFolder = options.DefaultMovieLibraryPath }; var movie = CreateNewMovie(organizationRequest, result, options); return(new Tuple <Movie, RemoteSearchResult>(movie, finalResult)); } } return(null); }