Browse Source

Added ability to switch between Shared Folder strategies

pull/165/head
JT 1 year ago
parent
commit
f1517e35c9
  1. 2
      CHANGELOG.md
  2. 9
      StabilityMatrix.Avalonia/Languages/Resources.Designer.cs
  3. 3
      StabilityMatrix.Avalonia/Languages/Resources.resx
  4. 95
      StabilityMatrix.Avalonia/ViewModels/PackageManager/PackageCardViewModel.cs
  5. 34
      StabilityMatrix.Avalonia/Views/PackageManagerPage.axaml
  6. 38
      StabilityMatrix.Core/Models/Packages/ComfyUI.cs
  7. 55
      StabilityMatrix.Core/Models/Packages/VladAutomatic.cs

2
CHANGELOG.md

@ -6,6 +6,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
and this project adheres to [Semantic Versioning 2.0](https://semver.org/spec/v2.0.0.html).
## v2.5.0
### Added
- Added option to change the Shared Folder method for packages using the three-dots menu on the Packages page
### Changed
- Model Browser page size is now 20 instead of 14
### Fixed

9
StabilityMatrix.Avalonia/Languages/Resources.Designer.cs generated

@ -1283,6 +1283,15 @@ namespace StabilityMatrix.Avalonia.Languages {
}
}
/// <summary>
/// Looks up a localized string similar to Model Sharing.
/// </summary>
public static string Label_SharedModelStrategyShort {
get {
return ResourceManager.GetString("Label_SharedModelStrategyShort", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Show Model Images.
/// </summary>

3
StabilityMatrix.Avalonia/Languages/Resources.resx

@ -642,4 +642,7 @@
<data name="Label_AutoScrollToEnd" xml:space="preserve">
<value>Automatically scroll to end of console output</value>
</data>
<data name="Label_SharedModelStrategyShort" xml:space="preserve">
<value>Model Sharing</value>
</data>
</root>

95
StabilityMatrix.Avalonia/ViewModels/PackageManager/PackageCardViewModel.cs

@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Avalonia.Controls;
using Avalonia.Controls.Notifications;
@ -20,7 +21,6 @@ using StabilityMatrix.Core.Models;
using StabilityMatrix.Core.Models.FileInterfaces;
using StabilityMatrix.Core.Models.PackageModification;
using StabilityMatrix.Core.Models.Packages;
using StabilityMatrix.Core.Models.Progress;
using StabilityMatrix.Core.Processes;
using StabilityMatrix.Core.Services;
@ -50,6 +50,18 @@ public partial class PackageCardViewModel : ProgressViewModel
[ObservableProperty]
private bool isUnknownPackage;
[ObservableProperty]
private bool isSharedModelSymlink;
[ObservableProperty]
private bool isSharedModelConfig;
[ObservableProperty]
private bool isSharedModelDisabled;
[ObservableProperty]
private bool canUseConfigMethod;
public PackageCardViewModel(
ILogger<PackageCardViewModel> logger,
IPackageFactory packageFactory,
@ -85,11 +97,18 @@ public partial class PackageCardViewModel : ProgressViewModel
var basePackage = packageFactory[value.PackageName];
CardImageSource = basePackage?.PreviewImageUri.ToString() ?? Assets.NoImage.ToString();
InstalledVersion = value.Version?.DisplayVersion ?? "Unknown";
CanUseConfigMethod =
basePackage?.AvailableSharedFolderMethods.Contains(SharedFolderMethod.Configuration)
?? false;
}
}
public override async Task OnLoadedAsync()
{
IsSharedModelSymlink = Package?.PreferredSharedFolderMethod == SharedFolderMethod.Symlink;
IsSharedModelConfig =
Package?.PreferredSharedFolderMethod == SharedFolderMethod.Configuration;
IsSharedModelDisabled = Package?.PreferredSharedFolderMethod == SharedFolderMethod.None;
IsUpdateAvailable = await HasUpdate();
}
@ -312,4 +331,78 @@ public partial class PackageCardViewModel : ProgressViewModel
return false;
}
}
public void ToggleSharedModelSymlink() => IsSharedModelSymlink = !IsSharedModelSymlink;
public void ToggleSharedModelConfig() => IsSharedModelConfig = !IsSharedModelConfig;
public void ToggleSharedModelNone() => IsSharedModelDisabled = !IsSharedModelDisabled;
// fake radio button stuff
partial void OnIsSharedModelSymlinkChanged(bool oldValue, bool newValue)
{
if (oldValue == newValue)
return;
var basePackage = packageFactory[Package!.PackageName];
if (!newValue)
{
basePackage!.RemoveModelFolderLinks(Package.FullPath!, SharedFolderMethod.Symlink);
return;
}
basePackage!.SetupModelFolders(Package.FullPath!, SharedFolderMethod.Symlink);
settingsManager.Transaction(
s =>
s.InstalledPackages.First(x => x.Id == Package.Id).PreferredSharedFolderMethod =
SharedFolderMethod.Symlink
);
IsSharedModelConfig = false;
IsSharedModelDisabled = false;
}
partial void OnIsSharedModelConfigChanged(bool oldValue, bool newValue)
{
if (oldValue == newValue)
return;
var basePackage = packageFactory[Package!.PackageName];
if (!newValue)
{
basePackage!.RemoveModelFolderLinks(
Package.FullPath!,
SharedFolderMethod.Configuration
);
return;
}
basePackage!.SetupModelFolders(Package.FullPath!, SharedFolderMethod.Configuration);
settingsManager.Transaction(
s =>
s.InstalledPackages.First(x => x.Id == Package.Id).PreferredSharedFolderMethod =
SharedFolderMethod.Configuration
);
IsSharedModelSymlink = false;
IsSharedModelDisabled = false;
}
partial void OnIsSharedModelDisabledChanged(bool oldValue, bool newValue)
{
if (oldValue == newValue)
return;
if (!newValue)
return;
settingsManager.Transaction(
s =>
s.InstalledPackages.First(x => x.Id == Package!.Id).PreferredSharedFolderMethod =
SharedFolderMethod.None
);
IsSharedModelSymlink = false;
IsSharedModelConfig = false;
}
}

