Browse Source

moved Plugins to separate repo

LukePulverenti 12 years ago
parent
commit
746c5d2fa7
54 changed files with 104 additions and 4693 deletions
  1. 5 5
      MediaBrowser.Api/PluginService.cs
  2. 15 15
      MediaBrowser.ApiInteraction.Javascript/ApiClient.js
  3. 1 1
      MediaBrowser.ApiInteraction/ApiClient.cs
  4. 2 2
      MediaBrowser.Common/Plugins/BasePlugin.cs
  5. 1 1
      MediaBrowser.Common/Plugins/IPlugin.cs
  6. 2 2
      MediaBrowser.Controller/Kernel.cs
  7. 1 1
      MediaBrowser.Controller/MediaBrowser.Controller.csproj
  8. 0 81
      MediaBrowser.Controller/Plugins/BaseConfigurationPage.cs
  9. 61 0
      MediaBrowser.Controller/Plugins/IPluginConfigurationPage.cs
  10. 1 1
      MediaBrowser.Model/Plugins/PluginInfo.cs
  11. 0 50
      MediaBrowser.Plugins.Dlna/Configuration/DlnaConfigurationPage.cs
  12. 0 39
      MediaBrowser.Plugins.Dlna/Configuration/PluginConfiguration.cs
  13. 0 92
      MediaBrowser.Plugins.Dlna/Configuration/configPage.html
  14. 0 91
      MediaBrowser.Plugins.Dlna/MediaBrowser.Plugins.Dlna.csproj
  15. 0 1027
      MediaBrowser.Plugins.Dlna/Plugin.cs
  16. 0 35
      MediaBrowser.Plugins.Dlna/Properties/AssemblyInfo.cs
  17. 0 109
      MediaBrowser.Plugins.MpcHc/MediaBrowser.Plugins.MpcHc.csproj
  18. 0 580
      MediaBrowser.Plugins.MpcHc/MpcHcMediaPlayer.cs
  19. 0 32
      MediaBrowser.Plugins.MpcHc/Plugin.cs
  20. 0 53
      MediaBrowser.Plugins.MpcHc/Properties/AssemblyInfo.cs
  21. 0 62
      MediaBrowser.Plugins.MpcHc/Properties/Resources.Designer.cs
  22. 0 117
      MediaBrowser.Plugins.MpcHc/Properties/Resources.resx
  23. 0 30
      MediaBrowser.Plugins.MpcHc/Properties/Settings.Designer.cs
  24. 0 7
      MediaBrowser.Plugins.MpcHc/Properties/Settings.settings
  25. 0 11
      MediaBrowser.Plugins.MpcHc/app.config
  26. 0 108
      MediaBrowser.Plugins.Tmt5/MediaBrowser.Plugins.Tmt5.csproj
  27. 0 32
      MediaBrowser.Plugins.Tmt5/Plugin.cs
  28. 0 53
      MediaBrowser.Plugins.Tmt5/Properties/AssemblyInfo.cs
  29. 0 62
      MediaBrowser.Plugins.Tmt5/Properties/Resources.Designer.cs
  30. 0 117
      MediaBrowser.Plugins.Tmt5/Properties/Resources.resx
  31. 0 30
      MediaBrowser.Plugins.Tmt5/Properties/Settings.Designer.cs
  32. 0 7
      MediaBrowser.Plugins.Tmt5/Properties/Settings.settings
  33. 0 405
      MediaBrowser.Plugins.Tmt5/Tmt5MediaPlayer.cs
  34. 0 11
      MediaBrowser.Plugins.Tmt5/app.config
  35. 0 314
      MediaBrowser.Plugins.Trailers/AppleTrailerListingDownloader.cs
  36. 0 46
      MediaBrowser.Plugins.Trailers/Configuration/PluginConfiguration.cs
  37. 0 50
      MediaBrowser.Plugins.Trailers/Configuration/TrailerConfigurationPage.cs
  38. 0 119
      MediaBrowser.Plugins.Trailers/Configuration/configPage.html
  39. 0 33
      MediaBrowser.Plugins.Trailers/Entities/TrailerCollectionFolder.cs
  40. 0 88
      MediaBrowser.Plugins.Trailers/MediaBrowser.Plugins.Trailers.csproj
  41. 0 119
      MediaBrowser.Plugins.Trailers/Plugin.cs
  42. 0 34
      MediaBrowser.Plugins.Trailers/Properties/AssemblyInfo.cs
  43. 0 143
      MediaBrowser.Plugins.Trailers/Providers/TrailerFromJsonProvider.cs
  44. 0 51
      MediaBrowser.Plugins.Trailers/Resolvers/TrailerResolver.cs
  45. 0 311
      MediaBrowser.Plugins.Trailers/ScheduledTasks/CurrentTrailerDownloadTask.cs
  46. 0 45
      MediaBrowser.Plugins.Trailers/TrailerInfo.cs
  47. 0 24
      MediaBrowser.UI.sln
  48. 1 1
      MediaBrowser.UI/Controller/PluginUpdater.cs
  49. 3 2
      MediaBrowser.UI/MediaBrowser.UI.csproj
  50. 3 4
      MediaBrowser.WebDashboard/Api/DashboardService.cs
  51. 4 4
      MediaBrowser.WebDashboard/Html/scripts/PluginUpdatesPage.js
  52. 3 3
      MediaBrowser.WebDashboard/Html/scripts/PluginsPage.js
  53. 0 33
      MediaBrowser.sln
  54. 1 0
      Nuget/MediaBrowser.Server.Core.nupkg.REMOVED.git-id

+ 5 - 5
MediaBrowser.Api/PluginService.cs

@@ -141,7 +141,7 @@ namespace MediaBrowser.Api
         /// <returns>System.Object.</returns>
         public object Get(GetPluginAssembly request)
         {
-            var plugin = Kernel.Plugins.First(p => p.UniqueId == request.Id);
+            var plugin = Kernel.Plugins.First(p => p.Id == request.Id);
 
             return ToStaticFileResult(plugin.AssemblyFilePath);
         }
