Пример #1
0
        public void TestMovieMerge()
        {
            MovieInfo clone = _movie.Clone();

            clone.MergeWith(_movieSearch);

            Assert.AreEqual(clone.MovieName.Text, _movieSearch.MovieName.Text, "Error merging strings by length");
            Assert.IsTrue(clone.Awards.Contains("Emmy"), "Error adding missing award");
            Assert.IsFalse(clone.Genres.Any(g => g.Name == "Adventure"), "Error with only merging if genre is empty");
            Assert.IsTrue(clone.ProductionCompanies.Any(p => p.Name == "Company Name" && p.AudioDbId == 333), "Error adding missing company");
            Assert.AreEqual(clone.Rating.RatingValue, _movieSearch.Rating.RatingValue, "Error updating rating");
            Assert.AreEqual(clone.MovieDbId, _movieSearch.MovieDbId, "Error merging integer id");
            Assert.AreEqual(clone.ImdbId, _movieSearch.ImdbId, "Error merging string id");
            Assert.IsTrue(!clone.Summary.IsEmpty, "Error updating empty string");
            Assert.AreEqual(clone.Actors[1].Name, "Actor Name Long 2", "Error merging strings by length");
            Assert.AreEqual(clone.Actors[1].TvdbId, _movieSearch.Actors[0].TvdbId, "Error merging actors");
            Assert.IsTrue(clone.Actors[1].DateOfDeath.HasValue, "Error merging actors");
        }
Пример #2
0
        /// <summary>
        /// Tries to lookup the Movie online and downloads images.
        /// </summary>
        /// <param name="movieInfo">Movie to check</param>
        /// <returns><c>true</c> if successful</returns>
        public virtual async Task <bool> FindAndUpdateMovieAsync(MovieInfo movieInfo)
        {
            try
            {
                // Try online lookup
                if (!await InitAsync().ConfigureAwait(false))
                {
                    return(false);
                }

                MovieInfo movieMatch = null;
                string    movieId    = null;
                bool      matchFound = false;
                TLang     language   = FindBestMatchingLanguage(movieInfo.Languages);

                if (GetMovieId(movieInfo, out movieId))
                {
                    // Prefer memory cache
                    CheckCacheAndRefresh();
                    if (_memoryCache.TryGetValue(movieId, out movieMatch))
                    {
                        matchFound = true;
                    }
                }

                if (!matchFound)
                {
                    MovieMatch match = GetStroredMatch(movieInfo);
                    movieMatch = movieInfo.Clone();
                    if (string.IsNullOrEmpty(movieId))
                    {
                        Logger.Debug(_id + ": Try to lookup movie \"{0}\" from cache: {1}", movieInfo, match != null && !string.IsNullOrEmpty(match.Id));

                        if (match != null)
                        {
                            if (SetMovieId(movieMatch, match.Id))
                            {
                                //If Id was found in cache the online movie info is probably also in the cache
                                if (await _wrapper.UpdateFromOnlineMovieAsync(movieMatch, language, true).ConfigureAwait(false))
                                {
                                    Logger.Debug(_id + ": Found movie {0} in cache", movieInfo.ToString());
                                    matchFound = true;
                                }
                            }
                            else if (string.IsNullOrEmpty(movieId))
                            {
                                //Match was found but with invalid Id probably to avoid a retry
                                //No Id is available so online search will probably fail again
                                return(false);
                            }
                        }
                    }
                    else
                    {
                        if (match != null && movieId != match.Id)
                        {
                            //Id was changed so remove it so it can be updated
                            _storage.TryRemoveMatch(match);
                        }
                    }

                    if (!matchFound)
                    {
                        Logger.Debug(_id + ": Search for movie {0} online", movieInfo.ToString());

                        //Try to update movie information from online source if online Ids are present
                        if (!await _wrapper.UpdateFromOnlineMovieAsync(movieMatch, language, false).ConfigureAwait(false))
                        {
                            //Search for the movie online and update the Ids if a match is found
                            if (await _wrapper.SearchMovieUniqueAndUpdateAsync(movieMatch, language).ConfigureAwait(false))
                            {
                                //Ids were updated now try to update movie information from online source
                                if (await _wrapper.UpdateFromOnlineMovieAsync(movieMatch, language, false).ConfigureAwait(false))
                                {
                                    matchFound = true;
                                }
                            }
                        }
                        else
                        {
                            matchFound = true;
                        }
                    }
                }

                //Always save match even if none to avoid retries
                StoreMovieMatch(movieInfo, movieMatch);

                if (matchFound)
                {
                    movieInfo.MergeWith(movieMatch, true);

                    //Store person matches
                    foreach (PersonInfo person in movieInfo.Actors)
                    {
                        string id;
                        if (GetPersonId(person, out id))
                        {
                            _actorMatcher.StoreNameMatch(id, person.Name, person.Name);
                        }
                    }
                    foreach (PersonInfo person in movieInfo.Directors)
                    {
                        string id;
                        if (GetPersonId(person, out id))
                        {
                            _directorMatcher.StoreNameMatch(id, person.Name, person.Name);
                        }
                    }
                    foreach (PersonInfo person in movieInfo.Writers)
                    {
                        string id;
                        if (GetPersonId(person, out id))
                        {
                            _writerMatcher.StoreNameMatch(id, person.Name, person.Name);
                        }
                    }

                    //Store character matches
                    foreach (CharacterInfo character in movieInfo.Characters)
                    {
                        string id;
                        if (GetCharacterId(character, out id))
                        {
                            _characterMatcher.StoreNameMatch(id, character.Name, character.Name);
                        }
                    }

                    //Store company matches
                    foreach (CompanyInfo company in movieInfo.ProductionCompanies)
                    {
                        string id;
                        if (GetCompanyId(company, out id))
                        {
                            _companyMatcher.StoreNameMatch(id, company.Name, company.Name);
                        }
                    }

                    if (GetMovieId(movieInfo, out movieId))
                    {
                        _memoryCache.TryAdd(movieId, movieInfo);
                    }

                    return(true);
                }

                return(false);
            }
            catch (Exception ex)
            {
                Logger.Debug(_id + ": Exception while processing movie {0}", ex, movieInfo.ToString());
                return(false);
            }
        }
