From 0c9a71f626e0e552cf670103b8dad8e61de1fb69 Mon Sep 17 00:00:00 2001 From: sr55 Date: Sun, 6 Jun 2010 18:22:39 +0000 Subject: WinGui: - Moved all the services that handle parsing, scanning, encodes and the queue out into a separate library. git-svn-id: svn://svn.handbrake.fr/HandBrake/trunk@3362 b64f7644-9d1e-0410-96f1-a4d463321fa5 --- .../Services/Queue.cs | 410 +++++++++++++++++++++ 1 file changed, 410 insertions(+) create mode 100644 win/C#/HandBrake.ApplicationServices/Services/Queue.cs (limited to 'win/C#/HandBrake.ApplicationServices/Services/Queue.cs') diff --git a/win/C#/HandBrake.ApplicationServices/Services/Queue.cs b/win/C#/HandBrake.ApplicationServices/Services/Queue.cs new file mode 100644 index 000000000..f61bb6e29 --- /dev/null +++ b/win/C#/HandBrake.ApplicationServices/Services/Queue.cs @@ -0,0 +1,410 @@ +/* Queue.cs $ + This file is part of the HandBrake source code. + Homepage: . + It may be used under the terms of the GNU General Public License. */ + +namespace HandBrake.ApplicationServices.Services +{ + using System; + using System.Collections.Generic; + using System.Collections.ObjectModel; + using System.IO; + using System.Linq; + using System.Threading; + using System.Windows.Forms; + using System.Xml.Serialization; + + using HandBrake.ApplicationServices.Functions; + using HandBrake.ApplicationServices.Model; + + /// + /// The HandBrake Queue + /// + public class Queue : Encode + { + /// + /// The Queue Job List + /// + private readonly List queue = new List(); + + /// + /// An XML Serializer + /// + private static XmlSerializer serializer; + + /// + /// The Next Job ID + /// + private int nextJobId; + + /// + /// Fires when the Queue has started + /// + public event EventHandler QueueStarted; + + /// + /// Fires when a job is Added, Removed or Re-Ordered. + /// Should be used for triggering an update of the Queue Window. + /// + public event EventHandler QueueListChanged; + + /// + /// Fires when a pause to the encode queue has been requested. + /// + public event EventHandler QueuePauseRequested; + + /// + /// Fires when the entire encode queue has completed. + /// + public event EventHandler QueueCompleted; + + #region Properties + /// + /// Gets or sets the last encode that was processed. + /// + /// + public Job LastEncode { get; set; } + + /// + /// Gets a value indicating whether Request Pause + /// + public bool Paused { get; private set; } + + /// + /// Gets the current state of the encode queue. + /// + public ReadOnlyCollection CurrentQueue + { + get { return this.queue.AsReadOnly(); } + } + + /// + /// Gets the number of items in the queue. + /// + public int Count + { + get { return this.queue.Count; } + } + #endregion + + #region Queue + + /// + /// Gets and removes the next job in the queue. + /// + /// The job that was removed from the queue. + private Job GetNextJob() + { + Job job = this.queue[0]; + this.LastEncode = job; + this.Remove(0); // Remove the item which we are about to pass out. + + this.WriteQueueStateToFile("hb_queue_recovery.xml"); + + return job; + } + + /// + /// Adds an item to the queue. + /// + /// + /// The query that will be passed to the HandBrake CLI. + /// + /// + /// The title. + /// + /// + /// The location of the source video. + /// + /// + /// The location where the encoded video will be. + /// + /// + /// Custom job + /// + public void Add(string query, int title, string source, string destination, bool customJob) + { + Job newJob = new Job + { + Id = this.nextJobId++, + Title = title, + Query = query, + Source = source, + Destination = destination, + CustomQuery = customJob + }; + + this.queue.Add(newJob); + this.WriteQueueStateToFile("hb_queue_recovery.xml"); + + if (this.QueueListChanged != null) + this.QueueListChanged(this, new EventArgs()); + } + + /// + /// Removes an item from the queue. + /// + /// The zero-based location of the job in the queue. + public void Remove(int index) + { + this.queue.RemoveAt(index); + this.WriteQueueStateToFile("hb_queue_recovery.xml"); + + if (this.QueueListChanged != null) + this.QueueListChanged(this, new EventArgs()); + } + + /// + /// Retrieve a job from the queue + /// + /// the job id + /// A job for the given index or blank job object + public Job GetJob(int index) + { + if (this.queue.Count >= (index + 1)) + return this.queue[index]; + + return new Job(); + } + + /// + /// Moves an item up one position in the queue. + /// + /// The zero-based location of the job in the queue. + public void MoveUp(int index) + { + if (index > 0) + { + Job item = queue[index]; + + queue.RemoveAt(index); + queue.Insert((index - 1), item); + } + + WriteQueueStateToFile("hb_queue_recovery.xml"); // Update the queue recovery file + + if (this.QueueListChanged != null) + this.QueueListChanged(this, new EventArgs()); + } + + /// + /// Moves an item down one position in the queue. + /// + /// The zero-based location of the job in the queue. + public void MoveDown(int index) + { + if (index < this.queue.Count - 1) + { + Job item = this.queue[index]; + + this.queue.RemoveAt(index); + this.queue.Insert((index + 1), item); + } + + this.WriteQueueStateToFile("hb_queue_recovery.xml"); // Update the queue recovery file + + if (this.QueueListChanged != null) + this.QueueListChanged(this, new EventArgs()); + } + + /// + /// Writes the current state of the queue to a file. + /// + /// The location of the file to write the queue to. + public void WriteQueueStateToFile(string file) + { + string appDataPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), + @"HandBrake\hb_queue_recovery.xml"); + string tempPath = file == "hb_queue_recovery.xml" ? appDataPath : file; + + try + { + using (FileStream strm = new FileStream(tempPath, FileMode.Create, FileAccess.Write)) + { + if (serializer == null) + serializer = new XmlSerializer(typeof(List)); + serializer.Serialize(strm, queue); + strm.Close(); + strm.Dispose(); + } + } + catch (Exception) + { + return; + } + } + + /// + /// Writes the current state of the queue in the form of a batch (.bat) file. + /// + /// The location of the file to write the batch file to. + public bool WriteBatchScriptToFile(string file) + { + string queries = string.Empty; + foreach (Job queueItem in this.queue) + { + string qItem = queueItem.Query; + string fullQuery = '"' + Application.StartupPath + "\\HandBrakeCLI.exe" + '"' + qItem; + + if (queries == string.Empty) + queries = queries + fullQuery; + else + queries = queries + " && " + fullQuery; + } + string strCmdLine = queries; + + if (file != string.Empty) + { + try + { + // Create a StreamWriter and open the file, Write the batch file query to the file and + // Close the stream + using (StreamWriter line = new StreamWriter(file)) + { + line.WriteLine(strCmdLine); + } + + return true; + } + catch (Exception exc) + { + Main.ShowExceptiowWindow("Unable to write to the file. Please make sure that the location has the correct permissions for file writing.", exc.ToString()); + } + } + return false; + } + + /// + /// Reads a serialized XML file that represents a queue of encoding jobs. + /// + /// The location of the file to read the queue from. + public void LoadQueueFromFile(string file) + { + string appDataPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), + @"HandBrake\hb_queue_recovery.xml"); + string tempPath = file == "hb_queue_recovery.xml" ? appDataPath : file; + + if (File.Exists(tempPath)) + { + using (FileStream strm = new FileStream(tempPath, FileMode.Open, FileAccess.Read)) + { + if (strm.Length != 0) + { + if (serializer == null) + serializer = new XmlSerializer(typeof(List)); + + List list = serializer.Deserialize(strm) as List; + + if (list != null) + foreach (Job item in list) + this.queue.Add(item); + + if (file != "hb_queue_recovery.xml") + this.WriteQueueStateToFile("hb_queue_recovery.xml"); + } + } + } + } + + /// + /// Checks the current queue for an existing instance of the specified destination. + /// + /// The destination of the encode. + /// Whether or not the supplied destination is already in the queue. + public bool CheckForDestinationDuplicate(string destination) + { + return this.queue.Any(checkItem => checkItem.Destination.Contains(destination.Replace("\\\\", "\\"))); + } + + #endregion + + #region Encoding + + /// + /// Starts encoding the first job in the queue and continues encoding until all jobs + /// have been encoded. + /// + public void Start() + { + if (this.Count != 0) + { + if (this.Paused) + this.Paused = false; + else + { + this.Paused = false; + try + { + Thread theQueue = new Thread(this.StartQueue) { IsBackground = true }; + theQueue.Start(); + + if (this.QueueStarted != null) + this.QueueStarted(this, new EventArgs()); + } + catch (Exception exc) + { + Main.ShowExceptiowWindow("Unable to Start Queue", exc.ToString()); + } + } + } + } + + /// + /// Requests a pause of the encode queue. + /// + public void Pause() + { + this.Paused = true; + + if (this.QueuePauseRequested != null) + this.QueuePauseRequested(this, new EventArgs()); + } + + /// + /// Run through all the jobs on the queue. + /// + /// Object State + private void StartQueue(object state) + { + // Run through each item on the queue + while (this.Count != 0) + { + Job encJob = this.GetNextJob(); + this.WriteQueueStateToFile("hb_queue_recovery.xml"); // Update the queue recovery file + + Run(encJob, false); + + if (HbProcess == null) + { + return; + } + HbProcess.WaitForExit(); + + AddCLIQueryToLog(encJob); + this.CopyLog(this.LastEncode.Destination); + + HbProcess.Close(); + HbProcess.Dispose(); + + // Growl + if (Properties.Settings.Default.growlEncode) + GrowlCommunicator.Notify("Encode Completed", + "Put down that cocktail...\nyour Handbrake encode is done."); + + while (this.Paused) // Need to find a better way of doing this. + { + Thread.Sleep(2000); + } + } + this.LastEncode = new Job(); + + if (this.QueueCompleted != null) + this.QueueCompleted(this, new EventArgs()); + + // After the encode is done, we may want to shutdown, suspend etc. + Finish(); + } + + #endregion + } +} \ No newline at end of file -- cgit v1.2.3