private async Task <Series> AutoDetectSeries( string seriesName, int?seriesYear, TvFileOrganizationOptions options, CancellationToken cancellationToken) { if (options.AutoDetectSeries) { RemoteSearchResult finalResult = null; // Perform remote search var seriesInfo = new SeriesInfo { Name = seriesName, Year = seriesYear }; var searchQuery = new RemoteSearchQuery <SeriesInfo> { SearchInfo = seriesInfo }; var searchResults = await _providerManager.GetRemoteSearchResults <Series, SeriesInfo>(searchQuery, cancellationToken).ConfigureAwait(false); // Group series by name and year (if 2 series with the exact same name, the same year ...) var groupedResult = searchResults.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(seriesName, seriesYear, 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 EpisodeFileOrganizationRequest { NewSeriesName = finalResult.Name, NewSeriesProviderIds = finalResult.ProviderIds, NewSeriesYear = finalResult.ProductionYear, TargetFolder = options.DefaultSeriesLibraryPath }; return(await CreateNewSeries(organizationRequest, finalResult, options, cancellationToken).ConfigureAwait(false)); } } return(null); }
private Series GetMatchingSeries(string seriesName, FileOrganizationResult result, AutoOrganizeOptions options) { var parsedName = _libraryManager.ParseName(seriesName); var yearInName = parsedName.Year; var nameWithoutYear = parsedName.Name; result.ExtractedName = nameWithoutYear; result.ExtractedYear = yearInName; var series = _libraryManager.GetItemList(new InternalItemsQuery { IncludeItemTypes = new[] { typeof(Series).Name }, Recursive = true, DtoOptions = new DtoOptions(true) }) .Cast <Series>() .Select(i => NameUtils.GetMatchScore(nameWithoutYear, yearInName, i)) .Where(i => i.Item2 > 0) .OrderByDescending(i => i.Item2) .Select(i => i.Item1) .FirstOrDefault(); if (series == null) { SmartMatchInfo info = options.SmartMatchInfos.FirstOrDefault(e => e.MatchStrings.Contains(nameWithoutYear, StringComparer.OrdinalIgnoreCase)); if (info != null) { series = _libraryManager.GetItemList(new InternalItemsQuery { IncludeItemTypes = new[] { typeof(Series).Name }, Recursive = true, Name = info.ItemName, DtoOptions = new DtoOptions(true) }).Cast <Series>().FirstOrDefault(); } } return(series); }
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[] { typeof(Series).Name }, 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[] { typeof(Series).Name }, Recursive = true, Name = info.ItemName, DtoOptions = new DtoOptions(true) }).Cast <Series>().FirstOrDefault(s => s.Path.StartsWith(targetFolder, StringComparison.Ordinal)); } } return(series); }
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[] { typeof(Movie).Name }, 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 Movie GetMatchingMovie(string movieName, int?movieYear, FileOrganizationResult result, MovieFileOrganizationOptions options) { var parsedName = _libraryManager.ParseName(movieName); var yearInName = parsedName.Year; var nameWithoutYear = parsedName.Name; if (string.IsNullOrWhiteSpace(nameWithoutYear)) { nameWithoutYear = movieName; } if (!yearInName.HasValue) { yearInName = movieYear; } if (result != null) { result.ExtractedName = nameWithoutYear; result.ExtractedYear = yearInName; } var movie = _libraryManager.GetItemList(new InternalItemsQuery { IncludeItemTypes = new[] { typeof(Movie).Name }, 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(); return(movie); }
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; } #region Search One var movieInfo = new MovieInfo { Name = nameWithoutYear, Year = yearInName, }; var searchResultsTask = await _providerManager.GetRemoteSearchResults <Movie, MovieInfo>(new RemoteSearchQuery <MovieInfo> { SearchInfo = movieInfo }, cancellationToken); #endregion // 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.OriginalPath, options, cancellationToken); return(new Tuple <Movie, RemoteSearchResult>(movie, finalResult)); } } return(null); }