diff --git a/MediaBrowser.Api/BaseApiService.cs b/MediaBrowser.Api/BaseApiService.cs index 7a14ace777..ecab943491 100644 --- a/MediaBrowser.Api/BaseApiService.cs +++ b/MediaBrowser.Api/BaseApiService.cs @@ -198,50 +198,6 @@ namespace MediaBrowser.Api return libraryManager.GetPerson(DeSlugPersonName(name, libraryManager)); } - protected IList GetAllLibraryItems(string userId, IUserManager userManager, ILibraryManager libraryManager, string parentId, Func filter) - { - if (!string.IsNullOrEmpty(parentId)) - { - var folder = (Folder)libraryManager.GetItemById(new Guid(parentId)); - - if (!string.IsNullOrWhiteSpace(userId)) - { - var user = userManager.GetUserById(userId); - - if (user == null) - { - throw new ArgumentException("User not found"); - } - - return folder - .GetRecursiveChildren(user, filter) - .ToList(); - } - - return folder - .GetRecursiveChildren(filter); - } - if (!string.IsNullOrWhiteSpace(userId)) - { - var user = userManager.GetUserById(userId); - - if (user == null) - { - throw new ArgumentException("User not found"); - } - - return userManager - .GetUserById(userId) - .RootFolder - .GetRecursiveChildren(user, filter) - .ToList(); - } - - return libraryManager - .RootFolder - .GetRecursiveChildren(filter); - } - /// /// Deslugs an artist name by finding the correct entry in the library /// diff --git a/MediaBrowser.Api/GamesService.cs b/MediaBrowser.Api/GamesService.cs index 93cc010793..28324af5d4 100644 --- a/MediaBrowser.Api/GamesService.cs +++ b/MediaBrowser.Api/GamesService.cs @@ -102,12 +102,16 @@ namespace MediaBrowser.Api /// System.Object. public object Get(GetGameSystemSummaries request) { - var gameSystems = GetAllLibraryItems(request.UserId, _userManager, _libraryManager, null, i => i is GameSystem) + var user = request.UserId == null ? null : _userManager.GetUserById(request.UserId); + var query = new InternalItemsQuery(user) + { + IncludeItemTypes = new[] { typeof(GameSystem).Name } + }; + var parentIds = new string[] { } ; + var gameSystems = _libraryManager.GetItems(query, user, parentIds) .Cast() .ToList(); - var user = request.UserId == null ? null : _userManager.GetUserById(request.UserId); - var result = gameSystems .Select(i => GetSummary(i, user)) .ToList(); @@ -119,8 +123,15 @@ namespace MediaBrowser.Api public object Get(GetPlayerIndex request) { - var games = GetAllLibraryItems(request.UserId, _userManager, _libraryManager, null, i => i is Game) - .Cast(); + var user = request.UserId == null ? null : _userManager.GetUserById(request.UserId); + var query = new InternalItemsQuery(user) + { + IncludeItemTypes = new[] { typeof(Game).Name } + }; + var parentIds = new string[] { }; + var games = _libraryManager.GetItems(query, user, parentIds) + .Cast() + .ToList(); var lookup = games .ToLookup(i => i.PlayersSupported ?? -1) diff --git a/MediaBrowser.Api/Library/LibraryService.cs b/MediaBrowser.Api/Library/LibraryService.cs index 904e8cdf64..c4ab025980 100644 --- a/MediaBrowser.Api/Library/LibraryService.cs +++ b/MediaBrowser.Api/Library/LibraryService.cs @@ -677,6 +677,50 @@ namespace MediaBrowser.Api.Library return ToOptimizedSerializedResultUsingCache(counts); } + private IList GetAllLibraryItems(string userId, IUserManager userManager, ILibraryManager libraryManager, string parentId, Func filter) + { + if (!string.IsNullOrEmpty(parentId)) + { + var folder = (Folder)libraryManager.GetItemById(new Guid(parentId)); + + if (!string.IsNullOrWhiteSpace(userId)) + { + var user = userManager.GetUserById(userId); + + if (user == null) + { + throw new ArgumentException("User not found"); + } + + return folder + .GetRecursiveChildren(user, filter) + .ToList(); + } + + return folder + .GetRecursiveChildren(filter); + } + if (!string.IsNullOrWhiteSpace(userId)) + { + var user = userManager.GetUserById(userId); + + if (user == null) + { + throw new ArgumentException("User not found"); + } + + return userManager + .GetUserById(userId) + .RootFolder + .GetRecursiveChildren(user, filter) + .ToList(); + } + + return libraryManager + .RootFolder + .GetRecursiveChildren(filter); + } + private bool FilterItem(BaseItem item, GetItemCounts request, string userId) { if (!string.IsNullOrWhiteSpace(userId)) diff --git a/MediaBrowser.Api/Movies/MoviesService.cs b/MediaBrowser.Api/Movies/MoviesService.cs index 1681c6fc6b..3240766951 100644 --- a/MediaBrowser.Api/Movies/MoviesService.cs +++ b/MediaBrowser.Api/Movies/MoviesService.cs @@ -117,10 +117,7 @@ namespace MediaBrowser.Api.Movies public async Task Get(GetSimilarMovies request) { var result = await GetSimilarItemsResult( - // Strip out secondary versions - request, item => (item is Movie) && !((Video)item).PrimaryVersionId.HasValue, - - SimilarItemsHelper.GetSimiliarityScore).ConfigureAwait(false); + request, SimilarItemsHelper.GetSimiliarityScore).ConfigureAwait(false); return ToOptimizedSerializedResultUsingCache(result); } @@ -128,10 +125,7 @@ namespace MediaBrowser.Api.Movies public async Task Get(GetSimilarTrailers request) { var result = await GetSimilarItemsResult( - // Strip out secondary versions - request, item => (item is Movie) && !((Video)item).PrimaryVersionId.HasValue, - - SimilarItemsHelper.GetSimiliarityScore).ConfigureAwait(false); + request, SimilarItemsHelper.GetSimiliarityScore).ConfigureAwait(false); return ToOptimizedSerializedResultUsingCache(result); } @@ -140,8 +134,12 @@ namespace MediaBrowser.Api.Movies { var user = _userManager.GetUserById(request.UserId); - IEnumerable movies = GetAllLibraryItems(request.UserId, _userManager, _libraryManager, request.ParentId, i => i is Movie); - + var query = new InternalItemsQuery(user) + { + IncludeItemTypes = new[] { typeof(Movie).Name } + }; + var parentIds = string.IsNullOrWhiteSpace(request.ParentId) ? new string[] { } : new[] { request.ParentId }; + var movies = _libraryManager.GetItems(query, user, parentIds); movies = _libraryManager.ReplaceVideosWithPrimaryVersions(movies); var listEligibleForCategories = new List(); @@ -184,21 +182,27 @@ namespace MediaBrowser.Api.Movies return ToOptimizedResult(result); } - private async Task GetSimilarItemsResult(BaseGetSimilarItemsFromItem request, Func includeInSearch, Func, List, BaseItem, int> getSimilarityScore) + private async Task GetSimilarItemsResult(BaseGetSimilarItemsFromItem request, Func, List, BaseItem, int> getSimilarityScore) { var user = !string.IsNullOrWhiteSpace(request.UserId) ? _userManager.GetUserById(request.UserId) : null; var item = string.IsNullOrEmpty(request.Id) ? (!string.IsNullOrWhiteSpace(request.UserId) ? user.RootFolder : _libraryManager.RootFolder) : _libraryManager.GetItemById(request.Id); - - Func filter = i => i.Id != item.Id && includeInSearch(i); - - var inputItems = user == null - ? _libraryManager.RootFolder.GetRecursiveChildren(filter) - : user.RootFolder.GetRecursiveChildren(user, filter); - - var list = inputItems.ToList(); + + var query = new InternalItemsQuery(user) + { + IncludeItemTypes = new[] { typeof(Movie).Name } + }; + var parentIds = new string[] { }; + var list = _libraryManager.GetItems(query, user, parentIds) + .Where(i => + { + // Strip out secondary versions + var v = i as Video; + return v != null && !v.PrimaryVersionId.HasValue; + }) + .ToList(); if (user != null && user.Configuration.IncludeTrailersInSuggestions) { diff --git a/MediaBrowser.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs b/MediaBrowser.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs index 434578718a..0898e39167 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs @@ -114,7 +114,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.Listings var requestString = _jsonSerializer.SerializeToString(requestList); _logger.Debug("Request string for schedules is: " + requestString); httpOptions.RequestContent = requestString; - using (var response = await _httpClient.Post(httpOptions)) + using (var response = await Post(httpOptions).ConfigureAwait(false)) { StreamReader reader = new StreamReader(response.Content); string responseString = reader.ReadToEnd(); @@ -136,7 +136,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.Listings var requestBody = "[\"" + string.Join("\", \"", programsID) + "\"]"; httpOptions.RequestContent = requestBody; - using (var innerResponse = await _httpClient.Post(httpOptions)) + using (var innerResponse = await Post(httpOptions).ConfigureAwait(false)) { StreamReader innerReader = new StreamReader(innerResponse.Content); responseString = innerReader.ReadToEnd(); @@ -225,7 +225,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.Listings httpOptions.RequestHeaders["token"] = token; - using (var response = await _httpClient.Get(httpOptions)) + using (var response = await Get(httpOptions).ConfigureAwait(false)) { var root = _jsonSerializer.DeserializeFromStream(response); _logger.Info("Found " + root.map.Count() + " channels on the lineup on ScheduleDirect"); @@ -466,7 +466,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.Listings LogErrorResponseBody = true }; List images; - using (var innerResponse2 = await _httpClient.Post(httpOptions)) + using (var innerResponse2 = await Post(httpOptions).ConfigureAwait(false)) { images = _jsonSerializer.DeserializeFromStream>( innerResponse2.Content); @@ -498,7 +498,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.Listings try { - using (Stream responce = await _httpClient.Get(options).ConfigureAwait(false)) + using (Stream responce = await Get(options).ConfigureAwait(false)) { var root = _jsonSerializer.DeserializeFromStream>(responce); @@ -567,7 +567,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.Listings if (long.TryParse(savedToken.Value, NumberStyles.Any, CultureInfo.InvariantCulture, out ticks)) { // If it's under 24 hours old we can still use it - if ((DateTime.UtcNow.Ticks - ticks) < TimeSpan.FromHours(24).Ticks) + if ((DateTime.UtcNow.Ticks - ticks) < TimeSpan.FromHours(20).Ticks) { return savedToken.Name; } @@ -600,6 +600,32 @@ namespace MediaBrowser.Server.Implementations.LiveTv.Listings } } + private async Task Post(HttpRequestOptions options) + { + try + { + return await _httpClient.Post(options).ConfigureAwait(false); + } + catch + { + _tokens.Clear(); + throw; + } + } + + private async Task Get(HttpRequestOptions options) + { + try + { + return await _httpClient.Get(options).ConfigureAwait(false); + } + catch + { + _tokens.Clear(); + throw; + } + } + private async Task GetTokenInternal(string username, string password, CancellationToken cancellationToken) { @@ -614,7 +640,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.Listings //_logger.Info("Obtaining token from Schedules Direct from addres: " + httpOptions.Url + " with body " + // httpOptions.RequestContent); - using (var responce = await _httpClient.Post(httpOptions)) + using (var responce = await Post(httpOptions).ConfigureAwait(false)) { var root = _jsonSerializer.DeserializeFromStream(responce.Content); if (root.message == "OK") @@ -696,7 +722,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.Listings try { - using (var response = await _httpClient.Get(options).ConfigureAwait(false)) + using (var response = await Get(options).ConfigureAwait(false)) { var root = _jsonSerializer.DeserializeFromStream(response); diff --git a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs index ee89c0f974..4d394d14a7 100644 --- a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs +++ b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs @@ -80,6 +80,8 @@ namespace MediaBrowser.Server.Implementations.Persistence private IDbCommand _deleteAncestorsCommand; private IDbCommand _saveAncestorCommand; + private IDbCommand _updateInheritedRatingCommand; + private const int LatestSchemaVersion = 29; /// @@ -532,6 +534,11 @@ namespace MediaBrowser.Server.Implementations.Persistence { _saveStreamCommand.Parameters.Add(_saveStreamCommand, "@" + col); } + + _updateInheritedRatingCommand = _connection.CreateCommand(); + _updateInheritedRatingCommand.CommandText = "Update TypedBaseItems set InheritedParentalRatingValue=@InheritedParentalRatingValue where Guid=@Guid"; + _updateInheritedRatingCommand.Parameters.Add(_updateInheritedRatingCommand, "@InheritedParentalRatingValue"); + _updateInheritedRatingCommand.Parameters.Add(_updateInheritedRatingCommand, "@Guid"); } /// @@ -2011,55 +2018,79 @@ 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(); - //} + var newValues = new List>(); + + using (var cmd = _connection.CreateCommand()) + { + cmd.CommandText = "select Guid,InheritedParentalRatingValue,(select Max(ParentalRatingValue, (select COALESCE(MAX(ParentalRatingValue),0) from TypedBaseItems where guid in (Select AncestorId from AncestorIds where ItemId=Outer.guid)))) as NewInheritedParentalRatingValue from typedbaseitems as Outer where InheritedParentalRatingValue <> NewInheritedParentalRatingValue"; + + using (var reader = cmd.ExecuteReader(CommandBehavior.SequentialAccess | CommandBehavior.SingleResult)) + { + while (reader.Read()) + { + var id = reader.GetGuid(0); + var newValue = reader.GetInt32(2); + + newValues.Add(new Tuple(id, newValue)); + } + } + } + + if (newValues.Count == 0) + { + return; + } + + await _writeLock.WaitAsync(cancellationToken).ConfigureAwait(false); + + IDbTransaction transaction = null; + + try + { + transaction = _connection.BeginTransaction(); + + foreach (var item in newValues) + { + _updateInheritedRatingCommand.GetParameter(0).Value = item.Item1; + _updateInheritedRatingCommand.GetParameter(1).Value = item.Item2; + + _updateInheritedRatingCommand.Transaction = transaction; + _updateInheritedRatingCommand.ExecuteNonQuery(); + + _updateInheritedRatingCommand.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()