Implemented UI plugin downloading

This commit is contained in:
LukePulverenti Luke Pulverenti luke pulverenti 2012-09-03 15:12:02 -04:00
parent 4500f1d11b
commit 26aef6b082
11 changed files with 118 additions and 28 deletions

View File

@ -0,0 +1,31 @@
using System;
using System.IO;
using System.Net;
using System.Threading.Tasks;
using MediaBrowser.Common.Net.Handlers;
using MediaBrowser.Controller;
namespace MediaBrowser.Api.HttpHandlers
{
class PluginAssemblyHandler : BaseHandler
{
public override Task<string> GetContentType()
{
throw new NotImplementedException();
}
protected override Task WriteResponseToOutputStream(Stream stream)
{
throw new NotImplementedException();
}
public override Task ProcessRequest(HttpListenerContext ctx)
{
string filename = ctx.Request.QueryString["assemblyfilename"];
string path = Path.Combine(Kernel.Instance.ApplicationPaths.PluginsPath, filename);
return new StaticFileHandler() { Path = path }.ProcessRequest(ctx);
}
}
}

View File

@ -21,7 +21,8 @@ namespace MediaBrowser.Api.HttpHandlers
Name = p.Name, Name = p.Name,
Enabled = p.Enabled, Enabled = p.Enabled,
DownloadToUI = p.DownloadToUI, DownloadToUI = p.DownloadToUI,
Version = p.Version.ToString() Version = p.Version.ToString(),
AssemblyFileName = p.AssemblyFileName
}; };
}); });

View File

@ -67,6 +67,7 @@
<Compile Include="HttpHandlers\ItemHandler.cs" /> <Compile Include="HttpHandlers\ItemHandler.cs" />
<Compile Include="HttpHandlers\ItemListHandler.cs" /> <Compile Include="HttpHandlers\ItemListHandler.cs" />
<Compile Include="HttpHandlers\PersonHandler.cs" /> <Compile Include="HttpHandlers\PersonHandler.cs" />
<Compile Include="HttpHandlers\PluginAssemblyHandler.cs" />
<Compile Include="HttpHandlers\PluginConfigurationHandler.cs" /> <Compile Include="HttpHandlers\PluginConfigurationHandler.cs" />
<Compile Include="HttpHandlers\PluginsHandler.cs" /> <Compile Include="HttpHandlers\PluginsHandler.cs" />
<Compile Include="HttpHandlers\ServerConfigurationHandler.cs" /> <Compile Include="HttpHandlers\ServerConfigurationHandler.cs" />

View File

@ -113,6 +113,10 @@ namespace MediaBrowser.Api
{ {
return new DefaultUserHandler(); return new DefaultUserHandler();
} }
else if (localPath.EndsWith("/api/pluginassembly", StringComparison.OrdinalIgnoreCase))
{
return new PluginAssemblyHandler();
}
return null; return null;
} }

View File

