diff options
author | sr55 <[email protected]> | 2012-10-13 17:52:14 +0000 |
---|---|---|
committer | sr55 <[email protected]> | 2012-10-13 17:52:14 +0000 |
commit | 2a18d05b52ea084b4bb968f3622872a8a08d83fa (patch) | |
tree | f63657f90345ba60d1ce74eec44f9dd3358c9213 /win/CS/HandBrake.ApplicationServices | |
parent | ef8ce8c1327f5e01dfe0853501eb80ced39beb1c (diff) |
WinGui: API Tidyup Part 3 of many.
git-svn-id: svn://svn.handbrake.fr/HandBrake/trunk@5015 b64f7644-9d1e-0410-96f1-a4d463321fa5
Diffstat (limited to 'win/CS/HandBrake.ApplicationServices')
6 files changed, 576 insertions, 707 deletions
diff --git a/win/CS/HandBrake.ApplicationServices/HandBrake.ApplicationServices.csproj b/win/CS/HandBrake.ApplicationServices/HandBrake.ApplicationServices.csproj index 7039a22e3..af024c7e8 100644 --- a/win/CS/HandBrake.ApplicationServices/HandBrake.ApplicationServices.csproj +++ b/win/CS/HandBrake.ApplicationServices/HandBrake.ApplicationServices.csproj @@ -133,7 +133,6 @@ <Compile Include="Services\Base\EncodeBase.cs" />
<Compile Include="Services\Encode.cs" />
<Compile Include="Services\Interfaces\IEncode.cs" />
- <Compile Include="Services\Interfaces\IQueueManager.cs" />
<Compile Include="Services\Interfaces\IQueueProcessor.cs" />
<Compile Include="Services\Interfaces\IScan.cs" />
<Compile Include="Services\Interfaces\IPresetService.cs" />
@@ -141,7 +140,6 @@ <Compile Include="Services\LibEncode.cs" />
<Compile Include="Services\LibScan.cs" />
<Compile Include="Services\PresetService.cs" />
- <Compile Include="Services\QueueManager.cs" />
<Compile Include="Services\QueueProcessor.cs" />
<Compile Include="Services\ScanService.cs" />
<Compile Include="Services\UserSettingService.cs" />
diff --git a/win/CS/HandBrake.ApplicationServices/Services/Interfaces/IQueueManager.cs b/win/CS/HandBrake.ApplicationServices/Services/Interfaces/IQueueManager.cs deleted file mode 100644 index b52be1aef..000000000 --- a/win/CS/HandBrake.ApplicationServices/Services/Interfaces/IQueueManager.cs +++ /dev/null @@ -1,149 +0,0 @@ -// --------------------------------------------------------------------------------------------------------------------
-// <copyright file="IQueueManager.cs" company="HandBrake Project (http://handbrake.fr)">
-// This file is part of the HandBrake source code - It may be used under the terms of the GNU General Public License.
-// </copyright>
-// <summary>
-// The Queue Manager Interface
-// </summary>
-// --------------------------------------------------------------------------------------------------------------------
-
-namespace HandBrake.ApplicationServices.Services.Interfaces
-{
- using System;
- using System.Collections.ObjectModel;
-
- using HandBrake.ApplicationServices.Model;
-
- /// <summary>
- /// The Queue Manager Interface
- /// </summary>
- public interface IQueueManager
- {
- /// <summary>
- /// Fires when a job is Added, Removed or Re-Ordered.
- /// Should be used for triggering an update of the Queue Window.
- /// </summary>
- event EventHandler QueueChanged;
-
- /// <summary>
- /// Gets or sets Last Processed Job.
- /// This is set when the job is poped of the queue by GetNextJobForProcessing();
- /// </summary>
- QueueTask LastProcessedJob { get; set; }
-
- /// <summary>
- /// Gets The current queue.
- /// </summary>
- ObservableCollection<QueueTask> Queue { get; }
-
- /// <summary>
- /// Gets the number of jobs in the queue
- /// </summary>
- int Count { get; }
-
- /// <summary>
- /// Add a job to the Queue.
- /// This method is Thread Safe.
- /// </summary>
- /// <param name="job">
- /// The encode Job object.
- /// </param>
- void Add(QueueTask job);
-
- /// <summary>
- /// Remove a job from the Queue.
- /// This method is Thread Safe
- /// </summary>
- /// <param name="job">
- /// The job.
- /// </param>
- void Remove(QueueTask job);
-
- /// <summary>
- /// Reset a Queued Item from Error or Completed to Waiting
- /// </summary>
- /// <param name="job">
- /// The job.
- /// </param>
- void ResetJobStatusToWaiting(QueueTask job);
-
- /// <summary>
- /// Clear down the Queue�s completed items
- /// </summary>
- void ClearCompleted();
-
- /// <summary>
- /// Clear down all Queue Items
- /// </summary>
- void Clear();
-
- /// <summary>
- /// Get the first job on the queue for processing.
- /// This also removes the job from the Queue and sets the LastProcessedJob
- /// </summary>
- /// <returns>
- /// An encode Job object.
- /// </returns>
- QueueTask GetNextJobForProcessing();
-
- /// <summary>
- /// Moves an item up one position in the queue.
- /// </summary>
- /// <param name="index">The zero-based location of the job in the queue.</param>
- void MoveUp(int index);
-
- /// <summary>
- /// Moves an item down one position in the queue.
- /// </summary>
- /// <param name="index">The zero-based location of the job in the queue.</param>
- void MoveDown(int index);
-
- /// <summary>
- /// Backup any changes to the queue file
- /// </summary>
- /// <param name="exportPath">
- /// If this is not null or empty, this will be used instead of the standard backup location.
- /// </param>
- void BackupQueue(string exportPath);
-
- /// <summary>
- /// Restore a Queue from file or from the queue backup file.
- /// </summary>
- /// <param name="importPath">
- /// The import path. String.Empty or null will result in the default file being loaded.
- /// </param>
- void RestoreQueue(string importPath);
-
- /// <summary>
- /// Checks the current queue for an existing instance of the specified destination.
- /// </summary>
- /// <param name="destination">The destination of the encode.</param>
- /// <returns>Whether or not the supplied destination is already in the queue.</returns>
- bool CheckForDestinationPathDuplicates(string destination);
-
- /// <summary>
- /// Create a batch script from the queue
- /// </summary>
- /// <param name="path">
- /// The path to the location for the script to be saved.
- /// </param>
- /// <param name="previewScanCount">
- /// The preview Scan Count.
- /// </param>
- /// <param name="verbosity">
- /// The verbosity.
- /// </param>
- /// <param name="disableLibdvdnav">
- /// The disable Libdvdnav.
- /// </param>
- /// <returns>
- /// True if sucessful
- /// </returns>
- bool WriteBatchScriptToFile(string path, int previewScanCount, int verbosity, bool disableLibdvdnav);
-
- /// <summary>
- /// Temp workaround until this can be fixed properly.
- /// </summary>
- void ResetInstanceId();
- }
-}
\ No newline at end of file diff --git a/win/CS/HandBrake.ApplicationServices/Services/Interfaces/IQueueProcessor.cs b/win/CS/HandBrake.ApplicationServices/Services/Interfaces/IQueueProcessor.cs index dd5746387..c9285ebfe 100644 --- a/win/CS/HandBrake.ApplicationServices/Services/Interfaces/IQueueProcessor.cs +++ b/win/CS/HandBrake.ApplicationServices/Services/Interfaces/IQueueProcessor.cs @@ -10,21 +10,27 @@ namespace HandBrake.ApplicationServices.Services.Interfaces
{
using System;
+ using System.Collections.ObjectModel;
+
+ using HandBrake.ApplicationServices.Model;
/// <summary>
/// The Queue Processor
/// </summary>
public interface IQueueProcessor
{
+ #region Events
+
/// <summary>
/// Fires when the Queue has started
/// </summary>
event QueueProcessor.QueueProgressStatus JobProcessingStarted;
/// <summary>
- /// Fires when a pause to the encode queue has been requested.
+ /// Fires when a job is Added, Removed or Re-Ordered.
+ /// Should be used for triggering an update of the Queue Window.
/// </summary>
- event EventHandler QueuePaused;
+ event EventHandler QueueChanged;
/// <summary>
/// Fires when the entire encode queue has completed.
@@ -32,14 +38,23 @@ namespace HandBrake.ApplicationServices.Services.Interfaces event EventHandler QueueCompleted;
/// <summary>
- /// Gets the IEncodeService instance.
+ /// Fires when a pause to the encode queue has been requested.
/// </summary>
- IEncodeServiceWrapper EncodeService { get; }
+ event EventHandler QueuePaused;
+
+ #endregion
+
+ #region Properties
/// <summary>
- /// Gets the IQueueManager instance.
+ /// Gets the number of jobs in the queue
/// </summary>
- IQueueManager QueueManager { get; }
+ int Count { get; }
+
+ /// <summary>
+ /// Gets the IEncodeService instance.
+ /// </summary>
+ IEncodeServiceWrapper EncodeService { get; }
/// <summary>
/// Gets a value indicating whether IsProcessing.
@@ -47,10 +62,82 @@ namespace HandBrake.ApplicationServices.Services.Interfaces bool IsProcessing { get; }
/// <summary>
- /// Starts encoding the first job in the queue and continues encoding until all jobs
- /// have been encoded.
+ /// Gets or sets Last Processed Job.
+ /// This is set when the job is poped of the queue by GetNextJobForProcessing();
/// </summary>
- void Start();
+ QueueTask LastProcessedJob { get; set; }
+
+ /// <summary>
+ /// Gets The current queue.
+ /// </summary>
+ ObservableCollection<QueueTask> Queue { get; }
+
+ #endregion
+
+ #region Public Methods
+
+ /// <summary>
+ /// Add a job to the Queue.
+ /// This method is Thread Safe.
+ /// </summary>
+ /// <param name="job">
+ /// The encode Job object.
+ /// </param>
+ void Add(QueueTask job);
+
+ /// <summary>
+ /// Backup any changes to the queue file
+ /// </summary>
+ /// <param name="exportPath">
+ /// If this is not null or empty, this will be used instead of the standard backup location.
+ /// </param>
+ void BackupQueue(string exportPath);
+
+ /// <summary>
+ /// Checks the current queue for an existing instance of the specified destination.
+ /// </summary>
+ /// <param name="destination">
+ /// The destination of the encode.
+ /// </param>
+ /// <returns>
+ /// Whether or not the supplied destination is already in the queue.
+ /// </returns>
+ bool CheckForDestinationPathDuplicates(string destination);
+
+ /// <summary>
+ /// Clear down all Queue Items
+ /// </summary>
+ void Clear();
+
+ /// <summary>
+ /// Clear down the Queue�s completed items
+ /// </summary>
+ void ClearCompleted();
+
+ /// <summary>
+ /// Get the first job on the queue for processing.
+ /// This also removes the job from the Queue and sets the LastProcessedJob
+ /// </summary>
+ /// <returns>
+ /// An encode Job object.
+ /// </returns>
+ QueueTask GetNextJobForProcessing();
+
+ /// <summary>
+ /// Moves an item down one position in the queue.
+ /// </summary>
+ /// <param name="index">
+ /// The zero-based location of the job in the queue.
+ /// </param>
+ void MoveDown(int index);
+
+ /// <summary>
+ /// Moves an item up one position in the queue.
+ /// </summary>
+ /// <param name="index">
+ /// The zero-based location of the job in the queue.
+ /// </param>
+ void MoveUp(int index);
/// <summary>
/// Requests a pause of the encode queue.
@@ -58,12 +145,41 @@ namespace HandBrake.ApplicationServices.Services.Interfaces void Pause();
/// <summary>
- /// Swap encode service.
- /// Temp method until Castle is hooked up.
+ /// Remove a job from the Queue.
+ /// This method is Thread Safe
/// </summary>
- /// <param name="service">
- /// The service.
+ /// <param name="job">
+ /// The job.
/// </param>
- void SwapEncodeService(IEncodeServiceWrapper service);
+ void Remove(QueueTask job);
+
+ /// <summary>
+ /// Temp workaround until this can be fixed properly.
+ /// </summary>
+ void ResetInstanceId();
+
+ /// <summary>
+ /// Reset a Queued Item from Error or Completed to Waiting
+ /// </summary>
+ /// <param name="job">
+ /// The job.
+ /// </param>
+ void ResetJobStatusToWaiting(QueueTask job);
+
+ /// <summary>
+ /// Restore a Queue from file or from the queue backup file.
+ /// </summary>
+ /// <param name="importPath">
+ /// The import path. String.Empty or null will result in the default file being loaded.
+ /// </param>
+ void RestoreQueue(string importPath);
+
+ /// <summary>
+ /// Starts encoding the first job in the queue and continues encoding until all jobs
+ /// have been encoded.
+ /// </summary>
+ void Start();
+
+ #endregion
}
}
\ No newline at end of file diff --git a/win/CS/HandBrake.ApplicationServices/Services/QueueManager.cs b/win/CS/HandBrake.ApplicationServices/Services/QueueManager.cs deleted file mode 100644 index 161653da0..000000000 --- a/win/CS/HandBrake.ApplicationServices/Services/QueueManager.cs +++ /dev/null @@ -1,430 +0,0 @@ -// --------------------------------------------------------------------------------------------------------------------
-// <copyright file="QueueManager.cs" company="HandBrake Project (http://handbrake.fr)">
-// This file is part of the HandBrake source code - It may be used under the terms of the GNU General Public License.
-// </copyright>
-// <summary>
-// The Queue Manager.
-// Thread Safe.
-// </summary>
-// --------------------------------------------------------------------------------------------------------------------
-
-namespace HandBrake.ApplicationServices.Services
-{
- using System;
- using System.Collections.Generic;
- using System.Collections.ObjectModel;
- using System.IO;
- using System.Linq;
- using System.Windows.Forms;
- using System.Xml.Serialization;
-
- using Caliburn.Micro;
-
- using HandBrake.ApplicationServices.Exceptions;
- using HandBrake.ApplicationServices.Model;
- using HandBrake.ApplicationServices.Services.Interfaces;
- using HandBrake.ApplicationServices.Utilities;
-
- using EventArgs = System.EventArgs;
-
- /// <summary>
- /// The Queue Manager.
- /// Thread Safe.
- /// </summary>
- public class QueueManager : IQueueManager
- {
- /*
- * TODO
- * - Rewrite the batch script generator.
- * - QueueTask, switch everything to use the Task property, which is a model of all settings.
- */
-
- #region Private Variables
-
- /// <summary>
- /// A Lock object to maintain thread safety
- /// </summary>
- static readonly object QueueLock = new object();
-
- /// <summary>
- /// The Queue of Job objects
- /// </summary>
- private readonly ObservableCollection<QueueTask> queue = new ObservableCollection<QueueTask>();
-
- /// <summary>
- /// HandBrakes Queue file with a place holder for an extra string.
- /// </summary>
- private string queueFile;
-
- #endregion
-
- /// <summary>
- /// Initializes a new instance of the <see cref="QueueManager"/> class.
- /// </summary>
- public QueueManager()
- {
- // If this is the first instance, just use the main queue file, otherwise add the instance id to the filename.
- this.queueFile = string.Format("hb_queue_recovery{0}.xml", GeneralUtilities.GetInstanceCount);
- }
-
- #region Events
-
- /// <summary>
- /// Fires when a job is Added, Removed or Re-Ordered.
- /// Should be used for triggering an update of the Queue Window.
- /// </summary>
- public event EventHandler QueueChanged;
-
- /// <summary>
- /// Invoke the Queue Changed Event
- /// </summary>
- /// <param name="e">
- /// The e.
- /// </param>
- private void InvokeQueueChanged(EventArgs e)
- {
- try
- {
- this.BackupQueue(string.Empty);
- }
- catch (Exception)
- {
- // Do Nothing.
- }
-
- EventHandler handler = this.QueueChanged;
- if (handler != null)
- {
- handler(this, e);
- }
- }
-
- #endregion
-
- #region Public Properties
-
- /// <summary>
- /// Gets or sets Last Processed Job.
- /// This is set when the job is poped of the queue by GetNextJobForProcessing();
- /// </summary>
- public QueueTask LastProcessedJob { get; set; }
-
- /// <summary>
- /// Gets the number of jobs in the queue;
- /// </summary>
- public int Count
- {
- get
- {
- return this.queue.Where(item => item.Status == QueueItemStatus.Waiting).Count();
- }
- }
-
- /// <summary>
- /// Gets The current queue.
- /// </summary>
- public ObservableCollection<QueueTask> Queue
- {
- get
- {
- return this.queue;
- }
- }
-
- #endregion
-
- #region Public Methods
-
- /// <summary>
- /// Add a job to the Queue.
- /// This method is Thread Safe.
- /// </summary>
- /// <param name="job">
- /// The encode Job object.
- /// </param>
- public void Add(QueueTask job)
- {
- lock (QueueLock)
- {
- queue.Add(job);
- InvokeQueueChanged(EventArgs.Empty);
- }
- }
-
- /// <summary>
- /// Remove a job from the Queue.
- /// This method is Thread Safe
- /// </summary>
- /// <param name="job">
- /// The job.
- /// </param>
- public void Remove(QueueTask job)
- {
- lock (QueueLock)
- {
- queue.Remove(job);
- InvokeQueueChanged(EventArgs.Empty);
- }
- }
-
- /// <summary>
- /// Reset a Queued Item from Error or Completed to Waiting
- /// </summary>
- /// <param name="job">
- /// The job.
- /// </param>
- public void ResetJobStatusToWaiting(QueueTask job)
- {
- if (job.Status != QueueItemStatus.Error && job.Status != QueueItemStatus.Completed)
- {
- throw new GeneralApplicationException("Job Error", "Unable to reset job status as it is not in an Error or Completed state", null);
- }
-
- job.Status = QueueItemStatus.Waiting;
- }
-
- /// <summary>
- /// Clear down the Queue´s completed items
- /// </summary>
- public void ClearCompleted()
- {
- Execute.OnUIThread(
- () =>
- {
- List<QueueTask> deleteList = this.queue.Where(task => task.Status == QueueItemStatus.Completed).ToList();
- foreach (QueueTask item in deleteList)
- {
- this.queue.Remove(item);
- }
- this.InvokeQueueChanged(EventArgs.Empty);
- });
- }
-
- /// <summary>
- /// Clear down all Queue Items
- /// </summary>
- public void Clear()
- {
- List<QueueTask> deleteList = this.queue.ToList();
- foreach (QueueTask item in deleteList)
- {
- this.queue.Remove(item);
- }
- this.InvokeQueueChanged(EventArgs.Empty);
- }
-
- /// <summary>
- /// Get the first job on the queue for processing.
- /// This also removes the job from the Queue and sets the LastProcessedJob
- /// </summary>
- /// <returns>
- /// An encode Job object.
- /// </returns>
- public QueueTask GetNextJobForProcessing()
- {
- if (this.queue.Count > 0)
- {
- QueueTask job = this.queue.FirstOrDefault(q => q.Status == QueueItemStatus.Waiting);
- if (job != null)
- {
- job.Status = QueueItemStatus.InProgress;
- this.LastProcessedJob = job;
- InvokeQueueChanged(EventArgs.Empty);
- }
-
- this.BackupQueue(string.Empty);
- return job;
- }
-
- this.BackupQueue(string.Empty);
- return null;
- }
-
- /// <summary>
- /// Moves an item up one position in the queue.
- /// </summary>
- /// <param name="index">The zero-based location of the job in the queue.</param>
- public void MoveUp(int index)
- {
- if (index > 0)
- {
- QueueTask item = queue[index];
-
- queue.RemoveAt(index);
- queue.Insert((index - 1), item);
- }
-
- this.InvokeQueueChanged(EventArgs.Empty);
- }
-
- /// <summary>
- /// Moves an item down one position in the queue.
- /// </summary>
- /// <param name="index">The zero-based location of the job in the queue.</param>
- public void MoveDown(int index)
- {
- if (index < this.queue.Count - 1)
- {
- QueueTask item = this.queue[index];
-
- this.queue.RemoveAt(index);
- this.queue.Insert((index + 1), item);
- }
-
- this.InvokeQueueChanged(EventArgs.Empty);
- }
-
- /// <summary>
- /// Backup any changes to the queue file
- /// </summary>
- /// <param name="exportPath">
- /// If this is not null or empty, this will be used instead of the standard backup location.
- /// </param>
- public void BackupQueue(string exportPath)
- {
- string appDataPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), @"HandBrake\");
- string tempPath = !string.IsNullOrEmpty(exportPath) ? exportPath : appDataPath + string.Format(this.queueFile, string.Empty);
-
-
- using (FileStream strm = new FileStream(tempPath, FileMode.Create, FileAccess.Write))
- {
- List<QueueTask> tasks = queue.Where(item => item.Status != QueueItemStatus.Completed).ToList();
- XmlSerializer serializer = new XmlSerializer(typeof(List<QueueTask>));
- serializer.Serialize(strm, tasks);
- strm.Close();
- strm.Dispose();
- }
- }
-
- /// <summary>
- /// Restore a Queue from file or from the queue backup file.
- /// </summary>
- /// <param name="importPath">
- /// The import path. String.Empty or null will result in the default file being loaded.
- /// </param>
- public void RestoreQueue(string importPath)
- {
- string appDataPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), @"HandBrake\");
- string tempPath = !string.IsNullOrEmpty(importPath) ? importPath : (appDataPath + string.Format(this.queueFile, string.Empty));
-
- if (File.Exists(tempPath))
- {
- bool invokeUpdate = false;
- using (FileStream strm = new FileStream((!string.IsNullOrEmpty(importPath) ? importPath : tempPath), FileMode.Open, FileAccess.Read))
- {
- if (strm.Length != 0)
- {
- XmlSerializer serializer = new XmlSerializer(typeof(List<QueueTask>));
-
- List<QueueTask> list;
-
- try
- {
- list = serializer.Deserialize(strm) as List<QueueTask>;
- }
- catch (Exception exc)
- {
- throw new GeneralApplicationException("Unable to restore queue file.", "The file may be corrupted or from an older incompatible version of HandBrake", exc);
- }
-
- if (list != null)
- foreach (QueueTask item in list)
- {
- if (item.Status != QueueItemStatus.Completed)
- {
- // Reset InProgress/Error to Waiting so it can be processed
- if (item.Status == QueueItemStatus.InProgress)
- {
- item.Status = QueueItemStatus.Waiting;
- }
-
- this.queue.Add(item);
- }
- }
-
- invokeUpdate = true;
- }
- }
-
- if (invokeUpdate)
- {
- this.InvokeQueueChanged(EventArgs.Empty);
- }
- }
- }
-
- /// <summary>
- /// Checks the current queue for an existing instance of the specified destination.
- /// </summary>
- /// <param name="destination">The destination of the encode.</param>
- /// <returns>Whether or not the supplied destination is already in the queue.</returns>
- public bool CheckForDestinationPathDuplicates(string destination)
- {
- return this.queue.Any(checkItem => checkItem.Task.Destination.Contains(destination.Replace("\\\\", "\\")));
- }
-
- /// <summary>
- /// Writes the current state of the queue in the form of a batch (.bat) file.
- /// </summary>
- /// <param name="file">
- /// The location of the file to write the batch file to.
- /// </param>
- /// <param name="previewScanCount">
- /// The preview Scan Count.
- /// </param>
- /// <param name="verbosity">
- /// The verbosity.
- /// </param>
- /// <param name="disableLibdvdnav">
- /// The disable Libdvdnav.
- /// </param>
- /// <returns>
- /// The write batch script to file.
- /// </returns>
- public bool WriteBatchScriptToFile(string file, int previewScanCount, int verbosity, bool disableLibdvdnav)
- {
- string queries = string.Empty;
- foreach (QueueTask queueItem in this.queue)
- {
- string qItem = QueryGeneratorUtility.GenerateQuery(new EncodeTask(queueItem.Task), previewScanCount, verbosity, disableLibdvdnav);
- 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)
- {
- throw new Exception("Unable to write to the file. Please make sure that the location has the correct permissions for file writing.", exc);
- }
- }
- return false;
- }
-
- /// <summary>
- /// Temp workaround until this can be fixed properly.
- /// </summary>
- public void ResetInstanceId()
- {
- this.queueFile = string.Format("hb_queue_recovery{0}.xml", GeneralUtilities.GetInstanceCount);
- }
-
- #endregion
- }
-}
diff --git a/win/CS/HandBrake.ApplicationServices/Services/QueueProcessor.cs b/win/CS/HandBrake.ApplicationServices/Services/QueueProcessor.cs index 39f31a44c..0b3290839 100644 --- a/win/CS/HandBrake.ApplicationServices/Services/QueueProcessor.cs +++ b/win/CS/HandBrake.ApplicationServices/Services/QueueProcessor.cs @@ -10,10 +10,18 @@ namespace HandBrake.ApplicationServices.Services
{
using System;
+ using System.Collections.Generic;
+ using System.Collections.ObjectModel;
using System.Diagnostics;
+ using System.IO;
+ using System.Linq;
using System.Windows.Forms;
+ using System.Xml.Serialization;
+
+ using Caliburn.Micro;
using HandBrake.ApplicationServices.EventArgs;
+ using HandBrake.ApplicationServices.Exceptions;
using HandBrake.ApplicationServices.Model;
using HandBrake.ApplicationServices.Services.Interfaces;
using HandBrake.ApplicationServices.Utilities;
@@ -23,17 +31,35 @@ namespace HandBrake.ApplicationServices.Services /// </summary>
public class QueueProcessor : IQueueProcessor
{
+ #region Constants and Fields
+
+ /// <summary>
+ /// A Lock object to maintain thread safety
+ /// </summary>
+ private static readonly object QueueLock = new object();
+
+ /// <summary>
+ /// The Queue of Job objects
+ /// </summary>
+ private readonly ObservableCollection<QueueTask> queue = new ObservableCollection<QueueTask>();
+
/// <summary>
/// The User Setting Service
/// </summary>
private readonly IUserSettingService userSettingService;
/// <summary>
+ /// HandBrakes Queue file with a place holder for an extra string.
+ /// </summary>
+ private string queueFile;
+
+ #endregion
+
+ #region Constructors and Destructors
+
+ /// <summary>
/// Initializes a new instance of the <see cref="QueueProcessor"/> class.
/// </summary>
- /// <param name="queueManager">
- /// The queue manager.
- /// </param>
/// <param name="encodeService">
/// The encode Service.
/// </param>
@@ -43,24 +69,18 @@ namespace HandBrake.ApplicationServices.Services /// <exception cref="ArgumentNullException">
/// Services are not setup
/// </exception>
- public QueueProcessor(IQueueManager queueManager, IEncodeServiceWrapper encodeService, IUserSettingService userSettingService)
+ public QueueProcessor(IEncodeServiceWrapper encodeService, IUserSettingService userSettingService)
{
this.userSettingService = userSettingService;
- this.QueueManager = queueManager;
this.EncodeService = encodeService;
- if (this.QueueManager == null)
- {
- throw new ArgumentNullException("queueManager");
- }
-
- if (this.QueueManager == null)
- {
- throw new ArgumentNullException("queueManager");
- }
+ // If this is the first instance, just use the main queue file, otherwise add the instance id to the filename.
+ this.queueFile = string.Format("hb_queue_recovery{0}.xml", GeneralUtilities.GetInstanceCount);
}
- #region Events
+ #endregion
+
+ #region Delegates
/// <summary>
/// Queue Progess Status
@@ -73,15 +93,20 @@ namespace HandBrake.ApplicationServices.Services /// </param>
public delegate void QueueProgressStatus(object sender, QueueProgressEventArgs e);
+ #endregion
+
+ #region Events
+
/// <summary>
/// Fires when the Queue has started
/// </summary>
public event QueueProgressStatus JobProcessingStarted;
/// <summary>
- /// Fires when a pause to the encode queue has been requested.
+ /// Fires when a job is Added, Removed or Re-Ordered.
+ /// Should be used for triggering an update of the Queue Window.
/// </summary>
- public event EventHandler QueuePaused;
+ public event EventHandler QueueChanged;
/// <summary>
/// Fires when the entire encode queue has completed.
@@ -89,87 +114,312 @@ namespace HandBrake.ApplicationServices.Services public event EventHandler QueueCompleted;
/// <summary>
- /// Invoke the JobProcessingStarted event
+ /// Fires when a pause to the encode queue has been requested.
/// </summary>
- /// <param name="e">
- /// The QueueProgressEventArgs.
+ public event EventHandler QueuePaused;
+
+ #endregion
+
+ #region Properties
+
+ /// <summary>
+ /// Gets the number of jobs in the queue;
+ /// </summary>
+ public int Count
+ {
+ get
+ {
+ return this.queue.Count(item => item.Status == QueueItemStatus.Waiting);
+ }
+ }
+
+ /// <summary>
+ /// Gets the IEncodeService instance.
+ /// </summary>
+ public IEncodeServiceWrapper EncodeService { get; private set; }
+
+ /// <summary>
+ /// Gets a value indicating whether IsProcessing.
+ /// </summary>
+ public bool IsProcessing { get; private set; }
+
+ /// <summary>
+ /// Gets or sets Last Processed Job.
+ /// This is set when the job is poped of the queue by GetNextJobForProcessing();
+ /// </summary>
+ public QueueTask LastProcessedJob { get; set; }
+
+ /// <summary>
+ /// Gets The current queue.
+ /// </summary>
+ public ObservableCollection<QueueTask> Queue
+ {
+ get
+ {
+ return this.queue;
+ }
+ }
+
+ #endregion
+
+ #region Public Methods
+
+ /// <summary>
+ /// Add a job to the Queue.
+ /// This method is Thread Safe.
+ /// </summary>
+ /// <param name="job">
+ /// The encode Job object.
/// </param>
- private void InvokeJobProcessingStarted(QueueProgressEventArgs e)
+ public void Add(QueueTask job)
{
- QueueProgressStatus handler = this.JobProcessingStarted;
- if (handler != null)
+ lock (QueueLock)
{
- handler(this, e);
+ this.queue.Add(job);
+ this.InvokeQueueChanged(EventArgs.Empty);
}
}
/// <summary>
- /// Invoke the QueuePaused event
+ /// Backup any changes to the queue file
/// </summary>
- /// <param name="e">
- /// The EventArgs.
+ /// <param name="exportPath">
+ /// If this is not null or empty, this will be used instead of the standard backup location.
/// </param>
- private void InvokeQueuePaused(EventArgs e)
+ public void BackupQueue(string exportPath)
{
- EventHandler handler = this.QueuePaused;
- if (handler != null)
+ string appDataPath = Path.Combine(
+ Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), @"HandBrake\");
+ string tempPath = !string.IsNullOrEmpty(exportPath)
+ ? exportPath
+ : appDataPath + string.Format(this.queueFile, string.Empty);
+
+ using (var strm = new FileStream(tempPath, FileMode.Create, FileAccess.Write))
{
- handler(this, e);
+ List<QueueTask> tasks = this.queue.Where(item => item.Status != QueueItemStatus.Completed).ToList();
+ var serializer = new XmlSerializer(typeof(List<QueueTask>));
+ serializer.Serialize(strm, tasks);
+ strm.Close();
+ strm.Dispose();
}
}
/// <summary>
- /// Invoke the QueueCompleted event.
+ /// Checks the current queue for an existing instance of the specified destination.
/// </summary>
- /// <param name="e">
- /// The EventArgs.
+ /// <param name="destination">
+ /// The destination of the encode.
/// </param>
- private void InvokeQueueCompleted(EventArgs e)
+ /// <returns>
+ /// Whether or not the supplied destination is already in the queue.
+ /// </returns>
+ public bool CheckForDestinationPathDuplicates(string destination)
{
- this.IsProcessing = false;
+ return this.queue.Any(checkItem => checkItem.Task.Destination.Contains(destination.Replace("\\\\", "\\")));
+ }
- EventHandler handler = this.QueueCompleted;
- if (handler != null)
+ /// <summary>
+ /// Clear down all Queue Items
+ /// </summary>
+ public void Clear()
+ {
+ List<QueueTask> deleteList = this.queue.ToList();
+ foreach (QueueTask item in deleteList)
{
- handler(this, e);
+ this.queue.Remove(item);
}
+ this.InvokeQueueChanged(EventArgs.Empty);
}
- #endregion
+ /// <summary>
+ /// Clear down the Queue´s completed items
+ /// </summary>
+ public void ClearCompleted()
+ {
+ Execute.OnUIThread(
+ () =>
+ {
+ List<QueueTask> deleteList =
+ this.queue.Where(task => task.Status == QueueItemStatus.Completed).ToList();
+ foreach (QueueTask item in deleteList)
+ {
+ this.queue.Remove(item);
+ }
+ this.InvokeQueueChanged(EventArgs.Empty);
+ });
+ }
- #region Properties
+ /// <summary>
+ /// Get the first job on the queue for processing.
+ /// This also removes the job from the Queue and sets the LastProcessedJob
+ /// </summary>
+ /// <returns>
+ /// An encode Job object.
+ /// </returns>
+ public QueueTask GetNextJobForProcessing()
+ {
+ if (this.queue.Count > 0)
+ {
+ QueueTask job = this.queue.FirstOrDefault(q => q.Status == QueueItemStatus.Waiting);
+ if (job != null)
+ {
+ job.Status = QueueItemStatus.InProgress;
+ this.LastProcessedJob = job;
+ this.InvokeQueueChanged(EventArgs.Empty);
+ }
+
+ this.BackupQueue(string.Empty);
+ return job;
+ }
+
+ this.BackupQueue(string.Empty);
+ return null;
+ }
/// <summary>
- /// Gets a value indicating whether IsProcessing.
+ /// Moves an item down one position in the queue.
/// </summary>
- public bool IsProcessing { get; private set; }
+ /// <param name="index">
+ /// The zero-based location of the job in the queue.
+ /// </param>
+ public void MoveDown(int index)
+ {
+ if (index < this.queue.Count - 1)
+ {
+ QueueTask item = this.queue[index];
+
+ this.queue.RemoveAt(index);
+ this.queue.Insert((index + 1), item);
+ }
+
+ this.InvokeQueueChanged(EventArgs.Empty);
+ }
/// <summary>
- /// Gets the IEncodeService instance.
+ /// Moves an item up one position in the queue.
/// </summary>
- public IEncodeServiceWrapper EncodeService { get; private set; }
+ /// <param name="index">
+ /// The zero-based location of the job in the queue.
+ /// </param>
+ public void MoveUp(int index)
+ {
+ if (index > 0)
+ {
+ QueueTask item = this.queue[index];
+
+ this.queue.RemoveAt(index);
+ this.queue.Insert((index - 1), item);
+ }
+
+ this.InvokeQueueChanged(EventArgs.Empty);
+ }
/// <summary>
- /// Gets the IQueueManager instance.
+ /// Remove a job from the Queue.
+ /// This method is Thread Safe
/// </summary>
- public IQueueManager QueueManager { get; private set; }
+ /// <param name="job">
+ /// The job.
+ /// </param>
+ public void Remove(QueueTask job)
+ {
+ lock (QueueLock)
+ {
+ this.queue.Remove(job);
+ this.InvokeQueueChanged(EventArgs.Empty);
+ }
+ }
- #endregion
+ /// <summary>
+ /// Temp workaround until this can be fixed properly.
+ /// </summary>
+ public void ResetInstanceId()
+ {
+ this.queueFile = string.Format("hb_queue_recovery{0}.xml", GeneralUtilities.GetInstanceCount);
+ }
/// <summary>
- /// Starts encoding the first job in the queue and continues encoding until all jobs
- /// have been encoded.
+ /// Reset a Queued Item from Error or Completed to Waiting
/// </summary>
- public void Start()
+ /// <param name="job">
+ /// The job.
+ /// </param>
+ public void ResetJobStatusToWaiting(QueueTask job)
{
- if (IsProcessing)
+ if (job.Status != QueueItemStatus.Error && job.Status != QueueItemStatus.Completed)
{
- throw new Exception("Already Processing the Queue");
+ throw new GeneralApplicationException(
+ "Job Error", "Unable to reset job status as it is not in an Error or Completed state", null);
}
- IsProcessing = true;
- this.EncodeService.EncodeCompleted += this.EncodeServiceEncodeCompleted;
- this.ProcessNextJob();
+ job.Status = QueueItemStatus.Waiting;
+ }
+
+ /// <summary>
+ /// Restore a Queue from file or from the queue backup file.
+ /// </summary>
+ /// <param name="importPath">
+ /// The import path. String.Empty or null will result in the default file being loaded.
+ /// </param>
+ public void RestoreQueue(string importPath)
+ {
+ string appDataPath = Path.Combine(
+ Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), @"HandBrake\");
+ string tempPath = !string.IsNullOrEmpty(importPath)
+ ? importPath
+ : (appDataPath + string.Format(this.queueFile, string.Empty));
+
+ if (File.Exists(tempPath))
+ {
+ bool invokeUpdate = false;
+ using (
+ var strm = new FileStream(
+ (!string.IsNullOrEmpty(importPath) ? importPath : tempPath), FileMode.Open, FileAccess.Read))
+ {
+ if (strm.Length != 0)
+ {
+ var serializer = new XmlSerializer(typeof(List<QueueTask>));
+
+ List<QueueTask> list;
+
+ try
+ {
+ list = serializer.Deserialize(strm) as List<QueueTask>;
+ }
+ catch (Exception exc)
+ {
+ throw new GeneralApplicationException(
+ "Unable to restore queue file.",
+ "The file may be corrupted or from an older incompatible version of HandBrake",
+ exc);
+ }
+
+ if (list != null)
+ {
+ foreach (QueueTask item in list)
+ {
+ if (item.Status != QueueItemStatus.Completed)
+ {
+ // Reset InProgress/Error to Waiting so it can be processed
+ if (item.Status == QueueItemStatus.InProgress)
+ {
+ item.Status = QueueItemStatus.Waiting;
+ }
+
+ this.queue.Add(item);
+ }
+ }
+ }
+
+ invokeUpdate = true;
+ }
+ }
+
+ if (invokeUpdate)
+ {
+ this.InvokeQueueChanged(EventArgs.Empty);
+ }
+ }
}
/// <summary>
@@ -182,17 +432,25 @@ namespace HandBrake.ApplicationServices.Services }
/// <summary>
- /// Swap encode service.
- /// Temp method until Castle is hooked up.
+ /// Starts encoding the first job in the queue and continues encoding until all jobs
+ /// have been encoded.
/// </summary>
- /// <param name="service">
- /// The service.
- /// </param>
- public void SwapEncodeService(IEncodeServiceWrapper service)
+ public void Start()
{
- this.EncodeService = service;
+ if (this.IsProcessing)
+ {
+ throw new Exception("Already Processing the Queue");
+ }
+
+ this.IsProcessing = true;
+ this.EncodeService.EncodeCompleted += this.EncodeServiceEncodeCompleted;
+ this.ProcessNextJob();
}
+ #endregion
+
+ #region Methods
+
/// <summary>
/// After an encode is complete, move onto the next job.
/// </summary>
@@ -204,39 +462,139 @@ namespace HandBrake.ApplicationServices.Services /// </param>
private void EncodeServiceEncodeCompleted(object sender, EncodeCompletedEventArgs e)
{
- this.QueueManager.LastProcessedJob.Status = QueueItemStatus.Completed;
+ this.LastProcessedJob.Status = QueueItemStatus.Completed;
// Clear the completed item of the queue if the setting is set.
- if (userSettingService.GetUserSetting<bool>(ASUserSettingConstants.ClearCompletedFromQueue))
+ if (this.userSettingService.GetUserSetting<bool>(ASUserSettingConstants.ClearCompletedFromQueue))
{
- this.QueueManager.ClearCompleted();
+ this.ClearCompleted();
}
if (!e.Successful)
{
- this.QueueManager.LastProcessedJob.Status = QueueItemStatus.Error;
+ this.LastProcessedJob.Status = QueueItemStatus.Error;
this.Pause();
}
// Handling Log Data
- this.EncodeService.ProcessLogs(this.QueueManager.LastProcessedJob.Task.Destination);
+ this.EncodeService.ProcessLogs(this.LastProcessedJob.Task.Destination);
// Post-Processing
if (e.Successful)
{
- SendToApplication(this.QueueManager.LastProcessedJob.Task.Destination);
+ this.SendToApplication(this.LastProcessedJob.Task.Destination);
}
// Move onto the next job.
if (this.IsProcessing)
{
this.ProcessNextJob();
- }
- else
+ }
+ else
{
this.EncodeService.EncodeCompleted -= this.EncodeServiceEncodeCompleted;
this.InvokeQueueCompleted(EventArgs.Empty);
- this.QueueManager.BackupQueue(string.Empty);
+ this.BackupQueue(string.Empty);
+ }
+ }
+
+ /// <summary>
+ /// Perform an action after an encode. e.g a shutdown, standby, restart etc.
+ /// </summary>
+ private void Finish()
+ {
+ // Do something whent he encode ends.
+ switch (this.userSettingService.GetUserSetting<string>(ASUserSettingConstants.WhenCompleteAction))
+ {
+ case "Shutdown":
+ Process.Start("Shutdown", "-s -t 60");
+ break;
+ case "Log off":
+ Win32.ExitWindowsEx(0, 0);
+ break;
+ case "Suspend":
+ Application.SetSuspendState(PowerState.Suspend, true, true);
+ break;
+ case "Hibernate":
+ Application.SetSuspendState(PowerState.Hibernate, true, true);
+ break;
+ case "Lock System":
+ Win32.LockWorkStation();
+ break;
+ case "Quit HandBrake":
+ Application.Exit();
+ break;
+ }
+ }
+
+ /// <summary>
+ /// Invoke the JobProcessingStarted event
+ /// </summary>
+ /// <param name="e">
+ /// The QueueProgressEventArgs.
+ /// </param>
+ private void InvokeJobProcessingStarted(QueueProgressEventArgs e)
+ {
+ QueueProgressStatus handler = this.JobProcessingStarted;
+ if (handler != null)
+ {
+ handler(this, e);
+ }
+ }
+
+ /// <summary>
+ /// Invoke the Queue Changed Event
+ /// </summary>
+ /// <param name="e">
+ /// The e.
+ /// </param>
+ private void InvokeQueueChanged(EventArgs e)
+ {
+ try
+ {
+ this.BackupQueue(string.Empty);
+ }
+ catch (Exception)
+ {
+ // Do Nothing.
+ }
+
+ EventHandler handler = this.QueueChanged;
+ if (handler != null)
+ {
+ handler(this, e);
+ }
+ }
+
+ /// <summary>
+ /// Invoke the QueueCompleted event.
+ /// </summary>
+ /// <param name="e">
+ /// The EventArgs.
+ /// </param>
+ private void InvokeQueueCompleted(EventArgs e)
+ {
+ this.IsProcessing = false;
+
+ EventHandler handler = this.QueueCompleted;
+ if (handler != null)
+ {
+ handler(this, e);
+ }
+ }
+
+ /// <summary>
+ /// Invoke the QueuePaused event
+ /// </summary>
+ /// <param name="e">
+ /// The EventArgs.
+ /// </param>
+ private void InvokeQueuePaused(EventArgs e)
+ {
+ EventHandler handler = this.QueuePaused;
+ if (handler != null)
+ {
+ handler(this, e);
}
}
@@ -252,11 +610,11 @@ namespace HandBrake.ApplicationServices.Services return;
}
- QueueTask job = this.QueueManager.GetNextJobForProcessing();
+ QueueTask job = this.GetNextJobForProcessing();
if (job != null)
{
this.InvokeJobProcessingStarted(new QueueProgressEventArgs(job));
- this.EncodeService.Start(job, true);
+ this.EncodeService.Start(job, true);
}
else
{
@@ -267,53 +625,32 @@ namespace HandBrake.ApplicationServices.Services this.InvokeQueueCompleted(EventArgs.Empty);
// Run the After encode completeion work
- Finish();
+ this.Finish();
}
}
/// <summary>
/// Send a file to a 3rd party application after encoding has completed.
/// </summary>
- /// <param name="file"> The file path</param>
+ /// <param name="file">
+ /// The file path
+ /// </param>
private void SendToApplication(string file)
{
- if (userSettingService.GetUserSetting<bool>(ASUserSettingConstants.SendFile) && !string.IsNullOrEmpty(userSettingService.GetUserSetting<string>(ASUserSettingConstants.SendFileTo)))
+ if (this.userSettingService.GetUserSetting<bool>(ASUserSettingConstants.SendFile) &&
+ !string.IsNullOrEmpty(this.userSettingService.GetUserSetting<string>(ASUserSettingConstants.SendFileTo)))
{
- string args = string.Format("{0} \"{1}\"", userSettingService.GetUserSetting<string>(ASUserSettingConstants.SendFileToArgs), file);
- ProcessStartInfo vlc = new ProcessStartInfo(userSettingService.GetUserSetting<string>(ASUserSettingConstants.SendFileTo), args);
+ string args = string.Format(
+ "{0} \"{1}\"",
+ this.userSettingService.GetUserSetting<string>(ASUserSettingConstants.SendFileToArgs),
+ file);
+ var vlc =
+ new ProcessStartInfo(
+ this.userSettingService.GetUserSetting<string>(ASUserSettingConstants.SendFileTo), args);
Process.Start(vlc);
}
}
- /// <summary>
- /// Perform an action after an encode. e.g a shutdown, standby, restart etc.
- /// </summary>
- private void Finish()
- {
- // Do something whent he encode ends.
- switch (userSettingService.GetUserSetting<string>(ASUserSettingConstants.WhenCompleteAction))
- {
- case "Shutdown":
- Process.Start("Shutdown", "-s -t 60");
- break;
- case "Log off":
- Win32.ExitWindowsEx(0, 0);
- break;
- case "Suspend":
- Application.SetSuspendState(PowerState.Suspend, true, true);
- break;
- case "Hibernate":
- Application.SetSuspendState(PowerState.Hibernate, true, true);
- break;
- case "Lock System":
- Win32.LockWorkStation();
- break;
- case "Quit HandBrake":
- Application.Exit();
- break;
- default:
- break;
- }
- }
+ #endregion
}
}
\ No newline at end of file diff --git a/win/CS/HandBrake.ApplicationServices/ServicesWindsorInstaller.cs b/win/CS/HandBrake.ApplicationServices/ServicesWindsorInstaller.cs index d2e0f0bb7..b787aa18b 100644 --- a/win/CS/HandBrake.ApplicationServices/ServicesWindsorInstaller.cs +++ b/win/CS/HandBrake.ApplicationServices/ServicesWindsorInstaller.cs @@ -30,11 +30,8 @@ namespace HandBrake.ApplicationServices public void Install(IWindsorContainer container, IConfigurationStore store)
{
container.Register(Component.For<IPresetService>().ImplementedBy<PresetService>());
- container.Register(Component.For<IQueueManager>().ImplementedBy<QueueManager>());
container.Register(Component.For<IQueueProcessor>().ImplementedBy<QueueProcessor>());
container.Register(Component.For<IUserSettingService>().ImplementedBy<UserSettingService>());
- // container.Register(Component.For<IScan>().ImplementedBy<ScanService>());
- // container.Register(Component.For<IEncode>().ImplementedBy<Encode>());
}
#endregion
|