From 807d4cb007509e5038580282ce3c6a3aae95b854 Mon Sep 17 00:00:00 2001 From: Jason Dove Date: Thu, 11 Feb 2021 06:14:36 -0600 Subject: [PATCH] use xml writer so strings are properly escaped --- ErsatzTV.Core/Iptv/ChannelGuide.cs | 77 +++++++++++++++++++++--------- 1 file changed, 55 insertions(+), 22 deletions(-) diff --git a/ErsatzTV.Core/Iptv/ChannelGuide.cs b/ErsatzTV.Core/Iptv/ChannelGuide.cs index ea2d99839..d13127604 100644 --- a/ErsatzTV.Core/Iptv/ChannelGuide.cs +++ b/ErsatzTV.Core/Iptv/ChannelGuide.cs @@ -2,6 +2,7 @@ using System.IO; using System.Linq; using System.Text; +using System.Xml; using ErsatzTV.Core.Domain; using static LanguageExt.Prelude; @@ -23,19 +24,31 @@ namespace ErsatzTV.Core.Iptv public string ToXml() { var sb = new StringBuilder(); - sb.AppendLine(""); - sb.AppendLine(""); - + using var xml = XmlWriter.Create(sb); + xml.WriteStartDocument(); + + xml.WriteStartElement("tv"); + xml.WriteAttributeString("generator-info-name", "ersatztv"); + foreach (Channel channel in _channels) { - sb.AppendLine($""); - sb.AppendLine($"{channel.Name}"); - sb.AppendLine( + xml.WriteStartElement("channel"); + xml.WriteAttributeString("id", channel.Number.ToString()); + + xml.WriteStartElement("display-name"); + xml.WriteAttributeString("lang", "en"); + xml.WriteString(channel.Name); + xml.WriteEndElement(); // display-name + + xml.WriteStartElement("icon"); + xml.WriteAttributeString( + "src", !string.IsNullOrWhiteSpace(channel.Logo) - ? $"" - : $""); + ? $"{_scheme}://{_host}/iptv/images/{channel.Logo}" + : $"{_scheme}://{_host}/images/ersatztv-500.png"); + xml.WriteEndElement(); // icon - sb.AppendLine(""); + xml.WriteEndElement(); // channel } foreach (Channel channel in _channels) @@ -50,35 +63,55 @@ namespace ErsatzTV.Core.Iptv Title = Path.GetFileName(playoutItem.MediaItem.Path) }); - sb.AppendLine( - $""); - sb.AppendLine($"{metadata.Title}"); - sb.AppendLine(""); - sb.AppendLine(""); + xml.WriteStartElement("programme"); + xml.WriteAttributeString("start", start); + xml.WriteAttributeString("stop", stop); + xml.WriteAttributeString("channel", channel.Number.ToString()); + + xml.WriteStartElement("title"); + xml.WriteAttributeString("lang", "en"); + xml.WriteString(metadata.Title); + xml.WriteEndElement(); // title + + xml.WriteStartElement("previously-shown"); + xml.WriteEndElement(); // previously-shown + + xml.WriteStartElement("sub-title"); + xml.WriteAttributeString("lang", "en"); + xml.WriteEndElement(); // sub-title int season = Optional(metadata.SeasonNumber).IfNone(0); int episode = Optional(metadata.EpisodeNumber).IfNone(0); if (season > 0 && episode > 0) { - sb.AppendLine($"{season - 1}.{episode - 1}.0/1"); + xml.WriteStartElement("episode-num"); + xml.WriteAttributeString("system", "xmltv_ns"); + xml.WriteString($"{season - 1}.{episode - 1}.0/1"); + xml.WriteEndElement(); // episode-num } // sb.AppendLine(""); - sb.AppendLine($"{metadata.Description}"); + xml.WriteStartElement("desc"); + xml.WriteAttributeString("lang", "en"); + xml.WriteString(metadata.Description); + xml.WriteEndElement(); // desc if (!string.IsNullOrWhiteSpace(metadata.ContentRating)) { - sb.AppendLine(""); - sb.AppendLine($"{metadata.ContentRating}"); - sb.AppendLine(""); + xml.WriteStartElement("rating"); + xml.WriteAttributeString("system", "MPAA"); + xml.WriteStartElement("value"); + xml.WriteString(metadata.ContentRating); + xml.WriteEndElement(); // value + xml.WriteEndElement(); // rating } - sb.AppendLine(""); + xml.WriteEndElement(); // programme } } - sb.AppendLine(""); - + xml.WriteEndElement(); // tv + xml.WriteEndDocument(); return sb.ToString(); }