From c7b95a251317fdb01d160cc3dcaf5d23779437d4 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Wed, 15 Apr 2015 23:23:13 -0400 Subject: [PATCH] 3.0.5582.2 --- MediaBrowser.Api/StartupWizardService.cs | 1 - .../Persistence/IItemRepository.cs | 9 +- .../Encoder/MediaEncoder.cs | 33 +++--- .../Configuration/ServerConfiguration.cs | 5 - .../MediaInfo/VideoImageProvider.cs | 6 +- .../Library/UserViewManager.cs | 6 +- .../LiveTv/LiveTvManager.cs | 106 ++++++++++-------- .../Localization/Server/server.json | 2 +- .../Persistence/SqliteItemRepository.cs | 34 +++++- SharedVersion.cs | 4 +- 10 files changed, 128 insertions(+), 78 deletions(-) diff --git a/MediaBrowser.Api/StartupWizardService.cs b/MediaBrowser.Api/StartupWizardService.cs index edcce10d2a..4655f2c6f9 100644 --- a/MediaBrowser.Api/StartupWizardService.cs +++ b/MediaBrowser.Api/StartupWizardService.cs @@ -66,7 +66,6 @@ namespace MediaBrowser.Api _config.Configuration.EnableStandaloneMetadata = true; _config.Configuration.EnableLibraryMetadataSubFolder = true; _config.Configuration.EnableUserSpecificUserViews = true; - _config.Configuration.EnableUserSpecificUserViews2 = true; _config.SaveConfiguration(); } diff --git a/MediaBrowser.Controller/Persistence/IItemRepository.cs b/MediaBrowser.Controller/Persistence/IItemRepository.cs index f306518df4..aa5376ec3f 100644 --- a/MediaBrowser.Controller/Persistence/IItemRepository.cs +++ b/MediaBrowser.Controller/Persistence/IItemRepository.cs @@ -107,7 +107,7 @@ namespace MediaBrowser.Controller.Persistence /// /// The type. /// IEnumerable{Guid}. - IEnumerable GetItemsOfType(Type type); + IEnumerable GetItemIdsOfType(Type type); /// /// Saves the children. @@ -133,6 +133,13 @@ namespace MediaBrowser.Controller.Persistence /// The cancellation token. /// Task. Task SaveMediaStreams(Guid id, IEnumerable streams, CancellationToken cancellationToken); + + /// + /// Gets the type of the items of. + /// + /// The type. + /// IEnumerable<BaseItem>. + IEnumerable GetItemsOfType(Type type); } } diff --git a/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs b/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs index 956b3723d9..d076a5b6ba 100644 --- a/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs +++ b/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs @@ -489,27 +489,34 @@ namespace MediaBrowser.MediaEncoding.Encoder await resourcePool.WaitAsync(cancellationToken).ConfigureAwait(false); var processWrapper = new ProcessWrapper(process, this); - - StartProcess(processWrapper); + bool ranToCompletion; var memoryStream = new MemoryStream(); + try + { + StartProcess(processWrapper); + #pragma warning disable 4014 - // Important - don't await the log task or we won't be able to kill ffmpeg when the user stops playback - process.StandardOutput.BaseStream.CopyToAsync(memoryStream); + // Important - don't await the log task or we won't be able to kill ffmpeg when the user stops playback + process.StandardOutput.BaseStream.CopyToAsync(memoryStream); #pragma warning restore 4014 - // MUST read both stdout and stderr asynchronously or a deadlock may occurr - process.BeginErrorReadLine(); + // MUST read both stdout and stderr asynchronously or a deadlock may occurr + process.BeginErrorReadLine(); - var ranToCompletion = process.WaitForExit(10000); + ranToCompletion = process.WaitForExit(10000); + + if (!ranToCompletion) + { + StopProcess(processWrapper, 1000, false); + } - if (!ranToCompletion) - { - StopProcess(processWrapper, 1000, false); } - - resourcePool.Release(); + finally + { + resourcePool.Release(); + } var exitCode = ranToCompletion ? processWrapper.ExitCode ?? 0 : -1; @@ -614,7 +621,7 @@ namespace MediaBrowser.MediaEncoding.Encoder ranToCompletion = true; break; } - + cancellationToken.ThrowIfCancellationRequested(); var jpegCount = Directory.GetFiles(targetDirectory) diff --git a/MediaBrowser.Model/Configuration/ServerConfiguration.cs b/MediaBrowser.Model/Configuration/ServerConfiguration.cs index 0808a79ab9..72f9174388 100644 --- a/MediaBrowser.Model/Configuration/ServerConfiguration.cs +++ b/MediaBrowser.Model/Configuration/ServerConfiguration.cs @@ -49,11 +49,6 @@ namespace MediaBrowser.Model.Configuration /// /// true if [enable user specific user views]; otherwise, false. public bool EnableUserSpecificUserViews { get; set; } - /// - /// Gets or sets a value indicating whether [enable user specific user views2]. - /// - /// true if [enable user specific user views2]; otherwise, false. - public bool EnableUserSpecificUserViews2 { get; set; } /// /// Gets or sets the value pointing to the file system where the ssl certiifcate is located.. diff --git a/MediaBrowser.Providers/MediaInfo/VideoImageProvider.cs b/MediaBrowser.Providers/MediaInfo/VideoImageProvider.cs index 7c32432251..bcea66662e 100644 --- a/MediaBrowser.Providers/MediaInfo/VideoImageProvider.cs +++ b/MediaBrowser.Providers/MediaInfo/VideoImageProvider.cs @@ -6,6 +6,7 @@ using MediaBrowser.Controller.Providers; using MediaBrowser.Model.Drawing; using MediaBrowser.Model.Entities; using MediaBrowser.Model.IO; +using MediaBrowser.Model.Logging; using MediaBrowser.Model.MediaInfo; using System; using System.Collections.Generic; @@ -20,13 +21,15 @@ namespace MediaBrowser.Providers.MediaInfo private readonly IMediaEncoder _mediaEncoder; private readonly IServerConfigurationManager _config; private readonly ILibraryManager _libraryManager; + private readonly ILogger _logger; - public VideoImageProvider(IIsoManager isoManager, IMediaEncoder mediaEncoder, IServerConfigurationManager config, ILibraryManager libraryManager) + public VideoImageProvider(IIsoManager isoManager, IMediaEncoder mediaEncoder, IServerConfigurationManager config, ILibraryManager libraryManager, ILogger logger) { _isoManager = isoManager; _mediaEncoder = mediaEncoder; _config = config; _libraryManager = libraryManager; + _logger = logger; } /// @@ -74,6 +77,7 @@ namespace MediaBrowser.Providers.MediaInfo // Can't extract if we didn't find a video stream in the file if (!video.DefaultVideoStreamIndex.HasValue) { + _logger.Debug("Skipping image extraction due to missing DefaultVideoStreamIndex for {0}.", video.Path ?? string.Empty); return Task.FromResult(new DynamicImageResponse { HasImage = false }); } diff --git a/MediaBrowser.Server.Implementations/Library/UserViewManager.cs b/MediaBrowser.Server.Implementations/Library/UserViewManager.cs index e5a8a3fa03..d5d0af74c1 100644 --- a/MediaBrowser.Server.Implementations/Library/UserViewManager.cs +++ b/MediaBrowser.Server.Implementations/Library/UserViewManager.cs @@ -209,11 +209,6 @@ namespace MediaBrowser.Server.Implementations.Library var enableRichView = !user.Configuration.PlainFolderViews.Contains(parentId.ToString("N"), StringComparer.OrdinalIgnoreCase); - if (_config.Configuration.EnableUserSpecificUserViews2) - { - return await GetUserView(parentId, name, viewType, enableRichView, string.Empty, user, cancellationToken).ConfigureAwait(false); - } - if (_config.Configuration.EnableUserSpecificUserViews) { viewType = enableRichView ? viewType : null; @@ -227,6 +222,7 @@ namespace MediaBrowser.Server.Implementations.Library return view; } + viewType = enableRichView ? viewType : CollectionType.Folders; return await _libraryManager.GetNamedView(user, name, viewType, sortName, cancellationToken).ConfigureAwait(false); } else diff --git a/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs b/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs index d704277c14..5791da1ea2 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs @@ -54,11 +54,9 @@ namespace MediaBrowser.Server.Implementations.LiveTv new ConcurrentDictionary(); private List _channelIdList = new List(); - private Dictionary _programs = new Dictionary(); + private Dictionary _programs; private readonly ConcurrentDictionary _refreshedPrograms = new ConcurrentDictionary(); - private readonly SemaphoreSlim _refreshSemaphore = new SemaphoreSlim(1, 1); - public LiveTvManager(IApplicationHost appHost, IServerConfigurationManager config, ILogger logger, IItemRepository itemRepo, IImageProcessor imageProcessor, IUserDataManager userDataManager, IDtoService dtoService, IUserManager userManager, ILibraryManager libraryManager, ITaskManager taskManager, ILocalizationManager localization, IJsonSerializer jsonSerializer, IProviderManager providerManager) { _config = config; @@ -109,6 +107,37 @@ namespace MediaBrowser.Server.Implementations.LiveTv _taskManager.CancelIfRunningAndQueue(); } + private readonly object _programsDataLock = new object(); + private Dictionary GetProgramsDictionary() + { + if (_programs == null) + { + lock (_programsDataLock) + { + if (_programs == null) + { + var dict = new Dictionary(); + + foreach (var item in _itemRepo.GetItemsOfType(typeof (LiveTvProgram)) + .Cast() + .ToList()) + { + dict[item.Id] = item; + } + + _programs = dict; + } + } + } + + return _programs; + } + + private IEnumerable GetPrograms() + { + return GetProgramsDictionary().Values; + } + public async Task> GetInternalChannels(LiveTvChannelQuery query, CancellationToken cancellationToken) { var user = string.IsNullOrEmpty(query.UserId) ? null : _userManager.GetUserById(query.UserId); @@ -260,7 +289,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv LiveTvProgram obj = null; - _programs.TryGetValue(guid, out obj); + GetProgramsDictionary().TryGetValue(guid, out obj); if (obj != null) { @@ -597,7 +626,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv item.ProductionYear = info.ProductionYear; item.PremiereDate = item.PremiereDate ?? info.OriginalAirDate; - + await item.UpdateToRepository(ItemUpdateType.MetadataImport, cancellationToken).ConfigureAwait(false); return item; @@ -691,7 +720,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv public async Task> GetPrograms(ProgramQuery query, CancellationToken cancellationToken) { - IEnumerable programs = _programs.Values; + IEnumerable programs = GetPrograms(); if (query.MinEndDate.HasValue) { @@ -806,7 +835,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv public async Task> GetRecommendedProgramsInternal(RecommendedProgramQuery query, CancellationToken cancellationToken) { - IEnumerable programs = _programs.Values; + IEnumerable programs = GetPrograms(); var user = _userManager.GetUserById(query.UserId); @@ -995,24 +1024,15 @@ namespace MediaBrowser.Server.Implementations.LiveTv internal async Task RefreshChannels(IProgress progress, CancellationToken cancellationToken) { - await _refreshSemaphore.WaitAsync(cancellationToken).ConfigureAwait(false); + var innerProgress = new ActionableProgress(); + innerProgress.RegisterAction(p => progress.Report(p * .9)); + await RefreshChannelsInternal(innerProgress, cancellationToken).ConfigureAwait(false); - try - { - var innerProgress = new ActionableProgress(); - innerProgress.RegisterAction(p => progress.Report(p * .9)); - await RefreshChannelsInternal(innerProgress, cancellationToken).ConfigureAwait(false); + innerProgress = new ActionableProgress(); + innerProgress.RegisterAction(p => progress.Report(90 + (p * .1))); + await CleanDatabaseInternal(progress, cancellationToken).ConfigureAwait(false); - innerProgress = new ActionableProgress(); - innerProgress.RegisterAction(p => progress.Report(90 + (p * .1))); - await CleanDatabaseInternal(progress, cancellationToken).ConfigureAwait(false); - - RefreshIfNeeded(_programs.Values.Where(i => (i.StartDate - DateTime.UtcNow).TotalDays <= 1).ToList()); - } - finally - { - _refreshSemaphore.Release(); - } + RefreshIfNeeded(GetPrograms().Where(i => (i.StartDate - DateTime.UtcNow).TotalDays <= 1).ToList()); } private async Task RefreshChannelsInternal(IProgress progress, CancellationToken cancellationToken) @@ -1136,7 +1156,11 @@ namespace MediaBrowser.Server.Implementations.LiveTv progress.Report(80 * percent + 10); } - _programs = programs.ToDictionary(i => i.Id); + lock (_programsDataLock) + { + _programs = programs.ToDictionary(i => i.Id); + } + _refreshedPrograms.Clear(); progress.Report(90); @@ -1147,28 +1171,14 @@ namespace MediaBrowser.Server.Implementations.LiveTv progress.Report(100); } - public async Task CleanDatabase(IProgress progress, CancellationToken cancellationToken) - { - await _refreshSemaphore.WaitAsync(cancellationToken).ConfigureAwait(false); - - try - { - await DeleteOldPrograms(_programs.Keys.ToList(), progress, cancellationToken).ConfigureAwait(false); - } - finally - { - _refreshSemaphore.Release(); - } - } - private Task CleanDatabaseInternal(IProgress progress, CancellationToken cancellationToken) { - return DeleteOldPrograms(_programs.Keys.ToList(), progress, cancellationToken); + return DeleteOldPrograms(GetProgramsDictionary().Keys.ToList(), progress, cancellationToken); } private async Task DeleteOldPrograms(List currentIdList, IProgress progress, CancellationToken cancellationToken) { - var list = _itemRepo.GetItemsOfType(typeof(LiveTvProgram)).ToList(); + var list = _itemRepo.GetItemIdsOfType(typeof(LiveTvProgram)).ToList(); var numComplete = 0; @@ -1549,7 +1559,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv { var now = DateTime.UtcNow; - var program = _programs.Values + var program = GetPrograms() .Where(i => string.Equals(externalChannelId, i.ExternalChannelId, StringComparison.OrdinalIgnoreCase)) .OrderBy(i => i.StartDate) .SkipWhile(i => now >= (i.EndDate ?? DateTime.MinValue)) @@ -1742,7 +1752,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv { var dtoOptions = new DtoOptions(); dtoOptions.Fields.Remove(ItemFields.SyncInfo); - + var recordingResult = await GetRecordings(new RecordingQuery { UserId = query.UserId @@ -1855,13 +1865,15 @@ namespace MediaBrowser.Server.Implementations.LiveTv public GuideInfo GetGuideInfo() { - var programs = _programs.ToList(); + var programs = GetPrograms().OrderBy(i => i.StartDate).ToList(); - var startDate = _programs.Count == 0 ? DateTime.MinValue : - programs.Select(i => i.Value.StartDate).Min(); + var startDate = programs.Count == 0 ? + DateTime.MinValue : + programs[0].StartDate; - var endDate = programs.Count == 0 ? DateTime.MinValue : - programs.Select(i => i.Value.StartDate).Max(); + var endDate = programs.Count == 0 ? + DateTime.MinValue : + programs[programs.Count - 1].StartDate; return new GuideInfo { diff --git a/MediaBrowser.Server.Implementations/Localization/Server/server.json b/MediaBrowser.Server.Implementations/Localization/Server/server.json index 2b9ad3d993..1affc43bf8 100644 --- a/MediaBrowser.Server.Implementations/Localization/Server/server.json +++ b/MediaBrowser.Server.Implementations/Localization/Server/server.json @@ -1433,5 +1433,5 @@ "ToAccessPreferencesHelp": "To access your preferences later, click your user icon in the top right header and select My Preferences.", "HeaderViewStyles": "View Styles", "LabelSelectViewStyles": "Enable rich presentations for:", - "LabelSelectViewStylesHelp": "If enabled, views will be built with metadata to offer categories such as Suggestions, Latest, Genres, and more. If disabled, they'll be displayed with plain folders." + "LabelSelectViewStylesHelp": "If enabled, views will be built with metadata to offer categories such as Suggestions, Latest, Genres, and more. If disabled, they'll be displayed with simple folders." } diff --git a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs index 12ce60d45b..61432d00fb 100644 --- a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs +++ b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs @@ -522,7 +522,7 @@ namespace MediaBrowser.Server.Implementations.Persistence } } - public IEnumerable GetItemsOfType(Type type) + public IEnumerable GetItemsOfType(Type type) { if (type == null) { @@ -530,7 +530,37 @@ namespace MediaBrowser.Server.Implementations.Persistence } CheckDisposed(); - + + using (var cmd = _connection.CreateCommand()) + { + cmd.CommandText = "select type,data from TypedBaseItems where type = @type"; + + cmd.Parameters.Add(cmd, "@type", DbType.String).Value = type.FullName; + + using (var reader = cmd.ExecuteReader(CommandBehavior.SequentialAccess | CommandBehavior.SingleResult)) + { + while (reader.Read()) + { + var item = GetItem(reader); + + if (item != null) + { + yield return item; + } + } + } + } + } + + public IEnumerable GetItemIdsOfType(Type type) + { + if (type == null) + { + throw new ArgumentNullException("type"); + } + + CheckDisposed(); + using (var cmd = _connection.CreateCommand()) { cmd.CommandText = "select guid from TypedBaseItems where type = @type"; diff --git a/SharedVersion.cs b/SharedVersion.cs index 9660d919f3..e922d75910 100644 --- a/SharedVersion.cs +++ b/SharedVersion.cs @@ -1,4 +1,4 @@ using System.Reflection; -[assembly: AssemblyVersion("3.0.*")] -//[assembly: AssemblyVersion("3.0.5582.1")] +//[assembly: AssemblyVersion("3.0.*")] +[assembly: AssemblyVersion("3.0.5582.2")]