public void TestNfoArtistReaderWriteMetadata() { ArtistStub artistStub = CreateTestArtistStub(); IDictionary <Guid, IList <MediaItemAspect> > aspects = new Dictionary <Guid, IList <MediaItemAspect> >(); NfoArtistReader reader = new NfoArtistReader(new ConsoleLogger(LogLevel.All, true), 1, false, null, new NfoAudioMetadataExtractorSettings(), false); reader.GetArtistStubs().Add(artistStub); reader.TryWriteMetadata(aspects); MediaItemAspect mediaAspect = MediaItemAspect.GetAspect(aspects, MediaAspect.Metadata); Assert.NotNull(mediaAspect); Assert.AreEqual(artistStub.Name, mediaAspect.GetAttributeValue <string>(MediaAspect.ATTR_TITLE)); MediaItemAspect personAspect = MediaItemAspect.GetAspect(aspects, PersonAspect.Metadata); Assert.NotNull(personAspect); Assert.AreEqual(artistStub.Name, personAspect.GetAttributeValue <string>(PersonAspect.ATTR_PERSON_NAME)); Assert.AreEqual(PersonAspect.OCCUPATION_ARTIST, personAspect.GetAttributeValue <string>(PersonAspect.ATTR_OCCUPATION)); Assert.AreEqual(artistStub.Biography, personAspect.GetAttributeValue <string>(PersonAspect.ATTR_BIOGRAPHY)); Assert.AreEqual(artistStub.Birthdate, personAspect.GetAttributeValue <DateTime?>(PersonAspect.ATTR_DATEOFBIRTH)); Assert.AreEqual(artistStub.Deathdate, personAspect.GetAttributeValue <DateTime?>(PersonAspect.ATTR_DATEOFDEATH)); Assert.IsFalse(personAspect.GetAttributeValue <bool>(PersonAspect.ATTR_GROUP)); IList <MediaItemAspect> externalIdentifiers; Assert.IsTrue(aspects.TryGetValue(ExternalIdentifierAspect.ASPECT_ID, out externalIdentifiers)); Assert.IsTrue(TestUtils.HasExternalId(externalIdentifiers, ExternalIdentifierAspect.SOURCE_AUDIODB, ExternalIdentifierAspect.TYPE_PERSON, artistStub.AudioDbId.ToString())); Assert.IsTrue(TestUtils.HasExternalId(externalIdentifiers, ExternalIdentifierAspect.SOURCE_MUSICBRAINZ, ExternalIdentifierAspect.TYPE_PERSON, artistStub.MusicBrainzArtistId)); //Thumbnail aspect no longer used. FanArt cache used instead because of expanded FanArt support //MediaItemAspect thumbnailAspect = MediaItemAspect.GetAspect(aspects, ThumbnailLargeAspect.Metadata); //Assert.NotNull(thumbnailAspect); //CollectionAssert.AreEqual(artistStub.Thumb, thumbnailAspect.GetAttributeValue<byte[]>(ThumbnailLargeAspect.ATTR_THUMBNAIL)); //Test Group aspects.Clear(); artistStub.Birthdate = null; artistStub.Deathdate = null; reader = new NfoArtistReader(new ConsoleLogger(LogLevel.All, true), 1, false, null, new NfoAudioMetadataExtractorSettings(), false); reader.GetArtistStubs().Add(artistStub); reader.TryWriteMetadata(aspects); personAspect = MediaItemAspect.GetAspect(aspects, PersonAspect.Metadata); Assert.NotNull(personAspect); Assert.AreEqual(artistStub.Formeddate, personAspect.GetAttributeValue <DateTime?>(PersonAspect.ATTR_DATEOFBIRTH)); Assert.AreEqual(artistStub.Disbandeddate, personAspect.GetAttributeValue <DateTime?>(PersonAspect.ATTR_DATEOFDEATH)); Assert.IsTrue(personAspect.GetAttributeValue <bool>(PersonAspect.ATTR_GROUP)); }
/// <summary> /// Asynchronously tries to get an <see cref="NfoArtistReader"/> for the given <param name="mediaItemAccessor"></param> /// </summary> /// <param name="mediaItemAccessor">Points to the resource for which we try to extract metadata</param> /// <param name="extractedAspectData">Dictionary of <see cref="MediaItemAspect"/>s with the extracted metadata</param> /// <param name="forceQuickMode">If <c>true</c>, nothing is downloaded from the internet</param> /// <returns><c>true</c> if metadata was found and stored into <param name="extractedAspectData"></param>, else <c>false</c></returns> protected async Task <NfoArtistReader> TryGetNfoArtistReaderAsync(IResourceAccessor mediaItemAccessor) { // Get a unique number for this call to TryExtractMetadataAsync. We use this to make reading the debug log easier. // This MetadataExtractor is called in parallel for multiple MediaItems so that the respective debug log entries // for one call are not contained one after another in debug log. We therefore prepend this number before every log entry. var miNumber = Interlocked.Increment(ref _lastMediaItemNumber); try { _debugLogger.Info("[#{0}]: Start extracting metadata for resource '{1}'", miNumber, mediaItemAccessor); // This MetadataExtractor only works for MediaItems accessible by an IFileSystemResourceAccessor. // Otherwise it is not possible to find a nfo-file in the MediaItem's directory. if (!(mediaItemAccessor is IFileSystemResourceAccessor)) { _debugLogger.Info("[#{0}]: Cannot extract metadata; mediaItemAccessor is not an IFileSystemResourceAccessor", miNumber); return(null); } // First we try to find an IFileSystemResourceAccessor pointing to the artist nfo-file. IFileSystemResourceAccessor artistNfoFsra; if (TryGetArtistNfoSResourceAccessor(miNumber, mediaItemAccessor as IFileSystemResourceAccessor, out artistNfoFsra)) { // If we found one, we (asynchronously) extract the metadata into a stub object var artistNfoReader = new NfoArtistReader(_debugLogger, miNumber, false, _httpClient, _settings); using (artistNfoFsra) { if (await artistNfoReader.TryReadMetadataAsync(artistNfoFsra).ConfigureAwait(false)) { return(artistNfoReader); } else { _debugLogger.Warn("[#{0}]: No valid metadata found in album nfo-file", miNumber); } } } } catch (Exception e) { ServiceRegistration.Get <ILogger>().Warn("NfoAudioMetadataExtractor: Exception while extracting metadata for resource '{0}'; enable debug logging for more details.", mediaItemAccessor); _debugLogger.Error("[#{0}]: Exception while extracting metadata", e, miNumber); } return(null); }
/// <summary> /// Asynchronously tries to extract series actors for the given <param name="mediaItemAccessor"></param> /// </summary> /// <param name="mediaItemAccessor">Points to the resource for which we try to extract metadata</param> /// <param name="extractedAspects">List of MediaItemAspect dictionaries to update with metadata</param> /// <returns><c>true</c> if metadata was found and stored into the <paramref name="extractedAspects"/>, else <c>false</c></returns> protected async Task <bool> TryExtractAlbumArtistMetadataAsync(IResourceAccessor mediaItemAccessor, IList <IDictionary <Guid, IList <MediaItemAspect> > > extractedAspects) { NfoArtistReader artistReader = await TryGetNfoArtistReaderAsync(mediaItemAccessor).ConfigureAwait(false); if (artistReader != null) { IDictionary <Guid, IList <MediaItemAspect> > aspects = new Dictionary <Guid, IList <MediaItemAspect> >(); if (artistReader.TryWriteMetadata(aspects)) { extractedAspects.Add(aspects); return(true); } } NfoAlbumReader albumNfoReader = await TryGetNfoAlbumReaderAsync(mediaItemAccessor).ConfigureAwait(false); if (albumNfoReader != null) { return(albumNfoReader.TryWriteArtistMetadata(extractedAspects)); } return(false); }
public override async Task CollectFanArtAsync(Guid mediaItemId, IDictionary <Guid, IList <MediaItemAspect> > aspects) { IResourceLocator mediaItemLocator = null; if (!BaseInfo.IsVirtualResource(aspects)) { mediaItemLocator = GetResourceLocator(aspects); } if (!aspects.ContainsKey(AudioAspect.ASPECT_ID) || mediaItemLocator == null) { return; } IFanArtCache fanArtCache = ServiceRegistration.Get <IFanArtCache>(); using (IResourceAccessor mediaItemAccessor = mediaItemLocator.CreateAccessor()) { //Album fanart if (RelationshipExtractorUtils.TryGetLinkedId(AudioAlbumAspect.ROLE_ALBUM, aspects, out Guid albumMediaItemId) && AddToCache(albumMediaItemId)) { var existingCovers = fanArtCache.GetFanArtFiles(albumMediaItemId, FanArtTypes.Cover); if (!existingCovers.Any()) //Only get album cover if needed for better performance { NfoAlbumReader albumNfoReader = await AUDIO_EXTRACTOR.TryGetNfoAlbumReaderAsync(mediaItemAccessor, true).ConfigureAwait(false); if (albumNfoReader != null) { var stubs = albumNfoReader.GetAlbumStubs(); var mainStub = stubs?.FirstOrDefault(); if (mainStub?.Thumb != null) { await fanArtCache.TrySaveFanArt(albumMediaItemId, mainStub.Title, FanArtTypes.Cover, p => TrySaveFileImage(mainStub.Thumb, p, "Thumb", "Nfo.")).ConfigureAwait(false); } } } } //Artist fanart IList <Tuple <Guid, string> > artists = GetArtists(aspects); if (artists?.Count > 0) { foreach (var artist in artists) { var existingThumbs = fanArtCache.GetFanArtFiles(artist.Item1, FanArtTypes.Thumbnail); if (!existingThumbs.Any() && AddToCache(artist.Item1)) //Only get artist thumbnail if needed for better performance { NfoArtistReader artistReader = await AUDIO_EXTRACTOR.TryGetNfoArtistReaderAsync(mediaItemAccessor, artist.Item2, true).ConfigureAwait(false); if (artistReader != null) { var stubs = artistReader.GetArtistStubs(); var mainStub = stubs?.FirstOrDefault(); if (string.Equals(mainStub?.Name, artist.Item2, StringComparison.InvariantCultureIgnoreCase)) { if (mainStub?.Thumb != null) { await fanArtCache.TrySaveFanArt(artist.Item1, artist.Item2, FanArtTypes.Thumbnail, p => TrySaveFileImage(mainStub.Thumb, p, "Thumb", "Nfo.")).ConfigureAwait(false); } } } } } } } }