From d0f3262ba3afbe33aaf97e6744764485a9ef44f6 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Fri, 30 Aug 2013 19:54:49 -0400 Subject: [PATCH 1/5] Added Book --- MediaBrowser.Controller/Entities/Book.cs | 35 +++++++++++++++++++ .../MediaBrowser.Controller.csproj | 1 + 2 files changed, 36 insertions(+) create mode 100644 MediaBrowser.Controller/Entities/Book.cs diff --git a/MediaBrowser.Controller/Entities/Book.cs b/MediaBrowser.Controller/Entities/Book.cs new file mode 100644 index 0000000000..20df731a78 --- /dev/null +++ b/MediaBrowser.Controller/Entities/Book.cs @@ -0,0 +1,35 @@ + +namespace MediaBrowser.Controller.Entities +{ + public class Book : BaseItem + { + public override string MediaType + { + get + { + return Model.Entities.MediaType.Book; + } + } + + public string SeriesName { get; set; } + + /// + /// + /// + public override string MetaLocation + { + get + { + return System.IO.Path.GetDirectoryName(Path); + } + } + + protected override bool UseParentPathToCreateResolveArgs + { + get + { + return !IsInMixedFolder; + } + } + } +} diff --git a/MediaBrowser.Controller/MediaBrowser.Controller.csproj b/MediaBrowser.Controller/MediaBrowser.Controller.csproj index bbc73d0ad7..e0e8b78e19 100644 --- a/MediaBrowser.Controller/MediaBrowser.Controller.csproj +++ b/MediaBrowser.Controller/MediaBrowser.Controller.csproj @@ -72,6 +72,7 @@ Properties\SharedVersion.cs + From e031694a9980f1d30bba149400accc5df841c668 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Fri, 30 Aug 2013 19:55:17 -0400 Subject: [PATCH 2/5] Front-load soundtrack links --- MediaBrowser.Controller/Dto/DtoBuilder.cs | 168 ++---------------- MediaBrowser.Controller/Entities/BaseItem.cs | 6 + .../MediaBrowser.Providers.csproj | 1 + .../Movies/MovieXmlParser.cs | 2 +- .../Music/SoundtrackPostScanTask.cs | 159 +++++++++++++++++ .../Savers/EpisodeXmlSaver.cs | 3 +- .../Savers/MovieXmlSaver.cs | 4 +- .../Savers/XmlSaverHelpers.cs | 11 +- MediaBrowser.Providers/TV/EpisodeXmlParser.cs | 2 +- 9 files changed, 193 insertions(+), 163 deletions(-) create mode 100644 MediaBrowser.Providers/Music/SoundtrackPostScanTask.cs diff --git a/MediaBrowser.Controller/Dto/DtoBuilder.cs b/MediaBrowser.Controller/Dto/DtoBuilder.cs index b2b858b6da..ea994e103a 100644 --- a/MediaBrowser.Controller/Dto/DtoBuilder.cs +++ b/MediaBrowser.Controller/Dto/DtoBuilder.cs @@ -104,33 +104,9 @@ namespace MediaBrowser.Controller.Dto if (fields.Contains(ItemFields.SoundtrackIds)) { - var series = item as Series; - - if (series != null) - { - AttachSoundtrackIds(dto, series, user); - } - - var movie = item as Movie; - - if (movie != null) - { - AttachSoundtrackIds(dto, movie, user); - } - - var album = item as MusicAlbum; - - if (album != null) - { - AttachSoundtrackIds(dto, album, user); - } - - var game = item as Game; - - if (game != null) - { - AttachSoundtrackIds(dto, game, user); - } + dto.SoundtrackIds = item.SoundtrackIds + .Select(i => i.ToString("N")) + .ToArray(); } // Make sure all the tasks we kicked off have completed. @@ -142,132 +118,6 @@ namespace MediaBrowser.Controller.Dto return dto; } - private void AttachSoundtrackIds(BaseItemDto dto, Movie item, User user) - { - var tmdb = item.GetProviderId(MetadataProviders.Tmdb); - - if (string.IsNullOrEmpty(tmdb)) - { - return; - } - - var recursiveChildren = user == null - ? _libraryManager.RootFolder.RecursiveChildren - : user.RootFolder.GetRecursiveChildren(user); - - dto.SoundtrackIds = recursiveChildren - .Where(i => - { - if (!string.IsNullOrEmpty(tmdb) && - string.Equals(tmdb, i.GetProviderId(MetadataProviders.Tmdb), StringComparison.OrdinalIgnoreCase) && - i is MusicAlbum) - { - return true; - } - return false; - }) - .Select(GetClientItemId) - .ToArray(); - } - - private void AttachSoundtrackIds(BaseItemDto dto, Series item, User user) - { - var tvdb = item.GetProviderId(MetadataProviders.Tvdb); - - if (string.IsNullOrEmpty(tvdb)) - { - return; - } - - var recursiveChildren = user == null - ? _libraryManager.RootFolder.RecursiveChildren - : user.RootFolder.GetRecursiveChildren(user); - - dto.SoundtrackIds = recursiveChildren - .Where(i => - { - if (!string.IsNullOrEmpty(tvdb) && - string.Equals(tvdb, i.GetProviderId(MetadataProviders.Tvdb), StringComparison.OrdinalIgnoreCase) && - i is MusicAlbum) - { - return true; - } - return false; - }) - .Select(GetClientItemId) - .ToArray(); - } - - private void AttachSoundtrackIds(BaseItemDto dto, Game item, User user) - { - var gamesdb = item.GetProviderId(MetadataProviders.Gamesdb); - - if (string.IsNullOrEmpty(gamesdb)) - { - return; - } - - var recursiveChildren = user == null - ? _libraryManager.RootFolder.RecursiveChildren - : user.RootFolder.GetRecursiveChildren(user); - - dto.SoundtrackIds = recursiveChildren - .Where(i => - { - if (!string.IsNullOrEmpty(gamesdb) && - string.Equals(gamesdb, i.GetProviderId(MetadataProviders.Gamesdb), StringComparison.OrdinalIgnoreCase) && - i is MusicAlbum) - { - return true; - } - return false; - }) - .Select(GetClientItemId) - .ToArray(); - } - - private void AttachSoundtrackIds(BaseItemDto dto, MusicAlbum item, User user) - { - var tmdb = item.GetProviderId(MetadataProviders.Tmdb); - var tvdb = item.GetProviderId(MetadataProviders.Tvdb); - var gamesdb = item.GetProviderId(MetadataProviders.Gamesdb); - - if (string.IsNullOrEmpty(tmdb) && string.IsNullOrEmpty(tvdb) && string.IsNullOrEmpty(gamesdb)) - { - return; - } - - var recursiveChildren = user == null - ? _libraryManager.RootFolder.RecursiveChildren - : user.RootFolder.GetRecursiveChildren(user); - - dto.SoundtrackIds = recursiveChildren - .Where(i => - { - if (!string.IsNullOrEmpty(tmdb) && - string.Equals(tmdb, i.GetProviderId(MetadataProviders.Tmdb), StringComparison.OrdinalIgnoreCase) && - i is Movie) - { - return true; - } - if (!string.IsNullOrEmpty(tvdb) && - string.Equals(tvdb, i.GetProviderId(MetadataProviders.Tvdb), StringComparison.OrdinalIgnoreCase) && - i is Series) - { - return true; - } - if (!string.IsNullOrEmpty(gamesdb) && - string.Equals(gamesdb, i.GetProviderId(MetadataProviders.Gamesdb), StringComparison.OrdinalIgnoreCase) && - i is Game) - { - return true; - } - return false; - }) - .Select(GetClientItemId) - .ToArray(); - } - /// /// Attaches the user specific info. /// @@ -716,8 +566,20 @@ namespace MediaBrowser.Controller.Dto { SetMusicVideoProperties(dto, musicVideo); } + + var book = item as Book; + + if (book != null) + { + SetBookProperties(dto, book); + } } + private void SetBookProperties(BaseItemDto dto, Book item) + { + dto.SeriesName = item.SeriesName; + } + private void SetMusicVideoProperties(BaseItemDto dto, MusicVideo item) { if (!string.IsNullOrEmpty(item.Album)) diff --git a/MediaBrowser.Controller/Entities/BaseItem.cs b/MediaBrowser.Controller/Entities/BaseItem.cs index 3c8c2411ec..e756d22113 100644 --- a/MediaBrowser.Controller/Entities/BaseItem.cs +++ b/MediaBrowser.Controller/Entities/BaseItem.cs @@ -23,6 +23,11 @@ namespace MediaBrowser.Controller.Entities /// public abstract class BaseItem : IHasProviderIds { + /// + /// MusicAlbums in the library that are the soundtrack for this item + /// + public List SoundtrackIds { get; set; } + protected BaseItem() { Genres = new List(); @@ -38,6 +43,7 @@ namespace MediaBrowser.Controller.Entities Tags = new List(); ThemeSongIds = new List(); ThemeVideoIds = new List(); + SoundtrackIds = new List(); LocalTrailerIds = new List(); LockedFields = new List(); } diff --git a/MediaBrowser.Providers/MediaBrowser.Providers.csproj b/MediaBrowser.Providers/MediaBrowser.Providers.csproj index 28e6173789..761cdccbe3 100644 --- a/MediaBrowser.Providers/MediaBrowser.Providers.csproj +++ b/MediaBrowser.Providers/MediaBrowser.Providers.csproj @@ -81,6 +81,7 @@ + diff --git a/MediaBrowser.Providers/Movies/MovieXmlParser.cs b/MediaBrowser.Providers/Movies/MovieXmlParser.cs index a265419554..7361be04f5 100644 --- a/MediaBrowser.Providers/Movies/MovieXmlParser.cs +++ b/MediaBrowser.Providers/Movies/MovieXmlParser.cs @@ -48,7 +48,7 @@ namespace MediaBrowser.Providers.Movies { case "Chapters": - _chaptersTask = FetchChaptersFromXmlNode(item, reader.ReadSubtree(), _itemRepo, CancellationToken.None); + //_chaptersTask = FetchChaptersFromXmlNode(item, reader.ReadSubtree(), _itemRepo, CancellationToken.None); break; default: diff --git a/MediaBrowser.Providers/Music/SoundtrackPostScanTask.cs b/MediaBrowser.Providers/Music/SoundtrackPostScanTask.cs new file mode 100644 index 0000000000..18868d3eae --- /dev/null +++ b/MediaBrowser.Providers/Music/SoundtrackPostScanTask.cs @@ -0,0 +1,159 @@ +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.Model.Entities; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; + +namespace MediaBrowser.Providers.Music +{ + public class SoundtrackPostScanTask : ILibraryPostScanTask + { + private readonly ILibraryManager _libraryManager; + + public SoundtrackPostScanTask(ILibraryManager libraryManager) + { + _libraryManager = libraryManager; + } + + public Task Run(IProgress progress, CancellationToken cancellationToken) + { + return Task.Run(() => RunInternal(progress, cancellationToken)); + } + + private void RunInternal(IProgress progress, CancellationToken cancellationToken) + { + var allItems = _libraryManager.RootFolder + .RecursiveChildren + .ToList(); + + var musicAlbums = allItems + .OfType() + .ToList(); + + AttachMovieSoundtracks(allItems, musicAlbums, cancellationToken); + + progress.Report(25); + + AttachTvSoundtracks(allItems, musicAlbums, cancellationToken); + + progress.Report(50); + + AttachGameSoundtracks(allItems, musicAlbums, cancellationToken); + + progress.Report(75); + + AttachAlbumLinks(allItems, musicAlbums, cancellationToken); + + progress.Report(100); + } + + private void AttachMovieSoundtracks(IEnumerable allItems, List allAlbums, CancellationToken cancellationToken) + { + foreach (var movie in allItems + .Where(i => (i is Movie) || (i is Trailer))) + { + cancellationToken.ThrowIfCancellationRequested(); + + var tmdbId = movie.GetProviderId(MetadataProviders.Tmdb); + + if (string.IsNullOrEmpty(tmdbId)) + { + movie.SoundtrackIds = new List(); + continue; + } + + movie.SoundtrackIds = allAlbums + .Where(i => string.Equals(tmdbId, i.GetProviderId(MetadataProviders.Tmdb), StringComparison.OrdinalIgnoreCase)) + .Select(i => i.Id) + .ToList(); + } + } + + private void AttachTvSoundtracks(IEnumerable allItems, List allAlbums, CancellationToken cancellationToken) + { + foreach (var series in allItems.OfType()) + { + cancellationToken.ThrowIfCancellationRequested(); + + var tvdbId = series.GetProviderId(MetadataProviders.Tvdb); + + if (string.IsNullOrEmpty(tvdbId)) + { + series.SoundtrackIds = new List(); + continue; + } + + series.SoundtrackIds = allAlbums + .Where(i => string.Equals(tvdbId, i.GetProviderId(MetadataProviders.Tvdb), StringComparison.OrdinalIgnoreCase)) + .Select(i => i.Id) + .ToList(); + } + } + + private void AttachGameSoundtracks(IEnumerable allItems, List allAlbums, CancellationToken cancellationToken) + { + foreach (var game in allItems.OfType()) + { + cancellationToken.ThrowIfCancellationRequested(); + + var gamesdb = game.GetProviderId(MetadataProviders.Gamesdb); + + if (string.IsNullOrEmpty(gamesdb)) + { + game.SoundtrackIds = new List(); + continue; + } + + game.SoundtrackIds = allAlbums + .Where(i => string.Equals(gamesdb, i.GetProviderId(MetadataProviders.Gamesdb), StringComparison.OrdinalIgnoreCase)) + .Select(i => i.Id) + .ToList(); + } + } + + private void AttachAlbumLinks(List allItems, IEnumerable allAlbums, CancellationToken cancellationToken) + { + foreach (var album in allAlbums) + { + cancellationToken.ThrowIfCancellationRequested(); + + var tmdb = album.GetProviderId(MetadataProviders.Tmdb); + var tvdb = album.GetProviderId(MetadataProviders.Tvdb); + var gamesdb = album.GetProviderId(MetadataProviders.Gamesdb); + + if (string.IsNullOrEmpty(tmdb) && string.IsNullOrEmpty(tvdb) && string.IsNullOrEmpty(gamesdb)) + { + album.SoundtrackIds = new List(); + continue; + } + + album.SoundtrackIds = allItems. + Where(i => + { + if (!string.IsNullOrEmpty(tmdb) && string.Equals(tmdb, i.GetProviderId(MetadataProviders.Tmdb), StringComparison.OrdinalIgnoreCase) && i is Movie) + { + return true; + } + if (!string.IsNullOrEmpty(tmdb) && string.Equals(tmdb, i.GetProviderId(MetadataProviders.Tmdb), StringComparison.OrdinalIgnoreCase) && i is Trailer) + { + return true; + } + if (!string.IsNullOrEmpty(tvdb) && string.Equals(tvdb, i.GetProviderId(MetadataProviders.Tvdb), StringComparison.OrdinalIgnoreCase) && i is Series) + { + return true; + } + + return !string.IsNullOrEmpty(gamesdb) && string.Equals(gamesdb, i.GetProviderId(MetadataProviders.Gamesdb), StringComparison.OrdinalIgnoreCase) && i is Game; + }) + .Select(i => i.Id) + .ToList(); + } + } + } +} diff --git a/MediaBrowser.Providers/Savers/EpisodeXmlSaver.cs b/MediaBrowser.Providers/Savers/EpisodeXmlSaver.cs index b36f7966b6..d90cb94c29 100644 --- a/MediaBrowser.Providers/Savers/EpisodeXmlSaver.cs +++ b/MediaBrowser.Providers/Savers/EpisodeXmlSaver.cs @@ -81,8 +81,7 @@ namespace MediaBrowser.Providers.Savers } XmlSaverHelpers.AddCommonNodes(item, builder); - XmlSaverHelpers.AddMediaInfo(episode, builder); - XmlSaverHelpers.AddChapters((Video)item, builder, _itemRepository); + XmlSaverHelpers.AddMediaInfo(episode, builder, _itemRepository); builder.Append(""); diff --git a/MediaBrowser.Providers/Savers/MovieXmlSaver.cs b/MediaBrowser.Providers/Savers/MovieXmlSaver.cs index 154b4ab601..2402bcd7f5 100644 --- a/MediaBrowser.Providers/Savers/MovieXmlSaver.cs +++ b/MediaBrowser.Providers/Savers/MovieXmlSaver.cs @@ -97,9 +97,7 @@ namespace MediaBrowser.Providers.Savers var video = (Video)item; - XmlSaverHelpers.AddMediaInfo(video, builder); - - XmlSaverHelpers.AddChapters(video, builder, _itemRepository); + XmlSaverHelpers.AddMediaInfo(video, builder, _itemRepository); builder.Append(""); diff --git a/MediaBrowser.Providers/Savers/XmlSaverHelpers.cs b/MediaBrowser.Providers/Savers/XmlSaverHelpers.cs index edeea611a3..0ec4df0918 100644 --- a/MediaBrowser.Providers/Savers/XmlSaverHelpers.cs +++ b/MediaBrowser.Providers/Savers/XmlSaverHelpers.cs @@ -451,9 +451,11 @@ namespace MediaBrowser.Providers.Savers /// /// The item. /// The builder. - public static void AddMediaInfo(T item, StringBuilder builder) + public static void AddMediaInfo(T item, StringBuilder builder, IItemRepository itemRepository) where T : BaseItem, IHasMediaStreams { + var video = item as Video; + builder.Append(""); foreach (var stream in item.MediaStreams) @@ -526,8 +528,6 @@ namespace MediaBrowser.Providers.Savers builder.Append("" + Convert.ToInt32(timespan.TotalSeconds).ToString(UsCulture) + ""); } - var video = item as Video; - if (video != null && video.Video3DFormat.HasValue) { switch (video.Video3DFormat.Value) @@ -552,6 +552,11 @@ namespace MediaBrowser.Providers.Savers } builder.Append(""); + + if (video != null) + { + AddChapters(video, builder, itemRepository); + } } } } diff --git a/MediaBrowser.Providers/TV/EpisodeXmlParser.cs b/MediaBrowser.Providers/TV/EpisodeXmlParser.cs index 7920273007..837c7f4b9a 100644 --- a/MediaBrowser.Providers/TV/EpisodeXmlParser.cs +++ b/MediaBrowser.Providers/TV/EpisodeXmlParser.cs @@ -49,7 +49,7 @@ namespace MediaBrowser.Providers.TV { case "Chapters": - _chaptersTask = FetchChaptersFromXmlNode(item, reader.ReadSubtree(), _itemRepo, CancellationToken.None); + //_chaptersTask = FetchChaptersFromXmlNode(item, reader.ReadSubtree(), _itemRepo, CancellationToken.None); break; case "Episode": From b538dc31b1581bc29cf7be64fb91e495a214c244 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Fri, 30 Aug 2013 21:08:32 -0400 Subject: [PATCH 3/5] added new properties and endpoints for series special features --- MediaBrowser.Api/UserLibrary/ItemsService.cs | 9 +++ .../UserLibrary/UserLibraryService.cs | 43 ++++++++++--- MediaBrowser.Controller/Dto/DtoBuilder.cs | 8 ++- MediaBrowser.Controller/Entities/TV/Series.cs | 6 ++ MediaBrowser.Model/Dto/BaseItemDto.cs | 2 + MediaBrowser.Model/Querying/ItemQuery.cs | 2 + .../MediaBrowser.Providers.csproj | 1 + .../TV/SeriesPostScanTask.cs | 64 +++++++++++++++++++ 8 files changed, 124 insertions(+), 11 deletions(-) create mode 100644 MediaBrowser.Providers/TV/SeriesPostScanTask.cs diff --git a/MediaBrowser.Api/UserLibrary/ItemsService.cs b/MediaBrowser.Api/UserLibrary/ItemsService.cs index 5e0bfca971..d06941bb81 100644 --- a/MediaBrowser.Api/UserLibrary/ItemsService.cs +++ b/MediaBrowser.Api/UserLibrary/ItemsService.cs @@ -172,6 +172,9 @@ namespace MediaBrowser.Api.UserLibrary [ApiMember(Name = "AdjacentTo", Description = "Optional. Return items that are siblings of a supplied item.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")] public string AdjacentTo { get; set; } + [ApiMember(Name = "MinIndexNumber", Description = "Optional filter index number.", IsRequired = false, DataType = "int", ParameterType = "query", Verb = "GET")] + public int? MinIndexNumber { get; set; } + /// /// Gets the order by. /// @@ -511,6 +514,12 @@ namespace MediaBrowser.Api.UserLibrary items = items.Where(i => i.Id == previousId || i.Id == nextId); } + // Min index number + if (request.MinIndexNumber.HasValue) + { + items = items.Where(i => i.IndexNumber.HasValue && i.IndexNumber.Value >= request.MinIndexNumber.Value); + } + // Min official rating if (!string.IsNullOrEmpty(request.MinOfficialRating)) { diff --git a/MediaBrowser.Api/UserLibrary/UserLibraryService.cs b/MediaBrowser.Api/UserLibrary/UserLibraryService.cs index a6c53b4a42..de25651ed7 100644 --- a/MediaBrowser.Api/UserLibrary/UserLibraryService.cs +++ b/MediaBrowser.Api/UserLibrary/UserLibraryService.cs @@ -1,6 +1,7 @@ using MediaBrowser.Controller.Dto; using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Entities.Movies; +using MediaBrowser.Controller.Entities.TV; using MediaBrowser.Controller.Library; using MediaBrowser.Controller.Persistence; using MediaBrowser.Controller.Session; @@ -325,7 +326,7 @@ namespace MediaBrowser.Api.UserLibrary /// Class GetSpecialFeatures /// [Route("/Users/{UserId}/Items/{Id}/SpecialFeatures", "GET")] - [Api(Description = "Gets special features for a movie")] + [Api(Description = "Gets special features for an item")] public class GetSpecialFeatures : IReturn> { /// @@ -404,16 +405,40 @@ namespace MediaBrowser.Api.UserLibrary // Get everything var fields = Enum.GetNames(typeof(ItemFields)).Select(i => (ItemFields)Enum.Parse(typeof(ItemFields), i, true)).ToList(); - var movie = (Movie)item; - var dtoBuilder = new DtoBuilder(Logger, _libraryManager, _userDataRepository, _itemRepo); - var tasks = movie.SpecialFeatureIds - .Select(_itemRepo.RetrieveItem) - .OrderBy(i => i.SortName) - .Select(i => dtoBuilder.GetBaseItemDto(i, fields, user, movie)); + var movie = item as Movie; - return Task.WhenAll(tasks); + // Get them from the db + if (movie != null) + { + // Avoid implicitly captured closure + var movie1 = movie; + + var tasks = movie.SpecialFeatureIds + .Select(_itemRepo.RetrieveItem) + .OrderBy(i => i.SortName) + .Select(i => dtoBuilder.GetBaseItemDto(i, fields, user, movie1)); + + return Task.WhenAll(tasks); + } + + var series = item as Series; + + // Get them from the child tree + if (series != null) + { + var tasks = series + .RecursiveChildren + .OfType() + .Where(i => i.ParentIndexNumber.HasValue && i.ParentIndexNumber.Value == 0) + .OrderBy(i => i.SortName) + .Select(i => dtoBuilder.GetBaseItemDto(i, fields, user)); + + return Task.WhenAll(tasks); + } + + throw new ArgumentException("The item does not support special features"); } /// @@ -589,7 +614,7 @@ namespace MediaBrowser.Api.UserLibrary return DtoBuilder.GetUserItemDataDto(data); } - + /// /// Posts the specified request. /// diff --git a/MediaBrowser.Controller/Dto/DtoBuilder.cs b/MediaBrowser.Controller/Dto/DtoBuilder.cs index ea994e103a..f762c7cc6b 100644 --- a/MediaBrowser.Controller/Dto/DtoBuilder.cs +++ b/MediaBrowser.Controller/Dto/DtoBuilder.cs @@ -108,7 +108,7 @@ namespace MediaBrowser.Controller.Dto .Select(i => i.ToString("N")) .ToArray(); } - + // Make sure all the tasks we kicked off have completed. if (tasks.Count > 0) { @@ -532,6 +532,10 @@ namespace MediaBrowser.Controller.Dto dto.AirDays = series.AirDays; dto.AirTime = series.AirTime; dto.Status = series.Status; + + dto.SpecialFeatureCount = series.SpecialFeatureIds.Count; + + dto.SeasonCount = series.SeasonCount; } if (episode != null) @@ -579,7 +583,7 @@ namespace MediaBrowser.Controller.Dto { dto.SeriesName = item.SeriesName; } - + private void SetMusicVideoProperties(BaseItemDto dto, MusicVideo item) { if (!string.IsNullOrEmpty(item.Album)) diff --git a/MediaBrowser.Controller/Entities/TV/Series.cs b/MediaBrowser.Controller/Entities/TV/Series.cs index 2458e56193..1e4d56e1a5 100644 --- a/MediaBrowser.Controller/Entities/TV/Series.cs +++ b/MediaBrowser.Controller/Entities/TV/Series.cs @@ -13,9 +13,15 @@ namespace MediaBrowser.Controller.Entities.TV /// public class Series : Folder { + public List SpecialFeatureIds { get; set; } + + public int SeasonCount { get; set; } + public Series() { AirDays = new List(); + + SpecialFeatureIds = new List(); } /// diff --git a/MediaBrowser.Model/Dto/BaseItemDto.cs b/MediaBrowser.Model/Dto/BaseItemDto.cs index fa9ed2536a..b843465dfc 100644 --- a/MediaBrowser.Model/Dto/BaseItemDto.cs +++ b/MediaBrowser.Model/Dto/BaseItemDto.cs @@ -138,6 +138,8 @@ namespace MediaBrowser.Model.Dto /// The production year. public int? ProductionYear { get; set; } + public int? SeasonCount { get; set; } + /// /// Gets or sets the players supported by a game. /// diff --git a/MediaBrowser.Model/Querying/ItemQuery.cs b/MediaBrowser.Model/Querying/ItemQuery.cs index 18b263960a..fe9848513d 100644 --- a/MediaBrowser.Model/Querying/ItemQuery.cs +++ b/MediaBrowser.Model/Querying/ItemQuery.cs @@ -176,6 +176,8 @@ namespace MediaBrowser.Model.Querying /// The max official rating. public string MaxOfficialRating { get; set; } + public int? MinIndexNumber { get; set; } + /// /// Initializes a new instance of the class. /// diff --git a/MediaBrowser.Providers/MediaBrowser.Providers.csproj b/MediaBrowser.Providers/MediaBrowser.Providers.csproj index 761cdccbe3..9d07394944 100644 --- a/MediaBrowser.Providers/MediaBrowser.Providers.csproj +++ b/MediaBrowser.Providers/MediaBrowser.Providers.csproj @@ -107,6 +107,7 @@ + diff --git a/MediaBrowser.Providers/TV/SeriesPostScanTask.cs b/MediaBrowser.Providers/TV/SeriesPostScanTask.cs new file mode 100644 index 0000000000..a781551dee --- /dev/null +++ b/MediaBrowser.Providers/TV/SeriesPostScanTask.cs @@ -0,0 +1,64 @@ +using MediaBrowser.Controller.Entities.TV; +using MediaBrowser.Controller.Library; +using System; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; + +namespace MediaBrowser.Providers.TV +{ + class SeriesPostScanTask : ILibraryPostScanTask + { + /// + /// The _library manager + /// + private readonly ILibraryManager _libraryManager; + + public SeriesPostScanTask(ILibraryManager libraryManager) + { + _libraryManager = libraryManager; + } + + public Task Run(IProgress progress, CancellationToken cancellationToken) + { + return Task.Run(() => RunInternal(progress, cancellationToken)); + } + + private void RunInternal(IProgress progress, CancellationToken cancellationToken) + { + var seriesList = _libraryManager.RootFolder + .RecursiveChildren + .OfType() + .ToList(); + + var numComplete = 0; + + foreach (var series in seriesList) + { + cancellationToken.ThrowIfCancellationRequested(); + + var episodes = series.RecursiveChildren + .OfType() + .ToList(); + + series.SpecialFeatureIds = episodes + .Where(i => i.ParentIndexNumber.HasValue && i.ParentIndexNumber.Value == 0) + .Select(i => i.Id) + .ToList(); + + series.SeasonCount = episodes + .Select(i => i.ParentIndexNumber ?? 0) + .Where(i => i != 0) + .Distinct() + .Count(); + + numComplete++; + double percent = numComplete; + percent /= seriesList.Count; + percent *= 100; + + progress.Report(percent); + } + } + } +} From 9158014b4fb00e1713b7e764b834e4120bc3f3e3 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Fri, 30 Aug 2013 21:13:15 -0400 Subject: [PATCH 4/5] updated nuget --- MediaBrowser.Api/Playback/Hls/BaseHlsService.cs | 6 +++--- Nuget/MediaBrowser.Common.Internal.nuspec | 4 ++-- Nuget/MediaBrowser.Common.nuspec | 2 +- Nuget/MediaBrowser.Server.Core.nuspec | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/MediaBrowser.Api/Playback/Hls/BaseHlsService.cs b/MediaBrowser.Api/Playback/Hls/BaseHlsService.cs index fc98e2a734..f5bf14cf96 100644 --- a/MediaBrowser.Api/Playback/Hls/BaseHlsService.cs +++ b/MediaBrowser.Api/Playback/Hls/BaseHlsService.cs @@ -146,9 +146,9 @@ namespace MediaBrowser.Api.Playback.Hls builder.AppendLine(playlistUrl); // Low bitrate stream - builder.AppendLine("#EXT-X-STREAM-INF:PROGRAM-ID=1, BANDWIDTH=64000"); - playlistUrl = "hls/" + Path.GetFileName(firstPlaylist).Replace(".m3u8", "-low/stream.m3u8"); - builder.AppendLine(playlistUrl); + //builder.AppendLine("#EXT-X-STREAM-INF:PROGRAM-ID=1, BANDWIDTH=64000"); + //playlistUrl = "hls/" + Path.GetFileName(firstPlaylist).Replace(".m3u8", "-low/stream.m3u8"); + //builder.AppendLine(playlistUrl); return builder.ToString(); } diff --git a/Nuget/MediaBrowser.Common.Internal.nuspec b/Nuget/MediaBrowser.Common.Internal.nuspec index 156b69094e..fa21b23c0d 100644 --- a/Nuget/MediaBrowser.Common.Internal.nuspec +++ b/Nuget/MediaBrowser.Common.Internal.nuspec @@ -2,7 +2,7 @@ MediaBrowser.Common.Internal - 3.0.188 + 3.0.189 MediaBrowser.Common.Internal Luke ebr,Luke,scottisafool @@ -12,7 +12,7 @@ Contains common components shared by Media Browser Theater and Media Browser Server. Not intended for plugin developer consumption. Copyright © Media Browser 2013 - + diff --git a/Nuget/MediaBrowser.Common.nuspec b/Nuget/MediaBrowser.Common.nuspec index e1e4adcb11..b2e257760d 100644 --- a/Nuget/MediaBrowser.Common.nuspec +++ b/Nuget/MediaBrowser.Common.nuspec @@ -2,7 +2,7 @@ MediaBrowser.Common - 3.0.188 + 3.0.189 MediaBrowser.Common Media Browser Team ebr,Luke,scottisafool diff --git a/Nuget/MediaBrowser.Server.Core.nuspec b/Nuget/MediaBrowser.Server.Core.nuspec index 3038388665..87e32a24d5 100644 --- a/Nuget/MediaBrowser.Server.Core.nuspec +++ b/Nuget/MediaBrowser.Server.Core.nuspec @@ -2,7 +2,7 @@ MediaBrowser.Server.Core - 3.0.188 + 3.0.189 Media Browser.Server.Core Media Browser Team ebr,Luke,scottisafool @@ -12,7 +12,7 @@ Contains core components required to build plugins for Media Browser Server. Copyright © Media Browser 2013 - + From 2e99fb29bba1e9f7c98d82f72c3a3a51b9773378 Mon Sep 17 00:00:00 2001 From: blackice013 Date: Sat, 31 Aug 2013 11:16:36 +1000 Subject: [PATCH 5/5] Update CONTRIBUTORS.md Contributed to MB Classic bug report on GitHub. --- CONTRIBUTORS.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index 8bab285613..137487cef2 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -55,3 +55,4 @@ - [jordy1955] (https://github.com/jordy1955) - [JoshFink] (https://github.com/JoshFink) - [Detector1](https://github.com/Detector1) + - [BlackIce013](https://github.com/blackice013)