/// <summary> /// Adds the common nodes. /// </summary> /// <returns>Task.</returns> private void AddCommonNodes(BaseItem item, LibraryOptions libraryOptions, XmlWriter writer, ILibraryManager libraryManager, IUserManager userManager, IUserDataManager userDataRepo, IFileSystem fileSystem, IServerConfigurationManager config) { var writtenProviderIds = new HashSet <string>(StringComparer.OrdinalIgnoreCase); var overview = (item.Overview ?? string.Empty); var options = config.GetNfoConfiguration(); if (item is MusicArtist) { WriteOverviewNode(writer, overview, "biography"); } else if (item is MusicAlbum) { WriteOverviewNode(writer, overview, "review"); } else { WriteOverviewNode(writer, overview, "plot"); } if (item is Video) { var outline = (item.Tagline ?? string.Empty); WriteOverviewNode(writer, outline, "outline"); } else { WriteOverviewNode(writer, overview, "outline"); } if (!string.IsNullOrEmpty(item.CustomRating)) { writer.WriteElementString("customrating", item.CustomRating); } writer.WriteElementString("lockdata", item.IsLocked.ToString().ToLowerInvariant()); if (item.LockedFields.Length > 0) { writer.WriteElementString("lockedfields", string.Join("|", item.LockedFields)); } writer.WriteElementString("dateadded", item.DateCreated.LocalDateTime.ToString(DateAddedFormat)); writer.WriteElementString("title", item.Name ?? string.Empty); if (!string.IsNullOrEmpty(item.OriginalTitle)) { writer.WriteElementString("originaltitle", item.OriginalTitle); } var people = item.SupportsPeople ? libraryManager.GetItemPeople(new InternalPeopleQuery { ItemIds = new[] { item.InternalId }, EnableImages = options.SaveImagePathsInNfo, EnableProviderIds = true }) : new List <PersonInfo>(); AddActors(people, writer, libraryManager, fileSystem, libraryOptions, options.SaveImagePathsInNfo); var directors = people .Where(i => IsPersonType(i, PersonType.Director)) .ToList(); foreach (var person in directors) { writer.WriteStartElement("director"); foreach (var providerId in person.ProviderIds) { writer.WriteAttributeString(providerId.Key.ToLowerInvariant() + "id", providerId.Value); } writer.WriteString(person.Name); writer.WriteEndElement(); } var writers = people .Where(i => IsPersonType(i, PersonType.Writer)) .ToList(); foreach (var person in writers) { writer.WriteStartElement("writer"); foreach (var providerId in person.ProviderIds) { writer.WriteAttributeString(providerId.Key.ToLowerInvariant() + "id", providerId.Value); } writer.WriteString(person.Name); writer.WriteEndElement(); } foreach (var person in writers) { writer.WriteStartElement("credits"); foreach (var providerId in person.ProviderIds) { writer.WriteAttributeString(providerId.Key.ToLowerInvariant() + "id", providerId.Value); } writer.WriteString(person.Name); writer.WriteEndElement(); } foreach (var trailer in item.RemoteTrailers) { writer.WriteElementString("trailer", GetOutputTrailerUrl(trailer)); } if (item.CommunityRating.HasValue) { writer.WriteElementString("rating", item.CommunityRating.Value.ToString(CultureInfo.InvariantCulture)); } if (item.ProductionYear.HasValue) { writer.WriteElementString("year", item.ProductionYear.Value.ToString(CultureInfo.InvariantCulture)); } var sortName = item.SortName; if (!string.IsNullOrEmpty(sortName)) { writer.WriteElementString("sorttitle", sortName); } if (!string.IsNullOrEmpty(item.OfficialRating)) { writer.WriteElementString("mpaa", item.OfficialRating); } var imdb = item.GetProviderId(MetadataProviders.Imdb); if (!string.IsNullOrEmpty(imdb)) { if (item is Series) { writer.WriteElementString("imdb_id", imdb); } else { writer.WriteElementString("imdbid", imdb); } writtenProviderIds.Add(MetadataProviders.Imdb.ToString()); } // Series xml saver already saves this if (!(item is Series)) { var tvdb = item.GetProviderId(MetadataProviders.Tvdb); if (!string.IsNullOrEmpty(tvdb)) { writer.WriteElementString("tvdbid", tvdb); writtenProviderIds.Add(MetadataProviders.Tvdb.ToString()); } } var tmdb = item.GetProviderId(MetadataProviders.Tmdb); if (!string.IsNullOrEmpty(tmdb)) { writer.WriteElementString("tmdbid", tmdb); writtenProviderIds.Add(MetadataProviders.Tmdb.ToString()); } if (!string.IsNullOrEmpty(item.PreferredMetadataLanguage)) { writer.WriteElementString("language", item.PreferredMetadataLanguage); } if (!string.IsNullOrEmpty(item.PreferredMetadataCountryCode)) { writer.WriteElementString("countrycode", item.PreferredMetadataCountryCode); } if (item.PremiereDate.HasValue && !(item is Episode)) { var formatString = options.ReleaseDateFormat; if (item is MusicArtist) { writer.WriteElementString("formed", item.PremiereDate.Value.LocalDateTime.ToString(formatString)); } else { writer.WriteElementString("premiered", item.PremiereDate.Value.LocalDateTime.ToString(formatString)); writer.WriteElementString("releasedate", item.PremiereDate.Value.LocalDateTime.ToString(formatString)); } } if (item.EndDate.HasValue) { if (!(item is Episode)) { var formatString = options.ReleaseDateFormat; writer.WriteElementString("enddate", item.EndDate.Value.LocalDateTime.ToString(formatString)); } } if (item.CriticRating.HasValue) { writer.WriteElementString("criticrating", item.CriticRating.Value.ToString(CultureInfo.InvariantCulture)); } // Use original runtime here, actual file runtime later in MediaInfo var runTimeTicks = item.RunTimeTicks; if (runTimeTicks.HasValue) { var timespan = TimeSpan.FromTicks(runTimeTicks.Value); writer.WriteElementString("runtime", Convert.ToInt64(timespan.TotalMinutes).ToString(CultureInfo.InvariantCulture)); } if (!string.IsNullOrEmpty(item.Tagline)) { writer.WriteElementString("tagline", item.Tagline); } if (item is Person) { foreach (var country in item.ProductionLocations) { writer.WriteElementString("placeofbirth", country); } } else { foreach (var country in item.ProductionLocations) { writer.WriteElementString("country", country); } } foreach (var genre in item.GenreItems) { writer.WriteElementString("genre", genre.Name); } foreach (var studio in item.StudioItems) { writer.WriteElementString("studio", studio.Name); } foreach (var tag in item.TagItems) { if (item is MusicAlbum || item is MusicArtist) { writer.WriteElementString("style", tag.Name); } else { writer.WriteElementString("tag", tag.Name); } } var collections = item.GetAllKnownCollections(); foreach (var collection in collections) { writer.WriteStartElement("set"); var providerIds = collection.ProviderIds ?? (collection.Id.Equals(0) ? new ProviderIdDictionary() : LibraryManager.GetProviderIds(collection.Id)); foreach (var providerIdPair in providerIds) { var providerIdValue = providerIdPair.Value; if (string.IsNullOrEmpty(providerIdValue)) { // safeguard continue; } var providerIdName = providerIdPair.Key; if (string.Equals(providerIdName, "Tmdb", StringComparison.OrdinalIgnoreCase)) { providerIdName = "tmdbcolid"; } writer.WriteAttributeString(providerIdName, providerIdValue); } writer.WriteElementString("name", collection.Name); writer.WriteEndElement(); } var externalId = item.GetProviderId(MetadataProviders.AudioDbArtist); if (!string.IsNullOrEmpty(externalId)) { writer.WriteElementString("audiodbartistid", externalId); writtenProviderIds.Add(MetadataProviders.AudioDbArtist.ToString()); } externalId = item.GetProviderId(MetadataProviders.AudioDbAlbum); if (!string.IsNullOrEmpty(externalId)) { writer.WriteElementString("audiodbalbumid", externalId); writtenProviderIds.Add(MetadataProviders.AudioDbAlbum.ToString()); } externalId = item.GetProviderId(MetadataProviders.Zap2It); if (!string.IsNullOrEmpty(externalId)) { writer.WriteElementString("zap2itid", externalId); writtenProviderIds.Add(MetadataProviders.Zap2It.ToString()); } externalId = item.GetProviderId(MetadataProviders.MusicBrainzAlbum); if (!string.IsNullOrEmpty(externalId)) { writer.WriteElementString("musicbrainzalbumid", externalId); writtenProviderIds.Add(MetadataProviders.MusicBrainzAlbum.ToString()); } externalId = item.GetProviderId(MetadataProviders.MusicBrainzAlbumArtist); if (!string.IsNullOrEmpty(externalId)) { writer.WriteElementString("musicbrainzalbumartistid", externalId); writtenProviderIds.Add(MetadataProviders.MusicBrainzAlbumArtist.ToString()); } externalId = item.GetProviderId(MetadataProviders.MusicBrainzArtist); if (!string.IsNullOrEmpty(externalId)) { writer.WriteElementString("musicbrainzartistid", externalId); writtenProviderIds.Add(MetadataProviders.MusicBrainzArtist.ToString()); } externalId = item.GetProviderId(MetadataProviders.MusicBrainzReleaseGroup); if (!string.IsNullOrEmpty(externalId)) { writer.WriteElementString("musicbrainzreleasegroupid", externalId); writtenProviderIds.Add(MetadataProviders.MusicBrainzReleaseGroup.ToString()); } externalId = item.GetProviderId(MetadataProviders.Gamesdb); if (!string.IsNullOrEmpty(externalId)) { writer.WriteElementString("gamesdbid", externalId); writtenProviderIds.Add(MetadataProviders.Gamesdb.ToString()); } externalId = item.GetProviderId(MetadataProviders.TvRage); if (!string.IsNullOrEmpty(externalId)) { writer.WriteElementString("tvrageid", externalId); writtenProviderIds.Add(MetadataProviders.TvRage.ToString()); } if (item.ProviderIds != null) { foreach (var providerIdPair in item.ProviderIds) { var providerKey = providerIdPair.Key; var providerId = providerIdPair.Value; if (string.IsNullOrEmpty(providerId)) { continue; } writer.WriteStartElement("uniqueid"); writer.WriteAttributeString("type", providerKey); writer.WriteString(providerId); writer.WriteEndElement(); if (!writtenProviderIds.Contains(providerKey)) { try { var tagName = GetTagForProviderKey(providerKey); //Logger.Debug("Verifying custom provider tagname {0}", tagName); XmlConvert.VerifyName(tagName); //Logger.Debug("Saving custom provider tagname {0}", tagName); writer.WriteElementString(GetTagForProviderKey(providerKey), providerId); } catch (ArgumentException) { // catch invalid names without failing the entire operation } catch (XmlException) { // catch invalid names without failing the entire operation } } } } if (options.SaveImagePathsInNfo) { AddImages(item, writer, libraryManager, libraryOptions); } AddUserData(item, writer, userManager, userDataRepo, options); }