Browse Source

fixes around http response caching, updated the mb icon in the dashboard, and isolated web socket events

LukePulverenti 12 years ago
parent
commit
fe3323a492

+ 9 - 5
MediaBrowser.Common.Implementations/HttpServer/BaseRestService.cs

@@ -11,7 +11,6 @@ using System;
 using System.Globalization;
 using System.IO;
 using System.Linq;
-using System.Net;
 using System.Threading.Tasks;
 using MimeTypes = MediaBrowser.Common.Net.MimeTypes;
 
@@ -94,7 +93,8 @@ namespace MediaBrowser.Common.Implementations.HttpServer
 
             if (result != null)
             {
-                return result;
+                // Return null so that service stack won't do anything
+                return null;
             }
 
             return ToOptimizedResult(factoryFn());
@@ -129,7 +129,8 @@ namespace MediaBrowser.Common.Implementations.HttpServer
 
             if (result != null)
             {
-                return result;
+                // Return null so that service stack won't do anything
+                return null;
             }
 
             return factoryFn();
@@ -192,7 +193,8 @@ namespace MediaBrowser.Common.Implementations.HttpServer
 
             if (result != null)
             {
-                return result;
+                // Return null so that service stack won't do anything
+                return null;
             }
 
             var compress = ShouldCompressResponse(contentType);
@@ -299,7 +301,9 @@ namespace MediaBrowser.Common.Implementations.HttpServer
                     Response.ContentType = contentType;
                 }
 
-                return new HttpResult(new byte[] { }, HttpStatusCode.NotModified);
+                Response.StatusCode = 304;
+
+                return new byte[]{};
             }
 
             SetCachingHeaders(cacheKeyString, lastDateModified, cacheDuration);

+ 6 - 0
MediaBrowser.Common.Implementations/ScheduledTasks/ScheduledTaskWorker.cs

@@ -367,6 +367,12 @@ namespace MediaBrowser.Common.Implementations.ScheduledTasks
             OnTaskCompleted(startTime, endTime, status);
         }
 
+        /// <summary>
+        /// Executes the task.
+        /// </summary>
+        /// <param name="cancellationToken">The cancellation token.</param>
+        /// <param name="progress">The progress.</param>
+        /// <returns>Task.</returns>
         private Task ExecuteTask(CancellationToken cancellationToken, IProgress<double> progress)
         {
             return Task.Run(async () => await ScheduledTask.Execute(cancellationToken, progress).ConfigureAwait(false));

+ 1 - 1
MediaBrowser.Common.Implementations/ScheduledTasks/TaskManager.cs

@@ -100,7 +100,7 @@ namespace MediaBrowser.Common.Implementations.ScheduledTasks
 
             QueueScheduledTask(scheduledTask);
         }
-
+        
         /// <summary>
         /// Queues the scheduled task.
         /// </summary>

+ 7 - 2
MediaBrowser.Common/Kernel/BaseKernel.cs

@@ -23,6 +23,11 @@ namespace MediaBrowser.Common.Kernel
         where TConfigurationType : BaseApplicationConfiguration, new()
         where TApplicationPathsType : IApplicationPaths
     {
+        /// <summary>
+        /// Occurs when [has pending restart changed].
+        /// </summary>
+        public event EventHandler HasPendingRestartChanged;
+
         #region ConfigurationUpdated Event
         /// <summary>
         /// Occurs when [configuration updated].
@@ -126,7 +131,7 @@ namespace MediaBrowser.Common.Kernel
         /// Gets or sets the TCP manager.
         /// </summary>
         /// <value>The TCP manager.</value>
-        public IServerManager ServerManager { get; private set; }
+        private IServerManager ServerManager { get; set; }
 
         /// <summary>
         /// Gets the plug-in security manager.
@@ -284,7 +289,7 @@ namespace MediaBrowser.Common.Kernel
         {
             HasPendingRestart = true;
 
-            ServerManager.SendWebSocketMessage("HasPendingRestartChanged", GetSystemInfo());
+            EventHelper.QueueEventIfNotNull(HasPendingRestartChanged, this, EventArgs.Empty, Logger);
         }
 
         /// <summary>

+ 5 - 6
MediaBrowser.Common/Kernel/IKernel.cs

@@ -13,6 +13,11 @@ namespace MediaBrowser.Common.Kernel
     /// </summary>
     public interface IKernel : IDisposable
     {
+        /// <summary>
+        /// Occurs when [has pending restart changed].
+        /// </summary>
+        event EventHandler HasPendingRestartChanged;
+
         /// <summary>
         /// Gets the application paths.
         /// </summary>
@@ -84,12 +89,6 @@ namespace MediaBrowser.Common.Kernel
         /// <value>The HTTP server URL prefix.</value>
         string HttpServerUrlPrefix { get; }
 
-        /// <summary>
-        /// Gets the TCP manager.
-        /// </summary>
-        /// <value>The TCP manager.</value>
-        IServerManager ServerManager { get; }
-
         /// <summary>
         /// Gets the plug-in security manager.
         /// </summary>

+ 0 - 1
MediaBrowser.Common/MediaBrowser.Common.csproj

@@ -79,7 +79,6 @@
     <Compile Include="Net\WebSocketConnectEventArgs.cs" />
     <Compile Include="Net\WebSocketMessageType.cs" />
     <Compile Include="Net\WebSocketState.cs" />
-    <Compile Include="Plugins\BaseUiPlugin.cs" />
     <Compile Include="Plugins\IPlugin.cs" />
     <Compile Include="Plugins\IUIPlugin.cs" />
     <Compile Include="Progress\ActionableProgress.cs" />

+ 1 - 13
MediaBrowser.Common/Plugins/BasePlugin.cs

@@ -251,18 +251,6 @@ namespace MediaBrowser.Common.Plugins
             }
         }
 
