瀏覽代碼

get stable and beta server packages from github

Luke Pulverenti 9 年之前
父節點
當前提交
82b8d60720

+ 1 - 1
MediaBrowser.Api/PackageService.cs

@@ -233,7 +233,7 @@ namespace MediaBrowser.Api
                 throw new ResourceNotFoundException(string.Format("Package not found: {0}", request.Name));
             }
 
-            Task.Run(() => _installationManager.InstallPackage(package, new Progress<double>(), CancellationToken.None));
+            Task.Run(() => _installationManager.InstallPackage(package, true, new Progress<double>(), CancellationToken.None));
         }
 
         /// <summary>

+ 1 - 1
MediaBrowser.Common.Implementations/HttpClientManager/HttpClientManager.cs

@@ -150,7 +150,7 @@ namespace MediaBrowser.Common.Implementations.HttpClientManager
 
             request.Method = method;
             request.Timeout = options.TimeoutMs;
-
+            
             if (httpWebRequest != null)
             {
                 if (!string.IsNullOrEmpty(options.Host))

+ 2 - 0
MediaBrowser.Common.Implementations/MediaBrowser.Common.Implementations.csproj

@@ -68,6 +68,7 @@
       <HintPath>..\packages\SimpleInjector.3.1.2\lib\net45\SimpleInjector.dll</HintPath>
     </Reference>
     <Reference Include="System" />
+    <Reference Include="System.Configuration" />
     <Reference Include="System.Core" />
     <Reference Include="Microsoft.CSharp" />
     <Reference Include="System.Data" />
@@ -107,6 +108,7 @@
     <Compile Include="Security\SuppporterInfoResponse.cs" />
     <Compile Include="Serialization\JsonSerializer.cs" />
     <Compile Include="Serialization\XmlSerializer.cs" />
+    <Compile Include="Updates\GithubUpdater.cs" />
     <Compile Include="Updates\InstallationManager.cs" />
   </ItemGroup>
   <ItemGroup>

+ 195 - 0
MediaBrowser.Common.Implementations/Updates/GithubUpdater.cs

@@ -0,0 +1,195 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Reflection;
+using System.Text;
+using System.Threading;
+using System.Threading.Tasks;
+using MediaBrowser.Common.Net;
+using MediaBrowser.Model.Serialization;
+using MediaBrowser.Model.Updates;
+
+namespace MediaBrowser.Common.Implementations.Updates
+{
+    public class GithubUpdater
+    {
+        private readonly IHttpClient _httpClient;
+        private readonly IJsonSerializer _jsonSerializer;
+        private TimeSpan _cacheLength;
+
+        public GithubUpdater(IHttpClient httpClient, IJsonSerializer jsonSerializer, TimeSpan cacheLength)
+        {
+            _httpClient = httpClient;
+            _jsonSerializer = jsonSerializer;
+            _cacheLength = cacheLength;
+        }
+
+        public async Task<CheckForUpdateResult> CheckForUpdateResult(string organzation, string repository, Version minVersion, bool includePrerelease, string assetFilename, string packageName, string targetFilename, CancellationToken cancellationToken)
+        {
+            var url = string.Format("https://api.github.com/repos/{0}/{1}/releases", organzation, repository);
+
+            var options = new HttpRequestOptions
+            {
+                Url = url,
+                EnableKeepAlive = false,
+                CancellationToken = cancellationToken,
+                UserAgent = "Emby/3.0"
+
+            };
+
+            if (_cacheLength.Ticks > 0)
+            {
+                options.CacheMode = CacheMode.Unconditional;
+                options.CacheLength = _cacheLength;
+            }
+
+            using (var stream = await _httpClient.Get(new HttpRequestOptions
+            {
+                Url = url,
+                EnableKeepAlive = false,
+                CancellationToken = cancellationToken,
+                UserAgent = "Emby/3.0"
+
+            }).ConfigureAwait(false))
+            {
+                var obj = _jsonSerializer.DeserializeFromStream<RootObject[]>(stream);
+
+                var availableUpdate = CheckForUpdateResult(obj, minVersion, includePrerelease, assetFilename, packageName, targetFilename);
+
+                return availableUpdate ?? new CheckForUpdateResult
+                {
+                    IsUpdateAvailable = false
+                };
+            }
+        }
+
+        private CheckForUpdateResult CheckForUpdateResult(RootObject[] obj, Version minVersion, bool includePrerelease, string assetFilename, string packageName, string targetFilename)
+        {
+            if (!includePrerelease)
+            {
+                obj = obj.Where(i => !i.prerelease).ToArray();
+            }
+
+            // TODO:
+            // Filter using name and check for suffixes such as -beta, -dev?
+
+            return obj.Select(i => CheckForUpdateResult(i, minVersion, assetFilename, packageName, targetFilename)).FirstOrDefault(i => i != null);
+        }
+
+        private CheckForUpdateResult CheckForUpdateResult(RootObject obj, Version minVersion, string assetFilename, string packageName, string targetFilename)
+        {
+            Version version;
+            if (!Version.TryParse(obj.tag_name, out version))
+            {
+                return null;
+            }
+
+            if (version < minVersion)
+            {
+                return null;
+            }
+
+            var asset = (obj.assets ?? new List<Asset>()).FirstOrDefault(i => string.Equals(assetFilename, Path.GetFileName(i.browser_download_url), StringComparison.OrdinalIgnoreCase));
+
+            if (asset == null)
+            {
+                return null;
+            }
+
+            return new CheckForUpdateResult
+            {
+                AvailableVersion = version.ToString(),
+                IsUpdateAvailable = version > minVersion,
+                Package = new PackageVersionInfo
+                {
+                    classification = obj.prerelease ? PackageVersionClass.Beta : PackageVersionClass.Release,
+                    name = packageName,
+                    sourceUrl = asset.browser_download_url,
+                    targetFilename = targetFilename,
+                    versionStr = version.ToString(),
+                    requiredVersionStr = "1.0.0"
+                }
+            };
+        }
+
+        public class Uploader
+        {
+            public string login { get; set; }
+            public int id { get; set; }
+            public string avatar_url { get; set; }
+            public string gravatar_id { get; set; }
+            public string url { get; set; }
+            public string html_url { get; set; }
+            public string followers_url { get; set; }
+            public string following_url { get; set; }
+            public string gists_url { get; set; }
+            public string starred_url { get; set; }
+            public string subscriptions_url { get; set; }
+            public string organizations_url { get; set; }
+            public string repos_url { get; set; }
+            public string events_url { get; set; }
+            public string received_events_url { get; set; }
+            public string type { get; set; }
+            public bool site_admin { get; set; }
+        }
+
+        public class Asset
+        {
+            public string url { get; set; }
+            public int id { get; set; }
+            public string name { get; set; }
+            public object label { get; set; }
+            public Uploader uploader { get; set; }
+            public string content_type { get; set; }
+            public string state { get; set; }
+            public int size { get; set; }
+            public int download_count { get; set; }
+            public string created_at { get; set; }
+            public string updated_at { get; set; }
+            public string browser_download_url { get; set; }
+        }
+
+        public class Author
+        {
+            public string login { get; set; }
+            public int id { get; set; }
+            public string avatar_url { get; set; }
+            public string gravatar_id { get; set; }
+            public string url { get; set; }
+            public string html_url { get; set; }
+            public string followers_url { get; set; }
+            public string following_url { get; set; }
+            public string gists_url { get; set; }
+            public string starred_url { get; set; }
+            public string subscriptions_url { get; set; }
+            public string organizations_url { get; set; }
+            public string repos_url { get; set; }
+            public string events_url { get; set; }
+            public string received_events_url { get; set; }
+            public string type { get; set; }
+            public bool site_admin { get; set; }
+        }
+
+        public class RootObject
+        {
+            public string url { get; set; }
+            public string assets_url { get; set; }
+            public string upload_url { get; set; }
+            public string html_url { get; set; }
+            public int id { get; set; }
+            public string tag_name { get; set; }
+            public string target_commitish { get; set; }
+            public string name { get; set; }
+            public bool draft { get; set; }
+            public Author author { get; set; }
+            public bool prerelease { get; set; }
+            public string created_at { get; set; }
+            public string published_at { get; set; }
+            public List<Asset> assets { get; set; }
+            public string tarball_url { get; set; }
+            public string zipball_url { get; set; }
+            public string body { get; set; }
+        }
+    }
+}

+ 6 - 6
MediaBrowser.Common.Implementations/Updates/InstallationManager.cs

@@ -438,11 +438,12 @@ namespace MediaBrowser.Common.Implementations.Updates
         /// Installs the package.
         /// </summary>
         /// <param name="package">The package.</param>
+        /// <param name="isPlugin">if set to <c>true</c> [is plugin].</param>
         /// <param name="progress">The progress.</param>
         /// <param name="cancellationToken">The cancellation token.</param>
         /// <returns>Task.</returns>
         /// <exception cref="System.ArgumentNullException">package</exception>
-        public async Task InstallPackage(PackageVersionInfo package, IProgress<double> progress, CancellationToken cancellationToken)
+        public async Task InstallPackage(PackageVersionInfo package, bool isPlugin, IProgress<double> progress, CancellationToken cancellationToken)
         {
             if (package == null)
             {
@@ -495,7 +496,7 @@ namespace MediaBrowser.Common.Implementations.Updates
 
             try
             {
-                await InstallPackageInternal(package, innerProgress, linkedToken).ConfigureAwait(false);
+                await InstallPackageInternal(package, isPlugin, innerProgress, linkedToken).ConfigureAwait(false);
 
                 lock (CurrentInstallations)
                 {
@@ -551,18 +552,17 @@ namespace MediaBrowser.Common.Implementations.Updates
         /// Installs the package internal.
         /// </summary>
         /// <param name="package">The package.</param>
+        /// <param name="isPlugin">if set to <c>true</c> [is plugin].</param>
         /// <param name="progress">The progress.</param>
         /// <param name="cancellationToken">The cancellation token.</param>
         /// <returns>Task.</returns>
-        private async Task InstallPackageInternal(PackageVersionInfo package, IProgress<double> progress, CancellationToken cancellationToken)
+        private async Task InstallPackageInternal(PackageVersionInfo package, bool isPlugin, IProgress<double> progress, CancellationToken cancellationToken)
         {
             // Do the install
             await PerformPackageInstallation(progress, package, cancellationToken).ConfigureAwait(false);
 
-            var extension = Path.GetExtension(package.targetFilename) ?? "";
-
             // Do plugin-specific processing
-            if (!string.Equals(extension, ".zip", StringComparison.OrdinalIgnoreCase) && !string.Equals(extension, ".rar", StringComparison.OrdinalIgnoreCase) && !string.Equals(extension, ".7z", StringComparison.OrdinalIgnoreCase))
+            if (isPlugin)
             {
                 // Set last update time if we were installed before
                 var plugin = _applicationHost.Plugins.FirstOrDefault(p => string.Equals(p.Id.ToString(), package.guid, StringComparison.OrdinalIgnoreCase))

+ 2 - 1
MediaBrowser.Common/Updates/IInstallationManager.cs

@@ -105,11 +105,12 @@ namespace MediaBrowser.Common.Updates
         /// Installs the package.
         /// </summary>
         /// <param name="package">The package.</param>
+        /// <param name="isPlugin">if set to <c>true</c> [is plugin].</param>
         /// <param name="progress">The progress.</param>
         /// <param name="cancellationToken">The cancellation token.</param>
         /// <returns>Task.</returns>
         /// <exception cref="System.ArgumentNullException">package</exception>
-        Task InstallPackage(PackageVersionInfo package, IProgress<double> progress, CancellationToken cancellationToken);
+        Task InstallPackage(PackageVersionInfo package, bool isPlugin, IProgress<double> progress, CancellationToken cancellationToken);
 
         /// <summary>
         /// Uninstalls a plugin

+ 1 - 1
MediaBrowser.Server.Implementations/ScheduledTasks/PluginUpdateTask.cs

@@ -72,7 +72,7 @@ namespace MediaBrowser.Server.Implementations.ScheduledTasks
 
                 try
                 {
-                    await _installationManager.InstallPackage(i, new Progress<double>(), cancellationToken).ConfigureAwait(false);
+                    await _installationManager.InstallPackage(i, true, new Progress<double>(), cancellationToken).ConfigureAwait(false);
                 }
                 catch (OperationCanceledException)
                 {

+ 12 - 1
MediaBrowser.Server.Startup.Common/ApplicationHost.cs

@@ -101,6 +101,7 @@ using System.Reflection;
 using System.Threading;
 using System.Threading.Tasks;
 using CommonIO;
+using MediaBrowser.Common.Implementations.Updates;
 
 namespace MediaBrowser.Server.Startup.Common
 {
@@ -1308,6 +1309,16 @@ namespace MediaBrowser.Server.Startup.Common
         /// <returns>Task{CheckForUpdateResult}.</returns>
         public override async Task<CheckForUpdateResult> CheckForApplicationUpdate(CancellationToken cancellationToken, IProgress<double> progress)
         {
+            if (ConfigurationManager.CommonConfiguration.SystemUpdateLevel != PackageVersionClass.Dev)
+            {
+                var includePreRelease = ConfigurationManager.CommonConfiguration.SystemUpdateLevel != PackageVersionClass.Release;
+
+                var cacheLength = TimeSpan.FromHours(1);
+
+                return await new GithubUpdater(HttpClient, JsonSerializer, cacheLength)
+                    .CheckForUpdateResult("MediaBrowser", "Emby", ApplicationVersion, includePreRelease, "emby.windows.zip", "MBServer", "Mbserver.zip", cancellationToken).ConfigureAwait(false);
+            }
+
             var availablePackages = await InstallationManager.GetAvailablePackagesWithoutRegistrationInfo(cancellationToken).ConfigureAwait(false);
 
             var version = InstallationManager.GetLatestCompatibleVersion(availablePackages, _remotePackageName, null, ApplicationVersion, ConfigurationManager.CommonConfiguration.SystemUpdateLevel);
@@ -1339,7 +1350,7 @@ namespace MediaBrowser.Server.Startup.Common
         /// <returns>Task.</returns>
         public override async Task UpdateApplication(PackageVersionInfo package, CancellationToken cancellationToken, IProgress<double> progress)
         {
-            await InstallationManager.InstallPackage(package, progress, cancellationToken).ConfigureAwait(false);
+            await InstallationManager.InstallPackage(package, false, progress, cancellationToken).ConfigureAwait(false);
 
             HasUpdateAvailable = false;