aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--MediaBrowser.Api/PackageService.cs2
-rw-r--r--MediaBrowser.Common.Implementations/HttpClientManager/HttpClientManager.cs2
-rw-r--r--MediaBrowser.Common.Implementations/MediaBrowser.Common.Implementations.csproj2
-rw-r--r--MediaBrowser.Common.Implementations/Updates/GithubUpdater.cs195
-rw-r--r--MediaBrowser.Common.Implementations/Updates/InstallationManager.cs12
-rw-r--r--MediaBrowser.Common/Updates/IInstallationManager.cs3
-rw-r--r--MediaBrowser.Server.Implementations/ScheduledTasks/PluginUpdateTask.cs2
-rw-r--r--MediaBrowser.Server.Startup.Common/ApplicationHost.cs13
8 files changed, 220 insertions, 11 deletions
diff --git a/MediaBrowser.Api/PackageService.cs b/MediaBrowser.Api/PackageService.cs
index 4f9efad50..6d8378aae 100644
--- a/MediaBrowser.Api/PackageService.cs
+++ b/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>
diff --git a/MediaBrowser.Common.Implementations/HttpClientManager/HttpClientManager.cs b/MediaBrowser.Common.Implementations/HttpClientManager/HttpClientManager.cs
index 054c5aaaf..c30cdf1a7 100644
--- a/MediaBrowser.Common.Implementations/HttpClientManager/HttpClientManager.cs
+++ b/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))
diff --git a/MediaBrowser.Common.Implementations/MediaBrowser.Common.Implementations.csproj b/MediaBrowser.Common.Implementations/MediaBrowser.Common.Implementations.csproj
index 59e20ec6e..e87a6ad16 100644
--- a/MediaBrowser.Common.Implementations/MediaBrowser.Common.Implementations.csproj
+++ b/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>
diff --git a/MediaBrowser.Common.Implementations/Updates/GithubUpdater.cs b/MediaBrowser.Common.Implementations/Updates/GithubUpdater.cs
new file mode 100644
index 000000000..aff3dcf8d
--- /dev/null
+++ b/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; }
+ }
+ }
+}
diff --git a/MediaBrowser.Common.Implementations/Updates/InstallationManager.cs b/MediaBrowser.Common.Implementations/Updates/InstallationManager.cs
index 014275331..d155f11c7 100644
--- a/MediaBrowser.Common.Implementations/Updates/InstallationManager.cs
+++ b/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))
diff --git a/MediaBrowser.Common/Updates/IInstallationManager.cs b/MediaBrowser.Common/Updates/IInstallationManager.cs
index 7d721da6f..68853f05e 100644
--- a/MediaBrowser.Common/Updates/IInstallationManager.cs
+++ b/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
diff --git a/MediaBrowser.Server.Implementations/ScheduledTasks/PluginUpdateTask.cs b/MediaBrowser.Server.Implementations/ScheduledTasks/PluginUpdateTask.cs
index 96f469f69..457f5a33d 100644
--- a/MediaBrowser.Server.Implementations/ScheduledTasks/PluginUpdateTask.cs
+++ b/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)
{
diff --git a/MediaBrowser.Server.Startup.Common/ApplicationHost.cs b/MediaBrowser.Server.Startup.Common/ApplicationHost.cs
index 2bc01ebe1..3690c8f67 100644
--- a/MediaBrowser.Server.Startup.Common/ApplicationHost.cs
+++ b/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;