@@ -153,7 +153,7 @@ namespace MediaBrowser.Api
         /// <returns>System.Object.</returns>
         public object Get(GetPluginConfiguration request)
         {
-            var plugin = Kernel.Plugins.First(p => p.UniqueId == request.Id);
+            var plugin = Kernel.Plugins.First(p => p.Id == request.Id);
 
             var dateModified = plugin.ConfigurationDateLastModified;
 
@@ -169,7 +169,7 @@ namespace MediaBrowser.Api
         /// <returns>System.Object.</returns>
         public object Get(GetPluginConfigurationFile request)
         {
-            var plugin = Kernel.Plugins.First(p => p.UniqueId == request.Id);
+            var plugin = Kernel.Plugins.First(p => p.Id == request.Id);
 
             return ToStaticFileResult(plugin.ConfigurationFilePath);
         }
@@ -218,7 +218,7 @@ namespace MediaBrowser.Api
             var pathInfo = PathInfo.Parse(Request.PathInfo);
             var id = new Guid(pathInfo.GetArgumentValue<string>(1));
 
-            var plugin = Kernel.Plugins.First(p => p.UniqueId == id);
+            var plugin = Kernel.Plugins.First(p => p.Id == id);
 
             var configuration = JsonSerializer.DeserializeFromStream(request.RequestStream, plugin.ConfigurationType) as BasePluginConfiguration;
 
@@ -233,7 +233,7 @@ namespace MediaBrowser.Api
         {
             var kernel = (Kernel)Kernel;
 
-            var plugin = kernel.Plugins.First(p => p.UniqueId == request.Id);
+            var plugin = kernel.Plugins.First(p => p.Id == request.Id);
 
             kernel.InstallationManager.UninstallPlugin(plugin);
         }

+ 15 - 15
MediaBrowser.ApiInteraction.Javascript/ApiClient.js

@@ -382,15 +382,15 @@ var ApiClient = {
 
     /**
      * Gets the configuration of a plugin
-     * @param {String} uniqueId
+     * @param {String} Id
      */
-    getPluginConfiguration: function (uniqueId) {
+    getPluginConfiguration: function (id) {
 
-        if (!uniqueId) {
-            throw new Error("null uniqueId");
+        if (!id) {
+            throw new Error("null Id");
         }
 
-        var url = ApiClient.getUrl("Plugins/" + uniqueId + "/Configuration");
+        var url = ApiClient.getUrl("Plugins/" + id + "/Configuration");
 
         return $.getJSON(url);
     },
@@ -407,15 +407,15 @@ var ApiClient = {
 
     /**
      * Uninstalls a plugin
-     * @param {String} uniqueId
+     * @param {String} Id
      */
-    uninstallPlugin: function (uniqueId) {
+    uninstallPlugin: function (id) {
 
-        if (!uniqueId) {
-            throw new Error("null uniqueId");
+        if (!id) {
+            throw new Error("null Id");
         }
 
-        var url = ApiClient.getUrl("Plugins/" + uniqueId);
+        var url = ApiClient.getUrl("Plugins/" + id);
 
         return $.ajax({
             type: "DELETE",
@@ -1207,20 +1207,20 @@ var ApiClient = {
 
     /**
      * Updates a plugin's configuration
-     * @param {String} uniqueId
+     * @param {String} Id
      * @param {Object} configuration
      */
-    updatePluginConfiguration: function (uniqueId, configuration) {
+    updatePluginConfiguration: function (id, configuration) {
 
-        if (!uniqueId) {
-            throw new Error("null uniqueId");
+        if (!id) {
+            throw new Error("null Id");
         }
 
         if (!configuration) {
             throw new Error("null configuration");
         }
 
-        var url = ApiClient.getUrl("Plugins/" + uniqueId + "/Configuration");
+        var url = ApiClient.getUrl("Plugins/" + id + "/Configuration");
 
         return $.post(url, JSON.stringify(configuration));
     },

+ 1 - 1
MediaBrowser.ApiInteraction/ApiClient.cs

@@ -362,7 +362,7 @@ namespace MediaBrowser.ApiInteraction
                 throw new ArgumentNullException("plugin");
             }
 
-            var url = GetApiUrl("Plugins/" + plugin.UniqueId + "/Assembly");
+            var url = GetApiUrl("Plugins/" + plugin.Id + "/Assembly");
 
             return HttpClient.GetStreamAsync(url, Logger, CancellationToken.None);
         }

+ 2 - 2
MediaBrowser.Common/Plugins/BasePlugin.cs

@@ -90,7 +90,7 @@ namespace MediaBrowser.Common.Plugins
         /// Gets the unique id.
         /// </summary>
         /// <value>The unique id.</value>
-        public Guid UniqueId
+        public Guid Id
         {
             get
             {
@@ -419,7 +419,7 @@ namespace MediaBrowser.Common.Plugins
                 ConfigurationDateLastModified = ConfigurationDateLastModified,
                 Description = Description,
                 IsCorePlugin = IsCorePlugin,
-                UniqueId = UniqueId,
+                Id = Id,
                 EnableAutoUpdate = Configuration.EnableAutoUpdate,
                 UpdateClass = Configuration.UpdateClass,
                 ConfigurationFileName = ConfigurationFileName

+ 1 - 1
MediaBrowser.Common/Plugins/IPlugin.cs

@@ -35,7 +35,7 @@ namespace MediaBrowser.Common.Plugins
         /// Gets the unique id.
         /// </summary>
         /// <value>The unique id.</value>
-        Guid UniqueId { get; }
+        Guid Id { get; }
 
         /// <summary>
         /// Gets the plugin version

+ 2 - 2
MediaBrowser.Controller/Kernel.cs

@@ -182,8 +182,8 @@ namespace MediaBrowser.Controller
         /// Gets the list of plugin configuration pages
         /// </summary>
         /// <value>The configuration pages.</value>
-        [ImportMany(typeof(BaseConfigurationPage))]
-        public IEnumerable<BaseConfigurationPage> PluginConfigurationPages { get; private set; }
+        [ImportMany(typeof(IPluginConfigurationPage))]
+        public IEnumerable<IPluginConfigurationPage> PluginConfigurationPages { get; private set; }
 
         /// <summary>
         /// Gets the intro providers.

+ 1 - 1
MediaBrowser.Controller/MediaBrowser.Controller.csproj

@@ -128,7 +128,7 @@
     <Compile Include="Persistence\IUserRepository.cs" />
     <Compile Include="Persistence\TypeMapper.cs" />
     <Compile Include="Playback\IIntroProvider.cs" />
-    <Compile Include="Plugins\BaseConfigurationPage.cs" />
+    <Compile Include="Plugins\IPluginConfigurationPage.cs" />
     <Compile Include="Plugins\PluginSecurityManager.cs" />
     <Compile Include="Providers\FanartBaseProvider.cs" />
     <Compile Include="Providers\BaseImageEnhancer.cs" />

+ 0 - 81
MediaBrowser.Controller/Plugins/BaseConfigurationPage.cs

@@ -1,81 +0,0 @@
-using MediaBrowser.Common.Plugins;
-using System.IO;
-
-namespace MediaBrowser.Controller.Plugins
-{
-    /// <summary>
-    /// Class BaseConfigurationPage
-    /// </summary>
-    public abstract class BaseConfigurationPage
-    {
-        /// <summary>
-        /// Gets the name.
-        /// </summary>
-        /// <value>The name.</value>
-        public abstract string Name { get; }
-
-        /// <summary>
-        /// Gets the description.
-        /// </summary>
-        /// <value>The description.</value>
-        public virtual string Description
-        {
-            get { return string.Empty; }
-        }
-
-        /// <summary>
-        /// Gets the type of the configuration page.
-        /// </summary>
-        /// <value>The type of the configuration page.</value>
-        public virtual ConfigurationPageType ConfigurationPageType
-        {
-            get { return ConfigurationPageType.PluginConfiguration; }
-        }
-
-        /// <summary>
-        /// Gets the HTML stream from manifest resource.
-        /// </summary>
-        /// <param name="resource">The resource.</param>
-        /// <returns>Stream.</returns>
-        protected Stream GetHtmlStreamFromManifestResource(string resource)
-        {
-            return GetType().Assembly.GetManifestResourceStream(resource);
-        }
-
-        /// <summary>
-        /// Gets the HTML stream.
-        /// </summary>
-        /// <returns>Stream.</returns>
-        public abstract Stream GetHtmlStream();
-
-        /// <summary>
-        /// Gets the name of the plugin.
-        /// </summary>
-        /// <value>The name of the plugin.</value>
-        public virtual string OwnerPluginName
-        {
-            get { return GetOwnerPlugin().Name; }
-        }
-        
-        /// <summary>
-        /// Gets the owner plugin.
-        /// </summary>
-        /// <returns>BasePlugin.</returns>
-        public abstract IPlugin GetOwnerPlugin();
-    }
-
-    /// <summary>
-    /// Enum ConfigurationPageType
-    /// </summary>
-    public enum ConfigurationPageType
-    {
-        /// <summary>
-        /// The plugin configuration
-        /// </summary>
-        PluginConfiguration,
-        /// <summary>
-        /// The none
-        /// </summary>
-        None
-    }
-}

+ 61 - 0
MediaBrowser.Controller/Plugins/IPluginConfigurationPage.cs

@@ -0,0 +1,61 @@
+using System;
+using System.IO;
+
+namespace MediaBrowser.Controller.Plugins
+{
+    /// <summary>
+    /// Interface IConfigurationPage
+    /// </summary>
+    public interface IPluginConfigurationPage
+    {
+        /// <summary>
+        /// Gets the name.
+        /// </summary>
+        /// <value>The name.</value>
+        string Name { get; }
+
+        /// <summary>
+        /// Gets the type of the configuration page.
+        /// </summary>
+        /// <value>The type of the configuration page.</value>
+        ConfigurationPageType ConfigurationPageType { get; }
+
+        /// <summary>
+        /// Gets the plugin id.
+        /// </summary>
+        /// <value>The plugin id.</value>
+        Guid? PluginId { get; }
+
+        /// <summary>
+        /// Gets the HTML stream.
+        /// </summary>
+        /// <returns>Stream.</returns>
+        Stream GetHtmlStream();
+
+        /// <summary>
+        /// Gets the version. Typically taken from Plugin.Version
+        /// </summary>
+        /// <value>The version.</value>
+        string Version { get; }
+
+        /// <summary>
+        /// For http caching purposes. Typically taken from Plugin.AssemblyDateLastModified
+        /// </summary>
+        DateTime DateLastModified { get; }
+    }
+
+    /// <summary>
+    /// Enum ConfigurationPageType
+    /// </summary>
+    public enum ConfigurationPageType
+    {
+        /// <summary>
+        /// The plugin configuration
+        /// </summary>
+        PluginConfiguration,
+        /// <summary>
+        /// The none
+        /// </summary>
+        None
+    }
+}

+ 1 - 1
MediaBrowser.Model/Plugins/PluginInfo.cs

@@ -71,7 +71,7 @@ namespace MediaBrowser.Model.Plugins
         /// </summary>
         /// <value>The unique id.</value>
         [ProtoMember(9)]
-        public Guid UniqueId { get; set; }
+        public Guid Id { get; set; }
 
         /// <summary>
         /// Whether or not this plug-in should be automatically updated when a

+ 0 - 50
MediaBrowser.Plugins.Dlna/Configuration/DlnaConfigurationPage.cs

@@ -1,50 +0,0 @@
-using MediaBrowser.Common.Plugins;
-using MediaBrowser.Controller.Plugins;
-using System.ComponentModel.Composition;
-using System.IO;
-
-namespace MediaBrowser.Plugins.Dlna.Configuration
-{
-    /// <summary>
-    /// Class DlnaConfigurationPage
-    /// </summary>
-    [Export(typeof(BaseConfigurationPage))]
-    class DlnaConfigurationPage : BaseConfigurationPage
-    {
-        /// <summary>
-        /// Gets the name.
-        /// </summary>
-        /// <value>The name.</value>
-        public override string Name
-        {
-            get { return "Dlna"; }
-        }
-
-        /// <summary>
-        /// Gets the HTML stream.
-        /// </summary>
-        /// <returns>Stream.</returns>
-        public override Stream GetHtmlStream()
-        {
-            return GetHtmlStreamFromManifestResource("MediaBrowser.Plugins.Dlna.Configuration.configPage.html");
-        }
-
-        /// <summary>
-        /// Gets the owner plugin.
-        /// </summary>
-        /// <returns>BasePlugin.</returns>
-        public override IPlugin GetOwnerPlugin()
-        {
-            return Plugin.Instance;
-        }
-
-        /// <summary>
-        /// Gets the type of the configuration page.
-        /// </summary>
-        /// <value>The type of the configuration page.</value>
-        public override ConfigurationPageType ConfigurationPageType
-        {
-            get { return ConfigurationPageType.PluginConfiguration; }
-        }
-    }
-}

+ 0 - 39
MediaBrowser.Plugins.Dlna/Configuration/PluginConfiguration.cs

@@ -1,39 +0,0 @@
-using MediaBrowser.Model.Plugins;
-
-namespace MediaBrowser.Plugins.Dlna.Configuration
-{
-    /// <summary>
-    /// Class PluginConfiguration
-    /// </summary>
-    public class PluginConfiguration : BasePluginConfiguration
-    {
-        /// <summary>
-        /// Gets or sets the friendly name of the DLNA Server.
-        /// </summary>
-        /// <value>The friendly name of the DLNA Server.</value>
-        public string FriendlyDlnaName { get; set; }
-
-        /// <summary>
-        /// Gets or sets the Port Number for the DLNA Server.
-        /// </summary>
-        /// <value>The Port Number of the DLNA Server.</value>
-        public short? DlnaPortNumber { get; set; }
-
-        /// <summary>
-        /// Gets or sets the name of the user to impersonate.
-        /// </summary>
-        /// <value>The name of the User.</value>
-        public string UserName { get; set; }
-
-        /// <summary>
-        /// Initializes a new instance of the <see cref="PluginConfiguration" /> class.
-        /// </summary>
-        public PluginConfiguration()
-            : base()
-        {
-            //this.DlnaPortNumber = 1845;
-            this.FriendlyDlnaName = "MB3 UPnP";
-            this.UserName = string.Empty;
-        }
-    }
-}

+ 0 - 92
MediaBrowser.Plugins.Dlna/Configuration/configPage.html

@@ -1,92 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-    <title>dlna</title>
-</head>
-<body>
-    <div id="dlnaConfigurationPage" data-role="page" class="page type-interior pluginConfigurationPage">
-
-        <div data-role="content">
-            <div class="content-primary">
-                <form id="dlnaConfigurationForm">
-
-                    <ul class="ulForm" data-role="listview">
-                        <li>
-                            <label for="txtUserName">
-                                User name:
-                            </label>
-                            <input id="txtUserName" name="txtUserName" />
-                        </li>
-                        <li>
-                            <label for="txtFriendlyDlnaName">
-                                Friendly Dlna Server Name:
-                            </label>
-                            <input id="txtFriendlyDlnaName" name="txtFriendlyDlnaName" />
-                        </li>                        
-                        <li>
-                            <label for="txtDlnaPortNumber">
-                                Dlna Server Port:
-                            </label>
-                            <input type="number" id="txtDlnaPortNumber" name="txtDlnaPortNumber" pattern="[0-9]*" min="1" />
-                            <div class="fieldDescription">
-                                If specified, the Dlna server will use this port
-                            </div>
-                        </li>
-                        <li>
-                            <button type="submit" data-theme="b">Save</button>
-                            <div class="fieldDescription">
-                                Saving will restart the dlna server.
-                            </div>
-                            <button type="button" onclick="history.back();">Cancel</button>
-                        </li>
-                    </ul>
-
-                </form>
-            </div>
-        </div>
-
-        <script type="text/javascript">
-
-            var dlnaConfigurationPage = {
-                pluginUniqueId: "f1855371-7cf5-40d2-bcd8-b780d7f006af"
-            };
-
-            $('#dlnaConfigurationPage').on('pageshow', function (event) {
-
-                Dashboard.showLoadingMsg();
-
-                var page = this;
-
-                ApiClient.getPluginConfiguration(dlnaConfigurationPage.pluginUniqueId).done(function (config) {
-
-                    $('#txtUserName', page).val(config.UserName);
-                    $('#txtFriendlyDlnaName', page).val(config.FriendlyDlnaName);
-                    $('#txtDlnaPortNumber', page).val(config.DlnaPortNumber || "");
-
-                    Dashboard.hideLoadingMsg();
-                });
-            });
-
-            $('#dlnaConfigurationForm').on('submit', function (e) {
-
-                Dashboard.showLoadingMsg();
-
-                var form = this;
-
-                ApiClient.getPluginConfiguration(dlnaConfigurationPage.pluginUniqueId).done(function (config) {
-
-                    config.UserName = $('#txtUserName', form).val();
-                    config.FriendlyDlnaName = $('#txtFriendlyDlnaName', form).val();
-                    var dlnaPortNumber = $('#txtDlnaPortNumber', form).val();
-                    config.DlnaPortNumber = dlnaPortNumber ? dlnaPortNumber : null;
-
-                    ApiClient.updatePluginConfiguration(dlnaConfigurationPage.pluginUniqueId, config).done(Dashboard.processPluginConfigurationUpdateResult);
-                });
-
-                // Disable default form submission
-                return false;
-            });
-        </script>
-    </div>
-</body>
-</html>

+ 0 - 91
MediaBrowser.Plugins.Dlna/MediaBrowser.Plugins.Dlna.csproj

@@ -1,91 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
-  <PropertyGroup>
-    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
-    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
-    <ProjectGuid>{A2CF4266-2110-419E-8620-E2FEEFCA0F48}</ProjectGuid>
-    <OutputType>Library</OutputType>
-    <AppDesignerFolder>Properties</AppDesignerFolder>
-    <RootNamespace>MediaBrowser.Plugins.Dlna</RootNamespace>
-    <AssemblyName>MediaBrowser.Plugins.Dlna</AssemblyName>
-    <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
-    <FileAlignment>512</FileAlignment>
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
-    <DebugSymbols>true</DebugSymbols>
-    <DebugType>full</DebugType>
-    <Optimize>false</Optimize>
-    <OutputPath>bin\Debug\</OutputPath>
-    <DefineConstants>DEBUG;TRACE</DefineConstants>
-    <ErrorReport>prompt</ErrorReport>
-    <WarningLevel>4</WarningLevel>
-    <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
-    <DebugType>pdbonly</DebugType>
-    <Optimize>true</Optimize>
-    <OutputPath>bin\Release\</OutputPath>
-    <DefineConstants>TRACE</DefineConstants>
-    <ErrorReport>prompt</ErrorReport>
-    <WarningLevel>4</WarningLevel>
-  </PropertyGroup>
-  <PropertyGroup>
-    <RunPostBuildEvent>Always</RunPostBuildEvent>
-  </PropertyGroup>
-  <ItemGroup>
-    <Reference Include="Platinum.Managed">
-      <HintPath>..\ThirdParty\UPnP\Libs\Platinum.Managed.dll</HintPath>
-    </Reference>
-    <Reference Include="System" />
-    <Reference Include="System.ComponentModel.Composition" />
-    <Reference Include="System.Core" />
-    <Reference Include="System.Xml.Linq" />
-    <Reference Include="System.Data.DataSetExtensions" />
-    <Reference Include="Microsoft.CSharp" />
-    <Reference Include="System.Data" />
-    <Reference Include="System.Xml" />
-  </ItemGroup>
-  <ItemGroup>
-    <Compile Include="Configuration\DlnaConfigurationPage.cs" />
-    <Compile Include="Configuration\PluginConfiguration.cs" />
-    <Compile Include="Plugin.cs" />
-    <Compile Include="Properties\AssemblyInfo.cs" />
-  </ItemGroup>
-  <ItemGroup>
-    <ProjectReference Include="..\MediaBrowser.Common\MediaBrowser.Common.csproj">
-      <Project>{9142eefa-7570-41e1-bfcc-468bb571af2f}</Project>
-      <Name>MediaBrowser.Common</Name>
-    </ProjectReference>
-    <ProjectReference Include="..\MediaBrowser.Controller\MediaBrowser.Controller.csproj">
-      <Project>{17e1f4e6-8abd-4fe5-9ecf-43d4b6087ba2}</Project>
-      <Name>MediaBrowser.Controller</Name>
-    </ProjectReference>
-    <ProjectReference Include="..\MediaBrowser.Model\MediaBrowser.Model.csproj">
-      <Project>{7eeeb4bb-f3e8-48fc-b4c5-70f0fff8329b}</Project>
-      <Name>MediaBrowser.Model</Name>
-    </ProjectReference>
-  </ItemGroup>
-  <ItemGroup>
-    <EmbeddedResource Include="..\ThirdParty\UPnP\Libs\Platinum.Managed.dll">
-      <Link>Assemblies\Platinum.Managed.dll</Link>
-    </EmbeddedResource>
-  </ItemGroup>
-  <ItemGroup>
-    <Content Include="..\ThirdParty\UPnP\Libs\log4net.dll">
-      <Link>Assemblies\log4net.dll</Link>
-    </Content>
-    <EmbeddedResource Include="Configuration\configPage.html" />
-  </ItemGroup>
-  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
-  <PropertyGroup>
-    <PostBuildEvent>xcopy "$(TargetPath)" "$(SolutionDir)\ProgramData-Server\Plugins\" /y</PostBuildEvent>
-  </PropertyGroup>
-  <!-- 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">
-  </Target>
-  <Target Name="AfterBuild">
-  </Target>
-  -->
-</Project>

+ 0 - 1027
MediaBrowser.Plugins.Dlna/Plugin.cs

@@ -1,1027 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.ComponentModel.Composition;
-using System.IO;
-using System.Linq;
-using System.Reflection;
-using MediaBrowser.Common.Extensions;
-using MediaBrowser.Common.Net;
-using MediaBrowser.Common.Plugins;
-using MediaBrowser.Controller.Entities;
-using MediaBrowser.Controller.Entities.Audio;
-using MediaBrowser.Controller.Entities.TV;
-using MediaBrowser.Model.Entities;
-using MediaBrowser.Plugins.Dlna.Configuration;
-
-namespace MediaBrowser.Plugins.Dlna
-{
-    /// <summary>
-    /// Class Plugin
-    /// </summary>
-    [Export(typeof(IPlugin))]
-    public class Plugin : BasePlugin<PluginConfiguration>
-    {
-        //these are Neptune values, they probably belong in the managed wrapper somewhere, but they aren't
-        //techincally theres 50 to 100 of these values, but these 3 seem to be the most useful
-        private const int NEP_Failure = -1;
-        private const int NEP_NotImplemented = -2012;
-        private const int NEP_Success = 0;
-
-        private Platinum.UPnP _Upnp;
-        private Platinum.MediaConnect _PlatinumServer;
-        private User _CurrentUser;
-
-
-        /// <summary>
-        /// Gets the name.
-        /// </summary>
-        /// <value>The name.</value>
-        public override string Name
-        {
-            get { return "DLNA Server"; }
-        }
-
-        /// <summary>
-        /// Gets the description.
-        /// </summary>
-        /// <value>The description.</value>
-        public override string Description
-        {
-            get { return "DLNA Server"; }
-        }
-
-        /// <summary>
-        /// Gets the instance.
-        /// </summary>
-        /// <value>The instance.</value>
-        public static Plugin Instance { get; private set; }
-
-        /// <summary>
-        /// Initializes a new instance of the <see cref="Plugin" /> class.
-        /// </summary>
-        public Plugin()
-            : base()
-        {
-            Instance = this;
-        }
-
-        /// <summary>
-        /// Initializes the on server.
-        /// </summary>
-        /// <param name="isFirstRun">if set to <c>true</c> [is first run].</param>
-        protected override void InitializeOnServer(bool isFirstRun)
-        {
-            base.InitializeOnServer(isFirstRun);
-
-            Kernel.ReloadCompleted += Kernel_ReloadCompleted;
-            AppDomain.CurrentDomain.AssemblyResolve += CurrentDomain_AssemblyResolve;
-
-        }
-
-        /// <summary>
-        /// Handles the AssemblyResolve event of the CurrentDomain control.
-        /// </summary>
-        /// <param name="sender">The source of the event.</param>
-        /// <param name="args">The <see cref="ResolveEventArgs" /> instance containing the event data.</param>
-        /// <returns>Assembly.</returns>
-        Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
-        {
-            var askedAssembly = new AssemblyName(args.Name);
-
-            var resourcePath = "MediaBrowser.Plugins.Dlna.Assemblies." + askedAssembly.Name + ".dll";
-
-            using (var stream = GetType().Assembly.GetManifestResourceStream(resourcePath))
-            {
-                if (stream != null)
-                {
-                    Logger.Info("Loading assembly from resource {0}", resourcePath);
-
-                    using (var memoryStream = new MemoryStream())
-                    {
-                        stream.CopyTo(memoryStream);
-
-                        memoryStream.Position = 0;
-
-                        return Assembly.Load(memoryStream.ToArray());
-                    }
-                }
-            }
-
-            return null;
-        }
-
-        /// <summary>
-        /// Disposes the on server.
-        /// </summary>
-        /// <param name="dispose">if set to <c>true</c> [dispose].</param>
-        protected override void DisposeOnServer(bool dispose)
-        {
-            if (dispose)
-            {
-                Kernel.ReloadCompleted -= Kernel_ReloadCompleted;
-                AppDomain.CurrentDomain.AssemblyResolve -= CurrentDomain_AssemblyResolve;
-                DisposeDlnaServer();
-            }
-
-            base.DisposeOnServer(dispose);
-        }
-
-        /// <summary>
-        /// Handles the ReloadCompleted 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_ReloadCompleted(object sender, EventArgs e)
-        {
-            InitializeDlnaServer();
-        }
-
-        /// <summary>
-        /// Initializes the dlna server.
-        /// </summary>
-        private void InitializeDlnaServer()
-        {
-            this.SetupUPnPServer();
-        }
-
-        /// <summary>
-        /// Disposes the dlna server.
-        /// </summary>
-        private void DisposeDlnaServer()
-        {
-            this.CleanupUPnPServer();
-        }
-
-        private void SetupUPnPServer()
-        {
-
-            this._Upnp = new Platinum.UPnP();
-            // Will need a config setting to set the friendly name of the upnp server
-            //this._PlatinumServer = new Platinum.MediaConnect("MB3 UPnP", "MB3UPnP", 1901);
-            if (this.Configuration.DlnaPortNumber.HasValue)
-                this._PlatinumServer = new Platinum.MediaConnect(this.Configuration.FriendlyDlnaName, "MB3UPnP", this.Configuration.DlnaPortNumber.Value);
-            else
-                this._PlatinumServer = new Platinum.MediaConnect(this.Configuration.FriendlyDlnaName);
-
-            this._PlatinumServer.BrowseMetadata += new Platinum.MediaConnect.BrowseMetadataDelegate(server_BrowseMetadata);
-            this._PlatinumServer.BrowseDirectChildren += new Platinum.MediaConnect.BrowseDirectChildrenDelegate(server_BrowseDirectChildren);
-            this._PlatinumServer.ProcessFileRequest += new Platinum.MediaConnect.ProcessFileRequestDelegate(server_ProcessFileRequest);
-            this._PlatinumServer.SearchContainer += new Platinum.MediaConnect.SearchContainerDelegate(server_SearchContainer);
-
-            this._Upnp.AddDeviceHost(this._PlatinumServer);
-            this._Upnp.Start();
-        }
-
-        private void CleanupUPnPServer()
-        {
-            if (this._Upnp != null && this._Upnp.Running)
-                this._Upnp.Stop();
-
-            if (this._PlatinumServer != null)
-            {
-                this._PlatinumServer.BrowseMetadata -= new Platinum.MediaConnect.BrowseMetadataDelegate(server_BrowseMetadata);
-                this._PlatinumServer.BrowseDirectChildren -= new Platinum.MediaConnect.BrowseDirectChildrenDelegate(server_BrowseDirectChildren);
-                this._PlatinumServer.ProcessFileRequest -= new Platinum.MediaConnect.ProcessFileRequestDelegate(server_ProcessFileRequest);
-                this._PlatinumServer.SearchContainer -= new Platinum.MediaConnect.SearchContainerDelegate(server_SearchContainer);
-
-                this._PlatinumServer.Dispose();
-                this._PlatinumServer = null;
-            }
-
-            if (this._Upnp != null)
-            {
-                this._Upnp.Dispose();
-                this._Upnp = null;
-            }
-        }
-
-        private int server_BrowseMetadata(Platinum.Action action, string object_id, string filter, int starting_index, int requested_count, string sort_criteria, Platinum.HttpRequestContext context)
-        {
-            Logger.Info("BrowseMetadata Entered - Parameters: action:{0} object_id:{1} filter:{2} starting_index:{3} requested_count:{4} sort_criteria:{5} context:{6}",
-                action.ToLogString(), object_id, filter, starting_index, requested_count, sort_criteria, context.ToLogString());
-
-            //nothing much seems to call BrowseMetadata so far
-            //but perhaps that is because we aren't handing out the correct info for the client to call this... I don't know
-
-            //PS3 calls it
-            //Parameters: action:Action Name:Browse Description:Platinum.ActionDescription Arguments: object_id:0 
-            //filter:@id,upnp:class,res,res@protocolInfo,res@av:authenticationUri,res@size,dc:title,upnp:albumArtURI,res@dlna:ifoFileURI,res@protection,res@bitrate,res@duration,res@sampleFrequency,res@bitsPerSample,res@nrAudioChannels,res@resolution,res@colorDepth,dc:date,av:dateTime,upnp:artist,upnp:album,upnp:genre,dc:contributer,upnp:storageFree,upnp:storageUsed,upnp:originalTrackNumber,dc:publisher,dc:language,dc:region,dc:description,upnp:toc,@childCount,upnp:albumArtURI@dlna:profileID,res@dlna:cleartextSize 
-            //starting_index:0 requested_count:1 sort_criteria: context:HttpRequestContext LocalAddress:HttpRequestContext.SocketAddress IP:192.168.1.56 Port:1845 RemoteAddress:HttpRequestContext.SocketAddress IP:192.168.1.40 Port:49277 Request:http://192.168.1.56:1845/ContentDirectory/7c6b1b90-872b-2cda-3c5c-21a0e430ce5e/control.xml Signature:PS3
-
-
-
-            if (object_id == "0")
-            {
-                var root = new Platinum.MediaContainer();
-                root.Title = "Root";
-                root.ObjectID = "0";
-                root.ParentID = "-1";
-                root.Class = new Platinum.ObjectClass("object.container.storageFolder", "");
-
-                var didl = Platinum.Didl.header + root.ToDidl(filter) + Platinum.Didl.footer;
-                action.SetArgumentValue("Result", didl);
-                action.SetArgumentValue("NumberReturned", "1");
-                action.SetArgumentValue("TotalMatches", "1");
-
-                // update ID may be wrong here, it should be the one of the container?
-                action.SetArgumentValue("UpdateId", "1");
-
-                return NEP_Success;
-            }
-            else
-            {
-                return NEP_Failure;
-            }
-        }
-        private int server_BrowseDirectChildren(Platinum.Action action, String object_id, String filter, Int32 starting_index, Int32 requested_count, String sort_criteria, Platinum.HttpRequestContext context)
-        {
-            Logger.Info("BrowseDirectChildren Entered - Parameters: action:{0} object_id:{1} filter:{2} starting_index:{3} requested_count:{4} sort_criteria:{5} context:{6}",
-                action.ToLogString(), object_id, filter, starting_index, requested_count, sort_criteria, context.ToLogString());
-
-            //WMP doesn't care how many results we return and what type they are
-            //Xbox360 Music App is unknown, it calls SearchContainer and stops, not sure what will happen once we return it results
-            //XBox360 Video App has fairly specific filter string and it need it - if you serve it music (mp3), it'll put music in the video list, so we have to do our own filtering
-
-            //XBox360 Video App
-            //  action: "Browse"
-            //  object_id: "15"
-            //  filter: "dc:title,res,res@protection,res@duration,res@bitrate,upnp:genre,upnp:actor,res@microsoft:codec"
-            //  starting_index: 0
-            //  requested_count: 100
-            //  sort_criteria: "+upnp:class,+dc:title"
-            //
-            //the wierd thing about the filter is that there isn't much in it that says "only give me video"... except...
-            //if we look at the doc available here: http://msdn.microsoft.com/en-us/library/windows/hardware/gg487545.aspx which describes the way WMP does its DLNA serving (not clienting)
-            //doc is also a search cached google docs here: https://docs.google.com/viewer?a=v&q=cache:tnrdpTFCc84J:download.microsoft.com/download/0/0/b/00bba048-35e6-4e5b-a3dc-36da83cbb0d1/NetCompat_WMP11.docx+&hl=en&gl=au&pid=bl&srcid=ADGEESiBSKE1ZJeWmgYVOkKmRJuYaSL3_50KL1o6Ugp28JL1Ytq-2QbEeu6xFD8rbWcX35ZG4d7qPQnzqURGR5vig79S2Arj5umQNPnLeJo1k5_iWYbqPejeMHwwAv0ATmq2ynoZCBNL&sig=AHIEtbQ2qZJ8xMXLZYBWHHerezzXShKoVg
-            //it describes object 15 as beeing Root/Video/Folders which can contain object.storageFolder
-            //so perhaps thats what is saying 'only give me video'
-            //I'm just not sure if those folders listed with object IDs are all well known across clients or if these ones are WMP specific
-            //if they are device specific but also significant, then that might explain why Plex goes to the trouble of having configurable client device profiles for its DLNA server
-
-            var didl = Platinum.Didl.header;
-
-            IEnumerable<BaseItem> children = null;
-
-            // I need to ask someone on the MB team if there's a better way to do this, it seems like it 
-            //could get pretty expensive to get ALL children all the time
-            //if it's our only option perhaps we should cache results locally or something similar
-            children = this.CurrentUser.RootFolder.GetRecursiveChildren(this.CurrentUser);
-            //children = children.Filter(Extensions.FilterType.Music | Extensions.FilterType.Video).Page(starting_index, requested_count);
-
-            int itemCount = 0;
-
-            if (children != null)
-            {
-                foreach (var child in children)
-                {
-                    
-                    using (var item = BaseItemToMediaItem(child, context))
-                    {
-                        if (item != null)
-                        {
-                            string test;
-                            test = item.ToDidl(filter);
-                            didl += item.ToDidl(filter);
-                            itemCount++;
-                        }
-                    }
-                }
-
-                didl += Platinum.Didl.footer;
-                
-                action.SetArgumentValue("Result", didl);
-                action.SetArgumentValue("NumberReturned", itemCount.ToString());
-                action.SetArgumentValue("TotalMatches", itemCount.ToString());
-
-                // update ID may be wrong here, it should be the one of the container?
-                action.SetArgumentValue("UpdateId", "1");
-
-                return NEP_Success;
-            }
-            return NEP_Failure;
-        }
-        private int server_ProcessFileRequest(Platinum.HttpRequestContext context, Platinum.HttpResponse response)
-        {
-            Logger.Info("ProcessFileRequest Entered - Parameters: context:{0} response:{1}",
-                context.ToLogString(), response);
-
-            Uri uri = context.Request.URI;
-            var id = uri.AbsolutePath.TrimStart('/');
-            Guid itemID;
-            if (Guid.TryParseExact(id, "D", out itemID))
-            {
-                var item = this.CurrentUser.RootFolder.FindItemById(itemID, this.CurrentUser);
-
-                if (item != null)
-                {
-                    //this is how the Xbox 360 Video app asks for artwork, it tacks this query string onto its request
-                    //?albumArt=true
-                    if (uri.Query == "?albumArt=true")
-                    {
-                        if (!string.IsNullOrWhiteSpace(item.PrimaryImagePath))
-                            //let see if we can serve artwork like this to the Xbox 360 Video App
-                            Platinum.MediaServer.SetResponseFilePath(context, response, Kernel.HttpServerUrlPrefix.Replace("+", context.LocalAddress.ip) + "/api/image?id=" + item.Id.ToString() + "&type=primary");
-                        //Platinum.MediaServer.SetResponseFilePath(context, response, item.PrimaryImagePath);
-                    }
-                    else
-                        Platinum.MediaServer.SetResponseFilePath(context, response, item.Path);
-                    //this does not work for WMP
-                    //Platinum.MediaServer.SetResponseFilePath(context, response, Kernel.HttpServerUrlPrefix.Replace("+", context.LocalAddress.ip) + "/api/video.ts?id=" + item.Id.ToString());
-
-                    return NEP_Success;
-                }
-            }
-            return NEP_Failure;
-        }
-        private int server_SearchContainer(Platinum.Action action, string object_id, string searchCriteria, string filter, int starting_index, int requested_count, string sort_criteria, Platinum.HttpRequestContext context)
-        {
-            Logger.Info("SearchContainer Entered - Parameters: action:{0} object_id:{1} searchCriteria:{7} filter:{2} starting_index:{3} requested_count:{4} sort_criteria:{5} context:{6}",
-                action.ToLogString(), object_id, filter, starting_index, requested_count, sort_criteria, context.ToLogString(), searchCriteria);
-
-            //Doesn't call search at all:
-            //  XBox360 Video App
-
-            //Calls search but does not require it to be implemented:
-            //  WMP, probably uses it just for its "images" section
-
-            //Calls search Seems to require it:
-            //  XBox360 Music App
-
-            //WMP
-            //  action: "Search"
-            //  object_id: "0"
-            //  searchCriteria: "upnp:class derivedfrom \"object.item.imageItem\" and @refID exists false"
-            //  filter: "*"
-            //  starting_index: 0
-            //  requested_count: 200
-            //  sort_criteria: "-dc:date"
-
-            //XBox360 Music App
-            //  action: "Search"
-            //  object_id: "7"
-            //  searchCriteria: "(upnp:class = \"object.container.album.musicAlbum\")"
-            //  filter: "dc:title,upnp:artist"
-            //  starting_index: 0
-            //  requested_count: 1000
-            //  sort_criteria: "+dc:title"
-            //
-            //XBox360 Music App seems to work souly using SearchContainer and ProcessFileRequest
-            //I think the current resource Uri's aren't going to work because it seems to require an extension like .mp3 to work, but this requires further testing
-            //When hitting the Album tab of the app it's searching criteria is object.container.album.musicAlbum
-            //this means it wants albums put into containers, I thought Platinum might do this for us, but it doesn't
-
-
-            var didl = Platinum.Didl.header;
-
-            IEnumerable<BaseItem> children = null;
-
-            // I need to ask someone on the MB team if there's a better way to do this, it seems like it 
-            //could get pretty expensive to get ALL children all the time
-            //if it's our only option perhaps we should cache results locally or something similar
-            children = this.CurrentUser.RootFolder.GetRecursiveChildren(this.CurrentUser);
-            //children = children.Filter(Extensions.FilterType.Music | Extensions.FilterType.Video).Page(starting_index, requested_count);
-
-            //var test = GetFilterFromCriteria(searchCriteria);
-            children = children.Where(GetBaseItemMatchFromCriteria(searchCriteria));
-
-
-            int itemCount = 0;
-
-            if (children != null)
-            {
-                Platinum.MediaItem item = null;
-                foreach (var child in children)
-                {
-                    item = BaseItemToMediaItem(child, context);
-
-                    if (item != null)
-                    {
-                        item.ParentID = string.Empty;
-
-                        didl += item.ToDidl(filter);
-                        itemCount++;
-                    }
-                }
-
-                didl += Platinum.Didl.footer;
-
-                action.SetArgumentValue("Result", didl);
-                action.SetArgumentValue("NumberReturned", itemCount.ToString());
-                action.SetArgumentValue("TotalMatches", itemCount.ToString());
-
-                // update ID may be wrong here, it should be the one of the container?
-                action.SetArgumentValue("UpdateId", "1");
-
-                return NEP_Success;
-            }
-            return NEP_Failure;
-        }
-
-        private Platinum.MediaItem BaseItemToMediaItem(BaseItem child, Platinum.HttpRequestContext context)
-        {
-            Platinum.MediaItem result = null;
-            Platinum.MediaResource resource = null;
-
-            if (child.IsFolder)
-            {
-                //DLNA is a fairly flat system, there doesn't appear to be much room in the system for folders so far
-                //I haven't tested too many DLNA clients yet tho
-                result = null;
-                //item =  new Platinum.MediaItem();
-                //item.Class = new Platinum.ObjectClass("object.container.storageFolder", "");
-            }
-            else if (child is Episode)
-            {
-                result = MediaItemHelper.GetMediaItem((Episode)child);
-                resource = MediaItemHelper.GetMediaResource((Episode)child);
-            }
-            else if (child is Video)
-            {
-                result = MediaItemHelper.GetMediaItem((Video)child);
-                resource = MediaItemHelper.GetMediaResource((Video)child);
-            }
-            else if (child is Audio)
-            {
-                result = MediaItemHelper.GetMediaItem((Audio)child);
-                resource = MediaItemHelper.GetMediaResource((Audio)child);
-            }
-
-            if (result != null)
-            {
-                //have a go at finding the mime type
-                var mimeType = string.Empty;
-                if (child.Path != null && Path.HasExtension(child.Path))
-                    mimeType = MimeTypes.GetMimeType(child.Path);
-
-                resource.ProtoInfo = Platinum.ProtocolInfo.GetProtocolInfoFromMimeType(mimeType, true, context);
-
-                // get list of ips and make sure the ip the request came from is used for the first resource returned
-                // this ensures that clients which look only at the first resource will be able to reach the item
-                IEnumerable<String> ips = GetUPnPIPAddresses(context); //.Distinct();
-
-                // iterate through all ips and create a resource for each
-                // I think we need extensions (".mp3" type extensions) on these for Xbox360 Video and Music apps to work
-
-                
-                //resource.URI = new Uri(Kernel.HttpServerUrlPrefix + "/api/video.ts?id=" + child.Id.ToString("D")).ToString();
-                //result.AddResource(resource);
-
-                foreach (String ip in ips)
-                {
-                    //doesn't work for WMP
-                    //resource.URI = new Uri(Kernel.HttpServerUrlPrefix.Replace("+", ip) + "/api/video.ts?id=" + child.Id.ToString()).ToString();
-                    resource.URI = new Uri("http://" + ip + ":" + context.LocalAddress.port + "/" + child.Id.ToString("D")).ToString();
-
-                    result.AddResource(resource);
-                }
-                MediaItemHelper.AddAlbumArtInfoToMediaItem(result, child, Kernel.HttpServerUrlPrefix, ips);
-            }
-
-            return result;
-        }
-
-        private void AddResourcesToMediaItem(Platinum.MediaItem item, BaseItem child, Platinum.HttpRequestContext context)
-        {
-            Platinum.MediaResource resource = null;
-
-            if (child is Video)
-            {
-                var videoChild = (Video)child;
-                resource = new Platinum.MediaResource();
-
-                if (videoChild.DefaultVideoStream != null)
-                {
-                    //Bitrate is Bytes per second
-                    if (videoChild.DefaultVideoStream.BitRate.HasValue)
-                        resource.Bitrate = (uint)videoChild.DefaultVideoStream.BitRate;
-
-                    //not sure if we know Colour Depth
-                    //resource.ColorDepth
-                    if (videoChild.DefaultVideoStream.Channels.HasValue)
-                        resource.NbAudioChannels = (uint)videoChild.DefaultVideoStream.Channels.Value;
-
-                    //resource.Protection
-                    //resource.ProtoInfo
-
-                    //we must know resolution, I'm just not sure how to get it
-                    //resource.Resolution
-
-                    //I'm not sure what this actually means, is it Sample Rate
-                    if (videoChild.DefaultVideoStream.SampleRate.HasValue)
-                        resource.SampleFrequency = (uint)videoChild.DefaultVideoStream.SampleRate.Value;
-                    //file size?
-                    //resource.Size
-
-                }
-            }
-            else if (child is Audio)
-            {
-
-            }
-
-            // get list of ips and make sure the ip the request came from is used for the first resource returned
-            // this ensures that clients which look only at the first resource will be able to reach the item
-            List<String> ips = GetUPnPIPAddresses(context);
-
-            // iterate through all ips and create a resource for each
-            // I think we need extensions (".mp3" type extensions) on these for Xbox360 Video and Music apps to work
-
-            foreach (String ip in ips)
-            {
-                resource.URI = new Uri("http://" + ip + ":" + context.LocalAddress.port + "/" + child.Id.ToString("D")).ToString();
-                item.AddResource(resource);
-            }
-        }
-
-        /// <summary>
-        /// Gets a list of valid IP Addresses that the UPnP server is using
-        /// </summary>
-        /// <param name="context"></param>
-        /// <returns></returns>
-        private List<String> GetUPnPIPAddresses(Platinum.HttpRequestContext context)
-        {
-            // get list of ips and make sure the ip the request came from is used for the first resource returned
-            // this ensures that clients which look only at the first resource will be able to reach the item
-            List<String> result = Platinum.UPnP.GetIpAddresses(true); //if this call is expensive we could cache the results
-            String localIP = context.LocalAddress.ip;
-            if (localIP != "0.0.0.0")
-            {
-                result.Remove(localIP);
-                result.Insert(0, localIP);
-            }
-            return result;
-        }
-
-        /// <summary>
-        /// Gets the MB User with a user name that matches the user name configured in the plugin config
-        /// </summary>
-        /// <returns>MediaBrowser.Controller.Entities.User</returns>
-        private User CurrentUser
-        {
-            get
-            {
-                if (this._CurrentUser == null)
-                {
-                    //this looks like a lot of processing but it really isn't
-                    //its mostly gaurding against no users or no matching user existing
-                    var serverKernel = Controller.Kernel.Instance;
-                    if (serverKernel.Users.Any())
-                    {
-                        if (string.IsNullOrWhiteSpace(this.Configuration.UserName))
-                            this._CurrentUser = serverKernel.Users.First();
-                        else
-                        {
-                            this._CurrentUser = serverKernel.Users.FirstOrDefault(i => string.Equals(i.Name, this.Configuration.UserName, StringComparison.OrdinalIgnoreCase));
-                            if (this._CurrentUser == null)
-                            {
-                                //log and return first user
-                                this._CurrentUser = serverKernel.Users.First();
-                                Logger.Error("Configured user: \"{0}\" not found. Using first user found: \"{1}\" instead", this.Configuration.UserName, this._CurrentUser.Name);
-                            }
-                        }
-                    }
-                    else
-                    {
-                        Logger.Fatal("No users in the system");
-                        this._CurrentUser = null;
-                    }
-                }
-                return this._CurrentUser;
-            }
-        }
-
-        #region "A Search Idea"
-        //this is just an idea of how we might do some search
-        //it's a bit lackluster in places and might be overkill in others
-        //all in all it might not be a good idea, but I thought I'd see how it felt
-
-        private Func<BaseItem, bool> GetBaseItemMatchFromCriteria(string searchCriteria)
-        {
-            //WMP Search when clicking Music:
-            //"upnp:class derivedfrom \"object.item.audioItem\" and @refID exists false"
-            //WMP Search when clicking Videos:
-            //"upnp:class derivedfrom \"object.item.videoItem\" and @refID exists false"
-            //WMP Search when clicking Pictures:
-            //"upnp:class derivedfrom \"object.item.imageItem\" and @refID exists false"
-            //WMP Search when clicking Recorded TV:
-            //"upnp:class derivedfrom \"object.item.videoItem\" and @refID exists false"
-
-            //we really need a syntax tree parser here
-            //but the requests never seem to get more complex than "'Condition One' And 'Condition Two'"
-            //something like Rosylin would be fun but it'd be serious overkill
-            //the syntax seems to be very clear and there are only a handful of valid constructs
-            //so this very basic parsing will provide some support for now
-
-            Queue<string> criteriaQueue = new Queue<string>(searchCriteria.Split(' '));
-
-            Func<BaseItem, bool> result = null;
-            var currentMainOperatorIsAnd = false;
-
-            //loop through in order and process - do not parallelise, order is important
-            while (criteriaQueue.Any())
-            {
-                Func<BaseItem, bool> currentFilter = null;
-
-                var metadataElement = criteriaQueue.Dequeue();
-                var criteriaOperator = criteriaQueue.Dequeue();
-                var value = criteriaQueue.Dequeue();
-                if (value.StartsWith("\"") || value.StartsWith("\\\""))
-                    while (!value.EndsWith("\""))
-                    {
-                        value += criteriaQueue.Dequeue();
-                    }
-                value = value.Trim();
-
-
-                if (string.Equals(metadataElement, "upnp:class", StringComparison.OrdinalIgnoreCase))
-                    currentFilter = GetUpnpClassFilter(criteriaOperator, value);
-                else if (string.Equals(metadataElement, "@refID", StringComparison.OrdinalIgnoreCase))
-                {
-                    //not entirely sure what refID is for
-                    //Platinum has ReferenceID which I assume is the same thing, but we're not using it yet
-
-                }
-                else
-                {
-                    //fail??
-                }
-
-
-                if (currentFilter != null)
-                {
-                    if (result == null)
-                        result = currentFilter;
-                    else
-                        if (currentMainOperatorIsAnd)
-                            result = (i) => result(i) && currentFilter(i);
-                        else
-                            result = (i) => result(i) || currentFilter(i);
-                }
-                if (criteriaQueue.Any())
-                {
-                    var op = criteriaQueue.Dequeue();
-                    if (string.Equals(op, "and", StringComparison.OrdinalIgnoreCase))
-                        currentMainOperatorIsAnd = true;
-                    else
-                        currentMainOperatorIsAnd = false;
-                }
-            }
-            return result;
-        }
-
-        private Func<BaseItem, bool> GetUpnpClassFilter(string criteriaOperator, string value)
-        {
-            //"upnp:class derivedfrom \"object.item.videoItem\" "
-            //"(upnp:class = \"object.container.album.musicAlbum\")"
-
-            //only two options are valid for criteria
-            // =, derivedfrom
-
-            //there are only a few values we care about
-            //object.item.videoItem
-            //object.item.audioItem
-            //object.container.storageFolder
-
-            if (string.Equals(criteriaOperator, "=", StringComparison.OrdinalIgnoreCase))
-            {
-                if (value.Contains("object.item.videoItem"))
-                    return (i) => (i is Video);
-                else if (value.Contains("object.item.audioItem"))
-                    return (i) => (i is Audio);
-                else if (value.Contains("object.container.storageFolder"))
-                    return (i) => (i is Folder);
-                else
-                    //something has gone wrong, don't filter anything
-                    return (i) => true;
-            }
-            else if (string.Equals(criteriaOperator, "derivedfrom", StringComparison.OrdinalIgnoreCase))
-            {
-                if (value.Contains("object.item.videoItem"))
-                    return (i) => (i is Video);
-                else if (value.Contains("object.item.audioItem"))
-                    return (i) => (i is Audio);
-                else if (value.Contains("object.container.storageFolder"))
-                    return (i) => (i is Folder);
-                else
-                    //something has gone wrong, don't filter anything
-                    return (i) => true;
-            }
-            else
-            {
-                //something has gone wrong, don't filter anything
-                return (i) => true;
-            }
-        }
-        #endregion
-
-        public override void UpdateConfiguration(Model.Plugins.BasePluginConfiguration configuration)
-        {
-            base.UpdateConfiguration(configuration);
-            var config = (PluginConfiguration)configuration;
-
-            this.CleanupUPnPServer();
-            this._CurrentUser = null;
-            this.SetupUPnPServer();
-        }
-    }
-
-    internal static class MediaItemHelper
-    {
-        internal static Platinum.MediaResource GetMediaResource(Video item)
-        {
-            var result = GetMediaResource((BaseItem)item);
-
-            if (item.DefaultVideoStream != null)
-            {
-                //Bitrate is Bytes per second
-                if (item.DefaultVideoStream.BitRate.HasValue)
-                    result.Bitrate = (uint)item.DefaultVideoStream.BitRate;
-
-                //not sure if we know Colour Depth
-                //resource.ColorDepth
-                if (item.DefaultVideoStream.Channels.HasValue)
-                    result.NbAudioChannels = (uint)item.DefaultVideoStream.Channels.Value;
-
-                //resource.Protection
-                //resource.ProtoInfo
-
-                //we must know resolution, I'm just not sure how to get it
-                //resource.Resolution
-
-                //I'm not sure what this actually means, is it Sample Rate
-                if (item.DefaultVideoStream.SampleRate.HasValue)
-                    result.SampleFrequency = (uint)item.DefaultVideoStream.SampleRate.Value;
-                //file size?
-                //resource.Size
-
-                ////to do subtitles for clients that can deal with external subtitles (like srt)
-                ////we will have to do something like this
-                //IEnumerable<String> ips = GetUPnPIPAddresses(context);
-                //foreach (var st in videoChild.MediaStreams)
-                //{
-                //    if (st.Type == MediaStreamType.Subtitle)
-                //    {
-                //        Platinum.MediaResource subtitleResource = new Platinum.MediaResource();
-                //        subtitleResource.ProtoInfo = Platinum.ProtocolInfo.GetProtocolInfo(st.Path, with_dlna_extension: false);
-                //        foreach (String ip in ips)
-                //        {
-                //            //we'll need to figure out which of these options works for whick players
-                //            //either serve them ourselves
-                //            resource.URI = new Uri("http://" + ip + ":" + context.LocalAddress.port + "/" + child.Id.ToString("D")).ToString();
-                //            //or get the web api to serve them directly
-                //            resource.URI = new Uri(Kernel.HttpServerUrlPrefix.Replace("+", ip) + "/api/video?id=" + child.Id.ToString() + "&type=Subtitle").ToString();
-                //            result.AddResource(resource);
-                //        }
-                //    }
-                //}
-            }
-            return result;
-        }
-        internal static Platinum.MediaItem GetMediaItem(Video item)
-        {
-            var result = GetMediaItem((BaseItem)item);
-            result.Title = GetTitle(item);
-            return result;
-        }
-
-        internal static Platinum.MediaResource GetMediaResource(Episode item)
-        {
-            //there's nothing specific about an episode that requires extra Resources
-            return GetMediaResource((Video)item);
-        }
-        internal static Platinum.MediaItem GetMediaItem(Episode item)
-        {
-            var result = GetMediaItem((Video)item);
-
-            if (item.IndexNumber.HasValue)
-                result.Recorded.EpisodeNumber = (uint)item.IndexNumber.Value;
-            if (item.Series != null && item.Series.Name != null)
-                result.Recorded.SeriesTitle = item.Series.Name;
-            result.Recorded.ProgramTitle = item.Name == null ? string.Empty : item.Name;
-
-            return result;
-        }
-
-        internal static Platinum.MediaResource GetMediaResource(Audio item)
-        {
-            //there's nothing specific about an audio item that requires extra Resources
-            return GetMediaResource((BaseItem)item);
-        }
-        internal static Platinum.MediaItem GetMediaItem(Audio item)
-        {
-            var result = GetMediaItem((BaseItem)item);
-            result.Title = GetTitle(item);
-            result.People.AddArtist(new Platinum.PersonRole(item.Artist));
-            result.People.Contributor = item.AlbumArtist;
-            result.Affiliation.Album = item.Album;
-            return result;
-        }
-
-        internal static Platinum.MediaResource GetMediaResource(BaseItem item)
-        {
-            var result = new Platinum.MediaResource();
-            //duration is in seconds
-            if (item.RunTimeTicks.HasValue)
-                result.Duration = (uint)TimeSpan.FromTicks(item.RunTimeTicks.Value).TotalSeconds;
-
-            return result;
-        }
-        internal static Platinum.MediaItem GetMediaItem(BaseItem item)
-        {
-            var result = new Platinum.MediaItem();
-
-            result.ObjectID = item.Id.ToString();
-
-            //if (child.Parent != null)
-            //    result.ParentID = child.Parent.Id.ToString();
-            result.Class = item.GetPlatinumClassObject();
-
-            result.Description.Date = item.PremiereDate.HasValue ? item.PremiereDate.Value.ToString() : string.Empty;
-            result.Description.Language = item.Language == null ? string.Empty : item.Language;
-            result.Description.DescriptionText = "this is DescriptionText";
-            result.Description.LongDescriptionText = item.Overview == null ? string.Empty : item.Overview;
-            result.Description.Rating = item.CommunityRating.ToString();
-
-            if (item.Genres != null)
-            {
-                foreach (var genre in item.Genres)
-                {
-                    result.Affiliation.AddGenre(genre);
-                }
-            }
-            if (item.People != null)
-            {
-                foreach (var person in item.People)
-                {
-                    if (string.Equals(person.Type, PersonType.Actor, StringComparison.OrdinalIgnoreCase))
-                        result.People.AddActor(new Platinum.PersonRole(person.Name, person.Role == null ? string.Empty : person.Role));
-                    else if (string.Equals(person.Type, PersonType.MusicArtist, StringComparison.OrdinalIgnoreCase))
-                    {
-                        result.People.AddArtist(new Platinum.PersonRole(person.Name, "MusicArtist"));
-                        result.People.AddArtist(new Platinum.PersonRole(person.Name, "Performer"));
-                    }
-                    else if (string.Equals(person.Type, PersonType.Composer, StringComparison.OrdinalIgnoreCase))
-                        result.People.AddAuthors(new Platinum.PersonRole(person.Name, "Composer"));
-                    else if (string.Equals(person.Type, PersonType.Writer, StringComparison.OrdinalIgnoreCase))
-                        result.People.AddAuthors(new Platinum.PersonRole(person.Name, "Writer"));
-                    else if (string.Equals(person.Type, PersonType.Director, StringComparison.OrdinalIgnoreCase))
-                    {
-                        result.People.AddAuthors(new Platinum.PersonRole(person.Name, "Director"));
-                        result.People.Director = result.People.Director + " " + person.Name;
-                    }
-                    else
-                        result.People.AddArtist(new Platinum.PersonRole(person.Name, person.Type == null ? string.Empty : person.Type));
-                }
-            }
-            return result;
-        }
-
-        internal static void AddAlbumArtInfoToMediaItem(Platinum.MediaItem item, BaseItem child, string httpServerUrlPrefix, IEnumerable<String> ips)
-        {
-            foreach (var ip in ips)
-            {
-                AddAlbumArtInfoToMediaItem(item, child, httpServerUrlPrefix, ip);
-            }
-        }
-        private static void AddAlbumArtInfoToMediaItem(Platinum.MediaItem item, BaseItem child, string httpServerUrlPrefix, string ip)
-        {
-            //making the artwork a direct hit to the MediaBrowser server instead of via the DLNA plugin works for WMP
-            item.Extra.AddAlbumArtInfo(new Platinum.AlbumArtInfo(httpServerUrlPrefix.Replace("+", ip) + "/api/image?id=" + child.Id.ToString() + "&type=primary"));
-        }
-
-        
-        /// <summary>
-        /// Gets the title.
-        /// </summary>
-        /// <param name="video">The video.</param>
-        /// <returns>System.String.</returns>
-        private static string GetTitle(Video video)
-        {
-            //we have to be extremely careful with all string handling
-            //if we set a null reference to a Platinum string it will not marshall to native correctly and things got very bad very quickly
-            var title = video.Name == null ? string.Empty : video.Name;
-
-            var episode = video as Episode;
-
-            if (episode != null)
-            {
-                if (episode.Season != null)
-                {
-                    title = string.Format("{0}-{1}", episode.Season.Name, title);
-                }
-                if (episode.Series != null)
-                {
-                    title = string.Format("{0}-{1}", episode.Series.Name, title);
-                }
-            }
-
-            return title;
-        }
-
-        /// <summary>
-        /// Gets the title.
-        /// </summary>
-        /// <param name="audio">The audio.</param>
-        /// <returns>System.String.</returns>
-        private static string GetTitle(Audio audio)
-        {
-            return audio.Name == null ? string.Empty : audio.Name;
-        }
-
-    }
-
-    internal static class Extensions
-    {
-        [Flags()]
-        internal enum FilterType
-        {
-            Folder = 1,
-            Music = 2,
-            Video = 4
-        }
-        internal static IEnumerable<BaseItem> Filter(this IEnumerable<BaseItem> en, FilterType filter)
-        {
-            return en.Where(i => (
-                (((filter & FilterType.Folder) == FilterType.Folder) && (i is Folder)) ||
-                (((filter & FilterType.Music) == FilterType.Music) && (i is Audio)) ||
-                (((filter & FilterType.Video) == FilterType.Video) && (i is Video)))
-                                );
-        }
-
-        internal static IEnumerable<BaseItem> Page(this IEnumerable<BaseItem> en, int starting_index, int requested_count)
-        {
-            return en.Skip(starting_index).Take(requested_count);
-        }
-
-
-        internal static Platinum.ObjectClass GetPlatinumClassObject(this BaseItem item)
-        {
-            if (item is Video)
-                return new Platinum.ObjectClass("object.item.videoItem", "");
-            else if (item is Audio)
-                return new Platinum.ObjectClass("object.item.audioItem.musicTrack", "");
-            else if (item is Folder)
-                return new Platinum.ObjectClass("object.container.storageFolder", "");
-            else
-                return null;
-        }
-        internal static Platinum.ObjectClass GetPlatinumClassObject(this Folder item)
-        {
-            return new Platinum.ObjectClass("object.container.storageFolder", "");
-        }
-        internal static Platinum.ObjectClass GetPlatinumClassObject(this Audio item)
-        {
-            return new Platinum.ObjectClass("object.item.audioItem.musicTrack", "");
-        }
-        internal static Platinum.ObjectClass GetPlatinumClassObject(this Video item)
-        {
-            return new Platinum.ObjectClass("object.item.videoItem", "");
-        }
-    }
-    internal static class LoggingExtensions
-    {
-        //provide some json-esque string that can be used for Verbose logging purposed
-        internal static string ToLogString(this Platinum.Action item)
-        {
-            return string.Format(" {{ Name:\"{0}\", Description:\"{1}\", Arguments:{2} }} ",
-                item.Name, item.Description.ToLogString(), item.Arguments.ToLogString());
-
-        }
-        internal static string ToLogString(this IEnumerable<Platinum.ActionArgumentDescription> items)
-        {
-            var result = "[";
-            foreach (var arg in items)
-            {
-                result += (" " + arg.ToLogString());
-            }
-            result += " ]";
-            return result;
-        }
-        internal static string ToLogString(this Platinum.ActionArgumentDescription item)
-        {
-            return string.Format(" {{ Name:\"{0}\", Direction:{1}, HasReturnValue:{2}, RelatedStateVariable:{3} }} ",
-                item.Name, item.Direction, item.HasReturnValue, item.RelatedStateVariable.ToLogString());
-
-        }
-        internal static string ToLogString(this Platinum.StateVariable item)
-        {
-            return string.Format(" {{ Name:\"{0}\", DataType:{1}, DataTypeString:\"{2}\", Value:{3}, ValueString:\"{4}\" }} ",
-                item.Name, item.DataType, item.DataTypeString, item.Value, item.ValueString);
-        }
-        internal static string ToLogString(this Platinum.ActionDescription item)
-        {
-            return string.Format(" {{ Name:\"{0}\", Arguments:{1} }} ",
-                item.Name, item.Arguments.ToLogString());
-        }
-        internal static string ToLogString(this Platinum.HttpRequestContext item)
-        {
-            return string.Format(" {{ LocalAddress:{0}, RemoteAddress:{1}, Request:\"{2}\", Signature:{3} }}",
-                item.LocalAddress.ToLogString(), item.RemoteAddress.ToLogString(), item.Request.URI.ToString(), item.Signature);
-        }
-        internal static string ToLogString(this Platinum.HttpRequestContext.SocketAddress item)
-        {
-            return string.Format("{{ IP:{0}, Port:{1} }}",
-                item.ip, item.port);
-        }
-    }
-}

+ 0 - 35
MediaBrowser.Plugins.Dlna/Properties/AssemblyInfo.cs

@@ -1,35 +0,0 @@
-using System.Reflection;
-using System.Runtime.CompilerServices;
-using System.Runtime.InteropServices;
-
-// General Information about an assembly is controlled through the following 
-// set of attributes. Change these attribute values to modify the information
-// associated with an assembly.
-[assembly: AssemblyTitle("MediaBrowser.Plugins.Dlna")]
-[assembly: AssemblyDescription("")]
-[assembly: AssemblyConfiguration("")]
-[assembly: AssemblyCompany("")]
-[assembly: AssemblyProduct("MediaBrowser.Plugins.Dlna")]
-[assembly: AssemblyCopyright("Copyright ©  2013")]
-[assembly: AssemblyTrademark("")]
-[assembly: AssemblyCulture("")]
-
-// Setting ComVisible to false makes the types in this assembly not visible 
-// to COM components.  If you need to access a type in this assembly from 
-// COM, set the ComVisible attribute to true on that type.
-[assembly: ComVisible(false)]
-
-// The following GUID is for the ID of the typelib if this project is exposed to COM
-[assembly: Guid("f1855371-7cf5-40d2-bcd8-b780d7f006af")]
-
-// Version information for an assembly consists of the following four values:
-//
-//      Major Version
-//      Minor Version 
-//      Build Number
-//      Revision
-//
-// You can specify all the values or you can default the Build and Revision Numbers 
-// by using the '*' as shown below:
-// [assembly: AssemblyVersion("1.0.*")]
-[assembly: AssemblyVersion("1.0.*")]

+ 0 - 109
MediaBrowser.Plugins.MpcHc/MediaBrowser.Plugins.MpcHc.csproj

@@ -1,109 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
-  <PropertyGroup>
-    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
-    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
-    <ProjectGuid>{2E94BC08-A7A2-42DD-9893-EAA3DACD1CF9}</ProjectGuid>
-    <OutputType>library</OutputType>
-    <AppDesignerFolder>Properties</AppDesignerFolder>
-    <RootNamespace>MediaBrowser.Plugins.MpcHc</RootNamespace>
-    <AssemblyName>MediaBrowser.Plugins.MpcHc</AssemblyName>
-    <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
-    <FileAlignment>512</FileAlignment>
-    <ProjectTypeGuids>{60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
-    <WarningLevel>4</WarningLevel>
-    <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\</SolutionDir>
-    <RestorePackages>true</RestorePackages>
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
-    <DebugSymbols>true</DebugSymbols>
-    <DebugType>full</DebugType>
-    <Optimize>false</Optimize>
-    <OutputPath>bin\Debug\</OutputPath>
-    <DefineConstants>DEBUG;TRACE</DefineConstants>
-    <ErrorReport>prompt</ErrorReport>
-    <WarningLevel>4</WarningLevel>
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
-    <DebugType>pdbonly</DebugType>
-    <Optimize>true</Optimize>
-    <OutputPath>bin\Release\</OutputPath>
-    <DefineConstants>TRACE</DefineConstants>
-    <ErrorReport>prompt</ErrorReport>
-    <WarningLevel>4</WarningLevel>
-  </PropertyGroup>
-  <PropertyGroup>
-    <RunPostBuildEvent>Always</RunPostBuildEvent>
-  </PropertyGroup>
-  <ItemGroup>
-    <Reference Include="System" />
-    <Reference Include="System.ComponentModel.Composition" />
-    <Reference Include="System.Data" />
-    <Reference Include="System.Net.Http" />
-    <Reference Include="System.Xml" />
-    <Reference Include="Microsoft.CSharp" />
-    <Reference Include="System.Core" />
-    <Reference Include="System.Xml.Linq" />
-    <Reference Include="System.Data.DataSetExtensions" />
-    <Reference Include="System.Xaml">
-      <RequiredTargetFramework>4.0</RequiredTargetFramework>
-    </Reference>
-    <Reference Include="WindowsBase" />
-    <Reference Include="PresentationCore" />
-    <Reference Include="PresentationFramework" />
-  </ItemGroup>
-  <ItemGroup>
-    <Compile Include="MpcHcMediaPlayer.cs" />
-    <Compile Include="Plugin.cs" />
-    <Compile Include="Properties\AssemblyInfo.cs">
-      <SubType>Code</SubType>
-    </Compile>
-    <Compile Include="Properties\Resources.Designer.cs">
-      <AutoGen>True</AutoGen>
-      <DesignTime>True</DesignTime>
-      <DependentUpon>Resources.resx</DependentUpon>
-    </Compile>
-    <Compile Include="Properties\Settings.Designer.cs">
-      <AutoGen>True</AutoGen>
-      <DependentUpon>Settings.settings</DependentUpon>
-      <DesignTimeSharedInput>True</DesignTimeSharedInput>
-    </Compile>
-    <EmbeddedResource Include="Properties\Resources.resx">
-      <Generator>ResXFileCodeGenerator</Generator>
-      <LastGenOutput>Resources.Designer.cs</LastGenOutput>
-    </EmbeddedResource>
-    <None Include="app.config" />
-    <None Include="Properties\Settings.settings">
-      <Generator>SettingsSingleFileGenerator</Generator>
-      <LastGenOutput>Settings.Designer.cs</LastGenOutput>
-    </None>
-    <AppDesigner Include="Properties\" />
-  </ItemGroup>
-  <ItemGroup>
-    <ProjectReference Include="..\MediaBrowser.Common\MediaBrowser.Common.csproj">
-      <Project>{9142eefa-7570-41e1-bfcc-468bb571af2f}</Project>
-      <Name>MediaBrowser.Common</Name>
-    </ProjectReference>
-    <ProjectReference Include="..\MediaBrowser.Model\MediaBrowser.Model.csproj">
-      <Project>{7eeeb4bb-f3e8-48fc-b4c5-70f0fff8329b}</Project>
-      <Name>MediaBrowser.Model</Name>
-    </ProjectReference>
-    <ProjectReference Include="..\MediaBrowser.UI\MediaBrowser.UI.csproj">
-      <Project>{b5ece1fb-618e-420b-9a99-8e972d76920a}</Project>
-      <Name>MediaBrowser.UI</Name>
-    </ProjectReference>
-  </ItemGroup>
-  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
-  <PropertyGroup>
-    <PostBuildEvent>xcopy "$(TargetPath)" "$(SolutionDir)\ProgramData-Server\Plugins\" /y</PostBuildEvent>
-  </PropertyGroup>
-  <Import Project="$(SolutionDir)\.nuget\nuget.targets" />
-  <!-- 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">
-  </Target>
-  <Target Name="AfterBuild">
-  </Target>
-  -->
-</Project>

+ 0 - 580
MediaBrowser.Plugins.MpcHc/MpcHcMediaPlayer.cs

@@ -1,580 +0,0 @@
-using MediaBrowser.Model.Dto;
-using MediaBrowser.Model.Entities;
-using MediaBrowser.Model.Logging;
-using MediaBrowser.UI.Configuration;
-using MediaBrowser.UI.Controller;
-using MediaBrowser.UI.Playback;
-using MediaBrowser.UI.Playback.ExternalPlayer;
-using System;
-using System.Collections.Generic;
-using System.ComponentModel.Composition;
-using System.IO;
-using System.Linq;
-using System.Net.Http;
-using System.Threading;
-using System.Threading.Tasks;
-
-namespace MediaBrowser.Plugins.MpcHc
-{
-    /// <summary>
-    /// Class GenericExternalPlayer
-    /// </summary>
-    [Export(typeof(BaseMediaPlayer))]
-    public class MpcHcMediaPlayer : BaseExternalPlayer
-    {
-        /// <summary>
-        /// The state sync lock
-        /// </summary>
-        private object stateSyncLock = new object();
-
-        /// <summary>
-        /// The MPC HTTP interface resource pool
-        /// </summary>
-        private SemaphoreSlim MpcHttpInterfaceResourcePool = new SemaphoreSlim(1, 1);
-
-        [ImportingConstructor]
-        public MpcHcMediaPlayer([Import("logger")] ILogger logger)
-            : base(logger)
-        {
-        }
-
-        /// <summary>
-        /// Gets or sets the HTTP interface cancellation token.
-        /// </summary>
-        /// <value>The HTTP interface cancellation token.</value>
-        private CancellationTokenSource HttpInterfaceCancellationTokenSource { get; set; }
-
-        /// <summary>
-        /// Gets or sets a value indicating whether this instance has started playing.
-        /// </summary>
-        /// <value><c>true</c> if this instance has started playing; otherwise, <c>false</c>.</value>
-        private bool HasStartedPlaying { get; set; }
-
-        /// <summary>
-        /// Gets or sets the status update timer.
-        /// </summary>
-        /// <value>The status update timer.</value>
-        private Timer StatusUpdateTimer { get; set; }
-
-        /// <summary>
-        /// Gets a value indicating whether this instance can monitor progress.
-        /// </summary>
-        /// <value><c>true</c> if this instance can monitor progress; otherwise, <c>false</c>.</value>
-        protected override bool CanMonitorProgress
-        {
-            get
-            {
-                return true;
-            }
-        }
-
-        /// <summary>
-        /// The _current position ticks
-        /// </summary>
-        private long? _currentPositionTicks;
-
-        /// <summary>
-        /// Gets the current position ticks.
-        /// </summary>
-        /// <value>The current position ticks.</value>
-        public override long? CurrentPositionTicks
-        {
-            get
-            {
-                return _currentPositionTicks;
-            }
-        }
-
-        /// <summary>
-        /// The _current playlist index
-        /// </summary>
-        private int _currentPlaylistIndex;
-
-        /// <summary>
-        /// Gets the index of the current playlist.
-        /// </summary>
-        /// <value>The index of the current playlist.</value>
-        public override int CurrentPlaylistIndex
-        {
-            get
-            {
-                return _currentPlaylistIndex;
-            }
-        }
-
-        /// <summary>
-        /// Gets the name.
-        /// </summary>
-        /// <value>The name.</value>
-        public override string Name
-        {
-            get { return "MpcHc"; }
-        }
-
-        /// <summary>
-        /// Gets a value indicating whether this instance can close automatically.
-        /// </summary>
-        /// <value><c>true</c> if this instance can close automatically; otherwise, <c>false</c>.</value>
-        protected override bool CanCloseAutomatically
-        {
-            get
-            {
-                return true;
-            }
-        }
-
-        /// <summary>
-        /// Determines whether this instance can play the specified item.
-        /// </summary>
-        /// <param name="item">The item.</param>
-        /// <returns><c>true</c> if this instance can play the specified item; otherwise, <c>false</c>.</returns>
-        public override bool CanPlay(BaseItemDto item)
-        {
-            return item.IsVideo || item.IsAudio;
-        }
-
-        /// <summary>
-        /// Gets the command arguments.
-        /// </summary>
-        /// <param name="items">The items.</param>
-        /// <param name="options">The options.</param>
-        /// <param name="playerConfiguration">The player configuration.</param>
-        /// <returns>System.String.</returns>
-        protected override string GetCommandArguments(List<BaseItemDto> items, PlayOptions options, PlayerConfiguration playerConfiguration)
-        {
-            var formatString = "{0} /play /fullscreen /close";
-
-            var firstItem = items[0];
-
-            var startTicks = Math.Max(options.StartPositionTicks, 0);
-
-            if (startTicks > 0 && firstItem.IsVideo && firstItem.VideoType.HasValue && firstItem.VideoType.Value == VideoType.Dvd)
-            {
-                formatString += " /dvdpos 1#" + TimeSpan.FromTicks(startTicks).ToString("hh\\:mm\\:ss");
-            }
-            else
-            {
-                formatString += " /start " + TimeSpan.FromTicks(startTicks).TotalMilliseconds;
-            }
-
-
-            return GetCommandArguments(items, formatString);
-        }
-
-        /// <summary>
-        /// Gets the path for command line.
-        /// </summary>
-        /// <param name="item">The item.</param>
-        /// <returns>System.String.</returns>
-        protected override string GetPathForCommandLine(BaseItemDto item)
-        {
-            var path = base.GetPathForCommandLine(item);
-
-            if (item.IsVideo && item.VideoType.HasValue)
-            {
-                if (item.VideoType.Value == VideoType.Dvd)
-                {
-                    // Point directly to the video_ts path
-                    // Otherwise mpc will play any other media files that might exist in the dvd top folder (e.g. video backdrops).
-                    var videoTsPath = Path.Combine(path, "video_ts");
-
-                    if (Directory.Exists(videoTsPath))
-                    {
-                        path = videoTsPath;
-                    }
-                }
-                if (item.VideoType.Value == VideoType.BluRay)
-                {
-                    // Point directly to the bdmv path
-                    var bdmvPath = Path.Combine(path, "bdmv");
-
-                    if (Directory.Exists(bdmvPath))
-                    {
-                        path = bdmvPath;
-                    }
-                }
-            }
-
-            return FormatPath(path);
-        }
-
-        /// <summary>
-        /// Formats the path.
-        /// </summary>
-        /// <param name="path">The path.</param>
-        /// <returns>System.String.</returns>
-        private string FormatPath(string path)
-        {
-            if (path.EndsWith(":\\", StringComparison.OrdinalIgnoreCase))
-            {
-                path = path.TrimEnd('\\');
-            }
-
-            return path;
-        }
-
-        /// <summary>
-        /// Called when [external player launched].
-        /// </summary>
-        protected override void OnExternalPlayerLaunched()
-        {
-            base.OnExternalPlayerLaunched();
-
-            ReloadStatusUpdateTimer();
-        }
-
-        /// <summary>
-        /// Reloads the status update timer.
-        /// </summary>
-        private void ReloadStatusUpdateTimer()
-        {
-            DisposeStatusTimer();
-
-            HttpInterfaceCancellationTokenSource = new CancellationTokenSource();
-
-            StatusUpdateTimer = new Timer(OnStatusUpdateTimerStopped, null, TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(1));
-        }
-
-        /// <summary>
-        /// Called when [status update timer stopped].
-        /// </summary>
-        /// <param name="state">The state.</param>
-        private async void OnStatusUpdateTimerStopped(object state)
-        {
-            try
-            {
-                var token = HttpInterfaceCancellationTokenSource.Token;
-
-                using (var stream = await UIKernel.Instance.HttpManager.Get(StatusUrl, MpcHttpInterfaceResourcePool, token).ConfigureAwait(false))
-                {
-                    token.ThrowIfCancellationRequested();
-
-                    using (var reader = new StreamReader(stream))
-                    {
-                        token.ThrowIfCancellationRequested();
-
-                        var result = await reader.ReadToEndAsync().ConfigureAwait(false);
-
-                        token.ThrowIfCancellationRequested();
-
-                        ProcessStatusResult(result);
-                    }
-                }
-            }
-            catch (HttpRequestException ex)
-            {
-                Logger.ErrorException("Error connecting to MpcHc status interface", ex);
-            }
-            catch (OperationCanceledException)
-            {
-                // Manually cancelled by us
-                Logger.Info("Status request cancelled");
-            }
-        }
-
-        /// <summary>
-        /// Processes the status result.
-        /// </summary>
-        /// <param name="result">The result.</param>
-        private async void ProcessStatusResult(string result)
-        {
-            // Sample result
-            // OnStatus('test.avi', 'Playing', 5292, '00:00:05', 1203090, '00:20:03', 0, 100, 'C:\test.avi')
-            // 5292 = position in ms
-            // 00:00:05 = position
-            // 1203090 = duration in ms
-            // 00:20:03 = duration
-
-            var quoteChar = result.IndexOf(", \"", StringComparison.OrdinalIgnoreCase) == -1 ? '\'' : '\"';
-
-            // Strip off the leading "OnStatus(" and the trailing ")"
-            result = result.Substring(result.IndexOf(quoteChar));
-            result = result.Substring(0, result.LastIndexOf(quoteChar));
-
-            // Strip off the filename at the beginning
-            result = result.Substring(result.IndexOf(string.Format("{0}, {0}", quoteChar), StringComparison.OrdinalIgnoreCase) + 3);
-
-            // Find the last index of ", '" so that we can extract and then strip off the file path at the end.
-            var lastIndexOfSeparator = result.LastIndexOf(", " + quoteChar, StringComparison.OrdinalIgnoreCase);
-
-            // Get the current playing file path
-            var currentPlayingFile = result.Substring(lastIndexOfSeparator + 2).Trim(quoteChar);
-
-            // Strip off the current playing file path
-            result = result.Substring(0, lastIndexOfSeparator);
-
-            var values = result.Split(',').Select(v => v.Trim().Trim(quoteChar)).ToList();
-
-            var currentPositionTicks = TimeSpan.FromMilliseconds(double.Parse(values[1])).Ticks;
-            //var currentDurationTicks = TimeSpan.FromMilliseconds(double.Parse(values[3])).Ticks;
-
-            var playstate = values[0];
-
-            var playlistIndex = GetPlaylistIndex(currentPlayingFile);
-
-            if (playstate.Equals("stopped", StringComparison.OrdinalIgnoreCase))
-            {
-                if (HasStartedPlaying)
-                {
-                    await ClosePlayer().ConfigureAwait(false);
-                }
-            }
-            else
-            {
-                lock (stateSyncLock)
-                {
-                    if (_currentPlaylistIndex != playlistIndex)
-                    {
-                        OnMediaChanged(_currentPlaylistIndex, _currentPositionTicks, playlistIndex);
-                    }
-
-                    _currentPositionTicks = currentPositionTicks;
-                    _currentPlaylistIndex = playlistIndex;
-                }
-
-                if (playstate.Equals("playing", StringComparison.OrdinalIgnoreCase))
-                {
-                    HasStartedPlaying = true;
-                    PlayState = PlayState.Playing;
-                }
-                else if (playstate.Equals("paused", StringComparison.OrdinalIgnoreCase))
-                {
-                    HasStartedPlaying = true;
-                    PlayState = PlayState.Paused;
-                }
-            }
-        }
-
-        /// <summary>
-        /// Gets the index of the playlist.
-        /// </summary>
-        /// <param name="nowPlayingPath">The now playing path.</param>
-        /// <returns>System.Int32.</returns>
-        private int GetPlaylistIndex(string nowPlayingPath)
-        {
-            for (var i = 0; i < Playlist.Count; i++)
-            {
-                var item = Playlist[i];
-
-                var pathArg = GetPathForCommandLine(item);
-
-                if (pathArg.Equals(nowPlayingPath, StringComparison.OrdinalIgnoreCase))
-                {
-                    return i;
-                }
-
-                if (item.VideoType.HasValue)
-                {
-                    if (item.VideoType.Value == VideoType.BluRay || item.VideoType.Value == VideoType.Dvd || item.VideoType.Value == VideoType.HdDvd)
-                    {
-                        if (nowPlayingPath.StartsWith(pathArg, StringComparison.OrdinalIgnoreCase))
-                        {
-                            return i;
-                        }
-                    }
-                }
-            }
-            return -1;
-        }
-
-        /// <summary>
-        /// Called when [player stopped internal].
-        /// </summary>
-        protected override void OnPlayerStoppedInternal()
-        {
-            HttpInterfaceCancellationTokenSource.Cancel();
-
-            DisposeStatusTimer();
-            _currentPositionTicks = null;
-            _currentPlaylistIndex = 0;
-            HasStartedPlaying = false;
-            HttpInterfaceCancellationTokenSource = null;
-
-            base.OnPlayerStoppedInternal();
-        }
-
-        /// <summary>
-        /// Disposes the status timer.
-        /// </summary>
-        private void DisposeStatusTimer()
-        {
-            if (StatusUpdateTimer != null)
-            {
-                StatusUpdateTimer.Dispose();
-            }
-        }
-
-        /// <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)
-            {
-                DisposeStatusTimer();
-
-                MpcHttpInterfaceResourcePool.Dispose();
-            }
-
-            base.Dispose(dispose);
-        }
-
-        /// <summary>
-        /// Seeks the internal.
-        /// </summary>
-        /// <param name="positionTicks">The position ticks.</param>
-        /// <returns>Task.</returns>
-        protected override Task SeekInternal(long positionTicks)
-        {
-            var additionalParams = new Dictionary<string, string>();
-
-            var time = TimeSpan.FromTicks(positionTicks);
-
-            var timeString = time.Hours + ":" + time.Minutes + ":" + time.Seconds;
-
-            additionalParams.Add("position", timeString);
-
-            return SendCommandToPlayer("-1", additionalParams);
-        }
-
-        /// <summary>
-        /// Pauses the internal.
-        /// </summary>
-        /// <returns>Task.</returns>
-        protected override Task PauseInternal()
-        {
-            return SendCommandToPlayer("888", new Dictionary<string, string>());
-        }
-
-        /// <summary>
-        /// Uns the pause internal.
-        /// </summary>
-        /// <returns>Task.</returns>
-        protected override Task UnPauseInternal()
-        {
-            return SendCommandToPlayer("887", new Dictionary<string, string>());
-        }
-
-        /// <summary>
-        /// Stops the internal.
-        /// </summary>
-        /// <returns>Task.</returns>
-        protected override Task StopInternal()
-        {
-            return SendCommandToPlayer("890", new Dictionary<string, string>());
-        }
-
-        /// <summary>
-        /// Closes the player.
-        /// </summary>
-        /// <returns>Task.</returns>
-        protected Task ClosePlayer()
-        {
-            return SendCommandToPlayer("816", new Dictionary<string, string>());
-        }
-
-        /// <summary>
-        /// Sends a command to MPC using the HTTP interface
-        /// http://www.autohotkey.net/~specter333/MPC/HTTP%20Commands.txt
-        /// </summary>
-        /// <param name="commandNumber">The command number.</param>
-        /// <param name="additionalParams">The additional params.</param>
-        /// <returns>Task.</returns>
-        /// <exception cref="System.ArgumentNullException">commandNumber</exception>
-        private async Task SendCommandToPlayer(string commandNumber, Dictionary<string, string> additionalParams)
-        {
-            if (string.IsNullOrEmpty(commandNumber))
-            {
-                throw new ArgumentNullException("commandNumber");
-            }
-
-            if (additionalParams == null)
-            {
-                throw new ArgumentNullException("additionalParams");
-            }
-
-            var url = CommandUrl + "?wm_command=" + commandNumber;
-
-            url = additionalParams.Keys.Aggregate(url, (current, name) => current + ("&" + name + "=" + additionalParams[name]));
-
-            Logger.Info("Sending command to MPC: " + url);
-
-            try
-            {
-                using (var stream = await UIKernel.Instance.HttpManager.Get(url, MpcHttpInterfaceResourcePool, HttpInterfaceCancellationTokenSource.Token).ConfigureAwait(false))
-                {
-                }
-            }
-            catch (HttpRequestException ex)
-            {
-                Logger.ErrorException("Error connecting to MpcHc command interface", ex);
-            }
-            catch (OperationCanceledException)
-            {
-                // Manually cancelled by us
-                Logger.Info("Command request cancelled");
-            }
-        }
-
-        /// <summary>
-        /// Gets a value indicating whether this instance can pause.
-        /// </summary>
-        /// <value><c>true</c> if this instance can pause; otherwise, <c>false</c>.</value>
-        public override bool CanPause
-        {
-            get
-            {
-                return true;
-            }
-        }
-
-        /// <summary>
-        /// Gets the server name that the http interface will be running on
-        /// </summary>
-        /// <value>The HTTP server.</value>
-        private string HttpServer
-        {
-            get
-            {
-                return "localhost";
-            }
-        }
-
-        /// <summary>
-        /// Gets the port that the web interface will be running on
-        /// </summary>
-        /// <value>The HTTP port.</value>
-        private string HttpPort
-        {
-            get
-            {
-                return "13579";
-            }
-        }
-
-        /// <summary>
-        /// Gets the url of that will be called to for status
-        /// </summary>
-        /// <value>The status URL.</value>
-        private string StatusUrl
-        {
-            get
-            {
-                return "http://" + HttpServer + ":" + HttpPort + "/status.html";
-            }
-        }
-
-        /// <summary>
-        /// Gets the url of that will be called to send commands
-        /// </summary>
-        /// <value>The command URL.</value>
-        private string CommandUrl
-        {
-            get
-            {
-                return "http://" + HttpServer + ":" + HttpPort + "/command.html";
-            }
-        }
-    }
-}

+ 0 - 32
MediaBrowser.Plugins.MpcHc/Plugin.cs

@@ -1,32 +0,0 @@
-using MediaBrowser.Common.Plugins;
-using MediaBrowser.Model.Plugins;
-using System;
-using System.ComponentModel.Composition;
-
-namespace MediaBrowser.Plugins.MpcHc
-{
-    /// <summary>
-    /// Class Plugin
-    /// </summary>
-    [Export(typeof(IPlugin))]
-    public class Plugin : BaseUiPlugin<BasePluginConfiguration>
-    {
-        /// <summary>
-        /// Gets the name of the plugin
-        /// </summary>
-        /// <value>The name.</value>
-        public override string Name
-        {
-            get { return "MPC-HC Integration"; }
-        }
-
-        /// <summary>
-        /// Gets the minimum required UI version.
-        /// </summary>
-        /// <value>The minimum required UI version.</value>
-        public override Version MinimumRequiredUIVersion
-        {
-            get { return new Version("2.9.4782.23738"); }
-        }
-    }
-}

+ 0 - 53
MediaBrowser.Plugins.MpcHc/Properties/AssemblyInfo.cs

@@ -1,53 +0,0 @@
-using System.Reflection;
-using System.Runtime.InteropServices;
-using System.Windows;
-
-// General Information about an assembly is controlled through the following 
-// set of attributes. Change these attribute values to modify the information
-// associated with an assembly.
-[assembly: AssemblyTitle("MediaBrowser.Plugins.MpcHc")]
-[assembly: AssemblyDescription("")]
-[assembly: AssemblyConfiguration("")]
-[assembly: AssemblyCompany("")]
-[assembly: AssemblyProduct("MediaBrowser.Plugins.MpcHc")]
-[assembly: AssemblyCopyright("Copyright ©  2013")]
-[assembly: AssemblyTrademark("")]
-[assembly: AssemblyCulture("")]
-
-// Setting ComVisible to false makes the types in this assembly not visible 
-// to COM components.  If you need to access a type in this assembly from 
-// COM, set the ComVisible attribute to true on that type.
-[assembly: ComVisible(false)]
-
-//In order to begin building localizable applications, set 
-//<UICulture>CultureYouAreCodingWith</UICulture> in your .csproj file
-//inside a <PropertyGroup>.  For example, if you are using US english
-//in your source files, set the <UICulture> to en-US.  Then uncomment
-//the NeutralResourceLanguage attribute below.  Update the "en-US" in
-//the line below to match the UICulture setting in the project file.
-
-//[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.Satellite)]
-
-
-[assembly:ThemeInfo(
-    ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located
-                             //(used if a resource is not found in the page, 
-                             // or application resource dictionaries)
-    ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located
-                                      //(used if a resource is not found in the page, 
-                                      // app, or any theme specific resource dictionaries)
-)]
-
-[assembly: Guid("F6D17656-25FE-4564-9246-B4584F797348")]
-
-// Version information for an assembly consists of the following four values:
-//
-//      Major Version
-//      Minor Version 
-//      Build Number
-//      Revision
-//
-// You can specify all the values or you can default the Build and Revision Numbers 
-// by using the '*' as shown below:
-// [assembly: AssemblyVersion("1.0.*")]
-[assembly: AssemblyVersion("1.0.*")]

+ 0 - 62
MediaBrowser.Plugins.MpcHc/Properties/Resources.Designer.cs

@@ -1,62 +0,0 @@
-//------------------------------------------------------------------------------
-// <auto-generated>
-//     This code was generated by a tool.
-//     Runtime Version:4.0.30319.18010
-//
-//     Changes to this file may cause incorrect behavior and will be lost if
-//     the code is regenerated.
-// </auto-generated>
-//------------------------------------------------------------------------------
-
-namespace MediaBrowser.Plugins.MpcHc.Properties {
-    
-    
-    /// <summary>
-    ///   A strongly-typed resource class, for looking up localized strings, etc.
-    /// </summary>
-    // This class was auto-generated by the StronglyTypedResourceBuilder
-    // class via a tool like ResGen or Visual Studio.
-    // To add or remove a member, edit your .ResX file then rerun ResGen
-    // with the /str option, or rebuild your VS project.
-    [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
-    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
-    [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
-    internal class Resources {
-        
-        private static global::System.Resources.ResourceManager resourceMan;
-        
-        private static global::System.Globalization.CultureInfo resourceCulture;
-        
-        [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
-        internal Resources() {
-        }
-        
-        /// <summary>
-        ///   Returns the cached ResourceManager instance used by this class.
-        /// </summary>
-        [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
-        internal static global::System.Resources.ResourceManager ResourceManager {
-            get {
-                if ((resourceMan == null)) {
-                    global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("MediaBrowser.Plugins.MpcHc.Properties.Resources", typeof(Resources).Assembly);
-                    resourceMan = temp;
-                }
-                return resourceMan;
-            }
-        }
-        
-        /// <summary>
-        ///   Overrides the current thread's CurrentUICulture property for all
-        ///   resource lookups using this strongly typed resource class.
-        /// </summary>
-        [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
-        internal static global::System.Globalization.CultureInfo Culture {
-            get {
-                return resourceCulture;
-            }
-            set {
-                resourceCulture = value;
-            }
-        }
-    }
-}

+ 0 - 117
MediaBrowser.Plugins.MpcHc/Properties/Resources.resx

@@ -1,117 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<root>
-  <!-- 
-    Microsoft ResX Schema 
-    
-    Version 2.0
-    
-    The primary goals of this format is to allow a simple XML format 
-    that is mostly human readable. The generation and parsing of the 
-    various data types are done through the TypeConverter classes 
-    associated with the data types.
-    
-    Example:
-    
-    ... ado.net/XML headers & schema ...
-    <resheader name="resmimetype">text/microsoft-resx</resheader>
-    <resheader name="version">2.0</resheader>
-    <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
-    <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
-    <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
-    <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
-    <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
-        <value>[base64 mime encoded serialized .NET Framework object]</value>
-    </data>
-    <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
-        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
-        <comment>This is a comment</comment>
-    </data>
-                
-    There are any number of "resheader" rows that contain simple 
-    name/value pairs.
-    
-    Each data row contains a name, and value. The row also contains a 
-    type or mimetype. Type corresponds to a .NET class that support 
-    text/value conversion through the TypeConverter architecture. 
-    Classes that don't support this are serialized and stored with the 
-    mimetype set.
-    
-    The mimetype is used for serialized objects, and tells the 
-    ResXResourceReader how to depersist the object. This is currently not 
-    extensible. For a given mimetype the value must be set accordingly:
-    
-    Note - application/x-microsoft.net.object.binary.base64 is the format 
-    that the ResXResourceWriter will generate, however the reader can 
-    read any of the formats listed below.
-    
-    mimetype: application/x-microsoft.net.object.binary.base64
-    value   : The object must be serialized with 
-            : System.Serialization.Formatters.Binary.BinaryFormatter
-            : and then encoded with base64 encoding.
-    
-    mimetype: application/x-microsoft.net.object.soap.base64
-    value   : The object must be serialized with 
-            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
-            : and then encoded with base64 encoding.
-
-    mimetype: application/x-microsoft.net.object.bytearray.base64
-    value   : The object must be serialized into a byte array 
-            : using a System.ComponentModel.TypeConverter
-            : and then encoded with base64 encoding.
-    -->
-  <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
-    <xsd:element name="root" msdata:IsDataSet="true">
-      <xsd:complexType>
-        <xsd:choice maxOccurs="unbounded">
-          <xsd:element name="metadata">
-            <xsd:complexType>
-              <xsd:sequence>
-                <xsd:element name="value" type="xsd:string" minOccurs="0" />
-              </xsd:sequence>
-              <xsd:attribute name="name" type="xsd:string" />
-              <xsd:attribute name="type" type="xsd:string" />
-              <xsd:attribute name="mimetype" type="xsd:string" />
-            </xsd:complexType>
-          </xsd:element>
-          <xsd:element name="assembly">
-            <xsd:complexType>
-              <xsd:attribute name="alias" type="xsd:string" />
-              <xsd:attribute name="name" type="xsd:string" />
-            </xsd:complexType>
-          </xsd:element>
-          <xsd:element name="data">
-            <xsd:complexType>
-              <xsd:sequence>
-                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
-                <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
-              </xsd:sequence>
-              <xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" />
-              <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
-              <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
-            </xsd:complexType>
-          </xsd:element>
-          <xsd:element name="resheader">
-            <xsd:complexType>
-              <xsd:sequence>
-                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
-              </xsd:sequence>
-              <xsd:attribute name="name" type="xsd:string" use="required" />
-            </xsd:complexType>
-          </xsd:element>
-        </xsd:choice>
-      </xsd:complexType>
-    </xsd:element>
-  </xsd:schema>
-  <resheader name="resmimetype">
-    <value>text/microsoft-resx</value>
-  </resheader>
-  <resheader name="version">
-    <value>2.0</value>
-  </resheader>
-  <resheader name="reader">
-    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
-  </resheader>
-  <resheader name="writer">
-    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
-  </resheader>
-</root>

+ 0 - 30
MediaBrowser.Plugins.MpcHc/Properties/Settings.Designer.cs

@@ -1,30 +0,0 @@
-//------------------------------------------------------------------------------
-// <auto-generated>
-//     This code was generated by a tool.
-//     Runtime Version:4.0.30319.18010
-//
-//     Changes to this file may cause incorrect behavior and will be lost if
-//     the code is regenerated.
-// </auto-generated>
-//------------------------------------------------------------------------------
-
-namespace MediaBrowser.Plugins.MpcHc.Properties
-{
-    
-    
-    [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
-    [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")]
-    internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase
-    {
-        
-        private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
-        
-        public static Settings Default
-        {
-            get
-            {
-                return defaultInstance;
-            }
-        }
-    }
-}

+ 0 - 7
MediaBrowser.Plugins.MpcHc/Properties/Settings.settings

@@ -1,7 +0,0 @@
-<?xml version='1.0' encoding='utf-8'?>
-<SettingsFile xmlns="uri:settings" CurrentProfile="(Default)">
-  <Profiles>
-    <Profile Name="(Default)" />
-  </Profiles>
-  <Settings />
-</SettingsFile>

+ 0 - 11
MediaBrowser.Plugins.MpcHc/app.config

@@ -1,11 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<configuration>
-  <runtime>
-    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
-      <dependentAssembly>
-        <assemblyIdentity name="NLog" publicKeyToken="5120e14c03d0593c" culture="neutral" />
-        <bindingRedirect oldVersion="0.0.0.0-2.0.0.0" newVersion="2.0.0.0" />
-      </dependentAssembly>
-    </assemblyBinding>
-  </runtime>
-</configuration>

+ 0 - 108
MediaBrowser.Plugins.Tmt5/MediaBrowser.Plugins.Tmt5.csproj

@@ -1,108 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
-  <PropertyGroup>
-    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
-    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
-    <ProjectGuid>{BE9BAA85-9EF2-4308-92E4-0D2B6E33C487}</ProjectGuid>
-    <OutputType>library</OutputType>
-    <AppDesignerFolder>Properties</AppDesignerFolder>
-    <RootNamespace>MediaBrowser.Plugins.Tmt5</RootNamespace>
-    <AssemblyName>MediaBrowser.Plugins.Tmt5</AssemblyName>
-    <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
-    <FileAlignment>512</FileAlignment>
-    <ProjectTypeGuids>{60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
-    <WarningLevel>4</WarningLevel>
-    <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\</SolutionDir>
-    <RestorePackages>true</RestorePackages>
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
-    <DebugSymbols>true</DebugSymbols>
-    <DebugType>full</DebugType>
-    <Optimize>false</Optimize>
-    <OutputPath>bin\Debug\</OutputPath>
-    <DefineConstants>DEBUG;TRACE</DefineConstants>
-    <ErrorReport>prompt</ErrorReport>
-    <WarningLevel>4</WarningLevel>
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
-    <DebugType>pdbonly</DebugType>
-    <Optimize>true</Optimize>
-    <OutputPath>bin\Release\</OutputPath>
-    <DefineConstants>TRACE</DefineConstants>
-    <ErrorReport>prompt</ErrorReport>
-    <WarningLevel>4</WarningLevel>
-  </PropertyGroup>
-  <PropertyGroup>
-    <RunPostBuildEvent>Always</RunPostBuildEvent>
-  </PropertyGroup>
-  <ItemGroup>
-    <Reference Include="System" />
-    <Reference Include="System.ComponentModel.Composition" />
-    <Reference Include="System.Data" />
-    <Reference Include="System.Xml" />
-    <Reference Include="Microsoft.CSharp" />
-    <Reference Include="System.Core" />
-    <Reference Include="System.Xml.Linq" />
-    <Reference Include="System.Data.DataSetExtensions" />
-    <Reference Include="System.Xaml">
-      <RequiredTargetFramework>4.0</RequiredTargetFramework>
-    </Reference>
-    <Reference Include="WindowsBase" />
-    <Reference Include="PresentationCore" />
-    <Reference Include="PresentationFramework" />
-  </ItemGroup>
-  <ItemGroup>
-    <Compile Include="Tmt5MediaPlayer.cs" />
-    <Compile Include="Plugin.cs" />
-    <Compile Include="Properties\AssemblyInfo.cs">
-      <SubType>Code</SubType>
-    </Compile>
-    <Compile Include="Properties\Resources.Designer.cs">
-      <AutoGen>True</AutoGen>
-      <DesignTime>True</DesignTime>
-      <DependentUpon>Resources.resx</DependentUpon>
-    </Compile>
-    <Compile Include="Properties\Settings.Designer.cs">
-      <AutoGen>True</AutoGen>
-      <DependentUpon>Settings.settings</DependentUpon>
-      <DesignTimeSharedInput>True</DesignTimeSharedInput>
-    </Compile>
-    <EmbeddedResource Include="Properties\Resources.resx">
-      <Generator>ResXFileCodeGenerator</Generator>
-      <LastGenOutput>Resources.Designer.cs</LastGenOutput>
-    </EmbeddedResource>
-    <None Include="app.config" />
-    <None Include="Properties\Settings.settings">
-      <Generator>SettingsSingleFileGenerator</Generator>
-      <LastGenOutput>Settings.Designer.cs</LastGenOutput>
-    </None>
-    <AppDesigner Include="Properties\" />
-  </ItemGroup>
-  <ItemGroup>
-    <ProjectReference Include="..\MediaBrowser.Common\MediaBrowser.Common.csproj">
-      <Project>{9142eefa-7570-41e1-bfcc-468bb571af2f}</Project>
-      <Name>MediaBrowser.Common</Name>
-    </ProjectReference>
-    <ProjectReference Include="..\MediaBrowser.Model\MediaBrowser.Model.csproj">
-      <Project>{7eeeb4bb-f3e8-48fc-b4c5-70f0fff8329b}</Project>
-      <Name>MediaBrowser.Model</Name>
-    </ProjectReference>
-    <ProjectReference Include="..\MediaBrowser.UI\MediaBrowser.UI.csproj">
-      <Project>{b5ece1fb-618e-420b-9a99-8e972d76920a}</Project>
-      <Name>MediaBrowser.UI</Name>
-    </ProjectReference>
-  </ItemGroup>
-  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
-  <PropertyGroup>
-    <PostBuildEvent>xcopy "$(TargetPath)" "$(SolutionDir)\ProgramData-Server\Plugins\" /y</PostBuildEvent>
-  </PropertyGroup>
-  <Import Project="$(SolutionDir)\.nuget\nuget.targets" />
-  <!-- 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">
-  </Target>
-  <Target Name="AfterBuild">
-  </Target>
-  -->
-</Project>

+ 0 - 32
MediaBrowser.Plugins.Tmt5/Plugin.cs

@@ -1,32 +0,0 @@
-using MediaBrowser.Common.Plugins;
-using MediaBrowser.Model.Plugins;
-using System;
-using System.ComponentModel.Composition;
-
-namespace MediaBrowser.Plugins.Tmt5
-{
-    /// <summary>
-    /// Class Plugin
-    /// </summary>
-    [Export(typeof(IPlugin))]
-    public class Plugin : BaseUiPlugin<BasePluginConfiguration>
-    {
-        /// <summary>
-        /// Gets the name of the plugin
-        /// </summary>
-        /// <value>The name.</value>
-        public override string Name
-        {
-            get { return "TMT5 Integration"; }
-        }
-
-        /// <summary>
-        /// Gets the minimum required UI version.
-        /// </summary>
-        /// <value>The minimum required UI version.</value>
-        public override Version MinimumRequiredUIVersion
-        {
-            get { return new Version("2.9.4782.23738"); }
-        }
-    }
-}

+ 0 - 53
MediaBrowser.Plugins.Tmt5/Properties/AssemblyInfo.cs

@@ -1,53 +0,0 @@
-using System.Reflection;
-using System.Runtime.InteropServices;
-using System.Windows;
-
-// General Information about an assembly is controlled through the following 
-// set of attributes. Change these attribute values to modify the information
-// associated with an assembly.
-[assembly: AssemblyTitle("MediaBrowser.Plugins.Tmt5")]
-[assembly: AssemblyDescription("")]
-[assembly: AssemblyConfiguration("")]
-[assembly: AssemblyCompany("")]
-[assembly: AssemblyProduct("MediaBrowser.Plugins.Tmt5")]
-[assembly: AssemblyCopyright("Copyright ©  2013")]
-[assembly: AssemblyTrademark("")]
-[assembly: AssemblyCulture("")]
-
-// Setting ComVisible to false makes the types in this assembly not visible 
-// to COM components.  If you need to access a type in this assembly from 
-// COM, set the ComVisible attribute to true on that type.
-[assembly: ComVisible(false)]
-
-//In order to begin building localizable applications, set 
-//<UICulture>CultureYouAreCodingWith</UICulture> in your .csproj file
-//inside a <PropertyGroup>.  For example, if you are using US english
-//in your source files, set the <UICulture> to en-US.  Then uncomment
-//the NeutralResourceLanguage attribute below.  Update the "en-US" in
-//the line below to match the UICulture setting in the project file.
-
-//[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.Satellite)]
-
-
-[assembly:ThemeInfo(
-    ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located
-                             //(used if a resource is not found in the page, 
-                             // or application resource dictionaries)
-    ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located
-                                      //(used if a resource is not found in the page, 
-                                      // app, or any theme specific resource dictionaries)
-)]
-
-[assembly: Guid("3921C21B-B8C0-46C2-92DE-CC0E1FE0C434")]
-
-// Version information for an assembly consists of the following four values:
-//
-//      Major Version
-//      Minor Version 
-//      Build Number
-//      Revision
-//
-// You can specify all the values or you can default the Build and Revision Numbers 
-// by using the '*' as shown below:
-// [assembly: AssemblyVersion("1.0.*")]
-[assembly: AssemblyVersion("1.0.*")]

+ 0 - 62
MediaBrowser.Plugins.Tmt5/Properties/Resources.Designer.cs

@@ -1,62 +0,0 @@
-//------------------------------------------------------------------------------
-// <auto-generated>
-//     This code was generated by a tool.
-//     Runtime Version:4.0.30319.18010
-//
-//     Changes to this file may cause incorrect behavior and will be lost if
-//     the code is regenerated.
-// </auto-generated>
-//------------------------------------------------------------------------------
-
-namespace MediaBrowser.Plugins.Tmt5.Properties {
-    
-    
-    /// <summary>
-    ///   A strongly-typed resource class, for looking up localized strings, etc.
-    /// </summary>
-    // This class was auto-generated by the StronglyTypedResourceBuilder
-    // class via a tool like ResGen or Visual Studio.
-    // To add or remove a member, edit your .ResX file then rerun ResGen
-    // with the /str option, or rebuild your VS project.
-    [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
-    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
-    [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
-    internal class Resources {
-        
-        private static global::System.Resources.ResourceManager resourceMan;
-        
-        private static global::System.Globalization.CultureInfo resourceCulture;
-        
-        [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
-        internal Resources() {
-        }
-        
-        /// <summary>
-        ///   Returns the cached ResourceManager instance used by this class.
-        /// </summary>
-        [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
-        internal static global::System.Resources.ResourceManager ResourceManager {
-            get {
-                if ((resourceMan == null)) {
-                    global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("MediaBrowser.Plugins.Tmt5.Properties.Resources", typeof(Resources).Assembly);
-                    resourceMan = temp;
-                }
-                return resourceMan;
-            }
-        }
-        
-        /// <summary>
-        ///   Overrides the current thread's CurrentUICulture property for all
-        ///   resource lookups using this strongly typed resource class.
-        /// </summary>
-        [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
-        internal static global::System.Globalization.CultureInfo Culture {
-            get {
-                return resourceCulture;
-            }
-            set {
-                resourceCulture = value;
-            }
-        }
-    }
-}

+ 0 - 117
MediaBrowser.Plugins.Tmt5/Properties/Resources.resx

@@ -1,117 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<root>
-  <!-- 
-    Microsoft ResX Schema 
-    
-    Version 2.0
-    
-    The primary goals of this format is to allow a simple XML format 
-    that is mostly human readable. The generation and parsing of the 
-    various data types are done through the TypeConverter classes 
-    associated with the data types.
-    
-    Example:
-    
-    ... ado.net/XML headers & schema ...
-    <resheader name="resmimetype">text/microsoft-resx</resheader>
-    <resheader name="version">2.0</resheader>
-    <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
-    <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
-    <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
-    <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
-    <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
-        <value>[base64 mime encoded serialized .NET Framework object]</value>
-    </data>
-    <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
-        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
-        <comment>This is a comment</comment>
-    </data>
-                
-    There are any number of "resheader" rows that contain simple 
-    name/value pairs.
-    
-    Each data row contains a name, and value. The row also contains a 
-    type or mimetype. Type corresponds to a .NET class that support 
-    text/value conversion through the TypeConverter architecture. 
-    Classes that don't support this are serialized and stored with the 
-    mimetype set.
-    
-    The mimetype is used for serialized objects, and tells the 
-    ResXResourceReader how to depersist the object. This is currently not 
-    extensible. For a given mimetype the value must be set accordingly:
-    
-    Note - application/x-microsoft.net.object.binary.base64 is the format 
-    that the ResXResourceWriter will generate, however the reader can 
-    read any of the formats listed below.
-    
-    mimetype: application/x-microsoft.net.object.binary.base64
-    value   : The object must be serialized with 
-            : System.Serialization.Formatters.Binary.BinaryFormatter
-            : and then encoded with base64 encoding.
-    
-    mimetype: application/x-microsoft.net.object.soap.base64
-    value   : The object must be serialized with 
-            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
-            : and then encoded with base64 encoding.
-
-    mimetype: application/x-microsoft.net.object.bytearray.base64
-    value   : The object must be serialized into a byte array 
-            : using a System.ComponentModel.TypeConverter
-            : and then encoded with base64 encoding.
-    -->
-  <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
-    <xsd:element name="root" msdata:IsDataSet="true">
-      <xsd:complexType>
-        <xsd:choice maxOccurs="unbounded">
-          <xsd:element name="metadata">
-            <xsd:complexType>
-              <xsd:sequence>
-                <xsd:element name="value" type="xsd:string" minOccurs="0" />
-              </xsd:sequence>
-              <xsd:attribute name="name" type="xsd:string" />
-              <xsd:attribute name="type" type="xsd:string" />
-              <xsd:attribute name="mimetype" type="xsd:string" />
-            </xsd:complexType>
-          </xsd:element>
-          <xsd:element name="assembly">
-            <xsd:complexType>
-              <xsd:attribute name="alias" type="xsd:string" />
-              <xsd:attribute name="name" type="xsd:string" />
-            </xsd:complexType>
-          </xsd:element>
-          <xsd:element name="data">
-            <xsd:complexType>
-              <xsd:sequence>
-                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
-                <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
-              </xsd:sequence>
-              <xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" />
-              <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
-              <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
-            </xsd:complexType>
-          </xsd:element>
-          <xsd:element name="resheader">
-            <xsd:complexType>
-              <xsd:sequence>
-                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
-              </xsd:sequence>
-              <xsd:attribute name="name" type="xsd:string" use="required" />
-            </xsd:complexType>
-          </xsd:element>
-        </xsd:choice>
-      </xsd:complexType>
-    </xsd:element>
-  </xsd:schema>
-  <resheader name="resmimetype">
-    <value>text/microsoft-resx</value>
-  </resheader>
-  <resheader name="version">
-    <value>2.0</value>
-  </resheader>
-  <resheader name="reader">
-    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
-  </resheader>
-  <resheader name="writer">
-    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
-  </resheader>
-</root>

+ 0 - 30
MediaBrowser.Plugins.Tmt5/Properties/Settings.Designer.cs

@@ -1,30 +0,0 @@
-//------------------------------------------------------------------------------
-// <auto-generated>
-//     This code was generated by a tool.
-//     Runtime Version:4.0.30319.18010
-//
-//     Changes to this file may cause incorrect behavior and will be lost if
-//     the code is regenerated.
-// </auto-generated>
-//------------------------------------------------------------------------------
-
-namespace MediaBrowser.Plugins.Tmt5.Properties
-{
-    
-    
-    [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
-    [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")]
-    internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase
-    {
-        
-        private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
-        
-        public static Settings Default
-        {
-            get
-            {
-                return defaultInstance;
-            }
-        }
-    }
-}

+ 0 - 7
MediaBrowser.Plugins.Tmt5/Properties/Settings.settings

@@ -1,7 +0,0 @@
-<?xml version='1.0' encoding='utf-8'?>
-<SettingsFile xmlns="uri:settings" CurrentProfile="(Default)">
-  <Profiles>
-    <Profile Name="(Default)" />
-  </Profiles>
-  <Settings />
-</SettingsFile>

+ 0 - 405
MediaBrowser.Plugins.Tmt5/Tmt5MediaPlayer.cs

@@ -1,405 +0,0 @@
-using MediaBrowser.Common.IO;
-using MediaBrowser.Model.Dto;
-using MediaBrowser.Model.Logging;
-using MediaBrowser.UI.Configuration;
-using MediaBrowser.UI.Playback;
-using MediaBrowser.UI.Playback.ExternalPlayer;
-using System;
-using System.Collections.Generic;
-using System.Collections.Specialized;
-using System.ComponentModel.Composition;
-using System.Diagnostics;
-using System.Globalization;
-using System.IO;
-using System.Threading.Tasks;
-
-namespace MediaBrowser.Plugins.Tmt5
-{
-    /// <summary>
-    /// Class GenericExternalPlayer
-    /// </summary>
-    [Export(typeof(BaseMediaPlayer))]
-    public class Tmt5MediaPlayer : BaseExternalPlayer
-    {
-        [ImportingConstructor]
-        public Tmt5MediaPlayer([Import("logger")] ILogger logger)
-            : base(logger)
-        {
-        }
-
-        /// <summary>
-        /// Gets the name.
-        /// </summary>
-        /// <value>The name.</value>
-        public override string Name
-        {
-            get { return "TMT5"; }
-        }
-
-        /// <summary>
-        /// Gets a value indicating whether this instance can pause.
-        /// </summary>
-        /// <value><c>true</c> if this instance can pause; otherwise, <c>false</c>.</value>
-        public override bool CanPause
-        {
-            get
-            {
-                return true;
-            }
-        }
-
-        /// <summary>
-        /// Gets a value indicating whether this instance can close automatically.
-        /// </summary>
-        /// <value><c>true</c> if this instance can close automatically; otherwise, <c>false</c>.</value>
-        protected override bool CanCloseAutomatically
-        {
-            get
-            {
-                return true;
-            }
-        }
-
-        /// <summary>
-        /// Gets the play state directory.
-        /// </summary>
-        /// <value>The play state directory.</value>
-        private string PlayStateDirectory
-        {
-            get
-            {
-                return Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "ArcSoft");
-            }
-        }
-
-
-        /// <summary>
-        /// The _current position ticks
-        /// </summary>
-        private long? _currentPositionTicks;
-
-        /// <summary>
-        /// Gets the current position ticks.
-        /// </summary>
-        /// <value>The current position ticks.</value>
-        public override long? CurrentPositionTicks
-        {
-            get
-            {
-                return _currentPositionTicks;
-            }
-        }
-
-        /// <summary>
-        /// The _current playlist index
-        /// </summary>
-        private int _currentPlaylistIndex;
-
-        /// <summary>
-        /// Gets the index of the current playlist.
-        /// </summary>
-        /// <value>The index of the current playlist.</value>
-        public override int CurrentPlaylistIndex
-        {
-            get
-            {
-                return _currentPlaylistIndex;
-            }
-        }
-
-        /// <summary>
-        /// Gets or sets the status file watcher.
-        /// </summary>
-        /// <value>The status file watcher.</value>
-        private FileSystemWatcher StatusFileWatcher { get; set; }
-
-        /// <summary>
-        /// Gets or sets a value indicating whether this instance has started playing.
-        /// </summary>
-        /// <value><c>true</c> if this instance has started playing; otherwise, <c>false</c>.</value>
-        private bool HasStartedPlaying { get; set; }
-
-        /// <summary>
-        /// Gets or sets a value indicating whether this instance has stopped playing.
-        /// </summary>
-        /// <value><c>true</c> if this instance has stopped playing; otherwise, <c>false</c>.</value>
-        private bool HasStoppedPlaying { get; set; }
-
-        /// <summary>
-        /// Determines whether this instance can play the specified item.
-        /// </summary>
-        /// <param name="item">The item.</param>
-        /// <returns><c>true</c> if this instance can play the specified item; otherwise, <c>false</c>.</returns>
-        public override bool CanPlay(BaseItemDto item)
-        {
-            return item.IsVideo || item.IsAudio;
-        }
-
-        /// <summary>
-        /// Called when [player stopped internal].
-        /// </summary>
-        protected override void OnPlayerStoppedInternal()
-        {
-            DisposeFileSystemWatcher();
-            HasStartedPlaying = false;
-            HasStoppedPlaying = false;
-            _currentPlaylistIndex = 0;
-            _currentPositionTicks = 0;
-
-            base.OnPlayerStoppedInternal();
-        }
-
-        /// <summary>
-        /// Gets the command arguments.
-        /// </summary>
-        /// <param name="items">The items.</param>
-        /// <param name="options">The options.</param>
-        /// <param name="playerConfiguration">The player configuration.</param>
-        /// <returns>System.String.</returns>
-        protected override string GetCommandArguments(List<BaseItemDto> items, PlayOptions options, PlayerConfiguration playerConfiguration)
-        {
-            return "\"" + items[0].Path + "\"";
-        }
-
-        /// <summary>
-        /// Called when [external player launched].
-        /// </summary>
-        protected override void OnExternalPlayerLaunched()
-        {
-            base.OnExternalPlayerLaunched();
-
-            // If the playstate directory exists, start watching it
-            if (Directory.Exists(PlayStateDirectory))
-            {
-                ReloadFileSystemWatcher();
-            }
-        }
-
-        /// <summary>
-        /// Pauses the internal.
-        /// </summary>
-        /// <returns>Task.</returns>
-        protected override Task PauseInternal()
-        {
-            return SendCommandToMMC("-pause");
-        }
-
-        /// <summary>
-        /// Uns the pause internal.
-        /// </summary>
-        /// <returns>Task.</returns>
-        protected override Task UnPauseInternal()
-        {
-            return SendCommandToMMC("-play");
-        }
-
-        /// <summary>
-        /// Stops the internal.
-        /// </summary>
-        /// <returns>Task.</returns>
-        protected override Task StopInternal()
-        {
-            return SendCommandToMMC("-stop");
-        }
-
-        /// <summary>
-        /// Closes the player.
-        /// </summary>
-        /// <returns>Task.</returns>
-        protected Task ClosePlayer()
-        {
-            return SendCommandToMMC("-close");
-        }
-
-        /// <summary>
-        /// Seeks the internal.
-        /// </summary>
-        /// <param name="positionTicks">The position ticks.</param>
-        /// <returns>Task.</returns>
-        /// <exception cref="System.InvalidOperationException">No media to seek to</exception>
-        protected override Task SeekInternal(long positionTicks)
-        {
-            if (CurrentMedia == null)
-            {
-                throw new InvalidOperationException("No media to seek to");
-            }
-
-            if (CurrentMedia.Chapters == null)
-            {
-                throw new InvalidOperationException("TMT5 cannot seek without chapter information");
-            }
-
-            var chapterIndex = 0;
-
-            for (var i = 0; i < CurrentMedia.Chapters.Count; i++)
-            {
-                if (CurrentMedia.Chapters[i].StartPositionTicks < positionTicks)
-                {
-                    chapterIndex = i;
-                }
-            }
-
-            return JumpToChapter(chapterIndex);
-        }
-
-        /// <summary>
-        /// Jumps to chapter.
-        /// </summary>
-        /// <param name="chapter">The chapter.</param>
-        /// <returns>Task.</returns>
-        protected Task JumpToChapter(int chapter)
-        {
-            return SendCommandToMMC(" -chapter " + chapter);
-        }
-
-        /// <summary>
-        /// Sends an arbitrary command to the TMT MMC console
-        /// </summary>
-        /// <param name="command">The command.</param>
-        /// <returns>Task.</returns>
-        protected Task SendCommandToMMC(string command)
-        {
-            return Task.Run(() =>
-            {
-                var directory = Path.GetDirectoryName(CurrentPlayerConfiguration.Command);
-
-                var processInfo = new ProcessStartInfo
-                {
-                    FileName = Path.Combine(directory, "MMCEDT5.exe"),
-                    Arguments = command,
-                    CreateNoWindow = true
-                };
-
-                Logger.Debug("{0} {1}", processInfo.FileName, processInfo.Arguments);
-
-                using (var process = Process.Start(processInfo))
-                {
-                    process.WaitForExit(2000);
-                }
-            });
-        }
-
-        /// <summary>
-        /// Reloads the file system watcher.
-        /// </summary>
-        private void ReloadFileSystemWatcher()
-        {
-            DisposeFileSystemWatcher();
-
-            Logger.Info("Watching TMT folder: " + PlayStateDirectory);
-
-            StatusFileWatcher = new FileSystemWatcher(PlayStateDirectory, "*.set")
-            {
-                IncludeSubdirectories = true
-            };
-
-            // Need to include subdirectories since there are subfolders undearneath this with the TMT version #.
-            StatusFileWatcher.Changed += StatusFileWatcher_Changed;
-            StatusFileWatcher.EnableRaisingEvents = true;
-        }
-
-        private static readonly CultureInfo UsCulture = new CultureInfo("en-US");
-
-        /// <summary>
-        /// Handles the Changed event of the StatusFileWatcher control.
-        /// </summary>
-        /// <param name="sender">The source of the event.</param>
-        /// <param name="e">The <see cref="FileSystemEventArgs" /> instance containing the event data.</param>
-        async void StatusFileWatcher_Changed(object sender, FileSystemEventArgs e)
-        {
-            Logger.Debug("TMT File Watcher reports change type {1} at {0}", e.FullPath, e.ChangeType);
-
-            NameValueCollection values;
-
-            try
-            {
-                values = FileSystem.ParseIniFile(e.FullPath);
-            }
-            catch (IOException)
-            {
-                // This can happen if the file is being written to at the exact moment we're trying to access it
-                // Unfortunately we kind of have to just eat it
-                return;
-            }
-
-            var tmtPlayState = values["State"];
-
-            if (tmtPlayState.Equals("play", StringComparison.OrdinalIgnoreCase))
-            {
-                PlayState = PlayState.Playing;
-
-                // Playback just started
-                HasStartedPlaying = true;
-
-                if (CurrentPlayOptions.StartPositionTicks > 0)
-                {
-                    SeekInternal(CurrentPlayOptions.StartPositionTicks);
-                }
-            }
-            else if (tmtPlayState.Equals("pause", StringComparison.OrdinalIgnoreCase))
-            {
-                PlayState = PlayState.Paused;
-            }
-
-            // If playback has previously started...
-            // First notify the Progress event handler
-            // Then check if playback has stopped
-            if (HasStartedPlaying)
-            {
-                TimeSpan currentPosition;
-
-                //TimeSpan.TryParse(values["TotalTime"], out currentDuration);
-
-                if (TimeSpan.TryParse(values["CurTime"], UsCulture, out currentPosition))
-                {
-                    _currentPositionTicks = currentPosition.Ticks;
-                }
-
-                _currentPlaylistIndex = 0;
-
-                // Playback has stopped
-                if (tmtPlayState.Equals("stop", StringComparison.OrdinalIgnoreCase))
-                {
-                    Logger.Info("Playstate changed to stopped");
-
-                    if (!HasStoppedPlaying)
-                    {
-                        HasStoppedPlaying = true;
-
-                        DisposeFileSystemWatcher();
-
-                        await ClosePlayer().ConfigureAwait(false);
-                    }
-                }
-            }
-        }
-
-        /// <summary>
-        /// Disposes the file system watcher.
-        /// </summary>
-        private void DisposeFileSystemWatcher()
-        {
-            if (StatusFileWatcher != null)
-            {
-                StatusFileWatcher.EnableRaisingEvents = false;
-                StatusFileWatcher.Changed -= StatusFileWatcher_Changed;
-                StatusFileWatcher.Dispose();
-                StatusFileWatcher = null;
-            }
-        }
-
-        /// <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)
-            {
-                DisposeFileSystemWatcher();
-            }
-
-            base.Dispose(dispose);
-        }
-    }
-}

+ 0 - 11
MediaBrowser.Plugins.Tmt5/app.config

@@ -1,11 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<configuration>
-  <runtime>
-    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
-      <dependentAssembly>
-        <assemblyIdentity name="NLog" publicKeyToken="5120e14c03d0593c" culture="neutral" />
-        <bindingRedirect oldVersion="0.0.0.0-2.0.0.0" newVersion="2.0.0.0" />
-      </dependentAssembly>
-    </assemblyBinding>
-  </runtime>
-</configuration>

+ 0 - 314
MediaBrowser.Plugins.Trailers/AppleTrailerListingDownloader.cs

@@ -1,314 +0,0 @@
-using MediaBrowser.Common.Extensions;
-using MediaBrowser.Controller;
-using MediaBrowser.Controller.Entities;
-using MediaBrowser.Controller.Extensions;
-using MediaBrowser.Model.Entities;
-using System;
-using System.Collections.Generic;
-using System.Globalization;
-using System.Threading;
-using System.Threading.Tasks;
-using System.Xml;
-
-namespace MediaBrowser.Plugins.Trailers
-{
-    /// <summary>
-    /// Fetches Apple's list of current movie trailers
-    /// </summary>
-    public static class AppleTrailerListingDownloader
-    {
-        /// <summary>
-        /// The trailer feed URL
-        /// </summary>
-        private const string TrailerFeedUrl = "http://trailers.apple.com/trailers/home/xml/current_720p.xml";
-
-        /// <summary>
-        /// Downloads a list of trailer info's from the apple url
-        /// </summary>
-        /// <returns>Task{List{TrailerInfo}}.</returns>
-        public static async Task<List<TrailerInfo>> GetTrailerList(CancellationToken cancellationToken)
-        {
-            var stream = await Kernel.Instance.HttpManager.Get(TrailerFeedUrl, Kernel.Instance.ResourcePools.AppleTrailerVideos, cancellationToken).ConfigureAwait(false);
-
-            var list = new List<TrailerInfo>();
-
-            using (var reader = XmlReader.Create(stream, new XmlReaderSettings { Async = true }))
-            {
-                await reader.MoveToContentAsync().ConfigureAwait(false);
-
-                while (await reader.ReadAsync().ConfigureAwait(false))
-                {
-                    cancellationToken.ThrowIfCancellationRequested();
-
-                    if (reader.NodeType == XmlNodeType.Element)
-                    {
-                        switch (reader.Name)
-                        {
-                            case "movieinfo":
-                                var trailer = FetchTrailerInfo(reader.ReadSubtree());
-                                list.Add(trailer);
-                                break;
-                        }
-                    }
-                }
-            }
-
-            return list;
-        }
-
-        /// <summary>
-        /// Fetches trailer info from an xml node
-        /// </summary>
-        /// <param name="reader">The reader.</param>
-        /// <returns>TrailerInfo.</returns>
-        private static TrailerInfo FetchTrailerInfo(XmlReader reader)
-        {
-            var trailerInfo = new TrailerInfo { };
-
-            reader.MoveToContent();
-
-            while (reader.Read())
-            {
-                if (reader.NodeType == XmlNodeType.Element)
-                {
-                    switch (reader.Name)
-                    {
-                        case "info":
-                            FetchInfo(reader.ReadSubtree(), trailerInfo);
-                            break;
-                        case "cast":
-                            FetchCast(reader.ReadSubtree(), trailerInfo);
-                            break;
-                        case "genre":
-                            FetchGenres(reader.ReadSubtree(), trailerInfo);
-                            break;
-                        case "poster":
-                            FetchPosterUrl(reader.ReadSubtree(), trailerInfo);
-                            break;
-                        case "preview":
-                            FetchTrailerUrl(reader.ReadSubtree(), trailerInfo);
-                            break;
-                        default:
-                            reader.Skip();
-                            break;
-                    }
-                }
-            }
-
-            return trailerInfo;
-        }
-
-        private static readonly CultureInfo USCulture = new CultureInfo("en-US");
-        
-        /// <summary>
-        /// Fetches from the info node
-        /// </summary>
-        /// <param name="reader">The reader.</param>
-        /// <param name="info">The info.</param>
-        private static void FetchInfo(XmlReader reader, TrailerInfo info)
-        {
-            reader.MoveToContent();
-            reader.Read();
-
-            while (reader.NodeType == XmlNodeType.Element)
-            {
-                switch (reader.Name)
-                {
-                    case "title":
-                        info.Video.Name = reader.ReadStringSafe();
-                        break;
-                    case "runtime":
-                        {
-                            var runtime = reader.ReadStringSafe();
-
-                            if (!string.IsNullOrWhiteSpace(runtime))
-                            {
-                                if (runtime.StartsWith(":", StringComparison.OrdinalIgnoreCase))
-                                {
-                                    runtime = "0" + runtime;
-                                }
-
-                                TimeSpan runtimeTimeSpan;
-
-                                if (TimeSpan.TryParse(runtime, USCulture, out runtimeTimeSpan))
-                                {
-                                    info.Video.RunTimeTicks = runtimeTimeSpan.Ticks;
-                                }
-                            }
-                            break;
-                        }
-                    case "rating":
-                        info.Video.OfficialRating = reader.ReadStringSafe();
-                        break;
-                    case "studio":
-                        {
-                            var studio = reader.ReadStringSafe();
-                            if (!string.IsNullOrWhiteSpace(studio))
-                            {
-                                info.Video.AddStudio(studio);
-                            }
-                            break;
-                        }
-                    case "postdate":
-                        {
-                            DateTime date;
-
-                            if (DateTime.TryParse(reader.ReadStringSafe(), USCulture, DateTimeStyles.None, out date))
-                            {
-                                info.PostDate = date;
-                            }
-                            break;
-                        }
-                    case "releasedate":
-                        {
-                            var val = reader.ReadStringSafe();
-
-                            if (!string.IsNullOrWhiteSpace(val))
-                            {
-                                DateTime date;
-
-                                if (DateTime.TryParse(val, USCulture, DateTimeStyles.None, out date))
-                                {
-                                    info.Video.PremiereDate = date;
-                                    info.Video.ProductionYear = date.Year;
-                                }
-                            }
-
-                            break;
-                        }
-                    case "director":
-                        {
-                            var directors = reader.ReadStringSafe() ?? string.Empty;
-
-                            foreach (var director in directors.Split(',', StringSplitOptions.RemoveEmptyEntries))
-                            {
-                                var name = director.Trim();
-
-                                if (!string.IsNullOrWhiteSpace(name))
-                                {
-                                    info.Video.AddPerson(new PersonInfo { Name = name, Type = PersonType.Director });
-                                }
-                            }
-                            break;
-                        }
-                    case "description":
-                        info.Video.Overview = reader.ReadStringSafe();
-                        break;
-                    default:
-                        reader.Skip();
-                        break;
-                }
-            }
-        }
-
-        /// <summary>
-        /// Fetches from the genre node
-        /// </summary>
-        /// <param name="reader">The reader.</param>
-        /// <param name="info">The info.</param>
-        private static void FetchGenres(XmlReader reader, TrailerInfo info)
-        {
-            reader.MoveToContent();
-            reader.Read();
-
-            while (reader.IsStartElement())
-            {
-                if (reader.NodeType == XmlNodeType.Element)
-                {
-                    switch (reader.Name)
-                    {
-                        case "name":
-                            info.Video.AddGenre(reader.ReadStringSafe());
-                            break;
-                        default:
-                            reader.Skip();
-                            break;
-                    }
-                }
-            }
-
-        }
-
-        /// <summary>
-        /// Fetches from the cast node
-        /// </summary>
-        /// <param name="reader">The reader.</param>
-        /// <param name="info">The info.</param>
-        private static void FetchCast(XmlReader reader, TrailerInfo info)
-        {
-            reader.MoveToContent();
-            reader.Read();
-
-            while (reader.IsStartElement())
-            {
-                if (reader.NodeType == XmlNodeType.Element)
-                {
-                    switch (reader.Name)
-                    {
-                        case "name":
-                            info.Video.AddPerson(new PersonInfo { Name = reader.ReadStringSafe(), Type = PersonType.Actor });
-                            break;
-                        default:
-                            reader.Skip();
-                            break;
-                    }
-                }
-            }
-
-        }
-
-        /// <summary>
-        /// Fetches from the preview node
-        /// </summary>
-        /// <param name="reader">The reader.</param>
-        /// <param name="info">The info.</param>
-        private static void FetchTrailerUrl(XmlReader reader, TrailerInfo info)
-        {
-            reader.MoveToContent();
-            reader.Read();
-
-            while (reader.NodeType == XmlNodeType.Element)
-            {
-                switch (reader.Name)
-                {
-                    case "large":
-                        info.TrailerUrl = reader.ReadStringSafe();
-                        break;
-                    default:
-                        reader.Skip();
-                        break;
-                }
-            }
-
-        }
-
-        /// <summary>
-        /// Fetches from the poster node
-        /// </summary>
-        /// <param name="reader">The reader.</param>
-        /// <param name="info">The info.</param>
-        private static void FetchPosterUrl(XmlReader reader, TrailerInfo info)
-        {
-            reader.MoveToContent();
-            reader.Read();
-
-            while (reader.NodeType == XmlNodeType.Element)
-            {
-                switch (reader.Name)
-                {
-                    case "location":
-                        info.ImageUrl = reader.ReadStringSafe();
-                        break;
-                    case "xlarge":
-                        info.HdImageUrl = reader.ReadStringSafe();
-                        break;
-                    default:
-                        reader.Skip();
-                        break;
-                }
-            }
-
-        }
-
-    }
-}

+ 0 - 46
MediaBrowser.Plugins.Trailers/Configuration/PluginConfiguration.cs

@@ -1,46 +0,0 @@
-using MediaBrowser.Model.Plugins;
-
-namespace MediaBrowser.Plugins.Trailers.Configuration
-{
-    /// <summary>
-    /// Class PluginConfiguration
-    /// </summary>
-    public class PluginConfiguration : BasePluginConfiguration
-    {
-        /// <summary>
-        /// Gets or sets the name of the folder.
-        /// </summary>
-        /// <value>The name of the folder.</value>
-        public string FolderName { get; set; }
-
-        /// <summary>
-        /// Trailers older than this will not be downloaded and deleted if already downloaded.
-        /// </summary>
-        /// <value>The max trailer age.</value>
-        public int? MaxTrailerAge { get; set; }
-
-        /// <summary>
-        /// Gets the path to where trailers should be downloaded.
-        /// If not supplied then programdata/cache/trailers will be used.
-        /// </summary>
-        /// <value>The download path.</value>
-        public string DownloadPath { get; set; }
-
-        /// <summary>
-        /// Gets or sets a value indicating whether [delete old trailers].
-        /// </summary>
-        /// <value><c>true</c> if [delete old trailers]; otherwise, <c>false</c>.</value>
-        public bool DeleteOldTrailers { get; set; }
-        
-        /// <summary>
-        /// Initializes a new instance of the <see cref="PluginConfiguration" /> class.
-        /// </summary>
-        public PluginConfiguration()
-            : base()
-        {
-            FolderName = "Trailers";
-
-            MaxTrailerAge = 60;
-        }
-    }
-}

+ 0 - 50
MediaBrowser.Plugins.Trailers/Configuration/TrailerConfigurationPage.cs

@@ -1,50 +0,0 @@
-using MediaBrowser.Common.Plugins;
-using MediaBrowser.Controller.Plugins;
-using System.ComponentModel.Composition;
-using System.IO;
-
-namespace MediaBrowser.Plugins.Trailers.Configuration
-{
-    /// <summary>
-    /// Class TrailerConfigurationPage
-    /// </summary>
-    [Export(typeof(BaseConfigurationPage))]
-    class TrailerConfigurationPage : BaseConfigurationPage
-    {
-        /// <summary>
-        /// Gets the name.
-        /// </summary>
-        /// <value>The name.</value>
-        public override string Name
-        {
-            get { return "Trailers"; }
-        }
-
-        /// <summary>
-        /// Gets the HTML stream.
-        /// </summary>
-        /// <returns>Stream.</returns>
-        public override Stream GetHtmlStream()
-        {
-            return GetHtmlStreamFromManifestResource("MediaBrowser.Plugins.Trailers.Configuration.configPage.html");
-        }
-
-        /// <summary>
-        /// Gets the owner plugin.
-        /// </summary>
-        /// <returns>BasePlugin.</returns>
-        public override IPlugin GetOwnerPlugin()
-        {
-            return Plugin.Instance;
-        }
-
-        /// <summary>
-        /// Gets the type of the configuration page.
-        /// </summary>
-        /// <value>The type of the configuration page.</value>
-        public override ConfigurationPageType ConfigurationPageType
-        {
-            get { return ConfigurationPageType.PluginConfiguration; }
-        }
-    }
-}

+ 0 - 119
MediaBrowser.Plugins.Trailers/Configuration/configPage.html

@@ -1,119 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-    <title>Trailers</title>
-</head>
-<body>
-    <div id="trailersConfigurationPage" data-role="page" class="page type-interior pluginConfigurationPage">
-
-        <div data-role="content">
-            <div class="content-primary">
-                <form id="trailersConfigurationForm">
-
-                    <ul class="ulForm" data-role="listview">
-                        <li>
-                            <label for="txtFolderName">
-                                Trailer collection name:
-                            </label>
-                            <input id="txtFolderName" name="txtFolderName" />
-                        </li>
-                        <li>
-                            <label for="txtMaxTrailerAge">
-                                Max trailer age (days):
-                            </label>
-                            <input type="number" id="txtMaxTrailerAge" name="txtMaxTrailerAge" pattern="[0-9]*" min="1" />
-                            <div class="fieldDescription">
-                                If specified, trailers older than this will not be downloaded
-                            </div>
-                        </li>
-                        <li>
-                            <input type="checkbox" id="chkDeleteOldTrailers" name="chkDeleteOldTrailers" />
-                            <label for="chkDeleteOldTrailers">Delete trailers older than the max age</label>
-                        </li>
-                        <li>
-                            <label for="txtDownloadPath">
-                                Download path:
-                            </label>
-                            <div style="display: inline-block; width:92%;">
-                                <input id="txtDownloadPath" name="txtDownloadPath" data-inline="true" />
-                            </div>
-                            <button type="button" data-icon="folder-close" data-iconpos="notext" data-inline="true" onclick="TrailersConfigurationPage.selectDirectory();">Select Directory</button>
-                            <div class="fieldDescription">
-                                By default, trailers are downloaded to an internal data directory. Using a different location may make it easier to share over your network.
-                            </div>
-                        </li>
-                        <li>
-                            <button type="submit" data-theme="b">Save</button>
-                            <button type="button" onclick="history.back();">Cancel</button>
-                        </li>
-                    </ul>
-
-                </form>
-            </div>
-        </div>
-
-        <script type="text/javascript">
-
-            var TrailersConfigurationPage = {
-                pluginUniqueId: "986a7283-205a-4436-862d-23135c067f8a",
-
-                selectDirectory: function () {
-
-                    Dashboard.selectDirectory({
-                        callback: function (path) {
-
-                            if (path) {
-                                $('#txtDownloadPath', $.mobile.activePage).val(path);
-                            }
-                            $('#popupDirectoryPicker', $.mobile.activePage).popup("close");
-                        },
-
-                        header: "Select Trailer Path"
-                    });
-
-                }
-            };
-
-            $('#trailersConfigurationPage').on('pageshow', function (event) {
-
-                Dashboard.showLoadingMsg();
-
-                var page = this;
-
-                ApiClient.getPluginConfiguration(TrailersConfigurationPage.pluginUniqueId).done(function (config) {
-
-                    $('#txtDownloadPath', page).val(config.DownloadPath);
-                    $('#txtFolderName', page).val(config.FolderName);
-                    $('#txtMaxTrailerAge', page).val(config.MaxTrailerAge || "");
-                    $('#chkDeleteOldTrailers', page).checked(config.DeleteOldTrailers).checkboxradio("refresh");
-
-                    Dashboard.hideLoadingMsg();
-                });
-            });
-
-            $('#trailersConfigurationForm').on('submit', function (e) {
-
-                Dashboard.showLoadingMsg();
-
-                var form = this;
-
-                ApiClient.getPluginConfiguration(TrailersConfigurationPage.pluginUniqueId).done(function (config) {
-
-                    config.DownloadPath = $('#txtDownloadPath', form).val();
-                    config.FolderName = $('#txtFolderName', form).val();
-                    var maxTrailerAge = $('#txtMaxTrailerAge', form).val();
-
-                    config.MaxTrailerAge = maxTrailerAge ? maxTrailerAge : null;
-
-                    config.DeleteOldTrailers = $('#chkDeleteOldTrailers', form).checked();
-
-                    ApiClient.updatePluginConfiguration(TrailersConfigurationPage.pluginUniqueId, config).done(Dashboard.processPluginConfigurationUpdateResult);
-                });
-
-                // Disable default form submission
-                return false;
-            });
-        </script>
-    </div>
-</body>
-</html>

+ 0 - 33
MediaBrowser.Plugins.Trailers/Entities/TrailerCollectionFolder.cs

@@ -1,33 +0,0 @@
-using MediaBrowser.Controller.Entities;
-using System.ComponentModel.Composition;
-
-namespace MediaBrowser.Plugins.Trailers.Entities
-{
-    /// <summary>
-    /// Class TrailerCollectionFolder
-    /// </summary>
-    [Export(typeof(BasePluginFolder))]
-    class TrailerCollectionFolder : BasePluginFolder
-    {
-        /// <summary>
-        /// Gets the name.
-        /// </summary>
-        /// <value>The name.</value>
-        public override string Name
-        {
-            get
-            {
-                return Plugin.Instance.Configuration.FolderName;
-            }
-        }
-
-        /// <summary>
-        /// Gets the path.
-        /// </summary>
-        /// <value>The path.</value>
-        public override string Path
-        {
-            get { return Plugin.Instance.DownloadPath; }
-        }
-    }
-}

+ 0 - 88
MediaBrowser.Plugins.Trailers/MediaBrowser.Plugins.Trailers.csproj

@@ -1,88 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
-  <PropertyGroup>
-    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
-    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
-    <ProjectGuid>{2F4C01E2-7C9F-4F08-922E-27AC4A1D53FF}</ProjectGuid>
-    <OutputType>Library</OutputType>
-    <AppDesignerFolder>Properties</AppDesignerFolder>
-    <RootNamespace>MediaBrowser.Plugins.Trailers</RootNamespace>
-    <AssemblyName>MediaBrowser.Plugins.Trailers</AssemblyName>
-    <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
-    <FileAlignment>512</FileAlignment>
-    <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\</SolutionDir>
-    <RestorePackages>true</RestorePackages>
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
-    <DebugSymbols>true</DebugSymbols>
-    <DebugType>full</DebugType>
-    <Optimize>false</Optimize>
-    <OutputPath>bin\Debug\</OutputPath>
-    <DefineConstants>DEBUG;TRACE</DefineConstants>
-    <ErrorReport>prompt</ErrorReport>
-    <WarningLevel>4</WarningLevel>
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
-    <DebugType>pdbonly</DebugType>
-    <Optimize>true</Optimize>
-    <OutputPath>bin\Release\</OutputPath>
-    <DefineConstants>TRACE</DefineConstants>
-    <ErrorReport>prompt</ErrorReport>
-    <WarningLevel>4</WarningLevel>
-  </PropertyGroup>
-  <PropertyGroup>
-    <RunPostBuildEvent>Always</RunPostBuildEvent>
-  </PropertyGroup>
-  <ItemGroup>
-    <Reference Include="System" />
-    <Reference Include="System.ComponentModel.Composition" />
-    <Reference Include="System.Core" />
-    <Reference Include="System.Xml.Linq" />
-    <Reference Include="System.Data.DataSetExtensions" />
-    <Reference Include="Microsoft.CSharp" />
-    <Reference Include="System.Data" />
-    <Reference Include="System.Xml" />
-  </ItemGroup>
-  <ItemGroup>
-    <Compile Include="AppleTrailerListingDownloader.cs" />
-    <Compile Include="Configuration\PluginConfiguration.cs" />
-    <Compile Include="Configuration\TrailerConfigurationPage.cs" />
-    <Compile Include="Providers\TrailerFromJsonProvider.cs" />
-    <Compile Include="Resolvers\TrailerResolver.cs" />
-    <Compile Include="ScheduledTasks\CurrentTrailerDownloadTask.cs" />
-    <Compile Include="Plugin.cs" />
-    <Compile Include="Properties\AssemblyInfo.cs" />
-    <Compile Include="Entities\TrailerCollectionFolder.cs" />
-    <Compile Include="TrailerInfo.cs" />
-  </ItemGroup>
-  <ItemGroup>
-    <ProjectReference Include="..\MediaBrowser.Common\MediaBrowser.Common.csproj">
-      <Project>{9142eefa-7570-41e1-bfcc-468bb571af2f}</Project>
-      <Name>MediaBrowser.Common</Name>
-    </ProjectReference>
-    <ProjectReference Include="..\MediaBrowser.Controller\MediaBrowser.Controller.csproj">
-      <Project>{17e1f4e6-8abd-4fe5-9ecf-43d4b6087ba2}</Project>
-      <Name>MediaBrowser.Controller</Name>
-    </ProjectReference>
-    <ProjectReference Include="..\MediaBrowser.Model\MediaBrowser.Model.csproj">
-      <Project>{7eeeb4bb-f3e8-48fc-b4c5-70f0fff8329b}</Project>
-      <Name>MediaBrowser.Model</Name>
-    </ProjectReference>
-  </ItemGroup>
-  <ItemGroup>
-    <EmbeddedResource Include="Configuration\configPage.html" />
-  </ItemGroup>
-  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
-  <PropertyGroup>
-    <PostBuildEvent>xcopy "$(TargetPath)" "$(SolutionDir)\ProgramData-Server\Plugins\" /y</PostBuildEvent>
-  </PropertyGroup>
-  <Import Project="$(SolutionDir)\.nuget\nuget.targets" />
-  <!-- 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">
-  </Target>
-  <Target Name="AfterBuild">
-  </Target>
-  -->
-</Project>

+ 0 - 119
MediaBrowser.Plugins.Trailers/Plugin.cs

@@ -1,119 +0,0 @@
-using MediaBrowser.Common.Plugins;
-using MediaBrowser.Controller.ScheduledTasks;
-using MediaBrowser.Model.Plugins;
-using MediaBrowser.Plugins.Trailers.Configuration;
-using MediaBrowser.Plugins.Trailers.ScheduledTasks;
-using System;
-using System.ComponentModel.Composition;
-using System.IO;
-
-namespace MediaBrowser.Plugins.Trailers
-{
-    /// <summary>
-    /// Class Plugin
-    /// </summary>
-    [Export(typeof(IPlugin))]
-    public class Plugin : BasePlugin<PluginConfiguration>
-    {
-        /// <summary>
-        /// Gets the name of the plugin
-        /// </summary>
-        /// <value>The name.</value>
-        public override string Name
-        {
-            get { return "Trailers"; }
-        }
-
-        /// <summary>
-        /// Gets the description.
-        /// </summary>
-        /// <value>The description.</value>
-        public override string Description
-        {
-            get
-            {
-                return "Movie trailers for your collection.";
-            }
-        }
-
-        /// <summary>
-        /// Gets the instance.
-        /// </summary>
-        /// <value>The instance.</value>
-        public static Plugin Instance { get; private set; }
-
-        /// <summary>
-        /// Initializes a new instance of the <see cref="Plugin" /> class.
-        /// </summary>
-        public Plugin()
-            : base()
-        {
-            Instance = this;
-        }
-
-        /// <summary>
-        /// The _download path
-        /// </summary>
-        private string _downloadPath;
-        /// <summary>
-        /// Gets the path to the trailer download directory
-        /// </summary>
-        /// <value>The download path.</value>
-        public string DownloadPath
-        {
-            get
-            {
-                if (_downloadPath == null)
-                {
-                    // Use 
-                    _downloadPath = Configuration.DownloadPath;
-
-                    if (string.IsNullOrWhiteSpace(_downloadPath))
-                    {
-                        _downloadPath = Path.Combine(Controller.Kernel.Instance.ApplicationPaths.DataPath, Name);
-                    }
-
-                    if (!Directory.Exists(_downloadPath))
-                    {
-                        Directory.CreateDirectory(_downloadPath);
-                    }
-                }
-                return _downloadPath;
-            }
-        }
-
-        /// <summary>
-        /// Starts the plugin on the server
-        /// </summary>
-        /// <param name="isFirstRun">if set to <c>true</c> [is first run].</param>
-        protected override void InitializeOnServer(bool isFirstRun)
-        {
-            base.InitializeOnServer(isFirstRun);
-
-            if (isFirstRun)
-            {
-                Kernel.TaskManager.QueueScheduledTask<CurrentTrailerDownloadTask>();
-            }
-        }
-
-        /// <summary>
-        /// Completely overwrites the current configuration with a new copy
-        /// Returns true or false indicating success or failure
-        /// </summary>
-        /// <param name="configuration">The configuration.</param>
-        public override void UpdateConfiguration(BasePluginConfiguration configuration)
-        {
-            var config = (PluginConfiguration) configuration;
-
-            var pathChanged = !string.Equals(Configuration.DownloadPath, config.DownloadPath, StringComparison.OrdinalIgnoreCase);
-
-            base.UpdateConfiguration(configuration);
-
-            if (pathChanged)
-            {
-                _downloadPath = null;
-                Kernel.TaskManager.QueueScheduledTask<RefreshMediaLibraryTask>();
-            }
-        }
-    }
-}

+ 0 - 34
MediaBrowser.Plugins.Trailers/Properties/AssemblyInfo.cs

@@ -1,34 +0,0 @@
-using System.Reflection;
-using System.Runtime.InteropServices;
-
-// General Information about an assembly is controlled through the following 
-// set of attributes. Change these attribute values to modify the information
-// associated with an assembly.
-[assembly: AssemblyTitle("MediaBrowser.Plugins.Trailers")]
-[assembly: AssemblyDescription("")]
-[assembly: AssemblyConfiguration("")]
-[assembly: AssemblyCompany("")]
-[assembly: AssemblyProduct("MediaBrowser.Plugins.Trailers")]
-[assembly: AssemblyCopyright("Copyright ©  2012")]
-[assembly: AssemblyTrademark("")]
-[assembly: AssemblyCulture("")]
-
-// Setting ComVisible to false makes the types in this assembly not visible 
-// to COM components.  If you need to access a type in this assembly from 
-// COM, set the ComVisible attribute to true on that type.
-[assembly: ComVisible(false)]
-
-// The following GUID is for the ID of the typelib if this project is exposed to COM
-[assembly: Guid("986a7283-205a-4436-862d-23135c067f8a")]
-
-// Version information for an assembly consists of the following four values:
-//
-//      Major Version
-//      Minor Version 
-//      Build Number
-//      Revision
-//
-// You can specify all the values or you can default the Build and Revision Numbers 
-// by using the '*' as shown below:
-// [assembly: AssemblyVersion("1.0.*")]
-[assembly: AssemblyVersion("1.0.*")]

+ 0 - 143
MediaBrowser.Plugins.Trailers/Providers/TrailerFromJsonProvider.cs

@@ -1,143 +0,0 @@
-using MediaBrowser.Common.Serialization;
-using MediaBrowser.Controller.Entities;
-using MediaBrowser.Controller.Providers;
-using MediaBrowser.Plugins.Trailers.Entities;
-using System;
-using System.ComponentModel.Composition;
-using System.IO;
-using System.Threading;
-using System.Threading.Tasks;
-
-namespace MediaBrowser.Plugins.Trailers.Providers
-{
-    /// <summary>
-    /// Class TrailerFromJsonProvider
-    /// </summary>
-    [Export(typeof(BaseMetadataProvider))]
-    class TrailerFromJsonProvider : BaseMetadataProvider
-    {
-        /// <summary>
-        /// Supportses the specified item.
-        /// </summary>
-        /// <param name="item">The item.</param>
-        /// <returns><c>true</c> if XXXX, <c>false</c> otherwise</returns>
-        public override bool Supports(BaseItem item)
-        {
-            var trailer = item as Trailer;
-
-            return trailer != null && trailer.Parent is TrailerCollectionFolder;
-        }
-
-        /// <summary>
-        /// Override this to return the date that should be compared to the last refresh date
-        /// to determine if this provider should be re-fetched.
-        /// </summary>
-        /// <param name="item">The item.</param>
-        /// <returns>DateTime.</returns>
-        protected override DateTime CompareDate(BaseItem item)
-        {
-            var entry = item.ResolveArgs.GetMetaFileByPath(Path.Combine(item.MetaLocation, "trailer.json"));
-            return entry != null ? entry.Value.LastWriteTimeUtc : DateTime.MinValue;
-        }
-
-        /// <summary>
-        /// Fetches metadata and returns true or false indicating if any work that requires persistence was done
-        /// </summary>
-        /// <param name="item">The item.</param>
-        /// <param name="force">if set to <c>true</c> [force].</param>
-        /// <returns>Task{System.Boolean}.</returns>
-        protected override Task<bool> FetchAsyncInternal(BaseItem item, bool force, CancellationToken cancellationToken)
-        {
-            return Task.Run(() => Fetch((Trailer)item));
-        }
-
-        /// <summary>
-        /// Fetches the specified item.
-        /// </summary>
-        /// <param name="item">The item.</param>
-        /// <returns><c>true</c> if XXXX, <c>false</c> otherwise</returns>
-        private bool Fetch(Trailer item)
-        {
-            var metadataFile = item.ResolveArgs.GetMetaFileByPath(Path.Combine(item.MetaLocation, "trailer.json"));
-
-            if (metadataFile.HasValue)
-            {
-                var tempTrailer = JsonSerializer.DeserializeFromFile<Trailer>(metadataFile.Value.Path);
-
-                ImportMetdata(tempTrailer, item);
-
-                SetLastRefreshed(item, DateTime.UtcNow);
-                return true;
-            }
-            return false;
-        }
-
-        /// <summary>
-        /// Gets the priority.
-        /// </summary>
-        /// <value>The priority.</value>
-        public override MetadataProviderPriority Priority
-        {
-            get { return MetadataProviderPriority.First; }
-        }
-
-        /// <summary>
-        /// Imports the metdata.
-        /// </summary>
-        /// <param name="source">The source.</param>
-        /// <param name="target">The target.</param>
-        private void ImportMetdata(Trailer source, Trailer target)
-        {
-            if (!string.IsNullOrWhiteSpace(source.Name))
-            {
-                target.Name = source.Name;
-            }
-
-            if (source.RunTimeTicks.HasValue)
-            {
-                target.RunTimeTicks = source.RunTimeTicks;
-            }
-
-            if (source.Genres != null)
-            {
-                foreach (var entry in source.Genres)
-                {
-                    target.AddGenre(entry);
-                }
-            }
-
-            if (!string.IsNullOrWhiteSpace(source.OfficialRating))
-            {
-                target.OfficialRating = source.OfficialRating;
-            }
-
-            if (!string.IsNullOrWhiteSpace(source.Overview))
-            {
-                target.Overview = source.Overview;
-            }
-
-            if (source.People != null)
-            {
-                target.AddPeople(source.People);
-            }
-
-            if (source.PremiereDate.HasValue)
-            {
-                target.PremiereDate = source.PremiereDate;
-            }
-
-            if (source.ProductionYear.HasValue)
-            {
-                target.ProductionYear = source.ProductionYear;
-            }
-
-            if (source.Studios != null)
-            {
-                foreach (var entry in source.Studios)
-                {
-                    target.AddStudio(entry);
-                }
-            }
-        }
-    }
-}

+ 0 - 51
MediaBrowser.Plugins.Trailers/Resolvers/TrailerResolver.cs

@@ -1,51 +0,0 @@
-using MediaBrowser.Controller.Entities;
-using MediaBrowser.Controller.Library;
-using MediaBrowser.Controller.Resolvers;
-using System;
-using System.ComponentModel.Composition;
-using System.Linq;
-
-namespace MediaBrowser.Plugins.Trailers.Resolvers
-{
-    /// <summary>
-    /// Class TrailerResolver
-    /// </summary>
-    [Export(typeof(IBaseItemResolver))]
-    public class TrailerResolver : BaseVideoResolver<Trailer>
-    {
-        /// <summary>
-        /// Resolves the specified args.
-        /// </summary>
-        /// <param name="args">The args.</param>
-        /// <returns>Trailer.</returns>
-        protected override Trailer Resolve(ItemResolveArgs args)
-        {
-            // Must be a directory and under the trailer download folder
-            if (args.IsDirectory && args.Path.StartsWith(Plugin.Instance.DownloadPath, StringComparison.OrdinalIgnoreCase))
-            {
-                // The trailer must be a video file
-                return FindTrailer(args);
-            }
-
-            return null;
-        }
-
-        /// <summary>
-        /// Finds a movie based on a child file system entries
-        /// </summary>
-        /// <param name="args">The args.</param>
-        /// <returns>Trailer.</returns>
-        private Trailer FindTrailer(ItemResolveArgs args)
-        {
-            // Loop through each child file/folder and see if we find a video
-            return args.FileSystemChildren
-                .Where(c => !c.IsDirectory)
-                .Select(child => base.Resolve(new ItemResolveArgs
-                {
-                    FileInfo = child,
-                    Path = child.Path
-                }))
-                .FirstOrDefault(i => i != null);
-        }
-    }
-}

+ 0 - 311
MediaBrowser.Plugins.Trailers/ScheduledTasks/CurrentTrailerDownloadTask.cs

@@ -1,311 +0,0 @@
-using MediaBrowser.Common.IO;
-using MediaBrowser.Common.ScheduledTasks;
-using MediaBrowser.Common.Serialization;
-using MediaBrowser.Controller;
-using MediaBrowser.Controller.Entities;
-using MediaBrowser.Model.Net;
-using MediaBrowser.Model.Tasks;
-using MediaBrowser.Plugins.Trailers.Entities;
-using System;
-using System.Collections.Generic;
-using System.ComponentModel.Composition;
-using System.IO;
-using System.Linq;
-using System.Threading;
-using System.Threading.Tasks;
-
-namespace MediaBrowser.Plugins.Trailers.ScheduledTasks
-{
-    /// <summary>
-    /// Downloads trailers from the web at scheduled times
-    /// </summary>
-    [Export(typeof(IScheduledTask))]
-    public class CurrentTrailerDownloadTask : BaseScheduledTask<Kernel>
-    {
-        /// <summary>
-        /// Creates the triggers that define when the task will run
-        /// </summary>
-        /// <returns>IEnumerable{BaseTaskTrigger}.</returns>
-        protected override IEnumerable<BaseTaskTrigger> GetDefaultTriggers()
-        {
-            var trigger = new DailyTrigger { TimeOfDay = TimeSpan.FromHours(2) }; //2am
-
-            return new[] { trigger };
-        }
-
-        /// <summary>
-        /// Returns the task to be executed
-        /// </summary>
-        /// <param name="cancellationToken">The cancellation token.</param>
-        /// <param name="progress">The progress.</param>
-        /// <returns>Task.</returns>
-        protected override async Task ExecuteInternal(CancellationToken cancellationToken, IProgress<double> progress)
-        {
-            // Get the list of trailers
-            var trailers = await AppleTrailerListingDownloader.GetTrailerList(cancellationToken).ConfigureAwait(false);
-
-            progress.Report(1);
-
-            var trailersToDownload = trailers.Where(t => !IsOldTrailer(t.Video)).ToList();
-
-            cancellationToken.ThrowIfCancellationRequested();
-
-            var numComplete = 0;
-
-            // Fetch them all in parallel
-            var tasks = trailersToDownload.Select(t => Task.Run(async () =>
-            {
-                cancellationToken.ThrowIfCancellationRequested();
-
-                try
-                {
-                    await DownloadTrailer(t, cancellationToken).ConfigureAwait(false);
-                }
-                catch (Exception ex)
-                {
-                    Logger.ErrorException("Error downloading {0}", ex, t.TrailerUrl);
-                }
-
-                // Update progress
-                lock (progress)
-                {
-                    numComplete++;
-                    double percent = numComplete;
-                    percent /= trailersToDownload.Count;
-
-                    // Leave 1% for DeleteOldTrailers
-                    progress.Report((99 * percent) + 1);
-                }
-            }));
-
-            cancellationToken.ThrowIfCancellationRequested();
-            
-            await Task.WhenAll(tasks).ConfigureAwait(false);
-
-            cancellationToken.ThrowIfCancellationRequested();
-            
-            if (Plugin.Instance.Configuration.DeleteOldTrailers)
-            {
-                // Enforce MaxTrailerAge
-                DeleteOldTrailers();
-            }
-
-            progress.Report(100);
-        }
-
-        /// <summary>
-        /// Downloads a single trailer into the trailers directory
-        /// </summary>
-        /// <param name="trailer">The trailer.</param>
-        /// <param name="cancellationToken">The cancellation token.</param>
-        /// <returns>Task.</returns>
-        private async Task DownloadTrailer(TrailerInfo trailer, CancellationToken cancellationToken)
-        {
-            // Construct the trailer foldername
-            var folderName = FileSystem.GetValidFilename(trailer.Video.Name);
-
-            if (trailer.Video.ProductionYear.HasValue)
-            {
-                folderName += string.Format(" ({0})", trailer.Video.ProductionYear);
-            }
-
-            var folderPath = Path.Combine(Plugin.Instance.DownloadPath, folderName);
-
-            // Figure out which image we're going to download
-            var imageUrl = trailer.HdImageUrl ?? trailer.ImageUrl;
-
-            // Construct the video filename (to match the folder name)
-            var videoFileName = Path.ChangeExtension(folderName, Path.GetExtension(trailer.TrailerUrl));
-
-            // Construct the image filename (folder + original extension)
-            var imageFileName = Path.ChangeExtension("folder", Path.GetExtension(imageUrl));
-
-            // Construct full paths
-            var videoFilePath = Path.Combine(folderPath, videoFileName);
-            var imageFilePath = Path.Combine(folderPath, imageFileName);
-
-            // Create tasks to download each of them, if we don't already have them
-            Task<string> videoTask = null;
-            Task<MemoryStream> imageTask = null;
-
-            var tasks = new List<Task>();
-
-            if (!File.Exists(videoFilePath))
-            {
-                Logger.Info("Downloading trailer: " + trailer.TrailerUrl);
-
-                // Fetch the video to a temp file because it's too big to put into a MemoryStream
-                videoTask = Kernel.HttpManager.FetchToTempFile(trailer.TrailerUrl, Kernel.ResourcePools.AppleTrailerVideos, cancellationToken, new Progress<double> { }, "QuickTime/7.6.2");
-                tasks.Add(videoTask);
-            }
-
-            if (!string.IsNullOrWhiteSpace(imageUrl) && !File.Exists(imageFilePath))
-            {
-                // Fetch the image to a memory stream
-                Logger.Info("Downloading trailer image: " + imageUrl);
-                imageTask = Kernel.HttpManager.FetchToMemoryStream(imageUrl, Kernel.ResourcePools.AppleTrailerImages, cancellationToken);
-                tasks.Add(imageTask);
-            }
-
-            try
-            {
-                // Wait for both downloads to finish
-                await Task.WhenAll(tasks).ConfigureAwait(false);
-            }
-            catch (HttpException ex)
-            {
-                Logger.ErrorException("Error downloading trailer file or image", ex);
-            }
-
-            var videoFailed = false;
-            var directoryEnsured = false;
-
-            // Proces the video file task result
-            if (videoTask != null)
-            {
-                if (videoTask.Status == TaskStatus.RanToCompletion)
-                {
-                    EnsureDirectory(folderPath);
-
-                    directoryEnsured = true;
-
-                    // Move the temp file to the final destination
-                    try
-                    {
-                        File.Move(videoTask.Result, videoFilePath);
-                    }
-                    catch (IOException ex)
-                    {
-                        Logger.ErrorException("Error moving temp file", ex);
-                        File.Delete(videoTask.Result);
-                        videoFailed = true;
-                    }
-                }
-                else
-                {
-                    Logger.Info("Trailer download failed: " + trailer.TrailerUrl);
-
-                    // Don't bother with the image if the video download failed
-                    videoFailed = true;
-                }
-            }
-
-            // Process the image file task result
-            if (imageTask != null && !videoFailed && imageTask.Status == TaskStatus.RanToCompletion)
-            {
-                if (!directoryEnsured)
-                {
-                    EnsureDirectory(folderPath);
-                }
-
-                try
-                {
-                    // Save the image to the file system
-                    using (var fs = new FileStream(imageFilePath, FileMode.Create, FileAccess.Write, FileShare.Read, StreamDefaults.DefaultFileStreamBufferSize, FileOptions.Asynchronous))
-                    {
-                        using (var sourceStream = imageTask.Result)
-                        {
-                            await sourceStream.CopyToAsync(fs).ConfigureAwait(false);
-                        }
-                    }
-                }
-                catch (IOException ex)
-                {
-                    Logger.ErrorException("Error saving image to file system", ex);
-                }
-            }
-
-            // Save metadata only if the video was downloaded
-            if (!videoFailed && videoTask != null)
-            {
-                JsonSerializer.SerializeToFile(trailer.Video, Path.Combine(folderPath, "trailer.json"));
-            }
-        }
-
-        /// <summary>
-        /// Determines whether [is old trailer] [the specified trailer].
-        /// </summary>
-        /// <param name="trailer">The trailer.</param>
-        /// <returns><c>true</c> if [is old trailer] [the specified trailer]; otherwise, <c>false</c>.</returns>
-        private bool IsOldTrailer(Trailer trailer)
-        {
-            if (!Plugin.Instance.Configuration.MaxTrailerAge.HasValue)
-            {
-                return false;
-            }
-
-            if (!trailer.PremiereDate.HasValue)
-            {
-                return false;
-            }
-
-            var now = DateTime.UtcNow;
-
-            // Not old if it still hasn't premiered.
-            if (now < trailer.PremiereDate.Value)
-            {
-                return false;
-            }
-
-            return (DateTime.UtcNow - trailer.PremiereDate.Value).TotalDays >
-                   Plugin.Instance.Configuration.MaxTrailerAge.Value;
-        }
-
-        /// <summary>
-        /// Deletes trailers that are older than the supplied date
-        /// </summary>
-        private void DeleteOldTrailers()
-        {
-            var collectionFolder = (Folder)Kernel.RootFolder.Children.First(c => c.GetType().Name.Equals(typeof(TrailerCollectionFolder).Name));
-
-            foreach (var trailer in collectionFolder.RecursiveChildren.OfType<Trailer>().Where(IsOldTrailer))
-            {
-                Logger.Info("Deleting old trailer: " + trailer.Name);
-
-                Directory.Delete(Path.GetDirectoryName(trailer.Path), true);
-            }
-        }
-
-        /// <summary>
-        /// Ensures the directory.
-        /// </summary>
-        /// <param name="path">The path.</param>
-        private void EnsureDirectory(string path)
-        {
-            if (!Directory.Exists(path))
-            {
-                Directory.CreateDirectory(path);
-            }
-        }
-
-        /// <summary>
-        /// Gets the name of the task
-        /// </summary>
-        /// <value>The name.</value>
-        public override string Name
-        {
-            get { return "Find current trailers"; }
-        }
-
-        /// <summary>
-        /// Gets the category.
-        /// </summary>
-        /// <value>The category.</value>
-        public override string Category
-        {
-            get
-            {
-                return "Trailers";
-            }
-        }
-
-        /// <summary>
-        /// Gets the description.
-        /// </summary>
-        /// <value>The description.</value>
-        public override string Description
-        {
-            get { return "Searches the web for upcoming movie trailers, and downloads them based on your Trailer plugin settings."; }
-        }
-    }
-}

+ 0 - 45
MediaBrowser.Plugins.Trailers/TrailerInfo.cs

@@ -1,45 +0,0 @@
-using MediaBrowser.Controller.Entities;
-using System;
-
-namespace MediaBrowser.Plugins.Trailers
-{
-    /// <summary>
-    /// This is a stub class used to hold information about a trailer
-    /// </summary>
-    public class TrailerInfo
-    {
-        /// <summary>
-        /// Gets or sets the video.
-        /// </summary>
-        /// <value>The video.</value>
-        public Trailer Video { get; set; }
-        /// <summary>
-        /// Gets or sets the image URL.
-        /// </summary>
-        /// <value>The image URL.</value>
-        public string ImageUrl { get; set; }
-        /// <summary>
-        /// Gets or sets the hd image URL.
-        /// </summary>
-        /// <value>The hd image URL.</value>
-        public string HdImageUrl { get; set; }
-        /// <summary>
-        /// Gets or sets the trailer URL.
-        /// </summary>
-        /// <value>The trailer URL.</value>
-        public string TrailerUrl { get; set; }
-        /// <summary>
-        /// Gets or sets the post date.
-        /// </summary>
-        /// <value>The post date.</value>
-        public DateTime PostDate { get; set; }
-
-        /// <summary>
-        /// Initializes a new instance of the <see cref="TrailerInfo" /> class.
-        /// </summary>
-        public TrailerInfo()
-        {
-            Video = new Trailer();
-        }
-    }
-}

+ 0 - 24
MediaBrowser.UI.sln

@@ -11,10 +11,6 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MediaBrowser.ApiInteraction
 EndProject
 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MediaBrowser.Plugins.DefaultTheme", "MediaBrowser.Plugins.DefaultTheme\MediaBrowser.Plugins.DefaultTheme.csproj", "{6E892999-711D-4E24-8BAC-DACF5BFA783A}"
 EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MediaBrowser.Plugins.MpcHc", "MediaBrowser.Plugins.MpcHc\MediaBrowser.Plugins.MpcHc.csproj", "{2E94BC08-A7A2-42DD-9893-EAA3DACD1CF9}"
-EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MediaBrowser.Plugins.Tmt5", "MediaBrowser.Plugins.Tmt5\MediaBrowser.Plugins.Tmt5.csproj", "{BE9BAA85-9EF2-4308-92E4-0D2B6E33C487}"
-EndProject
 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MediaBrowser.UI.Uninstall", "MediaBrowser.UI.Uninstall\MediaBrowser.UI.Uninstall.csproj", "{E4BE0659-4084-407B-B8A8-67802331CC9E}"
 EndProject
 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MediaBrowser.IsoMounter", "MediaBrowser.IsoMounter\MediaBrowser.IsoMounter.csproj", "{5356AE30-6A6E-4A64-81E3-F76C50595E64}"
@@ -95,26 +91,6 @@ Global
 		{6E892999-711D-4E24-8BAC-DACF5BFA783A}.Release|Mixed Platforms.Build.0 = Release|Any CPU
 		{6E892999-711D-4E24-8BAC-DACF5BFA783A}.Release|x86.ActiveCfg = Release|Any CPU
 		{6E892999-711D-4E24-8BAC-DACF5BFA783A}.Release|x86.Build.0 = Release|Any CPU
-		{2E94BC08-A7A2-42DD-9893-EAA3DACD1CF9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
-		{2E94BC08-A7A2-42DD-9893-EAA3DACD1CF9}.Debug|Any CPU.Build.0 = Debug|Any CPU
-		{2E94BC08-A7A2-42DD-9893-EAA3DACD1CF9}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
-		{2E94BC08-A7A2-42DD-9893-EAA3DACD1CF9}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
-		{2E94BC08-A7A2-42DD-9893-EAA3DACD1CF9}.Debug|x86.ActiveCfg = Debug|Any CPU
-		{2E94BC08-A7A2-42DD-9893-EAA3DACD1CF9}.Release|Any CPU.ActiveCfg = Release|Any CPU
-		{2E94BC08-A7A2-42DD-9893-EAA3DACD1CF9}.Release|Any CPU.Build.0 = Release|Any CPU
-		{2E94BC08-A7A2-42DD-9893-EAA3DACD1CF9}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
-		{2E94BC08-A7A2-42DD-9893-EAA3DACD1CF9}.Release|Mixed Platforms.Build.0 = Release|Any CPU
-		{2E94BC08-A7A2-42DD-9893-EAA3DACD1CF9}.Release|x86.ActiveCfg = Release|Any CPU
-		{BE9BAA85-9EF2-4308-92E4-0D2B6E33C487}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
-		{BE9BAA85-9EF2-4308-92E4-0D2B6E33C487}.Debug|Any CPU.Build.0 = Debug|Any CPU
-		{BE9BAA85-9EF2-4308-92E4-0D2B6E33C487}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
-		{BE9BAA85-9EF2-4308-92E4-0D2B6E33C487}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
-		{BE9BAA85-9EF2-4308-92E4-0D2B6E33C487}.Debug|x86.ActiveCfg = Debug|Any CPU
-		{BE9BAA85-9EF2-4308-92E4-0D2B6E33C487}.Release|Any CPU.ActiveCfg = Release|Any CPU
-		{BE9BAA85-9EF2-4308-92E4-0D2B6E33C487}.Release|Any CPU.Build.0 = Release|Any CPU
-		{BE9BAA85-9EF2-4308-92E4-0D2B6E33C487}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
-		{BE9BAA85-9EF2-4308-92E4-0D2B6E33C487}.Release|Mixed Platforms.Build.0 = Release|Any CPU
-		{BE9BAA85-9EF2-4308-92E4-0D2B6E33C487}.Release|x86.ActiveCfg = Release|Any CPU
 		{E4BE0659-4084-407B-B8A8-67802331CC9E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
 		{E4BE0659-4084-407B-B8A8-67802331CC9E}.Debug|Any CPU.Build.0 = Debug|Any CPU
 		{E4BE0659-4084-407B-B8A8-67802331CC9E}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU

+ 1 - 1
MediaBrowser.UI/Controller/PluginUpdater.cs

@@ -217,7 +217,7 @@ namespace MediaBrowser.UI.Controller
             _logger.Info("Downloading {0} Configuration", pluginInfo.Name);
 
             // First download to a MemoryStream. This way if the download is cut off, we won't be left with a partial file
-            using (var stream = await UIKernel.Instance.ApiClient.GetPluginConfigurationFileAsync(pluginInfo.UniqueId).ConfigureAwait(false))
+            using (var stream = await UIKernel.Instance.ApiClient.GetPluginConfigurationFileAsync(pluginInfo.Id).ConfigureAwait(false))
             {
                 using (var memoryStream = new MemoryStream())
                 {

+ 3 - 2
MediaBrowser.UI/MediaBrowser.UI.csproj

@@ -5,7 +5,7 @@
     <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
     <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
     <ProjectGuid>{B5ECE1FB-618E-420B-9A99-8E972D76920A}</ProjectGuid>
-    <OutputType>WinExe</OutputType>
+    <OutputType>Library</OutputType>
     <AppDesignerFolder>Properties</AppDesignerFolder>
     <RootNamespace>MediaBrowser.UI</RootNamespace>
     <AssemblyName>MediaBrowser.UI</AssemblyName>
@@ -57,7 +57,8 @@
     <WarningLevel>4</WarningLevel>
   </PropertyGroup>
   <PropertyGroup>
-    <StartupObject>MediaBrowser.UI.App</StartupObject>
+    <StartupObject>
+    </StartupObject>
   </PropertyGroup>
   <PropertyGroup>
     <ApplicationIcon>Resources\Images\Icon.ico</ApplicationIcon>

+ 3 - 4
MediaBrowser.WebDashboard/Api/DashboardService.cs

@@ -25,7 +25,7 @@ namespace MediaBrowser.WebDashboard.Api
     /// Class GetDashboardConfigurationPages
     /// </summary>
     [Route("/dashboard/ConfigurationPages", "GET")]
-    public class GetDashboardConfigurationPages : IReturn<List<BaseConfigurationPage>>
+    public class GetDashboardConfigurationPages : IReturn<List<IPluginConfigurationPage>>
     {
         /// <summary>
         /// Gets or sets the type of the page.
@@ -38,7 +38,7 @@ namespace MediaBrowser.WebDashboard.Api
     /// Class GetDashboardConfigurationPage
     /// </summary>
     [Route("/dashboard/ConfigurationPage", "GET")]
-    public class GetDashboardConfigurationPage : IReturn<BaseConfigurationPage>
+    public class GetDashboardConfigurationPage : IReturn<IPluginConfigurationPage>
     {
         /// <summary>
         /// Gets or sets the name.
@@ -139,9 +139,8 @@ namespace MediaBrowser.WebDashboard.Api
             var kernel = (Kernel)Kernel;
 
             var page = kernel.PluginConfigurationPages.First(p => p.Name.Equals(request.Name, StringComparison.OrdinalIgnoreCase));
-            var plugin = page.GetOwnerPlugin();
 
-            return ToStaticResult(plugin.Version.ToString().GetMD5(), plugin.AssemblyDateLastModified, null, MimeTypes.GetMimeType("page.html"), () => ModifyHtml(page.GetHtmlStream()));
+            return ToStaticResult(page.Version.GetMD5(), page.DateLastModified, null, MimeTypes.GetMimeType("page.html"), () => ModifyHtml(page.GetHtmlStream()));
         }
 
         /// <summary>

+ 4 - 4
MediaBrowser.WebDashboard/Html/scripts/PluginUpdatesPage.js

@@ -41,7 +41,7 @@
         var options = PluginUpdatesPage.getHtmlOptions(["Off", "On"], (plugin.EnableAutoUpdate ? "On" : "Off"));
 
         html += "<td>";
-        html += "<select data-uniqueid='" + plugin.UniqueId + "' onchange='PluginUpdatesPage.setAutoUpdate(this);' data-role='slider' id='" + fieldId + "' name='" + fieldId + "'>" + options + "</select>";
+        html += "<select data-id='" + plugin.Id + "' onchange='PluginUpdatesPage.setAutoUpdate(this);' data-role='slider' id='" + fieldId + "' name='" + fieldId + "'>" + options + "</select>";
         html += "</td>";
 
         fieldId = "liPluginUpdateFieldb" + fieldIndex;
@@ -49,7 +49,7 @@
         options = PluginUpdatesPage.getHtmlOptions(["Release", "Beta", "Dev"], plugin.UpdateClass);
 
         html += "<td>";
-        html += "<select data-uniqueid='" + plugin.UniqueId + "' onchange='PluginUpdatesPage.setUpdateClass(this);' data-inline='true' id='" + fieldId + "' name='" + fieldId + "'>" + options + "</select>";
+        html += "<select data-id='" + plugin.Id + "' onchange='PluginUpdatesPage.setUpdateClass(this);' data-inline='true' id='" + fieldId + "' name='" + fieldId + "'>" + options + "</select>";
         html += "</td>";
 
         html += "</tr>";
@@ -79,7 +79,7 @@
 
     setAutoUpdate: function (select) {
 
-        var id = $(select).attr('data-uniqueid');
+        var id = $(select).attr('data-id');
 
         Dashboard.showLoadingMsg();
 
@@ -93,7 +93,7 @@
 
     setUpdateClass: function (select) {
 
-        var id = $(select).attr('data-uniqueid');
+        var id = $(select).attr('data-id');
 
         Dashboard.showLoadingMsg();
 

+ 3 - 3
MediaBrowser.WebDashboard/Html/scripts/PluginsPage.js

@@ -40,7 +40,7 @@
             }
             
             var configPage = $.grep(pluginConfigurationPages, function (pluginConfigurationPage) {
-                return pluginConfigurationPage.OwnerPluginName == plugin.Name;
+                return pluginConfigurationPage.PluginId == plugin.Id;
             })[0];
 
             html += "<li>";
@@ -56,7 +56,7 @@
             html += "</a>";
 
             if (!plugin.IsCorePlugin) {
-                html += "<a data-uniqueid='" + plugin.UniqueId + "' data-pluginname='" + plugin.Name + "' onclick='PluginsPage.deletePlugin(this);' href='#'>Delete</a>";
+                html += "<a data-id='" + plugin.Id + "' data-pluginname='" + plugin.Name + "' onclick='PluginsPage.deletePlugin(this);' href='#'>Delete</a>";
             }
 
             html += "</li>";
@@ -70,7 +70,7 @@
     deletePlugin: function (link) {
 
         var name = link.getAttribute('data-pluginname');
-        var uniqueid = link.getAttribute('data-uniqueid');
+        var uniqueid = link.getAttribute('data-id');
 
         var msg = "Are you sure you wish to uninstall " + name + "?";
 

+ 0 - 33
MediaBrowser.sln

@@ -20,8 +20,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
 		Performance19.psess = Performance19.psess
 	EndProjectSection
 EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MediaBrowser.Plugins.Trailers", "MediaBrowser.Plugins.Trailers\MediaBrowser.Plugins.Trailers.csproj", "{2F4C01E2-7C9F-4F08-922E-27AC4A1D53FF}"
-EndProject
 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MediaBrowser.ApiInteraction.Javascript", "MediaBrowser.ApiInteraction.Javascript\MediaBrowser.ApiInteraction.Javascript.csproj", "{767B536E-D90C-4D74-A14B-8564B16F3499}"
 EndProject
 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MediaBrowser.ApiInteraction", "MediaBrowser.ApiInteraction\MediaBrowser.ApiInteraction.csproj", "{921C0F64-FDA7-4E9F-9E73-0CB0EEDB2422}"
@@ -41,8 +39,6 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BDInfo", "BDInfo\BDInfo.csp
 EndProject
 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MediaBrowser.IsoMounter", "MediaBrowser.IsoMounter\MediaBrowser.IsoMounter.csproj", "{5356AE30-6A6E-4A64-81E3-F76C50595E64}"
 EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MediaBrowser.Plugins.Dlna", "MediaBrowser.Plugins.Dlna\MediaBrowser.Plugins.Dlna.csproj", "{A2CF4266-2110-419E-8620-E2FEEFCA0F48}"
-EndProject
 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MediaBrowser.Installer", "MediaBrowser.Installer\MediaBrowser.Installer.csproj", "{3879F78A-D6F6-45E5-B2A8-D8DCF2DABB74}"
 EndProject
 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MediaBrowser.Server.Sqlite", "MediaBrowser.Server.Sqlite\MediaBrowser.Server.Sqlite.csproj", "{8649ED6B-8504-4D00-BFA5-B8C73CC744DB}"
@@ -163,21 +159,6 @@ Global
 		{5624B7B5-B5A7-41D8-9F10-CC5611109619}.Release|x64.ActiveCfg = Release|Any CPU
 		{5624B7B5-B5A7-41D8-9F10-CC5611109619}.Release|x86.ActiveCfg = Release|Any CPU
 		{5624B7B5-B5A7-41D8-9F10-CC5611109619}.Release|x86.Build.0 = Release|Any CPU
-		{2F4C01E2-7C9F-4F08-922E-27AC4A1D53FF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
-		{2F4C01E2-7C9F-4F08-922E-27AC4A1D53FF}.Debug|Any CPU.Build.0 = Debug|Any CPU
-		{2F4C01E2-7C9F-4F08-922E-27AC4A1D53FF}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
-		{2F4C01E2-7C9F-4F08-922E-27AC4A1D53FF}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
-		{2F4C01E2-7C9F-4F08-922E-27AC4A1D53FF}.Debug|Win32.ActiveCfg = Debug|Any CPU
-		{2F4C01E2-7C9F-4F08-922E-27AC4A1D53FF}.Debug|x64.ActiveCfg = Debug|Any CPU
-		{2F4C01E2-7C9F-4F08-922E-27AC4A1D53FF}.Debug|x86.ActiveCfg = Debug|Any CPU
-		{2F4C01E2-7C9F-4F08-922E-27AC4A1D53FF}.Debug|x86.Build.0 = Debug|Any CPU
-		{2F4C01E2-7C9F-4F08-922E-27AC4A1D53FF}.Release|Any CPU.ActiveCfg = Release|Any CPU
-		{2F4C01E2-7C9F-4F08-922E-27AC4A1D53FF}.Release|Any CPU.Build.0 = Release|Any CPU
-		{2F4C01E2-7C9F-4F08-922E-27AC4A1D53FF}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
-		{2F4C01E2-7C9F-4F08-922E-27AC4A1D53FF}.Release|Mixed Platforms.Build.0 = Release|Any CPU
-		{2F4C01E2-7C9F-4F08-922E-27AC4A1D53FF}.Release|Win32.ActiveCfg = Release|Any CPU
-		{2F4C01E2-7C9F-4F08-922E-27AC4A1D53FF}.Release|x64.ActiveCfg = Release|Any CPU
-		{2F4C01E2-7C9F-4F08-922E-27AC4A1D53FF}.Release|x86.ActiveCfg = Release|Any CPU
 		{767B536E-D90C-4D74-A14B-8564B16F3499}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
 		{767B536E-D90C-4D74-A14B-8564B16F3499}.Debug|Any CPU.Build.0 = Debug|Any CPU
 		{767B536E-D90C-4D74-A14B-8564B16F3499}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
@@ -267,20 +248,6 @@ Global
 		{5356AE30-6A6E-4A64-81E3-F76C50595E64}.Release|Win32.ActiveCfg = Release|Any CPU
 		{5356AE30-6A6E-4A64-81E3-F76C50595E64}.Release|x64.ActiveCfg = Release|Any CPU
 		{5356AE30-6A6E-4A64-81E3-F76C50595E64}.Release|x86.ActiveCfg = Release|Any CPU
-		{A2CF4266-2110-419E-8620-E2FEEFCA0F48}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
-		{A2CF4266-2110-419E-8620-E2FEEFCA0F48}.Debug|Any CPU.Build.0 = Debug|Any CPU
-		{A2CF4266-2110-419E-8620-E2FEEFCA0F48}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
-		{A2CF4266-2110-419E-8620-E2FEEFCA0F48}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
-		{A2CF4266-2110-419E-8620-E2FEEFCA0F48}.Debug|Win32.ActiveCfg = Debug|Any CPU
-		{A2CF4266-2110-419E-8620-E2FEEFCA0F48}.Debug|x64.ActiveCfg = Debug|Any CPU
-		{A2CF4266-2110-419E-8620-E2FEEFCA0F48}.Debug|x86.ActiveCfg = Debug|Any CPU
-		{A2CF4266-2110-419E-8620-E2FEEFCA0F48}.Release|Any CPU.ActiveCfg = Release|Any CPU
-		{A2CF4266-2110-419E-8620-E2FEEFCA0F48}.Release|Any CPU.Build.0 = Release|Any CPU
-		{A2CF4266-2110-419E-8620-E2FEEFCA0F48}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
-		{A2CF4266-2110-419E-8620-E2FEEFCA0F48}.Release|Mixed Platforms.Build.0 = Release|Any CPU
-		{A2CF4266-2110-419E-8620-E2FEEFCA0F48}.Release|Win32.ActiveCfg = Release|Any CPU
-		{A2CF4266-2110-419E-8620-E2FEEFCA0F48}.Release|x64.ActiveCfg = Release|Any CPU
-		{A2CF4266-2110-419E-8620-E2FEEFCA0F48}.Release|x86.ActiveCfg = Release|Any CPU
 		{3879F78A-D6F6-45E5-B2A8-D8DCF2DABB74}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
 		{3879F78A-D6F6-45E5-B2A8-D8DCF2DABB74}.Debug|Any CPU.Build.0 = Debug|Any CPU
 		{3879F78A-D6F6-45E5-B2A8-D8DCF2DABB74}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU

+ 1 - 0
Nuget/MediaBrowser.Server.Core.nupkg.REMOVED.git-id

@@ -0,0 +1 @@
+da3d30d634468465d8995ba6cb1c0872959b3e9c