-        /// <summary>
-        /// Returns true or false indicating if the plugin should be downloaded and run within the Ui.
-        /// </summary>
-        /// <value><c>true</c> if [download to UI]; otherwise, <c>false</c>.</value>
-        public virtual bool DownloadToUi
-        {
-            get
-            {
-                return false;
-            }
-        }
-
         /// <summary>
         /// Gets the logger.
         /// </summary>
@@ -422,7 +410,7 @@ namespace MediaBrowser.Common.Plugins
             var info = new PluginInfo
             {
                 Name = Name,
-                DownloadToUI = DownloadToUi,
+                DownloadToUI = this is IUIPlugin,
                 Version = Version.ToString(),
                 AssemblyFileName = AssemblyFileName,
                 ConfigurationDateLastModified = ConfigurationDateLastModified,

+ 0 - 30
MediaBrowser.Common/Plugins/BaseUiPlugin.cs

@@ -1,30 +0,0 @@
-using MediaBrowser.Model.Plugins;
-using System;
-
-namespace MediaBrowser.Common.Plugins
-{
-    /// <summary>
-    /// Represents a common base class for any plugin that has ui components
-    /// </summary>
-    public abstract class BaseUiPlugin<TConfigurationType> : BasePlugin<TConfigurationType>, IUIPlugin
-        where TConfigurationType : BasePluginConfiguration
-    {
-        /// <summary>
-        /// Returns true or false indicating if the plugin should be downloaded and run within the Ui.
-        /// </summary>
-        /// <value><c>true</c> if [download to UI]; otherwise, <c>false</c>.</value>
-        public sealed override bool DownloadToUi
-        {
-            get
-            {
-                return true;
-            }
-        }
-
-        /// <summary>
-        /// Gets the minimum required UI version.
-        /// </summary>
-        /// <value>The minimum required UI version.</value>
-        public abstract Version MinimumRequiredUIVersion { get; }
-    }
-}

+ 0 - 6
MediaBrowser.Common/Plugins/IPlugin.cs

@@ -92,12 +92,6 @@ namespace MediaBrowser.Common.Plugins
         /// <value>The data folder path.</value>
         string DataFolderPath { get; }
 
-        /// <summary>
-        /// Returns true or false indicating if the plugin should be downloaded and run within the Ui.
-        /// </summary>
-        /// <value><c>true</c> if [download to UI]; otherwise, <c>false</c>.</value>
-        bool DownloadToUi { get; }
-
         /// <summary>
         /// Gets the logger.
         /// </summary>

+ 4 - 27
MediaBrowser.Controller/Kernel.cs

@@ -10,7 +10,6 @@ using MediaBrowser.Controller.Persistence;
 using MediaBrowser.Controller.Playback;
 using MediaBrowser.Controller.Plugins;
 using MediaBrowser.Controller.Providers;
-using MediaBrowser.Controller.Resolvers;
 using MediaBrowser.Controller.Updates;
 using MediaBrowser.Controller.Weather;
 using MediaBrowser.Model.Configuration;
@@ -52,7 +51,7 @@ namespace MediaBrowser.Controller
         /// Gets the installation manager.
         /// </summary>
         /// <value>The installation manager.</value>
-        public InstallationManager InstallationManager { get; private set; }
+        public InstallationManager InstallationManager { get; set; }
 
         /// <summary>
         /// Gets or sets the file system manager.
@@ -112,18 +111,6 @@ namespace MediaBrowser.Controller
         /// <value>The image enhancers.</value>
         public IEnumerable<IImageEnhancer> ImageEnhancers { get; private set; }
 
-        /// <summary>
-        /// Gets the list of currently registered entity resolvers
-        /// </summary>
-        /// <value>The entity resolvers enumerable.</value>
-        public IEnumerable<IBaseItemResolver> EntityResolvers { get; private set; }
-
-        /// <summary>
-        /// Gets the list of BasePluginFolders added by plugins
-        /// </summary>
-        /// <value>The plugin folders.</value>
-        public IEnumerable<IVirtualFolderCreator> PluginFolderCreators { get; private set; }
-
         /// <summary>
         /// Gets the list of available user repositories
         /// </summary>
@@ -154,12 +141,6 @@ namespace MediaBrowser.Controller
         /// <value>The item repository.</value>
         public IItemRepository ItemRepository { get; private set; }
 
-        /// <summary>
-        /// Gets the list of available item repositories
-        /// </summary>
-        /// <value>The user data repositories.</value>
-        private IEnumerable<IUserDataRepository> UserDataRepositories { get; set; }
-
         /// <summary>
         /// Gets the list of available DisplayPreferencesRepositories
         /// </summary>
@@ -167,10 +148,10 @@ namespace MediaBrowser.Controller
         private IEnumerable<IDisplayPreferencesRepository> DisplayPreferencesRepositories { get; set; }
 
         /// <summary>
-        /// Gets the list of entity resolution ignore rules
+        /// Gets the list of available item repositories
         /// </summary>
-        /// <value>The entity resolution ignore rules.</value>
-        public IEnumerable<IResolutionIgnoreRule> EntityResolutionIgnoreRules { get; private set; }
+        /// <value>The user data repositories.</value>
+        private IEnumerable<IUserDataRepository> UserDataRepositories { get; set; }
 
         /// <summary>
         /// Gets the active user data repository
@@ -217,7 +198,6 @@ namespace MediaBrowser.Controller
             BaseItem.LibraryManager = ApplicationHost.Resolve<ILibraryManager>();
             User.UserManager = ApplicationHost.Resolve<IUserManager>();
 
-            InstallationManager = (InstallationManager)ApplicationHost.CreateInstance(typeof(InstallationManager));
             FFMpegManager = (FFMpegManager)ApplicationHost.CreateInstance(typeof(FFMpegManager));
             ImageManager = (ImageManager)ApplicationHost.CreateInstance(typeof(ImageManager));
             ProviderManager = (ProviderManager)ApplicationHost.CreateInstance(typeof(ProviderManager));
@@ -225,7 +205,6 @@ namespace MediaBrowser.Controller
             
             base.FindParts();
 
-            EntityResolutionIgnoreRules = ApplicationHost.GetExports<IResolutionIgnoreRule>();
             UserDataRepositories = ApplicationHost.GetExports<IUserDataRepository>();
             UserRepositories = ApplicationHost.GetExports<IUserRepository>();
             DisplayPreferencesRepositories = ApplicationHost.GetExports<IDisplayPreferencesRepository>();
@@ -234,9 +213,7 @@ namespace MediaBrowser.Controller
             IntroProviders = ApplicationHost.GetExports<IIntroProvider>();
             PluginConfigurationPages = ApplicationHost.GetExports<IPluginConfigurationPage>();
             ImageEnhancers = ApplicationHost.GetExports<IImageEnhancer>().OrderBy(e => e.Priority).ToArray();
-            PluginFolderCreators = ApplicationHost.GetExports<IVirtualFolderCreator>();
             StringFiles = ApplicationHost.GetExports<LocalizedStringData>();
-            EntityResolvers = ApplicationHost.GetExports<IBaseItemResolver>().OrderBy(e => e.Priority).ToArray();
             MetadataProviders = ApplicationHost.GetExports<BaseMetadataProvider>().OrderBy(e => e.Priority).ToArray();
         }
 

