3.0.5582.2

This commit is contained in:
Luke Pulverenti 2015-04-15 23:23:13 -04:00
parent 71e1283c2f
commit c7b95a2513
10 changed files with 128 additions and 78 deletions

View File

@ -66,7 +66,6 @@ namespace MediaBrowser.Api
_config.Configuration.EnableStandaloneMetadata = true; _config.Configuration.EnableStandaloneMetadata = true;
_config.Configuration.EnableLibraryMetadataSubFolder = true; _config.Configuration.EnableLibraryMetadataSubFolder = true;
_config.Configuration.EnableUserSpecificUserViews = true; _config.Configuration.EnableUserSpecificUserViews = true;
_config.Configuration.EnableUserSpecificUserViews2 = true;
_config.SaveConfiguration(); _config.SaveConfiguration();
} }

View File

@ -107,7 +107,7 @@ namespace MediaBrowser.Controller.Persistence
/// </summary> /// </summary>
/// <param name="type">The type.</param> /// <param name="type">The type.</param>
/// <returns>IEnumerable{Guid}.</returns> /// <returns>IEnumerable{Guid}.</returns>
IEnumerable<Guid> GetItemsOfType(Type type); IEnumerable<Guid> GetItemIdsOfType(Type type);
/// <summary> /// <summary>
/// Saves the children. /// Saves the children.
@ -133,6 +133,13 @@ namespace MediaBrowser.Controller.Persistence
/// <param name="cancellationToken">The cancellation token.</param> /// <param name="cancellationToken">The cancellation token.</param>
/// <returns>Task.</returns> /// <returns>Task.</returns>
Task SaveMediaStreams(Guid id, IEnumerable<MediaStream> streams, CancellationToken cancellationToken); Task SaveMediaStreams(Guid id, IEnumerable<MediaStream> streams, CancellationToken cancellationToken);
/// <summary>
/// Gets the type of the items of.
/// </summary>
/// <param name="type">The type.</param>
/// <returns>IEnumerable&lt;BaseItem&gt;.</returns>
IEnumerable<BaseItem> GetItemsOfType(Type type);
} }
} }

View File

@ -489,11 +489,14 @@ namespace MediaBrowser.MediaEncoding.Encoder
await resourcePool.WaitAsync(cancellationToken).ConfigureAwait(false); await resourcePool.WaitAsync(cancellationToken).ConfigureAwait(false);
var processWrapper = new ProcessWrapper(process, this); var processWrapper = new ProcessWrapper(process, this);
bool ranToCompletion;
StartProcess(processWrapper);
var memoryStream = new MemoryStream(); var memoryStream = new MemoryStream();
try
{
StartProcess(processWrapper);
#pragma warning disable 4014 #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 // 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); process.StandardOutput.BaseStream.CopyToAsync(memoryStream);
@ -502,14 +505,18 @@ namespace MediaBrowser.MediaEncoding.Encoder
// MUST read both stdout and stderr asynchronously or a deadlock may occurr // MUST read both stdout and stderr asynchronously or a deadlock may occurr
process.BeginErrorReadLine(); process.BeginErrorReadLine();
var ranToCompletion = process.WaitForExit(10000); ranToCompletion = process.WaitForExit(10000);
if (!ranToCompletion) if (!ranToCompletion)
{ {
StopProcess(processWrapper, 1000, false); StopProcess(processWrapper, 1000, false);
} }
}
finally
{
resourcePool.Release(); resourcePool.Release();
}
var exitCode = ranToCompletion ? processWrapper.ExitCode ?? 0 : -1; var exitCode = ranToCompletion ? processWrapper.ExitCode ?? 0 : -1;

View File

