ApplicationHost.cs 76 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789
  1. using MediaBrowser.Api;
  2. using MediaBrowser.Common;
  3. using MediaBrowser.Common.Configuration;
  4. using MediaBrowser.Common.Events;
  5. using MediaBrowser.Common.Extensions;
  6. using Emby.Common.Implementations.ScheduledTasks;
  7. using MediaBrowser.Common.Net;
  8. using MediaBrowser.Common.Progress;
  9. using MediaBrowser.Controller;
  10. using MediaBrowser.Controller.Channels;
  11. using MediaBrowser.Controller.Chapters;
  12. using MediaBrowser.Controller.Collections;
  13. using MediaBrowser.Controller.Configuration;
  14. using MediaBrowser.Controller.Connect;
  15. using MediaBrowser.Controller.Devices;
  16. using MediaBrowser.Controller.Dlna;
  17. using MediaBrowser.Controller.Drawing;
  18. using MediaBrowser.Controller.Dto;
  19. using MediaBrowser.Controller.Entities;
  20. using MediaBrowser.Controller.FileOrganization;
  21. using MediaBrowser.Controller.Library;
  22. using MediaBrowser.Controller.LiveTv;
  23. using MediaBrowser.Controller.MediaEncoding;
  24. using MediaBrowser.Controller.Net;
  25. using MediaBrowser.Controller.Notifications;
  26. using MediaBrowser.Controller.Persistence;
  27. using MediaBrowser.Controller.Playlists;
  28. using MediaBrowser.Controller.Plugins;
  29. using MediaBrowser.Controller.Providers;
  30. using MediaBrowser.Controller.Resolvers;
  31. using MediaBrowser.Controller.Security;
  32. using MediaBrowser.Controller.Session;
  33. using MediaBrowser.Controller.Sorting;
  34. using MediaBrowser.Controller.Subtitles;
  35. using MediaBrowser.Controller.Sync;
  36. using MediaBrowser.Controller.TV;
  37. using MediaBrowser.LocalMetadata.Savers;
  38. using MediaBrowser.MediaEncoding.BdInfo;
  39. using MediaBrowser.MediaEncoding.Encoder;
  40. using MediaBrowser.MediaEncoding.Subtitles;
  41. using MediaBrowser.Model.Logging;
  42. using MediaBrowser.Model.MediaInfo;
  43. using MediaBrowser.Model.System;
  44. using MediaBrowser.Model.Updates;
  45. using MediaBrowser.Providers.Chapters;
  46. using MediaBrowser.Providers.Manager;
  47. using MediaBrowser.Providers.Subtitles;
  48. using MediaBrowser.WebDashboard.Api;
  49. using MediaBrowser.XbmcMetadata.Providers;
  50. using System;
  51. using System.Collections.Concurrent;
  52. using System.Collections.Generic;
  53. using System.Globalization;
  54. using System.IO;
  55. using System.Linq;
  56. using System.Net;
  57. using System.Net.Sockets;
  58. using System.Reflection;
  59. using System.Security.Cryptography.X509Certificates;
  60. using System.Threading;
  61. using System.Threading.Tasks;
  62. using Emby.Common.Implementations;
  63. using Emby.Common.Implementations.Archiving;
  64. using Emby.Common.Implementations.IO;
  65. using Emby.Common.Implementations.Reflection;
  66. using Emby.Common.Implementations.Serialization;
  67. using Emby.Common.Implementations.TextEncoding;
  68. using Emby.Common.Implementations.Xml;
  69. using Emby.Photos;
  70. using MediaBrowser.Model.IO;
  71. using MediaBrowser.Api.Playback;
  72. using MediaBrowser.Common.Plugins;
  73. using MediaBrowser.Common.Security;
  74. using MediaBrowser.Common.Updates;
  75. using MediaBrowser.Controller.Entities.Audio;
  76. using MediaBrowser.Controller.Entities.Movies;
  77. using MediaBrowser.Controller.Entities.TV;
  78. using Emby.Dlna;
  79. using Emby.Dlna.ConnectionManager;
  80. using Emby.Dlna.ContentDirectory;
  81. using Emby.Dlna.Main;
  82. using Emby.Dlna.MediaReceiverRegistrar;
  83. using Emby.Dlna.Ssdp;
  84. using Emby.Server.Core;
  85. using Emby.Server.Implementations.Activity;
  86. using Emby.Server.Implementations.Devices;
  87. using Emby.Server.Implementations.FFMpeg;
  88. using Emby.Server.Core.IO;
  89. using Emby.Server.Core.Localization;
  90. using Emby.Server.Implementations.Migrations;
  91. using Emby.Server.Implementations.Security;
  92. using Emby.Server.Implementations.Social;
  93. using Emby.Server.Implementations.Channels;
  94. using Emby.Server.Implementations.Collections;
  95. using Emby.Server.Implementations.Dto;
  96. using Emby.Server.Implementations.IO;
  97. using Emby.Server.Implementations.FileOrganization;
  98. using Emby.Server.Implementations.HttpServer;
  99. using Emby.Server.Implementations.HttpServer.Security;
  100. using Emby.Server.Implementations.Library;
  101. using Emby.Server.Implementations.LiveTv;
  102. using Emby.Server.Implementations.Localization;
  103. using Emby.Server.Implementations.MediaEncoder;
  104. using Emby.Server.Implementations.Notifications;
  105. using Emby.Server.Implementations.Data;
  106. using Emby.Server.Implementations.Playlists;
  107. using Emby.Server.Implementations;
  108. using Emby.Server.Implementations.ServerManager;
  109. using Emby.Server.Implementations.Session;
  110. using Emby.Server.Implementations.Windows;
  111. using Emby.Server.Implementations.TV;
  112. using Emby.Server.Implementations.Updates;
  113. using MediaBrowser.Model.Activity;
  114. using MediaBrowser.Model.Configuration;
  115. using MediaBrowser.Model.Dlna;
  116. using MediaBrowser.Model.Globalization;
  117. using MediaBrowser.Model.Net;
  118. using MediaBrowser.Model.News;
  119. using MediaBrowser.Model.Reflection;
  120. using MediaBrowser.Model.Serialization;
  121. using MediaBrowser.Model.Services;
  122. using MediaBrowser.Model.Social;
  123. using MediaBrowser.Model.Text;
  124. using MediaBrowser.Model.Xml;
  125. using OpenSubtitlesHandler;
  126. using ServiceStack;
  127. using SocketHttpListener.Primitives;
  128. using StringExtensions = MediaBrowser.Controller.Extensions.StringExtensions;
  129. using Emby.Drawing;
  130. using Emby.Server.Implementations.Migrations;
  131. using MediaBrowser.Model.Diagnostics;
  132. using Emby.Common.Implementations.Diagnostics;
  133. using Emby.Server.Implementations.Configuration;
  134. namespace Emby.Server.Core
  135. {
  136. /// <summary>
  137. /// Class CompositionRoot
  138. /// </summary>
  139. public abstract class ApplicationHost : BaseApplicationHost<ServerApplicationPaths>, IServerApplicationHost, IDependencyContainer
  140. {
  141. /// <summary>
  142. /// Gets the server configuration manager.
  143. /// </summary>
  144. /// <value>The server configuration manager.</value>
  145. public IServerConfigurationManager ServerConfigurationManager
  146. {
  147. get { return (IServerConfigurationManager)ConfigurationManager; }
  148. }
  149. /// <summary>
  150. /// Gets the configuration manager.
  151. /// </summary>
  152. /// <returns>IConfigurationManager.</returns>
  153. protected override IConfigurationManager GetConfigurationManager()
  154. {
  155. return new ServerConfigurationManager(ApplicationPaths, LogManager, XmlSerializer, FileSystemManager);
  156. }
  157. /// <summary>
  158. /// Gets or sets the server manager.
  159. /// </summary>
  160. /// <value>The server manager.</value>
  161. private IServerManager ServerManager { get; set; }
  162. /// <summary>
  163. /// Gets or sets the user manager.
  164. /// </summary>
  165. /// <value>The user manager.</value>
  166. public IUserManager UserManager { get; set; }
  167. /// <summary>
  168. /// Gets or sets the library manager.
  169. /// </summary>
  170. /// <value>The library manager.</value>
  171. internal ILibraryManager LibraryManager { get; set; }
  172. /// <summary>
  173. /// Gets or sets the directory watchers.
  174. /// </summary>
  175. /// <value>The directory watchers.</value>
  176. private ILibraryMonitor LibraryMonitor { get; set; }
  177. /// <summary>
  178. /// Gets or sets the provider manager.
  179. /// </summary>
  180. /// <value>The provider manager.</value>
  181. private IProviderManager ProviderManager { get; set; }
  182. /// <summary>
  183. /// Gets or sets the HTTP server.
  184. /// </summary>
  185. /// <value>The HTTP server.</value>
  186. private IHttpServer HttpServer { get; set; }
  187. private IDtoService DtoService { get; set; }
  188. private IImageProcessor ImageProcessor { get; set; }
  189. /// <summary>
  190. /// Gets or sets the media encoder.
  191. /// </summary>
  192. /// <value>The media encoder.</value>
  193. private IMediaEncoder MediaEncoder { get; set; }
  194. private ISubtitleEncoder SubtitleEncoder { get; set; }
  195. private IConnectManager ConnectManager { get; set; }
  196. private ISessionManager SessionManager { get; set; }
  197. private ILiveTvManager LiveTvManager { get; set; }
  198. public ILocalizationManager LocalizationManager { get; set; }
  199. private IEncodingManager EncodingManager { get; set; }
  200. private IChannelManager ChannelManager { get; set; }
  201. private ISyncManager SyncManager { get; set; }
  202. /// <summary>
  203. /// Gets or sets the user data repository.
  204. /// </summary>
  205. /// <value>The user data repository.</value>
  206. private IUserDataManager UserDataManager { get; set; }
  207. private IUserRepository UserRepository { get; set; }
  208. internal IDisplayPreferencesRepository DisplayPreferencesRepository { get; set; }
  209. internal IItemRepository ItemRepository { get; set; }
  210. private INotificationsRepository NotificationsRepository { get; set; }
  211. private IFileOrganizationRepository FileOrganizationRepository { get; set; }
  212. private INotificationManager NotificationManager { get; set; }
  213. private ISubtitleManager SubtitleManager { get; set; }
  214. private IChapterManager ChapterManager { get; set; }
  215. private IDeviceManager DeviceManager { get; set; }
  216. internal IUserViewManager UserViewManager { get; set; }
  217. private IAuthenticationRepository AuthenticationRepository { get; set; }
  218. private ISyncRepository SyncRepository { get; set; }
  219. private ITVSeriesManager TVSeriesManager { get; set; }
  220. private ICollectionManager CollectionManager { get; set; }
  221. private IMediaSourceManager MediaSourceManager { get; set; }
  222. private IPlaylistManager PlaylistManager { get; set; }
  223. /// <summary>
  224. /// Gets or sets the installation manager.
  225. /// </summary>
  226. /// <value>The installation manager.</value>
  227. protected IInstallationManager InstallationManager { get; private set; }
  228. /// <summary>
  229. /// Gets the security manager.
  230. /// </summary>
  231. /// <value>The security manager.</value>
  232. protected ISecurityManager SecurityManager { get; private set; }
  233. /// <summary>
  234. /// Gets or sets the zip client.
  235. /// </summary>
  236. /// <value>The zip client.</value>
  237. protected IZipClient ZipClient { get; private set; }
  238. protected IAuthService AuthService { get; private set; }
  239. protected readonly StartupOptions StartupOptions;
  240. private readonly string _releaseAssetFilename;
  241. internal IPowerManagement PowerManagement { get; private set; }
  242. internal IImageEncoder ImageEncoder { get; private set; }
  243. private readonly Action<string, string> _certificateGenerator;
  244. private readonly Func<string> _defaultUserNameFactory;
  245. /// <summary>
  246. /// Initializes a new instance of the <see cref="ApplicationHost" /> class.
  247. /// </summary>
  248. public ApplicationHost(ServerApplicationPaths applicationPaths,
  249. ILogManager logManager,
  250. StartupOptions options,
  251. IFileSystem fileSystem,
  252. IPowerManagement powerManagement,
  253. string releaseAssetFilename,
  254. IEnvironmentInfo environmentInfo,
  255. IImageEncoder imageEncoder,
  256. ISystemEvents systemEvents,
  257. IMemoryStreamFactory memoryStreamFactory,
  258. INetworkManager networkManager,
  259. Action<string, string> certificateGenerator,
  260. Func<string> defaultUsernameFactory)
  261. : base(applicationPaths,
  262. logManager,
  263. fileSystem,
  264. environmentInfo,
  265. systemEvents,
  266. memoryStreamFactory,
  267. networkManager)
  268. {
  269. StartupOptions = options;
  270. _certificateGenerator = certificateGenerator;
  271. _releaseAssetFilename = releaseAssetFilename;
  272. _defaultUserNameFactory = defaultUsernameFactory;
  273. PowerManagement = powerManagement;
  274. ImageEncoder = imageEncoder;
  275. SetBaseExceptionMessage();
  276. if (environmentInfo.OperatingSystem == MediaBrowser.Model.System.OperatingSystem.Windows)
  277. {
  278. fileSystem.AddShortcutHandler(new LnkShortcutHandler());
  279. }
  280. fileSystem.AddShortcutHandler(new MbLinkShortcutHandler(fileSystem));
  281. }
  282. private Version _version;
  283. /// <summary>
  284. /// Gets the current application version
  285. /// </summary>
  286. /// <value>The application version.</value>
  287. public override Version ApplicationVersion
  288. {
  289. get
  290. {
  291. return _version ?? (_version = GetAssembly(GetType()).GetName().Version);
  292. }
  293. }
  294. public virtual bool SupportsRunningAsService
  295. {
  296. get
  297. {
  298. return false;
  299. }
  300. }
  301. /// <summary>
  302. /// Gets the name.
  303. /// </summary>
  304. /// <value>The name.</value>
  305. public override string Name
  306. {
  307. get
  308. {
  309. return "Emby Server";
  310. }
  311. }
  312. public virtual bool IsRunningAsService
  313. {
  314. get
  315. {
  316. return false;
  317. }
  318. }
  319. private Assembly GetAssembly(Type type)
  320. {
  321. return type.GetTypeInfo().Assembly;
  322. }
  323. public virtual bool SupportsAutoRunAtStartup
  324. {
  325. get
  326. {
  327. return EnvironmentInfo.OperatingSystem == MediaBrowser.Model.System.OperatingSystem.Windows;
  328. }
  329. }
  330. private void SetBaseExceptionMessage()
  331. {
  332. var builder = GetBaseExceptionMessage(ApplicationPaths);
  333. // Skip if plugins haven't been loaded yet
  334. //if (Plugins != null)
  335. //{
  336. // var pluginString = string.Join("|", Plugins.Select(i => i.Name + "-" + i.Version.ToString()).ToArray());
  337. // builder.Insert(0, string.Format("Plugins: {0}{1}", pluginString, Environment.NewLine));
  338. //}
  339. builder.Insert(0, string.Format("Version: {0}{1}", ApplicationVersion, Environment.NewLine));
  340. builder.Insert(0, "*** Error Report ***" + Environment.NewLine);
  341. LogManager.ExceptionMessagePrefix = builder.ToString();
  342. }
  343. /// <summary>
  344. /// Runs the startup tasks.
  345. /// </summary>
  346. public override async Task RunStartupTasks()
  347. {
  348. await PerformPreInitMigrations().ConfigureAwait(false);
  349. await base.RunStartupTasks().ConfigureAwait(false);
  350. await MediaEncoder.Init().ConfigureAwait(false);
  351. if (string.IsNullOrWhiteSpace(MediaEncoder.EncoderPath))
  352. {
  353. if (ServerConfigurationManager.Configuration.IsStartupWizardCompleted)
  354. {
  355. ServerConfigurationManager.Configuration.IsStartupWizardCompleted = false;
  356. ServerConfigurationManager.SaveConfiguration();
  357. }
  358. }
  359. Logger.Info("ServerId: {0}", SystemId);
  360. Logger.Info("Core startup complete");
  361. HttpServer.GlobalResponse = null;
  362. PerformPostInitMigrations();
  363. Logger.Info("Post-init migrations complete");
  364. foreach (var entryPoint in GetExports<IServerEntryPoint>().ToList())
  365. {
  366. var name = entryPoint.GetType().FullName;
  367. Logger.Info("Starting entry point {0}", name);
  368. var now = DateTime.UtcNow;
  369. try
  370. {
  371. entryPoint.Run();
  372. }
  373. catch (Exception ex)
  374. {
  375. Logger.ErrorException("Error in {0}", ex, name);
  376. }
  377. Logger.Info("Entry point completed: {0}. Duration: {1} seconds", name, (DateTime.UtcNow - now).TotalSeconds.ToString(CultureInfo.InvariantCulture));
  378. }
  379. Logger.Info("All entry points have started");
  380. LogManager.RemoveConsoleOutput();
  381. }
  382. protected override IJsonSerializer CreateJsonSerializer()
  383. {
  384. try
  385. {
  386. // https://github.com/ServiceStack/ServiceStack/blob/master/tests/ServiceStack.WebHost.IntegrationTests/Web.config#L4
  387. Licensing.RegisterLicense("1001-e1JlZjoxMDAxLE5hbWU6VGVzdCBCdXNpbmVzcyxUeXBlOkJ1c2luZXNzLEhhc2g6UHVNTVRPclhvT2ZIbjQ5MG5LZE1mUTd5RUMzQnBucTFEbTE3TDczVEF4QUNMT1FhNXJMOWkzVjFGL2ZkVTE3Q2pDNENqTkQyUktRWmhvUVBhYTBiekJGUUZ3ZE5aZHFDYm9hL3lydGlwUHI5K1JsaTBYbzNsUC85cjVJNHE5QVhldDN6QkE4aTlvdldrdTgyTk1relY2eis2dFFqTThYN2lmc0JveHgycFdjPSxFeHBpcnk6MjAxMy0wMS0wMX0=");
  388. }
  389. catch
  390. {
  391. // Failing under mono
  392. }
  393. var result = new JsonSerializer(FileSystemManager, LogManager.GetLogger("JsonSerializer"));
  394. ServiceStack.Text.JsConfig<LiveTvProgram>.ExcludePropertyNames = new[] { "ProviderIds", "ImageInfos", "ProductionLocations", "ThemeSongIds", "ThemeVideoIds", "TotalBitrate", "Taglines", "Keywords", "ExtraType" };
  395. ServiceStack.Text.JsConfig<LiveTvChannel>.ExcludePropertyNames = new[] { "ProviderIds", "ImageInfos", "ProductionLocations", "ThemeSongIds", "ThemeVideoIds", "TotalBitrate", "Taglines", "Keywords", "ExtraType" };
  396. ServiceStack.Text.JsConfig<LiveTvVideoRecording>.ExcludePropertyNames = new[] { "ProviderIds", "ImageInfos", "ProductionLocations", "ThemeSongIds", "ThemeVideoIds", "TotalBitrate", "Taglines", "Keywords", "ExtraType" };
  397. ServiceStack.Text.JsConfig<LiveTvAudioRecording>.ExcludePropertyNames = new[] { "Artists", "AlbumArtists", "ChannelMediaSources", "ProviderIds", "ImageInfos", "ProductionLocations", "ThemeSongIds", "ThemeVideoIds", "TotalBitrate", "Taglines", "Keywords", "ExtraType" };
  398. ServiceStack.Text.JsConfig<Series>.ExcludePropertyNames = new[] { "ProviderIds", "ImageInfos", "ProductionLocations", "ThemeSongIds", "ThemeVideoIds", "TotalBitrate", "Taglines", "Keywords", "ExtraType" };
  399. ServiceStack.Text.JsConfig<Audio>.ExcludePropertyNames = new[] { "Artists", "AlbumArtists", "ChannelMediaSources", "ProviderIds", "ImageInfos", "ProductionLocations", "ThemeSongIds", "ThemeVideoIds", "TotalBitrate", "Taglines", "Keywords", "ExtraType" };
  400. ServiceStack.Text.JsConfig<MusicAlbum>.ExcludePropertyNames = new[] { "Artists", "AlbumArtists", "ProviderIds", "ImageInfos", "ProductionLocations", "ThemeSongIds", "ThemeVideoIds", "TotalBitrate", "Taglines", "Keywords", "ExtraType" };
  401. ServiceStack.Text.JsConfig<MusicArtist>.ExcludePropertyNames = new[] { "ProviderIds", "ImageInfos", "ProductionLocations", "ThemeSongIds", "ThemeVideoIds", "TotalBitrate", "Taglines", "Keywords", "ExtraType" };
  402. ServiceStack.Text.JsConfig<MusicGenre>.ExcludePropertyNames = new[] { "ProviderIds", "ImageInfos", "ProductionLocations", "ThemeSongIds", "ThemeVideoIds", "TotalBitrate", "Taglines", "Keywords", "ExtraType" };
  403. ServiceStack.Text.JsConfig<MusicVideo>.ExcludePropertyNames = new[] { "Artists", "AlbumArtists", "ProviderIds", "ImageInfos", "ProductionLocations", "ThemeSongIds", "ThemeVideoIds", "TotalBitrate", "Taglines", "Keywords", "ExtraType" };
  404. ServiceStack.Text.JsConfig<Movie>.ExcludePropertyNames = new[] { "ProviderIds", "ImageInfos", "ProductionLocations", "ThemeSongIds", "ThemeVideoIds", "TotalBitrate", "Taglines", "Keywords", "ExtraType" };
  405. ServiceStack.Text.JsConfig<Playlist>.ExcludePropertyNames = new[] { "ProviderIds", "ImageInfos", "ProductionLocations", "ThemeSongIds", "ThemeVideoIds", "TotalBitrate", "Taglines", "Keywords", "ExtraType" };
  406. ServiceStack.Text.JsConfig<AudioPodcast>.ExcludePropertyNames = new[] { "Artists", "AlbumArtists", "ChannelMediaSources", "ProviderIds", "ImageInfos", "ProductionLocations", "ThemeSongIds", "ThemeVideoIds", "TotalBitrate", "Taglines", "Keywords", "ExtraType" };
  407. ServiceStack.Text.JsConfig<AudioBook>.ExcludePropertyNames = new[] { "Artists", "AlbumArtists", "ChannelMediaSources", "ProviderIds", "ImageInfos", "ProductionLocations", "ThemeSongIds", "ThemeVideoIds", "TotalBitrate", "Taglines", "Keywords", "ExtraType" };
  408. ServiceStack.Text.JsConfig<Trailer>.ExcludePropertyNames = new[] { "ProviderIds", "ImageInfos", "ProductionLocations", "ThemeSongIds", "ThemeVideoIds", "TotalBitrate", "Taglines", "Keywords", "ExtraType" };
  409. ServiceStack.Text.JsConfig<BoxSet>.ExcludePropertyNames = new[] { "ProviderIds", "ImageInfos", "ProductionLocations", "ThemeSongIds", "ThemeVideoIds", "TotalBitrate", "Taglines", "Keywords", "ExtraType" };
  410. ServiceStack.Text.JsConfig<Episode>.ExcludePropertyNames = new[] { "ProviderIds", "ImageInfos", "ProductionLocations", "ThemeSongIds", "ThemeVideoIds", "TotalBitrate", "Taglines", "Keywords", "ExtraType" };
  411. ServiceStack.Text.JsConfig<Season>.ExcludePropertyNames = new[] { "ProviderIds", "ImageInfos", "ProductionLocations", "ThemeSongIds", "ThemeVideoIds", "TotalBitrate", "Taglines", "Keywords", "ExtraType" };
  412. ServiceStack.Text.JsConfig<Book>.ExcludePropertyNames = new[] { "ProviderIds", "ImageInfos", "ProductionLocations", "ThemeSongIds", "ThemeVideoIds", "TotalBitrate", "Taglines", "Keywords", "ExtraType" };
  413. ServiceStack.Text.JsConfig<CollectionFolder>.ExcludePropertyNames = new[] { "ProviderIds", "ImageInfos", "ProductionLocations", "ThemeSongIds", "ThemeVideoIds", "TotalBitrate", "Taglines", "Keywords", "ExtraType" };
  414. ServiceStack.Text.JsConfig<Folder>.ExcludePropertyNames = new[] { "ProviderIds", "ImageInfos", "ProductionLocations", "ThemeSongIds", "ThemeVideoIds", "TotalBitrate", "Taglines", "Keywords", "ExtraType" };
  415. ServiceStack.Text.JsConfig<Game>.ExcludePropertyNames = new[] { "ProviderIds", "ImageInfos", "ProductionLocations", "ThemeSongIds", "ThemeVideoIds", "TotalBitrate", "Taglines", "Keywords", "ExtraType" };
  416. ServiceStack.Text.JsConfig<GameGenre>.ExcludePropertyNames = new[] { "ProviderIds", "ImageInfos", "ProductionLocations", "ThemeSongIds", "ThemeVideoIds", "TotalBitrate", "Taglines", "Keywords", "ExtraType" };
  417. ServiceStack.Text.JsConfig<GameSystem>.ExcludePropertyNames = new[] { "ProviderIds", "ImageInfos", "ProductionLocations", "ThemeSongIds", "ThemeVideoIds", "TotalBitrate", "Taglines", "Keywords", "ExtraType" };
  418. ServiceStack.Text.JsConfig<Genre>.ExcludePropertyNames = new[] { "ProviderIds", "ImageInfos", "ProductionLocations", "ThemeSongIds", "ThemeVideoIds", "TotalBitrate", "Taglines", "Keywords", "ExtraType" };
  419. ServiceStack.Text.JsConfig<Person>.ExcludePropertyNames = new[] { "PlaceOfBirth", "ProviderIds", "ImageInfos", "ProductionLocations", "ThemeSongIds", "ThemeVideoIds", "TotalBitrate", "Taglines", "Keywords", "ExtraType" };
  420. ServiceStack.Text.JsConfig<Photo>.ExcludePropertyNames = new[] { "ProviderIds", "ImageInfos", "ProductionLocations", "ThemeSongIds", "ThemeVideoIds", "TotalBitrate", "Taglines", "Keywords", "ExtraType" };
  421. ServiceStack.Text.JsConfig<PhotoAlbum>.ExcludePropertyNames = new[] { "ProviderIds", "ImageInfos", "ProductionLocations", "ThemeSongIds", "ThemeVideoIds", "TotalBitrate", "Taglines", "Keywords", "ExtraType" };
  422. ServiceStack.Text.JsConfig<Studio>.ExcludePropertyNames = new[] { "ProviderIds", "ImageInfos", "ProductionLocations", "ThemeSongIds", "ThemeVideoIds", "TotalBitrate", "Taglines", "Keywords", "ExtraType" };
  423. ServiceStack.Text.JsConfig<UserRootFolder>.ExcludePropertyNames = new[] { "ProviderIds", "ImageInfos", "ProductionLocations", "ThemeSongIds", "ThemeVideoIds", "TotalBitrate", "Taglines", "Keywords", "ExtraType" };
  424. ServiceStack.Text.JsConfig<UserView>.ExcludePropertyNames = new[] { "ProviderIds", "ImageInfos", "ProductionLocations", "ThemeSongIds", "ThemeVideoIds", "TotalBitrate", "Taglines", "Keywords", "ExtraType" };
  425. ServiceStack.Text.JsConfig<Video>.ExcludePropertyNames = new[] { "ProviderIds", "ImageInfos", "ProductionLocations", "ThemeSongIds", "ThemeVideoIds", "TotalBitrate", "Taglines", "Keywords", "ExtraType" };
  426. ServiceStack.Text.JsConfig<Year>.ExcludePropertyNames = new[] { "ProviderIds", "ImageInfos", "ProductionLocations", "ThemeSongIds", "ThemeVideoIds", "TotalBitrate", "Taglines", "Keywords", "ExtraType" };
  427. ServiceStack.Text.JsConfig<Channel>.ExcludePropertyNames = new[] { "ProviderIds", "ImageInfos", "ProductionLocations", "ThemeSongIds", "ThemeVideoIds", "TotalBitrate", "Taglines", "Keywords", "ExtraType" };
  428. ServiceStack.Text.JsConfig<AggregateFolder>.ExcludePropertyNames = new[] { "ProviderIds", "ImageInfos", "ProductionLocations", "ThemeSongIds", "ThemeVideoIds", "TotalBitrate", "Taglines", "Keywords", "ExtraType" };
  429. return result;
  430. }
  431. public override Task Init(IProgress<double> progress)
  432. {
  433. HttpPort = ServerConfigurationManager.Configuration.HttpServerPortNumber;
  434. HttpsPort = ServerConfigurationManager.Configuration.HttpsPortNumber;
  435. // Safeguard against invalid configuration
  436. if (HttpPort == HttpsPort)
  437. {
  438. HttpPort = ServerConfiguration.DefaultHttpPort;
  439. HttpsPort = ServerConfiguration.DefaultHttpsPort;
  440. }
  441. return base.Init(progress);
  442. }
  443. private async Task PerformPreInitMigrations()
  444. {
  445. var migrations = new List<IVersionMigration>
  446. {
  447. new UpdateLevelMigration(ServerConfigurationManager, this, HttpClient, JsonSerializer, _releaseAssetFilename, Logger)
  448. };
  449. foreach (var task in migrations)
  450. {
  451. try
  452. {
  453. await task.Run().ConfigureAwait(false);
  454. }
  455. catch (Exception ex)
  456. {
  457. Logger.ErrorException("Error running migration", ex);
  458. }
  459. }
  460. }
  461. private void PerformPostInitMigrations()
  462. {
  463. var migrations = new List<IVersionMigration>
  464. {
  465. new LibraryScanMigration(ServerConfigurationManager, TaskManager),
  466. new GuideMigration(ServerConfigurationManager, TaskManager)
  467. };
  468. foreach (var task in migrations)
  469. {
  470. try
  471. {
  472. task.Run();
  473. }
  474. catch (Exception ex)
  475. {
  476. Logger.ErrorException("Error running migration", ex);
  477. }
  478. }
  479. }
  480. protected abstract IConnectManager CreateConnectManager();
  481. protected abstract ISyncManager CreateSyncManager();
  482. /// <summary>
  483. /// Registers resources that classes will depend on
  484. /// </summary>
  485. protected override async Task RegisterResources(IProgress<double> progress)
  486. {
  487. await base.RegisterResources(progress).ConfigureAwait(false);
  488. RegisterSingleInstance(PowerManagement);
  489. SecurityManager = new PluginSecurityManager(this, HttpClient, JsonSerializer, ApplicationPaths, LogManager, FileSystemManager, CryptographyProvider);
  490. RegisterSingleInstance(SecurityManager);
  491. InstallationManager = new InstallationManager(LogManager.GetLogger("InstallationManager"), this, ApplicationPaths, HttpClient, JsonSerializer, SecurityManager, ConfigurationManager, FileSystemManager, CryptographyProvider);
  492. RegisterSingleInstance(InstallationManager);
  493. ZipClient = new ZipClient(FileSystemManager);
  494. RegisterSingleInstance(ZipClient);
  495. RegisterSingleInstance<IHttpResultFactory>(new HttpResultFactory(LogManager, FileSystemManager, JsonSerializer, MemoryStreamFactory));
  496. RegisterSingleInstance<IServerApplicationHost>(this);
  497. RegisterSingleInstance<IServerApplicationPaths>(ApplicationPaths);
  498. RegisterSingleInstance(ServerConfigurationManager);
  499. IAssemblyInfo assemblyInfo = new AssemblyInfo();
  500. RegisterSingleInstance<IAssemblyInfo>(assemblyInfo);
  501. LocalizationManager = new LocalizationManager(ServerConfigurationManager, FileSystemManager, JsonSerializer, LogManager.GetLogger("LocalizationManager"), assemblyInfo, new TextLocalizer());
  502. StringExtensions.LocalizationManager = LocalizationManager;
  503. RegisterSingleInstance(LocalizationManager);
  504. ITextEncoding textEncoding = new TextEncoding(FileSystemManager);
  505. RegisterSingleInstance(textEncoding);
  506. Utilities.EncodingHelper = textEncoding;
  507. RegisterSingleInstance<IBlurayExaminer>(() => new BdInfoExaminer(FileSystemManager, textEncoding));
  508. RegisterSingleInstance<IXmlReaderSettingsFactory>(new XmlReaderSettingsFactory());
  509. UserDataManager = new UserDataManager(LogManager, ServerConfigurationManager);
  510. RegisterSingleInstance(UserDataManager);
  511. UserRepository = GetUserRepository();
  512. // This is only needed for disposal purposes. If removing this, make sure to have the manager handle disposing it
  513. RegisterSingleInstance(UserRepository);
  514. var displayPreferencesRepo = new SqliteDisplayPreferencesRepository(LogManager.GetLogger("SqliteDisplayPreferencesRepository"), JsonSerializer, ApplicationPaths, MemoryStreamFactory);
  515. DisplayPreferencesRepository = displayPreferencesRepo;
  516. RegisterSingleInstance(DisplayPreferencesRepository);
  517. var itemRepo = new SqliteItemRepository(ServerConfigurationManager, JsonSerializer, LogManager.GetLogger("SqliteItemRepository"), MemoryStreamFactory, assemblyInfo, FileSystemManager, EnvironmentInfo, TimerFactory);
  518. ItemRepository = itemRepo;
  519. RegisterSingleInstance(ItemRepository);
  520. FileOrganizationRepository = GetFileOrganizationRepository();
  521. RegisterSingleInstance(FileOrganizationRepository);
  522. AuthenticationRepository = await GetAuthenticationRepository().ConfigureAwait(false);
  523. RegisterSingleInstance(AuthenticationRepository);
  524. UserManager = new UserManager(LogManager.GetLogger("UserManager"), ServerConfigurationManager, UserRepository, XmlSerializer, NetworkManager, () => ImageProcessor, () => DtoService, () => ConnectManager, this, JsonSerializer, FileSystemManager, CryptographyProvider, _defaultUserNameFactory());
  525. RegisterSingleInstance(UserManager);
  526. LibraryManager = new LibraryManager(Logger, TaskManager, UserManager, ServerConfigurationManager, UserDataManager, () => LibraryMonitor, FileSystemManager, () => ProviderManager, () => UserViewManager);
  527. RegisterSingleInstance(LibraryManager);
  528. var musicManager = new MusicManager(LibraryManager);
  529. RegisterSingleInstance<IMusicManager>(new MusicManager(LibraryManager));
  530. LibraryMonitor = new LibraryMonitor(LogManager, TaskManager, LibraryManager, ServerConfigurationManager, FileSystemManager, TimerFactory, SystemEvents, EnvironmentInfo);
  531. RegisterSingleInstance(LibraryMonitor);
  532. ProviderManager = new ProviderManager(HttpClient, ServerConfigurationManager, LibraryMonitor, LogManager, FileSystemManager, ApplicationPaths, () => LibraryManager, JsonSerializer, MemoryStreamFactory);
  533. RegisterSingleInstance(ProviderManager);
  534. RegisterSingleInstance<ISearchEngine>(() => new SearchEngine(LogManager, LibraryManager, UserManager));
  535. CertificatePath = GetCertificatePath(true);
  536. Certificate = GetCertificate(CertificatePath);
  537. HttpServer = HttpServerFactory.CreateServer(this, LogManager, ServerConfigurationManager, NetworkManager, MemoryStreamFactory, "Emby", "web/index.html", textEncoding, SocketFactory, CryptographyProvider, JsonSerializer, XmlSerializer, EnvironmentInfo, Certificate, FileSystemManager, SupportsDualModeSockets);
  538. HttpServer.GlobalResponse = LocalizationManager.GetLocalizedString("StartupEmbyServerIsLoading");
  539. RegisterSingleInstance(HttpServer, false);
  540. progress.Report(10);
  541. ServerManager = new ServerManager(this, JsonSerializer, LogManager.GetLogger("ServerManager"), ServerConfigurationManager, MemoryStreamFactory, textEncoding);
  542. RegisterSingleInstance(ServerManager);
  543. var innerProgress = new ActionableProgress<double>();
  544. innerProgress.RegisterAction(p => progress.Report((.75 * p) + 15));
  545. ImageProcessor = GetImageProcessor();
  546. RegisterSingleInstance(ImageProcessor);
  547. TVSeriesManager = new TVSeriesManager(UserManager, UserDataManager, LibraryManager, ServerConfigurationManager);
  548. RegisterSingleInstance(TVSeriesManager);
  549. SyncManager = CreateSyncManager();
  550. RegisterSingleInstance(SyncManager);
  551. DtoService = new DtoService(LogManager.GetLogger("DtoService"), LibraryManager, UserDataManager, ItemRepository, ImageProcessor, ServerConfigurationManager, FileSystemManager, ProviderManager, () => ChannelManager, SyncManager, this, () => DeviceManager, () => MediaSourceManager, () => LiveTvManager);
  552. RegisterSingleInstance(DtoService);
  553. var encryptionManager = new EncryptionManager();
  554. RegisterSingleInstance<IEncryptionManager>(encryptionManager);
  555. ConnectManager = CreateConnectManager();
  556. RegisterSingleInstance(ConnectManager);
  557. DeviceManager = new DeviceManager(new DeviceRepository(ApplicationPaths, JsonSerializer, LogManager.GetLogger("DeviceManager"), FileSystemManager), UserManager, FileSystemManager, LibraryMonitor, ServerConfigurationManager, LogManager.GetLogger("DeviceManager"), NetworkManager);
  558. RegisterSingleInstance(DeviceManager);
  559. var newsService = new Emby.Server.Implementations.News.NewsService(ApplicationPaths, JsonSerializer);
  560. RegisterSingleInstance<INewsService>(newsService);
  561. var fileOrganizationService = new FileOrganizationService(TaskManager, FileOrganizationRepository, LogManager.GetLogger("FileOrganizationService"), LibraryMonitor, LibraryManager, ServerConfigurationManager, FileSystemManager, ProviderManager);
  562. RegisterSingleInstance<IFileOrganizationService>(fileOrganizationService);
  563. progress.Report(15);
  564. ChannelManager = new ChannelManager(UserManager, DtoService, LibraryManager, LogManager.GetLogger("ChannelManager"), ServerConfigurationManager, FileSystemManager, UserDataManager, JsonSerializer, LocalizationManager, HttpClient, ProviderManager);
  565. RegisterSingleInstance(ChannelManager);
  566. MediaSourceManager = new MediaSourceManager(ItemRepository, UserManager, LibraryManager, LogManager.GetLogger("MediaSourceManager"), JsonSerializer, FileSystemManager, UserDataManager, TimerFactory);
  567. RegisterSingleInstance(MediaSourceManager);
  568. SessionManager = new SessionManager(UserDataManager, LogManager.GetLogger("SessionManager"), LibraryManager, UserManager, musicManager, DtoService, ImageProcessor, JsonSerializer, this, HttpClient, AuthenticationRepository, DeviceManager, MediaSourceManager, TimerFactory);
  569. RegisterSingleInstance(SessionManager);
  570. var dlnaManager = new DlnaManager(XmlSerializer, FileSystemManager, ApplicationPaths, LogManager.GetLogger("Dlna"), JsonSerializer, this, assemblyInfo);
  571. RegisterSingleInstance<IDlnaManager>(dlnaManager);
  572. var connectionManager = new ConnectionManager(dlnaManager, ServerConfigurationManager, LogManager.GetLogger("UpnpConnectionManager"), HttpClient, new XmlReaderSettingsFactory());
  573. RegisterSingleInstance<IConnectionManager>(connectionManager);
  574. CollectionManager = new CollectionManager(LibraryManager, FileSystemManager, LibraryMonitor, LogManager.GetLogger("CollectionManager"), ProviderManager);
  575. RegisterSingleInstance(CollectionManager);
  576. PlaylistManager = new PlaylistManager(LibraryManager, FileSystemManager, LibraryMonitor, LogManager.GetLogger("PlaylistManager"), UserManager, ProviderManager);
  577. RegisterSingleInstance<IPlaylistManager>(PlaylistManager);
  578. LiveTvManager = new LiveTvManager(this, ServerConfigurationManager, Logger, ItemRepository, ImageProcessor, UserDataManager, DtoService, UserManager, LibraryManager, TaskManager, LocalizationManager, JsonSerializer, ProviderManager, FileSystemManager, SecurityManager);
  579. RegisterSingleInstance(LiveTvManager);
  580. UserViewManager = new UserViewManager(LibraryManager, LocalizationManager, UserManager, ChannelManager, LiveTvManager, ServerConfigurationManager);
  581. RegisterSingleInstance(UserViewManager);
  582. var contentDirectory = new ContentDirectory(dlnaManager, UserDataManager, ImageProcessor, LibraryManager, ServerConfigurationManager, UserManager, LogManager.GetLogger("UpnpContentDirectory"), HttpClient, LocalizationManager, ChannelManager, MediaSourceManager, UserViewManager, () => MediaEncoder, new XmlReaderSettingsFactory());
  583. RegisterSingleInstance<IContentDirectory>(contentDirectory);
  584. var mediaRegistrar = new MediaReceiverRegistrar(LogManager.GetLogger("MediaReceiverRegistrar"), HttpClient, ServerConfigurationManager, new XmlReaderSettingsFactory());
  585. RegisterSingleInstance<IMediaReceiverRegistrar>(mediaRegistrar);
  586. NotificationManager = new NotificationManager(LogManager, UserManager, ServerConfigurationManager);
  587. RegisterSingleInstance(NotificationManager);
  588. SubtitleManager = new SubtitleManager(LogManager.GetLogger("SubtitleManager"), FileSystemManager, LibraryMonitor, LibraryManager, MediaSourceManager);
  589. RegisterSingleInstance(SubtitleManager);
  590. RegisterSingleInstance<IDeviceDiscovery>(new DeviceDiscovery(LogManager.GetLogger("IDeviceDiscovery"), ServerConfigurationManager, SocketFactory, TimerFactory));
  591. ChapterManager = new ChapterManager(LibraryManager, LogManager.GetLogger("ChapterManager"), ServerConfigurationManager, ItemRepository);
  592. RegisterSingleInstance(ChapterManager);
  593. await RegisterMediaEncoder(innerProgress).ConfigureAwait(false);
  594. progress.Report(90);
  595. EncodingManager = new EncodingManager(FileSystemManager, Logger, MediaEncoder, ChapterManager, LibraryManager);
  596. RegisterSingleInstance(EncodingManager);
  597. var sharingRepo = new SharingRepository(LogManager.GetLogger("SharingRepository"), ApplicationPaths);
  598. sharingRepo.Initialize();
  599. // This is only needed for disposal purposes. If removing this, make sure to have the manager handle disposing it
  600. RegisterSingleInstance<ISharingRepository>(sharingRepo);
  601. RegisterSingleInstance<ISharingManager>(new SharingManager(sharingRepo, ServerConfigurationManager, LibraryManager, this));
  602. var activityLogRepo = GetActivityLogRepository();
  603. RegisterSingleInstance(activityLogRepo);
  604. RegisterSingleInstance<IActivityManager>(new ActivityManager(LogManager.GetLogger("ActivityManager"), activityLogRepo, UserManager));
  605. var authContext = new AuthorizationContext(AuthenticationRepository, ConnectManager);
  606. RegisterSingleInstance<IAuthorizationContext>(authContext);
  607. RegisterSingleInstance<ISessionContext>(new SessionContext(UserManager, authContext, SessionManager));
  608. AuthService = new AuthService(UserManager, authContext, ServerConfigurationManager, ConnectManager, SessionManager, DeviceManager);
  609. RegisterSingleInstance<IAuthService>(AuthService);
  610. SubtitleEncoder = new SubtitleEncoder(LibraryManager, LogManager.GetLogger("SubtitleEncoder"), ApplicationPaths, FileSystemManager, MediaEncoder, JsonSerializer, HttpClient, MediaSourceManager, MemoryStreamFactory, ProcessFactory, textEncoding);
  611. RegisterSingleInstance(SubtitleEncoder);
  612. displayPreferencesRepo.Initialize();
  613. var userDataRepo = new SqliteUserDataRepository(LogManager.GetLogger("SqliteUserDataRepository"), ApplicationPaths, FileSystemManager);
  614. ((UserDataManager)UserDataManager).Repository = userDataRepo;
  615. itemRepo.Initialize(userDataRepo);
  616. ((LibraryManager)LibraryManager).ItemRepository = ItemRepository;
  617. ConfigureNotificationsRepository();
  618. progress.Report(100);
  619. SetStaticProperties();
  620. await ((UserManager)UserManager).Initialize().ConfigureAwait(false);
  621. }
  622. protected virtual bool SupportsDualModeSockets
  623. {
  624. get
  625. {
  626. return true;
  627. }
  628. }
  629. private ICertificate GetCertificate(string certificateLocation)
  630. {
  631. if (string.IsNullOrWhiteSpace(certificateLocation))
  632. {
  633. return null;
  634. }
  635. try
  636. {
  637. if (!FileSystemManager.FileExists(certificateLocation))
  638. {
  639. return null;
  640. }
  641. X509Certificate2 localCert = new X509Certificate2(certificateLocation);
  642. //localCert.PrivateKey = PrivateKey.CreateFromFile(pvk_file).RSA;
  643. if (!localCert.HasPrivateKey)
  644. {
  645. //throw new FileNotFoundException("Secure requested, no private key included", certificateLocation);
  646. return null;
  647. }
  648. return new Certificate(localCert);
  649. }
  650. catch (Exception ex)
  651. {
  652. Logger.ErrorException("Error loading cert from {0}", ex, certificateLocation);
  653. return null;
  654. }
  655. }
  656. private IImageProcessor GetImageProcessor()
  657. {
  658. var maxConcurrentImageProcesses = Math.Max(Environment.ProcessorCount, 4);
  659. if (StartupOptions.ContainsOption("-imagethreads"))
  660. {
  661. int.TryParse(StartupOptions.GetOption("-imagethreads"), NumberStyles.Any, CultureInfo.InvariantCulture, out maxConcurrentImageProcesses);
  662. }
  663. return new ImageProcessor(LogManager.GetLogger("ImageProcessor"), ServerConfigurationManager.ApplicationPaths, FileSystemManager, JsonSerializer, ImageEncoder, maxConcurrentImageProcesses, () => LibraryManager, TimerFactory);
  664. }
  665. protected virtual FFMpegInstallInfo GetFfmpegInstallInfo()
  666. {
  667. var info = new FFMpegInstallInfo();
  668. // Windows builds: http://ffmpeg.zeranoe.com/builds/
  669. // Linux builds: http://johnvansickle.com/ffmpeg/
  670. // OS X builds: http://ffmpegmac.net/
  671. // OS X x64: http://www.evermeet.cx/ffmpeg/
  672. if (EnvironmentInfo.OperatingSystem == MediaBrowser.Model.System.OperatingSystem.Linux)
  673. {
  674. info.FFMpegFilename = "ffmpeg";
  675. info.FFProbeFilename = "ffprobe";
  676. info.ArchiveType = "7z";
  677. info.Version = "20170308";
  678. info.DownloadUrls = GetLinuxDownloadUrls();
  679. }
  680. else if (EnvironmentInfo.OperatingSystem == MediaBrowser.Model.System.OperatingSystem.Windows)
  681. {
  682. info.FFMpegFilename = "ffmpeg.exe";
  683. info.FFProbeFilename = "ffprobe.exe";
  684. info.Version = "20170308";
  685. info.ArchiveType = "7z";
  686. info.DownloadUrls = GetWindowsDownloadUrls();
  687. }
  688. else if (EnvironmentInfo.OperatingSystem == MediaBrowser.Model.System.OperatingSystem.OSX)
  689. {
  690. info.FFMpegFilename = "ffmpeg";
  691. info.FFProbeFilename = "ffprobe";
  692. info.ArchiveType = "7z";
  693. info.Version = "20170308";
  694. info.DownloadUrls = GetMacDownloadUrls();
  695. }
  696. else
  697. {
  698. // No version available - user requirement
  699. info.DownloadUrls = new string[] { };
  700. }
  701. return info;
  702. }
  703. private string[] GetMacDownloadUrls()
  704. {
  705. switch (EnvironmentInfo.SystemArchitecture)
  706. {
  707. case Architecture.X64:
  708. return new[]
  709. {
  710. "https://embydata.com/downloads/ffmpeg/osx/ffmpeg-x64-20170308.7z"
  711. };
  712. }
  713. return new string[] { };
  714. }
  715. private string[] GetWindowsDownloadUrls()
  716. {
  717. switch (EnvironmentInfo.SystemArchitecture)
  718. {
  719. case Architecture.X64:
  720. return new[]
  721. {
  722. "https://embydata.com/downloads/ffmpeg/windows/ffmpeg-20170308-win64.7z"
  723. };
  724. case Architecture.X86:
  725. return new[]
  726. {
  727. "https://embydata.com/downloads/ffmpeg/windows/ffmpeg-20170308-win32.7z"
  728. };
  729. }
  730. return new string[] { };
  731. }
  732. private string[] GetLinuxDownloadUrls()
  733. {
  734. switch (EnvironmentInfo.SystemArchitecture)
  735. {
  736. case Architecture.X64:
  737. return new[]
  738. {
  739. "https://embydata.com/downloads/ffmpeg/linux/ffmpeg-git-20170301-64bit-static.7z"
  740. };
  741. case Architecture.X86:
  742. return new[]
  743. {
  744. "https://embydata.com/downloads/ffmpeg/linux/ffmpeg-git-20170301-32bit-static.7z"
  745. };
  746. }
  747. return new string[] { };
  748. }
  749. /// <summary>
  750. /// Registers the media encoder.
  751. /// </summary>
  752. /// <returns>Task.</returns>
  753. private async Task RegisterMediaEncoder(IProgress<double> progress)
  754. {
  755. string encoderPath = null;
  756. string probePath = null;
  757. var info = await new FFMpegLoader(Logger, ApplicationPaths, HttpClient, ZipClient, FileSystemManager, GetFfmpegInstallInfo())
  758. .GetFFMpegInfo(StartupOptions, progress).ConfigureAwait(false);
  759. encoderPath = info.EncoderPath;
  760. probePath = info.ProbePath;
  761. var hasExternalEncoder = string.Equals(info.Version, "external", StringComparison.OrdinalIgnoreCase);
  762. var mediaEncoder = new MediaEncoder(LogManager.GetLogger("MediaEncoder"),
  763. JsonSerializer,
  764. encoderPath,
  765. probePath,
  766. hasExternalEncoder,
  767. ServerConfigurationManager,
  768. FileSystemManager,
  769. LiveTvManager,
  770. IsoManager,
  771. LibraryManager,
  772. ChannelManager,
  773. SessionManager,
  774. () => SubtitleEncoder,
  775. () => MediaSourceManager,
  776. HttpClient,
  777. ZipClient,
  778. MemoryStreamFactory,
  779. ProcessFactory,
  780. (Environment.ProcessorCount > 2 ? 14000 : 40000),
  781. EnvironmentInfo.OperatingSystem == MediaBrowser.Model.System.OperatingSystem.Windows,
  782. EnvironmentInfo);
  783. MediaEncoder = mediaEncoder;
  784. RegisterSingleInstance(MediaEncoder);
  785. }
  786. /// <summary>
  787. /// Gets the user repository.
  788. /// </summary>
  789. /// <returns>Task{IUserRepository}.</returns>
  790. private IUserRepository GetUserRepository()
  791. {
  792. var repo = new SqliteUserRepository(LogManager.GetLogger("SqliteUserRepository"), ApplicationPaths, JsonSerializer, MemoryStreamFactory);
  793. repo.Initialize();
  794. return repo;
  795. }
  796. /// <summary>
  797. /// Gets the file organization repository.
  798. /// </summary>
  799. /// <returns>Task{IUserRepository}.</returns>
  800. private IFileOrganizationRepository GetFileOrganizationRepository()
  801. {
  802. var repo = new SqliteFileOrganizationRepository(LogManager.GetLogger("SqliteFileOrganizationRepository"), ServerConfigurationManager.ApplicationPaths);
  803. repo.Initialize();
  804. return repo;
  805. }
  806. private async Task<IAuthenticationRepository> GetAuthenticationRepository()
  807. {
  808. var repo = new AuthenticationRepository(LogManager.GetLogger("AuthenticationRepository"), ServerConfigurationManager.ApplicationPaths);
  809. repo.Initialize();
  810. return repo;
  811. }
  812. private IActivityRepository GetActivityLogRepository()
  813. {
  814. var repo = new ActivityRepository(LogManager.GetLogger("ActivityRepository"), ServerConfigurationManager.ApplicationPaths);
  815. repo.Initialize();
  816. return repo;
  817. }
  818. /// <summary>
  819. /// Configures the repositories.
  820. /// </summary>
  821. private void ConfigureNotificationsRepository()
  822. {
  823. var repo = new SqliteNotificationsRepository(LogManager.GetLogger("SqliteNotificationsRepository"), ServerConfigurationManager.ApplicationPaths, FileSystemManager);
  824. repo.Initialize();
  825. NotificationsRepository = repo;
  826. RegisterSingleInstance(NotificationsRepository);
  827. }
  828. /// <summary>
  829. /// Dirty hacks
  830. /// </summary>
  831. private void SetStaticProperties()
  832. {
  833. // For now there's no real way to inject these properly
  834. BaseItem.Logger = LogManager.GetLogger("BaseItem");
  835. BaseItem.ConfigurationManager = ServerConfigurationManager;
  836. BaseItem.LibraryManager = LibraryManager;
  837. BaseItem.ProviderManager = ProviderManager;
  838. BaseItem.LocalizationManager = LocalizationManager;
  839. BaseItem.ItemRepository = ItemRepository;
  840. User.XmlSerializer = XmlSerializer;
  841. User.UserManager = UserManager;
  842. Folder.UserManager = UserManager;
  843. BaseItem.FileSystem = FileSystemManager;
  844. BaseItem.UserDataManager = UserDataManager;
  845. BaseItem.ChannelManager = ChannelManager;
  846. BaseItem.LiveTvManager = LiveTvManager;
  847. Folder.UserViewManager = UserViewManager;
  848. UserView.TVSeriesManager = TVSeriesManager;
  849. UserView.PlaylistManager = PlaylistManager;
  850. BaseItem.CollectionManager = CollectionManager;
  851. BaseItem.MediaSourceManager = MediaSourceManager;
  852. CollectionFolder.XmlSerializer = XmlSerializer;
  853. BaseStreamingService.AppHost = this;
  854. BaseStreamingService.HttpClient = HttpClient;
  855. Utilities.CryptographyProvider = CryptographyProvider;
  856. AuthenticatedAttribute.AuthService = AuthService;
  857. }
  858. /// <summary>
  859. /// Finds the parts.
  860. /// </summary>
  861. protected override void FindParts()
  862. {
  863. if (!ServerConfigurationManager.Configuration.IsPortAuthorized)
  864. {
  865. RegisterServerWithAdministratorAccess();
  866. ServerConfigurationManager.Configuration.IsPortAuthorized = true;
  867. ConfigurationManager.SaveConfiguration();
  868. }
  869. RegisterModules();
  870. base.FindParts();
  871. HttpServer.Init(GetExports<IService>(false));
  872. ServerManager.AddWebSocketListeners(GetExports<IWebSocketListener>(false));
  873. StartServer();
  874. LibraryManager.AddParts(GetExports<IResolverIgnoreRule>(),
  875. GetExports<IVirtualFolderCreator>(),
  876. GetExports<IItemResolver>(),
  877. GetExports<IIntroProvider>(),
  878. GetExports<IBaseItemComparer>(),
  879. GetExports<ILibraryPostScanTask>());
  880. ProviderManager.AddParts(GetExports<IImageProvider>(),
  881. GetExports<IMetadataService>(),
  882. GetExports<IMetadataProvider>(),
  883. GetExports<IMetadataSaver>(),
  884. GetExports<IExternalId>());
  885. ImageProcessor.AddParts(GetExports<IImageEnhancer>());
  886. LiveTvManager.AddParts(GetExports<ILiveTvService>(), GetExports<ITunerHost>(), GetExports<IListingsProvider>());
  887. SubtitleManager.AddParts(GetExports<ISubtitleProvider>());
  888. SessionManager.AddParts(GetExports<ISessionControllerFactory>());
  889. ChannelManager.AddParts(GetExports<IChannel>());
  890. MediaSourceManager.AddParts(GetExports<IMediaSourceProvider>());
  891. NotificationManager.AddParts(GetExports<INotificationService>(), GetExports<INotificationTypeFactory>());
  892. SyncManager.AddParts(GetExports<ISyncProvider>());
  893. }
  894. private string CertificatePath { get; set; }
  895. private ICertificate Certificate { get; set; }
  896. private IEnumerable<string> GetUrlPrefixes()
  897. {
  898. var hosts = new List<string>();
  899. hosts.Add("+");
  900. return hosts.SelectMany(i =>
  901. {
  902. var prefixes = new List<string>
  903. {
  904. "http://"+i+":" + HttpPort + "/"
  905. };
  906. if (!string.IsNullOrWhiteSpace(CertificatePath))
  907. {
  908. prefixes.Add("https://" + i + ":" + HttpsPort + "/");
  909. }
  910. return prefixes;
  911. });
  912. }
  913. /// <summary>
  914. /// Starts the server.
  915. /// </summary>
  916. private void StartServer()
  917. {
  918. try
  919. {
  920. ServerManager.Start(GetUrlPrefixes());
  921. return;
  922. }
  923. catch (Exception ex)
  924. {
  925. Logger.ErrorException("Error starting http server", ex);
  926. if (HttpPort == ServerConfiguration.DefaultHttpPort)
  927. {
  928. throw;
  929. }
  930. }
  931. HttpPort = ServerConfiguration.DefaultHttpPort;
  932. try
  933. {
  934. ServerManager.Start(GetUrlPrefixes());
  935. }
  936. catch (Exception ex)
  937. {
  938. Logger.ErrorException("Error starting http server", ex);
  939. throw;
  940. }
  941. }
  942. private string GetCertificatePath(bool generateCertificate)
  943. {
  944. if (!string.IsNullOrWhiteSpace(ServerConfigurationManager.Configuration.CertificatePath))
  945. {
  946. // Custom cert
  947. return ServerConfigurationManager.Configuration.CertificatePath;
  948. }
  949. // Generate self-signed cert
  950. var certHost = GetHostnameFromExternalDns(ServerConfigurationManager.Configuration.WanDdns);
  951. var certPath = Path.Combine(ServerConfigurationManager.ApplicationPaths.ProgramDataPath, "ssl", "cert_" + (certHost + "1").GetMD5().ToString("N") + ".pfx");
  952. if (generateCertificate)
  953. {
  954. if (!FileSystemManager.FileExists(certPath))
  955. {
  956. FileSystemManager.CreateDirectory(Path.GetDirectoryName(certPath));
  957. try
  958. {
  959. _certificateGenerator(certPath, certHost);
  960. }
  961. catch (Exception ex)
  962. {
  963. Logger.ErrorException("Error creating ssl cert", ex);
  964. return null;
  965. }
  966. }
  967. }
  968. return certPath;
  969. }
  970. /// <summary>
  971. /// Called when [configuration updated].
  972. /// </summary>
  973. /// <param name="sender">The sender.</param>
  974. /// <param name="e">The <see cref="EventArgs"/> instance containing the event data.</param>
  975. protected override void OnConfigurationUpdated(object sender, EventArgs e)
  976. {
  977. base.OnConfigurationUpdated(sender, e);
  978. var requiresRestart = false;
  979. // Don't do anything if these haven't been set yet
  980. if (HttpPort != 0 && HttpsPort != 0)
  981. {
  982. // Need to restart if ports have changed
  983. if (ServerConfigurationManager.Configuration.HttpServerPortNumber != HttpPort ||
  984. ServerConfigurationManager.Configuration.HttpsPortNumber != HttpsPort)
  985. {
  986. if (ServerConfigurationManager.Configuration.IsPortAuthorized)
  987. {
  988. ServerConfigurationManager.Configuration.IsPortAuthorized = false;
  989. ServerConfigurationManager.SaveConfiguration();
  990. requiresRestart = true;
  991. }
  992. }
  993. }
  994. if (!HttpServer.UrlPrefixes.SequenceEqual(GetUrlPrefixes(), StringComparer.OrdinalIgnoreCase))
  995. {
  996. requiresRestart = true;
  997. }
  998. if (!string.Equals(CertificatePath, GetCertificatePath(false), StringComparison.OrdinalIgnoreCase))
  999. {
  1000. requiresRestart = true;
  1001. }
  1002. if (requiresRestart)
  1003. {
  1004. Logger.Info("App needs to be restarted due to configuration change.");
  1005. NotifyPendingRestart();
  1006. }
  1007. }
  1008. /// <summary>
  1009. /// Restarts this instance.
  1010. /// </summary>
  1011. public override async Task Restart()
  1012. {
  1013. if (!CanSelfRestart)
  1014. {
  1015. throw new PlatformNotSupportedException("The server is unable to self-restart. Please restart manually.");
  1016. }
  1017. try
  1018. {
  1019. await SessionManager.SendServerRestartNotification(CancellationToken.None).ConfigureAwait(false);
  1020. }
  1021. catch (Exception ex)
  1022. {
  1023. Logger.ErrorException("Error sending server restart notification", ex);
  1024. }
  1025. Logger.Info("Calling RestartInternal");
  1026. RestartInternal();
  1027. }
  1028. protected abstract void RestartInternal();
  1029. /// <summary>
  1030. /// Gets the composable part assemblies.
  1031. /// </summary>
  1032. /// <returns>IEnumerable{Assembly}.</returns>
  1033. protected override IEnumerable<Assembly> GetComposablePartAssemblies()
  1034. {
  1035. var list = GetPluginAssemblies()
  1036. .ToList();
  1037. // Gets all plugin assemblies by first reading all bytes of the .dll and calling Assembly.Load against that
  1038. // This will prevent the .dll file from getting locked, and allow us to replace it when needed
  1039. // Include composable parts in the Api assembly
  1040. list.Add(GetAssembly(typeof(ApiEntryPoint)));
  1041. // Include composable parts in the Dashboard assembly
  1042. list.Add(GetAssembly(typeof(DashboardService)));
  1043. // Include composable parts in the Model assembly
  1044. list.Add(GetAssembly(typeof(SystemInfo)));
  1045. // Include composable parts in the Common assembly
  1046. list.Add(GetAssembly(typeof(IApplicationHost)));
  1047. // Include composable parts in the Controller assembly
  1048. list.Add(GetAssembly(typeof(IServerApplicationHost)));
  1049. // Include composable parts in the Providers assembly
  1050. list.Add(GetAssembly(typeof(ProviderUtils)));
  1051. // Include composable parts in the Photos assembly
  1052. list.Add(GetAssembly(typeof(PhotoProvider)));
  1053. // Common implementations
  1054. list.Add(GetAssembly(typeof(TaskManager)));
  1055. // Emby.Server implementations
  1056. list.Add(GetAssembly(typeof(InstallationManager)));
  1057. // Emby.Server.Core
  1058. list.Add(GetAssembly(typeof(ApplicationHost)));
  1059. // MediaEncoding
  1060. list.Add(GetAssembly(typeof(MediaEncoder)));
  1061. // Dlna
  1062. list.Add(GetAssembly(typeof(DlnaEntryPoint)));
  1063. // Local metadata
  1064. list.Add(GetAssembly(typeof(BoxSetXmlSaver)));
  1065. // Xbmc
  1066. list.Add(GetAssembly(typeof(ArtistNfoProvider)));
  1067. list.AddRange(GetAssembliesWithPartsInternal());
  1068. // Include composable parts in the running assembly
  1069. list.Add(GetAssembly(typeof(ApplicationHost)));
  1070. return list;
  1071. }
  1072. protected abstract List<Assembly> GetAssembliesWithPartsInternal();
  1073. /// <summary>
  1074. /// Gets the plugin assemblies.
  1075. /// </summary>
  1076. /// <returns>IEnumerable{Assembly}.</returns>
  1077. private IEnumerable<Assembly> GetPluginAssemblies()
  1078. {
  1079. try
  1080. {
  1081. return Directory.EnumerateFiles(ApplicationPaths.PluginsPath, "*.dll", SearchOption.TopDirectoryOnly)
  1082. .Where(EnablePlugin)
  1083. .Select(LoadAssembly)
  1084. .Where(a => a != null)
  1085. .ToList();
  1086. }
  1087. catch (DirectoryNotFoundException)
  1088. {
  1089. return new List<Assembly>();
  1090. }
  1091. }
  1092. private bool EnablePlugin(string path)
  1093. {
  1094. var filename = Path.GetFileName(path);
  1095. var exclude = new[]
  1096. {
  1097. "mbplus.dll",
  1098. "mbintros.dll",
  1099. "embytv.dll"
  1100. };
  1101. return !exclude.Contains(filename ?? string.Empty, StringComparer.OrdinalIgnoreCase);
  1102. }
  1103. /// <summary>
  1104. /// Gets the system status.
  1105. /// </summary>
  1106. /// <returns>SystemInfo.</returns>
  1107. public async Task<SystemInfo> GetSystemInfo()
  1108. {
  1109. var localAddress = await GetLocalApiUrl().ConfigureAwait(false);
  1110. return new SystemInfo
  1111. {
  1112. HasPendingRestart = HasPendingRestart,
  1113. Version = ApplicationVersion.ToString(),
  1114. WebSocketPortNumber = HttpPort,
  1115. FailedPluginAssemblies = FailedAssemblies.ToList(),
  1116. InProgressInstallations = InstallationManager.CurrentInstallations.Select(i => i.Item1).ToList(),
  1117. CompletedInstallations = InstallationManager.CompletedInstallations.ToList(),
  1118. Id = SystemId,
  1119. ProgramDataPath = ApplicationPaths.ProgramDataPath,
  1120. LogPath = ApplicationPaths.LogDirectoryPath,
  1121. ItemsByNamePath = ApplicationPaths.ItemsByNamePath,
  1122. InternalMetadataPath = ApplicationPaths.InternalMetadataPath,
  1123. CachePath = ApplicationPaths.CachePath,
  1124. MacAddress = GetMacAddress(),
  1125. HttpServerPortNumber = HttpPort,
  1126. SupportsHttps = SupportsHttps,
  1127. HttpsPortNumber = HttpsPort,
  1128. OperatingSystem = EnvironmentInfo.OperatingSystem.ToString(),
  1129. OperatingSystemDisplayName = OperatingSystemDisplayName,
  1130. CanSelfRestart = CanSelfRestart,
  1131. CanSelfUpdate = CanSelfUpdate,
  1132. WanAddress = ConnectManager.WanApiAddress,
  1133. HasUpdateAvailable = HasUpdateAvailable,
  1134. SupportsAutoRunAtStartup = SupportsAutoRunAtStartup,
  1135. TranscodingTempPath = ApplicationPaths.TranscodingTempPath,
  1136. SupportsRunningAsService = SupportsRunningAsService,
  1137. ServerName = FriendlyName,
  1138. LocalAddress = localAddress,
  1139. SupportsLibraryMonitor = true,
  1140. EncoderLocationType = MediaEncoder.EncoderLocationType,
  1141. SystemArchitecture = EnvironmentInfo.SystemArchitecture,
  1142. SystemUpdateLevel = ConfigurationManager.CommonConfiguration.SystemUpdateLevel,
  1143. PackageName = StartupOptions.GetOption("-package")
  1144. };
  1145. }
  1146. public bool EnableHttps
  1147. {
  1148. get
  1149. {
  1150. return SupportsHttps && ServerConfigurationManager.Configuration.EnableHttps;
  1151. }
  1152. }
  1153. public bool SupportsHttps
  1154. {
  1155. get { return Certificate != null; }
  1156. }
  1157. public async Task<string> GetLocalApiUrl()
  1158. {
  1159. try
  1160. {
  1161. // Return the first matched address, if found, or the first known local address
  1162. var address = (await GetLocalIpAddresses().ConfigureAwait(false)).FirstOrDefault(i => !i.Equals(IpAddressInfo.Loopback) && !i.Equals(IpAddressInfo.IPv6Loopback));
  1163. if (address != null)
  1164. {
  1165. return GetLocalApiUrl(address);
  1166. }
  1167. return null;
  1168. }
  1169. catch (Exception ex)
  1170. {
  1171. Logger.ErrorException("Error getting local Ip address information", ex);
  1172. }
  1173. return null;
  1174. }
  1175. public string GetLocalApiUrl(IpAddressInfo ipAddress)
  1176. {
  1177. if (ipAddress.AddressFamily == IpAddressFamily.InterNetworkV6)
  1178. {
  1179. return GetLocalApiUrl("[" + ipAddress.Address + "]");
  1180. }
  1181. return GetLocalApiUrl(ipAddress.Address);
  1182. }
  1183. public string GetLocalApiUrl(string host)
  1184. {
  1185. return string.Format("http://{0}:{1}",
  1186. host,
  1187. HttpPort.ToString(CultureInfo.InvariantCulture));
  1188. }
  1189. public async Task<List<IpAddressInfo>> GetLocalIpAddresses()
  1190. {
  1191. var addresses = ServerConfigurationManager
  1192. .Configuration
  1193. .LocalNetworkAddresses
  1194. .Select(NormalizeConfiguredLocalAddress)
  1195. .Where(i => i != null)
  1196. .ToList();
  1197. if (addresses.Count == 0)
  1198. {
  1199. addresses.AddRange(NetworkManager.GetLocalIpAddresses());
  1200. var list = new List<IpAddressInfo>();
  1201. foreach (var address in addresses)
  1202. {
  1203. var valid = await IsIpAddressValidAsync(address).ConfigureAwait(false);
  1204. if (valid)
  1205. {
  1206. list.Add(address);
  1207. }
  1208. }
  1209. addresses = list;
  1210. }
  1211. return addresses;
  1212. }
  1213. private IpAddressInfo NormalizeConfiguredLocalAddress(string address)
  1214. {
  1215. var index = address.Trim('/').IndexOf('/');
  1216. if (index != -1)
  1217. {
  1218. address = address.Substring(index + 1);
  1219. }
  1220. IpAddressInfo result;
  1221. if (NetworkManager.TryParseIpAddress(address.Trim('/'), out result))
  1222. {
  1223. return result;
  1224. }
  1225. return null;
  1226. }
  1227. private readonly ConcurrentDictionary<string, bool> _validAddressResults = new ConcurrentDictionary<string, bool>(StringComparer.OrdinalIgnoreCase);
  1228. private DateTime _lastAddressCacheClear;
  1229. private async Task<bool> IsIpAddressValidAsync(IpAddressInfo address)
  1230. {
  1231. if (address.Equals(IpAddressInfo.Loopback) ||
  1232. address.Equals(IpAddressInfo.IPv6Loopback))
  1233. {
  1234. return true;
  1235. }
  1236. var apiUrl = GetLocalApiUrl(address);
  1237. apiUrl += "/system/ping";
  1238. if ((DateTime.UtcNow - _lastAddressCacheClear).TotalMinutes >= 15)
  1239. {
  1240. _lastAddressCacheClear = DateTime.UtcNow;
  1241. _validAddressResults.Clear();
  1242. }
  1243. bool cachedResult;
  1244. if (_validAddressResults.TryGetValue(apiUrl, out cachedResult))
  1245. {
  1246. return cachedResult;
  1247. }
  1248. try
  1249. {
  1250. using (var response = await HttpClient.SendAsync(new HttpRequestOptions
  1251. {
  1252. Url = apiUrl,
  1253. LogErrorResponseBody = false,
  1254. LogErrors = false,
  1255. LogRequest = false,
  1256. TimeoutMs = 30000,
  1257. BufferContent = false
  1258. }, "POST").ConfigureAwait(false))
  1259. {
  1260. using (var reader = new StreamReader(response.Content))
  1261. {
  1262. var result = reader.ReadToEnd();
  1263. var valid = string.Equals(Name, result, StringComparison.OrdinalIgnoreCase);
  1264. _validAddressResults.AddOrUpdate(apiUrl, valid, (k, v) => valid);
  1265. //Logger.Debug("Ping test result to {0}. Success: {1}", apiUrl, valid);
  1266. return valid;
  1267. }
  1268. }
  1269. }
  1270. catch
  1271. {
  1272. //Logger.Debug("Ping test result to {0}. Success: {1}", apiUrl, false);
  1273. _validAddressResults.AddOrUpdate(apiUrl, false, (k, v) => false);
  1274. return false;
  1275. }
  1276. }
  1277. public string FriendlyName
  1278. {
  1279. get
  1280. {
  1281. return string.IsNullOrWhiteSpace(ServerConfigurationManager.Configuration.ServerName)
  1282. ? Environment.MachineName
  1283. : ServerConfigurationManager.Configuration.ServerName;
  1284. }
  1285. }
  1286. public int HttpPort { get; private set; }
  1287. public int HttpsPort { get; private set; }
  1288. /// <summary>
  1289. /// Gets the mac address.
  1290. /// </summary>
  1291. /// <returns>System.String.</returns>
  1292. private string GetMacAddress()
  1293. {
  1294. try
  1295. {
  1296. return NetworkManager.GetMacAddress();
  1297. }
  1298. catch (Exception ex)
  1299. {
  1300. Logger.ErrorException("Error getting mac address", ex);
  1301. return null;
  1302. }
  1303. }
  1304. /// <summary>
  1305. /// Shuts down.
  1306. /// </summary>
  1307. public override async Task Shutdown()
  1308. {
  1309. try
  1310. {
  1311. await SessionManager.SendServerShutdownNotification(CancellationToken.None).ConfigureAwait(false);
  1312. }
  1313. catch (Exception ex)
  1314. {
  1315. Logger.ErrorException("Error sending server shutdown notification", ex);
  1316. }
  1317. ShutdownInternal();
  1318. }
  1319. protected abstract void ShutdownInternal();
  1320. /// <summary>
  1321. /// Registers the server with administrator access.
  1322. /// </summary>
  1323. private void RegisterServerWithAdministratorAccess()
  1324. {
  1325. Logger.Info("Requesting administrative access to authorize http server");
  1326. try
  1327. {
  1328. AuthorizeServer();
  1329. }
  1330. catch (NotImplementedException)
  1331. {
  1332. }
  1333. catch (Exception ex)
  1334. {
  1335. Logger.ErrorException("Error authorizing server", ex);
  1336. }
  1337. }
  1338. protected virtual void AuthorizeServer()
  1339. {
  1340. throw new NotImplementedException();
  1341. }
  1342. public event EventHandler HasUpdateAvailableChanged;
  1343. private bool _hasUpdateAvailable;
  1344. public bool HasUpdateAvailable
  1345. {
  1346. get { return _hasUpdateAvailable; }
  1347. set
  1348. {
  1349. var fireEvent = value && !_hasUpdateAvailable;
  1350. _hasUpdateAvailable = value;
  1351. if (fireEvent)
  1352. {
  1353. EventHelper.FireEventIfNotNull(HasUpdateAvailableChanged, this, EventArgs.Empty, Logger);
  1354. }
  1355. }
  1356. }
  1357. /// <summary>
  1358. /// Checks for update.
  1359. /// </summary>
  1360. /// <param name="cancellationToken">The cancellation token.</param>
  1361. /// <param name="progress">The progress.</param>
  1362. /// <returns>Task{CheckForUpdateResult}.</returns>
  1363. public override async Task<CheckForUpdateResult> CheckForApplicationUpdate(CancellationToken cancellationToken, IProgress<double> progress)
  1364. {
  1365. var cacheLength = TimeSpan.FromHours(3);
  1366. var updateLevel = ConfigurationManager.CommonConfiguration.SystemUpdateLevel;
  1367. if (updateLevel == PackageVersionClass.Beta)
  1368. {
  1369. cacheLength = TimeSpan.FromHours(1);
  1370. }
  1371. else if (updateLevel == PackageVersionClass.Dev)
  1372. {
  1373. cacheLength = TimeSpan.FromMinutes(5);
  1374. }
  1375. var result = await new GithubUpdater(HttpClient, JsonSerializer).CheckForUpdateResult("MediaBrowser", "Emby", ApplicationVersion, updateLevel, _releaseAssetFilename,
  1376. "MBServer", "Mbserver.zip", cacheLength, cancellationToken).ConfigureAwait(false);
  1377. HasUpdateAvailable = result.IsUpdateAvailable;
  1378. return result;
  1379. }
  1380. /// <summary>
  1381. /// Updates the application.
  1382. /// </summary>
  1383. /// <param name="package">The package that contains the update</param>
  1384. /// <param name="cancellationToken">The cancellation token.</param>
  1385. /// <param name="progress">The progress.</param>
  1386. public override async Task UpdateApplication(PackageVersionInfo package, CancellationToken cancellationToken, IProgress<double> progress)
  1387. {
  1388. await InstallationManager.InstallPackage(package, false, progress, cancellationToken).ConfigureAwait(false);
  1389. HasUpdateAvailable = false;
  1390. OnApplicationUpdated(package);
  1391. }
  1392. /// <summary>
  1393. /// Configures the automatic run at startup.
  1394. /// </summary>
  1395. /// <param name="autorun">if set to <c>true</c> [autorun].</param>
  1396. protected override void ConfigureAutoRunAtStartup(bool autorun)
  1397. {
  1398. if (SupportsAutoRunAtStartup)
  1399. {
  1400. ConfigureAutoRunInternal(autorun);
  1401. }
  1402. }
  1403. protected virtual void ConfigureAutoRunInternal(bool autorun)
  1404. {
  1405. throw new NotImplementedException();
  1406. }
  1407. /// <summary>
  1408. /// This returns localhost in the case of no external dns, and the hostname if the
  1409. /// dns is prefixed with a valid Uri prefix.
  1410. /// </summary>
  1411. /// <param name="externalDns">The external dns prefix to get the hostname of.</param>
  1412. /// <returns>The hostname in <paramref name="externalDns"/></returns>
  1413. private static string GetHostnameFromExternalDns(string externalDns)
  1414. {
  1415. if (string.IsNullOrWhiteSpace(externalDns))
  1416. {
  1417. return "localhost";
  1418. }
  1419. try
  1420. {
  1421. return new Uri(externalDns).Host;
  1422. }
  1423. catch
  1424. {
  1425. return externalDns;
  1426. }
  1427. }
  1428. public void LaunchUrl(string url)
  1429. {
  1430. if (EnvironmentInfo.OperatingSystem != MediaBrowser.Model.System.OperatingSystem.Windows &&
  1431. EnvironmentInfo.OperatingSystem != MediaBrowser.Model.System.OperatingSystem.OSX)
  1432. {
  1433. throw new NotImplementedException();
  1434. }
  1435. var process = ProcessFactory.Create(new ProcessOptions
  1436. {
  1437. FileName = url,
  1438. //EnableRaisingEvents = true,
  1439. UseShellExecute = true,
  1440. ErrorDialog = false
  1441. });
  1442. process.Exited += ProcessExited;
  1443. try
  1444. {
  1445. process.Start();
  1446. }
  1447. catch (Exception ex)
  1448. {
  1449. Console.WriteLine("Error launching url: {0}", url);
  1450. Logger.ErrorException("Error launching url: {0}", ex, url);
  1451. throw;
  1452. }
  1453. }
  1454. private static void ProcessExited(object sender, EventArgs e)
  1455. {
  1456. ((IProcess)sender).Dispose();
  1457. }
  1458. public void EnableLoopback(string appName)
  1459. {
  1460. if (EnvironmentInfo.OperatingSystem == MediaBrowser.Model.System.OperatingSystem.Windows)
  1461. {
  1462. LoopUtil.Run(appName);
  1463. }
  1464. }
  1465. private void RegisterModules()
  1466. {
  1467. var moduleTypes = GetExportTypes<IDependencyModule>();
  1468. foreach (var type in moduleTypes)
  1469. {
  1470. try
  1471. {
  1472. var instance = Activator.CreateInstance(type) as IDependencyModule;
  1473. if (instance != null)
  1474. instance.BindDependencies(this);
  1475. }
  1476. catch (Exception ex)
  1477. {
  1478. Logger.ErrorException("Error setting up dependency bindings for " + type.Name, ex);
  1479. }
  1480. }
  1481. }
  1482. void IDependencyContainer.RegisterSingleInstance<T>(T obj, bool manageLifetime)
  1483. {
  1484. RegisterSingleInstance(obj, manageLifetime);
  1485. }
  1486. void IDependencyContainer.RegisterSingleInstance<T>(Func<T> func)
  1487. {
  1488. RegisterSingleInstance(func);
  1489. }
  1490. void IDependencyContainer.Register(Type typeInterface, Type typeImplementation)
  1491. {
  1492. Container.Register(typeInterface, typeImplementation);
  1493. }
  1494. }
  1495. }