// --------------------------------------------------------------------------------------------------------------------
//
// This file is part of the HandBrake source code - It may be used under the terms of the GNU General Public License.
//
//
// A Base Class for the Encode Services.
//
// --------------------------------------------------------------------------------------------------------------------
namespace HandBrake.ApplicationServices.Services.Encode
{
using System;
using System.Diagnostics;
using System.IO;
using System.Text;
using HandBrake.ApplicationServices.Exceptions;
using HandBrake.ApplicationServices.Model;
using HandBrake.ApplicationServices.Services.Encode.EventArgs;
using HandBrake.ApplicationServices.Services.Encode.Interfaces;
using HandBrake.ApplicationServices.Services.Encode.Model;
using HandBrake.ApplicationServices.Utilities;
///
/// A Base Class for the Encode Services.
///
public class EncodeBase
{
#region Private Variables
///
/// A Lock for the filewriter
///
private static readonly object FileWriterLock = new object();
///
/// The Log File Header
///
private readonly StringBuilder header;
///
/// The Log Buffer
///
private StringBuilder logBuffer;
///
/// The Log file writer
///
private StreamWriter fileWriter;
#endregion
///
/// Initializes a new instance of the class.
///
public EncodeBase()
{
this.logBuffer = new StringBuilder();
this.header = GeneralUtilities.CreateLogHeader();
this.LogIndex = 0;
}
#region Events
///
/// Fires when a new QueueTask starts
///
public event EventHandler EncodeStarted;
///
/// Fires when a QueueTask finishes.
///
public event EncodeCompletedStatus EncodeCompleted;
///
/// Encode process has progressed
///
public event EncodeProgessStatus EncodeStatusChanged;
#endregion
#region Properties
///
/// Gets or sets a value indicating whether IsEncoding.
///
public bool IsEncoding { get; protected set; }
///
/// Gets ActivityLog.
///
public string ActivityLog
{
get
{
string noLog = "There is no log information to display." + Environment.NewLine + Environment.NewLine
+ "This window will only display logging information after you have started an encode." + Environment.NewLine
+ Environment.NewLine + "You can find previous log files in the log directory or by clicking the 'Open Log Directory' button above.";
return string.IsNullOrEmpty(this.logBuffer.ToString())
? noLog
: this.header + this.logBuffer.ToString();
}
}
///
/// Gets the log index.
///
public int LogIndex { get; private set; }
///
/// Gets LogBuffer.
///
public StringBuilder LogBuffer
{
get
{
return this.logBuffer;
}
}
#endregion
#region Invoke Events
///
/// Invoke the Encode Status Changed Event.
///
///
/// The EncodeProgressEventArgs.
///
public void InvokeEncodeStatusChanged(EncodeProgressEventArgs e)
{
EncodeProgessStatus handler = this.EncodeStatusChanged;
if (handler != null)
{
handler(this, e);
}
}
///
/// Invoke the Encode Completed Event
///
///
/// The EncodeCompletedEventArgs.
///
public void InvokeEncodeCompleted(EncodeCompletedEventArgs e)
{
EncodeCompletedStatus handler = this.EncodeCompleted;
if (handler != null)
{
handler(this, e);
}
this.LogIndex = 0; // Reset
}
///
/// Invoke the Encode Started Event
///
///
/// The EventArgs.
///
public void InvokeEncodeStarted(System.EventArgs e)
{
EventHandler handler = this.EncodeStarted;
if (handler != null)
{
handler(this, e);
}
}
#endregion
#region Methods
///
/// A Stop Method to be implemeneted.
///
public virtual void Stop()
{
// Do Nothing
}
///
/// Save a copy of the log to the users desired location or a default location
/// if this feature is enabled in options.
///
///
/// The Destination File Path
///
///
/// The configuration.
///
public void ProcessLogs(string destination, HBConfiguration configuration)
{
try
{
string logDir = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) +
"\\HandBrake\\logs";
string tempLogFile = Path.Combine(logDir, string.Format("last_encode_log{0}.txt", GeneralUtilities.ProcessId));
string encodeDestinationPath = Path.GetDirectoryName(destination);
string destinationFile = Path.GetFileName(destination);
string encodeLogFile = destinationFile + " " +
DateTime.Now.ToString().Replace("/", "-").Replace(":", "-") + ".txt";
// Make sure the log directory exists.
if (!Directory.Exists(logDir))
{
Directory.CreateDirectory(logDir);
}
// Copy the Log to HandBrakes log folder in the users applciation data folder.
File.Copy(tempLogFile, Path.Combine(logDir, encodeLogFile));
// Save a copy of the log file in the same location as the enocde.
if (configuration.SaveLogWithVideo)
{
File.Copy(tempLogFile, Path.Combine(encodeDestinationPath, encodeLogFile));
}
// Save a copy of the log file to a user specified location
if (Directory.Exists(configuration.SaveLogCopyDirectory) && configuration.SaveLogToCopyDirectory)
{
File.Copy(
tempLogFile, Path.Combine(configuration.SaveLogCopyDirectory, encodeLogFile));
}
}
catch (Exception exc)
{
Debug.WriteLine(exc); // This exception doesn't warrent user interaction, but it should be logged
}
}
///
/// Setup the logging.
///
protected void SetupLogging()
{
this.ShutdownFileWriter();
string logDir = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "\\HandBrake\\logs";
string logFile = Path.Combine(logDir, string.Format("last_encode_log{0}.txt", GeneralUtilities.ProcessId));
string logFile2 = Path.Combine(logDir, string.Format("tmp_appReadable_log{0}.txt", GeneralUtilities.ProcessId));
try
{
this.logBuffer = new StringBuilder();
this.logBuffer.AppendLine();
// Clear the current Encode Logs)
if (File.Exists(logFile))
{
File.Delete(logFile);
}
if (File.Exists(logFile2))
{
File.Delete(logFile2);
}
lock (FileWriterLock)
{
this.fileWriter = new StreamWriter(logFile) { AutoFlush = true };
this.fileWriter.WriteLine(this.header);
this.fileWriter.WriteLine();
}
}
catch (Exception)
{
if (this.fileWriter != null)
{
lock (FileWriterLock)
{
this.fileWriter.Flush();
this.fileWriter.Close();
this.fileWriter.Dispose();
}
}
throw;
}
}
///
/// The service log message.
///
///
/// The message.
///
protected void ServiceLogMessage(string message)
{
this.ProcessLogMessage(string.Format("# {0}", message));
}
///
/// Process an Incomming Log Message.
///
///
/// The message.
///
protected void ProcessLogMessage(string message)
{
if (!string.IsNullOrEmpty(message))
{
try
{
this.LogIndex = this.LogIndex + 1;
lock (this.LogBuffer)
{
this.LogBuffer.AppendLine(message);
}
lock (FileWriterLock)
{
if (this.fileWriter != null && this.fileWriter.BaseStream.CanWrite)
{
this.fileWriter.WriteLine(message);
}
}
}
catch (Exception exc)
{
Debug.WriteLine(exc); // This exception doesn't warrent user interaction, but it should be logged
}
}
}
///
/// Shutdown and Dispose of the File Writer.
///
protected void ShutdownFileWriter()
{
try
{
lock (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 warrent user interaction, but it should be logged
}
}
///
/// Verify the Encode Destination path exists and if not, create it.
///
///
/// The task.
///
///
/// If the creation fails, an exception is thrown.
///
protected void VerifyEncodeDestinationPath(EncodeTask task)
{
// Make sure the path exists, attempt to create it if it doesn't
try
{
string path = Directory.GetParent(task.Destination).ToString();
if (!Directory.Exists(path))
{
Directory.CreateDirectory(path);
}
}
catch (Exception exc)
{
throw new GeneralApplicationException(
"Unable to create directory for the encoded output.", "Please verify that you have a valid path.", exc);
}
}
#endregion
}
}