Esempio n. 1
0
        private async Task <bool> ExtractMovieData(ILocalFsResourceAccessor lfsra, IDictionary <Guid, IList <MediaItemAspect> > extractedAspectData)
        {
            // VideoAspect must be present to be sure it is actually a video resource.
            if (!extractedAspectData.ContainsKey(VideoAspect.ASPECT_ID) && !extractedAspectData.ContainsKey(SubtitleAspect.ASPECT_ID))
            {
                return(false);
            }

            // Calling EnsureLocalFileSystemAccess not necessary; only string operation
            string[] pathsToTest = new[] { lfsra.LocalFileSystemPath, lfsra.CanonicalLocalResourcePath.ToString() };
            string   title       = null;
            string   sortTitle   = null;
            bool     isReimport  = extractedAspectData.ContainsKey(ReimportAspect.ASPECT_ID);

            MovieInfo movieInfo = new MovieInfo();

            if (extractedAspectData.ContainsKey(MovieAspect.ASPECT_ID))
            {
                movieInfo.FromMetadata(extractedAspectData);
            }

            if (movieInfo.MovieName.IsEmpty)
            {
                //Try to get title
                if (MediaItemAspect.TryGetAttribute(extractedAspectData, MediaAspect.ATTR_TITLE, out title) &&
                    !string.IsNullOrEmpty(title) && !lfsra.ResourceName.StartsWith(title, StringComparison.InvariantCultureIgnoreCase))
                {
                    //The title may still contain tags and other noise, try and parse it for a title and year.
                    MovieNameMatcher.MatchTitleYear(title, movieInfo);
                }
            }
            if (movieInfo.MovieNameSort.IsEmpty)
            {
                //Try to get sort title
                if (MediaItemAspect.TryGetAttribute(extractedAspectData, MediaAspect.ATTR_SORT_TITLE, out sortTitle) && !string.IsNullOrEmpty(sortTitle))
                {
                    movieInfo.MovieNameSort = sortTitle;
                }
            }

            if (!isReimport) //Ignore tags or file based information for reimport because they might be the cause of the wrong import
            {
                if (movieInfo.MovieDbId == 0)
                {
                    try
                    {
                        // Try to use an existing TMDB id for exact mapping
                        string tmdbId = await MatroskaMatcher.TryMatchTmdbIdAsync(lfsra).ConfigureAwait(false);

                        if (!string.IsNullOrEmpty(tmdbId))
                        {
                            movieInfo.MovieDbId = Convert.ToInt32(tmdbId);
                        }
                    }
                    catch (Exception ex)
                    {
                        ServiceRegistration.Get <ILogger>().Debug("MoviesMetadataExtractor: Exception reading TMDB ID for '{0}'", ex, lfsra.CanonicalLocalResourcePath);
                    }
                }

                if (string.IsNullOrEmpty(movieInfo.ImdbId))
                {
                    try
                    {
                        // Try to use an existing IMDB id for exact mapping
                        string imdbId = await MatroskaMatcher.TryMatchImdbIdAsync(lfsra).ConfigureAwait(false);

                        if (!string.IsNullOrEmpty(imdbId))
                        {
                            movieInfo.ImdbId = imdbId;
                        }
                        else if (pathsToTest.Any(path => ImdbIdMatcher.TryMatchImdbId(path, out imdbId)))
                        {
                            movieInfo.ImdbId = imdbId;
                        }
                    }
                    catch (Exception ex)
                    {
                        ServiceRegistration.Get <ILogger>().Debug("MoviesMetadataExtractor: Exception reading IMDB ID for '{0}'", ex, lfsra.CanonicalLocalResourcePath);
                    }
                }

                if (!movieInfo.IsBaseInfoPresent || !movieInfo.ReleaseDate.HasValue)
                {
                    // Also test the full path year. This is useful if the path contains the real name and year.
                    foreach (string path in pathsToTest)
                    {
                        if (MovieNameMatcher.MatchTitleYear(path, movieInfo))
                        {
                            break;
                        }
                    }
                    //Fall back to MediaAspect.ATTR_TITLE
                    if (movieInfo.MovieName.IsEmpty && !string.IsNullOrEmpty(title))
                    {
                        movieInfo.MovieName = title;
                    }

                    /* Clear the names from unwanted strings */
                    MovieNameMatcher.CleanupTitle(movieInfo);
                }

                if (!movieInfo.ReleaseDate.HasValue && !movieInfo.HasExternalId)
                {
                    // When searching movie title, the year can be relevant for multiple titles with same name but different years
                    DateTime recordingDate;
                    if (MediaItemAspect.TryGetAttribute(extractedAspectData, MediaAspect.ATTR_RECORDINGTIME, out recordingDate))
                    {
                        movieInfo.ReleaseDate = recordingDate;
                    }
                }

                try
                {
                    await MatroskaMatcher.ExtractFromTagsAsync(lfsra, movieInfo).ConfigureAwait(false);

                    MP4Matcher.ExtractFromTags(lfsra, movieInfo);
                }
                catch (Exception ex)
                {
                    ServiceRegistration.Get <ILogger>().Debug("MoviesMetadataExtractor: Exception reading tags for '{0}'", ex, lfsra.CanonicalLocalResourcePath);
                }
            }

            // Allow the online lookup to choose best matching language for metadata
            if (movieInfo.Languages.Count == 0)
            {
                IList <MultipleMediaItemAspect> audioAspects;
                if (MediaItemAspect.TryGetAspects(extractedAspectData, VideoAudioStreamAspect.Metadata, out audioAspects))
                {
                    foreach (MultipleMediaItemAspect aspect in audioAspects)
                    {
                        string language = (string)aspect.GetAttributeValue(VideoAudioStreamAspect.ATTR_AUDIOLANGUAGE);
                        if (!string.IsNullOrEmpty(language) && !movieInfo.Languages.Contains(language))
                        {
                            movieInfo.Languages.Add(language);
                        }
                    }
                }
            }

            if (SkipOnlineSearches && !SkipFanArtDownload)
            {
                MovieInfo tempInfo = movieInfo.Clone();
                if (await OnlineMatcherService.Instance.FindAndUpdateMovieAsync(tempInfo).ConfigureAwait(false))
                {
                    movieInfo.CopyIdsFrom(tempInfo);
                    movieInfo.HasChanged = tempInfo.HasChanged;
                }
            }
            else if (!SkipOnlineSearches)
            {
                await OnlineMatcherService.Instance.FindAndUpdateMovieAsync(movieInfo).ConfigureAwait(false);
            }

            //Asign genre ids
            if (movieInfo.Genres.Count > 0)
            {
                IGenreConverter converter = ServiceRegistration.Get <IGenreConverter>();
                foreach (var genre in movieInfo.Genres)
                {
                    if (!genre.Id.HasValue && converter.GetGenreId(genre.Name, GenreCategory.Movie, null, out int genreId))
                    {
                        genre.Id             = genreId;
                        movieInfo.HasChanged = true;
                    }
                }
            }

            //Send it to the videos section
            if (!SkipOnlineSearches && !movieInfo.HasExternalId)
            {
                return(false);
            }

            //Create custom collection (overrides online collection)
            MovieCollectionInfo collectionInfo = movieInfo.CloneBasicInstance <MovieCollectionInfo>();
            string collectionName;

            if (string.IsNullOrEmpty(collectionInfo.NameId) && CollectionFolderHasFanArt(lfsra, out collectionName))
            {
                collectionInfo = new MovieCollectionInfo();
                collectionInfo.CollectionName = collectionName;
                if (!collectionInfo.CollectionName.IsEmpty)
                {
                    movieInfo.CollectionName = collectionInfo.CollectionName;
                    movieInfo.CopyIdsFrom(collectionInfo); //Reset ID's
                    movieInfo.HasChanged = true;
                }
            }

            if (movieInfo.MovieNameSort.IsEmpty)
            {
                if (!movieInfo.CollectionName.IsEmpty && movieInfo.ReleaseDate.HasValue)
                {
                    movieInfo.MovieNameSort = $"{movieInfo.CollectionName.Text} {movieInfo.ReleaseDate.Value.Year}-{movieInfo.ReleaseDate.Value.Month.ToString("00")}";
                }
                else if (!movieInfo.MovieName.IsEmpty)
                {
                    movieInfo.MovieNameSort = BaseInfo.GetSortTitle(movieInfo.MovieName.Text);
                }
                else
                {
                    movieInfo.MovieNameSort = BaseInfo.GetSortTitle(title);
                }
            }
            movieInfo.SetMetadata(extractedAspectData);

            return(movieInfo.IsBaseInfoPresent);
        }
