/* 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;
using System.Diagnostics;
namespace Handbrake.Queue
{
public class QueueHandler
{
private static XmlSerializer ser = new XmlSerializer(typeof(List));
List queue = new List();
int id; // Unique identifer number for each job
private QueueItem lastItem;
#region Queue Handling
public List getQueue()
{
return queue;
}
///
/// Get's the next CLI query for encoding
///
/// String
public string getNextItemForEncoding()
{
QueueItem job = queue[0];
String query = job.Query;
lastItem = 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 getLastQueryItem()
{
return lastItem;
}
///
/// 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 Boolean remove(int index)
{
queue.RemoveAt(index);
return true;
}
///
/// 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;
if (file == "hb_queue_recovery.xml")
tempPath = Path.Combine(Path.GetTempPath(), "hb_queue_recovery.xml");
else
tempPath = 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
//------------------------------------------------------------------------
Functions.Encode encodeHandler = new Functions.Encode();
private Boolean started = false;
private Boolean paused;
private Boolean encoding;
#region Encoding
public Boolean isEncodeStarted
{
get { return started; }
}
public Boolean isPaused
{
get { return paused; }
}
public Boolean isEncoding
{
get { return encoding; }
}
public void startEncode()
{
Thread theQueue;
if (this.count() != 0)
{
if (paused)
paused = false;
else
{
paused = false;
try
{
theQueue = new Thread(startProc) {IsBackground = true};
theQueue.Start();
}
catch (Exception exc)
{
MessageBox.Show(exc.ToString());
}
}
}
}
public void pauseEncode()
{
paused = true;
EncodePaused(null);
}
private void startProc(object state)
{
Process hbProc;
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
EncodeStarted(null);
hbProc = encodeHandler.runCli(this, query);
hbProc.WaitForExit();
encodeHandler.addCLIQueryToLog(query);
encodeHandler.copyLog(query, getLastQueryItem().Destination);
hbProc.Close();
hbProc.Dispose();
EncodeFinished(null);
while (paused) // 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();
}
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);
encoding = 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);
encoding = false;
}
protected virtual void EncodeQueueFinished(EventArgs e)
{
if (OnQueueFinished != null)
OnQueueFinished(this, e);
}
#endregion
}
}