diff --git a/MediaBrowser.Server.Mac/AppController.cs b/MediaBrowser.Server.Mac/AppController.cs index d2ef0cd924..1823e21528 100644 --- a/MediaBrowser.Server.Mac/AppController.cs +++ b/MediaBrowser.Server.Mac/AppController.cs @@ -20,9 +20,11 @@ namespace MediaBrowser.Server.Mac private NSMenuItem apiMenuItem; private NSMenuItem communityMenuItem; + public static AppController Instance; + public AppController() { - + Instance = this; } public override void AwakeFromNib() @@ -71,13 +73,14 @@ namespace MediaBrowser.Server.Mac statusItem.Menu.AddItem (quitMenuItem); } - private IServerApplicationHost AppHost{ get; set;} - private ILogger Logger{ get; set;} + public IServerApplicationHost AppHost{ get; set;} + public IServerConfigurationManager ConfigurationManager { get; set;} + public ILogger Logger{ get; set;} + public ILocalizationManager Localization { get; set;} private void Quit(NSObject sender) { - NSApplication.SharedApplication.Terminate(this); - //AppHost.Shutdown(); + AppHost.Shutdown(); } private void Community(NSObject sender) @@ -104,6 +107,44 @@ namespace MediaBrowser.Server.Mac { BrowserLauncher.OpenSwagger(AppHost, Logger); } + + public void Terminate() + { + InvokeOnMainThread (() => NSApplication.SharedApplication.Terminate(this)); + } + + private string _uiCulture; + /// + /// Handles the ConfigurationUpdated event of the Instance control. + /// + /// The source of the event. + /// The instance containing the event data. + void Instance_ConfigurationUpdated(object sender, EventArgs e) + { + if (!string.Equals(ConfigurationManager.Configuration.UICulture, _uiCulture, + StringComparison.OrdinalIgnoreCase)) + { + LocalizeText(); + } + } + + private void LocalizeText() + { + _uiCulture = ConfigurationManager.Configuration.UICulture; + + BeginInvokeOnMainThread (LocalizeInternal); + } + + private void LocalizeInternal() { + + quitMenuItem.Title = Localization.GetLocalizedString("LabelExit"); + communityMenuItem.Title = Localization.GetLocalizedString("LabelVisitCommunity"); + githubMenuItem.Title = Localization.GetLocalizedString("LabelGithub"); + apiMenuItem.Title = Localization.GetLocalizedString("LabelApiDocumentation"); + developerMenuItem.Title = Localization.GetLocalizedString("LabelDeveloperResources"); + browseMenuItem.Title = Localization.GetLocalizedString("LabelBrowseLibrary"); + configureMenuItem.Title = Localization.GetLocalizedString("LabelConfigureMediaBrowser"); + } } } diff --git a/MediaBrowser.Server.Mac/Main.cs b/MediaBrowser.Server.Mac/Main.cs index 8a8f19f5e7..88b9497ead 100644 --- a/MediaBrowser.Server.Mac/Main.cs +++ b/MediaBrowser.Server.Mac/Main.cs @@ -1,18 +1,171 @@ using System; +using System.Diagnostics; using System.Drawing; -using MonoMac.Foundation; +using System.IO; +using System.Linq; +using System.Net; +using System.Net.Security; +using System.Reflection; +using System.Runtime.InteropServices; +using System.Security.Cryptography.X509Certificates; +using System.Threading; +using System.Threading.Tasks; +using MediaBrowser.Common.Configuration; +using MediaBrowser.Common.Implementations.IO; +using MediaBrowser.Common.Implementations.Logging; +using MediaBrowser.Model.Logging; +using MediaBrowser.Server.Implementations; +using MediaBrowser.Server.Mono.Native; +using MediaBrowser.Server.Startup.Common; +using MediaBrowser.Server.Startup.Common.Browser; +using Microsoft.Win32; +using Microsoft.Win32; using MonoMac.AppKit; +using MonoMac.Foundation; using MonoMac.ObjCRuntime; namespace MediaBrowser.Server.Mac { class MainClass { + private static ApplicationHost _appHost; + + private static ILogger _logger; + static void Main (string[] args) { + var applicationPath = Assembly.GetEntryAssembly().Location; + + var options = new StartupOptions(); + + // Allow this to be specified on the command line. + var customProgramDataPath = options.GetOption("-programdata"); + + var appPaths = CreateApplicationPaths(applicationPath, customProgramDataPath); + + var logManager = new NlogManager(appPaths.LogDirectoryPath, "server"); + logManager.ReloadLogger(LogSeverity.Info); + logManager.AddConsoleOutput(); + + var logger = _logger = logManager.GetLogger("Main"); + + ApplicationHost.LogEnvironmentInfo(logger, appPaths, true); + + AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException; + + StartApplication(appPaths, logManager, options); + RunNSApp (args); + } + + private static void RunNSApp(string[] args) { + NSApplication.Init (); + + AppController.Instance.AppHost = _appHost; + AppController.Instance.Logger = _logger; + AppController.Instance.ConfigurationManager = _appHost.ServerConfigurationManager; + AppController.Instance.Localization = _appHost.LocalizationManager; + NSApplication.Main (args); } + + private static ServerApplicationPaths CreateApplicationPaths(string applicationPath, string programDataPath) + { + if (string.IsNullOrEmpty(programDataPath)) + { + return new ServerApplicationPaths(applicationPath); + } + + return new ServerApplicationPaths(programDataPath, applicationPath); + } + + /// + /// Runs the application. + /// + /// The app paths. + /// The log manager. + /// The options. + private static void StartApplication(ServerApplicationPaths appPaths, + ILogManager logManager, + StartupOptions options) + { + SystemEvents.SessionEnding += SystemEvents_SessionEnding; + + // Allow all https requests + ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(delegate { return true; }); + + var fileSystem = new CommonFileSystem(logManager.GetLogger("FileSystem"), false, true); + + var nativeApp = new NativeApp(); + + _appHost = new ApplicationHost(appPaths, logManager, options, fileSystem, "MBServer.Mono", false, nativeApp); + + if (options.ContainsOption("-v")) { + Console.WriteLine (_appHost.ApplicationVersion.ToString()); + return; + } + + Console.WriteLine ("appHost.Init"); + + var initProgress = new Progress(); + + var task = _appHost.Init(initProgress); + task = task.ContinueWith(new Action(a => _appHost.RunStartupTasks())); + + Task.WaitAll(task); + } + + /// + /// Handles the SessionEnding event of the SystemEvents control. + /// + /// The source of the event. + /// The instance containing the event data. + static void SystemEvents_SessionEnding(object sender, SessionEndingEventArgs e) + { + if (e.Reason == SessionEndReasons.SystemShutdown) + { + Shutdown(); + } + } + + public static void Shutdown() + { + ShutdownApp(); + } + + private static void ShutdownApp() + { + _logger.Info ("Calling ApplicationHost.Dispose"); + _appHost.Dispose (); + + _logger.Info("AppController.Terminate"); + AppController.Instance.Terminate (); + } + + /// + /// Handles the UnhandledException event of the CurrentDomain control. + /// + /// The source of the event. + /// The instance containing the event data. + static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e) + { + var exception = (Exception)e.ExceptionObject; + + new UnhandledExceptionWriter(_appHost.ServerConfigurationManager.ApplicationPaths, _logger, _appHost.LogManager).Log(exception); + + if (!Debugger.IsAttached) + { + Environment.Exit(System.Runtime.InteropServices.Marshal.GetHRForException(exception)); + } + } + } + + class NoCheckCertificatePolicy : ICertificatePolicy + { + public bool CheckValidationResult (ServicePoint srvPoint, X509Certificate certificate, WebRequest request, int certificateProblem) + { + return true; + } } } diff --git a/MediaBrowser.Server.Mac/MediaBrowser.Server.Mac.csproj b/MediaBrowser.Server.Mac/MediaBrowser.Server.Mac.csproj index bf3bd77163..2f67874882 100644 --- a/MediaBrowser.Server.Mac/MediaBrowser.Server.Mac.csproj +++ b/MediaBrowser.Server.Mac/MediaBrowser.Server.Mac.csproj @@ -112,6 +112,14 @@ {9142EEFA-7570-41E1-BFCC-468BB571AF2F} MediaBrowser.Common + + {C4D2573A-3FD3-441F-81AF-174AC4CD4E1D} + MediaBrowser.Common.Implementations + + + {2E781478-814D-4A48-9D80-BFF206441A65} + MediaBrowser.Server.Implementations +