@ -569,7 +569,7 @@ namespace MediaBrowser.ApiInteraction
/// <summary> /// <summary>
/// Gets a list of plugins installed on the server /// Gets a list of plugins installed on the server
/// </summary> /// </summary>
public async Task<PluginInfo[]> GetInstalledPlugins() public async Task<PluginInfo[]> GetInstalledPluginsAsync()
{ {
string url = ApiUrl + "/plugins"; string url = ApiUrl + "/plugins";
@ -578,7 +578,17 @@ namespace MediaBrowser.ApiInteraction
return DeserializeFromStream<PluginInfo[]>(stream); return DeserializeFromStream<PluginInfo[]>(stream);
} }
} }
/// <summary>
/// Gets a list of plugins installed on the server
/// </summary>
public Task<Stream> GetPluginAssemblyAsync(PluginInfo plugin)
{
string url = ApiUrl + "/pluginassembly?assemblyfilename=" + plugin.AssemblyFileName;
return GetStreamAsync(url);
}
/// <summary> /// <summary>
/// Gets weather information for the default location as set in configuration /// Gets weather information for the default location as set in configuration
/// </summary> /// </summary>
@ -655,7 +665,7 @@ namespace MediaBrowser.ApiInteraction
return GetStreamAsync(url); return GetStreamAsync(url);
} }
private T DeserializeFromStream<T>(Stream stream) private T DeserializeFromStream<T>(Stream stream)
{ {
return DeserializeFromStream<T>(stream, SerializationFormat); return DeserializeFromStream<T>(stream, SerializationFormat);

View File

@ -59,21 +59,18 @@ namespace MediaBrowser.Common.Kernel
ApplicationPaths = new TApplicationPathsType(); ApplicationPaths = new TApplicationPathsType();
} }
public virtual Task Init(IProgress<TaskProgress> progress) public virtual async Task Init(IProgress<TaskProgress> progress)
{ {
return Task.Run(() => ReloadLogger();
{
ReloadLogger();
progress.Report(new TaskProgress() { Description = "Loading configuration", PercentComplete = 0 }); progress.Report(new TaskProgress() { Description = "Loading configuration", PercentComplete = 0 });
ReloadConfiguration(); ReloadConfiguration();
progress.Report(new TaskProgress() { Description = "Starting Http server", PercentComplete = 5 }); progress.Report(new TaskProgress() { Description = "Starting Http server", PercentComplete = 5 });
ReloadHttpServer(); ReloadHttpServer();
progress.Report(new TaskProgress() { Description = "Loading Plugins", PercentComplete = 10 }); progress.Report(new TaskProgress() { Description = "Loading Plugins", PercentComplete = 10 });
ReloadComposableParts(); await ReloadComposableParts().ConfigureAwait(false);
});
} }
/// <summary> /// <summary>
@ -98,10 +95,25 @@ namespace MediaBrowser.Common.Kernel
/// Uses MEF to locate plugins /// Uses MEF to locate plugins
/// Subclasses can use this to locate types within plugins /// Subclasses can use this to locate types within plugins
/// </summary> /// </summary>
protected void ReloadComposableParts() protected virtual Task ReloadComposableParts()
{ {
DisposeComposableParts(); return Task.Run(() =>
{
DisposeComposableParts();
var container = GetCompositionContainer(includeCurrentAssembly: true);
container.ComposeParts(this);
OnComposablePartsLoaded();
container.Catalog.Dispose();
container.Dispose();
});
}
public CompositionContainer GetCompositionContainer(bool includeCurrentAssembly = false)
{
// Gets all plugin assemblies by first reading all bytes of the .dll and calling Assembly.Load against that // Gets all plugin assemblies by first reading all bytes of the .dll and calling Assembly.Load against that
// This will prevent the .dll file from getting locked, and allow us to replace it when needed // This will prevent the .dll file from getting locked, and allow us to replace it when needed
IEnumerable<Assembly> pluginAssemblies = Directory.GetFiles(ApplicationPaths.PluginsPath, "*.dll", SearchOption.TopDirectoryOnly).Select(f => Assembly.Load(File.ReadAllBytes((f)))); IEnumerable<Assembly> pluginAssemblies = Directory.GetFiles(ApplicationPaths.PluginsPath, "*.dll", SearchOption.TopDirectoryOnly).Select(f => Assembly.Load(File.ReadAllBytes((f))));
@ -112,17 +124,13 @@ namespace MediaBrowser.Common.Kernel
// Uncomment this if it's ever needed // Uncomment this if it's ever needed
//catalog.Catalogs.Add(new AssemblyCatalog(Assembly.GetExecutingAssembly())); //catalog.Catalogs.Add(new AssemblyCatalog(Assembly.GetExecutingAssembly()));
// Include composable parts in the subclass assembly if (includeCurrentAssembly)
catalog.Catalogs.Add(new AssemblyCatalog(GetType().Assembly)); {
// Include composable parts in the subclass assembly
catalog.Catalogs.Add(new AssemblyCatalog(GetType().Assembly));
}
var container = new CompositionContainer(catalog); return new CompositionContainer(catalog);
container.ComposeParts(this);
OnComposablePartsLoaded();
catalog.Dispose();
container.Dispose();
} }
/// <summary> /// <summary>

View File

@ -65,6 +65,7 @@
<HintPath>..\packages\Rx-Linq.2.0.20823\lib\Net45\System.Reactive.Linq.dll</HintPath> <HintPath>..\packages\Rx-Linq.2.0.20823\lib\Net45\System.Reactive.Linq.dll</HintPath>
</Reference> </Reference>
<Reference Include="System.Runtime.Remoting" /> <Reference Include="System.Runtime.Remoting" />
<Reference Include="System.Runtime.Serialization" />
<Reference Include="System.Windows.Interactivity"> <Reference Include="System.Windows.Interactivity">
<HintPath>..\packages\MahApps.Metro.0.9.0.0\lib\net40\System.Windows.Interactivity.dll</HintPath> <HintPath>..\packages\MahApps.Metro.0.9.0.0\lib\net40\System.Windows.Interactivity.dll</HintPath>
</Reference> </Reference>

View File

@ -148,6 +148,12 @@ namespace MediaBrowser.Common.Net
return "application/x-mpegURL"; return "application/x-mpegURL";
} }
// Misc
else if (ext.EndsWith("dll", StringComparison.OrdinalIgnoreCase))
{
return "application/x-msdownload";
}
throw new InvalidOperationException("Argument not supported: " + path); throw new InvalidOperationException("Argument not supported: " + path);
} }
} }

View File

@ -63,6 +63,28 @@ namespace MediaBrowser.Common.Plugins
} }
} }
/// <summary>
/// Gets the name the assembly file
/// </summary>
public string AssemblyFileName
{
get
{
return GetType().Assembly.GetName().Name + ".dll";
}
}
/// <summary>
/// Gets the path to the assembly file
/// </summary>
public string AssemblyFilePath
{
get
{
return Path.Combine(Kernel.ApplicationPaths.PluginsPath, AssemblyFileName);
}
}
/// <summary> /// <summary>
/// Gets or sets the current plugin configuration /// Gets or sets the current plugin configuration
/// </summary> /// </summary>

View File

@ -23,5 +23,11 @@ namespace MediaBrowser.Model.DTO
[ProtoMember(5)] [ProtoMember(5)]
public string Version { get; set; } public string Version { get; set; }
[ProtoMember(6)]
public string AssemblyFileName { get; set; }
[ProtoMember(7)]
public string ConfigurationFileName { get; set; }
} }
} }

View File

@ -32,5 +32,5 @@ using System.Runtime.InteropServices;
// You can specify all the values or you can default the Build and Revision Numbers // You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below: // by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")] // [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")] [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyFileVersion("1.0.0.0")]