@ -49,11 +49,6 @@ namespace MediaBrowser.Model.Configuration
/// </summary> /// </summary>
/// <value><c>true</c> if [enable user specific user views]; otherwise, <c>false</c>.</value> /// <value><c>true</c> if [enable user specific user views]; otherwise, <c>false</c>.</value>
public bool EnableUserSpecificUserViews { get; set; } public bool EnableUserSpecificUserViews { get; set; }
/// <summary>
/// Gets or sets a value indicating whether [enable user specific user views2].
/// </summary>
/// <value><c>true</c> if [enable user specific user views2]; otherwise, <c>false</c>.</value>
public bool EnableUserSpecificUserViews2 { get; set; }
/// <summary> /// <summary>
/// Gets or sets the value pointing to the file system where the ssl certiifcate is located.. /// Gets or sets the value pointing to the file system where the ssl certiifcate is located..

View File

@ -6,6 +6,7 @@ using MediaBrowser.Controller.Providers;
using MediaBrowser.Model.Drawing; using MediaBrowser.Model.Drawing;
using MediaBrowser.Model.Entities; using MediaBrowser.Model.Entities;
using MediaBrowser.Model.IO; using MediaBrowser.Model.IO;
using MediaBrowser.Model.Logging;
using MediaBrowser.Model.MediaInfo; using MediaBrowser.Model.MediaInfo;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
@ -20,13 +21,15 @@ namespace MediaBrowser.Providers.MediaInfo
private readonly IMediaEncoder _mediaEncoder; private readonly IMediaEncoder _mediaEncoder;
private readonly IServerConfigurationManager _config; private readonly IServerConfigurationManager _config;
private readonly ILibraryManager _libraryManager; 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; _isoManager = isoManager;
_mediaEncoder = mediaEncoder; _mediaEncoder = mediaEncoder;
_config = config; _config = config;
_libraryManager = libraryManager; _libraryManager = libraryManager;
_logger = logger;
} }
/// <summary> /// <summary>
@ -74,6 +77,7 @@ namespace MediaBrowser.Providers.MediaInfo
// Can't extract if we didn't find a video stream in the file // Can't extract if we didn't find a video stream in the file
if (!video.DefaultVideoStreamIndex.HasValue) 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 }); return Task.FromResult(new DynamicImageResponse { HasImage = false });
} }

View File

@ -209,11 +209,6 @@ namespace MediaBrowser.Server.Implementations.Library
var enableRichView = !user.Configuration.PlainFolderViews.Contains(parentId.ToString("N"), StringComparer.OrdinalIgnoreCase); 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) if (_config.Configuration.EnableUserSpecificUserViews)
{ {
viewType = enableRichView ? viewType : null; viewType = enableRichView ? viewType : null;
@ -227,6 +222,7 @@ namespace MediaBrowser.Server.Implementations.Library
return view; return view;
} }
viewType = enableRichView ? viewType : CollectionType.Folders;
return await _libraryManager.GetNamedView(user, name, viewType, sortName, cancellationToken).ConfigureAwait(false); return await _libraryManager.GetNamedView(user, name, viewType, sortName, cancellationToken).ConfigureAwait(false);
} }
else else

View File

