diff options
author | sr55 <[email protected]> | 2019-12-29 17:29:36 +0000 |
---|---|---|
committer | sr55 <[email protected]> | 2019-12-29 17:29:53 +0000 |
commit | 282b04f2fe39205664fbccc81aaab1048294811c (patch) | |
tree | 68e6b1a9d16e2d4e8479338462b641aa05bf4d4c | |
parent | f63e7b79c83d62055f96f0a1a687cffae208a9c8 (diff) |
WinGui: Experimental Worker Process (Basic logging is now operational) + UI Infrastructure (currently hidden) needed for the feature. + More Refactoring.
31 files changed, 532 insertions, 405 deletions
diff --git a/win/CS/HandBrake.Worker/HandBrake.Worker.csproj b/win/CS/HandBrake.Worker/HandBrake.Worker.csproj index 8ea258b44..f075859c0 100644 --- a/win/CS/HandBrake.Worker/HandBrake.Worker.csproj +++ b/win/CS/HandBrake.Worker/HandBrake.Worker.csproj @@ -44,14 +44,16 @@ <Reference Include="System.Xml" /> </ItemGroup> <ItemGroup> - <Compile Include="ApiRouter.cs" /> + <Compile Include="Routing\ApiRouter.cs" /> + <Compile Include="Registration\ConnectionRegistrar.cs" /> <Compile Include="HttpServer.cs" /> <Compile Include="Logging\Interfaces\ILogHandler.cs" /> <Compile Include="Logging\LogHandler.cs" /> - <Compile Include="Logging\Models\LogHandlerConfig.cs" /> <Compile Include="Logging\Models\LogMessage.cs" /> <Compile Include="Program.cs" /> <Compile Include="Properties\AssemblyInfo.cs" /> + <Compile Include="Registration\Model\ConnectionResult.cs" /> + <Compile Include="Utilities\HttpUtilities.cs" /> </ItemGroup> <ItemGroup> <None Include="App.config" /> diff --git a/win/CS/HandBrake.Worker/Logging/Interfaces/ILogHandler.cs b/win/CS/HandBrake.Worker/Logging/Interfaces/ILogHandler.cs index 3daa69ba0..eaa527ed6 100644 --- a/win/CS/HandBrake.Worker/Logging/Interfaces/ILogHandler.cs +++ b/win/CS/HandBrake.Worker/Logging/Interfaces/ILogHandler.cs @@ -9,31 +9,22 @@ namespace HandBrake.Worker.Logging.Interfaces { + using System.Collections.Generic; + using HandBrake.Worker.Logging.Models; public interface ILogHandler { - /// <summary> - /// Enable logging for this worker process. - /// </summary> - /// <param name="config"> - /// Configuration for the logger. - /// </param> - /// <remarks> - /// If this is not called, all log messages from libhb will be ignored. - /// </remarks> - void ConfigureLogging(LogHandlerConfig config); - string GetFullLog(); - long GetLatestLogIndex(); + List<LogMessage> GetLogMessages(); /// <summary> /// Get the log data from a given index /// </summary> /// <param name="index">index is zero based</param> /// <returns>Full log as a string</returns> - string GetLogFromIndex(int index); + List<LogMessage> GetLogMessagesFromIndex(int index); /// <summary> /// Empty the log cache and reset the log handler to defaults. diff --git a/win/CS/HandBrake.Worker/Logging/LogHandler.cs b/win/CS/HandBrake.Worker/Logging/LogHandler.cs index a3390a881..b0f11c1e7 100644 --- a/win/CS/HandBrake.Worker/Logging/LogHandler.cs +++ b/win/CS/HandBrake.Worker/Logging/LogHandler.cs @@ -1,5 +1,5 @@ // -------------------------------------------------------------------------------------------------------------------- -// <copyright file="LogHandler.cs" company="HandBrake Project (https://handbrake.fr)"> +// <copyright file="LogHandler.cs" company="HandBrake Project (http://handbrake.fr)"> // This file is part of the HandBrake source code - It may be used under the terms of the GNU General Public License. // </copyright> // <summary> @@ -10,13 +10,11 @@ namespace HandBrake.Worker.Logging { - using System; using System.Collections.Generic; - using System.Diagnostics; - using System.IO; using System.Linq; using System.Text; + using HandBrake.Interop.Interop; using HandBrake.Interop.Interop.EventArgs; using HandBrake.Worker.Logging.Interfaces; using HandBrake.Worker.Logging.Models; @@ -24,17 +22,17 @@ namespace HandBrake.Worker.Logging public class LogHandler : ILogHandler { private readonly object lockObject = new object(); - private readonly object fileWriterLock = new object(); private readonly StringBuilder logBuilder = new StringBuilder(); private readonly List<LogMessage> logMessages = new List<LogMessage>(); - private bool isLoggingEnabled; - private long messageIndex; - private string diskLogPath; - private bool deleteLogFirst; - private bool isDiskLoggingEnabled; - private StreamWriter fileWriter; - private string logHeader; + private bool isLoggingEnabled = true; + private int messageIndex; + + public LogHandler() + { + HandBrakeUtils.MessageLogged += this.HandBrakeUtils_MessageLogged; + HandBrakeUtils.ErrorLogged += this.HandBrakeUtils_ErrorLogged; + } public IEnumerable<LogMessage> LogMessages { @@ -55,27 +53,27 @@ namespace HandBrake.Worker.Logging } } - public long GetLatestLogIndex() + public List<LogMessage> GetLogMessages() { lock (this.lockObject) { - return this.messageIndex; + return new List<LogMessage>(this.logMessages); } } - public string GetLogFromIndex(int index) + public List<LogMessage> GetLogMessagesFromIndex(int index) { - StringBuilder log = new StringBuilder(); + List<LogMessage> log = new List<LogMessage>(); lock (this.lockObject) { // Note messageIndex is not 0 based. - for (int i = index; i < this.messageIndex; i++) + for (int i = index; i < this.messageIndex; i++) { - log.AppendLine(this.logMessages[i].Content); + log.Add(this.logMessages[i]); } } - return log.ToString(); + return log; } public void LogMessage(string content) @@ -91,7 +89,6 @@ namespace HandBrake.Worker.Logging this.messageIndex = this.messageIndex + 1; this.logMessages.Add(msg); this.logBuilder.AppendLine(msg.Content); - this.LogMessageToDisk(msg); if (this.logMessages.Count > 50000) { @@ -99,25 +96,12 @@ namespace HandBrake.Worker.Logging msg = new LogMessage("Log Service Pausing. Too Many Log messages. This may indicate a problem with your encode.", this.messageIndex); this.logMessages.Add(msg); this.logBuilder.AppendLine(msg.Content); - this.LogMessageToDisk(msg); this.isLoggingEnabled = false; } } } - public void ConfigureLogging(LogHandlerConfig config) - { - this.isLoggingEnabled = true; - this.logHeader = config.Header; - this.LogMessage(config.Header); - - if (config.EnableDiskLogging) - { - this.EnableLoggingToDisk(config.LogFile, config.DeleteCurrentLogFirst); - } - } - public void Reset() { lock (this.lockObject) @@ -125,131 +109,6 @@ namespace HandBrake.Worker.Logging this.logMessages.Clear(); this.logBuilder.Clear(); this.messageIndex = 0; - - try - { - lock (this.fileWriterLock) - { - if (this.fileWriter != null) - { - this.fileWriter.Flush(); - this.fileWriter.Close(); - this.fileWriter.Dispose(); - } - - this.fileWriter = null; - } - } - catch (Exception exc) - { - Debug.WriteLine(exc); - } - - if (this.fileWriter == null) - { - this.isDiskLoggingEnabled = false; - this.EnableLoggingToDisk(this.diskLogPath, this.deleteLogFirst); - } - - if (!string.IsNullOrEmpty(this.logHeader)) - { - this.SetupLogHeader(this.logHeader); - } - } - } - - protected void ShutdownFileWriter() - { - try - { - lock (this.fileWriterLock) - { - if (this.fileWriter != null) - { - this.fileWriter.Flush(); - this.fileWriter.Close(); - this.fileWriter.Dispose(); - } - - this.fileWriter = null; - } - } - catch (Exception exc) - { - Debug.WriteLine(exc); // This exception doesn't warrant user interaction, but it should be logged - } - } - - private void SetupLogHeader(string header) - { - this.logHeader = header; - this.LogMessage(header); - } - - private void EnableLoggingToDisk(string logFile, bool deleteCurrentLogFirst) - { - if (this.isDiskLoggingEnabled) - { - throw new Exception("Disk Logging already enabled!"); - } - - try - { - if (!Directory.Exists(Path.GetDirectoryName(logFile))) - { - throw new Exception("Log Directory does not exist. This service will not create it for you!"); - } - - if (deleteCurrentLogFirst && File.Exists(logFile)) - { - File.Delete(logFile); - } - - this.diskLogPath = logFile; - this.isDiskLoggingEnabled = true; - this.deleteLogFirst = deleteCurrentLogFirst; - - lock (this.fileWriterLock) - { - this.fileWriter = new StreamWriter(logFile) { AutoFlush = true }; - } - } - catch (Exception exc) - { - this.LogMessage("Failed to Initialise Disk Logging. " + Environment.NewLine + exc); - - if (this.fileWriter != null) - { - lock (this.fileWriterLock) - { - this.fileWriter.Flush(); - this.fileWriter.Close(); - this.fileWriter.Dispose(); - } - } - } - } - - private void LogMessageToDisk(LogMessage msg) - { - if (!this.isDiskLoggingEnabled) - { - return; - } - - try - { - lock (this.fileWriterLock) - { - if (this.fileWriter != null && this.fileWriter.BaseStream.CanWrite) - { - this.fileWriter.WriteLine(msg.Content); - } - } - } - catch (Exception exc) - { - Debug.WriteLine(exc); // This exception doesn't warrant user interaction, but it should be logged } } diff --git a/win/CS/HandBrake.Worker/Logging/Models/LogMessage.cs b/win/CS/HandBrake.Worker/Logging/Models/LogMessage.cs index c47e331b0..63472cd49 100644 --- a/win/CS/HandBrake.Worker/Logging/Models/LogMessage.cs +++ b/win/CS/HandBrake.Worker/Logging/Models/LogMessage.cs @@ -11,7 +11,7 @@ namespace HandBrake.Worker.Logging.Models { public class LogMessage { - public LogMessage(string content, long messageIndex) + public LogMessage(string content, int messageIndex) { this.Content = content; this.MessageIndex = messageIndex; @@ -19,6 +19,6 @@ namespace HandBrake.Worker.Logging.Models public string Content { get; private set; } - public long MessageIndex { get; private set; } + public int MessageIndex { get; private set; } } } diff --git a/win/CS/HandBrake.Worker/Program.cs b/win/CS/HandBrake.Worker/Program.cs index 95c13ddec..326643d13 100644 --- a/win/CS/HandBrake.Worker/Program.cs +++ b/win/CS/HandBrake.Worker/Program.cs @@ -14,20 +14,18 @@ namespace HandBrake.Worker using System.Net; using System.Threading; + using HandBrake.Worker.Registration; + using HandBrake.Worker.Routing; + public class Program { - /* - * TODO - * Support for connecting via sockets. - * All methods will return a json state object response. - */ - private static ApiRouter router; private static ManualResetEvent manualResetEvent = new ManualResetEvent(false); + private static ConnectionRegistrar registrar = new ConnectionRegistrar(); public static void Main(string[] args) { - int port = 8036; // Default Port; + int port = 8037; // Default Port; int verbosity = 1; if (args.Length != 0) @@ -66,7 +64,6 @@ namespace HandBrake.Worker Console.WriteLine("Web Server Started"); - // Console.ReadKey(); // Block from closing. manualResetEvent.WaitOne(); webServer.Stop(); @@ -77,6 +74,17 @@ namespace HandBrake.Worker Dictionary<string, Func<HttpListenerRequest, string>> apiHandlers = new Dictionary<string, Func<HttpListenerRequest, string>>(); + // Worker APIs + apiHandlers.Add("Pair", registrar.Pair); + apiHandlers.Add("GetToken", registrar.GetToken); + apiHandlers.Add("Shutdown", ShutdownServer); + + // Logging + apiHandlers.Add("GetAllLogMessages", router.GetAllLogMessages); + apiHandlers.Add("GetLogMessagesFromIndex", router.GetLogMessagesFromIndex); + apiHandlers.Add("ResetLogging", router.ResetLogging); + + // HandBrake APIs apiHandlers.Add("Version", router.GetVersionInfo); apiHandlers.Add("StartEncode", router.StartEncode); apiHandlers.Add("PauseEncode", router.PauseEncode); @@ -84,14 +92,7 @@ namespace HandBrake.Worker apiHandlers.Add("StopEncode", router.StopEncode); apiHandlers.Add("PollEncodeProgress", router.PollEncodeProgress); apiHandlers.Add("SetConfiguration", router.SetConfiguration); - apiHandlers.Add("Shutdown", ShutdownServer); - - // Logging - apiHandlers.Add("ConfigureLogging", router.ConfigureLogging); - apiHandlers.Add("GetFullLog", router.GetFullLog); - apiHandlers.Add("GetLatestLogIndex", router.GetLatestLogIndex); - apiHandlers.Add("GetLogFromIndex", router.GetLogFromIndex); - + return apiHandlers; } diff --git a/win/CS/HandBrake.Worker/Registration/ConnectionRegistrar.cs b/win/CS/HandBrake.Worker/Registration/ConnectionRegistrar.cs new file mode 100644 index 000000000..6dca9d950 --- /dev/null +++ b/win/CS/HandBrake.Worker/Registration/ConnectionRegistrar.cs @@ -0,0 +1,53 @@ +// -------------------------------------------------------------------------------------------------------------------- +// <copyright file="ConnectionRegistrar.cs" company="HandBrake Project (http://handbrake.fr)"> +// This file is part of the HandBrake source code - It may be used under the terms of the GNU General Public License. +// </copyright> +// <summary> +// Defines the ConnectionRegistrar type. +// </summary> +// <remarks> +// To be clear, this is NOT a security service! +// This service simply allows the UI to verify which worker process it is connected to. +// </remarks> +// -------------------------------------------------------------------------------------------------------------------- + +namespace HandBrake.Worker.Registration +{ + using System; + using System.Net; + + using HandBrake.Worker.Registration.Model; + using HandBrake.Worker.Utilities; + + using Newtonsoft.Json; + + public class ConnectionRegistrar + { + private readonly JsonSerializerSettings jsonNetSettings = new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore }; + private string token; + + public ConnectionRegistrar() + { + } + + public string Pair(HttpListenerRequest request) + { + string tokenKey = HttpUtilities.GetRequestPostData(request); + + + if (!string.IsNullOrEmpty(token)) + { + return JsonConvert.SerializeObject(new ConnectionResult(false, null, "Already Paired"), Formatting.Indented, this.jsonNetSettings); + } + + this.token = tokenKey; + + return JsonConvert.SerializeObject(new ConnectionResult(true, tokenKey, null), Formatting.Indented, this.jsonNetSettings); + } + + public string GetToken(HttpListenerRequest request) + { + return this.token; + } + } +} diff --git a/win/CS/HandBrake.Worker/Registration/Model/ConnectionResult.cs b/win/CS/HandBrake.Worker/Registration/Model/ConnectionResult.cs new file mode 100644 index 000000000..d11c12cec --- /dev/null +++ b/win/CS/HandBrake.Worker/Registration/Model/ConnectionResult.cs @@ -0,0 +1,31 @@ +// -------------------------------------------------------------------------------------------------------------------- +// <copyright file="ConnectionResult.cs" company="HandBrake Project (http://handbrake.fr)"> +// This file is part of the HandBrake source code - It may be used under the terms of the GNU General Public License. +// </copyright> +// <summary> +// Defines the ConnectionResult type. +// </summary> +// -------------------------------------------------------------------------------------------------------------------- + +namespace HandBrake.Worker.Registration.Model +{ + public class ConnectionResult + { + public ConnectionResult() + { + } + + public ConnectionResult(bool isSuccessfulConnection, string token, string error) + { + this.IsSuccessfulConnection = isSuccessfulConnection; + this.Token = token; + this.Error = error; + } + + public bool IsSuccessfulConnection { get; set; } + + public string Token { get; set; } + + public string Error { get; set; } + } +} diff --git a/win/CS/HandBrake.Worker/ApiRouter.cs b/win/CS/HandBrake.Worker/Routing/ApiRouter.cs index 5fc18bd22..a98f7413d 100644 --- a/win/CS/HandBrake.Worker/ApiRouter.cs +++ b/win/CS/HandBrake.Worker/Routing/ApiRouter.cs @@ -8,12 +8,11 @@ // </summary> // -------------------------------------------------------------------------------------------------------------------- -namespace HandBrake.Worker +namespace HandBrake.Worker.Routing { using System; - using System.IO; + using System.Collections.Generic; using System.Net; - using System.Runtime.InteropServices; using HandBrake.Interop.Interop; using HandBrake.Interop.Interop.Json.State; @@ -21,6 +20,7 @@ namespace HandBrake.Worker using HandBrake.Worker.Logging; using HandBrake.Worker.Logging.Interfaces; using HandBrake.Worker.Logging.Models; + using HandBrake.Worker.Utilities; using Newtonsoft.Json; @@ -29,6 +29,7 @@ namespace HandBrake.Worker private readonly JsonSerializerSettings jsonNetSettings = new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore }; private HandBrakeInstance handbrakeInstance; private ILogHandler logHandler; + private bool isLoggingConfigured = false; public string Initialise(int verbosity) { @@ -56,7 +57,7 @@ namespace HandBrake.Worker public string StartEncode(HttpListenerRequest request) { - string requestPostData = GetRequestPostData(request); + string requestPostData = HttpUtilities.GetRequestPostData(request); Console.WriteLine(requestPostData); this.handbrakeInstance.StartEncode(requestPostData); @@ -105,69 +106,32 @@ namespace HandBrake.Worker /* Logging API */ - - // POST - JSON - public string ConfigureLogging(HttpListenerRequest request) - { - string requestPostData = GetRequestPostData(request); - - JsonSerializerSettings settings = new JsonSerializerSettings - { - NullValueHandling = NullValueHandling.Ignore, - }; - LogHandlerConfig config; - if (!string.IsNullOrEmpty(requestPostData)) - { - config = JsonConvert.DeserializeObject<LogHandlerConfig>(requestPostData, settings); - } - else - { - config = new LogHandlerConfig(false, null, false, "Logging Not Configured!"); - } - - this.logHandler.ConfigureLogging(config); - return null; - } // GET - public string GetFullLog(HttpListenerRequest request) + public string GetAllLogMessages(HttpListenerRequest request) { - return this.logHandler.GetFullLog(); + return JsonConvert.SerializeObject(this.logHandler.GetLogMessages(), Formatting.Indented, this.jsonNetSettings); } + // POST - public string GetLogFromIndex(HttpListenerRequest request) + public string GetLogMessagesFromIndex(HttpListenerRequest request) { - string requestPostData = GetRequestPostData(request); + string requestPostData = HttpUtilities.GetRequestPostData(request); if (int.TryParse(requestPostData, out int index)) { - return this.logHandler.GetLogFromIndex(index); + return JsonConvert.SerializeObject(this.logHandler.GetLogMessagesFromIndex(index), Formatting.Indented, this.jsonNetSettings); } return null; } - // POST - public string GetLatestLogIndex(HttpListenerRequest request) + public string ResetLogging(HttpListenerRequest request) { - return this.logHandler.GetLatestLogIndex().ToString(); - } + this.logHandler.Reset(); - private static string GetRequestPostData(HttpListenerRequest request) - { - if (!request.HasEntityBody) - { - return null; - } - - using (Stream inputStream = request.InputStream) - { - using (StreamReader streamReader = new StreamReader(inputStream, request.ContentEncoding)) - { - return streamReader.ReadToEnd(); - } - } + return null; } } } diff --git a/win/CS/HandBrake.Worker/Utilities/HttpUtilities.cs b/win/CS/HandBrake.Worker/Utilities/HttpUtilities.cs new file mode 100644 index 000000000..49320587a --- /dev/null +++ b/win/CS/HandBrake.Worker/Utilities/HttpUtilities.cs @@ -0,0 +1,33 @@ +// -------------------------------------------------------------------------------------------------------------------- +// <copyright file="HttpUtilities.cs" company="HandBrake Project (http://handbrake.fr)"> +// This file is part of the HandBrake source code - It may be used under the terms of the GNU General Public License. +// </copyright> +// <summary> +// Defines the HttpUtilities type. +// </summary> +// -------------------------------------------------------------------------------------------------------------------- + +namespace HandBrake.Worker.Utilities +{ + using System.IO; + using System.Net; + + public class HttpUtilities + { + public static string GetRequestPostData(HttpListenerRequest request) + { + if (!request.HasEntityBody) + { + return null; + } + + using (Stream inputStream = request.InputStream) + { + using (StreamReader streamReader = new StreamReader(inputStream, request.ContentEncoding)) + { + return streamReader.ReadToEnd(); + } + } + } + } +} diff --git a/win/CS/HandBrakeWPF/App.xaml.cs b/win/CS/HandBrakeWPF/App.xaml.cs index afec33498..2269162a2 100644 --- a/win/CS/HandBrakeWPF/App.xaml.cs +++ b/win/CS/HandBrakeWPF/App.xaml.cs @@ -129,7 +129,7 @@ namespace HandBrakeWPF }
// NO-Hardware Mode
- bool noHardware = e.Args.Any(f => f.Equals("--no-hardware")) || (Portable.IsPortable() && !Portable.IsHardwareEnabled());
+ bool noHardware = e.Args.Any(f => f.Equals("--no-hardware")) || (Portable.IsPortable() && !Portable.IsHardwareEnabled());
// Initialise the Engine
HandBrakeWPF.Helpers.LogManager.Init();
diff --git a/win/CS/HandBrakeWPF/Converters/Options/OptionsTabConverter.cs b/win/CS/HandBrakeWPF/Converters/Options/OptionsTabConverter.cs index 045c1dd22..7dc5583a7 100644 --- a/win/CS/HandBrakeWPF/Converters/Options/OptionsTabConverter.cs +++ b/win/CS/HandBrakeWPF/Converters/Options/OptionsTabConverter.cs @@ -55,6 +55,9 @@ namespace HandBrakeWPF.Converters.Options case OptionsTab.Video:
if ((OptionsTab)parameter == OptionsTab.Video) return Visibility.Visible;
break;
+ //case OptionsTab.Experimental:
+ // if ((OptionsTab)parameter == OptionsTab.Experimental) return Visibility.Visible;
+ // break;
}
}
diff --git a/win/CS/HandBrakeWPF/Helpers/LogManager.cs b/win/CS/HandBrakeWPF/Helpers/LogManager.cs index 429c5f971..2320a2944 100644 --- a/win/CS/HandBrakeWPF/Helpers/LogManager.cs +++ b/win/CS/HandBrakeWPF/Helpers/LogManager.cs @@ -15,6 +15,7 @@ namespace HandBrakeWPF.Helpers using HandBrake.Worker.Logging.Models; + using HandBrakeWPF.Services.Logging.Model; using HandBrakeWPF.Utilities; using ILog = HandBrakeWPF.Services.Logging.Interfaces.ILog; diff --git a/win/CS/HandBrakeWPF/Instance/HandBrakeInstanceManager.cs b/win/CS/HandBrakeWPF/Instance/HandBrakeInstanceManager.cs index bfcf2ecd7..914d7916f 100644 --- a/win/CS/HandBrakeWPF/Instance/HandBrakeInstanceManager.cs +++ b/win/CS/HandBrakeWPF/Instance/HandBrakeInstanceManager.cs @@ -29,9 +29,6 @@ namespace HandBrakeWPF.Instance private static HandBrakeInstance previewInstance; private static bool noHardware; - /// <summary> - /// The init. - /// </summary> public static void Init(bool noHardwareMode) { noHardware = noHardwareMode; @@ -46,7 +43,7 @@ namespace HandBrakeWPF.Instance /// The verbosity. /// </param> /// <param name="configuration"> - /// The configuratio. + /// The configuration. /// </param> /// <returns> /// The <see cref="IHandBrakeInstance"/>. diff --git a/win/CS/HandBrakeWPF/Instance/RemoteInstance.cs b/win/CS/HandBrakeWPF/Instance/RemoteInstance.cs index c65a7f2af..36221da4d 100644 --- a/win/CS/HandBrakeWPF/Instance/RemoteInstance.cs +++ b/win/CS/HandBrakeWPF/Instance/RemoteInstance.cs @@ -4,7 +4,7 @@ // </copyright> // <summary> // An Implementation of IEncodeInstance that works with a remote process rather than locally in-process. -// This class is effectivly just a shim. +// This class is effectively just a shim. // </summary> // -------------------------------------------------------------------------------------------------------------------- @@ -15,6 +15,9 @@ namespace HandBrakeWPF.Instance using System.Diagnostics; using System.Linq; using System.Net.Http; + using System.Net.Http.Headers; + using System.Runtime.CompilerServices; + using System.Text; using System.Threading.Tasks; using System.Timers; @@ -24,29 +27,30 @@ namespace HandBrakeWPF.Instance using HandBrake.Interop.Interop.Json.State; using HandBrakeWPF.Instance.Model; + using HandBrakeWPF.Utilities; using Newtonsoft.Json; /* * TODO: - * 1. Add support for logging. - * 2. Code to detect what ports are in use / select one within range. - * 3. Add support for communciating via socket instead of HTTP. + * - Handle Worker Shutdown. + * - Worker Registration Process + * - Port in Use Handling + * - Setting Configuration (libdvdnav) + * - Setting No Hardware mode */ - public class RemoteInstance : IEncodeInstance, IDisposable + public class RemoteInstance : HttpRequestBase, IEncodeInstance, IDisposable { - private const double EncodePollIntervalMs = 500; - private readonly HttpClient client = new HttpClient(); - private readonly string serverUrl; - private readonly int port; + private const double EncodePollIntervalMs = 1000; + private Process workerProcess; private Timer encodePollTimer; public RemoteInstance(int port) { this.port = port; - this.serverUrl = "http://localhost/"; + this.serverUrl = string.Format("http://127.0.0.1:{0}/", this.port); } public event EventHandler<EncodeCompletedEventArgs> EncodeCompleted; @@ -55,8 +59,8 @@ namespace HandBrakeWPF.Instance public async void PauseEncode() { - this.StopPollingProgres(); await this.MakeHttpGetRequest("PauseEncode"); + this.StopPollingProgress(); } public async void ResumeEncode() @@ -68,18 +72,17 @@ namespace HandBrakeWPF.Instance public async void StartEncode(JsonEncodeObject jobToStart) { JsonSerializerSettings settings = new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore }; - string job = JsonConvert.SerializeObject(jobToStart, Formatting.Indented, settings); + string job = JsonConvert.SerializeObject(jobToStart, Formatting.None, settings); - var values = new Dictionary<string, string> { { "jpb", job } }; - await this.MakeHttpPostRequest("StartEncode", values); + await this.MakeHttpJsonPostRequest("StartEncode", job); this.MonitorEncodeProgress(); } public async void StopEncode() { - this.StopPollingProgres(); await this.MakeHttpGetRequest("StopEncode"); + this.StopPollingProgress(); } public JsonState GetEncodeProgress() @@ -98,9 +101,9 @@ namespace HandBrakeWPF.Instance return state; } - public void Initialize(int verbosity, bool noHardware) + public void Initialize(int verbosityLvl, bool noHardwareMode) { - this.StartServer(); + this.StartServer(verbosityLvl, noHardwareMode); } public void Dispose() @@ -111,16 +114,16 @@ namespace HandBrakeWPF.Instance this.StopServer(); } - private void StartServer() + private void StartServer(int verbosityLvl, bool noHardwareMode) { if (this.workerProcess == null || this.workerProcess.HasExited) { this.workerProcess = new Process(); this.workerProcess.StartInfo = - new ProcessStartInfo("HandBrake.Worker.exe", string.Format("--port={0}", this.port)) - { - WindowStyle = ProcessWindowStyle.Normal - }; + new ProcessStartInfo("HandBrake.Worker.exe", string.Format("--port={0} --verbosity={1}", this.port, verbosityLvl)) + { + WindowStyle = ProcessWindowStyle.Normal + }; this.workerProcess.Start(); this.workerProcess.Exited += this.WorkerProcess_Exited; @@ -147,8 +150,9 @@ namespace HandBrakeWPF.Instance this.encodePollTimer.Start(); } - private void StopPollingProgres() + private void StopPollingProgress() { + this.PollEncodeProgress(); // Get the final progress state. this.encodePollTimer?.Stop(); } @@ -167,8 +171,20 @@ namespace HandBrakeWPF.Instance private async void PollEncodeProgress() { - ServerResponse response = await this.MakeHttpGetRequest("PollEncodeProgress"); - if (!response.WasSuccessful) + ServerResponse response = null; + try + { + response = await this.MakeHttpGetRequest("PollEncodeProgress"); + } + catch (Exception e) + { + if (this.encodePollTimer != null) + { + this.encodePollTimer.Stop(); + } + } + + if (response == null || !response.WasSuccessful) { return; } @@ -203,42 +219,5 @@ namespace HandBrakeWPF.Instance this.EncodeCompleted?.Invoke(sender: this, e: new EncodeCompletedEventArgs(state.WorkDone.Error != 0)); } } - - private async Task<ServerResponse> MakeHttpPostRequest(string urlPath, Dictionary<string, string> postValues) - { - if (postValues == null || !postValues.Any()) - { - throw new InvalidOperationException("No Post Values Found."); - } - - if (postValues.Any()) - { - FormUrlEncodedContent content = new FormUrlEncodedContent(postValues); - HttpResponseMessage response = await this.client.PostAsync(this.serverUrl + urlPath, content); - if (response != null) - { - string returnContent = await response.Content.ReadAsStringAsync(); - ServerResponse serverResponse = new ServerResponse(response.IsSuccessStatusCode, returnContent); - - return serverResponse; - } - } - - return null; - } - - private async Task<ServerResponse> MakeHttpGetRequest(string urlPath) - { - HttpResponseMessage response = await this.client.GetAsync(this.serverUrl + urlPath); - if (response != null) - { - string returnContent = await response.Content.ReadAsStringAsync(); - ServerResponse serverResponse = new ServerResponse(response.IsSuccessStatusCode, returnContent); - - return serverResponse; - } - - return null; - } } } diff --git a/win/CS/HandBrakeWPF/Model/OptionsTab.cs b/win/CS/HandBrakeWPF/Model/OptionsTab.cs index bcdcb4e99..bf0008ad2 100644 --- a/win/CS/HandBrakeWPF/Model/OptionsTab.cs +++ b/win/CS/HandBrakeWPF/Model/OptionsTab.cs @@ -38,5 +38,8 @@ namespace HandBrakeWPF.Model [DisplayName(typeof(Resources), "Options_About")]
About,
+
+ //[DisplayName(typeof(Resources), "Options_Experimental")]
+ //Experimental,
}
}
diff --git a/win/CS/HandBrakeWPF/Properties/Resources.Designer.cs b/win/CS/HandBrakeWPF/Properties/Resources.Designer.cs index 5d84b0c07..7a93220b5 100644 --- a/win/CS/HandBrakeWPF/Properties/Resources.Designer.cs +++ b/win/CS/HandBrakeWPF/Properties/Resources.Designer.cs @@ -2912,6 +2912,15 @@ namespace HandBrakeWPF.Properties { } /// <summary> + /// Looks up a localized string similar to Experimental. + /// </summary> + public static string Options_Experimental { + get { + return ResourceManager.GetString("Options_Experimental", resourceCulture); + } + } + + /// <summary> /// Looks up a localized string similar to File Format:. /// </summary> public static string Options_Format { @@ -3545,6 +3554,15 @@ namespace HandBrakeWPF.Properties { } /// <summary> + /// Looks up a localized string similar to Port range must be between 5000 and 32767. + /// </summary> + public static string OptionsView_RemotePortLimit { + get { + return ResourceManager.GetString("OptionsView_RemotePortLimit", resourceCulture); + } + } + + /// <summary> /// Looks up a localized string similar to Please select a folder.. /// </summary> public static string OptionsView_SelectFolder { diff --git a/win/CS/HandBrakeWPF/Properties/Resources.resx b/win/CS/HandBrakeWPF/Properties/Resources.resx index 051d217b8..193dca52a 100644 --- a/win/CS/HandBrakeWPF/Properties/Resources.resx +++ b/win/CS/HandBrakeWPF/Properties/Resources.resx @@ -2175,4 +2175,10 @@ Where supported, any user presets will have been imported.</value> <data name="OptionsView_AlwaysUseDefaultPath" xml:space="preserve">
<value>Always use the default path for each new name generated.</value>
</data>
+ <data name="OptionsView_RemotePortLimit" xml:space="preserve">
+ <value>Port range must be between 5000 and 32767</value>
+ </data>
+ <data name="Options_Experimental" xml:space="preserve">
+ <value>Experimental</value>
+ </data>
</root>
\ No newline at end of file diff --git a/win/CS/HandBrakeWPF/Services/Encode/EncodeBase.cs b/win/CS/HandBrakeWPF/Services/Encode/EncodeBase.cs index 300f27f15..22249e5e6 100644 --- a/win/CS/HandBrakeWPF/Services/Encode/EncodeBase.cs +++ b/win/CS/HandBrakeWPF/Services/Encode/EncodeBase.cs @@ -132,7 +132,7 @@ namespace HandBrakeWPF.Services.Encode string encodeDestinationPath = Path.GetDirectoryName(destination); string destinationFile = Path.GetFileName(destination); string encodeLogFile = destinationFile + " " + DateTime.Now.ToString(CultureInfo.InvariantCulture).Replace("/", "-").Replace(":", "-") + ".txt"; - string logContent = this.logService.ActivityLog; + string logContent = this.logService.GetFullLog(); // Make sure the log directory exists. if (!Directory.Exists(logDir)) diff --git a/win/CS/HandBrakeWPF/Services/Logging/EventArgs/LogEventArgs.cs b/win/CS/HandBrakeWPF/Services/Logging/EventArgs/LogEventArgs.cs index 121010e31..034d3cb90 100644 --- a/win/CS/HandBrakeWPF/Services/Logging/EventArgs/LogEventArgs.cs +++ b/win/CS/HandBrakeWPF/Services/Logging/EventArgs/LogEventArgs.cs @@ -11,7 +11,7 @@ namespace HandBrakeWPF.Services.Logging.EventArgs { using System; - using LogMessage = HandBrakeWPF.Services.Logging.Model.LogMessage; + using HandBrake.Worker.Logging.Models; /// <summary> /// The Message Logged Event Args diff --git a/win/CS/HandBrakeWPF/Services/Logging/Interfaces/ILog.cs b/win/CS/HandBrakeWPF/Services/Logging/Interfaces/ILog.cs index 07f3ea635..d82a1ed0d 100644 --- a/win/CS/HandBrakeWPF/Services/Logging/Interfaces/ILog.cs +++ b/win/CS/HandBrakeWPF/Services/Logging/Interfaces/ILog.cs @@ -12,15 +12,17 @@ namespace HandBrakeWPF.Services.Logging.Interfaces using System; using System.Collections.Generic; + using HandBrake.Worker.Logging.Interfaces; using HandBrake.Worker.Logging.Models; + using HandBrakeWPF.Services.Logging.Model; + using LogEventArgs = HandBrakeWPF.Services.Logging.EventArgs.LogEventArgs; - using LogMessage = HandBrakeWPF.Services.Logging.Model.LogMessage; /// <summary> /// The Log interface. /// </summary> - public interface ILog + public interface ILog : ILogHandler { /// <summary> /// The message logged. @@ -33,21 +35,6 @@ namespace HandBrakeWPF.Services.Logging.Interfaces event EventHandler LogReset; /// <summary> - /// Gets the log messages. - /// </summary> - IEnumerable<LogMessage> LogMessages { get; } - - /// <summary> - /// Gets the activity log. - /// </summary> - string ActivityLog { get; } - - /// <summary> - /// The reset. - /// </summary> - void Reset(); - - /// <summary> /// Enable logging for this worker process. /// </summary> /// <param name="config"> diff --git a/win/CS/HandBrakeWPF/Services/Logging/LogService.cs b/win/CS/HandBrakeWPF/Services/Logging/LogService.cs index 3bc4c2b5b..c11b764b0 100644 --- a/win/CS/HandBrakeWPF/Services/Logging/LogService.cs +++ b/win/CS/HandBrakeWPF/Services/Logging/LogService.cs @@ -18,16 +18,23 @@ namespace HandBrakeWPF.Services.Logging using System.IO; using System.Linq; using System.Text; + using System.Timers; using HandBrake.Interop.Interop; using HandBrake.Interop.Interop.EventArgs; using HandBrake.Worker.Logging.Models; + using HandBrakeWPF.Instance.Model; + using HandBrakeWPF.Services.Interfaces; + using HandBrakeWPF.Services.Logging.Model; + using HandBrakeWPF.Utilities; + + using Newtonsoft.Json; + using ILog = Interfaces.ILog; using LogEventArgs = EventArgs.LogEventArgs; - using LogMessage = Model.LogMessage; - public class LogService : ILog + public class LogService : HttpRequestBase, ILog { // TODO List. // Maybe make the event weak? @@ -39,17 +46,29 @@ namespace HandBrakeWPF.Services.Logging private bool isLoggingEnabled; private List<LogMessage> logMessages = new List<LogMessage>(); - private long messageIndex; + private int messageIndex; private string diskLogPath; private bool deleteLogFirst; private bool isDiskLoggingEnabled; private StreamWriter fileWriter; private string logHeader; + private Timer remoteLogPollTimer; + private int remoteIndex = 0; + private bool isRemotePollingEnabled = false; - public LogService() + public LogService(IUserSettingService userSettingService) { HandBrakeUtils.MessageLogged += this.HandBrakeUtils_MessageLogged; HandBrakeUtils.ErrorLogged += this.HandBrakeUtils_ErrorLogged; + + if (userSettingService.GetUserSetting<bool>(UserSettingConstants.RemoteServiceEnabled)) + { + this.ActivateRemoteLogPolling(); + this.isRemotePollingEnabled = true; + + this.port = userSettingService.GetUserSetting<int>(UserSettingConstants.RemoteServicePort); + this.serverUrl = string.Format("http://127.0.0.1:{0}/", this.port); + } } public event EventHandler<LogEventArgs> MessageLogged; @@ -67,17 +86,6 @@ namespace HandBrakeWPF.Services.Logging } } - public string ActivityLog - { - get - { - lock (this.lockObject) - { - return this.logBuilder.ToString(); - } - } - } - public void LogMessage(string content) { if (!this.isLoggingEnabled) @@ -85,7 +93,6 @@ namespace HandBrakeWPF.Services.Logging return; } - LogMessage msg = new LogMessage(content, this.messageIndex); lock (this.lockObject) { @@ -127,10 +134,64 @@ namespace HandBrakeWPF.Services.Logging this.LogMessage(config.Header); } - public void Reset() + public string GetFullLog() { lock (this.lockObject) { + return this.logBuilder.ToString(); + } + } + + public List<LogMessage> GetLogMessages() + { + lock (this.lockObject) + { + return new List<LogMessage>(this.logMessages); + } + } + + public List<LogMessage> GetLogMessagesFromIndex(int index) + { + List<LogMessage> log = new List<LogMessage>(); + lock (this.lockObject) + { + // Note messageIndex is not 0 based. + for (int i = index; i < this.messageIndex; i++) + { + log.Add(this.logMessages[i]); + } + } + + return log; + } + + public long GetLatestLogIndex() + { + lock (this.lockObject) + { + return this.messageIndex; + } + } + + public async void Reset() + { + //if (this.isRemotePollingEnabled) + //{ + // try + // { + // await this.MakeHttpGetRequest("ResetLogging"); + // } + // catch (Exception e) + // { + // if (this.remoteLogPollTimer != null) + // { + // this.remoteLogPollTimer.Stop(); + // } + // } + //} + + lock (this.lockObject) + { this.logMessages.Clear(); this.logBuilder.Clear(); this.messageIndex = 0; @@ -297,5 +358,62 @@ namespace HandBrakeWPF.Services.Logging this.LogMessage(e.Message); } + + private void ActivateRemoteLogPolling() + { + this.remoteLogPollTimer = new Timer(); + this.remoteLogPollTimer.Interval = 1000; + + this.remoteLogPollTimer.Elapsed += (o, e) => + { + try + { + this.PollRemoteLog(); + } + catch (Exception exc) + { + Debug.WriteLine(exc); + } + }; + this.remoteLogPollTimer.Start(); + } + + private async void PollRemoteLog() + { + ServerResponse response = null; + try + { + int nextIndex = this.remoteIndex + 1; + string json = JsonConvert.SerializeObject(nextIndex, Formatting.Indented, this.jsonNetSettings); + + response = await this.MakeHttpJsonPostRequest("GetLogMessagesFromIndex", json); + } + catch (Exception e) + { + Debug.WriteLine("No Endpoint"); + } + + if (response == null || !response.WasSuccessful) + { + return; + } + + string statusJson = response.JsonResponse; + + List<LogMessage> messages = null; + if (!string.IsNullOrEmpty(statusJson)) + { + messages = JsonConvert.DeserializeObject<List<LogMessage>>(statusJson, this.jsonNetSettings); + } + + if (messages != null) + { + foreach (var item in messages) + { + this.LogMessage(item.Content); + this.remoteIndex = item.MessageIndex; + } + } + } } } diff --git a/win/CS/HandBrake.Worker/Logging/Models/LogHandlerConfig.cs b/win/CS/HandBrakeWPF/Services/Logging/Model/LogHandlerConfig.cs index 2cbb97cb3..183590ca1 100644 --- a/win/CS/HandBrake.Worker/Logging/Models/LogHandlerConfig.cs +++ b/win/CS/HandBrakeWPF/Services/Logging/Model/LogHandlerConfig.cs @@ -7,7 +7,7 @@ // </summary> // -------------------------------------------------------------------------------------------------------------------- -namespace HandBrake.Worker.Logging.Models +namespace HandBrakeWPF.Services.Logging.Model { public class LogHandlerConfig { @@ -31,4 +31,4 @@ namespace HandBrake.Worker.Logging.Models public string Header { get; set; } } -} +}
\ No newline at end of file diff --git a/win/CS/HandBrakeWPF/Services/Logging/Model/LogMessage.cs b/win/CS/HandBrakeWPF/Services/Logging/Model/LogMessage.cs deleted file mode 100644 index 51e5a1cb6..000000000 --- a/win/CS/HandBrakeWPF/Services/Logging/Model/LogMessage.cs +++ /dev/null @@ -1,42 +0,0 @@ -// -------------------------------------------------------------------------------------------------------------------- -// <copyright file="LogMessage.cs" company="HandBrake Project (http://handbrake.fr)"> -// This file is part of the HandBrake source code - It may be used under the terms of the GNU General Public License. -// </copyright> -// <summary> -// The message. -// </summary> -// -------------------------------------------------------------------------------------------------------------------- - -namespace HandBrakeWPF.Services.Logging.Model -{ - /// <summary> - /// An Immutable Log Entry. - /// </summary> - public class LogMessage - { - /// <summary> - /// Initializes a new instance of the <see cref="LogMessage"/> class. - /// </summary> - /// <param name="content"> - /// The content. - /// </param> - /// <param name="messageIndex"> - /// The message Index. - /// </param> - public LogMessage(string content, long messageIndex) - { - this.Content = content; - this.MessageIndex = messageIndex; - } - - /// <summary> - /// Gets the content. - /// </summary> - public string Content { get; private set; } - - /// <summary> - /// Gets the message index. - /// </summary> - public long MessageIndex { get; private set; } - } -} diff --git a/win/CS/HandBrakeWPF/Services/PrePostActionService.cs b/win/CS/HandBrakeWPF/Services/PrePostActionService.cs index 57be5051e..636f82d7b 100644 --- a/win/CS/HandBrakeWPF/Services/PrePostActionService.cs +++ b/win/CS/HandBrakeWPF/Services/PrePostActionService.cs @@ -17,15 +17,9 @@ namespace HandBrakeWPF.Services using Caliburn.Micro;
- using HandBrake.Interop.Utilities;
-
using HandBrakeWPF.EventArgs;
- using HandBrakeWPF.Instance;
using HandBrakeWPF.Model.Options;
- using HandBrakeWPF.Properties;
using HandBrakeWPF.Services.Interfaces;
- using HandBrakeWPF.Services.Logging;
- using HandBrakeWPF.Services.Logging.Model;
using HandBrakeWPF.Services.Queue.Interfaces;
using HandBrakeWPF.Services.Scan.Interfaces;
using HandBrakeWPF.Utilities;
diff --git a/win/CS/HandBrakeWPF/Services/Presets/PresetService.cs b/win/CS/HandBrakeWPF/Services/Presets/PresetService.cs index 8b4a1ba68..6c715fa8f 100644 --- a/win/CS/HandBrakeWPF/Services/Presets/PresetService.cs +++ b/win/CS/HandBrakeWPF/Services/Presets/PresetService.cs @@ -33,7 +33,6 @@ namespace HandBrakeWPF.Services.Presets using HandBrakeWPF.Services.Interfaces;
using HandBrakeWPF.Services.Logging;
using HandBrakeWPF.Services.Logging.Interfaces;
- using HandBrakeWPF.Services.Logging.Model;
using HandBrakeWPF.Services.Presets.Factories;
using HandBrakeWPF.Services.Presets.Interfaces;
using HandBrakeWPF.Services.Presets.Model;
diff --git a/win/CS/HandBrakeWPF/Services/SystemService.cs b/win/CS/HandBrakeWPF/Services/SystemService.cs index 587a82128..2eb5bebb3 100644 --- a/win/CS/HandBrakeWPF/Services/SystemService.cs +++ b/win/CS/HandBrakeWPF/Services/SystemService.cs @@ -10,20 +10,14 @@ namespace HandBrakeWPF.Services { using System; - using System.Runtime.CompilerServices; using System.Timers; using HandBrakeWPF.Properties; using HandBrakeWPF.Services.Encode.Interfaces; - using HandBrakeWPF.Services.Encode.Model; using HandBrakeWPF.Services.Interfaces; - using HandBrakeWPF.Services.Logging; using HandBrakeWPF.Services.Logging.Interfaces; - using HandBrakeWPF.Services.Logging.Model; using HandBrakeWPF.Utilities; - using Ookii.Dialogs.Wpf; - public class SystemService : ISystemService { private readonly IUserSettingService userSettingService; diff --git a/win/CS/HandBrakeWPF/Utilities/HttpRequestBase.cs b/win/CS/HandBrakeWPF/Utilities/HttpRequestBase.cs new file mode 100644 index 000000000..cc2898b43 --- /dev/null +++ b/win/CS/HandBrakeWPF/Utilities/HttpRequestBase.cs @@ -0,0 +1,62 @@ +// -------------------------------------------------------------------------------------------------------------------- +// <copyright file="HttpRequestBase.cs" company="HandBrake Project (http://handbrake.fr)"> +// This file is part of the HandBrake source code - It may be used under the terms of the GNU General Public License. +// </copyright> +// <summary> +// Defines the HttpRequestBase type. +// </summary> +// -------------------------------------------------------------------------------------------------------------------- + +namespace HandBrakeWPF.Utilities +{ + using System; + using System.Net.Http; + using System.Text; + using System.Threading.Tasks; + + using HandBrakeWPF.Instance.Model; + + using Newtonsoft.Json; + + public class HttpRequestBase + { + protected readonly JsonSerializerSettings jsonNetSettings = new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore }; + protected HttpClient client = new HttpClient(); + protected string serverUrl; + protected int port; + + public async Task<ServerResponse> MakeHttpJsonPostRequest(string urlPath, string json) + { + if (string.IsNullOrEmpty(json)) + { + throw new InvalidOperationException("No Post Values Found."); + } + + StringContent content = new StringContent(json, Encoding.UTF8, "application/json"); + HttpResponseMessage response = await client.PostAsync(this.serverUrl + urlPath, content); + if (response != null) + { + string returnContent = await response.Content.ReadAsStringAsync(); + ServerResponse serverResponse = new ServerResponse(response.IsSuccessStatusCode, returnContent); + + return serverResponse; + } + + return null; + } + + public async Task<ServerResponse> MakeHttpGetRequest(string urlPath) + { + HttpResponseMessage response = await client.GetAsync(this.serverUrl + urlPath); + if (response != null) + { + string returnContent = await response.Content.ReadAsStringAsync(); + ServerResponse serverResponse = new ServerResponse(response.IsSuccessStatusCode, returnContent); + + return serverResponse; + } + + return null; + } + } +} diff --git a/win/CS/HandBrakeWPF/ViewModels/LogViewModel.cs b/win/CS/HandBrakeWPF/ViewModels/LogViewModel.cs index 0e8d5ab6a..baead2f52 100644 --- a/win/CS/HandBrakeWPF/ViewModels/LogViewModel.cs +++ b/win/CS/HandBrakeWPF/ViewModels/LogViewModel.cs @@ -16,6 +16,8 @@ namespace HandBrakeWPF.ViewModels using Caliburn.Micro;
+ using HandBrake.Worker.Logging.Models;
+
using HandBrakeWPF.Properties;
using HandBrakeWPF.Services.Interfaces;
using HandBrakeWPF.Utilities;
@@ -23,7 +25,6 @@ namespace HandBrakeWPF.ViewModels using ILog = HandBrakeWPF.Services.Logging.Interfaces.ILog;
using LogEventArgs = HandBrakeWPF.Services.Logging.EventArgs.LogEventArgs;
- using LogMessage = HandBrakeWPF.Services.Logging.Model.LogMessage;
using LogService = HandBrakeWPF.Services.Logging.LogService;
/// <summary>
@@ -96,7 +97,7 @@ namespace HandBrakeWPF.ViewModels // Refresh the Log Display
this.log.Clear();
- foreach (LogMessage logMessage in this.logService.LogMessages)
+ foreach (LogMessage logMessage in this.logService.GetLogMessages())
{
this.log.AppendLine(logMessage.Content);
this.lastReadIndex = logMessage.MessageIndex;
@@ -156,7 +157,7 @@ namespace HandBrakeWPF.ViewModels this.log.Clear();
this.lastReadIndex = 0;
- foreach (LogMessage logMessage in this.logService.LogMessages)
+ foreach (LogMessage logMessage in this.logService.GetLogMessages())
{
this.log.AppendLine(logMessage.Content);
this.lastReadIndex = logMessage.MessageIndex;
diff --git a/win/CS/HandBrakeWPF/ViewModels/OptionsViewModel.cs b/win/CS/HandBrakeWPF/ViewModels/OptionsViewModel.cs index 5513d37ed..2a3166554 100644 --- a/win/CS/HandBrakeWPF/ViewModels/OptionsViewModel.cs +++ b/win/CS/HandBrakeWPF/ViewModels/OptionsViewModel.cs @@ -109,6 +109,10 @@ namespace HandBrakeWPF.ViewModels private bool useDarkTheme;
private bool alwaysUseDefaultPath;
+ // Experimental
+ private int remoteServicePort;
+ private bool remoteServiceEnabled;
+
#endregion
#region Constructors and Destructors
@@ -1265,6 +1269,47 @@ namespace HandBrakeWPF.ViewModels #endregion
+ // Experimental
+ public bool RemoteServiceEnabled
+ {
+ get => this.remoteServiceEnabled;
+ set
+ {
+ if (value == this.remoteServiceEnabled)
+ {
+ return;
+ }
+
+ this.remoteServiceEnabled = value;
+ this.NotifyOfPropertyChange(() => this.RemoteServiceEnabled);
+ }
+ }
+
+ public int RemoteServicePort
+ {
+ get => this.remoteServicePort;
+ set
+ {
+ if (value == this.remoteServicePort)
+ {
+ return;
+ }
+
+ if (value > 32767 || value < 5000)
+ {
+ this.errorService.ShowMessageBox(
+ Resources.OptionsView_RemotePortLimit,
+ Resources.Error,
+ MessageBoxButton.OK,
+ MessageBoxImage.Error);
+ return; // Allow only valid ports, not in the ephemeral range
+ }
+
+ this.remoteServicePort = value;
+ this.NotifyOfPropertyChange(() => this.RemoteServicePort);
+ }
+ }
+
#region Public Methods
/// <summary>
@@ -1572,6 +1617,12 @@ namespace HandBrakeWPF.ViewModels // Use dvdnav
this.DisableLibdvdNav = userSettingService.GetUserSetting<bool>(UserSettingConstants.DisableLibDvdNav);
+
+ // #############################
+ // Experimental
+ // #############################
+ this.RemoteServiceEnabled = this.userSettingService.GetUserSetting<bool>(UserSettingConstants.RemoteServiceEnabled);
+ this.RemoteServicePort = userSettingService.GetUserSetting<int>(UserSettingConstants.RemoteServicePort);
}
/// <summary>
@@ -1677,6 +1728,10 @@ namespace HandBrakeWPF.ViewModels }
this.userSettingService.SetUserSetting(UserSettingConstants.DisableLibDvdNav, this.DisableLibdvdNav);
+
+ /* Experimental */
+ this.userSettingService.SetUserSetting(UserSettingConstants.RemoteServiceEnabled, this.RemoteServiceEnabled);
+ this.userSettingService.SetUserSetting(UserSettingConstants.RemoteServicePort, this.RemoteServicePort);
}
/// <summary>
diff --git a/win/CS/HandBrakeWPF/Views/OptionsView.xaml b/win/CS/HandBrakeWPF/Views/OptionsView.xaml index ef383956e..479e4c7e4 100644 --- a/win/CS/HandBrakeWPF/Views/OptionsView.xaml +++ b/win/CS/HandBrakeWPF/Views/OptionsView.xaml @@ -456,6 +456,24 @@ <ContentControl x:Name="AboutViewModel" />
</StackPanel>
+
+ <!--<StackPanel Name="Experimental" Orientation="Vertical" Margin="10,5,0,0"
+ Visibility="{Binding SelectedTab, Converter={StaticResource tabConverter}, ConverterParameter={x:Static local:OptionsTab.Experimental}}">
+
+ <TextBlock Text="{x:Static Properties:Resources.Options_Experimental}" FontSize="20" FontFamily="Segoe UI Light" />
+
+ <TextBlock Text="WARNING: Experimental features are not recommended for daily use. These are very early development previews of potential future features." FontWeight="Bold" Margin="0,10,0,0" />
+
+ <TextBlock Text="Worker Processes" FontSize="14" Margin="0,20,0,10"/>
+
+ <CheckBox Content="Enable Worker Processes. (All encodes will be performed on a seperate worker process)" IsChecked="{Binding RemoteServiceEnabled}" Margin="10,5,0,0" />
+
+ <StackPanel Orientation="Horizontal" Margin="10,10,0,0">
+ <TextBlock Text="Worker Process Port: " />
+ <TextBox Text="{Binding RemoteServicePort}" Width="100" />
+ </StackPanel>
+
+ </StackPanel>-->
</StackPanel>
</ScrollViewer>
diff --git a/win/CS/HandBrakeWPF/defaultsettings.xml b/win/CS/HandBrakeWPF/defaultsettings.xml index c560f1df0..a27ea4156 100644 --- a/win/CS/HandBrakeWPF/defaultsettings.xml +++ b/win/CS/HandBrakeWPF/defaultsettings.xml @@ -477,7 +477,7 @@ <string>RemoteServicePort</string>
</key>
<value>
- <anyType xmlns:q1="http://www.w3.org/2001/XMLSchema" d4p1:type="q1:int" xmlns:d4p1="http://www.w3.org/2001/XMLSchema-instance">8080</anyType>
+ <anyType xmlns:q1="http://www.w3.org/2001/XMLSchema" d4p1:type="q1:int" xmlns:d4p1="http://www.w3.org/2001/XMLSchema-instance">8387</anyType>
</value>
</item>
|