aboutsummaryrefslogtreecommitdiff
path: root/MediaBrowser.XbmcMetadata
diff options
context:
space:
mode:
authorLuke Pulverenti <luke.pulverenti@gmail.com>2014-07-08 20:46:11 -0400
committerLuke Pulverenti <luke.pulverenti@gmail.com>2014-07-08 20:46:11 -0400
commit651d483dec489a84bf93fe900e537cc7be9c4cbd (patch)
tree58933f9a84a82e1a1db89c7d7dfa975de7575700 /MediaBrowser.XbmcMetadata
parentc02e917f5657db4bd76fc6ca17c535fc441c641c (diff)
rework nfo savers
Diffstat (limited to 'MediaBrowser.XbmcMetadata')
-rw-r--r--MediaBrowser.XbmcMetadata/MediaBrowser.XbmcMetadata.csproj14
-rw-r--r--MediaBrowser.XbmcMetadata/Parsers/BaseNfoParser.cs9
-rw-r--r--MediaBrowser.XbmcMetadata/Savers/AlbumNfoSaver.cs112
-rw-r--r--MediaBrowser.XbmcMetadata/Savers/AlbumXmlSaver.cs134
-rw-r--r--MediaBrowser.XbmcMetadata/Savers/ArtistNfoSaver.cs94
-rw-r--r--MediaBrowser.XbmcMetadata/Savers/ArtistXmlSaver.cs116
-rw-r--r--MediaBrowser.XbmcMetadata/Savers/BaseNfoSaver.cs (renamed from MediaBrowser.XbmcMetadata/Savers/XmlSaverHelpers.cs)497
-rw-r--r--MediaBrowser.XbmcMetadata/Savers/EpisodeNfoSaver.cs122
-rw-r--r--MediaBrowser.XbmcMetadata/Savers/EpisodeXmlSaver.cs141
-rw-r--r--MediaBrowser.XbmcMetadata/Savers/MovieNfoSaver.cs (renamed from MediaBrowser.XbmcMetadata/Savers/MovieXmlSaver.cs)98
-rw-r--r--MediaBrowser.XbmcMetadata/Savers/SeasonNfoSaver.cs63
-rw-r--r--MediaBrowser.XbmcMetadata/Savers/SeasonXmlSaver.cs86
-rw-r--r--MediaBrowser.XbmcMetadata/Savers/SeriesNfoSaver.cs113
-rw-r--r--MediaBrowser.XbmcMetadata/Savers/SeriesXmlSaver.cs122
14 files changed, 844 insertions, 877 deletions
diff --git a/MediaBrowser.XbmcMetadata/MediaBrowser.XbmcMetadata.csproj b/MediaBrowser.XbmcMetadata/MediaBrowser.XbmcMetadata.csproj
index a3928d7742..972595b94f 100644
--- a/MediaBrowser.XbmcMetadata/MediaBrowser.XbmcMetadata.csproj
+++ b/MediaBrowser.XbmcMetadata/MediaBrowser.XbmcMetadata.csproj
@@ -56,13 +56,13 @@
<Compile Include="Providers\MovieNfoProvider.cs" />
<Compile Include="Providers\SeasonNfoProvider.cs" />
<Compile Include="Providers\SeriesNfoProvider.cs" />
- <Compile Include="Savers\AlbumXmlSaver.cs" />
- <Compile Include="Savers\ArtistXmlSaver.cs" />
- <Compile Include="Savers\EpisodeXmlSaver.cs" />
- <Compile Include="Savers\MovieXmlSaver.cs" />
- <Compile Include="Savers\SeasonXmlSaver.cs" />
- <Compile Include="Savers\SeriesXmlSaver.cs" />
- <Compile Include="Savers\XmlSaverHelpers.cs" />
+ <Compile Include="Savers\AlbumNfoSaver.cs" />
+ <Compile Include="Savers\ArtistNfoSaver.cs" />
+ <Compile Include="Savers\BaseNfoSaver.cs" />
+ <Compile Include="Savers\EpisodeNfoSaver.cs" />
+ <Compile Include="Savers\MovieNfoSaver.cs" />
+ <Compile Include="Savers\SeasonNfoSaver.cs" />
+ <Compile Include="Savers\SeriesNfoSaver.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\MediaBrowser.Common\MediaBrowser.Common.csproj">
diff --git a/MediaBrowser.XbmcMetadata/Parsers/BaseNfoParser.cs b/MediaBrowser.XbmcMetadata/Parsers/BaseNfoParser.cs
index 49851f42a7..6e31b01783 100644
--- a/MediaBrowser.XbmcMetadata/Parsers/BaseNfoParser.cs
+++ b/MediaBrowser.XbmcMetadata/Parsers/BaseNfoParser.cs
@@ -11,6 +11,7 @@ using System.Linq;
using System.Text;
using System.Threading;
using System.Xml;
+using MediaBrowser.XbmcMetadata.Savers;
namespace MediaBrowser.XbmcMetadata.Parsers
{
@@ -63,8 +64,7 @@ namespace MediaBrowser.XbmcMetadata.Parsers
ValidationType = ValidationType.None
};
- //Fetch(item, metadataFile, settings, Encoding.GetEncoding("ISO-8859-1"), cancellationToken);
- Fetch(item, metadataFile, settings, Encoding.UTF8, cancellationToken);
+ Fetch(item, metadataFile, settings, cancellationToken);
}
/// <summary>
@@ -73,11 +73,10 @@ namespace MediaBrowser.XbmcMetadata.Parsers
/// <param name="item">The item.</param>
/// <param name="metadataFile">The metadata file.</param>
/// <param name="settings">The settings.</param>
- /// <param name="encoding">The encoding.</param>
/// <param name="cancellationToken">The cancellation token.</param>
- private void Fetch(T item, string metadataFile, XmlReaderSettings settings, Encoding encoding, CancellationToken cancellationToken)
+ private void Fetch(T item, string metadataFile, XmlReaderSettings settings, CancellationToken cancellationToken)
{
- using (var streamReader = new StreamReader(metadataFile))
+ using (var streamReader = BaseNfoSaver.GetStreamReader(metadataFile))
{
// Use XmlReader for best performance
using (var reader = XmlReader.Create(streamReader, settings))
diff --git a/MediaBrowser.XbmcMetadata/Savers/AlbumNfoSaver.cs b/MediaBrowser.XbmcMetadata/Savers/AlbumNfoSaver.cs
new file mode 100644
index 0000000000..800cb8e108
--- /dev/null
+++ b/MediaBrowser.XbmcMetadata/Savers/AlbumNfoSaver.cs
@@ -0,0 +1,112 @@
+using MediaBrowser.Common.IO;
+using MediaBrowser.Controller.Configuration;
+using MediaBrowser.Controller.Entities;
+using MediaBrowser.Controller.Entities.Audio;
+using MediaBrowser.Controller.Library;
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.IO;
+using System.Linq;
+using System.Xml;
+
+namespace MediaBrowser.XbmcMetadata.Savers
+{
+ public class AlbumNfoSaver : BaseNfoSaver
+ {
+ public AlbumNfoSaver(IFileSystem fileSystem, IServerConfigurationManager configurationManager, ILibraryManager libraryManager, IUserManager userManager, IUserDataManager userDataManager)
+ : base(fileSystem, configurationManager, libraryManager, userManager, userDataManager)
+ {
+ }
+
+ public override string GetSavePath(IHasMetadata item)
+ {
+ return Path.Combine(item.Path, "album.nfo");
+ }
+
+ protected override string GetRootElementName(IHasMetadata item)
+ {
+ return "album";
+ }
+
+ public override bool IsEnabledFor(IHasMetadata item, ItemUpdateType updateType)
+ {
+ if (!item.SupportsLocalMetadata)
+ {
+ return false;
+ }
+
+ return item is MusicAlbum && updateType >= ItemUpdateType.MetadataDownload;
+ }
+
+ protected override void WriteCustomElements(IHasMetadata item, XmlWriter writer)
+ {
+ var album = (MusicAlbum)item;
+
+ var tracks = album.Tracks
+ .ToList();
+
+ var artists = tracks
+ .SelectMany(i =>
+ {
+ var list = new List<string>();
+
+ if (!string.IsNullOrEmpty(i.AlbumArtist))
+ {
+ list.Add(i.AlbumArtist);
+ }
+ list.AddRange(i.Artists);
+
+ return list;
+ })
+ .Distinct(StringComparer.OrdinalIgnoreCase);
+
+ foreach (var artist in artists)
+ {
+ writer.WriteElementString("artist", artist);
+ }
+
+ AddTracks(tracks, writer);
+ }
+
+ private static readonly CultureInfo UsCulture = new CultureInfo("en-US");
+
+ private void AddTracks(IEnumerable<Audio> tracks, XmlWriter writer)
+ {
+ foreach (var track in tracks.OrderBy(i => i.ParentIndexNumber ?? 0).ThenBy(i => i.IndexNumber ?? 0))
+ {
+ writer.WriteStartElement("track");
+
+ if (track.IndexNumber.HasValue)
+ {
+ writer.WriteElementString("position", track.IndexNumber.Value.ToString(UsCulture));
+ }
+
+ if (!string.IsNullOrEmpty(track.Name))
+ {
+ writer.WriteElementString("title", track.Name);
+ }
+
+ if (track.RunTimeTicks.HasValue)
+ {
+ var time = TimeSpan.FromTicks(track.RunTimeTicks.Value).ToString(@"mm\:ss");
+
+ writer.WriteElementString("duration", time);
+ }
+
+ writer.WriteEndElement();
+ }
+ }
+
+ protected override List<string> GetTagsUsed()
+ {
+ var list = new List<string>
+ {
+ "track",
+ "artist"
+ };
+
+ return list;
+ }
+ }
+}
diff --git a/MediaBrowser.XbmcMetadata/Savers/AlbumXmlSaver.cs b/MediaBrowser.XbmcMetadata/Savers/AlbumXmlSaver.cs
deleted file mode 100644
index 252ca62f23..0000000000
--- a/MediaBrowser.XbmcMetadata/Savers/AlbumXmlSaver.cs
+++ /dev/null
@@ -1,134 +0,0 @@
-using MediaBrowser.Common.IO;
-using MediaBrowser.Controller.Configuration;
-using MediaBrowser.Controller.Entities;
-using MediaBrowser.Controller.Entities.Audio;
-using MediaBrowser.Controller.Library;
-using MediaBrowser.Model.Entities;
-using System;
-using System.Collections.Generic;
-using System.Globalization;
-using System.IO;
-using System.Linq;
-using System.Security;
-using System.Text;
-using System.Threading;
-
-namespace MediaBrowser.XbmcMetadata.Savers
-{
- public class AlbumXmlSaver : IMetadataFileSaver
- {
- private readonly ILibraryManager _libraryManager;
- private readonly IUserManager _userManager;
- private readonly IUserDataManager _userDataRepo;
-
- private readonly IFileSystem _fileSystem;
- private readonly IServerConfigurationManager _config;
-
- public AlbumXmlSaver(ILibraryManager libraryManager, IUserManager userManager, IUserDataManager userDataRepo, IFileSystem fileSystem, IServerConfigurationManager config)
- {
- _libraryManager = libraryManager;
- _userManager = userManager;
- _userDataRepo = userDataRepo;
- _fileSystem = fileSystem;
- _config = config;
- }
-
- public string Name
- {
- get
- {
- return "Xbmc Nfo";
- }
- }
-
- public string GetSavePath(IHasMetadata item)
- {
- return Path.Combine(item.Path, "album.nfo");
- }
-
- public void Save(IHasMetadata item, CancellationToken cancellationToken)
- {
- var album = (MusicAlbum)item;
-
- var builder = new StringBuilder();
-
- builder.Append("<album>");
-
- XmlSaverHelpers.AddCommonNodes(album, builder, _libraryManager, _userManager, _userDataRepo, _fileSystem, _config);
-
- var tracks = album.Tracks
- .ToList();
-
- var artists = tracks
- .SelectMany(i =>
- {
- var list = new List<string>();
-
- if (!string.IsNullOrEmpty(i.AlbumArtist))
- {
- list.Add(i.AlbumArtist);
- }
- list.AddRange(i.Artists);
-
- return list;
- })
- .Distinct(StringComparer.OrdinalIgnoreCase);
-
- foreach (var artist in artists)
- {
- builder.Append("<artist>" + SecurityElement.Escape(artist) + "</artist>");
- }
-
- AddTracks(tracks, builder);
-
- builder.Append("</album>");
-
- var xmlFilePath = GetSavePath(item);
-
- XmlSaverHelpers.Save(builder, xmlFilePath, new List<string>
- {
- "track",
- "artist"
- });
- }
-
- public bool IsEnabledFor(IHasMetadata item, ItemUpdateType updateType)
- {
- if (!item.SupportsLocalMetadata)
- {
- return false;
- }
-
- return item is MusicAlbum && updateType >= ItemUpdateType.MetadataDownload;
- }
-
- private static readonly CultureInfo UsCulture = new CultureInfo("en-US");
-
- private void AddTracks(IEnumerable<Audio> tracks, StringBuilder builder)
- {
- foreach (var track in tracks.OrderBy(i => i.ParentIndexNumber ?? 0).ThenBy(i => i.IndexNumber ?? 0))
- {
- builder.Append("<track>");
-
- if (track.IndexNumber.HasValue)
- {
- builder.Append("<position>" + SecurityElement.Escape(track.IndexNumber.Value.ToString(UsCulture)) + "</position>");
- }
-
- if (!string.IsNullOrEmpty(track.Name))
- {
- builder.Append("<title>" + SecurityElement.Escape(track.Name) + "</title>");
- }
-
- if (track.RunTimeTicks.HasValue)
- {
- var time = TimeSpan.FromTicks(track.RunTimeTicks.Value).ToString(@"mm\:ss");
-
- builder.Append("<duration>" + SecurityElement.Escape(time) + "</duration>");
- }
-
- builder.Append("</track>");
- }
- }
- }
-}
diff --git a/MediaBrowser.XbmcMetadata/Savers/ArtistNfoSaver.cs b/MediaBrowser.XbmcMetadata/Savers/ArtistNfoSaver.cs
new file mode 100644
index 0000000000..a76eaef839
--- /dev/null
+++ b/MediaBrowser.XbmcMetadata/Savers/ArtistNfoSaver.cs
@@ -0,0 +1,94 @@
+using MediaBrowser.Common.IO;
+using MediaBrowser.Controller.Configuration;
+using MediaBrowser.Controller.Entities;
+using MediaBrowser.Controller.Entities.Audio;
+using MediaBrowser.Controller.Library;
+using MediaBrowser.XbmcMetadata.Configuration;
+using System.Collections.Generic;
+using System.Globalization;
+using System.IO;
+using System.Linq;
+using System.Xml;
+
+namespace MediaBrowser.XbmcMetadata.Savers
+{
+ public class ArtistNfoSaver : BaseNfoSaver
+ {
+ public ArtistNfoSaver(IFileSystem fileSystem, IServerConfigurationManager configurationManager, ILibraryManager libraryManager, IUserManager userManager, IUserDataManager userDataManager)
+ : base(fileSystem, configurationManager, libraryManager, userManager, userDataManager)
+ {
+ }
+
+ public override string GetSavePath(IHasMetadata item)
+ {
+ return Path.Combine(item.Path, "artist.nfo");
+ }
+
+ protected override string GetRootElementName(IHasMetadata item)
+ {
+ return "artist";
+ }
+
+ public override bool IsEnabledFor(IHasMetadata item, ItemUpdateType updateType)
+ {
+ if (!item.SupportsLocalMetadata)
+ {
+ return false;
+ }
+
+ return item is MusicArtist && updateType >= ItemUpdateType.MetadataDownload;
+ }
+
+ protected override void WriteCustomElements(IHasMetadata item, XmlWriter writer)
+ {
+ var artist = (MusicArtist)item;
+
+ if (artist.EndDate.HasValue)
+ {
+ var formatString = ConfigurationManager.GetNfoConfiguration().ReleaseDateFormat;
+
+ writer.WriteElementString("disbanded", artist.EndDate.Value.ToString(formatString));
+ }
+
+ var albums = artist
+ .RecursiveChildren
+ .OfType<MusicAlbum>()
+ .ToList();
+
+ AddAlbums(albums, writer);
+ }
+
+ private static readonly CultureInfo UsCulture = new CultureInfo("en-US");
+
+ private void AddAlbums(IEnumerable<MusicAlbum> albums, XmlWriter writer)
+ {
+ foreach (var album in albums)
+ {
+ writer.WriteStartElement("album");
+
+ if (!string.IsNullOrEmpty(album.Name))
+ {
+ writer.WriteElementString("title", album.Name);
+ }
+
+ if (album.ProductionYear.HasValue)
+ {
+ writer.WriteElementString("year", album.ProductionYear.Value.ToString(UsCulture));
+ }
+
+ writer.WriteEndElement();
+ }
+ }
+
+ protected override List<string> GetTagsUsed()
+ {
+ var list = new List<string>
+ {
+ "album",
+ "disbanded"
+ };
+
+ return list;
+ }
+ }
+} \ No newline at end of file
diff --git a/MediaBrowser.XbmcMetadata/Savers/ArtistXmlSaver.cs b/MediaBrowser.XbmcMetadata/Savers/ArtistXmlSaver.cs
deleted file mode 100644
index 937d702d34..0000000000
--- a/MediaBrowser.XbmcMetadata/Savers/ArtistXmlSaver.cs
+++ /dev/null
@@ -1,116 +0,0 @@
-using MediaBrowser.Common.IO;
-using MediaBrowser.Controller.Configuration;
-using MediaBrowser.Controller.Entities;
-using MediaBrowser.Controller.Entities.Audio;
-using MediaBrowser.Controller.Library;
-using MediaBrowser.Model.Entities;
-using MediaBrowser.XbmcMetadata.Configuration;
-using System.Collections.Generic;
-using System.Globalization;
-using System.IO;
-using System.Linq;
-using System.Security;
-using System.Text;
-using System.Threading;
-
-namespace MediaBrowser.XbmcMetadata.Savers
-{
- public class ArtistXmlSaver : IMetadataFileSaver
- {
- private readonly ILibraryManager _libraryManager;
- private readonly IUserManager _userManager;
- private readonly IUserDataManager _userDataRepo;
-
- private readonly IFileSystem _fileSystem;
- private readonly IServerConfigurationManager _config;
-
- private static readonly CultureInfo UsCulture = new CultureInfo("en-US");
-
- public ArtistXmlSaver(ILibraryManager libraryManager, IUserManager userManager, IUserDataManager userDataRepo, IFileSystem fileSystem, IServerConfigurationManager config)
- {
- _libraryManager = libraryManager;
- _userManager = userManager;
- _userDataRepo = userDataRepo;
- _fileSystem = fileSystem;
- _config = config;
- }
-
- public string GetSavePath(IHasMetadata item)
- {
- return Path.Combine(item.Path, "artist.nfo");
- }
-
- public string Name
- {
- get
- {
- return "Xbmc Nfo";
- }
- }
-
- public void Save(IHasMetadata item, CancellationToken cancellationToken)
- {
- var artist = (MusicArtist)item;
-
- var builder = new StringBuilder();
-
- builder.Append("<artist>");
-
- XmlSaverHelpers.AddCommonNodes(artist, builder, _libraryManager, _userManager, _userDataRepo, _fileSystem, _config);
-
- if (artist.EndDate.HasValue)
- {
- var formatString = _config.GetNfoConfiguration().ReleaseDateFormat;
-
- builder.Append("<disbanded>" + SecurityElement.Escape(artist.EndDate.Value.ToString(formatString)) + "</disbanded>");
- }
-
- var albums = artist
- .RecursiveChildren
- .OfType<MusicAlbum>()
- .ToList();
-
- AddAlbums(albums, builder);
-
- builder.Append("</artist>");
-
- var xmlFilePath = GetSavePath(item);
-
- XmlSaverHelpers.Save(builder, xmlFilePath, new List<string>
- {
- "album",
- "disbanded"
- });
- }
-
- public bool IsEnabledFor(IHasMetadata item, ItemUpdateType updateType)
- {
- if (!item.SupportsLocalMetadata)
- {
- return false;
- }
-
- return item is MusicArtist && updateType >= ItemUpdateType.MetadataDownload;
- }
-
- private void AddAlbums(IEnumerable<MusicAlbum> albums, StringBuilder builder)
- {
- foreach (var album in albums)
- {
- builder.Append("<album>");
-
- if (!string.IsNullOrEmpty(album.Name))
- {
- builder.Append("<title>" + SecurityElement.Escape(album.Name) + "</title>");
- }
-
- if (album.ProductionYear.HasValue)
- {
- builder.Append("<year>" + SecurityElement.Escape(album.ProductionYear.Value.ToString(UsCulture)) + "</year>");
- }
-
- builder.Append("</album>");
- }
- }
- }
-}
diff --git a/MediaBrowser.XbmcMetadata/Savers/XmlSaverHelpers.cs b/MediaBrowser.XbmcMetadata/Savers/BaseNfoSaver.cs
index 7111a429ab..cb9137ad09 100644
--- a/MediaBrowser.XbmcMetadata/Savers/XmlSaverHelpers.cs
+++ b/MediaBrowser.XbmcMetadata/Savers/BaseNfoSaver.cs
@@ -15,13 +15,13 @@ using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
-using System.Security;
using System.Text;
+using System.Threading;
using System.Xml;
namespace MediaBrowser.XbmcMetadata.Savers
{
- public static class XmlSaverHelpers
+ public abstract class BaseNfoSaver : IMetadataFileSaver
{
private static readonly CultureInfo UsCulture = new CultureInfo("en-US");
@@ -98,34 +98,78 @@ namespace MediaBrowser.XbmcMetadata.Savers
}.ToDictionary(i => i, StringComparer.OrdinalIgnoreCase);
+ protected BaseNfoSaver(IFileSystem fileSystem, IServerConfigurationManager configurationManager, ILibraryManager libraryManager, IUserManager userManager, IUserDataManager userDataManager)
+ {
+ 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; }
+
+ public string Name
+ {
+ get
+ {
+ return "Xbmc Nfo";
+ }
+ }
+
+ /// <summary>
+ /// Gets the save path.
+ /// </summary>
+ /// <param name="item">The item.</param>
+ /// <returns>System.String.</returns>
+ public abstract string GetSavePath(IHasMetadata item);
+
+ /// <summary>
+ /// Gets the name of the root element.
+ /// </summary>
+ /// <param name="item">The item.</param>
+ /// <returns>System.String.</returns>
+ protected abstract string GetRootElementName(IHasMetadata item);
+
/// <summary>
- /// Saves the specified XML.
+ /// Determines whether [is enabled for] [the specified item].
/// </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)
+ /// <param name="item">The item.</param>
+ /// <param name="updateType">Type of the update.</param>
+ /// <returns><c>true</c> if [is enabled for] [the specified item]; otherwise, <c>false</c>.</returns>
+ public abstract bool IsEnabledFor(IHasMetadata item, ItemUpdateType updateType);
+
+ protected virtual List<string> GetTagsUsed()
+ {
+ return new List<string>();
+ }
+
+ public void Save(IHasMetadata item, CancellationToken cancellationToken)
{
- if (File.Exists(path))
+ var path = GetSavePath(item);
+
+ using (var memoryStream = new MemoryStream())
{
- var tags = xmlTagsUsed.ToList();
+ Save(item, memoryStream, path);
- var position = xml.ToString().LastIndexOf("</", StringComparison.OrdinalIgnoreCase);
- xml.Insert(position, GetCustomTags(path, tags));
- }
+ memoryStream.Position = 0;
- var xmlDocument = new XmlDocument();
- xmlDocument.LoadXml(xml.ToString());
+ cancellationToken.ThrowIfCancellationRequested();
- //Add the new node to the document.
- xmlDocument.InsertBefore(xmlDocument.CreateXmlDeclaration("1.0", "UTF-8", "yes"), xmlDocument.DocumentElement);
+ SaveToFile(memoryStream, path);
+ }
+ }
- Directory.CreateDirectory(Path.GetDirectoryName(path));
+ private void SaveToFile(Stream stream, string path)
+ {
+ var file = new FileInfo(path);
var wasHidden = false;
- var file = new FileInfo(path);
-
// This will fail if the file is hidden
if (file.Exists)
{
@@ -139,10 +183,7 @@ namespace MediaBrowser.XbmcMetadata.Savers
using (var filestream = new FileStream(path, FileMode.Create, FileAccess.Write, FileShare.Read))
{
- using (var streamWriter = new StreamWriter(filestream, Encoding.UTF8))
- {
- xmlDocument.Save(streamWriter);
- }
+ stream.CopyTo(filestream);
}
if (wasHidden)
@@ -154,130 +195,136 @@ namespace MediaBrowser.XbmcMetadata.Savers
}
}
- /// <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)
+ private void Save(IHasMetadata item, Stream stream, string xmlPath)
{
- var settings = new XmlReaderSettings
+ var settings = new XmlWriterSettings
{
- CheckCharacters = false,
- IgnoreProcessingInstructions = true,
- IgnoreComments = true,
- ValidationType = ValidationType.None
+ Indent = true,
+ Encoding = Encoding.UTF8,
+ CloseOutput = false
};
- var builder = new StringBuilder();
-
- using (var streamReader = new StreamReader(path, Encoding.UTF8))
+ using (XmlWriter writer = XmlWriter.Create(stream, settings))
{
- // Use XmlReader for best performance
- using (var reader = XmlReader.Create(streamReader, settings))
+ var root = GetRootElementName(item);
+
+ writer.WriteStartDocument(true);
+
+ writer.WriteStartElement(root);
+
+ var baseItem = item as BaseItem;
+
+ if (baseItem != null)
{
- reader.MoveToContent();
+ AddCommonNodes(baseItem, writer, LibraryManager, UserManager, UserDataManager, FileSystem, ConfigurationManager);
+ }
- // Loop through each element
- while (reader.Read())
- {
- if (reader.NodeType == XmlNodeType.Element)
- {
- var name = reader.Name;
+ WriteCustomElements(item, writer);
- if (!CommonTags.ContainsKey(name) && !xmlTagsUsed.Contains(name, StringComparer.OrdinalIgnoreCase))
- {
- builder.AppendLine(reader.ReadOuterXml());
- }
- else
- {
- reader.Skip();
- }
- }
- }
+ var hasMediaSources = baseItem as IHasMediaSources;
+
+ if (hasMediaSources != null)
+ {
+ AddMediaInfo(hasMediaSources, writer);
}
- }
- return builder.ToString();
+ var tagsUsed = GetTagsUsed();
+
+ try
+ {
+ AddCustomTags(xmlPath, tagsUsed, writer);
+ }
+ catch (FileNotFoundException)
+ {
+
+ }
+
+ writer.WriteEndElement();
+
+ writer.WriteEndDocument();
+ }
}
- public static void AddMediaInfo<T>(T item, StringBuilder builder)
- where T : BaseItem, IHasMediaSources
+ protected abstract void WriteCustomElements(IHasMetadata item, XmlWriter writer);
+
+ public static void AddMediaInfo<T>(T item, XmlWriter writer)
+ where T : IHasMediaSources
{
- builder.Append("<fileinfo>");
- builder.Append("<streamdetails>");
+ writer.WriteStartElement("fileinfo");
+ writer.WriteStartElement("streamdetails");
- foreach (var stream in item.GetMediaSources(false).First().MediaStreams)
+ var mediaSource = item.GetMediaSources(false).First();
+
+ foreach (var stream in mediaSource.MediaStreams)
{
- builder.Append("<" + stream.Type.ToString().ToLower() + ">");
+ writer.WriteStartElement(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>");
+ writer.WriteElementString("codec", stream.Codec);
+ writer.WriteElementString("micodec", stream.Codec);
}
if (stream.BitRate.HasValue)
{
- builder.Append("<bitrate>" + stream.BitRate.Value.ToString(UsCulture) + "</bitrate>");
+ writer.WriteElementString("bitrate", stream.BitRate.Value.ToString(UsCulture));
}
if (stream.Width.HasValue)
{
- builder.Append("<width>" + stream.Width.Value.ToString(UsCulture) + "</width>");
+ writer.WriteElementString("width", stream.Width.Value.ToString(UsCulture));
}
if (stream.Height.HasValue)
{
- builder.Append("<height>" + stream.Height.Value.ToString(UsCulture) + "</height>");
+ writer.WriteElementString("height", stream.Height.Value.ToString(UsCulture));
}
if (!string.IsNullOrEmpty(stream.AspectRatio))
{
- builder.Append("<aspect>" + SecurityElement.Escape(stream.AspectRatio) + "</aspect>");
- builder.Append("<aspectratio>" + SecurityElement.Escape(stream.AspectRatio) + "</aspectratio>");
+ writer.WriteElementString("aspect", stream.AspectRatio);
+ writer.WriteElementString("aspectratio", stream.AspectRatio);
}
var framerate = stream.AverageFrameRate ?? stream.RealFrameRate;
if (framerate.HasValue)
{
- builder.Append("<framerate>" + framerate.Value.ToString(UsCulture) + "</framerate>");
+ writer.WriteElementString("framerate", framerate.Value.ToString(UsCulture));
}
if (!string.IsNullOrEmpty(stream.Language))
{
- builder.Append("<language>" + SecurityElement.Escape(stream.Language) + "</language>");
+ writer.WriteElementString("language", stream.Language);
}
var scanType = stream.IsInterlaced ? "interlaced" : "progressive";
if (!string.IsNullOrEmpty(scanType))
{
- builder.Append("<scantype>" + SecurityElement.Escape(scanType) + "</scantype>");
+ writer.WriteElementString("scantype", scanType);
}
if (stream.Channels.HasValue)
{
- builder.Append("<channels>" + stream.Channels.Value.ToString(UsCulture) + "</channels>");
+ writer.WriteElementString("channels", stream.Channels.Value.ToString(UsCulture));
}
if (stream.SampleRate.HasValue)
{
- builder.Append("<samplingrate>" + stream.SampleRate.Value.ToString(UsCulture) + "</samplingrate>");
+ writer.WriteElementString("samplingrate", stream.SampleRate.Value.ToString(UsCulture));
}
- builder.Append("<default>" + SecurityElement.Escape(stream.IsDefault.ToString()) + "</default>");
- builder.Append("<forced>" + SecurityElement.Escape(stream.IsForced.ToString()) + "</forced>");
+ writer.WriteElementString("default", stream.IsDefault.ToString());
+ writer.WriteElementString("forced", stream.IsForced.ToString());
if (stream.Type == MediaStreamType.Video)
{
- if (item.RunTimeTicks.HasValue)
+ if (mediaSource.RunTimeTicks.HasValue)
{
- var timespan = TimeSpan.FromTicks(item.RunTimeTicks.Value);
+ var timespan = TimeSpan.FromTicks(mediaSource.RunTimeTicks.Value);
- builder.Append("<duration>" + Convert.ToInt32(timespan.TotalMinutes).ToString(UsCulture) + "</duration>");
- builder.Append("<durationinseconds>" + Convert.ToInt32(timespan.TotalSeconds).ToString(UsCulture) + "</durationinseconds>");
+ writer.WriteElementString("duration", Convert.ToInt32(timespan.TotalMinutes).ToString(UsCulture));
+ writer.WriteElementString("durationinseconds", Convert.ToInt32(timespan.TotalSeconds).ToString(UsCulture));
}
var video = item as Video;
@@ -291,34 +338,34 @@ namespace MediaBrowser.XbmcMetadata.Savers
switch (video.Video3DFormat.Value)
{
case Video3DFormat.FullSideBySide:
- builder.Append("<format3d>FSBS</format3d>");
+ writer.WriteElementString("format3d", "FSBS");
break;
case Video3DFormat.FullTopAndBottom:
- builder.Append("<format3d>FTAB</format3d>");
+ writer.WriteElementString("format3d", "FTAB");
break;
case Video3DFormat.HalfSideBySide:
- builder.Append("<format3d>HSBS</format3d>");
+ writer.WriteElementString("format3d", "HSBS");
break;
case Video3DFormat.HalfTopAndBottom:
- builder.Append("<format3d>HTAB</format3d>");
+ writer.WriteElementString("format3d", "HTAB");
break;
}
}
}
}
- builder.Append("</" + stream.Type.ToString().ToLower() + ">");
+ writer.WriteEndElement();
}
- builder.Append("</streamdetails>");
- builder.Append("</fileinfo>");
+ writer.WriteEndElement();
+ writer.WriteEndElement();
}
/// <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)
+ public static void AddCommonNodes(BaseItem item, XmlWriter writer, ILibraryManager libraryManager, IUserManager userManager, IUserDataManager userDataRepo, IFileSystem fileSystem, IServerConfigurationManager config)
{
var overview = (item.Overview ?? string.Empty)
.StripHtml()
@@ -328,15 +375,15 @@ namespace MediaBrowser.XbmcMetadata.Savers
if (item is MusicArtist)
{
- builder.Append("<biography><![CDATA[" + overview + "]]></biography>");
+ writer.WriteElementString("biography", overview);
}
else if (item is MusicAlbum)
{
- builder.Append("<review><![CDATA[" + overview + "]]></review>");
+ writer.WriteElementString("review", overview);
}
else
{
- builder.Append("<plot><![CDATA[" + overview + "]]></plot>");
+ writer.WriteElementString("plot", overview);
}
var hasShortOverview = item as IHasShortOverview;
@@ -346,30 +393,34 @@ namespace MediaBrowser.XbmcMetadata.Savers
.StripHtml()
.Replace("&quot;", "'");
- builder.Append("<outline><![CDATA[" + outline + "]]></outline>");
+ writer.WriteElementString("outline", outline);
}
else
{
- builder.Append("<outline><![CDATA[" + overview + "]]></outline>");
+ writer.WriteElementString("outline", overview);
+ }
+
+ if (!string.IsNullOrWhiteSpace(item.CustomRating))
+ {
+ writer.WriteElementString("customrating", item.CustomRating);
}
- builder.Append("<customrating>" + SecurityElement.Escape(item.CustomRating ?? string.Empty) + "</customrating>");
- builder.Append("<lockdata>" + item.IsLocked.ToString().ToLower() + "</lockdata>");
+ writer.WriteElementString("lockdata", item.IsLocked.ToString().ToLower());
if (item.LockedFields.Count > 0)
{
- builder.Append("<lockedfields>" + string.Join("|", item.LockedFields.Select(i => i.ToString()).ToArray()) + "</lockedfields>");
+ writer.WriteElementString("lockedfields", string.Join("|", item.LockedFields.Select(i => i.ToString()).ToArray()));
}
-
+
if (!string.IsNullOrEmpty(item.DisplayMediaType))
{
- builder.Append("<type>" + SecurityElement.Escape(item.DisplayMediaType) + "</type>");
+ writer.WriteElementString("type", item.DisplayMediaType);
}
- builder.Append("<dateadded>" + SecurityElement.Escape(item.DateCreated.ToString("yyyy-MM-dd HH:mm:ss")) + "</dateadded>");
+ writer.WriteElementString("dateadded", item.DateCreated.ToString("yyyy-MM-dd HH:mm:ss"));
- builder.Append("<title>" + SecurityElement.Escape(item.Name ?? string.Empty) + "</title>");
- builder.Append("<originaltitle>" + SecurityElement.Escape(item.Name ?? string.Empty) + "</originaltitle>");
+ writer.WriteElementString("title", item.Name ?? string.Empty);
+ writer.WriteElementString("originaltitle", item.Name ?? string.Empty);
var directors = item.People
.Where(i => IsPersonType(i, PersonType.Director))
@@ -378,7 +429,7 @@ namespace MediaBrowser.XbmcMetadata.Savers
foreach (var person in directors)
{
- builder.Append("<director>" + SecurityElement.Escape(person) + "</director>");
+ writer.WriteElementString("director", person);
}
var writers = item.People
@@ -389,12 +440,12 @@ namespace MediaBrowser.XbmcMetadata.Savers
foreach (var person in writers)
{
- builder.Append("<writer>" + SecurityElement.Escape(person) + "</writer>");
+ writer.WriteElementString("writer", person);
}
foreach (var person in writers)
{
- builder.Append("<credits>" + SecurityElement.Escape(person) + "</credits>");
+ writer.WriteElementString("credits", person);
}
var hasTrailer = item as IHasTrailers;
@@ -402,33 +453,33 @@ namespace MediaBrowser.XbmcMetadata.Savers
{
foreach (var trailer in hasTrailer.RemoteTrailers)
{
- builder.Append("<trailer>" + SecurityElement.Escape(GetOutputTrailerUrl(trailer.Url)) + "</trailer>");
+ writer.WriteElementString("trailer", GetOutputTrailerUrl(trailer.Url));
}
}
if (item.CommunityRating.HasValue)
{
- builder.Append("<rating>" + SecurityElement.Escape(item.CommunityRating.Value.ToString(UsCulture)) + "</rating>");
+ writer.WriteElementString("rating", item.CommunityRating.Value.ToString(UsCulture));
}
if (item.ProductionYear.HasValue)
{
- builder.Append("<year>" + SecurityElement.Escape(item.ProductionYear.Value.ToString(UsCulture)) + "</year>");
+ writer.WriteElementString("year", item.ProductionYear.Value.ToString(UsCulture));
}
if (!string.IsNullOrEmpty(item.ForcedSortName))
{
- builder.Append("<sorttitle>" + SecurityElement.Escape(item.ForcedSortName) + "</sorttitle>");
+ writer.WriteElementString("sorttitle", item.ForcedSortName);
}
if (!string.IsNullOrEmpty(item.OfficialRating))
{
- builder.Append("<mpaa>" + SecurityElement.Escape(item.OfficialRating) + "</mpaa>");
+ writer.WriteElementString("mpaa", item.OfficialRating);
}
if (!string.IsNullOrEmpty(item.OfficialRatingDescription))
{
- builder.Append("<mpaadescription>" + SecurityElement.Escape(item.OfficialRatingDescription) + "</mpaadescription>");
+ writer.WriteElementString("mpaadescription", item.OfficialRatingDescription);
}
var hasAspectRatio = item as IHasAspectRatio;
@@ -436,27 +487,27 @@ namespace MediaBrowser.XbmcMetadata.Savers
{
if (!string.IsNullOrEmpty(hasAspectRatio.AspectRatio))
{
- builder.Append("<aspectratio>" + SecurityElement.Escape(hasAspectRatio.AspectRatio) + "</aspectratio>");
+ writer.WriteElementString("aspectratio", hasAspectRatio.AspectRatio);
}
}
if (!string.IsNullOrEmpty(item.HomePageUrl))
{
- builder.Append("<website>" + SecurityElement.Escape(item.HomePageUrl) + "</website>");
+ writer.WriteElementString("website", item.HomePageUrl);
}
var rt = item.GetProviderId(MetadataProviders.RottenTomatoes);
if (!string.IsNullOrEmpty(rt))
{
- builder.Append("<rottentomatoesid>" + SecurityElement.Escape(rt) + "</rottentomatoesid>");
+ writer.WriteElementString("rottentomatoesid", rt);
}
var tmdbCollection = item.GetProviderId(MetadataProviders.TmdbCollection);
if (!string.IsNullOrEmpty(tmdbCollection))
{
- builder.Append("<collectionnumber>" + SecurityElement.Escape(tmdbCollection) + "</collectionnumber>");
+ writer.WriteElementString("collectionnumber", tmdbCollection);
}
var imdb = item.GetProviderId(MetadataProviders.Imdb);
@@ -464,11 +515,11 @@ namespace MediaBrowser.XbmcMetadata.Savers
{
if (item is Series)
{
- builder.Append("<imdb_id>" + SecurityElement.Escape(imdb) + "</imdb_id>");
+ writer.WriteElementString("imdb_id", imdb);
}
else
{
- builder.Append("<imdbid>" + SecurityElement.Escape(imdb) + "</imdbid>");
+ writer.WriteElementString("imdbid", imdb);
}
}
@@ -478,20 +529,20 @@ namespace MediaBrowser.XbmcMetadata.Savers
var tvdb = item.GetProviderId(MetadataProviders.Tvdb);
if (!string.IsNullOrEmpty(tvdb))
{
- builder.Append("<tvdbid>" + SecurityElement.Escape(tvdb) + "</tvdbid>");
+ writer.WriteElementString("tvdbid", tvdb);
}
}
var tmdb = item.GetProviderId(MetadataProviders.Tmdb);
if (!string.IsNullOrEmpty(tmdb))
{
- builder.Append("<tmdbid>" + SecurityElement.Escape(tmdb) + "</tmdbid>");
+ writer.WriteElementString("tmdbid", tmdb);
}
var tvcom = item.GetProviderId(MetadataProviders.Tvcom);
if (!string.IsNullOrEmpty(tvcom))
{
- builder.Append("<tvcomid>" + SecurityElement.Escape(tvcom) + "</tvcomid>");
+ writer.WriteElementString("tvcomid", tvcom);
}
var hasLanguage = item as IHasPreferredMetadataLanguage;
@@ -499,7 +550,7 @@ namespace MediaBrowser.XbmcMetadata.Savers
{
if (!string.IsNullOrEmpty(hasLanguage.PreferredMetadataLanguage))
{
- builder.Append("<language>" + SecurityElement.Escape(hasLanguage.PreferredMetadataLanguage) + "</language>");
+ writer.WriteElementString("language", hasLanguage.PreferredMetadataLanguage);
}
}
@@ -509,12 +560,12 @@ namespace MediaBrowser.XbmcMetadata.Savers
if (item is MusicArtist)
{
- builder.Append("<formed>" + SecurityElement.Escape(item.PremiereDate.Value.ToString(formatString)) + "</formed>");
+ writer.WriteElementString("formed", item.PremiereDate.Value.ToString(formatString));
}
else
{
- builder.Append("<premiered>" + SecurityElement.Escape(item.PremiereDate.Value.ToString(formatString)) + "</premiered>");
- builder.Append("<releasedate>" + SecurityElement.Escape(item.PremiereDate.Value.ToString(formatString)) + "</releasedate>");
+ writer.WriteElementString("premiered", item.PremiereDate.Value.ToString(formatString));
+ writer.WriteElementString("releasedate", item.PremiereDate.Value.ToString(formatString));
}
}
@@ -524,7 +575,7 @@ namespace MediaBrowser.XbmcMetadata.Savers
{
var formatString = options.ReleaseDateFormat;
- builder.Append("<enddate>" + SecurityElement.Escape(item.EndDate.Value.ToString(formatString)) + "</enddate>");
+ writer.WriteElementString("enddate", item.EndDate.Value.ToString(formatString));
}
}
@@ -534,12 +585,12 @@ namespace MediaBrowser.XbmcMetadata.Savers
{
if (hasCriticRating.CriticRating.HasValue)
{
- builder.Append("<criticrating>" + SecurityElement.Escape(hasCriticRating.CriticRating.Value.ToString(UsCulture)) + "</criticrating>");
+ writer.WriteElementString("criticrating", hasCriticRating.CriticRating.Value.ToString(UsCulture));
}
if (!string.IsNullOrEmpty(hasCriticRating.CriticRatingSummary))
{
- builder.Append("<criticratingsummary><![CDATA[" + hasCriticRating.CriticRatingSummary + "]]></criticratingsummary>");
+ writer.WriteElementString("criticratingsummary", hasCriticRating.CriticRatingSummary);
}
}
@@ -549,13 +600,13 @@ namespace MediaBrowser.XbmcMetadata.Savers
{
if (!string.IsNullOrEmpty(hasDisplayOrder.DisplayOrder))
{
- builder.Append("<displayorder>" + SecurityElement.Escape(hasDisplayOrder.DisplayOrder) + "</displayorder>");
+ writer.WriteElementString("displayorder", hasDisplayOrder.DisplayOrder);
}
}
if (item.VoteCount.HasValue)
{
- builder.Append("<votes>" + SecurityElement.Escape(item.VoteCount.Value.ToString(UsCulture)) + "</votes>");
+ writer.WriteElementString("votes", item.VoteCount.Value.ToString(UsCulture));
}
var hasBudget = item as IHasBudget;
@@ -563,19 +614,19 @@ namespace MediaBrowser.XbmcMetadata.Savers
{
if (hasBudget.Budget.HasValue)
{
- builder.Append("<budget>" + SecurityElement.Escape(hasBudget.Budget.Value.ToString(UsCulture)) + "</budget>");
+ writer.WriteElementString("budget", hasBudget.Budget.Value.ToString(UsCulture));
}
if (hasBudget.Revenue.HasValue)
{
- builder.Append("<revenue>" + SecurityElement.Escape(hasBudget.Revenue.Value.ToString(UsCulture)) + "</revenue>");
+ writer.WriteElementString("revenue", hasBudget.Revenue.Value.ToString(UsCulture));
}
}
var hasMetascore = item as IHasMetascore;
if (hasMetascore != null && hasMetascore.Metascore.HasValue)
{
- builder.Append("<metascore>" + SecurityElement.Escape(hasMetascore.Metascore.Value.ToString(UsCulture)) + "</metascore>");
+ writer.WriteElementString("metascore", hasMetascore.Metascore.Value.ToString(UsCulture));
}
// Use original runtime here, actual file runtime later in MediaInfo
@@ -585,7 +636,7 @@ namespace MediaBrowser.XbmcMetadata.Savers
{
var timespan = TimeSpan.FromTicks(runTimeTicks.Value);
- builder.Append("<runtime>" + Convert.ToInt32(timespan.TotalMinutes).ToString(UsCulture) + "</runtime>");
+ writer.WriteElementString("runtime", Convert.ToInt32(timespan.TotalMinutes).ToString(UsCulture));
}
var hasTaglines = item as IHasTaglines;
@@ -593,7 +644,7 @@ namespace MediaBrowser.XbmcMetadata.Savers
{
foreach (var tagline in hasTaglines.Taglines)
{
- builder.Append("<tagline>" + SecurityElement.Escape(tagline) + "</tagline>");
+ writer.WriteElementString("tagline", tagline);
}
}
@@ -602,18 +653,18 @@ namespace MediaBrowser.XbmcMetadata.Savers
{
foreach (var country in hasProductionLocations.ProductionLocations)
{
- builder.Append("<country>" + SecurityElement.Escape(country) + "</country>");
+ writer.WriteElementString("country", country);
}
}
foreach (var genre in item.Genres)
{
- builder.Append("<genre>" + SecurityElement.Escape(genre) + "</genre>");
+ writer.WriteElementString("genre", genre);
}
foreach (var studio in item.Studios)
{
- builder.Append("<studio>" + SecurityElement.Escape(studio) + "</studio>");
+ writer.WriteElementString("studio", studio);
}
var hasTags = item as IHasTags;
@@ -623,11 +674,11 @@ namespace MediaBrowser.XbmcMetadata.Savers
{
if (item is MusicAlbum || item is MusicArtist)
{
- builder.Append("<style>" + SecurityElement.Escape(tag) + "</style>");
+ writer.WriteElementString("style", tag);
}
else
{
- builder.Append("<tag>" + SecurityElement.Escape(tag) + "</tag>");
+ writer.WriteElementString("tag", tag);
}
}
}
@@ -637,111 +688,111 @@ namespace MediaBrowser.XbmcMetadata.Savers
{
foreach (var tag in hasKeywords.Keywords)
{
- builder.Append("<plotkeyword>" + SecurityElement.Escape(tag) + "</plotkeyword>");
+ writer.WriteElementString("plotkeyword", tag);
}
}
var hasAwards = item as IHasAwards;
if (hasAwards != null && !string.IsNullOrEmpty(hasAwards.AwardSummary))
{
- builder.Append("<awardsummary>" + SecurityElement.Escape(hasAwards.AwardSummary) + "</awardsummary>");
+ writer.WriteElementString("awardsummary", hasAwards.AwardSummary);
}
var externalId = item.GetProviderId(MetadataProviders.AudioDbArtist);
if (!string.IsNullOrEmpty(externalId))
{
- builder.Append("<audiodbartistid>" + SecurityElement.Escape(externalId) + "</audiodbartistid>");
+ writer.WriteElementString("audiodbartistid", externalId);
}
externalId = item.GetProviderId(MetadataProviders.AudioDbAlbum);
if (!string.IsNullOrEmpty(externalId))
{
- builder.Append("<audiodbalbumid>" + SecurityElement.Escape(externalId) + "</audiodbalbumid>");
+ writer.WriteElementString("audiodbalbumid", externalId);
}
externalId = item.GetProviderId(MetadataProviders.Zap2It);
if (!string.IsNullOrEmpty(externalId))
{
- builder.Append("<zap2itid>" + SecurityElement.Escape(externalId) + "</zap2itid>");
+ writer.WriteElementString("zap2itid", externalId);
}
externalId = item.GetProviderId(MetadataProviders.MusicBrainzAlbum);
if (!string.IsNullOrEmpty(externalId))
{
- builder.Append("<musicbrainzalbumid>" + SecurityElement.Escape(externalId) + "</musicbrainzalbumid>");
+ writer.WriteElementString("musicbrainzalbumid", externalId);
}
externalId = item.GetProviderId(MetadataProviders.MusicBrainzAlbumArtist);
if (!string.IsNullOrEmpty(externalId))
{
- builder.Append("<musicbrainzalbumartistid>" + SecurityElement.Escape(externalId) + "</musicbrainzalbumartistid>");
+ writer.WriteElementString("musicbrainzalbumartistid", externalId);
}
externalId = item.GetProviderId(MetadataProviders.MusicBrainzArtist);
if (!string.IsNullOrEmpty(externalId))
{
- builder.Append("<musicbrainzartistid>" + SecurityElement.Escape(externalId) + "</musicbrainzartistid>");
+ writer.WriteElementString("musicbrainzartistid", externalId);
}
externalId = item.GetProviderId(MetadataProviders.MusicBrainzReleaseGroup);
if (!string.IsNullOrEmpty(externalId))
{
- builder.Append("<musicbrainzreleasegroupid>" + SecurityElement.Escape(externalId) + "</musicbrainzreleasegroupid>");
+ writer.WriteElementString("musicbrainzreleasegroupid", externalId);
}
externalId = item.GetProviderId(MetadataProviders.Gamesdb);
if (!string.IsNullOrEmpty(externalId))
{
- builder.Append("<gamesdbid>" + SecurityElement.Escape(externalId) + "</gamesdbid>");
+ writer.WriteElementString("gamesdbid", externalId);
}
externalId = item.GetProviderId(MetadataProviders.TvRage);
if (!string.IsNullOrEmpty(externalId))
{
- builder.Append("<tvrageid>" + SecurityElement.Escape(externalId) + "</tvrageid>");
+ writer.WriteElementString("tvrageid", externalId);
}
if (options.SaveImagePathsInNfo)
{
- AddImages(item, builder, fileSystem, config);
+ AddImages(item, writer, fileSystem, config);
}
- AddUserData(item, builder, userManager, userDataRepo, options);
+ AddUserData(item, writer, userManager, userDataRepo, options);
- AddActors(item, builder, libraryManager, fileSystem, config);
+ AddActors(item, writer, libraryManager, fileSystem, config);
var folder = item as BoxSet;
if (folder != null)
{
- AddCollectionItems(folder, builder);
+ AddCollectionItems(folder, writer);
}
}
- public static void AddChapters(Video item, StringBuilder builder, IItemRepository repository)
+ public static void AddChapters(Video item, XmlWriter writer, IItemRepository repository)
{
var chapters = repository.GetChapters(item.Id);
foreach (var chapter in chapters)
{
- builder.Append("<chapter>");
- builder.Append("<name>" + SecurityElement.Escape(chapter.Name) + "</name>");
+ writer.WriteStartElement("chapter");
+ writer.WriteElementString("name", chapter.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>");
+ writer.WriteElementString("startpositionms", ms.ToString(UsCulture));
+ writer.WriteEndElement();
}
}
- public static void AddCollectionItems(Folder item, StringBuilder builder)
+ private static void AddCollectionItems(Folder item, XmlWriter writer)
{
var items = item.LinkedChildren
.Where(i => i.Type == LinkedChildType.Manual && !string.IsNullOrWhiteSpace(i.ItemName))
@@ -749,17 +800,17 @@ namespace MediaBrowser.XbmcMetadata.Savers
foreach (var link in items)
{
- builder.Append("<collectionitem>");
+ writer.WriteStartElement("collectionitem");
- builder.Append("<name>" + SecurityElement.Escape(link.ItemName) + "</name>");
- builder.Append("<type>" + SecurityElement.Escape(link.ItemType) + "</type>");
+ writer.WriteElementString("name", link.ItemName);
+ writer.WriteElementString("type", link.ItemType);
if (link.ItemYear.HasValue)
{
- builder.Append("<year>" + SecurityElement.Escape(link.ItemYear.Value.ToString(UsCulture)) + "</year>");
+ writer.WriteElementString("year", link.ItemYear.Value.ToString(UsCulture));
}
- builder.Append("</collectionitem>");
+ writer.WriteEndElement();
}
}
@@ -777,26 +828,26 @@ namespace MediaBrowser.XbmcMetadata.Savers
StringComparison.OrdinalIgnoreCase);
}
- private static void AddImages(BaseItem item, StringBuilder builder, IFileSystem fileSystem, IServerConfigurationManager config)
+ private static void AddImages(BaseItem item, XmlWriter writer, IFileSystem fileSystem, IServerConfigurationManager config)
{
- builder.Append("<art>");
+ writer.WriteStartElement("art");
var poster = item.PrimaryImagePath;
if (!string.IsNullOrEmpty(poster))
{
- builder.Append("<poster>" + SecurityElement.Escape(GetPathToSave(item.PrimaryImagePath, fileSystem, config)) + "</poster>");
+ writer.WriteElementString("poster", GetPathToSave(item.PrimaryImagePath, fileSystem, config));
}
foreach (var backdrop in item.GetImages(ImageType.Backdrop))
{
- builder.Append("<fanart>" + SecurityElement.Escape(GetPathToSave(backdrop.Path, fileSystem, config)) + "</fanart>");
+ writer.WriteElementString("fanart", GetPathToSave(backdrop.Path, fileSystem, config));
}
- builder.Append("</art>");
+ writer.WriteEndElement();
}
- private static void AddUserData(BaseItem item, StringBuilder builder, IUserManager userManager, IUserDataManager userDataRepo, XbmcMetadataOptions options)
+ private static void AddUserData(BaseItem item, XmlWriter writer, IUserManager userManager, IUserDataManager userDataRepo, XbmcMetadataOptions options)
{
var userId = options.UserId;
if (string.IsNullOrWhiteSpace(userId))
@@ -818,25 +869,25 @@ namespace MediaBrowser.XbmcMetadata.Savers
var userdata = userDataRepo.GetUserData(user.Id, item.GetUserDataKey());
- builder.Append("<playcount>" + userdata.PlayCount.ToString(UsCulture) + "</playcount>");
- builder.Append("<watched>" + userdata.Played.ToString().ToLower() + "</watched>");
+ writer.WriteElementString("playcount", userdata.PlayCount.ToString(UsCulture));
+ writer.WriteElementString("watched", userdata.Played.ToString().ToLower());
if (userdata.LastPlayedDate.HasValue)
{
- builder.Append("<lastplayed>" + SecurityElement.Escape(userdata.LastPlayedDate.Value.ToString("yyyy-MM-dd HH:mm:ss")) + "</lastplayed>");
+ writer.WriteElementString("lastplayed", userdata.LastPlayedDate.Value.ToString("yyyy-MM-dd HH:mm:ss").ToLower());
}
- builder.Append("<resume>");
+ writer.WriteStartElement("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>");
+ writer.WriteElementString("position", TimeSpan.FromTicks(userdata.PlaybackPositionTicks).TotalSeconds.ToString(UsCulture));
+ writer.WriteElementString("total", TimeSpan.FromTicks(runTimeTicks).TotalSeconds.ToString(UsCulture));
- builder.Append("</resume>");
+ writer.WriteEndElement();
}
- public static void AddActors(BaseItem item, StringBuilder builder, ILibraryManager libraryManager, IFileSystem fileSystem, IServerConfigurationManager config)
+ private static void AddActors(BaseItem item, XmlWriter writer, ILibraryManager libraryManager, IFileSystem fileSystem, IServerConfigurationManager config)
{
var actors = item.People
.Where(i => !IsPersonType(i, PersonType.Director) && !IsPersonType(i, PersonType.Writer))
@@ -844,14 +895,26 @@ namespace MediaBrowser.XbmcMetadata.Savers
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>");
+ writer.WriteStartElement("actor");
+
+ if (!string.IsNullOrWhiteSpace(person.Name))
+ {
+ writer.WriteElementString("name", person.Name);
+ }
+
+ if (!string.IsNullOrWhiteSpace(person.Role))
+ {
+ writer.WriteElementString("role", person.Role);
+ }
+ if (!string.IsNullOrWhiteSpace(person.Type))
+ {
+ writer.WriteElementString("type", person.Type);
+ }
+
if (person.SortOrder.HasValue)
{
- builder.Append("<sortorder>" + SecurityElement.Escape(person.SortOrder.Value.ToString(UsCulture)) + "</sortorder>");
+ writer.WriteElementString("sortorder", person.SortOrder.Value.ToString(UsCulture));
}
try
@@ -860,7 +923,7 @@ namespace MediaBrowser.XbmcMetadata.Savers
if (!string.IsNullOrEmpty(personEntity.PrimaryImagePath))
{
- builder.Append("<thumb>" + SecurityElement.Escape(GetPathToSave(personEntity.PrimaryImagePath, fileSystem, config)) + "</thumb>");
+ writer.WriteElementString("thumb", GetPathToSave(personEntity.PrimaryImagePath, fileSystem, config));
}
}
catch (Exception)
@@ -868,15 +931,10 @@ namespace MediaBrowser.XbmcMetadata.Savers
// Already logged in core
}
- builder.Append("</actor>");
+ writer.WriteEndElement();
}
}
- 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)
@@ -887,24 +945,53 @@ namespace MediaBrowser.XbmcMetadata.Savers
return path;
}
- public static string ReplaceString(string str, string oldValue, string newValue, StringComparison comparison)
+ 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 void AddCustomTags(string path, List<string> xmlTagsUsed, XmlWriter writer)
{
- var sb = new StringBuilder();
+ var settings = new XmlReaderSettings
+ {
+ CheckCharacters = false,
+ IgnoreProcessingInstructions = true,
+ IgnoreComments = true,
+ ValidationType = ValidationType.None
+ };
- int previousIndex = 0;
- int index = str.IndexOf(oldValue, comparison);
- while (index != -1)
+ using (var streamReader = GetStreamReader(path))
{
- sb.Append(str.Substring(previousIndex, index - previousIndex));
- sb.Append(newValue);
- index += oldValue.Length;
+ // 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;
- previousIndex = index;
- index = str.IndexOf(oldValue, index, comparison);
+ if (!CommonTags.ContainsKey(name) && !xmlTagsUsed.Contains(name, StringComparer.OrdinalIgnoreCase))
+ {
+ writer.WriteNode(reader, false);
+ }
+ else
+ {
+ reader.Skip();
+ }
+ }
+ }
+ }
}
- sb.Append(str.Substring(previousIndex));
- return sb.ToString();
+ }
+
+ public static StreamReader GetStreamReader(string path)
+ {
+ return new StreamReader(path, Encoding.UTF8);
}
}
}
diff --git a/MediaBrowser.XbmcMetadata/Savers/EpisodeNfoSaver.cs b/MediaBrowser.XbmcMetadata/Savers/EpisodeNfoSaver.cs
new file mode 100644
index 0000000000..381faedf4a
--- /dev/null
+++ b/MediaBrowser.XbmcMetadata/Savers/EpisodeNfoSaver.cs
@@ -0,0 +1,122 @@
+using MediaBrowser.Common.IO;
+using MediaBrowser.Controller.Configuration;
+using MediaBrowser.Controller.Entities;
+using MediaBrowser.Controller.Entities.TV;
+using MediaBrowser.Controller.Library;
+using MediaBrowser.XbmcMetadata.Configuration;
+using System.Collections.Generic;
+using System.Globalization;
+using System.IO;
+using System.Xml;
+
+namespace MediaBrowser.XbmcMetadata.Savers
+{
+ public class EpisodeNfoSaver : BaseNfoSaver
+ {
+ public EpisodeNfoSaver(IFileSystem fileSystem, IServerConfigurationManager configurationManager, ILibraryManager libraryManager, IUserManager userManager, IUserDataManager userDataManager)
+ : base(fileSystem, configurationManager, libraryManager, userManager, userDataManager)
+ {
+ }
+
+ public override string GetSavePath(IHasMetadata item)
+ {
+ return GetMovieSavePath(item);
+ }
+
+ public static string GetMovieSavePath(IHasMetadata item)
+ {
+ return Path.ChangeExtension(item.Path, ".nfo");
+ }
+
+ protected override string GetRootElementName(IHasMetadata item)
+ {
+ return "episodedetails";
+ }
+
+ public override bool IsEnabledFor(IHasMetadata item, ItemUpdateType updateType)
+ {
+ if (!item.SupportsLocalMetadata)
+ {
+ return false;
+ }
+
+ return item is Episode && updateType >= ItemUpdateType.MetadataDownload;
+ }
+
+ protected override void WriteCustomElements(IHasMetadata item, XmlWriter writer)
+ {
+ var episode = (Episode)item;
+
+ if (episode.IndexNumber.HasValue)
+ {
+ writer.WriteElementString("episode", episode.IndexNumber.Value.ToString(UsCulture));
+ }
+
+ if (episode.IndexNumberEnd.HasValue)
+ {
+ writer.WriteElementString("episodenumberend", episode.IndexNumberEnd.Value.ToString(UsCulture));
+ }
+
+ if (episode.ParentIndexNumber.HasValue)
+ {
+ writer.WriteElementString("season", episode.ParentIndexNumber.Value.ToString(UsCulture));
+ }
+
+ if (episode.PremiereDate.HasValue)
+ {
+ var formatString = ConfigurationManager.GetNfoConfiguration().ReleaseDateFormat;
+
+ writer.WriteElementString("aired", episode.PremiereDate.Value.ToString(formatString));
+ }
+
+ if (episode.AirsAfterSeasonNumber.HasValue)
+ {
+ writer.WriteElementString("airsafter_season", episode.AirsAfterSeasonNumber.Value.ToString(UsCulture));
+ }
+ if (episode.AirsBeforeEpisodeNumber.HasValue)
+ {
+ writer.WriteElementString("airsbefore_episode", episode.AirsBeforeEpisodeNumber.Value.ToString(UsCulture));
+ }
+ if (episode.AirsBeforeSeasonNumber.HasValue)
+ {
+ writer.WriteElementString("airsbefore_season", episode.AirsBeforeSeasonNumber.Value.ToString(UsCulture));
+ }
+
+ if (episode.DvdEpisodeNumber.HasValue)
+ {
+ writer.WriteElementString("DVD_episodenumber", episode.DvdEpisodeNumber.Value.ToString(UsCulture));
+ }
+
+ if (episode.DvdSeasonNumber.HasValue)
+ {
+ writer.WriteElementString("DVD_season", episode.DvdSeasonNumber.Value.ToString(UsCulture));
+ }
+
+ if (episode.AbsoluteEpisodeNumber.HasValue)
+ {
+ writer.WriteElementString("absolute_number", episode.AbsoluteEpisodeNumber.Value.ToString(UsCulture));
+ }
+ }
+
+ private static readonly CultureInfo UsCulture = new CultureInfo("en-US");
+
+ protected override List<string> GetTagsUsed()
+ {
+ var list = new List<string>
+ {
+ "aired",
+ "season",
+ "episode",
+ "episodenumberend",
+ "airsafter_season",
+ "airsbefore_episode",
+ "airsbefore_season",
+ "DVD_episodenumber",
+ "DVD_season",
+ "absolute_number"
+ };
+
+ return list;
+ }
+ }
+}
diff --git a/MediaBrowser.XbmcMetadata/Savers/EpisodeXmlSaver.cs b/MediaBrowser.XbmcMetadata/Savers/EpisodeXmlSaver.cs
deleted file mode 100644
index 1b5c24aad5..0000000000
--- a/MediaBrowser.XbmcMetadata/Savers/EpisodeXmlSaver.cs
+++ /dev/null
@@ -1,141 +0,0 @@
-using System.Collections.Generic;
-using System.Globalization;
-using System.IO;
-using System.Security;
-using System.Text;
-using System.Threading;
-using MediaBrowser.Common.IO;
-using MediaBrowser.Controller.Configuration;
-using MediaBrowser.Controller.Entities;
-using MediaBrowser.Controller.Entities.TV;
-using MediaBrowser.Controller.Library;
-using MediaBrowser.Model.Entities;
-using MediaBrowser.XbmcMetadata.Configuration;
-
-namespace MediaBrowser.XbmcMetadata.Savers
-{
- public class EpisodeXmlSaver : IMetadataFileSaver
- {
- private readonly ILibraryManager _libraryManager;
- private readonly IUserManager _userManager;
- private readonly IUserDataManager _userDataRepo;
-
- private readonly CultureInfo _usCulture = new CultureInfo("en-US");
-
- private readonly IFileSystem _fileSystem;
- private readonly IServerConfigurationManager _config;
-
- public EpisodeXmlSaver(ILibraryManager libraryManager, IUserManager userManager, IUserDataManager userDataRepo, IFileSystem fileSystem, IServerConfigurationManager config)
- {
- _libraryManager = libraryManager;
- _userManager = userManager;
- _userDataRepo = userDataRepo;
- _fileSystem = fileSystem;
- _config = config;
- }
-
- public string Name
- {
- get
- {
- return "Xbmc Nfo";
- }
- }
-
- public string GetSavePath(IHasMetadata item)
- {
- return Path.ChangeExtension(item.Path, ".nfo");
- }
-
- public void Save(IHasMetadata item, CancellationToken cancellationToken)
- {
- var episode = (Episode)item;
-
- var builder = new StringBuilder();
-
- builder.Append("<episodedetails>");
-
- XmlSaverHelpers.AddCommonNodes(episode, builder, _libraryManager, _userManager, _userDataRepo, _fileSystem, _config);
-
- if (episode.IndexNumber.HasValue)
- {
- builder.Append("<episode>" + episode.IndexNumber.Value.ToString(_usCulture) + "</episode>");
- }
-
- if (episode.IndexNumberEnd.HasValue)
- {
- builder.Append("<episodenumberend>" + SecurityElement.Escape(episode.IndexNumberEnd.Value.ToString(_usCulture)) + "</episodenumberend>");
- }
-
- if (episode.ParentIndexNumber.HasValue)
- {
- builder.Append("<season>" + episode.ParentIndexNumber.Value.ToString(_usCulture) + "</season>");
- }
-
- if (episode.PremiereDate.HasValue)
- {
- var formatString = _config.GetNfoConfiguration().ReleaseDateFormat;
-
- builder.Append("<aired>" + SecurityElement.Escape(episode.PremiereDate.Value.ToString(formatString)) + "</aired>");
- }
-
- if (episode.AirsAfterSeasonNumber.HasValue)
- {
- builder.Append("<airsafter_season>" + SecurityElement.Escape(episode.AirsAfterSeasonNumber.Value.ToString(_usCulture)) + "</airsafter_season>");
- }
- if (episode.AirsBeforeEpisodeNumber.HasValue)
- {
- builder.Append("<airsbefore_episode>" + SecurityElement.Escape(episode.AirsBeforeEpisodeNumber.Value.ToString(_usCulture)) + "</airsbefore_episode>");
- }
- if (episode.AirsBeforeSeasonNumber.HasValue)
- {
- builder.Append("<airsbefore_season>" + SecurityElement.Escape(episode.AirsBeforeSeasonNumber.Value.ToString(_usCulture)) + "</airsbefore_season>");
- }
-
- if (episode.DvdEpisodeNumber.HasValue)
- {
- builder.Append("<DVD_episodenumber>" + SecurityElement.Escape(episode.DvdEpisodeNumber.Value.ToString(_usCulture)) + "</DVD_episodenumber>");
- }
-
- if (episode.DvdSeasonNumber.HasValue)
- {
- builder.Append("<DVD_season>" + SecurityElement.Escape(episode.DvdSeasonNumber.Value.ToString(_usCulture)) + "</DVD_season>");
- }
-
- if (episode.AbsoluteEpisodeNumber.HasValue)
- {
- builder.Append("<absolute_number>" + SecurityElement.Escape(episode.AbsoluteEpisodeNumber.Value.ToString(_usCulture)) + "</absolute_number>");
- }
-
- XmlSaverHelpers.AddMediaInfo((Episode)item, builder);
-
- builder.Append("</episodedetails>");
-
- var xmlFilePath = GetSavePath(item);
-
- XmlSaverHelpers.Save(builder, xmlFilePath, new List<string>
- {
- "aired",
- "season",
- "episode",
- "episodenumberend",
- "airsafter_season",
- "airsbefore_episode",
- "airsbefore_season",
- "DVD_episodenumber",
- "DVD_season",
- "absolute_number"
- });
- }
-
- public bool IsEnabledFor(IHasMetadata item, ItemUpdateType updateType)
- {
- if (!item.SupportsLocalMetadata)
- {
- return false;
- }
-
- return item is Episode && updateType >= ItemUpdateType.MetadataDownload;
- }
- }
-}
diff --git a/MediaBrowser.XbmcMetadata/Savers/MovieXmlSaver.cs b/MediaBrowser.XbmcMetadata/Savers/MovieNfoSaver.cs
index fa2155e30a..9c8442e167 100644
--- a/MediaBrowser.XbmcMetadata/Savers/MovieXmlSaver.cs
+++ b/MediaBrowser.XbmcMetadata/Savers/MovieNfoSaver.cs
@@ -6,40 +6,20 @@ using MediaBrowser.Controller.Entities.TV;
using MediaBrowser.Controller.Library;
using MediaBrowser.Model.Entities;
using System.Collections.Generic;
+using System.Globalization;
using System.IO;
-using System.Security;
-using System.Text;
-using System.Threading;
+using System.Xml;
namespace MediaBrowser.XbmcMetadata.Savers
{
- public class MovieXmlSaver : IMetadataFileSaver
+ public class MovieNfoSaver : BaseNfoSaver
{
- private readonly ILibraryManager _libraryManager;
- private readonly IUserManager _userManager;
- private readonly IUserDataManager _userDataRepo;
-
- private readonly IFileSystem _fileSystem;
- private readonly IServerConfigurationManager _config;
-
- public MovieXmlSaver(ILibraryManager libraryManager, IUserManager userManager, IUserDataManager userDataRepo, IFileSystem fileSystem, IServerConfigurationManager config)
+ public MovieNfoSaver(IFileSystem fileSystem, IServerConfigurationManager configurationManager, ILibraryManager libraryManager, IUserManager userManager, IUserDataManager userDataManager)
+ : base(fileSystem, configurationManager, libraryManager, userManager, userDataManager)
{
- _libraryManager = libraryManager;
- _userManager = userManager;
- _userDataRepo = userDataRepo;
- _fileSystem = fileSystem;
- _config = config;
}
- public string Name
- {
- get
- {
- return "Xbmc Nfo";
- }
- }
-
- public string GetSavePath(IHasMetadata item)
+ public override string GetSavePath(IHasMetadata item)
{
return GetMovieSavePath(item);
}
@@ -58,23 +38,36 @@ namespace MediaBrowser.XbmcMetadata.Savers
return Path.ChangeExtension(item.Path, ".nfo");
}
- public void Save(IHasMetadata item, CancellationToken cancellationToken)
+ protected override string GetRootElementName(IHasMetadata item)
{
- var video = (Video)item;
+ return item is MusicVideo ? "musicvideo" : "movie";
+ }
- var builder = new StringBuilder();
+ public override bool IsEnabledFor(IHasMetadata item, ItemUpdateType updateType)
+ {
+ if (!item.SupportsLocalMetadata)
+ {
+ return false;
+ }
- var tag = item is MusicVideo ? "musicvideo" : "movie";
+ var video = item as Video;
- builder.Append("<" + tag + ">");
+ // Check parent for null to avoid running this against things like video backdrops
+ if (video != null && !(item is Episode) && !video.IsOwnedItem)
+ {
+ return updateType >= ItemUpdateType.MetadataDownload;
+ }
- XmlSaverHelpers.AddCommonNodes(video, builder, _libraryManager, _userManager, _userDataRepo, _fileSystem, _config);
+ return false;
+ }
+ protected override void WriteCustomElements(IHasMetadata item, XmlWriter writer)
+ {
var imdb = item.GetProviderId(MetadataProviders.Imdb);
if (!string.IsNullOrEmpty(imdb))
{
- builder.Append("<id>" + SecurityElement.Escape(imdb) + "</id>");
+ writer.WriteElementString("id", imdb);
}
var musicVideo = item as MusicVideo;
@@ -83,11 +76,11 @@ namespace MediaBrowser.XbmcMetadata.Savers
{
if (!string.IsNullOrEmpty(musicVideo.Artist))
{
- builder.Append("<artist>" + SecurityElement.Escape(musicVideo.Artist) + "</artist>");
+ writer.WriteElementString("artist", musicVideo.Artist);
}
if (!string.IsNullOrEmpty(musicVideo.Album))
{
- builder.Append("<album>" + SecurityElement.Escape(musicVideo.Album) + "</album>");
+ writer.WriteElementString("album", musicVideo.Album);
}
}
@@ -97,41 +90,24 @@ namespace MediaBrowser.XbmcMetadata.Savers
{
if (!string.IsNullOrEmpty(movie.TmdbCollectionName))
{
- builder.Append("<set>" + SecurityElement.Escape(movie.TmdbCollectionName) + "</set>");
+ writer.WriteElementString("set", movie.TmdbCollectionName);
}
}
+ }
- XmlSaverHelpers.AddMediaInfo((Video)item, builder);
-
- builder.Append("</" + tag + ">");
-
- var xmlFilePath = GetSavePath(item);
+ private static readonly CultureInfo UsCulture = new CultureInfo("en-US");
- XmlSaverHelpers.Save(builder, xmlFilePath, new List<string>
- {
+ protected override List<string> GetTagsUsed()
+ {
+ var list = new List<string>
+ {
"album",
"artist",
"set",
"id"
- });
- }
+ };
- public bool IsEnabledFor(IHasMetadata item, ItemUpdateType updateType)
- {
- if (!item.SupportsLocalMetadata)
- {
- return false;
- }
-
- var video = item as Video;
-
- // Check parent for null to avoid running this against things like video backdrops
- if (video != null && !(item is Episode) && !video.IsOwnedItem)
- {
- return updateType >= ItemUpdateType.MetadataDownload;
- }
-
- return false;
+ return list;
}
}
}
diff --git a/MediaBrowser.XbmcMetadata/Savers/SeasonNfoSaver.cs b/MediaBrowser.XbmcMetadata/Savers/SeasonNfoSaver.cs
new file mode 100644
index 0000000000..fd5819b3d2
--- /dev/null
+++ b/MediaBrowser.XbmcMetadata/Savers/SeasonNfoSaver.cs
@@ -0,0 +1,63 @@
+using MediaBrowser.Common.IO;
+using MediaBrowser.Controller.Configuration;
+using MediaBrowser.Controller.Entities;
+using MediaBrowser.Controller.Entities.TV;
+using MediaBrowser.Controller.Library;
+using System.Collections.Generic;
+using System.Globalization;
+using System.IO;
+using System.Xml;
+
+namespace MediaBrowser.XbmcMetadata.Savers
+{
+ public class SeasonNfoSaver : BaseNfoSaver
+ {
+ public SeasonNfoSaver(IFileSystem fileSystem, IServerConfigurationManager configurationManager, ILibraryManager libraryManager, IUserManager userManager, IUserDataManager userDataManager) : base(fileSystem, configurationManager, libraryManager, userManager, userDataManager)
+ {
+ }
+
+ public override string GetSavePath(IHasMetadata item)
+ {
+ return Path.Combine(item.Path, "season.nfo");
+ }
+
+ protected override string GetRootElementName(IHasMetadata item)
+ {
+ return "season";
+ }
+
+ public override bool IsEnabledFor(IHasMetadata item, ItemUpdateType updateType)
+ {
+ if (!item.SupportsLocalMetadata)
+ {
+ return false;
+ }
+
+ if (!(item is Season))
+ {
+ return false;
+ }
+
+ return updateType >= ItemUpdateType.MetadataDownload || (updateType >= ItemUpdateType.MetadataImport && File.Exists(GetSavePath(item)));
+ }
+
+ protected override void WriteCustomElements(IHasMetadata item, XmlWriter writer)
+ {
+ var season = (Season)item;
+
+ if (season.IndexNumber.HasValue)
+ {
+ writer.WriteElementString("seasonnumber", season.IndexNumber.Value.ToString(CultureInfo.InvariantCulture));
+ }
+ }
+
+ protected override List<string> GetTagsUsed()
+ {
+ var list = base.GetTagsUsed();
+
+ list.Add("seasonnumber");
+
+ return list;
+ }
+ }
+}
diff --git a/MediaBrowser.XbmcMetadata/Savers/SeasonXmlSaver.cs b/MediaBrowser.XbmcMetadata/Savers/SeasonXmlSaver.cs
deleted file mode 100644
index a96b0636f2..0000000000
--- a/MediaBrowser.XbmcMetadata/Savers/SeasonXmlSaver.cs
+++ /dev/null
@@ -1,86 +0,0 @@
-using MediaBrowser.Common.IO;
-using MediaBrowser.Controller.Configuration;
-using MediaBrowser.Controller.Entities;
-using MediaBrowser.Controller.Entities.TV;
-using MediaBrowser.Controller.Library;
-using System.Collections.Generic;
-using System.Globalization;
-using System.IO;
-using System.Security;
-using System.Text;
-using System.Threading;
-
-namespace MediaBrowser.XbmcMetadata.Savers
-{
- public class SeasonXmlSaver : IMetadataFileSaver
- {
- private readonly ILibraryManager _libraryManager;
- private readonly IUserManager _userManager;
- private readonly IUserDataManager _userDataRepo;
-
- private readonly IFileSystem _fileSystem;
- private readonly IServerConfigurationManager _config;
-
- public SeasonXmlSaver(ILibraryManager libraryManager, IUserManager userManager, IUserDataManager userDataRepo, IFileSystem fileSystem, IServerConfigurationManager config)
- {
- _libraryManager = libraryManager;
- _userManager = userManager;
- _userDataRepo = userDataRepo;
- _fileSystem = fileSystem;
- _config = config;
- }
-
- public string Name
- {
- get
- {
- return "Xbmc Nfo";
- }
- }
-
- public string GetSavePath(IHasMetadata item)
- {
- return Path.Combine(item.Path, "season.nfo");
- }
-
- public void Save(IHasMetadata item, CancellationToken cancellationToken)
- {
- var builder = new StringBuilder();
-
- builder.Append("<season>");
-
- var season = (Season)item;
-
- if (season.IndexNumber.HasValue)
- {
- builder.Append("<seasonnumber>" + SecurityElement.Escape(season.IndexNumber.Value.ToString(CultureInfo.InvariantCulture)) + "</seasonnumber>");
- }
-
- XmlSaverHelpers.AddCommonNodes((Season)item, builder, _libraryManager, _userManager, _userDataRepo, _fileSystem, _config);
-
- builder.Append("</season>");
-
- var xmlFilePath = GetSavePath(item);
-
- XmlSaverHelpers.Save(builder, xmlFilePath, new List<string>
- {
- "seasonnumber"
- });
- }
-
- public bool IsEnabledFor(IHasMetadata item, ItemUpdateType updateType)
- {
- if (!item.SupportsLocalMetadata)
- {
- return false;
- }
-
- if (!(item is Season))
- {
- return false;
- }
-
- return updateType >= ItemUpdateType.MetadataDownload || (updateType >= ItemUpdateType.MetadataImport && File.Exists(GetSavePath(item)));
- }
- }
-}
diff --git a/MediaBrowser.XbmcMetadata/Savers/SeriesNfoSaver.cs b/MediaBrowser.XbmcMetadata/Savers/SeriesNfoSaver.cs
new file mode 100644
index 0000000000..473b5f46bb
--- /dev/null
+++ b/MediaBrowser.XbmcMetadata/Savers/SeriesNfoSaver.cs
@@ -0,0 +1,113 @@
+using MediaBrowser.Common.IO;
+using MediaBrowser.Controller.Configuration;
+using MediaBrowser.Controller.Entities;
+using MediaBrowser.Controller.Entities.TV;
+using MediaBrowser.Controller.Library;
+using MediaBrowser.Model.Entities;
+using System.Collections.Generic;
+using System.Globalization;
+using System.IO;
+using System.Xml;
+
+namespace MediaBrowser.XbmcMetadata.Savers
+{
+ public class SeriesNfoSaver : BaseNfoSaver
+ {
+ public SeriesNfoSaver(IFileSystem fileSystem, IServerConfigurationManager configurationManager, ILibraryManager libraryManager, IUserManager userManager, IUserDataManager userDataManager)
+ : base(fileSystem, configurationManager, libraryManager, userManager, userDataManager)
+ {
+ }
+
+ public override string GetSavePath(IHasMetadata item)
+ {
+ return Path.Combine(item.Path, "tvshow.nfo");
+ }
+
+ protected override string GetRootElementName(IHasMetadata item)
+ {
+ return "tvshow";
+ }
+
+ public override bool IsEnabledFor(IHasMetadata item, ItemUpdateType updateType)
+ {
+ if (!item.SupportsLocalMetadata)
+ {
+ return false;
+ }
+
+ return item is Series && updateType >= ItemUpdateType.MetadataDownload;
+ }
+
+ protected override void WriteCustomElements(IHasMetadata item, XmlWriter writer)
+ {
+ var series = (Series)item;
+
+ var tvdb = item.GetProviderId(MetadataProviders.Tvdb);
+
+ if (!string.IsNullOrEmpty(tvdb))
+ {
+ writer.WriteElementString("id", tvdb);
+
+ writer.WriteStartElement("episodeguide");
+
+ var language = item.GetPreferredMetadataLanguage();
+ language = string.IsNullOrEmpty(language)
+ ? "en"
+ : language;
+
+ writer.WriteStartElement("url");
+ writer.WriteAttributeString("cache", string.Format("{0}.xml", tvdb));
+ writer.WriteString(string.Format("http://www.thetvdb.com/api/1D62F2F90030C444/series/{0}/all/{1}.zip", tvdb, language));
+ writer.WriteEndElement();
+
+ writer.WriteEndElement();
+ }
+
+ writer.WriteElementString("season", "-1");
+ writer.WriteElementString("episode", "-1");
+
+ if (series.Status.HasValue)
+ {
+ writer.WriteElementString("status", series.Status.Value.ToString());
+ }
+
+ if (!string.IsNullOrEmpty(series.AirTime))
+ {
+ writer.WriteElementString("airs_time", series.AirTime);
+ }
+
+ if (series.AirDays.Count == 7)
+ {
+ writer.WriteElementString("airs_dayofweek", "Daily");
+ }
+ else if (series.AirDays.Count > 0)
+ {
+ writer.WriteElementString("airs_dayofweek", series.AirDays[0].ToString());
+ }
+
+ if (series.AnimeSeriesIndex.HasValue)
+ {
+ writer.WriteElementString("animeseriesindex", series.AnimeSeriesIndex.Value.ToString(CultureInfo.InvariantCulture));
+ }
+ }
+
+ private static readonly CultureInfo UsCulture = new CultureInfo("en-US");
+
+ protected override List<string> GetTagsUsed()
+ {
+ var list = new List<string>
+ {
+ "id",
+ "episodeguide",
+ "season",
+ "episode",
+ "status",
+ "airs_time",
+ "airs_dayofweek",
+ "animeseriesindex"
+ };
+
+ return list;
+ }
+ }
+}
diff --git a/MediaBrowser.XbmcMetadata/Savers/SeriesXmlSaver.cs b/MediaBrowser.XbmcMetadata/Savers/SeriesXmlSaver.cs
deleted file mode 100644
index 94d46f61d3..0000000000
--- a/MediaBrowser.XbmcMetadata/Savers/SeriesXmlSaver.cs
+++ /dev/null
@@ -1,122 +0,0 @@
-using System.Collections.Generic;
-using System.Globalization;
-using System.IO;
-using System.Security;
-using System.Text;
-using System.Threading;
-using MediaBrowser.Common.IO;
-using MediaBrowser.Controller.Configuration;
-using MediaBrowser.Controller.Entities;
-using MediaBrowser.Controller.Entities.TV;
-using MediaBrowser.Controller.Library;
-using MediaBrowser.Model.Entities;
-
-namespace MediaBrowser.XbmcMetadata.Savers
-{
- public class SeriesXmlSaver : IMetadataFileSaver
- {
- private readonly ILibraryManager _libraryManager;
- private readonly IUserManager _userManager;
- private readonly IUserDataManager _userDataRepo;
-
- private readonly IFileSystem _fileSystem;
- private readonly IServerConfigurationManager _config;
-
- public SeriesXmlSaver(IServerConfigurationManager config, ILibraryManager libraryManager, IUserManager userManager, IUserDataManager userDataRepo, IFileSystem fileSystem)
- {
- _config = config;
- _libraryManager = libraryManager;
- _userManager = userManager;
- _userDataRepo = userDataRepo;
- _fileSystem = fileSystem;
- }
-
- public string Name
- {
- get
- {
- return "Xbmc Nfo";
- }
- }
-
- public string GetSavePath(IHasMetadata item)
- {
- return Path.Combine(item.Path, "tvshow.nfo");
- }
-
- public void Save(IHasMetadata item, CancellationToken cancellationToken)
- {
- var series = (Series)item;
-
- var builder = new StringBuilder();
-
- builder.Append("<tvshow>");
-
- XmlSaverHelpers.AddCommonNodes(series, builder, _libraryManager, _userManager, _userDataRepo, _fileSystem, _config);
-
- var tvdb = item.GetProviderId(MetadataProviders.Tvdb);
-
- if (!string.IsNullOrEmpty(tvdb))
- {
- builder.Append("<id>" + SecurityElement.Escape(tvdb) + "</id>");
-
- builder.AppendFormat("<episodeguide><url cache=\"{0}.xml\">http://www.thetvdb.com/api/1D62F2F90030C444/series/{0}/all/{1}.zip</url></episodeguide>",
- tvdb,
- string.IsNullOrEmpty(_config.Configuration.PreferredMetadataLanguage) ? "en" : _config.Configuration.PreferredMetadataLanguage);
- }
-
- builder.Append("<season>-1</season>");
- builder.Append("<episode>-1</episode>");
-
- if (series.Status.HasValue)
- {
- builder.Append("<status>" + SecurityElement.Escape(series.Status.Value.ToString()) + "</status>");
- }
-
- if (!string.IsNullOrEmpty(series.AirTime))
- {
- builder.Append("<airs_time>" + SecurityElement.Escape(series.AirTime) + "</airs_time>");
- }
-
- if (series.AirDays.Count == 7)
- {
- builder.Append("<airs_dayofweek>" + SecurityElement.Escape("Daily") + "</airs_dayofweek>");
- }
- else if (series.AirDays.Count > 0)
- {
- builder.Append("<airs_dayofweek>" + SecurityElement.Escape(series.AirDays[0].ToString()) + "</airs_dayofweek>");
- }
-
- if (series.AnimeSeriesIndex.HasValue)
- {
- builder.Append("<animeseriesindex>" + SecurityElement.Escape(series.AnimeSeriesIndex.Value.ToString(CultureInfo.InvariantCulture)) + "</animeseriesindex>");
- }
-
- builder.Append("</tvshow>");
-
- var xmlFilePath = GetSavePath(item);
-
- XmlSaverHelpers.Save(builder, xmlFilePath, new List<string>
- {
- "id",
- "episodeguide",
- "season",
- "episode",
- "status",
- "airs_time",
- "airs_dayofweek",
- "animeseriesindex"
- });
- }
-
- public bool IsEnabledFor(IHasMetadata item, ItemUpdateType updateType)
- {
- if (!item.SupportsLocalMetadata)
- {
- return false;
- }
-
- return item is Series && updateType >= ItemUpdateType.MetadataDownload;
- }
- }
-}