1 namespace HandBrake.ApplicationServices.Services
\r
4 using System.Collections.Generic;
\r
5 using System.Collections.ObjectModel;
\r
8 using System.Windows.Forms;
\r
9 using System.Xml.Serialization;
\r
11 using HandBrake.ApplicationServices.Model;
\r
12 using HandBrake.ApplicationServices.Services.Interfaces;
\r
14 using EventArgs = System.EventArgs;
\r
17 /// The Queue Manager.
\r
20 public class QueueManager : IQueueManager
\r
24 * - Rewrite the batch script generator.
\r
27 #region Private Variables
\r
30 /// A Lock object to maintain thread safety
\r
32 static readonly object QueueLock = new object();
\r
35 /// The Queue of Job objects
\r
37 private readonly List<QueueTask> queue = new List<QueueTask>();
\r
40 /// HandBrakes Queue file with a place holder for an extra string.
\r
42 private readonly string queueFile;
\r
45 /// The ID of the job last added
\r
47 private int lastJobId;
\r
50 /// The instance Id of this HandBrake instance.
\r
52 private int instanceId;
\r
57 /// Initializes a new instance of the <see cref="QueueManager"/> class.
\r
59 /// <param name="instanceId">
\r
60 /// The instance Id.
\r
62 public QueueManager(int instanceId)
\r
64 this.instanceId = instanceId;
\r
66 // If this is the first instance, just use the main queue file, otherwise add the instance id to the filename.
\r
67 this.queueFile = instanceId == 0 ? "hb_queue_recovery.xml" : string.Format("hb_queue_recovery{0}.xml", instanceId);
\r
72 /// Fires when a job is Added, Removed or Re-Ordered.
\r
73 /// Should be used for triggering an update of the Queue Window.
\r
75 public event EventHandler QueueChanged;
\r
78 /// Invoke the Queue Changed Event
\r
80 /// <param name="e">
\r
83 private void InvokeQueueChanged(EventArgs e)
\r
87 this.BackupQueue(string.Empty);
\r
94 EventHandler handler = this.QueueChanged;
\r
95 if (handler != null)
\r
103 #region Public Properties
\r
106 /// Gets or sets Last Processed Job.
\r
107 /// This is set when the job is poped of the queue by GetNextJobForProcessing();
\r
109 public QueueTask LastProcessedJob { get; set; }
\r
112 /// Gets the number of jobs in the queue;
\r
118 return this.queue.Count;
\r
123 /// Gets The current queue.
\r
125 public ReadOnlyCollection<QueueTask> Queue
\r
129 return this.queue.AsReadOnly();
\r
135 #region Public Methods
\r
138 /// Add a job to the Queue.
\r
139 /// This method is Thread Safe.
\r
141 /// <param name="job">
\r
142 /// The encode Job object.
\r
144 public void Add(QueueTask job)
\r
148 // Tag the job with an ID
\r
149 job.Id = lastJobId++;
\r
151 InvokeQueueChanged(EventArgs.Empty);
\r
156 /// Remove a job from the Queue.
\r
157 /// This method is Thread Safe
\r
159 /// <param name="job">
\r
162 public void Remove(QueueTask job)
\r
166 // Tag the job with an ID
\r
167 job.Id = lastJobId++;
\r
169 InvokeQueueChanged(EventArgs.Empty);
\r
174 /// Get the first job on the queue for processing.
\r
175 /// This also removes the job from the Queue and sets the LastProcessedJob
\r
178 /// An encode Job object.
\r
180 public QueueTask GetNextJobForProcessing()
\r
182 if (this.queue.Count > 0)
\r
184 QueueTask job = this.queue[0];
\r
185 this.LastProcessedJob = job;
\r
186 this.Remove(job); // Remove the item which we are about to pass out.
\r
195 /// Moves an item up one position in the queue.
\r
197 /// <param name="index">The zero-based location of the job in the queue.</param>
\r
198 public void MoveUp(int index)
\r
202 QueueTask item = queue[index];
\r
204 queue.RemoveAt(index);
\r
205 queue.Insert((index - 1), item);
\r
208 this.InvokeQueueChanged(EventArgs.Empty);
\r
212 /// Moves an item down one position in the queue.
\r
214 /// <param name="index">The zero-based location of the job in the queue.</param>
\r
215 public void MoveDown(int index)
\r
217 if (index < this.queue.Count - 1)
\r
219 QueueTask item = this.queue[index];
\r
221 this.queue.RemoveAt(index);
\r
222 this.queue.Insert((index + 1), item);
\r
225 this.InvokeQueueChanged(EventArgs.Empty);
\r
229 /// Backup any changes to the queue file
\r
231 /// <param name="exportPath">
\r
232 /// If this is not null or empty, this will be used instead of the standard backup location.
\r
234 public void BackupQueue(string exportPath)
\r
236 string appDataPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), @"HandBrake\");
\r
237 string tempPath = !string.IsNullOrEmpty(exportPath) ? exportPath : appDataPath + string.Format(this.queueFile, string.Empty);
\r
239 if (File.Exists(tempPath))
\r
241 using (FileStream strm = new FileStream(tempPath, FileMode.Create, FileAccess.Write))
\r
243 XmlSerializer serializer = new XmlSerializer(typeof(List<QueueTask>));
\r
244 serializer.Serialize(strm, queue);
\r
252 /// Restore a Queue from file or from the queue backup file.
\r
254 /// <param name="importPath">
\r
255 /// The import path. String.Empty or null will result in the default file being loaded.
\r
257 public void RestoreQueue(string importPath)
\r
259 string appDataPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), @"HandBrake\");
\r
260 string tempPath = !string.IsNullOrEmpty(importPath) ? importPath : (appDataPath + string.Format(this.queueFile, string.Empty));
\r
262 if (File.Exists(tempPath))
\r
264 using (FileStream strm = new FileStream((!string.IsNullOrEmpty(importPath) ? importPath : tempPath), FileMode.Open, FileAccess.Read))
\r
266 if (strm.Length != 0)
\r
268 XmlSerializer serializer = new XmlSerializer(typeof(List<QueueTask>));
\r
270 List<QueueTask> list = serializer.Deserialize(strm) as List<QueueTask>;
\r
273 foreach (QueueTask item in list)
\r
274 this.queue.Add(item);
\r
276 this.InvokeQueueChanged(EventArgs.Empty);
\r
283 /// Checks the current queue for an existing instance of the specified destination.
\r
285 /// <param name="destination">The destination of the encode.</param>
\r
286 /// <returns>Whether or not the supplied destination is already in the queue.</returns>
\r
287 public bool CheckForDestinationPathDuplicates(string destination)
\r
289 return this.queue.Any(checkItem => checkItem.Task.Destination.Contains(destination.Replace("\\\\", "\\")));
\r
293 /// Writes the current state of the queue in the form of a batch (.bat) file.
\r
295 /// <param name="file">
\r
296 /// The location of the file to write the batch file to.
\r
299 /// The write batch script to file.
\r
301 public bool WriteBatchScriptToFile(string file)
\r
303 string queries = string.Empty;
\r
304 foreach (QueueTask queueItem in this.queue)
\r
306 string qItem = queueItem.Query;
\r
307 string fullQuery = '"' + Application.StartupPath + "\\HandBrakeCLI.exe" + '"' + qItem;
\r
309 if (queries == string.Empty)
\r
310 queries = queries + fullQuery;
\r
312 queries = queries + " && " + fullQuery;
\r
314 string strCmdLine = queries;
\r
316 if (file != string.Empty)
\r
320 // Create a StreamWriter and open the file, Write the batch file query to the file and
\r
321 // Close the stream
\r
322 using (StreamWriter line = new StreamWriter(file))
\r
324 line.WriteLine(strCmdLine);
\r
329 catch (Exception exc)
\r
331 throw new Exception("Unable to write to the file. Please make sure that the location has the correct permissions for file writing.", exc);
\r