@ -1,5 +1,4 @@
using Emby.Common.Implementations ;
using Emby.Common.Implementations.Serialization ;
using Emby.Common.Implementations.Serialization ;
using Emby.Dlna ;
using Emby.Dlna.ConnectionManager ;
using Emby.Dlna.ContentDirectory ;
@ -8,12 +7,16 @@ using Emby.Dlna.MediaReceiverRegistrar;
using Emby.Dlna.Ssdp ;
using Emby.Drawing ;
using Emby.Photos ;
using Emby.Server.Core.Cryptography ;
using Emby.Server.Implementations.Activity ;
using Emby.Server.Implementations.Archiving ;
using Emby.Server.Implementations.Channels ;
using Emby.Server.Implementations.Collections ;
using Emby.Server.Implementations.Configuration ;
using Emby.Server.Implementations.Cryptography ;
using Emby.Server.Implementations.Data ;
using Emby.Server.Implementations.Devices ;
using Emby.Server.Implementations.Diagnostics ;
using Emby.Server.Implementations.Dto ;
using Emby.Server.Implementations.FFMpeg ;
using Emby.Server.Implementations.HttpServer ;
@ -23,14 +26,20 @@ using Emby.Server.Implementations.Library;
using Emby.Server.Implementations.LiveTv ;
using Emby.Server.Implementations.Localization ;
using Emby.Server.Implementations.MediaEncoder ;
using Emby.Server.Implementations. Migrations ;
using Emby.Server.Implementations. Net ;
using Emby.Server.Implementations.Notifications ;
using Emby.Server.Implementations.Playlists ;
using Emby.Server.Implementations.Reflection ;
using Emby.Server.Implementations.ScheduledTasks ;
using Emby.Server.Implementations.Security ;
using Emby.Server.Implementations.Serialization ;
using Emby.Server.Implementations.Session ;
using Emby.Server.Implementations.Social ;
using Emby.Server.Implementations.Threading ;
using Emby.Server.Implementations.TV ;
using Emby.Server.Implementations.Updates ;
using Emby.Server.Implementations.Xml ;
using Emby.Server.MediaEncoding.Subtitles ;
using MediaBrowser.Api ;
using MediaBrowser.Common ;
using MediaBrowser.Common.Configuration ;
@ -52,9 +61,6 @@ using MediaBrowser.Controller.Dlna;
using MediaBrowser.Controller.Drawing ;
using MediaBrowser.Controller.Dto ;
using MediaBrowser.Controller.Entities ;
using MediaBrowser.Controller.Entities.Audio ;
using MediaBrowser.Controller.Entities.Movies ;
using MediaBrowser.Controller.Entities.TV ;
using MediaBrowser.Controller.Library ;
using MediaBrowser.Controller.LiveTv ;
using MediaBrowser.Controller.MediaEncoding ;
@ -72,10 +78,13 @@ using MediaBrowser.Controller.Subtitles;
using MediaBrowser.Controller.Sync ;
using MediaBrowser.Controller.TV ;
using MediaBrowser.LocalMetadata.Savers ;
using MediaBrowser.MediaEncoding.BdInfo ;
using MediaBrowser.Model.Activity ;
using MediaBrowser.Model.Configuration ;
using MediaBrowser.Model.Cryptography ;
using MediaBrowser.Model.Diagnostics ;
using MediaBrowser.Model.Dlna ;
using MediaBrowser.Model.Events ;
using MediaBrowser.Model.Globalization ;
using MediaBrowser.Model.IO ;
using MediaBrowser.Model.Logging ;
@ -87,7 +96,9 @@ using MediaBrowser.Model.Serialization;
using MediaBrowser.Model.Services ;
using MediaBrowser.Model.Social ;
using MediaBrowser.Model.System ;
using MediaBrowser.Model.Tasks ;
using MediaBrowser.Model.Text ;
using MediaBrowser.Model.Threading ;
using MediaBrowser.Model.Updates ;
using MediaBrowser.Model.Xml ;
using MediaBrowser.Providers.Chapters ;
@ -97,7 +108,6 @@ using MediaBrowser.WebDashboard.Api;
using MediaBrowser.XbmcMetadata.Providers ;
using OpenSubtitlesHandler ;
using ServiceStack ;
using SocketHttpListener.Primitives ;
using System ;
using System.Collections.Concurrent ;
using System.Collections.Generic ;
@ -111,30 +121,15 @@ using System.Security.Cryptography.X509Certificates;
using System.Text ;
using System.Threading ;
using System.Threading.Tasks ;
using Emby.Server.Core.Cryptography ;
using Emby.Server.Implementations.Archiving ;
using Emby.Server.Implementations.Cryptography ;
using Emby.Server.Implementations.Diagnostics ;
using Emby.Server.Implementations.Net ;
using Emby.Server.Implementations.Reflection ;
using Emby.Server.Implementations.ScheduledTasks ;
using Emby.Server.Implementations.Serialization ;
using Emby.Server.Implementations.Threading ;
using Emby.Server.Implementations.Xml ;
using Emby.Server.MediaEncoding.Subtitles ;
using MediaBrowser.MediaEncoding.BdInfo ;
using MediaBrowser.Model.Cryptography ;
using MediaBrowser.Model.Events ;
using MediaBrowser.Model.Tasks ;
using MediaBrowser.Model.Threading ;
using StringExtensions = MediaBrowser . Controller . Extensions . StringExtensions ;
using X509Certificate = System . Security . Cryptography . X509Certificates . X509Certificate ;
namespace Emby.Server.Implementations
{
/// <summary>
/// Class CompositionRoot
/// </summary>
public abstract class ApplicationHost : IServerApplicationHost , IDependencyContainer
public abstract class ApplicationHost : IServerApplicationHost , IDependencyContainer , IDisposable
{
/// <summary>
/// Gets a value indicating whether this instance can self restart.
@ -170,6 +165,8 @@ namespace Emby.Server.Implementations
/// <value><c>true</c> if this instance has pending application restart; otherwise, <c>false</c>.</value>
public bool HasPendingRestart { get ; private set ; }
public bool IsShuttingDown { get ; private set ; }
/// <summary>
/// Gets or sets the logger.
/// </summary>
@ -366,7 +363,7 @@ namespace Emby.Server.Implementations
protected IAuthService AuthService { get ; private set ; }
protected readonly StartupOptions StartupOptions ;
pr ivate readonly string _r eleaseAssetFilename;
pr otected readonly string R eleaseAssetFilename;
internal IPowerManagement PowerManagement { get ; private set ; }
internal IImageEncoder ImageEncoder { get ; private set ; }
@ -419,7 +416,7 @@ namespace Emby.Server.Implementations
Logger = LogManager . GetLogger ( "App" ) ;
StartupOptions = options ;
_r eleaseAssetFilename = releaseAssetFilename ;
R eleaseAssetFilename = releaseAssetFilename ;
PowerManagement = powerManagement ;
ImageEncoder = imageEncoder ;
@ -442,14 +439,6 @@ namespace Emby.Server.Implementations
}
}
public virtual bool SupportsRunningAsService
{
get
{
return false ;
}
}
private DeviceId _deviceId ;
public string SystemId
{
@ -476,14 +465,6 @@ namespace Emby.Server.Implementations
}
}
public virtual bool IsRunningAsService
{
get
{
return false ;
}
}
private Assembly GetAssembly ( Type type )
{
return type . GetTypeInfo ( ) . Assembly ;
@ -827,7 +808,7 @@ namespace Emby.Server.Implementations
RegisterSingleInstance ( MemoryStreamFactory ) ;
RegisterSingleInstance ( SystemEvents ) ;
RegisterSingleInstance ( LogManager );
RegisterSingleInstance ( LogManager , false );
RegisterSingleInstance ( Logger ) ;
RegisterSingleInstance ( EnvironmentInfo ) ;
@ -1051,7 +1032,7 @@ namespace Emby.Server.Implementations
( ( UserManager ) UserManager ) . Initialize ( ) ;
}
p rotected virtual string PackageRuntime
p ublic virtual string PackageRuntime
{
get
{
@ -1073,6 +1054,7 @@ namespace Emby.Server.Implementations
builder . AppendLine ( string . Format ( "Operating system: {0}" , Environment . OSVersion ) ) ;
builder . AppendLine ( string . Format ( "64-Bit OS: {0}" , Environment . Is64BitOperatingSystem ) ) ;
builder . AppendLine ( string . Format ( "64-Bit Process: {0}" , Environment . Is64BitProcess ) ) ;
builder . AppendLine ( string . Format ( "User Interactive: {0}" , Environment . UserInteractive ) ) ;
Type type = Type . GetType ( "Mono.Runtime" ) ;
if ( type ! = null )
@ -1167,7 +1149,7 @@ namespace Emby.Server.Implementations
}
}
private I Certificate GetCertificate ( CertificateInfo info )
private X509 Certificate GetCertificate ( CertificateInfo info )
{
var certificateLocation = info = = null ? null : info . Path ;
@ -1194,7 +1176,7 @@ namespace Emby.Server.Implementations
return null ;
}
return new Certificate ( localCert ) ;
return localCert ;
}
catch ( Exception ex )
{
@ -1482,13 +1464,26 @@ namespace Emby.Server.Implementations
var assembly = plugin . GetType ( ) . Assembly ;
var assemblyName = assembly . GetName ( ) ;
var attribute = ( GuidAttribute ) assembly . GetCustomAttributes ( typeof ( GuidAttribute ) , true ) [ 0 ] ;
var assemblyId = new Guid ( attribute . Value ) ;
var assemblyFileName = assemblyName . Name + ".dll" ;
var assemblyFilePath = Path . Combine ( ApplicationPaths . PluginsPath , assemblyFileName ) ;
assemblyPlugin . SetAttributes ( assemblyFilePath , assemblyFileName , assemblyName . Version , assemblyId ) ;
assemblyPlugin . SetAttributes ( assemblyFilePath , assemblyFileName , assemblyName . Version ) ;
try
{
var idAttributes = assembly . GetCustomAttributes ( typeof ( GuidAttribute ) , true ) ;
if ( idAttributes . Length > 0 )
{
var attribute = ( GuidAttribute ) idAttributes [ 0 ] ;
var assemblyId = new Guid ( attribute . Value ) ;
assemblyPlugin . SetId ( assemblyId ) ;
}
}
catch ( Exception ex )
{
Logger . ErrorException ( "Error getting plugin Id from {0}." , ex , plugin . GetType ( ) . FullName ) ;
}
}
var isFirstRun = ! File . Exists ( plugin . ConfigurationFilePath ) ;
@ -1570,7 +1565,7 @@ namespace Emby.Server.Implementations
}
private CertificateInfo CertificateInfo { get ; set ; }
private I Certificate Certificate { get ; set ; }
private X509 Certificate Certificate { get ; set ; }
private IEnumerable < string > GetUrlPrefixes ( )
{
@ -1601,7 +1596,7 @@ namespace Emby.Server.Implementations
{
try
{
ServerManager . Start ( GetUrlPrefixes ( ) );
ServerManager . Start ( GetUrlPrefixes ( ) .ToArray ( ) );
return ;
}
catch ( Exception ex )
@ -1618,7 +1613,7 @@ namespace Emby.Server.Implementations
try
{
ServerManager . Start ( GetUrlPrefixes ( ) );
ServerManager . Start ( GetUrlPrefixes ( ) .ToArray ( ) );
}
catch ( Exception ex )
{
@ -1740,25 +1735,35 @@ namespace Emby.Server.Implementations
/// <summary>
/// Restarts this instance.
/// </summary>
public async Task Restart ( )
public void Restart ( )
{
if ( ! CanSelfRestart )
{
throw new PlatformNotSupportedException ( "The server is unable to self-restart. Please restart manually." ) ;
}
try
if ( IsShuttingDown )
{
await SessionManager . SendServerRestartNotification ( CancellationToken . None ) . ConfigureAwait ( false ) ;
return ;
}
catch ( Exception ex )
IsShuttingDown = true ;
Task . Run ( async ( ) = >
{
Logger . ErrorException ( "Error sending server restart notification" , ex ) ;
}
try
{
await SessionManager . SendServerRestartNotification ( CancellationToken . None ) . ConfigureAwait ( false ) ;
}
catch ( Exception ex )
{
Logger . ErrorException ( "Error sending server restart notification" , ex ) ;
}
Logger . Info ( "Calling RestartInternal" ) ;
Logger . Info ( "Calling RestartInternal" ) ;
RestartInternal ( ) ;
RestartInternal ( ) ;
} ) ;
}
protected abstract void RestartInternal ( ) ;
@ -1847,7 +1852,32 @@ namespace Emby.Server.Implementations
"mbplus.dll" ,
"mbintros.dll" ,
"embytv.dll" ,
"Messenger.dll"
"Messenger.dll" ,
"MediaBrowser.Plugins.TvMazeProvider.dll" ,
"MBBookshelf.dll" ,
"MediaBrowser.Channels.Adult.YouJizz.dll" ,
"MediaBrowser.Channels.Vine-co.dll" ,
"MediaBrowser.Plugins.Vimeo.dll" ,
"MediaBrowser.Channels.Vevo.dll" ,
"MediaBrowser.Plugins.Twitch.dll" ,
"MediaBrowser.Channels.SvtPlay.dll" ,
"MediaBrowser.Plugins.SoundCloud.dll" ,
"MediaBrowser.Plugins.SnesBox.dll" ,
"MediaBrowser.Plugins.RottenTomatoes.dll" ,
"MediaBrowser.Plugins.Revision3.dll" ,
"MediaBrowser.Plugins.NesBox.dll" ,
"MBChapters.dll" ,
"MediaBrowser.Channels.LeagueOfLegends.dll" ,
"MediaBrowser.Plugins.ADEProvider.dll" ,
"MediaBrowser.Channels.BallStreams.dll" ,
"MediaBrowser.Channels.Adult.Beeg.dll" ,
"ChannelDownloader.dll" ,
"Hamstercat.Emby.EmbyBands.dll" ,
"EmbyTV.dll" ,
"MediaBrowser.Channels.HitboxTV.dll" ,
"MediaBrowser.Channels.HockeyStreams.dll" ,
"MediaBrowser.Plugins.ITV.dll" ,
"MediaBrowser.Plugins.Lastfm.dll"
} ;
return ! exclude . Contains ( filename ? ? string . Empty , StringComparer . OrdinalIgnoreCase ) ;
@ -1864,6 +1894,7 @@ namespace Emby.Server.Implementations
return new SystemInfo
{
HasPendingRestart = HasPendingRestart ,
IsShuttingDown = IsShuttingDown ,
Version = ApplicationVersion . ToString ( ) ,
WebSocketPortNumber = HttpPort ,
FailedPluginAssemblies = FailedAssemblies . ToArray ( ) ,
@ -1887,7 +1918,6 @@ namespace Emby.Server.Implementations
HasUpdateAvailable = HasUpdateAvailable ,
SupportsAutoRunAtStartup = SupportsAutoRunAtStartup ,
TranscodingTempPath = ApplicationPaths . TranscodingTempPath ,
SupportsRunningAsService = SupportsRunningAsService ,
ServerName = FriendlyName ,
LocalAddress = localAddress ,
SupportsLibraryMonitor = true ,
@ -2091,6 +2121,13 @@ namespace Emby.Server.Implementations
/// </summary>
public async Task Shutdown ( )
{
if ( IsShuttingDown )
{
return ;
}
IsShuttingDown = true ;
try
{
await SessionManager . SendServerShutdownNotification ( CancellationToken . None ) . ConfigureAwait ( false ) ;
@ -2169,22 +2206,31 @@ namespace Emby.Server.Implementations
/// <returns>Task{CheckForUpdateResult}.</returns>
public async Task < CheckForUpdateResult > CheckForApplicationUpdate ( CancellationToken cancellationToken , IProgress < double > progress )
{
var cacheLength = TimeSpan . FromHours ( 1 ) ;
var updateLevel = SystemUpdateLevel ;
if ( updateLevel ! = PackageVersionClass . Release )
{
cacheLength = TimeSpan . FromMinutes ( 5 ) ;
}
var result = await new GithubUpdater ( HttpClient , JsonSerializer ) . CheckForUpdateResult ( "MediaBrowser" , "Emby" , ApplicationVersion , updateLevel , _releaseAssetFilename ,
"MBServer" , "Mbserver.zip" , cacheLength , cancellationToken ) . ConfigureAwait ( false ) ;
var cacheLength = updateLevel = = PackageVersionClass . Release ?
TimeSpan . FromHours ( 4 ) :
TimeSpan . FromMinutes ( 5 ) ;
var result = await new GithubUpdater ( HttpClient , JsonSerializer ) . CheckForUpdateResult ( "MediaBrowser" ,
"Emby" ,
ApplicationVersion ,
updateLevel ,
ReleaseAssetFilename ,
"MBServer" ,
UpdateTargetFileName ,
cacheLength ,
cancellationToken ) . ConfigureAwait ( false ) ;
HasUpdateAvailable = result . IsUpdateAvailable ;
return result ;
}
protected virtual string UpdateTargetFileName
{
get { return "Mbserver.zip" ; }
}
/// <summary>
/// Updates the application.
/// </summary>
@ -2327,6 +2373,7 @@ namespace Emby.Server.Implementations
_disposed = true ;
Dispose ( true ) ;
GC . SuppressFinalize ( this ) ;
}
}
@ -2340,6 +2387,7 @@ namespace Emby.Server.Implementations
{
var type = GetType ( ) ;
LogManager . AddConsoleOutput ( ) ;
Logger . Info ( "Disposing " + type . Name ) ;
var parts = DisposableParts . Distinct ( ) . Where ( i = > i . GetType ( ) ! = type ) . ToList ( ) ;