From 818662e051a07b15a9ac15df177835d7e4ef236b Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Wed, 28 Oct 2015 00:06:13 -0400 Subject: use ImageMagick scale method --- MediaBrowser.Controller/LiveTv/LiveTvProgram.cs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'MediaBrowser.Controller/LiveTv/LiveTvProgram.cs') diff --git a/MediaBrowser.Controller/LiveTv/LiveTvProgram.cs b/MediaBrowser.Controller/LiveTv/LiveTvProgram.cs index e4b52fd99..96a3743d0 100644 --- a/MediaBrowser.Controller/LiveTv/LiveTvProgram.cs +++ b/MediaBrowser.Controller/LiveTv/LiveTvProgram.cs @@ -49,6 +49,12 @@ namespace MediaBrowser.Controller.LiveTv /// The audio. public ProgramAudio? Audio { get; set; } + /// + /// Gets or sets the name of the service. + /// + /// The name of the service. + public string ServiceName { get; set; } + /// /// Gets or sets a value indicating whether this instance is repeat. /// @@ -63,12 +69,6 @@ namespace MediaBrowser.Controller.LiveTv [IgnoreDataMember] public string EpisodeTitle { get; set; } - /// - /// Gets or sets the name of the service. - /// - /// The name of the service. - public string ServiceName { get; set; } - /// /// Gets or sets a value indicating whether this instance is movie. /// -- cgit v1.2.3 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 --- Emby.Drawing/ImageMagick/ImageMagickEncoder.cs | 3 ++ MediaBrowser.Api/Movies/MoviesService.cs | 3 +- MediaBrowser.Api/TvShowsService.cs | 35 ++++++++----- .../Logging/NlogManager.cs | 2 +- .../Security/PluginSecurityManager.cs | 9 ++++ MediaBrowser.Common/MediaBrowser.Common.csproj | 1 + .../Security/PaymentRequiredException.cs | 8 +++ MediaBrowser.Controller/Entities/BaseItem.cs | 10 +++- .../Entities/InternalItemsQuery.cs | 11 ++++ MediaBrowser.Controller/Library/ILibraryManager.cs | 8 +++ .../LiveTv/LiveTvAudioRecording.cs | 1 - MediaBrowser.Controller/LiveTv/LiveTvProgram.cs | 35 +++++-------- .../LiveTv/LiveTvVideoRecording.cs | 1 - .../MediaBrowser.Controller.csproj | 1 + .../Net/PaymentRequiredException.cs | 15 ++++++ .../Providers/MetadataStatus.cs | 14 ----- MediaBrowser.Providers/Manager/MetadataService.cs | 22 +++++--- .../Dto/DtoService.cs | 8 ++- .../HttpServer/HttpListenerHost.cs | 4 +- .../HttpServer/LoggerUtils.cs | 5 +- .../SocketSharp/WebSocketSharpListener.cs | 10 +--- .../Library/LibraryManager.cs | 12 ++--- .../Library/SearchEngine.cs | 3 +- .../LiveTv/LiveTvManager.cs | 40 +++++++-------- .../Persistence/SqliteItemRepository.cs | 60 ++++++++++++++++++++-- .../Persistence/SqliteProviderInfoRepository.cs | 13 ++--- .../TV/TVSeriesManager.cs | 20 ++++++-- 27 files changed, 232 insertions(+), 122 deletions(-) create mode 100644 MediaBrowser.Common/Security/PaymentRequiredException.cs create mode 100644 MediaBrowser.Controller/Net/PaymentRequiredException.cs (limited to 'MediaBrowser.Controller/LiveTv/LiveTvProgram.cs') diff --git a/Emby.Drawing/ImageMagick/ImageMagickEncoder.cs b/Emby.Drawing/ImageMagick/ImageMagickEncoder.cs index c5ba6d9c8..d097c8da3 100644 --- a/Emby.Drawing/ImageMagick/ImageMagickEncoder.cs +++ b/Emby.Drawing/ImageMagick/ImageMagickEncoder.cs @@ -136,6 +136,9 @@ namespace Emby.Drawing.ImageMagick public void EncodeImage(string inputPath, string outputPath, int width, int height, int quality, ImageProcessingOptions options) { + // Even if the caller specified 100, don't use it because it takes forever + quality = Math.Min(quality, 99); + if (string.IsNullOrWhiteSpace(options.BackgroundColor) || !HasTransparency(inputPath)) { using (var originalImage = new MagickWand(inputPath)) diff --git a/MediaBrowser.Api/Movies/MoviesService.cs b/MediaBrowser.Api/Movies/MoviesService.cs index fe8bae1a5..1681c6fc6 100644 --- a/MediaBrowser.Api/Movies/MoviesService.cs +++ b/MediaBrowser.Api/Movies/MoviesService.cs @@ -379,9 +379,10 @@ namespace MediaBrowser.Api.Movies { foreach (var name in names) { - var itemsWithActor = _libraryManager.GetItemIds(new InternalItemsQuery + var itemsWithActor = _libraryManager.GetItemIds(new InternalItemsQuery(user) { Person = name + }); var items = allMovies diff --git a/MediaBrowser.Api/TvShowsService.cs b/MediaBrowser.Api/TvShowsService.cs index 29a4a8bb5..19d12fe65 100644 --- a/MediaBrowser.Api/TvShowsService.cs +++ b/MediaBrowser.Api/TvShowsService.cs @@ -159,7 +159,7 @@ namespace MediaBrowser.Api [ApiMember(Name = "StartItemId", Description = "Optional. Skip through the list until a given item is found.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")] public string StartItemId { get; set; } - + /// /// Skips over a given number of items within the results. Use for paging. /// @@ -273,21 +273,32 @@ namespace MediaBrowser.Api { var user = _userManager.GetUserById(request.UserId); - var items = GetAllLibraryItems(request.UserId, _userManager, _libraryManager, request.ParentId, i => i is Episode); + var minPremiereDate = DateTime.Now.Date.AddDays(-1).ToUniversalTime(); + + IEnumerable items; + + if (string.IsNullOrWhiteSpace(request.ParentId)) + { + 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(); - var unairedEpisodes = itemsList.Where(i => i.IsUnaired).ToList(); - - var minPremiereDate = DateTime.Now.Date.AddDays(-1).ToUniversalTime(); - var previousEpisodes = itemsList.Where(i => !i.IsUnaired && (i.PremiereDate ?? DateTime.MinValue) >= minPremiereDate).ToList(); - - previousEpisodes.AddRange(unairedEpisodes); - - var pagedItems = ApplyPaging(previousEpisodes, request.StartIndex, request.Limit); + var pagedItems = ApplyPaging(itemsList, request.StartIndex, request.Limit); var options = GetDtoOptions(request); @@ -440,7 +451,7 @@ namespace MediaBrowser.Api } episodes = season.GetEpisodes(user); - } + } else if (request.Season.HasValue) { var series = _libraryManager.GetItemById(request.Id) as Series; @@ -495,7 +506,7 @@ namespace MediaBrowser.Api .ToList(); var pagedItems = ApplyPaging(returnList, request.StartIndex, request.Limit); - + var dtoOptions = GetDtoOptions(request); var dtos = _dtoService.GetBaseItemDtos(pagedItems, dtoOptions, user) diff --git a/MediaBrowser.Common.Implementations/Logging/NlogManager.cs b/MediaBrowser.Common.Implementations/Logging/NlogManager.cs index 391e7c212..1bbcccd88 100644 --- a/MediaBrowser.Common.Implementations/Logging/NlogManager.cs +++ b/MediaBrowser.Common.Implementations/Logging/NlogManager.cs @@ -110,7 +110,7 @@ namespace MediaBrowser.Common.Implementations.Logging var logFile = new FileTarget { FileName = path, - Layout = "${longdate} ${level} - ${logger}: ${message}" + Layout = "${longdate} ${level} ${logger}: ${message}" }; logFile.Name = "ApplicationLogFile"; diff --git a/MediaBrowser.Common.Implementations/Security/PluginSecurityManager.cs b/MediaBrowser.Common.Implementations/Security/PluginSecurityManager.cs index c17a637fe..7cc31ad7a 100644 --- a/MediaBrowser.Common.Implementations/Security/PluginSecurityManager.cs +++ b/MediaBrowser.Common.Implementations/Security/PluginSecurityManager.cs @@ -219,6 +219,10 @@ namespace MediaBrowser.Common.Implementations.Security { SupporterKey = reg.key; } + else + { + throw new PaymentRequiredException(); + } } } @@ -227,6 +231,11 @@ namespace MediaBrowser.Common.Implementations.Security SaveAppStoreInfo(parameters); throw; } + catch (PaymentRequiredException) + { + SaveAppStoreInfo(parameters); + throw; + } catch (Exception e) { _logger.ErrorException("Error registering appstore purchase {0}", e, parameters ?? "NO PARMS SENT"); diff --git a/MediaBrowser.Common/MediaBrowser.Common.csproj b/MediaBrowser.Common/MediaBrowser.Common.csproj index b2f62dd21..ccdb319fe 100644 --- a/MediaBrowser.Common/MediaBrowser.Common.csproj +++ b/MediaBrowser.Common/MediaBrowser.Common.csproj @@ -89,6 +89,7 @@ + diff --git a/MediaBrowser.Common/Security/PaymentRequiredException.cs b/MediaBrowser.Common/Security/PaymentRequiredException.cs new file mode 100644 index 000000000..27b3e6961 --- /dev/null +++ b/MediaBrowser.Common/Security/PaymentRequiredException.cs @@ -0,0 +1,8 @@ +using System; + +namespace MediaBrowser.Common.Security +{ + public class PaymentRequiredException : Exception + { + } +} diff --git a/MediaBrowser.Controller/Entities/BaseItem.cs b/MediaBrowser.Controller/Entities/BaseItem.cs index 19d5576c6..fdf035e8d 100644 --- a/MediaBrowser.Controller/Entities/BaseItem.cs +++ b/MediaBrowser.Controller/Entities/BaseItem.cs @@ -24,6 +24,7 @@ using System.Runtime.Serialization; using System.Threading; using System.Threading.Tasks; using CommonIO; +using MediaBrowser.Model.LiveTv; namespace MediaBrowser.Controller.Entities { @@ -134,6 +135,13 @@ namespace MediaBrowser.Controller.Entities [IgnoreDataMember] public bool? IsHD { get; set; } + /// + /// Gets or sets the audio. + /// + /// The audio. + [IgnoreDataMember] + public ProgramAudio? Audio { get; set; } + /// /// Return the id that should be used to key display prefs for this item. /// Default is based on the type for everything except actual generic folders. @@ -178,7 +186,7 @@ namespace MediaBrowser.Controller.Entities } /// - /// Id of the program. + /// If this content came from an external service, the id of the content on that service /// [IgnoreDataMember] public string ExternalId 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; + } + } } } diff --git a/MediaBrowser.Controller/Library/ILibraryManager.cs b/MediaBrowser.Controller/Library/ILibraryManager.cs index c7ab88524..96bb6e2b6 100644 --- a/MediaBrowser.Controller/Library/ILibraryManager.cs +++ b/MediaBrowser.Controller/Library/ILibraryManager.cs @@ -543,5 +543,13 @@ namespace MediaBrowser.Controller.Library /// Index of the image. /// Task. Task ConvertImageToLocal(IHasImages item, ItemImageInfo image, int imageIndex); + + /// + /// Gets the items. + /// + /// The query. + /// The user. + /// List<BaseItem>. + IEnumerable GetItems(InternalItemsQuery query, User user); } } \ No newline at end of file diff --git a/MediaBrowser.Controller/LiveTv/LiveTvAudioRecording.cs b/MediaBrowser.Controller/LiveTv/LiveTvAudioRecording.cs index 03c05ec69..dd6a53d45 100644 --- a/MediaBrowser.Controller/LiveTv/LiveTvAudioRecording.cs +++ b/MediaBrowser.Controller/LiveTv/LiveTvAudioRecording.cs @@ -36,7 +36,6 @@ namespace MediaBrowser.Controller.LiveTv public bool IsLive { get; set; } [IgnoreDataMember] public bool IsPremiere { get; set; } - public ProgramAudio? Audio { get; set; } /// /// Gets the user data key. diff --git a/MediaBrowser.Controller/LiveTv/LiveTvProgram.cs b/MediaBrowser.Controller/LiveTv/LiveTvProgram.cs index 96a3743d0..aa1a3b9c2 100644 --- a/MediaBrowser.Controller/LiveTv/LiveTvProgram.cs +++ b/MediaBrowser.Controller/LiveTv/LiveTvProgram.cs @@ -32,10 +32,11 @@ namespace MediaBrowser.Controller.LiveTv } /// - /// Gets or sets the type of the channel. + /// Gets or sets the name. /// - /// The type of the channel. - public ChannelType ChannelType { get; set; } + /// The name. + [IgnoreDataMember] + public string ServiceName { get; set; } /// /// The start date of the program, in UTC. @@ -43,18 +44,6 @@ namespace MediaBrowser.Controller.LiveTv [IgnoreDataMember] public DateTime StartDate { get; set; } - /// - /// Gets or sets the audio. - /// - /// The audio. - public ProgramAudio? Audio { get; set; } - - /// - /// Gets or sets the name of the service. - /// - /// The name of the service. - public string ServiceName { get; set; } - /// /// Gets or sets a value indicating whether this instance is repeat. /// @@ -145,14 +134,14 @@ namespace MediaBrowser.Controller.LiveTv } } - [IgnoreDataMember] - public override string MediaType - { - get - { - return ChannelType == ChannelType.TV ? Model.Entities.MediaType.Video : Model.Entities.MediaType.Audio; - } - } + //[IgnoreDataMember] + //public override string MediaType + //{ + // get + // { + // return ChannelType == ChannelType.TV ? Model.Entities.MediaType.Video : Model.Entities.MediaType.Audio; + // } + //} [IgnoreDataMember] public bool IsAiring diff --git a/MediaBrowser.Controller/LiveTv/LiveTvVideoRecording.cs b/MediaBrowser.Controller/LiveTv/LiveTvVideoRecording.cs index 77404cfe8..de8764e6d 100644 --- a/MediaBrowser.Controller/LiveTv/LiveTvVideoRecording.cs +++ b/MediaBrowser.Controller/LiveTv/LiveTvVideoRecording.cs @@ -36,7 +36,6 @@ namespace MediaBrowser.Controller.LiveTv public bool IsLive { get; set; } [IgnoreDataMember] public bool IsPremiere { get; set; } - public ProgramAudio? Audio { get; set; } /// /// Gets the user data key. diff --git a/MediaBrowser.Controller/MediaBrowser.Controller.csproj b/MediaBrowser.Controller/MediaBrowser.Controller.csproj index bcf4de2a2..600674114 100644 --- a/MediaBrowser.Controller/MediaBrowser.Controller.csproj +++ b/MediaBrowser.Controller/MediaBrowser.Controller.csproj @@ -248,6 +248,7 @@ + diff --git a/MediaBrowser.Controller/Net/PaymentRequiredException.cs b/MediaBrowser.Controller/Net/PaymentRequiredException.cs new file mode 100644 index 000000000..e09fe092e --- /dev/null +++ b/MediaBrowser.Controller/Net/PaymentRequiredException.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace MediaBrowser.Controller.Net +{ + /// + /// Corresponds to a 402 response code + /// + public class PaymentRequiredException : Exception + { + } +} diff --git a/MediaBrowser.Controller/Providers/MetadataStatus.cs b/MediaBrowser.Controller/Providers/MetadataStatus.cs index 9b946aee2..654d72e2a 100644 --- a/MediaBrowser.Controller/Providers/MetadataStatus.cs +++ b/MediaBrowser.Controller/Providers/MetadataStatus.cs @@ -40,22 +40,8 @@ namespace MediaBrowser.Controller.Providers /// The date last images refresh. public DateTime? DateLastImagesRefresh { get; set; } - /// - /// Gets or sets the last result error message. - /// - /// The last result error message. - public string LastErrorMessage { get; set; } - public DateTime? ItemDateModified { get; set; } - public void AddStatus(string errorMessage) - { - if (string.IsNullOrEmpty(LastErrorMessage)) - { - LastErrorMessage = errorMessage; - } - } - public bool IsDirty { get; private set; } public void SetDateLastMetadataRefresh(DateTime? date) diff --git a/MediaBrowser.Providers/Manager/MetadataService.cs b/MediaBrowser.Providers/Manager/MetadataService.cs index 6860aeff3..a7f58e32b 100644 --- a/MediaBrowser.Providers/Manager/MetadataService.cs +++ b/MediaBrowser.Providers/Manager/MetadataService.cs @@ -99,7 +99,6 @@ namespace MediaBrowser.Providers.Manager var updateType = ItemUpdateType.None; var refreshResult = GetLastResult(item); - refreshResult.LastErrorMessage = string.Empty; var itemImageProvider = new ItemImageProvider(Logger, ProviderManager, ServerConfigurationManager, FileSystem); var localImagesFailed = false; @@ -119,7 +118,6 @@ namespace MediaBrowser.Providers.Manager { localImagesFailed = true; Logger.ErrorException("Error validating images for {0}", ex, item.Path ?? item.Name ?? "Unknown name"); - refreshResult.AddStatus(ex.Message); } var metadataResult = new MetadataResult @@ -150,7 +148,6 @@ namespace MediaBrowser.Providers.Manager var result = await RefreshWithProviders(metadataResult, id, refreshOptions, providers, itemImageProvider, cancellationToken).ConfigureAwait(false); updateType = updateType | result.UpdateType; - refreshResult.AddStatus(result.ErrorMessage); if (result.Failures == 0) { refreshResult.SetDateLastMetadataRefresh(DateTime.UtcNow); @@ -172,7 +169,6 @@ namespace MediaBrowser.Providers.Manager var result = await itemImageProvider.RefreshImages(itemOfType, providers, refreshOptions, config, cancellationToken).ConfigureAwait(false); updateType = updateType | result.UpdateType; - refreshResult.AddStatus(result.ErrorMessage); if (result.Failures == 0) { refreshResult.SetDateLastImagesRefresh(DateTime.UtcNow); @@ -231,22 +227,32 @@ namespace MediaBrowser.Providers.Manager private DateTime GetLastRefreshDate(IHasMetadata item) { - if (item.DateLastRefreshed != default(DateTime)) + if (EnableDateLastRefreshed(item)) { return item.DateLastRefreshed; } + return item.DateLastSaved; + } + + private bool EnableDateLastRefreshed(IHasMetadata item) + { if (ServerConfigurationManager.Configuration.EnableDateLastRefresh) { - return item.DateLastRefreshed; + return true; + } + + if (item.DateLastRefreshed != default(DateTime)) + { + return true; } if (item is BoxSet || (item is IItemByName && !(item is MusicArtist))) { - return item.DateLastRefreshed; + return true; } - return item.DateLastSaved; + return false; } protected async Task SaveItem(MetadataResult result, ItemUpdateType reason, CancellationToken cancellationToken) diff --git a/MediaBrowser.Server.Implementations/Dto/DtoService.cs b/MediaBrowser.Server.Implementations/Dto/DtoService.cs index 20e1eb543..fcda802f4 100644 --- a/MediaBrowser.Server.Implementations/Dto/DtoService.cs +++ b/MediaBrowser.Server.Implementations/Dto/DtoService.cs @@ -472,7 +472,7 @@ namespace MediaBrowser.Server.Implementations.Dto // These are just far too slow. // TODO: Disable for CollectionFolder - if (!(folder is UserRootFolder) && !(folder is UserView)) + if (!(folder is UserRootFolder) && !(folder is UserView) && !(folder is IChannelItem)) { SetSpecialCounts(folder, user, dto, fields, syncProgress); } @@ -1042,7 +1042,11 @@ namespace MediaBrowser.Server.Implementations.Dto dto.IsFolder = item.IsFolder; dto.MediaType = item.MediaType; dto.LocationType = item.LocationType; - dto.IsHD = item.IsHD; + if (item.IsHD.HasValue && item.IsHD.Value) + { + dto.IsHD = item.IsHD; + } + dto.Audio = item.Audio; dto.PreferredMetadataCountryCode = item.PreferredMetadataCountryCode; dto.PreferredMetadataLanguage = item.PreferredMetadataLanguage; diff --git a/MediaBrowser.Server.Implementations/HttpServer/HttpListenerHost.cs b/MediaBrowser.Server.Implementations/HttpServer/HttpListenerHost.cs index e8bb40ba1..6abfa0674 100644 --- a/MediaBrowser.Server.Implementations/HttpServer/HttpListenerHost.cs +++ b/MediaBrowser.Server.Implementations/HttpServer/HttpListenerHost.cs @@ -92,7 +92,9 @@ namespace MediaBrowser.Server.Implementations.HttpServer {typeof (FileNotFoundException), 404}, {typeof (DirectoryNotFoundException), 404}, {typeof (SecurityException), 401}, - {typeof (UnauthorizedAccessException), 500} + {typeof (PaymentRequiredException), 402}, + {typeof (UnauthorizedAccessException), 500}, + {typeof (ApplicationException), 500} }; HostConfig.Instance.DebugMode = true; diff --git a/MediaBrowser.Server.Implementations/HttpServer/LoggerUtils.cs b/MediaBrowser.Server.Implementations/HttpServer/LoggerUtils.cs index 02ce38ef1..fae702023 100644 --- a/MediaBrowser.Server.Implementations/HttpServer/LoggerUtils.cs +++ b/MediaBrowser.Server.Implementations/HttpServer/LoggerUtils.cs @@ -16,7 +16,10 @@ namespace MediaBrowser.Server.Implementations.HttpServer /// The duration. public static void LogResponse(ILogger logger, int statusCode, string url, string endPoint, TimeSpan duration) { - logger.Info("HTTP Response {0} to {1}. Time: {2}ms. {3}", statusCode, endPoint, Convert.ToInt32(duration.TotalMilliseconds).ToString(CultureInfo.InvariantCulture), url); + var durationMs = duration.TotalMilliseconds; + var logSuffix = durationMs >= 1000 ? "ms (slow)" : "ms"; + + logger.Info("HTTP Response {0} to {1}. Time: {2}{3}. {4}", statusCode, endPoint, Convert.ToInt32(durationMs).ToString(CultureInfo.InvariantCulture), logSuffix, url); } } } diff --git a/MediaBrowser.Server.Implementations/HttpServer/SocketSharp/WebSocketSharpListener.cs b/MediaBrowser.Server.Implementations/HttpServer/SocketSharp/WebSocketSharpListener.cs index f8178c115..9f80c8ac9 100644 --- a/MediaBrowser.Server.Implementations/HttpServer/SocketSharp/WebSocketSharpListener.cs +++ b/MediaBrowser.Server.Implementations/HttpServer/SocketSharp/WebSocketSharpListener.cs @@ -183,15 +183,7 @@ namespace MediaBrowser.Server.Implementations.HttpServer.SocketSharp /// The request. private static void LogRequest(ILogger logger, HttpListenerRequest request) { - var log = new StringBuilder(); - - var headers = string.Join(",", request.Headers.AllKeys.Where(i => !string.Equals(i, "cookie", StringComparison.OrdinalIgnoreCase) && !string.Equals(i, "Referer", StringComparison.OrdinalIgnoreCase)).Select(k => k + "=" + request.Headers[k])); - - log.AppendLine("Ip: " + request.RemoteEndPoint + ". Headers: " + headers); - - var type = request.IsWebSocketRequest ? "Web Socket" : "HTTP " + request.HttpMethod; - - logger.LogMultiline(type + " " + request.Url, LogSeverity.Info, log); + logger.Info("{0} {1}. UserAgent: {2}", (request.IsWebSocketRequest ? "WS" : "HTTP " + request.HttpMethod), request.Url, request.UserAgent ?? string.Empty); } private void HandleError(Exception ex, HttpListenerContext context) diff --git a/MediaBrowser.Server.Implementations/Library/LibraryManager.cs b/MediaBrowser.Server.Implementations/Library/LibraryManager.cs index 92acd08d1..daa3d8ad4 100644 --- a/MediaBrowser.Server.Implementations/Library/LibraryManager.cs +++ b/MediaBrowser.Server.Implementations/Library/LibraryManager.cs @@ -1280,6 +1280,11 @@ namespace MediaBrowser.Server.Implementations.Library return ItemRepository.GetItemIdsList(query); } + public IEnumerable GetItems(InternalItemsQuery query, User user) + { + return GetItemIds(query).Select(GetItemById).Where(i => i.IsVisibleStandalone(user)); + } + /// /// Gets the intros. /// @@ -1811,14 +1816,9 @@ namespace MediaBrowser.Server.Implementations.Library isNew = true; } - if (!item.UserId.HasValue) + if (!item.UserId.HasValue || !string.Equals(viewType, item.ViewType, StringComparison.OrdinalIgnoreCase)) { item.UserId = user.Id; - await item.UpdateToRepository(ItemUpdateType.MetadataEdit, cancellationToken).ConfigureAwait(false); - } - - if (!string.Equals(viewType, item.ViewType, StringComparison.OrdinalIgnoreCase)) - { item.ViewType = viewType; await item.UpdateToRepository(ItemUpdateType.MetadataEdit, cancellationToken).ConfigureAwait(false); } diff --git a/MediaBrowser.Server.Implementations/Library/SearchEngine.cs b/MediaBrowser.Server.Implementations/Library/SearchEngine.cs index d6aff1192..108a891e0 100644 --- a/MediaBrowser.Server.Implementations/Library/SearchEngine.cs +++ b/MediaBrowser.Server.Implementations/Library/SearchEngine.cs @@ -157,12 +157,11 @@ namespace MediaBrowser.Server.Implementations.Library AddIfMissing(excludeItemTypes, typeof(CollectionFolder).Name); - var mediaItems = _libraryManager.GetItems(new InternalItemsQuery + var mediaItems = _libraryManager.GetItems(new InternalItemsQuery(user) { NameContains = searchTerm, ExcludeItemTypes = excludeItemTypes.ToArray(), IncludeItemTypes = includeItemTypes.ToArray(), - MaxParentalRating = user == null ? null : user.Policy.MaxParentalRating, Limit = (query.Limit.HasValue ? (int?)(query.Limit.Value * 3) : null), }).Items; diff --git a/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs b/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs index edfca0d6c..d7c9edae3 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs @@ -607,6 +607,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv var item = _libraryManager.GetItemById(id) as LiveTvProgram; var isNew = false; + var forceUpdate = false; if (item == null) { @@ -621,7 +622,11 @@ namespace MediaBrowser.Server.Implementations.LiveTv }; } - item.ChannelType = channelType; + //item.ChannelType = channelType; + if (!string.Equals(item.ServiceName, serviceName, StringComparison.Ordinal)) + { + forceUpdate = true; + } item.ServiceName = serviceName; item.Audio = info.Audio; @@ -666,7 +671,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv { await _libraryManager.CreateItem(item, cancellationToken).ConfigureAwait(false); } - else if (string.IsNullOrWhiteSpace(info.Etag)) + else if (forceUpdate || string.IsNullOrWhiteSpace(info.Etag)) { await _libraryManager.UpdateItem(item, ItemUpdateType.MetadataImport, cancellationToken).ConfigureAwait(false); } @@ -814,7 +819,9 @@ namespace MediaBrowser.Server.Implementations.LiveTv public async Task> GetPrograms(ProgramQuery query, DtoOptions options, CancellationToken cancellationToken) { - var internalQuery = new InternalItemsQuery + var user = string.IsNullOrEmpty(query.UserId) ? null : _userManager.GetUserById(query.UserId); + + var internalQuery = new InternalItemsQuery(user) { IncludeItemTypes = new[] { typeof(LiveTvProgram).Name }, MinEndDate = query.MinEndDate, @@ -832,11 +839,8 @@ namespace MediaBrowser.Server.Implementations.LiveTv SortOrder = query.SortOrder ?? SortOrder.Ascending }; - var user = string.IsNullOrEmpty(query.UserId) ? null : _userManager.GetUserById(query.UserId); if (user != null) { - internalQuery.MaxParentalRating = user.Policy.MaxParentalRating; - if (user.Policy.BlockUnratedItems.Contains(UnratedItem.LiveTvProgram)) { internalQuery.HasParentalRating = true; @@ -874,7 +878,9 @@ namespace MediaBrowser.Server.Implementations.LiveTv public async Task> GetRecommendedProgramsInternal(RecommendedProgramQuery query, CancellationToken cancellationToken) { - var internalQuery = new InternalItemsQuery + var user = _userManager.GetUserById(query.UserId); + + var internalQuery = new InternalItemsQuery(user) { IncludeItemTypes = new[] { typeof(LiveTvProgram).Name }, IsAiring = query.IsAiring, @@ -895,11 +901,8 @@ namespace MediaBrowser.Server.Implementations.LiveTv } } - var user = _userManager.GetUserById(query.UserId); if (user != null) { - internalQuery.MaxParentalRating = user.Policy.MaxParentalRating; - if (user.Policy.BlockUnratedItems.Contains(UnratedItem.LiveTvProgram)) { internalQuery.HasParentalRating = true; @@ -1037,6 +1040,11 @@ namespace MediaBrowser.Server.Implementations.LiveTv { var internalProgram = GetInternalProgram(program.Id); + if (string.IsNullOrWhiteSpace(internalProgram.ServiceName)) + { + continue; + } + List timerList; if (!timers.TryGetValue(internalProgram.ServiceName, out timerList)) { @@ -1052,7 +1060,6 @@ namespace MediaBrowser.Server.Implementations.LiveTv } } - var timer = timerList.FirstOrDefault(i => string.Equals(i.ProgramId, internalProgram.ExternalId, StringComparison.OrdinalIgnoreCase)); if (timer != null) @@ -1429,18 +1436,10 @@ namespace MediaBrowser.Server.Implementations.LiveTv public void AddInfoToProgramDto(BaseItem item, BaseItemDto dto, bool addChannelInfo, User user = null) { var program = (LiveTvProgram)item; - var service = GetService(program); - - dto.Id = _tvDtoService.GetInternalProgramId(service.Name, program.ExternalId).ToString("N"); dto.StartDate = program.StartDate; dto.EpisodeTitle = program.EpisodeTitle; - dto.Audio = program.Audio; - if (program.IsHD.HasValue && program.IsHD.Value) - { - dto.IsHD = program.IsHD; - } if (program.IsRepeat) { dto.IsRepeat = program.IsRepeat; @@ -1499,7 +1498,6 @@ namespace MediaBrowser.Server.Implementations.LiveTv var info = recording; - dto.Id = item.Id.ToString("N"); dto.SeriesTimerId = string.IsNullOrEmpty(info.SeriesTimerId) ? null : _tvDtoService.GetInternalSeriesTimerId(service.Name, info.SeriesTimerId).ToString("N"); @@ -1508,8 +1506,6 @@ namespace MediaBrowser.Server.Implementations.LiveTv dto.RecordingStatus = info.Status; dto.IsRepeat = info.IsRepeat; dto.EpisodeTitle = info.EpisodeTitle; - dto.Audio = info.Audio; - dto.IsHD = info.IsHD; dto.IsMovie = info.IsMovie; dto.IsSeries = info.IsSeries; dto.IsSports = info.IsSports; diff --git a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs index 256b057d9..730632bb3 100644 --- a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs +++ b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs @@ -19,6 +19,7 @@ using System.Runtime.Serialization; using System.Threading; using System.Threading.Tasks; using MediaBrowser.Controller.Channels; +using MediaBrowser.Model.LiveTv; namespace MediaBrowser.Server.Implementations.Persistence { @@ -76,7 +77,7 @@ namespace MediaBrowser.Server.Implementations.Persistence private IDbCommand _deleteStreamsCommand; private IDbCommand _saveStreamCommand; - private const int LatestSchemaVersion = 16; + private const int LatestSchemaVersion = 17; /// /// Initializes a new instance of the class. @@ -202,7 +203,9 @@ namespace MediaBrowser.Server.Implementations.Persistence _connection.AddColumn(_logger, "TypedBaseItems", "IsInMixedFolder", "BIT"); _connection.AddColumn(_logger, "TypedBaseItems", "LockedFields", "Text"); _connection.AddColumn(_logger, "TypedBaseItems", "Studios", "Text"); - + _connection.AddColumn(_logger, "TypedBaseItems", "Audio", "Text"); + _connection.AddColumn(_logger, "TypedBaseItems", "ExternalServiceId", "Text"); + PrepareStatements(); new MediaStreamColumns(_connection, _logger).AddColumns(); @@ -311,7 +314,10 @@ namespace MediaBrowser.Server.Implementations.Persistence "DateCreated", "DateModified", "guid", - "Genres" + "Genres", + "ParentId", + "Audio", + "ExternalServiceId" }; private readonly string[] _mediaStreamSaveColumns = @@ -403,7 +409,9 @@ namespace MediaBrowser.Server.Implementations.Persistence "DateLastSaved", "IsInMixedFolder", "LockedFields", - "Studios" + "Studios", + "Audio", + "ExternalServiceId" }; _saveItemCommand = _connection.CreateCommand(); _saveItemCommand.CommandText = "replace into TypedBaseItems (" + string.Join(",", saveColumns.ToArray()) + ") values ("; @@ -637,6 +645,25 @@ namespace MediaBrowser.Server.Implementations.Persistence _saveItemCommand.GetParameter(index++).Value = string.Join("|", item.LockedFields.Select(i => i.ToString()).ToArray()); _saveItemCommand.GetParameter(index++).Value = string.Join("|", item.Studios.ToArray()); + if (item.Audio.HasValue) + { + _saveItemCommand.GetParameter(index++).Value = item.Audio.Value.ToString(); + } + else + { + _saveItemCommand.GetParameter(index++).Value = null; + } + + var tvItem = item as ILiveTvItem; + if (tvItem != null) + { + _saveItemCommand.GetParameter(index++).Value = tvItem.ServiceName; + } + else + { + _saveItemCommand.GetParameter(index++).Value = null; + } + _saveItemCommand.Transaction = transaction; _saveItemCommand.ExecuteNonQuery(); @@ -940,6 +967,25 @@ namespace MediaBrowser.Server.Implementations.Persistence item.Genres = reader.GetString(40).Split('|').Where(i => !string.IsNullOrWhiteSpace(i)).ToList(); } + if (!reader.IsDBNull(41)) + { + item.ParentId = reader.GetGuid(41); + } + + if (!reader.IsDBNull(42)) + { + item.Audio = (ProgramAudio)Enum.Parse(typeof(ProgramAudio), reader.GetString(42), true); + } + + if (!reader.IsDBNull(43)) + { + var tvItem = item as ILiveTvItem; + if (tvItem != null) + { + item.ForcedSortName = reader.GetString(43); + } + } + return item; } @@ -1668,6 +1714,12 @@ namespace MediaBrowser.Server.Implementations.Persistence cmd.Parameters.Add(cmd, "@MinStartDate", DbType.Date).Value = query.MinStartDate.Value; } + if (query.MinPremiereDate.HasValue) + { + whereClauses.Add("PremiereDate>=@MinPremiereDate"); + cmd.Parameters.Add(cmd, "@MinPremiereDate", DbType.Date).Value = query.MinPremiereDate.Value; + } + if (query.MaxStartDate.HasValue) { whereClauses.Add("StartDate<=@MaxStartDate"); diff --git a/MediaBrowser.Server.Implementations/Persistence/SqliteProviderInfoRepository.cs b/MediaBrowser.Server.Implementations/Persistence/SqliteProviderInfoRepository.cs index e7853b458..a63b93dc7 100644 --- a/MediaBrowser.Server.Implementations/Persistence/SqliteProviderInfoRepository.cs +++ b/MediaBrowser.Server.Implementations/Persistence/SqliteProviderInfoRepository.cs @@ -47,7 +47,7 @@ namespace MediaBrowser.Server.Implementations.Persistence string[] queries = { - "create table if not exists MetadataStatus (ItemId GUID PRIMARY KEY, ItemName TEXT, ItemType TEXT, SeriesName TEXT, DateLastMetadataRefresh datetime, DateLastImagesRefresh datetime, LastErrorMessage TEXT, ItemDateModified DateTimeNull)", + "create table if not exists MetadataStatus (ItemId GUID PRIMARY KEY, ItemName TEXT, ItemType TEXT, SeriesName TEXT, DateLastMetadataRefresh datetime, DateLastImagesRefresh datetime, ItemDateModified DateTimeNull)", "create index if not exists idx_MetadataStatus on MetadataStatus(ItemId)", //pragmas @@ -71,7 +71,6 @@ namespace MediaBrowser.Server.Implementations.Persistence "SeriesName", "DateLastMetadataRefresh", "DateLastImagesRefresh", - "LastErrorMessage", "ItemDateModified" }; @@ -185,12 +184,7 @@ namespace MediaBrowser.Server.Implementations.Persistence if (!reader.IsDBNull(6)) { - result.LastErrorMessage = reader.GetString(6); - } - - if (!reader.IsDBNull(7)) - { - result.ItemDateModified = reader.GetDateTime(7).ToUniversalTime(); + result.ItemDateModified = reader.GetDateTime(6).ToUniversalTime(); } return result; @@ -219,8 +213,7 @@ namespace MediaBrowser.Server.Implementations.Persistence _saveStatusCommand.GetParameter(3).Value = status.SeriesName; _saveStatusCommand.GetParameter(4).Value = status.DateLastMetadataRefresh; _saveStatusCommand.GetParameter(5).Value = status.DateLastImagesRefresh; - _saveStatusCommand.GetParameter(6).Value = status.LastErrorMessage; - _saveStatusCommand.GetParameter(7).Value = status.ItemDateModified; + _saveStatusCommand.GetParameter(6).Value = status.ItemDateModified; _saveStatusCommand.Transaction = transaction; diff --git a/MediaBrowser.Server.Implementations/TV/TVSeriesManager.cs b/MediaBrowser.Server.Implementations/TV/TVSeriesManager.cs index f34b43e43..93ebd0a1c 100644 --- a/MediaBrowser.Server.Implementations/TV/TVSeriesManager.cs +++ b/MediaBrowser.Server.Implementations/TV/TVSeriesManager.cs @@ -36,8 +36,22 @@ namespace MediaBrowser.Server.Implementations.TV ? new string[] { } : new[] { request.ParentId }; - var items = GetAllLibraryItems(user, parentIds, i => i is Series) - .Cast(); + IEnumerable items; + + if (parentIds.Length == 0) + { + items = _libraryManager.GetItems(new InternalItemsQuery(user) + { + IncludeItemTypes = new[] { typeof(Series).Name }, + SortOrder = SortOrder.Ascending + + }, user).Cast(); + } + else + { + items = GetAllLibraryItems(user, parentIds, i => i is Series) + .Cast(); + } // Avoid implicitly captured closure var episodes = GetNextUpEpisodes(request, user, items); @@ -64,7 +78,7 @@ namespace MediaBrowser.Server.Implementations.TV return GetResult(episodes, null, request); } - private IEnumerable GetAllLibraryItems(User user, string[] parentIds, Func filter) + private IEnumerable GetAllLibraryItems(User user, string[] parentIds, Func filter) { if (parentIds.Length > 0) { -- 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/LiveTv/LiveTvProgram.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 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/LiveTv/LiveTvProgram.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