diff options
23 files changed, 279 insertions, 101 deletions
diff --git a/MediaBrowser.Api/DisplayPreferencesService.cs b/MediaBrowser.Api/DisplayPreferencesService.cs index 16aafafb0..206f5bf7b 100644 --- a/MediaBrowser.Api/DisplayPreferencesService.cs +++ b/MediaBrowser.Api/DisplayPreferencesService.cs @@ -1,5 +1,4 @@ -using MediaBrowser.Common.Extensions; -using MediaBrowser.Controller.Persistence; +using MediaBrowser.Controller.Persistence; using MediaBrowser.Model.Entities; using MediaBrowser.Model.Serialization; using ServiceStack; @@ -79,14 +78,6 @@ namespace MediaBrowser.Api { var result = _displayPreferencesManager.GetDisplayPreferences(request.Id, request.UserId, request.Client); - if (result == null) - { - result = new DisplayPreferences - { - Id = request.Id - }; - } - return ToOptimizedSerializedResultUsingCache(result); } diff --git a/MediaBrowser.Api/ScheduledTasks/ScheduledTasksWebSocketListener.cs b/MediaBrowser.Api/ScheduledTasks/ScheduledTasksWebSocketListener.cs index c143635bf..0d61c2ce1 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.Model.Events; using MediaBrowser.Model.Logging; using MediaBrowser.Model.Tasks; using System.Collections.Generic; @@ -11,7 +12,7 @@ namespace MediaBrowser.Api.ScheduledTasks /// <summary> /// Class ScheduledTasksWebSocketListener /// </summary> - public class ScheduledTasksWebSocketListener : BasePeriodicWebSocketListener<IEnumerable<TaskInfo>, object> + public class ScheduledTasksWebSocketListener : BasePeriodicWebSocketListener<IEnumerable<TaskInfo>, WebSocketListenerState> { /// <summary> /// Gets or sets the task manager. @@ -37,6 +38,26 @@ namespace MediaBrowser.Api.ScheduledTasks : base(logger) { TaskManager = taskManager; + + TaskManager.TaskExecuting += TaskManager_TaskExecuting; + TaskManager.TaskCompleted += TaskManager_TaskCompleted; + } + + void TaskManager_TaskCompleted(object sender, TaskCompletionEventArgs e) + { + SendData(true); + e.Task.TaskProgress -= Argument_TaskProgress; + } + + void TaskManager_TaskExecuting(object sender, GenericEventArgs<IScheduledTaskWorker> e) + { + SendData(true); + e.Argument.TaskProgress += Argument_TaskProgress; + } + + void Argument_TaskProgress(object sender, GenericEventArgs<double> e) + { + SendData(false); } /// <summary> @@ -44,12 +65,20 @@ namespace MediaBrowser.Api.ScheduledTasks /// </summary> /// <param name="state">The state.</param> /// <returns>Task{IEnumerable{TaskInfo}}.</returns> - protected override Task<IEnumerable<TaskInfo>> GetDataToSend(object state) + protected override Task<IEnumerable<TaskInfo>> GetDataToSend(WebSocketListenerState state) { return Task.FromResult(TaskManager.ScheduledTasks .OrderBy(i => i.Name) .Select(ScheduledTaskHelpers.GetTaskInfo) .Where(i => !i.IsHidden)); } + + protected override bool SendOnTimer + { + get + { + return false; + } + } } } diff --git a/MediaBrowser.Api/WebSocket/LogFileWebSocketListener.cs b/MediaBrowser.Api/WebSocket/LogFileWebSocketListener.cs index 7fbea2f40..46dabb042 100644 --- a/MediaBrowser.Api/WebSocket/LogFileWebSocketListener.cs +++ b/MediaBrowser.Api/WebSocket/LogFileWebSocketListener.cs @@ -133,7 +133,7 @@ namespace MediaBrowser.Api.WebSocket /// <summary> /// Class LogFileWebSocketState /// </summary> - public class LogFileWebSocketState + public class LogFileWebSocketState : WebSocketListenerState { /// <summary> /// Gets or sets the last log file path. diff --git a/MediaBrowser.Api/WebSocket/SessionInfoWebSocketListener.cs b/MediaBrowser.Api/WebSocket/SessionInfoWebSocketListener.cs index 721d8976b..a16ea863f 100644 --- a/MediaBrowser.Api/WebSocket/SessionInfoWebSocketListener.cs +++ b/MediaBrowser.Api/WebSocket/SessionInfoWebSocketListener.cs @@ -11,7 +11,7 @@ namespace MediaBrowser.Api.WebSocket /// <summary> /// Class SessionInfoWebSocketListener /// </summary> - class SessionInfoWebSocketListener : BasePeriodicWebSocketListener<IEnumerable<SessionInfoDto>, object> + class SessionInfoWebSocketListener : BasePeriodicWebSocketListener<IEnumerable<SessionInfoDto>, WebSocketListenerState> { /// <summary> /// Gets the name. @@ -43,7 +43,7 @@ namespace MediaBrowser.Api.WebSocket /// </summary> /// <param name="state">The state.</param> /// <returns>Task{SystemInfo}.</returns> - protected override Task<IEnumerable<SessionInfoDto>> GetDataToSend(object state) + protected override Task<IEnumerable<SessionInfoDto>> GetDataToSend(WebSocketListenerState state) { return Task.FromResult(_sessionManager.Sessions.Where(i => i.IsActive).Select(_sessionManager.GetSessionInfoDto)); } diff --git a/MediaBrowser.Api/WebSocket/SystemInfoWebSocketListener.cs b/MediaBrowser.Api/WebSocket/SystemInfoWebSocketListener.cs index 62e642c92..2940bcef0 100644 --- a/MediaBrowser.Api/WebSocket/SystemInfoWebSocketListener.cs +++ b/MediaBrowser.Api/WebSocket/SystemInfoWebSocketListener.cs @@ -9,7 +9,7 @@ namespace MediaBrowser.Api.WebSocket /// <summary> /// Class SystemInfoWebSocketListener /// </summary> - public class SystemInfoWebSocketListener : BasePeriodicWebSocketListener<SystemInfo, object> + public class SystemInfoWebSocketListener : BasePeriodicWebSocketListener<SystemInfo, WebSocketListenerState> { /// <summary> /// Gets the name. @@ -41,7 +41,7 @@ namespace MediaBrowser.Api.WebSocket /// </summary> /// <param name="state">The state.</param> /// <returns>Task{SystemInfo}.</returns> - protected override Task<SystemInfo> GetDataToSend(object state) + protected override Task<SystemInfo> GetDataToSend(WebSocketListenerState state) { return Task.FromResult(_appHost.GetSystemInfo()); } diff --git a/MediaBrowser.Common.Implementations/ScheduledTasks/ScheduledTaskWorker.cs b/MediaBrowser.Common.Implementations/ScheduledTasks/ScheduledTaskWorker.cs index d7d0cb886..68222d843 100644 --- a/MediaBrowser.Common.Implementations/ScheduledTasks/ScheduledTaskWorker.cs +++ b/MediaBrowser.Common.Implementations/ScheduledTasks/ScheduledTaskWorker.cs @@ -1,6 +1,8 @@ using MediaBrowser.Common.Configuration; +using MediaBrowser.Common.Events; using MediaBrowser.Common.Extensions; using MediaBrowser.Common.ScheduledTasks; +using MediaBrowser.Model.Events; using MediaBrowser.Model.Logging; using MediaBrowser.Model.Serialization; using MediaBrowser.Model.Tasks; @@ -18,6 +20,8 @@ namespace MediaBrowser.Common.Implementations.ScheduledTasks /// </summary> public class ScheduledTaskWorker : IScheduledTaskWorker { + public event EventHandler<GenericEventArgs<double>> TaskProgress; + /// <summary> /// Gets or sets the scheduled task. /// </summary> @@ -344,13 +348,13 @@ namespace MediaBrowser.Common.Implementations.ScheduledTasks throw new InvalidOperationException("Cannot execute a Task that is already running"); } + var progress = new Progress<double>(); + CurrentCancellationTokenSource = new CancellationTokenSource(); Logger.Info("Executing {0}", Name); - ((TaskManager)TaskManager).OnTaskExecuting(ScheduledTask); - - var progress = new Progress<double>(); + ((TaskManager)TaskManager).OnTaskExecuting(this); progress.ProgressChanged += progress_ProgressChanged; @@ -412,6 +416,12 @@ namespace MediaBrowser.Common.Implementations.ScheduledTasks void progress_ProgressChanged(object sender, double e) { CurrentProgress = e; + + EventHelper.FireEventIfNotNull(TaskProgress, this, new GenericEventArgs<double> + { + Argument = e + + }, Logger); } /// <summary> @@ -546,7 +556,7 @@ namespace MediaBrowser.Common.Implementations.ScheduledTasks LastExecutionResult = result; - ((TaskManager) TaskManager).OnTaskCompleted(ScheduledTask, result); + ((TaskManager)TaskManager).OnTaskCompleted(this, result); } /// <summary> diff --git a/MediaBrowser.Common.Implementations/ScheduledTasks/TaskManager.cs b/MediaBrowser.Common.Implementations/ScheduledTasks/TaskManager.cs index cead5de04..5aec39b89 100644 --- a/MediaBrowser.Common.Implementations/ScheduledTasks/TaskManager.cs +++ b/MediaBrowser.Common.Implementations/ScheduledTasks/TaskManager.cs @@ -17,8 +17,8 @@ namespace MediaBrowser.Common.Implementations.ScheduledTasks /// </summary> public class TaskManager : ITaskManager { - public event EventHandler<EventArgs> TaskExecuting; - public event EventHandler<GenericEventArgs<TaskResult>> TaskCompleted; + public event EventHandler<GenericEventArgs<IScheduledTaskWorker>> TaskExecuting; + public event EventHandler<TaskCompletionEventArgs> TaskCompleted; /// <summary> /// Gets the list of Scheduled Tasks @@ -125,7 +125,7 @@ namespace MediaBrowser.Common.Implementations.ScheduledTasks // If it's idle just execute immediately if (task.State == TaskState.Idle) { - ((ScheduledTaskWorker)task).Execute(); + Execute(task); return; } @@ -149,7 +149,8 @@ namespace MediaBrowser.Common.Implementations.ScheduledTasks { var myTasks = ScheduledTasks.ToList(); - myTasks.AddRange(tasks.Select(t => new ScheduledTaskWorker(t, ApplicationPaths, this, JsonSerializer, Logger))); + var list = tasks.ToList(); + myTasks.AddRange(list.Select(t => new ScheduledTaskWorker(t, ApplicationPaths, this, JsonSerializer, Logger))); ScheduledTasks = myTasks.ToArray(); } @@ -189,9 +190,13 @@ namespace MediaBrowser.Common.Implementations.ScheduledTasks /// Called when [task executing]. /// </summary> /// <param name="task">The task.</param> - internal void OnTaskExecuting(IScheduledTask task) + internal void OnTaskExecuting(IScheduledTaskWorker task) { - EventHelper.QueueEventIfNotNull(TaskExecuting, task, EventArgs.Empty, Logger); + EventHelper.QueueEventIfNotNull(TaskExecuting, this, new GenericEventArgs<IScheduledTaskWorker> + { + Argument = task + + }, Logger); } /// <summary> @@ -199,9 +204,15 @@ namespace MediaBrowser.Common.Implementations.ScheduledTasks /// </summary> /// <param name="task">The task.</param> /// <param name="result">The result.</param> - internal void OnTaskCompleted(IScheduledTask task, TaskResult result) + internal void OnTaskCompleted(IScheduledTaskWorker task, TaskResult result) { - EventHelper.QueueEventIfNotNull(TaskCompleted, task, new GenericEventArgs<TaskResult> { Argument = result }, Logger); + EventHelper.QueueEventIfNotNull(TaskCompleted, task, new TaskCompletionEventArgs + { + Result = result, + Task = task + + }, Logger); + ExecuteQueuedTasks(); } @@ -219,7 +230,7 @@ namespace MediaBrowser.Common.Implementations.ScheduledTasks if (scheduledTask.State == TaskState.Idle) { - ((ScheduledTaskWorker)scheduledTask).Execute(); + Execute(scheduledTask); _taskQueue.Remove(type); } diff --git a/MediaBrowser.Common/Net/BasePeriodicWebSocketListener.cs b/MediaBrowser.Common/Net/BasePeriodicWebSocketListener.cs index 33d3f368b..a2af3707b 100644 --- a/MediaBrowser.Common/Net/BasePeriodicWebSocketListener.cs +++ b/MediaBrowser.Common/Net/BasePeriodicWebSocketListener.cs @@ -15,7 +15,7 @@ namespace MediaBrowser.Common.Net /// <typeparam name="TReturnDataType">The type of the T return data type.</typeparam> /// <typeparam name="TStateType">The type of the T state type.</typeparam> public abstract class BasePeriodicWebSocketListener<TReturnDataType, TStateType> : IWebSocketListener, IDisposable - where TStateType : class, new() + where TStateType : WebSocketListenerState, new() where TReturnDataType : class { /// <summary> @@ -83,7 +83,15 @@ namespace MediaBrowser.Common.Net } protected readonly CultureInfo UsCulture = new CultureInfo("en-US"); - + + protected virtual bool SendOnTimer + { + get + { + return true; + } + } + /// <summary> /// Starts sending messages over a web socket /// </summary> @@ -99,9 +107,15 @@ namespace MediaBrowser.Common.Net Logger.Info("{1} Begin transmitting over websocket to {0}", message.Connection.RemoteEndPoint, GetType().Name); - var timer = new Timer(TimerCallback, message.Connection, Timeout.Infinite, Timeout.Infinite); + var timer = SendOnTimer ? + new Timer(TimerCallback, message.Connection, Timeout.Infinite, Timeout.Infinite) : + null; - var state = new TStateType(); + var state = new TStateType + { + IntervalMs = periodMs, + InitialDelayMs = dueTimeMs + }; var semaphore = new SemaphoreSlim(1, 1); @@ -110,14 +124,17 @@ namespace MediaBrowser.Common.Net ActiveConnections.Add(new Tuple<IWebSocketConnection, CancellationTokenSource, Timer, TStateType, SemaphoreSlim>(message.Connection, cancellationTokenSource, timer, state, semaphore)); } - timer.Change(TimeSpan.FromMilliseconds(dueTimeMs), TimeSpan.FromMilliseconds(periodMs)); + if (timer != null) + { + timer.Change(TimeSpan.FromMilliseconds(dueTimeMs), TimeSpan.FromMilliseconds(periodMs)); + } } /// <summary> /// Timers the callback. /// </summary> /// <param name="state">The state.</param> - private async void TimerCallback(object state) + private void TimerCallback(object state) { var connection = (IWebSocketConnection)state; @@ -139,11 +156,50 @@ namespace MediaBrowser.Common.Net return; } + SendData(tuple); + } + + protected void SendData(bool force) + { + List<Tuple<IWebSocketConnection, CancellationTokenSource, Timer, TStateType, SemaphoreSlim>> 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<IWebSocketConnection, CancellationTokenSource, Timer, TStateType, SemaphoreSlim> tuple) + { + var connection = tuple.Item1; + try { await tuple.Item5.WaitAsync(tuple.Item2.Token).ConfigureAwait(false); - var data = await GetDataToSend(tuple.Item4).ConfigureAwait(false); + var state = tuple.Item4; + + var data = await GetDataToSend(state).ConfigureAwait(false); if (data != null) { @@ -153,6 +209,8 @@ namespace MediaBrowser.Common.Net Data = data }, tuple.Item2.Token).ConfigureAwait(false); + + state.DateLastSendUtc = DateTime.UtcNow; } tuple.Item5.Release(); @@ -196,13 +254,18 @@ namespace MediaBrowser.Common.Net { Logger.Info("{1} stop transmitting over websocket to {0}", connection.Item1.RemoteEndPoint, GetType().Name); - try - { - connection.Item3.Dispose(); - } - catch (ObjectDisposedException) + var timer = connection.Item3; + + if (timer != null) { + try + { + timer.Dispose(); + } + catch (ObjectDisposedException) + { + } } try @@ -212,7 +275,7 @@ namespace MediaBrowser.Common.Net } catch (ObjectDisposedException) { - + } try @@ -223,7 +286,7 @@ namespace MediaBrowser.Common.Net { } - + ActiveConnections.Remove(connection); } @@ -253,4 +316,11 @@ namespace MediaBrowser.Common.Net 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/ScheduledTasks/IScheduledTaskWorker.cs b/MediaBrowser.Common/ScheduledTasks/IScheduledTaskWorker.cs index d0d363df7..f50bd9e76 100644 --- a/MediaBrowser.Common/ScheduledTasks/IScheduledTaskWorker.cs +++ b/MediaBrowser.Common/ScheduledTasks/IScheduledTaskWorker.cs @@ -1,4 +1,5 @@ -using MediaBrowser.Model.Tasks; +using MediaBrowser.Model.Events; +using MediaBrowser.Model.Tasks; using System; using System.Collections.Generic; @@ -10,6 +11,11 @@ namespace MediaBrowser.Common.ScheduledTasks public interface IScheduledTaskWorker : IDisposable { /// <summary> + /// Occurs when [task progress]. + /// </summary> + event EventHandler<GenericEventArgs<double>> TaskProgress; + + /// <summary> /// Gets or sets the scheduled task. /// </summary> /// <value>The scheduled task.</value> diff --git a/MediaBrowser.Common/ScheduledTasks/ITaskManager.cs b/MediaBrowser.Common/ScheduledTasks/ITaskManager.cs index 38548801b..01dc355c3 100644 --- a/MediaBrowser.Common/ScheduledTasks/ITaskManager.cs +++ b/MediaBrowser.Common/ScheduledTasks/ITaskManager.cs @@ -1,5 +1,4 @@ using MediaBrowser.Model.Events; -using MediaBrowser.Model.Tasks; using System; using System.Collections.Generic; using System.Threading.Tasks; @@ -50,7 +49,7 @@ namespace MediaBrowser.Common.ScheduledTasks void Cancel(IScheduledTaskWorker task); Task Execute(IScheduledTaskWorker task); - event EventHandler<EventArgs> TaskExecuting; - event EventHandler<GenericEventArgs<TaskResult>> TaskCompleted; + event EventHandler<GenericEventArgs<IScheduledTaskWorker>> TaskExecuting; + event EventHandler<TaskCompletionEventArgs> TaskCompleted; } }
\ No newline at end of file diff --git a/MediaBrowser.Common/ScheduledTasks/TaskCompletionEventArgs.cs b/MediaBrowser.Common/ScheduledTasks/TaskCompletionEventArgs.cs index 8aab6b50d..2974806d0 100644 --- a/MediaBrowser.Common/ScheduledTasks/TaskCompletionEventArgs.cs +++ b/MediaBrowser.Common/ScheduledTasks/TaskCompletionEventArgs.cs @@ -5,7 +5,7 @@ namespace MediaBrowser.Common.ScheduledTasks { public class TaskCompletionEventArgs : EventArgs { - public IScheduledTask Task { get; set; } + public IScheduledTaskWorker Task { get; set; } public TaskResult Result { get; set; } } diff --git a/MediaBrowser.MediaEncoding/MediaBrowser.MediaEncoding.csproj b/MediaBrowser.MediaEncoding/MediaBrowser.MediaEncoding.csproj index 19287b0cb..a67d69f79 100644 --- a/MediaBrowser.MediaEncoding/MediaBrowser.MediaEncoding.csproj +++ b/MediaBrowser.MediaEncoding/MediaBrowser.MediaEncoding.csproj @@ -85,13 +85,7 @@ </ItemGroup> <ItemGroup /> <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> - <Import Project="$(SolutionDir)\.nuget\NuGet.targets" Condition="Exists('$(SolutionDir)\.nuget\NuGet.targets')" /> - <Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild"> - <PropertyGroup> - <ErrorText>This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText> - </PropertyGroup> - <Error Condition="!Exists('$(SolutionDir)\.nuget\NuGet.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\.nuget\NuGet.targets'))" /> - </Target> + <Import Project="$(SolutionDir)\.nuget\NuGet.targets" Condition=" '$(ConfigurationName)' != 'Release Mono' " /> <!-- To modify your build process, add your task inside one of the targets below and uncomment it. Other similar extension points exist, see Microsoft.Common.targets. <Target Name="BeforeBuild"> diff --git a/MediaBrowser.Mono.sln b/MediaBrowser.Mono.sln index a5b084812..9c2397046 100644 --- a/MediaBrowser.Mono.sln +++ b/MediaBrowser.Mono.sln @@ -23,6 +23,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MediaBrowser.Dlna", "MediaB EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MediaBrowser.MediaEncoding", "MediaBrowser.MediaEncoding\MediaBrowser.MediaEncoding.csproj", "{0BD82FA6-EB8A-4452-8AF5-74F9C3849451}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OpenSubtitlesHandler", "OpenSubtitlesHandler\OpenSubtitlesHandler.csproj", "{4A4402D4-E910-443B-B8FC-2C18286A2CA0}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|x86 = Debug|x86 @@ -33,8 +35,8 @@ Global GlobalSection(ProjectConfigurationPlatforms) = postSolution {0BD82FA6-EB8A-4452-8AF5-74F9C3849451}.Debug|x86.ActiveCfg = Debug|Any CPU {0BD82FA6-EB8A-4452-8AF5-74F9C3849451}.Debug|x86.Build.0 = Debug|Any CPU - {0BD82FA6-EB8A-4452-8AF5-74F9C3849451}.Release Mono|Any CPU.ActiveCfg = Release|Any CPU - {0BD82FA6-EB8A-4452-8AF5-74F9C3849451}.Release Mono|Any CPU.Build.0 = Release|Any CPU + {0BD82FA6-EB8A-4452-8AF5-74F9C3849451}.Release Mono|Any CPU.ActiveCfg = Release Mono|Any CPU + {0BD82FA6-EB8A-4452-8AF5-74F9C3849451}.Release Mono|Any CPU.Build.0 = Release Mono|Any CPU {0BD82FA6-EB8A-4452-8AF5-74F9C3849451}.Release|Any CPU.ActiveCfg = Release|Any CPU {0BD82FA6-EB8A-4452-8AF5-74F9C3849451}.Release|Any CPU.Build.0 = Release|Any CPU {0BD82FA6-EB8A-4452-8AF5-74F9C3849451}.Release|x86.ActiveCfg = Release|Any CPU @@ -71,6 +73,14 @@ Global {442B5058-DCAF-4263-BB6A-F21E31120A1B}.Release|Any CPU.Build.0 = Release|Any CPU {442B5058-DCAF-4263-BB6A-F21E31120A1B}.Release|x86.ActiveCfg = Release|Any CPU {442B5058-DCAF-4263-BB6A-F21E31120A1B}.Release|x86.Build.0 = Release|Any CPU + {4A4402D4-E910-443B-B8FC-2C18286A2CA0}.Debug|x86.ActiveCfg = Debug|Any CPU + {4A4402D4-E910-443B-B8FC-2C18286A2CA0}.Debug|x86.Build.0 = Debug|Any CPU + {4A4402D4-E910-443B-B8FC-2C18286A2CA0}.Release Mono|Any CPU.ActiveCfg = Release Mono|Any CPU + {4A4402D4-E910-443B-B8FC-2C18286A2CA0}.Release Mono|Any CPU.Build.0 = Release Mono|Any CPU + {4A4402D4-E910-443B-B8FC-2C18286A2CA0}.Release|Any CPU.ActiveCfg = Release|Any CPU + {4A4402D4-E910-443B-B8FC-2C18286A2CA0}.Release|Any CPU.Build.0 = Release|Any CPU + {4A4402D4-E910-443B-B8FC-2C18286A2CA0}.Release|x86.ActiveCfg = Release|Any CPU + {4A4402D4-E910-443B-B8FC-2C18286A2CA0}.Release|x86.Build.0 = Release|Any CPU {4FD51AC5-2C16-4308-A993-C3A84F3B4582}.Debug|x86.ActiveCfg = Debug|Any CPU {4FD51AC5-2C16-4308-A993-C3A84F3B4582}.Debug|x86.Build.0 = Debug|Any CPU {4FD51AC5-2C16-4308-A993-C3A84F3B4582}.Release Mono|Any CPU.ActiveCfg = Release Mono|Any CPU diff --git a/MediaBrowser.Mono.userprefs b/MediaBrowser.Mono.userprefs index 15813ef56..f115a532e 100644 --- a/MediaBrowser.Mono.userprefs +++ b/MediaBrowser.Mono.userprefs @@ -5,7 +5,7 @@ <File FileName="MediaBrowser.Server.Mono\app.config" Line="1" Column="1" /> <File FileName="MediaBrowser.ServerApplication\ApplicationHost.cs" Line="1" Column="1" /> <File FileName="MediaBrowser.Server.Mono\Native\NativeApp.cs" Line="1" Column="1" /> - <File FileName="MediaBrowser.Server.Mono\Program.cs" Line="36" Column="37" /> + <File FileName="MediaBrowser.Server.Mono\Program.cs" Line="24" Column="15" /> </Files> </MonoDevelop.Ide.Workbench> <MonoDevelop.Ide.DebuggingService.Breakpoints> diff --git a/MediaBrowser.Server.Implementations/EntryPoints/Notifications/Notifications.cs b/MediaBrowser.Server.Implementations/EntryPoints/Notifications/Notifications.cs index fdc81db37..242e81d1f 100644 --- a/MediaBrowser.Server.Implementations/EntryPoints/Notifications/Notifications.cs +++ b/MediaBrowser.Server.Implementations/EntryPoints/Notifications/Notifications.cs @@ -6,6 +6,7 @@ using MediaBrowser.Common.Updates; using MediaBrowser.Controller; using MediaBrowser.Controller.Configuration; using MediaBrowser.Controller.Entities; +using MediaBrowser.Controller.Entities.Audio; using MediaBrowser.Controller.Library; using MediaBrowser.Controller.Notifications; using MediaBrowser.Controller.Plugins; @@ -257,7 +258,7 @@ namespace MediaBrowser.Server.Implementations.EntryPoints.Notifications NotificationType = NotificationType.NewLibraryContent.ToString() }; - notification.Variables["Name"] = item.Name; + notification.Variables["Name"] = GetItemName(item); await SendNotification(notification).ConfigureAwait(false); } @@ -274,6 +275,31 @@ namespace MediaBrowser.Server.Implementations.EntryPoints.Notifications } } + private string GetItemName(BaseItem item) + { + var name = item.Name; + + var hasSeries = item as IHasSeries; + + if (hasSeries != null) + { + name = hasSeries.SeriesName + " - " + name; + } + + var hasArtist = item as IHasArtist; + if (hasArtist != null) + { + var artists = hasArtist.AllArtists; + + if (artists.Count > 0) + { + name = hasArtist.AllArtists[0] + " - " + name; + } + } + + return name; + } + async void _userManager_UserCreated(object sender, GenericEventArgs<User> e) { var notification = new NotificationRequest @@ -286,9 +312,9 @@ namespace MediaBrowser.Server.Implementations.EntryPoints.Notifications await SendNotification(notification).ConfigureAwait(false); } - async void _taskManager_TaskCompleted(object sender, GenericEventArgs<TaskResult> e) + async void _taskManager_TaskCompleted(object sender, TaskCompletionEventArgs e) { - var result = e.Argument; + var result = e.Result; if (result.Status == TaskCompletionStatus.Failed) { @@ -301,8 +327,8 @@ namespace MediaBrowser.Server.Implementations.EntryPoints.Notifications NotificationType = type }; - notification.Variables["Name"] = e.Argument.Name; - notification.Variables["ErrorMessage"] = e.Argument.ErrorMessage; + notification.Variables["Name"] = result.Name; + notification.Variables["ErrorMessage"] = result.ErrorMessage; await SendNotification(notification).ConfigureAwait(false); } diff --git a/MediaBrowser.Server.Implementations/EntryPoints/ServerEventNotifier.cs b/MediaBrowser.Server.Implementations/EntryPoints/ServerEventNotifier.cs index 54cd21cdf..d6ad7771b 100644 --- a/MediaBrowser.Server.Implementations/EntryPoints/ServerEventNotifier.cs +++ b/MediaBrowser.Server.Implementations/EntryPoints/ServerEventNotifier.cs @@ -106,9 +106,9 @@ namespace MediaBrowser.Server.Implementations.EntryPoints _serverManager.SendWebSocketMessage("PackageInstallationFailed", e.InstallationInfo); } - void _taskManager_TaskCompleted(object sender, GenericEventArgs<TaskResult> e) + void _taskManager_TaskCompleted(object sender, TaskCompletionEventArgs e) { - _serverManager.SendWebSocketMessage("ScheduledTaskEnded", e.Argument); + _serverManager.SendWebSocketMessage("ScheduledTaskEnded", e.Result); } /// <summary> diff --git a/MediaBrowser.Server.Implementations/Persistence/SqliteDisplayPreferencesRepository.cs b/MediaBrowser.Server.Implementations/Persistence/SqliteDisplayPreferencesRepository.cs index 7ae87684a..ac1c5ef55 100644 --- a/MediaBrowser.Server.Implementations/Persistence/SqliteDisplayPreferencesRepository.cs +++ b/MediaBrowser.Server.Implementations/Persistence/SqliteDisplayPreferencesRepository.cs @@ -191,10 +191,12 @@ namespace MediaBrowser.Server.Implementations.Persistence throw new ArgumentNullException("displayPreferencesId"); } + var guidId = displayPreferencesId.GetMD5(); + var cmd = _connection.CreateCommand(); cmd.CommandText = "select data from userdisplaypreferences where id = @id and userId=@userId and client=@client"; - cmd.Parameters.Add(cmd, "@id", DbType.Guid).Value = displayPreferencesId.GetMD5(); + cmd.Parameters.Add(cmd, "@id", DbType.Guid).Value = guidId; cmd.Parameters.Add(cmd, "@userId", DbType.Guid).Value = userId; cmd.Parameters.Add(cmd, "@client", DbType.String).Value = client; @@ -209,7 +211,10 @@ namespace MediaBrowser.Server.Implementations.Persistence } } - return null; + return new DisplayPreferences + { + Id = guidId.ToString("N") + }; } /// <summary> diff --git a/MediaBrowser.Server.Implementations/Session/SessionManager.cs b/MediaBrowser.Server.Implementations/Session/SessionManager.cs index ea709cd24..d2a047b42 100644 --- a/MediaBrowser.Server.Implementations/Session/SessionManager.cs +++ b/MediaBrowser.Server.Implementations/Session/SessionManager.cs @@ -282,7 +282,18 @@ namespace MediaBrowser.Server.Implementations.Session if (!string.IsNullOrWhiteSpace(info.ItemId) && libraryItem != null) { - info.Item = GetItemInfo(libraryItem, runtimeTicks, libraryItem, info.MediaSourceId); + var current = session.NowPlayingItem; + + if (current == null || !string.Equals(current.Id, info.ItemId, StringComparison.OrdinalIgnoreCase)) + { + info.Item = GetItemInfo(libraryItem, libraryItem, info.MediaSourceId); + } + else + { + info.Item = current; + } + + info.Item.RunTimeTicks = runtimeTicks; } session.NowPlayingItem = info.Item; @@ -1182,12 +1193,11 @@ namespace MediaBrowser.Server.Implementations.Session /// Converts a BaseItem to a BaseItemInfo /// </summary> /// <param name="item">The item.</param> - /// <param name="runtimeTicks">The now playing runtime ticks.</param> /// <param name="chapterOwner">The chapter owner.</param> /// <param name="mediaSourceId">The media source identifier.</param> /// <returns>BaseItemInfo.</returns> /// <exception cref="System.ArgumentNullException">item</exception> - private BaseItemInfo GetItemInfo(BaseItem item, long? runtimeTicks, BaseItem chapterOwner, string mediaSourceId) + private BaseItemInfo GetItemInfo(BaseItem item, BaseItem chapterOwner, string mediaSourceId) { if (item == null) { @@ -1200,7 +1210,7 @@ namespace MediaBrowser.Server.Implementations.Session Name = item.Name, MediaType = item.MediaType, Type = item.GetClientTypeName(), - RunTimeTicks = runtimeTicks, + RunTimeTicks = item.RunTimeTicks, IndexNumber = item.IndexNumber, ParentIndexNumber = item.ParentIndexNumber, PremiereDate = item.PremiereDate, @@ -1376,7 +1386,7 @@ namespace MediaBrowser.Server.Implementations.Session { var item = _libraryManager.GetItemById(new Guid(itemId)); - var info = GetItemInfo(item, item.RunTimeTicks, null, null); + var info = GetItemInfo(item, null, null); ReportNowViewingItem(sessionId, info); } diff --git a/MediaBrowser.Server.Mono/Native/NativeApp.cs b/MediaBrowser.Server.Mono/Native/NativeApp.cs index deff79b4b..1cf217910 100644 --- a/MediaBrowser.Server.Mono/Native/NativeApp.cs +++ b/MediaBrowser.Server.Mono/Native/NativeApp.cs @@ -51,5 +51,10 @@ namespace MediaBrowser.ServerApplication.Native { get { return false; } } + + public static void PreventSystemStandby() + { + + } } } diff --git a/MediaBrowser.ServerApplication/EntryPoints/KeepServerAwake.cs b/MediaBrowser.ServerApplication/EntryPoints/KeepServerAwake.cs index 42b6c3164..9881bdf18 100644 --- a/MediaBrowser.ServerApplication/EntryPoints/KeepServerAwake.cs +++ b/MediaBrowser.ServerApplication/EntryPoints/KeepServerAwake.cs @@ -1,9 +1,9 @@ using MediaBrowser.Controller.Plugins; using MediaBrowser.Controller.Session; using MediaBrowser.Model.Logging; +using MediaBrowser.ServerApplication.Native; using System; using System.Linq; -using System.Runtime.InteropServices; using System.Threading; namespace MediaBrowser.ServerApplication.EntryPoints @@ -37,7 +37,7 @@ namespace MediaBrowser.ServerApplication.EntryPoints { try { - SystemHelper.ResetStandbyTimer(); + NativeApp.PreventSystemStandby(); } catch (Exception ex) { @@ -54,25 +54,4 @@ namespace MediaBrowser.ServerApplication.EntryPoints } } } - - internal enum EXECUTION_STATE : uint - { - ES_NONE = 0, - ES_SYSTEM_REQUIRED = 0x00000001, - ES_DISPLAY_REQUIRED = 0x00000002, - ES_USER_PRESENT = 0x00000004, - ES_AWAYMODE_REQUIRED = 0x00000040, - ES_CONTINUOUS = 0x80000000 - } - - public class SystemHelper - { - [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)] - static extern EXECUTION_STATE SetThreadExecutionState(EXECUTION_STATE esFlags); - - public static void ResetStandbyTimer() - { - EXECUTION_STATE es = SetThreadExecutionState(EXECUTION_STATE.ES_SYSTEM_REQUIRED); - } - } } diff --git a/MediaBrowser.ServerApplication/FFMpeg/FFMpegDownloadInfo.cs b/MediaBrowser.ServerApplication/FFMpeg/FFMpegDownloadInfo.cs index 19aa7a684..b4fc47d02 100644 --- a/MediaBrowser.ServerApplication/FFMpeg/FFMpegDownloadInfo.cs +++ b/MediaBrowser.ServerApplication/FFMpeg/FFMpegDownloadInfo.cs @@ -194,12 +194,12 @@ namespace MediaBrowser.ServerApplication.FFMpeg var uname = new Uname(); #if __MonoCS__ - Utsname uname; - var callResult = Syscall.uname(out uname); + Utsname utsname; + var callResult = Syscall.uname(out utsname); if (callResult == 0) { - uname.sysname= uname.sysname; - uname.machine= uname.machine; + uname.sysname= utsname.sysname; + uname.machine= utsname.machine; } #endif return uname; diff --git a/MediaBrowser.ServerApplication/Native/NativeApp.cs b/MediaBrowser.ServerApplication/Native/NativeApp.cs index 646a7bc98..2388b610b 100644 --- a/MediaBrowser.ServerApplication/Native/NativeApp.cs +++ b/MediaBrowser.ServerApplication/Native/NativeApp.cs @@ -1,4 +1,5 @@ - +using System.Runtime.InteropServices; + namespace MediaBrowser.ServerApplication.Native { /// <summary> @@ -57,5 +58,31 @@ namespace MediaBrowser.ServerApplication.Native return MainStartup.CanSelfUpdate; } } + + public static void PreventSystemStandby() + { + SystemHelper.ResetStandbyTimer(); + } + + internal enum EXECUTION_STATE : uint + { + ES_NONE = 0, + ES_SYSTEM_REQUIRED = 0x00000001, + ES_DISPLAY_REQUIRED = 0x00000002, + ES_USER_PRESENT = 0x00000004, + ES_AWAYMODE_REQUIRED = 0x00000040, + ES_CONTINUOUS = 0x80000000 + } + + public class SystemHelper + { + [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)] + static extern EXECUTION_STATE SetThreadExecutionState(EXECUTION_STATE esFlags); + + public static void ResetStandbyTimer() + { + EXECUTION_STATE es = SetThreadExecutionState(EXECUTION_STATE.ES_SYSTEM_REQUIRED); + } + } } } diff --git a/OpenSubtitlesHandler/OpenSubtitlesHandler.csproj b/OpenSubtitlesHandler/OpenSubtitlesHandler.csproj index ba27c7140..d1257d058 100644 --- a/OpenSubtitlesHandler/OpenSubtitlesHandler.csproj +++ b/OpenSubtitlesHandler/OpenSubtitlesHandler.csproj @@ -29,6 +29,11 @@ <ErrorReport>prompt</ErrorReport> <WarningLevel>4</WarningLevel> </PropertyGroup> + <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release Mono|AnyCPU' "> + <Optimize>false</Optimize> + <OutputPath>bin\Release Mono</OutputPath> + <WarningLevel>4</WarningLevel> + </PropertyGroup> <ItemGroup> <Reference Include="System" /> <Reference Include="System.Core" /> @@ -113,6 +118,7 @@ <Content Include="XML-RPC\Docs\XML-RPC.txt" /> </ItemGroup> <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> + <Import Project="$(SolutionDir)\.nuget\NuGet.targets" Condition=" '$(ConfigurationName)' != 'Release Mono' " /> <!-- To modify your build process, add your task inside one of the targets below and uncomment it. Other similar extension points exist, see Microsoft.Common.targets. <Target Name="BeforeBuild"> |
