Browse Source

Add configurable model path to settings

pull/5/head
Ionite 1 year ago
parent
commit
9472c24238
No known key found for this signature in database
  1. 15
      StabilityMatrix/Helper/SettingsManager.cs
  2. 16
      StabilityMatrix/Models/Settings.cs
  3. 32
      StabilityMatrix/Models/SharedFolders.cs
  4. 6
      StabilityMatrix/ViewModels/CheckpointBrowserCardViewModel.cs
  5. 6
      StabilityMatrix/ViewModels/CheckpointBrowserViewModel.cs
  6. 14
      StabilityMatrix/ViewModels/CheckpointManagerViewModel.cs
  7. 6
      StabilityMatrix/ViewModels/TextToImageViewModel.cs

15
StabilityMatrix/Helper/SettingsManager.cs

@ -18,8 +18,6 @@ public class SettingsManager : ISettingsManager
SettingsFileName); SettingsFileName);
private readonly string? originalEnvPath = Environment.GetEnvironmentVariable("PATH", EnvironmentVariableTarget.Process); private readonly string? originalEnvPath = Environment.GetEnvironmentVariable("PATH", EnvironmentVariableTarget.Process);
public IA3WebApi? A3WebApi { get; set; }
public Settings Settings { get; private set; } = new(); public Settings Settings { get; private set; } = new();
public SettingsManager() public SettingsManager()
@ -189,6 +187,18 @@ public class SettingsManager : ISettingsManager
SaveSettings(); SaveSettings();
} }
public void SetModelsDirectory(string? directory)
{
Settings.ModelsDirectory = directory;
SaveSettings();
}
public void SetFirstLaunchSetupComplete(bool value)
{
Settings.FirstLaunchSetupComplete = value;
SaveSettings();
}
private void LoadSettings() private void LoadSettings()
{ {
var settingsContent = File.ReadAllText(SettingsPath); var settingsContent = File.ReadAllText(SettingsPath);
@ -196,6 +206,7 @@ public class SettingsManager : ISettingsManager
{ {
Converters = { new JsonStringEnumConverter() } Converters = { new JsonStringEnumConverter() }
})!; })!;
Settings.SetDefaults();
} }
private void SaveSettings() private void SaveSettings()

16
StabilityMatrix/Models/Settings.cs

