diff --git a/MediaBrowser.Api/TvShowsService.cs b/MediaBrowser.Api/TvShowsService.cs index ead232888e..2dad9533fe 100644 --- a/MediaBrowser.Api/TvShowsService.cs +++ b/MediaBrowser.Api/TvShowsService.cs @@ -286,7 +286,7 @@ namespace MediaBrowser.Api StartIndex = request.StartIndex, Limit = request.Limit - }, user, parentIds); + }, parentIds); var options = GetDtoOptions(request); diff --git a/MediaBrowser.Controller/Entities/InternalItemsQuery.cs b/MediaBrowser.Controller/Entities/InternalItemsQuery.cs index 038a463161..5c60e19f0c 100644 --- a/MediaBrowser.Controller/Entities/InternalItemsQuery.cs +++ b/MediaBrowser.Controller/Entities/InternalItemsQuery.cs @@ -103,7 +103,9 @@ namespace MediaBrowser.Controller.Entities public Guid? ParentId { get; set; } public string[] AncestorIds { get; set; } - + + public LocationType[] ExcludeLocationTypes { get; set; } + public InternalItemsQuery() { Tags = new string[] { }; @@ -123,6 +125,7 @@ namespace MediaBrowser.Controller.Entities ChannelIds = new string[] { }; ItemIds = new string[] { }; AncestorIds = new string[] { }; + ExcludeLocationTypes = new LocationType[] { }; } public InternalItemsQuery(User user) diff --git a/MediaBrowser.Controller/Library/ILibraryManager.cs b/MediaBrowser.Controller/Library/ILibraryManager.cs index c24cf9bce3..9e434541a5 100644 --- a/MediaBrowser.Controller/Library/ILibraryManager.cs +++ b/MediaBrowser.Controller/Library/ILibraryManager.cs @@ -560,6 +560,6 @@ namespace MediaBrowser.Controller.Library /// The user. /// The parent ids. /// QueryResult<BaseItem>. - QueryResult GetItemsResult(InternalItemsQuery query, User user, IEnumerable parentIds); + QueryResult GetItemsResult(InternalItemsQuery query, IEnumerable parentIds); } } \ No newline at end of file diff --git a/MediaBrowser.Controller/LiveTv/LiveTvAudioRecording.cs b/MediaBrowser.Controller/LiveTv/LiveTvAudioRecording.cs index dd6a53d458..f1634a8a53 100644 --- a/MediaBrowser.Controller/LiveTv/LiveTvAudioRecording.cs +++ b/MediaBrowser.Controller/LiveTv/LiveTvAudioRecording.cs @@ -139,5 +139,10 @@ namespace MediaBrowser.Controller.LiveTv return list; } + + public override bool IsVisibleStandalone(User user) + { + return IsVisible(user); + } } } diff --git a/MediaBrowser.Controller/LiveTv/LiveTvVideoRecording.cs b/MediaBrowser.Controller/LiveTv/LiveTvVideoRecording.cs index de8764e6d9..96a465201c 100644 --- a/MediaBrowser.Controller/LiveTv/LiveTvVideoRecording.cs +++ b/MediaBrowser.Controller/LiveTv/LiveTvVideoRecording.cs @@ -149,5 +149,10 @@ namespace MediaBrowser.Controller.LiveTv return list; } + + public override bool IsVisibleStandalone(User user) + { + return IsVisible(user); + } } } diff --git a/MediaBrowser.Dlna/ContentDirectory/ControlHandler.cs b/MediaBrowser.Dlna/ContentDirectory/ControlHandler.cs index ba50f2f320..c70014cb6b 100644 --- a/MediaBrowser.Dlna/ContentDirectory/ControlHandler.cs +++ b/MediaBrowser.Dlna/ContentDirectory/ControlHandler.cs @@ -489,7 +489,7 @@ namespace MediaBrowser.Dlna.ContentDirectory Limit = limit, StartIndex = startIndex - }, user, new string[] { }); + }, new string[] { }); var serverItems = itemsResult.Items.Select(i => new ServerItem { diff --git a/MediaBrowser.Server.Implementations/Library/LibraryManager.cs b/MediaBrowser.Server.Implementations/Library/LibraryManager.cs index 522038b469..f24edf086f 100644 --- a/MediaBrowser.Server.Implementations/Library/LibraryManager.cs +++ b/MediaBrowser.Server.Implementations/Library/LibraryManager.cs @@ -1297,21 +1297,32 @@ namespace MediaBrowser.Server.Implementations.Library if (user != null) { + AddUserToQuery(query, user); items = items.Where(i => i.IsVisibleStandalone(user)); } return items; } - public QueryResult GetItemsResult(InternalItemsQuery query, User user, IEnumerable parentIds) + public QueryResult GetItemsResult(InternalItemsQuery query, IEnumerable parentIds) { var parents = parentIds.Select(i => GetItemById(new Guid(i))).ToList(); query.AncestorIds = parents.SelectMany(i => i.GetIdsForAncestorQuery()).Select(i => i.ToString("N")).ToArray(); + if (query.User != null) + { + AddUserToQuery(query, query.User); + } + return GetItems(query); } + private void AddUserToQuery(InternalItemsQuery query, User user) + { + + } + /// /// Gets the intros. /// diff --git a/MediaBrowser.Server.Implementations/Library/UserViewManager.cs b/MediaBrowser.Server.Implementations/Library/UserViewManager.cs index c2938475c6..177d82b22f 100644 --- a/MediaBrowser.Server.Implementations/Library/UserViewManager.cs +++ b/MediaBrowser.Server.Implementations/Library/UserViewManager.cs @@ -245,16 +245,8 @@ namespace MediaBrowser.Server.Implementations.Library var currentUser = user; - Func filter = i => + var libraryItems = GetItemsForLatestItems(user, request.ParentId, includeTypes).Where(i => { - if (includeTypes.Length > 0) - { - if (!includeTypes.Contains(i.GetType().Name, StringComparer.OrdinalIgnoreCase)) - { - return false; - } - } - if (request.IsPlayed.HasValue) { var val = request.IsPlayed.Value; @@ -264,29 +256,12 @@ namespace MediaBrowser.Server.Implementations.Library } } - return i.LocationType != LocationType.Virtual && !i.IsFolder; - }; - - // Avoid implicitly captured closure - var libraryItems = string.IsNullOrEmpty(request.ParentId) && user != null ? - GetItemsConfiguredForLatest(user, filter) : - GetAllLibraryItems(request.UserId, _userManager, _libraryManager, request.ParentId, filter); - - libraryItems = libraryItems.OrderByDescending(i => i.DateCreated); - - if (request.IsPlayed.HasValue) - { - var takeLimit = (request.Limit ?? 20) * 20; - libraryItems = libraryItems.Take(takeLimit); - } - - // Avoid implicitly captured closure - var items = libraryItems - .ToList(); + return true; + }); var list = new List>>(); - foreach (var item in items) + foreach (var item in libraryItems) { // Only grab the index container for media var container = item.IsFolder || !request.GroupItems ? null : item.LatestItemsIndexContainer; @@ -318,59 +293,23 @@ namespace MediaBrowser.Server.Implementations.Library return list; } - protected IList GetAllLibraryItems(string userId, IUserManager userManager, ILibraryManager libraryManager, string parentId, Func filter) + private IEnumerable GetItemsForLatestItems(User user, string parentId, string[] includeItemTypes) { - if (!string.IsNullOrEmpty(parentId)) + var parentIds = string.IsNullOrEmpty(parentId) + ? new string[] { } + : new[] { parentId }; + + return _libraryManager.GetItems(new InternalItemsQuery(user) { - var folder = (Folder)libraryManager.GetItemById(new Guid(parentId)); + IncludeItemTypes = includeItemTypes, + SortOrder = SortOrder.Descending, + SortBy = new[] { ItemSortBy.DateCreated }, + IsFolder = false, + ExcludeItemTypes = new[] { "ChannelItem", "Recording" }, + ExcludeLocationTypes = new[] { LocationType.Virtual } - if (!string.IsNullOrWhiteSpace(userId)) - { - var user = userManager.GetUserById(userId); + }, user, parentIds); - if (user == null) - { - throw new ArgumentException("User not found"); - } - - return folder - .GetRecursiveChildren(user, filter) - .ToList(); - } - - return folder - .GetRecursiveChildren(filter); - } - if (!string.IsNullOrWhiteSpace(userId)) - { - var user = userManager.GetUserById(userId); - - if (user == null) - { - throw new ArgumentException("User not found"); - } - - return user - .RootFolder - .GetRecursiveChildren(user, filter) - .ToList(); - } - - return libraryManager - .RootFolder - .GetRecursiveChildren(filter); - } - - private IEnumerable GetItemsConfiguredForLatest(User user, Func filter) - { - // Avoid implicitly captured closure - var currentUser = user; - - return user.RootFolder.GetChildren(user, true) - .OfType() - .Where(i => !user.Configuration.LatestItemsExcludes.Contains(i.Id.ToString("N"))) - .SelectMany(i => i.GetRecursiveChildren(currentUser, filter)) - .DistinctBy(i => i.Id); } } } diff --git a/MediaBrowser.Server.Implementations/Persistence/CleanDatabaseScheduledTask.cs b/MediaBrowser.Server.Implementations/Persistence/CleanDatabaseScheduledTask.cs index 74688d9b1e..aef2157c3b 100644 --- a/MediaBrowser.Server.Implementations/Persistence/CleanDatabaseScheduledTask.cs +++ b/MediaBrowser.Server.Implementations/Persistence/CleanDatabaseScheduledTask.cs @@ -24,7 +24,7 @@ namespace MediaBrowser.Server.Implementations.Persistence private readonly IServerConfigurationManager _config; private readonly IFileSystem _fileSystem; - public const int MigrationVersion = 1; + public const int MigrationVersion = 2; public CleanDatabaseScheduledTask(ILibraryManager libraryManager, IItemRepository itemRepo, ILogger logger, IServerConfigurationManager config, IFileSystem fileSystem) { diff --git a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs index 20d890d027..4d86330e5a 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 _deleteAncestorsCommand; private IDbCommand _saveAncestorCommand; - private const int LatestSchemaVersion = 18; + private const int LatestSchemaVersion = 19; /// /// Initializes a new instance of the class. @@ -213,6 +213,7 @@ namespace MediaBrowser.Server.Implementations.Persistence _connection.AddColumn(_logger, "TypedBaseItems", "Audio", "Text"); _connection.AddColumn(_logger, "TypedBaseItems", "ExternalServiceId", "Text"); _connection.AddColumn(_logger, "TypedBaseItems", "Tags", "Text"); + _connection.AddColumn(_logger, "TypedBaseItems", "IsFolder", "BIT"); PrepareStatements(); @@ -438,7 +439,8 @@ namespace MediaBrowser.Server.Implementations.Persistence "Studios", "Audio", "ExternalServiceId", - "Tags" + "Tags", + "IsFolder" }; _saveItemCommand = _connection.CreateCommand(); _saveItemCommand.CommandText = "replace into TypedBaseItems (" + string.Join(",", saveColumns.ToArray()) + ") values ("; @@ -702,7 +704,8 @@ namespace MediaBrowser.Server.Implementations.Persistence } _saveItemCommand.GetParameter(index++).Value = string.Join("|", item.Tags.ToArray()); - + _saveItemCommand.GetParameter(index++).Value = item.IsFolder; + _saveItemCommand.Transaction = transaction; _saveItemCommand.ExecuteNonQuery(); @@ -1576,7 +1579,7 @@ namespace MediaBrowser.Server.Implementations.Persistence _logger.Debug(cmd.CommandText); - using (var reader = cmd.ExecuteReader(CommandBehavior.SequentialAccess)) + using (var reader = cmd.ExecuteReader(CommandBehavior.SequentialAccess | CommandBehavior.SingleResult)) { while (reader.Read()) { @@ -1760,6 +1763,11 @@ namespace MediaBrowser.Server.Implementations.Persistence whereClauses.Add("IsSports=@IsSports"); cmd.Parameters.Add(cmd, "@IsSports", DbType.Boolean).Value = query.IsSports; } + if (query.IsFolder.HasValue) + { + whereClauses.Add("IsFolder=@IsFolder"); + cmd.Parameters.Add(cmd, "@IsFolder", DbType.Boolean).Value = query.IsFolder; + } var includeTypes = query.IncludeItemTypes.SelectMany(MapIncludeItemTypes).ToArray(); if (includeTypes.Length == 1) @@ -1911,6 +1919,17 @@ namespace MediaBrowser.Server.Implementations.Persistence var inClause = string.Join(",", query.AncestorIds.Select(i => "'" + i + "'").ToArray()); whereClauses.Add(string.Format("Guid in (select itemId from AncestorIds where AncestorId in ({0}))", inClause)); } + if (query.ExcludeLocationTypes.Length == 1) + { + whereClauses.Add("LocationType<>@LocationType"); + cmd.Parameters.Add(cmd, "@LocationType", DbType.String).Value = query.ExcludeLocationTypes[0].ToString(); + } + if (query.ExcludeLocationTypes.Length > 1) + { + var val = string.Join(",", query.ExcludeLocationTypes.Select(i => "'" + i + "'").ToArray()); + + whereClauses.Add("LocationType not in (" + val + ")"); + } if (addPaging) { @@ -1976,6 +1995,7 @@ namespace MediaBrowser.Server.Implementations.Persistence dict[t.Name] = new[] { t.FullName }; } + dict["ChannelItem"] = new[] { typeof(ChannelVideoItem).FullName, typeof(ChannelAudioItem).FullName, typeof(ChannelFolderItem).FullName }; dict["Recording"] = new[] { typeof(LiveTvAudioRecording).FullName, typeof(LiveTvVideoRecording).FullName }; dict["Program"] = new[] { typeof(LiveTvProgram).FullName }; dict["TvChannel"] = new[] { typeof(LiveTvChannel).FullName };