Multi-Platform Package Manager for Stable Diffusion
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

229 lines
7.4 KiB

using System.Text.Json.Serialization;
using StabilityMatrix.Core.Helper;
namespace StabilityMatrix.Core.Models;
/// <summary>
/// Profile information for a user-installed package.
/// </summary>
public class InstalledPackage : IJsonOnDeserialized
{
// Unique ID for the installation
public Guid Id { get; set; }
1 year ago
// User defined name
public string? DisplayName { get; set; }
1 year ago
// Package name
public string? PackageName { get; set; }
1 year ago
// Package version
[Obsolete("Use Version instead. (Kept for migration)")]
public string? PackageVersion { get; set; }
1 year ago
[Obsolete("Use Version instead. (Kept for migration)")]
public string? InstalledBranch { get; set; }
1 year ago
[Obsolete("Use Version instead. (Kept for migration)")]
public string? DisplayVersion { get; set; }
1 year ago
public InstalledPackageVersion? Version { get; set; }
1 year ago
// Old type absolute path
[Obsolete("Use LibraryPath instead. (Kept for migration)")]
public string? Path { get; set; }
1 year ago
/// <summary>
/// Relative path from the library root.
/// </summary>
public string? LibraryPath { get; set; }
1 year ago
/// <summary>
/// Full path to the package, using LibraryPath and GlobalConfig.LibraryDir.
/// </summary>
[JsonIgnore]
1 year ago
public string? FullPath =>
LibraryPath != null ? System.IO.Path.Combine(GlobalConfig.LibraryDir, LibraryPath) : null;
public string? LaunchCommand { get; set; }
public List<LaunchOption>? LaunchArgs { get; set; }
public DateTimeOffset? LastUpdateCheck { get; set; }
public bool UpdateAvailable { get; set; }
public TorchVersion? PreferredTorchVersion { get; set; }
public SharedFolderMethod? PreferredSharedFolderMethod { get; set; }
1 year ago
/// <summary>
/// Get the path as a relative sub-path of the relative path.
/// If not a sub-path, return null.
/// </summary>
1 year ago
public static string? GetSubPath(string relativeTo, string path)
{
var relativePath = System.IO.Path.GetRelativePath(relativeTo, path);
// GetRelativePath returns the path if it's not relative
1 year ago
if (relativePath == path)
return null;
// Further check if the path is a sub-path of the library
1 year ago
var isSubPath =
relativePath != "."
&& relativePath != ".."
&& !relativePath.StartsWith(".." + System.IO.Path.DirectorySeparatorChar)
&& !System.IO.Path.IsPathRooted(relativePath);
return isSubPath ? relativePath : null;
1 year ago
}
/// <summary>
/// Migrates the old Path to the new LibraryPath.
/// If libraryDirectory is null, GlobalConfig.LibraryDir is used.
/// </summary>
/// <returns>True if the path was migrated, false otherwise.</returns>
public bool TryPureMigratePath(string? libraryDirectory = null)
{
#pragma warning disable CS0618
var oldPath = Path;
#pragma warning restore CS0618
1 year ago
if (oldPath == null)
return false;
// Check if the path is a sub-path of the library
var library = libraryDirectory ?? GlobalConfig.LibraryDir;
var relativePath = GetSubPath(library, oldPath);
1 year ago
// If so we migrate without any IO operations
if (relativePath != null)
{
LibraryPath = relativePath;
#pragma warning disable CS0618
Path = null;
#pragma warning restore CS0618
return true;
}
return false;
}
/// <summary>
/// Check if the old Path can be migrated to the new LibraryPath.
/// </summary>
/// <param name="libraryDirectory"></param>
/// <returns></returns>
public bool CanPureMigratePath(string? libraryDirectory = null)
{
#pragma warning disable CS0618
var oldPath = Path;
#pragma warning restore CS0618
1 year ago
if (oldPath == null)
return false;
// Check if the path is a sub-path of the library
var library = libraryDirectory ?? GlobalConfig.LibraryDir;
var relativePath = GetSubPath(library, oldPath);
return relativePath != null;
}
/// <summary>
/// Migrate the old Path to the new LibraryPath.
/// If libraryDirectory is null, GlobalConfig.LibraryDir is used.
/// Will move the package directory to Library/Packages if not relative.
/// </summary>
public async Task MigratePath(string? libraryDirectory = null)
{
#pragma warning disable CS0618
var oldPath = Path;
#pragma warning restore CS0618
1 year ago
if (oldPath == null)
return;
1 year ago
var libDir = libraryDirectory ?? GlobalConfig.LibraryDir;
// if old package Path is same as new library, return
if (oldPath.Replace(DisplayName, "") == libDir)
{
// Update the paths
#pragma warning disable CS0618
Path = null;
#pragma warning restore CS0618
LibraryPath = System.IO.Path.Combine("Packages", DisplayName);
return;
}
1 year ago
// Try using pure migration first
1 year ago
if (TryPureMigratePath(libraryDirectory))
return;
// If not, we need to move the package directory
var packageFolderName = new DirectoryInfo(oldPath).Name;
1 year ago
// Get the new Library/Packages path
var library = libraryDirectory ?? GlobalConfig.LibraryDir;
var newPackagesDir = System.IO.Path.Combine(library, "Packages");
1 year ago
// Get the new target path
var newPackagePath = System.IO.Path.Combine(newPackagesDir, packageFolderName);
// Ensure it is not already there, if so, add a suffix until it's not
var suffix = 2;
while (Directory.Exists(newPackagePath))
{
1 year ago
newPackagePath = System.IO.Path.Combine(
newPackagesDir,
$"{packageFolderName}-{suffix}"
);
suffix++;
}
1 year ago
// Move the package directory
await Task.Run(() => Utilities.CopyDirectory(oldPath, newPackagePath, true));
// Update the paths
#pragma warning disable CS0618
Path = null;
#pragma warning restore CS0618
LibraryPath = System.IO.Path.Combine("Packages", packageFolderName);
}
1 year ago
public static IEqualityComparer<InstalledPackage> Comparer { get; } =
new PropertyComparer<InstalledPackage>(p => p.Id);
1 year ago
1 year ago
protected bool Equals(InstalledPackage other)
{
return Id.Equals(other.Id);
}
public override bool Equals(object? obj)
{
1 year ago
if (ReferenceEquals(null, obj))
return false;
if (ReferenceEquals(this, obj))
return true;
return obj.GetType() == this.GetType() && Equals((InstalledPackage)obj);
1 year ago
}
public override int GetHashCode()
{
return Id.GetHashCode();
}
#pragma warning disable CS0618 // Type or member is obsolete
public void OnDeserialized()
{
// Handle version migration
1 year ago
if (Version != null)
return;
1 year ago
if (
string.IsNullOrWhiteSpace(InstalledBranch) && !string.IsNullOrWhiteSpace(PackageVersion)
)
{
// release mode
1 year ago
Version = new InstalledPackageVersion { InstalledReleaseVersion = PackageVersion };
}
else if (!string.IsNullOrWhiteSpace(PackageVersion))
{
Version = new InstalledPackageVersion
{
InstalledBranch = InstalledBranch,
InstalledCommitSha = PackageVersion
};
}
}
#pragma warning restore CS0618 // Type or member is obsolete
}