From 823e558ade82445c8517d570e1dcd6a56a561ae2 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Thu, 27 Oct 2016 01:11:31 -0400 Subject: [PATCH] stub out BaseXmlSaver.cs --- .../MediaBrowser.LocalMetadata.csproj | 1 + .../Savers/BaseXmlSaver.cs | 346 ++++++++++++++++++ 2 files changed, 347 insertions(+) create mode 100644 MediaBrowser.LocalMetadata/Savers/BaseXmlSaver.cs diff --git a/MediaBrowser.LocalMetadata/MediaBrowser.LocalMetadata.csproj b/MediaBrowser.LocalMetadata/MediaBrowser.LocalMetadata.csproj index b0e943b6ec..f2812eb3af 100644 --- a/MediaBrowser.LocalMetadata/MediaBrowser.LocalMetadata.csproj +++ b/MediaBrowser.LocalMetadata/MediaBrowser.LocalMetadata.csproj @@ -68,6 +68,7 @@ + diff --git a/MediaBrowser.LocalMetadata/Savers/BaseXmlSaver.cs b/MediaBrowser.LocalMetadata/Savers/BaseXmlSaver.cs new file mode 100644 index 0000000000..eed846b7f3 --- /dev/null +++ b/MediaBrowser.LocalMetadata/Savers/BaseXmlSaver.cs @@ -0,0 +1,346 @@ +using System; +using System.Collections.Generic; +using System.Globalization; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading; +using System.Xml; +using MediaBrowser.Common.Extensions; +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.Model.Extensions; +using MediaBrowser.Model.IO; +using MediaBrowser.Model.Logging; +using MediaBrowser.Model.Xml; + +namespace MediaBrowser.LocalMetadata.Savers +{ + public abstract class BaseNfoSaver : IMetadataFileSaver + { + private static readonly CultureInfo UsCulture = new CultureInfo("en-US"); + + private static readonly Dictionary 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", + + "isuserfavorite", + "userrating", + + "countrycode" + + }.ToDictionary(i => i, StringComparer.OrdinalIgnoreCase); + + protected BaseNfoSaver(IFileSystem fileSystem, IServerConfigurationManager configurationManager, ILibraryManager libraryManager, IUserManager userManager, IUserDataManager userDataManager, ILogger logger, IXmlReaderSettingsFactory xmlReaderSettingsFactory) + { + Logger = logger; + XmlReaderSettingsFactory = xmlReaderSettingsFactory; + UserDataManager = userDataManager; + UserManager = userManager; + LibraryManager = libraryManager; + ConfigurationManager = configurationManager; + FileSystem = fileSystem; + } + + protected IFileSystem FileSystem { get; private set; } + protected IServerConfigurationManager ConfigurationManager { get; private set; } + protected ILibraryManager LibraryManager { get; private set; } + protected IUserManager UserManager { get; private set; } + protected IUserDataManager UserDataManager { get; private set; } + protected ILogger Logger { get; private set; } + protected IXmlReaderSettingsFactory XmlReaderSettingsFactory { get; private set; } + + protected ItemUpdateType MinimumUpdateType + { + get + { + return ItemUpdateType.MetadataDownload; + } + } + + public string Name + { + get + { + return SaverName; + } + } + + public static string SaverName + { + get + { + return "Emby Xml"; + } + } + + public string GetSavePath(IHasMetadata item) + { + return GetLocalSavePath(item); + } + + /// + /// Gets the save path. + /// + /// The item. + /// System.String. + protected abstract string GetLocalSavePath(IHasMetadata item); + + /// + /// Gets the name of the root element. + /// + /// The item. + /// System.String. + protected abstract string GetRootElementName(IHasMetadata item); + + /// + /// Determines whether [is enabled for] [the specified item]. + /// + /// The item. + /// Type of the update. + /// true if [is enabled for] [the specified item]; otherwise, false. + public abstract bool IsEnabledFor(IHasMetadata item, ItemUpdateType updateType); + + protected virtual List GetTagsUsed() + { + return new List(); + } + + public void Save(IHasMetadata item, CancellationToken cancellationToken) + { + var path = GetSavePath(item); + + using (var memoryStream = new MemoryStream()) + { + Save(item, memoryStream, path); + + memoryStream.Position = 0; + + cancellationToken.ThrowIfCancellationRequested(); + + SaveToFile(memoryStream, path); + } + } + + private void SaveToFile(Stream stream, string path) + { + FileSystem.CreateDirectory(Path.GetDirectoryName(path)); + + var file = FileSystem.GetFileInfo(path); + + var wasHidden = false; + + // This will fail if the file is hidden + if (file.Exists) + { + if (file.IsHidden) + { + FileSystem.SetHidden(path, false); + + wasHidden = true; + } + } + + using (var filestream = FileSystem.GetFileStream(path, FileOpenMode.Create, FileAccessMode.Write, FileShareMode.Read)) + { + stream.CopyTo(filestream); + } + + if (wasHidden || ConfigurationManager.Configuration.SaveMetadataHidden) + { + FileSystem.SetHidden(path, true); + } + } + + private void Save(IHasMetadata item, Stream stream, string xmlPath) + { + var settings = new XmlWriterSettings + { + Indent = true, + Encoding = Encoding.UTF8, + CloseOutput = false + }; + + using (XmlWriter writer = XmlWriter.Create(stream, settings)) + { + var root = GetRootElementName(item); + + writer.WriteStartDocument(true); + + writer.WriteStartElement(root); + + var baseItem = item as BaseItem; + + if (baseItem != null) + { + AddCommonNodes(baseItem, writer, LibraryManager, UserManager, UserDataManager, FileSystem, ConfigurationManager); + } + + WriteCustomElements(item, writer); + + var tagsUsed = GetTagsUsed(); + + try + { + AddCustomTags(xmlPath, tagsUsed, writer, Logger, FileSystem); + } + catch (FileNotFoundException) + { + + } + catch (IOException) + { + + } + catch (XmlException ex) + { + Logger.ErrorException("Error reading existng xml", ex); + } + + writer.WriteEndElement(); + + writer.WriteEndDocument(); + } + } + + protected abstract void WriteCustomElements(IHasMetadata item, XmlWriter writer); + + public const string DateAddedFormat = "yyyy-MM-dd HH:mm:ss"; + + /// + /// Adds the common nodes. + /// + /// Task. + public static void AddCommonNodes(BaseItem item, XmlWriter writer, ILibraryManager libraryManager, IUserManager userManager, IUserDataManager userDataRepo, IFileSystem fileSystem, IServerConfigurationManager config) + { + var writtenProviderIds = new HashSet(StringComparer.OrdinalIgnoreCase); + + } + + private static bool IsPersonType(PersonInfo person, string type) + { + return string.Equals(person.Type, type, StringComparison.OrdinalIgnoreCase) || string.Equals(person.Role, type, StringComparison.OrdinalIgnoreCase); + } + + private void AddCustomTags(string path, List xmlTagsUsed, XmlWriter writer, ILogger logger, IFileSystem fileSystem) + { + var settings = XmlReaderSettingsFactory.Create(false); + + settings.CheckCharacters = false; + settings.IgnoreProcessingInstructions = true; + settings.IgnoreComments = true; + + using (var fileStream = fileSystem.OpenRead(path)) + { + using (var streamReader = new StreamReader(fileStream, Encoding.UTF8)) + { + // Use XmlReader for best performance + using (var reader = XmlReader.Create(streamReader, settings)) + { + try + { + reader.MoveToContent(); + } + catch (Exception ex) + { + logger.ErrorException("Error reading existing xml tags from {0}.", ex, path); + return; + } + + // 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)) + { + writer.WriteNode(reader, false); + } + else + { + reader.Skip(); + } + } + } + } + } + } + } + } +}