@ -1,5 +1,8 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.Linq; using System.Linq;
using Wpf.Ui.Controls.Window; using Wpf.Ui.Controls.Window;
@ -7,6 +10,7 @@ namespace StabilityMatrix.Models;
public class Settings public class Settings
{ {
public bool FirstLaunchSetupComplete { get; set; }
public string? Theme { get; set; } public string? Theme { get; set; }
public WindowBackdropType? WindowBackdropType { get; set; } public WindowBackdropType? WindowBackdropType { get; set; }
public List<InstalledPackage> InstalledPackages { get; set; } = new(); public List<InstalledPackage> InstalledPackages { get; set; } = new();
@ -17,6 +21,18 @@ public class Settings
public string? WebApiHost { get; set; } public string? WebApiHost { get; set; }
public string? WebApiPort { get; set; } public string? WebApiPort { get; set; }
[NotNull]
public string? ModelsDirectory { get; set; }
/// <summary>
/// Sets default values for settings
/// </summary>
[MemberNotNull(nameof(ModelsDirectory))]
public void SetDefaults()
{
ModelsDirectory ??= Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "StabilityMatrix", "Models");
}
public InstalledPackage? GetActiveInstalledPackage() public InstalledPackage? GetActiveInstalledPackage()
{ {
return InstalledPackages.FirstOrDefault(x => x.Id == ActiveInstalledPackage); return InstalledPackages.FirstOrDefault(x => x.Id == ActiveInstalledPackage);

32
StabilityMatrix/Models/SharedFolders.cs

@ -3,21 +3,19 @@ using System.IO;
using NCode.ReparsePoints; using NCode.ReparsePoints;
using NLog; using NLog;
using StabilityMatrix.Extensions; using StabilityMatrix.Extensions;
using StabilityMatrix.Helper;
using StabilityMatrix.Models.Packages; using StabilityMatrix.Models.Packages;
namespace StabilityMatrix.Models; namespace StabilityMatrix.Models;
public class SharedFolders : ISharedFolders public class SharedFolders : ISharedFolders
{ {
private const string SharedFoldersName = "Models";
private static readonly Logger Logger = LogManager.GetCurrentClassLogger(); private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
public static string SharedFoldersPath = private readonly ISettingsManager settingsManager;
Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "StabilityMatrix",
SharedFoldersName);
public static string SharedFolderTypeToName(SharedFolderType folderType) public SharedFolders(ISettingsManager settingsManager)
{ {
return Enum.GetName(typeof(SharedFolderType), folderType)!; this.settingsManager = settingsManager;
} }
public void SetupLinksForPackage(BasePackage basePackage, string installPath) public void SetupLinksForPackage(BasePackage basePackage, string installPath)
@ -31,7 +29,7 @@ public class SharedFolders : ISharedFolders
var provider = ReparsePointFactory.Provider; var provider = ReparsePointFactory.Provider;
foreach (var (folderType, relativePath) in sharedFolders) foreach (var (folderType, relativePath) in sharedFolders)
{ {
var source = Path.GetFullPath(Path.Combine(SharedFoldersPath, folderType.GetStringValue())); var source = Path.Combine(settingsManager.Settings.ModelsDirectory, folderType.GetStringValue());
var destination = Path.GetFullPath(Path.Combine(installPath, relativePath)); var destination = Path.GetFullPath(Path.Combine(installPath, relativePath));
// Create source folder if it doesn't exist // Create source folder if it doesn't exist
if (!Directory.Exists(source)) if (!Directory.Exists(source))
@ -64,4 +62,24 @@ public class SharedFolders : ISharedFolders
provider.CreateLink(destination, source, LinkType.Junction); provider.CreateLink(destination, source, LinkType.Junction);
} }
} }
public void RemoveLinksForPackage(BasePackage package, string installPath)
{
var sharedFolders = package.SharedFolders;
if (sharedFolders == null)
{
return;
}
foreach (var (_, relativePath) in sharedFolders)
{
var destination = Path.GetFullPath(Path.Combine(installPath, relativePath));
// Delete the destination folder if it exists
if (Directory.Exists(destination))
{
Logger.Info($"Deleting junction target {destination}");
Directory.Delete(destination, false);
}
}
}
} }

6
StabilityMatrix/ViewModels/CheckpointBrowserCardViewModel.cs