@ -54,11 +54,9 @@ namespace MediaBrowser.Server.Implementations.LiveTv
new ConcurrentDictionary<string, LiveStreamData>(); new ConcurrentDictionary<string, LiveStreamData>();
private List<Guid> _channelIdList = new List<Guid>(); private List<Guid> _channelIdList = new List<Guid>();
private Dictionary<Guid, LiveTvProgram> _programs = new Dictionary<Guid, LiveTvProgram>(); private Dictionary<Guid, LiveTvProgram> _programs;
private readonly ConcurrentDictionary<Guid, bool> _refreshedPrograms = new ConcurrentDictionary<Guid, bool>(); private readonly ConcurrentDictionary<Guid, bool> _refreshedPrograms = new ConcurrentDictionary<Guid, bool>();
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) 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; _config = config;
@ -109,6 +107,37 @@ namespace MediaBrowser.Server.Implementations.LiveTv
_taskManager.CancelIfRunningAndQueue<RefreshChannelsScheduledTask>(); _taskManager.CancelIfRunningAndQueue<RefreshChannelsScheduledTask>();
} }
private readonly object _programsDataLock = new object();
private Dictionary<Guid, LiveTvProgram> GetProgramsDictionary()
{
if (_programs == null)
{
lock (_programsDataLock)
{
if (_programs == null)
{
var dict = new Dictionary<Guid, LiveTvProgram>();
foreach (var item in _itemRepo.GetItemsOfType(typeof (LiveTvProgram))
.Cast<LiveTvProgram>()
.ToList())
{
dict[item.Id] = item;
}
_programs = dict;
}
}
}
return _programs;
}
private IEnumerable<LiveTvProgram> GetPrograms()
{
return GetProgramsDictionary().Values;
}
public async Task<QueryResult<LiveTvChannel>> GetInternalChannels(LiveTvChannelQuery query, CancellationToken cancellationToken) public async Task<QueryResult<LiveTvChannel>> GetInternalChannels(LiveTvChannelQuery query, CancellationToken cancellationToken)
{ {
var user = string.IsNullOrEmpty(query.UserId) ? null : _userManager.GetUserById(query.UserId); var user = string.IsNullOrEmpty(query.UserId) ? null : _userManager.GetUserById(query.UserId);
@ -260,7 +289,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv
LiveTvProgram obj = null; LiveTvProgram obj = null;
_programs.TryGetValue(guid, out obj); GetProgramsDictionary().TryGetValue(guid, out obj);
if (obj != null) if (obj != null)
{ {
@ -691,7 +720,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv
public async Task<QueryResult<ProgramInfoDto>> GetPrograms(ProgramQuery query, CancellationToken cancellationToken) public async Task<QueryResult<ProgramInfoDto>> GetPrograms(ProgramQuery query, CancellationToken cancellationToken)
{ {
IEnumerable<LiveTvProgram> programs = _programs.Values; IEnumerable<LiveTvProgram> programs = GetPrograms();
if (query.MinEndDate.HasValue) if (query.MinEndDate.HasValue)
{ {
@ -806,7 +835,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv
public async Task<QueryResult<LiveTvProgram>> GetRecommendedProgramsInternal(RecommendedProgramQuery query, CancellationToken cancellationToken) public async Task<QueryResult<LiveTvProgram>> GetRecommendedProgramsInternal(RecommendedProgramQuery query, CancellationToken cancellationToken)
{ {
IEnumerable<LiveTvProgram> programs = _programs.Values; IEnumerable<LiveTvProgram> programs = GetPrograms();
var user = _userManager.GetUserById(query.UserId); var user = _userManager.GetUserById(query.UserId);
@ -994,10 +1023,6 @@ namespace MediaBrowser.Server.Implementations.LiveTv
} }
internal async Task RefreshChannels(IProgress<double> progress, CancellationToken cancellationToken) internal async Task RefreshChannels(IProgress<double> progress, CancellationToken cancellationToken)
{
await _refreshSemaphore.WaitAsync(cancellationToken).ConfigureAwait(false);
try
{ {
var innerProgress = new ActionableProgress<double>(); var innerProgress = new ActionableProgress<double>();
innerProgress.RegisterAction(p => progress.Report(p * .9)); innerProgress.RegisterAction(p => progress.Report(p * .9));
@ -1007,12 +1032,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv
innerProgress.RegisterAction(p => progress.Report(90 + (p * .1))); innerProgress.RegisterAction(p => progress.Report(90 + (p * .1)));
await CleanDatabaseInternal(progress, cancellationToken).ConfigureAwait(false); await CleanDatabaseInternal(progress, cancellationToken).ConfigureAwait(false);
RefreshIfNeeded(_programs.Values.Where(i => (i.StartDate - DateTime.UtcNow).TotalDays <= 1).ToList()); RefreshIfNeeded(GetPrograms().Where(i => (i.StartDate - DateTime.UtcNow).TotalDays <= 1).ToList());
}
finally
{
_refreshSemaphore.Release();
}
} }
private async Task RefreshChannelsInternal(IProgress<double> progress, CancellationToken cancellationToken) private async Task RefreshChannelsInternal(IProgress<double> progress, CancellationToken cancellationToken)
@ -1136,7 +1156,11 @@ namespace MediaBrowser.Server.Implementations.LiveTv
progress.Report(80 * percent + 10); progress.Report(80 * percent + 10);
} }
lock (_programsDataLock)
{
_programs = programs.ToDictionary(i => i.Id); _programs = programs.ToDictionary(i => i.Id);
}
_refreshedPrograms.Clear(); _refreshedPrograms.Clear();
progress.Report(90); progress.Report(90);
@ -1147,28 +1171,14 @@ namespace MediaBrowser.Server.Implementations.LiveTv
progress.Report(100); progress.Report(100);
} }
public async Task CleanDatabase(IProgress<double> 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<double> progress, CancellationToken cancellationToken) private Task CleanDatabaseInternal(IProgress<double> progress, CancellationToken cancellationToken)
{ {
return DeleteOldPrograms(_programs.Keys.ToList(), progress, cancellationToken); return DeleteOldPrograms(GetProgramsDictionary().Keys.ToList(), progress, cancellationToken);
} }
private async Task DeleteOldPrograms(List<Guid> currentIdList, IProgress<double> progress, CancellationToken cancellationToken) private async Task DeleteOldPrograms(List<Guid> currentIdList, IProgress<double> progress, CancellationToken cancellationToken)
{ {
var list = _itemRepo.GetItemsOfType(typeof(LiveTvProgram)).ToList(); var list = _itemRepo.GetItemIdsOfType(typeof(LiveTvProgram)).ToList();
var numComplete = 0; var numComplete = 0;
@ -1549,7 +1559,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv
{ {
var now = DateTime.UtcNow; var now = DateTime.UtcNow;
var program = _programs.Values var program = GetPrograms()
.Where(i => string.Equals(externalChannelId, i.ExternalChannelId, StringComparison.OrdinalIgnoreCase)) .Where(i => string.Equals(externalChannelId, i.ExternalChannelId, StringComparison.OrdinalIgnoreCase))
.OrderBy(i => i.StartDate) .OrderBy(i => i.StartDate)
.SkipWhile(i => now >= (i.EndDate ?? DateTime.MinValue)) .SkipWhile(i => now >= (i.EndDate ?? DateTime.MinValue))
@ -1855,13 +1865,15 @@ namespace MediaBrowser.Server.Implementations.LiveTv
public GuideInfo GetGuideInfo() public GuideInfo GetGuideInfo()
{ {
var programs = _programs.ToList(); var programs = GetPrograms().OrderBy(i => i.StartDate).ToList();
var startDate = _programs.Count == 0 ? DateTime.MinValue : var startDate = programs.Count == 0 ?
programs.Select(i => i.Value.StartDate).Min(); DateTime.MinValue :
programs[0].StartDate;
var endDate = programs.Count == 0 ? DateTime.MinValue : var endDate = programs.Count == 0 ?
programs.Select(i => i.Value.StartDate).Max(); DateTime.MinValue :
programs[programs.Count - 1].StartDate;
return new GuideInfo return new GuideInfo
{ {

View File

@ -1433,5 +1433,5 @@
"ToAccessPreferencesHelp": "To access your preferences later, click your user icon in the top right header and select My Preferences.", "ToAccessPreferencesHelp": "To access your preferences later, click your user icon in the top right header and select My Preferences.",
"HeaderViewStyles": "View Styles", "HeaderViewStyles": "View Styles",
"LabelSelectViewStyles": "Enable rich presentations for:", "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."
} }

View File

@ -522,7 +522,37 @@ namespace MediaBrowser.Server.Implementations.Persistence
} }
} }
public IEnumerable<Guid> GetItemsOfType(Type type) public IEnumerable<BaseItem> GetItemsOfType(Type type)
{
if (type == null)
{
throw new ArgumentNullException("type");
}
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<Guid> GetItemIdsOfType(Type type)
{ {
if (type == null) if (type == null)
{ {

View File

@ -1,4 +1,4 @@
using System.Reflection; using System.Reflection;
[assembly: AssemblyVersion("3.0.*")] //[assembly: AssemblyVersion("3.0.*")]
//[assembly: AssemblyVersion("3.0.5582.1")] [assembly: AssemblyVersion("3.0.5582.2")]