aboutsummaryrefslogtreecommitdiff
path: root/MediaBrowser.Server.Implementations
diff options
context:
space:
mode:
Diffstat (limited to 'MediaBrowser.Server.Implementations')
-rw-r--r--MediaBrowser.Server.Implementations/Configuration/ServerConfigurationManager.cs32
-rw-r--r--MediaBrowser.Server.Implementations/Library/UserManager.cs58
-rw-r--r--MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs7
-rw-r--r--MediaBrowser.Server.Implementations/MediaEncoder/MediaEncoder.cs90
-rw-r--r--MediaBrowser.Server.Implementations/ServerApplicationPaths.cs12
5 files changed, 91 insertions, 108 deletions
diff --git a/MediaBrowser.Server.Implementations/Configuration/ServerConfigurationManager.cs b/MediaBrowser.Server.Implementations/Configuration/ServerConfigurationManager.cs
index 415205cb1..cb3621fd1 100644
--- a/MediaBrowser.Server.Implementations/Configuration/ServerConfigurationManager.cs
+++ b/MediaBrowser.Server.Implementations/Configuration/ServerConfigurationManager.cs
@@ -26,6 +26,7 @@ namespace MediaBrowser.Server.Implementations.Configuration
{
UpdateItemsByNamePath();
UpdateTranscodingTempPath();
+ UpdateMetadataPath();
}
/// <summary>
@@ -77,6 +78,16 @@ namespace MediaBrowser.Server.Implementations.Configuration
}
/// <summary>
+ /// Updates the metadata path.
+ /// </summary>
+ private void UpdateMetadataPath()
+ {
+ ((ServerApplicationPaths)ApplicationPaths).InternalMetadataPath = string.IsNullOrEmpty(Configuration.MetadataPath) ?
+ null :
+ Configuration.MetadataPath;
+ }
+
+ /// <summary>
/// Updates the transcoding temporary path.
/// </summary>
private void UpdateTranscodingTempPath()
@@ -98,6 +109,7 @@ namespace MediaBrowser.Server.Implementations.Configuration
ValidateItemByNamePath(newConfig);
ValidateTranscodingTempPath(newConfig);
ValidatePathSubstitutions(newConfig);
+ ValidateMetadataPath(newConfig);
base.ReplaceConfiguration(newConfiguration);
}
@@ -166,5 +178,25 @@ namespace MediaBrowser.Server.Implementations.Configuration
}
}
}
+
+ /// <summary>
+ /// Validates the metadata path.
+ /// </summary>
+ /// <param name="newConfig">The new configuration.</param>
+ /// <exception cref="System.IO.DirectoryNotFoundException"></exception>
+ private void ValidateMetadataPath(ServerConfiguration newConfig)
+ {
+ var newPath = newConfig.MetadataPath;
+
+ if (!string.IsNullOrWhiteSpace(newPath)
+ && !string.Equals(Configuration.MetadataPath ?? string.Empty, newPath))
+ {
+ // Validate
+ if (!Directory.Exists(newPath))
+ {
+ throw new DirectoryNotFoundException(string.Format("{0} does not exist.", newPath));
+ }
+ }
+ }
}
}
diff --git a/MediaBrowser.Server.Implementations/Library/UserManager.cs b/MediaBrowser.Server.Implementations/Library/UserManager.cs
index 06028d37e..2ee843f09 100644
--- a/MediaBrowser.Server.Implementations/Library/UserManager.cs
+++ b/MediaBrowser.Server.Implementations/Library/UserManager.cs
@@ -260,6 +260,8 @@ namespace MediaBrowser.Server.Implementations.Library
public event EventHandler<GenericEventArgs<User>> UserCreated;
+ private readonly SemaphoreSlim _userListLock = new SemaphoreSlim(1, 1);
+
/// <summary>
/// Creates the user.
/// </summary>
@@ -279,19 +281,28 @@ namespace MediaBrowser.Server.Implementations.Library
throw new ArgumentException(string.Format("A user with the name '{0}' already exists.", name));
}
- var user = InstantiateNewUser(name);
+ await _userListLock.WaitAsync(CancellationToken.None).ConfigureAwait(false);
- var list = Users.ToList();
- list.Add(user);
- Users = list;
+ try
+ {
+ var user = InstantiateNewUser(name);
- user.DateLastSaved = DateTime.UtcNow;
+ var list = Users.ToList();
+ list.Add(user);
+ Users = list;
- await UserRepository.SaveUser(user, CancellationToken.None).ConfigureAwait(false);
+ user.DateLastSaved = DateTime.UtcNow;
- EventHelper.QueueEventIfNotNull(UserCreated, this, new GenericEventArgs<User> { Argument = user }, _logger);
+ await UserRepository.SaveUser(user, CancellationToken.None).ConfigureAwait(false);
- return user;
+ EventHelper.QueueEventIfNotNull(UserCreated, this, new GenericEventArgs<User> { Argument = user }, _logger);
+
+ return user;
+ }
+ finally
+ {
+ _userListLock.Release();
+ }
}
/// <summary>
@@ -325,23 +336,32 @@ namespace MediaBrowser.Server.Implementations.Library
throw new ArgumentException(string.Format("The user '{0}' cannot be deleted because there must be at least one admin user in the system.", user.Name));
}
- await UserRepository.DeleteUser(user, CancellationToken.None).ConfigureAwait(false);
-
- var path = user.ConfigurationFilePath;
+ await _userListLock.WaitAsync(CancellationToken.None).ConfigureAwait(false);
try
{
- File.Delete(path);
+ await UserRepository.DeleteUser(user, CancellationToken.None).ConfigureAwait(false);
+
+ var path = user.ConfigurationFilePath;
+
+ try
+ {
+ File.Delete(path);
+ }
+ catch (IOException ex)
+ {
+ _logger.ErrorException("Error deleting file {0}", ex, path);
+ }
+
+ // Force this to be lazy loaded again
+ Users = await LoadUsers().ConfigureAwait(false);
+
+ OnUserDeleted(user);
}
- catch (IOException ex)
+ finally
{
- _logger.ErrorException("Error deleting file {0}", ex, path);
+ _userListLock.Release();
}
-
- // Force this to be lazy loaded again
- Users = await LoadUsers().ConfigureAwait(false);
-
- OnUserDeleted(user);
}
/// <summary>
diff --git a/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs b/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs
index 6a4c3930a..db8786d62 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs
+++ b/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs
@@ -1498,8 +1498,11 @@ namespace MediaBrowser.Server.Implementations.LiveTv
{
var programs = _programs.ToList();
- var startDate = programs.Select(i => i.Value.StartDate).Min();
- var endDate = programs.Select(i => i.Value.StartDate).Max();
+ var startDate = _programs.Count == 0 ? DateTime.MinValue :
+ programs.Select(i => i.Value.StartDate).Min();
+
+ var endDate = programs.Count == 0 ? DateTime.MinValue :
+ programs.Select(i => i.Value.StartDate).Max();
return new GuideInfo
{
diff --git a/MediaBrowser.Server.Implementations/MediaEncoder/MediaEncoder.cs b/MediaBrowser.Server.Implementations/MediaEncoder/MediaEncoder.cs
index fddba7662..c646d80bc 100644
--- a/MediaBrowser.Server.Implementations/MediaEncoder/MediaEncoder.cs
+++ b/MediaBrowser.Server.Implementations/MediaEncoder/MediaEncoder.cs
@@ -175,6 +175,10 @@ namespace MediaBrowser.Server.Implementations.MediaEncoder
string probeSizeArgument,
CancellationToken cancellationToken)
{
+ var args = extractChapters
+ ? "{0} -i {1} -threads 0 -v info -print_format json -show_streams -show_chapters -show_format"
+ : "{0} -i {1} -threads 0 -v info -print_format json -show_streams -show_format";
+
var process = new Process
{
StartInfo = new ProcessStartInfo
@@ -186,8 +190,7 @@ namespace MediaBrowser.Server.Implementations.MediaEncoder
RedirectStandardOutput = true,
RedirectStandardError = true,
FileName = FFProbePath,
- Arguments = string.Format(
- "{0} -i {1} -threads 0 -v info -print_format json -show_streams -show_format",
+ Arguments = string.Format(args,
probeSizeArgument, inputPath).Trim(),
WindowStyle = ProcessWindowStyle.Hidden,
@@ -204,7 +207,6 @@ namespace MediaBrowser.Server.Implementations.MediaEncoder
await _ffProbeResourcePool.WaitAsync(cancellationToken).ConfigureAwait(false);
InternalMediaInfoResult result;
- string standardError = null;
try
{
@@ -221,24 +223,9 @@ namespace MediaBrowser.Server.Implementations.MediaEncoder
try
{
- Task<string> standardErrorReadTask = null;
-
- // MUST read both stdout and stderr asynchronously or a deadlock may occurr
- if (extractChapters)
- {
- standardErrorReadTask = process.StandardError.ReadToEndAsync();
- }
- else
- {
- process.BeginErrorReadLine();
- }
+ process.BeginErrorReadLine();
result = _jsonSerializer.DeserializeFromStream<InternalMediaInfoResult>(process.StandardOutput.BaseStream);
-
- if (extractChapters)
- {
- standardError = await standardErrorReadTask.ConfigureAwait(false);
- }
}
catch
{
@@ -282,11 +269,6 @@ namespace MediaBrowser.Server.Implementations.MediaEncoder
}
}
- if (extractChapters && !string.IsNullOrEmpty(standardError))
- {
- AddChapters(result, standardError);
- }
-
return result;
}
@@ -296,66 +278,6 @@ namespace MediaBrowser.Server.Implementations.MediaEncoder
protected readonly CultureInfo UsCulture = new CultureInfo("en-US");
/// <summary>
- /// Adds the chapters.
- /// </summary>
- /// <param name="result">The result.</param>
- /// <param name="standardError">The standard error.</param>
- private void AddChapters(InternalMediaInfoResult result, string standardError)
- {
- var lines = standardError.Split('\n').Select(l => l.TrimStart());
-
- var chapters = new List<ChapterInfo>();
-
- ChapterInfo lastChapter = null;
-
- foreach (var line in lines)
- {
- if (line.StartsWith("Chapter", StringComparison.OrdinalIgnoreCase))
- {
- // Example:
- // Chapter #0.2: start 400.534, end 4565.435
- const string srch = "start ";
- var start = line.IndexOf(srch, StringComparison.OrdinalIgnoreCase);
-
- if (start == -1)
- {
- continue;
- }
-
- var subString = line.Substring(start + srch.Length);
- subString = subString.Substring(0, subString.IndexOf(','));
-
- double seconds;
-
- if (double.TryParse(subString, NumberStyles.Any, UsCulture, out seconds))
- {
- lastChapter = new ChapterInfo
- {
- StartPositionTicks = TimeSpan.FromSeconds(seconds).Ticks
- };
-
- chapters.Add(lastChapter);
- }
- }
-
- else if (line.StartsWith("title", StringComparison.OrdinalIgnoreCase))
- {
- if (lastChapter != null && string.IsNullOrEmpty(lastChapter.Name))
- {
- var index = line.IndexOf(':');
-
- if (index != -1)
- {
- lastChapter.Name = line.Substring(index + 1).Trim().TrimEnd('\r');
- }
- }
- }
- }
-
- result.Chapters = chapters;
- }
-
- /// <summary>
/// Processes the exited.
/// </summary>
/// <param name="sender">The sender.</param>
diff --git a/MediaBrowser.Server.Implementations/ServerApplicationPaths.cs b/MediaBrowser.Server.Implementations/ServerApplicationPaths.cs
index c36c49df0..df2a5f83c 100644
--- a/MediaBrowser.Server.Implementations/ServerApplicationPaths.cs
+++ b/MediaBrowser.Server.Implementations/ServerApplicationPaths.cs
@@ -1,6 +1,6 @@
-using System;
-using MediaBrowser.Common.Implementations;
+using MediaBrowser.Common.Implementations;
using MediaBrowser.Controller;
+using System;
using System.IO;
namespace MediaBrowser.Server.Implementations
@@ -239,14 +239,20 @@ namespace MediaBrowser.Server.Implementations
}
}
+ private string _internalMetadataPath;
public string InternalMetadataPath
{
get
{
- return Path.Combine(DataPath, "metadata");
+ return _internalMetadataPath ?? (_internalMetadataPath = Path.Combine(DataPath, "metadata"));
+ }
+ set
+ {
+ _internalMetadataPath = value;
}
}
+
public string GetInternalMetadataPath(Guid id)
{
var idString = id.ToString("N");