Skip to content

Commit

Permalink
Open download location and launch/open installer from operation conte…
Browse files Browse the repository at this point in the history
…xt menu
  • Loading branch information
marticliment committed Jan 16, 2025
1 parent c31ada3 commit f7bd72e
Show file tree
Hide file tree
Showing 5 changed files with 108 additions and 67 deletions.
52 changes: 26 additions & 26 deletions src/UniGetUI.PackageEngine.Operations/AbstractOperation.cs
Original file line number Diff line number Diff line change
Expand Up @@ -99,10 +99,10 @@ public void ApplyCapabilities(bool admin, bool interactive, bool skiphash, Packa

public enum LineType
{
OperationInfo,
Progress,
StdOUT,
StdERR
VerboseDetails,
ProgressIndicator,
Information,
Error
}

private List<(string, LineType)> LogList = new();
Expand All @@ -121,11 +121,11 @@ public AbstractOperation(bool queue_enabled)
{
QUEUE_ENABLED = queue_enabled;
Status = OperationStatus.InQueue;
Line("Please wait...", LineType.Progress);
Line("Please wait...", LineType.ProgressIndicator);

if(int.TryParse(Settings.GetValue("ParallelOperationCount"), out int _maxPps))
{
MAX_OPERATIONS = _maxPps;
MAX_OPERATIONS = _maxPps;
Logger.Debug($"Parallel operation limit set to {MAX_OPERATIONS}");
}
else
Expand Down Expand Up @@ -161,7 +161,7 @@ public void Cancel()

protected void Line(string line, LineType type)
{
if(type != LineType.Progress) LogList.Add((line, type));
if(type != LineType.ProgressIndicator) LogList.Add((line, type));
LogLineAdded?.Invoke(this, (line, type));
}

Expand Down Expand Up @@ -189,8 +189,8 @@ public async Task MainThread()
throw new InvalidOperationException("This operation was already on the queue");

Status = OperationStatus.InQueue;
Line(Metadata.OperationInformation, LineType.OperationInfo);
Line(Metadata.Status, LineType.Progress);
Line(Metadata.OperationInformation, LineType.VerboseDetails);
Line(Metadata.Status, LineType.ProgressIndicator);

// BEGIN QUEUE HANDLER
if (QUEUE_ENABLED)
Expand All @@ -210,7 +210,7 @@ public async Task MainThread()
if (pos != lastPos)
{
lastPos = pos;
Line(CoreTools.Translate("Operation on queue (position {0})...", pos), LineType.Progress);
Line(CoreTools.Translate("Operation on queue (position {0})...", pos), LineType.ProgressIndicator);
}

await Task.Delay(100);
Expand All @@ -220,7 +220,7 @@ public async Task MainThread()

// BEGIN ACTUAL OPERATION
OperationVeredict result;
Line(CoreTools.Translate("Starting operation..."), LineType.Progress);
Line(CoreTools.Translate("Starting operation..."), LineType.ProgressIndicator);
if(Status is OperationStatus.InQueue) Status = OperationStatus.Running;
OperationStarting?.Invoke(this, EventArgs.Empty);

Expand All @@ -245,7 +245,7 @@ public async Task MainThread()
{
result = OperationVeredict.Failure;
Logger.Error(e);
foreach (string l in e.ToString().Split("\n")) Line(l, LineType.StdERR);
foreach (string l in e.ToString().Split("\n")) Line(l, LineType.Error);
}
} while (result == OperationVeredict.AutoRetry);

Expand All @@ -258,27 +258,27 @@ public async Task MainThread()
{
Status = OperationStatus.Succeeded;
OperationSucceeded?.Invoke(this, EventArgs.Empty);
Line(Metadata.SuccessMessage, LineType.StdOUT);
Line(Metadata.SuccessMessage, LineType.Information);
}
else if (result == OperationVeredict.Failure)
{
Status = OperationStatus.Failed;
OperationFailed?.Invoke(this, EventArgs.Empty);
Line(Metadata.FailureMessage, LineType.StdERR);
Line(Metadata.FailureMessage, LineType.Error);
Line(Metadata.FailureMessage + " - " + CoreTools.Translate("Click here for more details"),
LineType.Progress);
LineType.ProgressIndicator);
}
else if (result == OperationVeredict.Canceled)
{
Status = OperationStatus.Canceled;
Line(CoreTools.Translate("Operation canceled by user"), LineType.StdERR);
Line(CoreTools.Translate("Operation canceled by user"), LineType.Error);
}
}
catch (Exception ex)
{
Line("An internal error occurred:", LineType.StdERR);
Line("An internal error occurred:", LineType.Error);
foreach (var line in ex.ToString().Split("\n"))
Line(line, LineType.StdERR);
Line(line, LineType.Error);

while (OperationQueue.Remove(this)) ;

Expand All @@ -290,14 +290,14 @@ public async Task MainThread()
}
catch (Exception e2)
{
Line("An internal error occurred while handling an internal error:", LineType.StdERR);
Line("An internal error occurred while handling an internal error:", LineType.Error);
foreach (var line in e2.ToString().Split("\n"))
Line(line, LineType.StdERR);
Line(line, LineType.Error);
}

