diff --git a/MediaBrowser.Dlna/DlnaManager.cs b/MediaBrowser.Dlna/DlnaManager.cs index ec9ecb9ef2..958188f37a 100644 --- a/MediaBrowser.Dlna/DlnaManager.cs +++ b/MediaBrowser.Dlna/DlnaManager.cs @@ -20,13 +20,15 @@ namespace MediaBrowser.Dlna private readonly IXmlSerializer _xmlSerializer; private readonly IFileSystem _fileSystem; private readonly ILogger _logger; + private readonly IJsonSerializer _jsonSerializer; - public DlnaManager(IXmlSerializer xmlSerializer, IFileSystem fileSystem, IApplicationPaths appPaths, ILogger logger) + public DlnaManager(IXmlSerializer xmlSerializer, IFileSystem fileSystem, IApplicationPaths appPaths, ILogger logger, IJsonSerializer jsonSerializer) { _xmlSerializer = xmlSerializer; _fileSystem = fileSystem; _appPaths = appPaths; _logger = logger; + _jsonSerializer = jsonSerializer; //DumpProfiles(); } @@ -381,10 +383,66 @@ namespace MediaBrowser.Dlna public void CreateProfile(DeviceProfile profile) { + profile = ReserializeProfile(profile); + + if (string.IsNullOrWhiteSpace(profile.Name)) + { + throw new ArgumentException("Profile is missing Name"); + } + + var newFilename = _fileSystem.GetValidFilename(profile.Name) + ".xml"; + var path = Path.Combine(UserProfilesPath, newFilename); + + _xmlSerializer.SerializeToFile(profile, path); } public void UpdateProfile(DeviceProfile profile) { + profile = ReserializeProfile(profile); + + if (string.IsNullOrWhiteSpace(profile.Id)) + { + throw new ArgumentException("Profile is missing Id"); + } + if (string.IsNullOrWhiteSpace(profile.Name)) + { + throw new ArgumentException("Profile is missing Name"); + } + + var current = GetProfileInfosInternal().First(i => string.Equals(i.Info.Id, profile.Id, StringComparison.OrdinalIgnoreCase)); + + if (current.Info.Type == DeviceProfileType.System) + { + throw new ArgumentException("System profiles are readonly"); + } + + var newFilename = _fileSystem.GetValidFilename(profile.Name) + ".xml"; + var path = Path.Combine(UserProfilesPath, newFilename); + + if (!string.Equals(path, current.Path, StringComparison.Ordinal)) + { + File.Delete(current.Path); + } + + _xmlSerializer.SerializeToFile(profile, path); + } + + /// + /// Recreates the object using serialization, to ensure it's not a subclass. + /// If it's a subclass it may not serlialize properly to xml (different root element tag name) + /// + /// + /// + private DeviceProfile ReserializeProfile(DeviceProfile profile) + { + if (profile.GetType() == typeof(DeviceProfile)) + { + return profile; + } + + var json = _jsonSerializer.SerializeToString(profile); + + return _jsonSerializer.DeserializeFromString(json); } class InternalProfileInfo diff --git a/MediaBrowser.ServerApplication/ApplicationHost.cs b/MediaBrowser.ServerApplication/ApplicationHost.cs index b7e9017d6e..d9d5e007e8 100644 --- a/MediaBrowser.ServerApplication/ApplicationHost.cs +++ b/MediaBrowser.ServerApplication/ApplicationHost.cs @@ -503,7 +503,7 @@ namespace MediaBrowser.ServerApplication var appThemeManager = new AppThemeManager(ApplicationPaths, FileSystemManager, JsonSerializer, Logger); RegisterSingleInstance(appThemeManager); - var dlnaManager = new DlnaManager(XmlSerializer, FileSystemManager, ApplicationPaths, LogManager.GetLogger("DLNA")); + var dlnaManager = new DlnaManager(XmlSerializer, FileSystemManager, ApplicationPaths, LogManager.GetLogger("DLNA"), JsonSerializer); RegisterSingleInstance(dlnaManager); var collectionManager = new CollectionManager(LibraryManager, FileSystemManager, LibraryMonitor);