Example #1
0
        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);
        }
Example #2
0
        public async Task <IEnumerable <RemoteSearchResult> > GetRemoteSearchResults <TItemType, TLookupType>(RemoteSearchQuery <TLookupType> searchInfo,
                                                                                                              CancellationToken cancellationToken)
            where TItemType : BaseItem, new()
            where TLookupType : ItemLookupInfo
        {
            // Give it a dummy path just so that it looks like a file system item
            var dummy = new TItemType
            {
                Path = "C:\\",

                // Dummy this up to fool the local trailer check
                Parent = new Folder()
            };

            var options = GetMetadataOptions(dummy);

            var providers = GetMetadataProvidersInternal <TItemType>(dummy, options, searchInfo.IncludeDisabledProviders)
                            .OfType <IRemoteSearchProvider <TLookupType> >();

            if (!string.IsNullOrEmpty(searchInfo.SearchProviderName))
            {
                providers = providers.Where(i => string.Equals(i.Name, searchInfo.SearchProviderName, StringComparison.OrdinalIgnoreCase));
            }

            if (string.IsNullOrWhiteSpace(searchInfo.SearchInfo.MetadataLanguage))
            {
                searchInfo.SearchInfo.MetadataLanguage = ConfigurationManager.Configuration.PreferredMetadataLanguage;
            }
            if (string.IsNullOrWhiteSpace(searchInfo.SearchInfo.MetadataCountryCode))
            {
                searchInfo.SearchInfo.MetadataCountryCode = ConfigurationManager.Configuration.MetadataCountryCode;
            }

            foreach (var provider in providers)
            {
                var results = await GetSearchResults(provider, searchInfo.SearchInfo, cancellationToken).ConfigureAwait(false);

                var list = results.ToList();

                if (list.Count > 0)
                {
                    return(list.Take(10));
                }
            }

            // Nothing found
            return(new List <RemoteSearchResult>());
        }
Example #3
0
        private async Task <IEnumerable <RemoteSearchResult> > GetRemoteSearchResults <TItemType, TLookupType>(RemoteSearchQuery <TLookupType> searchInfo, BaseItem referenceItem, CancellationToken cancellationToken)
            where TItemType : BaseItem, new()
            where TLookupType : ItemLookupInfo
        {
            LibraryOptions libraryOptions;

            if (referenceItem == null)
            {
                // Give it a dummy path just so that it looks like a file system item
                var dummy = new TItemType
                {
                    Path     = Path.Combine(_appPaths.InternalMetadataPath, "dummy"),
                    ParentId = Guid.NewGuid()
                };

                dummy.SetParent(new Folder());

                referenceItem  = dummy;
                libraryOptions = new LibraryOptions();
            }
            else
            {
                libraryOptions = _libraryManager.GetLibraryOptions(referenceItem);
            }

            var options = GetMetadataOptions(referenceItem);

            var providers = GetMetadataProvidersInternal <TItemType>(referenceItem, libraryOptions, options, searchInfo.IncludeDisabledProviders, false)
                            .OfType <IRemoteSearchProvider <TLookupType> >();

            if (!string.IsNullOrEmpty(searchInfo.SearchProviderName))
            {
                providers = providers.Where(i => string.Equals(i.Name, searchInfo.SearchProviderName, StringComparison.OrdinalIgnoreCase));
            }

            if (string.IsNullOrWhiteSpace(searchInfo.SearchInfo.MetadataLanguage))
            {
                searchInfo.SearchInfo.MetadataLanguage = _configurationManager.Configuration.PreferredMetadataLanguage;
            }

            if (string.IsNullOrWhiteSpace(searchInfo.SearchInfo.MetadataCountryCode))
            {
                searchInfo.SearchInfo.MetadataCountryCode = _configurationManager.Configuration.MetadataCountryCode;
            }

            var resultList = new List <RemoteSearchResult>();

            foreach (var provider in providers)
            {
                try
                {
                    var results = await GetSearchResults(provider, searchInfo.SearchInfo, cancellationToken).ConfigureAwait(false);

                    foreach (var result in results)
                    {
                        var existingMatch = resultList.FirstOrDefault(i => i.ProviderIds.Any(p => string.Equals(result.GetProviderId(p.Key), p.Value, StringComparison.OrdinalIgnoreCase)));

                        if (existingMatch == null)
                        {
                            resultList.Add(result);
                        }
                        else
                        {
                            foreach (var providerId in result.ProviderIds)
                            {
                                if (!existingMatch.ProviderIds.ContainsKey(providerId.Key))
                                {
                                    existingMatch.ProviderIds.Add(providerId.Key, providerId.Value);
                                }
                            }

                            if (string.IsNullOrWhiteSpace(existingMatch.ImageUrl))
                            {
                                existingMatch.ImageUrl = result.ImageUrl;
                            }
                        }
                    }
                }
#pragma warning disable CA1031 // do not catch general exception types
                catch (Exception ex)
#pragma warning restore CA1031 // do not catch general exception types
                {
                    _logger.LogError(ex, "Provider {ProviderName} failed to retrieve search results", provider.Name);
                }
            }

            return(resultList);
        }