Esempio n. 2
0
        private bool ExtractMovieData(ILocalFsResourceAccessor lfsra, IDictionary <Guid, IList <MediaItemAspect> > extractedAspectData, bool importOnly)
        {
            // Calling EnsureLocalFileSystemAccess not necessary; only string operation
            string[] pathsToTest = new[] { lfsra.LocalFileSystemPath, lfsra.CanonicalLocalResourcePath.ToString() };
            string   title       = null;
            string   sortTitle   = null;

            // VideoAspect must be present to be sure it is actually a video resource.
            if (!extractedAspectData.ContainsKey(VideoStreamAspect.ASPECT_ID) && !extractedAspectData.ContainsKey(SubtitleAspect.ASPECT_ID))
            {
                return(false);
            }

            if (extractedAspectData.ContainsKey(SubtitleAspect.ASPECT_ID) && !importOnly)
            {
                return(false); //Subtitles can only be imported not refreshed
            }
            bool refresh = false;

            if (extractedAspectData.ContainsKey(MovieAspect.ASPECT_ID))
            {
                refresh = true;
            }

            MovieInfo movieInfo = new MovieInfo();

            if (refresh)
            {
                movieInfo.FromMetadata(extractedAspectData);
            }

            if (movieInfo.MovieName.IsEmpty)
            {
                //Try to get title
                if (MediaItemAspect.TryGetAttribute(extractedAspectData, MediaAspect.ATTR_TITLE, out title) &&
                    !string.IsNullOrEmpty(title) && !lfsra.ResourceName.StartsWith(title, StringComparison.InvariantCultureIgnoreCase))
                {
                    movieInfo.MovieName = title;
                    /* Clear the names from unwanted strings */
                    MovieNameMatcher.CleanupTitle(movieInfo);
                }
            }
            if (movieInfo.MovieNameSort.IsEmpty)
            {
                //Try to get sort title
                if (MediaItemAspect.TryGetAttribute(extractedAspectData, MediaAspect.ATTR_SORT_TITLE, out sortTitle) && !string.IsNullOrEmpty(sortTitle))
                {
                    movieInfo.MovieNameSort = sortTitle;
                }
            }

            if (movieInfo.MovieDbId == 0)
            {
                try
                {
                    // Try to use an existing TMDB id for exact mapping
                    string tmdbId;
                    if (MatroskaMatcher.TryMatchTmdbId(lfsra, out tmdbId))
                    {
                        movieInfo.MovieDbId = Convert.ToInt32(tmdbId);
                    }
                }
                catch (Exception ex)
                {
                    ServiceRegistration.Get <ILogger>().Debug("MoviesMetadataExtractor: Exception reading TMDB ID for '{0}'", ex, lfsra.CanonicalLocalResourcePath);
                }
            }

            if (string.IsNullOrEmpty(movieInfo.ImdbId))
            {
                try
                {
                    // Try to use an existing IMDB id for exact mapping
                    string imdbId = null;
                    if (pathsToTest.Any(path => MatroskaMatcher.TryMatchImdbId(lfsra, out imdbId)))
                    {
                        movieInfo.ImdbId = imdbId;
                    }
                    else if (pathsToTest.Any(path => ImdbIdMatcher.TryMatchImdbId(path, out imdbId)))
                    {
                        movieInfo.ImdbId = imdbId;
                    }
                }
                catch (Exception ex)
                {
                    ServiceRegistration.Get <ILogger>().Debug("MoviesMetadataExtractor: Exception reading IMDB ID for '{0}'", ex, lfsra.CanonicalLocalResourcePath);
                }
            }

            if (!movieInfo.IsBaseInfoPresent)
            {
                // Also test the full path year. This is useful if the path contains the real name and year.
                foreach (string path in pathsToTest)
                {
                    if (MovieNameMatcher.MatchTitleYear(path, movieInfo))
                    {
                        break;
                    }
                }
                //Fall back to MediaAspect.ATTR_TITLE
                if (movieInfo.MovieName.IsEmpty && !string.IsNullOrEmpty(title))
                {
                    movieInfo.MovieName = title;
                }

                /* Clear the names from unwanted strings */
                MovieNameMatcher.CleanupTitle(movieInfo);
            }

            if (!movieInfo.ReleaseDate.HasValue && !movieInfo.HasExternalId)
            {
                // When searching movie title, the year can be relevant for multiple titles with same name but different years
                DateTime recordingDate;
                if (MediaItemAspect.TryGetAttribute(extractedAspectData, MediaAspect.ATTR_RECORDINGTIME, out recordingDate))
                {
                    movieInfo.ReleaseDate = recordingDate;
                }
            }

            // Allow the online lookup to choose best matching language for metadata
            if (movieInfo.Languages.Count == 0)
            {
                IList <MultipleMediaItemAspect> audioAspects;
                if (MediaItemAspect.TryGetAspects(extractedAspectData, VideoAudioStreamAspect.Metadata, out audioAspects))
                {
                    foreach (MultipleMediaItemAspect aspect in audioAspects)
                    {
                        string language = (string)aspect.GetAttributeValue(VideoAudioStreamAspect.ATTR_AUDIOLANGUAGE);
                        if (!string.IsNullOrEmpty(language) && !movieInfo.Languages.Contains(language))
                        {
                            movieInfo.Languages.Add(language);
                        }
                    }
                }
            }

            if (importOnly)
            {
                try
                {
                    MatroskaMatcher.ExtractFromTags(lfsra, movieInfo);
                    MP4Matcher.ExtractFromTags(lfsra, movieInfo);
                }
                catch (Exception ex)
                {
                    ServiceRegistration.Get <ILogger>().Debug("MoviesMetadataExtractor: Exception reading tags for '{0}'", ex, lfsra.CanonicalLocalResourcePath);
                }
            }

            if (SkipOnlineSearches && !SkipFanArtDownload)
            {
                MovieInfo tempInfo = movieInfo.Clone();
                OnlineMatcherService.Instance.FindAndUpdateMovie(tempInfo, importOnly);
                movieInfo.CopyIdsFrom(tempInfo);
                movieInfo.HasChanged = tempInfo.HasChanged;
            }
            else if (!SkipOnlineSearches)
            {
                OnlineMatcherService.Instance.FindAndUpdateMovie(movieInfo, importOnly);
            }

            //Send it to the videos section
            if (!SkipOnlineSearches && !movieInfo.HasExternalId)
            {
                return(false);
            }

            if (importOnly)
            {
                //Create custom collection (overrides online collection)
                MovieCollectionInfo collectionInfo = movieInfo.CloneBasicInstance <MovieCollectionInfo>();
                string collectionName;
                if (string.IsNullOrEmpty(collectionInfo.NameId) && CollectionFolderHasFanArt(lfsra, out collectionName))
                {
                    collectionInfo = new MovieCollectionInfo();
                    collectionInfo.CollectionName = collectionName;
                    if (!collectionInfo.CollectionName.IsEmpty)
                    {
                        movieInfo.CollectionName = collectionInfo.CollectionName;
                        movieInfo.CopyIdsFrom(collectionInfo); //Reset ID's
                        movieInfo.HasChanged = true;
                    }
                }
            }
            movieInfo.AssignNameId();

            if (refresh)
            {
                if ((IncludeActorDetails && !BaseInfo.HasRelationship(extractedAspectData, PersonAspect.ROLE_ACTOR) && movieInfo.Actors.Count > 0) ||
                    (IncludeCharacterDetails && !BaseInfo.HasRelationship(extractedAspectData, CharacterAspect.ROLE_CHARACTER) && movieInfo.Characters.Count > 0) ||
                    (IncludeDirectorDetails && !BaseInfo.HasRelationship(extractedAspectData, PersonAspect.ROLE_DIRECTOR) && movieInfo.Directors.Count > 0) ||
                    (IncludeWriterDetails && !BaseInfo.HasRelationship(extractedAspectData, PersonAspect.ROLE_WRITER) && movieInfo.Writers.Count > 0) ||
                    (IncludeProductionCompanyDetails && !BaseInfo.HasRelationship(extractedAspectData, CompanyAspect.ROLE_COMPANY) && movieInfo.ProductionCompanies.Count > 0))
                {
                    movieInfo.HasChanged = true;
                }
            }

            if (!movieInfo.HasChanged && !importOnly)
            {
                return(false);
            }

            movieInfo.SetMetadata(extractedAspectData);

            return(movieInfo.IsBaseInfoPresent);
        }