diff --git a/ConfusedPolarBear.Plugin.IntroSkipper/Plugin.cs b/ConfusedPolarBear.Plugin.IntroSkipper/Plugin.cs index 867ade4..f79d082 100644 --- a/ConfusedPolarBear.Plugin.IntroSkipper/Plugin.cs +++ b/ConfusedPolarBear.Plugin.IntroSkipper/Plugin.cs @@ -7,7 +7,6 @@ using MediaBrowser.Common.Configuration; using MediaBrowser.Common.Plugins; using MediaBrowser.Controller.Configuration; using MediaBrowser.Controller.Entities; -using MediaBrowser.Controller.Entities.TV; using MediaBrowser.Controller.Library; using MediaBrowser.Controller.Persistence; using MediaBrowser.Model.Entities; @@ -24,7 +23,6 @@ public class Plugin : BasePlugin, IHasWebPages { private readonly object _serializationLock = new(); private readonly object _introsLock = new(); - private IXmlSerializer _xmlSerializer; private ILibraryManager _libraryManager; private IItemRepository _itemRepository; private ILogger _logger; @@ -54,13 +52,14 @@ public class Plugin : BasePlugin, IHasWebPages { Instance = this; - _xmlSerializer = xmlSerializer; _libraryManager = libraryManager; _itemRepository = itemRepository; _logger = logger; FFmpegPath = serverConfiguration.GetEncodingOptions().EncoderAppPathDisplay; + ArgumentNullException.ThrowIfNull(applicationPaths); + var introsDirectory = Path.Join(applicationPaths.CachePath, "introskipper"); FingerprintCachePath = Path.Join(introsDirectory, "chromaprints"); _introPath = Path.Join(applicationPaths.CachePath, "introskipper", "intros.xml"); @@ -95,6 +94,10 @@ public class Plugin : BasePlugin, IHasWebPages } } + // migrate from XMLSchema to DataContract + XmlSerializationHelper.MigrateXML(_introPath); + XmlSerializationHelper.MigrateXML(_creditsPath); + ConfigurationChanged += OnConfigurationChanged; // TODO: remove when https://github.com/jellyfin/jellyfin-meta/discussions/30 is complete @@ -205,7 +208,14 @@ public class Plugin : BasePlugin, IHasWebPages introList.Add(intro.Value); } - _xmlSerializer.SerializeToFile(introList, _introPath); + try + { + XmlSerializationHelper.SerializeToXml(introList, _introPath); + } + catch (Exception e) + { + _logger.LogError("SaveTimestamps intros {Message}", e.Message); + } // Serialize credits introList.Clear(); @@ -215,7 +225,14 @@ public class Plugin : BasePlugin, IHasWebPages introList.Add(intro.Value); } - _xmlSerializer.SerializeToFile(introList, _creditsPath); + try + { + XmlSerializationHelper.SerializeToXml(introList, _creditsPath); + } + catch (Exception e) + { + _logger.LogError("SaveTimestamps credits {Message}", e.Message); + } } } @@ -227,9 +244,7 @@ public class Plugin : BasePlugin, IHasWebPages if (File.Exists(_introPath)) { // Since dictionaries can't be easily serialized, analysis results are stored on disk as a list. - var introList = (List)_xmlSerializer.DeserializeFromFile( - typeof(List), - _introPath); + var introList = XmlSerializationHelper.DeserializeFromXml(_introPath); foreach (var intro in introList) { @@ -239,9 +254,7 @@ public class Plugin : BasePlugin, IHasWebPages if (File.Exists(_creditsPath)) { - var creditList = (List)_xmlSerializer.DeserializeFromFile( - typeof(List), - _creditsPath); + var creditList = XmlSerializationHelper.DeserializeFromXml(_creditsPath); foreach (var credit in creditList) { diff --git a/ConfusedPolarBear.Plugin.IntroSkipper/XmlSerializationHelper.cs b/ConfusedPolarBear.Plugin.IntroSkipper/XmlSerializationHelper.cs new file mode 100644 index 0000000..bf2c321 --- /dev/null +++ b/ConfusedPolarBear.Plugin.IntroSkipper/XmlSerializationHelper.cs @@ -0,0 +1,74 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Runtime.Serialization; +using System.Text; +using System.Xml; + +namespace ConfusedPolarBear.Plugin.IntroSkipper +{ + internal sealed class XmlSerializationHelper + { + public static void SerializeToXml(T obj, string filePath) + { + // Create a FileStream to write the XML file + using FileStream fileStream = new FileStream(filePath, FileMode.Create); + // Create a DataContractSerializer for type T + DataContractSerializer serializer = new DataContractSerializer(typeof(T)); + + // Serialize the object to the FileStream + serializer.WriteObject(fileStream, obj); + } + + public static List DeserializeFromXml(string filePath) + { + var result = new List(); + try + { + // Create a FileStream to read the XML file + using FileStream fileStream = new FileStream(filePath, FileMode.Open); + // Create an XmlDictionaryReader to read the XML + XmlDictionaryReader reader = XmlDictionaryReader.CreateTextReader(fileStream, new XmlDictionaryReaderQuotas()); + + // Create a DataContractSerializer for type T + DataContractSerializer serializer = new DataContractSerializer(typeof(List)); + + // Deserialize the object from the XML + result = serializer.ReadObject(reader) as List; + + // Close the reader + reader.Close(); + } + catch (Exception ex) + { + Console.WriteLine($"Error deserializing XML: {ex.Message}"); + } +#pragma warning disable CS8603 + // Return the deserialized object + return result; +#pragma warning restore CS8603 + } + + public static void MigrateXML(string filePath) + { + if (File.Exists(filePath)) + { + string searchString = ""; + string replacementString = ""; + + // Read the content of the file + string fileContent = File.ReadAllText(filePath, Encoding.UTF8); + + // Check if the target string exists at the beginning + if (fileContent.Contains(searchString, StringComparison.OrdinalIgnoreCase)) + { + // Replace the target string + fileContent = fileContent.Replace(searchString, replacementString, StringComparison.OrdinalIgnoreCase); + + // Write the modified content back to the file + File.WriteAllText(filePath, fileContent, Encoding.UTF8); + } + } + } + } +}