From 0ec3d217e71ea20a9e377e479db88c4d4cd39baf Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Fri, 26 Dec 2014 12:45:06 -0500 Subject: sync updates --- .../Session/SessionManager.cs | 80 +--------------------- 1 file changed, 3 insertions(+), 77 deletions(-) (limited to 'MediaBrowser.Server.Implementations/Session') diff --git a/MediaBrowser.Server.Implementations/Session/SessionManager.cs b/MediaBrowser.Server.Implementations/Session/SessionManager.cs index 1f294c325..4c587d1ab 100644 --- a/MediaBrowser.Server.Implementations/Session/SessionManager.cs +++ b/MediaBrowser.Server.Implementations/Session/SessionManager.cs @@ -67,12 +67,6 @@ namespace MediaBrowser.Server.Implementations.Session private readonly IAuthenticationRepository _authRepo; private readonly IDeviceManager _deviceManager; - /// - /// Gets or sets the configuration manager. - /// - /// The configuration manager. - private readonly IServerConfigurationManager _configurationManager; - /// /// The _active connections /// @@ -105,18 +99,9 @@ namespace MediaBrowser.Server.Implementations.Session private readonly SemaphoreSlim _sessionLock = new SemaphoreSlim(1, 1); - /// - /// Initializes a new instance of the class. - /// - /// The user data repository. - /// The configuration manager. - /// The logger. - /// The user repository. - /// The library manager. - public SessionManager(IUserDataManager userDataRepository, IServerConfigurationManager configurationManager, ILogger logger, IUserRepository userRepository, ILibraryManager libraryManager, IUserManager userManager, IMusicManager musicManager, IDtoService dtoService, IImageProcessor imageProcessor, IItemRepository itemRepo, IJsonSerializer jsonSerializer, IServerApplicationHost appHost, IHttpClient httpClient, IAuthenticationRepository authRepo, IDeviceManager deviceManager) + public SessionManager(IUserDataManager userDataRepository, ILogger logger, IUserRepository userRepository, ILibraryManager libraryManager, IUserManager userManager, IMusicManager musicManager, IDtoService dtoService, IImageProcessor imageProcessor, IItemRepository itemRepo, IJsonSerializer jsonSerializer, IServerApplicationHost appHost, IHttpClient httpClient, IAuthenticationRepository authRepo, IDeviceManager deviceManager) { _userDataRepository = userDataRepository; - _configurationManager = configurationManager; _logger = logger; _userRepository = userRepository; _libraryManager = libraryManager; @@ -689,7 +674,7 @@ namespace MediaBrowser.Server.Implementations.Session if (positionTicks.HasValue) { - UpdatePlayState(item, data, positionTicks.Value); + _userDataRepository.UpdatePlayState(item, data, positionTicks.Value); await _userDataRepository.SaveUserData(userId, item, data, UserDataSaveReason.PlaybackProgress, CancellationToken.None).ConfigureAwait(false); } @@ -779,7 +764,7 @@ namespace MediaBrowser.Server.Implementations.Session if (positionTicks.HasValue) { - playedToCompletion = UpdatePlayState(item, data, positionTicks.Value); + playedToCompletion = _userDataRepository.UpdatePlayState(item, data, positionTicks.Value); } else { @@ -795,65 +780,6 @@ namespace MediaBrowser.Server.Implementations.Session return playedToCompletion; } - /// - /// Updates playstate position for an item but does not save - /// - /// The item - /// User data for the item - /// The current playback position - private bool UpdatePlayState(BaseItem item, UserItemData data, long positionTicks) - { - var playedToCompletion = false; - - var hasRuntime = item.RunTimeTicks.HasValue && item.RunTimeTicks > 0; - - // If a position has been reported, and if we know the duration - if (positionTicks > 0 && hasRuntime) - { - var pctIn = Decimal.Divide(positionTicks, item.RunTimeTicks.Value) * 100; - - // Don't track in very beginning - if (pctIn < _configurationManager.Configuration.MinResumePct) - { - positionTicks = 0; - } - - // If we're at the end, assume completed - else if (pctIn > _configurationManager.Configuration.MaxResumePct || positionTicks >= item.RunTimeTicks.Value) - { - positionTicks = 0; - data.Played = playedToCompletion = true; - } - - else - { - // Enforce MinResumeDuration - var durationSeconds = TimeSpan.FromTicks(item.RunTimeTicks.Value).TotalSeconds; - - if (durationSeconds < _configurationManager.Configuration.MinResumeDurationSeconds) - { - positionTicks = 0; - data.Played = playedToCompletion = true; - } - } - } - else if (!hasRuntime) - { - // If we don't know the runtime we'll just have to assume it was fully played - data.Played = playedToCompletion = true; - positionTicks = 0; - } - - if (item is Audio) - { - positionTicks = 0; - } - - data.PlaybackPositionTicks = positionTicks; - - return playedToCompletion; - } - /// /// Gets the session. /// -- cgit v1.2.3 From 2e53ff1fd0379ed6e4861f062815402230205ff0 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Fri, 26 Dec 2014 14:34:39 -0500 Subject: move files out of common --- .../ScheduledTasksWebSocketListener.cs | 1 + .../Session/SessionInfoWebSocketListener.cs | 1 + .../System/ActivityLogWebSocketListener.cs | 4 +- .../System/SystemInfoWebSocketListener.cs | 1 + .../Configuration/ConfigurationHelper.cs | 59 ++++ .../MediaBrowser.Common.Implementations.csproj | 1 + .../Configuration/ConfigurationHelper.cs | 59 ---- MediaBrowser.Common/MediaBrowser.Common.csproj | 3 - .../Net/BasePeriodicWebSocketListener.cs | 326 -------------------- MediaBrowser.Common/Net/IWebSocketListener.cs | 17 -- .../MediaBrowser.Controller.csproj | 2 + .../Net/BasePeriodicWebSocketListener.cs | 327 +++++++++++++++++++++ MediaBrowser.Controller/Net/IWebSocketListener.cs | 18 ++ .../Session/SessionWebSocketListener.cs | 1 + 14 files changed, 413 insertions(+), 407 deletions(-) create mode 100644 MediaBrowser.Common.Implementations/Configuration/ConfigurationHelper.cs delete mode 100644 MediaBrowser.Common/Configuration/ConfigurationHelper.cs delete mode 100644 MediaBrowser.Common/Net/BasePeriodicWebSocketListener.cs delete mode 100644 MediaBrowser.Common/Net/IWebSocketListener.cs create mode 100644 MediaBrowser.Controller/Net/BasePeriodicWebSocketListener.cs create mode 100644 MediaBrowser.Controller/Net/IWebSocketListener.cs (limited to 'MediaBrowser.Server.Implementations/Session') diff --git a/MediaBrowser.Api/ScheduledTasks/ScheduledTasksWebSocketListener.cs b/MediaBrowser.Api/ScheduledTasks/ScheduledTasksWebSocketListener.cs index f34c53b16..cb8f91ab6 100644 --- a/MediaBrowser.Api/ScheduledTasks/ScheduledTasksWebSocketListener.cs +++ b/MediaBrowser.Api/ScheduledTasks/ScheduledTasksWebSocketListener.cs @@ -1,5 +1,6 @@ using MediaBrowser.Common.Net; using MediaBrowser.Common.ScheduledTasks; +using MediaBrowser.Controller.Net; using MediaBrowser.Model.Events; using MediaBrowser.Model.Logging; using MediaBrowser.Model.Tasks; diff --git a/MediaBrowser.Api/Session/SessionInfoWebSocketListener.cs b/MediaBrowser.Api/Session/SessionInfoWebSocketListener.cs index e6b525e53..25130776e 100644 --- a/MediaBrowser.Api/Session/SessionInfoWebSocketListener.cs +++ b/MediaBrowser.Api/Session/SessionInfoWebSocketListener.cs @@ -1,5 +1,6 @@ using MediaBrowser.Common.Net; using MediaBrowser.Controller.Library; +using MediaBrowser.Controller.Net; using MediaBrowser.Controller.Session; using MediaBrowser.Model.Logging; using MediaBrowser.Model.Session; diff --git a/MediaBrowser.Api/System/ActivityLogWebSocketListener.cs b/MediaBrowser.Api/System/ActivityLogWebSocketListener.cs index 4629b2a8c..a951cd3d6 100644 --- a/MediaBrowser.Api/System/ActivityLogWebSocketListener.cs +++ b/MediaBrowser.Api/System/ActivityLogWebSocketListener.cs @@ -1,5 +1,5 @@ -using MediaBrowser.Common.Net; -using MediaBrowser.Controller.Activity; +using MediaBrowser.Controller.Activity; +using MediaBrowser.Controller.Net; using MediaBrowser.Model.Activity; using MediaBrowser.Model.Events; using MediaBrowser.Model.Logging; diff --git a/MediaBrowser.Api/System/SystemInfoWebSocketListener.cs b/MediaBrowser.Api/System/SystemInfoWebSocketListener.cs index c20cef3b3..49a3e3291 100644 --- a/MediaBrowser.Api/System/SystemInfoWebSocketListener.cs +++ b/MediaBrowser.Api/System/SystemInfoWebSocketListener.cs @@ -1,5 +1,6 @@ using MediaBrowser.Common.Net; using MediaBrowser.Controller; +using MediaBrowser.Controller.Net; using MediaBrowser.Model.Logging; using MediaBrowser.Model.System; using System.Threading.Tasks; diff --git a/MediaBrowser.Common.Implementations/Configuration/ConfigurationHelper.cs b/MediaBrowser.Common.Implementations/Configuration/ConfigurationHelper.cs new file mode 100644 index 000000000..ff5b8bd59 --- /dev/null +++ b/MediaBrowser.Common.Implementations/Configuration/ConfigurationHelper.cs @@ -0,0 +1,59 @@ +using MediaBrowser.Model.Serialization; +using System; +using System.IO; +using System.Linq; + +namespace MediaBrowser.Common.Implementations.Configuration +{ + /// + /// Class ConfigurationHelper + /// + public static class ConfigurationHelper + { + /// + /// Reads an xml configuration file from the file system + /// It will immediately re-serialize and save if new serialization data is available due to property changes + /// + /// The type. + /// The path. + /// The XML serializer. + /// System.Object. + public static object GetXmlConfiguration(Type type, string path, IXmlSerializer xmlSerializer) + { + object configuration; + + byte[] buffer = null; + + // Use try/catch to avoid the extra file system lookup using File.Exists + try + { + buffer = File.ReadAllBytes(path); + + configuration = xmlSerializer.DeserializeFromBytes(type, buffer); + } + catch (Exception) + { + configuration = Activator.CreateInstance(type); + } + + using (var stream = new MemoryStream()) + { + xmlSerializer.SerializeToStream(configuration, stream); + + // Take the object we just got and serialize it back to bytes + var newBytes = stream.ToArray(); + + // If the file didn't exist before, or if something has changed, re-save + if (buffer == null || !buffer.SequenceEqual(newBytes)) + { + Directory.CreateDirectory(Path.GetDirectoryName(path)); + + // Save it after load in case we got new items + File.WriteAllBytes(path, newBytes); + } + + return configuration; + } + } + } +} diff --git a/MediaBrowser.Common.Implementations/MediaBrowser.Common.Implementations.csproj b/MediaBrowser.Common.Implementations/MediaBrowser.Common.Implementations.csproj index 42a402940..0aaf0b4e0 100644 --- a/MediaBrowser.Common.Implementations/MediaBrowser.Common.Implementations.csproj +++ b/MediaBrowser.Common.Implementations/MediaBrowser.Common.Implementations.csproj @@ -80,6 +80,7 @@ + diff --git a/MediaBrowser.Common/Configuration/ConfigurationHelper.cs b/MediaBrowser.Common/Configuration/ConfigurationHelper.cs deleted file mode 100644 index 7212b70e1..000000000 --- a/MediaBrowser.Common/Configuration/ConfigurationHelper.cs +++ /dev/null @@ -1,59 +0,0 @@ -using MediaBrowser.Model.Serialization; -using System; -using System.IO; -using System.Linq; - -namespace MediaBrowser.Common.Configuration -{ - /// - /// Class ConfigurationHelper - /// - public static class ConfigurationHelper - { - /// - /// Reads an xml configuration file from the file system - /// It will immediately re-serialize and save if new serialization data is available due to property changes - /// - /// The type. - /// The path. - /// The XML serializer. - /// System.Object. - public static object GetXmlConfiguration(Type type, string path, IXmlSerializer xmlSerializer) - { - object configuration; - - byte[] buffer = null; - - // Use try/catch to avoid the extra file system lookup using File.Exists - try - { - buffer = File.ReadAllBytes(path); - - configuration = xmlSerializer.DeserializeFromBytes(type, buffer); - } - catch (Exception) - { - configuration = Activator.CreateInstance(type); - } - - using (var stream = new MemoryStream()) - { - xmlSerializer.SerializeToStream(configuration, stream); - - // Take the object we just got and serialize it back to bytes - var newBytes = stream.ToArray(); - - // If the file didn't exist before, or if something has changed, re-save - if (buffer == null || !buffer.SequenceEqual(newBytes)) - { - Directory.CreateDirectory(Path.GetDirectoryName(path)); - - // Save it after load in case we got new items - File.WriteAllBytes(path, newBytes); - } - - return configuration; - } - } - } -} diff --git a/MediaBrowser.Common/MediaBrowser.Common.csproj b/MediaBrowser.Common/MediaBrowser.Common.csproj index 140a4ae0e..b4cc17f51 100644 --- a/MediaBrowser.Common/MediaBrowser.Common.csproj +++ b/MediaBrowser.Common/MediaBrowser.Common.csproj @@ -53,7 +53,6 @@ Properties\SharedVersion.cs - @@ -64,11 +63,9 @@ - - diff --git a/MediaBrowser.Common/Net/BasePeriodicWebSocketListener.cs b/MediaBrowser.Common/Net/BasePeriodicWebSocketListener.cs deleted file mode 100644 index a2af3707b..000000000 --- a/MediaBrowser.Common/Net/BasePeriodicWebSocketListener.cs +++ /dev/null @@ -1,326 +0,0 @@ -using MediaBrowser.Model.Logging; -using MediaBrowser.Model.Net; -using System; -using System.Collections.Generic; -using System.Globalization; -using System.Linq; -using System.Threading; -using System.Threading.Tasks; - -namespace MediaBrowser.Common.Net -{ - /// - /// Starts sending data over a web socket periodically when a message is received, and then stops when a corresponding stop message is received - /// - /// The type of the T return data type. - /// The type of the T state type. - public abstract class BasePeriodicWebSocketListener : IWebSocketListener, IDisposable - where TStateType : WebSocketListenerState, new() - where TReturnDataType : class - { - /// - /// The _active connections - /// - protected readonly List> ActiveConnections = - new List>(); - - /// - /// Gets the name. - /// - /// The name. - protected abstract string Name { get; } - - /// - /// Gets the data to send. - /// - /// The state. - /// Task{`1}. - protected abstract Task GetDataToSend(TStateType state); - - /// - /// The logger - /// - protected ILogger Logger; - - /// - /// Initializes a new instance of the class. - /// - /// The logger. - /// logger - protected BasePeriodicWebSocketListener(ILogger logger) - { - if (logger == null) - { - throw new ArgumentNullException("logger"); - } - - Logger = logger; - } - - /// - /// The null task result - /// - protected Task NullTaskResult = Task.FromResult(true); - - /// - /// Processes the message. - /// - /// The message. - /// Task. - public Task ProcessMessage(WebSocketMessageInfo message) - { - if (message.MessageType.Equals(Name + "Start", StringComparison.OrdinalIgnoreCase)) - { - Start(message); - } - - if (message.MessageType.Equals(Name + "Stop", StringComparison.OrdinalIgnoreCase)) - { - Stop(message); - } - - return NullTaskResult; - } - - protected readonly CultureInfo UsCulture = new CultureInfo("en-US"); - - protected virtual bool SendOnTimer - { - get - { - return true; - } - } - - /// - /// Starts sending messages over a web socket - /// - /// The message. - private void Start(WebSocketMessageInfo message) - { - var vals = message.Data.Split(','); - - var dueTimeMs = long.Parse(vals[0], UsCulture); - var periodMs = long.Parse(vals[1], UsCulture); - - var cancellationTokenSource = new CancellationTokenSource(); - - Logger.Info("{1} Begin transmitting over websocket to {0}", message.Connection.RemoteEndPoint, GetType().Name); - - var timer = SendOnTimer ? - new Timer(TimerCallback, message.Connection, Timeout.Infinite, Timeout.Infinite) : - null; - - var state = new TStateType - { - IntervalMs = periodMs, - InitialDelayMs = dueTimeMs - }; - - var semaphore = new SemaphoreSlim(1, 1); - - lock (ActiveConnections) - { - ActiveConnections.Add(new Tuple(message.Connection, cancellationTokenSource, timer, state, semaphore)); - } - - if (timer != null) - { - timer.Change(TimeSpan.FromMilliseconds(dueTimeMs), TimeSpan.FromMilliseconds(periodMs)); - } - } - - /// - /// Timers the callback. - /// - /// The state. - private void TimerCallback(object state) - { - var connection = (IWebSocketConnection)state; - - Tuple tuple; - - lock (ActiveConnections) - { - tuple = ActiveConnections.FirstOrDefault(c => c.Item1 == connection); - } - - if (tuple == null) - { - return; - } - - if (connection.State != WebSocketState.Open || tuple.Item2.IsCancellationRequested) - { - DisposeConnection(tuple); - return; - } - - SendData(tuple); - } - - protected void SendData(bool force) - { - List> tuples; - - lock (ActiveConnections) - { - tuples = ActiveConnections - .Where(c => - { - if (c.Item1.State == WebSocketState.Open && !c.Item2.IsCancellationRequested) - { - var state = c.Item4; - - if (force || (DateTime.UtcNow - state.DateLastSendUtc).TotalMilliseconds >= state.IntervalMs) - { - return true; - } - } - - return false; - }) - .ToList(); - } - - foreach (var tuple in tuples) - { - SendData(tuple); - } - } - - private async void SendData(Tuple tuple) - { - var connection = tuple.Item1; - - try - { - await tuple.Item5.WaitAsync(tuple.Item2.Token).ConfigureAwait(false); - - var state = tuple.Item4; - - var data = await GetDataToSend(state).ConfigureAwait(false); - - if (data != null) - { - await connection.SendAsync(new WebSocketMessage - { - MessageType = Name, - Data = data - - }, tuple.Item2.Token).ConfigureAwait(false); - - state.DateLastSendUtc = DateTime.UtcNow; - } - - tuple.Item5.Release(); - } - catch (OperationCanceledException) - { - if (tuple.Item2.IsCancellationRequested) - { - DisposeConnection(tuple); - } - } - catch (Exception ex) - { - Logger.ErrorException("Error sending web socket message {0}", ex, Name); - DisposeConnection(tuple); - } - } - - /// - /// Stops sending messages over a web socket - /// - /// The message. - private void Stop(WebSocketMessageInfo message) - { - lock (ActiveConnections) - { - var connection = ActiveConnections.FirstOrDefault(c => c.Item1 == message.Connection); - - if (connection != null) - { - DisposeConnection(connection); - } - } - } - - /// - /// Disposes the connection. - /// - /// The connection. - private void DisposeConnection(Tuple connection) - { - Logger.Info("{1} stop transmitting over websocket to {0}", connection.Item1.RemoteEndPoint, GetType().Name); - - var timer = connection.Item3; - - if (timer != null) - { - try - { - timer.Dispose(); - } - catch (ObjectDisposedException) - { - - } - } - - try - { - connection.Item2.Cancel(); - connection.Item2.Dispose(); - } - catch (ObjectDisposedException) - { - - } - - try - { - connection.Item5.Dispose(); - } - catch (ObjectDisposedException) - { - - } - - ActiveConnections.Remove(connection); - } - - /// - /// Releases unmanaged and - optionally - managed resources. - /// - /// true to release both managed and unmanaged resources; false to release only unmanaged resources. - protected virtual void Dispose(bool dispose) - { - if (dispose) - { - lock (ActiveConnections) - { - foreach (var connection in ActiveConnections.ToList()) - { - DisposeConnection(connection); - } - } - } - } - - /// - /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. - /// - public void Dispose() - { - Dispose(true); - } - } - - public class WebSocketListenerState - { - public DateTime DateLastSendUtc { get; set; } - public long InitialDelayMs { get; set; } - public long IntervalMs { get; set; } - } -} diff --git a/MediaBrowser.Common/Net/IWebSocketListener.cs b/MediaBrowser.Common/Net/IWebSocketListener.cs deleted file mode 100644 index 4b6c4111d..000000000 --- a/MediaBrowser.Common/Net/IWebSocketListener.cs +++ /dev/null @@ -1,17 +0,0 @@ -using System.Threading.Tasks; - -namespace MediaBrowser.Common.Net -{ - /// - ///This is an interface for listening to messages coming through a web socket connection - /// - public interface IWebSocketListener - { - /// - /// Processes the message. - /// - /// The message. - /// Task. - Task ProcessMessage(WebSocketMessageInfo message); - } -} diff --git a/MediaBrowser.Controller/MediaBrowser.Controller.csproj b/MediaBrowser.Controller/MediaBrowser.Controller.csproj index 3b9f3a5b2..21ae6bf61 100644 --- a/MediaBrowser.Controller/MediaBrowser.Controller.csproj +++ b/MediaBrowser.Controller/MediaBrowser.Controller.csproj @@ -207,6 +207,7 @@ + @@ -218,6 +219,7 @@ + diff --git a/MediaBrowser.Controller/Net/BasePeriodicWebSocketListener.cs b/MediaBrowser.Controller/Net/BasePeriodicWebSocketListener.cs new file mode 100644 index 000000000..f1e371c1a --- /dev/null +++ b/MediaBrowser.Controller/Net/BasePeriodicWebSocketListener.cs @@ -0,0 +1,327 @@ +using MediaBrowser.Common.Net; +using MediaBrowser.Model.Logging; +using MediaBrowser.Model.Net; +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; + +namespace MediaBrowser.Controller.Net +{ + /// + /// Starts sending data over a web socket periodically when a message is received, and then stops when a corresponding stop message is received + /// + /// The type of the T return data type. + /// The type of the T state type. + public abstract class BasePeriodicWebSocketListener : IWebSocketListener, IDisposable + where TStateType : WebSocketListenerState, new() + where TReturnDataType : class + { + /// + /// The _active connections + /// + protected readonly List> ActiveConnections = + new List>(); + + /// + /// Gets the name. + /// + /// The name. + protected abstract string Name { get; } + + /// + /// Gets the data to send. + /// + /// The state. + /// Task{`1}. + protected abstract Task GetDataToSend(TStateType state); + + /// + /// The logger + /// + protected ILogger Logger; + + /// + /// Initializes a new instance of the class. + /// + /// The logger. + /// logger + protected BasePeriodicWebSocketListener(ILogger logger) + { + if (logger == null) + { + throw new ArgumentNullException("logger"); + } + + Logger = logger; + } + + /// + /// The null task result + /// + protected Task NullTaskResult = Task.FromResult(true); + + /// + /// Processes the message. + /// + /// The message. + /// Task. + public Task ProcessMessage(WebSocketMessageInfo message) + { + if (message.MessageType.Equals(Name + "Start", StringComparison.OrdinalIgnoreCase)) + { + Start(message); + } + + if (message.MessageType.Equals(Name + "Stop", StringComparison.OrdinalIgnoreCase)) + { + Stop(message); + } + + return NullTaskResult; + } + + protected readonly CultureInfo UsCulture = new CultureInfo("en-US"); + + protected virtual bool SendOnTimer + { + get + { + return true; + } + } + + /// + /// Starts sending messages over a web socket + /// + /// The message. + private void Start(WebSocketMessageInfo message) + { + var vals = message.Data.Split(','); + + var dueTimeMs = long.Parse(vals[0], UsCulture); + var periodMs = long.Parse(vals[1], UsCulture); + + var cancellationTokenSource = new CancellationTokenSource(); + + Logger.Info("{1} Begin transmitting over websocket to {0}", message.Connection.RemoteEndPoint, GetType().Name); + + var timer = SendOnTimer ? + new Timer(TimerCallback, message.Connection, Timeout.Infinite, Timeout.Infinite) : + null; + + var state = new TStateType + { + IntervalMs = periodMs, + InitialDelayMs = dueTimeMs + }; + + var semaphore = new SemaphoreSlim(1, 1); + + lock (ActiveConnections) + { + ActiveConnections.Add(new Tuple(message.Connection, cancellationTokenSource, timer, state, semaphore)); + } + + if (timer != null) + { + timer.Change(TimeSpan.FromMilliseconds(dueTimeMs), TimeSpan.FromMilliseconds(periodMs)); + } + } + + /// + /// Timers the callback. + /// + /// The state. + private void TimerCallback(object state) + { + var connection = (IWebSocketConnection)state; + + Tuple tuple; + + lock (ActiveConnections) + { + tuple = ActiveConnections.FirstOrDefault(c => c.Item1 == connection); + } + + if (tuple == null) + { + return; + } + + if (connection.State != WebSocketState.Open || tuple.Item2.IsCancellationRequested) + { + DisposeConnection(tuple); + return; + } + + SendData(tuple); + } + + protected void SendData(bool force) + { + List> tuples; + + lock (ActiveConnections) + { + tuples = ActiveConnections + .Where(c => + { + if (c.Item1.State == WebSocketState.Open && !c.Item2.IsCancellationRequested) + { + var state = c.Item4; + + if (force || (DateTime.UtcNow - state.DateLastSendUtc).TotalMilliseconds >= state.IntervalMs) + { + return true; + } + } + + return false; + }) + .ToList(); + } + + foreach (var tuple in tuples) + { + SendData(tuple); + } + } + + private async void SendData(Tuple tuple) + { + var connection = tuple.Item1; + + try + { + await tuple.Item5.WaitAsync(tuple.Item2.Token).ConfigureAwait(false); + + var state = tuple.Item4; + + var data = await GetDataToSend(state).ConfigureAwait(false); + + if (data != null) + { + await connection.SendAsync(new WebSocketMessage + { + MessageType = Name, + Data = data + + }, tuple.Item2.Token).ConfigureAwait(false); + + state.DateLastSendUtc = DateTime.UtcNow; + } + + tuple.Item5.Release(); + } + catch (OperationCanceledException) + { + if (tuple.Item2.IsCancellationRequested) + { + DisposeConnection(tuple); + } + } + catch (Exception ex) + { + Logger.ErrorException("Error sending web socket message {0}", ex, Name); + DisposeConnection(tuple); + } + } + + /// + /// Stops sending messages over a web socket + /// + /// The message. + private void Stop(WebSocketMessageInfo message) + { + lock (ActiveConnections) + { + var connection = ActiveConnections.FirstOrDefault(c => c.Item1 == message.Connection); + + if (connection != null) + { + DisposeConnection(connection); + } + } + } + + /// + /// Disposes the connection. + /// + /// The connection. + private void DisposeConnection(Tuple connection) + { + Logger.Info("{1} stop transmitting over websocket to {0}", connection.Item1.RemoteEndPoint, GetType().Name); + + var timer = connection.Item3; + + if (timer != null) + { + try + { + timer.Dispose(); + } + catch (ObjectDisposedException) + { + + } + } + + try + { + connection.Item2.Cancel(); + connection.Item2.Dispose(); + } + catch (ObjectDisposedException) + { + + } + + try + { + connection.Item5.Dispose(); + } + catch (ObjectDisposedException) + { + + } + + ActiveConnections.Remove(connection); + } + + /// + /// Releases unmanaged and - optionally - managed resources. + /// + /// true to release both managed and unmanaged resources; false to release only unmanaged resources. + protected virtual void Dispose(bool dispose) + { + if (dispose) + { + lock (ActiveConnections) + { + foreach (var connection in ActiveConnections.ToList()) + { + DisposeConnection(connection); + } + } + } + } + + /// + /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. + /// + public void Dispose() + { + Dispose(true); + } + } + + public class WebSocketListenerState + { + public DateTime DateLastSendUtc { get; set; } + public long InitialDelayMs { get; set; } + public long IntervalMs { get; set; } + } +} diff --git a/MediaBrowser.Controller/Net/IWebSocketListener.cs b/MediaBrowser.Controller/Net/IWebSocketListener.cs new file mode 100644 index 000000000..2b4fc7676 --- /dev/null +++ b/MediaBrowser.Controller/Net/IWebSocketListener.cs @@ -0,0 +1,18 @@ +using MediaBrowser.Common.Net; +using System.Threading.Tasks; + +namespace MediaBrowser.Controller.Net +{ + /// + ///This is an interface for listening to messages coming through a web socket connection + /// + public interface IWebSocketListener + { + /// + /// Processes the message. + /// + /// The message. + /// Task. + Task ProcessMessage(WebSocketMessageInfo message); + } +} diff --git a/MediaBrowser.Server.Implementations/Session/SessionWebSocketListener.cs b/MediaBrowser.Server.Implementations/Session/SessionWebSocketListener.cs index ed590a1f2..36a7fcbd8 100644 --- a/MediaBrowser.Server.Implementations/Session/SessionWebSocketListener.cs +++ b/MediaBrowser.Server.Implementations/Session/SessionWebSocketListener.cs @@ -1,4 +1,5 @@ using MediaBrowser.Common.Net; +using MediaBrowser.Controller.Net; using MediaBrowser.Controller.Session; using MediaBrowser.Model.Logging; using MediaBrowser.Model.Serialization; -- cgit v1.2.3 From 0840bb9ba246d928161516e65a7b12e7ed08701b Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sat, 27 Dec 2014 13:06:32 -0500 Subject: move web socket classes to server project --- MediaBrowser.Common/MediaBrowser.Common.csproj | 4 -- MediaBrowser.Common/Net/IWebSocket.cs | 54 ---------------- MediaBrowser.Common/Net/IWebSocketConnection.cs | 72 --------------------- .../Net/WebSocketConnectEventArgs.cs | 21 ------- MediaBrowser.Common/Net/WebSocketMessageInfo.cs | 16 ----- MediaBrowser.Common/Plugins/BasePlugin.cs | 1 - .../Entities/IHasMediaSources.cs | 4 +- .../MediaBrowser.Controller.csproj | 4 ++ .../MediaEncoding/MediaStreamSelector.cs | 12 ++-- MediaBrowser.Controller/Net/IWebSocket.cs | 54 ++++++++++++++++ .../Net/IWebSocketConnection.cs | 73 ++++++++++++++++++++++ .../Net/WebSocketConnectEventArgs.cs | 21 +++++++ .../Net/WebSocketMessageInfo.cs | 16 +++++ MediaBrowser.Dlna/Main/DlnaEntryPoint.cs | 1 + .../Connect/ConnectEntryPoint.cs | 1 + .../EntryPoints/UdpServerEntryPoint.cs | 1 + .../EntryPoints/UsageEntryPoint.cs | 1 + .../EntryPoints/UsageReporter.cs | 1 + .../HttpServer/IHttpListener.cs | 1 + .../HttpServer/NativeWebSocket.cs | 1 + .../HttpServer/NetListener/HttpListenerServer.cs | 1 + .../HttpServer/SocketSharp/SharpWebSocket.cs | 1 + .../SocketSharp/WebSocketSharpListener.cs | 1 + .../ServerManager/WebSocketConnection.cs | 1 + .../Session/WebSocketController.cs | 1 + .../Udp/UdpServer.cs | 1 + MediaBrowser.Server.Mono/Native/BaseMonoApp.cs | 1 + .../Networking/NetworkManager.cs | 1 + MediaBrowser.Server.Startup.Common/INativeApp.cs | 1 + .../Native/WindowsApp.cs | 1 + .../Networking/NetworkManager.cs | 1 + 31 files changed, 193 insertions(+), 177 deletions(-) delete mode 100644 MediaBrowser.Common/Net/IWebSocket.cs delete mode 100644 MediaBrowser.Common/Net/IWebSocketConnection.cs delete mode 100644 MediaBrowser.Common/Net/WebSocketConnectEventArgs.cs delete mode 100644 MediaBrowser.Common/Net/WebSocketMessageInfo.cs create mode 100644 MediaBrowser.Controller/Net/IWebSocket.cs create mode 100644 MediaBrowser.Controller/Net/IWebSocketConnection.cs create mode 100644 MediaBrowser.Controller/Net/WebSocketConnectEventArgs.cs create mode 100644 MediaBrowser.Controller/Net/WebSocketMessageInfo.cs (limited to 'MediaBrowser.Server.Implementations/Session') diff --git a/MediaBrowser.Common/MediaBrowser.Common.csproj b/MediaBrowser.Common/MediaBrowser.Common.csproj index b4cc17f51..c46dd4a4f 100644 --- a/MediaBrowser.Common/MediaBrowser.Common.csproj +++ b/MediaBrowser.Common/MediaBrowser.Common.csproj @@ -69,10 +69,6 @@ - - - - diff --git a/MediaBrowser.Common/Net/IWebSocket.cs b/MediaBrowser.Common/Net/IWebSocket.cs deleted file mode 100644 index b31a95319..000000000 --- a/MediaBrowser.Common/Net/IWebSocket.cs +++ /dev/null @@ -1,54 +0,0 @@ -using MediaBrowser.Model.Net; -using System; -using System.Threading; -using System.Threading.Tasks; - -namespace MediaBrowser.Common.Net -{ - /// - /// Interface IWebSocket - /// - public interface IWebSocket : IDisposable - { - /// - /// Occurs when [closed]. - /// - event EventHandler Closed; - - /// - /// Gets or sets the state. - /// - /// The state. - WebSocketState State { get; } - - /// - /// Gets or sets the receive action. - /// - /// The receive action. - Action OnReceiveBytes { get; set; } - - /// - /// Gets or sets the on receive. - /// - /// The on receive. - Action OnReceive { get; set; } - - /// - /// Sends the async. - /// - /// The bytes. - /// if set to true [end of message]. - /// The cancellation token. - /// Task. - Task SendAsync(byte[] bytes, bool endOfMessage, CancellationToken cancellationToken); - - /// - /// Sends the asynchronous. - /// - /// The text. - /// if set to true [end of message]. - /// The cancellation token. - /// Task. - Task SendAsync(string text, bool endOfMessage, CancellationToken cancellationToken); - } -} diff --git a/MediaBrowser.Common/Net/IWebSocketConnection.cs b/MediaBrowser.Common/Net/IWebSocketConnection.cs deleted file mode 100644 index b7715e20b..000000000 --- a/MediaBrowser.Common/Net/IWebSocketConnection.cs +++ /dev/null @@ -1,72 +0,0 @@ -using MediaBrowser.Model.Net; -using System; -using System.Threading; -using System.Threading.Tasks; - -namespace MediaBrowser.Common.Net -{ - public interface IWebSocketConnection : IDisposable - { - /// - /// Occurs when [closed]. - /// - event EventHandler Closed; - - /// - /// Gets the id. - /// - /// The id. - Guid Id { get; } - - /// - /// Gets the last activity date. - /// - /// The last activity date. - DateTime LastActivityDate { get; } - - /// - /// Gets or sets the receive action. - /// - /// The receive action. - Action OnReceive { get; set; } - - /// - /// Gets the state. - /// - /// The state. - WebSocketState State { get; } - - /// - /// Gets the remote end point. - /// - /// The remote end point. - string RemoteEndPoint { get; } - - /// - /// Sends a message asynchronously. - /// - /// - /// The message. - /// The cancellation token. - /// Task. - /// message - Task SendAsync(WebSocketMessage message, CancellationToken cancellationToken); - - /// - /// Sends a message asynchronously. - /// - /// The buffer. - /// The cancellation token. - /// Task. - Task SendAsync(byte[] buffer, CancellationToken cancellationToken); - - /// - /// Sends a message asynchronously. - /// - /// The text. - /// The cancellation token. - /// Task. - /// buffer - Task SendAsync(string text, CancellationToken cancellationToken); - } -} \ No newline at end of file diff --git a/MediaBrowser.Common/Net/WebSocketConnectEventArgs.cs b/MediaBrowser.Common/Net/WebSocketConnectEventArgs.cs deleted file mode 100644 index ce22c9520..000000000 --- a/MediaBrowser.Common/Net/WebSocketConnectEventArgs.cs +++ /dev/null @@ -1,21 +0,0 @@ -using System; - -namespace MediaBrowser.Common.Net -{ - /// - /// Class WebSocketConnectEventArgs - /// - public class WebSocketConnectEventArgs : EventArgs - { - /// - /// Gets or sets the web socket. - /// - /// The web socket. - public IWebSocket WebSocket { get; set; } - /// - /// Gets or sets the endpoint. - /// - /// The endpoint. - public string Endpoint { get; set; } - } -} diff --git a/MediaBrowser.Common/Net/WebSocketMessageInfo.cs b/MediaBrowser.Common/Net/WebSocketMessageInfo.cs deleted file mode 100644 index c1f935a7b..000000000 --- a/MediaBrowser.Common/Net/WebSocketMessageInfo.cs +++ /dev/null @@ -1,16 +0,0 @@ -using MediaBrowser.Model.Net; - -namespace MediaBrowser.Common.Net -{ - /// - /// Class WebSocketMessageInfo - /// - public class WebSocketMessageInfo : WebSocketMessage - { - /// - /// Gets or sets the connection. - /// - /// The connection. - public IWebSocketConnection Connection { get; set; } - } -} \ No newline at end of file diff --git a/MediaBrowser.Common/Plugins/BasePlugin.cs b/MediaBrowser.Common/Plugins/BasePlugin.cs index ce068463e..9d0133c67 100644 --- a/MediaBrowser.Common/Plugins/BasePlugin.cs +++ b/MediaBrowser.Common/Plugins/BasePlugin.cs @@ -5,7 +5,6 @@ using System; using System.IO; using System.Reflection; using System.Runtime.InteropServices; -using System.Threading; namespace MediaBrowser.Common.Plugins { diff --git a/MediaBrowser.Controller/Entities/IHasMediaSources.cs b/MediaBrowser.Controller/Entities/IHasMediaSources.cs index d487362f5..98d268298 100644 --- a/MediaBrowser.Controller/Entities/IHasMediaSources.cs +++ b/MediaBrowser.Controller/Entities/IHasMediaSources.cs @@ -49,8 +49,8 @@ namespace MediaBrowser.Controller.Entities : new[] { user.Configuration.AudioLanguagePreference }; var preferredSubs = string.IsNullOrEmpty(user.Configuration.SubtitleLanguagePreference) - ? new string[] { } - : new[] { user.Configuration.SubtitleLanguagePreference }; + ? new List { } + : new List { user.Configuration.SubtitleLanguagePreference }; foreach (var source in sources) { diff --git a/MediaBrowser.Controller/MediaBrowser.Controller.csproj b/MediaBrowser.Controller/MediaBrowser.Controller.csproj index 21ae6bf61..3ed87ced8 100644 --- a/MediaBrowser.Controller/MediaBrowser.Controller.csproj +++ b/MediaBrowser.Controller/MediaBrowser.Controller.csproj @@ -219,11 +219,15 @@ + + + + diff --git a/MediaBrowser.Controller/MediaEncoding/MediaStreamSelector.cs b/MediaBrowser.Controller/MediaEncoding/MediaStreamSelector.cs index 58a68c257..4a807df7a 100644 --- a/MediaBrowser.Controller/MediaEncoding/MediaStreamSelector.cs +++ b/MediaBrowser.Controller/MediaEncoding/MediaStreamSelector.cs @@ -34,15 +34,13 @@ namespace MediaBrowser.Controller.MediaEncoding } public static int? GetDefaultSubtitleStreamIndex(List streams, - IEnumerable preferredLanguages, + List preferredLanguages, SubtitlePlaybackMode mode, string audioTrackLanguage) { - var languages = preferredLanguages.ToList(); - streams = GetSortedStreams(streams, MediaStreamType.Subtitle, languages).ToList(); + streams = GetSortedStreams(streams, MediaStreamType.Subtitle, preferredLanguages).ToList(); var full = streams.Where(s => !s.IsForced); - var forced = streams.Where(s => s.IsForced && string.Equals(s.Language, audioTrackLanguage, StringComparison.OrdinalIgnoreCase)); MediaStream stream = null; @@ -54,9 +52,9 @@ namespace MediaBrowser.Controller.MediaEncoding if (mode == SubtitlePlaybackMode.Default) { // if the audio language is not understood by the user, load their preferred subs, if there are any - if (!ContainsOrdinal(languages, audioTrackLanguage)) + if (!ContainsOrdinal(preferredLanguages, audioTrackLanguage)) { - stream = full.FirstOrDefault(s => ContainsOrdinal(languages, s.Language)); + stream = full.FirstOrDefault(s => ContainsOrdinal(preferredLanguages, s.Language)); } } else if (mode == SubtitlePlaybackMode.Always) @@ -66,7 +64,7 @@ namespace MediaBrowser.Controller.MediaEncoding } // load forced subs if we have found no suitable full subtitles - stream = stream ?? forced.FirstOrDefault(); + stream = stream ?? streams.FirstOrDefault(s => s.IsForced && string.Equals(s.Language, audioTrackLanguage, StringComparison.OrdinalIgnoreCase)); if (stream != null) { diff --git a/MediaBrowser.Controller/Net/IWebSocket.cs b/MediaBrowser.Controller/Net/IWebSocket.cs new file mode 100644 index 000000000..b88f2c389 --- /dev/null +++ b/MediaBrowser.Controller/Net/IWebSocket.cs @@ -0,0 +1,54 @@ +using MediaBrowser.Model.Net; +using System; +using System.Threading; +using System.Threading.Tasks; + +namespace MediaBrowser.Controller.Net +{ + /// + /// Interface IWebSocket + /// + public interface IWebSocket : IDisposable + { + /// + /// Occurs when [closed]. + /// + event EventHandler Closed; + + /// + /// Gets or sets the state. + /// + /// The state. + WebSocketState State { get; } + + /// + /// Gets or sets the receive action. + /// + /// The receive action. + Action OnReceiveBytes { get; set; } + + /// + /// Gets or sets the on receive. + /// + /// The on receive. + Action OnReceive { get; set; } + + /// + /// Sends the async. + /// + /// The bytes. + /// if set to true [end of message]. + /// The cancellation token. + /// Task. + Task SendAsync(byte[] bytes, bool endOfMessage, CancellationToken cancellationToken); + + /// + /// Sends the asynchronous. + /// + /// The text. + /// if set to true [end of message]. + /// The cancellation token. + /// Task. + Task SendAsync(string text, bool endOfMessage, CancellationToken cancellationToken); + } +} diff --git a/MediaBrowser.Controller/Net/IWebSocketConnection.cs b/MediaBrowser.Controller/Net/IWebSocketConnection.cs new file mode 100644 index 000000000..83ead5a12 --- /dev/null +++ b/MediaBrowser.Controller/Net/IWebSocketConnection.cs @@ -0,0 +1,73 @@ +using MediaBrowser.Common.Net; +using MediaBrowser.Model.Net; +using System; +using System.Threading; +using System.Threading.Tasks; + +namespace MediaBrowser.Controller.Net +{ + public interface IWebSocketConnection : IDisposable + { + /// + /// Occurs when [closed]. + /// + event EventHandler Closed; + + /// + /// Gets the id. + /// + /// The id. + Guid Id { get; } + + /// + /// Gets the last activity date. + /// + /// The last activity date. + DateTime LastActivityDate { get; } + + /// + /// Gets or sets the receive action. + /// + /// The receive action. + Action OnReceive { get; set; } + + /// + /// Gets the state. + /// + /// The state. + WebSocketState State { get; } + + /// + /// Gets the remote end point. + /// + /// The remote end point. + string RemoteEndPoint { get; } + + /// + /// Sends a message asynchronously. + /// + /// + /// The message. + /// The cancellation token. + /// Task. + /// message + Task SendAsync(WebSocketMessage message, CancellationToken cancellationToken); + + /// + /// Sends a message asynchronously. + /// + /// The buffer. + /// The cancellation token. + /// Task. + Task SendAsync(byte[] buffer, CancellationToken cancellationToken); + + /// + /// Sends a message asynchronously. + /// + /// The text. + /// The cancellation token. + /// Task. + /// buffer + Task SendAsync(string text, CancellationToken cancellationToken); + } +} \ No newline at end of file diff --git a/MediaBrowser.Controller/Net/WebSocketConnectEventArgs.cs b/MediaBrowser.Controller/Net/WebSocketConnectEventArgs.cs new file mode 100644 index 000000000..394fcd92f --- /dev/null +++ b/MediaBrowser.Controller/Net/WebSocketConnectEventArgs.cs @@ -0,0 +1,21 @@ +using System; + +namespace MediaBrowser.Controller.Net +{ + /// + /// Class WebSocketConnectEventArgs + /// + public class WebSocketConnectEventArgs : EventArgs + { + /// + /// Gets or sets the web socket. + /// + /// The web socket. + public IWebSocket WebSocket { get; set; } + /// + /// Gets or sets the endpoint. + /// + /// The endpoint. + public string Endpoint { get; set; } + } +} diff --git a/MediaBrowser.Controller/Net/WebSocketMessageInfo.cs b/MediaBrowser.Controller/Net/WebSocketMessageInfo.cs new file mode 100644 index 000000000..332f16420 --- /dev/null +++ b/MediaBrowser.Controller/Net/WebSocketMessageInfo.cs @@ -0,0 +1,16 @@ +using MediaBrowser.Model.Net; + +namespace MediaBrowser.Controller.Net +{ + /// + /// Class WebSocketMessageInfo + /// + public class WebSocketMessageInfo : WebSocketMessage + { + /// + /// Gets or sets the connection. + /// + /// The connection. + public IWebSocketConnection Connection { get; set; } + } +} \ No newline at end of file diff --git a/MediaBrowser.Dlna/Main/DlnaEntryPoint.cs b/MediaBrowser.Dlna/Main/DlnaEntryPoint.cs index 810b1e568..dc4aff190 100644 --- a/MediaBrowser.Dlna/Main/DlnaEntryPoint.cs +++ b/MediaBrowser.Dlna/Main/DlnaEntryPoint.cs @@ -7,6 +7,7 @@ using MediaBrowser.Controller.Dlna; using MediaBrowser.Controller.Drawing; using MediaBrowser.Controller.Library; using MediaBrowser.Controller.Localization; +using MediaBrowser.Controller.Net; using MediaBrowser.Controller.Persistence; using MediaBrowser.Controller.Plugins; using MediaBrowser.Controller.Session; diff --git a/MediaBrowser.Server.Implementations/Connect/ConnectEntryPoint.cs b/MediaBrowser.Server.Implementations/Connect/ConnectEntryPoint.cs index 52ec5c9b1..5acec2d6b 100644 --- a/MediaBrowser.Server.Implementations/Connect/ConnectEntryPoint.cs +++ b/MediaBrowser.Server.Implementations/Connect/ConnectEntryPoint.cs @@ -1,6 +1,7 @@ using MediaBrowser.Common.Configuration; using MediaBrowser.Common.Net; using MediaBrowser.Controller.Connect; +using MediaBrowser.Controller.Net; using MediaBrowser.Controller.Plugins; using MediaBrowser.Model.Logging; using System; diff --git a/MediaBrowser.Server.Implementations/EntryPoints/UdpServerEntryPoint.cs b/MediaBrowser.Server.Implementations/EntryPoints/UdpServerEntryPoint.cs index 386c16513..d97ccb9bd 100644 --- a/MediaBrowser.Server.Implementations/EntryPoints/UdpServerEntryPoint.cs +++ b/MediaBrowser.Server.Implementations/EntryPoints/UdpServerEntryPoint.cs @@ -1,5 +1,6 @@ using MediaBrowser.Common.Net; using MediaBrowser.Controller; +using MediaBrowser.Controller.Net; using MediaBrowser.Controller.Plugins; using MediaBrowser.Model.Logging; using MediaBrowser.Model.Serialization; diff --git a/MediaBrowser.Server.Implementations/EntryPoints/UsageEntryPoint.cs b/MediaBrowser.Server.Implementations/EntryPoints/UsageEntryPoint.cs index de53201c9..098a1d2bd 100644 --- a/MediaBrowser.Server.Implementations/EntryPoints/UsageEntryPoint.cs +++ b/MediaBrowser.Server.Implementations/EntryPoints/UsageEntryPoint.cs @@ -2,6 +2,7 @@ using MediaBrowser.Common.Extensions; using MediaBrowser.Common.Implementations.Security; using MediaBrowser.Common.Net; +using MediaBrowser.Controller.Net; using MediaBrowser.Controller.Plugins; using MediaBrowser.Controller.Session; using MediaBrowser.Model.Logging; diff --git a/MediaBrowser.Server.Implementations/EntryPoints/UsageReporter.cs b/MediaBrowser.Server.Implementations/EntryPoints/UsageReporter.cs index 36ba55828..940be6d02 100644 --- a/MediaBrowser.Server.Implementations/EntryPoints/UsageReporter.cs +++ b/MediaBrowser.Server.Implementations/EntryPoints/UsageReporter.cs @@ -4,6 +4,7 @@ using System; using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; +using MediaBrowser.Controller.Net; namespace MediaBrowser.Server.Implementations.EntryPoints { diff --git a/MediaBrowser.Server.Implementations/HttpServer/IHttpListener.cs b/MediaBrowser.Server.Implementations/HttpServer/IHttpListener.cs index 86e8856cf..dfde34e25 100644 --- a/MediaBrowser.Server.Implementations/HttpServer/IHttpListener.cs +++ b/MediaBrowser.Server.Implementations/HttpServer/IHttpListener.cs @@ -1,5 +1,6 @@ using System.Threading.Tasks; using MediaBrowser.Common.Net; +using MediaBrowser.Controller.Net; using ServiceStack.Web; using System; using System.Collections.Generic; diff --git a/MediaBrowser.Server.Implementations/HttpServer/NativeWebSocket.cs b/MediaBrowser.Server.Implementations/HttpServer/NativeWebSocket.cs index 8cc614fe5..f8e8bb9dd 100644 --- a/MediaBrowser.Server.Implementations/HttpServer/NativeWebSocket.cs +++ b/MediaBrowser.Server.Implementations/HttpServer/NativeWebSocket.cs @@ -1,6 +1,7 @@ using System.Text; using MediaBrowser.Common.Events; using MediaBrowser.Common.Net; +using MediaBrowser.Controller.Net; using MediaBrowser.Model.Logging; using System; using System.Net.WebSockets; diff --git a/MediaBrowser.Server.Implementations/HttpServer/NetListener/HttpListenerServer.cs b/MediaBrowser.Server.Implementations/HttpServer/NetListener/HttpListenerServer.cs index 2d41cc26f..9635854d4 100644 --- a/MediaBrowser.Server.Implementations/HttpServer/NetListener/HttpListenerServer.cs +++ b/MediaBrowser.Server.Implementations/HttpServer/NetListener/HttpListenerServer.cs @@ -1,4 +1,5 @@ using MediaBrowser.Common.Net; +using MediaBrowser.Controller.Net; using MediaBrowser.Model.Logging; using ServiceStack; using ServiceStack.Host.HttpListener; diff --git a/MediaBrowser.Server.Implementations/HttpServer/SocketSharp/SharpWebSocket.cs b/MediaBrowser.Server.Implementations/HttpServer/SocketSharp/SharpWebSocket.cs index 7ff3a1247..354b1e20f 100644 --- a/MediaBrowser.Server.Implementations/HttpServer/SocketSharp/SharpWebSocket.cs +++ b/MediaBrowser.Server.Implementations/HttpServer/SocketSharp/SharpWebSocket.cs @@ -1,6 +1,7 @@ using System.Text; using MediaBrowser.Common.Events; using MediaBrowser.Common.Net; +using MediaBrowser.Controller.Net; using MediaBrowser.Model.Logging; using System; using System.Threading; diff --git a/MediaBrowser.Server.Implementations/HttpServer/SocketSharp/WebSocketSharpListener.cs b/MediaBrowser.Server.Implementations/HttpServer/SocketSharp/WebSocketSharpListener.cs index 9deb34e91..ffaecc0d5 100644 --- a/MediaBrowser.Server.Implementations/HttpServer/SocketSharp/WebSocketSharpListener.cs +++ b/MediaBrowser.Server.Implementations/HttpServer/SocketSharp/WebSocketSharpListener.cs @@ -1,4 +1,5 @@ using MediaBrowser.Common.Net; +using MediaBrowser.Controller.Net; using MediaBrowser.Model.Logging; using ServiceStack; using ServiceStack.Web; diff --git a/MediaBrowser.Server.Implementations/ServerManager/WebSocketConnection.cs b/MediaBrowser.Server.Implementations/ServerManager/WebSocketConnection.cs index 3c3d7740a..a8950da89 100644 --- a/MediaBrowser.Server.Implementations/ServerManager/WebSocketConnection.cs +++ b/MediaBrowser.Server.Implementations/ServerManager/WebSocketConnection.cs @@ -1,5 +1,6 @@ using MediaBrowser.Common.Events; using MediaBrowser.Common.Net; +using MediaBrowser.Controller.Net; using MediaBrowser.Model.Logging; using MediaBrowser.Model.Net; using MediaBrowser.Model.Serialization; diff --git a/MediaBrowser.Server.Implementations/Session/WebSocketController.cs b/MediaBrowser.Server.Implementations/Session/WebSocketController.cs index 0756aa1ec..0788ed2ce 100644 --- a/MediaBrowser.Server.Implementations/Session/WebSocketController.cs +++ b/MediaBrowser.Server.Implementations/Session/WebSocketController.cs @@ -1,4 +1,5 @@ using MediaBrowser.Common.Net; +using MediaBrowser.Controller.Net; using MediaBrowser.Controller.Session; using MediaBrowser.Model.Entities; using MediaBrowser.Model.Logging; diff --git a/MediaBrowser.Server.Implementations/Udp/UdpServer.cs b/MediaBrowser.Server.Implementations/Udp/UdpServer.cs index 91a4940ae..d80e0b66e 100644 --- a/MediaBrowser.Server.Implementations/Udp/UdpServer.cs +++ b/MediaBrowser.Server.Implementations/Udp/UdpServer.cs @@ -1,5 +1,6 @@ using MediaBrowser.Common.Net; using MediaBrowser.Controller; +using MediaBrowser.Controller.Net; using MediaBrowser.Model.ApiClient; using MediaBrowser.Model.Logging; using MediaBrowser.Model.Serialization; diff --git a/MediaBrowser.Server.Mono/Native/BaseMonoApp.cs b/MediaBrowser.Server.Mono/Native/BaseMonoApp.cs index 39d2d52d7..227c32242 100644 --- a/MediaBrowser.Server.Mono/Native/BaseMonoApp.cs +++ b/MediaBrowser.Server.Mono/Native/BaseMonoApp.cs @@ -1,4 +1,5 @@ using MediaBrowser.Common.Net; +using MediaBrowser.Controller.Net; using MediaBrowser.IsoMounter; using MediaBrowser.Model.Logging; using MediaBrowser.Server.Mono.Networking; diff --git a/MediaBrowser.Server.Mono/Networking/NetworkManager.cs b/MediaBrowser.Server.Mono/Networking/NetworkManager.cs index 60c250115..d76a7c7ee 100644 --- a/MediaBrowser.Server.Mono/Networking/NetworkManager.cs +++ b/MediaBrowser.Server.Mono/Networking/NetworkManager.cs @@ -1,5 +1,6 @@ using MediaBrowser.Common.Implementations.Networking; using MediaBrowser.Common.Net; +using MediaBrowser.Controller.Net; using MediaBrowser.Model.IO; using MediaBrowser.Model.Logging; using MediaBrowser.Model.Net; diff --git a/MediaBrowser.Server.Startup.Common/INativeApp.cs b/MediaBrowser.Server.Startup.Common/INativeApp.cs index 5042e1cea..cf0135fa8 100644 --- a/MediaBrowser.Server.Startup.Common/INativeApp.cs +++ b/MediaBrowser.Server.Startup.Common/INativeApp.cs @@ -1,4 +1,5 @@ using MediaBrowser.Common.Net; +using MediaBrowser.Controller.Net; using MediaBrowser.Model.Logging; using System.Collections.Generic; using System.Reflection; diff --git a/MediaBrowser.ServerApplication/Native/WindowsApp.cs b/MediaBrowser.ServerApplication/Native/WindowsApp.cs index 9a37c268c..071216418 100644 --- a/MediaBrowser.ServerApplication/Native/WindowsApp.cs +++ b/MediaBrowser.ServerApplication/Native/WindowsApp.cs @@ -1,4 +1,5 @@ using MediaBrowser.Common.Net; +using MediaBrowser.Controller.Net; using MediaBrowser.IsoMounter; using MediaBrowser.Model.Logging; using MediaBrowser.Server.Startup.Common; diff --git a/MediaBrowser.ServerApplication/Networking/NetworkManager.cs b/MediaBrowser.ServerApplication/Networking/NetworkManager.cs index fc4d26363..4dbe0f347 100644 --- a/MediaBrowser.ServerApplication/Networking/NetworkManager.cs +++ b/MediaBrowser.ServerApplication/Networking/NetworkManager.cs @@ -1,5 +1,6 @@ using MediaBrowser.Common.Implementations.Networking; using MediaBrowser.Common.Net; +using MediaBrowser.Controller.Net; using MediaBrowser.Model.IO; using MediaBrowser.Model.Logging; using MediaBrowser.Model.Net; -- cgit v1.2.3 From 7bce2e04b618671faafc32a39978d0d8c87cba21 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sat, 27 Dec 2014 17:52:41 -0500 Subject: sync updates --- MediaBrowser.Api/Sync/SyncService.cs | 12 ++++++++ MediaBrowser.Controller/Entities/BaseItem.cs | 2 +- .../Net/IWebSocketConnection.cs | 3 +- MediaBrowser.Controller/Sync/ISyncManager.cs | 14 ++++----- MediaBrowser.Dlna/Main/DlnaEntryPoint.cs | 1 - .../Configuration/ServerConfiguration.cs | 2 ++ MediaBrowser.Model/Sync/DeviceFileInfo.cs | 2 +- MediaBrowser.Model/Sync/ItemFIleInfo.cs | 2 +- .../Connect/ConnectEntryPoint.cs | 1 - .../EntryPoints/UdpServerEntryPoint.cs | 1 - .../EntryPoints/UsageEntryPoint.cs | 2 -- .../EntryPoints/UsageReporter.cs | 1 - .../HttpServer/HttpListenerHost.cs | 16 ++++++---- .../HttpServer/IHttpListener.cs | 5 ++-- .../HttpServer/NativeWebSocket.cs | 5 ++-- .../HttpServer/NetListener/HttpListenerServer.cs | 3 +- .../HttpServer/SocketSharp/SharpWebSocket.cs | 5 +--- .../SocketSharp/WebSocketSharpListener.cs | 3 +- .../ServerManager/WebSocketConnection.cs | 1 - .../Session/WebSocketController.cs | 3 +- .../Sync/SyncManager.cs | 20 +++++++++---- .../Sync/SyncRepository.cs | 16 ++++++---- .../Udp/UdpServer.cs | 1 - MediaBrowser.Server.Mac/Native/BaseMonoApp.cs | 2 +- MediaBrowser.Server.Mono/Native/BaseMonoApp.cs | 3 +- .../Networking/NetworkManager.cs | 1 - .../ApplicationHost.cs | 35 +++++++++++----------- MediaBrowser.Server.Startup.Common/INativeApp.cs | 6 ++-- .../Native/RegisterServer.bat | 18 ++++------- .../Native/ServerAuthorization.cs | 9 ++---- .../Native/WindowsApp.cs | 5 ++-- .../Networking/NetworkManager.cs | 1 - Nuget/MediaBrowser.Common.Internal.nuspec | 4 +-- Nuget/MediaBrowser.Common.nuspec | 2 +- Nuget/MediaBrowser.Model.Signed.nuspec | 2 +- Nuget/MediaBrowser.Server.Core.nuspec | 4 +-- 36 files changed, 109 insertions(+), 104 deletions(-) (limited to 'MediaBrowser.Server.Implementations/Session') diff --git a/MediaBrowser.Api/Sync/SyncService.cs b/MediaBrowser.Api/Sync/SyncService.cs index ab4e75923..0036b316f 100644 --- a/MediaBrowser.Api/Sync/SyncService.cs +++ b/MediaBrowser.Api/Sync/SyncService.cs @@ -85,6 +85,13 @@ namespace MediaBrowser.Api.Sync { } + [Route("/Sync/Items/Ready", "GET", Summary = "Gets ready to download sync items.")] + public class GetReadySyncItems : IReturn> + { + [ApiMember(Name = "TargetId", Description = "TargetId", IsRequired = true, DataType = "string", ParameterType = "query", Verb = "GET")] + public string TargetId { get; set; } + } + [Authenticated] public class SyncService : BaseApiService { @@ -207,5 +214,10 @@ namespace MediaBrowser.Api.Sync await _syncManager.ReportOfflineAction(action).ConfigureAwait(false); } } + + public object Get(GetReadySyncItems request) + { + return ToOptimizedResult(_syncManager.GetReadySyncItems(request.TargetId)); + } } } diff --git a/MediaBrowser.Controller/Entities/BaseItem.cs b/MediaBrowser.Controller/Entities/BaseItem.cs index aea04187d..90427de75 100644 --- a/MediaBrowser.Controller/Entities/BaseItem.cs +++ b/MediaBrowser.Controller/Entities/BaseItem.cs @@ -14,6 +14,7 @@ using MediaBrowser.Model.Dto; using MediaBrowser.Model.Entities; using MediaBrowser.Model.Library; using MediaBrowser.Model.Logging; +using MediaBrowser.Model.Users; using System; using System.Collections.Generic; using System.IO; @@ -21,7 +22,6 @@ using System.Linq; using System.Runtime.Serialization; using System.Threading; using System.Threading.Tasks; -using MediaBrowser.Model.Users; namespace MediaBrowser.Controller.Entities { diff --git a/MediaBrowser.Controller/Net/IWebSocketConnection.cs b/MediaBrowser.Controller/Net/IWebSocketConnection.cs index 83ead5a12..37fd6708d 100644 --- a/MediaBrowser.Controller/Net/IWebSocketConnection.cs +++ b/MediaBrowser.Controller/Net/IWebSocketConnection.cs @@ -1,5 +1,4 @@ -using MediaBrowser.Common.Net; -using MediaBrowser.Model.Net; +using MediaBrowser.Model.Net; using System; using System.Threading; using System.Threading.Tasks; diff --git a/MediaBrowser.Controller/Sync/ISyncManager.cs b/MediaBrowser.Controller/Sync/ISyncManager.cs index e16a978c3..39cec4f00 100644 --- a/MediaBrowser.Controller/Sync/ISyncManager.cs +++ b/MediaBrowser.Controller/Sync/ISyncManager.cs @@ -82,18 +82,18 @@ namespace MediaBrowser.Controller.Sync /// SyncJobItem. SyncJobItem GetJobItem(string id); - /// - /// Gets the job item information. - /// - /// The identifier. - /// SyncedItem. - SyncedItem GetJobItemInfo(string id); - /// /// Reports the offline action. /// /// The action. /// Task. Task ReportOfflineAction(UserAction action); + + /// + /// Gets the ready synchronize items. + /// + /// The target identifier. + /// List<SyncedItem>. + List GetReadySyncItems(string targetId); } } diff --git a/MediaBrowser.Dlna/Main/DlnaEntryPoint.cs b/MediaBrowser.Dlna/Main/DlnaEntryPoint.cs index dc4aff190..810b1e568 100644 --- a/MediaBrowser.Dlna/Main/DlnaEntryPoint.cs +++ b/MediaBrowser.Dlna/Main/DlnaEntryPoint.cs @@ -7,7 +7,6 @@ using MediaBrowser.Controller.Dlna; using MediaBrowser.Controller.Drawing; using MediaBrowser.Controller.Library; using MediaBrowser.Controller.Localization; -using MediaBrowser.Controller.Net; using MediaBrowser.Controller.Persistence; using MediaBrowser.Controller.Plugins; using MediaBrowser.Controller.Session; diff --git a/MediaBrowser.Model/Configuration/ServerConfiguration.cs b/MediaBrowser.Model/Configuration/ServerConfiguration.cs index 730735499..ba5b6a122 100644 --- a/MediaBrowser.Model/Configuration/ServerConfiguration.cs +++ b/MediaBrowser.Model/Configuration/ServerConfiguration.cs @@ -165,6 +165,7 @@ namespace MediaBrowser.Model.Configuration public string[] InsecureApps7 { get; set; } public bool SaveMetadataHidden { get; set; } + public bool EnableWin8HttpListener { get; set; } public NameValuePair[] ContentTypes { get; set; } @@ -180,6 +181,7 @@ namespace MediaBrowser.Model.Configuration EnableDashboardResponseCaching = true; EnableAutomaticRestart = true; + EnableWin8HttpListener = true; EnableUPnP = true; diff --git a/MediaBrowser.Model/Sync/DeviceFileInfo.cs b/MediaBrowser.Model/Sync/DeviceFileInfo.cs index bc93b69bc..bb9a0c6ef 100644 --- a/MediaBrowser.Model/Sync/DeviceFileInfo.cs +++ b/MediaBrowser.Model/Sync/DeviceFileInfo.cs @@ -3,7 +3,7 @@ namespace MediaBrowser.Model.Sync { public class DeviceFileInfo { - public string Path { get; set; } + public string[] Path { get; set; } public string Name { get; set; } } } diff --git a/MediaBrowser.Model/Sync/ItemFIleInfo.cs b/MediaBrowser.Model/Sync/ItemFIleInfo.cs index 8095b0cff..ef19973a2 100644 --- a/MediaBrowser.Model/Sync/ItemFIleInfo.cs +++ b/MediaBrowser.Model/Sync/ItemFIleInfo.cs @@ -18,7 +18,7 @@ namespace MediaBrowser.Model.Sync /// Gets or sets the path. /// /// The path. - public string Path { get; set; } + public string[] Path { get; set; } /// /// Gets or sets the type of the image. /// diff --git a/MediaBrowser.Server.Implementations/Connect/ConnectEntryPoint.cs b/MediaBrowser.Server.Implementations/Connect/ConnectEntryPoint.cs index 5acec2d6b..52ec5c9b1 100644 --- a/MediaBrowser.Server.Implementations/Connect/ConnectEntryPoint.cs +++ b/MediaBrowser.Server.Implementations/Connect/ConnectEntryPoint.cs @@ -1,7 +1,6 @@ using MediaBrowser.Common.Configuration; using MediaBrowser.Common.Net; using MediaBrowser.Controller.Connect; -using MediaBrowser.Controller.Net; using MediaBrowser.Controller.Plugins; using MediaBrowser.Model.Logging; using System; diff --git a/MediaBrowser.Server.Implementations/EntryPoints/UdpServerEntryPoint.cs b/MediaBrowser.Server.Implementations/EntryPoints/UdpServerEntryPoint.cs index d97ccb9bd..386c16513 100644 --- a/MediaBrowser.Server.Implementations/EntryPoints/UdpServerEntryPoint.cs +++ b/MediaBrowser.Server.Implementations/EntryPoints/UdpServerEntryPoint.cs @@ -1,6 +1,5 @@ using MediaBrowser.Common.Net; using MediaBrowser.Controller; -using MediaBrowser.Controller.Net; using MediaBrowser.Controller.Plugins; using MediaBrowser.Model.Logging; using MediaBrowser.Model.Serialization; diff --git a/MediaBrowser.Server.Implementations/EntryPoints/UsageEntryPoint.cs b/MediaBrowser.Server.Implementations/EntryPoints/UsageEntryPoint.cs index 098a1d2bd..fcc664011 100644 --- a/MediaBrowser.Server.Implementations/EntryPoints/UsageEntryPoint.cs +++ b/MediaBrowser.Server.Implementations/EntryPoints/UsageEntryPoint.cs @@ -1,8 +1,6 @@ using MediaBrowser.Common; using MediaBrowser.Common.Extensions; -using MediaBrowser.Common.Implementations.Security; using MediaBrowser.Common.Net; -using MediaBrowser.Controller.Net; using MediaBrowser.Controller.Plugins; using MediaBrowser.Controller.Session; using MediaBrowser.Model.Logging; diff --git a/MediaBrowser.Server.Implementations/EntryPoints/UsageReporter.cs b/MediaBrowser.Server.Implementations/EntryPoints/UsageReporter.cs index 940be6d02..36ba55828 100644 --- a/MediaBrowser.Server.Implementations/EntryPoints/UsageReporter.cs +++ b/MediaBrowser.Server.Implementations/EntryPoints/UsageReporter.cs @@ -4,7 +4,6 @@ using System; using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; -using MediaBrowser.Controller.Net; namespace MediaBrowser.Server.Implementations.EntryPoints { diff --git a/MediaBrowser.Server.Implementations/HttpServer/HttpListenerHost.cs b/MediaBrowser.Server.Implementations/HttpServer/HttpListenerHost.cs index b754a943a..c3228db92 100644 --- a/MediaBrowser.Server.Implementations/HttpServer/HttpListenerHost.cs +++ b/MediaBrowser.Server.Implementations/HttpServer/HttpListenerHost.cs @@ -1,7 +1,6 @@ using Funq; using MediaBrowser.Common; using MediaBrowser.Common.Extensions; -using MediaBrowser.Common.Net; using MediaBrowser.Controller.Net; using MediaBrowser.Model.Logging; using MediaBrowser.Server.Implementations.HttpServer.NetListener; @@ -205,10 +204,7 @@ namespace MediaBrowser.Server.Implementations.HttpServer { HostContext.Config.HandlerFactoryPath = ListenerRequest.GetHandlerPathIfAny(UrlPrefixes.First()); - _listener = _supportsNativeWebSocket && NativeWebSocket.IsSupported - //? _listener = new HttpListenerServer(_logger, OnRequestReceived) - ? _listener = new WebSocketSharpListener(_logger, OnRequestReceived) - : _listener = new WebSocketSharpListener(_logger, OnRequestReceived); + _listener = GetListener(); _listener.WebSocketHandler = WebSocketHandler; _listener.ErrorHandler = ErrorHandler; @@ -217,6 +213,16 @@ namespace MediaBrowser.Server.Implementations.HttpServer _listener.Start(UrlPrefixes); } + private IHttpListener GetListener() + { + if (_supportsNativeWebSocket && NativeWebSocket.IsSupported) + { + return new HttpListenerServer(_logger, OnRequestReceived); + } + + return new WebSocketSharpListener(_logger, OnRequestReceived); + } + private void WebSocketHandler(WebSocketConnectEventArgs args) { if (WebSocketConnected != null) diff --git a/MediaBrowser.Server.Implementations/HttpServer/IHttpListener.cs b/MediaBrowser.Server.Implementations/HttpServer/IHttpListener.cs index dfde34e25..e77600e93 100644 --- a/MediaBrowser.Server.Implementations/HttpServer/IHttpListener.cs +++ b/MediaBrowser.Server.Implementations/HttpServer/IHttpListener.cs @@ -1,9 +1,8 @@ -using System.Threading.Tasks; -using MediaBrowser.Common.Net; -using MediaBrowser.Controller.Net; +using MediaBrowser.Controller.Net; using ServiceStack.Web; using System; using System.Collections.Generic; +using System.Threading.Tasks; namespace MediaBrowser.Server.Implementations.HttpServer { diff --git a/MediaBrowser.Server.Implementations/HttpServer/NativeWebSocket.cs b/MediaBrowser.Server.Implementations/HttpServer/NativeWebSocket.cs index f8e8bb9dd..cac2f8e09 100644 --- a/MediaBrowser.Server.Implementations/HttpServer/NativeWebSocket.cs +++ b/MediaBrowser.Server.Implementations/HttpServer/NativeWebSocket.cs @@ -1,10 +1,9 @@ -using System.Text; -using MediaBrowser.Common.Events; -using MediaBrowser.Common.Net; +using MediaBrowser.Common.Events; using MediaBrowser.Controller.Net; using MediaBrowser.Model.Logging; using System; using System.Net.WebSockets; +using System.Text; using System.Threading; using System.Threading.Tasks; using WebSocketMessageType = MediaBrowser.Model.Net.WebSocketMessageType; diff --git a/MediaBrowser.Server.Implementations/HttpServer/NetListener/HttpListenerServer.cs b/MediaBrowser.Server.Implementations/HttpServer/NetListener/HttpListenerServer.cs index 9635854d4..31c0e87b3 100644 --- a/MediaBrowser.Server.Implementations/HttpServer/NetListener/HttpListenerServer.cs +++ b/MediaBrowser.Server.Implementations/HttpServer/NetListener/HttpListenerServer.cs @@ -1,5 +1,4 @@ -using MediaBrowser.Common.Net; -using MediaBrowser.Controller.Net; +using MediaBrowser.Controller.Net; using MediaBrowser.Model.Logging; using ServiceStack; using ServiceStack.Host.HttpListener; diff --git a/MediaBrowser.Server.Implementations/HttpServer/SocketSharp/SharpWebSocket.cs b/MediaBrowser.Server.Implementations/HttpServer/SocketSharp/SharpWebSocket.cs index 354b1e20f..401d49325 100644 --- a/MediaBrowser.Server.Implementations/HttpServer/SocketSharp/SharpWebSocket.cs +++ b/MediaBrowser.Server.Implementations/HttpServer/SocketSharp/SharpWebSocket.cs @@ -1,12 +1,9 @@ -using System.Text; -using MediaBrowser.Common.Events; -using MediaBrowser.Common.Net; +using MediaBrowser.Common.Events; using MediaBrowser.Controller.Net; using MediaBrowser.Model.Logging; using System; using System.Threading; using System.Threading.Tasks; -using WebSocketMessageType = MediaBrowser.Model.Net.WebSocketMessageType; using WebSocketState = MediaBrowser.Model.Net.WebSocketState; namespace MediaBrowser.Server.Implementations.HttpServer.SocketSharp diff --git a/MediaBrowser.Server.Implementations/HttpServer/SocketSharp/WebSocketSharpListener.cs b/MediaBrowser.Server.Implementations/HttpServer/SocketSharp/WebSocketSharpListener.cs index ffaecc0d5..4d2d57b6e 100644 --- a/MediaBrowser.Server.Implementations/HttpServer/SocketSharp/WebSocketSharpListener.cs +++ b/MediaBrowser.Server.Implementations/HttpServer/SocketSharp/WebSocketSharpListener.cs @@ -1,5 +1,4 @@ -using MediaBrowser.Common.Net; -using MediaBrowser.Controller.Net; +using MediaBrowser.Controller.Net; using MediaBrowser.Model.Logging; using ServiceStack; using ServiceStack.Web; diff --git a/MediaBrowser.Server.Implementations/ServerManager/WebSocketConnection.cs b/MediaBrowser.Server.Implementations/ServerManager/WebSocketConnection.cs index a8950da89..9f75d522c 100644 --- a/MediaBrowser.Server.Implementations/ServerManager/WebSocketConnection.cs +++ b/MediaBrowser.Server.Implementations/ServerManager/WebSocketConnection.cs @@ -1,5 +1,4 @@ using MediaBrowser.Common.Events; -using MediaBrowser.Common.Net; using MediaBrowser.Controller.Net; using MediaBrowser.Model.Logging; using MediaBrowser.Model.Net; diff --git a/MediaBrowser.Server.Implementations/Session/WebSocketController.cs b/MediaBrowser.Server.Implementations/Session/WebSocketController.cs index 0788ed2ce..8eb129876 100644 --- a/MediaBrowser.Server.Implementations/Session/WebSocketController.cs +++ b/MediaBrowser.Server.Implementations/Session/WebSocketController.cs @@ -1,5 +1,4 @@ -using MediaBrowser.Common.Net; -using MediaBrowser.Controller.Net; +using MediaBrowser.Controller.Net; using MediaBrowser.Controller.Session; using MediaBrowser.Model.Entities; using MediaBrowser.Model.Logging; diff --git a/MediaBrowser.Server.Implementations/Sync/SyncManager.cs b/MediaBrowser.Server.Implementations/Sync/SyncManager.cs index a9e257a8c..22d0ee5e7 100644 --- a/MediaBrowser.Server.Implementations/Sync/SyncManager.cs +++ b/MediaBrowser.Server.Implementations/Sync/SyncManager.cs @@ -32,12 +32,12 @@ namespace MediaBrowser.Server.Implementations.Sync private readonly IImageProcessor _imageProcessor; private readonly ILogger _logger; private readonly IUserManager _userManager; - private readonly IDtoService _dtoService; + private readonly Func _dtoService; private readonly IApplicationHost _appHost; private ISyncProvider[] _providers = { }; - public SyncManager(ILibraryManager libraryManager, ISyncRepository repo, IImageProcessor imageProcessor, ILogger logger, IUserManager userManager, IDtoService dtoService, IApplicationHost appHost) + public SyncManager(ILibraryManager libraryManager, ISyncRepository repo, IImageProcessor imageProcessor, ILogger logger, IUserManager userManager, Func dtoService, IApplicationHost appHost) { _libraryManager = libraryManager; _repo = repo; @@ -323,9 +323,8 @@ namespace MediaBrowser.Server.Implementations.Sync return _repo.GetJobItems(query); } - public SyncedItem GetJobItemInfo(string id) + private SyncedItem GetJobItemInfo(SyncJobItem jobItem) { - var jobItem = GetJobItem(id); var job = _repo.GetJob(jobItem.JobId); var libraryItem = _libraryManager.GetItemById(jobItem.ItemId); @@ -338,7 +337,7 @@ namespace MediaBrowser.Server.Implementations.Sync UserId = job.UserId }; - syncedItem.Item = _dtoService.GetBaseItemDto(libraryItem, new DtoOptions()); + syncedItem.Item = _dtoService().GetBaseItemDto(libraryItem, new DtoOptions()); // TODO: this should be the media source of the transcoded output syncedItem.Item.MediaSources = syncedItem.Item.MediaSources @@ -365,5 +364,16 @@ namespace MediaBrowser.Server.Implementations.Sync { return Task.FromResult(true); } + + public List GetReadySyncItems(string targetId) + { + var jobItemResult = GetJobItems(new SyncJobItemQuery + { + TargetId = targetId, + //Status = SyncJobItemStatus.Transferring + }); + + return jobItemResult.Items.Select(GetJobItemInfo).ToList(); + } } } diff --git a/MediaBrowser.Server.Implementations/Sync/SyncRepository.cs b/MediaBrowser.Server.Implementations/Sync/SyncRepository.cs index 2ff6d7ae6..a981ffc57 100644 --- a/MediaBrowser.Server.Implementations/Sync/SyncRepository.cs +++ b/MediaBrowser.Server.Implementations/Sync/SyncRepository.cs @@ -36,7 +36,7 @@ namespace MediaBrowser.Server.Implementations.Sync public async Task Initialize() { - var dbFile = Path.Combine(_appPaths.DataPath, "sync7.db"); + var dbFile = Path.Combine(_appPaths.DataPath, "sync8.db"); _connection = await SqliteExtensions.ConnectToDb(dbFile, _logger).ConfigureAwait(false); @@ -298,7 +298,8 @@ namespace MediaBrowser.Server.Implementations.Sync _deleteJobCommand.Transaction = transaction; _deleteJobCommand.ExecuteNonQuery(); - _deleteJobItemsCommand.GetParameter(index++).Value = new Guid(id); + index = 0; + _deleteJobItemsCommand.GetParameter(index++).Value = id; _deleteJobItemsCommand.Transaction = transaction; _deleteJobItemsCommand.ExecuteNonQuery(); @@ -607,11 +608,16 @@ namespace MediaBrowser.Server.Implementations.Sync var info = new SyncJobItem { Id = reader.GetGuid(0).ToString("N"), - ItemId = reader.GetString(1), - MediaSourceId = reader.GetString(2), - JobId = reader.GetString(3) + ItemId = reader.GetString(1) }; + if (!reader.IsDBNull(2)) + { + info.MediaSourceId = reader.GetString(2); + } + + info.JobId = reader.GetString(3); + if (!reader.IsDBNull(4)) { info.OutputPath = reader.GetString(4); diff --git a/MediaBrowser.Server.Implementations/Udp/UdpServer.cs b/MediaBrowser.Server.Implementations/Udp/UdpServer.cs index d80e0b66e..91a4940ae 100644 --- a/MediaBrowser.Server.Implementations/Udp/UdpServer.cs +++ b/MediaBrowser.Server.Implementations/Udp/UdpServer.cs @@ -1,6 +1,5 @@ using MediaBrowser.Common.Net; using MediaBrowser.Controller; -using MediaBrowser.Controller.Net; using MediaBrowser.Model.ApiClient; using MediaBrowser.Model.Logging; using MediaBrowser.Model.Serialization; diff --git a/MediaBrowser.Server.Mac/Native/BaseMonoApp.cs b/MediaBrowser.Server.Mac/Native/BaseMonoApp.cs index a2c860413..576b5b75f 100644 --- a/MediaBrowser.Server.Mac/Native/BaseMonoApp.cs +++ b/MediaBrowser.Server.Mac/Native/BaseMonoApp.cs @@ -67,7 +67,7 @@ namespace MediaBrowser.Server.Mac return list; } - public void AuthorizeServer(int httpServerPort, string httpServerUrlPrefix, int udpPort, string tempDirectory) + public void AuthorizeServer(int udpPort, int httpServerPort, string tempDirectory) { } diff --git a/MediaBrowser.Server.Mono/Native/BaseMonoApp.cs b/MediaBrowser.Server.Mono/Native/BaseMonoApp.cs index 227c32242..7f61570a4 100644 --- a/MediaBrowser.Server.Mono/Native/BaseMonoApp.cs +++ b/MediaBrowser.Server.Mono/Native/BaseMonoApp.cs @@ -1,5 +1,4 @@ using MediaBrowser.Common.Net; -using MediaBrowser.Controller.Net; using MediaBrowser.IsoMounter; using MediaBrowser.Model.Logging; using MediaBrowser.Server.Mono.Networking; @@ -84,7 +83,7 @@ namespace MediaBrowser.Server.Mono.Native return list; } - public void AuthorizeServer(int httpServerPort, string httpServerUrlPrefix, int udpPort, string tempDirectory) + public void AuthorizeServer(int udpPort, int httpServerPort, string tempDirectory) { } diff --git a/MediaBrowser.Server.Mono/Networking/NetworkManager.cs b/MediaBrowser.Server.Mono/Networking/NetworkManager.cs index d76a7c7ee..60c250115 100644 --- a/MediaBrowser.Server.Mono/Networking/NetworkManager.cs +++ b/MediaBrowser.Server.Mono/Networking/NetworkManager.cs @@ -1,6 +1,5 @@ using MediaBrowser.Common.Implementations.Networking; using MediaBrowser.Common.Net; -using MediaBrowser.Controller.Net; using MediaBrowser.Model.IO; using MediaBrowser.Model.Logging; using MediaBrowser.Model.Net; diff --git a/MediaBrowser.Server.Startup.Common/ApplicationHost.cs b/MediaBrowser.Server.Startup.Common/ApplicationHost.cs index 06d63b355..8398c63cb 100644 --- a/MediaBrowser.Server.Startup.Common/ApplicationHost.cs +++ b/MediaBrowser.Server.Startup.Common/ApplicationHost.cs @@ -224,7 +224,7 @@ namespace MediaBrowser.Server.Startup.Common private readonly StartupOptions _startupOptions; private readonly string _remotePackageName; - private readonly bool _supportsNativeWebSocket; + private bool _supportsNativeWebSocket; internal INativeApp NativeApp { get; set; } @@ -454,6 +454,18 @@ namespace MediaBrowser.Server.Startup.Common RegisterSingleInstance(() => new SearchEngine(LogManager, LibraryManager, UserManager)); + if (IsFirstRun) + { + ServerConfigurationManager.Configuration.EnableWin8HttpListener = false; + ServerConfigurationManager.SaveConfiguration(); + _supportsNativeWebSocket = false; + } + + if (!ServerConfigurationManager.Configuration.EnableWin8HttpListener) + { + _supportsNativeWebSocket = false; + } + HttpServer = ServerFactory.CreateServer(this, LogManager, "Media Browser", WebApplicationName, "dashboard/index.html", _supportsNativeWebSocket); RegisterSingleInstance(HttpServer, false); progress.Report(10); @@ -470,7 +482,7 @@ namespace MediaBrowser.Server.Startup.Common ImageProcessor = new ImageProcessor(LogManager.GetLogger("ImageProcessor"), ServerConfigurationManager.ApplicationPaths, FileSystemManager, JsonSerializer, MediaEncoder); RegisterSingleInstance(ImageProcessor); - SyncManager = new SyncManager(LibraryManager, SyncRepository, ImageProcessor, LogManager.GetLogger("SyncManager"), UserManager, DtoService, this); + SyncManager = new SyncManager(LibraryManager, SyncRepository, ImageProcessor, LogManager.GetLogger("SyncManager"), UserManager, () => DtoService, this); RegisterSingleInstance(SyncManager); DtoService = new DtoService(Logger, LibraryManager, UserDataManager, ItemRepository, ImageProcessor, ServerConfigurationManager, FileSystemManager, ProviderManager, () => ChannelManager, SyncManager, this); @@ -735,7 +747,7 @@ namespace MediaBrowser.Server.Startup.Common ServerManager.AddWebSocketListeners(GetExports(false)); - StartServer(true); + StartServer(); LibraryManager.AddParts(GetExports(), GetExports(), @@ -773,8 +785,7 @@ namespace MediaBrowser.Server.Startup.Common /// /// Starts the server. /// - /// if set to true [retry on failure]. - private void StartServer(bool retryOnFailure) + private void StartServer() { try { @@ -784,16 +795,7 @@ namespace MediaBrowser.Server.Startup.Common { Logger.ErrorException("Error starting http server", ex); - if (retryOnFailure) - { - RegisterServerWithAdministratorAccess(); - - StartServer(false); - } - else - { - throw; - } + throw; } } @@ -1070,9 +1072,8 @@ namespace MediaBrowser.Server.Startup.Common try { NativeApp.AuthorizeServer( - ServerConfigurationManager.Configuration.HttpServerPortNumber, - HttpServerUrlPrefixes.First(), UdpServerEntryPoint.PortNumber, + ServerConfigurationManager.Configuration.HttpServerPortNumber, ConfigurationManager.CommonApplicationPaths.TempDirectory); } catch (Exception ex) diff --git a/MediaBrowser.Server.Startup.Common/INativeApp.cs b/MediaBrowser.Server.Startup.Common/INativeApp.cs index cf0135fa8..4abea57fb 100644 --- a/MediaBrowser.Server.Startup.Common/INativeApp.cs +++ b/MediaBrowser.Server.Startup.Common/INativeApp.cs @@ -1,5 +1,4 @@ using MediaBrowser.Common.Net; -using MediaBrowser.Controller.Net; using MediaBrowser.Model.Logging; using System.Collections.Generic; using System.Reflection; @@ -17,11 +16,10 @@ namespace MediaBrowser.Server.Startup.Common /// /// Authorizes the server. /// - /// The HTTP server port. - /// The HTTP server URL prefix. /// The UDP port. + /// The HTTP server port. /// The temporary directory. - void AuthorizeServer(int httpServerPort, string httpServerUrlPrefix, int udpPort, string tempDirectory); + void AuthorizeServer(int udpPort, int httpServerPort, string tempDirectory); /// /// Gets the environment. diff --git a/MediaBrowser.ServerApplication/Native/RegisterServer.bat b/MediaBrowser.ServerApplication/Native/RegisterServer.bat index 350412344..3346ecb31 100644 --- a/MediaBrowser.ServerApplication/Native/RegisterServer.bat +++ b/MediaBrowser.ServerApplication/Native/RegisterServer.bat @@ -1,21 +1,15 @@ -rem %1 = http server port -rem %2 = http server url -rem %3 = udp server port +rem %1 = udp server port +rem %2 = http server port if [%1]==[] GOTO DONE -netsh advfirewall firewall delete rule name="Port %1" protocol=TCP localport=%1 -netsh advfirewall firewall add rule name="Port %1" dir=in action=allow protocol=TCP localport=%1 +netsh advfirewall firewall delete rule name="Port %1" protocol=UDP localport=%1 +netsh advfirewall firewall add rule name="Port %1" dir=in action=allow protocol=UDP localport=%1 if [%2]==[] GOTO DONE -netsh http del urlacl url="%2" user="NT AUTHORITY\Authenticated Users" -netsh http add urlacl url="%2" user="NT AUTHORITY\Authenticated Users" - -if [%3]==[] GOTO DONE - -netsh advfirewall firewall delete rule name="Port %3" protocol=UDP localport=%3 -netsh advfirewall firewall add rule name="Port %3" dir=in action=allow protocol=UDP localport=%3 +netsh advfirewall firewall delete rule name="Port %2" protocol=TCP localport=%2 +netsh advfirewall firewall add rule name="Port %2" dir=in action=allow protocol=TCP localport=%2 :DONE diff --git a/MediaBrowser.ServerApplication/Native/ServerAuthorization.cs b/MediaBrowser.ServerApplication/Native/ServerAuthorization.cs index e5989db3b..d9063aa58 100644 --- a/MediaBrowser.ServerApplication/Native/ServerAuthorization.cs +++ b/MediaBrowser.ServerApplication/Native/ServerAuthorization.cs @@ -13,11 +13,10 @@ namespace MediaBrowser.ServerApplication.Native /// /// Authorizes the server. /// - /// The HTTP server port. - /// The HTTP server URL prefix. /// The UDP port. + /// The HTTP server port. /// The temp directory. - public static void AuthorizeServer(int httpServerPort, string httpServerUrlPrefix, int udpPort, string tempDirectory) + public static void AuthorizeServer(int udpPort, int httpServerPort, string tempDirectory) { Directory.CreateDirectory(tempDirectory); @@ -37,9 +36,7 @@ namespace MediaBrowser.ServerApplication.Native { FileName = tmpFile, - Arguments = string.Format("{0} {1} {2}", httpServerPort, - httpServerUrlPrefix, - udpPort), + Arguments = string.Format("{0} {1}", udpPort, httpServerPort), CreateNoWindow = true, WindowStyle = ProcessWindowStyle.Hidden, diff --git a/MediaBrowser.ServerApplication/Native/WindowsApp.cs b/MediaBrowser.ServerApplication/Native/WindowsApp.cs index 071216418..0970d6537 100644 --- a/MediaBrowser.ServerApplication/Native/WindowsApp.cs +++ b/MediaBrowser.ServerApplication/Native/WindowsApp.cs @@ -1,5 +1,4 @@ using MediaBrowser.Common.Net; -using MediaBrowser.Controller.Net; using MediaBrowser.IsoMounter; using MediaBrowser.Model.Logging; using MediaBrowser.Server.Startup.Common; @@ -22,9 +21,9 @@ namespace MediaBrowser.ServerApplication.Native return list; } - public void AuthorizeServer(int httpServerPort, string httpServerUrlPrefix, int udpPort, string tempDirectory) + public void AuthorizeServer(int httpServerPort, int udpPort, string tempDirectory) { - ServerAuthorization.AuthorizeServer(httpServerPort, httpServerUrlPrefix, udpPort, tempDirectory); + ServerAuthorization.AuthorizeServer(udpPort, httpServerPort, tempDirectory); } public NativeEnvironment Environment diff --git a/MediaBrowser.ServerApplication/Networking/NetworkManager.cs b/MediaBrowser.ServerApplication/Networking/NetworkManager.cs index 4dbe0f347..fc4d26363 100644 --- a/MediaBrowser.ServerApplication/Networking/NetworkManager.cs +++ b/MediaBrowser.ServerApplication/Networking/NetworkManager.cs @@ -1,6 +1,5 @@ using MediaBrowser.Common.Implementations.Networking; using MediaBrowser.Common.Net; -using MediaBrowser.Controller.Net; using MediaBrowser.Model.IO; using MediaBrowser.Model.Logging; using MediaBrowser.Model.Net; diff --git a/Nuget/MediaBrowser.Common.Internal.nuspec b/Nuget/MediaBrowser.Common.Internal.nuspec index 3fd559a4d..80e2f32f7 100644 --- a/Nuget/MediaBrowser.Common.Internal.nuspec +++ b/Nuget/MediaBrowser.Common.Internal.nuspec @@ -2,7 +2,7 @@ MediaBrowser.Common.Internal - 3.0.532 + 3.0.533 MediaBrowser.Common.Internal Luke ebr,Luke,scottisafool @@ -12,7 +12,7 @@ Contains common components shared by Media Browser Theater and Media Browser Server. Not intended for plugin developer consumption. Copyright © Media Browser 2013 - + diff --git a/Nuget/MediaBrowser.Common.nuspec b/Nuget/MediaBrowser.Common.nuspec index 84eec30d6..8c22ebb5d 100644 --- a/Nuget/MediaBrowser.Common.nuspec +++ b/Nuget/MediaBrowser.Common.nuspec @@ -2,7 +2,7 @@ MediaBrowser.Common - 3.0.532 + 3.0.533 MediaBrowser.Common Media Browser Team ebr,Luke,scottisafool diff --git a/Nuget/MediaBrowser.Model.Signed.nuspec b/Nuget/MediaBrowser.Model.Signed.nuspec index ad3bd826d..f313bd7a5 100644 --- a/Nuget/MediaBrowser.Model.Signed.nuspec +++ b/Nuget/MediaBrowser.Model.Signed.nuspec @@ -2,7 +2,7 @@ MediaBrowser.Model.Signed - 3.0.532 + 3.0.533 MediaBrowser.Model - Signed Edition Media Browser Team ebr,Luke,scottisafool diff --git a/Nuget/MediaBrowser.Server.Core.nuspec b/Nuget/MediaBrowser.Server.Core.nuspec index 191ab9e88..a31f8023b 100644 --- a/Nuget/MediaBrowser.Server.Core.nuspec +++ b/Nuget/MediaBrowser.Server.Core.nuspec @@ -2,7 +2,7 @@ MediaBrowser.Server.Core - 3.0.532 + 3.0.533 Media Browser.Server.Core Media Browser Team ebr,Luke,scottisafool @@ -12,7 +12,7 @@ Contains core components required to build plugins for Media Browser Server. Copyright © Media Browser 2013 - + -- cgit v1.2.3 From 5278959edef763bdf0b4d72ace75efd151ab5024 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sun, 28 Dec 2014 01:21:39 -0500 Subject: sync fixes --- MediaBrowser.Api/VideosService.cs | 8 +- .../Archiving/ZipClient.cs | 16 +++ MediaBrowser.Controller/Entities/Movies/BoxSet.cs | 11 +- .../Savers/FolderXmlSaver.cs | 2 +- MediaBrowser.Model/IO/IZipClient.cs | 8 ++ .../BoxSets/BoxSetMetadataService.cs | 2 +- .../Music/AlbumMetadataService.cs | 20 ++-- .../Music/ArtistMetadataService.cs | 21 ++-- MediaBrowser.Providers/TV/TvdbSeriesProvider.cs | 2 +- .../Library/LibraryManager.cs | 10 +- .../Library/Resolvers/Audio/MusicAlbumResolver.cs | 45 ++++---- .../Library/Resolvers/Movies/BoxSetResolver.cs | 17 +++ .../Library/Resolvers/Movies/MovieResolver.cs | 39 +------ .../Library/Resolvers/PhotoResolver.cs | 4 +- .../Library/Resolvers/TV/SeriesResolver.cs | 124 ++------------------- .../Library/UserManager.cs | 7 ++ .../Localization/JavaScript/javascript.json | 4 +- .../Localization/Server/server.json | 4 +- .../MediaBrowser.Server.Implementations.csproj | 2 +- .../Session/WebSocketController.cs | 11 -- .../Sync/SyncJobProcessor.cs | 76 +++++++------ .../Sync/SyncManager.cs | 23 +++- .../Sync/SyncRepository.cs | 7 +- .../packages.config | 2 +- .../MediaBrowser.Server.Mono.csproj | 4 - 25 files changed, 190 insertions(+), 279 deletions(-) (limited to 'MediaBrowser.Server.Implementations/Session') diff --git a/MediaBrowser.Api/VideosService.cs b/MediaBrowser.Api/VideosService.cs index 91b02089c..28db46b98 100644 --- a/MediaBrowser.Api/VideosService.cs +++ b/MediaBrowser.Api/VideosService.cs @@ -112,11 +112,11 @@ namespace MediaBrowser.Api { link.PrimaryVersionId = null; - await link.UpdateToRepository(ItemUpdateType.MetadataDownload, CancellationToken.None).ConfigureAwait(false); + await link.UpdateToRepository(ItemUpdateType.MetadataEdit, CancellationToken.None).ConfigureAwait(false); } video.LinkedAlternateVersions.Clear(); - await video.UpdateToRepository(ItemUpdateType.MetadataDownload, CancellationToken.None).ConfigureAwait(false); + await video.UpdateToRepository(ItemUpdateType.MetadataEdit, CancellationToken.None).ConfigureAwait(false); } public void Post(MergeVersions request) @@ -184,7 +184,7 @@ namespace MediaBrowser.Api { item.PrimaryVersionId = primaryVersion.Id; - await item.UpdateToRepository(ItemUpdateType.MetadataDownload, CancellationToken.None).ConfigureAwait(false); + await item.UpdateToRepository(ItemUpdateType.MetadataEdit, CancellationToken.None).ConfigureAwait(false); primaryVersion.LinkedAlternateVersions.Add(new LinkedChild { @@ -193,7 +193,7 @@ namespace MediaBrowser.Api }); } - await primaryVersion.UpdateToRepository(ItemUpdateType.MetadataDownload, CancellationToken.None).ConfigureAwait(false); + await primaryVersion.UpdateToRepository(ItemUpdateType.MetadataEdit, CancellationToken.None).ConfigureAwait(false); } } } diff --git a/MediaBrowser.Common.Implementations/Archiving/ZipClient.cs b/MediaBrowser.Common.Implementations/Archiving/ZipClient.cs index 23d40cf67..c32134d4f 100644 --- a/MediaBrowser.Common.Implementations/Archiving/ZipClient.cs +++ b/MediaBrowser.Common.Implementations/Archiving/ZipClient.cs @@ -4,6 +4,7 @@ using SharpCompress.Archive.SevenZip; using SharpCompress.Archive.Tar; using SharpCompress.Common; using SharpCompress.Reader; +using SharpCompress.Reader.Zip; using System.IO; namespace MediaBrowser.Common.Implementations.Archiving @@ -48,6 +49,21 @@ namespace MediaBrowser.Common.Implementations.Archiving } } + public void ExtractAllFromZip(Stream source, string targetPath, bool overwriteExistingFiles) + { + using (var reader = ZipReader.Open(source)) + { + var options = ExtractOptions.ExtractFullPath; + + if (overwriteExistingFiles) + { + options = options | ExtractOptions.Overwrite; + } + + reader.WriteAllToDirectory(targetPath, options); + } + } + /// /// Extracts all from7z. /// diff --git a/MediaBrowser.Controller/Entities/Movies/BoxSet.cs b/MediaBrowser.Controller/Entities/Movies/BoxSet.cs index 6563da8de..8d3cf9bad 100644 --- a/MediaBrowser.Controller/Entities/Movies/BoxSet.cs +++ b/MediaBrowser.Controller/Entities/Movies/BoxSet.cs @@ -19,7 +19,7 @@ namespace MediaBrowser.Controller.Entities.Movies public class BoxSet : Folder, IHasTrailers, IHasKeywords, IHasPreferredMetadataLanguage, IHasDisplayOrder, IHasLookupInfo, IMetadataContainer, IHasShares { public List Shares { get; set; } - + public BoxSet() { RemoteTrailers = new List(); @@ -171,10 +171,13 @@ namespace MediaBrowser.Controller.Entities.Movies { var userId = user.Id.ToString("N"); - return Shares.Any(i => string.Equals(userId, i.UserId, StringComparison.OrdinalIgnoreCase)) || + // Need to check Count > 0 for boxsets created prior to the introduction of Shares + if (Shares.Count > 0 && !Shares.Any(i => string.Equals(userId, i.UserId, StringComparison.OrdinalIgnoreCase))) + { + return false; + } - // Need to support this for boxsets created prior to the creation of Shares - Shares.Count == 0; + return true; } return false; diff --git a/MediaBrowser.LocalMetadata/Savers/FolderXmlSaver.cs b/MediaBrowser.LocalMetadata/Savers/FolderXmlSaver.cs index fa3d7d87d..67fa12b55 100644 --- a/MediaBrowser.LocalMetadata/Savers/FolderXmlSaver.cs +++ b/MediaBrowser.LocalMetadata/Savers/FolderXmlSaver.cs @@ -49,7 +49,7 @@ namespace MediaBrowser.LocalMetadata.Savers !(item is GameSystem) && !(item is Playlist)) { - return updateType >= ItemUpdateType.MetadataDownload; + return updateType >= ItemUpdateType.MetadataEdit; } } diff --git a/MediaBrowser.Model/IO/IZipClient.cs b/MediaBrowser.Model/IO/IZipClient.cs index ba0725da5..13b31c201 100644 --- a/MediaBrowser.Model/IO/IZipClient.cs +++ b/MediaBrowser.Model/IO/IZipClient.cs @@ -23,6 +23,14 @@ namespace MediaBrowser.Model.IO /// if set to true [overwrite existing files]. void ExtractAll(Stream source, string targetPath, bool overwriteExistingFiles); + /// + /// Extracts all from zip. + /// + /// The source. + /// The target path. + /// if set to true [overwrite existing files]. + void ExtractAllFromZip(Stream source, string targetPath, bool overwriteExistingFiles); + /// /// Extracts all from7z. /// diff --git a/MediaBrowser.Providers/BoxSets/BoxSetMetadataService.cs b/MediaBrowser.Providers/BoxSets/BoxSetMetadataService.cs index 062519f9d..5afaaa875 100644 --- a/MediaBrowser.Providers/BoxSets/BoxSetMetadataService.cs +++ b/MediaBrowser.Providers/BoxSets/BoxSetMetadataService.cs @@ -75,7 +75,7 @@ namespace MediaBrowser.Providers.BoxSets if (!string.Equals(currentOfficialRating ?? string.Empty, item.OfficialRating ?? string.Empty, StringComparison.OrdinalIgnoreCase)) { - updateType = updateType | ItemUpdateType.MetadataDownload; + updateType = updateType | ItemUpdateType.MetadataEdit; } } diff --git a/MediaBrowser.Providers/Music/AlbumMetadataService.cs b/MediaBrowser.Providers/Music/AlbumMetadataService.cs index 79fab2f70..6e3a5bf06 100644 --- a/MediaBrowser.Providers/Music/AlbumMetadataService.cs +++ b/MediaBrowser.Providers/Music/AlbumMetadataService.cs @@ -54,7 +54,7 @@ namespace MediaBrowser.Providers.Music if (currentList.Count != item.Genres.Count || !currentList.OrderBy(i => i).SequenceEqual(item.Genres.OrderBy(i => i), StringComparer.OrdinalIgnoreCase)) { - updateType = updateType | ItemUpdateType.MetadataDownload; + updateType = updateType | ItemUpdateType.MetadataEdit; } } @@ -68,7 +68,7 @@ namespace MediaBrowser.Providers.Music if (currentList.Count != item.Studios.Count || !currentList.OrderBy(i => i).SequenceEqual(item.Studios.OrderBy(i => i), StringComparer.OrdinalIgnoreCase)) { - updateType = updateType | ItemUpdateType.MetadataDownload; + updateType = updateType | ItemUpdateType.MetadataEdit; } } @@ -81,15 +81,15 @@ namespace MediaBrowser.Providers.Music if (!string.Equals(item.Name, name, StringComparison.Ordinal)) { item.Name = name; - updateType = updateType | ItemUpdateType.MetadataDownload; + updateType = updateType | ItemUpdateType.MetadataEdit; } } } - } - updateType = updateType | SetAlbumArtistFromSongs(item, songs); - updateType = updateType | SetArtistsFromSongs(item, songs); - updateType = updateType | SetDateFromSongs(item, songs); + updateType = updateType | SetAlbumArtistFromSongs(item, songs); + updateType = updateType | SetArtistsFromSongs(item, songs); + updateType = updateType | SetDateFromSongs(item, songs); + } return updateType; } @@ -106,7 +106,7 @@ namespace MediaBrowser.Providers.Music if (!item.AlbumArtists.SequenceEqual(albumArtists, StringComparer.OrdinalIgnoreCase)) { item.AlbumArtists = albumArtists; - updateType = updateType | ItemUpdateType.MetadataDownload; + updateType = updateType | ItemUpdateType.MetadataEdit; } return updateType; @@ -124,7 +124,7 @@ namespace MediaBrowser.Providers.Music if (currentList.Count != item.Artists.Count || !currentList.OrderBy(i => i).SequenceEqual(item.Artists.OrderBy(i => i), StringComparer.OrdinalIgnoreCase)) { - updateType = updateType | ItemUpdateType.MetadataDownload; + updateType = updateType | ItemUpdateType.MetadataEdit; } return updateType; @@ -158,7 +158,7 @@ namespace MediaBrowser.Providers.Music if ((originalPremiereDate ?? DateTime.MinValue) != (item.PremiereDate ?? DateTime.MinValue) || (originalProductionYear ?? -1) != (item.ProductionYear ?? -1)) { - updateType = updateType | ItemUpdateType.MetadataDownload; + updateType = updateType | ItemUpdateType.MetadataEdit; } return updateType; diff --git a/MediaBrowser.Providers/Music/ArtistMetadataService.cs b/MediaBrowser.Providers/Music/ArtistMetadataService.cs index 939bd2b3b..a73d82992 100644 --- a/MediaBrowser.Providers/Music/ArtistMetadataService.cs +++ b/MediaBrowser.Providers/Music/ArtistMetadataService.cs @@ -35,19 +35,22 @@ namespace MediaBrowser.Providers.Music { var updateType = base.BeforeSave(item); - if (!item.IsAccessedByName && !item.LockedFields.Contains(MetadataFields.Genres)) + if (!item.IsAccessedByName && !item.IsLocked) { - var songs = item.RecursiveChildren.OfType /// The entity resolvers enumerable. private IItemResolver[] EntityResolvers { get; set; } + private IMultiItemResolver[] MultiItemResolvers { get; set; } /// /// Gets or sets the comparers. @@ -196,9 +197,10 @@ namespace MediaBrowser.Server.Implementations.Library EntityResolutionIgnoreRules = rules.ToArray(); PluginFolderCreators = pluginFolders.ToArray(); EntityResolvers = resolvers.OrderBy(i => i.Priority).ToArray(); + MultiItemResolvers = EntityResolvers.OfType().ToArray(); IntroProviders = introProviders.ToArray(); Comparers = itemComparers.ToArray(); - + PostscanTasks = postscanTasks.OrderBy(i => { var hasOrder = i as IHasOrder; @@ -344,7 +346,7 @@ namespace MediaBrowser.Server.Implementations.Library try { - await UpdateItem(season, ItemUpdateType.MetadataDownload, cancellationToken).ConfigureAwait(false); + await UpdateItem(season, ItemUpdateType.MetadataEdit, cancellationToken).ConfigureAwait(false); } catch (Exception ex) { @@ -658,9 +660,7 @@ namespace MediaBrowser.Server.Implementations.Library if (parent != null) { - var multiItemResolvers = EntityResolvers.OfType(); - - foreach (var resolver in multiItemResolvers) + foreach (var resolver in MultiItemResolvers) { var result = resolver.ResolveMultiple(parent, fileList, collectionType, directoryService); diff --git a/MediaBrowser.Server.Implementations/Library/Resolvers/Audio/MusicAlbumResolver.cs b/MediaBrowser.Server.Implementations/Library/Resolvers/Audio/MusicAlbumResolver.cs index 05ff270fc..0f703cb22 100644 --- a/MediaBrowser.Server.Implementations/Library/Resolvers/Audio/MusicAlbumResolver.cs +++ b/MediaBrowser.Server.Implementations/Library/Resolvers/Audio/MusicAlbumResolver.cs @@ -121,14 +121,28 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers.Audio ILibraryManager libraryManager) { var discSubfolderCount = 0; + var notMultiDisc = false; foreach (var fileSystemInfo in list) { if ((fileSystemInfo.Attributes & FileAttributes.Directory) == FileAttributes.Directory) { - if (allowSubfolders && IsAlbumSubfolder(fileSystemInfo, directoryService, logger, fileSystem, libraryManager)) + if (allowSubfolders) { - discSubfolderCount++; + var path = fileSystemInfo.FullName; + var isMultiDisc = IsMultiDiscFolder(path); + var hasMusic = ContainsMusic(directoryService.GetFileSystemEntries(path), false, directoryService, logger, fileSystem, libraryManager); + + if (isMultiDisc && hasMusic) + { + logger.Debug("Found multi-disc folder: " + path); + discSubfolderCount++; + } + else if (hasMusic) + { + // If there are folders underneath with music that are not multidisc, then this can't be a multi-disc album + notMultiDisc = true; + } } } @@ -140,34 +154,15 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers.Audio } } - return discSubfolderCount > 0; - } - - private static bool IsAlbumSubfolder(FileSystemInfo directory, IDirectoryService directoryService, ILogger logger, IFileSystem fileSystem, ILibraryManager libraryManager) - { - var path = directory.FullName; - - if (IsMultiDiscFolder(path)) + if (notMultiDisc) { - logger.Debug("Found multi-disc folder: " + path); - - return ContainsMusic(directoryService.GetFileSystemEntries(path), false, directoryService, logger, fileSystem, libraryManager); + return false; } - return false; - } - - public static bool IsMultiDiscFolder(string path) - { - return IsMultiDiscAlbumFolder(path); + return discSubfolderCount > 0 && discSubfolderCount > 10; } - /// - /// Determines whether [is multi disc album folder] [the specified path]. - /// - /// The path. - /// true if [is multi disc album folder] [the specified path]; otherwise, false. - private static bool IsMultiDiscAlbumFolder(string path) + private static bool IsMultiDiscFolder(string path) { var parser = new AlbumParser(new ExtendedNamingOptions(), new Naming.Logging.NullLogger()); var result = parser.ParseMultiPart(path); diff --git a/MediaBrowser.Server.Implementations/Library/Resolvers/Movies/BoxSetResolver.cs b/MediaBrowser.Server.Implementations/Library/Resolvers/Movies/BoxSetResolver.cs index e3447afc9..390113cc8 100644 --- a/MediaBrowser.Server.Implementations/Library/Resolvers/Movies/BoxSetResolver.cs +++ b/MediaBrowser.Server.Implementations/Library/Resolvers/Movies/BoxSetResolver.cs @@ -4,6 +4,7 @@ using MediaBrowser.Controller.Library; using MediaBrowser.Model.Entities; using System; using System.IO; +using System.Linq; namespace MediaBrowser.Server.Implementations.Library.Resolvers.Movies { @@ -24,6 +25,11 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers.Movies // Contains [boxset] in the path if (args.IsDirectory) { + if (IsInvalid(args.GetCollectionType())) + { + return null; + } + var filename = Path.GetFileName(args.Path); if (string.IsNullOrEmpty(filename)) @@ -45,6 +51,17 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers.Movies return null; } + private bool IsInvalid(string collectionType) + { + var validCollectionTypes = new[] + { + CollectionType.Movies, + CollectionType.BoxSets + }; + + return !validCollectionTypes.Contains(collectionType ?? string.Empty, StringComparer.OrdinalIgnoreCase); + } + /// /// Sets the initial item values. /// diff --git a/MediaBrowser.Server.Implementations/Library/Resolvers/Movies/MovieResolver.cs b/MediaBrowser.Server.Implementations/Library/Resolvers/Movies/MovieResolver.cs index 01dc4db8a..f7a82c5b8 100644 --- a/MediaBrowser.Server.Implementations/Library/Resolvers/Movies/MovieResolver.cs +++ b/MediaBrowser.Server.Implementations/Library/Resolvers/Movies/MovieResolver.cs @@ -2,7 +2,6 @@ using MediaBrowser.Controller; using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Entities.Movies; -using MediaBrowser.Controller.Entities.TV; using MediaBrowser.Controller.Library; using MediaBrowser.Controller.Providers; using MediaBrowser.Controller.Resolvers; @@ -183,7 +182,7 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers.Movies return FindMovie public class SeriesResolver : FolderResolver { - private readonly IFileSystem _fileSystem; - private readonly ILogger _logger; - private readonly ILibraryManager _libraryManager; - - public SeriesResolver(IFileSystem fileSystem, ILogger logger, ILibraryManager libraryManager) - { - _fileSystem = fileSystem; - _logger = logger; - _libraryManager = libraryManager; - } - /// /// Gets the priority. /// @@ -50,27 +33,16 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers.TV { if (args.IsDirectory) { - // Avoid expensive tests against VF's and all their children by not allowing this - if (args.Parent.IsRoot) - { - return null; - } - var collectionType = args.GetCollectionType(); // If there's a collection type and it's not tv, it can't be a series - if (!string.Equals(collectionType, CollectionType.TvShows, StringComparison.OrdinalIgnoreCase)) - { - return null; - } - - if (args.HasParent() || args.HasParent()) - { - return null; - } - - if (IsSeriesFolder(args.Path, args.FileSystemChildren, args.DirectoryService, _fileSystem, _logger, _libraryManager)) + if (string.Equals(collectionType, CollectionType.TvShows, StringComparison.OrdinalIgnoreCase)) { + if (args.HasParent()) + { + return null; + } + return new Series { Path = args.Path, @@ -82,88 +54,6 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers.TV return null; } - /// - /// Determines whether [is series folder] [the specified path]. - /// - /// The path. - /// The file system children. - /// The directory service. - /// The file system. - /// The logger. - /// The library manager. - /// true if [is series folder] [the specified path]; otherwise, false. - public static bool IsSeriesFolder(string path, IEnumerable fileSystemChildren, IDirectoryService directoryService, IFileSystem fileSystem, ILogger logger, ILibraryManager libraryManager) - { - foreach (var child in fileSystemChildren) - { - var attributes = child.Attributes; - - if ((attributes & FileAttributes.Hidden) == FileAttributes.Hidden) - { - //logger.Debug("Igoring series file or folder marked hidden: {0}", child.FullName); - continue; - } - - // Can't enforce this because files saved by Bitcasa are always marked System - //if ((attributes & FileAttributes.System) == FileAttributes.System) - //{ - // logger.Debug("Igoring series subfolder marked system: {0}", child.FullName); - // continue; - //} - - if ((attributes & FileAttributes.Directory) == FileAttributes.Directory) - { - if (IsSeasonFolder(child.FullName)) - { - //logger.Debug("{0} is a series because of season folder {1}.", path, child.FullName); - return true; - } - } - else - { - var fullName = child.FullName; - - if (libraryManager.IsVideoFile(fullName) || IsVideoPlaceHolder(fullName)) - { - return true; - } - } - } - - logger.Debug("{0} is not a series folder.", path); - return false; - } - - /// - /// Determines whether [is place holder] [the specified path]. - /// - /// The path. - /// true if [is place holder] [the specified path]; otherwise, false. - /// path - private static bool IsVideoPlaceHolder(string path) - { - if (string.IsNullOrEmpty(path)) - { - throw new ArgumentNullException("path"); - } - - var extension = Path.GetExtension(path); - - return string.Equals(extension, ".disc", StringComparison.OrdinalIgnoreCase); - } - - /// - /// Determines whether [is season folder] [the specified path]. - /// - /// The path. - /// true if [is season folder] [the specified path]; otherwise, false. - private static bool IsSeasonFolder(string path) - { - var seasonNumber = new SeasonPathParser(new ExtendedNamingOptions(), new RegexProvider()).Parse(path, true).SeasonNumber; - - return seasonNumber.HasValue; - } - /// /// Sets the initial item values. /// diff --git a/MediaBrowser.Server.Implementations/Library/UserManager.cs b/MediaBrowser.Server.Implementations/Library/UserManager.cs index 1a45d35a0..503af4970 100644 --- a/MediaBrowser.Server.Implementations/Library/UserManager.cs +++ b/MediaBrowser.Server.Implementations/Library/UserManager.cs @@ -860,6 +860,13 @@ namespace MediaBrowser.Server.Implementations.Library private async Task UpdateUserPolicy(User user, UserPolicy userPolicy, bool fireEvent) { + // The xml serializer will output differently if the type is not exact + if (userPolicy.GetType() != typeof(UserPolicy)) + { + var json = _jsonSerializer.SerializeToString(userPolicy); + userPolicy = _jsonSerializer.DeserializeFromString(json); + } + var updateConfig = user.Policy.IsAdministrator != userPolicy.IsAdministrator || user.Policy.EnableLiveTvManagement != userPolicy.EnableLiveTvManagement || user.Policy.EnableLiveTvAccess != userPolicy.EnableLiveTvAccess || diff --git a/MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json b/MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json index a5813a0e2..ef1c8ca6b 100644 --- a/MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json +++ b/MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json @@ -420,7 +420,7 @@ "HeaderMediaLocations": "Media Locations", "LabelFolderTypeValue": "Folder type: {0}", "LabelPathSubstitutionHelp": "Optional: Path substitution can map server paths to network shares that clients can access for direct playback.", - "FolderTypeMixed": "Mixed content", + "FolderTypeUnset": "Unset (mixed content)", "FolderTypeMovies": "Movies", "FolderTypeMusic": "Music", "FolderTypeAdultVideos": "Adult videos", @@ -660,5 +660,5 @@ "LabelItemLimitHelp": "Optional. Set a limit to the number of items that will be synced.", "MessageBookPluginRequired": "Requires installation of the Bookshelf plugin", "MessageGamePluginRequired": "Requires installation of the GameBrowser plugin", - "MessageMixedContentHelp": "Content will be displayed as a plain folder structure" + "MessageUnsetContentHelp": "Content will be displayed as plain folders. For best results use the metadata manager to set the content types of sub-folders." } diff --git a/MediaBrowser.Server.Implementations/Localization/Server/server.json b/MediaBrowser.Server.Implementations/Localization/Server/server.json index 6046f8390..7f0809897 100644 --- a/MediaBrowser.Server.Implementations/Localization/Server/server.json +++ b/MediaBrowser.Server.Implementations/Localization/Server/server.json @@ -377,8 +377,8 @@ "LabelMaxScreenshotsPerItem": "Maximum number of screenshots per item:", "LabelMinBackdropDownloadWidth": "Minimum backdrop download width:", "LabelMinScreenshotDownloadWidth": "Minimum screenshot download width:", - "ButtonAddScheduledTaskTrigger": "Add Task Trigger", - "HeaderAddScheduledTaskTrigger": "Add Task Trigger", + "ButtonAddScheduledTaskTrigger": "Add Trigger", + "HeaderAddScheduledTaskTrigger": "Add Trigger", "ButtonAdd": "Add", "LabelTriggerType": "Trigger Type:", "OptionDaily": "Daily", diff --git a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj index 4d21d2e94..59196d0bb 100644 --- a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj +++ b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj @@ -51,7 +51,7 @@ False - ..\packages\MediaBrowser.Naming.1.0.0.22\lib\portable-net45+sl4+wp71+win8+wpa81\MediaBrowser.Naming.dll + ..\packages\MediaBrowser.Naming.1.0.0.23\lib\portable-net45+sl4+wp71+win8+wpa81\MediaBrowser.Naming.dll False diff --git a/MediaBrowser.Server.Implementations/Session/WebSocketController.cs b/MediaBrowser.Server.Implementations/Session/WebSocketController.cs index 8eb129876..7d1057397 100644 --- a/MediaBrowser.Server.Implementations/Session/WebSocketController.cs +++ b/MediaBrowser.Server.Implementations/Session/WebSocketController.cs @@ -73,17 +73,6 @@ namespace MediaBrowser.Server.Implementations.Session _logger.ErrorException("Error reporting session ended.", ex); } } - else - { - var capabilities = new ClientCapabilities - { - PlayableMediaTypes = Session.PlayableMediaTypes, - SupportedCommands = Session.SupportedCommands, - SupportsMediaControl = SupportsMediaControl - }; - - _sessionManager.ReportCapabilities(Session.Id, capabilities); - } } private IWebSocketConnection GetActiveSocket() diff --git a/MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs b/MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs index 5c933b4bd..5e129d9a1 100644 --- a/MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs +++ b/MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs @@ -316,35 +316,26 @@ namespace MediaBrowser.Server.Implementations.Sync var video = item as Video; if (video != null) { - jobItem.OutputPath = await Sync(jobItem, video, deviceProfile, cancellationToken).ConfigureAwait(false); + await Sync(jobItem, video, deviceProfile, cancellationToken).ConfigureAwait(false); } else if (item is Audio) { - jobItem.OutputPath = await Sync(jobItem, (Audio)item, deviceProfile, cancellationToken).ConfigureAwait(false); + await Sync(jobItem, (Audio)item, deviceProfile, cancellationToken).ConfigureAwait(false); } else if (item is Photo) { - jobItem.OutputPath = await Sync(jobItem, (Photo)item, deviceProfile, cancellationToken).ConfigureAwait(false); + await Sync(jobItem, (Photo)item, deviceProfile, cancellationToken).ConfigureAwait(false); } - else if (item is Game) - { - jobItem.OutputPath = await Sync(jobItem, (Game)item, deviceProfile, cancellationToken).ConfigureAwait(false); - } - - else if (item is Book) + else { - jobItem.OutputPath = await Sync(jobItem, (Book)item, deviceProfile, cancellationToken).ConfigureAwait(false); + await SyncGeneric(jobItem, item, deviceProfile, cancellationToken).ConfigureAwait(false); } - - jobItem.Progress = 50; - jobItem.Status = SyncJobItemStatus.Transferring; - await _syncRepo.Update(jobItem).ConfigureAwait(false); } - private async Task Sync(SyncJobItem jobItem, Video item, DeviceProfile profile, CancellationToken cancellationToken) + private async Task Sync(SyncJobItem jobItem, Video item, DeviceProfile profile, CancellationToken cancellationToken) { var options = new VideoOptions { @@ -359,26 +350,33 @@ namespace MediaBrowser.Server.Implementations.Sync var mediaSource = streamInfo.MediaSource; jobItem.MediaSourceId = streamInfo.MediaSourceId; - await _syncRepo.Update(jobItem).ConfigureAwait(false); - if (streamInfo.PlayMethod != PlayMethod.Transcode) + if (streamInfo.PlayMethod == PlayMethod.Transcode) + { + await _syncRepo.Update(jobItem).ConfigureAwait(false); + } + else { if (mediaSource.Protocol == MediaProtocol.File) { - return mediaSource.Path; + jobItem.OutputPath = mediaSource.Path; } if (mediaSource.Protocol == MediaProtocol.Http) { - return await DownloadFile(jobItem, mediaSource, cancellationToken).ConfigureAwait(false); + jobItem.OutputPath = await DownloadFile(jobItem, mediaSource, cancellationToken).ConfigureAwait(false); } throw new InvalidOperationException(string.Format("Cannot direct stream {0} protocol", mediaSource.Protocol)); } // TODO: Transcode - return mediaSource.Path; + jobItem.OutputPath = mediaSource.Path; + + jobItem.Progress = 50; + jobItem.Status = SyncJobItemStatus.Transferring; + await _syncRepo.Update(jobItem).ConfigureAwait(false); } - private async Task Sync(SyncJobItem jobItem, Audio item, DeviceProfile profile, CancellationToken cancellationToken) + private async Task Sync(SyncJobItem jobItem, Audio item, DeviceProfile profile, CancellationToken cancellationToken) { var options = new AudioOptions { @@ -393,38 +391,48 @@ namespace MediaBrowser.Server.Implementations.Sync var mediaSource = streamInfo.MediaSource; jobItem.MediaSourceId = streamInfo.MediaSourceId; - await _syncRepo.Update(jobItem).ConfigureAwait(false); - if (streamInfo.PlayMethod != PlayMethod.Transcode) + if (streamInfo.PlayMethod == PlayMethod.Transcode) + { + await _syncRepo.Update(jobItem).ConfigureAwait(false); + } + else { if (mediaSource.Protocol == MediaProtocol.File) { - return mediaSource.Path; + jobItem.OutputPath = mediaSource.Path; } if (mediaSource.Protocol == MediaProtocol.Http) { - return await DownloadFile(jobItem, mediaSource, cancellationToken).ConfigureAwait(false); + jobItem.OutputPath = await DownloadFile(jobItem, mediaSource, cancellationToken).ConfigureAwait(false); } throw new InvalidOperationException(string.Format("Cannot direct stream {0} protocol", mediaSource.Protocol)); } // TODO: Transcode - return mediaSource.Path; - } + jobItem.OutputPath = mediaSource.Path; - private async Task Sync(SyncJobItem jobItem, Photo item, DeviceProfile profile, CancellationToken cancellationToken) - { - return item.Path; + jobItem.Progress = 50; + jobItem.Status = SyncJobItemStatus.Transferring; + await _syncRepo.Update(jobItem).ConfigureAwait(false); } - private async Task Sync(SyncJobItem jobItem, Game item, DeviceProfile profile, CancellationToken cancellationToken) + private async Task Sync(SyncJobItem jobItem, Photo item, DeviceProfile profile, CancellationToken cancellationToken) { - return item.Path; + jobItem.OutputPath = item.Path; + + jobItem.Progress = 50; + jobItem.Status = SyncJobItemStatus.Transferring; + await _syncRepo.Update(jobItem).ConfigureAwait(false); } - private async Task Sync(SyncJobItem jobItem, Book item, DeviceProfile profile, CancellationToken cancellationToken) + private async Task SyncGeneric(SyncJobItem jobItem, BaseItem item, DeviceProfile profile, CancellationToken cancellationToken) { - return item.Path; + jobItem.OutputPath = item.Path; + + jobItem.Progress = 50; + jobItem.Status = SyncJobItemStatus.Transferring; + await _syncRepo.Update(jobItem).ConfigureAwait(false); } private async Task DownloadFile(SyncJobItem jobItem, MediaSourceInfo mediaSource, CancellationToken cancellationToken) diff --git a/MediaBrowser.Server.Implementations/Sync/SyncManager.cs b/MediaBrowser.Server.Implementations/Sync/SyncManager.cs index 22d0ee5e7..24b9b0b83 100644 --- a/MediaBrowser.Server.Implementations/Sync/SyncManager.cs +++ b/MediaBrowser.Server.Implementations/Sync/SyncManager.cs @@ -1,5 +1,4 @@ -using System.IO; -using MediaBrowser.Common; +using MediaBrowser.Common; using MediaBrowser.Common.Extensions; using MediaBrowser.Controller.Channels; using MediaBrowser.Controller.Drawing; @@ -20,6 +19,7 @@ using MediaBrowser.Model.Users; using MoreLinq; using System; using System.Collections.Generic; +using System.IO; using System.Linq; using System.Threading.Tasks; @@ -337,7 +337,19 @@ namespace MediaBrowser.Server.Implementations.Sync UserId = job.UserId }; - syncedItem.Item = _dtoService().GetBaseItemDto(libraryItem, new DtoOptions()); + var dtoOptions = new DtoOptions(); + + // Remove some bloat + dtoOptions.Fields.Remove(ItemFields.MediaStreams); + dtoOptions.Fields.Remove(ItemFields.IndexOptions); + dtoOptions.Fields.Remove(ItemFields.MediaSourceCount); + dtoOptions.Fields.Remove(ItemFields.OriginalPrimaryImageAspectRatio); + dtoOptions.Fields.Remove(ItemFields.Path); + dtoOptions.Fields.Remove(ItemFields.SeriesGenres); + dtoOptions.Fields.Remove(ItemFields.Settings); + dtoOptions.Fields.Remove(ItemFields.SyncInfo); + + syncedItem.Item = _dtoService().GetBaseItemDto(libraryItem, dtoOptions); // TODO: this should be the media source of the transcoded output syncedItem.Item.MediaSources = syncedItem.Item.MediaSources @@ -370,10 +382,11 @@ namespace MediaBrowser.Server.Implementations.Sync var jobItemResult = GetJobItems(new SyncJobItemQuery { TargetId = targetId, - //Status = SyncJobItemStatus.Transferring + Status = SyncJobItemStatus.Transferring }); - return jobItemResult.Items.Select(GetJobItemInfo).ToList(); + return jobItemResult.Items.Select(GetJobItemInfo) + .ToList(); } } } diff --git a/MediaBrowser.Server.Implementations/Sync/SyncRepository.cs b/MediaBrowser.Server.Implementations/Sync/SyncRepository.cs index a981ffc57..e5b323725 100644 --- a/MediaBrowser.Server.Implementations/Sync/SyncRepository.cs +++ b/MediaBrowser.Server.Implementations/Sync/SyncRepository.cs @@ -227,7 +227,7 @@ namespace MediaBrowser.Server.Implementations.Sync _saveJobCommand.GetParameter(index++).Value = job.TargetId; _saveJobCommand.GetParameter(index++).Value = job.Name; _saveJobCommand.GetParameter(index++).Value = job.Quality; - _saveJobCommand.GetParameter(index++).Value = job.Status; + _saveJobCommand.GetParameter(index++).Value = job.Status.ToString(); _saveJobCommand.GetParameter(index++).Value = job.Progress; _saveJobCommand.GetParameter(index++).Value = job.UserId; _saveJobCommand.GetParameter(index++).Value = string.Join(",", job.RequestedItemIds.ToArray()); @@ -466,13 +466,14 @@ namespace MediaBrowser.Server.Implementations.Sync whereClauses.Add("TargetId=@TargetId"); cmd.Parameters.Add(cmd, "@TargetId", DbType.String).Value = query.TargetId; } + if (query.Status.HasValue) { whereClauses.Add("Status=@Status"); cmd.Parameters.Add(cmd, "@Status", DbType.String).Value = query.Status.Value.ToString(); } - if (query.IsCompleted.HasValue) + else if (query.IsCompleted.HasValue) { if (query.IsCompleted.Value) { @@ -561,7 +562,7 @@ namespace MediaBrowser.Server.Implementations.Sync _saveJobItemCommand.GetParameter(index++).Value = jobItem.MediaSourceId; _saveJobItemCommand.GetParameter(index++).Value = jobItem.JobId; _saveJobItemCommand.GetParameter(index++).Value = jobItem.OutputPath; - _saveJobItemCommand.GetParameter(index++).Value = jobItem.Status; + _saveJobItemCommand.GetParameter(index++).Value = jobItem.Status.ToString(); _saveJobItemCommand.GetParameter(index++).Value = jobItem.TargetId; _saveJobItemCommand.GetParameter(index++).Value = jobItem.DateCreated; _saveJobItemCommand.GetParameter(index++).Value = jobItem.Progress; diff --git a/MediaBrowser.Server.Implementations/packages.config b/MediaBrowser.Server.Implementations/packages.config index 2fa4d1449..f4406913b 100644 --- a/MediaBrowser.Server.Implementations/packages.config +++ b/MediaBrowser.Server.Implementations/packages.config @@ -1,6 +1,6 @@  - + \ No newline at end of file diff --git a/MediaBrowser.Server.Mono/MediaBrowser.Server.Mono.csproj b/MediaBrowser.Server.Mono/MediaBrowser.Server.Mono.csproj index c53654e4f..e780f447f 100644 --- a/MediaBrowser.Server.Mono/MediaBrowser.Server.Mono.csproj +++ b/MediaBrowser.Server.Mono/MediaBrowser.Server.Mono.csproj @@ -131,10 +131,6 @@ - - libgdiplus.dylib - PreserveNewest - libwebp\osx\libwebp.5.dylib PreserveNewest -- cgit v1.2.3 From 8a9f16ff6ae94fe1e86d93495b4908e253f7dba2 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Mon, 29 Dec 2014 15:18:48 -0500 Subject: enable user device access --- MediaBrowser.Api/Session/SessionsService.cs | 22 +++++++- .../MediaBrowser.Common.Implementations.csproj | 7 +-- .../packages.config | 1 - MediaBrowser.Controller/Devices/IDeviceManager.cs | 8 +++ MediaBrowser.Controller/Entities/Audio/Audio.cs | 15 ++++++ MediaBrowser.Controller/Entities/Video.cs | 17 +++++- MediaBrowser.Model/Net/MimeTypes.cs | 16 ++++-- MediaBrowser.Model/Users/UserPolicy.cs | 6 +++ .../MediaInfo/AudioImageProvider.cs | 5 +- .../MediaInfo/FFProbeAudioInfo.cs | 23 ++++++--- .../MediaInfo/FFProbeVideoInfo.cs | 7 +++ .../MediaInfo/VideoImageProvider.cs | 2 +- .../Devices/DeviceManager.cs | 37 +++++++++++++ .../HttpServer/Security/AuthService.cs | 60 +++++++++++++++------- .../Library/Resolvers/Movies/BoxSetResolver.cs | 5 -- .../Library/Resolvers/Movies/MovieResolver.cs | 57 +++++--------------- .../Localization/JavaScript/javascript.json | 4 ++ .../Localization/Server/server.json | 4 ++ .../MediaBrowser.Server.Implementations.csproj | 2 +- .../Session/SessionManager.cs | 8 +++ .../packages.config | 2 +- .../ApplicationHost.cs | 2 +- Nuget/MediaBrowser.Common.Internal.nuspec | 5 +- Nuget/MediaBrowser.Common.nuspec | 2 +- Nuget/MediaBrowser.Model.Signed.nuspec | 2 +- Nuget/MediaBrowser.Server.Core.nuspec | 4 +- 26 files changed, 223 insertions(+), 100 deletions(-) (limited to 'MediaBrowser.Server.Implementations/Session') diff --git a/MediaBrowser.Api/Session/SessionsService.cs b/MediaBrowser.Api/Session/SessionsService.cs index 4f47b9f54..59b8e85c2 100644 --- a/MediaBrowser.Api/Session/SessionsService.cs +++ b/MediaBrowser.Api/Session/SessionsService.cs @@ -1,4 +1,5 @@ -using MediaBrowser.Controller.Library; +using MediaBrowser.Controller.Devices; +using MediaBrowser.Controller.Library; using MediaBrowser.Controller.Net; using MediaBrowser.Controller.Security; using MediaBrowser.Controller.Session; @@ -299,6 +300,7 @@ namespace MediaBrowser.Api.Session private readonly IUserManager _userManager; private readonly IAuthorizationContext _authContext; private readonly IAuthenticationRepository _authRepo; + private readonly IDeviceManager _deviceManager; /// /// Initializes a new instance of the class. @@ -307,12 +309,13 @@ namespace MediaBrowser.Api.Session /// The user manager. /// The authentication context. /// The authentication repo. - public SessionsService(ISessionManager sessionManager, IUserManager userManager, IAuthorizationContext authContext, IAuthenticationRepository authRepo) + public SessionsService(ISessionManager sessionManager, IUserManager userManager, IAuthorizationContext authContext, IAuthenticationRepository authRepo, IDeviceManager deviceManager) { _sessionManager = sessionManager; _userManager = userManager; _authContext = authContext; _authRepo = authRepo; + _deviceManager = deviceManager; } public void Delete(RevokeKey request) @@ -382,6 +385,21 @@ namespace MediaBrowser.Api.Session { result = result.Where(i => !i.UserId.HasValue); } + + result = result.Where(i => + { + var deviceId = i.DeviceId; + + if (!string.IsNullOrWhiteSpace(deviceId)) + { + if (!_deviceManager.CanAccessDevice(user.Id.ToString("N"), deviceId)) + { + return false; + } + } + + return true; + }); } return ToOptimizedResult(result.Select(_sessionManager.GetSessionInfoDto).ToList()); diff --git a/MediaBrowser.Common.Implementations/MediaBrowser.Common.Implementations.csproj b/MediaBrowser.Common.Implementations/MediaBrowser.Common.Implementations.csproj index 0aaf0b4e0..ff08c31bc 100644 --- a/MediaBrowser.Common.Implementations/MediaBrowser.Common.Implementations.csproj +++ b/MediaBrowser.Common.Implementations/MediaBrowser.Common.Implementations.csproj @@ -52,6 +52,10 @@ False ..\packages\NLog.3.1.0.0\lib\net45\NLog.dll + + False + ..\ThirdParty\SharpCompress\SharpCompress.dll + False ..\packages\SimpleInjector.2.6.1\lib\net45\SimpleInjector.dll @@ -65,9 +69,6 @@ - - ..\packages\sharpcompress.0.10.2\lib\net40\SharpCompress.dll - ..\ThirdParty\ServiceStack.Text\ServiceStack.Text.dll diff --git a/MediaBrowser.Common.Implementations/packages.config b/MediaBrowser.Common.Implementations/packages.config index c57aea0b5..63d288bbb 100644 --- a/MediaBrowser.Common.Implementations/packages.config +++ b/MediaBrowser.Common.Implementations/packages.config @@ -1,6 +1,5 @@  - diff --git a/MediaBrowser.Controller/Devices/IDeviceManager.cs b/MediaBrowser.Controller/Devices/IDeviceManager.cs index efd24336a..f5010bb45 100644 --- a/MediaBrowser.Controller/Devices/IDeviceManager.cs +++ b/MediaBrowser.Controller/Devices/IDeviceManager.cs @@ -85,5 +85,13 @@ namespace MediaBrowser.Controller.Devices /// The file. /// Task. Task AcceptCameraUpload(string deviceId, Stream stream, LocalFileInfo file); + + /// + /// Determines whether this instance [can access device] the specified user identifier. + /// + /// The user identifier. + /// The device identifier. + /// true if this instance [can access device] the specified user identifier; otherwise, false. + bool CanAccessDevice(string userId, string deviceId); } } diff --git a/MediaBrowser.Controller/Entities/Audio/Audio.cs b/MediaBrowser.Controller/Entities/Audio/Audio.cs index 623ae8968..c5ed09016 100644 --- a/MediaBrowser.Controller/Entities/Audio/Audio.cs +++ b/MediaBrowser.Controller/Entities/Audio/Audio.cs @@ -89,6 +89,21 @@ namespace MediaBrowser.Controller.Entities.Audio } } + [IgnoreDataMember] + public bool IsArchive + { + get + { + if (string.IsNullOrWhiteSpace(Path)) + { + return false; + } + var ext = System.IO.Path.GetExtension(Path) ?? string.Empty; + + return new[] { ".zip", ".rar", ".7z" }.Contains(ext, StringComparer.OrdinalIgnoreCase); + } + } + /// /// Gets or sets the artist. /// diff --git a/MediaBrowser.Controller/Entities/Video.cs b/MediaBrowser.Controller/Entities/Video.cs index 0c6125dbe..3abaf095c 100644 --- a/MediaBrowser.Controller/Entities/Video.cs +++ b/MediaBrowser.Controller/Entities/Video.cs @@ -91,6 +91,21 @@ namespace MediaBrowser.Controller.Entities get { return LocalAlternateVersions.Count > 0; } } + [IgnoreDataMember] + public bool IsArchive + { + get + { + if (string.IsNullOrWhiteSpace(Path)) + { + return false; + } + var ext = System.IO.Path.GetExtension(Path) ?? string.Empty; + + return new[] { ".zip", ".rar", ".7z" }.Contains(ext, StringComparer.OrdinalIgnoreCase); + } + } + public IEnumerable GetAdditionalPartIds() { return AdditionalParts.Select(i => LibraryManager.GetNewItemId(i, typeof(Video))); @@ -246,7 +261,7 @@ namespace MediaBrowser.Controller.Entities { return System.IO.Path.GetFileName(Path); } - + return System.IO.Path.GetFileNameWithoutExtension(Path); } diff --git a/MediaBrowser.Model/Net/MimeTypes.cs b/MediaBrowser.Model/Net/MimeTypes.cs index 19dda0603..1f54e48d1 100644 --- a/MediaBrowser.Model/Net/MimeTypes.cs +++ b/MediaBrowser.Model/Net/MimeTypes.cs @@ -73,10 +73,18 @@ namespace MediaBrowser.Model.Net {".m4v", "video/x-m4v"} }; - private static readonly Dictionary ExtensionLookup = - MimeTypeLookup - .GroupBy(i => i.Value) - .ToDictionary(x => x.Key, x => x.First().Key, StringComparer.OrdinalIgnoreCase); + private static readonly Dictionary ExtensionLookup = CreateExtensionLookup(); + + private static Dictionary CreateExtensionLookup() + { + var dict = MimeTypeLookup + .GroupBy(i => i.Value) + .ToDictionary(x => x.Key, x => x.First().Key, StringComparer.OrdinalIgnoreCase); + + dict["image/jpg"] = ".jpg"; + + return dict; + } /// /// Gets the type of the MIME. diff --git a/MediaBrowser.Model/Users/UserPolicy.cs b/MediaBrowser.Model/Users/UserPolicy.cs index 4d09ae8e8..0a6a37696 100644 --- a/MediaBrowser.Model/Users/UserPolicy.cs +++ b/MediaBrowser.Model/Users/UserPolicy.cs @@ -49,6 +49,9 @@ namespace MediaBrowser.Model.Users /// true if [enable synchronize]; otherwise, false. public bool EnableSync { get; set; } + public string[] EnabledDevices { get; set; } + public bool EnableAllDevices { get; set; } + public UserPolicy() { EnableLiveTvManagement = true; @@ -64,6 +67,9 @@ namespace MediaBrowser.Model.Users EnableUserPreferenceAccess = true; AccessSchedules = new AccessSchedule[] { }; + + EnabledDevices = new string[] { }; + EnableAllDevices = true; } } } diff --git a/MediaBrowser.Providers/MediaInfo/AudioImageProvider.cs b/MediaBrowser.Providers/MediaInfo/AudioImageProvider.cs index b0c1b10e4..65d8e287f 100644 --- a/MediaBrowser.Providers/MediaInfo/AudioImageProvider.cs +++ b/MediaBrowser.Providers/MediaInfo/AudioImageProvider.cs @@ -6,7 +6,6 @@ using MediaBrowser.Controller.Entities.Audio; using MediaBrowser.Controller.MediaEncoding; using MediaBrowser.Controller.Providers; using MediaBrowser.Model.Entities; -using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.IO; @@ -132,7 +131,9 @@ namespace MediaBrowser.Providers.MediaInfo public bool Supports(IHasImages item) { - return item is Audio; + var audio = item as Audio; + + return item.LocationType == LocationType.FileSystem && audio != null && !audio.IsArchive; } public bool HasChanged(IHasMetadata item, MetadataStatus status, IDirectoryService directoryService) diff --git a/MediaBrowser.Providers/MediaInfo/FFProbeAudioInfo.cs b/MediaBrowser.Providers/MediaInfo/FFProbeAudioInfo.cs index a856d5dba..2634bd9bc 100644 --- a/MediaBrowser.Providers/MediaInfo/FFProbeAudioInfo.cs +++ b/MediaBrowser.Providers/MediaInfo/FFProbeAudioInfo.cs @@ -38,6 +38,13 @@ namespace MediaBrowser.Providers.MediaInfo public async Task Probe(T item, CancellationToken cancellationToken) where T : Audio { + if (item.IsArchive) + { + var ext = Path.GetExtension(item.Path) ?? string.Empty; + item.Container = ext.TrimStart('.'); + return ItemUpdateType.MetadataImport; + } + var result = await GetMediaInfo(item, cancellationToken).ConfigureAwait(false); cancellationToken.ThrowIfCancellationRequested(); @@ -58,8 +65,8 @@ namespace MediaBrowser.Providers.MediaInfo cancellationToken.ThrowIfCancellationRequested(); var idString = item.Id.ToString("N"); - var cachePath = Path.Combine(_appPaths.CachePath, - "ffprobe-audio", + var cachePath = Path.Combine(_appPaths.CachePath, + "ffprobe-audio", idString.Substring(0, 2), idString, "v" + SchemaVersion + _mediaEncoder.Version + item.DateModified.Ticks.ToString(_usCulture) + ".json"); try @@ -132,7 +139,7 @@ namespace MediaBrowser.Providers.MediaInfo if (!string.IsNullOrEmpty(data.format.size)) { - audio.Size = long.Parse(data.format.size , _usCulture); + audio.Size = long.Parse(data.format.size, _usCulture); } else { @@ -217,9 +224,9 @@ namespace MediaBrowser.Providers.MediaInfo audio.ProductionYear = FFProbeHelpers.GetDictionaryNumericValue(tags, "date"); // Several different forms of retaildate - audio.PremiereDate = FFProbeHelpers.GetDictionaryDateTime(tags, "retaildate") ?? - FFProbeHelpers.GetDictionaryDateTime(tags, "retail date") ?? - FFProbeHelpers.GetDictionaryDateTime(tags, "retail_date") ?? + audio.PremiereDate = FFProbeHelpers.GetDictionaryDateTime(tags, "retaildate") ?? + FFProbeHelpers.GetDictionaryDateTime(tags, "retail date") ?? + FFProbeHelpers.GetDictionaryDateTime(tags, "retail_date") ?? FFProbeHelpers.GetDictionaryDateTime(tags, "date"); // If we don't have a ProductionYear try and get it from PremiereDate @@ -261,8 +268,8 @@ namespace MediaBrowser.Providers.MediaInfo { // Only use the comma as a delimeter if there are no slashes or pipes. // We want to be careful not to split names that have commas in them - var delimeter = !allowCommaDelimiter || _nameDelimiters.Any(i => val.IndexOf(i) != -1) ? - _nameDelimiters : + var delimeter = !allowCommaDelimiter || _nameDelimiters.Any(i => val.IndexOf(i) != -1) ? + _nameDelimiters : new[] { ',' }; return val.Split(delimeter, StringSplitOptions.RemoveEmptyEntries) diff --git a/MediaBrowser.Providers/MediaInfo/FFProbeVideoInfo.cs b/MediaBrowser.Providers/MediaInfo/FFProbeVideoInfo.cs index 7c078866a..7f025dea1 100644 --- a/MediaBrowser.Providers/MediaInfo/FFProbeVideoInfo.cs +++ b/MediaBrowser.Providers/MediaInfo/FFProbeVideoInfo.cs @@ -71,6 +71,13 @@ namespace MediaBrowser.Providers.MediaInfo CancellationToken cancellationToken) where T : Video { + if (item.IsArchive) + { + var ext = Path.GetExtension(item.Path) ?? string.Empty; + item.Container = ext.TrimStart('.'); + return ItemUpdateType.MetadataImport; + } + var isoMount = await MountIsoIfNeeded(item, cancellationToken).ConfigureAwait(false); BlurayDiscInfo blurayDiscInfo = null; diff --git a/MediaBrowser.Providers/MediaInfo/VideoImageProvider.cs b/MediaBrowser.Providers/MediaInfo/VideoImageProvider.cs index a91a01edc..7f55ce1ac 100644 --- a/MediaBrowser.Providers/MediaInfo/VideoImageProvider.cs +++ b/MediaBrowser.Providers/MediaInfo/VideoImageProvider.cs @@ -123,7 +123,7 @@ namespace MediaBrowser.Providers.MediaInfo { var video = item as Video; - return item.LocationType == LocationType.FileSystem && video != null && !video.IsPlaceHolder && !video.IsShortcut; + return item.LocationType == LocationType.FileSystem && video != null && !video.IsPlaceHolder && !video.IsShortcut && !video.IsArchive; } public int Order diff --git a/MediaBrowser.Server.Implementations/Devices/DeviceManager.cs b/MediaBrowser.Server.Implementations/Devices/DeviceManager.cs index 6cdc58118..3810fec66 100644 --- a/MediaBrowser.Server.Implementations/Devices/DeviceManager.cs +++ b/MediaBrowser.Server.Implementations/Devices/DeviceManager.cs @@ -5,6 +5,7 @@ using MediaBrowser.Controller.Devices; using MediaBrowser.Controller.Library; using MediaBrowser.Model.Devices; using MediaBrowser.Model.Events; +using MediaBrowser.Model.Extensions; using MediaBrowser.Model.Logging; using MediaBrowser.Model.Querying; using MediaBrowser.Model.Session; @@ -13,6 +14,7 @@ using System.Collections.Generic; using System.IO; using System.Linq; using System.Threading.Tasks; +using MediaBrowser.Model.Users; namespace MediaBrowser.Server.Implementations.Devices { @@ -188,6 +190,41 @@ namespace MediaBrowser.Server.Implementations.Devices EventHelper.FireEventIfNotNull(DeviceOptionsUpdated, this, new GenericEventArgs(device), _logger); } + + public bool CanAccessDevice(string userId, string deviceId) + { + if (string.IsNullOrWhiteSpace(userId)) + { + throw new ArgumentNullException("userId"); + } + if (string.IsNullOrWhiteSpace(deviceId)) + { + throw new ArgumentNullException("deviceId"); + } + + var user = _userManager.GetUserById(userId); + if (!CanAccessDevice(user.Policy, deviceId)) + { + var capabilities = GetCapabilities(deviceId); + + if (capabilities.SupportsUniqueIdentifier) + { + return false; + } + } + + return true; + } + + private bool CanAccessDevice(UserPolicy policy, string id) + { + if (policy.EnableAllDevices) + { + return true; + } + + return ListHelper.ContainsIgnoreCase(policy.EnabledDevices, id); + } } public class DevicesConfigStore : IConfigurationFactory diff --git a/MediaBrowser.Server.Implementations/HttpServer/Security/AuthService.cs b/MediaBrowser.Server.Implementations/HttpServer/Security/AuthService.cs index 13563ce19..1d17c641d 100644 --- a/MediaBrowser.Server.Implementations/HttpServer/Security/AuthService.cs +++ b/MediaBrowser.Server.Implementations/HttpServer/Security/AuthService.cs @@ -1,5 +1,6 @@ using MediaBrowser.Controller.Configuration; using MediaBrowser.Controller.Connect; +using MediaBrowser.Controller.Devices; using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Library; using MediaBrowser.Controller.Net; @@ -15,10 +16,11 @@ namespace MediaBrowser.Server.Implementations.HttpServer.Security { private readonly IServerConfigurationManager _config; - public AuthService(IUserManager userManager, IAuthorizationContext authorizationContext, IServerConfigurationManager config, IConnectManager connectManager, ISessionManager sessionManager) + public AuthService(IUserManager userManager, IAuthorizationContext authorizationContext, IServerConfigurationManager config, IConnectManager connectManager, ISessionManager sessionManager, IDeviceManager deviceManager) { AuthorizationContext = authorizationContext; _config = config; + DeviceManager = deviceManager; SessionManager = sessionManager; ConnectManager = connectManager; UserManager = userManager; @@ -28,6 +30,7 @@ namespace MediaBrowser.Server.Implementations.HttpServer.Security public IAuthorizationContext AuthorizationContext { get; private set; } public IConnectManager ConnectManager { get; private set; } public ISessionManager SessionManager { get; private set; } + public IDeviceManager DeviceManager { get; private set; } /// /// Redirect the client to a specific URL if authentication failed. @@ -68,24 +71,7 @@ namespace MediaBrowser.Server.Implementations.HttpServer.Security if (user != null) { - if (user.Policy.IsDisabled) - { - throw new SecurityException("User account has been disabled.") - { - SecurityExceptionType = SecurityExceptionType.Unauthenticated - }; - } - - if (!user.Policy.IsAdministrator && - !authAttribtues.EscapeParentalControl && - !user.IsParentalScheduleAllowed()) - { - request.AddResponseHeader("X-Application-Error-Code", "ParentalControl"); - throw new SecurityException("This user account is not allowed access at this time.") - { - SecurityExceptionType = SecurityExceptionType.ParentalControl - }; - } + ValidateUserAccess(user, request, authAttribtues, auth); } if (!IsExemptFromRoles(auth, authAttribtues)) @@ -108,6 +94,42 @@ namespace MediaBrowser.Server.Implementations.HttpServer.Security } } + private void ValidateUserAccess(User user, IServiceRequest request, + IAuthenticationAttributes authAttribtues, + AuthorizationInfo auth) + { + if (user.Policy.IsDisabled) + { + throw new SecurityException("User account has been disabled.") + { + SecurityExceptionType = SecurityExceptionType.Unauthenticated + }; + } + + if (!user.Policy.IsAdministrator && + !authAttribtues.EscapeParentalControl && + !user.IsParentalScheduleAllowed()) + { + request.AddResponseHeader("X-Application-Error-Code", "ParentalControl"); + + throw new SecurityException("This user account is not allowed access at this time.") + { + SecurityExceptionType = SecurityExceptionType.ParentalControl + }; + } + + if (!string.IsNullOrWhiteSpace(auth.DeviceId)) + { + if (!DeviceManager.CanAccessDevice(user.Id.ToString("N"), auth.DeviceId)) + { + throw new SecurityException("User is not allowed access from this device.") + { + SecurityExceptionType = SecurityExceptionType.ParentalControl + }; + } + } + } + private bool IsExemptFromAuthenticationToken(AuthorizationInfo auth, IAuthenticationAttributes authAttribtues) { if (!_config.Configuration.IsStartupWizardCompleted && diff --git a/MediaBrowser.Server.Implementations/Library/Resolvers/Movies/BoxSetResolver.cs b/MediaBrowser.Server.Implementations/Library/Resolvers/Movies/BoxSetResolver.cs index 390113cc8..67b9d546f 100644 --- a/MediaBrowser.Server.Implementations/Library/Resolvers/Movies/BoxSetResolver.cs +++ b/MediaBrowser.Server.Implementations/Library/Resolvers/Movies/BoxSetResolver.cs @@ -25,11 +25,6 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers.Movies // Contains [boxset] in the path if (args.IsDirectory) { - if (IsInvalid(args.GetCollectionType())) - { - return null; - } - var filename = Path.GetFileName(args.Path); if (string.IsNullOrEmpty(filename)) diff --git a/MediaBrowser.Server.Implementations/Library/Resolvers/Movies/MovieResolver.cs b/MediaBrowser.Server.Implementations/Library/Resolvers/Movies/MovieResolver.cs index f7a82c5b8..587c6668c 100644 --- a/MediaBrowser.Server.Implementations/Library/Resolvers/Movies/MovieResolver.cs +++ b/MediaBrowser.Server.Implementations/Library/Resolvers/Movies/MovieResolver.cs @@ -1,12 +1,9 @@ -using MediaBrowser.Common.IO; -using MediaBrowser.Controller; -using MediaBrowser.Controller.Entities; +using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Entities.Movies; using MediaBrowser.Controller.Library; using MediaBrowser.Controller.Providers; using MediaBrowser.Controller.Resolvers; using MediaBrowser.Model.Entities; -using MediaBrowser.Model.Logging; using MediaBrowser.Naming.Common; using MediaBrowser.Naming.IO; using MediaBrowser.Naming.Video; @@ -22,16 +19,8 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers.Movies /// public class MovieResolver : BaseVideoResolver