+ 6 - 6
MediaBrowser.Controller/Library/DtoBuilder.cs

@@ -24,11 +24,11 @@ namespace MediaBrowser.Controller.Library
         /// </summary>
         const string IndexFolderDelimeter = "-index-";
 
-        private ILogger Logger;
+        private readonly ILogger _logger;
 
         public DtoBuilder(ILogger logger)
         {
-            Logger = logger;
+            _logger = logger;
         }
 
         /// <summary>
@@ -62,7 +62,7 @@ namespace MediaBrowser.Controller.Library
                 catch (Exception ex)
                 {
                     // Have to use a catch-all unfortunately because some .net image methods throw plain Exceptions
-                    Logger.ErrorException("Error generating PrimaryImageAspectRatio for {0}", ex, item.Name);
+                    _logger.ErrorException("Error generating PrimaryImageAspectRatio for {0}", ex, item.Name);
                 }
             }
 
@@ -124,7 +124,7 @@ namespace MediaBrowser.Controller.Library
                 catch (Exception ex)
                 {
                     // Have to use a catch-all unfortunately because some .net image methods throw plain Exceptions
-                    Logger.ErrorException("Error generating PrimaryImageAspectRatio for {0}", ex, item.Name);
+                    _logger.ErrorException("Error generating PrimaryImageAspectRatio for {0}", ex, item.Name);
                 }
             }
 
