From 9b998a068a2622f43ac813800654e357f94d0c21 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Wed, 28 Oct 2015 15:40:38 -0400 Subject: update image encoding --- MediaBrowser.Controller/Entities/InternalItemsQuery.cs | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'MediaBrowser.Controller/Entities/InternalItemsQuery.cs') diff --git a/MediaBrowser.Controller/Entities/InternalItemsQuery.cs b/MediaBrowser.Controller/Entities/InternalItemsQuery.cs index 785e2fd2b..786c96d36 100644 --- a/MediaBrowser.Controller/Entities/InternalItemsQuery.cs +++ b/MediaBrowser.Controller/Entities/InternalItemsQuery.cs @@ -75,6 +75,7 @@ namespace MediaBrowser.Controller.Entities public string[] Tags { get; set; } public string[] OfficialRatings { get; set; } + public DateTime? MinPremiereDate { get; set; } public DateTime? MinStartDate { get; set; } public DateTime? MaxStartDate { get; set; } public DateTime? MinEndDate { get; set; } @@ -121,5 +122,15 @@ namespace MediaBrowser.Controller.Entities ChannelIds = new string[] { }; ItemIds = new string[] { }; } + + public InternalItemsQuery(User user) + : this() + { + if (user != null) + { + var policy = user.Policy; + MaxParentalRating = policy.MaxParentalRating; + } + } } } -- cgit v1.2.3 From 0bd1f36ececc04c86bbf49b1ffd07dd30a5878b1 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Thu, 29 Oct 2015 09:28:05 -0400 Subject: update db queries --- MediaBrowser.Api/PluginService.cs | 6 +- MediaBrowser.Api/TvShowsService.cs | 34 ++--- .../Security/PluginSecurityManager.cs | 17 ++- .../Entities/AggregateFolder.cs | 2 +- MediaBrowser.Controller/Entities/BaseItem.cs | 21 ++- MediaBrowser.Controller/Entities/Folder.cs | 45 ++++-- .../Entities/InternalItemsQuery.cs | 6 +- MediaBrowser.Controller/Entities/Person.cs | 9 ++ MediaBrowser.Controller/Entities/TV/Episode.cs | 14 ++ MediaBrowser.Controller/Entities/UserView.cs | 15 ++ MediaBrowser.Controller/Library/ILibraryManager.cs | 12 +- MediaBrowser.Controller/LiveTv/LiveTvProgram.cs | 9 ++ .../Persistence/IItemRepository.cs | 7 + .../ContentDirectory/ControlHandler.cs | 24 ++-- .../Configuration/ServerConfiguration.cs | 9 +- .../Collections/CollectionManager.cs | 1 + .../Dto/DtoService.cs | 14 +- .../Intros/DefaultIntroProvider.cs | 8 +- .../Library/LibraryManager.cs | 58 +++++--- .../Library/MusicManager.cs | 8 +- .../Library/SearchEngine.cs | 27 +--- .../LiveTv/LiveTvManager.cs | 34 ++--- .../Persistence/CleanDatabaseScheduledTask.cs | 8 ++ .../Persistence/SqliteItemRepository.cs | 152 +++++++++++++++++++-- .../Playlists/PlaylistManager.cs | 1 + .../TV/TVSeriesManager.cs | 48 ++----- .../ApplicationHost.cs | 2 +- .../MediaBrowser.Server.Startup.Common.csproj | 2 +- .../Migrations/DbMigration.cs | 34 +++++ .../Migrations/Release5767.cs | 48 ------- 30 files changed, 431 insertions(+), 244 deletions(-) create mode 100644 MediaBrowser.Server.Startup.Common/Migrations/DbMigration.cs delete mode 100644 MediaBrowser.Server.Startup.Common/Migrations/Release5767.cs (limited to 'MediaBrowser.Controller/Entities/InternalItemsQuery.cs') diff --git a/MediaBrowser.Api/PluginService.cs b/MediaBrowser.Api/PluginService.cs index a7fd14bf0..74b37df92 100644 --- a/MediaBrowser.Api/PluginService.cs +++ b/MediaBrowser.Api/PluginService.cs @@ -278,9 +278,11 @@ namespace MediaBrowser.Api /// /// /// - public async Task Post(RegisterAppstoreSale request) + public void Post(RegisterAppstoreSale request) { - await _securityManager.RegisterAppStoreSale(request.Parameters); + var task = _securityManager.RegisterAppStoreSale(request.Parameters); + + Task.WaitAll(task); } /// diff --git a/MediaBrowser.Api/TvShowsService.cs b/MediaBrowser.Api/TvShowsService.cs index 19d12fe65..ead232888 100644 --- a/MediaBrowser.Api/TvShowsService.cs +++ b/MediaBrowser.Api/TvShowsService.cs @@ -275,38 +275,26 @@ namespace MediaBrowser.Api var minPremiereDate = DateTime.Now.Date.AddDays(-1).ToUniversalTime(); - IEnumerable items; + var parentIds = string.IsNullOrWhiteSpace(request.ParentId) ? new string[] { } : new[] { request.ParentId }; - if (string.IsNullOrWhiteSpace(request.ParentId)) + var itemsResult = _libraryManager.GetItemsResult(new InternalItemsQuery(user) { - items = _libraryManager.GetItems(new InternalItemsQuery(user) - { - IncludeItemTypes = new[] { typeof(Episode).Name }, - SortBy = new[] { "PremiereDate", "SortName" }, - SortOrder = SortOrder.Ascending, - MinPremiereDate = minPremiereDate - - }, user); - } - else - { - items = GetAllLibraryItems(request.UserId, _userManager, _libraryManager, request.ParentId, i => i is Episode && (i.PremiereDate ?? DateTime.MinValue) >= minPremiereDate); - } - - var itemsList = _libraryManager - .Sort(items, user, new[] { "PremiereDate", "AirTime", "SortName" }, SortOrder.Ascending) - .Cast() - .ToList(); + IncludeItemTypes = new[] { typeof(Episode).Name }, + SortBy = new[] { "PremiereDate", "AirTime", "SortName" }, + SortOrder = SortOrder.Ascending, + MinPremiereDate = minPremiereDate, + StartIndex = request.StartIndex, + Limit = request.Limit - var pagedItems = ApplyPaging(itemsList, request.StartIndex, request.Limit); + }, user, parentIds); var options = GetDtoOptions(request); - var returnItems = _dtoService.GetBaseItemDtos(pagedItems, options, user).ToArray(); + var returnItems = _dtoService.GetBaseItemDtos(itemsResult.Items, options, user).ToArray(); var result = new ItemsResult { - TotalRecordCount = itemsList.Count, + TotalRecordCount = itemsResult.TotalRecordCount, Items = returnItems }; diff --git a/MediaBrowser.Common.Implementations/Security/PluginSecurityManager.cs b/MediaBrowser.Common.Implementations/Security/PluginSecurityManager.cs index 7cc31ad7a..1176407ce 100644 --- a/MediaBrowser.Common.Implementations/Security/PluginSecurityManager.cs +++ b/MediaBrowser.Common.Implementations/Security/PluginSecurityManager.cs @@ -8,8 +8,10 @@ using MediaBrowser.Model.Serialization; using System; using System.Collections.Generic; using System.Linq; +using System.Net; using System.Threading; using System.Threading.Tasks; +using MediaBrowser.Model.Net; namespace MediaBrowser.Common.Implementations.Security { @@ -219,10 +221,6 @@ namespace MediaBrowser.Common.Implementations.Security { SupporterKey = reg.key; } - else - { - throw new PaymentRequiredException(); - } } } @@ -231,10 +229,15 @@ namespace MediaBrowser.Common.Implementations.Security SaveAppStoreInfo(parameters); throw; } - catch (PaymentRequiredException) + catch (HttpException e) { - SaveAppStoreInfo(parameters); - throw; + _logger.ErrorException("Error registering appstore purchase {0}", e, parameters ?? "NO PARMS SENT"); + + if (e.StatusCode.HasValue && e.StatusCode.Value == HttpStatusCode.PaymentRequired) + { + throw new PaymentRequiredException(); + } + throw new ApplicationException("Error registering store sale"); } catch (Exception e) { diff --git a/MediaBrowser.Controller/Entities/AggregateFolder.cs b/MediaBrowser.Controller/Entities/AggregateFolder.cs index 14f8c1617..10372eb49 100644 --- a/MediaBrowser.Controller/Entities/AggregateFolder.cs +++ b/MediaBrowser.Controller/Entities/AggregateFolder.cs @@ -128,7 +128,7 @@ namespace MediaBrowser.Controller.Entities /// IEnumerable{BaseItem}. protected override IEnumerable GetNonCachedChildren(IDirectoryService directoryService) { - return base.GetNonCachedChildren(directoryService).Concat(_virtualChildren); + return base.GetNonCachedChildren(directoryService); } /// diff --git a/MediaBrowser.Controller/Entities/BaseItem.cs b/MediaBrowser.Controller/Entities/BaseItem.cs index fdf035e8d..f14e09616 100644 --- a/MediaBrowser.Controller/Entities/BaseItem.cs +++ b/MediaBrowser.Controller/Entities/BaseItem.cs @@ -639,7 +639,7 @@ namespace MediaBrowser.Controller.Entities /// /// The tags. public List Tags { get; set; } - + /// /// Gets or sets the home page URL. /// @@ -1898,5 +1898,24 @@ namespace MediaBrowser.Controller.Entities DateLastSaved.Ticks.ToString(CultureInfo.InvariantCulture) }; } + + public virtual IEnumerable GetAncestorIds() + { + return Parents.Select(i => i.Id).Concat(LibraryManager.GetCollectionFolders(this).Select(i => i.Id)); + } + + [IgnoreDataMember] + public virtual bool SupportsAncestors + { + get + { + return true; + } + } + + public virtual IEnumerable GetIdsForAncestorQuery() + { + return new[] { Id }; + } } } diff --git a/MediaBrowser.Controller/Entities/Folder.cs b/MediaBrowser.Controller/Entities/Folder.cs index fcbe54d05..e08eda1ac 100644 --- a/MediaBrowser.Controller/Entities/Folder.cs +++ b/MediaBrowser.Controller/Entities/Folder.cs @@ -149,7 +149,15 @@ namespace MediaBrowser.Controller.Entities await LibraryManager.CreateItem(item, cancellationToken).ConfigureAwait(false); - await ItemRepository.SaveChildren(Id, ActualChildren.Select(i => i.Id).ToList(), cancellationToken).ConfigureAwait(false); + if (!EnableNewFolderQuerying()) + { + await ItemRepository.SaveChildren(Id, ActualChildren.Select(i => i.Id).ToList(), cancellationToken).ConfigureAwait(false); + } + } + + private static bool EnableNewFolderQuerying() + { + return ConfigurationManager.Configuration.MigrationVersion >= 1; } protected void AddChildrenInternal(IEnumerable children) @@ -222,7 +230,12 @@ namespace MediaBrowser.Controller.Entities item.SetParent(null); - return ItemRepository.SaveChildren(Id, ActualChildren.Select(i => i.Id).ToList(), cancellationToken); + if (!EnableNewFolderQuerying()) + { + return ItemRepository.SaveChildren(Id, ActualChildren.Select(i => i.Id).ToList(), cancellationToken); + } + + return Task.FromResult(true); } /// @@ -471,6 +484,7 @@ namespace MediaBrowser.Controller.Entities } else { + child.SetParent(this); newItems.Add(child); validChildren.Add(child); } @@ -478,6 +492,7 @@ namespace MediaBrowser.Controller.Entities else { // Brand new item - needs to be added + child.SetParent(this); newItems.Add(child); validChildren.Add(child); } @@ -506,7 +521,6 @@ namespace MediaBrowser.Controller.Entities } else { - await UpdateIsOffline(item, false).ConfigureAwait(false); actualRemovals.Add(item); } } @@ -517,6 +531,9 @@ namespace MediaBrowser.Controller.Entities foreach (var item in actualRemovals) { + item.SetParent(null); + item.IsOffline = false; + await LibraryManager.DeleteItem(item, new DeleteOptions { DeleteFileLocation = false }).ConfigureAwait(false); LibraryManager.ReportItemRemoved(item); } } @@ -525,7 +542,10 @@ namespace MediaBrowser.Controller.Entities AddChildrenInternal(newItems); - await ItemRepository.SaveChildren(Id, ActualChildren.Select(i => i.Id).ToList(), cancellationToken).ConfigureAwait(false); + if (!EnableNewFolderQuerying()) + { + await ItemRepository.SaveChildren(Id, ActualChildren.Select(i => i.Id).ToList(), cancellationToken).ConfigureAwait(false); + } } } @@ -755,19 +775,16 @@ namespace MediaBrowser.Controller.Entities /// IEnumerable{BaseItem}. protected IEnumerable GetCachedChildren() { - if (ConfigurationManager.Configuration.DisableStartupScan) + if (EnableNewFolderQuerying()) { - return ItemRepository.GetChildrenItems(Id).Select(RetrieveChild).Where(i => i != null); - //return ItemRepository.GetItems(new InternalItemsQuery - //{ - // ParentId = Id + return ItemRepository.GetItemList(new InternalItemsQuery + { + ParentId = Id - //}).Items.Select(RetrieveChild).Where(i => i != null); - } - else - { - return ItemRepository.GetChildrenItems(Id).Select(RetrieveChild).Where(i => i != null); + }).Select(RetrieveChild).Where(i => i != null); } + + return ItemRepository.GetChildrenItems(Id).Select(RetrieveChild).Where(i => i != null); } private BaseItem RetrieveChild(BaseItem child) diff --git a/MediaBrowser.Controller/Entities/InternalItemsQuery.cs b/MediaBrowser.Controller/Entities/InternalItemsQuery.cs index 786c96d36..038a46316 100644 --- a/MediaBrowser.Controller/Entities/InternalItemsQuery.cs +++ b/MediaBrowser.Controller/Entities/InternalItemsQuery.cs @@ -102,7 +102,8 @@ namespace MediaBrowser.Controller.Entities public LocationType? LocationType { get; set; } public Guid? ParentId { get; set; } - + public string[] AncestorIds { get; set; } + public InternalItemsQuery() { Tags = new string[] { }; @@ -121,6 +122,7 @@ namespace MediaBrowser.Controller.Entities PersonIds = new string[] { }; ChannelIds = new string[] { }; ItemIds = new string[] { }; + AncestorIds = new string[] { }; } public InternalItemsQuery(User user) @@ -130,6 +132,8 @@ namespace MediaBrowser.Controller.Entities { var policy = user.Policy; MaxParentalRating = policy.MaxParentalRating; + + User = user; } } } diff --git a/MediaBrowser.Controller/Entities/Person.cs b/MediaBrowser.Controller/Entities/Person.cs index 6c277da56..120a376d4 100644 --- a/MediaBrowser.Controller/Entities/Person.cs +++ b/MediaBrowser.Controller/Entities/Person.cs @@ -101,6 +101,15 @@ namespace MediaBrowser.Controller.Entities return false; } } + + [IgnoreDataMember] + public override bool SupportsAncestors + { + get + { + return false; + } + } } /// diff --git a/MediaBrowser.Controller/Entities/TV/Episode.cs b/MediaBrowser.Controller/Entities/TV/Episode.cs index 92ca9e970..3d18b86df 100644 --- a/MediaBrowser.Controller/Entities/TV/Episode.cs +++ b/MediaBrowser.Controller/Entities/TV/Episode.cs @@ -265,6 +265,20 @@ namespace MediaBrowser.Controller.Entities.TV } } + public override IEnumerable GetAncestorIds() + { + var list = base.GetAncestorIds().ToList(); + + var seasonId = SeasonId; + + if (seasonId.HasValue && !list.Contains(seasonId.Value)) + { + list.Add(seasonId.Value); + } + + return list; + } + public override IEnumerable GetDeletePaths() { return new[] { Path }; diff --git a/MediaBrowser.Controller/Entities/UserView.cs b/MediaBrowser.Controller/Entities/UserView.cs index 5ee49ae5a..76188ce58 100644 --- a/MediaBrowser.Controller/Entities/UserView.cs +++ b/MediaBrowser.Controller/Entities/UserView.cs @@ -24,6 +24,21 @@ namespace MediaBrowser.Controller.Entities { return true; } + + public override IEnumerable GetIdsForAncestorQuery() + { + var list = new List(); + + if (DisplayParentId != Guid.Empty) + { + list.Add(DisplayParentId); + } + else if (ParentId != Guid.Empty) + { + list.Add(ParentId); + } + return list; + } public override Task> GetItems(InternalItemsQuery query) { diff --git a/MediaBrowser.Controller/Library/ILibraryManager.cs b/MediaBrowser.Controller/Library/ILibraryManager.cs index 96bb6e2b6..c24cf9bce 100644 --- a/MediaBrowser.Controller/Library/ILibraryManager.cs +++ b/MediaBrowser.Controller/Library/ILibraryManager.cs @@ -549,7 +549,17 @@ namespace MediaBrowser.Controller.Library /// /// The query. /// The user. + /// The parent ids. /// List<BaseItem>. - IEnumerable GetItems(InternalItemsQuery query, User user); + IEnumerable GetItems(InternalItemsQuery query, User user, IEnumerable parentIds); + + /// + /// Gets the items result. + /// + /// The query. + /// The user. + /// The parent ids. + /// QueryResult<BaseItem>. + QueryResult GetItemsResult(InternalItemsQuery query, User user, IEnumerable parentIds); } } \ No newline at end of file diff --git a/MediaBrowser.Controller/LiveTv/LiveTvProgram.cs b/MediaBrowser.Controller/LiveTv/LiveTvProgram.cs index aa1a3b9c2..55bc2269e 100644 --- a/MediaBrowser.Controller/LiveTv/LiveTvProgram.cs +++ b/MediaBrowser.Controller/LiveTv/LiveTvProgram.cs @@ -217,5 +217,14 @@ namespace MediaBrowser.Controller.LiveTv return base.SupportsPeople; } } + + [IgnoreDataMember] + public override bool SupportsAncestors + { + get + { + return false; + } + } } } diff --git a/MediaBrowser.Controller/Persistence/IItemRepository.cs b/MediaBrowser.Controller/Persistence/IItemRepository.cs index 8fc0aedd3..0b1c9c3e0 100644 --- a/MediaBrowser.Controller/Persistence/IItemRepository.cs +++ b/MediaBrowser.Controller/Persistence/IItemRepository.cs @@ -176,6 +176,13 @@ namespace MediaBrowser.Controller.Persistence /// The query. /// QueryResult<Tuple<Guid, System.String>>. QueryResult> GetItemIdsWithPath(InternalItemsQuery query); + + /// + /// Gets the item list. + /// + /// The query. + /// List<BaseItem>. + IEnumerable GetItemList(InternalItemsQuery query); } } diff --git a/MediaBrowser.Dlna/ContentDirectory/ControlHandler.cs b/MediaBrowser.Dlna/ContentDirectory/ControlHandler.cs index a9ce5587d..ba50f2f32 100644 --- a/MediaBrowser.Dlna/ContentDirectory/ControlHandler.cs +++ b/MediaBrowser.Dlna/ContentDirectory/ControlHandler.cs @@ -481,23 +481,17 @@ namespace MediaBrowser.Dlna.ContentDirectory private QueryResult GetItemsFromPerson(Person person, User user, int? startIndex, int? limit) { - var itemsWithPerson = _libraryManager.GetItems(new InternalItemsQuery + var itemsResult = _libraryManager.GetItemsResult(new InternalItemsQuery(user) { - Person = person.Name - - }).Items; - - var items = itemsWithPerson - .Where(i => i is Movie || i is Series || i is IChannelItem) - .Where(i => i.IsVisibleStandalone(user)) - .ToList(); + Person = person.Name, + IncludeItemTypes = new[] { typeof(Movie).Name, typeof(Series).Name, typeof(ChannelVideoItem).Name }, + SortBy = new[] { ItemSortBy.SortName }, + Limit = limit, + StartIndex = startIndex - items = _libraryManager.Sort(items, user, new[] { ItemSortBy.SortName }, SortOrder.Ascending) - .Skip(startIndex ?? 0) - .Take(limit ?? int.MaxValue) - .ToList(); + }, user, new string[] { }); - var serverItems = items.Select(i => new ServerItem + var serverItems = itemsResult.Items.Select(i => new ServerItem { Item = i, StubType = null @@ -506,7 +500,7 @@ namespace MediaBrowser.Dlna.ContentDirectory return new QueryResult { - TotalRecordCount = serverItems.Length, + TotalRecordCount = itemsResult.TotalRecordCount, Items = serverItems }; } diff --git a/MediaBrowser.Model/Configuration/ServerConfiguration.cs b/MediaBrowser.Model/Configuration/ServerConfiguration.cs index e4c4e4762..ec024e87c 100644 --- a/MediaBrowser.Model/Configuration/ServerConfiguration.cs +++ b/MediaBrowser.Model/Configuration/ServerConfiguration.cs @@ -67,7 +67,7 @@ namespace MediaBrowser.Model.Configuration /// /// true if [enable high quality image scaling]; otherwise, false. public bool EnableHighQualityImageScaling { get; set; } - + /// /// Gets or sets the item by name path. /// @@ -234,12 +234,14 @@ namespace MediaBrowser.Model.Configuration public string[] Migrations { get; set; } + public int MigrationVersion { get; set; } + /// /// Initializes a new instance of the class. /// public ServerConfiguration() { - Migrations = new string[] {}; + Migrations = new string[] { }; ImageSavingConvention = ImageSavingConvention.Compatible; PublicPort = 8096; @@ -583,7 +585,8 @@ namespace MediaBrowser.Model.Configuration Limit = 0, Type = ImageType.Thumb } - } + }, + DisabledMetadataFetchers = new []{ "TheMovieDb" } } }; } diff --git a/MediaBrowser.Server.Implementations/Collections/CollectionManager.cs b/MediaBrowser.Server.Implementations/Collections/CollectionManager.cs index 5c98e401f..4e742ca7a 100644 --- a/MediaBrowser.Server.Implementations/Collections/CollectionManager.cs +++ b/MediaBrowser.Server.Implementations/Collections/CollectionManager.cs @@ -40,6 +40,7 @@ namespace MediaBrowser.Server.Implementations.Collections public Folder GetCollectionsFolder(string userId) { return _libraryManager.RootFolder.Children.OfType() + .FirstOrDefault() ?? _libraryManager.GetUserRootFolder().Children.OfType() .FirstOrDefault(); } diff --git a/MediaBrowser.Server.Implementations/Dto/DtoService.cs b/MediaBrowser.Server.Implementations/Dto/DtoService.cs index fcda802f4..8439f28f7 100644 --- a/MediaBrowser.Server.Implementations/Dto/DtoService.cs +++ b/MediaBrowser.Server.Implementations/Dto/DtoService.cs @@ -163,16 +163,11 @@ namespace MediaBrowser.Server.Implementations.Dto if (person != null) { - var items = _libraryManager.GetItems(new InternalItemsQuery + var items = _libraryManager.GetItems(new InternalItemsQuery(user) { Person = byName.Name - }).Items; - - if (user != null) - { - return items.Where(i => i.IsVisibleStandalone(user)).ToList(); - } + }, user, new string[] { }); return items.ToList(); } @@ -471,8 +466,7 @@ namespace MediaBrowser.Server.Implementations.Dto dto.ChildCount = GetChildCount(folder, user); // These are just far too slow. - // TODO: Disable for CollectionFolder - if (!(folder is UserRootFolder) && !(folder is UserView) && !(folder is IChannelItem)) + if (!(folder is UserRootFolder) && !(folder is UserView) && !(folder is IChannelItem) && !(folder is ICollectionFolder)) { SetSpecialCounts(folder, user, dto, fields, syncProgress); } @@ -1524,7 +1518,7 @@ namespace MediaBrowser.Server.Implementations.Dto } dto.ChannelId = item.ChannelId; - + var channelItem = item as IChannelItem; if (channelItem != null) { diff --git a/MediaBrowser.Server.Implementations/Intros/DefaultIntroProvider.cs b/MediaBrowser.Server.Implementations/Intros/DefaultIntroProvider.cs index ec94e16db..6310b61d1 100644 --- a/MediaBrowser.Server.Implementations/Intros/DefaultIntroProvider.cs +++ b/MediaBrowser.Server.Implementations/Intros/DefaultIntroProvider.cs @@ -83,13 +83,11 @@ namespace MediaBrowser.Server.Implementations.Intros if (config.EnableIntrosFromMoviesInLibrary) { - var inputItems = _libraryManager.GetItems(new InternalItemsQuery + var inputItems = _libraryManager.GetItems(new InternalItemsQuery(user) { - IncludeItemTypes = new[] { typeof(Movie).Name }, + IncludeItemTypes = new[] { typeof(Movie).Name } - User = user - - }).Items; + }, user, new string[]{}); var itemsWithTrailers = inputItems .Where(i => diff --git a/MediaBrowser.Server.Implementations/Library/LibraryManager.cs b/MediaBrowser.Server.Implementations/Library/LibraryManager.cs index daa3d8ad4..522038b46 100644 --- a/MediaBrowser.Server.Implementations/Library/LibraryManager.cs +++ b/MediaBrowser.Server.Implementations/Library/LibraryManager.cs @@ -401,12 +401,12 @@ namespace MediaBrowser.Server.Implementations.Library { foreach (var path in item.GetDeletePaths().ToList()) { - if (_fileSystem.DirectoryExists(path)) + if (_fileSystem.DirectoryExists(path)) { _logger.Debug("Deleting path {0}", path); _fileSystem.DeleteDirectory(path, true); } - else if (_fileSystem.FileExists(path)) + else if (_fileSystem.FileExists(path)) { _logger.Debug("Deleting path {0}", path); _fileSystem.DeleteFile(path); @@ -697,7 +697,7 @@ namespace MediaBrowser.Server.Implementations.Library { var rootFolderPath = ConfigurationManager.ApplicationPaths.RootFolderPath; - _fileSystem.CreateDirectory(rootFolderPath); + _fileSystem.CreateDirectory(rootFolderPath); var rootFolder = GetItemById(GetNewItemId(rootFolderPath, typeof(AggregateFolder))) as AggregateFolder ?? (AggregateFolder)ResolvePath(_fileSystem.GetDirectoryInfo(rootFolderPath)); @@ -727,6 +727,13 @@ namespace MediaBrowser.Server.Implementations.Library folder = dbItem; } + //if (folder.ParentId != rootFolder.Id) + //{ + // folder.ParentId = rootFolder.Id; + // var task = folder.UpdateToRepository(ItemUpdateType.MetadataImport, CancellationToken.None); + // Task.WaitAll(task); + //} + rootFolder.AddVirtualChild(folder); RegisterItem(folder); @@ -748,7 +755,7 @@ namespace MediaBrowser.Server.Implementations.Library { var userRootPath = ConfigurationManager.ApplicationPaths.DefaultUserViewsPath; - _fileSystem.CreateDirectory(userRootPath); + _fileSystem.CreateDirectory(userRootPath); var tmpItem = GetItemById(GetNewItemId(userRootPath, typeof(UserRootFolder))) as UserRootFolder; @@ -1000,9 +1007,9 @@ namespace MediaBrowser.Server.Implementations.Library private void SetPropertiesFromSongs(MusicArtist artist, IEnumerable items) { - + } - + /// /// Validate and refresh the People sub-set of the IBN. /// The items are stored in the db but not loaded into memory until actually requested by an operation. @@ -1013,7 +1020,7 @@ namespace MediaBrowser.Server.Implementations.Library public Task ValidatePeople(CancellationToken cancellationToken, IProgress progress) { // Ensure the location is available. - _fileSystem.CreateDirectory(ConfigurationManager.ApplicationPaths.PeoplePath); + _fileSystem.CreateDirectory(ConfigurationManager.ApplicationPaths.PeoplePath); return new PeopleValidator(this, _logger, ConfigurationManager, _fileSystem).ValidatePeople(cancellationToken, progress); } @@ -1280,9 +1287,29 @@ namespace MediaBrowser.Server.Implementations.Library return ItemRepository.GetItemIdsList(query); } - public IEnumerable GetItems(InternalItemsQuery query, User user) + public IEnumerable GetItems(InternalItemsQuery query, User user, IEnumerable parentIds) { - return GetItemIds(query).Select(GetItemById).Where(i => i.IsVisibleStandalone(user)); + var parents = parentIds.Select(i => GetItemById(new Guid(i))).ToList(); + + query.AncestorIds = parents.SelectMany(i => i.GetIdsForAncestorQuery()).Select(i => i.ToString("N")).ToArray(); + + var items = GetItemIds(query).Select(GetItemById); + + if (user != null) + { + items = items.Where(i => i.IsVisibleStandalone(user)); + } + + return items; + } + + public QueryResult GetItemsResult(InternalItemsQuery query, User user, 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(); + + return GetItems(query); } /// @@ -1700,7 +1727,7 @@ namespace MediaBrowser.Server.Implementations.Library if (item == null || !string.Equals(item.Path, path, StringComparison.OrdinalIgnoreCase)) { - _fileSystem.CreateDirectory(path); + _fileSystem.CreateDirectory(path); item = new UserView { @@ -1719,8 +1746,7 @@ namespace MediaBrowser.Server.Implementations.Library if (!string.Equals(viewType, item.ViewType, StringComparison.OrdinalIgnoreCase)) { - item.ViewType = viewType; - await item.UpdateToRepository(ItemUpdateType.MetadataEdit, cancellationToken).ConfigureAwait(false); + refresh = true; } if (!refresh) @@ -1793,7 +1819,7 @@ namespace MediaBrowser.Server.Implementations.Library if (item == null) { - _fileSystem.CreateDirectory(path); + _fileSystem.CreateDirectory(path); item = new UserView { @@ -1917,7 +1943,7 @@ namespace MediaBrowser.Server.Implementations.Library return item; } - + public async Task GetNamedView(string name, string parentId, string viewType, @@ -1946,7 +1972,7 @@ namespace MediaBrowser.Server.Implementations.Library if (item == null) { - _fileSystem.CreateDirectory(path); + _fileSystem.CreateDirectory(path); item = new UserView { @@ -2379,7 +2405,7 @@ namespace MediaBrowser.Server.Implementations.Library return ItemRepository.UpdatePeople(item.Id, people); } - private readonly SemaphoreSlim _dynamicImageResourcePool = new SemaphoreSlim(1,1); + private readonly SemaphoreSlim _dynamicImageResourcePool = new SemaphoreSlim(1, 1); public async Task ConvertImageToLocal(IHasImages item, ItemImageInfo image, int imageIndex) { _logger.Debug("ConvertImageToLocal item {0}", item.Id); diff --git a/MediaBrowser.Server.Implementations/Library/MusicManager.cs b/MediaBrowser.Server.Implementations/Library/MusicManager.cs index aee101ef4..3d2286e1f 100644 --- a/MediaBrowser.Server.Implementations/Library/MusicManager.cs +++ b/MediaBrowser.Server.Implementations/Library/MusicManager.cs @@ -80,15 +80,13 @@ namespace MediaBrowser.Server.Implementations.Library { var genreList = genres.ToList(); - var inputItems = _libraryManager.GetItems(new InternalItemsQuery + var inputItems = _libraryManager.GetItems(new InternalItemsQuery(user) { IncludeItemTypes = new[] { typeof(Audio).Name }, - Genres = genreList.ToArray(), + Genres = genreList.ToArray() - User = user - - }).Items; + }, user, new string[] { }); var genresDictionary = genreList.ToDictionary(i => i, StringComparer.OrdinalIgnoreCase); diff --git a/MediaBrowser.Server.Implementations/Library/SearchEngine.cs b/MediaBrowser.Server.Implementations/Library/SearchEngine.cs index 108a891e0..82e0f92e6 100644 --- a/MediaBrowser.Server.Implementations/Library/SearchEngine.cs +++ b/MediaBrowser.Server.Implementations/Library/SearchEngine.cs @@ -156,18 +156,18 @@ namespace MediaBrowser.Server.Implementations.Library } AddIfMissing(excludeItemTypes, typeof(CollectionFolder).Name); - + var mediaItems = _libraryManager.GetItems(new InternalItemsQuery(user) { NameContains = searchTerm, ExcludeItemTypes = excludeItemTypes.ToArray(), IncludeItemTypes = includeItemTypes.ToArray(), - Limit = (query.Limit.HasValue ? (int?)(query.Limit.Value * 3) : null), + Limit = (query.Limit.HasValue ? (int?)(query.Limit.Value * 2) : null), - }).Items; + }, user, new string[] { }); // Add search hints based on item name - hints.AddRange(mediaItems.Where(i => IncludeInSearch(i) && IsVisible(i, user)).Select(item => + hints.AddRange(mediaItems.Where(IncludeInSearch).Select(item => { var index = GetIndex(item.Name, searchTerm, terms); @@ -183,25 +183,6 @@ namespace MediaBrowser.Server.Implementations.Library return Task.FromResult(returnValue); } - private bool IsVisible(BaseItem item, User user) - { - if (user == null) - { - return true; - } - - if (item is IItemByName) - { - var dual = item as IHasDualAccess; - if (dual == null || dual.IsAccessedByName) - { - return true; - } - } - - return item.IsVisibleStandalone(user); - } - private bool IncludeInSearch(BaseItem item) { var episode = item as Episode; diff --git a/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs b/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs index d7c9edae3..1b8966aa0 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs @@ -1357,7 +1357,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv await RefreshRecordings(cancellationToken).ConfigureAwait(false); - var internalQuery = new InternalItemsQuery + var internalQuery = new InternalItemsQuery(user) { IncludeItemTypes = new[] { typeof(LiveTvVideoRecording).Name, typeof(LiveTvAudioRecording).Name } }; @@ -1367,8 +1367,8 @@ namespace MediaBrowser.Server.Implementations.LiveTv internalQuery.ChannelIds = new[] { query.ChannelId }; } - var queryResult = _libraryManager.GetItems(internalQuery); - IEnumerable recordings = queryResult.Items.Cast(); + var queryResult = _libraryManager.GetItems(internalQuery, user, new string[]{}); + IEnumerable recordings = queryResult.Cast(); if (!string.IsNullOrEmpty(query.Id)) { @@ -1405,12 +1405,6 @@ namespace MediaBrowser.Server.Implementations.LiveTv .Where(i => _tvDtoService.GetInternalSeriesTimerId(i.ServiceName, i.SeriesTimerId) == guid); } - if (user != null) - { - var currentUser = user; - recordings = recordings.Where(i => i.IsParentalAllowed(currentUser)); - } - recordings = recordings.OrderByDescending(i => i.StartDate); var entityList = recordings.ToList(); @@ -1771,19 +1765,18 @@ namespace MediaBrowser.Server.Implementations.LiveTv var now = DateTime.UtcNow; - var programs = _libraryManager.GetItems(new InternalItemsQuery + var programs = _libraryManager.GetItems(new InternalItemsQuery(user) { IncludeItemTypes = new[] { typeof(LiveTvProgram).Name }, ChannelIds = new[] { id }, MaxStartDate = now, MinEndDate = now, - Limit = 1 + Limit = 1, + SortBy = new[] { "StartDate"} - }).Items.Cast(); + }, user, new string[]{}).Cast(); - var currentProgram = programs - .OrderBy(i => i.StartDate) - .FirstOrDefault(); + var currentProgram = programs.FirstOrDefault(); var dto = _tvDtoService.GetChannelInfoDto(channel, new DtoOptions(), currentProgram, user); @@ -1796,19 +1789,18 @@ namespace MediaBrowser.Server.Implementations.LiveTv var now = DateTime.UtcNow; - var programs = _libraryManager.GetItems(new InternalItemsQuery + var programs = _libraryManager.GetItems(new InternalItemsQuery(user) { IncludeItemTypes = new[] { typeof(LiveTvProgram).Name }, ChannelIds = new[] { channel.Id.ToString("N") }, MaxStartDate = now, MinEndDate = now, - Limit = 1 + Limit = 1, + SortBy = new[] { "StartDate" } - }).Items.Cast(); + }, user, new string []{}).Cast(); - var currentProgram = programs - .OrderBy(i => i.StartDate) - .FirstOrDefault(); + var currentProgram = programs.FirstOrDefault(); if (currentProgram != null) { diff --git a/MediaBrowser.Server.Implementations/Persistence/CleanDatabaseScheduledTask.cs b/MediaBrowser.Server.Implementations/Persistence/CleanDatabaseScheduledTask.cs index 60b8c00bd..74688d9b1 100644 --- a/MediaBrowser.Server.Implementations/Persistence/CleanDatabaseScheduledTask.cs +++ b/MediaBrowser.Server.Implementations/Persistence/CleanDatabaseScheduledTask.cs @@ -24,6 +24,8 @@ namespace MediaBrowser.Server.Implementations.Persistence private readonly IServerConfigurationManager _config; private readonly IFileSystem _fileSystem; + public const int MigrationVersion = 1; + public CleanDatabaseScheduledTask(ILibraryManager libraryManager, IItemRepository itemRepo, ILogger logger, IServerConfigurationManager config, IFileSystem fileSystem) { _libraryManager = libraryManager; @@ -121,6 +123,12 @@ namespace MediaBrowser.Server.Implementations.Persistence _config.SaveConfiguration(); } + if (_config.Configuration.MigrationVersion < MigrationVersion) + { + _config.Configuration.MigrationVersion = MigrationVersion; + _config.SaveConfiguration(); + } + progress.Report(100); } diff --git a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs index 167c96185..20d890d02 100644 --- a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs +++ b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs @@ -77,7 +77,10 @@ namespace MediaBrowser.Server.Implementations.Persistence private IDbCommand _deleteStreamsCommand; private IDbCommand _saveStreamCommand; - private const int LatestSchemaVersion = 17; + private IDbCommand _deleteAncestorsCommand; + private IDbCommand _saveAncestorCommand; + + private const int LatestSchemaVersion = 18; /// /// Initializes a new instance of the class. @@ -126,9 +129,13 @@ namespace MediaBrowser.Server.Implementations.Persistence string[] queries = { - "create table if not exists TypedBaseItems (guid GUID primary key, type TEXT, data BLOB)", + "create table if not exists TypedBaseItems (guid GUID primary key, type TEXT, data BLOB, ParentId GUID)", "create index if not exists idx_TypedBaseItems on TypedBaseItems(guid)", + "create index if not exists idx_ParentIdTypedBaseItems on TypedBaseItems(ParentId)", + "create table if not exists AncestorIds (ItemId GUID, AncestorId GUID, PRIMARY KEY (ItemId, AncestorId))", + "create index if not exists idx_AncestorIds on AncestorIds(ItemId,AncestorId)", + "create table if not exists ChildrenIds (ParentId GUID, ItemId GUID, PRIMARY KEY (ParentId, ItemId))", "create index if not exists idx_ChildrenIds on ChildrenIds(ParentId,ItemId)", @@ -205,6 +212,7 @@ namespace MediaBrowser.Server.Implementations.Persistence _connection.AddColumn(_logger, "TypedBaseItems", "Studios", "Text"); _connection.AddColumn(_logger, "TypedBaseItems", "Audio", "Text"); _connection.AddColumn(_logger, "TypedBaseItems", "ExternalServiceId", "Text"); + _connection.AddColumn(_logger, "TypedBaseItems", "Tags", "Text"); PrepareStatements(); @@ -429,7 +437,8 @@ namespace MediaBrowser.Server.Implementations.Persistence "LockedFields", "Studios", "Audio", - "ExternalServiceId" + "ExternalServiceId", + "Tags" }; _saveItemCommand = _connection.CreateCommand(); _saveItemCommand.CommandText = "replace into TypedBaseItems (" + string.Join(",", saveColumns.ToArray()) + ") values ("; @@ -472,6 +481,16 @@ namespace MediaBrowser.Server.Implementations.Persistence _savePersonCommand.Parameters.Add(_savePersonCommand, "@PersonType"); _savePersonCommand.Parameters.Add(_savePersonCommand, "@SortOrder"); _savePersonCommand.Parameters.Add(_savePersonCommand, "@ListOrder"); + + // Ancestors + _deleteAncestorsCommand = _connection.CreateCommand(); + _deleteAncestorsCommand.CommandText = "delete from AncestorIds where ItemId=@Id"; + _deleteAncestorsCommand.Parameters.Add(_deleteAncestorsCommand, "@Id"); + + _saveAncestorCommand = _connection.CreateCommand(); + _saveAncestorCommand.CommandText = "insert into AncestorIds (ItemId, AncestorId) values (@ItemId, @AncestorId)"; + _saveAncestorCommand.Parameters.Add(_saveAncestorCommand, "@ItemId"); + _saveAncestorCommand.Parameters.Add(_saveAncestorCommand, "@AncestorId"); // Chapters _deleteChaptersCommand = _connection.CreateCommand(); @@ -682,9 +701,16 @@ namespace MediaBrowser.Server.Implementations.Persistence _saveItemCommand.GetParameter(index++).Value = null; } + _saveItemCommand.GetParameter(index++).Value = string.Join("|", item.Tags.ToArray()); + _saveItemCommand.Transaction = transaction; _saveItemCommand.ExecuteNonQuery(); + + if (item.SupportsAncestors) + { + UpdateAncestors(item.Id, item.GetAncestorIds().Distinct().ToList(), transaction); + } } transaction.Commit(); @@ -765,22 +791,32 @@ namespace MediaBrowser.Server.Implementations.Persistence return null; } - BaseItem item; + BaseItem item = null; using (var stream = reader.GetMemoryStream(1)) { try { item = _jsonSerializer.DeserializeFromStream(stream, type) as BaseItem; + } + catch (SerializationException ex) + { + _logger.ErrorException("Error deserializing item", ex); + } - if (item == null) + if (item == null) + { + try + { + item = Activator.CreateInstance(type) as BaseItem; + } + catch { - return null; } } - catch (SerializationException ex) + + if (item == null) { - _logger.ErrorException("Error deserializing item", ex); return null; } } @@ -1328,6 +1364,8 @@ namespace MediaBrowser.Server.Implementations.Persistence cmd.Parameters.Add(cmd, "@ParentId", DbType.Guid).Value = parentId; + //_logger.Debug(cmd.CommandText); + using (var reader = cmd.ExecuteReader(CommandBehavior.SequentialAccess | CommandBehavior.SingleResult)) { while (reader.Read()) @@ -1373,6 +1411,50 @@ namespace MediaBrowser.Server.Implementations.Persistence } } + public IEnumerable GetItemList(InternalItemsQuery query) + { + if (query == null) + { + throw new ArgumentNullException("query"); + } + + CheckDisposed(); + + using (var cmd = _connection.CreateCommand()) + { + cmd.CommandText = "select " + string.Join(",", _retriveItemColumns) + " from TypedBaseItems"; + + var whereClauses = GetWhereClauses(query, cmd, true); + + var whereText = whereClauses.Count == 0 ? + string.Empty : + " where " + string.Join(" AND ", whereClauses.ToArray()); + + cmd.CommandText += whereText; + + cmd.CommandText += GetOrderByText(query); + + if (query.Limit.HasValue) + { + cmd.CommandText += " LIMIT " + query.Limit.Value.ToString(CultureInfo.InvariantCulture); + } + + //_logger.Debug(cmd.CommandText); + + using (var reader = cmd.ExecuteReader(CommandBehavior.SequentialAccess | CommandBehavior.SingleResult)) + { + while (reader.Read()) + { + var item = GetItem(reader); + if (item != null) + { + yield return item; + } + } + } + } + } + public QueryResult GetItems(InternalItemsQuery query) { if (query == null) @@ -1453,6 +1535,12 @@ namespace MediaBrowser.Server.Implementations.Persistence private string MapOrderByField(string name) { + if (string.Equals(name, "airtime", StringComparison.OrdinalIgnoreCase)) + { + // TODO + return "SortName"; + } + return name; } @@ -1813,6 +1901,17 @@ namespace MediaBrowser.Server.Implementations.Persistence } } + if (query.AncestorIds.Length == 1) + { + whereClauses.Add("Guid in (select itemId from AncestorIds where AncestorId=@AncestorId)"); + cmd.Parameters.Add(cmd, "@AncestorId", DbType.Guid).Value = new Guid(query.AncestorIds[0]); + } + if (query.AncestorIds.Length > 1) + { + 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 (addPaging) { if (query.StartIndex.HasValue && query.StartIndex.Value > 0) @@ -1847,6 +1946,7 @@ namespace MediaBrowser.Server.Implementations.Persistence typeof(Movie), typeof(BoxSet), typeof(Episode), + typeof(ChannelVideoItem), typeof(Season), typeof(Series), typeof(Book), @@ -1933,6 +2033,11 @@ namespace MediaBrowser.Server.Implementations.Persistence _deleteStreamsCommand.GetParameter(0).Value = id; _deleteStreamsCommand.Transaction = transaction; _deleteStreamsCommand.ExecuteNonQuery(); + + // Delete ancestors + _deleteAncestorsCommand.GetParameter(0).Value = id; + _deleteAncestorsCommand.Transaction = transaction; + _deleteAncestorsCommand.ExecuteNonQuery(); // Delete the item _deleteItemCommand.GetParameter(0).Value = id; @@ -2167,6 +2272,37 @@ namespace MediaBrowser.Server.Implementations.Persistence return whereClauses; } + private void UpdateAncestors(Guid itemId, List ancestorIds, IDbTransaction transaction) + { + if (itemId == Guid.Empty) + { + throw new ArgumentNullException("itemId"); + } + + if (ancestorIds == null) + { + throw new ArgumentNullException("ancestorIds"); + } + + CheckDisposed(); + + // First delete + _deleteAncestorsCommand.GetParameter(0).Value = itemId; + _deleteAncestorsCommand.Transaction = transaction; + + _deleteAncestorsCommand.ExecuteNonQuery(); + + foreach (var ancestorId in ancestorIds) + { + _saveAncestorCommand.GetParameter(0).Value = itemId; + _saveAncestorCommand.GetParameter(1).Value = ancestorId; + + _saveAncestorCommand.Transaction = transaction; + + _saveAncestorCommand.ExecuteNonQuery(); + } + } + public async Task UpdatePeople(Guid itemId, List people) { if (itemId == Guid.Empty) diff --git a/MediaBrowser.Server.Implementations/Playlists/PlaylistManager.cs b/MediaBrowser.Server.Implementations/Playlists/PlaylistManager.cs index d9b3ed755..048e2bf8d 100644 --- a/MediaBrowser.Server.Implementations/Playlists/PlaylistManager.cs +++ b/MediaBrowser.Server.Implementations/Playlists/PlaylistManager.cs @@ -264,6 +264,7 @@ namespace MediaBrowser.Server.Implementations.Playlists public Folder GetPlaylistsFolder(string userId) { return _libraryManager.RootFolder.Children.OfType() + .FirstOrDefault() ?? _libraryManager.GetUserRootFolder().Children.OfType() .FirstOrDefault(); } } diff --git a/MediaBrowser.Server.Implementations/TV/TVSeriesManager.cs b/MediaBrowser.Server.Implementations/TV/TVSeriesManager.cs index 93ebd0a1c..d913360f0 100644 --- a/MediaBrowser.Server.Implementations/TV/TVSeriesManager.cs +++ b/MediaBrowser.Server.Implementations/TV/TVSeriesManager.cs @@ -36,22 +36,12 @@ namespace MediaBrowser.Server.Implementations.TV ? new string[] { } : new[] { request.ParentId }; - IEnumerable items; - - if (parentIds.Length == 0) + var items = _libraryManager.GetItems(new InternalItemsQuery(user) { - items = _libraryManager.GetItems(new InternalItemsQuery(user) - { - IncludeItemTypes = new[] { typeof(Series).Name }, - SortOrder = SortOrder.Ascending + IncludeItemTypes = new[] { typeof(Series).Name }, + SortOrder = SortOrder.Ascending - }, user).Cast(); - } - else - { - items = GetAllLibraryItems(user, parentIds, i => i is Series) - .Cast(); - } + }, user, parentIds).Cast(); // Avoid implicitly captured closure var episodes = GetNextUpEpisodes(request, user, items); @@ -68,9 +58,12 @@ namespace MediaBrowser.Server.Implementations.TV throw new ArgumentException("User not found"); } - var items = parentsFolders - .SelectMany(i => i.GetRecursiveChildren(user, s => s is Series)) - .Cast(); + var items = _libraryManager.GetItems(new InternalItemsQuery(user) + { + IncludeItemTypes = new[] { typeof(Series).Name }, + SortOrder = SortOrder.Ascending + + }, user, parentsFolders.Select(i => i.Id.ToString("N"))).Cast(); // Avoid implicitly captured closure var episodes = GetNextUpEpisodes(request, user, items); @@ -78,27 +71,6 @@ namespace MediaBrowser.Server.Implementations.TV return GetResult(episodes, null, request); } - private IEnumerable GetAllLibraryItems(User user, string[] parentIds, Func filter) - { - if (parentIds.Length > 0) - { - return parentIds.SelectMany(i => - { - var folder = (Folder)_libraryManager.GetItemById(new Guid(i)); - - return folder.GetRecursiveChildren(user, filter); - - }); - } - - if (user == null) - { - throw new ArgumentException("User not found"); - } - - return user.RootFolder.GetRecursiveChildren(user, filter); - } - public IEnumerable GetNextUpEpisodes(NextUpQuery request, User user, IEnumerable series) { // Avoid implicitly captured closure diff --git a/MediaBrowser.Server.Startup.Common/ApplicationHost.cs b/MediaBrowser.Server.Startup.Common/ApplicationHost.cs index 97a457a1b..694bd1b79 100644 --- a/MediaBrowser.Server.Startup.Common/ApplicationHost.cs +++ b/MediaBrowser.Server.Startup.Common/ApplicationHost.cs @@ -363,7 +363,7 @@ namespace MediaBrowser.Server.Startup.Common { var migrations = new List { - new Release5767(ServerConfigurationManager, TaskManager) + new DbMigration(ServerConfigurationManager, TaskManager) }; foreach (var task in migrations) diff --git a/MediaBrowser.Server.Startup.Common/MediaBrowser.Server.Startup.Common.csproj b/MediaBrowser.Server.Startup.Common/MediaBrowser.Server.Startup.Common.csproj index 13b782e40..b58646a2e 100644 --- a/MediaBrowser.Server.Startup.Common/MediaBrowser.Server.Startup.Common.csproj +++ b/MediaBrowser.Server.Startup.Common/MediaBrowser.Server.Startup.Common.csproj @@ -72,7 +72,7 @@ - + diff --git a/MediaBrowser.Server.Startup.Common/Migrations/DbMigration.cs b/MediaBrowser.Server.Startup.Common/Migrations/DbMigration.cs new file mode 100644 index 000000000..de7cba68d --- /dev/null +++ b/MediaBrowser.Server.Startup.Common/Migrations/DbMigration.cs @@ -0,0 +1,34 @@ +using System.Threading.Tasks; +using MediaBrowser.Common.ScheduledTasks; +using MediaBrowser.Controller.Configuration; +using MediaBrowser.Server.Implementations.Persistence; + +namespace MediaBrowser.Server.Startup.Common.Migrations +{ + public class DbMigration : IVersionMigration + { + private readonly IServerConfigurationManager _config; + private readonly ITaskManager _taskManager; + + public DbMigration(IServerConfigurationManager config, ITaskManager taskManager) + { + _config = config; + _taskManager = taskManager; + } + + public void Run() + { + if (_config.Configuration.MigrationVersion < CleanDatabaseScheduledTask.MigrationVersion) + { + return; + } + + Task.Run(async () => + { + await Task.Delay(2000).ConfigureAwait(false); + + _taskManager.QueueScheduledTask(); + }); + } + } +} diff --git a/MediaBrowser.Server.Startup.Common/Migrations/Release5767.cs b/MediaBrowser.Server.Startup.Common/Migrations/Release5767.cs deleted file mode 100644 index 168230b87..000000000 --- a/MediaBrowser.Server.Startup.Common/Migrations/Release5767.cs +++ /dev/null @@ -1,48 +0,0 @@ -using System; -using System.Linq; -using System.Threading.Tasks; -using MediaBrowser.Common.ScheduledTasks; -using MediaBrowser.Controller.Configuration; -using MediaBrowser.Server.Implementations.LiveTv; -using MediaBrowser.Server.Implementations.Persistence; -using MediaBrowser.Server.Implementations.ScheduledTasks; - -namespace MediaBrowser.Server.Startup.Common.Migrations -{ - public class Release5767 : IVersionMigration - { - private readonly IServerConfigurationManager _config; - private readonly ITaskManager _taskManager; - - public Release5767(IServerConfigurationManager config, ITaskManager taskManager) - { - _config = config; - _taskManager = taskManager; - } - - public async void Run() - { - var name = "5767.1"; - - if (_config.Configuration.Migrations.Contains(name, StringComparer.OrdinalIgnoreCase)) - { - return; - } - - Task.Run(async () => - { - await Task.Delay(3000).ConfigureAwait(false); - - _taskManager.QueueScheduledTask(); - }); - - // Wait a few minutes before marking this as done. Make sure the server doesn't get restarted. - await Task.Delay(300000).ConfigureAwait(false); - - var list = _config.Configuration.Migrations.ToList(); - list.Add(name); - _config.Configuration.Migrations = list.ToArray(); - _config.SaveConfiguration(); - } - } -} -- cgit v1.2.3 From 67dc2a0bf98cf02c1ff07608c0f10b4e0ead6f58 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Thu, 29 Oct 2015 15:01:04 -0400 Subject: update item queries --- MediaBrowser.Api/TvShowsService.cs | 2 +- .../Entities/InternalItemsQuery.cs | 5 +- MediaBrowser.Controller/Library/ILibraryManager.cs | 2 +- .../LiveTv/LiveTvAudioRecording.cs | 5 ++ .../LiveTv/LiveTvVideoRecording.cs | 5 ++ .../ContentDirectory/ControlHandler.cs | 2 +- .../Library/LibraryManager.cs | 13 ++- .../Library/UserViewManager.cs | 93 ++++------------------ .../Persistence/CleanDatabaseScheduledTask.cs | 2 +- .../Persistence/SqliteItemRepository.cs | 28 ++++++- 10 files changed, 70 insertions(+), 87 deletions(-) (limited to 'MediaBrowser.Controller/Entities/InternalItemsQuery.cs') diff --git a/MediaBrowser.Api/TvShowsService.cs b/MediaBrowser.Api/TvShowsService.cs index ead232888..2dad9533f 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 038a46316..5c60e19f0 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 c24cf9bce..9e434541a 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 dd6a53d45..f1634a8a5 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 de8764e6d..96a465201 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 ba50f2f32..c70014cb6 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 522038b46..f24edf086 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 c2938475c..177d82b22 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 folder = (Folder)libraryManager.GetItemById(new Guid(parentId)); - - if (!string.IsNullOrWhiteSpace(userId)) - { - var user = userManager.GetUserById(userId); + var parentIds = string.IsNullOrEmpty(parentId) + ? new string[] { } + : new[] { parentId }; - if (user == null) - { - throw new ArgumentException("User not found"); - } - - return folder - .GetRecursiveChildren(user, filter) - .ToList(); - } - - return folder - .GetRecursiveChildren(filter); - } - if (!string.IsNullOrWhiteSpace(userId)) + return _libraryManager.GetItems(new InternalItemsQuery(user) { - var user = userManager.GetUserById(userId); - - if (user == null) - { - throw new ArgumentException("User not found"); - } + IncludeItemTypes = includeItemTypes, + SortOrder = SortOrder.Descending, + SortBy = new[] { ItemSortBy.DateCreated }, + IsFolder = false, + ExcludeItemTypes = new[] { "ChannelItem", "Recording" }, + ExcludeLocationTypes = new[] { LocationType.Virtual } - return user - .RootFolder - .GetRecursiveChildren(user, filter) - .ToList(); - } - - return libraryManager - .RootFolder - .GetRecursiveChildren(filter); - } + }, user, parentIds); - 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 74688d9b1..aef2157c3 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 20d890d02..4d86330e5 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 }; -- cgit v1.2.3 From ce34c35b944ec8dcc56a4a68ac4d363d0f76db06 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Fri, 6 Nov 2015 10:02:22 -0500 Subject: encode with qsv --- MediaBrowser.Api/Playback/BaseStreamingService.cs | 5 + MediaBrowser.Api/Playback/TranscodingThrottler.cs | 2 +- MediaBrowser.Api/UserLibrary/BaseItemsRequest.cs | 7 ++ MediaBrowser.Api/UserLibrary/ItemsService.cs | 1 + .../Channels/ChannelAudioItem.cs | 4 +- .../Channels/ChannelFolderItem.cs | 6 + .../Channels/ChannelVideoItem.cs | 4 +- MediaBrowser.Controller/Entities/Audio/Audio.cs | 4 +- .../Entities/Audio/MusicAlbum.cs | 5 + .../Entities/Audio/MusicArtist.cs | 5 + MediaBrowser.Controller/Entities/BaseItem.cs | 32 ++++- MediaBrowser.Controller/Entities/Book.cs | 4 +- MediaBrowser.Controller/Entities/Folder.cs | 18 +-- MediaBrowser.Controller/Entities/Game.cs | 4 +- MediaBrowser.Controller/Entities/GameSystem.cs | 5 + .../Entities/InternalItemsQuery.cs | 5 + MediaBrowser.Controller/Entities/Movies/BoxSet.cs | 5 + MediaBrowser.Controller/Entities/Movies/Movie.cs | 4 +- MediaBrowser.Controller/Entities/MusicVideo.cs | 4 +- MediaBrowser.Controller/Entities/Photo.cs | 5 - MediaBrowser.Controller/Entities/TV/Episode.cs | 17 +-- MediaBrowser.Controller/Entities/TV/Season.cs | 19 +-- MediaBrowser.Controller/Entities/TV/Series.cs | 5 + MediaBrowser.Controller/Entities/Trailer.cs | 4 +- .../Entities/UserViewBuilder.cs | 15 +++ .../LiveTv/LiveTvAudioRecording.cs | 4 +- MediaBrowser.Controller/LiveTv/LiveTvChannel.cs | 4 +- MediaBrowser.Controller/LiveTv/LiveTvProgram.cs | 4 +- .../LiveTv/LiveTvVideoRecording.cs | 4 +- MediaBrowser.Controller/LiveTv/RecordingGroup.cs | 6 + .../Configuration/EncodingOptions.cs | 4 +- MediaBrowser.Providers/TV/TvdbSeriesProvider.cs | 2 +- .../Channels/ChannelManager.cs | 50 ++++---- .../Channels/ChannelPostScanTask.cs | 8 +- .../Library/LibraryManager.cs | 42 ++++--- .../Library/MediaSourceManager.cs | 9 +- .../LiveTv/EmbyTV/EmbyTV.cs | 18 ++- .../LiveTv/LiveTvManager.cs | 60 ++++++---- .../Localization/LocalizationManager.cs | 7 ++ .../Persistence/CleanDatabaseScheduledTask.cs | 3 +- .../Persistence/SqliteItemRepository.cs | 133 ++++++++++++--------- .../Sync/MediaSync.cs | 2 +- .../Sync/SyncManager.cs | 8 +- 43 files changed, 324 insertions(+), 233 deletions(-) (limited to 'MediaBrowser.Controller/Entities/InternalItemsQuery.cs') diff --git a/MediaBrowser.Api/Playback/BaseStreamingService.cs b/MediaBrowser.Api/Playback/BaseStreamingService.cs index 426f1883e..e184e9ac9 100644 --- a/MediaBrowser.Api/Playback/BaseStreamingService.cs +++ b/MediaBrowser.Api/Playback/BaseStreamingService.cs @@ -291,6 +291,11 @@ namespace MediaBrowser.Api.Playback { get { + if (string.Equals(ApiEntryPoint.Instance.GetEncodingOptions().HardwareVideoDecoder, "qsv", StringComparison.OrdinalIgnoreCase)) + { + return "h264_qsv"; + } + return "libx264"; } } diff --git a/MediaBrowser.Api/Playback/TranscodingThrottler.cs b/MediaBrowser.Api/Playback/TranscodingThrottler.cs index fec3dda86..ece455009 100644 --- a/MediaBrowser.Api/Playback/TranscodingThrottler.cs +++ b/MediaBrowser.Api/Playback/TranscodingThrottler.cs @@ -42,7 +42,7 @@ namespace MediaBrowser.Api.Playback var options = GetOptions(); - if (options.EnableThrottling && IsThrottleAllowed(_job, options.ThrottleThresholdInSeconds)) + if (options.EnableThrottling && IsThrottleAllowed(_job, options.ThrottleThresholdSeconds)) { PauseTranscoding(); } diff --git a/MediaBrowser.Api/UserLibrary/BaseItemsRequest.cs b/MediaBrowser.Api/UserLibrary/BaseItemsRequest.cs index 4d844e6cb..aa86bfb33 100644 --- a/MediaBrowser.Api/UserLibrary/BaseItemsRequest.cs +++ b/MediaBrowser.Api/UserLibrary/BaseItemsRequest.cs @@ -199,6 +199,8 @@ namespace MediaBrowser.Api.UserLibrary [ApiMember(Name = "Genres", Description = "Optional. If specified, results will be filtered based on genre. This allows multiple, pipe delimeted.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET", AllowMultiple = true)] public string Genres { get; set; } + public string GenreIds { get; set; } + [ApiMember(Name = "OfficialRatings", Description = "Optional. If specified, results will be filtered based on OfficialRating. This allows multiple, pipe delimeted.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET", AllowMultiple = true)] public string OfficialRatings { get; set; } @@ -378,6 +380,11 @@ namespace MediaBrowser.Api.UserLibrary return (StudioIds ?? string.Empty).Split(new[] { '|' }, StringSplitOptions.RemoveEmptyEntries); } + public string[] GetGenreIds() + { + return (GenreIds ?? string.Empty).Split(new[] { '|' }, StringSplitOptions.RemoveEmptyEntries); + } + public string[] GetPersonTypes() { return (PersonTypes ?? string.Empty).Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries); diff --git a/MediaBrowser.Api/UserLibrary/ItemsService.cs b/MediaBrowser.Api/UserLibrary/ItemsService.cs index f1168ab7f..d12dc8053 100644 --- a/MediaBrowser.Api/UserLibrary/ItemsService.cs +++ b/MediaBrowser.Api/UserLibrary/ItemsService.cs @@ -210,6 +210,7 @@ namespace MediaBrowser.Api.UserLibrary Tags = request.GetTags(), OfficialRatings = request.GetOfficialRatings(), Genres = request.GetGenres(), + GenreIds = request.GetGenreIds(), Studios = request.GetStudios(), StudioIds = request.GetStudioIds(), Person = request.Person, diff --git a/MediaBrowser.Controller/Channels/ChannelAudioItem.cs b/MediaBrowser.Controller/Channels/ChannelAudioItem.cs index 653cec901..17dcf138b 100644 --- a/MediaBrowser.Controller/Channels/ChannelAudioItem.cs +++ b/MediaBrowser.Controller/Channels/ChannelAudioItem.cs @@ -18,9 +18,9 @@ namespace MediaBrowser.Controller.Channels public List ChannelMediaSources { get; set; } - protected override bool GetBlockUnratedValue(UserPolicy config) + public override UnratedItem GetBlockUnratedType() { - return config.BlockUnratedItems.Contains(UnratedItem.ChannelContent); + return UnratedItem.ChannelContent; } protected override string CreateUserDataKey() diff --git a/MediaBrowser.Controller/Channels/ChannelFolderItem.cs b/MediaBrowser.Controller/Channels/ChannelFolderItem.cs index 9010470f8..f662020bb 100644 --- a/MediaBrowser.Controller/Channels/ChannelFolderItem.cs +++ b/MediaBrowser.Controller/Channels/ChannelFolderItem.cs @@ -6,6 +6,7 @@ using System; using System.Runtime.Serialization; using System.Threading; using System.Threading.Tasks; +using MediaBrowser.Model.Configuration; using MediaBrowser.Model.Entities; namespace MediaBrowser.Controller.Channels @@ -20,6 +21,11 @@ namespace MediaBrowser.Controller.Channels return false; } + public override UnratedItem GetBlockUnratedType() + { + return UnratedItem.ChannelContent; + } + [IgnoreDataMember] public override bool SupportsLocalMetadata { diff --git a/MediaBrowser.Controller/Channels/ChannelVideoItem.cs b/MediaBrowser.Controller/Channels/ChannelVideoItem.cs index fb545e57a..79ad4b36b 100644 --- a/MediaBrowser.Controller/Channels/ChannelVideoItem.cs +++ b/MediaBrowser.Controller/Channels/ChannelVideoItem.cs @@ -42,9 +42,9 @@ namespace MediaBrowser.Controller.Channels return ExternalId; } - protected override bool GetBlockUnratedValue(UserPolicy config) + public override UnratedItem GetBlockUnratedType() { - return config.BlockUnratedItems.Contains(UnratedItem.ChannelContent); + return UnratedItem.ChannelContent; } [IgnoreDataMember] diff --git a/MediaBrowser.Controller/Entities/Audio/Audio.cs b/MediaBrowser.Controller/Entities/Audio/Audio.cs index 6feffc3ef..766f1e5ed 100644 --- a/MediaBrowser.Controller/Entities/Audio/Audio.cs +++ b/MediaBrowser.Controller/Entities/Audio/Audio.cs @@ -171,9 +171,9 @@ namespace MediaBrowser.Controller.Entities.Audio return base.CreateUserDataKey(); } - protected override bool GetBlockUnratedValue(UserPolicy config) + public override UnratedItem GetBlockUnratedType() { - return config.BlockUnratedItems.Contains(UnratedItem.Music); + return UnratedItem.Music; } public SongInfo GetLookupInfo() diff --git a/MediaBrowser.Controller/Entities/Audio/MusicAlbum.cs b/MediaBrowser.Controller/Entities/Audio/MusicAlbum.cs index 98d1eb4ce..59481f5df 100644 --- a/MediaBrowser.Controller/Entities/Audio/MusicAlbum.cs +++ b/MediaBrowser.Controller/Entities/Audio/MusicAlbum.cs @@ -110,6 +110,11 @@ namespace MediaBrowser.Controller.Entities.Audio return config.BlockUnratedItems.Contains(UnratedItem.Music); } + public override UnratedItem GetBlockUnratedType() + { + return UnratedItem.Music; + } + public AlbumInfo GetLookupInfo() { var id = GetItemLookupInfo(); diff --git a/MediaBrowser.Controller/Entities/Audio/MusicArtist.cs b/MediaBrowser.Controller/Entities/Audio/MusicArtist.cs index f6d1d32a4..02bcceada 100644 --- a/MediaBrowser.Controller/Entities/Audio/MusicArtist.cs +++ b/MediaBrowser.Controller/Entities/Audio/MusicArtist.cs @@ -138,6 +138,11 @@ namespace MediaBrowser.Controller.Entities.Audio return config.BlockUnratedItems.Contains(UnratedItem.Music); } + public override UnratedItem GetBlockUnratedType() + { + return UnratedItem.Music; + } + public async Task RefreshAllMetadata(MetadataRefreshOptions refreshOptions, IProgress progress, CancellationToken cancellationToken) { var items = GetRecursiveChildren().ToList(); diff --git a/MediaBrowser.Controller/Entities/BaseItem.cs b/MediaBrowser.Controller/Entities/BaseItem.cs index 798f1b7bb..5b0af42e8 100644 --- a/MediaBrowser.Controller/Entities/BaseItem.cs +++ b/MediaBrowser.Controller/Entities/BaseItem.cs @@ -690,10 +690,25 @@ namespace MediaBrowser.Controller.Entities [IgnoreDataMember] public int? ParentIndexNumber { get; set; } - [IgnoreDataMember] - public virtual string OfficialRatingForComparison + public virtual string GetOfficialRatingForComparison(bool inherit) { - get { return OfficialRating; } + if (inherit) + { + if (!string.IsNullOrWhiteSpace(OfficialRating)) + { + return OfficialRating; + } + + var parent = DisplayParent; + if (parent != null) + { + return parent.GetOfficialRatingForComparison(inherit); + } + + return null; + } + + return OfficialRating; } [IgnoreDataMember] @@ -1126,7 +1141,7 @@ namespace MediaBrowser.Controller.Entities if (string.IsNullOrWhiteSpace(rating)) { - rating = OfficialRatingForComparison; + rating = GetOfficialRatingForComparison(true); } if (string.IsNullOrWhiteSpace(rating)) @@ -1175,7 +1190,7 @@ namespace MediaBrowser.Controller.Entities if (string.IsNullOrWhiteSpace(rating)) { - rating = OfficialRatingForComparison; + rating = GetOfficialRatingForComparison(true); } if (string.IsNullOrWhiteSpace(rating)) @@ -1207,6 +1222,11 @@ namespace MediaBrowser.Controller.Entities return true; } + public virtual UnratedItem GetBlockUnratedType() + { + return UnratedItem.Other; + } + /// /// Gets the block unrated value. /// @@ -1225,7 +1245,7 @@ namespace MediaBrowser.Controller.Entities return false; } - return config.BlockUnratedItems.Contains(UnratedItem.Other); + return config.BlockUnratedItems.Contains(GetBlockUnratedType()); } /// diff --git a/MediaBrowser.Controller/Entities/Book.cs b/MediaBrowser.Controller/Entities/Book.cs index 8342c1c10..1b4904509 100644 --- a/MediaBrowser.Controller/Entities/Book.cs +++ b/MediaBrowser.Controller/Entities/Book.cs @@ -26,9 +26,9 @@ namespace MediaBrowser.Controller.Entities locationType != LocationType.Virtual; } - protected override bool GetBlockUnratedValue(UserPolicy config) + public override UnratedItem GetBlockUnratedType() { - return config.BlockUnratedItems.Contains(UnratedItem.Book); + return UnratedItem.Book; } public BookInfo GetLookupInfo() diff --git a/MediaBrowser.Controller/Entities/Folder.cs b/MediaBrowser.Controller/Entities/Folder.cs index 4b30e845b..97016baff 100644 --- a/MediaBrowser.Controller/Entities/Folder.cs +++ b/MediaBrowser.Controller/Entities/Folder.cs @@ -202,21 +202,6 @@ namespace MediaBrowser.Controller.Entities } } - [IgnoreDataMember] - public override string OfficialRatingForComparison - { - get - { - // Never want folders to be blocked by "BlockNotRated" - if (this is Series) - { - return base.OfficialRatingForComparison; - } - - return !string.IsNullOrWhiteSpace(base.OfficialRatingForComparison) ? base.OfficialRatingForComparison : "None"; - } - } - /// /// Removes the child. /// @@ -1190,7 +1175,8 @@ namespace MediaBrowser.Controller.Entities { User = user, Recursive = true, - IsFolder = false + IsFolder = false, + IsMissing = false }).ConfigureAwait(false); diff --git a/MediaBrowser.Controller/Entities/Game.cs b/MediaBrowser.Controller/Entities/Game.cs index ea518ce35..e073d09f6 100644 --- a/MediaBrowser.Controller/Entities/Game.cs +++ b/MediaBrowser.Controller/Entities/Game.cs @@ -98,9 +98,9 @@ namespace MediaBrowser.Controller.Entities return base.GetDeletePaths(); } - protected override bool GetBlockUnratedValue(UserPolicy config) + public override UnratedItem GetBlockUnratedType() { - return config.BlockUnratedItems.Contains(UnratedItem.Game); + return UnratedItem.Game; } public GameInfo GetLookupInfo() diff --git a/MediaBrowser.Controller/Entities/GameSystem.cs b/MediaBrowser.Controller/Entities/GameSystem.cs index 35f7e3350..bc35c4738 100644 --- a/MediaBrowser.Controller/Entities/GameSystem.cs +++ b/MediaBrowser.Controller/Entities/GameSystem.cs @@ -50,6 +50,11 @@ namespace MediaBrowser.Controller.Entities return false; } + public override UnratedItem GetBlockUnratedType() + { + return UnratedItem.Game; + } + public GameSystemInfo GetLookupInfo() { var id = GetItemLookupInfo(); diff --git a/MediaBrowser.Controller/Entities/InternalItemsQuery.cs b/MediaBrowser.Controller/Entities/InternalItemsQuery.cs index 5c60e19f0..ac1fc4641 100644 --- a/MediaBrowser.Controller/Entities/InternalItemsQuery.cs +++ b/MediaBrowser.Controller/Entities/InternalItemsQuery.cs @@ -1,6 +1,7 @@ using MediaBrowser.Model.Entities; using System; using System.Collections.Generic; +using MediaBrowser.Model.Configuration; namespace MediaBrowser.Controller.Entities { @@ -69,8 +70,10 @@ namespace MediaBrowser.Controller.Entities public string[] Studios { get; set; } public string[] StudioIds { get; set; } + public string[] GenreIds { get; set; } public ImageType[] ImageTypes { get; set; } public VideoType[] VideoTypes { get; set; } + public UnratedItem[] BlockUnratedItems { get; set; } public int[] Years { get; set; } public string[] Tags { get; set; } public string[] OfficialRatings { get; set; } @@ -108,6 +111,7 @@ namespace MediaBrowser.Controller.Entities public InternalItemsQuery() { + BlockUnratedItems = new UnratedItem[] { }; Tags = new string[] { }; OfficialRatings = new string[] { }; SortBy = new string[] { }; @@ -117,6 +121,7 @@ namespace MediaBrowser.Controller.Entities Genres = new string[] { }; Studios = new string[] { }; StudioIds = new string[] { }; + GenreIds = new string[] { }; ImageTypes = new ImageType[] { }; VideoTypes = new VideoType[] { }; Years = new int[] { }; diff --git a/MediaBrowser.Controller/Entities/Movies/BoxSet.cs b/MediaBrowser.Controller/Entities/Movies/BoxSet.cs index 9317f688f..73fee254c 100644 --- a/MediaBrowser.Controller/Entities/Movies/BoxSet.cs +++ b/MediaBrowser.Controller/Entities/Movies/BoxSet.cs @@ -65,6 +65,11 @@ namespace MediaBrowser.Controller.Entities.Movies return config.BlockUnratedItems.Contains(UnratedItem.Movie); } + public override UnratedItem GetBlockUnratedType() + { + return UnratedItem.Movie; + } + [IgnoreDataMember] public override bool IsPreSorted { diff --git a/MediaBrowser.Controller/Entities/Movies/Movie.cs b/MediaBrowser.Controller/Entities/Movies/Movie.cs index 1a8148edf..60642543f 100644 --- a/MediaBrowser.Controller/Entities/Movies/Movie.cs +++ b/MediaBrowser.Controller/Entities/Movies/Movie.cs @@ -159,9 +159,9 @@ namespace MediaBrowser.Controller.Entities.Movies return itemsChanged; } - protected override bool GetBlockUnratedValue(UserPolicy config) + public override UnratedItem GetBlockUnratedType() { - return config.BlockUnratedItems.Contains(UnratedItem.Movie); + return UnratedItem.Movie; } public MovieInfo GetLookupInfo() diff --git a/MediaBrowser.Controller/Entities/MusicVideo.cs b/MediaBrowser.Controller/Entities/MusicVideo.cs index b2cad02de..8a820b5ff 100644 --- a/MediaBrowser.Controller/Entities/MusicVideo.cs +++ b/MediaBrowser.Controller/Entities/MusicVideo.cs @@ -56,9 +56,9 @@ namespace MediaBrowser.Controller.Entities return this.GetProviderId(MetadataProviders.Tmdb) ?? this.GetProviderId(MetadataProviders.Imdb) ?? base.CreateUserDataKey(); } - protected override bool GetBlockUnratedValue(UserPolicy config) + public override UnratedItem GetBlockUnratedType() { - return config.BlockUnratedItems.Contains(UnratedItem.Music); + return UnratedItem.Music; } public MusicVideoInfo GetLookupInfo() diff --git a/MediaBrowser.Controller/Entities/Photo.cs b/MediaBrowser.Controller/Entities/Photo.cs index 6c2f2a326..859d327b3 100644 --- a/MediaBrowser.Controller/Entities/Photo.cs +++ b/MediaBrowser.Controller/Entities/Photo.cs @@ -68,10 +68,5 @@ namespace MediaBrowser.Controller.Entities public double? Longitude { get; set; } public double? Altitude { get; set; } public int? IsoSpeedRating { get; set; } - - protected override bool GetBlockUnratedValue(UserPolicy config) - { - return config.BlockUnratedItems.Contains(UnratedItem.Other); - } } } diff --git a/MediaBrowser.Controller/Entities/TV/Episode.cs b/MediaBrowser.Controller/Entities/TV/Episode.cs index 3d18b86df..86893f6d4 100644 --- a/MediaBrowser.Controller/Entities/TV/Episode.cs +++ b/MediaBrowser.Controller/Entities/TV/Episode.cs @@ -115,19 +115,6 @@ namespace MediaBrowser.Controller.Entities.TV return base.CreateUserDataKey(); } - /// - /// Our rating comes from our series - /// - [IgnoreDataMember] - public override string OfficialRatingForComparison - { - get - { - var series = Series; - return series != null ? series.OfficialRatingForComparison : base.OfficialRatingForComparison; - } - } - /// /// This Episode's Series Instance /// @@ -284,9 +271,9 @@ namespace MediaBrowser.Controller.Entities.TV return new[] { Path }; } - protected override bool GetBlockUnratedValue(UserPolicy config) + public override UnratedItem GetBlockUnratedType() { - return config.BlockUnratedItems.Contains(UnratedItem.Series); + return UnratedItem.Series; } public EpisodeInfo GetLookupInfo() diff --git a/MediaBrowser.Controller/Entities/TV/Season.cs b/MediaBrowser.Controller/Entities/TV/Season.cs index 21b89d7a9..44bf1c6cc 100644 --- a/MediaBrowser.Controller/Entities/TV/Season.cs +++ b/MediaBrowser.Controller/Entities/TV/Season.cs @@ -6,6 +6,7 @@ using MoreLinq; using System.Collections.Generic; using System.Linq; using System.Runtime.Serialization; +using MediaBrowser.Model.Configuration; namespace MediaBrowser.Controller.Entities.TV { @@ -87,19 +88,6 @@ namespace MediaBrowser.Controller.Entities.TV } } - /// - /// Our rating comes from our series - /// - [IgnoreDataMember] - public override string OfficialRatingForComparison - { - get - { - var series = Series; - return series != null ? series.OfficialRatingForComparison : base.OfficialRatingForComparison; - } - } - /// /// Creates the name of the sort. /// @@ -234,6 +222,11 @@ namespace MediaBrowser.Controller.Entities.TV return false; } + public override UnratedItem GetBlockUnratedType() + { + return UnratedItem.Series; + } + [IgnoreDataMember] public string SeriesName { diff --git a/MediaBrowser.Controller/Entities/TV/Series.cs b/MediaBrowser.Controller/Entities/TV/Series.cs index b23833845..420b3c313 100644 --- a/MediaBrowser.Controller/Entities/TV/Series.cs +++ b/MediaBrowser.Controller/Entities/TV/Series.cs @@ -333,6 +333,11 @@ namespace MediaBrowser.Controller.Entities.TV return config.BlockUnratedItems.Contains(UnratedItem.Series); } + public override UnratedItem GetBlockUnratedType() + { + return UnratedItem.Series; + } + public SeriesInfo GetLookupInfo() { var info = GetItemLookupInfo(); diff --git a/MediaBrowser.Controller/Entities/Trailer.cs b/MediaBrowser.Controller/Entities/Trailer.cs index 6ec512783..d37e2be93 100644 --- a/MediaBrowser.Controller/Entities/Trailer.cs +++ b/MediaBrowser.Controller/Entities/Trailer.cs @@ -97,9 +97,9 @@ namespace MediaBrowser.Controller.Entities return base.CreateUserDataKey(); } - protected override bool GetBlockUnratedValue(UserPolicy config) + public override UnratedItem GetBlockUnratedType() { - return config.BlockUnratedItems.Contains(UnratedItem.Trailer); + return UnratedItem.Trailer; } public TrailerInfo GetLookupInfo() diff --git a/MediaBrowser.Controller/Entities/UserViewBuilder.cs b/MediaBrowser.Controller/Entities/UserViewBuilder.cs index ed81e2d73..5778396cb 100644 --- a/MediaBrowser.Controller/Entities/UserViewBuilder.cs +++ b/MediaBrowser.Controller/Entities/UserViewBuilder.cs @@ -1057,6 +1057,11 @@ namespace MediaBrowser.Controller.Entities return false; } + if (request.GenreIds.Length > 0) + { + return false; + } + if (request.VideoTypes.Length > 0) { return false; @@ -1653,6 +1658,16 @@ namespace MediaBrowser.Controller.Entities return false; } + // Apply genre filter + if (query.GenreIds.Length > 0 && !query.GenreIds.Any(id => + { + var genreItem = libraryManager.GetItemById(id); + return genreItem != null && item.Genres.Contains(genreItem.Name, StringComparer.OrdinalIgnoreCase); + })) + { + return false; + } + // Apply year filter if (query.Years.Length > 0) { diff --git a/MediaBrowser.Controller/LiveTv/LiveTvAudioRecording.cs b/MediaBrowser.Controller/LiveTv/LiveTvAudioRecording.cs index f1634a8a5..d9834c191 100644 --- a/MediaBrowser.Controller/LiveTv/LiveTvAudioRecording.cs +++ b/MediaBrowser.Controller/LiveTv/LiveTvAudioRecording.cs @@ -105,9 +105,9 @@ namespace MediaBrowser.Controller.LiveTv } } - protected override bool GetBlockUnratedValue(UserPolicy config) + public override UnratedItem GetBlockUnratedType() { - return config.BlockUnratedItems.Contains(UnratedItem.LiveTvProgram); + return UnratedItem.LiveTvProgram; } protected override string GetInternalMetadataPath(string basePath) diff --git a/MediaBrowser.Controller/LiveTv/LiveTvChannel.cs b/MediaBrowser.Controller/LiveTv/LiveTvChannel.cs index 89168c578..8c4ee92cd 100644 --- a/MediaBrowser.Controller/LiveTv/LiveTvChannel.cs +++ b/MediaBrowser.Controller/LiveTv/LiveTvChannel.cs @@ -22,9 +22,9 @@ namespace MediaBrowser.Controller.LiveTv return GetClientTypeName() + "-" + Name; } - protected override bool GetBlockUnratedValue(UserPolicy config) + public override UnratedItem GetBlockUnratedType() { - return config.BlockUnratedItems.Contains(UnratedItem.LiveTvChannel); + return UnratedItem.LiveTvChannel; } /// diff --git a/MediaBrowser.Controller/LiveTv/LiveTvProgram.cs b/MediaBrowser.Controller/LiveTv/LiveTvProgram.cs index 55bc2269e..689e1d23b 100644 --- a/MediaBrowser.Controller/LiveTv/LiveTvProgram.cs +++ b/MediaBrowser.Controller/LiveTv/LiveTvProgram.cs @@ -170,9 +170,9 @@ namespace MediaBrowser.Controller.LiveTv return "Program"; } - protected override bool GetBlockUnratedValue(UserPolicy config) + public override UnratedItem GetBlockUnratedType() { - return config.BlockUnratedItems.Contains(UnratedItem.LiveTvProgram); + return UnratedItem.LiveTvProgram; } protected override string GetInternalMetadataPath(string basePath) diff --git a/MediaBrowser.Controller/LiveTv/LiveTvVideoRecording.cs b/MediaBrowser.Controller/LiveTv/LiveTvVideoRecording.cs index 96a465201..0e9ca3237 100644 --- a/MediaBrowser.Controller/LiveTv/LiveTvVideoRecording.cs +++ b/MediaBrowser.Controller/LiveTv/LiveTvVideoRecording.cs @@ -115,9 +115,9 @@ namespace MediaBrowser.Controller.LiveTv } } - protected override bool GetBlockUnratedValue(UserPolicy config) + public override UnratedItem GetBlockUnratedType() { - return config.BlockUnratedItems.Contains(UnratedItem.LiveTvProgram); + return UnratedItem.LiveTvProgram; } protected override string GetInternalMetadataPath(string basePath) diff --git a/MediaBrowser.Controller/LiveTv/RecordingGroup.cs b/MediaBrowser.Controller/LiveTv/RecordingGroup.cs index 175cf162b..2d58ef67f 100644 --- a/MediaBrowser.Controller/LiveTv/RecordingGroup.cs +++ b/MediaBrowser.Controller/LiveTv/RecordingGroup.cs @@ -1,4 +1,5 @@ using MediaBrowser.Controller.Entities; +using MediaBrowser.Model.Configuration; using MediaBrowser.Model.Users; namespace MediaBrowser.Controller.LiveTv @@ -11,6 +12,11 @@ namespace MediaBrowser.Controller.LiveTv return false; } + public override UnratedItem GetBlockUnratedType() + { + return UnratedItem.LiveTvProgram; + } + public override bool SupportsLocalMetadata { get diff --git a/MediaBrowser.Model/Configuration/EncodingOptions.cs b/MediaBrowser.Model/Configuration/EncodingOptions.cs index 4c3d1be37..77aa9e683 100644 --- a/MediaBrowser.Model/Configuration/EncodingOptions.cs +++ b/MediaBrowser.Model/Configuration/EncodingOptions.cs @@ -8,14 +8,14 @@ namespace MediaBrowser.Model.Configuration public double DownMixAudioBoost { get; set; } public bool EnableDebugLogging { get; set; } public bool EnableThrottling { get; set; } - public int ThrottleThresholdInSeconds { get; set; } + public int ThrottleThresholdSeconds { get; set; } public string HardwareVideoDecoder { get; set; } public EncodingOptions() { DownMixAudioBoost = 2; EnableThrottling = true; - ThrottleThresholdInSeconds = 100; + ThrottleThresholdSeconds = 100; EncodingThreadCount = -1; } } diff --git a/MediaBrowser.Providers/TV/TvdbSeriesProvider.cs b/MediaBrowser.Providers/TV/TvdbSeriesProvider.cs index 24ac7fca6..5e5f96031 100644 --- a/MediaBrowser.Providers/TV/TvdbSeriesProvider.cs +++ b/MediaBrowser.Providers/TV/TvdbSeriesProvider.cs @@ -287,7 +287,7 @@ namespace MediaBrowser.Providers.TV var automaticUpdatesEnabled = GetTvDbOptions().EnableAutomaticUpdates; - const int cacheDays = 2; + const int cacheDays = 1; var seriesFile = files.FirstOrDefault(i => string.Equals(seriesXmlFilename, i.Name, StringComparison.OrdinalIgnoreCase)); // No need to check age if automatic updates are enabled diff --git a/MediaBrowser.Server.Implementations/Channels/ChannelManager.cs b/MediaBrowser.Server.Implementations/Channels/ChannelManager.cs index 34e7f33fc..ad9d92c90 100644 --- a/MediaBrowser.Server.Implementations/Channels/ChannelManager.cs +++ b/MediaBrowser.Server.Implementations/Channels/ChannelManager.cs @@ -104,6 +104,11 @@ namespace MediaBrowser.Server.Implementations.Channels .OrderBy(i => i.Name); } + public IEnumerable GetInstalledChannelIds() + { + return GetAllChannels().Select(i => GetInternalChannelId(i.Name)); + } + public Task> GetChannelsInternal(ChannelQuery query, CancellationToken cancellationToken) { var user = string.IsNullOrWhiteSpace(query.UserId) @@ -416,20 +421,7 @@ namespace MediaBrowser.Server.Implementations.Channels var path = Channel.GetInternalMetadataPath(_config.ApplicationPaths.InternalMetadataPath, id); var isNew = false; - - if (!_fileSystem.DirectoryExists(path)) - { - _logger.Debug("Creating directory {0}", path); - - _fileSystem.CreateDirectory(path); - - if (!_fileSystem.DirectoryExists(path)) - { - throw new IOException("Path not created: " + path); - } - - isNew = true; - } + var forceUpdate = false; var item = _libraryManager.GetItemById(id) as Channel; var channelId = channelInfo.Name.GetMD5().ToString("N"); @@ -441,23 +433,27 @@ namespace MediaBrowser.Server.Implementations.Channels Name = channelInfo.Name, Id = id, DateCreated = _fileSystem.GetCreationTimeUtc(path), - DateModified = _fileSystem.GetLastWriteTimeUtc(path), - Path = path, - ChannelId = channelId + DateModified = _fileSystem.GetLastWriteTimeUtc(path) }; isNew = true; } - if (!string.Equals(item.ChannelId, channelId, StringComparison.OrdinalIgnoreCase)) + if (!string.Equals(item.Path, path, StringComparison.OrdinalIgnoreCase)) { isNew = true; } + item.Path = path; + + if (!string.Equals(item.ChannelId, channelId, StringComparison.OrdinalIgnoreCase)) + { + forceUpdate = true; + } item.ChannelId = channelId; if (item.ParentId != parentFolderId) { - isNew = true; + forceUpdate = true; } item.ParentId = parentFolderId; @@ -469,13 +465,17 @@ namespace MediaBrowser.Server.Implementations.Channels { item.Name = channelInfo.Name; } - - await item.RefreshMetadata(new MetadataRefreshOptions(_fileSystem) - { - ForceSave = isNew - }, cancellationToken); + if (isNew) + { + await _libraryManager.CreateItem(item, cancellationToken).ConfigureAwait(false); + } + else if (forceUpdate) + { + await item.UpdateToRepository(ItemUpdateType.None, cancellationToken).ConfigureAwait(false); + } + await item.RefreshMetadata(new MetadataRefreshOptions(_fileSystem), cancellationToken); return item; } @@ -1281,7 +1281,7 @@ namespace MediaBrowser.Server.Implementations.Channels if (!string.Equals(channelItem.ExternalId, info.Id, StringComparison.OrdinalIgnoreCase)) { - isNew = true; + forceUpdate = true; } channelItem.ExternalId = info.Id; diff --git a/MediaBrowser.Server.Implementations/Channels/ChannelPostScanTask.cs b/MediaBrowser.Server.Implementations/Channels/ChannelPostScanTask.cs index 2e9d42f49..da4a72cd4 100644 --- a/MediaBrowser.Server.Implementations/Channels/ChannelPostScanTask.cs +++ b/MediaBrowser.Server.Implementations/Channels/ChannelPostScanTask.cs @@ -123,15 +123,15 @@ namespace MediaBrowser.Server.Implementations.Channels private async Task CleanDatabase(CancellationToken cancellationToken) { - var allChannels = await _channelManager.GetChannelsInternal(new ChannelQuery { }, cancellationToken); + var installedChannelIds = ((ChannelManager)_channelManager).GetInstalledChannelIds(); - var allIds = _libraryManager.GetItemIds(new InternalItemsQuery + var databaseIds = _libraryManager.GetItemIds(new InternalItemsQuery { IncludeItemTypes = new[] { typeof(Channel).Name } }); - var invalidIds = allIds - .Except(allChannels.Items.Select(i => i.Id).ToList()) + var invalidIds = databaseIds + .Except(installedChannelIds) .ToList(); foreach (var id in invalidIds) diff --git a/MediaBrowser.Server.Implementations/Library/LibraryManager.cs b/MediaBrowser.Server.Implementations/Library/LibraryManager.cs index 70d28547c..0ba7dea53 100644 --- a/MediaBrowser.Server.Implementations/Library/LibraryManager.cs +++ b/MediaBrowser.Server.Implementations/Library/LibraryManager.cs @@ -1272,6 +1272,11 @@ namespace MediaBrowser.Server.Implementations.Library public QueryResult GetItems(InternalItemsQuery query) { + if (query.User != null) + { + AddUserToQuery(query, query.User); + } + var result = ItemRepository.GetItemIdsList(query); var items = result.Select(GetItemById).Where(i => i != null).ToArray(); @@ -1284,11 +1289,21 @@ namespace MediaBrowser.Server.Implementations.Library public QueryResult QueryItems(InternalItemsQuery query) { + if (query.User != null) + { + AddUserToQuery(query, query.User); + } + return ItemRepository.GetItems(query); } public List GetItemIds(InternalItemsQuery query) { + if (query.User != null) + { + AddUserToQuery(query, query.User); + } + return ItemRepository.GetItemIdsList(query); } @@ -1298,14 +1313,7 @@ namespace MediaBrowser.Server.Implementations.Library query.AncestorIds = parents.SelectMany(i => i.GetIdsForAncestorQuery()).Select(i => i.ToString("N")).ToArray(); - if (user != null) - { - AddUserToQuery(query, user); - } - - var items = GetItemIds(query).Select(GetItemById); - - return items; + return GetItemIds(query).Select(GetItemById); } public QueryResult GetItemsResult(InternalItemsQuery query, IEnumerable parentIds) @@ -1314,26 +1322,24 @@ namespace MediaBrowser.Server.Implementations.Library 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) { - if (query.AncestorIds.Length == 0) + if (query.AncestorIds.Length == 0 && !query.ParentId.HasValue && query.ChannelIds.Length == 0) { - // Need to filter on user folders + // TODO: Need to filter on user folders } - query.MaxParentalRating = user.Policy.MaxParentalRating; + // TODO: handle blocking by tags - // handle blocking by tags + query.MaxParentalRating = user.Policy.MaxParentalRating; - // handle unrated filter + if (user.Policy.MaxParentalRating.HasValue) + { + query.BlockUnratedItems = user.Policy.BlockUnratedItems; + } } /// diff --git a/MediaBrowser.Server.Implementations/Library/MediaSourceManager.cs b/MediaBrowser.Server.Implementations/Library/MediaSourceManager.cs index 99eeb625c..8afab39aa 100644 --- a/MediaBrowser.Server.Implementations/Library/MediaSourceManager.cs +++ b/MediaBrowser.Server.Implementations/Library/MediaSourceManager.cs @@ -107,14 +107,7 @@ namespace MediaBrowser.Server.Implementations.Library private int GetMaxAllowedBitrateForExternalSubtitleStream() { - // This is abitrary but at some point it becomes too slow to extract subtitles on the fly - // We need to learn more about when this is the case vs. when it isn't - if (Environment.ProcessorCount >= 8) - { - return 10000000; - } - - return 4000000; + return 20000000; } private IEnumerable GetMediaStreamsForItem(IEnumerable streams) diff --git a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs index 2ac06cda8..0e9328736 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs @@ -134,11 +134,11 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV public async Task RefreshSeriesTimers(CancellationToken cancellationToken, IProgress progress) { - var timers = await GetSeriesTimersAsync(cancellationToken).ConfigureAwait(false); + var seriesTimers = await GetSeriesTimersAsync(cancellationToken).ConfigureAwait(false); List channels = null; - foreach (var timer in timers) + foreach (var timer in seriesTimers) { List epgData; @@ -157,6 +157,16 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV } await UpdateTimersForSeriesTimer(epgData, timer).ConfigureAwait(false); } + + var timers = await GetTimersAsync(cancellationToken).ConfigureAwait(false); + + foreach (var timer in timers.ToList()) + { + if (DateTime.UtcNow > timer.EndDate && !_activeRecordings.ContainsKey(timer.Id)) + { + _timerProvider.Delete(timer); + } + } } private List _channelCache = null; @@ -828,12 +838,12 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV private async Task UpdateTimersForSeriesTimer(List epgData, SeriesTimerInfo seriesTimer) { + var newTimers = GetTimersForSeries(seriesTimer, epgData, _recordingProvider.GetAll()).ToList(); + var registration = await GetRegistrationInfo("seriesrecordings").ConfigureAwait(false); if (registration.IsValid) { - var newTimers = GetTimersForSeries(seriesTimer, epgData, _recordingProvider.GetAll()).ToList(); - foreach (var timer in newTimers) { _timerProvider.AddOrUpdate(timer); diff --git a/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs b/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs index db8ccd9af..f55d19a5d 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs @@ -534,7 +534,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv } } - private async Task GetChannel(ChannelInfo channelInfo, string serviceName, CancellationToken cancellationToken) + private async Task GetChannel(ChannelInfo channelInfo, string serviceName, Guid parentFolderId, CancellationToken cancellationToken) { var isNew = false; @@ -560,6 +560,12 @@ namespace MediaBrowser.Server.Implementations.LiveTv } item.ExternalId = channelInfo.Id; + if (!item.ParentId.Equals(parentFolderId)) + { + isNew = true; + } + item.ParentId = parentFolderId; + item.ChannelType = channelInfo.ChannelType; item.ServiceName = serviceName; item.Number = channelInfo.Number; @@ -601,7 +607,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv return item; } - private async Task GetProgram(ProgramInfo info, string channelId, ChannelType channelType, string serviceName, CancellationToken cancellationToken) + private async Task GetProgram(ProgramInfo info, LiveTvChannel channel, ChannelType channelType, string serviceName, CancellationToken cancellationToken) { var id = _tvDtoService.GetInternalProgramId(serviceName, info.Id); @@ -622,6 +628,12 @@ namespace MediaBrowser.Server.Implementations.LiveTv }; } + if (!item.ParentId.Equals(channel.Id)) + { + forceUpdate = true; + } + item.ParentId = channel.Id; + //item.ChannelType = channelType; if (!string.Equals(item.ServiceName, serviceName, StringComparison.Ordinal)) { @@ -630,7 +642,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv item.ServiceName = serviceName; item.Audio = info.Audio; - item.ChannelId = channelId; + item.ChannelId = channel.Id.ToString("N"); item.CommunityRating = item.CommunityRating ?? info.CommunityRating; item.EndDate = info.EndDate; item.EpisodeTitle = info.EpisodeTitle; @@ -695,7 +707,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv return item; } - private async Task CreateRecordingRecord(RecordingInfo info, string serviceName, CancellationToken cancellationToken) + private async Task CreateRecordingRecord(RecordingInfo info, string serviceName, Guid parentFolderId, CancellationToken cancellationToken) { var isNew = false; @@ -764,6 +776,12 @@ namespace MediaBrowser.Server.Implementations.LiveTv } recording.IsSeries = info.IsSeries; + if (!item.ParentId.Equals(parentFolderId)) + { + dataChanged = true; + } + item.ParentId = parentFolderId; + if (!item.HasImage(ImageType.Primary)) { if (!string.IsNullOrWhiteSpace(info.ImagePath)) @@ -856,14 +874,6 @@ namespace MediaBrowser.Server.Implementations.LiveTv SortOrder = query.SortOrder ?? SortOrder.Ascending }; - if (user != null) - { - if (user.Policy.BlockUnratedItems.Contains(UnratedItem.LiveTvProgram)) - { - internalQuery.HasParentalRating = true; - } - } - if (query.HasAired.HasValue) { if (query.HasAired.Value) @@ -918,14 +928,6 @@ namespace MediaBrowser.Server.Implementations.LiveTv } } - if (user != null) - { - if (user.Policy.BlockUnratedItems.Contains(UnratedItem.LiveTvProgram)) - { - internalQuery.HasParentalRating = true; - } - } - IEnumerable programs = _libraryManager.QueryItems(internalQuery).Items.Cast(); var programList = programs.ToList(); @@ -1168,6 +1170,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv var list = new List(); var numComplete = 0; + var folder = await GetInternalLiveTvFolder(cancellationToken).ConfigureAwait(false); foreach (var channelInfo in allChannelsList) { @@ -1175,7 +1178,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv try { - var item = await GetChannel(channelInfo.Item2, channelInfo.Item1, cancellationToken).ConfigureAwait(false); + var item = await GetChannel(channelInfo.Item2, channelInfo.Item1, folder.Id, cancellationToken).ConfigureAwait(false); list.Add(item); @@ -1219,11 +1222,9 @@ namespace MediaBrowser.Server.Implementations.LiveTv var channelPrograms = await service.GetProgramsAsync(currentChannel.ExternalId, start, end, cancellationToken).ConfigureAwait(false); - var channelId = currentChannel.Id.ToString("N"); - foreach (var program in channelPrograms) { - var programItem = await GetProgram(program, channelId, currentChannel.ChannelType, service.Name, cancellationToken).ConfigureAwait(false); + var programItem = await GetProgram(program, currentChannel, currentChannel.ChannelType, service.Name, cancellationToken).ConfigureAwait(false); programs.Add(programItem.Id); } @@ -1349,8 +1350,10 @@ namespace MediaBrowser.Server.Implementations.LiveTv }); var results = await Task.WhenAll(tasks).ConfigureAwait(false); + var folder = await GetInternalLiveTvFolder(cancellationToken).ConfigureAwait(false); + var parentFolderId = folder.Id; - var recordingTasks = results.SelectMany(i => i.ToList()).Select(i => CreateRecordingRecord(i.Item1, i.Item2.Name, cancellationToken)); + var recordingTasks = results.SelectMany(i => i.ToList()).Select(i => CreateRecordingRecord(i.Item1, i.Item2.Name, parentFolderId, cancellationToken)); var idList = await Task.WhenAll(recordingTasks).ConfigureAwait(false); @@ -1660,7 +1663,12 @@ namespace MediaBrowser.Server.Implementations.LiveTv } - await _libraryManager.DeleteItem((BaseItem)recording).ConfigureAwait(false); + // This is the responsibility of the live tv service + await _libraryManager.DeleteItem((BaseItem)recording, new DeleteOptions + { + DeleteFileLocation = false + + }).ConfigureAwait(false); _lastRecordingRefreshTime = DateTime.MinValue; } diff --git a/MediaBrowser.Server.Implementations/Localization/LocalizationManager.cs b/MediaBrowser.Server.Implementations/Localization/LocalizationManager.cs index cf6eb8f9d..94038c76a 100644 --- a/MediaBrowser.Server.Implementations/Localization/LocalizationManager.cs +++ b/MediaBrowser.Server.Implementations/Localization/LocalizationManager.cs @@ -243,6 +243,8 @@ namespace MediaBrowser.Server.Implementations.Localization _allParentalRatings.TryAdd(countryCode, dict); } + private readonly string[] _unratedValues = {"n/a", "unrated", "not rated"}; + /// /// Gets the rating level. /// @@ -253,6 +255,11 @@ namespace MediaBrowser.Server.Implementations.Localization throw new ArgumentNullException("rating"); } + if (_unratedValues.Contains(rating, StringComparer.OrdinalIgnoreCase)) + { + return null; + } + // Fairly common for some users to have "Rated R" in their rating field rating = rating.Replace("Rated ", string.Empty, StringComparison.OrdinalIgnoreCase); diff --git a/MediaBrowser.Server.Implementations/Persistence/CleanDatabaseScheduledTask.cs b/MediaBrowser.Server.Implementations/Persistence/CleanDatabaseScheduledTask.cs index 3234336e2..fee6e9b38 100644 --- a/MediaBrowser.Server.Implementations/Persistence/CleanDatabaseScheduledTask.cs +++ b/MediaBrowser.Server.Implementations/Persistence/CleanDatabaseScheduledTask.cs @@ -12,6 +12,7 @@ using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; using CommonIO; +using MediaBrowser.Controller.Channels; using MediaBrowser.Controller.Entities.Audio; namespace MediaBrowser.Server.Implementations.Persistence @@ -180,7 +181,7 @@ namespace MediaBrowser.Server.Implementations.Persistence //Limit = limit, // These have their own cleanup routines - ExcludeItemTypes = new[] { typeof(Person).Name, typeof(Genre).Name, typeof(MusicGenre).Name, typeof(GameGenre).Name, typeof(Studio).Name, typeof(Year).Name } + ExcludeItemTypes = new[] { typeof(Person).Name, typeof(Genre).Name, typeof(MusicGenre).Name, typeof(GameGenre).Name, typeof(Studio).Name, typeof(Year).Name, typeof(Channel).Name } }); var numComplete = 0; diff --git a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs index a33bdc0c7..ee89c0f97 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 = 25; + private const int LatestSchemaVersion = 29; /// /// Initializes a new instance of the class. @@ -219,6 +219,7 @@ namespace MediaBrowser.Server.Implementations.Persistence _connection.AddColumn(_logger, "TypedBaseItems", "Tags", "Text"); _connection.AddColumn(_logger, "TypedBaseItems", "IsFolder", "BIT"); _connection.AddColumn(_logger, "TypedBaseItems", "InheritedParentalRatingValue", "INT"); + _connection.AddColumn(_logger, "TypedBaseItems", "UnratedType", "Text"); PrepareStatements(); @@ -446,7 +447,8 @@ namespace MediaBrowser.Server.Implementations.Persistence "Audio", "ExternalServiceId", "Tags", - "IsFolder" + "IsFolder", + "UnratedType" }; _saveItemCommand = _connection.CreateCommand(); _saveItemCommand.CommandText = "replace into TypedBaseItems (" + string.Join(",", saveColumns.ToArray()) + ") values ("; @@ -714,6 +716,8 @@ namespace MediaBrowser.Server.Implementations.Persistence _saveItemCommand.GetParameter(index++).Value = string.Join("|", item.Tags.ToArray()); _saveItemCommand.GetParameter(index++).Value = item.IsFolder; + _saveItemCommand.GetParameter(index++).Value = item.GetBlockUnratedType().ToString(); + _saveItemCommand.Transaction = transaction; _saveItemCommand.ExecuteNonQuery(); @@ -1916,6 +1920,17 @@ namespace MediaBrowser.Server.Implementations.Persistence whereClauses.Add("ParentId NOT NULL AND ParentId NOT IN (select guid from TypedBaseItems)"); } } + 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 (query.AncestorIds.Length == 1) { @@ -1927,18 +1942,18 @@ namespace MediaBrowser.Server.Implementations.Persistence var inClause = string.Join(",", query.AncestorIds.Select(i => "'" + new Guid(i).ToString("N") + "'").ToArray()); whereClauses.Add(string.Format("Guid in (select itemId from AncestorIds where AncestorIdText in ({0}))", inClause)); } - if (query.ExcludeLocationTypes.Length == 1) + + if (query.BlockUnratedItems.Length == 1) { - whereClauses.Add("LocationType<>@LocationType"); - cmd.Parameters.Add(cmd, "@LocationType", DbType.String).Value = query.ExcludeLocationTypes[0].ToString(); + whereClauses.Add("(InheritedParentalRatingValue > 0 or UnratedType <> @UnratedType)"); + cmd.Parameters.Add(cmd, "@UnratedType", DbType.String).Value = query.BlockUnratedItems[0].ToString(); } - if (query.ExcludeLocationTypes.Length > 1) + if (query.BlockUnratedItems.Length > 1) { - var val = string.Join(",", query.ExcludeLocationTypes.Select(i => "'" + i + "'").ToArray()); - - whereClauses.Add("LocationType not in (" + val + ")"); + var inClause = string.Join(",", query.BlockUnratedItems.Select(i => "'" + i.ToString() + "'").ToArray()); + whereClauses.Add(string.Format("(InheritedParentalRatingValue > 0 or UnratedType not in ({0}))", inClause)); } - + if (addPaging) { if (query.StartIndex.HasValue && query.StartIndex.Value > 0) @@ -1996,55 +2011,55 @@ namespace MediaBrowser.Server.Implementations.Persistence public async Task UpdateInheritedValues(CancellationToken cancellationToken) { - await _writeLock.WaitAsync(cancellationToken).ConfigureAwait(false); - - IDbTransaction transaction = null; - - try - { - transaction = _connection.BeginTransaction(); - - using (var cmd = _connection.CreateCommand()) - { - cmd.CommandText = "update TypedBaseItems set InheritedParentalRatingValue = (select Max(ParentalRatingValue, (select COALESCE(MAX(ParentalRatingValue),0) from TypedBaseItems as T where guid in (Select AncestorId from AncestorIds where ItemId=T.guid))))"; - - cmd.Transaction = transaction; - cmd.ExecuteNonQuery(); - - cmd.ExecuteNonQuery(); - } - - transaction.Commit(); - } - catch (OperationCanceledException) - { - if (transaction != null) - { - transaction.Rollback(); - } - - throw; - } - catch (Exception e) - { - _logger.ErrorException("Error running query:", e); - - if (transaction != null) - { - transaction.Rollback(); - } - - throw; - } - finally - { - if (transaction != null) - { - transaction.Dispose(); - } - - _writeLock.Release(); - } + //await _writeLock.WaitAsync(cancellationToken).ConfigureAwait(false); + + //IDbTransaction transaction = null; + + //try + //{ + // transaction = _connection.BeginTransaction(); + + // using (var cmd = _connection.CreateCommand()) + // { + // cmd.CommandText = "update TypedBaseItems set InheritedParentalRatingValue = (select Max(ParentalRatingValue, (select COALESCE(MAX(ParentalRatingValue),0) from TypedBaseItems as T where guid in (Select AncestorId from AncestorIds where ItemId=T.guid))))"; + + // cmd.Transaction = transaction; + // cmd.ExecuteNonQuery(); + + // cmd.ExecuteNonQuery(); + // } + + // transaction.Commit(); + //} + //catch (OperationCanceledException) + //{ + // if (transaction != null) + // { + // transaction.Rollback(); + // } + + // throw; + //} + //catch (Exception e) + //{ + // _logger.ErrorException("Error running query:", e); + + // if (transaction != null) + // { + // transaction.Rollback(); + // } + + // throw; + //} + //finally + //{ + // if (transaction != null) + // { + // transaction.Dispose(); + // } + + // _writeLock.Release(); + //} } private static Dictionary GetTypeMapDictionary() diff --git a/MediaBrowser.Server.Implementations/Sync/MediaSync.cs b/MediaBrowser.Server.Implementations/Sync/MediaSync.cs index cff72ae58..fd2f8ae8d 100644 --- a/MediaBrowser.Server.Implementations/Sync/MediaSync.cs +++ b/MediaBrowser.Server.Implementations/Sync/MediaSync.cs @@ -66,7 +66,7 @@ namespace MediaBrowser.Server.Implementations.Sync // Do the data sync twice so the server knows what was removed from the device await SyncData(provider, dataProvider, serverId, target, cancellationToken).ConfigureAwait(false); - + progress.Report(100); } diff --git a/MediaBrowser.Server.Implementations/Sync/SyncManager.cs b/MediaBrowser.Server.Implementations/Sync/SyncManager.cs index db6a753b7..e7f217781 100644 --- a/MediaBrowser.Server.Implementations/Sync/SyncManager.cs +++ b/MediaBrowser.Server.Implementations/Sync/SyncManager.cs @@ -739,10 +739,10 @@ namespace MediaBrowser.Server.Implementations.Sync var requiresSaving = false; var removeFromDevice = false; - var libraryItem = _libraryManager.GetItemById(jobItem.ItemId); - if (request.LocalItemIds.Contains(jobItem.ItemId, StringComparer.OrdinalIgnoreCase)) { + var libraryItem = _libraryManager.GetItemById(jobItem.ItemId); + var job = _repo.GetJob(jobItem.JobId); var user = _userManager.GetUserById(job.UserId); @@ -845,10 +845,10 @@ namespace MediaBrowser.Server.Implementations.Sync var requiresSaving = false; var removeFromDevice = false; - var libraryItem = _libraryManager.GetItemById(jobItem.ItemId); - if (request.SyncJobItemIds.Contains(jobItem.Id, StringComparer.OrdinalIgnoreCase)) { + var libraryItem = _libraryManager.GetItemById(jobItem.ItemId); + var job = _repo.GetJob(jobItem.JobId); var user = _userManager.GetUserById(job.UserId); -- cgit v1.2.3 From 6f619eff5fca18bf736040ee3a10b8bff65dc394 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Fri, 6 Nov 2015 10:53:23 -0500 Subject: update SocketHttpListener --- MediaBrowser.Api/UserLibrary/ItemsService.cs | 9 --------- MediaBrowser.Controller/Entities/InternalItemsQuery.cs | 1 + MediaBrowser.Controller/Entities/UserViewBuilder.cs | 17 ++++++++++++++++- .../MediaBrowser.Server.Implementations.csproj | 4 ++-- MediaBrowser.Server.Implementations/packages.config | 2 +- 5 files changed, 20 insertions(+), 13 deletions(-) (limited to 'MediaBrowser.Controller/Entities/InternalItemsQuery.cs') diff --git a/MediaBrowser.Api/UserLibrary/ItemsService.cs b/MediaBrowser.Api/UserLibrary/ItemsService.cs index d12dc8053..e7a077a91 100644 --- a/MediaBrowser.Api/UserLibrary/ItemsService.cs +++ b/MediaBrowser.Api/UserLibrary/ItemsService.cs @@ -423,15 +423,6 @@ namespace MediaBrowser.Api.UserLibrary return false; } - // Min index number - if (request.MinIndexNumber.HasValue) - { - if (!(i.IndexNumber.HasValue && i.IndexNumber.Value >= request.MinIndexNumber.Value)) - { - return false; - } - } - // Min official rating if (!string.IsNullOrEmpty(request.MinOfficialRating)) { diff --git a/MediaBrowser.Controller/Entities/InternalItemsQuery.cs b/MediaBrowser.Controller/Entities/InternalItemsQuery.cs index ac1fc4641..944a144ec 100644 --- a/MediaBrowser.Controller/Entities/InternalItemsQuery.cs +++ b/MediaBrowser.Controller/Entities/InternalItemsQuery.cs @@ -91,6 +91,7 @@ namespace MediaBrowser.Controller.Entities public int? MinPlayers { get; set; } public int? MaxPlayers { get; set; } + public int? MinIndexNumber { get; set; } public double? MinCriticRating { get; set; } public double? MinCommunityRating { get; set; } diff --git a/MediaBrowser.Controller/Entities/UserViewBuilder.cs b/MediaBrowser.Controller/Entities/UserViewBuilder.cs index 5778396cb..4d5f14f8c 100644 --- a/MediaBrowser.Controller/Entities/UserViewBuilder.cs +++ b/MediaBrowser.Controller/Entities/UserViewBuilder.cs @@ -1102,10 +1102,15 @@ namespace MediaBrowser.Controller.Entities return false; } + if (request.MinIndexNumber.HasValue) + { + return false; + } + return true; } - public static IEnumerable FilterVirtualEpisodes( + private static IEnumerable FilterVirtualEpisodes( IEnumerable items, bool? isMissing, bool? isVirtualUnaired, @@ -1790,6 +1795,16 @@ namespace MediaBrowser.Controller.Entities } } + if (query.MinIndexNumber.HasValue) + { + var val = query.MinIndexNumber.Value; + + if (!(item.IndexNumber.HasValue && item.IndexNumber.Value >= val)) + { + return false; + } + } + return true; } diff --git a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj index b4d019d13..54e323d92 100644 --- a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj +++ b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj @@ -58,9 +58,9 @@ ..\ThirdParty\ServiceStack\ServiceStack.Api.Swagger.dll - + False - ..\packages\SocketHttpListener.1.0.0.13\lib\net45\SocketHttpListener.dll + ..\packages\SocketHttpListener.1.0.0.14\lib\net45\SocketHttpListener.dll diff --git a/MediaBrowser.Server.Implementations/packages.config b/MediaBrowser.Server.Implementations/packages.config index 603c86333..81dd22ff3 100644 --- a/MediaBrowser.Server.Implementations/packages.config +++ b/MediaBrowser.Server.Implementations/packages.config @@ -6,5 +6,5 @@ - + \ No newline at end of file -- cgit v1.2.3 From f6e73a428e299fb3037efa0e8d41e8866016c68c Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sat, 14 Nov 2015 13:57:26 -0500 Subject: update querying --- MediaBrowser.Controller/Entities/BaseItem.cs | 30 +++++++++ .../Entities/CollectionFolder.cs | 15 +++-- .../Entities/InternalItemsQuery.cs | 2 + MediaBrowser.Controller/Entities/UserView.cs | 3 +- .../Library/LibraryManager.cs | 76 ++++++++++++++++++---- .../Persistence/CleanDatabaseScheduledTask.cs | 2 +- .../Persistence/SqliteItemRepository.cs | 30 ++++++++- 7 files changed, 135 insertions(+), 23 deletions(-) (limited to 'MediaBrowser.Controller/Entities/InternalItemsQuery.cs') diff --git a/MediaBrowser.Controller/Entities/BaseItem.cs b/MediaBrowser.Controller/Entities/BaseItem.cs index d8bb51003..252689b4a 100644 --- a/MediaBrowser.Controller/Entities/BaseItem.cs +++ b/MediaBrowser.Controller/Entities/BaseItem.cs @@ -1939,6 +1939,36 @@ namespace MediaBrowser.Controller.Entities return GetParents().Select(i => i.Id).Concat(LibraryManager.GetCollectionFolders(this).Select(i => i.Id)); } + public BaseItem GetTopParent() + { + if (IsTopParent) + { + return this; + } + + return GetParents().FirstOrDefault(i => i.IsTopParent); + } + + [IgnoreDataMember] + public virtual bool IsTopParent + { + get + { + if (GetParent() is AggregateFolder || this is Channel || this is BasePluginFolder) + { + return true; + } + + var view = this as UserView; + if (view != null && string.Equals(view.ViewType, CollectionType.LiveTv, StringComparison.OrdinalIgnoreCase)) + { + return true; + } + + return false; + } + } + [IgnoreDataMember] public virtual bool SupportsAncestors { diff --git a/MediaBrowser.Controller/Entities/CollectionFolder.cs b/MediaBrowser.Controller/Entities/CollectionFolder.cs index 0da253186..b2c7c2fa8 100644 --- a/MediaBrowser.Controller/Entities/CollectionFolder.cs +++ b/MediaBrowser.Controller/Entities/CollectionFolder.cs @@ -181,9 +181,7 @@ namespace MediaBrowser.Controller.Entities } private List GetLinkedChildrenInternal() { - return LibraryManager.RootFolder.Children - .OfType() - .Where(i => i.Path != null && PhysicalLocations.Contains(i.Path, StringComparer.OrdinalIgnoreCase)) + return GetPhysicalParents() .SelectMany(c => c.LinkedChildren) .ToList(); } @@ -199,11 +197,14 @@ namespace MediaBrowser.Controller.Entities private IEnumerable GetActualChildren() { - return - LibraryManager.RootFolder.Children + return GetPhysicalParents().SelectMany(c => c.Children); + } + + public IEnumerable GetPhysicalParents() + { + return LibraryManager.RootFolder.Children .OfType() - .Where(i => i.Path != null && PhysicalLocations.Contains(i.Path, StringComparer.OrdinalIgnoreCase)) - .SelectMany(c => c.Children); + .Where(i => i.Path != null && PhysicalLocations.Contains(i.Path, StringComparer.OrdinalIgnoreCase)); } [IgnoreDataMember] diff --git a/MediaBrowser.Controller/Entities/InternalItemsQuery.cs b/MediaBrowser.Controller/Entities/InternalItemsQuery.cs index 944a144ec..682cec69d 100644 --- a/MediaBrowser.Controller/Entities/InternalItemsQuery.cs +++ b/MediaBrowser.Controller/Entities/InternalItemsQuery.cs @@ -107,6 +107,7 @@ namespace MediaBrowser.Controller.Entities public Guid? ParentId { get; set; } public string[] AncestorIds { get; set; } + public string[] TopParentIds { get; set; } public LocationType[] ExcludeLocationTypes { get; set; } @@ -131,6 +132,7 @@ namespace MediaBrowser.Controller.Entities ChannelIds = new string[] { }; ItemIds = new string[] { }; AncestorIds = new string[] { }; + TopParentIds = new string[] { }; ExcludeLocationTypes = new LocationType[] { }; } diff --git a/MediaBrowser.Controller/Entities/UserView.cs b/MediaBrowser.Controller/Entities/UserView.cs index df089b5b2..473c671ee 100644 --- a/MediaBrowser.Controller/Entities/UserView.cs +++ b/MediaBrowser.Controller/Entities/UserView.cs @@ -170,7 +170,8 @@ namespace MediaBrowser.Controller.Entities { CollectionType.Games, CollectionType.Books, - CollectionType.MusicVideos + CollectionType.MusicVideos , + CollectionType.HomeVideos }; return types.Contains(viewType ?? string.Empty, StringComparer.OrdinalIgnoreCase); diff --git a/MediaBrowser.Server.Implementations/Library/LibraryManager.cs b/MediaBrowser.Server.Implementations/Library/LibraryManager.cs index 6206c0b8b..86d354fc8 100644 --- a/MediaBrowser.Server.Implementations/Library/LibraryManager.cs +++ b/MediaBrowser.Server.Implementations/Library/LibraryManager.cs @@ -1336,16 +1336,16 @@ namespace MediaBrowser.Server.Implementations.Library private void AddUserToQuery(InternalItemsQuery query, User user) { - if (query.AncestorIds.Length == 0 && !query.ParentId.HasValue && query.ChannelIds.Length == 0) + if (query.AncestorIds.Length == 0 && !query.ParentId.HasValue && query.ChannelIds.Length == 0 && query.TopParentIds.Length == 0) { - //var userViews = _userviewManager().GetUserViews(new UserViewQuery - //{ - // UserId = user.Id.ToString("N"), - // IncludeHidden = true + var userViews = _userviewManager().GetUserViews(new UserViewQuery + { + UserId = user.Id.ToString("N"), + IncludeHidden = true - //}, CancellationToken.None).Result.ToList(); + }, CancellationToken.None).Result.ToList(); - //query.AncestorIds = userViews.SelectMany(i => i.GetIdsForAncestorQuery()).Distinct().Select(i => i.ToString("N")).ToArray(); + query.TopParentIds = userViews.SelectMany(GetTopParentsForQuery).Select(i => i.Id.ToString("N")).ToArray(); } // TODO: handle blocking by tags @@ -1358,6 +1358,60 @@ namespace MediaBrowser.Server.Implementations.Library } } + private IEnumerable GetTopParentsForQuery(BaseItem item) + { + var view = item as UserView; + + if (view != null) + { + if (string.Equals(view.ViewType, CollectionType.LiveTv)) + { + return new[] { view }; + } + if (string.Equals(view.ViewType, CollectionType.Channels)) + { + // TODO: Return channels + return new[] { view }; + } + + // Translate view into folders + if (view.DisplayParentId != Guid.Empty) + { + var displayParent = GetItemById(view.DisplayParentId); + if (displayParent != null) + { + return GetTopParentsForQuery(displayParent); + } + return new BaseItem[] { }; + } + if (view.ParentId != Guid.Empty) + { + var displayParent = GetItemById(view.ParentId); + if (displayParent != null) + { + return GetTopParentsForQuery(displayParent); + } + return new BaseItem[] { }; + } + + // Handle grouping + return new BaseItem[] { }; + } + + var collectionFolder = item as CollectionFolder; + if (collectionFolder != null) + { + return collectionFolder.GetPhysicalParents(); + } + + var topParent = item.GetTopParent(); + if (topParent != null) + { + return new[] { topParent }; + } + return new BaseItem[] { }; + } + /// /// Gets the intros. /// @@ -1726,14 +1780,14 @@ namespace MediaBrowser.Server.Implementations.Library private string GetTopFolderContentType(BaseItem item) { - while (!(item.GetParent() is AggregateFolder) && item.GetParent() != null) + if (item == null) { - item = item.GetParent(); + return null; } - if (item == null) + while (!(item.GetParent() is AggregateFolder) && item.GetParent() != null) { - return null; + item = item.GetParent(); } return GetUserRootFolder().Children diff --git a/MediaBrowser.Server.Implementations/Persistence/CleanDatabaseScheduledTask.cs b/MediaBrowser.Server.Implementations/Persistence/CleanDatabaseScheduledTask.cs index dd96b9790..db58e2315 100644 --- a/MediaBrowser.Server.Implementations/Persistence/CleanDatabaseScheduledTask.cs +++ b/MediaBrowser.Server.Implementations/Persistence/CleanDatabaseScheduledTask.cs @@ -25,7 +25,7 @@ namespace MediaBrowser.Server.Implementations.Persistence private readonly IServerConfigurationManager _config; private readonly IFileSystem _fileSystem; - public const int MigrationVersion = 4; + public const int MigrationVersion = 6; 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 bf95fa612..5c6adced6 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 const int LatestSchemaVersion = 32; + private const int LatestSchemaVersion = 37; /// /// Initializes a new instance of the class. @@ -223,6 +223,7 @@ namespace MediaBrowser.Server.Implementations.Persistence _connection.AddColumn(_logger, "TypedBaseItems", "IsFolder", "BIT"); _connection.AddColumn(_logger, "TypedBaseItems", "InheritedParentalRatingValue", "INT"); _connection.AddColumn(_logger, "TypedBaseItems", "UnratedType", "Text"); + _connection.AddColumn(_logger, "TypedBaseItems", "TopParentId", "Text"); PrepareStatements(); @@ -451,7 +452,8 @@ namespace MediaBrowser.Server.Implementations.Persistence "ExternalServiceId", "Tags", "IsFolder", - "UnratedType" + "UnratedType", + "TopParentId" }; _saveItemCommand = _connection.CreateCommand(); _saveItemCommand.CommandText = "replace into TypedBaseItems (" + string.Join(",", saveColumns.ToArray()) + ") values ("; @@ -725,7 +727,17 @@ namespace MediaBrowser.Server.Implementations.Persistence _saveItemCommand.GetParameter(index++).Value = item.IsFolder; _saveItemCommand.GetParameter(index++).Value = item.GetBlockUnratedType().ToString(); - + + var topParent = item.GetTopParent(); + if (topParent != null) + { + _saveItemCommand.GetParameter(index++).Value = topParent.Id.ToString("N"); + } + else + { + _saveItemCommand.GetParameter(index++).Value = null; + } + _saveItemCommand.Transaction = transaction; _saveItemCommand.ExecuteNonQuery(); @@ -1940,6 +1952,18 @@ namespace MediaBrowser.Server.Implementations.Persistence whereClauses.Add("LocationType not in (" + val + ")"); } + if (query.TopParentIds.Length == 1) + { + whereClauses.Add("(TopParentId is null or TopParentId=@TopParentId)"); + cmd.Parameters.Add(cmd, "@TopParentId", DbType.String).Value = query.TopParentIds[0]; + } + if (query.TopParentIds.Length > 1) + { + var val = string.Join(",", query.TopParentIds.Select(i => "'" + i + "'").ToArray()); + + whereClauses.Add("(TopParentId is null or TopParentId in (" + val + "))"); + } + if (query.AncestorIds.Length == 1) { whereClauses.Add("Guid in (select itemId from AncestorIds where AncestorId=@AncestorId)"); -- cgit v1.2.3 From 72a0c2afeba7b2af3f8eff37f551b28740554210 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sun, 15 Nov 2015 17:30:47 -0500 Subject: update playlist query --- MediaBrowser.Api/UserLibrary/ItemsService.cs | 5 +++++ MediaBrowser.Controller/Entities/InternalItemsQuery.cs | 9 +++++++++ MediaBrowser.Providers/TV/TvdbSeriesProvider.cs | 16 +++++++++++++++- .../Library/LibraryManager.cs | 11 +---------- .../Persistence/SqliteItemRepository.cs | 8 ++++++++ 5 files changed, 38 insertions(+), 11 deletions(-) (limited to 'MediaBrowser.Controller/Entities/InternalItemsQuery.cs') diff --git a/MediaBrowser.Api/UserLibrary/ItemsService.cs b/MediaBrowser.Api/UserLibrary/ItemsService.cs index e7a077a91..489580555 100644 --- a/MediaBrowser.Api/UserLibrary/ItemsService.cs +++ b/MediaBrowser.Api/UserLibrary/ItemsService.cs @@ -112,6 +112,11 @@ namespace MediaBrowser.Api.UserLibrary user == null ? _libraryManager.RootFolder : user.RootFolder : parentItem; + if (string.Equals(request.IncludeItemTypes, "Playlist", StringComparison.OrdinalIgnoreCase)) + { + item = user == null ? _libraryManager.RootFolder : user.RootFolder; + } + // Default list type = children if (!string.IsNullOrEmpty(request.Ids)) diff --git a/MediaBrowser.Controller/Entities/InternalItemsQuery.cs b/MediaBrowser.Controller/Entities/InternalItemsQuery.cs index 682cec69d..96cd305a6 100644 --- a/MediaBrowser.Controller/Entities/InternalItemsQuery.cs +++ b/MediaBrowser.Controller/Entities/InternalItemsQuery.cs @@ -31,6 +31,7 @@ namespace MediaBrowser.Controller.Entities public string[] MediaTypes { get; set; } public string[] IncludeItemTypes { get; set; } public string[] ExcludeItemTypes { get; set; } + public string[] ExcludeTags { get; set; } public string[] Genres { get; set; } public bool? IsMissing { get; set; } @@ -133,6 +134,7 @@ namespace MediaBrowser.Controller.Entities ItemIds = new string[] { }; AncestorIds = new string[] { }; TopParentIds = new string[] { }; + ExcludeTags = new string[] { }; ExcludeLocationTypes = new LocationType[] { }; } @@ -144,6 +146,13 @@ namespace MediaBrowser.Controller.Entities var policy = user.Policy; MaxParentalRating = policy.MaxParentalRating; + if (policy.MaxParentalRating.HasValue) + { + BlockUnratedItems = policy.BlockUnratedItems; + } + + ExcludeTags = policy.BlockedTags; + User = user; } } diff --git a/MediaBrowser.Providers/TV/TvdbSeriesProvider.cs b/MediaBrowser.Providers/TV/TvdbSeriesProvider.cs index 5e5f96031..ccf8800cf 100644 --- a/MediaBrowser.Providers/TV/TvdbSeriesProvider.cs +++ b/MediaBrowser.Providers/TV/TvdbSeriesProvider.cs @@ -175,6 +175,11 @@ namespace MediaBrowser.Providers.TV /// Task. internal async Task DownloadSeriesZip(string seriesId, string seriesDataPath, long? lastTvDbUpdateTime, string preferredMetadataLanguage, CancellationToken cancellationToken) { + if (string.IsNullOrWhiteSpace(seriesId)) + { + throw new ArgumentNullException("seriesId"); + } + try { await DownloadSeriesZip(seriesId, seriesDataPath, lastTvDbUpdateTime, preferredMetadataLanguage, preferredMetadataLanguage, cancellationToken).ConfigureAwait(false); @@ -196,6 +201,11 @@ namespace MediaBrowser.Providers.TV private async Task DownloadSeriesZip(string seriesId, string seriesDataPath, long? lastTvDbUpdateTime, string preferredMetadataLanguage, string saveAsMetadataLanguage, CancellationToken cancellationToken) { + if (string.IsNullOrWhiteSpace(seriesId)) + { + throw new ArgumentNullException("seriesId"); + } + var url = string.Format(SeriesGetZip, TVUtils.TvdbApiKey, seriesId, preferredMetadataLanguage); using (var zipStream = await _httpClient.Get(new HttpRequestOptions @@ -247,7 +257,11 @@ namespace MediaBrowser.Providers.TV string id; if (seriesProviderIds.TryGetValue(MetadataProviders.Tvdb.ToString(), out id)) { - return true; + // This check should ideally never be necessary but we're seeing some cases of this and haven't tracked them down yet. + if (string.IsNullOrWhiteSpace(id)) + { + return true; + } } //if (seriesProviderIds.TryGetValue(MetadataProviders.Imdb.ToString(), out id)) //{ diff --git a/MediaBrowser.Server.Implementations/Library/LibraryManager.cs b/MediaBrowser.Server.Implementations/Library/LibraryManager.cs index 86d354fc8..673cff69c 100644 --- a/MediaBrowser.Server.Implementations/Library/LibraryManager.cs +++ b/MediaBrowser.Server.Implementations/Library/LibraryManager.cs @@ -1345,16 +1345,7 @@ namespace MediaBrowser.Server.Implementations.Library }, CancellationToken.None).Result.ToList(); - query.TopParentIds = userViews.SelectMany(GetTopParentsForQuery).Select(i => i.Id.ToString("N")).ToArray(); - } - - // TODO: handle blocking by tags - - query.MaxParentalRating = user.Policy.MaxParentalRating; - - if (user.Policy.MaxParentalRating.HasValue) - { - query.BlockUnratedItems = user.Policy.BlockUnratedItems; + //query.TopParentIds = userViews.SelectMany(GetTopParentsForQuery).Select(i => i.Id.ToString("N")).ToArray(); } } diff --git a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs index 5c6adced6..d414ce7c1 100644 --- a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs +++ b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs @@ -1985,6 +1985,14 @@ namespace MediaBrowser.Server.Implementations.Persistence var inClause = string.Join(",", query.BlockUnratedItems.Select(i => "'" + i.ToString() + "'").ToArray()); whereClauses.Add(string.Format("(InheritedParentalRatingValue > 0 or UnratedType not in ({0}))", inClause)); } + + //var excludeTagIndex = 0; + //foreach (var excludeTag in query.ExcludeTags) + //{ + // whereClauses.Add("Tags not like @excludeTag" + excludeTagIndex); + // cmd.Parameters.Add(cmd, "@excludeTag" + excludeTagIndex, DbType.String).Value = "%" + excludeTag + "%"; + // excludeTagIndex++; + //} if (addPaging) { -- cgit v1.2.3 From 1d6f82e2eff578dc1ff075bfd01aec16fde7c857 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sun, 14 Feb 2016 12:58:31 -0500 Subject: update search results --- .../Entities/InternalItemsQuery.cs | 1 + .../Library/LibraryManager.cs | 2 +- .../Library/SearchEngine.cs | 1 + .../LiveTv/LiveTvManager.cs | 9 ++++++-- .../Persistence/SqliteItemRepository.cs | 26 +++++++++++++++++----- 5 files changed, 31 insertions(+), 8 deletions(-) (limited to 'MediaBrowser.Controller/Entities/InternalItemsQuery.cs') diff --git a/MediaBrowser.Controller/Entities/InternalItemsQuery.cs b/MediaBrowser.Controller/Entities/InternalItemsQuery.cs index 96cd305a6..0595d0569 100644 --- a/MediaBrowser.Controller/Entities/InternalItemsQuery.cs +++ b/MediaBrowser.Controller/Entities/InternalItemsQuery.cs @@ -27,6 +27,7 @@ namespace MediaBrowser.Controller.Entities public bool? IsLiked { get; set; } public bool? IsPlayed { get; set; } public bool? IsResumable { get; set; } + public bool? IncludeItemsByName { get; set; } public string[] MediaTypes { get; set; } public string[] IncludeItemTypes { get; set; } diff --git a/MediaBrowser.Server.Implementations/Library/LibraryManager.cs b/MediaBrowser.Server.Implementations/Library/LibraryManager.cs index e4cb58346..333b1fbe9 100644 --- a/MediaBrowser.Server.Implementations/Library/LibraryManager.cs +++ b/MediaBrowser.Server.Implementations/Library/LibraryManager.cs @@ -1324,7 +1324,7 @@ namespace MediaBrowser.Server.Implementations.Library SetTopParentIdsOrAncestors(query, parents); - return GetItemIds(query).Select(GetItemById); + return GetItemIds(query).Select(GetItemById).Where(i => i != null); } public QueryResult GetItemsResult(InternalItemsQuery query, IEnumerable parentIds) diff --git a/MediaBrowser.Server.Implementations/Library/SearchEngine.cs b/MediaBrowser.Server.Implementations/Library/SearchEngine.cs index aff982b0d..62392c1c7 100644 --- a/MediaBrowser.Server.Implementations/Library/SearchEngine.cs +++ b/MediaBrowser.Server.Implementations/Library/SearchEngine.cs @@ -163,6 +163,7 @@ namespace MediaBrowser.Server.Implementations.Library ExcludeItemTypes = excludeItemTypes.ToArray(), IncludeItemTypes = includeItemTypes.ToArray(), Limit = query.Limit, + IncludeItemsByName = true }, new string[] { }); diff --git a/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs b/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs index 85b2059ae..14bfcba27 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs @@ -300,6 +300,11 @@ namespace MediaBrowser.Server.Implementations.LiveTv public async Task GetInternalRecording(string id, CancellationToken cancellationToken) { + if (string.IsNullOrWhiteSpace(id)) + { + throw new ArgumentNullException("id"); + } + var result = await GetInternalRecordings(new RecordingQuery { Id = id @@ -1410,7 +1415,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv var queryResult = _libraryManager.GetItems(internalQuery, new string[] { }); IEnumerable recordings = queryResult.Cast(); - if (!string.IsNullOrEmpty(query.Id)) + if (!string.IsNullOrWhiteSpace(query.Id)) { var guid = new Guid(query.Id); @@ -1418,7 +1423,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv .Where(i => i.Id == guid); } - if (!string.IsNullOrEmpty(query.GroupId)) + if (!string.IsNullOrWhiteSpace(query.GroupId)) { var guid = new Guid(query.GroupId); diff --git a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs index d7bf294e3..346dcf359 100644 --- a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs +++ b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs @@ -1914,18 +1914,34 @@ namespace MediaBrowser.Server.Implementations.Persistence whereClauses.Add("LocationType not in (" + val + ")"); } + var enableItemsByName = query.IncludeItemsByName ?? query.IncludeItemTypes.Length > 0; + if (query.TopParentIds.Length == 1) { - whereClauses.Add("(TopParentId=@TopParentId or IsItemByName=@IsItemByName)"); + if (enableItemsByName) + { + whereClauses.Add("(TopParentId=@TopParentId or IsItemByName=@IsItemByName)"); + cmd.Parameters.Add(cmd, "@IsItemByName", DbType.Boolean).Value = true; + } + else + { + whereClauses.Add("(TopParentId=@TopParentId)"); + } cmd.Parameters.Add(cmd, "@TopParentId", DbType.String).Value = query.TopParentIds[0]; - cmd.Parameters.Add(cmd, "@IsItemByName", DbType.Boolean).Value = true; } if (query.TopParentIds.Length > 1) { var val = string.Join(",", query.TopParentIds.Select(i => "'" + i + "'").ToArray()); - - whereClauses.Add("(IsItemByName=@IsItemByName or TopParentId in (" + val + "))"); - cmd.Parameters.Add(cmd, "@IsItemByName", DbType.Boolean).Value = true; + + if (enableItemsByName) + { + whereClauses.Add("(IsItemByName=@IsItemByName or TopParentId in (" + val + "))"); + cmd.Parameters.Add(cmd, "@IsItemByName", DbType.Boolean).Value = true; + } + else + { + whereClauses.Add("(TopParentId in (" + val + "))"); + } } if (query.AncestorIds.Length == 1) -- cgit v1.2.3