ApplicationHost.cs 88 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385
  1. using Emby.Common.Implementations;
  2. using Emby.Common.Implementations.Serialization;
  3. using Emby.Dlna;
  4. using Emby.Dlna.ConnectionManager;
  5. using Emby.Dlna.ContentDirectory;
  6. using Emby.Dlna.Main;
  7. using Emby.Dlna.MediaReceiverRegistrar;
  8. using Emby.Dlna.Ssdp;
  9. using Emby.Drawing;
  10. using Emby.Photos;
  11. using Emby.Server.Implementations.Activity;
  12. using Emby.Server.Implementations.Channels;
  13. using Emby.Server.Implementations.Collections;
  14. using Emby.Server.Implementations.Configuration;
  15. using Emby.Server.Implementations.Data;
  16. using Emby.Server.Implementations.Devices;
  17. using Emby.Server.Implementations.Dto;
  18. using Emby.Server.Implementations.FFMpeg;
  19. using Emby.Server.Implementations.HttpServer;
  20. using Emby.Server.Implementations.HttpServer.Security;
  21. using Emby.Server.Implementations.IO;
  22. using Emby.Server.Implementations.Library;
  23. using Emby.Server.Implementations.LiveTv;
  24. using Emby.Server.Implementations.Localization;
  25. using Emby.Server.Implementations.MediaEncoder;
  26. using Emby.Server.Implementations.Migrations;
  27. using Emby.Server.Implementations.Notifications;
  28. using Emby.Server.Implementations.Playlists;
  29. using Emby.Server.Implementations.Security;
  30. using Emby.Server.Implementations.Session;
  31. using Emby.Server.Implementations.Social;
  32. using Emby.Server.Implementations.TV;
  33. using Emby.Server.Implementations.Updates;
  34. using MediaBrowser.Api;
  35. using MediaBrowser.Common;
  36. using MediaBrowser.Common.Configuration;
  37. using MediaBrowser.Common.Events;
  38. using MediaBrowser.Common.Extensions;
  39. using MediaBrowser.Common.Net;
  40. using MediaBrowser.Common.Plugins;
  41. using MediaBrowser.Common.Progress;
  42. using MediaBrowser.Common.Security;
  43. using MediaBrowser.Common.Updates;
  44. using MediaBrowser.Controller;
  45. using MediaBrowser.Controller.Channels;
  46. using MediaBrowser.Controller.Chapters;
  47. using MediaBrowser.Controller.Collections;
  48. using MediaBrowser.Controller.Configuration;
  49. using MediaBrowser.Controller.Connect;
  50. using MediaBrowser.Controller.Devices;
  51. using MediaBrowser.Controller.Dlna;
  52. using MediaBrowser.Controller.Drawing;
  53. using MediaBrowser.Controller.Dto;
  54. using MediaBrowser.Controller.Entities;
  55. using MediaBrowser.Controller.Entities.Audio;
  56. using MediaBrowser.Controller.Entities.Movies;
  57. using MediaBrowser.Controller.Entities.TV;
  58. using MediaBrowser.Controller.Library;
  59. using MediaBrowser.Controller.LiveTv;
  60. using MediaBrowser.Controller.MediaEncoding;
  61. using MediaBrowser.Controller.Net;
  62. using MediaBrowser.Controller.Notifications;
  63. using MediaBrowser.Controller.Persistence;
  64. using MediaBrowser.Controller.Playlists;
  65. using MediaBrowser.Controller.Plugins;
  66. using MediaBrowser.Controller.Providers;
  67. using MediaBrowser.Controller.Resolvers;
  68. using MediaBrowser.Controller.Security;
  69. using MediaBrowser.Controller.Session;
  70. using MediaBrowser.Controller.Sorting;
  71. using MediaBrowser.Controller.Subtitles;
  72. using MediaBrowser.Controller.Sync;
  73. using MediaBrowser.Controller.TV;
  74. using MediaBrowser.LocalMetadata.Savers;
  75. using MediaBrowser.Model.Activity;
  76. using MediaBrowser.Model.Configuration;
  77. using MediaBrowser.Model.Diagnostics;
  78. using MediaBrowser.Model.Dlna;
  79. using MediaBrowser.Model.Globalization;
  80. using MediaBrowser.Model.IO;
  81. using MediaBrowser.Model.Logging;
  82. using MediaBrowser.Model.MediaInfo;
  83. using MediaBrowser.Model.Net;
  84. using MediaBrowser.Model.News;
  85. using MediaBrowser.Model.Reflection;
  86. using MediaBrowser.Model.Serialization;
  87. using MediaBrowser.Model.Services;
  88. using MediaBrowser.Model.Social;
  89. using MediaBrowser.Model.System;
  90. using MediaBrowser.Model.Text;
  91. using MediaBrowser.Model.Updates;
  92. using MediaBrowser.Model.Xml;
  93. using MediaBrowser.Providers.Chapters;
  94. using MediaBrowser.Providers.Manager;
  95. using MediaBrowser.Providers.Subtitles;
  96. using MediaBrowser.WebDashboard.Api;
  97. using MediaBrowser.XbmcMetadata.Providers;
  98. using OpenSubtitlesHandler;
  99. using ServiceStack;
  100. using SocketHttpListener.Primitives;
  101. using System;
  102. using System.Collections.Concurrent;
  103. using System.Collections.Generic;
  104. using System.Globalization;
  105. using System.IO;
  106. using System.Linq;
  107. using System.Net;
  108. using System.Reflection;
  109. using System.Runtime.InteropServices;
  110. using System.Security.Cryptography.X509Certificates;
  111. using System.Text;
  112. using System.Threading;
  113. using System.Threading.Tasks;
  114. using Emby.Server.Core.Cryptography;
  115. using Emby.Server.Implementations.Archiving;
  116. using Emby.Server.Implementations.Cryptography;
  117. using Emby.Server.Implementations.Diagnostics;
  118. using Emby.Server.Implementations.Net;
  119. using Emby.Server.Implementations.Reflection;
  120. using Emby.Server.Implementations.ScheduledTasks;
  121. using Emby.Server.Implementations.Serialization;
  122. using Emby.Server.Implementations.Threading;
  123. using Emby.Server.Implementations.Xml;
  124. using Emby.Server.MediaEncoding.Subtitles;
  125. using MediaBrowser.MediaEncoding.BdInfo;
  126. using MediaBrowser.Model.Cryptography;
  127. using MediaBrowser.Model.Events;
  128. using MediaBrowser.Model.Tasks;
  129. using MediaBrowser.Model.Threading;
  130. using StringExtensions = MediaBrowser.Controller.Extensions.StringExtensions;
  131. namespace Emby.Server.Implementations
  132. {
  133. /// <summary>
  134. /// Class CompositionRoot
  135. /// </summary>
  136. public abstract class ApplicationHost : IServerApplicationHost, IDependencyContainer
  137. {
  138. /// <summary>
  139. /// Gets a value indicating whether this instance can self restart.
  140. /// </summary>
  141. /// <value><c>true</c> if this instance can self restart; otherwise, <c>false</c>.</value>
  142. public abstract bool CanSelfRestart { get; }
  143. /// <summary>
  144. /// Gets or sets a value indicating whether this instance can self update.
  145. /// </summary>
  146. /// <value><c>true</c> if this instance can self update; otherwise, <c>false</c>.</value>
  147. public virtual bool CanSelfUpdate
  148. {
  149. get
  150. {
  151. return false;
  152. }
  153. }
  154. /// <summary>
  155. /// Occurs when [has pending restart changed].
  156. /// </summary>
  157. public event EventHandler HasPendingRestartChanged;
  158. /// <summary>
  159. /// Occurs when [application updated].
  160. /// </summary>
  161. public event EventHandler<GenericEventArgs<PackageVersionInfo>> ApplicationUpdated;
  162. /// <summary>
  163. /// Gets or sets a value indicating whether this instance has changes that require the entire application to restart.
  164. /// </summary>
  165. /// <value><c>true</c> if this instance has pending application restart; otherwise, <c>false</c>.</value>
  166. public bool HasPendingRestart { get; private set; }
  167. /// <summary>
  168. /// Gets or sets the logger.
  169. /// </summary>
  170. /// <value>The logger.</value>
  171. protected ILogger Logger { get; set; }
  172. /// <summary>
  173. /// Gets or sets the plugins.
  174. /// </summary>
  175. /// <value>The plugins.</value>
  176. public IPlugin[] Plugins { get; protected set; }
  177. /// <summary>
  178. /// Gets or sets the log manager.
  179. /// </summary>
  180. /// <value>The log manager.</value>
  181. public ILogManager LogManager { get; protected set; }
  182. /// <summary>
  183. /// Gets the application paths.
  184. /// </summary>
  185. /// <value>The application paths.</value>
  186. protected ServerApplicationPaths ApplicationPaths { get; set; }
  187. /// <summary>
  188. /// Gets assemblies that failed to load
  189. /// </summary>
  190. /// <value>The failed assemblies.</value>
  191. public List<string> FailedAssemblies { get; protected set; }
  192. /// <summary>
  193. /// Gets all concrete types.
  194. /// </summary>
  195. /// <value>All concrete types.</value>
  196. public Type[] AllConcreteTypes { get; protected set; }
  197. /// <summary>
  198. /// The disposable parts
  199. /// </summary>
  200. protected readonly List<IDisposable> DisposableParts = new List<IDisposable>();
  201. /// <summary>
  202. /// Gets a value indicating whether this instance is first run.
  203. /// </summary>
  204. /// <value><c>true</c> if this instance is first run; otherwise, <c>false</c>.</value>
  205. public bool IsFirstRun { get; private set; }
  206. /// <summary>
  207. /// Gets the configuration manager.
  208. /// </summary>
  209. /// <value>The configuration manager.</value>
  210. protected IConfigurationManager ConfigurationManager { get; set; }
  211. public IFileSystem FileSystemManager { get; set; }
  212. protected IEnvironmentInfo EnvironmentInfo { get; set; }
  213. private IBlurayExaminer BlurayExaminer { get; set; }
  214. public PackageVersionClass SystemUpdateLevel
  215. {
  216. get
  217. {
  218. #if BETA
  219. return PackageVersionClass.Beta;
  220. #endif
  221. return PackageVersionClass.Release;
  222. }
  223. }
  224. public virtual string OperatingSystemDisplayName
  225. {
  226. get { return EnvironmentInfo.OperatingSystemName; }
  227. }
  228. /// <summary>
  229. /// The container
  230. /// </summary>
  231. protected readonly SimpleInjector.Container Container = new SimpleInjector.Container();
  232. protected ISystemEvents SystemEvents { get; set; }
  233. protected IMemoryStreamFactory MemoryStreamFactory { get; set; }
  234. /// <summary>
  235. /// Gets the server configuration manager.
  236. /// </summary>
  237. /// <value>The server configuration manager.</value>
  238. public IServerConfigurationManager ServerConfigurationManager
  239. {
  240. get { return (IServerConfigurationManager)ConfigurationManager; }
  241. }
  242. /// <summary>
  243. /// Gets the configuration manager.
  244. /// </summary>
  245. /// <returns>IConfigurationManager.</returns>
  246. protected IConfigurationManager GetConfigurationManager()
  247. {
  248. return new ServerConfigurationManager(ApplicationPaths, LogManager, XmlSerializer, FileSystemManager);
  249. }
  250. /// <summary>
  251. /// Gets or sets the server manager.
  252. /// </summary>
  253. /// <value>The server manager.</value>
  254. private IServerManager ServerManager { get; set; }
  255. /// <summary>
  256. /// Gets or sets the user manager.
  257. /// </summary>
  258. /// <value>The user manager.</value>
  259. public IUserManager UserManager { get; set; }
  260. /// <summary>
  261. /// Gets or sets the library manager.
  262. /// </summary>
  263. /// <value>The library manager.</value>
  264. internal ILibraryManager LibraryManager { get; set; }
  265. /// <summary>
  266. /// Gets or sets the directory watchers.
  267. /// </summary>
  268. /// <value>The directory watchers.</value>
  269. private ILibraryMonitor LibraryMonitor { get; set; }
  270. /// <summary>
  271. /// Gets or sets the provider manager.
  272. /// </summary>
  273. /// <value>The provider manager.</value>
  274. private IProviderManager ProviderManager { get; set; }
  275. /// <summary>
  276. /// Gets or sets the HTTP server.
  277. /// </summary>
  278. /// <value>The HTTP server.</value>
  279. private IHttpServer HttpServer { get; set; }
  280. private IDtoService DtoService { get; set; }
  281. public IImageProcessor ImageProcessor { get; set; }
  282. /// <summary>
  283. /// Gets or sets the media encoder.
  284. /// </summary>
  285. /// <value>The media encoder.</value>
  286. private IMediaEncoder MediaEncoder { get; set; }
  287. private ISubtitleEncoder SubtitleEncoder { get; set; }
  288. private IConnectManager ConnectManager { get; set; }
  289. private ISessionManager SessionManager { get; set; }
  290. private ILiveTvManager LiveTvManager { get; set; }
  291. public ILocalizationManager LocalizationManager { get; set; }
  292. private IEncodingManager EncodingManager { get; set; }
  293. private IChannelManager ChannelManager { get; set; }
  294. private ISyncManager SyncManager { get; set; }
  295. /// <summary>
  296. /// Gets or sets the user data repository.
  297. /// </summary>
  298. /// <value>The user data repository.</value>
  299. private IUserDataManager UserDataManager { get; set; }
  300. private IUserRepository UserRepository { get; set; }
  301. internal IDisplayPreferencesRepository DisplayPreferencesRepository { get; set; }
  302. internal IItemRepository ItemRepository { get; set; }
  303. private INotificationsRepository NotificationsRepository { get; set; }
  304. private INotificationManager NotificationManager { get; set; }
  305. private ISubtitleManager SubtitleManager { get; set; }
  306. private IChapterManager ChapterManager { get; set; }
  307. private IDeviceManager DeviceManager { get; set; }
  308. internal IUserViewManager UserViewManager { get; set; }
  309. private IAuthenticationRepository AuthenticationRepository { get; set; }
  310. private ITVSeriesManager TVSeriesManager { get; set; }
  311. private ICollectionManager CollectionManager { get; set; }
  312. private IMediaSourceManager MediaSourceManager { get; set; }
  313. private IPlaylistManager PlaylistManager { get; set; }
  314. /// <summary>
  315. /// Gets or sets the installation manager.
  316. /// </summary>
  317. /// <value>The installation manager.</value>
  318. protected IInstallationManager InstallationManager { get; private set; }
  319. /// <summary>
  320. /// Gets the security manager.
  321. /// </summary>
  322. /// <value>The security manager.</value>
  323. protected ISecurityManager SecurityManager { get; private set; }
  324. /// <summary>
  325. /// Gets or sets the zip client.
  326. /// </summary>
  327. /// <value>The zip client.</value>
  328. protected IZipClient ZipClient { get; private set; }
  329. protected IAuthService AuthService { get; private set; }
  330. protected readonly StartupOptions StartupOptions;
  331. private readonly string _releaseAssetFilename;
  332. internal IPowerManagement PowerManagement { get; private set; }
  333. internal IImageEncoder ImageEncoder { get; private set; }
  334. protected IProcessFactory ProcessFactory { get; private set; }
  335. protected ITimerFactory TimerFactory { get; private set; }
  336. protected ICryptoProvider CryptographyProvider = new CryptographyProvider();
  337. protected readonly IXmlSerializer XmlSerializer;
  338. protected ISocketFactory SocketFactory { get; private set; }
  339. protected ITaskManager TaskManager { get; private set; }
  340. public IHttpClient HttpClient { get; private set; }
  341. protected INetworkManager NetworkManager { get; set; }
  342. public IJsonSerializer JsonSerializer { get; private set; }
  343. protected IIsoManager IsoManager { get; private set; }
  344. /// <summary>
  345. /// Initializes a new instance of the <see cref="ApplicationHost" /> class.
  346. /// </summary>
  347. public ApplicationHost(ServerApplicationPaths applicationPaths,
  348. ILogManager logManager,
  349. StartupOptions options,
  350. IFileSystem fileSystem,
  351. IPowerManagement powerManagement,
  352. string releaseAssetFilename,
  353. IEnvironmentInfo environmentInfo,
  354. IImageEncoder imageEncoder,
  355. ISystemEvents systemEvents,
  356. INetworkManager networkManager)
  357. {
  358. // hack alert, until common can target .net core
  359. BaseExtensions.CryptographyProvider = CryptographyProvider;
  360. XmlSerializer = new MyXmlSerializer(fileSystem, logManager.GetLogger("XmlSerializer"));
  361. NetworkManager = networkManager;
  362. EnvironmentInfo = environmentInfo;
  363. SystemEvents = systemEvents;
  364. MemoryStreamFactory = new MemoryStreamProvider();
  365. FailedAssemblies = new List<string>();
  366. ApplicationPaths = applicationPaths;
  367. LogManager = logManager;
  368. FileSystemManager = fileSystem;
  369. ConfigurationManager = GetConfigurationManager();
  370. // Initialize this early in case the -v command line option is used
  371. Logger = LogManager.GetLogger("App");
  372. StartupOptions = options;
  373. _releaseAssetFilename = releaseAssetFilename;
  374. PowerManagement = powerManagement;
  375. ImageEncoder = imageEncoder;
  376. SetBaseExceptionMessage();
  377. fileSystem.AddShortcutHandler(new MbLinkShortcutHandler(fileSystem));
  378. }
  379. private Version _version;
  380. /// <summary>
  381. /// Gets the current application version
  382. /// </summary>
  383. /// <value>The application version.</value>
  384. public Version ApplicationVersion
  385. {
  386. get
  387. {
  388. return _version ?? (_version = GetAssembly(GetType()).GetName().Version);
  389. }
  390. }
  391. public virtual bool SupportsRunningAsService
  392. {
  393. get
  394. {
  395. return false;
  396. }
  397. }
  398. private DeviceId _deviceId;
  399. public string SystemId
  400. {
  401. get
  402. {
  403. if (_deviceId == null)
  404. {
  405. _deviceId = new DeviceId(ApplicationPaths, LogManager.GetLogger("SystemId"), FileSystemManager);
  406. }
  407. return _deviceId.Value;
  408. }
  409. }
  410. /// <summary>
  411. /// Gets the name.
  412. /// </summary>
  413. /// <value>The name.</value>
  414. public string Name
  415. {
  416. get
  417. {
  418. return "Emby Server";
  419. }
  420. }
  421. public virtual bool IsRunningAsService
  422. {
  423. get
  424. {
  425. return false;
  426. }
  427. }
  428. private Assembly GetAssembly(Type type)
  429. {
  430. return type.GetTypeInfo().Assembly;
  431. }
  432. public virtual bool SupportsAutoRunAtStartup
  433. {
  434. get
  435. {
  436. return EnvironmentInfo.OperatingSystem == MediaBrowser.Model.System.OperatingSystem.Windows;
  437. }
  438. }
  439. /// <summary>
  440. /// Creates an instance of type and resolves all constructor dependancies
  441. /// </summary>
  442. /// <param name="type">The type.</param>
  443. /// <returns>System.Object.</returns>
  444. public object CreateInstance(Type type)
  445. {
  446. try
  447. {
  448. return Container.GetInstance(type);
  449. }
  450. catch (Exception ex)
  451. {
  452. Logger.ErrorException("Error creating {0}", ex, type.FullName);
  453. throw;
  454. }
  455. }
  456. /// <summary>
  457. /// Creates the instance safe.
  458. /// </summary>
  459. /// <param name="type">The type.</param>
  460. /// <returns>System.Object.</returns>
  461. protected object CreateInstanceSafe(Type type)
  462. {
  463. try
  464. {
  465. return Container.GetInstance(type);
  466. }
  467. catch (Exception ex)
  468. {
  469. Logger.ErrorException("Error creating {0}", ex, type.FullName);
  470. // Don't blow up in release mode
  471. return null;
  472. }
  473. }
  474. /// <summary>
  475. /// Registers the specified obj.
  476. /// </summary>
  477. /// <typeparam name="T"></typeparam>
  478. /// <param name="obj">The obj.</param>
  479. /// <param name="manageLifetime">if set to <c>true</c> [manage lifetime].</param>
  480. protected void RegisterSingleInstance<T>(T obj, bool manageLifetime = true)
  481. where T : class
  482. {
  483. Container.RegisterSingleton(obj);
  484. if (manageLifetime)
  485. {
  486. var disposable = obj as IDisposable;
  487. if (disposable != null)
  488. {
  489. DisposableParts.Add(disposable);
  490. }
  491. }
  492. }
  493. /// <summary>
  494. /// Registers the single instance.
  495. /// </summary>
  496. /// <typeparam name="T"></typeparam>
  497. /// <param name="func">The func.</param>
  498. protected void RegisterSingleInstance<T>(Func<T> func)
  499. where T : class
  500. {
  501. Container.RegisterSingleton(func);
  502. }
  503. /// <summary>
  504. /// Resolves this instance.
  505. /// </summary>
  506. /// <typeparam name="T"></typeparam>
  507. /// <returns>``0.</returns>
  508. public T Resolve<T>()
  509. {
  510. return (T)Container.GetRegistration(typeof(T), true).GetInstance();
  511. }
  512. /// <summary>
  513. /// Resolves this instance.
  514. /// </summary>
  515. /// <typeparam name="T"></typeparam>
  516. /// <returns>``0.</returns>
  517. public T TryResolve<T>()
  518. {
  519. var result = Container.GetRegistration(typeof(T), false);
  520. if (result == null)
  521. {
  522. return default(T);
  523. }
  524. return (T)result.GetInstance();
  525. }
  526. /// <summary>
  527. /// Loads the assembly.
  528. /// </summary>
  529. /// <param name="file">The file.</param>
  530. /// <returns>Assembly.</returns>
  531. protected Assembly LoadAssembly(string file)
  532. {
  533. try
  534. {
  535. return Assembly.Load(File.ReadAllBytes(file));
  536. }
  537. catch (Exception ex)
  538. {
  539. FailedAssemblies.Add(file);
  540. Logger.ErrorException("Error loading assembly {0}", ex, file);
  541. return null;
  542. }
  543. }
  544. /// <summary>
  545. /// Gets the export types.
  546. /// </summary>
  547. /// <typeparam name="T"></typeparam>
  548. /// <returns>IEnumerable{Type}.</returns>
  549. public IEnumerable<Type> GetExportTypes<T>()
  550. {
  551. var currentType = typeof(T);
  552. return AllConcreteTypes.Where(currentType.IsAssignableFrom);
  553. }
  554. /// <summary>
  555. /// Gets the exports.
  556. /// </summary>
  557. /// <typeparam name="T"></typeparam>
  558. /// <param name="manageLiftime">if set to <c>true</c> [manage liftime].</param>
  559. /// <returns>IEnumerable{``0}.</returns>
  560. public IEnumerable<T> GetExports<T>(bool manageLiftime = true)
  561. {
  562. var parts = GetExportTypes<T>()
  563. .Select(CreateInstanceSafe)
  564. .Where(i => i != null)
  565. .Cast<T>()
  566. .ToList();
  567. if (manageLiftime)
  568. {
  569. lock (DisposableParts)
  570. {
  571. DisposableParts.AddRange(parts.OfType<IDisposable>());
  572. }
  573. }
  574. return parts;
  575. }
  576. private void SetBaseExceptionMessage()
  577. {
  578. var builder = GetBaseExceptionMessage(ApplicationPaths);
  579. builder.Insert(0, string.Format("Version: {0}{1}", ApplicationVersion, Environment.NewLine));
  580. builder.Insert(0, "*** Error Report ***" + Environment.NewLine);
  581. LogManager.ExceptionMessagePrefix = builder.ToString();
  582. }
  583. /// <summary>
  584. /// Runs the startup tasks.
  585. /// </summary>
  586. public async Task RunStartupTasks()
  587. {
  588. Resolve<ITaskManager>().AddTasks(GetExports<IScheduledTask>(false));
  589. ConfigureAutorun();
  590. ConfigurationManager.ConfigurationUpdated += OnConfigurationUpdated;
  591. await MediaEncoder.Init().ConfigureAwait(false);
  592. if (string.IsNullOrWhiteSpace(MediaEncoder.EncoderPath))
  593. {
  594. if (ServerConfigurationManager.Configuration.IsStartupWizardCompleted)
  595. {
  596. ServerConfigurationManager.Configuration.IsStartupWizardCompleted = false;
  597. ServerConfigurationManager.SaveConfiguration();
  598. }
  599. }
  600. Logger.Info("ServerId: {0}", SystemId);
  601. Logger.Info("Core startup complete");
  602. HttpServer.GlobalResponse = null;
  603. Logger.Info("Post-init migrations complete");
  604. foreach (var entryPoint in GetExports<IServerEntryPoint>().ToList())
  605. {
  606. var name = entryPoint.GetType().FullName;
  607. Logger.Info("Starting entry point {0}", name);
  608. var now = DateTime.UtcNow;
  609. try
  610. {
  611. entryPoint.Run();
  612. }
  613. catch (Exception ex)
  614. {
  615. Logger.ErrorException("Error in {0}", ex, name);
  616. }
  617. Logger.Info("Entry point completed: {0}. Duration: {1} seconds", name, (DateTime.UtcNow - now).TotalSeconds.ToString(CultureInfo.InvariantCulture), "ImageInfos");
  618. }
  619. Logger.Info("All entry points have started");
  620. LogManager.RemoveConsoleOutput();
  621. }
  622. /// <summary>
  623. /// Configures the autorun.
  624. /// </summary>
  625. private void ConfigureAutorun()
  626. {
  627. try
  628. {
  629. ConfigureAutoRunAtStartup(ConfigurationManager.CommonConfiguration.RunAtStartup);
  630. }
  631. catch (Exception ex)
  632. {
  633. Logger.ErrorException("Error configuring autorun", ex);
  634. }
  635. }
  636. private IJsonSerializer CreateJsonSerializer()
  637. {
  638. try
  639. {
  640. // https://github.com/ServiceStack/ServiceStack/blob/master/tests/ServiceStack.WebHost.IntegrationTests/Web.config#L4
  641. Licensing.RegisterLicense("1001-e1JlZjoxMDAxLE5hbWU6VGVzdCBCdXNpbmVzcyxUeXBlOkJ1c2luZXNzLEhhc2g6UHVNTVRPclhvT2ZIbjQ5MG5LZE1mUTd5RUMzQnBucTFEbTE3TDczVEF4QUNMT1FhNXJMOWkzVjFGL2ZkVTE3Q2pDNENqTkQyUktRWmhvUVBhYTBiekJGUUZ3ZE5aZHFDYm9hL3lydGlwUHI5K1JsaTBYbzNsUC85cjVJNHE5QVhldDN6QkE4aTlvdldrdTgyTk1relY2eis2dFFqTThYN2lmc0JveHgycFdjPSxFeHBpcnk6MjAxMy0wMS0wMX0=");
  642. }
  643. catch
  644. {
  645. // Failing under mono
  646. }
  647. return new JsonSerializer(FileSystemManager, LogManager.GetLogger("JsonSerializer"));
  648. }
  649. public async Task Init(IProgress<double> progress)
  650. {
  651. HttpPort = ServerConfigurationManager.Configuration.HttpServerPortNumber;
  652. HttpsPort = ServerConfigurationManager.Configuration.HttpsPortNumber;
  653. // Safeguard against invalid configuration
  654. if (HttpPort == HttpsPort)
  655. {
  656. HttpPort = ServerConfiguration.DefaultHttpPort;
  657. HttpsPort = ServerConfiguration.DefaultHttpsPort;
  658. }
  659. progress.Report(1);
  660. JsonSerializer = CreateJsonSerializer();
  661. OnLoggerLoaded(true);
  662. LogManager.LoggerLoaded += (s, e) => OnLoggerLoaded(false);
  663. IsFirstRun = !ConfigurationManager.CommonConfiguration.IsStartupWizardCompleted;
  664. progress.Report(2);
  665. LogManager.LogSeverity = ConfigurationManager.CommonConfiguration.EnableDebugLevelLogging
  666. ? LogSeverity.Debug
  667. : LogSeverity.Info;
  668. progress.Report(3);
  669. DiscoverTypes();
  670. progress.Report(14);
  671. SetHttpLimit();
  672. progress.Report(15);
  673. var innerProgress = new ActionableProgress<double>();
  674. innerProgress.RegisterAction(p => progress.Report(.8 * p + 15));
  675. await RegisterResources(innerProgress).ConfigureAwait(false);
  676. FindParts();
  677. progress.Report(95);
  678. await InstallIsoMounters(CancellationToken.None).ConfigureAwait(false);
  679. progress.Report(100);
  680. }
  681. protected virtual void OnLoggerLoaded(bool isFirstLoad)
  682. {
  683. Logger.Info("Application version: {0}", ApplicationVersion);
  684. if (!isFirstLoad)
  685. {
  686. LogEnvironmentInfo(Logger, ApplicationPaths, false);
  687. }
  688. // Put the app config in the log for troubleshooting purposes
  689. Logger.LogMultiline("Application configuration:", LogSeverity.Info, new StringBuilder(JsonSerializer.SerializeToString(ConfigurationManager.CommonConfiguration)));
  690. if (Plugins != null)
  691. {
  692. var pluginBuilder = new StringBuilder();
  693. foreach (var plugin in Plugins)
  694. {
  695. pluginBuilder.AppendLine(string.Format("{0} {1}", plugin.Name, plugin.Version));
  696. }
  697. Logger.LogMultiline("Plugins:", LogSeverity.Info, pluginBuilder);
  698. }
  699. }
  700. protected abstract IConnectManager CreateConnectManager();
  701. protected abstract ISyncManager CreateSyncManager();
  702. /// <summary>
  703. /// Registers resources that classes will depend on
  704. /// </summary>
  705. protected async Task RegisterResources(IProgress<double> progress)
  706. {
  707. RegisterSingleInstance(ConfigurationManager);
  708. RegisterSingleInstance<IApplicationHost>(this);
  709. RegisterSingleInstance<IApplicationPaths>(ApplicationPaths);
  710. RegisterSingleInstance(JsonSerializer);
  711. RegisterSingleInstance(MemoryStreamFactory);
  712. RegisterSingleInstance(SystemEvents);
  713. RegisterSingleInstance(LogManager);
  714. RegisterSingleInstance(Logger);
  715. RegisterSingleInstance(EnvironmentInfo);
  716. RegisterSingleInstance(FileSystemManager);
  717. HttpClient = new HttpClientManager.HttpClientManager(ApplicationPaths, LogManager.GetLogger("HttpClient"), FileSystemManager, MemoryStreamFactory, GetDefaultUserAgent);
  718. RegisterSingleInstance(HttpClient);
  719. RegisterSingleInstance(NetworkManager);
  720. IsoManager = new IsoManager();
  721. RegisterSingleInstance(IsoManager);
  722. TaskManager = new TaskManager(ApplicationPaths, JsonSerializer, LogManager.GetLogger("TaskManager"), FileSystemManager, SystemEvents);
  723. RegisterSingleInstance(TaskManager);
  724. RegisterSingleInstance(XmlSerializer);
  725. ProcessFactory = new ProcessFactory();
  726. RegisterSingleInstance(ProcessFactory);
  727. TimerFactory = new TimerFactory();
  728. RegisterSingleInstance(TimerFactory);
  729. RegisterSingleInstance(CryptographyProvider);
  730. SocketFactory = new SocketFactory(LogManager.GetLogger("SocketFactory"));
  731. RegisterSingleInstance(SocketFactory);
  732. RegisterSingleInstance(PowerManagement);
  733. SecurityManager = new PluginSecurityManager(this, HttpClient, JsonSerializer, ApplicationPaths, LogManager, FileSystemManager, CryptographyProvider);
  734. RegisterSingleInstance(SecurityManager);
  735. InstallationManager = new InstallationManager(LogManager.GetLogger("InstallationManager"), this, ApplicationPaths, HttpClient, JsonSerializer, SecurityManager, ConfigurationManager, FileSystemManager, CryptographyProvider, PackageRuntime);
  736. RegisterSingleInstance(InstallationManager);
  737. ZipClient = new ZipClient(FileSystemManager);
  738. RegisterSingleInstance(ZipClient);
  739. RegisterSingleInstance<IHttpResultFactory>(new HttpResultFactory(LogManager, FileSystemManager, JsonSerializer, MemoryStreamFactory));
  740. RegisterSingleInstance<IServerApplicationHost>(this);
  741. RegisterSingleInstance<IServerApplicationPaths>(ApplicationPaths);
  742. RegisterSingleInstance(ServerConfigurationManager);
  743. IAssemblyInfo assemblyInfo = new AssemblyInfo();
  744. RegisterSingleInstance<IAssemblyInfo>(assemblyInfo);
  745. LocalizationManager = new LocalizationManager(ServerConfigurationManager, FileSystemManager, JsonSerializer, LogManager.GetLogger("LocalizationManager"), assemblyInfo, new TextLocalizer());
  746. StringExtensions.LocalizationManager = LocalizationManager;
  747. RegisterSingleInstance(LocalizationManager);
  748. ITextEncoding textEncoding = new TextEncoding.TextEncoding(FileSystemManager, LogManager.GetLogger("TextEncoding"), JsonSerializer);
  749. RegisterSingleInstance(textEncoding);
  750. Utilities.EncodingHelper = textEncoding;
  751. BlurayExaminer = new BdInfoExaminer(FileSystemManager, textEncoding);
  752. RegisterSingleInstance(BlurayExaminer);
  753. RegisterSingleInstance<IXmlReaderSettingsFactory>(new XmlReaderSettingsFactory());
  754. UserDataManager = new UserDataManager(LogManager, ServerConfigurationManager);
  755. RegisterSingleInstance(UserDataManager);
  756. UserRepository = GetUserRepository();
  757. // This is only needed for disposal purposes. If removing this, make sure to have the manager handle disposing it
  758. RegisterSingleInstance(UserRepository);
  759. var displayPreferencesRepo = new SqliteDisplayPreferencesRepository(LogManager.GetLogger("SqliteDisplayPreferencesRepository"), JsonSerializer, ApplicationPaths, MemoryStreamFactory);
  760. DisplayPreferencesRepository = displayPreferencesRepo;
  761. RegisterSingleInstance(DisplayPreferencesRepository);
  762. var itemRepo = new SqliteItemRepository(ServerConfigurationManager, JsonSerializer, LogManager.GetLogger("SqliteItemRepository"), MemoryStreamFactory, assemblyInfo, FileSystemManager, EnvironmentInfo, TimerFactory);
  763. ItemRepository = itemRepo;
  764. RegisterSingleInstance(ItemRepository);
  765. AuthenticationRepository = GetAuthenticationRepository();
  766. RegisterSingleInstance(AuthenticationRepository);
  767. UserManager = new UserManager(LogManager.GetLogger("UserManager"), ServerConfigurationManager, UserRepository, XmlSerializer, NetworkManager, () => ImageProcessor, () => DtoService, () => ConnectManager, this, JsonSerializer, FileSystemManager, CryptographyProvider);
  768. RegisterSingleInstance(UserManager);
  769. LibraryManager = new LibraryManager(Logger, TaskManager, UserManager, ServerConfigurationManager, UserDataManager, () => LibraryMonitor, FileSystemManager, () => ProviderManager, () => UserViewManager);
  770. RegisterSingleInstance(LibraryManager);
  771. var musicManager = new MusicManager(LibraryManager);
  772. RegisterSingleInstance<IMusicManager>(new MusicManager(LibraryManager));
  773. LibraryMonitor = new LibraryMonitor(LogManager, TaskManager, LibraryManager, ServerConfigurationManager, FileSystemManager, TimerFactory, SystemEvents, EnvironmentInfo);
  774. RegisterSingleInstance(LibraryMonitor);
  775. ProviderManager = new ProviderManager(HttpClient, ServerConfigurationManager, LibraryMonitor, LogManager, FileSystemManager, ApplicationPaths, () => LibraryManager, JsonSerializer, MemoryStreamFactory);
  776. RegisterSingleInstance(ProviderManager);
  777. RegisterSingleInstance<ISearchEngine>(() => new SearchEngine(LogManager, LibraryManager, UserManager));
  778. CertificateInfo = GetCertificateInfo(true);
  779. Certificate = GetCertificate(CertificateInfo);
  780. HttpServer = HttpServerFactory.CreateServer(this, LogManager, ServerConfigurationManager, NetworkManager, MemoryStreamFactory, "Emby", "web/index.html", textEncoding, SocketFactory, CryptographyProvider, JsonSerializer, XmlSerializer, EnvironmentInfo, Certificate, FileSystemManager, SupportsDualModeSockets);
  781. HttpServer.GlobalResponse = LocalizationManager.GetLocalizedString("StartupEmbyServerIsLoading");
  782. RegisterSingleInstance(HttpServer, false);
  783. progress.Report(10);
  784. ServerManager = new ServerManager.ServerManager(this, JsonSerializer, LogManager.GetLogger("ServerManager"), ServerConfigurationManager, MemoryStreamFactory, textEncoding);
  785. RegisterSingleInstance(ServerManager);
  786. var innerProgress = new ActionableProgress<double>();
  787. innerProgress.RegisterAction(p => progress.Report((.75 * p) + 15));
  788. ImageProcessor = GetImageProcessor();
  789. RegisterSingleInstance(ImageProcessor);
  790. TVSeriesManager = new TVSeriesManager(UserManager, UserDataManager, LibraryManager, ServerConfigurationManager);
  791. RegisterSingleInstance(TVSeriesManager);
  792. SyncManager = CreateSyncManager();
  793. RegisterSingleInstance(SyncManager);
  794. DtoService = new DtoService(LogManager.GetLogger("DtoService"), LibraryManager, UserDataManager, ItemRepository, ImageProcessor, ServerConfigurationManager, FileSystemManager, ProviderManager, () => ChannelManager, SyncManager, this, () => DeviceManager, () => MediaSourceManager, () => LiveTvManager);
  795. RegisterSingleInstance(DtoService);
  796. var encryptionManager = new EncryptionManager();
  797. RegisterSingleInstance<IEncryptionManager>(encryptionManager);
  798. ConnectManager = CreateConnectManager();
  799. RegisterSingleInstance(ConnectManager);
  800. DeviceManager = new DeviceManager(new DeviceRepository(ApplicationPaths, JsonSerializer, LogManager.GetLogger("DeviceManager"), FileSystemManager), UserManager, FileSystemManager, LibraryMonitor, ServerConfigurationManager, LogManager.GetLogger("DeviceManager"), NetworkManager);
  801. RegisterSingleInstance(DeviceManager);
  802. var newsService = new Emby.Server.Implementations.News.NewsService(ApplicationPaths, JsonSerializer);
  803. RegisterSingleInstance<INewsService>(newsService);
  804. progress.Report(15);
  805. ChannelManager = new ChannelManager(UserManager, DtoService, LibraryManager, LogManager.GetLogger("ChannelManager"), ServerConfigurationManager, FileSystemManager, UserDataManager, JsonSerializer, LocalizationManager, HttpClient, ProviderManager);
  806. RegisterSingleInstance(ChannelManager);
  807. MediaSourceManager = new MediaSourceManager(ItemRepository, UserManager, LibraryManager, LogManager.GetLogger("MediaSourceManager"), JsonSerializer, FileSystemManager, UserDataManager, TimerFactory);
  808. RegisterSingleInstance(MediaSourceManager);
  809. SessionManager = new SessionManager(UserDataManager, LogManager.GetLogger("SessionManager"), LibraryManager, UserManager, musicManager, DtoService, ImageProcessor, JsonSerializer, this, HttpClient, AuthenticationRepository, DeviceManager, MediaSourceManager, TimerFactory);
  810. RegisterSingleInstance(SessionManager);
  811. var dlnaManager = new DlnaManager(XmlSerializer, FileSystemManager, ApplicationPaths, LogManager.GetLogger("Dlna"), JsonSerializer, this, assemblyInfo);
  812. RegisterSingleInstance<IDlnaManager>(dlnaManager);
  813. var connectionManager = new ConnectionManager(dlnaManager, ServerConfigurationManager, LogManager.GetLogger("UpnpConnectionManager"), HttpClient, new XmlReaderSettingsFactory());
  814. RegisterSingleInstance<IConnectionManager>(connectionManager);
  815. CollectionManager = new CollectionManager(LibraryManager, FileSystemManager, LibraryMonitor, LogManager.GetLogger("CollectionManager"), ProviderManager);
  816. RegisterSingleInstance(CollectionManager);
  817. PlaylistManager = new PlaylistManager(LibraryManager, FileSystemManager, LibraryMonitor, LogManager.GetLogger("PlaylistManager"), UserManager, ProviderManager);
  818. RegisterSingleInstance<IPlaylistManager>(PlaylistManager);
  819. LiveTvManager = new LiveTvManager(this, ServerConfigurationManager, Logger, ItemRepository, ImageProcessor, UserDataManager, DtoService, UserManager, LibraryManager, TaskManager, LocalizationManager, JsonSerializer, ProviderManager, FileSystemManager, SecurityManager);
  820. RegisterSingleInstance(LiveTvManager);
  821. UserViewManager = new UserViewManager(LibraryManager, LocalizationManager, UserManager, ChannelManager, LiveTvManager, ServerConfigurationManager);
  822. RegisterSingleInstance(UserViewManager);
  823. var contentDirectory = new ContentDirectory(dlnaManager, UserDataManager, ImageProcessor, LibraryManager, ServerConfigurationManager, UserManager, LogManager.GetLogger("UpnpContentDirectory"), HttpClient, LocalizationManager, ChannelManager, MediaSourceManager, UserViewManager, () => MediaEncoder, new XmlReaderSettingsFactory(), TVSeriesManager);
  824. RegisterSingleInstance<IContentDirectory>(contentDirectory);
  825. var mediaRegistrar = new MediaReceiverRegistrar(LogManager.GetLogger("MediaReceiverRegistrar"), HttpClient, ServerConfigurationManager, new XmlReaderSettingsFactory());
  826. RegisterSingleInstance<IMediaReceiverRegistrar>(mediaRegistrar);
  827. NotificationManager = new NotificationManager(LogManager, UserManager, ServerConfigurationManager);
  828. RegisterSingleInstance(NotificationManager);
  829. SubtitleManager = new SubtitleManager(LogManager.GetLogger("SubtitleManager"), FileSystemManager, LibraryMonitor, LibraryManager, MediaSourceManager);
  830. RegisterSingleInstance(SubtitleManager);
  831. RegisterSingleInstance<IDeviceDiscovery>(new DeviceDiscovery(LogManager.GetLogger("IDeviceDiscovery"), ServerConfigurationManager, SocketFactory, TimerFactory));
  832. ChapterManager = new ChapterManager(LibraryManager, LogManager.GetLogger("ChapterManager"), ServerConfigurationManager, ItemRepository);
  833. RegisterSingleInstance(ChapterManager);
  834. await RegisterMediaEncoder(innerProgress).ConfigureAwait(false);
  835. progress.Report(90);
  836. EncodingManager = new EncodingManager(FileSystemManager, Logger, MediaEncoder, ChapterManager, LibraryManager);
  837. RegisterSingleInstance(EncodingManager);
  838. var sharingRepo = new SharingRepository(LogManager.GetLogger("SharingRepository"), ApplicationPaths);
  839. sharingRepo.Initialize();
  840. // This is only needed for disposal purposes. If removing this, make sure to have the manager handle disposing it
  841. RegisterSingleInstance<ISharingRepository>(sharingRepo);
  842. RegisterSingleInstance<ISharingManager>(new SharingManager(sharingRepo, ServerConfigurationManager, LibraryManager, this));
  843. var activityLogRepo = GetActivityLogRepository();
  844. RegisterSingleInstance(activityLogRepo);
  845. RegisterSingleInstance<IActivityManager>(new ActivityManager(LogManager.GetLogger("ActivityManager"), activityLogRepo, UserManager));
  846. var authContext = new AuthorizationContext(AuthenticationRepository, ConnectManager);
  847. RegisterSingleInstance<IAuthorizationContext>(authContext);
  848. RegisterSingleInstance<ISessionContext>(new SessionContext(UserManager, authContext, SessionManager));
  849. AuthService = new AuthService(UserManager, authContext, ServerConfigurationManager, ConnectManager, SessionManager, DeviceManager);
  850. RegisterSingleInstance<IAuthService>(AuthService);
  851. SubtitleEncoder = new SubtitleEncoder(LibraryManager, LogManager.GetLogger("SubtitleEncoder"), ApplicationPaths, FileSystemManager, MediaEncoder, JsonSerializer, HttpClient, MediaSourceManager, MemoryStreamFactory, ProcessFactory, textEncoding);
  852. RegisterSingleInstance(SubtitleEncoder);
  853. displayPreferencesRepo.Initialize();
  854. var userDataRepo = new SqliteUserDataRepository(LogManager.GetLogger("SqliteUserDataRepository"), ApplicationPaths, FileSystemManager);
  855. ((UserDataManager)UserDataManager).Repository = userDataRepo;
  856. itemRepo.Initialize(userDataRepo);
  857. ((LibraryManager)LibraryManager).ItemRepository = ItemRepository;
  858. ConfigureNotificationsRepository();
  859. progress.Report(100);
  860. SetStaticProperties();
  861. ((UserManager)UserManager).Initialize();
  862. }
  863. protected virtual string PackageRuntime
  864. {
  865. get
  866. {
  867. return "netframework";
  868. }
  869. }
  870. public static void LogEnvironmentInfo(ILogger logger, IApplicationPaths appPaths, bool isStartup)
  871. {
  872. logger.LogMultiline("Emby", LogSeverity.Info, GetBaseExceptionMessage(appPaths));
  873. }
  874. protected static StringBuilder GetBaseExceptionMessage(IApplicationPaths appPaths)
  875. {
  876. var builder = new StringBuilder();
  877. builder.AppendLine(string.Format("Command line: {0}", string.Join(" ", Environment.GetCommandLineArgs())));
  878. builder.AppendLine(string.Format("Operating system: {0}", Environment.OSVersion));
  879. builder.AppendLine(string.Format("64-Bit OS: {0}", Environment.Is64BitOperatingSystem));
  880. builder.AppendLine(string.Format("64-Bit Process: {0}", Environment.Is64BitProcess));
  881. Type type = Type.GetType("Mono.Runtime");
  882. if (type != null)
  883. {
  884. MethodInfo displayName = type.GetMethod("GetDisplayName", BindingFlags.NonPublic | BindingFlags.Static);
  885. if (displayName != null)
  886. {
  887. builder.AppendLine("Mono: " + displayName.Invoke(null, null));
  888. }
  889. }
  890. builder.AppendLine(string.Format("Processor count: {0}", Environment.ProcessorCount));
  891. builder.AppendLine(string.Format("Program data path: {0}", appPaths.ProgramDataPath));
  892. builder.AppendLine(string.Format("Application directory: {0}", appPaths.ProgramSystemPath));
  893. return builder;
  894. }
  895. private void SetHttpLimit()
  896. {
  897. try
  898. {
  899. // Increase the max http request limit
  900. ServicePointManager.DefaultConnectionLimit = Math.Max(96, ServicePointManager.DefaultConnectionLimit);
  901. }
  902. catch (Exception ex)
  903. {
  904. Logger.ErrorException("Error setting http limit", ex);
  905. }
  906. }
  907. /// <summary>
  908. /// Installs the iso mounters.
  909. /// </summary>
  910. /// <param name="cancellationToken">The cancellation token.</param>
  911. /// <returns>Task.</returns>
  912. private async Task InstallIsoMounters(CancellationToken cancellationToken)
  913. {
  914. var list = new List<IIsoMounter>();
  915. foreach (var isoMounter in GetExports<IIsoMounter>())
  916. {
  917. try
  918. {
  919. if (isoMounter.RequiresInstallation && !isoMounter.IsInstalled)
  920. {
  921. Logger.Info("Installing {0}", isoMounter.Name);
  922. await isoMounter.Install(cancellationToken).ConfigureAwait(false);
  923. }
  924. list.Add(isoMounter);
  925. }
  926. catch (Exception ex)
  927. {
  928. Logger.ErrorException("{0} failed to load.", ex, isoMounter.Name);
  929. }
  930. }
  931. IsoManager.AddParts(list);
  932. }
  933. private string GetDefaultUserAgent()
  934. {
  935. var name = FormatAttribute(Name);
  936. return name + "/" + ApplicationVersion;
  937. }
  938. private string FormatAttribute(string str)
  939. {
  940. var arr = str.ToCharArray();
  941. arr = Array.FindAll<char>(arr, (c => (char.IsLetterOrDigit(c)
  942. || char.IsWhiteSpace(c))));
  943. var result = new string(arr);
  944. if (string.IsNullOrWhiteSpace(result))
  945. {
  946. result = "Emby";
  947. }
  948. return result;
  949. }
  950. protected virtual bool SupportsDualModeSockets
  951. {
  952. get
  953. {
  954. return true;
  955. }
  956. }
  957. private ICertificate GetCertificate(CertificateInfo info)
  958. {
  959. var certificateLocation = info == null ? null : info.Path;
  960. if (string.IsNullOrWhiteSpace(certificateLocation))
  961. {
  962. return null;
  963. }
  964. try
  965. {
  966. if (!FileSystemManager.FileExists(certificateLocation))
  967. {
  968. return null;
  969. }
  970. // Don't use an empty string password
  971. var password = string.IsNullOrWhiteSpace(info.Password) ? null : info.Password;
  972. X509Certificate2 localCert = new X509Certificate2(certificateLocation, password);
  973. //localCert.PrivateKey = PrivateKey.CreateFromFile(pvk_file).RSA;
  974. if (!localCert.HasPrivateKey)
  975. {
  976. //throw new FileNotFoundException("Secure requested, no private key included", certificateLocation);
  977. return null;
  978. }
  979. return new Certificate(localCert);
  980. }
  981. catch (Exception ex)
  982. {
  983. Logger.ErrorException("Error loading cert from {0}", ex, certificateLocation);
  984. return null;
  985. }
  986. }
  987. private IImageProcessor GetImageProcessor()
  988. {
  989. return new ImageProcessor(LogManager.GetLogger("ImageProcessor"), ServerConfigurationManager.ApplicationPaths, FileSystemManager, JsonSerializer, ImageEncoder, () => LibraryManager, TimerFactory, () => MediaEncoder);
  990. }
  991. protected virtual FFMpegInstallInfo GetFfmpegInstallInfo()
  992. {
  993. var info = new FFMpegInstallInfo();
  994. // Windows builds: http://ffmpeg.zeranoe.com/builds/
  995. // Linux builds: http://johnvansickle.com/ffmpeg/
  996. // OS X builds: http://ffmpegmac.net/
  997. // OS X x64: http://www.evermeet.cx/ffmpeg/
  998. if (EnvironmentInfo.OperatingSystem == MediaBrowser.Model.System.OperatingSystem.Linux)
  999. {
  1000. info.FFMpegFilename = "ffmpeg";
  1001. info.FFProbeFilename = "ffprobe";
  1002. info.ArchiveType = "7z";
  1003. info.Version = "20170308";
  1004. info.DownloadUrls = GetLinuxDownloadUrls();
  1005. }
  1006. else if (EnvironmentInfo.OperatingSystem == MediaBrowser.Model.System.OperatingSystem.Windows)
  1007. {
  1008. info.FFMpegFilename = "ffmpeg.exe";
  1009. info.FFProbeFilename = "ffprobe.exe";
  1010. info.Version = "20170308";
  1011. info.ArchiveType = "7z";
  1012. info.DownloadUrls = GetWindowsDownloadUrls();
  1013. }
  1014. else if (EnvironmentInfo.OperatingSystem == MediaBrowser.Model.System.OperatingSystem.OSX)
  1015. {
  1016. info.FFMpegFilename = "ffmpeg";
  1017. info.FFProbeFilename = "ffprobe";
  1018. info.ArchiveType = "7z";
  1019. info.Version = "20170308";
  1020. info.DownloadUrls = GetMacDownloadUrls();
  1021. }
  1022. else
  1023. {
  1024. // No version available - user requirement
  1025. info.DownloadUrls = new string[] { };
  1026. }
  1027. return info;
  1028. }
  1029. private string[] GetMacDownloadUrls()
  1030. {
  1031. switch (EnvironmentInfo.SystemArchitecture)
  1032. {
  1033. case MediaBrowser.Model.System.Architecture.X64:
  1034. return new[]
  1035. {
  1036. "https://embydata.com/downloads/ffmpeg/osx/ffmpeg-x64-20170308.7z"
  1037. };
  1038. }
  1039. return new string[] { };
  1040. }
  1041. private string[] GetWindowsDownloadUrls()
  1042. {
  1043. switch (EnvironmentInfo.SystemArchitecture)
  1044. {
  1045. case MediaBrowser.Model.System.Architecture.X64:
  1046. return new[]
  1047. {
  1048. "https://embydata.com/downloads/ffmpeg/windows/ffmpeg-20170308-win64.7z"
  1049. };
  1050. case MediaBrowser.Model.System.Architecture.X86:
  1051. return new[]
  1052. {
  1053. "https://embydata.com/downloads/ffmpeg/windows/ffmpeg-20170308-win32.7z"
  1054. };
  1055. }
  1056. return new string[] { };
  1057. }
  1058. private string[] GetLinuxDownloadUrls()
  1059. {
  1060. switch (EnvironmentInfo.SystemArchitecture)
  1061. {
  1062. case MediaBrowser.Model.System.Architecture.X64:
  1063. return new[]
  1064. {
  1065. "https://embydata.com/downloads/ffmpeg/linux/ffmpeg-git-20170301-64bit-static.7z"
  1066. };
  1067. case MediaBrowser.Model.System.Architecture.X86:
  1068. return new[]
  1069. {
  1070. "https://embydata.com/downloads/ffmpeg/linux/ffmpeg-git-20170301-32bit-static.7z"
  1071. };
  1072. }
  1073. return new string[] { };
  1074. }
  1075. /// <summary>
  1076. /// Registers the media encoder.
  1077. /// </summary>
  1078. /// <returns>Task.</returns>
  1079. private async Task RegisterMediaEncoder(IProgress<double> progress)
  1080. {
  1081. string encoderPath = null;
  1082. string probePath = null;
  1083. var info = await new FFMpegLoader(Logger, ApplicationPaths, HttpClient, ZipClient, FileSystemManager, GetFfmpegInstallInfo())
  1084. .GetFFMpegInfo(StartupOptions, progress).ConfigureAwait(false);
  1085. encoderPath = info.EncoderPath;
  1086. probePath = info.ProbePath;
  1087. var hasExternalEncoder = string.Equals(info.Version, "external", StringComparison.OrdinalIgnoreCase);
  1088. var mediaEncoder = new MediaEncoding.Encoder.MediaEncoder(LogManager.GetLogger("MediaEncoder"),
  1089. JsonSerializer,
  1090. encoderPath,
  1091. probePath,
  1092. hasExternalEncoder,
  1093. ServerConfigurationManager,
  1094. FileSystemManager,
  1095. LiveTvManager,
  1096. IsoManager,
  1097. LibraryManager,
  1098. ChannelManager,
  1099. SessionManager,
  1100. () => SubtitleEncoder,
  1101. () => MediaSourceManager,
  1102. HttpClient,
  1103. ZipClient,
  1104. MemoryStreamFactory,
  1105. ProcessFactory,
  1106. (Environment.ProcessorCount > 2 ? 14000 : 40000),
  1107. EnvironmentInfo.OperatingSystem == MediaBrowser.Model.System.OperatingSystem.Windows,
  1108. EnvironmentInfo,
  1109. BlurayExaminer);
  1110. MediaEncoder = mediaEncoder;
  1111. RegisterSingleInstance(MediaEncoder);
  1112. }
  1113. /// <summary>
  1114. /// Gets the user repository.
  1115. /// </summary>
  1116. /// <returns>Task{IUserRepository}.</returns>
  1117. private IUserRepository GetUserRepository()
  1118. {
  1119. var repo = new SqliteUserRepository(LogManager.GetLogger("SqliteUserRepository"), ApplicationPaths, JsonSerializer, MemoryStreamFactory);
  1120. repo.Initialize();
  1121. return repo;
  1122. }
  1123. private IAuthenticationRepository GetAuthenticationRepository()
  1124. {
  1125. var repo = new AuthenticationRepository(LogManager.GetLogger("AuthenticationRepository"), ServerConfigurationManager.ApplicationPaths);
  1126. repo.Initialize();
  1127. return repo;
  1128. }
  1129. private IActivityRepository GetActivityLogRepository()
  1130. {
  1131. var repo = new ActivityRepository(LogManager.GetLogger("ActivityRepository"), ServerConfigurationManager.ApplicationPaths);
  1132. repo.Initialize();
  1133. return repo;
  1134. }
  1135. /// <summary>
  1136. /// Configures the repositories.
  1137. /// </summary>
  1138. private void ConfigureNotificationsRepository()
  1139. {
  1140. var repo = new SqliteNotificationsRepository(LogManager.GetLogger("SqliteNotificationsRepository"), ServerConfigurationManager.ApplicationPaths, FileSystemManager);
  1141. repo.Initialize();
  1142. NotificationsRepository = repo;
  1143. RegisterSingleInstance(NotificationsRepository);
  1144. }
  1145. /// <summary>
  1146. /// Dirty hacks
  1147. /// </summary>
  1148. private void SetStaticProperties()
  1149. {
  1150. // For now there's no real way to inject these properly
  1151. BaseItem.Logger = LogManager.GetLogger("BaseItem");
  1152. BaseItem.ConfigurationManager = ServerConfigurationManager;
  1153. BaseItem.LibraryManager = LibraryManager;
  1154. BaseItem.ProviderManager = ProviderManager;
  1155. BaseItem.LocalizationManager = LocalizationManager;
  1156. BaseItem.ItemRepository = ItemRepository;
  1157. User.XmlSerializer = XmlSerializer;
  1158. User.UserManager = UserManager;
  1159. Folder.UserManager = UserManager;
  1160. BaseItem.FileSystem = FileSystemManager;
  1161. BaseItem.UserDataManager = UserDataManager;
  1162. BaseItem.ChannelManager = ChannelManager;
  1163. BaseItem.LiveTvManager = LiveTvManager;
  1164. Folder.UserViewManager = UserViewManager;
  1165. UserView.TVSeriesManager = TVSeriesManager;
  1166. UserView.PlaylistManager = PlaylistManager;
  1167. BaseItem.CollectionManager = CollectionManager;
  1168. BaseItem.MediaSourceManager = MediaSourceManager;
  1169. CollectionFolder.XmlSerializer = XmlSerializer;
  1170. Utilities.CryptographyProvider = CryptographyProvider;
  1171. AuthenticatedAttribute.AuthService = AuthService;
  1172. }
  1173. /// <summary>
  1174. /// Finds the parts.
  1175. /// </summary>
  1176. protected void FindParts()
  1177. {
  1178. if (!ServerConfigurationManager.Configuration.IsPortAuthorized)
  1179. {
  1180. RegisterServerWithAdministratorAccess();
  1181. ServerConfigurationManager.Configuration.IsPortAuthorized = true;
  1182. ConfigurationManager.SaveConfiguration();
  1183. }
  1184. RegisterModules();
  1185. ConfigurationManager.AddParts(GetExports<IConfigurationFactory>());
  1186. Plugins = GetExports<IPlugin>().Select(LoadPlugin).Where(i => i != null).ToArray();
  1187. HttpServer.Init(GetExports<IService>(false));
  1188. ServerManager.AddWebSocketListeners(GetExports<IWebSocketListener>(false));
  1189. StartServer();
  1190. LibraryManager.AddParts(GetExports<IResolverIgnoreRule>(),
  1191. GetExports<IVirtualFolderCreator>(),
  1192. GetExports<IItemResolver>(),
  1193. GetExports<IIntroProvider>(),
  1194. GetExports<IBaseItemComparer>(),
  1195. GetExports<ILibraryPostScanTask>());
  1196. ProviderManager.AddParts(GetExports<IImageProvider>(),
  1197. GetExports<IMetadataService>(),
  1198. GetExports<IMetadataProvider>(),
  1199. GetExports<IMetadataSaver>(),
  1200. GetExports<IExternalId>());
  1201. ImageProcessor.AddParts(GetExports<IImageEnhancer>());
  1202. LiveTvManager.AddParts(GetExports<ILiveTvService>(), GetExports<ITunerHost>(), GetExports<IListingsProvider>());
  1203. SubtitleManager.AddParts(GetExports<ISubtitleProvider>());
  1204. SessionManager.AddParts(GetExports<ISessionControllerFactory>());
  1205. ChannelManager.AddParts(GetExports<IChannel>());
  1206. MediaSourceManager.AddParts(GetExports<IMediaSourceProvider>());
  1207. NotificationManager.AddParts(GetExports<INotificationService>(), GetExports<INotificationTypeFactory>());
  1208. SyncManager.AddParts(GetExports<ISyncProvider>());
  1209. }
  1210. private IPlugin LoadPlugin(IPlugin plugin)
  1211. {
  1212. try
  1213. {
  1214. var assemblyPlugin = plugin as IPluginAssembly;
  1215. if (assemblyPlugin != null)
  1216. {
  1217. var assembly = plugin.GetType().Assembly;
  1218. var assemblyName = assembly.GetName();
  1219. var attribute = (GuidAttribute)assembly.GetCustomAttributes(typeof(GuidAttribute), true)[0];
  1220. var assemblyId = new Guid(attribute.Value);
  1221. var assemblyFileName = assemblyName.Name + ".dll";
  1222. var assemblyFilePath = Path.Combine(ApplicationPaths.PluginsPath, assemblyFileName);
  1223. assemblyPlugin.SetAttributes(assemblyFilePath, assemblyFileName, assemblyName.Version, assemblyId);
  1224. }
  1225. var isFirstRun = !File.Exists(plugin.ConfigurationFilePath);
  1226. plugin.SetStartupInfo(isFirstRun, File.GetLastWriteTimeUtc, s => Directory.CreateDirectory(s));
  1227. }
  1228. catch (Exception ex)
  1229. {
  1230. Logger.ErrorException("Error loading plugin {0}", ex, plugin.GetType().FullName);
  1231. return null;
  1232. }
  1233. return plugin;
  1234. }
  1235. /// <summary>
  1236. /// Discovers the types.
  1237. /// </summary>
  1238. protected void DiscoverTypes()
  1239. {
  1240. FailedAssemblies.Clear();
  1241. var assemblies = GetComposablePartAssemblies().ToList();
  1242. foreach (var assembly in assemblies)
  1243. {
  1244. Logger.Info("Loading {0}", assembly.FullName);
  1245. }
  1246. AllConcreteTypes = assemblies
  1247. .SelectMany(GetTypes)
  1248. .Where(t => t.IsClass && !t.IsAbstract && !t.IsInterface && !t.IsGenericType)
  1249. .ToArray();
  1250. }
  1251. /// <summary>
  1252. /// Gets a list of types within an assembly
  1253. /// This will handle situations that would normally throw an exception - such as a type within the assembly that depends on some other non-existant reference
  1254. /// </summary>
  1255. /// <param name="assembly">The assembly.</param>
  1256. /// <returns>IEnumerable{Type}.</returns>
  1257. /// <exception cref="System.ArgumentNullException">assembly</exception>
  1258. protected List<Type> GetTypes(Assembly assembly)
  1259. {
  1260. if (assembly == null)
  1261. {
  1262. return new List<Type>();
  1263. }
  1264. try
  1265. {
  1266. // This null checking really shouldn't be needed but adding it due to some
  1267. // unhandled exceptions in mono 5.0 that are a little hard to hunt down
  1268. var types = assembly.GetTypes() ?? new Type[] { };
  1269. return types.Where(t => t != null).ToList();
  1270. }
  1271. catch (ReflectionTypeLoadException ex)
  1272. {
  1273. if (ex.LoaderExceptions != null)
  1274. {
  1275. foreach (var loaderException in ex.LoaderExceptions)
  1276. {
  1277. if (loaderException != null)
  1278. {
  1279. Logger.Error("LoaderException: " + loaderException.Message);
  1280. }
  1281. }
  1282. }
  1283. // If it fails we can still get a list of the Types it was able to resolve
  1284. var types = ex.Types ?? new Type[] { };
  1285. return types.Where(t => t != null).ToList();
  1286. }
  1287. catch (Exception ex)
  1288. {
  1289. Logger.ErrorException("Error loading types from assembly", ex);
  1290. return new List<Type>();
  1291. }
  1292. }
  1293. private CertificateInfo CertificateInfo { get; set; }
  1294. private ICertificate Certificate { get; set; }
  1295. private IEnumerable<string> GetUrlPrefixes()
  1296. {
  1297. var hosts = new List<string>();
  1298. hosts.Add("+");
  1299. return hosts.SelectMany(i =>
  1300. {
  1301. var prefixes = new List<string>
  1302. {
  1303. "http://"+i+":" + HttpPort + "/"
  1304. };
  1305. if (CertificateInfo != null)
  1306. {
  1307. prefixes.Add("https://" + i + ":" + HttpsPort + "/");
  1308. }
  1309. return prefixes;
  1310. });
  1311. }
  1312. /// <summary>
  1313. /// Starts the server.
  1314. /// </summary>
  1315. private void StartServer()
  1316. {
  1317. try
  1318. {
  1319. ServerManager.Start(GetUrlPrefixes());
  1320. return;
  1321. }
  1322. catch (Exception ex)
  1323. {
  1324. Logger.ErrorException("Error starting http server", ex);
  1325. if (HttpPort == ServerConfiguration.DefaultHttpPort)
  1326. {
  1327. throw;
  1328. }
  1329. }
  1330. HttpPort = ServerConfiguration.DefaultHttpPort;
  1331. try
  1332. {
  1333. ServerManager.Start(GetUrlPrefixes());
  1334. }
  1335. catch (Exception ex)
  1336. {
  1337. Logger.ErrorException("Error starting http server", ex);
  1338. throw;
  1339. }
  1340. }
  1341. private CertificateInfo GetCertificateInfo(bool generateCertificate)
  1342. {
  1343. if (!string.IsNullOrWhiteSpace(ServerConfigurationManager.Configuration.CertificatePath))
  1344. {
  1345. // Custom cert
  1346. return new CertificateInfo
  1347. {
  1348. Path = ServerConfigurationManager.Configuration.CertificatePath,
  1349. Password = ServerConfigurationManager.Configuration.CertificatePassword
  1350. };
  1351. }
  1352. // Generate self-signed cert
  1353. var certHost = GetHostnameFromExternalDns(ServerConfigurationManager.Configuration.WanDdns);
  1354. var certPath = Path.Combine(ServerConfigurationManager.ApplicationPaths.ProgramDataPath, "ssl", "cert_" + (certHost + "2").GetMD5().ToString("N") + ".pfx");
  1355. var password = "embycert";
  1356. if (generateCertificate)
  1357. {
  1358. if (!FileSystemManager.FileExists(certPath))
  1359. {
  1360. FileSystemManager.CreateDirectory(FileSystemManager.GetDirectoryName(certPath));
  1361. try
  1362. {
  1363. CertificateGenerator.CreateSelfSignCertificatePfx(certPath, certHost, password, Logger);
  1364. }
  1365. catch (Exception ex)
  1366. {
  1367. Logger.ErrorException("Error creating ssl cert", ex);
  1368. return null;
  1369. }
  1370. }
  1371. }
  1372. return new CertificateInfo
  1373. {
  1374. Path = certPath,
  1375. Password = password
  1376. };
  1377. }
  1378. /// <summary>
  1379. /// Called when [configuration updated].
  1380. /// </summary>
  1381. /// <param name="sender">The sender.</param>
  1382. /// <param name="e">The <see cref="EventArgs"/> instance containing the event data.</param>
  1383. protected void OnConfigurationUpdated(object sender, EventArgs e)
  1384. {
  1385. ConfigureAutorun();
  1386. var requiresRestart = false;
  1387. // Don't do anything if these haven't been set yet
  1388. if (HttpPort != 0 && HttpsPort != 0)
  1389. {
  1390. // Need to restart if ports have changed
  1391. if (ServerConfigurationManager.Configuration.HttpServerPortNumber != HttpPort ||
  1392. ServerConfigurationManager.Configuration.HttpsPortNumber != HttpsPort)
  1393. {
  1394. if (ServerConfigurationManager.Configuration.IsPortAuthorized)
  1395. {
  1396. ServerConfigurationManager.Configuration.IsPortAuthorized = false;
  1397. ServerConfigurationManager.SaveConfiguration();
  1398. requiresRestart = true;
  1399. }
  1400. }
  1401. }
  1402. if (!HttpServer.UrlPrefixes.SequenceEqual(GetUrlPrefixes(), StringComparer.OrdinalIgnoreCase))
  1403. {
  1404. requiresRestart = true;
  1405. }
  1406. var currentCertPath = CertificateInfo == null ? null : CertificateInfo.Path;
  1407. var newCertInfo = GetCertificateInfo(false);
  1408. var newCertPath = newCertInfo == null ? null : newCertInfo.Path;
  1409. if (!string.Equals(currentCertPath, newCertPath, StringComparison.OrdinalIgnoreCase))
  1410. {
  1411. requiresRestart = true;
  1412. }
  1413. if (requiresRestart)
  1414. {
  1415. Logger.Info("App needs to be restarted due to configuration change.");
  1416. NotifyPendingRestart();
  1417. }
  1418. }
  1419. /// <summary>
  1420. /// Notifies that the kernel that a change has been made that requires a restart
  1421. /// </summary>
  1422. public void NotifyPendingRestart()
  1423. {
  1424. Logger.Info("App needs to be restarted.");
  1425. var changed = !HasPendingRestart;
  1426. HasPendingRestart = true;
  1427. if (changed)
  1428. {
  1429. EventHelper.QueueEventIfNotNull(HasPendingRestartChanged, this, EventArgs.Empty, Logger);
  1430. }
  1431. }
  1432. /// <summary>
  1433. /// Restarts this instance.
  1434. /// </summary>
  1435. public async Task Restart()
  1436. {
  1437. if (!CanSelfRestart)
  1438. {
  1439. throw new PlatformNotSupportedException("The server is unable to self-restart. Please restart manually.");
  1440. }
  1441. try
  1442. {
  1443. await SessionManager.SendServerRestartNotification(CancellationToken.None).ConfigureAwait(false);
  1444. }
  1445. catch (Exception ex)
  1446. {
  1447. Logger.ErrorException("Error sending server restart notification", ex);
  1448. }
  1449. Logger.Info("Calling RestartInternal");
  1450. RestartInternal();
  1451. }
  1452. protected abstract void RestartInternal();
  1453. /// <summary>
  1454. /// Gets the composable part assemblies.
  1455. /// </summary>
  1456. /// <returns>IEnumerable{Assembly}.</returns>
  1457. protected IEnumerable<Assembly> GetComposablePartAssemblies()
  1458. {
  1459. var list = GetPluginAssemblies()
  1460. .ToList();
  1461. // Gets all plugin assemblies by first reading all bytes of the .dll and calling Assembly.Load against that
  1462. // This will prevent the .dll file from getting locked, and allow us to replace it when needed
  1463. // Include composable parts in the Api assembly
  1464. list.Add(GetAssembly(typeof(ApiEntryPoint)));
  1465. // Include composable parts in the Dashboard assembly
  1466. list.Add(GetAssembly(typeof(DashboardService)));
  1467. // Include composable parts in the Model assembly
  1468. list.Add(GetAssembly(typeof(SystemInfo)));
  1469. // Include composable parts in the Common assembly
  1470. list.Add(GetAssembly(typeof(IApplicationHost)));
  1471. // Include composable parts in the Controller assembly
  1472. list.Add(GetAssembly(typeof(IServerApplicationHost)));
  1473. // Include composable parts in the Providers assembly
  1474. list.Add(GetAssembly(typeof(ProviderUtils)));
  1475. // Include composable parts in the Photos assembly
  1476. list.Add(GetAssembly(typeof(PhotoProvider)));
  1477. // Emby.Server implementations
  1478. list.Add(GetAssembly(typeof(InstallationManager)));
  1479. // MediaEncoding
  1480. list.Add(GetAssembly(typeof(MediaEncoding.Encoder.MediaEncoder)));
  1481. // Dlna
  1482. list.Add(GetAssembly(typeof(DlnaEntryPoint)));
  1483. // Local metadata
  1484. list.Add(GetAssembly(typeof(BoxSetXmlSaver)));
  1485. // Xbmc
  1486. list.Add(GetAssembly(typeof(ArtistNfoProvider)));
  1487. list.AddRange(GetAssembliesWithPartsInternal());
  1488. return list.ToList();
  1489. }
  1490. protected abstract List<Assembly> GetAssembliesWithPartsInternal();
  1491. /// <summary>
  1492. /// Gets the plugin assemblies.
  1493. /// </summary>
  1494. /// <returns>IEnumerable{Assembly}.</returns>
  1495. private IEnumerable<Assembly> GetPluginAssemblies()
  1496. {
  1497. try
  1498. {
  1499. return Directory.EnumerateFiles(ApplicationPaths.PluginsPath, "*.dll", SearchOption.TopDirectoryOnly)
  1500. .Where(EnablePlugin)
  1501. .Select(LoadAssembly)
  1502. .Where(a => a != null)
  1503. .ToList();
  1504. }
  1505. catch (DirectoryNotFoundException)
  1506. {
  1507. return new List<Assembly>();
  1508. }
  1509. }
  1510. private bool EnablePlugin(string path)
  1511. {
  1512. var filename = Path.GetFileName(path);
  1513. var exclude = new[]
  1514. {
  1515. "mbplus.dll",
  1516. "mbintros.dll",
  1517. "embytv.dll",
  1518. "Messenger.dll"
  1519. };
  1520. return !exclude.Contains(filename ?? string.Empty, StringComparer.OrdinalIgnoreCase);
  1521. }
  1522. /// <summary>
  1523. /// Gets the system status.
  1524. /// </summary>
  1525. /// <returns>SystemInfo.</returns>
  1526. public async Task<SystemInfo> GetSystemInfo()
  1527. {
  1528. var localAddress = await GetLocalApiUrl().ConfigureAwait(false);
  1529. return new SystemInfo
  1530. {
  1531. HasPendingRestart = HasPendingRestart,
  1532. Version = ApplicationVersion.ToString(),
  1533. WebSocketPortNumber = HttpPort,
  1534. FailedPluginAssemblies = FailedAssemblies.ToArray(),
  1535. InProgressInstallations = InstallationManager.CurrentInstallations.Select(i => i.Item1).ToArray(),
  1536. CompletedInstallations = InstallationManager.CompletedInstallations.ToArray(),
  1537. Id = SystemId,
  1538. ProgramDataPath = ApplicationPaths.ProgramDataPath,
  1539. LogPath = ApplicationPaths.LogDirectoryPath,
  1540. ItemsByNamePath = ApplicationPaths.ItemsByNamePath,
  1541. InternalMetadataPath = ApplicationPaths.InternalMetadataPath,
  1542. CachePath = ApplicationPaths.CachePath,
  1543. MacAddress = GetMacAddress(),
  1544. HttpServerPortNumber = HttpPort,
  1545. SupportsHttps = SupportsHttps,
  1546. HttpsPortNumber = HttpsPort,
  1547. OperatingSystem = EnvironmentInfo.OperatingSystem.ToString(),
  1548. OperatingSystemDisplayName = OperatingSystemDisplayName,
  1549. CanSelfRestart = CanSelfRestart,
  1550. CanSelfUpdate = CanSelfUpdate,
  1551. WanAddress = ConnectManager.WanApiAddress,
  1552. HasUpdateAvailable = HasUpdateAvailable,
  1553. SupportsAutoRunAtStartup = SupportsAutoRunAtStartup,
  1554. TranscodingTempPath = ApplicationPaths.TranscodingTempPath,
  1555. SupportsRunningAsService = SupportsRunningAsService,
  1556. ServerName = FriendlyName,
  1557. LocalAddress = localAddress,
  1558. SupportsLibraryMonitor = true,
  1559. EncoderLocationType = MediaEncoder.EncoderLocationType,
  1560. SystemArchitecture = EnvironmentInfo.SystemArchitecture,
  1561. SystemUpdateLevel = SystemUpdateLevel,
  1562. PackageName = StartupOptions.GetOption("-package")
  1563. };
  1564. }
  1565. public bool EnableHttps
  1566. {
  1567. get
  1568. {
  1569. return SupportsHttps && ServerConfigurationManager.Configuration.EnableHttps;
  1570. }
  1571. }
  1572. public bool SupportsHttps
  1573. {
  1574. get { return Certificate != null; }
  1575. }
  1576. public async Task<string> GetLocalApiUrl()
  1577. {
  1578. try
  1579. {
  1580. // Return the first matched address, if found, or the first known local address
  1581. var address = (await GetLocalIpAddresses().ConfigureAwait(false)).FirstOrDefault(i => !i.Equals(IpAddressInfo.Loopback) && !i.Equals(IpAddressInfo.IPv6Loopback));
  1582. if (address != null)
  1583. {
  1584. return GetLocalApiUrl(address);
  1585. }
  1586. return null;
  1587. }
  1588. catch (Exception ex)
  1589. {
  1590. Logger.ErrorException("Error getting local Ip address information", ex);
  1591. }
  1592. return null;
  1593. }
  1594. public string GetLocalApiUrl(IpAddressInfo ipAddress)
  1595. {
  1596. if (ipAddress.AddressFamily == IpAddressFamily.InterNetworkV6)
  1597. {
  1598. return GetLocalApiUrl("[" + ipAddress.Address + "]");
  1599. }
  1600. return GetLocalApiUrl(ipAddress.Address);
  1601. }
  1602. public string GetLocalApiUrl(string host)
  1603. {
  1604. return string.Format("http://{0}:{1}",
  1605. host,
  1606. HttpPort.ToString(CultureInfo.InvariantCulture));
  1607. }
  1608. public async Task<List<IpAddressInfo>> GetLocalIpAddresses()
  1609. {
  1610. var addresses = ServerConfigurationManager
  1611. .Configuration
  1612. .LocalNetworkAddresses
  1613. .Select(NormalizeConfiguredLocalAddress)
  1614. .Where(i => i != null)
  1615. .ToList();
  1616. if (addresses.Count == 0)
  1617. {
  1618. addresses.AddRange(NetworkManager.GetLocalIpAddresses());
  1619. var list = new List<IpAddressInfo>();
  1620. foreach (var address in addresses)
  1621. {
  1622. var valid = await IsIpAddressValidAsync(address).ConfigureAwait(false);
  1623. if (valid)
  1624. {
  1625. list.Add(address);
  1626. }
  1627. }
  1628. addresses = list;
  1629. }
  1630. return addresses;
  1631. }
  1632. private IpAddressInfo NormalizeConfiguredLocalAddress(string address)
  1633. {
  1634. var index = address.Trim('/').IndexOf('/');
  1635. if (index != -1)
  1636. {
  1637. address = address.Substring(index + 1);
  1638. }
  1639. IpAddressInfo result;
  1640. if (NetworkManager.TryParseIpAddress(address.Trim('/'), out result))
  1641. {
  1642. return result;
  1643. }
  1644. return null;
  1645. }
  1646. private readonly ConcurrentDictionary<string, bool> _validAddressResults = new ConcurrentDictionary<string, bool>(StringComparer.OrdinalIgnoreCase);
  1647. private DateTime _lastAddressCacheClear;
  1648. private async Task<bool> IsIpAddressValidAsync(IpAddressInfo address)
  1649. {
  1650. if (address.Equals(IpAddressInfo.Loopback) ||
  1651. address.Equals(IpAddressInfo.IPv6Loopback))
  1652. {
  1653. return true;
  1654. }
  1655. var apiUrl = GetLocalApiUrl(address);
  1656. apiUrl += "/system/ping";
  1657. if ((DateTime.UtcNow - _lastAddressCacheClear).TotalMinutes >= 15)
  1658. {
  1659. _lastAddressCacheClear = DateTime.UtcNow;
  1660. _validAddressResults.Clear();
  1661. }
  1662. bool cachedResult;
  1663. if (_validAddressResults.TryGetValue(apiUrl, out cachedResult))
  1664. {
  1665. return cachedResult;
  1666. }
  1667. try
  1668. {
  1669. using (var response = await HttpClient.SendAsync(new HttpRequestOptions
  1670. {
  1671. Url = apiUrl,
  1672. LogErrorResponseBody = false,
  1673. LogErrors = false,
  1674. LogRequest = false,
  1675. TimeoutMs = 30000,
  1676. BufferContent = false
  1677. }, "POST").ConfigureAwait(false))
  1678. {
  1679. using (var reader = new StreamReader(response.Content))
  1680. {
  1681. var result = reader.ReadToEnd();
  1682. var valid = string.Equals(Name, result, StringComparison.OrdinalIgnoreCase);
  1683. _validAddressResults.AddOrUpdate(apiUrl, valid, (k, v) => valid);
  1684. //Logger.Debug("Ping test result to {0}. Success: {1}", apiUrl, valid);
  1685. return valid;
  1686. }
  1687. }
  1688. }
  1689. catch
  1690. {
  1691. //Logger.Debug("Ping test result to {0}. Success: {1}", apiUrl, false);
  1692. _validAddressResults.AddOrUpdate(apiUrl, false, (k, v) => false);
  1693. return false;
  1694. }
  1695. }
  1696. public string FriendlyName
  1697. {
  1698. get
  1699. {
  1700. return string.IsNullOrWhiteSpace(ServerConfigurationManager.Configuration.ServerName)
  1701. ? Environment.MachineName
  1702. : ServerConfigurationManager.Configuration.ServerName;
  1703. }
  1704. }
  1705. public int HttpPort { get; private set; }
  1706. public int HttpsPort { get; private set; }
  1707. /// <summary>
  1708. /// Gets the mac address.
  1709. /// </summary>
  1710. /// <returns>System.String.</returns>
  1711. private string GetMacAddress()
  1712. {
  1713. try
  1714. {
  1715. return NetworkManager.GetMacAddress();
  1716. }
  1717. catch (Exception ex)
  1718. {
  1719. Logger.ErrorException("Error getting mac address", ex);
  1720. return null;
  1721. }
  1722. }
  1723. /// <summary>
  1724. /// Shuts down.
  1725. /// </summary>
  1726. public async Task Shutdown()
  1727. {
  1728. try
  1729. {
  1730. await SessionManager.SendServerShutdownNotification(CancellationToken.None).ConfigureAwait(false);
  1731. }
  1732. catch (Exception ex)
  1733. {
  1734. Logger.ErrorException("Error sending server shutdown notification", ex);
  1735. }
  1736. ShutdownInternal();
  1737. }
  1738. protected abstract void ShutdownInternal();
  1739. /// <summary>
  1740. /// Registers the server with administrator access.
  1741. /// </summary>
  1742. private void RegisterServerWithAdministratorAccess()
  1743. {
  1744. Logger.Info("Requesting administrative access to authorize http server");
  1745. try
  1746. {
  1747. AuthorizeServer();
  1748. }
  1749. catch (NotImplementedException)
  1750. {
  1751. }
  1752. catch (Exception ex)
  1753. {
  1754. Logger.ErrorException("Error authorizing server", ex);
  1755. }
  1756. }
  1757. protected virtual void AuthorizeServer()
  1758. {
  1759. throw new NotImplementedException();
  1760. }
  1761. public event EventHandler HasUpdateAvailableChanged;
  1762. private bool _hasUpdateAvailable;
  1763. public bool HasUpdateAvailable
  1764. {
  1765. get { return _hasUpdateAvailable; }
  1766. set
  1767. {
  1768. var fireEvent = value && !_hasUpdateAvailable;
  1769. _hasUpdateAvailable = value;
  1770. if (fireEvent)
  1771. {
  1772. EventHelper.FireEventIfNotNull(HasUpdateAvailableChanged, this, EventArgs.Empty, Logger);
  1773. }
  1774. }
  1775. }
  1776. /// <summary>
  1777. /// Removes the plugin.
  1778. /// </summary>
  1779. /// <param name="plugin">The plugin.</param>
  1780. public void RemovePlugin(IPlugin plugin)
  1781. {
  1782. var list = Plugins.ToList();
  1783. list.Remove(plugin);
  1784. Plugins = list.ToArray();
  1785. }
  1786. /// <summary>
  1787. /// Checks for update.
  1788. /// </summary>
  1789. /// <param name="cancellationToken">The cancellation token.</param>
  1790. /// <param name="progress">The progress.</param>
  1791. /// <returns>Task{CheckForUpdateResult}.</returns>
  1792. public async Task<CheckForUpdateResult> CheckForApplicationUpdate(CancellationToken cancellationToken, IProgress<double> progress)
  1793. {
  1794. var cacheLength = TimeSpan.FromHours(1);
  1795. var updateLevel = SystemUpdateLevel;
  1796. if (updateLevel != PackageVersionClass.Release)
  1797. {
  1798. cacheLength = TimeSpan.FromMinutes(5);
  1799. }
  1800. var result = await new GithubUpdater(HttpClient, JsonSerializer).CheckForUpdateResult("MediaBrowser", "Emby", ApplicationVersion, updateLevel, _releaseAssetFilename,
  1801. "MBServer", "Mbserver.zip", cacheLength, cancellationToken).ConfigureAwait(false);
  1802. HasUpdateAvailable = result.IsUpdateAvailable;
  1803. return result;
  1804. }
  1805. /// <summary>
  1806. /// Updates the application.
  1807. /// </summary>
  1808. /// <param name="package">The package that contains the update</param>
  1809. /// <param name="cancellationToken">The cancellation token.</param>
  1810. /// <param name="progress">The progress.</param>
  1811. public async Task UpdateApplication(PackageVersionInfo package, CancellationToken cancellationToken, IProgress<double> progress)
  1812. {
  1813. await InstallationManager.InstallPackage(package, false, progress, cancellationToken).ConfigureAwait(false);
  1814. HasUpdateAvailable = false;
  1815. OnApplicationUpdated(package);
  1816. }
  1817. /// <summary>
  1818. /// Configures the automatic run at startup.
  1819. /// </summary>
  1820. /// <param name="autorun">if set to <c>true</c> [autorun].</param>
  1821. protected void ConfigureAutoRunAtStartup(bool autorun)
  1822. {
  1823. if (SupportsAutoRunAtStartup)
  1824. {
  1825. ConfigureAutoRunInternal(autorun);
  1826. }
  1827. }
  1828. protected virtual void ConfigureAutoRunInternal(bool autorun)
  1829. {
  1830. throw new NotImplementedException();
  1831. }
  1832. /// <summary>
  1833. /// This returns localhost in the case of no external dns, and the hostname if the
  1834. /// dns is prefixed with a valid Uri prefix.
  1835. /// </summary>
  1836. /// <param name="externalDns">The external dns prefix to get the hostname of.</param>
  1837. /// <returns>The hostname in <paramref name="externalDns"/></returns>
  1838. private static string GetHostnameFromExternalDns(string externalDns)
  1839. {
  1840. if (string.IsNullOrWhiteSpace(externalDns))
  1841. {
  1842. return "localhost";
  1843. }
  1844. try
  1845. {
  1846. return new Uri(externalDns).Host;
  1847. }
  1848. catch
  1849. {
  1850. return externalDns;
  1851. }
  1852. }
  1853. public void LaunchUrl(string url)
  1854. {
  1855. if (EnvironmentInfo.OperatingSystem != MediaBrowser.Model.System.OperatingSystem.Windows &&
  1856. EnvironmentInfo.OperatingSystem != MediaBrowser.Model.System.OperatingSystem.OSX)
  1857. {
  1858. throw new NotImplementedException();
  1859. }
  1860. var process = ProcessFactory.Create(new ProcessOptions
  1861. {
  1862. FileName = url,
  1863. //EnableRaisingEvents = true,
  1864. UseShellExecute = true,
  1865. ErrorDialog = false
  1866. });
  1867. process.Exited += ProcessExited;
  1868. try
  1869. {
  1870. process.Start();
  1871. }
  1872. catch (Exception ex)
  1873. {
  1874. Console.WriteLine("Error launching url: {0}", url);
  1875. Logger.ErrorException("Error launching url: {0}", ex, url);
  1876. throw;
  1877. }
  1878. }
  1879. private static void ProcessExited(object sender, EventArgs e)
  1880. {
  1881. ((IProcess)sender).Dispose();
  1882. }
  1883. public virtual void EnableLoopback(string appName)
  1884. {
  1885. }
  1886. private void RegisterModules()
  1887. {
  1888. var moduleTypes = GetExportTypes<IDependencyModule>();
  1889. foreach (var type in moduleTypes)
  1890. {
  1891. try
  1892. {
  1893. var instance = Activator.CreateInstance(type) as IDependencyModule;
  1894. if (instance != null)
  1895. instance.BindDependencies(this);
  1896. }
  1897. catch (Exception ex)
  1898. {
  1899. Logger.ErrorException("Error setting up dependency bindings for " + type.Name, ex);
  1900. }
  1901. }
  1902. }
  1903. /// <summary>
  1904. /// Called when [application updated].
  1905. /// </summary>
  1906. /// <param name="package">The package.</param>
  1907. protected void OnApplicationUpdated(PackageVersionInfo package)
  1908. {
  1909. Logger.Info("Application has been updated to version {0}", package.versionStr);
  1910. EventHelper.FireEventIfNotNull(ApplicationUpdated, this, new GenericEventArgs<PackageVersionInfo>
  1911. {
  1912. Argument = package
  1913. }, Logger);
  1914. NotifyPendingRestart();
  1915. }
  1916. private bool _disposed;
  1917. /// <summary>
  1918. /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
  1919. /// </summary>
  1920. public void Dispose()
  1921. {
  1922. if (!_disposed)
  1923. {
  1924. _disposed = true;
  1925. Dispose(true);
  1926. }
  1927. }
  1928. /// <summary>
  1929. /// Releases unmanaged and - optionally - managed resources.
  1930. /// </summary>
  1931. /// <param name="dispose"><c>true</c> to release both managed and unmanaged resources; <c>false</c> to release only unmanaged resources.</param>
  1932. protected virtual void Dispose(bool dispose)
  1933. {
  1934. if (dispose)
  1935. {
  1936. var type = GetType();
  1937. Logger.Info("Disposing " + type.Name);
  1938. var parts = DisposableParts.Distinct().Where(i => i.GetType() != type).ToList();
  1939. DisposableParts.Clear();
  1940. foreach (var part in parts)
  1941. {
  1942. Logger.Info("Disposing " + part.GetType().Name);
  1943. try
  1944. {
  1945. part.Dispose();
  1946. }
  1947. catch (Exception ex)
  1948. {
  1949. Logger.ErrorException("Error disposing {0}", ex, part.GetType().Name);
  1950. }
  1951. }
  1952. }
  1953. }
  1954. void IDependencyContainer.RegisterSingleInstance<T>(T obj, bool manageLifetime)
  1955. {
  1956. RegisterSingleInstance(obj, manageLifetime);
  1957. }
  1958. void IDependencyContainer.RegisterSingleInstance<T>(Func<T> func)
  1959. {
  1960. RegisterSingleInstance(func);
  1961. }
  1962. void IDependencyContainer.Register(Type typeInterface, Type typeImplementation)
  1963. {
  1964. Container.Register(typeInterface, typeImplementation);
  1965. }
  1966. }
  1967. internal class CertificateInfo
  1968. {
  1969. public string Path { get; set; }
  1970. public string Password { get; set; }
  1971. }
  1972. }