@@ -219,7 +219,7 @@ namespace MediaBrowser.Controller.Library
             }
             catch (FileNotFoundException)
             {
-                Logger.Error("Image file does not exist: {0}", path);
+                _logger.Error("Image file does not exist: {0}", path);
                 return;
             }
 
@@ -581,7 +581,7 @@ namespace MediaBrowser.Controller.Library
                         }
                         catch (IOException ex)
                         {
-                            Logger.ErrorException("Error getting person {0}", ex, c.Name);
+                            _logger.ErrorException("Error getting person {0}", ex, c.Name);
                             return null;
                         }
                     })

+ 10 - 0
MediaBrowser.Controller/Library/ILibraryManager.cs

@@ -4,6 +4,7 @@ using System.Threading;
 using System.Threading.Tasks;
 using MediaBrowser.Controller.Entities;
 using MediaBrowser.Controller.IO;
+using MediaBrowser.Controller.Resolvers;
 using MediaBrowser.Model.Entities;
 
 namespace MediaBrowser.Controller.Library
@@ -141,5 +142,14 @@ namespace MediaBrowser.Controller.Library
         /// <param name="userId">The user id.</param>
         /// <returns>BaseItem.</returns>
         BaseItem GetItemById(Guid id, Guid userId);
+
+        /// <summary>
+        /// Adds the parts.
+        /// </summary>
+        /// <param name="rules">The rules.</param>
+        /// <param name="pluginFolders">The plugin folders.</param>
+        /// <param name="resolvers">The resolvers.</param>
+        void AddParts(IEnumerable<IResolutionIgnoreRule> rules, IEnumerable<IVirtualFolderCreator> pluginFolders,
+                      IEnumerable<IBaseItemResolver> resolvers);
     }
 }

+ 9 - 9
MediaBrowser.Controller/Updates/InstallationManager.cs

@@ -13,7 +13,6 @@ using System.Collections.Concurrent;
 using System.Collections.Generic;
 using System.IO;
 using System.Linq;
-using System.Security.Cryptography;
 using System.Threading;
 using System.Threading.Tasks;
 
@@ -24,12 +23,16 @@ namespace MediaBrowser.Controller.Updates
     /// </summary>
     public class InstallationManager : BaseManager<Kernel>
     {
+        public event EventHandler<GenericEventArgs<InstallationInfo>> PackageInstalling;
+        public event EventHandler<GenericEventArgs<InstallationInfo>> PackageInstallationCompleted;
+        public event EventHandler<GenericEventArgs<InstallationInfo>> PackageInstallationFailed;
+        public event EventHandler<GenericEventArgs<InstallationInfo>> PackageInstallationCancelled;
+
         /// <summary>
         /// The current installations
         /// </summary>
         public List<Tuple<InstallationInfo, CancellationTokenSource>> CurrentInstallations { get; set; }
             
-
         /// <summary>
         /// The completed installations
         /// </summary>
@@ -48,9 +51,6 @@ namespace MediaBrowser.Controller.Updates
         private void OnPluginUninstalled(IPlugin plugin)
         {
             EventHelper.QueueEventIfNotNull(PluginUninstalled, this, new GenericEventArgs<IPlugin> { Argument = plugin }, _logger);
-
-            // Notify connected ui's
-            Kernel.ServerManager.SendWebSocketMessage("PluginUninstalled", plugin.GetPluginInfo());
         }
         #endregion
 
@@ -372,7 +372,7 @@ namespace MediaBrowser.Controller.Updates
 
             var linkedToken = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken, innerCancellationTokenSource.Token).Token;
 
-            Kernel.ServerManager.SendWebSocketMessage("PackageInstalling", installationInfo);
+            EventHelper.QueueEventIfNotNull(PackageInstalling, this, new GenericEventArgs<InstallationInfo>() { Argument = installationInfo }, _logger);
 
             try
             {
@@ -385,7 +385,7 @@ namespace MediaBrowser.Controller.Updates
 
                 CompletedInstallations.Add(installationInfo);
 
-                Kernel.ServerManager.SendWebSocketMessage("PackageInstallationCompleted", installationInfo);
+                EventHelper.QueueEventIfNotNull(PackageInstallationCompleted, this, new GenericEventArgs<InstallationInfo>() { Argument = installationInfo }, _logger);
             }
             catch (OperationCanceledException)
             {
@@ -396,7 +396,7 @@ namespace MediaBrowser.Controller.Updates
 
                 _logger.Info("Package installation cancelled: {0} {1}", package.name, package.versionStr);
 
-                Kernel.ServerManager.SendWebSocketMessage("PackageInstallationCancelled", installationInfo);
+                EventHelper.QueueEventIfNotNull(PackageInstallationCancelled, this, new GenericEventArgs<InstallationInfo>() { Argument = installationInfo }, _logger);
 
                 throw;
             }
@@ -407,7 +407,7 @@ namespace MediaBrowser.Controller.Updates
                     CurrentInstallations.Remove(tuple);
                 }
 
