Plugin prerequisites - Added UI for installing/removing prerequisites

Plugin settings - Added button to reload plugin from disk
Confirm dialogs - Made cancel text optional so you can hide the button
This commit is contained in:
Robert committed 2021-04-28 00:33:56 +02:00
1 parent f1874d9fe3
commit 0cfddcbbaf
25 files changed
+741 -158

No files matched your search

+8
View File
@@ -125,6 +125,14 @@ namespace Artemis.Core
return Info.ToString();
}
/// <summary>
/// Determines whether the prerequisites of this plugin are met
/// </summary>
public bool ArePrerequisitesMet()
{
return Prerequisites.All(p => p.IsMet());
}
/// <summary>
/// Occurs when the plugin is enabled
/// </summary>
@@ -123,7 +123,7 @@ namespace Artemis.Core
/// Called to determine whether the prerequisite is met
/// </summary>
/// <returns><see langword="true" /> if the prerequisite is met; otherwise <see langword="false" /></returns>
public abstract Task<bool> IsMet();
public abstract bool IsMet();
/// <summary>
/// Called before installation starts
@@ -10,6 +10,8 @@ namespace Artemis.Core
public abstract class PluginPrerequisiteAction : CorePropertyChanged
{
private bool _progressIndeterminate;
private bool _showProgressBar;
private bool _showSubProgressBar;
private string? _status;
private bool _subProgressIndeterminate;
@@ -56,6 +58,24 @@ namespace Artemis.Core
set => SetAndNotify(ref _subProgressIndeterminate, value);
}
/// <summary>
/// Gets or sets a boolean indicating whether the progress bar should be shown
/// </summary>
public bool ShowProgressBar
{
get => _showProgressBar;
set => SetAndNotify(ref _showProgressBar, value);
}
/// <summary>
/// Gets or sets a boolean indicating whether the sub progress bar should be shown
/// </summary>
public bool ShowSubProgressBar
{
get => _showSubProgressBar;
set => SetAndNotify(ref _showSubProgressBar, value);
}
/// <summary>
/// Gets or sets the progress of the action (0 to 100)
/// </summary>
@@ -21,6 +21,9 @@ namespace Artemis.Core
{
Source = source;
Target = target;
ShowProgressBar = true;
ShowSubProgressBar = true;
}
/// <summary>
@@ -0,0 +1,44 @@
using System.IO;
using System.Threading;
using System.Threading.Tasks;
namespace Artemis.Core
{
/// <summary>
/// Represents a plugin prerequisite action that deletes a file
/// </summary>
public class DeleteFileAction : PluginPrerequisiteAction
{
/// <summary>
/// Creates a new instance of a copy folder action
/// </summary>
/// <param name="name">The name of the action</param>
/// <param name="target">The target folder to delete recursively</param>
public DeleteFileAction(string name, string target) : base(name)
{
Target = target;
ProgressIndeterminate = true;
}
/// <summary>
/// Gets or sets the target directory
/// </summary>
public string Target { get; }
/// <inheritdoc />
public override async Task Execute(CancellationToken cancellationToken)
{
ShowProgressBar = true;
Status = $"Removing {Target}";
await Task.Run(() =>
{
if (File.Exists(Target))
File.Delete(Target);
}, cancellationToken);
ShowProgressBar = false;
Status = $"Removed {Target}";
}
}
}
@@ -0,0 +1,49 @@
using System;
using System.IO;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
namespace Artemis.Core
{
/// <summary>
/// Represents a plugin prerequisite action that recursively deletes a folder
/// </summary>
public class DeleteFolderAction : PluginPrerequisiteAction
{
/// <summary>
/// Creates a new instance of a copy folder action
/// </summary>
/// <param name="name">The name of the action</param>
/// <param name="target">The target folder to delete recursively</param>
public DeleteFolderAction(string name, string target) : base(name)
{
if (Enum.GetValues<Environment.SpecialFolder>().Select(Environment.GetFolderPath).Contains(target))
throw new ArtemisCoreException($"Cannot delete special folder {target}, silly goose.");
Target = target;
ProgressIndeterminate = true;
}
/// <summary>
/// Gets or sets the target directory
/// </summary>
public string Target { get; }
/// <inheritdoc />
public override async Task Execute(CancellationToken cancellationToken)
{
ShowProgressBar = true;
Status = $"Removing {Target}";
await Task.Run(() =>
{
if (Directory.Exists(Target))
Directory.Delete(Target, true);
}, cancellationToken);
ShowProgressBar = false;
Status = $"Removed {Target}";
}
}
}
@@ -0,0 +1,62 @@
using System;
using System.IO;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace Artemis.Core
{
/// <summary>
/// Represents a plugin prerequisite action that copies a folder
/// </summary>
public class WriteBytesToFileAction : PluginPrerequisiteAction
{
/// <summary>
/// Creates a new instance of a copy folder action
/// </summary>
/// <param name="name">The name of the action</param>
/// <param name="target">The target file to write to (will be created if needed)</param>
/// <param name="content">The contents to write</param>
public WriteBytesToFileAction(string name, string target, byte[] content) : base(name)
{
Target = target;
ByteContent = content ?? throw new ArgumentNullException(nameof(content));
}
/// <summary>
/// Gets or sets the target file
/// </summary>
public string Target { get; }
/// <summary>
/// Gets or sets a boolean indicating whether or not to append to the file if it exists already, if set to
/// <see langword="false" /> the file will be deleted and recreated
/// </summary>
public bool Append { get; set; } = false;
/// <summary>
/// Gets the bytes that will be written
/// </summary>
public byte[] ByteContent { get; }
/// <inheritdoc />
public override async Task Execute(CancellationToken cancellationToken)
{
string outputDir = Path.GetDirectoryName(Target)!;
Utilities.CreateAccessibleDirectory(outputDir);
ShowProgressBar = true;
Status = $"Writing to {Path.GetFileName(Target)}...";
if (!Append && File.Exists(Target))
File.Delete(Target);
await using Stream fileStream = File.OpenWrite(Target);
await using MemoryStream sourceStream = new(ByteContent);
await sourceStream.CopyToAsync(sourceStream.Length, fileStream, Progress, cancellationToken);
ShowProgressBar = false;
Status = $"Finished writing to {Path.GetFileName(Target)}";
}
}
}
@@ -1,5 +1,6 @@
using System;
using System.IO;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
@@ -8,7 +9,7 @@ namespace Artemis.Core
/// <summary>
/// Represents a plugin prerequisite action that copies a folder
/// </summary>
public class WriteToFileAction : PluginPrerequisiteAction
public class WriteStringToFileAction : PluginPrerequisiteAction
{
/// <summary>
/// Creates a new instance of a copy folder action
@@ -16,22 +17,12 @@ namespace Artemis.Core
/// <param name="name">The name of the action</param>
/// <param name="target">The target file to write to (will be created if needed)</param>
/// <param name="content">The contents to write</param>
public WriteToFileAction(string name, string target, string content) : base(name)
{
Target = target ?? throw new ArgumentNullException(nameof(target));
Content = content ?? throw new ArgumentNullException(nameof(content));
}
/// <summary>
/// Creates a new instance of a copy folder action
/// </summary>
/// <param name="name">The name of the action</param>
/// <param name="target">The target file to write to (will be created if needed)</param>
/// <param name="content">The contents to write</param>
public WriteToFileAction(string name, string target, byte[] content) : base(name)
public WriteStringToFileAction(string name, string target, string content) : base(name)
{
Target = target;
ByteContent = content ?? throw new ArgumentNullException(nameof(content));
Content = content ?? throw new ArgumentNullException(nameof(content));
ProgressIndeterminate = true;
}
/// <summary>
@@ -40,30 +31,31 @@ namespace Artemis.Core
public string Target { get; }
/// <summary>
/// Gets the contents that will be written
/// Gets or sets a boolean indicating whether or not to append to the file if it exists already, if set to
/// <see langword="false" /> the file will be deleted and recreated
/// </summary>
public string? Content { get; }
public bool Append { get; set; } = false;
/// <summary>
/// Gets the bytes that will be written
/// Gets the string that will be written
/// </summary>
public byte[]? ByteContent { get; }
public string Content { get; }
/// <inheritdoc />
public override async Task Execute(CancellationToken cancellationToken)
{
string outputDir = Path.GetDirectoryName(Target)!;
Utilities.CreateAccessibleDirectory(outputDir);
ProgressIndeterminate = true;
ShowProgressBar = true;
Status = $"Writing to {Path.GetFileName(Target)}...";
if (Content != null)
if (Append)
await File.AppendAllTextAsync(Target, Content, cancellationToken);
else
await File.WriteAllTextAsync(Target, Content, cancellationToken);
else if (ByteContent != null)
await File.WriteAllBytesAsync(Target, ByteContent, cancellationToken);
ProgressIndeterminate = false;
ShowProgressBar = false;
Status = $"Finished writing to {Path.GetFileName(Target)}";
}
}