@ -20,16 +20,18 @@ public partial class CheckpointBrowserCardViewModel : ProgressViewModel
{ {
private readonly IDownloadService downloadService; private readonly IDownloadService downloadService;
private readonly ISnackbarService snackbarService; private readonly ISnackbarService snackbarService;
private readonly ISettingsManager settingsManager;
public CivitModel CivitModel { get; init; } public CivitModel CivitModel { get; init; }
public BitmapImage CardImage { get; init; } public BitmapImage CardImage { get; init; }
public override Visibility ProgressVisibility => Value > 0 ? Visibility.Visible : Visibility.Collapsed; public override Visibility ProgressVisibility => Value > 0 ? Visibility.Visible : Visibility.Collapsed;
public override Visibility TextVisibility => Value > 0 ? Visibility.Visible : Visibility.Collapsed; public override Visibility TextVisibility => Value > 0 ? Visibility.Visible : Visibility.Collapsed;
public CheckpointBrowserCardViewModel(CivitModel civitModel, IDownloadService downloadService, ISnackbarService snackbarService) public CheckpointBrowserCardViewModel(CivitModel civitModel, IDownloadService downloadService, ISnackbarService snackbarService, ISettingsManager settingsManager)
{ {
this.downloadService = downloadService; this.downloadService = downloadService;
this.snackbarService = snackbarService; this.snackbarService = snackbarService;
this.settingsManager = settingsManager;
CivitModel = civitModel; CivitModel = civitModel;
if (civitModel.ModelVersions.Any() && civitModel.ModelVersions[0].Images.Any()) if (civitModel.ModelVersions.Any() && civitModel.ModelVersions[0].Images.Any())
@ -62,7 +64,7 @@ public partial class CheckpointBrowserCardViewModel : ProgressViewModel
var latestModelFile = latestVersion.Files[0]; var latestModelFile = latestVersion.Files[0];
var fileExpectedSha256 = latestModelFile.Hashes.SHA256; var fileExpectedSha256 = latestModelFile.Hashes.SHA256;
var downloadFolder = Path.Combine(SharedFolders.SharedFoldersPath, var downloadFolder = Path.Combine(settingsManager.Settings.ModelsDirectory,
model.Type.ConvertTo<SharedFolderType>().GetStringValue()); model.Type.ConvertTo<SharedFolderType>().GetStringValue());
// Folders might be missing if user didn't install any packages yet // Folders might be missing if user didn't install any packages yet
Directory.CreateDirectory(downloadFolder); Directory.CreateDirectory(downloadFolder);

6
StabilityMatrix/ViewModels/CheckpointBrowserViewModel.cs

@ -21,6 +21,7 @@ public partial class CheckpointBrowserViewModel : ObservableObject
private readonly ICivitApi civitApi; private readonly ICivitApi civitApi;
private readonly IDownloadService downloadService; private readonly IDownloadService downloadService;
private readonly ISnackbarService snackbarService; private readonly ISnackbarService snackbarService;
private readonly ISettingsManager settingsManager;
private const int MaxModelsPerPage = 14; private const int MaxModelsPerPage = 14;
[ObservableProperty] private string? searchQuery; [ObservableProperty] private string? searchQuery;
@ -41,11 +42,12 @@ public partial class CheckpointBrowserViewModel : ObservableObject
public IEnumerable<CivitSortMode> AllSortModes => Enum.GetValues(typeof(CivitSortMode)).Cast<CivitSortMode>(); public IEnumerable<CivitSortMode> AllSortModes => Enum.GetValues(typeof(CivitSortMode)).Cast<CivitSortMode>();
public IEnumerable<CivitModelType> AllModelTypes => Enum.GetValues(typeof(CivitModelType)).Cast<CivitModelType>(); public IEnumerable<CivitModelType> AllModelTypes => Enum.GetValues(typeof(CivitModelType)).Cast<CivitModelType>();
public CheckpointBrowserViewModel(ICivitApi civitApi, IDownloadService downloadService, ISnackbarService snackbarService) public CheckpointBrowserViewModel(ICivitApi civitApi, IDownloadService downloadService, ISnackbarService snackbarService, ISettingsManager settingsManager)
{ {
this.civitApi = civitApi; this.civitApi = civitApi;
this.downloadService = downloadService; this.downloadService = downloadService;
this.snackbarService = snackbarService; this.snackbarService = snackbarService;
this.settingsManager = settingsManager;
SelectedPeriod = CivitPeriod.Month; SelectedPeriod = CivitPeriod.Month;
SortMode = CivitSortMode.HighestRated; SortMode = CivitSortMode.HighestRated;
@ -90,7 +92,7 @@ public partial class CheckpointBrowserViewModel : ObservableObject
CanGoToPreviousPage = CurrentPageNumber > 1; CanGoToPreviousPage = CurrentPageNumber > 1;
CanGoToNextPage = CurrentPageNumber < TotalPages; CanGoToNextPage = CurrentPageNumber < TotalPages;
ModelCards = new ObservableCollection<CheckpointBrowserCardViewModel>(models.Items.Select( ModelCards = new ObservableCollection<CheckpointBrowserCardViewModel>(models.Items.Select(
m => new CheckpointBrowserCardViewModel(m, downloadService, snackbarService))); m => new CheckpointBrowserCardViewModel(m, downloadService, snackbarService, settingsManager)));
Logger.Debug($"Found {models.Items.Length} models"); Logger.Debug($"Found {models.Items.Length} models");
} }
catch (ApiException e) catch (ApiException e)

14
StabilityMatrix/ViewModels/CheckpointManagerViewModel.cs

@ -5,6 +5,7 @@ using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using CommunityToolkit.Mvvm.ComponentModel; using CommunityToolkit.Mvvm.ComponentModel;
using NLog; using NLog;
using StabilityMatrix.Helper;
using StabilityMatrix.Models; using StabilityMatrix.Models;
namespace StabilityMatrix.ViewModels; namespace StabilityMatrix.ViewModels;
@ -13,27 +14,30 @@ public partial class CheckpointManagerViewModel : ObservableObject
{ {
private static readonly Logger Logger = LogManager.GetCurrentClassLogger(); private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
private readonly ISharedFolders sharedFolders; private readonly ISharedFolders sharedFolders;
private readonly ISettingsManager settingsManager;
public ObservableCollection<CheckpointFolder> CheckpointFolders { get; set; } = new(); public ObservableCollection<CheckpointFolder> CheckpointFolders { get; set; } = new();
public CheckpointManagerViewModel(ISharedFolders sharedFolders) public CheckpointManagerViewModel(ISharedFolders sharedFolders, ISettingsManager settingsManager)
{ {
this.sharedFolders = sharedFolders; this.sharedFolders = sharedFolders;
this.settingsManager = settingsManager;
} }
public async Task OnLoaded() public async Task OnLoaded()
{ {
var modelsDirectory = settingsManager.Settings.ModelsDirectory;
// Get all folders within the shared folder root // Get all folders within the shared folder root
if (string.IsNullOrWhiteSpace(SharedFolders.SharedFoldersPath)) if (string.IsNullOrWhiteSpace(modelsDirectory))
{ {
return; return;
} }
// Skip if the shared folder root doesn't exist // Skip if the shared folder root doesn't exist
if (!Directory.Exists(SharedFolders.SharedFoldersPath)) if (!Directory.Exists(modelsDirectory))
{ {
Logger.Debug($"Skipped shared folder index - {SharedFolders.SharedFoldersPath} doesn't exist"); Logger.Debug($"Skipped shared folder index - {modelsDirectory} doesn't exist");
return; return;
} }
var folders = Directory.GetDirectories(SharedFolders.SharedFoldersPath); var folders = Directory.GetDirectories(modelsDirectory);
CheckpointFolders.Clear(); CheckpointFolders.Clear();

6
StabilityMatrix/ViewModels/TextToImageViewModel.cs

@ -24,6 +24,7 @@ public partial class TextToImageViewModel : ObservableObject
private readonly IA3WebApiManager a3WebApiManager; private readonly IA3WebApiManager a3WebApiManager;
private readonly ISnackbarService snackbarService; private readonly ISnackbarService snackbarService;
private readonly PageContentDialogService pageContentDialogService; private readonly PageContentDialogService pageContentDialogService;
private readonly ISettingsManager settingsManager;
private AsyncDispatcherTimer? progressQueryTimer; private AsyncDispatcherTimer? progressQueryTimer;
[ObservableProperty] [ObservableProperty]
@ -72,12 +73,13 @@ public partial class TextToImageViewModel : ObservableObject
"DPM++ 2M Karras" "DPM++ 2M Karras"
}; };
public TextToImageViewModel(IA3WebApiManager a3WebApiManager, ILogger<TextToImageViewModel> logger, ISnackbarService snackbarService, PageContentDialogService pageContentDialogService) public TextToImageViewModel(IA3WebApiManager a3WebApiManager, ILogger<TextToImageViewModel> logger, ISnackbarService snackbarService, PageContentDialogService pageContentDialogService, ISettingsManager settingsManager)
{ {
this.logger = logger; this.logger = logger;
this.a3WebApiManager = a3WebApiManager; this.a3WebApiManager = a3WebApiManager;
this.snackbarService = snackbarService; this.snackbarService = snackbarService;
this.pageContentDialogService = pageContentDialogService; this.pageContentDialogService = pageContentDialogService;
this.settingsManager = settingsManager;
positivePromptText = "Positive"; positivePromptText = "Positive";
negativePromptText = "Negative"; negativePromptText = "Negative";
generationSteps = 10; generationSteps = 10;
@ -95,7 +97,7 @@ public partial class TextToImageViewModel : ObservableObject
} }
// Set the diffusion checkpoint folder // Set the diffusion checkpoint folder
var sdModelsDir = Path.Join(SharedFolders.SharedFoldersPath, SharedFolderType.StableDiffusion.GetStringValue()); var sdModelsDir = Path.Join(settingsManager.Settings.ModelsDirectory, SharedFolderType.StableDiffusion.GetStringValue());
if (!Directory.Exists(sdModelsDir)) if (!Directory.Exists(sdModelsDir))
{ {
logger.LogWarning("Skipped model folder index - {SdModelsDir} does not exist", sdModelsDir); logger.LogWarning("Skipped model folder index - {SdModelsDir} does not exist", sdModelsDir);

Loading…
Cancel
Save