From c1b3f2c136201cc5d260270a427333ca79b004f2 Mon Sep 17 00:00:00 2001 From: Jim Cartlidge Date: Sun, 13 Sep 2020 14:31:12 +0100 Subject: ContentDirectory --- Emby.Dlna/ContentDirectory/ControlHandler.cs | 541 ++++++++++++++++++++++----- 1 file changed, 453 insertions(+), 88 deletions(-) (limited to 'Emby.Dlna/ContentDirectory/ControlHandler.cs') diff --git a/Emby.Dlna/ContentDirectory/ControlHandler.cs b/Emby.Dlna/ContentDirectory/ControlHandler.cs index 4b108b89e..31f8ca772 100644 --- a/Emby.Dlna/ContentDirectory/ControlHandler.cs +++ b/Emby.Dlna/ContentDirectory/ControlHandler.cs @@ -1,6 +1,5 @@ -#pragma warning disable CS1591 - using System; +using System.Collections; using System.Collections.Generic; using System.Globalization; using System.IO; @@ -8,6 +7,7 @@ using System.Linq; using System.Text; using System.Threading; using System.Xml; +using Emby.Dlna.Configuration; using Emby.Dlna.Didl; using Emby.Dlna.Service; using Jellyfin.Data.Entities; @@ -38,6 +38,9 @@ using Series = MediaBrowser.Controller.Entities.TV.Series; namespace Emby.Dlna.ContentDirectory { + /// + /// Defines the . + /// public class ControlHandler : BaseControlHandler { private const string NsDc = "http://purl.org/dc/elements/1.1/"; @@ -58,6 +61,24 @@ namespace Emby.Dlna.ContentDirectory private readonly DeviceProfile _profile; + /// + /// Initializes a new instance of the class. + /// + /// The for use with the instance. + /// The for use with the instance. + /// The for use with the instance. + /// The server address to use in this instance> for use with the instance. + /// The for use with the instance. + /// The for use with the instance. + /// The for use with the instance. + /// The for use with the instance. + /// The system id for use with the instance. + /// The for use with the instance. + /// The for use with the instance. + /// The for use with the instance. + /// The for use with the instance. + /// The for use with the instance. + /// The for use with the instance. public ControlHandler( ILogger logger, ILibraryManager libraryManager, @@ -102,6 +123,16 @@ namespace Emby.Dlna.ContentDirectory /// protected override void WriteResult(string methodName, IDictionary methodParams, XmlWriter xmlWriter) { + if (xmlWriter == null) + { + throw new ArgumentNullException(nameof(xmlWriter)); + } + + if (methodParams == null) + { + throw new ArgumentNullException(nameof(methodParams)); + } + const string DeviceId = "test"; if (string.Equals(methodName, "GetSearchCapabilities", StringComparison.OrdinalIgnoreCase)) @@ -167,6 +198,10 @@ namespace Emby.Dlna.ContentDirectory throw new ResourceNotFoundException("Unexpected control request name: " + methodName); } + /// + /// Adds a "XSetBookmark" element to the xml document. + /// + /// The . private void HandleXSetBookmark(IDictionary sparams) { var id = sparams["ObjectID"]; @@ -189,41 +224,69 @@ namespace Emby.Dlna.ContentDirectory CancellationToken.None); } - private void HandleGetSearchCapabilities(XmlWriter xmlWriter) + /// + /// Adds the "SearchCaps" element to the xml document. + /// + /// The . + private static void HandleGetSearchCapabilities(XmlWriter xmlWriter) { xmlWriter.WriteElementString( "SearchCaps", "res@resolution,res@size,res@duration,dc:title,dc:creator,upnp:actor,upnp:artist,upnp:genre,upnp:album,dc:date,upnp:class,@id,@refID,@protocolInfo,upnp:author,dc:description,pv:avKeywords"); } - private void HandleGetSortCapabilities(XmlWriter xmlWriter) + /// + /// Adds the "SortCaps" element to the xml document. + /// + /// The . + private static void HandleGetSortCapabilities(XmlWriter xmlWriter) { xmlWriter.WriteElementString( "SortCaps", "res@duration,res@size,res@bitrate,dc:date,dc:title,dc:size,upnp:album,upnp:artist,upnp:albumArtist,upnp:episodeNumber,upnp:genre,upnp:originalTrackNumber,upnp:rating"); } - private void HandleGetSortExtensionCapabilities(XmlWriter xmlWriter) + /// + /// Adds the "SortExtensionCaps" element to the xml document. + /// + /// The . + private static void HandleGetSortExtensionCapabilities(XmlWriter xmlWriter) { xmlWriter.WriteElementString( "SortExtensionCaps", "res@duration,res@size,res@bitrate,dc:date,dc:title,dc:size,upnp:album,upnp:artist,upnp:albumArtist,upnp:episodeNumber,upnp:genre,upnp:originalTrackNumber,upnp:rating"); } + /// + /// Adds the "Id" element to the xml document. + /// + /// The . private void HandleGetSystemUpdateID(XmlWriter xmlWriter) { xmlWriter.WriteElementString("Id", _systemUpdateId.ToString(CultureInfo.InvariantCulture)); } - private void HandleGetFeatureList(XmlWriter xmlWriter) + /// + /// Adds the "FeatureList" element to the xml document. + /// + /// The . + private static void HandleGetFeatureList(XmlWriter xmlWriter) { xmlWriter.WriteElementString("FeatureList", WriteFeatureListXml()); } - private void HandleXGetFeatureList(XmlWriter xmlWriter) + /// + /// Adds the "FeatureList" element to the xml document. + /// + /// The . + private static void HandleXGetFeatureList(XmlWriter xmlWriter) => HandleGetFeatureList(xmlWriter); - private string WriteFeatureListXml() + /// + /// Builds a static feature list. + /// + /// The xml feature list. + private static string WriteFeatureListXml() { // TODO: clean this up var builder = new StringBuilder(); @@ -242,9 +305,16 @@ namespace Emby.Dlna.ContentDirectory return builder.ToString(); } - public string GetValueOrDefault(IDictionary sparams, string key, string defaultValue) + /// + /// Returns the value in the key of the dictionary, or defaultValue if it doesn't exist. + /// + /// The . + /// The key. + /// The defaultValue. + /// The . + public static string GetValueOrDefault(IDictionary sparams, string key, string defaultValue) { - if (sparams.TryGetValue(key, out string val)) + if (sparams != null && sparams.TryGetValue(key, out string val)) { return val; } @@ -252,6 +322,12 @@ namespace Emby.Dlna.ContentDirectory return defaultValue; } + /// + /// Builds the "Browse" xml response. + /// + /// The . + /// The . + /// The device Id to use. private void HandleBrowse(XmlWriter xmlWriter, IDictionary sparams, string deviceId) { var id = sparams["ObjectID"]; @@ -313,7 +389,6 @@ namespace Emby.Dlna.ContentDirectory } else { - var dlnaOptions = _config.GetDlnaConfiguration(); _didlBuilder.WriteItemElement(writer, item, _user, null, null, deviceId, filter); } @@ -326,7 +401,6 @@ namespace Emby.Dlna.ContentDirectory provided = childrenResult.Items.Count; - var dlnaOptions = _config.GetDlnaConfiguration(); foreach (var i in childrenResult.Items) { var childItem = i.Item; @@ -357,12 +431,24 @@ namespace Emby.Dlna.ContentDirectory xmlWriter.WriteElementString("UpdateID", _systemUpdateId.ToString(CultureInfo.InvariantCulture)); } + /// + /// Builds the response to the "X_BrowseByLetter request. + /// + /// The . + /// The . + /// The device id. private void HandleXBrowseByLetter(XmlWriter xmlWriter, IDictionary sparams, string deviceId) { // TODO: Implement this method HandleSearch(xmlWriter, sparams, deviceId); } + /// + /// Builds a response to the "Search" request. + /// + /// The xmlWriter. + /// The sparams. + /// The deviceId. private void HandleSearch(XmlWriter xmlWriter, IDictionary sparams, string deviceId) { var searchCriteria = new SearchCriteria(GetValueOrDefault(sparams, "SearchCriteria", string.Empty)); @@ -442,7 +528,17 @@ namespace Emby.Dlna.ContentDirectory xmlWriter.WriteElementString("UpdateID", _systemUpdateId.ToString(CultureInfo.InvariantCulture)); } - private QueryResult GetChildrenSorted(BaseItem item, User user, SearchCriteria search, SortCriteria sort, int? startIndex, int? limit) + /// + /// Returns the child items meeting the criteria. + /// + /// The . + /// The . + /// The . + /// The . + /// The start index. + /// The maximum number to return. + /// The . + private static QueryResult GetChildrenSorted(BaseItem item, User user, SearchCriteria search, SortCriteria sort, int? startIndex, int? limit) { var folder = (Folder)item; @@ -494,11 +590,25 @@ namespace Emby.Dlna.ContentDirectory }); } - private DtoOptions GetDtoOptions() + /// + /// Returns a new DtoOptions object. + /// + /// The . + private static DtoOptions GetDtoOptions() { return new DtoOptions(true); } + /// + /// Returns the User items meeting the criteria. + /// + /// The . + /// The . + /// The . + /// The . + /// The start index. + /// The maximum number to return. + /// The . private QueryResult GetUserItems(BaseItem item, StubType? stubType, User user, SortCriteria sort, int? startIndex, int? limit) { if (item is MusicGenre) @@ -568,6 +678,14 @@ namespace Emby.Dlna.ContentDirectory return ToResult(queryResult); } + /// + /// Returns the Live Tv Channels meeting the criteria. + /// + /// The . + /// The . + /// The start index. + /// The maximum number to return. + /// The . private QueryResult GetLiveTvChannels(User user, SortCriteria sort, int? startIndex, int? limit) { var query = new InternalItemsQuery(user) @@ -584,6 +702,16 @@ namespace Emby.Dlna.ContentDirectory return ToResult(result); } + /// + /// Returns the music folders meeting the criteria. + /// + /// The . + /// The . + /// The . + /// The . + /// The start index. + /// The maximum number to return. + /// The . private QueryResult GetMusicFolders(BaseItem item, User user, StubType? stubType, SortCriteria sort, int? startIndex, int? limit) { var query = new InternalItemsQuery(user) @@ -643,57 +771,58 @@ namespace Emby.Dlna.ContentDirectory return GetMusicGenres(item, user, query); } - var list = new List(); - - list.Add(new ServerItem(item) + var list = new List { - StubType = StubType.Latest - }); + new ServerItem(item) + { + StubType = StubType.Latest + }, - list.Add(new ServerItem(item) - { - StubType = StubType.Playlists - }); + new ServerItem(item) + { + StubType = StubType.Playlists + }, - list.Add(new ServerItem(item) - { - StubType = StubType.Albums - }); + new ServerItem(item) + { + StubType = StubType.Albums + }, - list.Add(new ServerItem(item) - { - StubType = StubType.AlbumArtists - }); + new ServerItem(item) + { + StubType = StubType.AlbumArtists + }, - list.Add(new ServerItem(item) - { - StubType = StubType.Artists - }); + new ServerItem(item) + { + StubType = StubType.Artists + }, - list.Add(new ServerItem(item) - { - StubType = StubType.Songs - }); + new ServerItem(item) + { + StubType = StubType.Songs + }, - list.Add(new ServerItem(item) - { - StubType = StubType.Genres - }); + new ServerItem(item) + { + StubType = StubType.Genres + }, - list.Add(new ServerItem(item) - { - StubType = StubType.FavoriteArtists - }); + new ServerItem(item) + { + StubType = StubType.FavoriteArtists + }, - list.Add(new ServerItem(item) - { - StubType = StubType.FavoriteAlbums - }); + new ServerItem(item) + { + StubType = StubType.FavoriteAlbums + }, - list.Add(new ServerItem(item) - { - StubType = StubType.FavoriteSongs - }); + new ServerItem(item) + { + StubType = StubType.FavoriteSongs + } + }; return new QueryResult { @@ -702,6 +831,16 @@ namespace Emby.Dlna.ContentDirectory }; } + /// + /// Returns the movie folders meeting the criteria. + /// + /// The . + /// The . + /// The . + /// The . + /// The start index. + /// The maximum number to return. + /// The . private QueryResult GetMovieFolders(BaseItem item, User user, StubType? stubType, SortCriteria sort, int? startIndex, int? limit) { var query = new InternalItemsQuery(user) @@ -776,6 +915,13 @@ namespace Emby.Dlna.ContentDirectory }; } + /// + /// Returns the folders meeting the criteria. + /// + /// The . + /// The start index. + /// The maximum number to return. + /// The . private QueryResult GetFolders(User user, int? startIndex, int? limit) { var folders = _libraryManager.GetUserRootFolder().GetChildren(user, true) @@ -796,6 +942,16 @@ namespace Emby.Dlna.ContentDirectory limit); } + /// + /// Returns the TV folders meeting the criteria. + /// + /// The . + /// The . + /// The . + /// The . + /// The start index. + /// The maximum number to return. + /// The . private QueryResult GetTvFolders(BaseItem item, User user, StubType? stubType, SortCriteria sort, int? startIndex, int? limit) { var query = new InternalItemsQuery(user) @@ -840,42 +996,43 @@ namespace Emby.Dlna.ContentDirectory return GetGenres(item, user, query); } - var list = new List(); - - list.Add(new ServerItem(item) + var list = new List { - StubType = StubType.ContinueWatching - }); + new ServerItem(item) + { + StubType = StubType.ContinueWatching + }, - list.Add(new ServerItem(item) - { - StubType = StubType.NextUp - }); + new ServerItem(item) + { + StubType = StubType.NextUp + }, - list.Add(new ServerItem(item) - { - StubType = StubType.Latest - }); + new ServerItem(item) + { + StubType = StubType.Latest + }, - list.Add(new ServerItem(item) - { - StubType = StubType.Series - }); + new ServerItem(item) + { + StubType = StubType.Series + }, - list.Add(new ServerItem(item) - { - StubType = StubType.FavoriteSeries - }); + new ServerItem(item) + { + StubType = StubType.FavoriteSeries + }, - list.Add(new ServerItem(item) - { - StubType = StubType.FavoriteEpisodes - }); + new ServerItem(item) + { + StubType = StubType.FavoriteEpisodes + }, - list.Add(new ServerItem(item) - { - StubType = StubType.Genres - }); + new ServerItem(item) + { + StubType = StubType.Genres + } + }; return new QueryResult { @@ -884,6 +1041,13 @@ namespace Emby.Dlna.ContentDirectory }; } + /// + /// Returns the Movies that are part watched that meet the criteria. + /// + /// The . + /// The . + /// The . + /// The . private QueryResult GetMovieContinueWatching(BaseItem parent, User user, InternalItemsQuery query) { query.Recursive = true; @@ -904,6 +1068,13 @@ namespace Emby.Dlna.ContentDirectory return ToResult(result); } + /// + /// Returns the series meeting the criteria. + /// + /// The . + /// The . + /// The . + /// The . private QueryResult GetSeries(BaseItem parent, User user, InternalItemsQuery query) { query.Recursive = true; @@ -917,6 +1088,13 @@ namespace Emby.Dlna.ContentDirectory return ToResult(result); } + /// + /// Returns the Movie folders meeting the criteria. + /// + /// The . + /// The . + /// The . + /// The . private QueryResult GetMovieMovies(BaseItem parent, User user, InternalItemsQuery query) { query.Recursive = true; @@ -930,6 +1108,12 @@ namespace Emby.Dlna.ContentDirectory return ToResult(result); } + /// + /// Returns the Movie collections meeting the criteria. + /// + /// The see cref="User"/>. + /// The see cref="InternalItemsQuery"/>. + /// The . private QueryResult GetMovieCollections(User user, InternalItemsQuery query) { query.Recursive = true; @@ -943,6 +1127,13 @@ namespace Emby.Dlna.ContentDirectory return ToResult(result); } + /// + /// Returns the Music albums meeting the criteria. + /// + /// The . + /// The . + /// The . + /// The . private QueryResult GetMusicAlbums(BaseItem parent, User user, InternalItemsQuery query) { query.Recursive = true; @@ -956,6 +1147,13 @@ namespace Emby.Dlna.ContentDirectory return ToResult(result); } + /// + /// Returns the Music songs meeting the criteria. + /// + /// The . + /// The . + /// The . + /// The . private QueryResult GetMusicSongs(BaseItem parent, User user, InternalItemsQuery query) { query.Recursive = true; @@ -969,6 +1167,13 @@ namespace Emby.Dlna.ContentDirectory return ToResult(result); } + /// + /// Returns the songs tagged as favourite that meet the criteria. + /// + /// The . + /// The . + /// The . + /// The . private QueryResult GetFavoriteSongs(BaseItem parent, User user, InternalItemsQuery query) { query.Recursive = true; @@ -982,6 +1187,13 @@ namespace Emby.Dlna.ContentDirectory return ToResult(result); } + /// + /// Returns the series tagged as favourite that meet the criteria. + /// + /// The . + /// The . + /// The . + /// The . private QueryResult GetFavoriteSeries(BaseItem parent, User user, InternalItemsQuery query) { query.Recursive = true; @@ -995,6 +1207,13 @@ namespace Emby.Dlna.ContentDirectory return ToResult(result); } + /// + /// Returns the episodes tagged as favourite that meet the criteria. + /// + /// The . + /// The . + /// The . + /// The . private QueryResult GetFavoriteEpisodes(BaseItem parent, User user, InternalItemsQuery query) { query.Recursive = true; @@ -1008,6 +1227,13 @@ namespace Emby.Dlna.ContentDirectory return ToResult(result); } + /// + /// Returns the movies tagged as favourite that meet the criteria. + /// + /// The . + /// The . + /// The . + /// The . private QueryResult GetMovieFavorites(BaseItem parent, User user, InternalItemsQuery query) { query.Recursive = true; @@ -1021,6 +1247,13 @@ namespace Emby.Dlna.ContentDirectory return ToResult(result); } + /// + /// /// Returns the albums tagged as favourite that meet the criteria. + /// + /// The . + /// The . + /// The . + /// The . private QueryResult GetFavoriteAlbums(BaseItem parent, User user, InternalItemsQuery query) { query.Recursive = true; @@ -1034,6 +1267,14 @@ namespace Emby.Dlna.ContentDirectory return ToResult(result); } + /// + /// Returns the genres meeting the criteria. + /// The GetGenres. + /// + /// The . + /// The . + /// The . + /// The . private QueryResult GetGenres(BaseItem parent, User user, InternalItemsQuery query) { var genresResult = _libraryManager.GetGenres(new InternalItemsQuery(user) @@ -1052,6 +1293,13 @@ namespace Emby.Dlna.ContentDirectory return ToResult(result); } + /// + /// Returns the music genres meeting the criteria. + /// + /// The . + /// The . + /// The . + /// The . private QueryResult GetMusicGenres(BaseItem parent, User user, InternalItemsQuery query) { var genresResult = _libraryManager.GetMusicGenres(new InternalItemsQuery(user) @@ -1070,6 +1318,13 @@ namespace Emby.Dlna.ContentDirectory return ToResult(result); } + /// + /// Returns the music albums by artist that meet the criteria. + /// + /// The . + /// The . + /// The . + /// The . private QueryResult GetMusicAlbumArtists(BaseItem parent, User user, InternalItemsQuery query) { var artists = _libraryManager.GetAlbumArtists(new InternalItemsQuery(user) @@ -1088,6 +1343,13 @@ namespace Emby.Dlna.ContentDirectory return ToResult(result); } + /// + /// Returns the music artists meeting the criteria. + /// + /// The . + /// The . + /// The . + /// The . private QueryResult GetMusicArtists(BaseItem parent, User user, InternalItemsQuery query) { var artists = _libraryManager.GetArtists(new InternalItemsQuery(user) @@ -1106,6 +1368,13 @@ namespace Emby.Dlna.ContentDirectory return ToResult(result); } + /// + /// Returns the artists tagged as favourite that meet the criteria. + /// + /// The . + /// The . + /// The . + /// The . private QueryResult GetFavoriteArtists(BaseItem parent, User user, InternalItemsQuery query) { var artists = _libraryManager.GetArtists(new InternalItemsQuery(user) @@ -1125,6 +1394,12 @@ namespace Emby.Dlna.ContentDirectory return ToResult(result); } + /// + /// Returns the music playlists meeting the criteria. + /// + /// The user. + /// The query. + /// The . private QueryResult GetMusicPlaylists(User user, InternalItemsQuery query) { query.Parent = null; @@ -1137,6 +1412,13 @@ namespace Emby.Dlna.ContentDirectory return ToResult(result); } + /// + /// Returns the latest music meeting the criteria. + /// + /// The . + /// The . + /// The . + /// The . private QueryResult GetMusicLatest(BaseItem parent, User user, InternalItemsQuery query) { query.OrderBy = Array.Empty<(string, SortOrder)>(); @@ -1155,6 +1437,12 @@ namespace Emby.Dlna.ContentDirectory return ToResult(items); } + /// + /// Returns the next up item meeting the criteria. + /// + /// The . + /// The . + /// The . private QueryResult GetNextUp(BaseItem parent, InternalItemsQuery query) { query.OrderBy = Array.Empty<(string, SortOrder)>(); @@ -1172,6 +1460,13 @@ namespace Emby.Dlna.ContentDirectory return ToResult(result); } + /// + /// Returns the latest tv meeting the criteria. + /// + /// The . + /// The . + /// The . + /// The . private QueryResult GetTvLatest(BaseItem parent, User user, InternalItemsQuery query) { query.OrderBy = Array.Empty<(string, SortOrder)>(); @@ -1190,6 +1485,13 @@ namespace Emby.Dlna.ContentDirectory return ToResult(items); } + /// + /// Returns the latest movies meeting the criteria. + /// + /// The . + /// The . + /// The . + /// The . private QueryResult GetMovieLatest(BaseItem parent, User user, InternalItemsQuery query) { query.OrderBy = Array.Empty<(string, SortOrder)>(); @@ -1208,6 +1510,16 @@ namespace Emby.Dlna.ContentDirectory return ToResult(items); } + /// + /// Returns music artist items that meet the criteria. + /// + /// The . + /// The . + /// The . + /// The . + /// The start index. + /// The maximum number to return. + /// The . private QueryResult GetMusicArtistItems(BaseItem item, Guid parentId, User user, SortCriteria sort, int? startIndex, int? limit) { var query = new InternalItemsQuery(user) @@ -1228,6 +1540,16 @@ namespace Emby.Dlna.ContentDirectory return ToResult(result); } + /// + /// Returns the genre items meeting the criteria. + /// + /// The . + /// The . + /// The . + /// The . + /// The start index. + /// The maximum number to return. + /// The . private QueryResult GetGenreItems(BaseItem item, Guid parentId, User user, SortCriteria sort, int? startIndex, int? limit) { var query = new InternalItemsQuery(user) @@ -1252,6 +1574,16 @@ namespace Emby.Dlna.ContentDirectory return ToResult(result); } + /// + /// Returns the music genre items meeting the criteria. + /// + /// The . + /// The . + /// The . + /// The . + /// The start index. + /// The maximum number to return. + /// The . private QueryResult GetMusicGenreItems(BaseItem item, Guid parentId, User user, SortCriteria sort, int? startIndex, int? limit) { var query = new InternalItemsQuery(user) @@ -1272,7 +1604,12 @@ namespace Emby.Dlna.ContentDirectory return ToResult(result); } - private QueryResult ToResult(BaseItem[] result) + /// + /// Converts a array into a . + /// + /// An array of . + /// A . + private static QueryResult ToResult(BaseItem[] result) { var serverItems = result .Select(i => new ServerItem(i)) @@ -1285,7 +1622,12 @@ namespace Emby.Dlna.ContentDirectory }; } - private QueryResult ToResult(QueryResult result) + /// + /// Converts a to a . + /// + /// A . + /// The . + private static QueryResult ToResult(QueryResult result) { var serverItems = result .Items @@ -1299,7 +1641,13 @@ namespace Emby.Dlna.ContentDirectory }; } - private void SetSorting(InternalItemsQuery query, SortCriteria sort, bool isPreSorted) + /// + /// Sets the sorting method on a query. + /// + /// The . + /// The . + /// True if pre-sorted. + private static void SetSorting(InternalItemsQuery query, SortCriteria sort, bool isPreSorted) { if (isPreSorted) { @@ -1311,13 +1659,25 @@ namespace Emby.Dlna.ContentDirectory } } - private QueryResult ApplyPaging(QueryResult result, int? startIndex, int? limit) + /// + /// Apply paging to a query. + /// + /// The . + /// The start index. + /// The maximum number to return. + /// A . + private static QueryResult ApplyPaging(QueryResult result, int? startIndex, int? limit) { result.Items = result.Items.Skip(startIndex ?? 0).Take(limit ?? int.MaxValue).ToArray(); return result; } + /// + /// Retreives the ServerItem id. + /// + /// The id. + /// The . private ServerItem GetItemFromObjectId(string id) { return DidlBuilder.IsIdRoot(id) @@ -1326,6 +1686,11 @@ namespace Emby.Dlna.ContentDirectory : ParseItemId(id); } + /// + /// Parses the item id into a . + /// + /// The . + /// The corresponding . private ServerItem ParseItemId(string id) { StubType? stubType = null; -- cgit v1.2.3