34
StabilityMatrix.Avalonia/Views/PackageManagerPage.axaml

@ -9,6 +9,7 @@
xmlns:packageManager="clr-namespace:StabilityMatrix.Avalonia.ViewModels.PackageManager"
xmlns:faicon="clr-namespace:Projektanker.Icons.Avalonia;assembly=Projektanker.Icons.Avalonia"
xmlns:lang="clr-namespace:StabilityMatrix.Avalonia.Languages"
xmlns:system="clr-namespace:System;assembly=System.Runtime"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:DataType="viewModels:PackageManagerViewModel"
x:CompileBindings="True"
@ -19,7 +20,7 @@
<!-- Title -->
<TextBlock Grid.Row="0" Text="{Binding Title}"
Margin="0,0,0,16"
FontSize="24"/>
FontSize="24" />
<!-- Cards -->
<ScrollViewer Grid.Row="1">
@ -69,6 +70,33 @@
<ui:SymbolIcon Symbol="OpenFolder" />
</MenuItem.Icon>
</MenuItem>
<MenuItem Header="{x:Static lang:Resources.Label_SharedModelStrategyShort}"
IsVisible="{Binding !IsUnknownPackage}">
<MenuItem.Icon>
<ui:SymbolIcon Symbol="FolderLink" />
</MenuItem.Icon>
<!-- ReSharper disable Xaml.RedundantResource -->
<MenuItem Header="Symlink"
Command="{Binding ToggleSharedModelSymlink}">
<MenuItem.Icon>
<CheckBox IsChecked="{Binding IsSharedModelSymlink}"/>
</MenuItem.Icon>
</MenuItem>
<MenuItem Header="Config"
Command="{Binding ToggleSharedModelConfig}"
IsVisible="{Binding CanUseConfigMethod}">
<MenuItem.Icon>
<CheckBox IsChecked="{Binding IsSharedModelConfig}"/>
</MenuItem.Icon>
</MenuItem>
<MenuItem Header="None"
Command="{Binding ToggleSharedModelNone}">
<MenuItem.Icon>
<CheckBox IsChecked="{Binding IsSharedModelDisabled}"/>
</MenuItem.Icon>
</MenuItem>
<!-- ReSharper enable Xaml.RedundantResource -->
</MenuItem>
<Separator />
<MenuItem Header="{x:Static lang:Resources.Action_Uninstall}"
Command="{Binding Uninstall}">
@ -120,7 +148,7 @@
VerticalAlignment="Center"
FontSize="18"
TextWrapping="Wrap"
Text="{x:Static lang:Resources.Label_UnknownPackage}"/>
Text="{x:Static lang:Resources.Label_UnknownPackage}" />
</Border>
@ -239,7 +267,7 @@
Target="{Binding #AddPackagesButton}"
Title="{x:Static lang:Resources.TeachingTip_AddPackageToGetStarted}"
PreferredPlacement="Top"
IsOpen="{Binding !Packages.Count}"/>
IsOpen="{Binding !Packages.Count}" />
<!-- Add Packages Button -->
<Button Grid.Row="2"