Example #4
0
        /// <inheritdoc/>
        public Task <IEnumerable <RemoteSearchResult> > GetRemoteSearchResults <TItemType, TLookupType>(RemoteSearchQuery <TLookupType> searchInfo, CancellationToken cancellationToken)
            where TItemType : BaseItem, new()
            where TLookupType : ItemLookupInfo
        {
            BaseItem referenceItem = null;

            if (!searchInfo.ItemId.Equals(Guid.Empty))
            {
                referenceItem = _libraryManager.GetItemById(searchInfo.ItemId);
            }

            return(GetRemoteSearchResults <TItemType, TLookupType>(searchInfo, referenceItem, cancellationToken));
        }
Example #5
0
        public async Task <ActionResult <IEnumerable <RemoteSearchResult> > > GetMovieRemoteSearchResults([FromBody, Required] RemoteSearchQuery <MovieInfo> query)
        {
            var results = await _providerManager.GetRemoteSearchResults <Movie, MovieInfo>(query, CancellationToken.None)
                          .ConfigureAwait(false);

            return(Ok(results));
        }
Example #6
0
        public async Task <IEnumerable <RemoteSearchResult> > GetRemoteSearchResults <TItemType, TLookupType>(RemoteSearchQuery <TLookupType> searchInfo,
                                                                                                              CancellationToken cancellationToken)
            where TItemType : BaseItem, new()
            where TLookupType : ItemLookupInfo
        {
            // Give it a dummy path just so that it looks like a file system item
            var dummy = new TItemType
            {
                Path     = Path.Combine(_appPaths.InternalMetadataPath, "dummy"),
                ParentId = Guid.NewGuid()
            };

            dummy.SetParent(new Folder());

            var options = GetMetadataOptions(dummy);

            var providers = GetMetadataProvidersInternal <TItemType>(dummy, options, searchInfo.IncludeDisabledProviders, false, false)
                            .OfType <IRemoteSearchProvider <TLookupType> >();

            if (!string.IsNullOrEmpty(searchInfo.SearchProviderName))
            {
                providers = providers.Where(i => string.Equals(i.Name, searchInfo.SearchProviderName, StringComparison.OrdinalIgnoreCase));
            }

            if (string.IsNullOrWhiteSpace(searchInfo.SearchInfo.MetadataLanguage))
            {
                searchInfo.SearchInfo.MetadataLanguage = ConfigurationManager.Configuration.PreferredMetadataLanguage;
            }
            if (string.IsNullOrWhiteSpace(searchInfo.SearchInfo.MetadataCountryCode))
            {
                searchInfo.SearchInfo.MetadataCountryCode = ConfigurationManager.Configuration.MetadataCountryCode;
            }

            var resultList = new List <RemoteSearchResult>();

            foreach (var provider in providers)
            {
                try
                {
                    var results = await GetSearchResults(provider, searchInfo.SearchInfo, cancellationToken).ConfigureAwait(false);

                    foreach (var result in results)
                    {
                        var existingMatch = resultList.FirstOrDefault(i => i.ProviderIds.Any(p => string.Equals(result.GetProviderId(p.Key), p.Value, StringComparison.OrdinalIgnoreCase)));

                        if (existingMatch == null)
                        {
                            resultList.Add(result);
                        }
                        else
                        {
                            foreach (var providerId in result.ProviderIds)
                            {
                                if (!existingMatch.ProviderIds.ContainsKey(providerId.Key))
                                {
                                    existingMatch.ProviderIds.Add(providerId.Key, providerId.Value);
                                }
                            }

                            if (string.IsNullOrWhiteSpace(existingMatch.ImageUrl))
                            {
                                existingMatch.ImageUrl = result.ImageUrl;
                            }
                        }
                    }
                }
                catch (Exception ex)
                {
                    // Logged at lower levels
                }
            }

            //_logger.Debug("Returning search results {0}", _json.SerializeToString(resultList));

            return(resultList);
        }
