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 1f294c325e..4c587d1ab6 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 f34c53b168..cb8f91ab6e 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 e6b525e534..25130776ee 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 4629b2a8ce..a951cd3d68 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 c20cef3b38..49a3e3291e 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 0000000000..ff5b8bd599 --- /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 42a4029407..0aaf0b4e0f 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 7212b70e1d..0000000000 --- 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 140a4ae0e4..b4cc17f514 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 a2af3707be..0000000000 --- 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 4b6c4111d0..0000000000 --- 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 3b9f3a5b23..21ae6bf61d 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 0000000000..f1e371c1a7 --- /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 0000000000..2b4fc7676e --- /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 ed590a1f24..36a7fcbd8a 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 b4cc17f514..c46dd4a4f6 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 b31a953192..0000000000 --- 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 b7715e20b9..0000000000 --- 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 ce22c95202..0000000000 --- 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 c1f935a7b4..0000000000 --- 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 ce068463ea..9d0133c67c 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 d487362f54..98d2682989 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 21ae6bf61d..3ed87ced8b 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 58a68c257e..4a807df7ac 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 0000000000..b88f2c3896 --- /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 0000000000..83ead5a12f --- /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 0000000000..394fcd92ff --- /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 0000000000..332f164208 --- /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 810b1e5684..dc4aff1901 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 52ec5c9b12..5acec2d6b9 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 386c16513b..d97ccb9bd2 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 de53201c9a..098a1d2bda 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 36ba55828a..940be6d02b 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 86e8856cfb..dfde34e25b 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 8cc614fe5d..f8e8bb9dd5 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 2d41cc26f2..9635854d46 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 7ff3a12478..354b1e20fd 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 9deb34e917..ffaecc0d54 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 3c3d7740a0..a8950da899 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 0756aa1ec5..0788ed2cee 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 91a4940ae3..d80e0b66ef 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 39d2d52d71..227c32242e 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 60c2501157..d76a7c7eea 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 5042e1cea3..cf0135fa82 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 9a37c268c9..0712164187 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 fc4d263636..4dbe0f3470 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 ab4e759230..0036b316ff 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 aea04187d9..90427de75d 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 83ead5a12f..37fd6708d9 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 e16a978c39..39cec4f00f 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 dc4aff1901..810b1e5684 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 7307354994..ba5b6a122f 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 bc93b69bcf..bb9a0c6ef2 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 8095b0cff2..ef19973a23 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 5acec2d6b9..52ec5c9b12 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 d97ccb9bd2..386c16513b 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 098a1d2bda..fcc6640119 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 940be6d02b..36ba55828a 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 b754a943a8..c3228db920 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 dfde34e25b..e77600e938 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 f8e8bb9dd5..cac2f8e094 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 9635854d46..31c0e87b33 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 354b1e20fd..401d49325a 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 ffaecc0d54..4d2d57b6ea 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 a8950da899..9f75d522c9 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 0788ed2cee..8eb1298768 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 a9e257a8c9..22d0ee5e7e 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 2ff6d7ae6b..a981ffc572 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 d80e0b66ef..91a4940ae3 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 a2c860413c..576b5b75f1 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 227c32242e..7f61570a4d 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 d76a7c7eea..60c2501157 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 06d63b355e..8398c63cbd 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 cf0135fa82..4abea57fb1 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 3504123444..3346ecb317 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 e5989db3bf..d9063aa580 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 0712164187..0970d6537a 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 4dbe0f3470..fc4d263636 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 3fd559a4d3..80e2f32f7b 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 84eec30d67..8c22ebb5df 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 ad3bd826d3..f313bd7a59 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 191ab9e88e..a31f8023bf 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 91b02089cc..28db46b986 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 23d40cf67f..c32134d4fc 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 6563da8de7..8d3cf9bad6 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 fa3d7d87db..67fa12b558 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 ba0725da53..13b31c2013 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 062519f9d5..5afaaa8753 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 79fab2f704..6e3a5bf063 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 939bd2b3be..a73d82992d 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 05ff270fc2..0f703cb22b 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 e3447afc99..390113cc8a 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 01dc4db8a8..f7a82c5b8c 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 1a45d35a0c..503af49709 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 a5813a0e24..ef1c8ca6be 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 6046f83902..7f0809897b 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 4d21d2e943..59196d0bb6 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 8eb1298768..7d1057397e 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 5c933b4bd5..5e129d9a19 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 22d0ee5e7e..24b9b0b83c 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 a981ffc572..e5b323725c 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 2fa4d1449c..f4406913b7 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 c53654e4fa..e780f447fe 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 4f47b9f54c..59b8e85c22 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 0aaf0b4e0f..ff08c31bce 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 c57aea0b5c..63d288bbbb 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 efd24336af..f5010bb455 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 623ae8968d..c5ed09016c 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 0c6125dbe5..3abaf095c8 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 19dda06031..1f54e48d11 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 4d09ae8e87..0a6a37696b 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 b0c1b10e4c..65d8e287f9 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 a856d5dba3..2634bd9bcd 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 7c078866a8..7f025dea1d 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 a91a01edca..7f55ce1ac2 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 6cdc581185..3810fec667 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 13563ce197..1d17c641d3 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 390113cc8a..67b9d546fd 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 f7a82c5b8c..587c6668c0 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