-                Kernel.ServerManager.SendWebSocketMessage("PackageInstallationFailed", installationInfo);
+                EventHelper.QueueEventIfNotNull(PackageInstallationFailed, this, new GenericEventArgs<InstallationInfo>() { Argument = installationInfo }, _logger);
 
                 throw;
             }

+ 34 - 16
MediaBrowser.Server.Implementations/Library/LibraryManager.cs

@@ -26,6 +26,24 @@ namespace MediaBrowser.Server.Implementations.Library
     /// </summary>
     public class LibraryManager : ILibraryManager
     {
+        /// <summary>
+        /// Gets the list of entity resolution ignore rules
+        /// </summary>
+        /// <value>The entity resolution ignore rules.</value>
+        public IEnumerable<IResolutionIgnoreRule> EntityResolutionIgnoreRules { get; private set; }
+
+        /// <summary>
+        /// Gets the list of BasePluginFolders added by plugins
+        /// </summary>
+        /// <value>The plugin folders.</value>
+        public IEnumerable<IVirtualFolderCreator> PluginFolderCreators { get; set; }
+
+        /// <summary>
+        /// Gets the list of currently registered entity resolvers
+        /// </summary>
+        /// <value>The entity resolvers enumerable.</value>
+        public IEnumerable<IBaseItemResolver> EntityResolvers { get; private set; }
+
         #region LibraryChanged Event
         /// <summary>
         /// Fires whenever any validation routine adds or removes items.  The added and removed items are properties of the args.
@@ -40,19 +58,6 @@ namespace MediaBrowser.Server.Implementations.Library
         public void ReportLibraryChanged(ChildrenChangedEventArgs args)
         {
             EventHelper.QueueEventIfNotNull(LibraryChanged, this, args, _logger);
-
-            // Had to put this in a separate method to avoid an implicitly captured closure
-            SendLibraryChangedWebSocketMessage(args);
-        }
-
-        /// <summary>
-        /// Sends the library changed web socket message.
-        /// </summary>
-        /// <param name="args">The <see cref="ChildrenChangedEventArgs" /> instance containing the event data.</param>
-        private void SendLibraryChangedWebSocketMessage(ChildrenChangedEventArgs args)
-        {
-            // Notify connected ui's
-            Kernel.ServerManager.SendWebSocketMessage("LibraryChanged", () => DtoBuilder.GetLibraryUpdateInfo(args));
         }
         #endregion
 
@@ -94,6 +99,19 @@ namespace MediaBrowser.Server.Implementations.Library
             kernel.ConfigurationUpdated += kernel_ConfigurationUpdated;
         }
 
+        /// <summary>
+        /// Adds the parts.
+        /// </summary>
+        /// <param name="rules">The rules.</param>
+        /// <param name="pluginFolders">The plugin folders.</param>
+        /// <param name="resolvers">The resolvers.</param>
+        public void AddParts(IEnumerable<IResolutionIgnoreRule> rules, IEnumerable<IVirtualFolderCreator> pluginFolders, IEnumerable<IBaseItemResolver> resolvers)
+        {
+            EntityResolutionIgnoreRules = rules;
+            PluginFolderCreators = pluginFolders;
+            EntityResolvers = resolvers;
+        }
+
         /// <summary>
         /// The _root folder
         /// </summary>
@@ -162,7 +180,7 @@ namespace MediaBrowser.Server.Implementations.Library
         /// <returns>BaseItem.</returns>
         public BaseItem ResolveItem(ItemResolveArgs args)
         {
-            return Kernel.EntityResolvers.Select(r => r.ResolvePath(args)).FirstOrDefault(i => i != null);
+            return EntityResolvers.Select(r => r.ResolvePath(args)).FirstOrDefault(i => i != null);
         }
 
         /// <summary>
@@ -195,7 +213,7 @@ namespace MediaBrowser.Server.Implementations.Library
             };
 
             // Return null if ignore rules deem that we should do so
-            if (Kernel.EntityResolutionIgnoreRules.Any(r => r.ShouldIgnore(args)))
+            if (EntityResolutionIgnoreRules.Any(r => r.ShouldIgnore(args)))
             {
                 return null;
             }
@@ -269,7 +287,7 @@ namespace MediaBrowser.Server.Implementations.Library
             var rootFolder = Kernel.ItemRepository.RetrieveItem(rootFolderPath.GetMBId(typeof(AggregateFolder))) as AggregateFolder ?? (AggregateFolder)ResolvePath(rootFolderPath);
 
             // Add in the plug-in folders
-            foreach (var child in Kernel.PluginFolderCreators)
+            foreach (var child in PluginFolderCreators)
             {
                 rootFolder.AddVirtualChild(child.GetFolder());
             }

+ 4 - 6
MediaBrowser.Server.Implementations/Library/UserManager.cs

@@ -83,6 +83,10 @@ namespace MediaBrowser.Server.Implementations.Library
         /// </summary>
         private readonly ILogger _logger;
 