Example #7
0
        public async Task <IEnumerable <RemoteSearchResult> > GetRemoteSearchResults <TItemType, TLookupType>(RemoteSearchQuery <TLookupType> searchInfo,
                                                                                                              CancellationToken cancellationToken)
            where TItemType : BaseItem, new()
            where TLookupType : ItemLookupInfo
        {
            const int maxResults = 10;

            // Give it a dummy path just so that it looks like a file system item
            var dummy = new TItemType
            {
                Path     = Path.Combine(_appPaths.InternalMetadataPath, "dummy"),
                ParentId = Guid.NewGuid()
            };

            dummy.SetParent(new Folder());

            var options = GetMetadataOptions(dummy);

            var providers = GetMetadataProvidersInternal <TItemType>(dummy, options, searchInfo.IncludeDisabledProviders, false)
                            .OfType <IRemoteSearchProvider <TLookupType> >();

            if (!string.IsNullOrEmpty(searchInfo.SearchProviderName))
            {
                providers = providers.Where(i => string.Equals(i.Name, searchInfo.SearchProviderName, StringComparison.OrdinalIgnoreCase));
            }

            if (string.IsNullOrWhiteSpace(searchInfo.SearchInfo.MetadataLanguage))
            {
                searchInfo.SearchInfo.MetadataLanguage = ConfigurationManager.Configuration.PreferredMetadataLanguage;
            }
            if (string.IsNullOrWhiteSpace(searchInfo.SearchInfo.MetadataCountryCode))
            {
                searchInfo.SearchInfo.MetadataCountryCode = ConfigurationManager.Configuration.MetadataCountryCode;
            }

            var resultList            = new List <RemoteSearchResult>();
            var foundProviderIds      = new Dictionary <Tuple <string, string>, RemoteSearchResult>();
            var foundTitleYearStrings = new HashSet <string>(StringComparer.OrdinalIgnoreCase);

            foreach (var provider in providers)
            {
                try
                {
                    var results = await GetSearchResults(provider, searchInfo.SearchInfo, cancellationToken).ConfigureAwait(false);

                    foreach (var result in results)
                    {
                        var bFound = false;

                        // This check prevents duplicate search results by comparing provider ids
                        foreach (var providerId in result.ProviderIds)
                        {
                            var idTuple = new Tuple <string, string>(providerId.Key.ToLower(), providerId.Value.ToLower());

                            if (!foundProviderIds.ContainsKey(idTuple))
                            {
                                foundProviderIds.Add(idTuple, result);
                            }
                            else
                            {
                                bFound = true;
                                var existingResult = foundProviderIds[idTuple];
                                if (string.IsNullOrEmpty(existingResult.ImageUrl) && !string.IsNullOrEmpty(result.ImageUrl))
                                {
                                    existingResult.ImageUrl = result.ImageUrl;
                                }
                            }
                        }

                        if (!bFound && resultList.Count < maxResults)
                        {
                            resultList.Add(result);
                        }
                    }
                }
                catch (Exception ex)
                {
                    // Logged at lower levels
                }
            }

            return(resultList);
        }