123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910 |
- using System;
- using System.Collections.Generic;
- using System.Globalization;
- using System.IO;
- using System.Linq;
- using System.Security;
- using System.Text;
- using System.Xml;
- using MediaBrowser.Common.Extensions;
- using MediaBrowser.Common.IO;
- using MediaBrowser.Controller.Configuration;
- using MediaBrowser.Controller.Entities;
- using MediaBrowser.Controller.Entities.Audio;
- using MediaBrowser.Controller.Entities.Movies;
- using MediaBrowser.Controller.Entities.TV;
- using MediaBrowser.Controller.Library;
- using MediaBrowser.Controller.Persistence;
- using MediaBrowser.Model.Configuration;
- using MediaBrowser.Model.Entities;
- using MediaBrowser.XbmcMetadata.Configuration;
- namespace MediaBrowser.XbmcMetadata.Savers
- {
- public static class XmlSaverHelpers
- {
- private static readonly CultureInfo UsCulture = new CultureInfo("en-US");
- private static readonly Dictionary<string, string> CommonTags = new[] {
-
- "plot",
- "customrating",
- "lockdata",
- "type",
- "dateadded",
- "title",
- "rating",
- "year",
- "sorttitle",
- "mpaa",
- "mpaadescription",
- "aspectratio",
- "website",
- "collectionnumber",
- "tmdbid",
- "rottentomatoesid",
- "language",
- "tvcomid",
- "budget",
- "revenue",
- "tagline",
- "studio",
- "genre",
- "tag",
- "runtime",
- "actor",
- "criticratingsummary",
- "criticrating",
- "fileinfo",
- "director",
- "writer",
- "trailer",
- "premiered",
- "releasedate",
- "outline",
- "id",
- "votes",
- "credits",
- "originaltitle",
- "watched",
- "playcount",
- "lastplayed",
- "art",
- "resume",
- "biography",
- "formed",
- "review",
- "style",
- "imdbid",
- "imdb_id",
- "plotkeyword",
- "country",
- "audiodbalbumid",
- "audiodbartistid",
- "awardsummary",
- "enddate",
- "lockedfields",
- "metascore",
- "zap2itid",
- "tvrageid",
- "gamesdbid",
- "musicbrainzartistid",
- "musicbrainzalbumartistid",
- "musicbrainzalbumid",
- "musicbrainzreleasegroupid",
- "tvdbid",
- "collectionitem"
- }.ToDictionary(i => i, StringComparer.OrdinalIgnoreCase);
- /// <summary>
- /// Saves the specified XML.
- /// </summary>
- /// <param name="xml">The XML.</param>
- /// <param name="path">The path.</param>
- /// <param name="xmlTagsUsed">The XML tags used.</param>
- public static void Save(StringBuilder xml, string path, List<string> xmlTagsUsed)
- {
- if (File.Exists(path))
- {
- var tags = xmlTagsUsed.ToList();
- var position = xml.ToString().LastIndexOf("</", StringComparison.OrdinalIgnoreCase);
- xml.Insert(position, GetCustomTags(path, tags));
- }
- var xmlDocument = new XmlDocument();
- xmlDocument.LoadXml(xml.ToString());
- //Add the new node to the document.
- xmlDocument.InsertBefore(xmlDocument.CreateXmlDeclaration("1.0", "UTF-8", "yes"), xmlDocument.DocumentElement);
- Directory.CreateDirectory(Path.GetDirectoryName(path));
- var wasHidden = false;
- var file = new FileInfo(path);
- // This will fail if the file is hidden
- if (file.Exists)
- {
- if ((file.Attributes & FileAttributes.Hidden) == FileAttributes.Hidden)
- {
- file.Attributes &= ~FileAttributes.Hidden;
- wasHidden = true;
- }
- }
- using (var filestream = new FileStream(path, FileMode.Create, FileAccess.Write, FileShare.Read))
- {
- using (var streamWriter = new StreamWriter(filestream, Encoding.UTF8))
- {
- xmlDocument.Save(streamWriter);
- }
- }
- if (wasHidden)
- {
- file.Refresh();
- // Add back the attribute
- file.Attributes |= FileAttributes.Hidden;
- }
- }
- /// <summary>
- /// Gets the custom tags.
- /// </summary>
- /// <param name="path">The path.</param>
- /// <param name="xmlTagsUsed">The XML tags used.</param>
- /// <returns>System.String.</returns>
- private static string GetCustomTags(string path, List<string> xmlTagsUsed)
- {
- var settings = new XmlReaderSettings
- {
- CheckCharacters = false,
- IgnoreProcessingInstructions = true,
- IgnoreComments = true,
- ValidationType = ValidationType.None
- };
- var builder = new StringBuilder();
- using (var streamReader = new StreamReader(path, Encoding.UTF8))
- {
- // Use XmlReader for best performance
- using (var reader = XmlReader.Create(streamReader, settings))
- {
- reader.MoveToContent();
- // Loop through each element
- while (reader.Read())
- {
- if (reader.NodeType == XmlNodeType.Element)
- {
- var name = reader.Name;
- if (!CommonTags.ContainsKey(name) && !xmlTagsUsed.Contains(name, StringComparer.OrdinalIgnoreCase))
- {
- builder.AppendLine(reader.ReadOuterXml());
- }
- else
- {
- reader.Skip();
- }
- }
- }
- }
- }
- return builder.ToString();
- }
- public static void AddMediaInfo<T>(T item, StringBuilder builder)
- where T : BaseItem, IHasMediaSources
- {
- builder.Append("<fileinfo>");
- builder.Append("<streamdetails>");
- foreach (var stream in item.GetMediaSources(false).First().MediaStreams)
- {
- builder.Append("<" + stream.Type.ToString().ToLower() + ">");
- if (!string.IsNullOrEmpty(stream.Codec))
- {
- builder.Append("<codec>" + SecurityElement.Escape(stream.Codec) + "</codec>");
- builder.Append("<micodec>" + SecurityElement.Escape(stream.Codec) + "</micodec>");
- }
- if (stream.BitRate.HasValue)
- {
- builder.Append("<bitrate>" + stream.BitRate.Value.ToString(UsCulture) + "</bitrate>");
- }
- if (stream.Width.HasValue)
- {
- builder.Append("<width>" + stream.Width.Value.ToString(UsCulture) + "</width>");
- }
- if (stream.Height.HasValue)
- {
- builder.Append("<height>" + stream.Height.Value.ToString(UsCulture) + "</height>");
- }
- if (!string.IsNullOrEmpty(stream.AspectRatio))
- {
- builder.Append("<aspect>" + SecurityElement.Escape(stream.AspectRatio) + "</aspect>");
- builder.Append("<aspectratio>" + SecurityElement.Escape(stream.AspectRatio) + "</aspectratio>");
- }
- var framerate = stream.AverageFrameRate ?? stream.RealFrameRate;
- if (framerate.HasValue)
- {
- builder.Append("<framerate>" + framerate.Value.ToString(UsCulture) + "</framerate>");
- }
- if (!string.IsNullOrEmpty(stream.Language))
- {
- builder.Append("<language>" + SecurityElement.Escape(stream.Language) + "</language>");
- }
- var scanType = stream.IsInterlaced ? "interlaced" : "progressive";
- if (!string.IsNullOrEmpty(scanType))
- {
- builder.Append("<scantype>" + SecurityElement.Escape(scanType) + "</scantype>");
- }
- if (stream.Channels.HasValue)
- {
- builder.Append("<channels>" + stream.Channels.Value.ToString(UsCulture) + "</channels>");
- }
- if (stream.SampleRate.HasValue)
- {
- builder.Append("<samplingrate>" + stream.SampleRate.Value.ToString(UsCulture) + "</samplingrate>");
- }
- builder.Append("<default>" + SecurityElement.Escape(stream.IsDefault.ToString()) + "</default>");
- builder.Append("<forced>" + SecurityElement.Escape(stream.IsForced.ToString()) + "</forced>");
- if (stream.Type == MediaStreamType.Video)
- {
- if (item.RunTimeTicks.HasValue)
- {
- var timespan = TimeSpan.FromTicks(item.RunTimeTicks.Value);
- builder.Append("<duration>" + Convert.ToInt32(timespan.TotalMinutes).ToString(UsCulture) + "</duration>");
- builder.Append("<durationinseconds>" + Convert.ToInt32(timespan.TotalSeconds).ToString(UsCulture) + "</durationinseconds>");
- }
- var video = item as Video;
- if (video != null)
- {
- //AddChapters(video, builder, itemRepository);
- if (video.Video3DFormat.HasValue)
- {
- switch (video.Video3DFormat.Value)
- {
- case Video3DFormat.FullSideBySide:
- builder.Append("<format3d>FSBS</format3d>");
- break;
- case Video3DFormat.FullTopAndBottom:
- builder.Append("<format3d>FTAB</format3d>");
- break;
- case Video3DFormat.HalfSideBySide:
- builder.Append("<format3d>HSBS</format3d>");
- break;
- case Video3DFormat.HalfTopAndBottom:
- builder.Append("<format3d>HTAB</format3d>");
- break;
- }
- }
- }
- }
- builder.Append("</" + stream.Type.ToString().ToLower() + ">");
- }
- builder.Append("</streamdetails>");
- builder.Append("</fileinfo>");
- }
- /// <summary>
- /// Adds the common nodes.
- /// </summary>
- /// <returns>Task.</returns>
- public static void AddCommonNodes(BaseItem item, StringBuilder builder, ILibraryManager libraryManager, IUserManager userManager, IUserDataManager userDataRepo, IFileSystem fileSystem, IServerConfigurationManager config)
- {
- var overview = (item.Overview ?? string.Empty)
- .StripHtml()
- .Replace(""", "'");
- var options = config.GetNfoConfiguration();
- if (item is MusicArtist)
- {
- builder.Append("<biography><![CDATA[" + overview + "]]></biography>");
- }
- else if (item is MusicAlbum)
- {
- builder.Append("<review><![CDATA[" + overview + "]]></review>");
- }
- else
- {
- builder.Append("<plot><![CDATA[" + overview + "]]></plot>");
- }
- var hasShortOverview = item as IHasShortOverview;
- if (hasShortOverview != null)
- {
- var outline = (hasShortOverview.ShortOverview ?? string.Empty)
- .StripHtml()
- .Replace(""", "'");
- builder.Append("<outline><![CDATA[" + outline + "]]></outline>");
- }
- else
- {
- builder.Append("<outline><![CDATA[" + overview + "]]></outline>");
- }
- builder.Append("<customrating>" + SecurityElement.Escape(item.CustomRating ?? string.Empty) + "</customrating>");
- builder.Append("<lockdata>" + item.IsLocked.ToString().ToLower() + "</lockdata>");
- if (item.LockedFields.Count > 0)
- {
- builder.Append("<lockedfields>" + string.Join("|", item.LockedFields.Select(i => i.ToString()).ToArray()) + "</lockedfields>");
- }
-
- if (!string.IsNullOrEmpty(item.DisplayMediaType))
- {
- builder.Append("<type>" + SecurityElement.Escape(item.DisplayMediaType) + "</type>");
- }
- builder.Append("<dateadded>" + SecurityElement.Escape(item.DateCreated.ToString("yyyy-MM-dd HH:mm:ss")) + "</dateadded>");
- builder.Append("<title>" + SecurityElement.Escape(item.Name ?? string.Empty) + "</title>");
- builder.Append("<originaltitle>" + SecurityElement.Escape(item.Name ?? string.Empty) + "</originaltitle>");
- var directors = item.People
- .Where(i => IsPersonType(i, PersonType.Director))
- .Select(i => i.Name)
- .ToList();
- foreach (var person in directors)
- {
- builder.Append("<director>" + SecurityElement.Escape(person) + "</director>");
- }
- var writers = item.People
- .Where(i => IsPersonType(i, PersonType.Writer))
- .Select(i => i.Name)
- .Distinct(StringComparer.OrdinalIgnoreCase)
- .ToList();
- foreach (var person in writers)
- {
- builder.Append("<writer>" + SecurityElement.Escape(person) + "</writer>");
- }
- if (writers.Count > 0)
- {
- builder.Append("<credits>" + SecurityElement.Escape(string.Join(" / ", writers.ToArray())) + "</credits>");
- }
- var hasTrailer = item as IHasTrailers;
- if (hasTrailer != null)
- {
- foreach (var trailer in hasTrailer.RemoteTrailers)
- {
- builder.Append("<trailer>" + SecurityElement.Escape(GetOutputTrailerUrl(trailer.Url)) + "</trailer>");
- }
- }
- if (item.CommunityRating.HasValue)
- {
- builder.Append("<rating>" + SecurityElement.Escape(item.CommunityRating.Value.ToString(UsCulture)) + "</rating>");
- }
- if (item.ProductionYear.HasValue)
- {
- builder.Append("<year>" + SecurityElement.Escape(item.ProductionYear.Value.ToString(UsCulture)) + "</year>");
- }
- if (!string.IsNullOrEmpty(item.ForcedSortName))
- {
- builder.Append("<sorttitle>" + SecurityElement.Escape(item.ForcedSortName) + "</sorttitle>");
- }
- if (!string.IsNullOrEmpty(item.OfficialRating))
- {
- builder.Append("<mpaa>" + SecurityElement.Escape(item.OfficialRating) + "</mpaa>");
- }
- if (!string.IsNullOrEmpty(item.OfficialRatingDescription))
- {
- builder.Append("<mpaadescription>" + SecurityElement.Escape(item.OfficialRatingDescription) + "</mpaadescription>");
- }
- var hasAspectRatio = item as IHasAspectRatio;
- if (hasAspectRatio != null)
- {
- if (!string.IsNullOrEmpty(hasAspectRatio.AspectRatio))
- {
- builder.Append("<aspectratio>" + SecurityElement.Escape(hasAspectRatio.AspectRatio) + "</aspectratio>");
- }
- }
- if (!string.IsNullOrEmpty(item.HomePageUrl))
- {
- builder.Append("<website>" + SecurityElement.Escape(item.HomePageUrl) + "</website>");
- }
- var rt = item.GetProviderId(MetadataProviders.RottenTomatoes);
- if (!string.IsNullOrEmpty(rt))
- {
- builder.Append("<rottentomatoesid>" + SecurityElement.Escape(rt) + "</rottentomatoesid>");
- }
- var tmdbCollection = item.GetProviderId(MetadataProviders.TmdbCollection);
- if (!string.IsNullOrEmpty(tmdbCollection))
- {
- builder.Append("<collectionnumber>" + SecurityElement.Escape(tmdbCollection) + "</collectionnumber>");
- }
- var imdb = item.GetProviderId(MetadataProviders.Imdb);
- if (!string.IsNullOrEmpty(imdb))
- {
- if (item is Series)
- {
- builder.Append("<imdb_id>" + SecurityElement.Escape(imdb) + "</imdb_id>");
- }
- else
- {
- builder.Append("<imdbid>" + SecurityElement.Escape(imdb) + "</imdbid>");
- }
- }
- // Series xml saver already saves this
- if (!(item is Series))
- {
- var tvdb = item.GetProviderId(MetadataProviders.Tvdb);
- if (!string.IsNullOrEmpty(tvdb))
- {
- builder.Append("<tvdbid>" + SecurityElement.Escape(tvdb) + "</tvdbid>");
- }
- }
- var tmdb = item.GetProviderId(MetadataProviders.Tmdb);
- if (!string.IsNullOrEmpty(tmdb))
- {
- builder.Append("<tmdbid>" + SecurityElement.Escape(tmdb) + "</tmdbid>");
- }
- var tvcom = item.GetProviderId(MetadataProviders.Tvcom);
- if (!string.IsNullOrEmpty(tvcom))
- {
- builder.Append("<tvcomid>" + SecurityElement.Escape(tvcom) + "</tvcomid>");
- }
- var hasLanguage = item as IHasPreferredMetadataLanguage;
- if (hasLanguage != null)
- {
- if (!string.IsNullOrEmpty(hasLanguage.PreferredMetadataLanguage))
- {
- builder.Append("<language>" + SecurityElement.Escape(hasLanguage.PreferredMetadataLanguage) + "</language>");
- }
- }
- if (item.PremiereDate.HasValue && !(item is Episode))
- {
- var formatString = options.ReleaseDateFormat;
- if (item is MusicArtist)
- {
- builder.Append("<formed>" + SecurityElement.Escape(item.PremiereDate.Value.ToString(formatString)) + "</formed>");
- }
- else
- {
- builder.Append("<premiered>" + SecurityElement.Escape(item.PremiereDate.Value.ToString(formatString)) + "</premiered>");
- builder.Append("<releasedate>" + SecurityElement.Escape(item.PremiereDate.Value.ToString(formatString)) + "</releasedate>");
- }
- }
- if (item.EndDate.HasValue)
- {
- if (!(item is Episode))
- {
- var formatString = options.ReleaseDateFormat;
- builder.Append("<enddate>" + SecurityElement.Escape(item.EndDate.Value.ToString(formatString)) + "</enddate>");
- }
- }
- var hasCriticRating = item as IHasCriticRating;
- if (hasCriticRating != null)
- {
- if (hasCriticRating.CriticRating.HasValue)
- {
- builder.Append("<criticrating>" + SecurityElement.Escape(hasCriticRating.CriticRating.Value.ToString(UsCulture)) + "</criticrating>");
- }
- if (!string.IsNullOrEmpty(hasCriticRating.CriticRatingSummary))
- {
- builder.Append("<criticratingsummary><![CDATA[" + hasCriticRating.CriticRatingSummary + "]]></criticratingsummary>");
- }
- }
- var hasDisplayOrder = item as IHasDisplayOrder;
- if (hasDisplayOrder != null)
- {
- if (!string.IsNullOrEmpty(hasDisplayOrder.DisplayOrder))
- {
- builder.Append("<displayorder>" + SecurityElement.Escape(hasDisplayOrder.DisplayOrder) + "</displayorder>");
- }
- }
- if (item.VoteCount.HasValue)
- {
- builder.Append("<votes>" + SecurityElement.Escape(item.VoteCount.Value.ToString(UsCulture)) + "</votes>");
- }
- var hasBudget = item as IHasBudget;
- if (hasBudget != null)
- {
- if (hasBudget.Budget.HasValue)
- {
- builder.Append("<budget>" + SecurityElement.Escape(hasBudget.Budget.Value.ToString(UsCulture)) + "</budget>");
- }
- if (hasBudget.Revenue.HasValue)
- {
- builder.Append("<revenue>" + SecurityElement.Escape(hasBudget.Revenue.Value.ToString(UsCulture)) + "</revenue>");
- }
- }
- var hasMetascore = item as IHasMetascore;
- if (hasMetascore != null && hasMetascore.Metascore.HasValue)
- {
- builder.Append("<metascore>" + SecurityElement.Escape(hasMetascore.Metascore.Value.ToString(UsCulture)) + "</metascore>");
- }
- // Use original runtime here, actual file runtime later in MediaInfo
- var runTimeTicks = item.RunTimeTicks;
- if (runTimeTicks.HasValue)
- {
- var timespan = TimeSpan.FromTicks(runTimeTicks.Value);
- builder.Append("<runtime>" + Convert.ToInt32(timespan.TotalMinutes).ToString(UsCulture) + "</runtime>");
- }
- var hasTaglines = item as IHasTaglines;
- if (hasTaglines != null)
- {
- foreach (var tagline in hasTaglines.Taglines)
- {
- builder.Append("<tagline>" + SecurityElement.Escape(tagline) + "</tagline>");
- }
- }
- var hasProductionLocations = item as IHasProductionLocations;
- if (hasProductionLocations != null)
- {
- foreach (var country in hasProductionLocations.ProductionLocations)
- {
- builder.Append("<country>" + SecurityElement.Escape(country) + "</country>");
- }
- }
- foreach (var genre in item.Genres)
- {
- builder.Append("<genre>" + SecurityElement.Escape(genre) + "</genre>");
- }
- foreach (var studio in item.Studios)
- {
- builder.Append("<studio>" + SecurityElement.Escape(studio) + "</studio>");
- }
- var hasTags = item as IHasTags;
- if (hasTags != null)
- {
- foreach (var tag in hasTags.Tags)
- {
- if (item is MusicAlbum || item is MusicArtist)
- {
- builder.Append("<style>" + SecurityElement.Escape(tag) + "</style>");
- }
- else
- {
- builder.Append("<tag>" + SecurityElement.Escape(tag) + "</tag>");
- }
- }
- }
- var hasKeywords = item as IHasKeywords;
- if (hasKeywords != null)
- {
- foreach (var tag in hasKeywords.Keywords)
- {
- builder.Append("<plotkeyword>" + SecurityElement.Escape(tag) + "</plotkeyword>");
- }
- }
- var hasAwards = item as IHasAwards;
- if (hasAwards != null && !string.IsNullOrEmpty(hasAwards.AwardSummary))
- {
- builder.Append("<awardsummary>" + SecurityElement.Escape(hasAwards.AwardSummary) + "</awardsummary>");
- }
- var externalId = item.GetProviderId(MetadataProviders.AudioDbArtist);
- if (!string.IsNullOrEmpty(externalId))
- {
- builder.Append("<audiodbartistid>" + SecurityElement.Escape(externalId) + "</audiodbartistid>");
- }
- externalId = item.GetProviderId(MetadataProviders.AudioDbAlbum);
- if (!string.IsNullOrEmpty(externalId))
- {
- builder.Append("<audiodbalbumid>" + SecurityElement.Escape(externalId) + "</audiodbalbumid>");
- }
- externalId = item.GetProviderId(MetadataProviders.Zap2It);
- if (!string.IsNullOrEmpty(externalId))
- {
- builder.Append("<zap2itid>" + SecurityElement.Escape(externalId) + "</zap2itid>");
- }
- externalId = item.GetProviderId(MetadataProviders.MusicBrainzAlbum);
- if (!string.IsNullOrEmpty(externalId))
- {
- builder.Append("<musicbrainzalbumid>" + SecurityElement.Escape(externalId) + "</musicbrainzalbumid>");
- }
- externalId = item.GetProviderId(MetadataProviders.MusicBrainzAlbumArtist);
- if (!string.IsNullOrEmpty(externalId))
- {
- builder.Append("<musicbrainzalbumartistid>" + SecurityElement.Escape(externalId) + "</musicbrainzalbumartistid>");
- }
- externalId = item.GetProviderId(MetadataProviders.MusicBrainzArtist);
- if (!string.IsNullOrEmpty(externalId))
- {
- builder.Append("<musicbrainzartistid>" + SecurityElement.Escape(externalId) + "</musicbrainzartistid>");
- }
- externalId = item.GetProviderId(MetadataProviders.MusicBrainzReleaseGroup);
- if (!string.IsNullOrEmpty(externalId))
- {
- builder.Append("<musicbrainzreleasegroupid>" + SecurityElement.Escape(externalId) + "</musicbrainzreleasegroupid>");
- }
- externalId = item.GetProviderId(MetadataProviders.Gamesdb);
- if (!string.IsNullOrEmpty(externalId))
- {
- builder.Append("<gamesdbid>" + SecurityElement.Escape(externalId) + "</gamesdbid>");
- }
- externalId = item.GetProviderId(MetadataProviders.TvRage);
- if (!string.IsNullOrEmpty(externalId))
- {
- builder.Append("<tvrageid>" + SecurityElement.Escape(externalId) + "</tvrageid>");
- }
- if (options.SaveImagePathsInNfo)
- {
- AddImages(item, builder, fileSystem, config);
- }
- AddUserData(item, builder, userManager, userDataRepo, options);
- AddActors(item, builder, libraryManager, fileSystem, config);
- var folder = item as BoxSet;
- if (folder != null)
- {
- AddCollectionItems(folder, builder);
- }
- }
- public static void AddChapters(Video item, StringBuilder builder, IItemRepository repository)
- {
- var chapters = repository.GetChapters(item.Id);
- foreach (var chapter in chapters)
- {
- builder.Append("<chapter>");
- builder.Append("<name>" + SecurityElement.Escape(chapter.Name) + "</name>");
- var time = TimeSpan.FromTicks(chapter.StartPositionTicks);
- var ms = Convert.ToInt64(time.TotalMilliseconds);
- builder.Append("<startpositionms>" + SecurityElement.Escape(ms.ToString(UsCulture)) + "</startpositionms>");
- builder.Append("</chapter>");
- }
- }
- public static void AddCollectionItems(Folder item, StringBuilder builder)
- {
- var items = item.LinkedChildren
- .Where(i => i.Type == LinkedChildType.Manual && !string.IsNullOrWhiteSpace(i.ItemName))
- .ToList();
- foreach (var link in items)
- {
- builder.Append("<collectionitem>");
- builder.Append("<name>" + SecurityElement.Escape(link.ItemName) + "</name>");
- builder.Append("<type>" + SecurityElement.Escape(link.ItemType) + "</type>");
- if (link.ItemYear.HasValue)
- {
- builder.Append("<year>" + SecurityElement.Escape(link.ItemYear.Value.ToString(UsCulture)) + "</year>");
- }
- builder.Append("</collectionitem>");
- }
- }
- /// <summary>
- /// Gets the output trailer URL.
- /// </summary>
- /// <param name="url">The URL.</param>
- /// <returns>System.String.</returns>
- private static string GetOutputTrailerUrl(string url)
- {
- // This is what xbmc expects
- return url.Replace("http://www.youtube.com/watch?v=",
- "plugin://plugin.video.youtube/?action=play_video&videoid=",
- StringComparison.OrdinalIgnoreCase);
- }
- private static void AddImages(BaseItem item, StringBuilder builder, IFileSystem fileSystem, IServerConfigurationManager config)
- {
- builder.Append("<art>");
- var poster = item.PrimaryImagePath;
- if (!string.IsNullOrEmpty(poster))
- {
- builder.Append("<poster>" + SecurityElement.Escape(GetPathToSave(item.PrimaryImagePath, fileSystem, config)) + "</poster>");
- }
- foreach (var backdrop in item.GetImages(ImageType.Backdrop))
- {
- builder.Append("<fanart>" + SecurityElement.Escape(GetPathToSave(backdrop.Path, fileSystem, config)) + "</fanart>");
- }
- builder.Append("</art>");
- }
- private static void AddUserData(BaseItem item, StringBuilder builder, IUserManager userManager, IUserDataManager userDataRepo, XbmcMetadataOptions options)
- {
- var userId = options.UserId;
- if (string.IsNullOrWhiteSpace(userId))
- {
- return;
- }
- var user = userManager.GetUserById(new Guid(userId));
- if (user == null)
- {
- return;
- }
- if (item.IsFolder)
- {
- return;
- }
- var userdata = userDataRepo.GetUserData(user.Id, item.GetUserDataKey());
- builder.Append("<playcount>" + userdata.PlayCount.ToString(UsCulture) + "</playcount>");
- builder.Append("<watched>" + userdata.Played.ToString().ToLower() + "</watched>");
- if (userdata.LastPlayedDate.HasValue)
- {
- builder.Append("<lastplayed>" + SecurityElement.Escape(userdata.LastPlayedDate.Value.ToString("yyyy-MM-dd HH:mm:ss")) + "</lastplayed>");
- }
- builder.Append("<resume>");
- var runTimeTicks = item.RunTimeTicks ?? 0;
- builder.Append("<position>" + TimeSpan.FromTicks(userdata.PlaybackPositionTicks).TotalSeconds.ToString(UsCulture) + "</position>");
- builder.Append("<total>" + TimeSpan.FromTicks(runTimeTicks).TotalSeconds.ToString(UsCulture) + "</total>");
- builder.Append("</resume>");
- }
- public static void AddActors(BaseItem item, StringBuilder builder, ILibraryManager libraryManager, IFileSystem fileSystem, IServerConfigurationManager config)
- {
- var actors = item.People
- .Where(i => !IsPersonType(i, PersonType.Director) && !IsPersonType(i, PersonType.Writer))
- .ToList();
- foreach (var person in actors)
- {
- builder.Append("<actor>");
- builder.Append("<name>" + SecurityElement.Escape(person.Name ?? string.Empty) + "</name>");
- builder.Append("<role>" + SecurityElement.Escape(person.Role ?? string.Empty) + "</role>");
- builder.Append("<type>" + SecurityElement.Escape(person.Type ?? string.Empty) + "</type>");
- if (person.SortOrder.HasValue)
- {
- builder.Append("<sortorder>" + SecurityElement.Escape(person.SortOrder.Value.ToString(UsCulture)) + "</sortorder>");
- }
- try
- {
- var personEntity = libraryManager.GetPerson(person.Name);
- if (!string.IsNullOrEmpty(personEntity.PrimaryImagePath))
- {
- builder.Append("<thumb>" + SecurityElement.Escape(GetPathToSave(personEntity.PrimaryImagePath, fileSystem, config)) + "</thumb>");
- }
- }
- catch (Exception)
- {
- // Already logged in core
- }
- builder.Append("</actor>");
- }
- }
- private static bool IsPersonType(PersonInfo person, string type)
- {
- return string.Equals(person.Type, type, StringComparison.OrdinalIgnoreCase) || string.Equals(person.Role, type, StringComparison.OrdinalIgnoreCase);
- }
- private static string GetPathToSave(string path, IFileSystem fileSystem, IServerConfigurationManager config)
- {
- foreach (var map in config.Configuration.PathSubstitutions)
- {
- path = fileSystem.SubstitutePath(path, map.From, map.To);
- }
- return path;
- }
- public static string ReplaceString(string str, string oldValue, string newValue, StringComparison comparison)
- {
- var sb = new StringBuilder();
- int previousIndex = 0;
- int index = str.IndexOf(oldValue, comparison);
- while (index != -1)
- {
- sb.Append(str.Substring(previousIndex, index - previousIndex));
- sb.Append(newValue);
- index += oldValue.Length;
- previousIndex = index;
- index = str.IndexOf(oldValue, index, comparison);
- }
- sb.Append(str.Substring(previousIndex));
- return sb.ToString();
- }
- }
- }
|