diff --git a/.gitignore b/.gitignore
index ff9e52259..9bbfd9b74 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,5 +1,7 @@
!*
+.directory
+
#################
## Eclipse
#################
diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md
index fdec0e75a..8945a17b5 100644
--- a/CONTRIBUTORS.md
+++ b/CONTRIBUTORS.md
@@ -9,15 +9,16 @@
- [bfayers](https://github.com/bfayers)
- [Bond_009](https://github.com/Bond-009)
- [AnthonyLavado](https://github.com/anthonylavado)
+ - [sparky8251](https://github.com/sparky8251)
# Emby Contributors
- - [LukePulverenti](https://github.com/LukePulverenti)
- - [ebr11](https://github.com/ebr11)
- - [lalmanzar](https://github.com/lalmanzar)
- - [schneifu](https://github.com/schneifu)
- - [Mark2xv](https://github.com/Mark2xv)
- - [ScottRapsey](https://github.com/ScottRapsey)
+ - [LukePulverenti](https://github.com/LukePulverenti)
+ - [ebr11](https://github.com/ebr11)
+ - [lalmanzar](https://github.com/lalmanzar)
+ - [schneifu](https://github.com/schneifu)
+ - [Mark2xv](https://github.com/Mark2xv)
+ - [ScottRapsey](https://github.com/ScottRapsey)
- [skynet600](https://github.com/skynet600)
- [Cheesegeezer](https://githum.com/Cheesegeezer)
- [Radeon](https://github.com/radeonorama)
diff --git a/Emby.Server.Implementations/ApplicationHost.cs b/Emby.Server.Implementations/ApplicationHost.cs
index f1e1b4b2d..3cc6151f1 100644
--- a/Emby.Server.Implementations/ApplicationHost.cs
+++ b/Emby.Server.Implementations/ApplicationHost.cs
@@ -368,7 +368,6 @@ namespace Emby.Server.Implementations
protected IAuthService AuthService { get; private set; }
public StartupOptions StartupOptions { get; private set; }
- protected readonly string ReleaseAssetFilename;
internal IPowerManagement PowerManagement { get; private set; }
internal IImageEncoder ImageEncoder { get; private set; }
@@ -393,7 +392,6 @@ namespace Emby.Server.Implementations
StartupOptions options,
IFileSystem fileSystem,
IPowerManagement powerManagement,
- string releaseAssetFilename,
IEnvironmentInfo environmentInfo,
IImageEncoder imageEncoder,
ISystemEvents systemEvents,
@@ -419,7 +417,6 @@ namespace Emby.Server.Implementations
Logger = LoggerFactory.CreateLogger("App");
StartupOptions = options;
- ReleaseAssetFilename = releaseAssetFilename;
PowerManagement = powerManagement;
ImageEncoder = imageEncoder;
@@ -1240,7 +1237,7 @@ namespace Emby.Server.Implementations
HttpClient,
ZipClient,
ProcessFactory,
- 5000, false,
+ 5000,
EnvironmentInfo);
MediaEncoder = mediaEncoder;
@@ -2286,56 +2283,6 @@ namespace Emby.Server.Implementations
Plugins = list.ToArray();
}
- ///
- /// Checks for update.
- ///
- /// The cancellation token.
- /// The progress.
- /// Task{CheckForUpdateResult}.
- public async Task CheckForApplicationUpdate(CancellationToken cancellationToken, IProgress progress)
- {
- var updateLevel = SystemUpdateLevel;
- var cacheLength = updateLevel == PackageVersionClass.Release ?
- TimeSpan.FromHours(12) :
- TimeSpan.FromMinutes(5);
-
- try
- {
- var result = await new GithubUpdater(HttpClient, JsonSerializer).CheckForUpdateResult("MediaBrowser",
- "Emby.Releases",
- ApplicationVersion,
- updateLevel,
- ReleaseAssetFilename,
- "MBServer",
- UpdateTargetFileName,
- cacheLength,
- cancellationToken).ConfigureAwait(false);
-
- HasUpdateAvailable = result.IsUpdateAvailable;
-
- return result;
- }
- catch (HttpException ex)
- {
- // users are overreacting to this occasionally failing
- if (ex.StatusCode.HasValue && ex.StatusCode.Value == HttpStatusCode.Forbidden)
- {
- HasUpdateAvailable = false;
- return new CheckForUpdateResult
- {
- IsUpdateAvailable = false
- };
- }
-
- throw;
- }
- }
-
- protected virtual string UpdateTargetFileName
- {
- get { return "Mbserver.zip"; }
- }
-
///
/// Updates the application.
///
diff --git a/Emby.Server.Implementations/Channels/ChannelManager.cs b/Emby.Server.Implementations/Channels/ChannelManager.cs
index 00da46f30..c2160d338 100644
--- a/Emby.Server.Implementations/Channels/ChannelManager.cs
+++ b/Emby.Server.Implementations/Channels/ChannelManager.cs
@@ -901,8 +901,8 @@ namespace Emby.Server.Implementations.Channels
private T GetItemById(string idString, string channelName, out bool isNew)
where T : BaseItem, new()
{
- var id = GetIdToHash(idString, channelName).GetMBId(typeof(T));
-
+ var id = _libraryManager.GetNewItemId(GetIdToHash(idString, channelName), typeof(T));
+
T item = null;
try
diff --git a/Emby.Server.Implementations/Devices/DeviceManager.cs b/Emby.Server.Implementations/Devices/DeviceManager.cs
index 250316211..82df96d8b 100644
--- a/Emby.Server.Implementations/Devices/DeviceManager.cs
+++ b/Emby.Server.Implementations/Devices/DeviceManager.cs
@@ -145,7 +145,8 @@ namespace Emby.Server.Implementations.Devices
HasUser = true
}).Items;
-
+
+ // TODO: DeviceQuery doesn't seem to be used from client. Not even Swagger.
if (query.SupportsSync.HasValue)
{
var val = query.SupportsSync.Value;
diff --git a/Emby.Server.Implementations/IO/SharpCifs/Smb/SmbFile.cs b/Emby.Server.Implementations/IO/SharpCifs/Smb/SmbFile.cs
index 151ec35c4..7fd9f0d84 100644
--- a/Emby.Server.Implementations/IO/SharpCifs/Smb/SmbFile.cs
+++ b/Emby.Server.Implementations/IO/SharpCifs/Smb/SmbFile.cs
@@ -3380,26 +3380,6 @@ namespace SharpCifs.Smb
SetAttributes(GetAttributes() & ~AttrReadonly);
}
- ///
- /// Returns a
- /// System.Uri
- /// for this SmbFile
. The
- /// URL
may be used as any other URL
might to
- /// access an SMB resource. Currently only retrieving data and information
- /// is supported (i.e. no doOutput).
- ///
- ///
- /// A new
- /// System.Uri
- ///
for this SmbFile
- ///
- /// System.UriFormatException
- [Obsolete(@"Use getURL() instead")]
- public virtual Uri ToUrl()
- {
- return Url;
- }
-
///
/// Computes a hashCode for this file based on the URL string and IP
/// address if the server.
diff --git a/Emby.Server.Implementations/Networking/IPNetwork/IPNetwork.cs b/Emby.Server.Implementations/Networking/IPNetwork/IPNetwork.cs
index 6d7785b90..8d0fb7997 100644
--- a/Emby.Server.Implementations/Networking/IPNetwork/IPNetwork.cs
+++ b/Emby.Server.Implementations/Networking/IPNetwork/IPNetwork.cs
@@ -189,7 +189,7 @@ namespace System.Net
internal
#endif
- IPNetwork(BigInteger ipaddress, AddressFamily family, byte cidr)
+ IPNetwork(BigInteger ipaddress, AddressFamily family, byte cidr)
{
int maxCidr = family == Sockets.AddressFamily.InterNetwork ? 32 : 128;
@@ -1164,18 +1164,6 @@ namespace System.Net
}
- [Obsolete("static Contains is deprecated, please use instance Contains.")]
- public static bool Contains(IPNetwork network, IPAddress ipaddress)
- {
-
- if (network == null)
- {
- throw new ArgumentNullException("network");
- }
-
- return network.Contains(ipaddress);
- }
-
///
/// return true is network2 is fully contained in network
///
@@ -1201,18 +1189,6 @@ namespace System.Net
return contains;
}
- [Obsolete("static Contains is deprecated, please use instance Contains.")]
- public static bool Contains(IPNetwork network, IPNetwork network2)
- {
-
- if (network == null)
- {
- throw new ArgumentNullException("network");
- }
-
- return network.Contains(network2);
- }
-
#endregion
#region overlap
@@ -1245,18 +1221,6 @@ namespace System.Net
return overlap;
}
- [Obsolete("static Overlap is deprecated, please use instance Overlap.")]
- public static bool Overlap(IPNetwork network, IPNetwork network2)
- {
-
- if (network == null)
- {
- throw new ArgumentNullException("network");
- }
-
- return network.Overlap(network2);
- }
-
#endregion
#region ToString
@@ -1341,18 +1305,6 @@ namespace System.Net
|| IPNetwork.IANA_CBLK_RESERVED1.Contains(this);
}
- [Obsolete("static IsIANAReserved is deprecated, please use instance IsIANAReserved.")]
- public static bool IsIANAReserved(IPNetwork ipnetwork)
- {
-
- if (ipnetwork == null)
- {
- throw new ArgumentNullException("ipnetwork");
- }
-
- return ipnetwork.IsIANAReserved();
- }
-
#endregion
#region Subnet
@@ -1371,16 +1323,6 @@ namespace System.Net
return ipnetworkCollection;
}
- [Obsolete("static Subnet is deprecated, please use instance Subnet.")]
- public static IPNetworkCollection Subnet(IPNetwork network, byte cidr)
- {
- if (network == null)
- {
- throw new ArgumentNullException("network");
- }
- return network.Subnet(cidr);
- }
-
///
/// Subnet a network into multiple nets of cidr mask
/// Subnet 192.168.0.0/24 into cidr 25 gives 192.168.0.0/25, 192.168.0.128/25
@@ -1402,16 +1344,6 @@ namespace System.Net
return true;
}
- [Obsolete("static TrySubnet is deprecated, please use instance TrySubnet.")]
- public static bool TrySubnet(IPNetwork network, byte cidr, out IPNetworkCollection ipnetworkCollection)
- {
- if (network == null)
- {
- throw new ArgumentNullException("network");
- }
- return network.TrySubnet(cidr, out ipnetworkCollection);
- }
-
#if TRAVISCI
public
#else
@@ -1476,12 +1408,6 @@ namespace System.Net
return supernet;
}
- [Obsolete("static Supernet is deprecated, please use instance Supernet.")]
- public static IPNetwork Supernet(IPNetwork network, IPNetwork network2)
- {
- return network.Supernet(network2);
- }
-
///
/// Try to supernet two consecutive cidr equal subnet into a single one
/// 192.168.0.0/24 + 192.168.1.0/24 = 192.168.0.0/23
@@ -1500,16 +1426,6 @@ namespace System.Net
return parsed;
}
- [Obsolete("static TrySupernet is deprecated, please use instance TrySupernet.")]
- public static bool TrySupernet(IPNetwork network, IPNetwork network2, out IPNetwork supernet)
- {
- if (network == null)
- {
- throw new ArgumentNullException("network");
- }
- return network.TrySupernet(network2, out supernet);
- }
-
#if TRAVISCI
public
#else
@@ -1920,18 +1836,6 @@ namespace System.Net
return sw.ToString();
}
- [Obsolete("static Print is deprecated, please use instance Print.")]
- public static string Print(IPNetwork ipnetwork)
- {
-
- if (ipnetwork == null)
- {
- throw new ArgumentNullException("ipnetwork");
- }
-
- return ipnetwork.Print();
- }
-
#endregion
#region TryGuessCidr
@@ -2018,12 +1922,6 @@ namespace System.Net
#region ListIPAddress
- [Obsolete("static ListIPAddress is deprecated, please use instance ListIPAddress.")]
- public static IPAddressCollection ListIPAddress(IPNetwork ipnetwork)
- {
- return ipnetwork.ListIPAddress();
- }
-
public IPAddressCollection ListIPAddress()
{
return new IPAddressCollection(this);
@@ -2167,4 +2065,4 @@ namespace System.Net
#endregion
}
-}
\ No newline at end of file
+}
diff --git a/Emby.Server.Implementations/ScheduledTasks/PluginUpdateTask.cs b/Emby.Server.Implementations/ScheduledTasks/PluginUpdateTask.cs
deleted file mode 100644
index 46a7f1f27..000000000
--- a/Emby.Server.Implementations/ScheduledTasks/PluginUpdateTask.cs
+++ /dev/null
@@ -1,142 +0,0 @@
-using MediaBrowser.Common;
-using MediaBrowser.Common.Updates;
-using Microsoft.Extensions.Logging;
-using MediaBrowser.Model.Net;
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.Linq;
-using System.Threading;
-using System.Threading.Tasks;
-using MediaBrowser.Common.Progress;
-using MediaBrowser.Model.Tasks;
-
-namespace Emby.Server.Implementations.ScheduledTasks
-{
- ///
- /// Plugin Update Task
- ///
- public class PluginUpdateTask : IScheduledTask, IConfigurableScheduledTask
- {
- ///
- /// The _logger
- ///
- private readonly ILogger _logger;
-
- private readonly IInstallationManager _installationManager;
-
- private readonly IApplicationHost _appHost;
-
- public PluginUpdateTask(ILogger logger, IInstallationManager installationManager, IApplicationHost appHost)
- {
- _logger = logger;
- _installationManager = installationManager;
- _appHost = appHost;
- }
-
- ///
- /// Creates the triggers that define when the task will run
- ///
- /// IEnumerable{BaseTaskTrigger}.
- public IEnumerable GetDefaultTriggers()
- {
- return new[] {
-
- // At startup
- new TaskTriggerInfo {Type = TaskTriggerInfo.TriggerStartup},
-
- // Every so often
- new TaskTriggerInfo { Type = TaskTriggerInfo.TriggerInterval, IntervalTicks = TimeSpan.FromHours(24).Ticks}
- };
- }
-
- public string Key
- {
- get { return "PluginUpdates"; }
- }
-
- ///
- /// Update installed plugins
- ///
- /// The cancellation token.
- /// The progress.
- /// Task.
- public async Task Execute(CancellationToken cancellationToken, IProgress progress)
- {
- progress.Report(0);
-
- var packagesToInstall = (await _installationManager.GetAvailablePluginUpdates(_appHost.ApplicationVersion, true, cancellationToken).ConfigureAwait(false)).ToList();
-
- progress.Report(10);
-
- var numComplete = 0;
-
- foreach (var package in packagesToInstall)
- {
- cancellationToken.ThrowIfCancellationRequested();
-
- try
- {
- await _installationManager.InstallPackage(package, true, new SimpleProgress(), cancellationToken).ConfigureAwait(false);
- }
- catch (OperationCanceledException)
- {
- // InstallPackage has it's own inner cancellation token, so only throw this if it's ours
- if (cancellationToken.IsCancellationRequested)
- {
- throw;
- }
- }
- catch (HttpException ex)
- {
- _logger.LogError(ex, "Error downloading {name}", package.name);
- }
- catch (IOException ex)
- {
- _logger.LogError(ex, "Error updating {name}", package.name);
- }
-
- // Update progress
- lock (progress)
- {
- numComplete++;
- double percent = numComplete;
- percent /= packagesToInstall.Count;
-
- progress.Report(90 * percent + 10);
- }
- }
-
- progress.Report(100);
- }
-
- ///
- /// Gets the name of the task
- ///
- /// The name.
- public string Name
- {
- get { return "Check for plugin updates"; }
- }
-
- ///
- /// Gets the description.
- ///
- /// The description.
- public string Description
- {
- get { return "Downloads and installs updates for plugins that are configured to update automatically."; }
- }
-
- public string Category
- {
- get { return "Application"; }
- }
-
- public bool IsHidden => true;
-
- public bool IsEnabled => true;
-
- public bool IsLogged => true;
- }
-}
diff --git a/Emby.Server.Implementations/ScheduledTasks/SystemUpdateTask.cs b/Emby.Server.Implementations/ScheduledTasks/SystemUpdateTask.cs
deleted file mode 100644
index 4cb97cbda..000000000
--- a/Emby.Server.Implementations/ScheduledTasks/SystemUpdateTask.cs
+++ /dev/null
@@ -1,128 +0,0 @@
-using MediaBrowser.Common;
-using MediaBrowser.Common.Configuration;
-using Microsoft.Extensions.Logging;
-using System;
-using System.Collections.Generic;
-using System.Threading;
-using System.Threading.Tasks;
-using MediaBrowser.Common.Progress;
-using MediaBrowser.Model.Tasks;
-
-namespace Emby.Server.Implementations.ScheduledTasks
-{
- ///
- /// Plugin Update Task
- ///
- public class SystemUpdateTask : IScheduledTask
- {
- ///
- /// The _app host
- ///
- private readonly IApplicationHost _appHost;
-
- ///
- /// Gets or sets the configuration manager.
- ///
- /// The configuration manager.
- private IConfigurationManager ConfigurationManager { get; set; }
- ///
- /// Gets or sets the logger.
- ///
- /// The logger.
- private ILogger Logger { get; set; }
-
- ///
- /// Initializes a new instance of the class.
- ///
- /// The app host.
- /// The configuration manager.
- /// The logger.
- public SystemUpdateTask(IApplicationHost appHost, IConfigurationManager configurationManager, ILogger logger)
- {
- _appHost = appHost;
- ConfigurationManager = configurationManager;
- Logger = logger;
- }
-
- ///
- /// Creates the triggers that define when the task will run
- ///
- /// IEnumerable{BaseTaskTrigger}.
- public IEnumerable GetDefaultTriggers()
- {
- return new[] {
-
- // At startup
- new TaskTriggerInfo {Type = TaskTriggerInfo.TriggerStartup},
-
- // Every so often
- new TaskTriggerInfo { Type = TaskTriggerInfo.TriggerInterval, IntervalTicks = TimeSpan.FromHours(24).Ticks}
- };
- }
-
- ///
- /// Returns the task to be executed
- ///
- /// The cancellation token.
- /// The progress.
- /// Task.
- public async Task Execute(CancellationToken cancellationToken, IProgress progress)
- {
- // Create a progress object for the update check
- var updateInfo = await _appHost.CheckForApplicationUpdate(cancellationToken, new SimpleProgress()).ConfigureAwait(false);
-
- if (!updateInfo.IsUpdateAvailable)
- {
- Logger.LogDebug("No application update available.");
- return;
- }
-
- cancellationToken.ThrowIfCancellationRequested();
-
- if (!_appHost.CanSelfUpdate) return;
-
- if (ConfigurationManager.CommonConfiguration.EnableAutoUpdate)
- {
- Logger.LogInformation("Update Revision {0} available. Updating...", updateInfo.AvailableVersion);
-
- await _appHost.UpdateApplication(updateInfo.Package, cancellationToken, progress).ConfigureAwait(false);
- }
- else
- {
- Logger.LogInformation("A new version of " + _appHost.Name + " is available.");
- }
- }
-
- ///
- /// Gets the name of the task
- ///
- /// The name.
- public string Name
- {
- get { return "Check for application updates"; }
- }
-
- ///
- /// Gets the description.
- ///
- /// The description.
- public string Description
- {
- get { return "Downloads and installs application updates."; }
- }
-
- ///
- /// Gets the category.
- ///
- /// The category.
- public string Category
- {
- get { return "Application"; }
- }
-
- public string Key
- {
- get { return "SystemUpdateTask"; }
- }
- }
-}
diff --git a/Jellyfin.Server/CoreAppHost.cs b/Jellyfin.Server/CoreAppHost.cs
index 2fb106b3c..b54634387 100644
--- a/Jellyfin.Server/CoreAppHost.cs
+++ b/Jellyfin.Server/CoreAppHost.cs
@@ -11,8 +11,8 @@ namespace Jellyfin.Server
{
public class CoreAppHost : ApplicationHost
{
- public CoreAppHost(ServerApplicationPaths applicationPaths, ILoggerFactory loggerFactory, StartupOptions options, IFileSystem fileSystem, IPowerManagement powerManagement, string releaseAssetFilename, IEnvironmentInfo environmentInfo, MediaBrowser.Controller.Drawing.IImageEncoder imageEncoder, ISystemEvents systemEvents, MediaBrowser.Common.Net.INetworkManager networkManager)
- : base(applicationPaths, loggerFactory, options, fileSystem, powerManagement, releaseAssetFilename, environmentInfo, imageEncoder, systemEvents, networkManager)
+ public CoreAppHost(ServerApplicationPaths applicationPaths, ILoggerFactory loggerFactory, StartupOptions options, IFileSystem fileSystem, IPowerManagement powerManagement, IEnvironmentInfo environmentInfo, MediaBrowser.Controller.Drawing.IImageEncoder imageEncoder, ISystemEvents systemEvents, MediaBrowser.Common.Net.INetworkManager networkManager)
+ : base(applicationPaths, loggerFactory, options, fileSystem, powerManagement, environmentInfo, imageEncoder, systemEvents, networkManager)
{
}
diff --git a/Jellyfin.Server/Program.cs b/Jellyfin.Server/Program.cs
index 0150cd533..9cc2fe103 100644
--- a/Jellyfin.Server/Program.cs
+++ b/Jellyfin.Server/Program.cs
@@ -73,7 +73,6 @@ namespace Jellyfin.Server
options,
fileSystem,
new PowerManagement(),
- "embyserver-mono_{version}.zip",
environmentInfo,
new NullImageEncoder(),
new SystemEvents(_loggerFactory.CreateLogger("SystemEvents")),
diff --git a/MediaBrowser.Common/Extensions/BaseExtensions.cs b/MediaBrowser.Common/Extensions/BaseExtensions.cs
index d7f4424fa..520c04244 100644
--- a/MediaBrowser.Common/Extensions/BaseExtensions.cs
+++ b/MediaBrowser.Common/Extensions/BaseExtensions.cs
@@ -34,25 +34,5 @@ namespace MediaBrowser.Common.Extensions
{
return CryptographyProvider.GetMD5(str);
}
-
- ///
- /// Gets the MB id.
- ///
- /// The STR.
- /// The type.
- /// Guid.
- /// type
- [Obsolete("Use LibraryManager.GetNewItemId")]
- public static Guid GetMBId(this string str, Type type)
- {
- if (type == null)
- {
- throw new ArgumentNullException("type");
- }
-
- var key = type.FullName + str.ToLower();
-
- return key.GetMD5();
- }
}
}
diff --git a/MediaBrowser.Common/IApplicationHost.cs b/MediaBrowser.Common/IApplicationHost.cs
index 32b942b60..39d69ea15 100644
--- a/MediaBrowser.Common/IApplicationHost.cs
+++ b/MediaBrowser.Common/IApplicationHost.cs
@@ -85,12 +85,6 @@ namespace MediaBrowser.Common
/// IEnumerable{``0}.
IEnumerable GetExports(bool manageLiftime = true);
- ///
- /// Checks for update.
- ///
- /// Task{CheckForUpdateResult}.
- Task CheckForApplicationUpdate(CancellationToken cancellationToken, IProgress progress);
-
///
/// Updates the application.
///
diff --git a/MediaBrowser.Common/Updates/GithubUpdater.cs b/MediaBrowser.Common/Updates/GithubUpdater.cs
deleted file mode 100644
index 22ed788e0..000000000
--- a/MediaBrowser.Common/Updates/GithubUpdater.cs
+++ /dev/null
@@ -1,274 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.Linq;
-using System.Threading;
-using System.Threading.Tasks;
-using MediaBrowser.Common.Net;
-using MediaBrowser.Model.Serialization;
-using MediaBrowser.Model.Updates;
-
-namespace MediaBrowser.Common.Updates
-{
- public class GithubUpdater
- {
- private readonly IHttpClient _httpClient;
- private readonly IJsonSerializer _jsonSerializer;
-
- public GithubUpdater(IHttpClient httpClient, IJsonSerializer jsonSerializer)
- {
- _httpClient = httpClient;
- _jsonSerializer = jsonSerializer;
- }
-
- public async Task CheckForUpdateResult(string organzation, string repository, Version minVersion, PackageVersionClass updateLevel, string assetFilename, string packageName, string targetFilename, TimeSpan cacheLength, 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",
- BufferContent = false
- };
-
- if (cacheLength.Ticks > 0)
- {
- options.CacheMode = CacheMode.Unconditional;
- options.CacheLength = cacheLength;
- }
-
- using (var response = await _httpClient.SendAsync(options, "GET").ConfigureAwait(false))
- using (var stream = response.Content)
- {
- var obj = await _jsonSerializer.DeserializeFromStreamAsync(stream).ConfigureAwait(false);
-
- return CheckForUpdateResult(obj, minVersion, updateLevel, assetFilename, packageName, targetFilename);
- }
- }
-
- private CheckForUpdateResult CheckForUpdateResult(RootObject[] obj, Version minVersion, PackageVersionClass updateLevel, string assetFilename, string packageName, string targetFilename)
- {
- if (updateLevel == PackageVersionClass.Release)
- {
- // Technically all we need to do is check that it's not pre-release
- // But let's addititional checks for -beta and -dev to handle builds that might be temporarily tagged incorrectly.
- obj = obj.Where(i => !i.prerelease && !i.name.EndsWith("-beta", StringComparison.OrdinalIgnoreCase) && !i.name.EndsWith("-dev", StringComparison.OrdinalIgnoreCase)).ToArray();
- }
- else if (updateLevel == PackageVersionClass.Beta)
- {
- obj = obj.Where(i => i.prerelease && i.name.EndsWith("-beta", StringComparison.OrdinalIgnoreCase)).ToArray();
- }
- else if (updateLevel == PackageVersionClass.Dev)
- {
- obj = obj.Where(i => !i.prerelease || i.name.EndsWith("-beta", StringComparison.OrdinalIgnoreCase) || i.name.EndsWith("-dev", StringComparison.OrdinalIgnoreCase)).ToArray();
- }
-
- var availableUpdate = obj
- .Select(i => CheckForUpdateResult(i, minVersion, assetFilename, packageName, targetFilename))
- .Where(i => i != null)
- .OrderByDescending(i => Version.Parse(i.AvailableVersion))
- .FirstOrDefault();
-
- return availableUpdate ?? new CheckForUpdateResult
- {
- IsUpdateAvailable = false
- };
- }
-
- private bool MatchesUpdateLevel(RootObject i, PackageVersionClass updateLevel)
- {
- if (updateLevel == PackageVersionClass.Beta)
- {
- return i.prerelease && i.name.EndsWith("-beta", StringComparison.OrdinalIgnoreCase);
- }
- if (updateLevel == PackageVersionClass.Dev)
- {
- return !i.prerelease || i.name.EndsWith("-beta", StringComparison.OrdinalIgnoreCase) ||
- i.name.EndsWith("-dev", StringComparison.OrdinalIgnoreCase);
- }
-
- // Technically all we need to do is check that it's not pre-release
- // But let's addititional checks for -beta and -dev to handle builds that might be temporarily tagged incorrectly.
- return !i.prerelease && !i.name.EndsWith("-beta", StringComparison.OrdinalIgnoreCase) &&
- !i.name.EndsWith("-dev", StringComparison.OrdinalIgnoreCase);
- }
-
- public async Task> GetLatestReleases(string organzation, string repository, string assetFilename, CancellationToken cancellationToken)
- {
- var list = new List();
-
- 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",
- BufferContent = false
- };
-
- using (var response = await _httpClient.SendAsync(options, "GET").ConfigureAwait(false))
- using (var stream = response.Content)
- {
- var obj = await _jsonSerializer.DeserializeFromStreamAsync(stream).ConfigureAwait(false);
-
- obj = obj.Where(i => (i.assets ?? new List()).Any(a => IsAsset(a, assetFilename, i.tag_name))).ToArray();
-
- list.AddRange(obj.Where(i => MatchesUpdateLevel(i, PackageVersionClass.Release)).OrderByDescending(GetVersion).Take(1));
- list.AddRange(obj.Where(i => MatchesUpdateLevel(i, PackageVersionClass.Beta)).OrderByDescending(GetVersion).Take(1));
- list.AddRange(obj.Where(i => MatchesUpdateLevel(i, PackageVersionClass.Dev)).OrderByDescending(GetVersion).Take(1));
-
- return list;
- }
- }
-
- public Version GetVersion(RootObject obj)
- {
- Version version;
- if (!Version.TryParse(obj.tag_name, out version))
- {
- return new Version(1, 0);
- }
-
- return version;
- }
-
- private CheckForUpdateResult CheckForUpdateResult(RootObject obj, Version minVersion, string assetFilename, string packageName, string targetFilename)
- {
- Version version;
- var versionString = obj.tag_name;
- if (!Version.TryParse(versionString, out version))
- {
- return null;
- }
-
- if (version < minVersion)
- {
- return null;
- }
-
- var asset = (obj.assets ?? new List()).FirstOrDefault(i => IsAsset(i, assetFilename, versionString));
-
- if (asset == null)
- {
- return null;
- }
-
- return new CheckForUpdateResult
- {
- AvailableVersion = version.ToString(),
- IsUpdateAvailable = version > minVersion,
- Package = new PackageVersionInfo
- {
- classification = obj.prerelease ?
- (obj.name.EndsWith("-dev", StringComparison.OrdinalIgnoreCase) ? PackageVersionClass.Dev : PackageVersionClass.Beta) :
- PackageVersionClass.Release,
- name = packageName,
- sourceUrl = asset.browser_download_url,
- targetFilename = targetFilename,
- versionStr = version.ToString(),
- requiredVersionStr = "1.0.0",
- description = obj.body,
- infoUrl = obj.html_url
- }
- };
- }
-
- private bool IsAsset(Asset asset, string assetFilename, string version)
- {
- var downloadFilename = Path.GetFileName(asset.browser_download_url) ?? string.Empty;
-
- assetFilename = assetFilename.Replace("{version}", version);
-
- if (downloadFilename.IndexOf(assetFilename, StringComparison.OrdinalIgnoreCase) != -1)
- {
- return true;
- }
-
- return string.Equals(assetFilename, downloadFilename, StringComparison.OrdinalIgnoreCase);
- }
-
- 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 assets { get; set; }
- public string tarball_url { get; set; }
- public string zipball_url { get; set; }
- public string body { get; set; }
- }
- }
-}
diff --git a/MediaBrowser.MediaEncoding/Encoder/EncoderValidator.cs b/MediaBrowser.MediaEncoding/Encoder/EncoderValidator.cs
index fb131f304..b68961889 100644
--- a/MediaBrowser.MediaEncoding/Encoder/EncoderValidator.cs
+++ b/MediaBrowser.MediaEncoding/Encoder/EncoderValidator.cs
@@ -1,7 +1,8 @@
using System;
using System.Collections.Generic;
-using System.Diagnostics;
using System.Globalization;
+using System.Linq;
+using System.Text.RegularExpressions;
using MediaBrowser.Model.Diagnostics;
using Microsoft.Extensions.Logging;
@@ -18,21 +19,21 @@ namespace MediaBrowser.MediaEncoding.Encoder
_processFactory = processFactory;
}
- public Tuple, List> Validate(string encoderPath)
+ public (IEnumerable decoders, IEnumerable encoders) Validate(string encoderPath)
{
- _logger.LogInformation("Validating media encoder at {0}", encoderPath);
+ _logger.LogInformation("Validating media encoder at {EncoderPath}", encoderPath);
- var decoders = GetDecoders(encoderPath);
- var encoders = GetEncoders(encoderPath);
+ var decoders = GetCodecs(encoderPath, Codec.Decoder);
+ var encoders = GetCodecs(encoderPath, Codec.Encoder);
_logger.LogInformation("Encoder validation complete");
- return new Tuple, List>(decoders, encoders);
+ return (decoders, encoders);
}
public bool ValidateVersion(string encoderAppPath, bool logOutput)
{
- string output = string.Empty;
+ string output = null;
try
{
output = GetProcessOutput(encoderAppPath, "-version");
@@ -71,20 +72,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
return true;
}
- private List GetDecoders(string encoderAppPath)
- {
- string output = string.Empty;
- try
- {
- output = GetProcessOutput(encoderAppPath, "-decoders");
- }
- catch (Exception ex)
- {
- _logger.LogError(ex, "Error detecting available decoders");
- }
-
- var found = new List();
- var required = new[]
+ private static readonly string[] requiredDecoders = new[]
{
"mpeg2video",
"h264_qsv",
@@ -101,33 +89,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
"hevc"
};
- foreach (var codec in required)
- {
- var srch = " " + codec + " ";
-
- if (output.IndexOf(srch, StringComparison.OrdinalIgnoreCase) != -1)
- {
- _logger.LogInformation("Decoder available: " + codec);
- found.Add(codec);
- }
- }
-
- return found;
- }
-
- private List GetEncoders(string encoderAppPath)
- {
- string output = null;
- try
- {
- output = GetProcessOutput(encoderAppPath, "-encoders");
- }
- catch
- {
- }
-
- var found = new List();
- var required = new[]
+ private static readonly string[] requiredEncoders = new[]
{
"libx264",
"libx265",
@@ -151,32 +113,46 @@ namespace MediaBrowser.MediaEncoding.Encoder
"ac3"
};
- output = output ?? string.Empty;
+ private enum Codec
+ {
+ Encoder,
+ Decoder
+ }
- var index = 0;
-
- foreach (var codec in required)
+ private IEnumerable GetCodecs(string encoderAppPath, Codec codec)
+ {
+ string codecstr = codec == Codec.Encoder ? "encoders" : "decoders";
+ string output = null;
+ try
{
- var srch = " " + codec + " ";
-
- if (output.IndexOf(srch, StringComparison.OrdinalIgnoreCase) != -1)
- {
- if (index < required.Length - 1)
- {
- _logger.LogInformation("Encoder available: " + codec);
- }
-
- found.Add(codec);
- }
- index++;
+ output = GetProcessOutput(encoderAppPath, "-" + codecstr);
}
+ catch (Exception ex)
+ {
+ _logger.LogError(ex, "Error detecting available {Codec}", codecstr);
+ }
+
+ if (string.IsNullOrWhiteSpace(output))
+ {
+ return Enumerable.Empty();
+ }
+
+ var required = codec == Codec.Encoder ? requiredEncoders : requiredDecoders;
+
+ var found = Regex
+ .Matches(output, @"^\s\S{6}\s(?[\w|-]+)\s+.+$", RegexOptions.Multiline)
+ .Cast()
+ .Select(x => x.Groups["codec"].Value)
+ .Where(x => required.Contains(x));
+
+ _logger.LogInformation("Available {Codec}: {Codecs}", codecstr, found);
return found;
}
private string GetProcessOutput(string path, string arguments)
{
- var process = _processFactory.Create(new ProcessOptions
+ IProcess process = _processFactory.Create(new ProcessOptions
{
CreateNoWindow = true,
UseShellExecute = false,
@@ -187,7 +163,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
RedirectStandardOutput = true
});
- _logger.LogInformation("Running {path} {arguments}", path, arguments);
+ _logger.LogInformation("Running {Path} {Arguments}", path, arguments);
using (process)
{
diff --git a/MediaBrowser.MediaEncoding/Encoder/FontConfigLoader.cs b/MediaBrowser.MediaEncoding/Encoder/FontConfigLoader.cs
deleted file mode 100644
index c62de0b11..000000000
--- a/MediaBrowser.MediaEncoding/Encoder/FontConfigLoader.cs
+++ /dev/null
@@ -1,179 +0,0 @@
-using System;
-using System.IO;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-using MediaBrowser.Common.Configuration;
-using MediaBrowser.Common.Net;
-using MediaBrowser.Common.Progress;
-using MediaBrowser.Model.IO;
-using MediaBrowser.Model.Net;
-using Microsoft.Extensions.Logging;
-
-namespace MediaBrowser.MediaEncoding.Encoder
-{
- public class FontConfigLoader
- {
- private readonly IHttpClient _httpClient;
- private readonly IApplicationPaths _appPaths;
- private readonly ILogger _logger;
- private readonly IZipClient _zipClient;
- private readonly IFileSystem _fileSystem;
-
- private readonly string[] _fontUrls =
- {
- "https://github.com/MediaBrowser/MediaBrowser.Resources/raw/master/ffmpeg/ARIALUNI.7z"
- };
-
- public FontConfigLoader(IHttpClient httpClient, IApplicationPaths appPaths, ILogger logger, IZipClient zipClient, IFileSystem fileSystem)
- {
- _httpClient = httpClient;
- _appPaths = appPaths;
- _logger = logger;
- _zipClient = zipClient;
- _fileSystem = fileSystem;
- }
-
- ///
- /// Extracts the fonts.
- ///
- /// The target path.
- /// Task.
- public async Task DownloadFonts(string targetPath)
- {
- try
- {
- var fontsDirectory = Path.Combine(targetPath, "fonts");
-
- _fileSystem.CreateDirectory(fontsDirectory);
-
- const string fontFilename = "ARIALUNI.TTF";
-
- var fontFile = Path.Combine(fontsDirectory, fontFilename);
-
- if (_fileSystem.FileExists(fontFile))
- {
- await WriteFontConfigFile(fontsDirectory).ConfigureAwait(false);
- }
- else
- {
- // Kick this off, but no need to wait on it
- var task = Task.Run(async () =>
- {
- await DownloadFontFile(fontsDirectory, fontFilename, new SimpleProgress()).ConfigureAwait(false);
-
- await WriteFontConfigFile(fontsDirectory).ConfigureAwait(false);
- });
- }
- }
- catch (HttpException ex)
- {
- // Don't let the server crash because of this
- _logger.LogError(ex, "Error downloading ffmpeg font files");
- }
- catch (Exception ex)
- {
- // Don't let the server crash because of this
- _logger.LogError(ex, "Error writing ffmpeg font files");
- }
- }
-
- ///
- /// Downloads the font file.
- ///
- /// The fonts directory.
- /// The font filename.
- /// Task.
- private async Task DownloadFontFile(string fontsDirectory, string fontFilename, IProgress progress)
- {
- var existingFile = _fileSystem
- .GetFilePaths(_appPaths.ProgramDataPath, true)
- .FirstOrDefault(i => string.Equals(fontFilename, Path.GetFileName(i), StringComparison.OrdinalIgnoreCase));
-
- if (existingFile != null)
- {
- try
- {
- _fileSystem.CopyFile(existingFile, Path.Combine(fontsDirectory, fontFilename), true);
- return;
- }
- catch (IOException ex)
- {
- // Log this, but don't let it fail the operation
- _logger.LogError(ex, "Error copying file");
- }
- }
-
- string tempFile = null;
-
- foreach (var url in _fontUrls)
- {
- progress.Report(0);
-
- try
- {
- tempFile = await _httpClient.GetTempFile(new HttpRequestOptions
- {
- Url = url,
- Progress = progress
-
- }).ConfigureAwait(false);
-
- break;
- }
- catch (Exception ex)
- {
- // The core can function without the font file, so handle this
- _logger.LogError(ex, "Failed to download ffmpeg font file from {url}", url);
- }
- }
-
- if (string.IsNullOrEmpty(tempFile))
- {
- return;
- }
-
- Extract7zArchive(tempFile, fontsDirectory);
-
- try
- {
- _fileSystem.DeleteFile(tempFile);
- }
- catch (IOException ex)
- {
- // Log this, but don't let it fail the operation
- _logger.LogError(ex, "Error deleting temp file {path}", tempFile);
- }
- }
- private void Extract7zArchive(string archivePath, string targetPath)
- {
- _logger.LogInformation("Extracting {ArchivePath} to {TargetPath}", archivePath, targetPath);
-
- _zipClient.ExtractAllFrom7z(archivePath, targetPath, true);
- }
-
- ///
- /// Writes the font config file.
- ///
- /// The fonts directory.
- /// Task.
- private async Task WriteFontConfigFile(string fontsDirectory)
- {
- const string fontConfigFilename = "fonts.conf";
- var fontConfigFile = Path.Combine(fontsDirectory, fontConfigFilename);
-
- if (!_fileSystem.FileExists(fontConfigFile))
- {
- var contents = string.Format("{0}ArialArial Unicode MS", fontsDirectory);
-
- var bytes = Encoding.UTF8.GetBytes(contents);
-
- using (var fileStream = _fileSystem.GetFileStream(fontConfigFile, FileOpenMode.Create, FileAccessMode.Write,
- FileShareMode.Read, true))
- {
- await fileStream.WriteAsync(bytes, 0, bytes.Length);
- }
- }
- }
- }
-}
diff --git a/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs b/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs
index 181fc0f65..a93dd9742 100644
--- a/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs
+++ b/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs
@@ -70,13 +70,27 @@ namespace MediaBrowser.MediaEncoding.Encoder
private readonly string _originalFFMpegPath;
private readonly string _originalFFProbePath;
private readonly int DefaultImageExtractionTimeoutMs;
- private readonly bool EnableEncoderFontFile;
-
private readonly IEnvironmentInfo _environmentInfo;
- public MediaEncoder(ILogger logger, IJsonSerializer jsonSerializer, string ffMpegPath, string ffProbePath, bool hasExternalEncoder, IServerConfigurationManager configurationManager, IFileSystem fileSystem, ILiveTvManager liveTvManager, IIsoManager isoManager, ILibraryManager libraryManager, IChannelManager channelManager, ISessionManager sessionManager, Func subtitleEncoder, Func mediaSourceManager, IHttpClient httpClient, IZipClient zipClient, IProcessFactory processFactory,
+ public MediaEncoder(ILogger logger,
+ IJsonSerializer jsonSerializer,
+ string ffMpegPath,
+ string ffProbePath,
+ bool hasExternalEncoder,
+ IServerConfigurationManager configurationManager,
+ IFileSystem fileSystem,
+ ILiveTvManager liveTvManager,
+ IIsoManager isoManager,
+ ILibraryManager libraryManager,
+ IChannelManager channelManager,
+ ISessionManager sessionManager,
+ Func subtitleEncoder,
+ Func mediaSourceManager,
+ IHttpClient httpClient,
+ IZipClient zipClient,
+ IProcessFactory processFactory,
int defaultImageExtractionTimeoutMs,
- bool enableEncoderFontFile, IEnvironmentInfo environmentInfo)
+ IEnvironmentInfo environmentInfo)
{
_logger = logger;
_jsonSerializer = jsonSerializer;
@@ -93,7 +107,6 @@ namespace MediaBrowser.MediaEncoding.Encoder
_zipClient = zipClient;
_processFactory = processFactory;
DefaultImageExtractionTimeoutMs = defaultImageExtractionTimeoutMs;
- EnableEncoderFontFile = enableEncoderFontFile;
_environmentInfo = environmentInfo;
FFProbePath = ffProbePath;
FFMpegPath = ffMpegPath;
@@ -175,18 +188,8 @@ namespace MediaBrowser.MediaEncoding.Encoder
{
var result = new EncoderValidator(_logger, _processFactory).Validate(FFMpegPath);
- SetAvailableDecoders(result.Item1);
- SetAvailableEncoders(result.Item2);
-
- if (EnableEncoderFontFile)
- {
- var directory = FileSystem.GetDirectoryName(FFMpegPath);
-
- if (!string.IsNullOrWhiteSpace(directory) && FileSystem.ContainsSubPath(ConfigurationManager.ApplicationPaths.ProgramDataPath, directory))
- {
- new FontConfigLoader(_httpClient, ConfigurationManager.ApplicationPaths, _logger, _zipClient, FileSystem).DownloadFonts(directory).ConfigureAwait(false);
- }
- }
+ SetAvailableDecoders(result.decoders);
+ SetAvailableEncoders(result.encoders);
}
}
@@ -401,14 +404,14 @@ namespace MediaBrowser.MediaEncoding.Encoder
}
private List _encoders = new List();
- public void SetAvailableEncoders(List list)
+ public void SetAvailableEncoders(IEnumerable list)
{
_encoders = list.ToList();
//_logger.Info("Supported encoders: {0}", string.Join(",", list.ToArray()));
}
private List _decoders = new List();
- public void SetAvailableDecoders(List list)
+ public void SetAvailableDecoders(IEnumerable list)
{
_decoders = list.ToList();
//_logger.Info("Supported decoders: {0}", string.Join(",", list.ToArray()));
diff --git a/MediaBrowser.Model/Devices/DeviceQuery.cs b/MediaBrowser.Model/Devices/DeviceQuery.cs
index 9ceea1ea8..fa2e11d4d 100644
--- a/MediaBrowser.Model/Devices/DeviceQuery.cs
+++ b/MediaBrowser.Model/Devices/DeviceQuery.cs
@@ -1,4 +1,6 @@
+using System;
+
namespace MediaBrowser.Model.Devices
{
public class DeviceQuery
@@ -17,6 +19,6 @@ namespace MediaBrowser.Model.Devices
/// Gets or sets the user identifier.
///
/// The user identifier.
- public string UserId { get; set; }
+ public Guid UserId { get; set; }
}
}