Line(Metadata.FailureMessage, LineType.StdERR);
Line(Metadata.FailureMessage, LineType.Error);
Line(Metadata.FailureMessage + " - " + CoreTools.Translate("Click here for more details"),
LineType.Progress);
LineType.ProgressIndicator);
}
}

Expand Down Expand Up @@ -338,10 +338,10 @@ public void Retry(string retryMode)
throw new InvalidOperationException("We weren't supposed to reach this, weren't we?");

ApplyRetryAction(retryMode);
Line($"", LineType.OperationInfo);
Line($"-----------------------", LineType.OperationInfo);
Line($"Retrying operation with RetryMode={retryMode}", LineType.OperationInfo);
Line($"", LineType.OperationInfo);
Line($"", LineType.VerboseDetails);
Line($"-----------------------", LineType.VerboseDetails);
Line($"Retrying operation with RetryMode={retryMode}", LineType.VerboseDetails);
Line($"", LineType.VerboseDetails);
if (Status is OperationStatus.Running or OperationStatus.InQueue) return;
_ = MainThread();
}
Expand Down
21 changes: 12 additions & 9 deletions src/UniGetUI.PackageEngine.Operations/DownloadOperation.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@ public class DownloadOperation : AbstractOperation
{
private IPackage _package;
private string downloadLocation;
public string DownloadLocation
{
get => downloadLocation;
}
private bool canceled;

public DownloadOperation(IPackage package, string downloadPath): base(true)
Expand Down Expand Up @@ -54,13 +58,13 @@ protected override async Task<OperationVeredict> PerformOperation()
canceled = false;
try
{
Line($"Fetching download url for package {_package.Id} on manager {_package.Manager.DisplayName}...", LineType.StdOUT);
Line($"Fetching download url for package {_package.Name} from {_package.Manager.DisplayName}...", LineType.Information);
await _package.Details.Load();
Uri? downloadUrl = _package.Details.InstallerUrl;
if (downloadUrl is null)
{
Line($"UniGetUI was not able to find any installer for this package. " +
$"Please check that this package has an applicable installer and try again later", LineType.StdERR);
$"Please check that this package has an applicable installer and try again later", LineType.Error);
return OperationVeredict.Failure;
}

Expand Down Expand Up @@ -92,29 +96,28 @@ protected override async Task<OperationVeredict> PerformOperation()
{
oldProgress = progress;
Line(CoreTools.TextProgressGenerator(
30,
progress,
30, progress,
$"{CoreTools.FormatAsSize(totalRead)}/{CoreTools.FormatAsSize(totalBytes)}"
), LineType.Progress);
), LineType.ProgressIndicator);
}
}

if (canceled)
{
fileStream.Close();
File.Delete(downloadLocation);
Line("User has canceled the operation", LineType.StdERR);
Line("User has canceled the operation", LineType.Error);
return OperationVeredict.Canceled;
}
}

Line($"The file was saved to {downloadLocation}", LineType.Progress);
Line($"The file was saved to {downloadLocation}", LineType.Information);
return OperationVeredict.Success;
}
catch (Exception ex)
{
Line($"{ex.GetType()}: {ex.Message}", LineType.StdERR);
Line($"{ex.StackTrace}", LineType.StdERR);
Line($"{ex.GetType()}: {ex.Message}", LineType.Error);
Line($"{ex.StackTrace}", LineType.Error);
return OperationVeredict.Failure;
}
}
Expand Down
22 changes: 11 additions & 11 deletions src/UniGetUI.PackageEngine.Operations/ProcessOperation.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ protected AbstractProcessOperation(bool queue_enabled) : base(queue_enabled)
}
catch (InvalidOperationException e)
{
Line("Attempted to cancel a process that hasn't ben created yet: " + e.Message, LineType.StdERR);
Line("Attempted to cancel a process that hasn't ben created yet: " + e.Message, LineType.Error);
}
};
OperationStarting += (_, _) =>
Expand All @@ -43,10 +43,10 @@ protected AbstractProcessOperation(bool queue_enabled) : base(queue_enabled)
process.StandardInput.WriteLine("");
}

var lineType = LineType.StdOUT;
var lineType = LineType.Information;
if (line.Length < 6 || line.EndsWith("install/uninstall to complete..."))
{
lineType = LineType.Progress;
lineType = LineType.ProgressIndicator;
}