Пример #3
0
        public bool TryMerge(IDictionary <Guid, IList <MediaItemAspect> > extractedAspects, IDictionary <Guid, IList <MediaItemAspect> > existingAspects)
        {
            try
            {
                MovieInfo existing  = new MovieInfo();
                MovieInfo extracted = new MovieInfo();

                //Extracted aspects
                IList <MultipleMediaItemAspect> providerResourceAspects;
                if (!MediaItemAspect.TryGetAspects(extractedAspects, ProviderResourceAspect.Metadata, out providerResourceAspects))
                {
                    return(false);
                }

                //Existing aspects
                IList <MultipleMediaItemAspect> existingProviderResourceAspects;
                MediaItemAspect.TryGetAspects(existingAspects, ProviderResourceAspect.Metadata, out existingProviderResourceAspects);

                //Don't merge virtual resources
                if (!providerResourceAspects.Where(p => p.GetAttributeValue <int>(ProviderResourceAspect.ATTR_TYPE) == ProviderResourceAspect.TYPE_VIRTUAL).Any())
                {
                    //Replace if existing is a virtual resource
                    if (existingProviderResourceAspects.Where(p => p.GetAttributeValue <int>(ProviderResourceAspect.ATTR_TYPE) == ProviderResourceAspect.TYPE_VIRTUAL).Any())
                    {
                        //Don't allow merge of subtitles into virtual item
                        if (extractedAspects.ContainsKey(SubtitleAspect.ASPECT_ID) && !extractedAspects.ContainsKey(VideoStreamAspect.ASPECT_ID))
                        {
                            return(false);
                        }

                        MediaItemAspect.SetAttribute(existingAspects, MediaAspect.ATTR_ISVIRTUAL, false);
                        MediaItemAspect.SetAttribute(existingAspects, MediaAspect.ATTR_ISSTUB,
                                                     providerResourceAspects.Where(p => p.GetAttributeValue <int>(ProviderResourceAspect.ATTR_TYPE) == ProviderResourceAspect.TYPE_STUB).Any());
                        var now = DateTime.Now;
                        MediaItemAspect.SetAttribute(existingAspects, ImporterAspect.ATTR_DATEADDED, now);
                        MediaItemAspect.SetAttribute(existingAspects, ImporterAspect.ATTR_LAST_IMPORT_DATE, now);
                        existingAspects.Remove(ProviderResourceAspect.ASPECT_ID);
                        foreach (Guid aspect in extractedAspects.Keys)
                        {
                            if (!existingAspects.ContainsKey(aspect))
                            {
                                existingAspects.Add(aspect, extractedAspects[aspect]);
                            }
                        }

                        existing.FromMetadata(existingAspects);
                        extracted.FromMetadata(extractedAspects);

                        existing.MergeWith(extracted, true);
                        existing.SetMetadata(existingAspects);
                        return(true);
                    }

                    //Merge
                    if (providerResourceAspects.Where(p => p.GetAttributeValue <int>(ProviderResourceAspect.ATTR_TYPE) == ProviderResourceAspect.TYPE_STUB).Any() ||
                        existingProviderResourceAspects.Where(p => p.GetAttributeValue <int>(ProviderResourceAspect.ATTR_TYPE) == ProviderResourceAspect.TYPE_STUB).Any())
                    {
                        MediaItemAspect.SetAttribute(existingAspects, MediaAspect.ATTR_ISVIRTUAL, false);
                        MediaItemAspect.SetAttribute(existingAspects, MediaAspect.ATTR_ISSTUB, true);
                        if (!ResourceAspectMerger.MergeVideoResourceAspects(extractedAspects, existingAspects))
                        {
                            return(false);
                        }
                    }
                }

                existing.FromMetadata(existingAspects);
                extracted.FromMetadata(extractedAspects);

                existing.MergeWith(extracted, true);
                existing.SetMetadata(existingAspects);
                if (!ResourceAspectMerger.MergeVideoResourceAspects(extractedAspects, existingAspects))
                {
                    return(false);
                }

                return(true);
            }
            catch (Exception e)
            {
                // Only log at the info level here - And simply return false. This lets the caller know that we
                // couldn't perform our task here.
                ServiceRegistration.Get <ILogger>().Info("MovieMergeHandler: Exception merging resources (Text: '{0}')", e.Message);
                return(false);
            }
        }