diff --git a/MediaBrowser.Api/Reports/ReportsService.cs b/MediaBrowser.Api/Reports/ReportsService.cs index d3e9abe69e..59e9692350 100644 --- a/MediaBrowser.Api/Reports/ReportsService.cs +++ b/MediaBrowser.Api/Reports/ReportsService.cs @@ -258,7 +258,8 @@ namespace MediaBrowser.Api.Reports MinPlayers = request.MinPlayers, MaxPlayers = request.MaxPlayers, MinCommunityRating = request.MinCommunityRating, - MinCriticRating = request.MinCriticRating + MinCriticRating = request.MinCriticRating, + ParentIndexNumber = request.ParentIndexNumber }; if (!string.IsNullOrWhiteSpace(request.Ids)) @@ -312,6 +313,29 @@ namespace MediaBrowser.Api.Reports query.MaxPremiereDate = DateTime.Parse(request.MaxPremiereDate, null, DateTimeStyles.RoundtripKind).ToUniversalTime(); } + // Filter by Series Status + if (!string.IsNullOrEmpty(request.SeriesStatus)) + { + query.SeriesStatuses = request.SeriesStatus.Split(',').Select(d => (SeriesStatus)Enum.Parse(typeof(SeriesStatus), d, true)).ToArray(); + } + + // Filter by Series AirDays + if (!string.IsNullOrEmpty(request.AirDays)) + { + query.AirDays = request.AirDays.Split(',').Select(d => (DayOfWeek)Enum.Parse(typeof(DayOfWeek), d, true)).ToArray(); + } + + // ExcludeLocationTypes + if (!string.IsNullOrEmpty(request.ExcludeLocationTypes)) + { + query.ExcludeLocationTypes = request.ExcludeLocationTypes.Split(',').Select(d => (LocationType)Enum.Parse(typeof(LocationType), d, true)).ToArray(); + } + + if (!string.IsNullOrEmpty(request.LocationTypes)) + { + query.LocationTypes = request.LocationTypes.Split(',').Select(d => (LocationType)Enum.Parse(typeof(LocationType), d, true)).ToArray(); + } + if (request.HasQueryLimit == false) { query.StartIndex = null; @@ -452,26 +476,6 @@ namespace MediaBrowser.Api.Reports } } - // LocationTypes - if (!string.IsNullOrEmpty(request.LocationTypes)) - { - var vals = request.LocationTypes.Split(','); - if (!vals.Contains(i.LocationType.ToString(), StringComparer.OrdinalIgnoreCase)) - { - return false; - } - } - - // ExcludeLocationTypes - if (!string.IsNullOrEmpty(request.ExcludeLocationTypes)) - { - var vals = request.ExcludeLocationTypes.Split(','); - if (vals.Contains(i.LocationType.ToString(), StringComparer.OrdinalIgnoreCase)) - { - return false; - } - } - if (!string.IsNullOrEmpty(request.AlbumArtistStartsWithOrGreater)) { var ok = new[] { i }.OfType() @@ -483,57 +487,6 @@ namespace MediaBrowser.Api.Reports } } - // Filter by Series Status - if (!string.IsNullOrEmpty(request.SeriesStatus)) - { - var vals = request.SeriesStatus.Split(','); - - var ok = new[] { i }.OfType().Any(p => p.Status.HasValue && vals.Contains(p.Status.Value.ToString(), StringComparer.OrdinalIgnoreCase)); - - if (!ok) - { - return false; - } - } - - // Filter by Series AirDays - if (!string.IsNullOrEmpty(request.AirDays)) - { - var days = request.AirDays.Split(',').Select(d => (DayOfWeek)Enum.Parse(typeof(DayOfWeek), d, true)); - - var ok = new[] { i }.OfType().Any(p => p.AirDays != null && days.Any(d => p.AirDays.Contains(d))); - - if (!ok) - { - return false; - } - } - - if (request.ParentIndexNumber.HasValue) - { - var filterValue = request.ParentIndexNumber.Value; - - var episode = i as Episode; - - if (episode != null) - { - if (episode.ParentIndexNumber.HasValue && episode.ParentIndexNumber.Value != filterValue) - { - return false; - } - } - - var song = i as Audio; - - if (song != null) - { - if (song.ParentIndexNumber.HasValue && song.ParentIndexNumber.Value != filterValue) - { - return false; - } - } - } - if (request.AiredDuringSeason.HasValue) { var episode = i as Episode; diff --git a/MediaBrowser.Api/UserLibrary/ItemsService.cs b/MediaBrowser.Api/UserLibrary/ItemsService.cs index e739ac7c2c..a48fcbc93a 100644 --- a/MediaBrowser.Api/UserLibrary/ItemsService.cs +++ b/MediaBrowser.Api/UserLibrary/ItemsService.cs @@ -231,7 +231,8 @@ namespace MediaBrowser.Api.UserLibrary MaxPlayers = request.MaxPlayers, MinCommunityRating = request.MinCommunityRating, MinCriticRating = request.MinCriticRating, - ParentId = string.IsNullOrWhiteSpace(request.ParentId) ? (Guid?)null : new Guid(request.ParentId) + ParentId = string.IsNullOrWhiteSpace(request.ParentId) ? (Guid?)null : new Guid(request.ParentId), + ParentIndexNumber = request.ParentIndexNumber }; if (!string.IsNullOrWhiteSpace(request.Ids)) @@ -285,6 +286,29 @@ namespace MediaBrowser.Api.UserLibrary query.MaxPremiereDate = DateTime.Parse(request.MaxPremiereDate, null, DateTimeStyles.RoundtripKind).ToUniversalTime(); } + // Filter by Series Status + if (!string.IsNullOrEmpty(request.SeriesStatus)) + { + query.SeriesStatuses = request.SeriesStatus.Split(',').Select(d => (SeriesStatus)Enum.Parse(typeof(SeriesStatus), d, true)).ToArray(); + } + + // Filter by Series AirDays + if (!string.IsNullOrEmpty(request.AirDays)) + { + query.AirDays = request.AirDays.Split(',').Select(d => (DayOfWeek)Enum.Parse(typeof(DayOfWeek), d, true)).ToArray(); + } + + // ExcludeLocationTypes + if (!string.IsNullOrEmpty(request.ExcludeLocationTypes)) + { + query.ExcludeLocationTypes = request.ExcludeLocationTypes.Split(',').Select(d => (LocationType)Enum.Parse(typeof(LocationType), d, true)).ToArray(); + } + + if (!string.IsNullOrEmpty(request.LocationTypes)) + { + query.LocationTypes = request.LocationTypes.Split(',').Select(d => (LocationType)Enum.Parse(typeof(LocationType), d, true)).ToArray(); + } + return query; } @@ -410,26 +434,6 @@ namespace MediaBrowser.Api.UserLibrary } } - // LocationTypes - if (!string.IsNullOrEmpty(request.LocationTypes)) - { - var vals = request.LocationTypes.Split(','); - if (!vals.Contains(i.LocationType.ToString(), StringComparer.OrdinalIgnoreCase)) - { - return false; - } - } - - // ExcludeLocationTypes - if (!string.IsNullOrEmpty(request.ExcludeLocationTypes)) - { - var vals = request.ExcludeLocationTypes.Split(','); - if (vals.Contains(i.LocationType.ToString(), StringComparer.OrdinalIgnoreCase)) - { - return false; - } - } - if (!string.IsNullOrEmpty(request.AlbumArtistStartsWithOrGreater)) { var ok = new[] { i }.OfType() @@ -441,57 +445,6 @@ namespace MediaBrowser.Api.UserLibrary } } - // Filter by Series Status - if (!string.IsNullOrEmpty(request.SeriesStatus)) - { - var vals = request.SeriesStatus.Split(','); - - var ok = new[] { i }.OfType().Any(p => p.Status.HasValue && vals.Contains(p.Status.Value.ToString(), StringComparer.OrdinalIgnoreCase)); - - if (!ok) - { - return false; - } - } - - // Filter by Series AirDays - if (!string.IsNullOrEmpty(request.AirDays)) - { - var days = request.AirDays.Split(',').Select(d => (DayOfWeek)Enum.Parse(typeof(DayOfWeek), d, true)); - - var ok = new[] { i }.OfType().Any(p => p.AirDays != null && days.Any(d => p.AirDays.Contains(d))); - - if (!ok) - { - return false; - } - } - - if (request.ParentIndexNumber.HasValue) - { - var filterValue = request.ParentIndexNumber.Value; - - var episode = i as Episode; - - if (episode != null) - { - if (episode.ParentIndexNumber.HasValue && episode.ParentIndexNumber.Value != filterValue) - { - return false; - } - } - - var song = i as Audio; - - if (song != null) - { - if (song.ParentIndexNumber.HasValue && song.ParentIndexNumber.Value != filterValue) - { - return false; - } - } - } - if (request.AiredDuringSeason.HasValue) { var episode = i as Episode; diff --git a/MediaBrowser.Controller/Entities/Folder.cs b/MediaBrowser.Controller/Entities/Folder.cs index efb784153a..5a5fe2a9f1 100644 --- a/MediaBrowser.Controller/Entities/Folder.cs +++ b/MediaBrowser.Controller/Entities/Folder.cs @@ -1094,13 +1094,6 @@ namespace MediaBrowser.Controller.Entities return true; } - // Apply year filter - if (query.Years.Length > 0) - { - Logger.Debug("Query requires post-filtering due to Years"); - return true; - } - // Apply official rating filter if (query.OfficialRatings.Length > 0) { @@ -1139,12 +1132,6 @@ namespace MediaBrowser.Controller.Entities return true; } - if (query.Years.Length > 0) - { - Logger.Debug("Query requires post-filtering due to Years"); - return true; - } - if (query.OfficialRatings.Length > 0) { Logger.Debug("Query requires post-filtering due to OfficialRatings"); @@ -1205,6 +1192,18 @@ namespace MediaBrowser.Controller.Entities return true; } + if (query.AirDays.Length > 0) + { + Logger.Debug("Query requires post-filtering due to AirDays"); + return true; + } + + if (query.SeriesStatuses.Length > 0) + { + Logger.Debug("Query requires post-filtering due to SeriesStatuses"); + return true; + } + return false; } diff --git a/MediaBrowser.Controller/Entities/InternalItemsQuery.cs b/MediaBrowser.Controller/Entities/InternalItemsQuery.cs index 05031691c8..e2b393d4d9 100644 --- a/MediaBrowser.Controller/Entities/InternalItemsQuery.cs +++ b/MediaBrowser.Controller/Entities/InternalItemsQuery.cs @@ -103,17 +103,18 @@ namespace MediaBrowser.Controller.Entities public string[] ChannelIds { get; set; } internal List ItemIdsFromPersonFilters { get; set; } + public int? ParentIndexNumber { get; set; } public int? MaxParentalRating { get; set; } public bool? IsCurrentSchema { get; set; } public bool? HasDeadParentId { get; set; } public bool? IsOffline { get; set; } - public LocationType? LocationType { get; set; } public Guid? ParentId { get; set; } public string[] AncestorIds { get; set; } public string[] TopParentIds { get; set; } + public LocationType[] LocationTypes { get; set; } public LocationType[] ExcludeLocationTypes { get; set; } public string[] PresetViews { get; set; } public SourceType[] SourceTypes { get; set; } @@ -121,6 +122,9 @@ namespace MediaBrowser.Controller.Entities public TrailerType[] TrailerTypes { get; set; } public TrailerType[] ExcludeTrailerTypes { get; set; } + public DayOfWeek[] AirDays { get; set; } + public SeriesStatus[] SeriesStatuses { get; set; } + public InternalItemsQuery() { BlockUnratedItems = new UnratedItem[] { }; @@ -144,12 +148,15 @@ namespace MediaBrowser.Controller.Entities AncestorIds = new string[] { }; TopParentIds = new string[] { }; ExcludeTags = new string[] { }; + LocationTypes = new LocationType[] { }; ExcludeLocationTypes = new LocationType[] { }; PresetViews = new string[] { }; SourceTypes = new SourceType[] { }; ExcludeSourceTypes = new SourceType[] { }; TrailerTypes = new TrailerType[] { }; ExcludeTrailerTypes = new TrailerType[] { }; + AirDays = new DayOfWeek[] { }; + SeriesStatuses = new SeriesStatus[] { }; } public InternalItemsQuery(User user) diff --git a/MediaBrowser.Controller/Entities/UserViewBuilder.cs b/MediaBrowser.Controller/Entities/UserViewBuilder.cs index 4439b9c6d1..c33212619b 100644 --- a/MediaBrowser.Controller/Entities/UserViewBuilder.cs +++ b/MediaBrowser.Controller/Entities/UserViewBuilder.cs @@ -1709,6 +1709,34 @@ namespace MediaBrowser.Controller.Entities } } + if (query.ParentIndexNumber.HasValue) + { + var filterValue = query.ParentIndexNumber.Value; + + if (item.ParentIndexNumber.HasValue && item.ParentIndexNumber.Value != filterValue) + { + return false; + } + } + + if (query.AirDays.Length > 0) + { + var ok = new[] { item }.OfType().Any(p => p.AirDays != null && query.AirDays.Any(d => p.AirDays.Contains(d))); + if (!ok) + { + return false; + } + } + + if (query.SeriesStatuses.Length > 0) + { + var ok = new[] { item }.OfType().Any(p => p.Status.HasValue && query.SeriesStatuses.Contains(p.Status.Value)); + if (!ok) + { + return false; + } + } + return true; } diff --git a/MediaBrowser.Server.Implementations/Persistence/CleanDatabaseScheduledTask.cs b/MediaBrowser.Server.Implementations/Persistence/CleanDatabaseScheduledTask.cs index 028d9eb1fa..bec105b0a1 100644 --- a/MediaBrowser.Server.Implementations/Persistence/CleanDatabaseScheduledTask.cs +++ b/MediaBrowser.Server.Implementations/Persistence/CleanDatabaseScheduledTask.cs @@ -208,7 +208,7 @@ namespace MediaBrowser.Server.Implementations.Persistence await item.Delete(new DeleteOptions { DeleteFileLocation = false - + }).ConfigureAwait(false); } @@ -225,7 +225,7 @@ namespace MediaBrowser.Server.Implementations.Persistence { var result = _itemRepo.GetItemIdsWithPath(new InternalItemsQuery { - LocationType = LocationType.FileSystem, + LocationTypes = new[] { LocationType.FileSystem }, //Limit = limit, // These have their own cleanup routines diff --git a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs index 491f2c1162..e17b7d953e 100644 --- a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs +++ b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs @@ -80,7 +80,7 @@ namespace MediaBrowser.Server.Implementations.Persistence private IDbCommand _saveAncestorCommand; private IDbCommand _updateInheritedRatingCommand; - + private const int LatestSchemaVersion = 48; /// @@ -160,7 +160,7 @@ namespace MediaBrowser.Server.Implementations.Persistence _connection.RunQueries(queries, Logger); _connection.AddColumn(Logger, "AncestorIds", "AncestorIdText", "Text"); - + _connection.AddColumn(Logger, "TypedBaseItems", "Path", "Text"); _connection.AddColumn(Logger, "TypedBaseItems", "StartDate", "DATETIME"); _connection.AddColumn(Logger, "TypedBaseItems", "EndDate", "DATETIME"); @@ -1809,11 +1809,6 @@ namespace MediaBrowser.Server.Implementations.Persistence whereClauses.Add("IsOffline=@IsOffline"); cmd.Parameters.Add(cmd, "@IsOffline", DbType.Boolean).Value = query.IsOffline; } - if (query.LocationType.HasValue) - { - whereClauses.Add("LocationType=@LocationType"); - cmd.Parameters.Add(cmd, "@LocationType", DbType.String).Value = query.LocationType.Value; - } if (query.IsMovie.HasValue) { whereClauses.Add("IsMovie=@IsMovie"); @@ -1906,6 +1901,11 @@ namespace MediaBrowser.Server.Implementations.Persistence // cmd.Parameters.Add(cmd, "@MaxPlayers", DbType.Int32).Value = query.MaxPlayers.Value; //} + if (query.ParentIndexNumber.HasValue) + { + whereClauses.Add("ParentIndexNumber=@MinEndDate"); + cmd.Parameters.Add(cmd, "@ParentIndexNumber", DbType.Int32).Value = query.ParentIndexNumber.Value; + } if (query.MinEndDate.HasValue) { whereClauses.Add("EndDate>=@MinEndDate"); @@ -1990,7 +1990,7 @@ namespace MediaBrowser.Server.Implementations.Persistence var clause = "(" + string.Join(" AND ", clauses.ToArray()) + ")"; whereClauses.Add(clause); } - + if (query.IsAiring.HasValue) { if (query.IsAiring.Value) @@ -2087,12 +2087,36 @@ namespace MediaBrowser.Server.Implementations.Persistence whereClauses.Add("ParentId NOT NULL AND ParentId NOT IN (select guid from TypedBaseItems)"); } } + + if (query.Years.Length == 1) + { + whereClauses.Add("ProductionYear=@Years"); + cmd.Parameters.Add(cmd, "@Years", DbType.Int32).Value = query.Years[0].ToString(); + } + else if (query.Years.Length > 1) + { + var val = string.Join(",", query.Years.ToArray()); + + whereClauses.Add("ProductionYear in (" + val + ")"); + } + + if (query.LocationTypes.Length == 1) + { + whereClauses.Add("LocationType=@LocationType"); + cmd.Parameters.Add(cmd, "@LocationType", DbType.String).Value = query.LocationTypes[0].ToString(); + } + else if (query.LocationTypes.Length > 1) + { + var val = string.Join(",", query.LocationTypes.Select(i => "'" + i + "'").ToArray()); + + whereClauses.Add("LocationType in (" + val + ")"); + } if (query.ExcludeLocationTypes.Length == 1) { - whereClauses.Add("LocationType<>@LocationType"); - cmd.Parameters.Add(cmd, "@LocationType", DbType.String).Value = query.ExcludeLocationTypes[0].ToString(); + whereClauses.Add("LocationType<>@ExcludeLocationTypes"); + cmd.Parameters.Add(cmd, "@ExcludeLocationTypes", DbType.String).Value = query.ExcludeLocationTypes[0].ToString(); } - if (query.ExcludeLocationTypes.Length > 1) + else if (query.ExcludeLocationTypes.Length > 1) { var val = string.Join(",", query.ExcludeLocationTypes.Select(i => "'" + i + "'").ToArray()); @@ -2128,7 +2152,7 @@ namespace MediaBrowser.Server.Implementations.Persistence if (query.TopParentIds.Length > 1) { var val = string.Join(",", query.TopParentIds.Select(i => "'" + i + "'").ToArray()); - + if (enableItemsByName) { whereClauses.Add("(IsItemByName=@IsItemByName or TopParentId in (" + val + "))"); @@ -2169,7 +2193,7 @@ namespace MediaBrowser.Server.Implementations.Persistence cmd.Parameters.Add(cmd, "@excludeTag" + excludeTagIndex, DbType.String).Value = "%" + excludeTag + "%"; excludeTagIndex++; } - + if (addPaging) { if (query.StartIndex.HasValue && query.StartIndex.Value > 0) @@ -2252,7 +2276,7 @@ namespace MediaBrowser.Server.Implementations.Persistence { return; } - + await WriteLock.WaitAsync(cancellationToken).ConfigureAwait(false); IDbTransaction transaction = null; diff --git a/Nuget/MediaBrowser.Common.Internal.nuspec b/Nuget/MediaBrowser.Common.Internal.nuspec index 259eb6f896..10a8987850 100644 --- a/Nuget/MediaBrowser.Common.Internal.nuspec +++ b/Nuget/MediaBrowser.Common.Internal.nuspec @@ -2,7 +2,7 @@ MediaBrowser.Common.Internal - 3.0.643 + 3.0.644 MediaBrowser.Common.Internal Luke ebr,Luke,scottisafool @@ -12,7 +12,7 @@ Contains common components shared by Emby Theater and Emby Server. Not intended for plugin developer consumption. Copyright © Emby 2013 - + diff --git a/Nuget/MediaBrowser.Common.nuspec b/Nuget/MediaBrowser.Common.nuspec index d1cb66cbb5..616f0ca2a1 100644 --- a/Nuget/MediaBrowser.Common.nuspec +++ b/Nuget/MediaBrowser.Common.nuspec @@ -2,7 +2,7 @@ MediaBrowser.Common - 3.0.643 + 3.0.644 MediaBrowser.Common Emby Team ebr,Luke,scottisafool diff --git a/Nuget/MediaBrowser.Model.Signed.nuspec b/Nuget/MediaBrowser.Model.Signed.nuspec index 056359ae4e..d17ff16b6a 100644 --- a/Nuget/MediaBrowser.Model.Signed.nuspec +++ b/Nuget/MediaBrowser.Model.Signed.nuspec @@ -2,7 +2,7 @@ MediaBrowser.Model.Signed - 3.0.643 + 3.0.644 MediaBrowser.Model - Signed Edition Emby Team ebr,Luke,scottisafool diff --git a/Nuget/MediaBrowser.Server.Core.nuspec b/Nuget/MediaBrowser.Server.Core.nuspec index 6737a432f2..2098bbcfee 100644 --- a/Nuget/MediaBrowser.Server.Core.nuspec +++ b/Nuget/MediaBrowser.Server.Core.nuspec @@ -2,7 +2,7 @@ MediaBrowser.Server.Core - 3.0.643 + 3.0.644 Media Browser.Server.Core Emby Team ebr,Luke,scottisafool @@ -12,7 +12,7 @@ Contains core components required to build plugins for Emby Server. Copyright © Emby 2013 - +