|
|
|
@ -17,10 +17,12 @@ using FluentAvalonia.UI.Controls;
|
|
|
|
|
using NLog; |
|
|
|
|
using StabilityMatrix.Avalonia.Controls; |
|
|
|
|
using StabilityMatrix.Avalonia.Services; |
|
|
|
|
using StabilityMatrix.Avalonia.ViewModels.Base; |
|
|
|
|
using StabilityMatrix.Core.Helper; |
|
|
|
|
using StabilityMatrix.Core.Helper.Factory; |
|
|
|
|
using StabilityMatrix.Core.Models; |
|
|
|
|
using StabilityMatrix.Core.Models.Database; |
|
|
|
|
using StabilityMatrix.Core.Models.PackageModification; |
|
|
|
|
using StabilityMatrix.Core.Models.Packages; |
|
|
|
|
using StabilityMatrix.Core.Models.Progress; |
|
|
|
|
using StabilityMatrix.Core.Processes; |
|
|
|
@ -49,6 +51,13 @@ public partial class InstallerViewModel : ContentDialogViewModelBase
|
|
|
|
|
[ObservableProperty] private string? releaseNotes; |
|
|
|
|
[ObservableProperty] private string latestVersionText = string.Empty; |
|
|
|
|
[ObservableProperty] private bool isAdvancedMode; |
|
|
|
|
[ObservableProperty] private bool showDuplicateWarning; |
|
|
|
|
[ObservableProperty] private string? installName; |
|
|
|
|
[ObservableProperty] private SharedFolderMethod selectedSharedFolderMethod; |
|
|
|
|
|
|
|
|
|
[ObservableProperty] |
|
|
|
|
[NotifyPropertyChangedFor(nameof(ShowTorchVersionOptions))] |
|
|
|
|
private TorchVersion selectedTorchVersion; |
|
|
|
|
|
|
|
|
|
// Version types (release or commit) |
|
|
|
|
[ObservableProperty] |
|
|
|
@ -60,20 +69,19 @@ public partial class InstallerViewModel : ContentDialogViewModelBase
|
|
|
|
|
[NotifyPropertyChangedFor(nameof(IsReleaseModeAvailable))] |
|
|
|
|
private PackageVersionType availableVersionTypes = |
|
|
|
|
PackageVersionType.GithubRelease | PackageVersionType.Commit; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public string ReleaseLabelText => IsReleaseMode ? "Version" : "Branch"; |
|
|
|
|
public bool IsReleaseMode |
|
|
|
|
{ |
|
|
|
|
get => SelectedVersionType == PackageVersionType.GithubRelease; |
|
|
|
|
set => SelectedVersionType = value ? PackageVersionType.GithubRelease : PackageVersionType.Commit; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
public bool IsReleaseModeAvailable => AvailableVersionTypes.HasFlag(PackageVersionType.GithubRelease); |
|
|
|
|
public bool ShowTorchVersionOptions => SelectedTorchVersion != TorchVersion.None; |
|
|
|
|
|
|
|
|
|
[ObservableProperty] private bool showDuplicateWarning; |
|
|
|
|
|
|
|
|
|
[ObservableProperty] private string? installName; |
|
|
|
|
|
|
|
|
|
public Base.ProgressViewModel InstallProgress { get; } = new(); |
|
|
|
|
public ProgressViewModel InstallProgress { get; } = new(); |
|
|
|
|
public IEnumerable<IPackageStep> Steps { get; set; } |
|
|
|
|
|
|
|
|
|
public InstallerViewModel( |
|
|
|
|
ISettingsManager settingsManager, |
|
|
|
@ -113,7 +121,7 @@ public partial class InstallerViewModel : ContentDialogViewModelBase
|
|
|
|
|
new ObservableCollection<PackageVersion>(versionOptions.AvailableVersions); |
|
|
|
|
if (!AvailableVersions.Any()) return; |
|
|
|
|
|
|
|
|
|
SelectedVersion = AvailableVersions[0]; |
|
|
|
|
SelectedVersion = AvailableVersions.First(x => !x.IsPrerelease); |
|
|
|
|
} |
|
|
|
|
else |
|
|
|
|
{ |
|
|
|
@ -136,9 +144,6 @@ public partial class InstallerViewModel : ContentDialogViewModelBase
|
|
|
|
|
var result = await notificationService.TryAsync(ActuallyInstall(), "Could not install package"); |
|
|
|
|
if (result.IsSuccessful) |
|
|
|
|
{ |
|
|
|
|
notificationService.Show(new Notification( |
|
|
|
|
$"Package {SelectedPackage.Name} installed successfully!", |
|
|
|
|
"Success", NotificationType.Success)); |
|
|
|
|
OnPrimaryButtonClick(); |
|
|
|
|
} |
|
|
|
|
else |
|
|
|
@ -156,83 +161,72 @@ public partial class InstallerViewModel : ContentDialogViewModelBase
|
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private async Task ActuallyInstall() |
|
|
|
|
private Task ActuallyInstall() |
|
|
|
|
{ |
|
|
|
|
if (string.IsNullOrWhiteSpace(InstallName)) |
|
|
|
|
{ |
|
|
|
|
notificationService.Show(new Notification("Package name is empty", |
|
|
|
|
"Please enter a name for the package", NotificationType.Error)); |
|
|
|
|
return; |
|
|
|
|
return Task.CompletedTask; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
try |
|
|
|
|
var installLocation = Path.Combine(settingsManager.LibraryDir, "Packages", InstallName); |
|
|
|
|
var prereqStep = new SetupPrerequisitesStep(prerequisiteHelper, pyRunner); |
|
|
|
|
|
|
|
|
|
var downloadOptions = new DownloadPackageVersionOptions(); |
|
|
|
|
var installedVersion = new InstalledPackageVersion(); |
|
|
|
|
if (IsReleaseMode) |
|
|
|
|
{ |
|
|
|
|
await InstallGitIfNecessary(); |
|
|
|
|
var installLocation = Path.Combine(settingsManager.LibraryDir, "Packages", InstallName); |
|
|
|
|
|
|
|
|
|
if (!PyRunner.PipInstalled || !PyRunner.VenvInstalled) |
|
|
|
|
{ |
|
|
|
|
InstallProgress.Text = "Installing dependencies..."; |
|
|
|
|
InstallProgress.IsIndeterminate = true; |
|
|
|
|
await pyRunner.Initialize(); |
|
|
|
|
|
|
|
|
|
if (!PyRunner.PipInstalled) |
|
|
|
|
{ |
|
|
|
|
await pyRunner.SetupPip(); |
|
|
|
|
} |
|
|
|
|
if (!PyRunner.VenvInstalled) |
|
|
|
|
{ |
|
|
|
|
await pyRunner.InstallPackage("virtualenv"); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
downloadOptions.VersionTag = SelectedVersion?.TagName ?? |
|
|
|
|
throw new NullReferenceException("Selected version is null"); |
|
|
|
|
installedVersion.InstalledReleaseVersion = downloadOptions.VersionTag; |
|
|
|
|
} |
|
|
|
|
else |
|
|
|
|
{ |
|
|
|
|
downloadOptions.CommitHash = SelectedCommit?.Sha ?? |
|
|
|
|
throw new NullReferenceException("Selected commit is null"); |
|
|
|
|
installedVersion.InstalledBranch = SelectedVersion?.TagName ?? |
|
|
|
|
throw new NullReferenceException("Selected version is null"); |
|
|
|
|
installedVersion.InstalledCommitSha = downloadOptions.CommitHash; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
var downloadOptions = new DownloadPackageVersionOptions(); |
|
|
|
|
var installedVersion = new InstalledPackageVersion(); |
|
|
|
|
if (IsReleaseMode) |
|
|
|
|
{ |
|
|
|
|
downloadOptions.VersionTag = SelectedVersion?.TagName ?? |
|
|
|
|
throw new NullReferenceException("Selected version is null"); |
|
|
|
|
installedVersion.InstalledReleaseVersion = downloadOptions.VersionTag; |
|
|
|
|
} |
|
|
|
|
else |
|
|
|
|
{ |
|
|
|
|
downloadOptions.CommitHash = SelectedCommit?.Sha ?? |
|
|
|
|
throw new NullReferenceException("Selected commit is null"); |
|
|
|
|
installedVersion.InstalledBranch = SelectedVersion?.TagName ?? |
|
|
|
|
throw new NullReferenceException("Selected version is null"); |
|
|
|
|
installedVersion.InstalledCommitSha = downloadOptions.CommitHash; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
await DownloadPackage(installLocation, downloadOptions); |
|
|
|
|
await InstallPackage(installLocation); |
|
|
|
|
var downloadStep = |
|
|
|
|
new DownloadPackageVersionStep(SelectedPackage, installLocation, downloadOptions); |
|
|
|
|
var installStep = new InstallPackageStep(SelectedPackage, SelectedTorchVersion, installLocation); |
|
|
|
|
var setupModelFoldersStep = new SetupModelFoldersStep(SelectedPackage, |
|
|
|
|
SelectedSharedFolderMethod, installLocation); |
|
|
|
|
|
|
|
|
|
InstallProgress.Text = "Setting up shared folder links..."; |
|
|
|
|
await SelectedPackage.SetupModelFolders(installLocation); |
|
|
|
|
|
|
|
|
|
InstallProgress.Text = "Done"; |
|
|
|
|
InstallProgress.IsIndeterminate = false; |
|
|
|
|
InstallProgress.Value = 100; |
|
|
|
|
EventManager.Instance.OnGlobalProgressChanged(100); |
|
|
|
|
var package = new InstalledPackage |
|
|
|
|
{ |
|
|
|
|
DisplayName = InstallName, |
|
|
|
|
LibraryPath = Path.Combine("Packages", InstallName), |
|
|
|
|
Id = Guid.NewGuid(), |
|
|
|
|
PackageName = SelectedPackage.Name, |
|
|
|
|
Version = installedVersion, |
|
|
|
|
LaunchCommand = SelectedPackage.LaunchCommand, |
|
|
|
|
LastUpdateCheck = DateTimeOffset.Now, |
|
|
|
|
PreferredTorchVersion = SelectedTorchVersion, |
|
|
|
|
PreferredSharedFolderMethod = SelectedSharedFolderMethod |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
var package = new InstalledPackage |
|
|
|
|
{ |
|
|
|
|
DisplayName = InstallName, |
|
|
|
|
LibraryPath = Path.Combine("Packages", InstallName), |
|
|
|
|
Id = Guid.NewGuid(), |
|
|
|
|
PackageName = SelectedPackage.Name, |
|
|
|
|
Version = installedVersion, |
|
|
|
|
LaunchCommand = SelectedPackage.LaunchCommand, |
|
|
|
|
LastUpdateCheck = DateTimeOffset.Now |
|
|
|
|
}; |
|
|
|
|
await using var st = settingsManager.BeginTransaction(); |
|
|
|
|
st.Settings.InstalledPackages.Add(package); |
|
|
|
|
st.Settings.ActiveInstalledPackageId = package.Id; |
|
|
|
|
} |
|
|
|
|
finally |
|
|
|
|
var addInstalledPackageStep = new AddInstalledPackageStep(settingsManager, package); |
|
|
|
|
|
|
|
|
|
var steps = new List<IPackageStep> |
|
|
|
|
{ |
|
|
|
|
InstallProgress.Value = 0; |
|
|
|
|
InstallProgress.IsIndeterminate = false; |
|
|
|
|
} |
|
|
|
|
prereqStep, |
|
|
|
|
downloadStep, |
|
|
|
|
installStep, |
|
|
|
|
setupModelFoldersStep, |
|
|
|
|
addInstalledPackageStep |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
Steps = steps; |
|
|
|
|
return Task.CompletedTask; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
public void Cancel() |
|
|
|
|
{ |
|
|
|
|
OnCloseButtonClick(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private void UpdateSelectedVersionToLatestMain() |
|
|
|
@ -255,51 +249,6 @@ public partial class InstallerViewModel : ContentDialogViewModelBase
|
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private static string GetDisplayVersion(string version, string? branch) |
|
|
|
|
{ |
|
|
|
|
return branch == null ? version : $"{branch}@{version[..7]}"; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private async Task DownloadPackage(string installLocation, DownloadPackageVersionOptions downloadOptions) |
|
|
|
|
{ |
|
|
|
|
InstallProgress.Text = "Downloading package..."; |
|
|
|
|
|
|
|
|
|
var progress = new Progress<ProgressReport>(progress => |
|
|
|
|
{ |
|
|
|
|
InstallProgress.IsIndeterminate = progress.IsIndeterminate; |
|
|
|
|
InstallProgress.Value = progress.Percentage; |
|
|
|
|
EventManager.Instance.OnGlobalProgressChanged((int) progress.Percentage); |
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
await SelectedPackage.DownloadPackage(installLocation, downloadOptions, progress); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private async Task InstallPackage(string installLocation) |
|
|
|
|
{ |
|
|
|
|
InstallProgress.Text = "Installing package..."; |
|
|
|
|
SelectedPackage.ConsoleOutput += SelectedPackageOnConsoleOutput; |
|
|
|
|
try |
|
|
|
|
{ |
|
|
|
|
var progress = new Progress<ProgressReport>(progress => |
|
|
|
|
{ |
|
|
|
|
InstallProgress.IsIndeterminate = progress.IsIndeterminate; |
|
|
|
|
InstallProgress.Value = progress.Percentage; |
|
|
|
|
EventManager.Instance.OnGlobalProgressChanged((int) progress.Percentage); |
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
await SelectedPackage.InstallPackage(installLocation, progress); |
|
|
|
|
} |
|
|
|
|
finally |
|
|
|
|
{ |
|
|
|
|
SelectedPackage.ConsoleOutput -= SelectedPackageOnConsoleOutput; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private void SelectedPackageOnConsoleOutput(object? sender, ProcessOutput e) |
|
|
|
|
{ |
|
|
|
|
InstallProgress.Description = e.Text; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
[RelayCommand] |
|
|
|
|
private async Task ShowPreview() |
|
|
|
|
{ |
|
|
|
@ -350,6 +299,9 @@ public partial class InstallerViewModel : ContentDialogViewModelBase
|
|
|
|
|
? PackageVersionType.Commit |
|
|
|
|
: PackageVersionType.GithubRelease | PackageVersionType.Commit; |
|
|
|
|
|
|
|
|
|
SelectedSharedFolderMethod = SelectedPackage.RecommendedSharedFolderMethod; |
|
|
|
|
SelectedTorchVersion = SelectedPackage.GetRecommendedTorchVersion(); |
|
|
|
|
|
|
|
|
|
if (Design.IsDesignMode) return; |
|
|
|
|
|
|
|
|
|
Dispatcher.UIThread.InvokeAsync(async () => |
|
|
|
@ -361,7 +313,7 @@ public partial class InstallerViewModel : ContentDialogViewModelBase
|
|
|
|
|
? new ObservableCollection<PackageVersion>(versionOptions.AvailableVersions) |
|
|
|
|
: new ObservableCollection<PackageVersion>(versionOptions.AvailableBranches); |
|
|
|
|
|
|
|
|
|
SelectedVersion = AvailableVersions[0]; |
|
|
|
|
SelectedVersion = AvailableVersions.First(x => !x.IsPrerelease); |
|
|
|
|
ReleaseNotes = SelectedVersion.ReleaseNotesMarkdown; |
|
|
|
|
|
|
|
|
|
Logger.Debug($"Loaded release notes for {ReleaseNotes}"); |
|
|
|
@ -383,34 +335,6 @@ public partial class InstallerViewModel : ContentDialogViewModelBase
|
|
|
|
|
}).SafeFireAndForget(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private async Task InstallGitIfNecessary() |
|
|
|
|
{ |
|
|
|
|
var progressHandler = new Progress<ProgressReport>(progress => |
|
|
|
|
{ |
|
|
|
|
if (progress.Message != null && progress.Message.Contains("Downloading")) |
|
|
|
|
{ |
|
|
|
|
InstallProgress.Text = $"Downloading prerequisites... {progress.Percentage:N0}%"; |
|
|
|
|
} |
|
|
|
|
else if (progress.Type == ProgressType.Extract) |
|
|
|
|
{ |
|
|
|
|
InstallProgress.Text = $"Installing git... {progress.Percentage:N0}%"; |
|
|
|
|
} |
|
|
|
|
else if (progress.Title != null && progress.Title.Contains("Unpacking")) |
|
|
|
|
{ |
|
|
|
|
InstallProgress.Text = $"Unpacking resources... {progress.Percentage:N0}%"; |
|
|
|
|
} |
|
|
|
|
else |
|
|
|
|
{ |
|
|
|
|
InstallProgress.Text = progress.Message; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
InstallProgress.IsIndeterminate = progress.IsIndeterminate; |
|
|
|
|
InstallProgress.Value = Convert.ToInt32(progress.Percentage); |
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
await prerequisiteHelper.InstallAllIfNecessary(progressHandler); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
partial void OnInstallNameChanged(string? value) |
|
|
|
|
{ |
|
|
|
|
ShowDuplicateWarning = |
|
|
|
|