+        /// <summary>
+        /// Gets or sets the kernel.
+        /// </summary>
+        /// <value>The kernel.</value>
         private Kernel Kernel { get; set; }
 
         /// <summary>
@@ -124,9 +128,6 @@ namespace MediaBrowser.Server.Implementations.Library
         private void OnUserUpdated(User user)
         {
             EventHelper.QueueEventIfNotNull(UserUpdated, this, new GenericEventArgs<User> { Argument = user }, _logger);
-
-            // Notify connected ui's
-            Kernel.ServerManager.SendWebSocketMessage("UserUpdated", new DtoBuilder(_logger).GetDtoUser(user));
         }
         #endregion
 
@@ -142,9 +143,6 @@ namespace MediaBrowser.Server.Implementations.Library
         private void OnUserDeleted(User user)
         {
             EventHelper.QueueEventIfNotNull(UserDeleted, this, new GenericEventArgs<User> { Argument = user }, _logger);
-
-            // Notify connected ui's
-            Kernel.ServerManager.SendWebSocketMessage("UserDeleted", user.Id.ToString());
         }
         #endregion
 

+ 40 - 5
MediaBrowser.ServerApplication/ApplicationHost.cs

@@ -1,5 +1,4 @@
 using MediaBrowser.Api;
-using MediaBrowser.ClickOnce;
 using MediaBrowser.Common.Implementations;
 using MediaBrowser.Common.Implementations.HttpServer;
 using MediaBrowser.Common.Implementations.Logging;
@@ -13,7 +12,10 @@ using MediaBrowser.Common.Net;
 using MediaBrowser.Common.ScheduledTasks;
 using MediaBrowser.Common.Updates;
 using MediaBrowser.Controller;
+using MediaBrowser.Controller.Entities;
 using MediaBrowser.Controller.Library;
+using MediaBrowser.Controller.Resolvers;
+using MediaBrowser.Controller.Updates;
 using MediaBrowser.IsoMounter;
 using MediaBrowser.Model.IO;
 using MediaBrowser.Model.Logging;
@@ -57,13 +59,15 @@ namespace MediaBrowser.ServerApplication
         /// </summary>
         private readonly IXmlSerializer _xmlSerializer = new XmlSerializer();
 
+        private WebSocketEvents _webSocketEvents;
+
         /// <summary>
         /// Gets the server application paths.
         /// </summary>
         /// <value>The server application paths.</value>
         protected IServerApplicationPaths ServerApplicationPaths
         {
-            get { return (IServerApplicationPaths) ApplicationPaths; }
+            get { return (IServerApplicationPaths)ApplicationPaths; }
         }
 
         /// <summary>
@@ -74,7 +78,7 @@ namespace MediaBrowser.ServerApplication
             : base()
         {
             Kernel = new Kernel(this, ServerApplicationPaths, _xmlSerializer, Logger);
-            
+
             var networkManager = new NetworkManager();
 
             var serverManager = new ServerManager(this, Kernel, networkManager, _jsonSerializer, Logger);
@@ -135,6 +139,20 @@ namespace MediaBrowser.ServerApplication
             RegisterSingleInstance<ILibraryManager>(new LibraryManager(Kernel, Logger, taskManager, userManager));
         }
 
+        /// <summary>
+        /// Finds the parts.
+        /// </summary>
+        protected override void FindParts()
+        {
+            base.FindParts();
+
+            Resolve<ILibraryManager>().AddParts(GetExports<IResolutionIgnoreRule>(), GetExports<IVirtualFolderCreator>(), GetExports<IBaseItemResolver>());
+
+            Kernel.InstallationManager = (InstallationManager)CreateInstance(typeof(InstallationManager));
+
+            _webSocketEvents = new WebSocketEvents(Resolve<IServerManager>(), Resolve<IKernel>(), Resolve<ILogger>(), Resolve<IUserManager>(), Resolve<ILibraryManager>(), Kernel.InstallationManager);
+        }
+
         /// <summary>
         /// Restarts this instance.
         /// </summary>
@@ -164,8 +182,8 @@ namespace MediaBrowser.ServerApplication
             var availablePackages = await pkgManager.GetAvailablePackages(Resolve<IHttpClient>(), Resolve<INetworkManager>(), Kernel.SecurityManager, Kernel.ResourcePools, Resolve<IJsonSerializer>(), CancellationToken.None).ConfigureAwait(false);
             var version = Kernel.InstallationManager.GetLatestCompatibleVersion(availablePackages, "MBServer", Kernel.Configuration.SystemUpdateLevel);
 
-            return version != null ? new CheckForUpdateResult {AvailableVersion = version.version, IsUpdateAvailable = version.version > ApplicationVersion, Package = version} :
-                       new CheckForUpdateResult {AvailableVersion = ApplicationVersion, IsUpdateAvailable = false};
+            return version != null ? new CheckForUpdateResult { AvailableVersion = version.version, IsUpdateAvailable = version.version > ApplicationVersion, Package = version } :
+                       new CheckForUpdateResult { AvailableVersion = ApplicationVersion, IsUpdateAvailable = false };
         }
 
         /// <summary>