Line(line, lineType);
Expand All @@ -55,10 +55,10 @@ protected AbstractProcessOperation(bool queue_enabled) : base(queue_enabled)
{
if (e.Data is null) return;
string line = e.Data.ToString().Trim();
var lineType = LineType.StdERR;
var lineType = LineType.Error;
if (line.Length < 6 || line.Contains("Waiting for another install..."))
{
lineType = LineType.Progress;
lineType = LineType.ProgressIndicator;
}

Line(line, lineType);
Expand All @@ -76,18 +76,18 @@ protected override async Task<OperationVeredict> PerformOperation()
if (process.StartInfo.FileName == "lol") throw new InvalidOperationException("StartInfo.FileName has not been set");
if (process.StartInfo.Arguments == "lol") throw new InvalidOperationException("StartInfo.Arguments has not been set");

Line($"Executing process with StartInfo:", LineType.OperationInfo);
Line($" - FileName: \"{process.StartInfo.FileName.Trim()}\"", LineType.OperationInfo);
Line($" - Arguments: \"{process.StartInfo.Arguments.Trim()}\"", LineType.OperationInfo);
Line($"Start Time: \"{DateTime.Now}\"", LineType.OperationInfo);
Line($"Executing process with StartInfo:", LineType.VerboseDetails);
Line($" - FileName: \"{process.StartInfo.FileName.Trim()}\"", LineType.VerboseDetails);
Line($" - Arguments: \"{process.StartInfo.Arguments.Trim()}\"", LineType.VerboseDetails);
Line($"Start Time: \"{DateTime.Now}\"", LineType.VerboseDetails);

process.Start();
process.BeginOutputReadLine();
process.BeginErrorReadLine();
await process.WaitForExitAsync();

Line($"End Time: \"{DateTime.Now}\"", LineType.OperationInfo);
Line($"Process return value: \"{process.ExitCode}\" (0x{process.ExitCode:X})", LineType.OperationInfo);
Line($"End Time: \"{DateTime.Now}\"", LineType.VerboseDetails);
Line($"Process return value: \"{process.ExitCode}\" (0x{process.ExitCode:X})", LineType.VerboseDetails);

if (ProcessKilled)
return OperationVeredict.Canceled;
Expand Down
66 changes: 52 additions & 14 deletions src/UniGetUI/Controls/OperationWidgets/OperationControl.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
using UniGetUI.Interface.Widgets;
using UniGetUI.PackageEngine.Operations;
using System.Collections.ObjectModel;
using System.Diagnostics;

namespace UniGetUI.Controls.OperationWidgets;

Expand Down Expand Up @@ -125,7 +126,7 @@ private async void OnOperationSucceeded(object? sender, EventArgs e)
}

// Clean succesful operation from list
if(!Settings.Get("MaintainSuccessfulInstalls"))
if(!Settings.Get("MaintainSuccessfulInstalls") && Operation is not DownloadOperation)
await TimeoutAndClose();
}

Expand Down Expand Up @@ -546,7 +547,6 @@ public List<BetterMenuItem> GetOperationOptions()
};
optionsMenu.Add(details);


var installationSettings = new BetterMenuItem() { Text = CoreTools.Translate("Installation options") };
installationSettings.IconName = IconType.Options;
installationSettings.Click += (_, _) =>
Expand All @@ -556,22 +556,60 @@ public List<BetterMenuItem> GetOperationOptions()
optionsMenu.Add(installationSettings);

string? location = packageOp.Package.Manager.DetailsHelper.GetInstallLocation(packageOp.Package);
if (location is not null && Directory.Exists(location))
var openLocation = new BetterMenuItem() { Text = CoreTools.Translate("Open install location") };
openLocation.IconName = IconType.OpenFolder;
openLocation.Click += (_, _) =>
{
Process.Start(new ProcessStartInfo() {
FileName = location ?? "",
UseShellExecute = true,
Verb = "open"
});
};
openLocation.IsEnabled = location is not null && Directory.Exists(location);
optionsMenu.Add(openLocation);

}

else if (Operation is DownloadOperation downloadOp)
{
var launchInstaller = new BetterMenuItem() { Text = CoreTools.Translate("Open") };
launchInstaller.IconName = IconType.Launch;
launchInstaller.Click += (_, _) =>
{
var openLocation = new BetterMenuItem() { Text = CoreTools.Translate("Open install location") };
openLocation.IconName = IconType.OpenFolder;
openLocation.Click += (_, _) =>
try
{
System.Diagnostics.Process.Start(new System.Diagnostics.ProcessStartInfo() {
FileName = location,
UseShellExecute = true,
Verb = "open"
Process.Start(new ProcessStartInfo()
{
FileName = downloadOp.DownloadLocation,
UseShellExecute = true
});
}
catch (Exception ex)
{
Logger.Error($"An error occurred while attempting to launch the file {downloadOp.DownloadLocation}.");
Logger.Error(ex);
}
};
launchInstaller.IsEnabled = downloadOp.Status is OperationStatus.Succeeded;
optionsMenu.Add(launchInstaller);

};
optionsMenu.Add(openLocation);
}

var showFileInExplorer = new BetterMenuItem() { Text = CoreTools.Translate("Show in explorer") };
showFileInExplorer.IconName = IconType.OpenFolder;
showFileInExplorer.Click += (_, _) =>
{
try
{
Process.Start("explorer.exe", "/select," + $"\"{downloadOp.DownloadLocation}\"");
}
catch (Exception ex)
{
Logger.Error($"An error occurred while attempting to show the file {downloadOp.DownloadLocation} on explorer.");
Logger.Error(ex);
}
};
showFileInExplorer.IsEnabled = downloadOp.Status is OperationStatus.Succeeded;
optionsMenu.Add(showFileInExplorer);
}

return optionsMenu;
Expand Down
Loading

0 comments on commit f7bd72e

Please sign in to comment.