From 767cdc1f6f6a63ce997fc9476911e2c361f9d402 Mon Sep 17 00:00:00 2001 From: LukePulverenti Date: Wed, 20 Feb 2013 20:33:05 -0500 Subject: Pushing missing changes --- MediaBrowser.Common/Plugins/BasePlugin.cs | 697 +++++++++++++++++++----------- 1 file changed, 450 insertions(+), 247 deletions(-) (limited to 'MediaBrowser.Common/Plugins/BasePlugin.cs') diff --git a/MediaBrowser.Common/Plugins/BasePlugin.cs b/MediaBrowser.Common/Plugins/BasePlugin.cs index 70e573817..3cce146fa 100644 --- a/MediaBrowser.Common/Plugins/BasePlugin.cs +++ b/MediaBrowser.Common/Plugins/BasePlugin.cs @@ -1,247 +1,450 @@ -using MediaBrowser.Common.Kernel; -using MediaBrowser.Common.Logging; -using MediaBrowser.Common.Serialization; -using MediaBrowser.Model.Plugins; -using System; -using System.IO; -using System.Reflection; - -namespace MediaBrowser.Common.Plugins -{ - /// - /// Provides a common base class for all plugins - /// - public abstract class BasePlugin : IDisposable - { - protected IKernel Kernel { get; private set; } - - /// - /// Gets or sets the plugin's current context - /// - protected KernelContext Context { get { return Kernel.KernelContext; } } - - /// - /// Gets the name of the plugin - /// - public abstract string Name { get; } - - /// - /// Gets the type of configuration this plugin uses - /// - public virtual Type ConfigurationType - { - get { return typeof (BasePluginConfiguration); } - } - - /// - /// Gets the plugin version - /// - public Version Version - { - get - { - return GetType().Assembly.GetName().Version; - } - } - - /// - /// Gets the name the assembly file - /// - public string AssemblyFileName - { - get - { - return GetType().Assembly.GetName().Name + ".dll"; - } - } - - private DateTime? _configurationDateLastModified; - public DateTime ConfigurationDateLastModified - { - get - { - if (_configurationDateLastModified == null) - { - if (File.Exists(ConfigurationFilePath)) - { - _configurationDateLastModified = File.GetLastWriteTimeUtc(ConfigurationFilePath); - } - } - - return _configurationDateLastModified ?? DateTime.MinValue; - } - } - - /// - /// Gets the path to the assembly file - /// - public string AssemblyFilePath - { - get - { - return Path.Combine(Kernel.ApplicationPaths.PluginsPath, AssemblyFileName); - } - } - - /// - /// Gets or sets the current plugin configuration - /// - public BasePluginConfiguration Configuration { get; protected set; } - - /// - /// Gets the name of the configuration file. Subclasses should override - /// - public virtual string ConfigurationFileName - { - get - { - return Name.Replace(" ", string.Empty) + ".xml"; - } - } - - /// - /// Gets the full path to the configuration file - /// - public string ConfigurationFilePath - { - get - { - return Path.Combine(Kernel.ApplicationPaths.PluginConfigurationsPath, ConfigurationFileName); - } - } - - private string _dataFolderPath; - /// - /// Gets the full path to the data folder, where the plugin can store any miscellaneous files needed - /// - public string DataFolderPath - { - get - { - if (_dataFolderPath == null) - { - // Give the folder name the same name as the config file name - // We can always make this configurable if/when needed - _dataFolderPath = Path.Combine(Kernel.ApplicationPaths.PluginsPath, Path.GetFileNameWithoutExtension(ConfigurationFileName)); - - if (!Directory.Exists(_dataFolderPath)) - { - Directory.CreateDirectory(_dataFolderPath); - } - } - - return _dataFolderPath; - } - } - - public bool Enabled - { - get - { - return Configuration.Enabled; - } - } - - /// - /// Returns true or false indicating if the plugin should be downloaded and run within the Ui. - /// - public virtual bool DownloadToUi - { - get - { - return false; - } - } - - public void Initialize(IKernel kernel) - { - Initialize(kernel, true); - } - - /// - /// Starts the plugin. - /// - public void Initialize(IKernel kernel, bool loadFeatures) - { - Kernel = kernel; - - if (loadFeatures) - { - ReloadConfiguration(); - - if (Enabled) - { - if (kernel.KernelContext == KernelContext.Server) - { - InitializeOnServer(); - } - else if (kernel.KernelContext == KernelContext.Ui) - { - InitializeInUi(); - } - } - } - } - - /// - /// Starts the plugin on the server - /// - protected virtual void InitializeOnServer() - { - } - - /// - /// Starts the plugin in the Ui - /// - protected virtual void InitializeInUi() - { - } - - /// - /// Disposes the plugins. Undos all actions performed during Init. - /// - public void Dispose() - { - Logger.LogInfo("Disposing {0} Plugin", Name); - - if (Context == KernelContext.Server) - { - DisposeOnServer(); - } - else if (Context == KernelContext.Ui) - { - InitializeInUi(); - } - } - - /// - /// Disposes the plugin on the server - /// - protected virtual void DisposeOnServer() - { - } - - /// - /// Disposes the plugin in the Ui - /// - protected virtual void DisposeInUi() - { - } - - public void ReloadConfiguration() - { - if (!File.Exists(ConfigurationFilePath)) - { - Configuration = Activator.CreateInstance(ConfigurationType) as BasePluginConfiguration; - XmlSerializer.SerializeToFile(Configuration, ConfigurationFilePath); - } - else - { - Configuration = XmlSerializer.DeserializeFromFile(ConfigurationType, ConfigurationFilePath) as BasePluginConfiguration; - } - - // Reset this so it will be loaded again next time it's accessed - _configurationDateLastModified = null; - } - } -} +using MediaBrowser.Common.Kernel; +using MediaBrowser.Common.Logging; +using MediaBrowser.Common.Serialization; +using MediaBrowser.Model.Logging; +using MediaBrowser.Model.Plugins; +using System; +using System.IO; +using System.Reflection; +using System.Runtime.InteropServices; +using System.Threading; + +namespace MediaBrowser.Common.Plugins +{ + /// + /// Provides a common base class for all plugins + /// + /// The type of the T configuration type. + public abstract class BasePlugin : IDisposable, IPlugin + where TConfigurationType : BasePluginConfiguration + { + /// + /// Gets the kernel. + /// + /// The kernel. + protected IKernel Kernel { get; private set; } + + /// + /// Gets or sets the plugin's current context + /// + /// The context. + protected KernelContext Context { get { return Kernel.KernelContext; } } + + /// + /// Gets the name of the plugin + /// + /// The name. + public abstract string Name { get; } + + /// + /// Gets the description. + /// + /// The description. + public virtual string Description + { + get { return string.Empty; } + } + + /// + /// Gets a value indicating whether this instance is a core plugin. + /// + /// true if this instance is a core plugin; otherwise, false. + public virtual bool IsCorePlugin + { + get + { + return false; + } + } + + /// + /// Gets the type of configuration this plugin uses + /// + /// The type of the configuration. + public Type ConfigurationType + { + get { return typeof(TConfigurationType); } + } + + /// + /// The _assembly name + /// + private AssemblyName _assemblyName; + /// + /// Gets the name of the assembly. + /// + /// The name of the assembly. + protected AssemblyName AssemblyName + { + get + { + return _assemblyName ?? (_assemblyName = GetType().Assembly.GetName()); + } + } + + /// + /// The _unique id + /// + private Guid? _uniqueId; + + /// + /// Gets the unique id. + /// + /// The unique id. + public Guid UniqueId + { + get + { + + if (!_uniqueId.HasValue) + { + _uniqueId = Marshal.GetTypeLibGuidForAssembly(GetType().Assembly); + } + + return _uniqueId.Value; + } + } + + /// + /// Gets the plugin version + /// + /// The version. + public Version Version + { + get + { + return AssemblyName.Version; + } + } + + /// + /// Gets the name the assembly file + /// + /// The name of the assembly file. + public string AssemblyFileName + { + get + { + return AssemblyName.Name + ".dll"; + } + } + + /// + /// Gets the last date modified of the configuration + /// + /// The configuration date last modified. + public DateTime ConfigurationDateLastModified + { + get + { + // Ensure it's been lazy loaded + var config = Configuration; + + return File.GetLastWriteTimeUtc(ConfigurationFilePath); + } + } + + /// + /// Gets the last date modified of the plugin + /// + /// The assembly date last modified. + public DateTime AssemblyDateLastModified + { + get + { + return File.GetLastWriteTimeUtc(AssemblyFilePath); + } + } + + /// + /// Gets the path to the assembly file + /// + /// The assembly file path. + public string AssemblyFilePath + { + get + { + return Path.Combine(Kernel.ApplicationPaths.PluginsPath, AssemblyFileName); + } + } + + /// + /// The _configuration sync lock + /// + private object _configurationSyncLock = new object(); + /// + /// The _configuration initialized + /// + private bool _configurationInitialized; + /// + /// The _configuration + /// + private TConfigurationType _configuration; + /// + /// Gets the plugin's configuration + /// + /// The configuration. + public TConfigurationType Configuration + { + get + { + // Lazy load + LazyInitializer.EnsureInitialized(ref _configuration, ref _configurationInitialized, ref _configurationSyncLock, () => XmlSerializer.GetXmlConfiguration(ConfigurationType, ConfigurationFilePath) as TConfigurationType); + return _configuration; + } + protected set + { + _configuration = value; + + if (value == null) + { + _configurationInitialized = false; + } + } + } + + /// + /// Gets the name of the configuration file. Subclasses should override + /// + /// The name of the configuration file. + public virtual string ConfigurationFileName + { + get { return Path.ChangeExtension(AssemblyFileName, ".xml"); } + } + + /// + /// Gets the full path to the configuration file + /// + /// The configuration file path. + public string ConfigurationFilePath + { + get + { + return Path.Combine(Kernel.ApplicationPaths.PluginConfigurationsPath, ConfigurationFileName); + } + } + + /// + /// The _data folder path + /// + private string _dataFolderPath; + /// + /// Gets the full path to the data folder, where the plugin can store any miscellaneous files needed + /// + /// The data folder path. + public string DataFolderPath + { + get + { + if (_dataFolderPath == null) + { + // Give the folder name the same name as the config file name + // We can always make this configurable if/when needed + _dataFolderPath = Path.Combine(Kernel.ApplicationPaths.PluginsPath, Path.GetFileNameWithoutExtension(ConfigurationFileName)); + + if (!Directory.Exists(_dataFolderPath)) + { + Directory.CreateDirectory(_dataFolderPath); + } + } + + return _dataFolderPath; + } + } + + /// + /// Returns true or false indicating if the plugin should be downloaded and run within the Ui. + /// + /// true if [download to UI]; otherwise, false. + public virtual bool DownloadToUi + { + get + { + return false; + } + } + + /// + /// Gets the logger. + /// + /// The logger. + public ILogger Logger { get; private set; } + + /// + /// Starts the plugin. + /// + /// The kernel. + /// kernel + public void Initialize(IKernel kernel) + { + if (kernel == null) + { + throw new ArgumentNullException("kernel"); + } + + Logger = LogManager.GetLogger(Name); + + Kernel = kernel; + + if (kernel.KernelContext == KernelContext.Server) + { + InitializeOnServer(!File.Exists(ConfigurationFilePath)); + } + else if (kernel.KernelContext == KernelContext.Ui) + { + InitializeInUi(); + } + } + + /// + /// Starts the plugin on the server + /// + /// if set to true [is first run]. + protected virtual void InitializeOnServer(bool isFirstRun) + { + } + + /// + /// Starts the plugin in the Ui + /// + protected virtual void InitializeInUi() + { + } + + /// + /// Disposes the plugins. Undos all actions performed during Init. + /// + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + + /// + /// Releases unmanaged and - optionally - managed resources. + /// + /// true to release both managed and unmanaged resources; false to release only unmanaged resources. + protected void Dispose(bool dispose) + { + if (Kernel.KernelContext == KernelContext.Server) + { + DisposeOnServer(dispose); + } + else if (Kernel.KernelContext == KernelContext.Ui) + { + DisposeInUI(dispose); + } + } + + /// + /// Releases unmanaged and - optionally - managed resources. + /// + /// true to release both managed and unmanaged resources; false to release only unmanaged resources. + protected virtual void DisposeOnServer(bool dispose) + { + + } + + /// + /// Releases unmanaged and - optionally - managed resources. + /// + /// true to release both managed and unmanaged resources; false to release only unmanaged resources. + protected virtual void DisposeInUI(bool dispose) + { + + } + + /// + /// The _save lock + /// + private readonly object _configurationSaveLock = new object(); + + /// + /// Saves the current configuration to the file system + /// + /// Cannot call Plugin.SaveConfiguration from the UI. + public virtual void SaveConfiguration() + { + if (Kernel.KernelContext != KernelContext.Server) + { + throw new InvalidOperationException("Cannot call Plugin.SaveConfiguration from the UI."); + } + + Logger.Info("Saving configuration"); + + lock (_configurationSaveLock) + { + XmlSerializer.SerializeToFile(Configuration, ConfigurationFilePath); + } + + // Notify connected UI's + Kernel.TcpManager.SendWebSocketMessage("PluginConfigurationUpdated-" + Name, Configuration); + } + + /// + /// Completely overwrites the current configuration with a new copy + /// Returns true or false indicating success or failure + /// + /// The configuration. + /// configuration + public virtual void UpdateConfiguration(BasePluginConfiguration configuration) + { + if (configuration == null) + { + throw new ArgumentNullException("configuration"); + } + + Configuration = (TConfigurationType)configuration; + + SaveConfiguration(); + } + + /// + /// Gets the plugin info. + /// + /// PluginInfo. + public PluginInfo GetPluginInfo() + { + var info = new PluginInfo + { + Name = Name, + DownloadToUI = DownloadToUi, + Version = Version.ToString(), + AssemblyFileName = AssemblyFileName, + ConfigurationDateLastModified = ConfigurationDateLastModified, + Description = Description, + IsCorePlugin = IsCorePlugin, + UniqueId = UniqueId, + EnableAutoUpdate = Configuration.EnableAutoUpdate, + UpdateClass = Configuration.UpdateClass, + ConfigurationFileName = ConfigurationFileName + }; + + var uiPlugin = this as IUIPlugin; + + if (uiPlugin != null) + { + info.MinimumRequiredUIVersion = uiPlugin.MinimumRequiredUIVersion.ToString(); + } + + return info; + } + + /// + /// Called when just before the plugin is uninstalled from the server. + /// + public virtual void OnUninstalling() + { + + } + + /// + /// Gets the plugin's configuration + /// + /// The configuration. + BasePluginConfiguration IPlugin.Configuration + { + get { return Configuration; } + } + } +} -- cgit v1.2.3