@@ -228,5 +246,22 @@ namespace MediaBrowser.ServerApplication
         {
             App.Instance.Dispatcher.Invoke(App.Instance.Shutdown);
         }
+
+        /// <summary>
+        /// Releases unmanaged and - optionally - managed resources.
+        /// </summary>
+        /// <param name="dispose"><c>true</c> to release both managed and unmanaged resources; <c>false</c> to release only unmanaged resources.</param>
+        protected override void Dispose(bool dispose)
+        {
+            if (dispose)
+            {
+                if (_webSocketEvents != null)
+                {
+                    _webSocketEvents.Dispose();
+                }
+            }
+
+            base.Dispose(dispose);
+        }
     }
 }

+ 1 - 0
MediaBrowser.ServerApplication/MediaBrowser.ServerApplication.csproj

@@ -162,6 +162,7 @@
     <Reference Include="PresentationFramework" />
   </ItemGroup>
   <ItemGroup>
+    <Compile Include="WebSocketEvents.cs" />
     <Page Include="App.xaml">
       <Generator>MSBuild:Compile</Generator>
       <SubType>Designer</SubType>

+ 199 - 0
MediaBrowser.ServerApplication/WebSocketEvents.cs

@@ -0,0 +1,199 @@
+using MediaBrowser.Common.Events;
+using MediaBrowser.Common.Kernel;
+using MediaBrowser.Common.Plugins;
+using MediaBrowser.Controller.Entities;
+using MediaBrowser.Controller.Library;
+using MediaBrowser.Controller.Updates;
+using MediaBrowser.Model.Logging;
+using MediaBrowser.Model.Updates;
+using System;
+
+namespace MediaBrowser.ServerApplication
+{
+    /// <summary>
+    /// Class WebSocketEvents
+    /// </summary>
+    public class WebSocketEvents : IDisposable
+    {
+        /// <summary>
+        /// The _server manager
+        /// </summary>
+        private readonly IServerManager _serverManager;
+        /// <summary>
+        /// The _logger
+        /// </summary>
+        private readonly ILogger _logger;
+
+        /// <summary>
+        /// The _user manager
+        /// </summary>
+        private readonly IUserManager _userManager;
+
+        /// <summary>
+        /// The _library manager
+        /// </summary>
+        private readonly ILibraryManager _libraryManager;
+
+        /// <summary>
+        /// The _installation manager
+        /// </summary>
+        private readonly InstallationManager _installationManager;
+
+        /// <summary>
+        /// The _kernel
+        /// </summary>
+        private readonly IKernel _kernel;
+        
+        /// <summary>
+        /// Initializes a new instance of the <see cref="WebSocketEvents" /> class.
+        /// </summary>
+        /// <param name="serverManager">The server manager.</param>
+        /// <param name="logger">The logger.</param>
+        /// <param name="userManager">The user manager.</param>
+        public WebSocketEvents(IServerManager serverManager, IKernel kernel, ILogger logger, IUserManager userManager, ILibraryManager libraryManager, InstallationManager installationManager)
+        {
+            _serverManager = serverManager;
+            _logger = logger;
+            _userManager = userManager;
+            _libraryManager = libraryManager;
+            _installationManager = installationManager;
+            _kernel = kernel;
+
+            _userManager.UserDeleted += userManager_UserDeleted;
+            _userManager.UserUpdated += userManager_UserUpdated;
+
+            _libraryManager.LibraryChanged += libraryManager_LibraryChanged;
+
+            kernel.HasPendingRestartChanged += kernel_HasPendingRestartChanged;
+
+            installationManager.PluginUninstalled += InstallationManager_PluginUninstalled;
+            installationManager.PackageInstalling += installationManager_PackageInstalling;
+            installationManager.PackageInstallationCancelled += installationManager_PackageInstallationCancelled;
+            installationManager.PackageInstallationCompleted += installationManager_PackageInstallationCompleted;
+            installationManager.PackageInstallationFailed += installationManager_PackageInstallationFailed;
+        }
+
+        /// <summary>
+        /// Installations the manager_ package installation failed.
+        /// </summary>
+        /// <param name="sender">The sender.</param>
+        /// <param name="e">The e.</param>
+        void installationManager_PackageInstallationFailed(object sender, GenericEventArgs<InstallationInfo> e)
+        {
+            _serverManager.SendWebSocketMessage("PackageInstallationFailed", e.Argument);
+        }
+
+        /// <summary>
+        /// Installations the manager_ package installation completed.
+        /// </summary>
+        /// <param name="sender">The sender.</param>
+        /// <param name="e">The e.</param>
+        void installationManager_PackageInstallationCompleted(object sender, GenericEventArgs<InstallationInfo> e)
+        {
+            _serverManager.SendWebSocketMessage("PackageInstallationCompleted", e.Argument);
+        }
+
+        /// <summary>
+        /// Installations the manager_ package installation cancelled.
+        /// </summary>
+        /// <param name="sender">The sender.</param>
+        /// <param name="e">The e.</param>
+        void installationManager_PackageInstallationCancelled(object sender, GenericEventArgs<InstallationInfo> e)
+        {
+            _serverManager.SendWebSocketMessage("PackageInstallationCancelled", e.Argument);
+        }
+
+        /// <summary>
+        /// Installations the manager_ package installing.
+        /// </summary>
+        /// <param name="sender">The sender.</param>
+        /// <param name="e">The e.</param>
+        void installationManager_PackageInstalling(object sender, GenericEventArgs<InstallationInfo> e)
+        {
+            _serverManager.SendWebSocketMessage("PackageInstalling", e.Argument);
+        }
+
+        /// <summary>
+        /// Handles the LibraryChanged event of the libraryManager control.
+        /// </summary>
+        /// <param name="sender">The source of the event.</param>
+        /// <param name="e">The <see cref="ChildrenChangedEventArgs" /> instance containing the event data.</param>
+        void libraryManager_LibraryChanged(object sender, ChildrenChangedEventArgs e)
+        {
+            _serverManager.SendWebSocketMessage("LibraryChanged", () => DtoBuilder.GetLibraryUpdateInfo(e));
+        }
+
+        /// <summary>
+        /// Installations the manager_ plugin uninstalled.
+        /// </summary>
+        /// <param name="sender">The sender.</param>
+        /// <param name="e">The e.</param>
+        void InstallationManager_PluginUninstalled(object sender, GenericEventArgs<IPlugin> e)
+        {
+            _serverManager.SendWebSocketMessage("PluginUninstalled", e.Argument.GetPluginInfo());
+        }
+
+        /// <summary>
+        /// Handles the HasPendingRestartChanged event of the kernel control.
+        /// </summary>
+        /// <param name="sender">The source of the event.</param>
+        /// <param name="e">The <see cref="EventArgs" /> instance containing the event data.</param>
+        void kernel_HasPendingRestartChanged(object sender, EventArgs e)
+        {
+            var kernel = (IKernel)sender;
+
+            _serverManager.SendWebSocketMessage("HasPendingRestartChanged", kernel.GetSystemInfo());
+        }
+
+        /// <summary>
+        /// Users the manager_ user updated.
+        /// </summary>
+        /// <param name="sender">The sender.</param>
+        /// <param name="e">The e.</param>
+        void userManager_UserUpdated(object sender, GenericEventArgs<User> e)
+        {
+            _serverManager.SendWebSocketMessage("UserUpdated", new DtoBuilder(_logger).GetDtoUser(e.Argument));
+        }
+
+        /// <summary>
+        /// Users the manager_ user deleted.
+        /// </summary>
+        /// <param name="sender">The sender.</param>
+        /// <param name="e">The e.</param>
+        void userManager_UserDeleted(object sender, GenericEventArgs<User> e)
+        {
+            _serverManager.SendWebSocketMessage("UserDeleted", e.Argument.Id.ToString());
+        }
+
+        /// <summary>
+        /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
+        /// </summary>
+        public void Dispose()
+        {
+            Dispose(true);
+        }
+
+        /// <summary>
+        /// Releases unmanaged and - optionally - managed resources.
+        /// </summary>
+        /// <param name="dispose"><c>true</c> to release both managed and unmanaged resources; <c>false</c> to release only unmanaged resources.</param>
+        protected virtual void Dispose(bool dispose)
+        {
+            if (dispose)
+            {
+                _userManager.UserDeleted -= userManager_UserDeleted;
+                _userManager.UserUpdated -= userManager_UserUpdated;
+
+                _libraryManager.LibraryChanged -= libraryManager_LibraryChanged;
+
+                _installationManager.PluginUninstalled -= InstallationManager_PluginUninstalled;
+                _installationManager.PackageInstalling -= installationManager_PackageInstalling;
+                _installationManager.PackageInstallationCancelled -= installationManager_PackageInstallationCancelled;
+                _installationManager.PackageInstallationCompleted -= installationManager_PackageInstallationCompleted;
+                _installationManager.PackageInstallationFailed -= installationManager_PackageInstallationFailed;
+
+                _kernel.HasPendingRestartChanged -= kernel_HasPendingRestartChanged;
+            }
+        }
+    }
+}

BIN
MediaBrowser.WebDashboard/Html/css/images/mblogoicon.png


+ 1 - 0
MediaBrowser.WebDashboard/Html/css/site.css

@@ -107,6 +107,7 @@ pre, textarea.pre {
 .imgLogoText {
     height: 45px;
     display: none;
+    margin-left: 5px;
 }