diff options
| author | Roy Ben-Shabat <Roy@Twine-s.com> | 2018-05-09 18:07:56 +0300 |
|---|---|---|
| committer | Roy Ben-Shabat <Roy@Twine-s.com> | 2018-05-09 18:07:56 +0300 |
| commit | e1236499b485a69648bea4d7871aa185e5dae745 (patch) | |
| tree | 8cd4ccd7d272c8c4e61d4bd6bcba434eb9522b85 /Software/Visual_Studio | |
| parent | 2a459c79e90a2ade3f1dac1ae4541c0f4d74965c (diff) | |
| download | Tango-e1236499b485a69648bea4d7871aa185e5dae745.tar.gz Tango-e1236499b485a69648bea4d7871aa185e5dae745.zip | |
New TemporaryManager !
Diffstat (limited to 'Software/Visual_Studio')
24 files changed, 678 insertions, 134 deletions
diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Developer/ViewModels/MainViewVM.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Developer/ViewModels/MainViewVM.cs index ab0df302e..739f0bcde 100644 --- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Developer/ViewModels/MainViewVM.cs +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Developer/ViewModels/MainViewVM.cs @@ -1856,8 +1856,8 @@ namespace Tango.MachineStudio.Developer.ViewModels { try { - String tempPath = PathHelper.GetTempFolderPath(); - String filePath = Path.Combine(tempPath, job.EmbroideryFileName); + var tempDir = TemporaryManager.CreateFolder(); + String filePath = Path.Combine(tempDir.Path, job.EmbroideryFileName); File.WriteAllBytes(filePath, job.EmbroideryFileData); EmbroideryFileConverter.ConvertEmbroideryFile(filePath, dlg.FileName); _notification.ShowInfo("Embroidery file exported successfully."); diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Stubs/ViewModels/MainViewVM.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Stubs/ViewModels/MainViewVM.cs index 54aa0c22b..df47273d0 100644 --- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Stubs/ViewModels/MainViewVM.cs +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Stubs/ViewModels/MainViewVM.cs @@ -451,7 +451,7 @@ namespace Tango.MachineStudio.Stubs.ViewModels ScriptEngine engine = new ScriptEngine(new StubOnExecuteParameters(_stubManager)); engine.ReferencedAssemblies.Add(this.GetType()); - await engine.Run(SelectedCodeTab.Code); + await engine.Run(SelectedCodeTab.Code,null); if (!thisStubManager.Aborted) { diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Synchronization/ViewModels/DirectSynchronizationViewVM.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Synchronization/ViewModels/DirectSynchronizationViewVM.cs index bb5ef68f1..b2175b46c 100644 --- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Synchronization/ViewModels/DirectSynchronizationViewVM.cs +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Synchronization/ViewModels/DirectSynchronizationViewVM.cs @@ -208,7 +208,7 @@ namespace Tango.MachineStudio.Synchronization.ViewModels using (_notification.PushTaskItem("Generating temporary files...")) { - String tempFolder = PathHelper.GetTempFolderPath(); + var tempFolder = TemporaryManager.CreateFolder(); //File path for the reflected remote data base SQLite. _masterDBFile = Path.Combine(tempFolder, "Remote.db"); diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Console/ConsoleWindowVM.cs b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Console/ConsoleWindowVM.cs index a3a0a734e..10b05bc64 100644 --- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Console/ConsoleWindowVM.cs +++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Console/ConsoleWindowVM.cs @@ -175,7 +175,7 @@ namespace Tango.MachineStudio.UI.Console engine.ReferencedAssemblies.Add(module.GetType()); } - await engine.Run(Code); + await engine.Run(Code, null); } private void WriteLine(String text) diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/TFS/TeamFoundationServiceExtendedClient.cs b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/TFS/TeamFoundationServiceExtendedClient.cs index 79572eb71..eb3572728 100644 --- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/TFS/TeamFoundationServiceExtendedClient.cs +++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/TFS/TeamFoundationServiceExtendedClient.cs @@ -133,13 +133,13 @@ namespace Tango.MachineStudio.UI.TFS item.Type = WorkItemType.Bug; var bitmap = UIHelper.TakeSnapshot(MainWindow.Instance); - String filePath = PathHelper.GetTempFilePath(); - bitmap.SaveJpeg(filePath, 30); + var tempFile = TemporaryManager.CreateFile(); + bitmap.SaveJpeg(tempFile.Path, 30); item.Attachments.Add(new Attachment() { Description = "Screen Capture", - FilePath = filePath, + FilePath = tempFile.Path, Name = "Screen Capture.jpg", }); @@ -156,26 +156,26 @@ namespace Tango.MachineStudio.UI.TFS if (appFileLogger != null) { - String appLogFile = PathHelper.GetTempFilePath(); - File.Copy(appFileLogger.LogFile, appLogFile); + var appLogFile = TemporaryManager.CreateFile(); + File.Copy(appFileLogger.LogFile, appLogFile.Path); item.Attachments.Add(new Attachment() { Description = "Application Log File", - FilePath = appLogFile, + FilePath = appLogFile.Path, Name = Path.GetFileName(appFileLogger.LogFile), }); } if (embeddedFileLogger != null && File.Exists(embeddedFileLogger.LogFile)) { - String embeddedLogFile = PathHelper.GetTempFilePath(); - File.Copy(appFileLogger.LogFile, embeddedLogFile); + var embeddedLogFile = TemporaryManager.CreateFile(); + File.Copy(appFileLogger.LogFile, embeddedLogFile.Path); item.Attachments.Add(new Attachment() { Description = "Embedded Log File", - FilePath = embeddedLogFile, + FilePath = embeddedLogFile.Path, Name = Path.GetFileName(embeddedFileLogger.LogFile), }); } @@ -201,13 +201,13 @@ namespace Tango.MachineStudio.UI.TFS machineView.Background = System.Windows.Media.Brushes.White; machineView.DataContext = new MachineDesigner.ViewModels.MainViewVM() { SelectedMachine = machine, Configuration = machine.Configuration }; - String configImageFile = PathHelper.GetTempFilePath(); - machineView.RenderToFile(configImageFile, System.Drawing.Imaging.ImageFormat.Jpeg, new Size(machineView.Width, machineView.Height), 100); + var configImageFile = TemporaryManager.CreateFile(); + machineView.RenderToFile(configImageFile.Path, System.Drawing.Imaging.ImageFormat.Jpeg, new Size(machineView.Width, machineView.Height), 100); item.Attachments.Add(new Attachment() { Description = "Machine Configuration", - FilePath = configImageFile, + FilePath = configImageFile.Path, Name = "Machine Configuration.jpg" }); diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModels/UpdateViewVM.cs b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModels/UpdateViewVM.cs index 0f6ec8b98..c8b4b6adc 100644 --- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModels/UpdateViewVM.cs +++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModels/UpdateViewVM.cs @@ -13,6 +13,7 @@ using System.Threading.Tasks; using Tango.Core.Commands; using Tango.Core.DI; using Tango.Core.Helpers; +using Tango.Core.IO; using Tango.Logging; using Tango.MachineStudio.Common.Authentication; using Tango.MachineStudio.Common.Navigation; @@ -45,7 +46,7 @@ namespace Tango.MachineStudio.UI.ViewModels private IStudioApplicationManager _application; private IAuthenticationProvider _authentication; private CheckForUpdatesResponse _updateInfo; - private String _newPackageTempFolder; + private TemporaryFolder _newPackageTempFolder; private UpdateStatus _status; public UpdateStatus Status @@ -184,7 +185,7 @@ namespace Tango.MachineStudio.UI.ViewModels Task.Factory.StartNew(() => { - var tempFile = PathHelper.GetTempFilePath() + ".zip"; + var tempFile = TemporaryManager.CreateFile(".zip"); try { @@ -192,7 +193,7 @@ namespace Tango.MachineStudio.UI.ViewModels int fileSize = 0; - using (FileStreamWrapper fs = new FileStreamWrapper(tempFile, FileMode.Create, (current) => + using (FileStreamWrapper fs = new FileStreamWrapper(tempFile.Path, FileMode.Create, (current) => { InvokeUINow(() => { @@ -216,9 +217,10 @@ namespace Tango.MachineStudio.UI.ViewModels Status = UpdateStatus.Updating; - _newPackageTempFolder = PathHelper.GetTempFolderPath(); + _newPackageTempFolder = TemporaryManager.CreateFolder(); + _newPackageTempFolder.Persist = true; - using (ZipFile zip = ZipFile.Read(tempFile)) + using (ZipFile zip = ZipFile.Read(tempFile.Path)) { int currentEntry = 0; @@ -235,7 +237,7 @@ namespace Tango.MachineStudio.UI.ViewModels { Thread.Sleep(10); - string newPath = Path.Combine(_newPackageTempFolder, entry.FileName); + string newPath = Path.Combine(_newPackageTempFolder.Path, entry.FileName); try { @@ -246,7 +248,7 @@ namespace Tango.MachineStudio.UI.ViewModels else { CurrentUpdateFile = Path.GetFileName(entry.FileName); - entry.Extract(_newPackageTempFolder, ExtractExistingFileAction.OverwriteSilently); + entry.Extract(_newPackageTempFolder.Path, ExtractExistingFileAction.OverwriteSilently); } } catch @@ -266,7 +268,7 @@ namespace Tango.MachineStudio.UI.ViewModels } finally { - PathHelper.TryDeleteFile(tempFile); + tempFile.Delete(); } }); } diff --git a/Software/Visual_Studio/Tango.Core/ExtendedObject.cs b/Software/Visual_Studio/Tango.Core/ExtendedObject.cs index 8ed7c5ecd..30179c3bf 100644 --- a/Software/Visual_Studio/Tango.Core/ExtendedObject.cs +++ b/Software/Visual_Studio/Tango.Core/ExtendedObject.cs @@ -9,6 +9,7 @@ using System.Text; using System.Threading.Tasks; using System.Windows; using Tango.Core.Commands; +using Tango.Core.IO; using Tango.Logging; namespace Tango.Core @@ -30,12 +31,23 @@ namespace Tango.Core /// Gets the default log manager. /// </summary> [JsonIgnore] + [NotMapped] public LogManager LogManager { get { return LogManager.Default; } } /// <summary> + /// Gets the temporary manager. + /// </summary> + [JsonIgnore] + [NotMapped] + public TemporaryManager TemporaryManager + { + get { return TemporaryManager.Default; } + } + + /// <summary> /// Occurs when a property has changed. /// </summary> [field: NonSerialized] diff --git a/Software/Visual_Studio/Tango.Core/ExtensionMethods/IEnumerableExtensions.cs b/Software/Visual_Studio/Tango.Core/ExtensionMethods/IEnumerableExtensions.cs index 1bb72d3e2..60c1c5656 100644 --- a/Software/Visual_Studio/Tango.Core/ExtensionMethods/IEnumerableExtensions.cs +++ b/Software/Visual_Studio/Tango.Core/ExtensionMethods/IEnumerableExtensions.cs @@ -22,6 +22,17 @@ public static class IEnumerableExtensions } /// <summary> + /// Creates a new read-only collection from the specified enumerable. + /// </summary> + /// <typeparam name="T"></typeparam> + /// <param name="enumerable">The enumerable.</param> + /// <returns></returns> + public static ReadOnlyCollection<T> ToReadOnlyCollection<T>(this IEnumerable<T> enumerable) + { + return new ReadOnlyCollection<T>(enumerable.ToList()); + } + + /// <summary> /// Replace an element in the array. /// </summary> /// <typeparam name="T"></typeparam> diff --git a/Software/Visual_Studio/Tango.Core/Helpers/PathHelper.cs b/Software/Visual_Studio/Tango.Core/Helpers/PathHelper.cs index 8b4338164..cd1f4b30b 100644 --- a/Software/Visual_Studio/Tango.Core/Helpers/PathHelper.cs +++ b/Software/Visual_Studio/Tango.Core/Helpers/PathHelper.cs @@ -12,27 +12,27 @@ namespace Tango.Core.Helpers /// </summary> public static class PathHelper { - /// <summary> - /// Creates a temporary folder in %temp%\Twine\{Random} and returns the path to that folder. - /// </summary> - /// <returns></returns> - public static String GetTempFolderPath() - { - String tempDirectory = Path.Combine(Path.GetTempPath(), "Twine", Path.GetRandomFileName()); - Directory.CreateDirectory(tempDirectory); - return tempDirectory; - } + ///// <summary> + ///// Creates a temporary folder in %temp%\Twine\{Random} and returns the path to that folder. + ///// </summary> + ///// <returns></returns> + //public static String GetTempFolderPath() + //{ + // String tempDirectory = Path.Combine(Path.GetTempPath(), "Twine", Path.GetRandomFileName()); + // Directory.CreateDirectory(tempDirectory); + // return tempDirectory; + //} - /// <summary> - /// Creates a temporary folder and file in %temp%\Twine\{RandomFile} and returns the path to that file. - /// </summary> - /// <returns></returns> - public static String GetTempFilePath() - { - String tempDirectory = Path.Combine(Path.GetTempPath(), "Twine"); - Directory.CreateDirectory(tempDirectory); - return Path.Combine(tempDirectory, Path.GetRandomFileName()); - } + ///// <summary> + ///// Creates a temporary folder and file in %temp%\Twine\{RandomFile} and returns the path to that file. + ///// </summary> + ///// <returns></returns> + //public static String GetTempFilePath() + //{ + // String tempDirectory = Path.Combine(Path.GetTempPath(), "Twine"); + // Directory.CreateDirectory(tempDirectory); + // return Path.Combine(tempDirectory, Path.GetRandomFileName()); + //} /// <summary> /// Gets the application startup path. @@ -43,23 +43,23 @@ namespace Tango.Core.Helpers return AppDomain.CurrentDomain.BaseDirectory; } - /// <summary> - /// Tries to delete the specified folder. - /// </summary> - /// <param name="path">The folder path.</param> - /// <returns></returns> - public static bool TryDeleteFolder(String path) - { - try - { - Directory.Delete(path, true); - return true; - } - catch - { - return false; - } - } + ///// <summary> + ///// Tries to delete the specified folder. + ///// </summary> + ///// <param name="path">The folder path.</param> + ///// <returns></returns> + //public static bool TryDeleteFolder(String path) + //{ + // try + // { + // Directory.Delete(path, true); + // return true; + // } + // catch + // { + // return false; + // } + //} /// <summary> /// Tries to delete the specified file. diff --git a/Software/Visual_Studio/Tango.Core/IO/ITemporaryItem.cs b/Software/Visual_Studio/Tango.Core/IO/ITemporaryItem.cs index ebfc70e60..cf1045a60 100644 --- a/Software/Visual_Studio/Tango.Core/IO/ITemporaryItem.cs +++ b/Software/Visual_Studio/Tango.Core/IO/ITemporaryItem.cs @@ -6,13 +6,58 @@ using System.Threading.Tasks; namespace Tango.Core.IO { + /// <summary> + /// Represents a <see cref="TemporaryManager"/> item. + /// </summary> public interface ITemporaryItem { + /// <summary> + /// Occurs when this item has been deleted. + /// </summary> + event EventHandler Deleted; + /// <summary> + /// Gets the creation date of the temporary item. + /// </summary> DateTime Date { get; } + /// <summary> + /// Gets the path to the temporary item. + /// </summary> String Path { get; } + /// <summary> + /// Gets the optional item tag. + /// </summary> + Object Tag { get; } + /// <summary> + /// Gets or sets a value indicating whether this <see cref="ITemporaryItem"/> should not be deleted by a parent item. + /// </summary> + bool Persist { get; set; } + /// <summary> + /// Gets the collection of child items. + /// </summary> IReadOnlyCollection<ITemporaryItem> Items { get; } - void AddItem(ITemporaryItem item); + /// <summary> + /// Adds a child item. + /// </summary> + /// <param name="item">The item.</param> + ITemporaryItem AddItem(ITemporaryItem item); + /// <summary> + /// Removes the specified child item. + /// </summary> + /// <param name="item">The item.</param> void RemoveItem(ITemporaryItem item); - void Delete(); + /// <summary> + /// Deletes the temporary item. + /// </summary> + /// <returns>True is deletion was successful.</returns> + bool Delete(); + /// <summary> + /// Deletes the temporary item asynchronously. + /// </summary> + /// <returns>True is deletion was successful.</returns> + Task<bool> DeleteAsync(); + /// <summary> + /// Makes the temporary item visible to the user somehow. + /// </summary> + void Display(); } } diff --git a/Software/Visual_Studio/Tango.Core/IO/TemporaryFile.cs b/Software/Visual_Studio/Tango.Core/IO/TemporaryFile.cs index 4e119875e..3e5bd579e 100644 --- a/Software/Visual_Studio/Tango.Core/IO/TemporaryFile.cs +++ b/Software/Visual_Studio/Tango.Core/IO/TemporaryFile.cs @@ -1,13 +1,104 @@ using System; using System.Collections.Generic; +using System.Diagnostics; +using System.IO; using System.Linq; using System.Text; using System.Threading.Tasks; namespace Tango.Core.IO { - public class TemporaryFile + /// <summary> + /// Represents a temporary file. + /// </summary> + /// <seealso cref="Tango.Core.IO.TemporaryItem" /> + public class TemporaryFile : TemporaryItem { + /// <summary> + /// Initializes a new instance of the <see cref="TemporaryFile"/> class. + /// </summary> + /// <param name="path">The temporary item path.</param> + public TemporaryFile(string path) : base(path) + { + Create(); + } + /// <summary> + /// Initializes a new instance of the <see cref="TemporaryFile"/> class. + /// </summary> + /// <param name="path">The temporary item path.</param> + /// <param name="tag">The item tag.</param> + public TemporaryFile(string path, object tag) : base(path, tag) + { + Create(); + } + + /// <summary> + /// Deletes the temporary item. + /// </summary> + /// <returns> + /// True is deletion was successful. + /// </returns> + public override bool Delete() + { + base.Delete(); + + try + { + if (File.Exists(Path)) + { + File.Delete(Path); + } + + return true; + } + catch + { + return false; + } + } + + /// <summary> + /// Creates/Overwrites a new file in the specified path. + /// </summary> + public virtual void Create() + { + File.Create(Path).Dispose(); + } + + /// <summary> + /// Creates a stream to the file path. + /// </summary> + /// <returns></returns> + public virtual FileStream CreateStream() + { + return new FileStream(Path, FileMode.OpenOrCreate); + } + + /// <summary> + /// Writes the specified text to the file. + /// </summary> + /// <param name="text">The text.</param> + public virtual void WriteAllText(String text) + { + File.WriteAllText(Path, text); + } + + /// <summary> + /// Writes the specified bytes to the file. + /// </summary> + /// <param name="data">The data.</param> + public virtual void WriteAllBytes(byte[] data) + { + File.WriteAllBytes(Path, data); + } + + /// <summary> + /// Makes the temporary item visible to the user somehow. + /// </summary> + public override void Display() + { + Process.Start("explorer.exe", string.Format("/select,\"{0}\"", Path)); + } } } diff --git a/Software/Visual_Studio/Tango.Core/IO/TemporaryFileManager.cs b/Software/Visual_Studio/Tango.Core/IO/TemporaryFileManager.cs deleted file mode 100644 index a4ff8fa27..000000000 --- a/Software/Visual_Studio/Tango.Core/IO/TemporaryFileManager.cs +++ /dev/null @@ -1,39 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace Tango.Core.IO -{ - /// <summary> - /// Represents the Tango system temporary file manager. - /// </summary> - public class TemporaryFileManager - { - #region Singleton - - private static TemporaryFileManager _default; - public static TemporaryFileManager Default - { - get - { - if (_default == null) - { - _default = new TemporaryFileManager(); - } - - return _default; - } - } - - private TemporaryFileManager() - { - - } - - #endregion - - - } -} diff --git a/Software/Visual_Studio/Tango.Core/IO/TemporaryFolder.cs b/Software/Visual_Studio/Tango.Core/IO/TemporaryFolder.cs new file mode 100644 index 000000000..f9cc4a088 --- /dev/null +++ b/Software/Visual_Studio/Tango.Core/IO/TemporaryFolder.cs @@ -0,0 +1,87 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Tango.Core.IO +{ + /// <summary> + /// Represents a temporary folder. + /// </summary> + /// <seealso cref="Tango.Core.IO.TemporaryItem" /> + public class TemporaryFolder : TemporaryItem + { + /// <summary> + /// Initializes a new instance of the <see cref="TemporaryFolder"/> class. + /// </summary> + /// <param name="path">The temporary item path.</param> + public TemporaryFolder(string path) : base(path) + { + Directory.CreateDirectory(path); + } + + /// <summary> + /// Initializes a new instance of the <see cref="TemporaryFolder"/> class. + /// </summary> + /// <param name="path">The temporary item path.</param> + /// <param name="tag">The item tag.</param> + public TemporaryFolder(string path, object tag) : base(path, tag) + { + Directory.CreateDirectory(path); + } + + /// <summary> + /// Deletes the temporary item. + /// </summary> + /// <returns> + /// True is deletion was successful. + /// </returns> + public override bool Delete() + { + base.Delete(); + + try + { + if (Directory.Exists(Path)) + { + Directory.Delete(Path); + } + + return true; + } + catch + { + return false; + } + } + + /// <summary> + /// Creates a new temporary file inside the temp folder and returns the file item. + /// </summary> + /// <returns></returns> + public virtual TemporaryFile CreateFile(String extension = null) + { + return AddItem(new TemporaryFile(System.IO.Path.Combine(Path, System.IO.Path.GetRandomFileName() + extension))) as TemporaryFile; + } + + /// <summary> + /// Creates a new temporary folder inside the temp folder and returns the folder item. + /// </summary> + /// <returns></returns> + public virtual TemporaryFolder CreateFolder() + { + return AddItem(new TemporaryFolder(System.IO.Path.Combine(Path, System.IO.Path.GetRandomFileName()))) as TemporaryFolder; + } + + /// <summary> + /// Makes the temporary item visible to the user somehow. + /// </summary> + public override void Display() + { + Process.Start("explorer.exe", string.Format("/select,\"{0}\"", Path)); + } + } +} diff --git a/Software/Visual_Studio/Tango.Core/IO/TemporaryItem.cs b/Software/Visual_Studio/Tango.Core/IO/TemporaryItem.cs index 46464bf15..662a0ad58 100644 --- a/Software/Visual_Studio/Tango.Core/IO/TemporaryItem.cs +++ b/Software/Visual_Studio/Tango.Core/IO/TemporaryItem.cs @@ -4,31 +4,168 @@ using System.Linq; using System.Text; using System.Threading.Tasks; using System.Collections.ObjectModel; +using System.IO; namespace Tango.Core.IO { + /// <summary> + /// Represents a temporary item base class. + /// </summary> + /// <seealso cref="Tango.Core.IO.ITemporaryItem" /> public abstract class TemporaryItem : ITemporaryItem { + /// <summary> + /// Occurs when this item has been deleted. + /// </summary> + public event EventHandler Deleted; + + /// <summary> + /// Gets the creation date of the temporary item. + /// </summary> public DateTime Date { get; protected set; } - public abstract string Path { get; protected set; } - public abstract IReadOnlyCollection<ITemporaryItem> Items { get; protected set; } - public virtual void AddItem(ITemporaryItem item) + /// <summary> + /// Gets the path to the temporary item. + /// </summary> + public string Path { get; protected set; } + + /// <summary> + /// Gets the optional item tag. + /// </summary> + public Object Tag { get; protected set; } + + /// <summary> + /// Gets or sets a value indicating whether this <see cref="ITemporaryItem" /> should not be deleted by a parent item. + /// </summary> + public bool Persist { get; set; } + + /// <summary> + /// Gets the collection of child items. + /// </summary> + public IReadOnlyCollection<ITemporaryItem> Items { get; private set; } + + /// <summary> + /// Initializes a new instance of the <see cref="TemporaryItem"/> class. + /// </summary> + /// <param name="path">The temporary item path.</param> + /// <param name="tag">The item tag.</param> + public TemporaryItem(String path, Object tag) + { + Items = new ReadOnlyCollection<ITemporaryItem>(new List<ITemporaryItem>()); + Date = DateTime.Now; + Path = path; + Tag = tag; + } + + /// <summary> + /// Initializes a new instance of the <see cref="TemporaryItem"/> class. + /// </summary> + /// <param name="path">The temporary item path.</param> + public TemporaryItem(String path) : this(path, null) { + + } + + /// <summary> + /// Adds a child item. + /// </summary> + /// <param name="item">The item.</param> + public ITemporaryItem AddItem(ITemporaryItem item) + { + item.Deleted += Item_Deleted; var list = Items.ToList(); list.Add(item); + Items = list.ToReadOnlyCollection(); + return item; + } - //IReadOnlyCollection<String> s = new ReadOnlyCollection<String>(); + /// <summary> + /// Removes the specified child item. + /// </summary> + public void RemoveItem(ITemporaryItem item) + { + item.Deleted -= Item_Deleted; + var list = Items.ToList(); + list.Remove(item); + Items = list.ToReadOnlyCollection(); + } + + /// <summary> + /// Handles the Deleted event of the child Item. + /// </summary> + /// <param name="sender">The source of the event.</param> + /// <param name="e">The <see cref="EventArgs"/> instance containing the event data.</param> + private void Item_Deleted(object sender, EventArgs e) + { + RemoveItem(sender as ITemporaryItem); } - public virtual void Delete() + /// <summary> + /// Deletes the temporary item. + /// </summary> + /// <returns> + /// True is deletion was successful. + /// </returns> + public virtual bool Delete() { + List<ITemporaryItem> remained = new List<ITemporaryItem>(); + + var items = Items; + + foreach (var item in items.Where(x => !x.Persist)) + { + if (!item.Delete()) + { + remained.Add(item); + } + else + { + Deleted?.Invoke(this, new EventArgs()); + } + } + + Items = new ReadOnlyCollection<ITemporaryItem>(remained); + return remained.Count == 0; } - public virtual void RemoveItem(ITemporaryItem item) + /// <summary> + /// Deletes the temporary item asynchronously. + /// </summary> + /// <returns> + /// True is deletion was successful. + /// </returns> + public Task<bool> DeleteAsync() { + return Task.Factory.StartNew<bool>(() => Delete()); + } + + /// <summary> + /// Makes the temporary item visible to the user somehow. + /// </summary> + public abstract void Display(); + + /// <summary> + /// Returns a <see cref="System.String" /> that represents this instance. + /// </summary> + /// <returns> + /// A <see cref="System.String" /> that represents this instance. + /// </returns> + public override string ToString() + { + return Path; + } + /// <summary> + /// Performs an explicit conversion from <see cref="TemporaryItem"/> to <see cref="String"/>. + /// </summary> + /// <param name="item">The item.</param> + /// <returns> + /// The result of the conversion. + /// </returns> + public static implicit operator String(TemporaryItem item) + { + return item.Path; } } } diff --git a/Software/Visual_Studio/Tango.Core/IO/TemporaryManager.cs b/Software/Visual_Studio/Tango.Core/IO/TemporaryManager.cs new file mode 100644 index 000000000..27702bd7f --- /dev/null +++ b/Software/Visual_Studio/Tango.Core/IO/TemporaryManager.cs @@ -0,0 +1,156 @@ +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Tango.Core.IO +{ + /// <summary> + /// Represents the Tango system temporary file manager. + /// </summary> + public class TemporaryManager : IDisposable + { + #region Singleton + + private static TemporaryManager _default; + /// <summary> + /// Gets the default temporary manager instance. + /// </summary> + public static TemporaryManager Default + { + get + { + if (_default == null) + { + _default = new TemporaryManager(); + } + + return _default; + } + } + + /// <summary> + /// Prevents a default instance of the <see cref="TemporaryManager"/> class from being created. + /// </summary> + private TemporaryManager() + { + Items = new List<ITemporaryItem>().ToReadOnlyCollection(); + RootPath = Path.Combine(Path.GetTempPath(), "Twine"); + Directory.CreateDirectory(RootPath); + } + + #endregion + + private bool _disposed; + + /// <summary> + /// Gets or sets the temporary root path. + /// </summary> + public String RootPath { get; protected set; } + + /// <summary> + /// Gets the collection of temporary items. + /// </summary> + public IReadOnlyCollection<ITemporaryItem> Items { get; protected set; } + + /// <summary> + /// Adds the item. + /// </summary> + /// <param name="item">The item.</param> + private void AddItem(ITemporaryItem item) + { + var list = Items.ToList(); + list.Add(item); + Items = list.ToReadOnlyCollection(); + item.Deleted += Item_Deleted; + } + + /// <summary> + /// Removes the item. + /// </summary> + /// <param name="item">The item.</param> + private void RemoveItem(ITemporaryItem item) + { + var list = Items.ToList(); + list.Remove(item); + Items = list.ToReadOnlyCollection(); + item.Deleted -= Item_Deleted; + } + + /// <summary> + /// Handles the Deleted event of the item. + /// </summary> + /// <param name="sender">The source of the event.</param> + /// <param name="e">The <see cref="EventArgs"/> instance containing the event data.</param> + private void Item_Deleted(object sender, EventArgs e) + { + RemoveItem(sender as ITemporaryItem); + } + + /// <summary> + /// Creates a new temporary folder and returns the folder item. + /// </summary> + /// <returns></returns> + public virtual TemporaryFolder CreateFolder() + { + TemporaryFolder folder = new TemporaryFolder(Path.Combine(RootPath, Path.GetRandomFileName())); + AddItem(folder); + return folder; + } + + /// <summary> + /// Creates a new temporary file and returns the file item. + /// </summary> + /// <returns></returns> + public virtual TemporaryFile CreateFile(String extension = null) + { + TemporaryFile file = new TemporaryFile(Path.Combine(RootPath, Path.GetRandomFileName() + extension)); + AddItem(file); + return file; + } + + /// <summary> + /// Deletes all items. + /// </summary> + public virtual void Clean() + { + var items = Items; + + foreach (var item in items.Where(x => !x.Persist)) + { + item.Delete(); + } + } + + /// <summary> + /// Deletes all items. + /// </summary> + public virtual Task CleanAsync() + { + return Task.Factory.StartNew(() => Clean()); + } + + /// <summary> + /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. + /// </summary> + public void Dispose() + { + if (!_disposed) + { + Clean(); + _disposed = true; + } + } + + /// <summary> + /// Finalizes an instance of the <see cref="TemporaryManager"/> class. + /// </summary> + ~TemporaryManager() + { + Dispose(); + } + } +} diff --git a/Software/Visual_Studio/Tango.Core/Tango.Core.csproj b/Software/Visual_Studio/Tango.Core/Tango.Core.csproj index 7063f4d86..97fbe7fd8 100644 --- a/Software/Visual_Studio/Tango.Core/Tango.Core.csproj +++ b/Software/Visual_Studio/Tango.Core/Tango.Core.csproj @@ -92,7 +92,8 @@ <Compile Include="Helpers\ThreadsHelper.cs" /> <Compile Include="IO\ITemporaryItem.cs" /> <Compile Include="IO\TemporaryFile.cs" /> - <Compile Include="IO\TemporaryFileManager.cs" /> + <Compile Include="IO\TemporaryFolder.cs" /> + <Compile Include="IO\TemporaryManager.cs" /> <Compile Include="IO\TemporaryItem.cs" /> <Compile Include="IParameterized.cs" /> <Compile Include="Json\HtmlContractResolver.cs" /> diff --git a/Software/Visual_Studio/Tango.Integration/Diagnostics/DiagnosticsFileRecorder.cs b/Software/Visual_Studio/Tango.Integration/Diagnostics/DiagnosticsFileRecorder.cs index 6482b579e..4b0517b34 100644 --- a/Software/Visual_Studio/Tango.Integration/Diagnostics/DiagnosticsFileRecorder.cs +++ b/Software/Visual_Studio/Tango.Integration/Diagnostics/DiagnosticsFileRecorder.cs @@ -12,6 +12,7 @@ using System.Windows.Media.Imaging; using Tango.BL.Entities; using Tango.Core; using Tango.Core.Helpers; +using Tango.Core.IO; using Tango.Logging; using Tango.PMR.Diagnostics; using Tango.Serialization; @@ -28,7 +29,7 @@ namespace Tango.Integration.Diagnostics { private ConcurrentQueue<DataFileFrame> _frames; //Holds the queue of data frames ready to be written to file. private Thread _recordingThread; //Holds the recording thread. - private String _tempDataFileName; //Holds the temporary recording file name. + private TemporaryFile _tempDataFile; //Holds the temporary recording file name. private FileStream _dataFileStream; //Holds the temporary recording file stream. private TaskCompletionSource<object> _stopCompletionSource; //Holds the "Stop" async method completion source. private DiagnosticsTimeCodeChannel _timeCodeChannel; //Holds the diagnostics time code channel. @@ -139,7 +140,7 @@ namespace Tango.Integration.Diagnostics _stopWatch.Stop(); _stopWatch = null; } - _tempDataFileName = PathHelper.GetTempFilePath(); + _tempDataFile = TemporaryManager.CreateFile(); _frames = new ConcurrentQueue<DataFileFrame>(); _events = new List<DiagnosticsFileEvent>(); _timeCodeChannel = new DiagnosticsTimeCodeChannel(); @@ -148,7 +149,7 @@ namespace Tango.Integration.Diagnostics TotalVideoFramesRecorded = 0; TotalBytesRecorded = 0; - _dataFileStream = new FileStream(_tempDataFileName, FileMode.Create); + _dataFileStream = _tempDataFile.CreateStream(); IsRecording = true; _recordingThread = new Thread(RecordingThreadMethod); @@ -268,7 +269,7 @@ namespace Tango.Integration.Diagnostics writer.Write(timeCodeData.Length); writer.Write(timeCodeData, 0, timeCodeData.Length); - using (Stream dataFileStream = File.OpenRead(_tempDataFileName)) + using (Stream dataFileStream = _tempDataFile.CreateStream()) { dataFileStream.CopyTo(fs); } @@ -347,7 +348,7 @@ namespace Tango.Integration.Diagnostics /// </summary> public void Dispose() { - PathHelper.TryDeleteFile(_tempDataFileName); + _tempDataFile.Delete(); } #endregion diff --git a/Software/Visual_Studio/Tango.Protobuf/Compilers/CCompiler.cs b/Software/Visual_Studio/Tango.Protobuf/Compilers/CCompiler.cs index fa0f130ac..1a8dc632f 100644 --- a/Software/Visual_Studio/Tango.Protobuf/Compilers/CCompiler.cs +++ b/Software/Visual_Studio/Tango.Protobuf/Compilers/CCompiler.cs @@ -5,6 +5,7 @@ using System.Linq; using System.Text; using System.Threading.Tasks; using Tango.Core.Helpers; +using Tango.Core.IO; namespace Tango.Protobuf.Compilers { @@ -49,12 +50,12 @@ namespace Tango.Protobuf.Compilers /// </returns> public override CompilerFolderResult CompileFolder(string sourceFolder, params String[] includeFolders) { - String temp = PathHelper.GetTempFolderPath(); - PathHelper.CopyDirectory(sourceFolder, temp, true); + var temp = TemporaryManager.Default.CreateFolder(); + PathHelper.CopyDirectory(sourceFolder, temp.Path, true); List<String> directories = Directory.GetDirectories(sourceFolder, "*", SearchOption.AllDirectories).Where(x => includeFolders == null || includeFolders.Length == 0 || includeFolders.Contains(Path.GetFileName(x))).ToList(); - foreach (var dir in Directory.GetDirectories(temp)) + foreach (var dir in Directory.GetDirectories(temp.Path)) { if (!directories.Select(x => Path.GetFileName(x)).Contains(Path.GetFileName(dir))) { @@ -62,7 +63,7 @@ namespace Tango.Protobuf.Compilers } } - foreach (var file in Directory.GetFiles(temp, "*.proto", SearchOption.AllDirectories)) + foreach (var file in Directory.GetFiles(temp.Path, "*.proto", SearchOption.AllDirectories)) { String str = File.ReadAllText(file); @@ -77,7 +78,7 @@ namespace Tango.Protobuf.Compilers File.WriteAllText(file, str); } - return base.CompileFolder(temp); + return base.CompileFolder(temp.Path); } } } diff --git a/Software/Visual_Studio/Tango.Protobuf/ProtoCompiler.cs b/Software/Visual_Studio/Tango.Protobuf/ProtoCompiler.cs index 65ce25300..d58d21ea9 100644 --- a/Software/Visual_Studio/Tango.Protobuf/ProtoCompiler.cs +++ b/Software/Visual_Studio/Tango.Protobuf/ProtoCompiler.cs @@ -7,6 +7,7 @@ using System.Reflection; using System.Text; using System.Threading.Tasks; using Tango.Core.Helpers; +using Tango.Core.IO; using Tango.Logging; namespace Tango.Protobuf @@ -56,7 +57,7 @@ namespace Tango.Protobuf { logManager.Log("Compiling file " + inputFile); - String tmpPath = PathHelper.GetTempFolderPath(); + var tmpPath = TemporaryManager.Default.CreateFolder(); logManager.Log("Temp path: " + tmpPath); @@ -123,7 +124,7 @@ namespace Tango.Protobuf } - if (PathHelper.TryDeleteFolder(tmpPath)) + if (tmpPath.Delete()) { logManager.Log("Removed temp path: " + tmpPath); } @@ -230,7 +231,7 @@ namespace Tango.Protobuf ImportsFolders.Clear(); ImportsFolders.AddRange(Directory.GetDirectories(sourceFolder, "*.*", SearchOption.AllDirectories)); - String tempPath = PathHelper.GetTempFolderPath(); + var tempPath = TemporaryManager.Default.CreateFolder(); foreach (var file in Directory.GetFiles(sourceFolder, "*.proto", SearchOption.AllDirectories)) { @@ -247,7 +248,7 @@ namespace Tango.Protobuf var result = CompileFolderDefault(tempPath, tempPath, fileResults); - PathHelper.TryDeleteFolder(tempPath); + tempPath.Delete(); logManager.Log(Path.GetFileName(sourceFolder) + "compiled!"); diff --git a/Software/Visual_Studio/Tango.UnitTesting/TFS_TST.cs b/Software/Visual_Studio/Tango.UnitTesting/TFS_TST.cs index 3fff8daae..47984792a 100644 --- a/Software/Visual_Studio/Tango.UnitTesting/TFS_TST.cs +++ b/Software/Visual_Studio/Tango.UnitTesting/TFS_TST.cs @@ -6,6 +6,7 @@ using System.Linq; using System.Text; using System.Threading.Tasks; using Tango.Core.Helpers; +using Tango.Core.IO; using Tango.TFS; namespace Tango.UnitTesting @@ -114,13 +115,13 @@ namespace Tango.UnitTesting item.ChangedBy = project.Members.Single(x => x.DisplayName.Contains("Shlomo")); item.AuthorizedAs = project.Members.Single(x => x.DisplayName.Contains("Shlomo")); - String tempFile = PathHelper.GetTempFilePath(); - File.AppendAllText(tempFile, "This is a test text file..."); + var tempFile = TemporaryManager.Default.CreateFile(); + File.AppendAllText(tempFile.Path, "This is a test text file..."); item.Attachments.Add(new Attachment() { Description = "Test Attachment", - FilePath = tempFile, + FilePath = tempFile.Path, Name = "TestDocument.txt" }); diff --git a/Software/Visual_Studio/Tango.UnitTesting/Tango.UnitTesting.csproj b/Software/Visual_Studio/Tango.UnitTesting/Tango.UnitTesting.csproj index fd7de86c4..71a9413c2 100644 --- a/Software/Visual_Studio/Tango.UnitTesting/Tango.UnitTesting.csproj +++ b/Software/Visual_Studio/Tango.UnitTesting/Tango.UnitTesting.csproj @@ -89,6 +89,7 @@ <Compile Include="DependencyInjection_TST.cs" /> <Compile Include="Logging_TST.cs" /> <Compile Include="MachineStudio_TST.cs" /> + <Compile Include="Temporary_TST.cs" /> <Compile Include="TFS_TST.cs" /> <Compile Include="Outlook_TST.cs" /> <Compile Include="Scripting_TST.cs" /> diff --git a/Software/Visual_Studio/Tango.UnitTesting/Temporary_TST.cs b/Software/Visual_Studio/Tango.UnitTesting/Temporary_TST.cs new file mode 100644 index 000000000..6e9d7eeb7 --- /dev/null +++ b/Software/Visual_Studio/Tango.UnitTesting/Temporary_TST.cs @@ -0,0 +1,34 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading; +using System.Threading.Tasks; +using Tango.Core.IO; + +namespace Tango.UnitTesting +{ + [TestClass] + [TestCategory("Temporary Files & Folders")] + public class Temporary_TST + { + [TestMethod] + public void Create_Temporary_Folder_And_Files_Display_And_Delete() + { + TemporaryManager manager = TemporaryManager.Default; + + var folder = manager.CreateFolder(); + + folder.Display(); + + Thread.Sleep(1000); + + for (int i = 0; i < 10; i++) + { + var file = folder.CreateFile(); + Thread.Sleep(1000); + } + } + } +} diff --git a/Software/Visual_Studio/Utilities/Tango.BugReporter/Program.cs b/Software/Visual_Studio/Utilities/Tango.BugReporter/Program.cs index b9b1897b1..39d50c4a8 100644 --- a/Software/Visual_Studio/Utilities/Tango.BugReporter/Program.cs +++ b/Software/Visual_Studio/Utilities/Tango.BugReporter/Program.cs @@ -13,6 +13,7 @@ using System.Reflection; using System.Text; using System.Threading.Tasks; using Tango.Core.Helpers; +using Tango.Core.IO; using Tango.TFS; namespace Tango.BugReporter @@ -108,17 +109,17 @@ namespace Tango.BugReporter var group = activeItems.GroupBy(x => x.AssignedTo); - var file = PathHelper.GetTempFilePath(); + var file = TemporaryManager.Default.CreateFile(); PdfDocumentRenderer pdfRenderer = new PdfDocumentRenderer(false, PdfFontEmbedding.None); pdfRenderer.Document = document; pdfRenderer.RenderDocument(); - pdfRenderer.PdfDocument.Save(file); + pdfRenderer.PdfDocument.Save(file.Path); ITeamFoundationEmailClient emailClient = new TeamFoundationEmailClient(new System.Net.NetworkCredential("roy@twine-s.com", "Maya2018")); Email mail = new Email(); - mail.Attachments.Add(new Attachment() { FilePath = file, Name = "VSTS-REPORT.pdf" }); + mail.Attachments.Add(new Attachment() { FilePath = file.Path, Name = "VSTS-REPORT.pdf" }); mail.From = project.Members.SingleOrDefault(x => x.DisplayName.Contains("Roy")); mail.To.Add(mail.From); mail.Subject = "VSTS Daily Report"; @@ -126,7 +127,7 @@ namespace Tango.BugReporter emailClient.Send(mail).Wait(); - PathHelper.TryDeleteFile(file); + file.Delete(); } private static Chart AddChart<T>(Section section, ChartType chartType, String header, IEnumerable<IGrouping<T, WorkItem>> workItemGroups, String propName) diff --git a/Software/Visual_Studio/Web/Tango.MachineService/Controllers/SynchronizationController.cs b/Software/Visual_Studio/Web/Tango.MachineService/Controllers/SynchronizationController.cs index fb937f52e..28d0cd3f1 100644 --- a/Software/Visual_Studio/Web/Tango.MachineService/Controllers/SynchronizationController.cs +++ b/Software/Visual_Studio/Web/Tango.MachineService/Controllers/SynchronizationController.cs @@ -9,6 +9,7 @@ using System.Threading.Tasks; using System.Web.Hosting; using System.Web.Http; using Tango.Core.Helpers; +using Tango.Core.IO; using Tango.PMR.Stubs; using Tango.PMR.Synchronization; using Tango.Synchronization.Local; @@ -26,7 +27,7 @@ namespace Tango.MachineService.Controllers [HttpPost] public SynchronizeDBResponse Synchronize(SynchronizeDBRequest request) { - String tempFolder = PathHelper.GetTempFolderPath(); + var tempFolder = TemporaryManager.Default.CreateFolder(); try { @@ -60,7 +61,7 @@ namespace Tango.MachineService.Controllers finally { //Remove all temporary files and folder. - PathHelper.TryDeleteFolder(tempFolder); + tempFolder.Delete(); } } } |
