From 2714127d2b663b735048da6d9def08efa38f2b5f Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sat, 2 Aug 2014 22:16:37 -0400 Subject: fixes #791 - Support server-side playlists --- .../MediaBrowser.LocalMetadata.csproj | 1 + .../Parsers/BoxSetXmlParser.cs | 54 ----------------- .../Savers/FolderXmlSaver.cs | 14 +++-- .../Savers/PlaylistXmlSaver.cs | 68 ++++++++++++++++++++++ .../Savers/XmlSaverHelpers.cs | 31 +++++++--- 5 files changed, 99 insertions(+), 69 deletions(-) create mode 100644 MediaBrowser.LocalMetadata/Savers/PlaylistXmlSaver.cs (limited to 'MediaBrowser.LocalMetadata') diff --git a/MediaBrowser.LocalMetadata/MediaBrowser.LocalMetadata.csproj b/MediaBrowser.LocalMetadata/MediaBrowser.LocalMetadata.csproj index 2cc7e989b..b103d9f5a 100644 --- a/MediaBrowser.LocalMetadata/MediaBrowser.LocalMetadata.csproj +++ b/MediaBrowser.LocalMetadata/MediaBrowser.LocalMetadata.csproj @@ -83,6 +83,7 @@ + diff --git a/MediaBrowser.LocalMetadata/Parsers/BoxSetXmlParser.cs b/MediaBrowser.LocalMetadata/Parsers/BoxSetXmlParser.cs index 51a4684d7..85a72cf28 100644 --- a/MediaBrowser.LocalMetadata/Parsers/BoxSetXmlParser.cs +++ b/MediaBrowser.LocalMetadata/Parsers/BoxSetXmlParser.cs @@ -71,59 +71,5 @@ namespace MediaBrowser.LocalMetadata.Parsers item.LinkedChildren = list; } - - private LinkedChild GetLinkedChild(XmlReader reader) - { - reader.MoveToContent(); - - var linkedItem = new LinkedChild - { - Type = LinkedChildType.Manual - }; - - while (reader.Read()) - { - if (reader.NodeType == XmlNodeType.Element) - { - switch (reader.Name) - { - case "Name": - { - linkedItem.ItemName = reader.ReadElementContentAsString(); - break; - } - - case "Type": - { - linkedItem.ItemType = reader.ReadElementContentAsString(); - break; - } - - case "Year": - { - var val = reader.ReadElementContentAsString(); - - if (!string.IsNullOrWhiteSpace(val)) - { - int rval; - - if (int.TryParse(val, NumberStyles.Integer, UsCulture, out rval)) - { - linkedItem.ItemYear = rval; - } - } - - break; - } - - default: - reader.Skip(); - break; - } - } - } - - return string.IsNullOrWhiteSpace(linkedItem.ItemName) || string.IsNullOrWhiteSpace(linkedItem.ItemType) ? null : linkedItem; - } } } diff --git a/MediaBrowser.LocalMetadata/Savers/FolderXmlSaver.cs b/MediaBrowser.LocalMetadata/Savers/FolderXmlSaver.cs index 6dd65b69c..c38a33c40 100644 --- a/MediaBrowser.LocalMetadata/Savers/FolderXmlSaver.cs +++ b/MediaBrowser.LocalMetadata/Savers/FolderXmlSaver.cs @@ -1,12 +1,13 @@ -using System.Collections.Generic; -using System.IO; -using System.Text; -using System.Threading; -using MediaBrowser.Controller.Entities; +using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Entities.Audio; using MediaBrowser.Controller.Entities.Movies; using MediaBrowser.Controller.Entities.TV; using MediaBrowser.Controller.Library; +using MediaBrowser.Controller.Playlists; +using System.Collections.Generic; +using System.IO; +using System.Text; +using System.Threading; namespace MediaBrowser.LocalMetadata.Savers { @@ -37,7 +38,8 @@ namespace MediaBrowser.LocalMetadata.Savers { if (!(item is Series) && !(item is BoxSet) && !(item is MusicArtist) && !(item is MusicAlbum) && !(item is Season) && - !(item is GameSystem)) + !(item is GameSystem) && + !(item is Playlist)) { return updateType >= ItemUpdateType.MetadataDownload; } diff --git a/MediaBrowser.LocalMetadata/Savers/PlaylistXmlSaver.cs b/MediaBrowser.LocalMetadata/Savers/PlaylistXmlSaver.cs new file mode 100644 index 000000000..cdb3a2500 --- /dev/null +++ b/MediaBrowser.LocalMetadata/Savers/PlaylistXmlSaver.cs @@ -0,0 +1,68 @@ +using MediaBrowser.Controller.Entities; +using MediaBrowser.Controller.Entities.Movies; +using MediaBrowser.Controller.Library; +using System.Collections.Generic; +using System.IO; +using System.Text; +using System.Threading; + +namespace MediaBrowser.LocalMetadata.Savers +{ + public class PlaylistXmlSaver : IMetadataFileSaver + { + public string Name + { + get + { + return "Media Browser Xml"; + } + } + + /// + /// Determines whether [is enabled for] [the specified item]. + /// + /// The item. + /// Type of the update. + /// true if [is enabled for] [the specified item]; otherwise, false. + public bool IsEnabledFor(IHasMetadata item, ItemUpdateType updateType) + { + if (!item.SupportsLocalMetadata) + { + return false; + } + + return item is BoxSet && updateType >= ItemUpdateType.MetadataDownload; + } + + /// + /// Saves the specified item. + /// + /// The item. + /// The cancellation token. + /// Task. + public void Save(IHasMetadata item, CancellationToken cancellationToken) + { + var builder = new StringBuilder(); + + builder.Append(""); + + XmlSaverHelpers.AddCommonNodes((BoxSet)item, builder); + + builder.Append(""); + + var xmlFilePath = GetSavePath(item); + + XmlSaverHelpers.Save(builder, xmlFilePath, new List { }); + } + + /// + /// Gets the save path. + /// + /// The item. + /// System.String. + public string GetSavePath(IHasMetadata item) + { + return Path.Combine(item.Path, "playlist.xml"); + } + } +} diff --git a/MediaBrowser.LocalMetadata/Savers/XmlSaverHelpers.cs b/MediaBrowser.LocalMetadata/Savers/XmlSaverHelpers.cs index 1a2c341da..491592989 100644 --- a/MediaBrowser.LocalMetadata/Savers/XmlSaverHelpers.cs +++ b/MediaBrowser.LocalMetadata/Savers/XmlSaverHelpers.cs @@ -10,6 +10,7 @@ using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Entities.Movies; using MediaBrowser.Controller.Entities.TV; using MediaBrowser.Controller.Persistence; +using MediaBrowser.Controller.Playlists; using MediaBrowser.Model.Entities; namespace MediaBrowser.LocalMetadata.Savers @@ -109,7 +110,8 @@ namespace MediaBrowser.LocalMetadata.Savers "VoteCount", "Website", "Zap2ItId", - "CollectionItems" + "CollectionItems", + "PlaylistItems" }.ToDictionary(i => i, StringComparer.OrdinalIgnoreCase); @@ -631,10 +633,16 @@ namespace MediaBrowser.LocalMetadata.Savers builder.Append(""); } - var folder = item as BoxSet; - if (folder != null) + var boxset = item as BoxSet; + if (boxset != null) { - AddCollectionItems(folder, builder); + AddLinkedChildren(boxset, builder, "CollectionItems", "CollectionItem"); + } + + var playlist = item as Playlist; + if (playlist != null) + { + AddLinkedChildren(playlist, builder, "PlaylistItems", "PlaylistItem"); } } @@ -693,7 +701,7 @@ namespace MediaBrowser.LocalMetadata.Savers } } - public static void AddCollectionItems(Folder item, StringBuilder builder) + public static void AddLinkedChildren(Folder item, StringBuilder builder, string pluralNodeName, string singularNodeName) { var items = item.LinkedChildren .Where(i => i.Type == LinkedChildType.Manual && !string.IsNullOrWhiteSpace(i.ItemName)) @@ -704,10 +712,10 @@ namespace MediaBrowser.LocalMetadata.Savers return; } - builder.Append(""); + builder.Append("<" + pluralNodeName + ">"); foreach (var link in items) { - builder.Append(""); + builder.Append("<" + singularNodeName + ">"); builder.Append("" + SecurityElement.Escape(link.ItemName) + ""); builder.Append("" + SecurityElement.Escape(link.ItemType) + ""); @@ -717,9 +725,14 @@ namespace MediaBrowser.LocalMetadata.Savers builder.Append("" + SecurityElement.Escape(link.ItemYear.Value.ToString(UsCulture)) + ""); } - builder.Append(""); + if (link.ItemIndexNumber.HasValue) + { + builder.Append("" + SecurityElement.Escape(link.ItemIndexNumber.Value.ToString(UsCulture)) + ""); + } + + builder.Append(""); } - builder.Append(""); + builder.Append(""); } } } -- cgit v1.2.3 From c5319bb4ae9606e07d62525a022e5a67f85a7d43 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Mon, 4 Aug 2014 23:41:56 -0400 Subject: update playlist xml saving --- .../DefaultTheme/DefaultThemeService.cs | 673 --------------------- MediaBrowser.Api/DefaultTheme/Models.cs | 83 --- MediaBrowser.Api/Library/LibraryService.cs | 5 + MediaBrowser.Api/MediaBrowser.Api.csproj | 2 - .../Serialization/JsonSerializer.cs | 20 - .../Serialization/XmlSerializer.cs | 15 - .../Configuration/ConfigurationHelper.cs | 28 +- MediaBrowser.Controller/Entities/BaseItem.cs | 7 - MediaBrowser.Controller/Entities/LinkedChild.cs | 8 +- MediaBrowser.Controller/Library/TVUtils.cs | 2 - .../Providers/BaseItemXmlParser.cs | 23 +- MediaBrowser.Dlna/Didl/DidlBuilder.cs | 2 +- .../MediaBrowser.LocalMetadata.csproj | 2 + .../Parsers/BoxSetXmlParser.cs | 9 +- .../Parsers/PlaylistXmlParser.cs | 72 +++ .../Providers/BoxSetXmlProvider.cs | 6 +- .../Providers/PlaylistXmlProvider.cs | 31 + .../Providers/TrailerXmlProvider.cs | 8 +- .../Savers/PlaylistXmlSaver.cs | 6 +- .../Savers/XmlSaverHelpers.cs | 6 +- .../Serialization/IJsonSerializer.cs | 8 - MediaBrowser.Model/Serialization/IXmlSerializer.cs | 7 - .../HttpServer/HttpListenerHost.cs | 2 +- .../Localization/JavaScript/ar.json | 15 +- .../Localization/JavaScript/ca.json | 15 +- .../Localization/JavaScript/cs.json | 15 +- .../Localization/JavaScript/da.json | 15 +- .../Localization/JavaScript/de.json | 15 +- .../Localization/JavaScript/el.json | 15 +- .../Localization/JavaScript/en_GB.json | 15 +- .../Localization/JavaScript/en_US.json | 15 +- .../Localization/JavaScript/es.json | 15 +- .../Localization/JavaScript/es_MX.json | 13 +- .../Localization/JavaScript/fr.json | 13 +- .../Localization/JavaScript/he.json | 15 +- .../Localization/JavaScript/it.json | 13 +- .../Localization/JavaScript/javascript.json | 7 +- .../Localization/JavaScript/kk.json | 15 +- .../Localization/JavaScript/ms.json | 15 +- .../Localization/JavaScript/nb.json | 15 +- .../Localization/JavaScript/nl.json | 13 +- .../Localization/JavaScript/pl.json | 15 +- .../Localization/JavaScript/pt_BR.json | 15 +- .../Localization/JavaScript/pt_PT.json | 15 +- .../Localization/JavaScript/ru.json | 19 +- .../Localization/JavaScript/sv.json | 13 +- .../Localization/JavaScript/tr.json | 19 +- .../Localization/JavaScript/vi.json | 15 +- .../Localization/JavaScript/zh_TW.json | 15 +- .../Localization/Server/ar.json | 48 +- .../Localization/Server/ca.json | 50 +- .../Localization/Server/cs.json | 48 +- .../Localization/Server/da.json | 48 +- .../Localization/Server/de.json | 48 +- .../Localization/Server/el.json | 48 +- .../Localization/Server/en_GB.json | 50 +- .../Localization/Server/en_US.json | 50 +- .../Localization/Server/es.json | 48 +- .../Localization/Server/es_MX.json | 48 +- .../Localization/Server/fr.json | 48 +- .../Localization/Server/he.json | 48 +- .../Localization/Server/it.json | 50 +- .../Localization/Server/kk.json | 52 +- .../Localization/Server/ko.json | 50 +- .../Localization/Server/ms.json | 50 +- .../Localization/Server/nb.json | 48 +- .../Localization/Server/nl.json | 50 +- .../Localization/Server/pl.json | 48 +- .../Localization/Server/pt_BR.json | 50 +- .../Localization/Server/pt_PT.json | 48 +- .../Localization/Server/ru.json | 58 +- .../Localization/Server/server.json | 47 +- .../Localization/Server/sv.json | 48 +- .../Localization/Server/tr.json | 66 +- .../Localization/Server/vi.json | 48 +- .../Localization/Server/zh_TW.json | 48 +- .../Persistence/SqliteExtensions.cs | 22 + 77 files changed, 1768 insertions(+), 1002 deletions(-) delete mode 100644 MediaBrowser.Api/DefaultTheme/DefaultThemeService.cs delete mode 100644 MediaBrowser.Api/DefaultTheme/Models.cs create mode 100644 MediaBrowser.LocalMetadata/Parsers/PlaylistXmlParser.cs create mode 100644 MediaBrowser.LocalMetadata/Providers/PlaylistXmlProvider.cs (limited to 'MediaBrowser.LocalMetadata') diff --git a/MediaBrowser.Api/DefaultTheme/DefaultThemeService.cs b/MediaBrowser.Api/DefaultTheme/DefaultThemeService.cs deleted file mode 100644 index 21ba47bd4..000000000 --- a/MediaBrowser.Api/DefaultTheme/DefaultThemeService.cs +++ /dev/null @@ -1,673 +0,0 @@ -using MediaBrowser.Controller.Drawing; -using MediaBrowser.Controller.Dto; -using MediaBrowser.Controller.Entities; -using MediaBrowser.Controller.Entities.Audio; -using MediaBrowser.Controller.Entities.Movies; -using MediaBrowser.Controller.Entities.TV; -using MediaBrowser.Controller.Library; -using MediaBrowser.Controller.Net; -using MediaBrowser.Controller.Persistence; -using MediaBrowser.Model.Entities; -using MediaBrowser.Model.Logging; -using MediaBrowser.Model.Querying; -using ServiceStack; -using System; -using System.Collections.Generic; -using System.Linq; - -namespace MediaBrowser.Api.DefaultTheme -{ - [Route("/MBT/DefaultTheme/Games", "GET")] - public class GetGamesView : IReturn - { - [ApiMember(Name = "UserId", IsRequired = true, DataType = "string", ParameterType = "query", Verb = "GET")] - public Guid UserId { get; set; } - - [ApiMember(Name = "RecentlyPlayedGamesLimit", IsRequired = false, DataType = "int", ParameterType = "query", Verb = "GET")] - public int RecentlyPlayedGamesLimit { get; set; } - - public string ParentId { get; set; } - } - - [Route("/MBT/DefaultTheme/TV", "GET")] - public class GetTvView : IReturn - { - [ApiMember(Name = "UserId", IsRequired = true, DataType = "string", ParameterType = "query", Verb = "GET")] - public Guid UserId { get; set; } - - [ApiMember(Name = "ComedyGenre", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET", AllowMultiple = true)] - public string ComedyGenre { get; set; } - - [ApiMember(Name = "RomanceGenre", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET", AllowMultiple = true)] - public string RomanceGenre { get; set; } - - [ApiMember(Name = "TopCommunityRating", IsRequired = false, DataType = "int", ParameterType = "query", Verb = "GET")] - public double TopCommunityRating { get; set; } - - [ApiMember(Name = "NextUpEpisodeLimit", IsRequired = false, DataType = "int", ParameterType = "query", Verb = "GET")] - public int NextUpEpisodeLimit { get; set; } - - [ApiMember(Name = "ResumableEpisodeLimit", IsRequired = false, DataType = "int", ParameterType = "query", Verb = "GET")] - public int ResumableEpisodeLimit { get; set; } - - [ApiMember(Name = "LatestEpisodeLimit", IsRequired = false, DataType = "int", ParameterType = "query", Verb = "GET")] - public int LatestEpisodeLimit { get; set; } - - public string ParentId { get; set; } - } - - [Route("/MBT/DefaultTheme/Movies", "GET")] - public class GetMovieView : IReturn - { - [ApiMember(Name = "UserId", IsRequired = true, DataType = "string", ParameterType = "query", Verb = "GET")] - public Guid UserId { get; set; } - - [ApiMember(Name = "FamilyGenre", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET", AllowMultiple = true)] - public string FamilyGenre { get; set; } - - [ApiMember(Name = "ComedyGenre", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET", AllowMultiple = true)] - public string ComedyGenre { get; set; } - - [ApiMember(Name = "RomanceGenre", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET", AllowMultiple = true)] - public string RomanceGenre { get; set; } - - [ApiMember(Name = "LatestMoviesLimit", IsRequired = false, DataType = "int", ParameterType = "query", Verb = "GET")] - public int LatestMoviesLimit { get; set; } - - [ApiMember(Name = "LatestTrailersLimit", IsRequired = false, DataType = "int", ParameterType = "query", Verb = "GET")] - public int LatestTrailersLimit { get; set; } - - public string ParentId { get; set; } - } - - [Route("/MBT/DefaultTheme/Favorites", "GET")] - public class GetFavoritesView : IReturn - { - [ApiMember(Name = "UserId", IsRequired = true, DataType = "string", ParameterType = "query", Verb = "GET")] - public Guid UserId { get; set; } - } - - [Authenticated] - public class DefaultThemeService : BaseApiService - { - private readonly IUserManager _userManager; - private readonly IDtoService _dtoService; - private readonly ILogger _logger; - private readonly ILibraryManager _libraryManager; - private readonly IUserDataManager _userDataManager; - - private readonly IImageProcessor _imageProcessor; - private readonly IItemRepository _itemRepo; - - public DefaultThemeService(IUserManager userManager, IDtoService dtoService, ILogger logger, ILibraryManager libraryManager, IImageProcessor imageProcessor, IUserDataManager userDataManager, IItemRepository itemRepo) - { - _userManager = userManager; - _dtoService = dtoService; - _logger = logger; - _libraryManager = libraryManager; - _imageProcessor = imageProcessor; - _userDataManager = userDataManager; - _itemRepo = itemRepo; - } - - public object Get(GetFavoritesView request) - { - var user = _userManager.GetUserById(request.UserId); - - var allItems = user.RootFolder.GetRecursiveChildren(user) - .ToList(); - - var allFavoriteItems = allItems.Where(i => _userDataManager.GetUserData(user.Id, i.GetUserDataKey()).IsFavorite) - .ToList(); - - var itemsWithImages = allFavoriteItems.Where(i => !string.IsNullOrEmpty(i.PrimaryImagePath)) - .ToList(); - - var itemsWithBackdrops = allFavoriteItems.Where(i => i.GetImages(ImageType.Backdrop).Any()) - .ToList(); - - var view = new FavoritesView(); - - var fields = new List(); - - view.BackdropItems = FilterItemsForBackdropDisplay(itemsWithBackdrops) - .Randomize("backdrop") - .Take(10) - .Select(i => _dtoService.GetBaseItemDto(i, fields, user)) - .ToList(); - - var spotlightItems = itemsWithBackdrops.Randomize("spotlight") - .Take(10) - .ToList(); - - view.SpotlightItems = spotlightItems - .Select(i => _dtoService.GetBaseItemDto(i, fields, user)) - .ToList(); - - fields.Add(ItemFields.PrimaryImageAspectRatio); - - view.Albums = itemsWithImages - .OfType() - .Randomize() - .Take(4) - .Select(i => _dtoService.GetBaseItemDto(i, fields, user)) - .ToList(); - - view.Books = itemsWithImages - .OfType() - .Randomize() - .Take(6) - .Select(i => _dtoService.GetBaseItemDto(i, fields, user)) - .ToList(); - - view.Episodes = itemsWithImages - .OfType() - .Randomize() - .Take(6) - .Select(i => _dtoService.GetBaseItemDto(i, fields, user)) - .ToList(); - - view.Games = itemsWithImages - .OfType() - .Randomize() - .Take(6) - .Select(i => _dtoService.GetBaseItemDto(i, fields, user)) - .ToList(); - - view.Movies = itemsWithImages - .OfType() - .Randomize() - .Take(6) - .Select(i => _dtoService.GetBaseItemDto(i, fields, user)) - .ToList(); - - view.Series = itemsWithImages - .OfType() - .Randomize() - .Take(6) - .Select(i => _dtoService.GetBaseItemDto(i, fields, user)) - .ToList(); - - view.Songs = itemsWithImages - .OfType