From 4e2764e516ba62506aa85765401769d0bc7192aa Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Wed, 26 Mar 2014 11:06:48 -0400 Subject: [PATCH] Create profile xml structure --- .../Playback/BaseStreamingService.cs | 32 +-- MediaBrowser.Api/Playback/StreamRequest.cs | 3 + MediaBrowser.Controller/Dlna/CodecProfile.cs | 12 + .../Dlna/ContainerProfile.cs | 4 + .../Dlna/DeviceIdentification.cs | 7 + MediaBrowser.Controller/Dlna/DeviceProfile.cs | 40 ++-- .../Dlna/DirectPlayProfile.cs | 7 + MediaBrowser.Controller/Dlna/IDlnaManager.cs | 22 +- MediaBrowser.Controller/Dlna/MediaProfile.cs | 11 + .../Dlna/TranscodingProfile.cs | 14 ++ MediaBrowser.Dlna/DlnaManager.cs | 207 +++++++++++++++++- MediaBrowser.Dlna/MediaBrowser.Dlna.csproj | 22 +- .../PlayTo/CurrentIdEventArgs.cs | 14 +- MediaBrowser.Dlna/PlayTo/Device.cs | 7 +- MediaBrowser.Dlna/PlayTo/DlnaController.cs | 32 +-- MediaBrowser.Dlna/PlayTo/PlaylistItem.cs | 2 + MediaBrowser.Dlna/PlayTo/StreamHelper.cs | 1 + MediaBrowser.Dlna/Profiles/DefaultProfile.cs | 2 + MediaBrowser.Dlna/Profiles/DenonAvrProfile.cs | 4 +- .../Profiles/Foobar2000Profile.cs | 4 +- MediaBrowser.Dlna/Profiles/LgTvProfile.cs | 4 +- .../Profiles/LinksysDMA2100Profile.cs | 4 +- .../Profiles/PanasonicVieraProfile.cs | 36 +-- .../Profiles/SamsungSmartTvProfile.cs | 4 +- .../Profiles/SonyBlurayPlayer2013Profile.cs | 4 +- .../Profiles/SonyBlurayPlayerProfile.cs | 4 +- .../Profiles/SonyBravia2010Profile.cs | 4 +- .../Profiles/SonyBravia2011Profile.cs | 4 +- .../Profiles/SonyBravia2012Profile.cs | 4 +- .../Profiles/SonyBravia2013Profile.cs | 4 +- MediaBrowser.Dlna/Profiles/SonyPs3Profile.cs | 4 +- MediaBrowser.Dlna/Profiles/WdtvLiveProfile.cs | 4 +- MediaBrowser.Dlna/Profiles/Xbox360Profile.cs | 4 +- MediaBrowser.Dlna/Profiles/XboxOneProfile.cs | 4 +- MediaBrowser.Dlna/Profiles/Xml/Default.xml | 39 ++++ MediaBrowser.Dlna/Profiles/Xml/Denon AVR.xml | 43 ++++ .../Profiles/Xml/LG Smart TV.xml | 71 ++++++ .../Profiles/Xml/Linksys DMA2100.xml | 43 ++++ .../Profiles/Xml/Panasonic Viera.xml | 64 ++++++ .../Profiles/Xml/Samsung Smart TV.xml | 100 +++++++++ .../Profiles/Xml/Sony Blu-ray Player 2013.xml | 67 ++++++ .../Profiles/Xml/Sony Blu-ray Player.xml | 95 ++++++++ .../Profiles/Xml/Sony Bravia (2010).xml | 98 +++++++++ .../Profiles/Xml/Sony Bravia (2011).xml | 101 +++++++++ .../Profiles/Xml/Sony Bravia (2012).xml | 84 +++++++ .../Profiles/Xml/Sony Bravia (2013).xml | 84 +++++++ .../Profiles/Xml/Sony PlayStation 3.xml | 92 ++++++++ MediaBrowser.Dlna/Profiles/Xml/WDTV Live.xml | 78 +++++++ MediaBrowser.Dlna/Profiles/Xml/Xbox 360.xml | 103 +++++++++ MediaBrowser.Dlna/Profiles/Xml/Xbox One.xml | 45 ++++ MediaBrowser.Dlna/Profiles/Xml/foobar2000.xml | 45 ++++ .../MediaBrowser.Model.Portable.csproj | 3 + .../MediaBrowser.Model.net35.csproj | 3 + MediaBrowser.Model/Dlna/DeviceProfileInfo.cs | 30 +++ MediaBrowser.Model/MediaBrowser.Model.csproj | 1 + .../LiveTv/LiveTvManager.cs | 7 +- .../ApplicationHost.cs | 10 +- .../MediaBrowser.WebDashboard.csproj | 8 +- 58 files changed, 1727 insertions(+), 122 deletions(-) create mode 100644 MediaBrowser.Dlna/Profiles/Xml/Default.xml create mode 100644 MediaBrowser.Dlna/Profiles/Xml/Denon AVR.xml create mode 100644 MediaBrowser.Dlna/Profiles/Xml/LG Smart TV.xml create mode 100644 MediaBrowser.Dlna/Profiles/Xml/Linksys DMA2100.xml create mode 100644 MediaBrowser.Dlna/Profiles/Xml/Panasonic Viera.xml create mode 100644 MediaBrowser.Dlna/Profiles/Xml/Samsung Smart TV.xml create mode 100644 MediaBrowser.Dlna/Profiles/Xml/Sony Blu-ray Player 2013.xml create mode 100644 MediaBrowser.Dlna/Profiles/Xml/Sony Blu-ray Player.xml create mode 100644 MediaBrowser.Dlna/Profiles/Xml/Sony Bravia (2010).xml create mode 100644 MediaBrowser.Dlna/Profiles/Xml/Sony Bravia (2011).xml create mode 100644 MediaBrowser.Dlna/Profiles/Xml/Sony Bravia (2012).xml create mode 100644 MediaBrowser.Dlna/Profiles/Xml/Sony Bravia (2013).xml create mode 100644 MediaBrowser.Dlna/Profiles/Xml/Sony PlayStation 3.xml create mode 100644 MediaBrowser.Dlna/Profiles/Xml/WDTV Live.xml create mode 100644 MediaBrowser.Dlna/Profiles/Xml/Xbox 360.xml create mode 100644 MediaBrowser.Dlna/Profiles/Xml/Xbox One.xml create mode 100644 MediaBrowser.Dlna/Profiles/Xml/foobar2000.xml create mode 100644 MediaBrowser.Model/Dlna/DeviceProfileInfo.cs diff --git a/MediaBrowser.Api/Playback/BaseStreamingService.cs b/MediaBrowser.Api/Playback/BaseStreamingService.cs index f65949ac7d..c365fcd829 100644 --- a/MediaBrowser.Api/Playback/BaseStreamingService.cs +++ b/MediaBrowser.Api/Playback/BaseStreamingService.cs @@ -1210,85 +1210,89 @@ namespace MediaBrowser.Api.Playback if (i == 0) { - request.DeviceId = val; + request.DeviceProfileId = val; } else if (i == 1) { - request.MediaSourceId = val; + request.DeviceId = val; } else if (i == 2) { - request.Static = string.Equals("true", val, StringComparison.OrdinalIgnoreCase); + request.MediaSourceId = val; } else if (i == 3) + { + request.Static = string.Equals("true", val, StringComparison.OrdinalIgnoreCase); + } + else if (i == 4) { if (videoRequest != null) { videoRequest.VideoCodec = val; } } - else if (i == 4) + else if (i == 5) { request.AudioCodec = val; } - else if (i == 5) + else if (i == 6) { if (videoRequest != null) { videoRequest.AudioStreamIndex = int.Parse(val, UsCulture); } } - else if (i == 6) + else if (i == 7) { if (videoRequest != null) { videoRequest.SubtitleStreamIndex = int.Parse(val, UsCulture); } } - else if (i == 7) + else if (i == 8) { if (videoRequest != null) { videoRequest.VideoBitRate = int.Parse(val, UsCulture); } } - else if (i == 8) + else if (i == 9) { request.AudioBitRate = int.Parse(val, UsCulture); } - else if (i == 9) + else if (i == 10) { request.MaxAudioChannels = int.Parse(val, UsCulture); } - else if (i == 10) + else if (i == 11) { if (videoRequest != null) { videoRequest.MaxWidth = int.Parse(val, UsCulture); } } - else if (i == 11) + else if (i == 12) { if (videoRequest != null) { videoRequest.MaxHeight = int.Parse(val, UsCulture); } } - else if (i == 12) + else if (i == 13) { if (videoRequest != null) { videoRequest.Framerate = int.Parse(val, UsCulture); } } - else if (i == 13) + else if (i == 14) { if (videoRequest != null) { request.StartTimeTicks = long.Parse(val, UsCulture); } } - else if (i == 14) + else if (i == 15) { if (videoRequest != null) { diff --git a/MediaBrowser.Api/Playback/StreamRequest.cs b/MediaBrowser.Api/Playback/StreamRequest.cs index 8db5920f6b..0eb2984fb5 100644 --- a/MediaBrowser.Api/Playback/StreamRequest.cs +++ b/MediaBrowser.Api/Playback/StreamRequest.cs @@ -65,6 +65,9 @@ namespace MediaBrowser.Api.Playback [ApiMember(Name = "Static", Description = "Optional. If true, the original file will be streamed statically without any encoding. Use either no url extension or the original file extension. true/false", IsRequired = false, DataType = "bool", ParameterType = "query", Verb = "GET")] public bool Static { get; set; } + [ApiMember(Name = "DeviceProfileId", Description = "Optional. The dlna device profile id to utilize.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")] + public string DeviceProfileId { get; set; } + /// /// For testing purposes /// diff --git a/MediaBrowser.Controller/Dlna/CodecProfile.cs b/MediaBrowser.Controller/Dlna/CodecProfile.cs index 0f61cad98d..75f80ed3b1 100644 --- a/MediaBrowser.Controller/Dlna/CodecProfile.cs +++ b/MediaBrowser.Controller/Dlna/CodecProfile.cs @@ -1,13 +1,18 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Xml.Serialization; namespace MediaBrowser.Controller.Dlna { public class CodecProfile { + [XmlAttribute("type")] public CodecType Type { get; set; } + public ProfileCondition[] Conditions { get; set; } + + [XmlAttribute("codec")] public string Codec { get; set; } public CodecProfile() @@ -37,9 +42,16 @@ namespace MediaBrowser.Controller.Dlna public class ProfileCondition { + [XmlAttribute("condition")] public ProfileConditionType Condition { get; set; } + + [XmlAttribute("property")] public ProfileConditionValue Property { get; set; } + + [XmlAttribute("value")] public string Value { get; set; } + + [XmlAttribute("isRequired")] public bool IsRequired { get; set; } public ProfileCondition() diff --git a/MediaBrowser.Controller/Dlna/ContainerProfile.cs b/MediaBrowser.Controller/Dlna/ContainerProfile.cs index 3bd3c9eaf6..1029ba72cb 100644 --- a/MediaBrowser.Controller/Dlna/ContainerProfile.cs +++ b/MediaBrowser.Controller/Dlna/ContainerProfile.cs @@ -1,12 +1,16 @@ using System.Collections.Generic; using System.Linq; +using System.Xml.Serialization; namespace MediaBrowser.Controller.Dlna { public class ContainerProfile { + [XmlAttribute("type")] public DlnaProfileType Type { get; set; } public ProfileCondition[] Conditions { get; set; } + + [XmlAttribute("container")] public string Container { get; set; } public ContainerProfile() diff --git a/MediaBrowser.Controller/Dlna/DeviceIdentification.cs b/MediaBrowser.Controller/Dlna/DeviceIdentification.cs index 7b8e3a1e72..c9cd4bc703 100644 --- a/MediaBrowser.Controller/Dlna/DeviceIdentification.cs +++ b/MediaBrowser.Controller/Dlna/DeviceIdentification.cs @@ -1,4 +1,6 @@  +using System.Xml.Serialization; + namespace MediaBrowser.Controller.Dlna { public class DeviceIdentification @@ -62,8 +64,13 @@ namespace MediaBrowser.Controller.Dlna public class HttpHeaderInfo { + [XmlAttribute("name")] public string Name { get; set; } + + [XmlAttribute("value")] public string Value { get; set; } + + [XmlAttribute("match")] public HeaderMatchType Match { get; set; } } diff --git a/MediaBrowser.Controller/Dlna/DeviceProfile.cs b/MediaBrowser.Controller/Dlna/DeviceProfile.cs index f34c4bf645..f5aff02629 100644 --- a/MediaBrowser.Controller/Dlna/DeviceProfile.cs +++ b/MediaBrowser.Controller/Dlna/DeviceProfile.cs @@ -1,9 +1,12 @@ using MediaBrowser.Model.Entities; using System; using System.Linq; +using System.Runtime.Serialization; +using System.Xml.Serialization; namespace MediaBrowser.Controller.Dlna { + [XmlRoot("Profile")] public class DeviceProfile { /// @@ -12,19 +15,9 @@ namespace MediaBrowser.Controller.Dlna /// The name. public string Name { get; set; } - /// - /// Gets or sets the transcoding profiles. - /// - /// The transcoding profiles. - public TranscodingProfile[] TranscodingProfiles { get; set; } - - /// - /// Gets or sets the direct play profiles. - /// - /// The direct play profiles. - public DirectPlayProfile[] DirectPlayProfiles { get; set; } - - public ContainerProfile[] ContainerProfiles { get; set; } + [XmlIgnore] + [IgnoreDataMember] + public string Id { get; set; } /// /// Gets or sets the identification. @@ -57,14 +50,27 @@ namespace MediaBrowser.Controller.Dlna public string ProtocolInfo { get; set; } - public MediaProfile[] MediaProfiles { get; set; } - public CodecProfile[] CodecProfiles { get; set; } - public int TimelineOffsetSeconds { get; set; } - public bool RequiresPlainVideoItems { get; set; } public bool RequiresPlainFolders { get; set; } + /// + /// Gets or sets the direct play profiles. + /// + /// The direct play profiles. + public DirectPlayProfile[] DirectPlayProfiles { get; set; } + + /// + /// Gets or sets the transcoding profiles. + /// + /// The transcoding profiles. + public TranscodingProfile[] TranscodingProfiles { get; set; } + + public ContainerProfile[] ContainerProfiles { get; set; } + + public CodecProfile[] CodecProfiles { get; set; } + public MediaProfile[] MediaProfiles { get; set; } + public DeviceProfile() { DirectPlayProfiles = new DirectPlayProfile[] { }; diff --git a/MediaBrowser.Controller/Dlna/DirectPlayProfile.cs b/MediaBrowser.Controller/Dlna/DirectPlayProfile.cs index 686b31287e..ad70640daa 100644 --- a/MediaBrowser.Controller/Dlna/DirectPlayProfile.cs +++ b/MediaBrowser.Controller/Dlna/DirectPlayProfile.cs @@ -1,14 +1,21 @@ using System.Collections.Generic; using System.Linq; +using System.Xml.Serialization; namespace MediaBrowser.Controller.Dlna { public class DirectPlayProfile { + [XmlAttribute("container")] public string Container { get; set; } + + [XmlAttribute("audioCodec")] public string AudioCodec { get; set; } + + [XmlAttribute("videoCodec")] public string VideoCodec { get; set; } + [XmlAttribute("type")] public DlnaProfileType Type { get; set; } public List GetContainers() diff --git a/MediaBrowser.Controller/Dlna/IDlnaManager.cs b/MediaBrowser.Controller/Dlna/IDlnaManager.cs index 22d13fc3ad..dd9b0e8a84 100644 --- a/MediaBrowser.Controller/Dlna/IDlnaManager.cs +++ b/MediaBrowser.Controller/Dlna/IDlnaManager.cs @@ -1,20 +1,15 @@ -using System.Collections.Generic; +using MediaBrowser.Model.Dlna; +using System.Collections.Generic; namespace MediaBrowser.Controller.Dlna { public interface IDlnaManager { /// - /// Gets the dlna profiles. + /// Gets the profile infos. /// - /// IEnumerable{DlnaProfile}. - IEnumerable GetProfiles(); - - /// - /// Gets the default profile. - /// - /// DlnaProfile. - DeviceProfile GetDefaultProfile(); + /// IEnumerable{DeviceProfileInfo}. + IEnumerable GetProfileInfos(); /// /// Gets the profile. @@ -23,6 +18,13 @@ namespace MediaBrowser.Controller.Dlna /// DeviceProfile. DeviceProfile GetProfile(IDictionary headers); + /// + /// Gets the profile. + /// + /// The identifier. + /// DeviceProfile. + DeviceProfile GetProfile(string id); + /// /// Gets the profile. /// diff --git a/MediaBrowser.Controller/Dlna/MediaProfile.cs b/MediaBrowser.Controller/Dlna/MediaProfile.cs index 9a9b56ddd5..bf3057294c 100644 --- a/MediaBrowser.Controller/Dlna/MediaProfile.cs +++ b/MediaBrowser.Controller/Dlna/MediaProfile.cs @@ -1,16 +1,27 @@ using System.Collections.Generic; using System.Linq; +using System.Xml.Serialization; namespace MediaBrowser.Controller.Dlna { public class MediaProfile { + [XmlAttribute("container")] public string Container { get; set; } + + [XmlAttribute("audioCodec")] public string AudioCodec { get; set; } + + [XmlAttribute("videoCodec")] public string VideoCodec { get; set; } + [XmlAttribute("type")] public DlnaProfileType Type { get; set; } + + [XmlAttribute("orgPn")] public string OrgPn { get; set; } + + [XmlAttribute("mimeType")] public string MimeType { get; set; } public ProfileCondition[] Conditions { get; set; } diff --git a/MediaBrowser.Controller/Dlna/TranscodingProfile.cs b/MediaBrowser.Controller/Dlna/TranscodingProfile.cs index d4cfae9893..289333aa77 100644 --- a/MediaBrowser.Controller/Dlna/TranscodingProfile.cs +++ b/MediaBrowser.Controller/Dlna/TranscodingProfile.cs @@ -1,19 +1,30 @@ using System.Collections.Generic; using System.Linq; +using System.Xml.Serialization; namespace MediaBrowser.Controller.Dlna { public class TranscodingProfile { + [XmlAttribute("container")] public string Container { get; set; } + [XmlAttribute("type")] public DlnaProfileType Type { get; set; } + [XmlAttribute("videoCodec")] public string VideoCodec { get; set; } + + [XmlAttribute("audioCodec")] public string AudioCodec { get; set; } + [XmlAttribute("estimateContentLength")] public bool EstimateContentLength { get; set; } + + [XmlAttribute("enableMpegtsM2TsMode")] public bool EnableMpegtsM2TsMode { get; set; } + + [XmlAttribute("transcodeSeekInfo")] public TranscodeSeekInfo TranscodeSeekInfo { get; set; } public TranscodingSetting[] Settings { get; set; } @@ -32,7 +43,10 @@ namespace MediaBrowser.Controller.Dlna public class TranscodingSetting { + [XmlAttribute("name")] public TranscodingSettingType Name { get; set; } + + [XmlAttribute("value")] public string Value { get; set; } } diff --git a/MediaBrowser.Dlna/DlnaManager.cs b/MediaBrowser.Dlna/DlnaManager.cs index 78876d239c..9d9df01e6d 100644 --- a/MediaBrowser.Dlna/DlnaManager.cs +++ b/MediaBrowser.Dlna/DlnaManager.cs @@ -1,10 +1,14 @@ using MediaBrowser.Common.Configuration; +using MediaBrowser.Common.Extensions; using MediaBrowser.Common.IO; using MediaBrowser.Controller.Dlna; using MediaBrowser.Dlna.Profiles; +using MediaBrowser.Model.Dlna; +using MediaBrowser.Model.Logging; using MediaBrowser.Model.Serialization; using System; using System.Collections.Generic; +using System.IO; using System.Linq; using System.Text.RegularExpressions; @@ -12,21 +16,36 @@ namespace MediaBrowser.Dlna { public class DlnaManager : IDlnaManager { - private IApplicationPaths _appPaths; + private readonly IApplicationPaths _appPaths; private readonly IXmlSerializer _xmlSerializer; private readonly IFileSystem _fileSystem; - private readonly IJsonSerializer _jsonSerializer; + private readonly ILogger _logger; - public DlnaManager(IXmlSerializer xmlSerializer, IFileSystem fileSystem, IJsonSerializer jsonSerializer) + public DlnaManager(IXmlSerializer xmlSerializer, IFileSystem fileSystem, IApplicationPaths appPaths, ILogger logger) { _xmlSerializer = xmlSerializer; _fileSystem = fileSystem; - _jsonSerializer = jsonSerializer; + _appPaths = appPaths; + _logger = logger; - GetProfiles(); + //DumpProfiles(); } public IEnumerable GetProfiles() + { + ExtractProfilesIfNeeded(); + + var list = GetProfiles(UserProfilesPath) + .OrderBy(i => i.Name) + .ToList(); + + list.AddRange(GetProfiles(SystemProfilesPath) + .OrderBy(i => i.Name)); + + return list; + } + + private void DumpProfiles() { var list = new List { @@ -45,16 +64,40 @@ namespace MediaBrowser.Dlna new DenonAvrProfile(), new LinksysDMA2100Profile(), new LgTvProfile(), - new Foobar2000Profile() + new Foobar2000Profile(), + new DefaultProfile() }; foreach (var item in list) { - //_xmlSerializer.SerializeToFile(item, "d:\\" + _fileSystem.GetValidFilename(item.Name) + ".xml"); - //_jsonSerializer.SerializeToFile(item, "d:\\" + _fileSystem.GetValidFilename(item.Name) + ".json"); + _xmlSerializer.SerializeToFile(item, "d:\\" + _fileSystem.GetValidFilename(item.Name) + ".xml"); } + } - return list; + private bool _extracted; + private readonly object _syncLock = new object(); + private void ExtractProfilesIfNeeded() + { + if (!_extracted) + { + lock (_syncLock) + { + if (!_extracted) + { + try + { + ExtractSystemProfiles(); + } + catch (Exception ex) + { + _logger.ErrorException("Error extracting DLNA profiles.", ex); + } + + _extracted = true; + } + + } + } } public DeviceProfile GetDefaultProfile() @@ -64,8 +107,12 @@ namespace MediaBrowser.Dlna public DeviceProfile GetProfile(DeviceIdentification deviceInfo) { - return GetProfiles().FirstOrDefault(i => IsMatch(deviceInfo, i.Identification)) ?? + var profile = GetProfiles().FirstOrDefault(i => IsMatch(deviceInfo, i.Identification)) ?? GetDefaultProfile(); + + _logger.Debug("Found matching device profile: {0}", profile.Name); + + return profile; } private bool IsMatch(DeviceIdentification deviceInfo, DeviceIdentification profileInfo) @@ -159,5 +206,145 @@ namespace MediaBrowser.Dlna return false; } + + private string UserProfilesPath + { + get + { + return Path.Combine(_appPaths.ConfigurationDirectoryPath, "dlna", "user"); + } + } + + private string SystemProfilesPath + { + get + { + return Path.Combine(_appPaths.ConfigurationDirectoryPath, "dlna", "system"); + } + } + + private IEnumerable GetProfiles(string path) + { + try + { + return new DirectoryInfo(path) + .EnumerateFiles("*", SearchOption.TopDirectoryOnly) + .Where(i => string.Equals(i.Extension, ".xml", StringComparison.OrdinalIgnoreCase)) + .Select(i => ParseProfileXmlFile(i.FullName)) + .Where(i => i != null) + .ToList(); + } + catch (DirectoryNotFoundException) + { + return new List(); + } + } + + private DeviceProfile ParseProfileXmlFile(string path) + { + try + { + var profile = (DeviceProfile)_xmlSerializer.DeserializeFromFile(typeof(DeviceProfile), path); + + profile.Id = path.ToLower().GetMD5().ToString("N"); + + return profile; + } + catch (Exception ex) + { + _logger.ErrorException("Error parsing profile xml: {0}", ex, path); + + return null; + } + } + + public DeviceProfile GetProfile(string id) + { + var info = GetProfileInfosInternal().First(i => string.Equals(i.Info.Id, id)); + + return ParseProfileXmlFile(info.Path); + } + + private IEnumerable GetProfileInfosInternal() + { + ExtractProfilesIfNeeded(); + + return GetProfileInfos(UserProfilesPath, DeviceProfileType.User) + .Concat(GetProfileInfos(SystemProfilesPath, DeviceProfileType.System)) + .OrderBy(i => i.Info.Type == DeviceProfileType.User ? 0 : 1) + .ThenBy(i => i.Info.Name); + } + + public IEnumerable GetProfileInfos() + { + return GetProfileInfosInternal().Select(i => i.Info); + } + + private IEnumerable GetProfileInfos(string path, DeviceProfileType type) + { + try + { + return new DirectoryInfo(path) + .EnumerateFiles("*", SearchOption.TopDirectoryOnly) + .Where(i => string.Equals(i.Extension, ".xml", StringComparison.OrdinalIgnoreCase)) + .Select(i => new InternalProfileInfo + { + Path = i.FullName, + + Info = new DeviceProfileInfo + { + Id = i.FullName.ToLower().GetMD5().ToString("N"), + Name = Path.GetFileNameWithoutExtension(i.FullName), + Type = type + } + }) + .ToList(); + } + catch (DirectoryNotFoundException) + { + return new List(); + } + } + + private void ExtractSystemProfiles() + { + var assembly = GetType().Assembly; + var namespaceName = GetType().Namespace + ".Profiles.Xml."; + + var systemProfilesPath = SystemProfilesPath; + + foreach (var name in assembly.GetManifestResourceNames() + .Where(i => i.StartsWith(namespaceName)) + .ToList()) + { + var filename = Path.GetFileName(name).Substring(namespaceName.Length); + + var path = Path.Combine(systemProfilesPath, filename); + + using (var stream = assembly.GetManifestResourceStream(name)) + { + var fileInfo = new FileInfo(path); + + if (!fileInfo.Exists || fileInfo.Length != stream.Length) + { + Directory.CreateDirectory(systemProfilesPath); + + using (var fileStream = _fileSystem.GetFileStream(path, FileMode.Create, FileAccess.Write, FileShare.Read)) + { + stream.CopyTo(fileStream); + } + } + } + } + + // Not necessary, but just to make it easy to find + Directory.CreateDirectory(UserProfilesPath); + } + + class InternalProfileInfo + { + internal DeviceProfileInfo Info { get; set; } + internal string Path { get; set; } + } } } \ No newline at end of file diff --git a/MediaBrowser.Dlna/MediaBrowser.Dlna.csproj b/MediaBrowser.Dlna/MediaBrowser.Dlna.csproj index bdfcae39b6..df1fed12f0 100644 --- a/MediaBrowser.Dlna/MediaBrowser.Dlna.csproj +++ b/MediaBrowser.Dlna/MediaBrowser.Dlna.csproj @@ -117,7 +117,27 @@ MediaBrowser.Model - + + + + + + + + + + + + + + + + + + + + +