/* QueueHandler.cs $
This file is part of the HandBrake source code.
Homepage: .
It may be used under the terms of the GNU General Public License. */
using System;
using System.Collections.Generic;
using System.IO;
using System.Windows.Forms;
using System.Xml.Serialization;
using System.Threading;
namespace Handbrake.EncodeQueue
{
public class QueueHandler
{
Encode encodeHandler = new Encode();
private static XmlSerializer ser = new XmlSerializer(typeof(List));
List queue = new List();
int id; // Unique identifer number for each job
#region Queue Handling
public List getQueue()
{
return queue;
}
///
/// Get's the next CLI query for encoding
///
/// String
private string getNextItemForEncoding()
{
QueueItem job = queue[0];
String query = job.Query;
lastQueueItem = job;
remove(0); // Remove the item which we are about to pass out.
return query;
}
///
/// Get the last query that was returned by getNextItemForEncoding()
///
///
public QueueItem lastQueueItem { get; set; }
///
/// Add's a new item to the queue
///
/// String
///
///
public void add(string query, string source, string destination)
{
QueueItem newJob = new QueueItem { Id = id, Query = query, Source = source, Destination = destination };
id++;
queue.Add(newJob);
}
///
/// Check to see if a destination path is already on the queue
///
/// Destination path
/// Boolean True/False. True = Path Exists
public Boolean checkDestinationPath(string destination)
{
foreach (QueueItem checkItem in queue)
{
if (checkItem.Destination.Contains(destination.Replace("\\\\", "\\")))
return true;
}
return false;
}
///
/// Removes an item from the queue.
///
/// Index
/// Bolean true if successful
public void remove(int index)
{
queue.RemoveAt(index);
}
///
/// Returns how many items are in the queue
///
/// Int
public int count()
{
return queue.Count;
}
///
/// Move an item with an index x, up in the queue
///
/// Int
public void moveUp(int index)
{
if (index > 0)
{
QueueItem item = queue[index];
queue.RemoveAt(index);
queue.Insert((index - 1), item);
}
}
///
/// Move an item with an index x, down in the queue
///
/// Int
public void moveDown(int index)
{
if (index < queue.Count - 1)
{
QueueItem item = queue[index];
queue.RemoveAt(index);
queue.Insert((index + 1), item);
}
}
///
/// Writes the current queue to disk. hb_queue_recovery.xml
/// This function is called after getNextItemForEncoding()
///
public void write2disk(string file)
{
string tempPath = file == "hb_queue_recovery.xml" ? Path.Combine(Path.GetTempPath(), "hb_queue_recovery.xml") : file;
try
{
using (FileStream strm = new FileStream(tempPath, FileMode.Create, FileAccess.Write))
{
ser.Serialize(strm, queue);
strm.Close();
strm.Dispose();
}
}
catch (Exception)
{
// Any Errors will be out of diskspace/permissions problems.
// Don't report them as they'll annoy the user.
}
}
///
/// Writes the current queue to disk to the location specified in file
///
///
public void writeBatchScript(string file)
{
string queries = "";
foreach (QueueItem queue_item in queue)
{
string q_item = queue_item.Query;
string fullQuery = '"' + Application.StartupPath + "\\HandBrakeCLI.exe" + '"' + q_item;
if (queries == string.Empty)
queries = queries + fullQuery;
else
queries = queries + " && " + fullQuery;
}
string strCmdLine = queries;
if (file != "")
{
try
{
// Create a StreamWriter and open the file, Write the batch file query to the file and
// Close the stream
StreamWriter line = new StreamWriter(file);
line.WriteLine(strCmdLine);
line.Close();
MessageBox.Show("Your batch script has been sucessfully saved.", "Status", MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
}
catch (Exception)
{
MessageBox.Show("Unable to write to the file. Please make sure that the location has the correct permissions for file writing.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Hand);
}
}
}
///
/// Recover the queue from hb_queue_recovery.xml
///
public void recoverQueue(string file)
{
string tempPath;
if (file == "hb_queue_recovery.xml")
tempPath = Path.Combine(Path.GetTempPath(), "hb_queue_recovery.xml");
else
tempPath = file;
if (File.Exists(tempPath))
{
using (FileStream strm = new FileStream(tempPath, FileMode.Open, FileAccess.Read))
{
if (strm.Length != 0)
{
List list = ser.Deserialize(strm) as List;
if (list != null)
foreach (QueueItem item in list)
queue.Add(item);
if (file != "hb_queue_recovery.xml")
write2disk("hb_queue_recovery.xml");
}
}
}
}
#endregion
#region Encoding
public Boolean isEncodeStarted { get; private set; }
public Boolean isPaused { get; private set; }
public Boolean isEncoding { get; private set; }
public EncodeProcess encodeProcess { get; set; }
public void startEncode()
{
Thread theQueue;
if (this.count() != 0)
{
if (isPaused)
isPaused = false;
else
{
isPaused = false;
try
{
theQueue = new Thread(startProc) { IsBackground = true };
theQueue.Start();
}
catch (Exception exc)
{
MessageBox.Show(exc.ToString());
}
}
}
}
public void pauseEncodeQueue()
{
isPaused = true;
EncodePaused(null);
}
public void endEncode()
{
encodeHandler.closeCLI(encodeProcess);
}
private void startProc(object state)
{
try
{
// Run through each item on the queue
while (this.count() != 0)
{
string query = getNextItemForEncoding();
write2disk("hb_queue_recovery.xml"); // Update the queue recovery file
encodeProcess = encodeHandler.runCli(query);
EncodeStarted(null);
encodeProcess.hbProcProcess.WaitForExit();
encodeHandler.addCLIQueryToLog(query);
encodeHandler.copyLog(lastQueueItem.Destination);
encodeProcess.hbProcProcess.Close();
encodeProcess.hbProcProcess.Dispose();
EncodeFinished(null);
while (isPaused) // Need to find a better way of doing this.
{
Thread.Sleep(10000);
}
}
EncodeQueueFinished(null);
// After the encode is done, we may want to shutdown, suspend etc.
encodeHandler.afterEncodeAction(encodeProcess);
}
catch (Exception exc)
{
throw new Exception(exc.ToString());
}
}
#endregion
#region Events
public event EventHandler OnEncodeStart;
public event EventHandler OnPaused;
public event EventHandler OnEncodeEnded;
public event EventHandler OnQueueFinished;
// Invoke the Changed event; called whenever encodestatus changes:
protected virtual void EncodeStarted(EventArgs e)
{
if (OnEncodeStart != null)
OnEncodeStart(this, e);
isEncoding = true;
}
protected virtual void EncodePaused(EventArgs e)
{
if (OnPaused != null)
OnPaused(this, e);
}
protected virtual void EncodeFinished(EventArgs e)
{
if (OnEncodeEnded != null)
OnEncodeEnded(this, e);
isEncoding = false;
}
protected virtual void EncodeQueueFinished(EventArgs e)
{
if (OnQueueFinished != null)
OnQueueFinished(this, e);
}
#endregion
}
}