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. 34
      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

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

16
StabilityMatrix/Models/Settings.cs

@ -1,5 +1,8 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.Linq;
using Wpf.Ui.Controls.Window;
@ -7,6 +10,7 @@ namespace StabilityMatrix.Models;
public class Settings
{
public bool FirstLaunchSetupComplete { get; set; }
public string? Theme { get; set; }
public WindowBackdropType? WindowBackdropType { get; set; }
public List<InstalledPackage> InstalledPackages { get; set; } = new();
@ -17,6 +21,18 @@ public class Settings
public string? WebApiHost { 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()
{
return InstalledPackages.FirstOrDefault(x => x.Id == ActiveInstalledPackage);

34
StabilityMatrix/Models/SharedFolders.cs

@ -3,23 +3,21 @@ using System.IO;
using NCode.ReparsePoints;
using NLog;
using StabilityMatrix.Extensions;
using StabilityMatrix.Helper;
using StabilityMatrix.Models.Packages;
namespace StabilityMatrix.Models;
public class SharedFolders : ISharedFolders
{
private const string SharedFoldersName = "Models";
private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
public static string SharedFoldersPath =
Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "StabilityMatrix",
SharedFoldersName);
private readonly ISettingsManager settingsManager;
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)
{
var sharedFolders = basePackage.SharedFolders;
@ -31,7 +29,7 @@ public class SharedFolders : ISharedFolders
var provider = ReparsePointFactory.Provider;
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));
// Create source folder if it doesn't exist
if (!Directory.Exists(source))
@ -64,4 +62,24 @@ public class SharedFolders : ISharedFolders
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 ISnackbarService snackbarService;
private readonly ISettingsManager settingsManager;
public CivitModel CivitModel { get; init; }
public BitmapImage CardImage { get; init; }
public override Visibility ProgressVisibility => 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.snackbarService = snackbarService;
this.settingsManager = settingsManager;
CivitModel = civitModel;
if (civitModel.ModelVersions.Any() && civitModel.ModelVersions[0].Images.Any())
@ -62,7 +64,7 @@ public partial class CheckpointBrowserCardViewModel : ProgressViewModel
var latestModelFile = latestVersion.Files[0];
var fileExpectedSha256 = latestModelFile.Hashes.SHA256;
var downloadFolder = Path.Combine(SharedFolders.SharedFoldersPath,
var downloadFolder = Path.Combine(settingsManager.Settings.ModelsDirectory,
model.Type.ConvertTo<SharedFolderType>().GetStringValue());
// Folders might be missing if user didn't install any packages yet
Directory.CreateDirectory(downloadFolder);

6
StabilityMatrix/ViewModels/CheckpointBrowserViewModel.cs

@ -21,6 +21,7 @@ public partial class CheckpointBrowserViewModel : ObservableObject
private readonly ICivitApi civitApi;
private readonly IDownloadService downloadService;
private readonly ISnackbarService snackbarService;
private readonly ISettingsManager settingsManager;
private const int MaxModelsPerPage = 14;
[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<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.downloadService = downloadService;
this.snackbarService = snackbarService;
this.settingsManager = settingsManager;
SelectedPeriod = CivitPeriod.Month;
SortMode = CivitSortMode.HighestRated;
@ -90,7 +92,7 @@ public partial class CheckpointBrowserViewModel : ObservableObject
CanGoToPreviousPage = CurrentPageNumber > 1;
CanGoToNextPage = CurrentPageNumber < TotalPages;
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");
}
catch (ApiException e)

14
StabilityMatrix/ViewModels/CheckpointManagerViewModel.cs

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

6
StabilityMatrix/ViewModels/TextToImageViewModel.cs

@ -24,6 +24,7 @@ public partial class TextToImageViewModel : ObservableObject
private readonly IA3WebApiManager a3WebApiManager;
private readonly ISnackbarService snackbarService;
private readonly PageContentDialogService pageContentDialogService;
private readonly ISettingsManager settingsManager;
private AsyncDispatcherTimer? progressQueryTimer;
[ObservableProperty]
@ -72,12 +73,13 @@ public partial class TextToImageViewModel : ObservableObject
"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.a3WebApiManager = a3WebApiManager;
this.snackbarService = snackbarService;
this.pageContentDialogService = pageContentDialogService;
this.settingsManager = settingsManager;
positivePromptText = "Positive";
negativePromptText = "Negative";
generationSteps = 10;
@ -95,7 +97,7 @@ public partial class TextToImageViewModel : ObservableObject
}
// 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))
{
logger.LogWarning("Skipped model folder index - {SdModelsDir} does not exist", sdModelsDir);

Loading…
Cancel
Save