From 1f9d32afc52e9bd133ddf22d12bdc468adaf9ebe Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sat, 30 Apr 2016 18:05:13 -0400 Subject: limit use of GetUserDataKey --- MediaBrowser.Server.Implementations/Sorting/DatePlayedComparer.cs | 2 +- MediaBrowser.Server.Implementations/Sorting/PlayCountComparer.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'MediaBrowser.Server.Implementations/Sorting') diff --git a/MediaBrowser.Server.Implementations/Sorting/DatePlayedComparer.cs b/MediaBrowser.Server.Implementations/Sorting/DatePlayedComparer.cs index c881591be..3edf23020 100644 --- a/MediaBrowser.Server.Implementations/Sorting/DatePlayedComparer.cs +++ b/MediaBrowser.Server.Implementations/Sorting/DatePlayedComparer.cs @@ -47,7 +47,7 @@ namespace MediaBrowser.Server.Implementations.Sorting /// DateTime. private DateTime GetDate(BaseItem x) { - var userdata = UserDataRepository.GetUserData(User.Id, x.GetUserDataKey()); + var userdata = UserDataRepository.GetUserData(User, x); if (userdata != null && userdata.LastPlayedDate.HasValue) { diff --git a/MediaBrowser.Server.Implementations/Sorting/PlayCountComparer.cs b/MediaBrowser.Server.Implementations/Sorting/PlayCountComparer.cs index 1bc5261b4..8b14efffc 100644 --- a/MediaBrowser.Server.Implementations/Sorting/PlayCountComparer.cs +++ b/MediaBrowser.Server.Implementations/Sorting/PlayCountComparer.cs @@ -34,7 +34,7 @@ namespace MediaBrowser.Server.Implementations.Sorting /// DateTime. private int GetValue(BaseItem x) { - var userdata = UserDataRepository.GetUserData(User.Id, x.GetUserDataKey()); + var userdata = UserDataRepository.GetUserData(User, x); return userdata == null ? 0 : userdata.PlayCount; } -- cgit v1.2.3 From cd02373e554df232d88063f41b8aee391f3e7667 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Mon, 2 May 2016 01:32:04 -0400 Subject: support pooling series and seasons --- .../Entities/InternalItemsQuery.cs | 1 + MediaBrowser.Controller/Entities/TV/Episode.cs | 33 ++++----- MediaBrowser.Controller/Entities/TV/Season.cs | 26 +++++-- MediaBrowser.Controller/Entities/TV/Series.cs | 63 ++++++++++++----- .../Persistence/SqliteItemRepository.cs | 16 ++++- .../Sorting/AiredEpisodeOrderComparer.cs | 10 +-- .../TV/TVSeriesManager.cs | 82 +++++++++++++--------- 7 files changed, 153 insertions(+), 78 deletions(-) (limited to 'MediaBrowser.Server.Implementations/Sorting') diff --git a/MediaBrowser.Controller/Entities/InternalItemsQuery.cs b/MediaBrowser.Controller/Entities/InternalItemsQuery.cs index f3b4f4053..b148251ff 100644 --- a/MediaBrowser.Controller/Entities/InternalItemsQuery.cs +++ b/MediaBrowser.Controller/Entities/InternalItemsQuery.cs @@ -46,6 +46,7 @@ namespace MediaBrowser.Controller.Entities public string NameLessThan { get; set; } public string NameContains { get; set; } + public string PresentationUniqueKey { get; set; } public string Path { get; set; } public string Person { get; set; } diff --git a/MediaBrowser.Controller/Entities/TV/Episode.cs b/MediaBrowser.Controller/Entities/TV/Episode.cs index 3ad6170a5..605b838cd 100644 --- a/MediaBrowser.Controller/Entities/TV/Episode.cs +++ b/MediaBrowser.Controller/Entities/TV/Episode.cs @@ -58,25 +58,7 @@ namespace MediaBrowser.Controller.Entities.TV { get { - return AirsAfterSeasonNumber ?? AirsBeforeSeasonNumber ?? PhysicalSeasonNumber; - } - } - - [IgnoreDataMember] - public int? PhysicalSeasonNumber - { - get - { - var value = ParentIndexNumber; - - if (value.HasValue) - { - return value; - } - - var season = Season; - - return season != null ? season.IndexNumber : null; + return AirsAfterSeasonNumber ?? AirsBeforeSeasonNumber ?? ParentIndexNumber; } } @@ -316,6 +298,19 @@ namespace MediaBrowser.Controller.Entities.TV Logger.ErrorException("Error in FillMissingEpisodeNumbersFromPath. Episode: {0}", ex, Path ?? Name ?? Id.ToString()); } + if (!ParentIndexNumber.HasValue) + { + var season = Season; + if (season != null) + { + if (season.ParentIndexNumber.HasValue) + { + ParentIndexNumber = season.ParentIndexNumber; + hasChanges = true; + } + } + } + return hasChanges; } } diff --git a/MediaBrowser.Controller/Entities/TV/Season.cs b/MediaBrowser.Controller/Entities/TV/Season.cs index ebd22c6c4..1f443071c 100644 --- a/MediaBrowser.Controller/Entities/TV/Season.cs +++ b/MediaBrowser.Controller/Entities/TV/Season.cs @@ -92,6 +92,24 @@ namespace MediaBrowser.Controller.Entities.TV } } + [IgnoreDataMember] + public override string PresentationUniqueKey + { + get + { + if (IndexNumber.HasValue) + { + var series = Series; + if (series != null) + { + return series.PresentationUniqueKey + "-" + (IndexNumber ?? 0).ToString("000"); + } + } + + return base.PresentationUniqueKey; + } + } + /// /// Creates the name of the sort. /// @@ -169,16 +187,16 @@ namespace MediaBrowser.Controller.Entities.TV public IEnumerable GetEpisodes(User user, bool includeMissingEpisodes, bool includeVirtualUnairedEpisodes) { - var episodes = GetRecursiveChildren(user) - .OfType(); - var series = Series; if (IndexNumber.HasValue && series != null) { - return series.GetEpisodes(user, IndexNumber.Value, includeMissingEpisodes, includeVirtualUnairedEpisodes, episodes); + return series.GetEpisodes(user, IndexNumber.Value, includeMissingEpisodes, includeVirtualUnairedEpisodes); } + var episodes = GetRecursiveChildren(user) + .OfType(); + if (series != null && series.ContainsEpisodesWithoutSeasonFolders) { var seasonNumber = IndexNumber; diff --git a/MediaBrowser.Controller/Entities/TV/Series.cs b/MediaBrowser.Controller/Entities/TV/Series.cs index c062b5fba..abca6a643 100644 --- a/MediaBrowser.Controller/Entities/TV/Series.cs +++ b/MediaBrowser.Controller/Entities/TV/Series.cs @@ -94,7 +94,7 @@ namespace MediaBrowser.Controller.Entities.TV [IgnoreDataMember] public override string PresentationUniqueKey { - get { return GetUserDataKey(); } + get { return GetUserDataKeys().First(); } } /// @@ -191,8 +191,28 @@ namespace MediaBrowser.Controller.Entities.TV public IEnumerable GetSeasons(User user, bool includeMissingSeasons, bool includeVirtualUnaired) { - var seasons = base.GetChildren(user, true) - .OfType(); + var seriesIds = LibraryManager.GetItemIds(new InternalItemsQuery(user) + { + PresentationUniqueKey = PresentationUniqueKey, + IncludeItemTypes = new[] { typeof(Series).Name } + }); + + IEnumerable seasons; + + if (seriesIds.Count > 1) + { + seasons = LibraryManager.GetItemList(new InternalItemsQuery(user) + { + AncestorIds = seriesIds.Select(i => i.ToString("N")).ToArray(), + IncludeItemTypes = new[] { typeof(Season).Name }, + SortBy = new[] { ItemSortBy.SortName } + + }).OfType(); + } + else + { + seasons = base.GetChildren(user, true).OfType(); + } if (!includeMissingSeasons && !includeVirtualUnaired) { @@ -210,9 +230,7 @@ namespace MediaBrowser.Controller.Entities.TV } } - return LibraryManager - .Sort(seasons, user, new[] { ItemSortBy.SortName }, SortOrder.Ascending) - .Cast(); + return seasons; } public IEnumerable GetEpisodes(User user) @@ -321,18 +339,31 @@ namespace MediaBrowser.Controller.Entities.TV public IEnumerable GetEpisodes(User user, int seasonNumber, bool includeMissingEpisodes, bool includeVirtualUnairedEpisodes) { - return GetEpisodes(user, seasonNumber, includeMissingEpisodes, includeVirtualUnairedEpisodes, - new List()); - } + var seriesIds = LibraryManager.GetItemIds(new InternalItemsQuery(user) + { + PresentationUniqueKey = PresentationUniqueKey, + IncludeItemTypes = new[] { typeof(Series).Name } + }); - internal IEnumerable GetEpisodes(User user, int seasonNumber, bool includeMissingEpisodes, bool includeVirtualUnairedEpisodes, IEnumerable additionalEpisodes) - { - var episodes = GetRecursiveChildren(user, i => i is Episode) - .Cast(); + IEnumerable episodes; - episodes = FilterEpisodesBySeason(episodes, seasonNumber, DisplaySpecialsWithSeasons); + if (seriesIds.Count > 1) + { + episodes = LibraryManager.GetItemList(new InternalItemsQuery(user) + { + AncestorIds = seriesIds.Select(i => i.ToString("N")).ToArray(), + IncludeItemTypes = new[] { typeof(Episode).Name }, + SortBy = new[] { ItemSortBy.SortName } - episodes = episodes.Concat(additionalEpisodes).Distinct(); + }).OfType(); + } + else + { + episodes = GetRecursiveChildren(user, i => i is Episode) + .Cast(); + } + + episodes = FilterEpisodesBySeason(episodes, seasonNumber, DisplaySpecialsWithSeasons); if (!includeMissingEpisodes) { @@ -360,7 +391,7 @@ namespace MediaBrowser.Controller.Entities.TV { if (!includeSpecials || seasonNumber < 1) { - return episodes.Where(i => (i.PhysicalSeasonNumber ?? -1) == seasonNumber); + return episodes.Where(i => (i.ParentIndexNumber ?? -1) == seasonNumber); } return episodes.Where(i => diff --git a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs index 87b3bffe4..6959de8e6 100644 --- a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs +++ b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs @@ -82,7 +82,7 @@ namespace MediaBrowser.Server.Implementations.Persistence private IDbCommand _updateInheritedRatingCommand; private IDbCommand _updateInheritedTagsCommand; - public const int LatestSchemaVersion = 66; + public const int LatestSchemaVersion = 68; /// /// Initializes a new instance of the class. @@ -1936,6 +1936,12 @@ namespace MediaBrowser.Server.Implementations.Persistence cmd.Parameters.Add(cmd, "@Path", DbType.String).Value = query.Path; } + if (!string.IsNullOrWhiteSpace(query.PresentationUniqueKey)) + { + whereClauses.Add("PresentationUniqueKey=@PresentationUniqueKey"); + cmd.Parameters.Add(cmd, "@PresentationUniqueKey", DbType.String).Value = query.PresentationUniqueKey; + } + if (query.MinCommunityRating.HasValue) { whereClauses.Add("CommunityRating>=@MinCommunityRating"); @@ -2323,6 +2329,11 @@ namespace MediaBrowser.Server.Implementations.Persistence private bool EnableGroupByPresentationUniqueKey(InternalItemsQuery query) { + if (!string.IsNullOrWhiteSpace(query.PresentationUniqueKey)) + { + return false; + } + if (query.IncludeItemTypes.Length == 0) { return true; @@ -2333,7 +2344,8 @@ namespace MediaBrowser.Server.Implementations.Persistence typeof(Video).Name , typeof(Movie).Name , typeof(MusicVideo).Name , - typeof(Series).Name }; + typeof(Series).Name , + typeof(Season).Name }; if (types.Any(i => query.IncludeItemTypes.Contains(i, StringComparer.OrdinalIgnoreCase))) { diff --git a/MediaBrowser.Server.Implementations/Sorting/AiredEpisodeOrderComparer.cs b/MediaBrowser.Server.Implementations/Sorting/AiredEpisodeOrderComparer.cs index 70cf805cf..91abbe34c 100644 --- a/MediaBrowser.Server.Implementations/Sorting/AiredEpisodeOrderComparer.cs +++ b/MediaBrowser.Server.Implementations/Sorting/AiredEpisodeOrderComparer.cs @@ -49,8 +49,8 @@ namespace MediaBrowser.Server.Implementations.Sorting private int Compare(Episode x, Episode y) { - var isXSpecial = (x.PhysicalSeasonNumber ?? -1) == 0; - var isYSpecial = (y.PhysicalSeasonNumber ?? -1) == 0; + var isXSpecial = (x.ParentIndexNumber ?? -1) == 0; + var isYSpecial = (y.ParentIndexNumber ?? -1) == 0; if (isXSpecial && isYSpecial) { @@ -74,7 +74,7 @@ namespace MediaBrowser.Server.Implementations.Sorting { // http://thetvdb.com/wiki/index.php?title=Special_Episodes - var xSeason = x.PhysicalSeasonNumber ?? -1; + var xSeason = x.ParentIndexNumber ?? -1; var ySeason = y.AirsAfterSeasonNumber ?? y.AirsBeforeSeasonNumber ?? -1; if (xSeason != ySeason) @@ -142,8 +142,8 @@ namespace MediaBrowser.Server.Implementations.Sorting private int CompareEpisodes(Episode x, Episode y) { - var xValue = (x.PhysicalSeasonNumber ?? -1) * 1000 + (x.IndexNumber ?? -1); - var yValue = (y.PhysicalSeasonNumber ?? -1) * 1000 + (y.IndexNumber ?? -1); + var xValue = (x.ParentIndexNumber ?? -1) * 1000 + (x.IndexNumber ?? -1); + var yValue = (y.ParentIndexNumber ?? -1) * 1000 + (y.IndexNumber ?? -1); return xValue.CompareTo(yValue); } diff --git a/MediaBrowser.Server.Implementations/TV/TVSeriesManager.cs b/MediaBrowser.Server.Implementations/TV/TVSeriesManager.cs index dc880d84b..ec91dc1b7 100644 --- a/MediaBrowser.Server.Implementations/TV/TVSeriesManager.cs +++ b/MediaBrowser.Server.Implementations/TV/TVSeriesManager.cs @@ -36,10 +36,25 @@ namespace MediaBrowser.Server.Implementations.TV ? new string[] { } : new[] { request.ParentId }; + string presentationUniqueKey = null; + int? limit = null; + if (!string.IsNullOrWhiteSpace(request.SeriesId)) + { + var series = _libraryManager.GetItemById(request.SeriesId); + + if (series != null) + { + presentationUniqueKey = series.PresentationUniqueKey; + limit = 1; + } + } + var items = _libraryManager.GetItemList(new InternalItemsQuery(user) { IncludeItemTypes = new[] { typeof(Series).Name }, - SortOrder = SortOrder.Ascending + SortOrder = SortOrder.Ascending, + PresentationUniqueKey = presentationUniqueKey, + Limit = limit }, parentIds).Cast(); @@ -58,10 +73,25 @@ namespace MediaBrowser.Server.Implementations.TV throw new ArgumentException("User not found"); } + string presentationUniqueKey = null; + int? limit = null; + if (!string.IsNullOrWhiteSpace(request.SeriesId)) + { + var series = _libraryManager.GetItemById(request.SeriesId); + + if (series != null) + { + presentationUniqueKey = series.PresentationUniqueKey; + limit = 1; + } + } + var items = _libraryManager.GetItemList(new InternalItemsQuery(user) { IncludeItemTypes = new[] { typeof(Series).Name }, - SortOrder = SortOrder.Ascending + SortOrder = SortOrder.Ascending, + PresentationUniqueKey = presentationUniqueKey, + Limit = limit }, parentsFolders.Select(i => i.Id.ToString("N"))).Cast(); @@ -76,30 +106,30 @@ namespace MediaBrowser.Server.Implementations.TV // Avoid implicitly captured closure var currentUser = user; - return FilterSeries(request, series) + return series .AsParallel() .Select(i => GetNextUp(i, currentUser)) // Include if an episode was found, and either the series is not unwatched or the specific series was requested .Where(i => i.Item1 != null && (!i.Item3 || !string.IsNullOrWhiteSpace(request.SeriesId))) - .OrderByDescending(i => - { - var episode = i.Item1; + //.OrderByDescending(i => + //{ + // var episode = i.Item1; - var seriesUserData = _userDataManager.GetUserData(user, episode.Series); + // var seriesUserData = _userDataManager.GetUserData(user, episode.Series); - if (seriesUserData.IsFavorite) - { - return 2; - } + // if (seriesUserData.IsFavorite) + // { + // return 2; + // } - if (seriesUserData.Likes.HasValue) - { - return seriesUserData.Likes.Value ? 1 : -1; - } + // if (seriesUserData.Likes.HasValue) + // { + // return seriesUserData.Likes.Value ? 1 : -1; + // } - return 0; - }) - .ThenByDescending(i => i.Item2) + // return 0; + //}) + .OrderByDescending(i => i.Item2) .ThenByDescending(i => i.Item1.PremiereDate ?? DateTime.MinValue) .Select(i => i.Item1); } @@ -142,7 +172,7 @@ namespace MediaBrowser.Server.Implementations.TV } else { - if (!episode.IsVirtualUnaired && (!episode.IsMissingEpisode || includeMissing)) + if (!episode.IsVirtualUnaired && (includeMissing || !episode.IsMissingEpisode)) { nextUp = episode; } @@ -154,24 +184,12 @@ namespace MediaBrowser.Server.Implementations.TV return new Tuple(nextUp, lastWatchedDate, false); } - var firstEpisode = allEpisodes.LastOrDefault(i => !i.IsVirtualUnaired && (!i.IsMissingEpisode || includeMissing) && !i.IsPlayed(user)); + var firstEpisode = allEpisodes.LastOrDefault(i => !i.IsVirtualUnaired && (includeMissing || !i.IsMissingEpisode) && !i.IsPlayed(user)); // Return the first episode return new Tuple(firstEpisode, DateTime.MinValue, true); } - private IEnumerable FilterSeries(NextUpQuery request, IEnumerable items) - { - if (!string.IsNullOrWhiteSpace(request.SeriesId)) - { - var id = new Guid(request.SeriesId); - - items = items.Where(i => i.Id == id); - } - - return items; - } - private QueryResult GetResult(IEnumerable items, int? totalRecordLimit, NextUpQuery query) { var itemsArray = totalRecordLimit.HasValue ? items.Take(totalRecordLimit.Value).ToArray() : items.ToArray(); -- cgit v1.2.3 From 99084edabeb1787f28496dffa55fbb260e34ae81 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sun, 8 May 2016 23:13:38 -0400 Subject: update windows ffmpeg --- MediaBrowser.Api/ApiEntryPoint.cs | 8 ++- MediaBrowser.Api/LiveTv/LiveTvService.cs | 20 ++++++- MediaBrowser.Api/Movies/MoviesService.cs | 1 - MediaBrowser.Api/UserLibrary/BaseItemsRequest.cs | 5 +- MediaBrowser.Api/UserLibrary/ItemsService.cs | 3 +- MediaBrowser.Controller/Entities/Audio/Audio.cs | 6 --- .../Entities/Audio/MusicAlbum.cs | 9 ++++ .../Entities/Audio/MusicArtist.cs | 9 ++++ MediaBrowser.Controller/Entities/BaseItem.cs | 11 ++++ MediaBrowser.Controller/Entities/Folder.cs | 49 +++++++++++------ MediaBrowser.Controller/Entities/IHasMetadata.cs | 2 + .../Entities/InternalItemsQuery.cs | 2 + MediaBrowser.Controller/Entities/MusicVideo.cs | 6 --- MediaBrowser.Controller/Entities/TV/Season.cs | 9 ++++ MediaBrowser.Controller/Entities/TV/Series.cs | 9 ++++ MediaBrowser.Controller/Entities/UserRootFolder.cs | 5 -- MediaBrowser.Controller/Playlists/Playlist.cs | 9 ++++ MediaBrowser.Model/LiveTv/ProgramQuery.cs | 3 ++ .../LiveTv/RecommendedProgramQuery.cs | 9 +++- MediaBrowser.Providers/Manager/MetadataService.cs | 61 +++++++++++++++++++-- .../Music/MusicBrainzArtistProvider.cs | 29 +++++++--- .../Dto/DtoService.cs | 33 ++++-------- .../Library/LibraryManager.cs | 14 +++-- .../LiveTv/EmbyTV/EmbyTV.cs | 18 ++++++- .../LiveTv/LiveTvManager.cs | 10 ++-- .../Persistence/SqliteItemRepository.cs | 62 ++++++++++++++++++++-- .../Sorting/DateLastMediaAddedComparer.cs | 8 +-- .../MediaBrowser.ServerApplication.csproj | 2 - .../Native/WindowsApp.cs | 17 ++++-- .../ffmpeg/ffmpegx64.7z.REMOVED.git-id | 1 - .../ffmpeg/ffmpegx86.7z.REMOVED.git-id | 1 - 31 files changed, 330 insertions(+), 101 deletions(-) delete mode 100644 MediaBrowser.ServerApplication/ffmpeg/ffmpegx64.7z.REMOVED.git-id delete mode 100644 MediaBrowser.ServerApplication/ffmpeg/ffmpegx86.7z.REMOVED.git-id (limited to 'MediaBrowser.Server.Implementations/Sorting') diff --git a/MediaBrowser.Api/ApiEntryPoint.cs b/MediaBrowser.Api/ApiEntryPoint.cs index 66ca8c25d..a677bc600 100644 --- a/MediaBrowser.Api/ApiEntryPoint.cs +++ b/MediaBrowser.Api/ApiEntryPoint.cs @@ -488,13 +488,17 @@ namespace MediaBrowser.Api { try { - Logger.Info("Killing ffmpeg process for {0}", job.Path); + Logger.Info("Stopping ffmpeg process with q command for {0}", job.Path); //process.Kill(); process.StandardInput.WriteLine("q"); // Need to wait because killing is asynchronous - process.WaitForExit(5000); + if (!process.WaitForExit(5000)) + { + Logger.Info("Killing ffmpeg process for {0}", job.Path); + process.Kill(); + } } catch (Exception ex) { diff --git a/MediaBrowser.Api/LiveTv/LiveTvService.cs b/MediaBrowser.Api/LiveTv/LiveTvService.cs index ebcf8fbea..d3a4558c8 100644 --- a/MediaBrowser.Api/LiveTv/LiveTvService.cs +++ b/MediaBrowser.Api/LiveTv/LiveTvService.cs @@ -254,6 +254,8 @@ namespace MediaBrowser.Api.LiveTv [ApiMember(Name = "EnableImages", Description = "Optional, include image information in output", IsRequired = false, DataType = "boolean", ParameterType = "query", Verb = "GET")] public bool? EnableImages { get; set; } + public bool EnableTotalRecordCount { get; set; } + [ApiMember(Name = "ImageTypeLimit", Description = "Optional, the max number of images to return, per image type", IsRequired = false, DataType = "int", ParameterType = "query", Verb = "GET")] public int? ImageTypeLimit { get; set; } @@ -266,12 +268,24 @@ namespace MediaBrowser.Api.LiveTv /// The fields. [ApiMember(Name = "Fields", Description = "Optional. Specify additional fields of information to return in the output. This allows multiple, comma delimeted. Options: Budget, Chapters, CriticRatingSummary, DateCreated, Genres, HomePageUrl, IndexOptions, MediaStreams, Overview, ParentId, Path, People, ProviderIds, PrimaryImageAspectRatio, Revenue, SortName, Studios, Taglines", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET", AllowMultiple = true)] public string Fields { get; set; } + + public GetPrograms() + { + EnableTotalRecordCount = true; + } } [Route("/LiveTv/Programs/Recommended", "GET", Summary = "Gets available live tv epgs..")] [Authenticated] public class GetRecommendedPrograms : IReturn>, IHasDtoOptions { + public bool EnableTotalRecordCount { get; set; } + + public GetRecommendedPrograms() + { + EnableTotalRecordCount = true; + } + [ApiMember(Name = "UserId", Description = "Optional filter by user id.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET,POST")] public string UserId { get; set; } @@ -662,7 +676,8 @@ namespace MediaBrowser.Api.LiveTv { ChannelIds = (request.ChannelIds ?? string.Empty).Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries).ToArray(), UserId = request.UserId, - HasAired = request.HasAired + HasAired = request.HasAired, + EnableTotalRecordCount = request.EnableTotalRecordCount }; if (!string.IsNullOrEmpty(request.MinStartDate)) @@ -709,7 +724,8 @@ namespace MediaBrowser.Api.LiveTv HasAired = request.HasAired, IsMovie = request.IsMovie, IsKids = request.IsKids, - IsSports = request.IsSports + IsSports = request.IsSports, + EnableTotalRecordCount = request.EnableTotalRecordCount }; var result = await _liveTvManager.GetRecommendedPrograms(query, GetDtoOptions(request), CancellationToken.None).ConfigureAwait(false); diff --git a/MediaBrowser.Api/Movies/MoviesService.cs b/MediaBrowser.Api/Movies/MoviesService.cs index 9590971d0..786615cc3 100644 --- a/MediaBrowser.Api/Movies/MoviesService.cs +++ b/MediaBrowser.Api/Movies/MoviesService.cs @@ -196,7 +196,6 @@ namespace MediaBrowser.Api.Movies var parentIds = new string[] { }; var list = _libraryManager.GetItemList(query, parentIds) - .DistinctBy(i => i.PresentationUniqueKey, StringComparer.OrdinalIgnoreCase) .DistinctBy(i => i.GetProviderId(MetadataProviders.Imdb) ?? Guid.NewGuid().ToString("N")) .ToList(); diff --git a/MediaBrowser.Api/UserLibrary/BaseItemsRequest.cs b/MediaBrowser.Api/UserLibrary/BaseItemsRequest.cs index 6867f6308..aee1a8d54 100644 --- a/MediaBrowser.Api/UserLibrary/BaseItemsRequest.cs +++ b/MediaBrowser.Api/UserLibrary/BaseItemsRequest.cs @@ -12,6 +12,7 @@ namespace MediaBrowser.Api.UserLibrary protected BaseItemsRequest() { EnableImages = true; + EnableTotalRecordCount = true; } /// @@ -104,7 +105,9 @@ namespace MediaBrowser.Api.UserLibrary [ApiMember(Name = "IsInBoxSet", Description = "Optional filter by items that are in boxsets, or not.", IsRequired = false, DataType = "bool", ParameterType = "query", Verb = "GET")] public bool? IsInBoxSet { get; set; } - + + public bool EnableTotalRecordCount { get; set; } + /// /// Skips over a given number of items within the results. Use for paging. /// diff --git a/MediaBrowser.Api/UserLibrary/ItemsService.cs b/MediaBrowser.Api/UserLibrary/ItemsService.cs index 7d2029cab..ff937078e 100644 --- a/MediaBrowser.Api/UserLibrary/ItemsService.cs +++ b/MediaBrowser.Api/UserLibrary/ItemsService.cs @@ -230,7 +230,8 @@ namespace MediaBrowser.Api.UserLibrary ParentId = string.IsNullOrWhiteSpace(request.ParentId) ? (Guid?)null : new Guid(request.ParentId), ParentIndexNumber = request.ParentIndexNumber, AiredDuringSeason = request.AiredDuringSeason, - AlbumArtistStartsWithOrGreater = request.AlbumArtistStartsWithOrGreater + AlbumArtistStartsWithOrGreater = request.AlbumArtistStartsWithOrGreater, + EnableTotalRecordCount = request.EnableTotalRecordCount }; if (!string.IsNullOrWhiteSpace(request.Ids)) diff --git a/MediaBrowser.Controller/Entities/Audio/Audio.cs b/MediaBrowser.Controller/Entities/Audio/Audio.cs index fd56a6746..c34a884ff 100644 --- a/MediaBrowser.Controller/Entities/Audio/Audio.cs +++ b/MediaBrowser.Controller/Entities/Audio/Audio.cs @@ -40,12 +40,6 @@ namespace MediaBrowser.Controller.Entities.Audio public List AlbumArtists { get; set; } - /// - /// Gets or sets the album. - /// - /// The album. - public string Album { get; set; } - [IgnoreDataMember] public bool IsThemeMedia { diff --git a/MediaBrowser.Controller/Entities/Audio/MusicAlbum.cs b/MediaBrowser.Controller/Entities/Audio/MusicAlbum.cs index 5cb4e8c9d..615276e83 100644 --- a/MediaBrowser.Controller/Entities/Audio/MusicAlbum.cs +++ b/MediaBrowser.Controller/Entities/Audio/MusicAlbum.cs @@ -48,6 +48,15 @@ namespace MediaBrowser.Controller.Entities.Audio } } + [IgnoreDataMember] + public override bool SupportsCumulativeRunTimeTicks + { + get + { + return true; + } + } + [IgnoreDataMember] public List AllArtists { diff --git a/MediaBrowser.Controller/Entities/Audio/MusicArtist.cs b/MediaBrowser.Controller/Entities/Audio/MusicArtist.cs index 6f6f124db..610497661 100644 --- a/MediaBrowser.Controller/Entities/Audio/MusicArtist.cs +++ b/MediaBrowser.Controller/Entities/Audio/MusicArtist.cs @@ -34,6 +34,15 @@ namespace MediaBrowser.Controller.Entities.Audio } } + [IgnoreDataMember] + public override bool SupportsCumulativeRunTimeTicks + { + get + { + return true; + } + } + [IgnoreDataMember] public override bool SupportsAddingToPlaylist { diff --git a/MediaBrowser.Controller/Entities/BaseItem.cs b/MediaBrowser.Controller/Entities/BaseItem.cs index 2e968c880..cd021d2ab 100644 --- a/MediaBrowser.Controller/Entities/BaseItem.cs +++ b/MediaBrowser.Controller/Entities/BaseItem.cs @@ -69,6 +69,12 @@ namespace MediaBrowser.Controller.Entities public List ImageInfos { get; set; } + /// + /// Gets or sets the album. + /// + /// The album. + public string Album { get; set; } + /// /// Gets or sets the channel identifier. /// @@ -1175,6 +1181,11 @@ namespace MediaBrowser.Controller.Entities get { return Id.ToString("N"); } } + public virtual bool RequiresRefresh() + { + return false; + } + private string _userDataKey; /// /// Gets the user data key. diff --git a/MediaBrowser.Controller/Entities/Folder.cs b/MediaBrowser.Controller/Entities/Folder.cs index 978fd7fed..457a0b3ab 100644 --- a/MediaBrowser.Controller/Entities/Folder.cs +++ b/MediaBrowser.Controller/Entities/Folder.cs @@ -28,6 +28,9 @@ namespace MediaBrowser.Controller.Entities public List ThemeSongIds { get; set; } public List ThemeVideoIds { get; set; } + [IgnoreDataMember] + public DateTime? DateLastMediaAdded { get; set; } + public Folder() { LinkedChildren = new List(); @@ -55,6 +58,36 @@ namespace MediaBrowser.Controller.Entities } } + [IgnoreDataMember] + public virtual bool SupportsCumulativeRunTimeTicks + { + get + { + return false; + } + } + + [IgnoreDataMember] + public virtual bool SupportsDateLastMediaAdded + { + get + { + return false; + } + } + + public override bool RequiresRefresh() + { + var baseResult = base.RequiresRefresh(); + + if (SupportsCumulativeRunTimeTicks && !RunTimeTicks.HasValue) + { + baseResult = true; + } + + return baseResult; + } + [IgnoreDataMember] public override string FileNameWithoutExtension { @@ -789,11 +822,6 @@ namespace MediaBrowser.Controller.Entities Logger.Debug("Query requires post-filtering due to ItemSortBy.AiredEpisodeOrder"); return true; } - if (query.SortBy.Contains(ItemSortBy.Album, StringComparer.OrdinalIgnoreCase)) - { - Logger.Debug("Query requires post-filtering due to ItemSortBy.Album"); - return true; - } if (query.SortBy.Contains(ItemSortBy.AlbumArtist, StringComparer.OrdinalIgnoreCase)) { Logger.Debug("Query requires post-filtering due to ItemSortBy.AlbumArtist"); @@ -809,11 +837,6 @@ namespace MediaBrowser.Controller.Entities Logger.Debug("Query requires post-filtering due to ItemSortBy.Budget"); return true; } - if (query.SortBy.Contains(ItemSortBy.DateLastContentAdded, StringComparer.OrdinalIgnoreCase)) - { - Logger.Debug("Query requires post-filtering due to ItemSortBy.DateLastContentAdded"); - return true; - } if (query.SortBy.Contains(ItemSortBy.GameSystem, StringComparer.OrdinalIgnoreCase)) { Logger.Debug("Query requires post-filtering due to ItemSortBy.GameSystem"); @@ -1086,12 +1109,6 @@ namespace MediaBrowser.Controller.Entities return true; } - if (query.AlbumNames.Length > 0) - { - Logger.Debug("Query requires post-filtering due to AlbumNames"); - return true; - } - if (query.ArtistNames.Length > 0) { Logger.Debug("Query requires post-filtering due to ArtistNames"); diff --git a/MediaBrowser.Controller/Entities/IHasMetadata.cs b/MediaBrowser.Controller/Entities/IHasMetadata.cs index 1f680b35f..c7940c8a9 100644 --- a/MediaBrowser.Controller/Entities/IHasMetadata.cs +++ b/MediaBrowser.Controller/Entities/IHasMetadata.cs @@ -49,5 +49,7 @@ namespace MediaBrowser.Controller.Entities /// /// true if [supports people]; otherwise, false. bool SupportsPeople { get; } + + bool RequiresRefresh(); } } diff --git a/MediaBrowser.Controller/Entities/InternalItemsQuery.cs b/MediaBrowser.Controller/Entities/InternalItemsQuery.cs index 385ee81e9..5236b0a27 100644 --- a/MediaBrowser.Controller/Entities/InternalItemsQuery.cs +++ b/MediaBrowser.Controller/Entities/InternalItemsQuery.cs @@ -137,10 +137,12 @@ namespace MediaBrowser.Controller.Entities public string AncestorWithPresentationUniqueKey { get; set; } public bool GroupByPresentationUniqueKey { get; set; } + public bool EnableTotalRecordCount { get; set; } public InternalItemsQuery() { GroupByPresentationUniqueKey = true; + EnableTotalRecordCount = true; AlbumNames = new string[] { }; ArtistNames = new string[] { }; diff --git a/MediaBrowser.Controller/Entities/MusicVideo.cs b/MediaBrowser.Controller/Entities/MusicVideo.cs index bf4c2559c..7119828e2 100644 --- a/MediaBrowser.Controller/Entities/MusicVideo.cs +++ b/MediaBrowser.Controller/Entities/MusicVideo.cs @@ -9,12 +9,6 @@ namespace MediaBrowser.Controller.Entities { public class MusicVideo : Video, IHasArtist, IHasMusicGenres, IHasProductionLocations, IHasBudget, IHasLookupInfo { - /// - /// Gets or sets the album. - /// - /// The album. - public string Album { get; set; } - /// /// Gets or sets the budget. /// diff --git a/MediaBrowser.Controller/Entities/TV/Season.cs b/MediaBrowser.Controller/Entities/TV/Season.cs index 4e6128527..ac8cc0ee2 100644 --- a/MediaBrowser.Controller/Entities/TV/Season.cs +++ b/MediaBrowser.Controller/Entities/TV/Season.cs @@ -32,6 +32,15 @@ namespace MediaBrowser.Controller.Entities.TV } } + [IgnoreDataMember] + public override bool SupportsDateLastMediaAdded + { + get + { + return true; + } + } + [IgnoreDataMember] public override Guid? DisplayParentId { diff --git a/MediaBrowser.Controller/Entities/TV/Series.cs b/MediaBrowser.Controller/Entities/TV/Series.cs index 680af1843..f8cdab8ce 100644 --- a/MediaBrowser.Controller/Entities/TV/Series.cs +++ b/MediaBrowser.Controller/Entities/TV/Series.cs @@ -48,6 +48,15 @@ namespace MediaBrowser.Controller.Entities.TV } } + [IgnoreDataMember] + public override bool SupportsDateLastMediaAdded + { + get + { + return true; + } + } + public bool DisplaySpecialsWithSeasons { get; set; } public List LocalTrailerIds { get; set; } diff --git a/MediaBrowser.Controller/Entities/UserRootFolder.cs b/MediaBrowser.Controller/Entities/UserRootFolder.cs index 8ce39c697..b9e997d17 100644 --- a/MediaBrowser.Controller/Entities/UserRootFolder.cs +++ b/MediaBrowser.Controller/Entities/UserRootFolder.cs @@ -102,10 +102,5 @@ namespace MediaBrowser.Controller.Entities LibraryManager.RegisterItem(item); } } - - public override void FillUserDataDtoValues(UserItemDataDto dto, UserItemData userData, User user) - { - // Nothing meaninful here and will only waste resources - } } } diff --git a/MediaBrowser.Controller/Playlists/Playlist.cs b/MediaBrowser.Controller/Playlists/Playlist.cs index cd0c5dc1c..003cbcfcd 100644 --- a/MediaBrowser.Controller/Playlists/Playlist.cs +++ b/MediaBrowser.Controller/Playlists/Playlist.cs @@ -39,6 +39,15 @@ namespace MediaBrowser.Controller.Playlists } } + [IgnoreDataMember] + public override bool SupportsCumulativeRunTimeTicks + { + get + { + return true; + } + } + public override bool IsAuthorizedToDelete(User user) { return true; diff --git a/MediaBrowser.Model/LiveTv/ProgramQuery.cs b/MediaBrowser.Model/LiveTv/ProgramQuery.cs index 7a877e356..0141191c1 100644 --- a/MediaBrowser.Model/LiveTv/ProgramQuery.cs +++ b/MediaBrowser.Model/LiveTv/ProgramQuery.cs @@ -14,8 +14,11 @@ namespace MediaBrowser.Model.LiveTv ChannelIds = new string[] { }; SortBy = new string[] { }; Genres = new string[] { }; + EnableTotalRecordCount = true; } + public bool EnableTotalRecordCount { get; set; } + /// /// Fields to return within the items, in addition to basic information /// diff --git a/MediaBrowser.Model/LiveTv/RecommendedProgramQuery.cs b/MediaBrowser.Model/LiveTv/RecommendedProgramQuery.cs index e83a8fda6..0e6d081a1 100644 --- a/MediaBrowser.Model/LiveTv/RecommendedProgramQuery.cs +++ b/MediaBrowser.Model/LiveTv/RecommendedProgramQuery.cs @@ -13,7 +13,14 @@ namespace MediaBrowser.Model.LiveTv public bool? EnableImages { get; set; } public int? ImageTypeLimit { get; set; } public ImageType[] EnableImageTypes { get; set; } - + + public bool EnableTotalRecordCount { get; set; } + + public RecommendedProgramQuery() + { + EnableTotalRecordCount = true; + } + /// /// Gets or sets the user identifier. /// diff --git a/MediaBrowser.Providers/Manager/MetadataService.cs b/MediaBrowser.Providers/Manager/MetadataService.cs index ae48c996a..218127ab9 100644 --- a/MediaBrowser.Providers/Manager/MetadataService.cs +++ b/MediaBrowser.Providers/Manager/MetadataService.cs @@ -310,6 +310,11 @@ namespace MediaBrowser.Providers.Manager return true; } + if (item is MusicVideo) + { + return true; + } + return false; } @@ -390,7 +395,6 @@ namespace MediaBrowser.Providers.Manager return _cachedTask; } - private readonly Task _cachedResult = Task.FromResult(ItemUpdateType.None); /// /// Befores the save. /// @@ -398,9 +402,58 @@ namespace MediaBrowser.Providers.Manager /// if set to true [is full refresh]. /// Type of the current update. /// ItemUpdateType. - protected virtual Task BeforeSave(TItemType item, bool isFullRefresh, ItemUpdateType currentUpdateType) + protected virtual async Task BeforeSave(TItemType item, bool isFullRefresh, ItemUpdateType currentUpdateType) + { + var updateType = ItemUpdateType.None; + + updateType |= SaveCumulativeRunTimeTicks(item, isFullRefresh, currentUpdateType); + updateType |= SaveDateLastMediaAdded(item, isFullRefresh, currentUpdateType); + + return updateType; + } + + private ItemUpdateType SaveCumulativeRunTimeTicks(TItemType item, bool isFullRefresh, ItemUpdateType currentUpdateType) + { + var updateType = ItemUpdateType.None; + + if (isFullRefresh || currentUpdateType > ItemUpdateType.None) + { + var folder = item as Folder; + if (folder != null && folder.SupportsCumulativeRunTimeTicks) + { + var ticks = folder.GetRecursiveChildren(i => !i.IsFolder).Select(i => i.RunTimeTicks ?? 0).Sum(); + + if (!folder.RunTimeTicks.HasValue || folder.RunTimeTicks.Value != ticks) + { + folder.RunTimeTicks = ticks; + updateType = ItemUpdateType.MetadataEdit; + } + } + } + + return updateType; + } + + private ItemUpdateType SaveDateLastMediaAdded(TItemType item, bool isFullRefresh, ItemUpdateType currentUpdateType) { - return _cachedResult; + var updateType = ItemUpdateType.None; + + if (isFullRefresh || currentUpdateType > ItemUpdateType.None) + { + var folder = item as Folder; + if (folder != null && folder.SupportsDateLastMediaAdded) + { + var date = folder.GetRecursiveChildren(i => !i.IsFolder).Select(i => i.DateCreated).Max(); + + if (!folder.DateLastMediaAdded.HasValue || folder.DateLastMediaAdded.Value != date) + { + folder.DateLastMediaAdded = date; + updateType = ItemUpdateType.MetadataEdit; + } + } + } + + return updateType; } /// @@ -420,7 +473,7 @@ namespace MediaBrowser.Providers.Manager : status.DateLastMetadataRefresh ?? default(DateTime); // Run all if either of these flags are true - var runAllProviders = options.ReplaceAllMetadata || options.MetadataRefreshMode == MetadataRefreshMode.FullRefresh || dateLastRefresh == default(DateTime); + var runAllProviders = options.ReplaceAllMetadata || options.MetadataRefreshMode == MetadataRefreshMode.FullRefresh || dateLastRefresh == default(DateTime) || item.RequiresRefresh(); if (!runAllProviders) { diff --git a/MediaBrowser.Providers/Music/MusicBrainzArtistProvider.cs b/MediaBrowser.Providers/Music/MusicBrainzArtistProvider.cs index ad900123e..2eb65f4e5 100644 --- a/MediaBrowser.Providers/Music/MusicBrainzArtistProvider.cs +++ b/MediaBrowser.Providers/Music/MusicBrainzArtistProvider.cs @@ -62,12 +62,25 @@ namespace MediaBrowser.Providers.Music private IEnumerable GetResultsFromResponse(XmlDocument doc) { - var ns = new XmlNamespaceManager(doc.NameTable); - ns.AddNamespace("mb", "https://musicbrainz.org/ns/mmd-2.0#"); + //var ns = new XmlNamespaceManager(doc.NameTable); + //ns.AddNamespace("mb", "https://musicbrainz.org/ns/mmd-2.0#"); var list = new List(); - var nodes = doc.SelectNodes("//mb:artist-list/mb:artist", ns); + var docElem = doc.DocumentElement; + + if (docElem == null) + { + return list; + } + + var artistList = docElem.FirstChild; + if (artistList == null) + { + return list; + } + + var nodes = artistList.ChildNodes; if (nodes != null) { @@ -79,11 +92,13 @@ namespace MediaBrowser.Providers.Music string mbzId = node.Attributes["id"].Value; - var nameNode = node.SelectSingleNode("//mb:name", ns); - - if (nameNode != null) + foreach (var child in node.ChildNodes.Cast()) { - name = nameNode.InnerText; + if (string.Equals(child.Name, "name", StringComparison.OrdinalIgnoreCase)) + { + name = node.InnerText; + break; + } } if (!string.IsNullOrWhiteSpace(mbzId) && !string.IsNullOrWhiteSpace(name)) diff --git a/MediaBrowser.Server.Implementations/Dto/DtoService.cs b/MediaBrowser.Server.Implementations/Dto/DtoService.cs index 0aec3230d..32610a6ad 100644 --- a/MediaBrowser.Server.Implementations/Dto/DtoService.cs +++ b/MediaBrowser.Server.Implementations/Dto/DtoService.cs @@ -499,6 +499,16 @@ namespace MediaBrowser.Server.Implementations.Dto } } + if (fields.Contains(ItemFields.CumulativeRunTimeTicks)) + { + dto.CumulativeRunTimeTicks = dto.RunTimeTicks; + } + + if (fields.Contains(ItemFields.DateLastMediaAdded)) + { + dto.DateLastMediaAdded = folder.DateLastMediaAdded; + } + dto.UserData.Played = dto.UserData.PlayedPercentage.HasValue && dto.UserData.PlayedPercentage.Value >= 100; } @@ -1613,9 +1623,7 @@ namespace MediaBrowser.Server.Implementations.Dto { var recursiveItemCount = 0; var unplayed = 0; - long runtime = 0; - DateTime? dateLastMediaAdded = null; double totalPercentPlayed = 0; double totalSyncPercent = 0; var addSyncInfo = fields.Contains(ItemFields.SyncInfo); @@ -1632,15 +1640,6 @@ namespace MediaBrowser.Server.Implementations.Dto // Loop through each recursive child foreach (var child in children) { - if (!dateLastMediaAdded.HasValue) - { - dateLastMediaAdded = child.DateCreated; - } - else - { - dateLastMediaAdded = new[] { dateLastMediaAdded.Value, child.DateCreated }.Max(); - } - var userdata = _userDataRepository.GetUserData(user, child); recursiveItemCount++; @@ -1669,8 +1668,6 @@ namespace MediaBrowser.Server.Implementations.Dto unplayed++; } - runtime += child.RunTimeTicks ?? 0; - if (addSyncInfo) { double percent = 0; @@ -1709,16 +1706,6 @@ namespace MediaBrowser.Server.Implementations.Dto } } } - - if (runtime > 0 && fields.Contains(ItemFields.CumulativeRunTimeTicks)) - { - dto.CumulativeRunTimeTicks = runtime; - } - - if (fields.Contains(ItemFields.DateLastMediaAdded)) - { - dto.DateLastMediaAdded = dateLastMediaAdded; - } } /// diff --git a/MediaBrowser.Server.Implementations/Library/LibraryManager.cs b/MediaBrowser.Server.Implementations/Library/LibraryManager.cs index f9bf3446f..c95b30172 100644 --- a/MediaBrowser.Server.Implementations/Library/LibraryManager.cs +++ b/MediaBrowser.Server.Implementations/Library/LibraryManager.cs @@ -1354,12 +1354,20 @@ namespace MediaBrowser.Server.Implementations.Library AddUserToQuery(query, query.User); } - var initialResult = ItemRepository.GetItemIds(query); + if (query.EnableTotalRecordCount) + { + var initialResult = ItemRepository.GetItemIds(query); + + return new QueryResult + { + TotalRecordCount = initialResult.TotalRecordCount, + Items = initialResult.Items.Select(GetItemById).Where(i => i != null).ToArray() + }; + } return new QueryResult { - TotalRecordCount = initialResult.TotalRecordCount, - Items = initialResult.Items.Select(GetItemById).Where(i => i != null).ToArray() + Items = ItemRepository.GetItemIdsList(query).Select(GetItemById).Where(i => i != null).ToArray() }; } diff --git a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs index c5920d3d6..b5e8ad79a 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs @@ -760,7 +760,14 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV if (info.IsMovie) { var customRecordingPath = config.MovieRecordingPath; - if ((string.IsNullOrWhiteSpace(customRecordingPath) || string.Equals(customRecordingPath, recordPath, StringComparison.OrdinalIgnoreCase)) && config.EnableRecordingSubfolders) + var allowSubfolder = true; + if (!string.IsNullOrWhiteSpace(customRecordingPath)) + { + allowSubfolder = string.Equals(customRecordingPath, recordPath, StringComparison.OrdinalIgnoreCase); + recordPath = customRecordingPath; + } + + if (allowSubfolder && config.EnableRecordingSubfolders) { recordPath = Path.Combine(recordPath, "Movies"); } @@ -775,7 +782,14 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV else if (info.IsSeries) { var customRecordingPath = config.SeriesRecordingPath; - if ((string.IsNullOrWhiteSpace(customRecordingPath) || string.Equals(customRecordingPath, recordPath, StringComparison.OrdinalIgnoreCase)) && config.EnableRecordingSubfolders) + var allowSubfolder = true; + if (!string.IsNullOrWhiteSpace(customRecordingPath)) + { + allowSubfolder = string.Equals(customRecordingPath, recordPath, StringComparison.OrdinalIgnoreCase); + recordPath = customRecordingPath; + } + + if (allowSubfolder && config.EnableRecordingSubfolders) { recordPath = Path.Combine(recordPath, "Series"); } diff --git a/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs b/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs index eec8328f8..175eed66c 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs @@ -886,7 +886,8 @@ namespace MediaBrowser.Server.Implementations.LiveTv StartIndex = query.StartIndex, Limit = query.Limit, SortBy = query.SortBy, - SortOrder = query.SortOrder ?? SortOrder.Ascending + SortOrder = query.SortOrder ?? SortOrder.Ascending, + EnableTotalRecordCount = query.EnableTotalRecordCount }; if (query.HasAired.HasValue) @@ -924,7 +925,8 @@ namespace MediaBrowser.Server.Implementations.LiveTv IsAiring = query.IsAiring, IsMovie = query.IsMovie, IsSports = query.IsSports, - IsKids = query.IsKids + IsKids = query.IsKids, + EnableTotalRecordCount = query.EnableTotalRecordCount }; if (query.HasAired.HasValue) @@ -1263,11 +1265,11 @@ namespace MediaBrowser.Server.Implementations.LiveTv private async Task CleanDatabaseInternal(List currentIdList, string[] validTypes, IProgress progress, CancellationToken cancellationToken) { - var list = _itemRepo.GetItemIds(new InternalItemsQuery + var list = _itemRepo.GetItemIdsList(new InternalItemsQuery { IncludeItemTypes = validTypes - }).Items.ToList(); + }).ToList(); var numComplete = 0; diff --git a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs index 09739f8a9..180bd3547 100644 --- a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs +++ b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs @@ -85,7 +85,7 @@ namespace MediaBrowser.Server.Implementations.Persistence private IDbCommand _updateInheritedRatingCommand; private IDbCommand _updateInheritedTagsCommand; - public const int LatestSchemaVersion = 76; + public const int LatestSchemaVersion = 77; /// /// Initializes a new instance of the class. @@ -235,6 +235,9 @@ namespace MediaBrowser.Server.Implementations.Persistence _connection.AddColumn(Logger, "TypedBaseItems", "SlugName", "Text"); _connection.AddColumn(Logger, "TypedBaseItems", "OriginalTitle", "Text"); _connection.AddColumn(Logger, "TypedBaseItems", "PrimaryVersionId", "Text"); + _connection.AddColumn(Logger, "TypedBaseItems", "DateLastMediaAdded", "DATETIME"); + _connection.AddColumn(Logger, "TypedBaseItems", "Album", "Text"); + _connection.AddColumn(Logger, "UserDataKeys", "Priority", "INT"); string[] postQueries = @@ -351,7 +354,9 @@ namespace MediaBrowser.Server.Implementations.Persistence "TrailerTypes", "DateModifiedDuringLastRefresh", "OriginalTitle", - "PrimaryVersionId" + "PrimaryVersionId", + "DateLastMediaAdded", + "Album" }; private readonly string[] _mediaStreamSaveColumns = @@ -463,7 +468,9 @@ namespace MediaBrowser.Server.Implementations.Persistence "PresentationUniqueKey", "SlugName", "OriginalTitle", - "PrimaryVersionId" + "PrimaryVersionId", + "DateLastMediaAdded", + "Album" }; _saveItemCommand = _connection.CreateCommand(); _saveItemCommand.CommandText = "replace into TypedBaseItems (" + string.Join(",", saveColumns.ToArray()) + ") values ("; @@ -824,6 +831,18 @@ namespace MediaBrowser.Server.Implementations.Persistence _saveItemCommand.GetParameter(index++).Value = null; } + var folder = item as Folder; + if (folder != null && folder.DateLastMediaAdded.HasValue) + { + _saveItemCommand.GetParameter(index++).Value = folder.DateLastMediaAdded.Value; + } + else + { + _saveItemCommand.GetParameter(index++).Value = null; + } + + _saveItemCommand.GetParameter(index++).Value = item.Album; + _saveItemCommand.Transaction = transaction; _saveItemCommand.ExecuteNonQuery(); @@ -1217,6 +1236,17 @@ namespace MediaBrowser.Server.Implementations.Persistence } } + var folder = item as Folder; + if (folder != null && !reader.IsDBNull(54)) + { + folder.DateLastMediaAdded = reader.GetDateTime(54).ToUniversalTime(); + } + + if (!reader.IsDBNull(55)) + { + item.Album = reader.GetString(55); + } + return item; } @@ -1777,6 +1807,10 @@ namespace MediaBrowser.Server.Implementations.Persistence { return new Tuple("played", false); } + if (string.Equals(name, ItemSortBy.DateLastContentAdded, StringComparison.OrdinalIgnoreCase)) + { + return new Tuple("DateLastMediaAdded", false); + } return new Tuple(name, false); } @@ -2484,7 +2518,7 @@ namespace MediaBrowser.Server.Implementations.Persistence if (query.MediaTypes.Length == 1) { whereClauses.Add("MediaType=@MediaTypes"); - cmd.Parameters.Add(cmd, "@MediaTypes", DbType.String).Value = query.MediaTypes[0].ToString(); + cmd.Parameters.Add(cmd, "@MediaTypes", DbType.String).Value = query.MediaTypes[0]; } if (query.MediaTypes.Length > 1) { @@ -2493,6 +2527,26 @@ namespace MediaBrowser.Server.Implementations.Persistence whereClauses.Add("MediaType in (" + val + ")"); } + if (query.AlbumNames.Length > 0) + { + var clause = "("; + + var index = 0; + foreach (var name in query.AlbumNames) + { + if (index > 0) + { + clause += " OR "; + } + clause += "Album=@AlbumName" + index; + index++; + cmd.Parameters.Add(cmd, "@AlbumName" + index, DbType.String).Value = name; + } + + clause += ")"; + whereClauses.Add(clause); + } + //var enableItemsByName = query.IncludeItemsByName ?? query.IncludeItemTypes.Length > 0; var enableItemsByName = query.IncludeItemsByName ?? false; diff --git a/MediaBrowser.Server.Implementations/Sorting/DateLastMediaAddedComparer.cs b/MediaBrowser.Server.Implementations/Sorting/DateLastMediaAddedComparer.cs index 68cd44ec9..5c51f5e0f 100644 --- a/MediaBrowser.Server.Implementations/Sorting/DateLastMediaAddedComparer.cs +++ b/MediaBrowser.Server.Implementations/Sorting/DateLastMediaAddedComparer.cs @@ -49,10 +49,10 @@ namespace MediaBrowser.Server.Implementations.Sorting if (folder != null) { - return folder.GetRecursiveChildren(User, i => !i.IsFolder) - .Select(i => i.DateCreated) - .OrderByDescending(i => i) - .FirstOrDefault(); + if (folder.DateLastMediaAdded.HasValue) + { + return folder.DateLastMediaAdded.Value; + } } return x.DateCreated; diff --git a/MediaBrowser.ServerApplication/MediaBrowser.ServerApplication.csproj b/MediaBrowser.ServerApplication/MediaBrowser.ServerApplication.csproj index f544a149d..366d4b608 100644 --- a/MediaBrowser.ServerApplication/MediaBrowser.ServerApplication.csproj +++ b/MediaBrowser.ServerApplication/MediaBrowser.ServerApplication.csproj @@ -142,8 +142,6 @@ - - diff --git a/MediaBrowser.ServerApplication/Native/WindowsApp.cs b/MediaBrowser.ServerApplication/Native/WindowsApp.cs index 808c7558e..271b02d9a 100644 --- a/MediaBrowser.ServerApplication/Native/WindowsApp.cs +++ b/MediaBrowser.ServerApplication/Native/WindowsApp.cs @@ -158,9 +158,9 @@ namespace MediaBrowser.ServerApplication.Native info.FFMpegFilename = "ffmpeg.exe"; info.FFProbeFilename = "ffprobe.exe"; - info.Version = "20160401"; + info.Version = "20160508"; info.ArchiveType = "7z"; - info.IsEmbedded = true; + info.IsEmbedded = false; info.DownloadUrls = GetDownloadUrls(); return info; @@ -212,11 +212,18 @@ namespace MediaBrowser.ServerApplication.Native switch (Environment.SystemArchitecture) { case Architecture.X86_X64: - return new[] { "MediaBrowser.ServerApplication.ffmpeg.ffmpegx64.7z" }; + return new[] + { + "https://github.com/MediaBrowser/Emby.Resources/raw/master/ffmpeg/windows/ffmpeg-20160508-win64.7z", + "https://ffmpeg.zeranoe.com/builds/win64/static/ffmpeg-20160508-git-caee88d-win64-static.7z" + }; case Architecture.X86: - return new[] { "MediaBrowser.ServerApplication.ffmpeg.ffmpegx86.7z" }; + return new[] + { + "https://github.com/MediaBrowser/Emby.Resources/raw/master/ffmpeg/windows/ffmpeg-20160508-win32.7z", + "https://ffmpeg.zeranoe.com/builds/win32/static/ffmpeg-20160508-git-caee88d-win32-static.7z" + }; } - return new string[] { }; } } diff --git a/MediaBrowser.ServerApplication/ffmpeg/ffmpegx64.7z.REMOVED.git-id b/MediaBrowser.ServerApplication/ffmpeg/ffmpegx64.7z.REMOVED.git-id deleted file mode 100644 index b0542b75f..000000000 --- a/MediaBrowser.ServerApplication/ffmpeg/ffmpegx64.7z.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -9dc10b022537738edce7eb71aa8dd4adbfee2c7b \ No newline at end of file diff --git a/MediaBrowser.ServerApplication/ffmpeg/ffmpegx86.7z.REMOVED.git-id b/MediaBrowser.ServerApplication/ffmpeg/ffmpegx86.7z.REMOVED.git-id deleted file mode 100644 index 3939ec44d..000000000 --- a/MediaBrowser.ServerApplication/ffmpeg/ffmpegx86.7z.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -00fa1afa35fbd0a7e97ad7956e42ae17f6882f64 \ No newline at end of file -- cgit v1.2.3 From 75b699fc4e2c78d4753c644d422d8a5e600ab7ce Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Mon, 9 May 2016 15:27:38 -0400 Subject: rework tabs --- MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs | 2 +- .../Sorting/DateLastMediaAddedComparer.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'MediaBrowser.Server.Implementations/Sorting') diff --git a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs index 20cc7f82a..6f83e5e06 100644 --- a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs +++ b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs @@ -852,7 +852,7 @@ namespace MediaBrowser.Server.Implementations.Persistence UpdateAncestors(item.Id, item.GetAncestorIds().Distinct().ToList(), transaction); } - UpdateUserDataKeys(item.Id, item.GetUserDataKeys(), transaction); + UpdateUserDataKeys(item.Id, item.GetUserDataKeys().Distinct(StringComparer.OrdinalIgnoreCase).ToList(), transaction); } transaction.Commit(); diff --git a/MediaBrowser.Server.Implementations/Sorting/DateLastMediaAddedComparer.cs b/MediaBrowser.Server.Implementations/Sorting/DateLastMediaAddedComparer.cs index 5c51f5e0f..e8c78b8e7 100644 --- a/MediaBrowser.Server.Implementations/Sorting/DateLastMediaAddedComparer.cs +++ b/MediaBrowser.Server.Implementations/Sorting/DateLastMediaAddedComparer.cs @@ -55,7 +55,7 @@ namespace MediaBrowser.Server.Implementations.Sorting } } - return x.DateCreated; + return DateTime.MinValue; } /// -- cgit v1.2.3 From de635fe22c935acc238201b312eed1db2ccb46cd Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sun, 10 Jul 2016 11:44:53 -0400 Subject: add faster access to series sort name --- MediaBrowser.Api/StartupWizardService.cs | 2 +- .../Updates/GithubUpdater.cs | 6 ++- MediaBrowser.Controller/Entities/Book.cs | 6 +++ MediaBrowser.Controller/Entities/Folder.cs | 23 ---------- MediaBrowser.Controller/Entities/IHasSeries.cs | 2 + MediaBrowser.Controller/Entities/TV/Episode.cs | 11 ++++- MediaBrowser.Controller/Entities/TV/Season.cs | 9 ++++ MediaBrowser.Controller/Entities/TV/Series.cs | 9 +--- .../Library/LibraryManager.cs | 7 ++- .../Persistence/SqliteItemRepository.cs | 52 ++++++++++++++++++++-- .../Sorting/SeriesSortNameComparer.cs | 24 +--------- MediaBrowser.WebDashboard/Api/DashboardService.cs | 11 ++--- 12 files changed, 94 insertions(+), 68 deletions(-) (limited to 'MediaBrowser.Server.Implementations/Sorting') diff --git a/MediaBrowser.Api/StartupWizardService.cs b/MediaBrowser.Api/StartupWizardService.cs index 87562b126..1bebd42eb 100644 --- a/MediaBrowser.Api/StartupWizardService.cs +++ b/MediaBrowser.Api/StartupWizardService.cs @@ -117,7 +117,7 @@ namespace MediaBrowser.Api config.EnableStandaloneMusicKeys = true; config.EnableCaseSensitiveItemIds = true; //config.EnableFolderView = true; - config.SchemaVersion = 107; + config.SchemaVersion = 108; } public void Post(UpdateStartupConfiguration request) diff --git a/MediaBrowser.Common.Implementations/Updates/GithubUpdater.cs b/MediaBrowser.Common.Implementations/Updates/GithubUpdater.cs index 2ffaedc4b..d1ec30210 100644 --- a/MediaBrowser.Common.Implementations/Updates/GithubUpdater.cs +++ b/MediaBrowser.Common.Implementations/Updates/GithubUpdater.cs @@ -54,7 +54,9 @@ namespace MediaBrowser.Common.Implementations.Updates { if (updateLevel == PackageVersionClass.Release) { - obj = obj.Where(i => !i.prerelease).ToArray(); + // Technically all we need to do is check that it's not pre-release + // But let's addititional checks for -beta and -dev to handle builds that might be temporarily tagged incorrectly. + obj = obj.Where(i => !i.prerelease && !i.name.EndsWith("-beta", StringComparison.OrdinalIgnoreCase) && !i.name.EndsWith("-dev", StringComparison.OrdinalIgnoreCase)).ToArray(); } else if (updateLevel == PackageVersionClass.Beta) { @@ -70,7 +72,7 @@ namespace MediaBrowser.Common.Implementations.Updates .Where(i => i != null) .OrderByDescending(i => Version.Parse(i.AvailableVersion)) .FirstOrDefault(); - + return availableUpdate ?? new CheckForUpdateResult { IsUpdateAvailable = false diff --git a/MediaBrowser.Controller/Entities/Book.cs b/MediaBrowser.Controller/Entities/Book.cs index 9d35c86d2..2ca56bc70 100644 --- a/MediaBrowser.Controller/Entities/Book.cs +++ b/MediaBrowser.Controller/Entities/Book.cs @@ -22,7 +22,13 @@ namespace MediaBrowser.Controller.Entities public string SeriesName { get; set; } [IgnoreDataMember] public Guid? SeriesId { get; set; } + [IgnoreDataMember] + public string SeriesSortName { get; set; } + public string FindSeriesSortName() + { + return SeriesSortName; + } public string FindSeriesName() { return SeriesName; diff --git a/MediaBrowser.Controller/Entities/Folder.cs b/MediaBrowser.Controller/Entities/Folder.cs index 210c11564..89b9479e7 100644 --- a/MediaBrowser.Controller/Entities/Folder.cs +++ b/MediaBrowser.Controller/Entities/Folder.cs @@ -760,11 +760,6 @@ namespace MediaBrowser.Controller.Entities Logger.Debug("Query requires post-filtering due to ItemSortBy.Revenue"); return true; } - if (query.SortBy.Contains(ItemSortBy.SeriesSortName, StringComparer.OrdinalIgnoreCase)) - { - Logger.Debug("Query requires post-filtering due to ItemSortBy.SeriesSortName"); - return true; - } if (query.SortBy.Contains(ItemSortBy.VideoBitRate, StringComparer.OrdinalIgnoreCase)) { Logger.Debug("Query requires post-filtering due to ItemSortBy.VideoBitRate"); @@ -859,24 +854,6 @@ namespace MediaBrowser.Controller.Entities return true; } - if (query.IsMissing.HasValue) - { - Logger.Debug("Query requires post-filtering due to IsMissing"); - return true; - } - - if (query.IsUnaired.HasValue) - { - Logger.Debug("Query requires post-filtering due to IsUnaired"); - return true; - } - - if (query.IsVirtualUnaired.HasValue) - { - Logger.Debug("Query requires post-filtering due to IsVirtualUnaired"); - return true; - } - if (UserViewBuilder.CollapseBoxSetItems(query, this, query.User, ConfigurationManager)) { Logger.Debug("Query requires post-filtering due to CollapseBoxSetItems"); diff --git a/MediaBrowser.Controller/Entities/IHasSeries.cs b/MediaBrowser.Controller/Entities/IHasSeries.cs index d4dbb8ef6..531f58788 100644 --- a/MediaBrowser.Controller/Entities/IHasSeries.cs +++ b/MediaBrowser.Controller/Entities/IHasSeries.cs @@ -11,6 +11,8 @@ namespace MediaBrowser.Controller.Entities /// The name of the series. string SeriesName { get; set; } string FindSeriesName(); + string SeriesSortName { get; set; } + string FindSeriesSortName(); Guid? SeriesId { get; set; } Guid? FindSeriesId(); } diff --git a/MediaBrowser.Controller/Entities/TV/Episode.cs b/MediaBrowser.Controller/Entities/TV/Episode.cs index 78c35ad48..726390f65 100644 --- a/MediaBrowser.Controller/Entities/TV/Episode.cs +++ b/MediaBrowser.Controller/Entities/TV/Episode.cs @@ -53,7 +53,16 @@ namespace MediaBrowser.Controller.Entities.TV /// This is the ending episode number for double episodes. /// /// The index number. - public int? IndexNumberEnd { get; set; } + public int? IndexNumberEnd { get; set; } + + [IgnoreDataMember] + public string SeriesSortName { get; set; } + + public string FindSeriesSortName() + { + var series = Series; + return series == null ? SeriesSortName : series.SortName; + } [IgnoreDataMember] protected override bool SupportsOwnedItems diff --git a/MediaBrowser.Controller/Entities/TV/Season.cs b/MediaBrowser.Controller/Entities/TV/Season.cs index 865cadeb9..ee01c60b1 100644 --- a/MediaBrowser.Controller/Entities/TV/Season.cs +++ b/MediaBrowser.Controller/Entities/TV/Season.cs @@ -51,6 +51,15 @@ namespace MediaBrowser.Controller.Entities.TV } } + [IgnoreDataMember] + public string SeriesSortName { get; set; } + + public string FindSeriesSortName() + { + var series = Series; + return series == null ? SeriesSortName : series.SortName; + } + // Genre, Rating and Stuido will all be the same protected override IEnumerable GetIndexByOptions() { diff --git a/MediaBrowser.Controller/Entities/TV/Series.cs b/MediaBrowser.Controller/Entities/TV/Series.cs index 09ddbc6b6..ad35b3d36 100644 --- a/MediaBrowser.Controller/Entities/TV/Series.cs +++ b/MediaBrowser.Controller/Entities/TV/Series.cs @@ -449,13 +449,8 @@ namespace MediaBrowser.Controller.Entities.TV return true; } - if (!episode.ParentIndexNumber.HasValue) - { - var season = episode.Season; - return season != null && string.Equals(GetUniqueSeriesKey(season), seasonPresentationKey, StringComparison.OrdinalIgnoreCase); - } - - return false; + var season = episode.Season; + return season != null && string.Equals(GetUniqueSeriesKey(season), seasonPresentationKey, StringComparison.OrdinalIgnoreCase); }); } diff --git a/MediaBrowser.Server.Implementations/Library/LibraryManager.cs b/MediaBrowser.Server.Implementations/Library/LibraryManager.cs index a6c5d5429..82be653e1 100644 --- a/MediaBrowser.Server.Implementations/Library/LibraryManager.cs +++ b/MediaBrowser.Server.Implementations/Library/LibraryManager.cs @@ -1932,7 +1932,7 @@ namespace MediaBrowser.Server.Implementations.Library private string GetContentTypeOverride(string path, bool inherit) { - var nameValuePair = ConfigurationManager.Configuration.ContentTypes.FirstOrDefault(i => string.Equals(i.Name, path, StringComparison.OrdinalIgnoreCase) || (inherit && _fileSystem.ContainsSubPath(i.Name, path))); + var nameValuePair = ConfigurationManager.Configuration.ContentTypes.FirstOrDefault(i => string.Equals(i.Name, path, StringComparison.OrdinalIgnoreCase) || (inherit && !string.IsNullOrWhiteSpace(i.Name) && _fileSystem.ContainsSubPath(i.Name, path))); if (nameValuePair != null) { return nameValuePair.Value; @@ -2813,6 +2813,11 @@ namespace MediaBrowser.Server.Implementations.Library private void RemoveContentTypeOverrides(string path) { + if (string.IsNullOrWhiteSpace(path)) + { + throw new ArgumentNullException("path"); + } + var removeList = new List(); foreach (var contentType in ConfigurationManager.Configuration.ContentTypes) diff --git a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs index a3217e3ed..5e09c1d0b 100644 --- a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs +++ b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs @@ -95,7 +95,7 @@ namespace MediaBrowser.Server.Implementations.Persistence private IDbCommand _updateInheritedRatingCommand; private IDbCommand _updateInheritedTagsCommand; - public const int LatestSchemaVersion = 107; + public const int LatestSchemaVersion = 108; /// /// Initializes a new instance of the class. @@ -272,6 +272,7 @@ namespace MediaBrowser.Server.Implementations.Persistence _connection.AddColumn(Logger, "TypedBaseItems", "SeasonName", "Text"); _connection.AddColumn(Logger, "TypedBaseItems", "SeasonId", "GUID"); _connection.AddColumn(Logger, "TypedBaseItems", "SeriesId", "GUID"); + _connection.AddColumn(Logger, "TypedBaseItems", "SeriesSortName", "Text"); _connection.AddColumn(Logger, "UserDataKeys", "Priority", "INT"); _connection.AddColumn(Logger, "ItemValues", "CleanValue", "Text"); @@ -412,7 +413,8 @@ namespace MediaBrowser.Server.Implementations.Persistence "SeriesName", "SeasonName", "SeasonId", - "SeriesId" + "SeriesId", + "SeriesSortName" }; private readonly string[] _mediaStreamSaveColumns = @@ -535,7 +537,8 @@ namespace MediaBrowser.Server.Implementations.Persistence "UserDataKey", "SeasonName", "SeasonId", - "SeriesId" + "SeriesId", + "SeriesSortName" }; _saveItemCommand = _connection.CreateCommand(); _saveItemCommand.CommandText = "replace into TypedBaseItems (" + string.Join(",", saveColumns.ToArray()) + ") values ("; @@ -982,10 +985,12 @@ namespace MediaBrowser.Server.Implementations.Persistence if (hasSeries != null) { _saveItemCommand.GetParameter(index++).Value = hasSeries.FindSeriesId(); + _saveItemCommand.GetParameter(index++).Value = hasSeries.FindSeriesSortName(); } else { _saveItemCommand.GetParameter(index++).Value = null; + _saveItemCommand.GetParameter(index++).Value = null; } _saveItemCommand.Transaction = transaction; @@ -1440,6 +1445,14 @@ namespace MediaBrowser.Server.Implementations.Persistence } } + if (hasSeries != null) + { + if (!reader.IsDBNull(63)) + { + hasSeries.SeriesSortName = reader.GetString(63); + } + } + return item; } @@ -3056,6 +3069,39 @@ namespace MediaBrowser.Server.Implementations.Persistence whereClauses.Add("LocationType<>'Virtual'"); } } + if (query.IsUnaired.HasValue) + { + if (query.IsUnaired.Value) + { + whereClauses.Add("PremiereDate >= DATETIME('now')"); + } + else + { + whereClauses.Add("PremiereDate < DATETIME('now')"); + } + } + if (query.IsMissing.HasValue && _config.Configuration.SchemaVersion >= 90) + { + if (query.IsMissing.Value) + { + whereClauses.Add("(IsVirtualItem=1 AND PremiereDate < DATETIME('now'))"); + } + else + { + whereClauses.Add("(IsVirtualItem=0 OR PremiereDate >= DATETIME('now'))"); + } + } + if (query.IsVirtualUnaired.HasValue && _config.Configuration.SchemaVersion >= 90) + { + if (query.IsVirtualUnaired.Value) + { + whereClauses.Add("(IsVirtualItem=1 AND PremiereDate >= DATETIME('now'))"); + } + else + { + whereClauses.Add("(IsVirtualItem=0 OR PremiereDate < DATETIME('now'))"); + } + } if (query.MediaTypes.Length == 1) { whereClauses.Add("MediaType=@MediaTypes"); diff --git a/MediaBrowser.Server.Implementations/Sorting/SeriesSortNameComparer.cs b/MediaBrowser.Server.Implementations/Sorting/SeriesSortNameComparer.cs index 4efc3218b..6bc1264a4 100644 --- a/MediaBrowser.Server.Implementations/Sorting/SeriesSortNameComparer.cs +++ b/MediaBrowser.Server.Implementations/Sorting/SeriesSortNameComparer.cs @@ -1,5 +1,4 @@ using MediaBrowser.Controller.Entities; -using MediaBrowser.Controller.Entities.TV; using MediaBrowser.Controller.Sorting; using MediaBrowser.Model.Querying; using System; @@ -21,28 +20,9 @@ namespace MediaBrowser.Server.Implementations.Sorting private string GetValue(BaseItem item) { - Series series = null; + var hasSeries = item as IHasSeries; - var season = item as Season; - - if (season != null) - { - series = season.Series; - } - - var episode = item as Episode; - - if (episode != null) - { - series = episode.Series; - } - - if (series == null) - { - series = item as Series; - } - - return series != null ? series.SortName : null; + return hasSeries != null ? hasSeries.SeriesSortName : null; } /// diff --git a/MediaBrowser.WebDashboard/Api/DashboardService.cs b/MediaBrowser.WebDashboard/Api/DashboardService.cs index 1a227126e..d42382442 100644 --- a/MediaBrowser.WebDashboard/Api/DashboardService.cs +++ b/MediaBrowser.WebDashboard/Api/DashboardService.cs @@ -349,8 +349,8 @@ namespace MediaBrowser.WebDashboard.Api } _fileSystem.DeleteDirectory(Path.Combine(bowerPath, "jquery", "src"), true); - _fileSystem.DeleteDirectory(Path.Combine(bowerPath, "fingerprintjs2", "flash"), true); - _fileSystem.DeleteDirectory(Path.Combine(bowerPath, "fingerprintjs2", "specs"), true); + //_fileSystem.DeleteDirectory(Path.Combine(bowerPath, "fingerprintjs2", "flash"), true); + //_fileSystem.DeleteDirectory(Path.Combine(bowerPath, "fingerprintjs2", "specs"), true); DeleteCryptoFiles(Path.Combine(bowerPath, "cryptojslib", "components")); @@ -358,12 +358,7 @@ namespace MediaBrowser.WebDashboard.Api DeleteFoldersByName(Path.Combine(bowerPath, "jstree"), "src"); DeleteFoldersByName(Path.Combine(bowerPath, "Sortable"), "meteor"); DeleteFoldersByName(Path.Combine(bowerPath, "Sortable"), "st"); - DeleteFoldersByName(Path.Combine(bowerPath, "Swiper"), "src"); - - _fileSystem.DeleteDirectory(Path.Combine(bowerPath, "marked"), true); - _fileSystem.DeleteDirectory(Path.Combine(bowerPath, "marked-element"), true); - _fileSystem.DeleteDirectory(Path.Combine(bowerPath, "prism"), true); - _fileSystem.DeleteDirectory(Path.Combine(bowerPath, "prism-element"), true); + //DeleteFoldersByName(Path.Combine(bowerPath, "Swiper"), "src"); if (string.Equals(mode, "cordova", StringComparison.OrdinalIgnoreCase)) { -- cgit v1.2.3