38
StabilityMatrix.Core/Models/Packages/ComfyUI.cs

@ -340,7 +340,7 @@ public class ComfyUI : BaseGitPackage
{
return sharedFolderMethod switch
{
SharedFolderMethod.Configuration => Task.CompletedTask,
SharedFolderMethod.Configuration => RemoveConfigSection(installDirectory),
SharedFolderMethod.None => Task.CompletedTask,
SharedFolderMethod.Symlink
=> base.RemoveModelFolderLinks(installDirectory, sharedFolderMethod),
@ -348,6 +348,42 @@ public class ComfyUI : BaseGitPackage
};
}
private Task RemoveConfigSection(string installDirectory)
{
var extraPathsYamlPath = Path.Combine(installDirectory, "extra_model_paths.yaml");
var exists = File.Exists(extraPathsYamlPath);
if (!exists)
{
return Task.CompletedTask;
}
var yaml = File.ReadAllText(extraPathsYamlPath);
using var sr = new StringReader(yaml);
var yamlStream = new YamlStream();
yamlStream.Load(sr);
if (!yamlStream.Documents.Any())
{
return Task.CompletedTask;
}
var root = yamlStream.Documents[0].RootNode;
if (root is not YamlMappingNode mappingNode)
{
return Task.CompletedTask;
}
mappingNode.Children.Remove("stability_matrix");
var serializer = new SerializerBuilder()
.WithNamingConvention(UnderscoredNamingConvention.Instance)
.Build();
var yamlData = serializer.Serialize(mappingNode);
File.WriteAllText(extraPathsYamlPath, yamlData);
return Task.CompletedTask;
}
private async Task InstallRocmTorch(
PyVenvRunner venvRunner,
IProgress<ProgressReport>? progress = null,

55
StabilityMatrix.Core/Models/Packages/VladAutomatic.cs

@ -444,6 +444,61 @@ public class VladAutomatic : BaseGitPackage
SharedFolderMethod.Symlink
=> base.RemoveModelFolderLinks(installDirectory, sharedFolderMethod),
SharedFolderMethod.None => Task.CompletedTask,
SharedFolderMethod.Configuration => RemoveConfigSettings(installDirectory),
_ => Task.CompletedTask
};
private Task RemoveConfigSettings(string installDirectory)
{
var configJsonPath = Path.Combine(installDirectory, "config.json");
var exists = File.Exists(configJsonPath);
JsonObject? configRoot;
if (exists)
{
var configJson = File.ReadAllText(configJsonPath);
try
{
configRoot = JsonSerializer.Deserialize<JsonObject>(configJson);
if (configRoot == null)
{
return Task.CompletedTask;
}
}
catch (JsonException e)
{
Logger.Error(e, "Error removing Vlad shared model config");
return Task.CompletedTask;
}
}
else
{
return Task.CompletedTask;
}
configRoot.Remove("ckpt_dir");
configRoot.Remove("diffusers_dir");
configRoot.Remove("vae_dir");
configRoot.Remove("lora_dir");
configRoot.Remove("lyco_dir");
configRoot.Remove("embeddings_dir");
configRoot.Remove("hypernetwork_dir");
configRoot.Remove("codeformer_models_path");
configRoot.Remove("gfpgan_models_path");
configRoot.Remove("bsrgan_models_path");
configRoot.Remove("esrgan_models_path");
configRoot.Remove("realesrgan_models_path");
configRoot.Remove("scunet_models_path");
configRoot.Remove("swinir_models_path");
configRoot.Remove("ldsr_models_path");
configRoot.Remove("clip_models_path");
configRoot.Remove("control_net_models_path");
var configJsonStr = JsonSerializer.Serialize(
configRoot,
new JsonSerializerOptions { WriteIndented = true }
);
File.WriteAllText(configJsonPath, configJsonStr);
return Task.CompletedTask;
}
}

Loading…
Cancel
Save