From 30ae65eafbe1bf9b7adae23437847cab8653a44c Mon Sep 17 00:00:00 2001 From: Adrian Gaborek Date: Fri, 21 Feb 2025 18:56:01 +0100 Subject: [PATCH 1/6] fix formatting issues --- scripts/apply_versions.py | 12 +- src/UniGetUI.Core.Data/CoreData.cs | 666 ++++++++++++++--------------- 2 files changed, 339 insertions(+), 339 deletions(-) diff --git a/scripts/apply_versions.py b/scripts/apply_versions.py index e86ec9868c..066979cbf1 100644 --- a/scripts/apply_versions.py +++ b/scripts/apply_versions.py @@ -11,13 +11,13 @@ if versionName == "": print("Version changer script aborted") exit() - + BuildNumber = -1 c = "" if os.path.exists("scripts/BuildNumber"): with open("scripts/BuildNumber", "r") as f: c = f.read() - + BuildNumber = int(c) if c != "" else int(input("Build number file was empty. Insert (integer) build number: "))-1 print(f"Build number set to {BuildNumber+1}") with open("scripts/BuildNumber", "w") as f: @@ -25,7 +25,7 @@ versionISS = str(input("Enter version (X.X.X.X) : ")) - while not versionISS.count('.') == 3: + while not versionISS.count('.') == 3: versionISS = str(input("Incorrect format. Enter version (X.X.X.X) : ")) def fileReplaceLinesWith(filename: str, list: dict[str, str], encoding="utf-8"): @@ -45,8 +45,8 @@ def fileReplaceLinesWith(filename: str, list: dict[str, str], encoding="utf-8"): f.truncate() fileReplaceLinesWith("src/UniGetUI.Core.Data/CoreData.cs", { - " public const string VersionName = ": f" \"{versionName}\"; // Do not modify this line, use file scripts/apply_versions.py\n", - " public const int BuildNumber = ": f" {BuildNumber+1}; // Do not modify this line, use file scripts/apply_versions.py\n", + " public const string VersionName =": f" \"{versionName}\"; // Do not modify this line, use file scripts/apply_versions.py\n", + " public const int BuildNumber =": f" {BuildNumber+1}; // Do not modify this line, use file scripts/apply_versions.py\n", }, encoding="utf-8-sig") @@ -68,7 +68,7 @@ def fileReplaceLinesWith(filename: str, list: dict[str, str], encoding="utf-8"): BETA_APP_NAME = "UniGetUI (PreRelease)" STABLE_APP_NAME = "UniGetUI" - + fileReplaceLinesWith("UniGetUI.iss", { "UninstallDisplayName=\"": f"{BETA_APP_NAME if IS_BETA else STABLE_APP_NAME}\"\n", }, encoding="utf-8-sig") diff --git a/src/UniGetUI.Core.Data/CoreData.cs b/src/UniGetUI.Core.Data/CoreData.cs index 34378dbe21..b015d6fd2a 100644 --- a/src/UniGetUI.Core.Data/CoreData.cs +++ b/src/UniGetUI.Core.Data/CoreData.cs @@ -1,333 +1,333 @@ -using System.Diagnostics; -using System.Net; -using System.Text.Json; -using System.Text.Json.Serialization.Metadata; -using UniGetUI.Core.Logging; - -namespace UniGetUI.Core.Data -{ - public static class CoreData - { - private static int? __code_page; - public static int CODE_PAGE { get => __code_page ??= GetCodePage(); } - public const string VersionName = "3.1.7-beta1"; // Do not modify this line, use file scripts/apply_versions.py - public const int BuildNumber = 81; // Do not modify this line, use file scripts/apply_versions.py - - public const string UserAgentString = $"UniGetUI/{VersionName} (https://marticliment.com/unigetui/; contact@marticliment.com)"; - - public static HttpClientHandler GenericHttpClientParameters - { - get - { - return new() - { - AutomaticDecompression = DecompressionMethods.All, - AllowAutoRedirect = true, - }; - } - } - - private static bool? IS_PORTABLE; - public static bool IsPortable { get => IS_PORTABLE ?? false; } - - /// - /// The directory where all the user data is stored. The directory is automatically created if it does not exist. - /// - public static string UniGetUIDataDirectory - { - get - { - if (IS_PORTABLE is null) - IS_PORTABLE = File.Exists(Path.Join(UniGetUIExecutableDirectory, "ForceUniGetUIPortable")); - - if (IS_PORTABLE is true) - { - string path = Path.Join(UniGetUIExecutableDirectory, "Settings"); - try - { - if (!Directory.Exists(path)) Directory.CreateDirectory(path); - var testfilepath = Path.Join(path, "PermissionTestFile"); - File.WriteAllText(testfilepath, "https://www.youtube.com/watch?v=dQw4w9WgXcQ"); - return path; - } - catch (Exception ex) - { - IS_PORTABLE = false; - Logger.Error($"Could not acces/write path {path}. UniGetUI will NOT be run in portable mode, and User settings will be used instead"); - Logger.Error(ex); - } - } - - string old_path = Path.Join(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), ".wingetui"); - string new_path = Path.Join(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "UniGetUI"); - return GetNewDataDirectoryOrMoveOld(old_path, new_path); - } - } - - /// - /// The directory where the installation options are stored. The directory is automatically created if it does not exist. - /// - public static string UniGetUIInstallationOptionsDirectory - { - get - { - string path = Path.Join(UniGetUIDataDirectory, "InstallationOptions"); - if (!Directory.Exists(path)) Directory.CreateDirectory(path); - return path; - } - } - - /// - /// The directory where the metadata cache is stored. The directory is automatically created if it does not exist. - /// - public static string UniGetUICacheDirectory_Data - { - get - { - string path = Path.Join(UniGetUIDataDirectory, "CachedMetadata"); - if (!Directory.Exists(path)) Directory.CreateDirectory(path); - return path; - } - } - - /// - /// The directory where the cached icons and screenshots are saved. The directory is automatically created if it does not exist. - /// - public static string UniGetUICacheDirectory_Icons - { - get - { - string path = Path.Join(UniGetUIDataDirectory, "CachedMedia"); - if (!Directory.Exists(path)) Directory.CreateDirectory(path); - return path; - } - } - - /// - /// The directory where the cached language files are stored. The directory is automatically created if it does not exist. - /// - public static string UniGetUICacheDirectory_Lang - { - get - { - string path= Path.Join(UniGetUIDataDirectory, "CachedLanguageFiles"); - if (!Directory.Exists(path)) Directory.CreateDirectory(path); - return path; - } - } - - /// - /// The directory where package backups will be saved by default. - /// - public static string UniGetUI_DefaultBackupDirectory - { - get - { - string old_dir = Path.Join(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), "WingetUI"); - string new_dir = Path.Join(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), "UniGetUI"); - return GetNewDataDirectoryOrMoveOld(old_dir, new_dir); - } - } - - public static bool IsDaemon; - public static bool WasDaemon; - - /// - /// The ID of the notification that is used to inform the user that updates are available - /// - public const int UpdatesAvailableNotificationTag = 1234; - /// - /// The ID of the notification that is used to inform the user that UniGetUI can be updated - /// - public const int UniGetUICanBeUpdated = 1235; - /// - /// The ID of the notification that is used to inform the user that shortcuts are available for deletion - /// - public const int NewShortcutsNotificationTag = 1236; - - /// - /// A path pointing to the location where the app is installed - /// - public static string UniGetUIExecutableDirectory - { - get - { - string? dir = Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location); - if (dir is not null) - { - return dir; - } - - Logger.Error("System.Reflection.Assembly.GetExecutingAssembly().Location returned an empty path"); - - return Path.Join(Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles), "UniGetUI"); - } - } - - /// - /// A path pointing to the executable file of the app - /// - public static string UniGetUIExecutableFile - { - get - { - string? filename = Process.GetCurrentProcess().MainModule?.FileName; - if (filename is not null) - { - return filename.Replace(".dll", ".exe"); - } - - Logger.Error("System.Reflection.Assembly.GetExecutingAssembly().Location returned an empty path"); - - return Path.Join(Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles), "UniGetUI", "UniGetUI.exe"); - } - } - - public static string ElevatorPath = ""; - - /// - /// This method will return the most appropriate data directory. - /// If the new directory exists, it will be used. - /// If the new directory does not exist, but the old directory does, it will be moved to the new location, and the new location will be used. - /// If none exist, the new directory will be created. - /// - /// The old/legacy directory - /// The new directory - /// The path to an existing, valid directory - private static string GetNewDataDirectoryOrMoveOld(string old_path, string new_path) - { - if (Directory.Exists(new_path) && !Directory.Exists(old_path)) - { - return new_path; - } - - if (Directory.Exists(new_path) && Directory.Exists(old_path)) - { - try - { - foreach (string old_subdir in Directory.GetDirectories(old_path, "*", SearchOption.AllDirectories)) - { - string new_subdir = old_subdir.Replace(old_path, new_path); - if (!Directory.Exists(new_subdir)) - { - Logger.Debug("New directory: " + new_subdir); - Directory.CreateDirectory(new_subdir); - } - else - { - Logger.Debug("Directory " + new_subdir + " already exists"); - } - } - - foreach (string old_file in Directory.GetFiles(old_path, "*", SearchOption.AllDirectories)) - { - string new_file = old_file.Replace(old_path, new_path); - if (!File.Exists(new_file)) - { - Logger.Info("Copying " + old_file); - File.Move(old_file, new_file); - } - else - { - Logger.Debug("File " + new_file + " already exists."); - File.Delete(old_file); - } - } - - foreach (string old_subdir in Directory.GetDirectories(old_path, "*", SearchOption.AllDirectories).Reverse()) - { - if (!Directory.EnumerateFiles(old_subdir).Any() && !Directory.EnumerateDirectories(old_subdir).Any()) - { - Logger.Debug("Deleting old empty subdirectory " + old_subdir); - Directory.Delete(old_subdir); - } - } - - if (!Directory.EnumerateFiles(old_path).Any() && !Directory.EnumerateDirectories(old_path).Any()) - { - Logger.Info("Deleting old Chocolatey directory " + old_path); - Directory.Delete(old_path); - } - - return new_path; - } - catch (Exception e) - { - Logger.Error(e); - return new_path; - } - } - - if (/*Directory.Exists(new_path)*/Directory.Exists(old_path)) - { - try - { - Directory.Move(old_path, new_path); - Task.Delay(100).Wait(); - return new_path; - } - catch (Exception e) - { - Logger.Error("Cannot move old data directory to new location. Directory to move: " + old_path + ". Destination: " + new_path); - Logger.Error(e); - return old_path; - } - } - - try - { - Logger.Debug("Creating non-existing data directory at: " + new_path); - Directory.CreateDirectory(new_path); - return new_path; - } - catch (Exception e) - { - Logger.Error("Could not create new directory. You may perhaps need to disable Controlled Folder Access from Windows Settings or make an exception for UniGetUI."); - Logger.Error(e); - return new_path; - } - } - - public static JsonSerializerOptions SerializingOptions = new() - { - TypeInfoResolverChain = { new DefaultJsonTypeInfoResolver() }, - WriteIndented = true, - }; - - private static int GetCodePage() - { - try - { - Process p = new Process - { - StartInfo = new ProcessStartInfo - { - FileName = "chcp.com", - RedirectStandardOutput = true, - UseShellExecute = false, - CreateNoWindow = true, - } - }; - p.Start(); - string contents = p.StandardOutput.ReadToEnd(); - string purifiedString = ""; - - foreach (var c in contents.Split(':')[^1].Trim()) - { - if (c >= '0' && c <= '9') - { - purifiedString += c; - } - } - - return int.Parse(purifiedString); - } - catch (Exception e) - { - Logger.Error(e); - return 0; - } - } - - } -} +using System.Diagnostics; +using System.Net; +using System.Text.Json; +using System.Text.Json.Serialization.Metadata; +using UniGetUI.Core.Logging; + +namespace UniGetUI.Core.Data +{ + public static class CoreData + { + private static int? __code_page; + public static int CODE_PAGE { get => __code_page ??= GetCodePage(); } + public const string VersionName = "3.1.7-beta1"; // Do not modify this line, use file scripts/apply_versions.py + public const int BuildNumber = 81; // Do not modify this line, use file scripts/apply_versions.py + + public const string UserAgentString = $"UniGetUI/{VersionName} (https://marticliment.com/unigetui/; contact@marticliment.com)"; + + public static HttpClientHandler GenericHttpClientParameters + { + get + { + return new() + { + AutomaticDecompression = DecompressionMethods.All, + AllowAutoRedirect = true, + }; + } + } + + private static bool? IS_PORTABLE; + public static bool IsPortable { get => IS_PORTABLE ?? false; } + + /// + /// The directory where all the user data is stored. The directory is automatically created if it does not exist. + /// + public static string UniGetUIDataDirectory + { + get + { + if (IS_PORTABLE is null) + IS_PORTABLE = File.Exists(Path.Join(UniGetUIExecutableDirectory, "ForceUniGetUIPortable")); + + if (IS_PORTABLE is true) + { + string path = Path.Join(UniGetUIExecutableDirectory, "Settings"); + try + { + if (!Directory.Exists(path)) Directory.CreateDirectory(path); + var testfilepath = Path.Join(path, "PermissionTestFile"); + File.WriteAllText(testfilepath, "https://www.youtube.com/watch?v=dQw4w9WgXcQ"); + return path; + } + catch (Exception ex) + { + IS_PORTABLE = false; + Logger.Error($"Could not acces/write path {path}. UniGetUI will NOT be run in portable mode, and User settings will be used instead"); + Logger.Error(ex); + } + } + + string old_path = Path.Join(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), ".wingetui"); + string new_path = Path.Join(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "UniGetUI"); + return GetNewDataDirectoryOrMoveOld(old_path, new_path); + } + } + + /// + /// The directory where the installation options are stored. The directory is automatically created if it does not exist. + /// + public static string UniGetUIInstallationOptionsDirectory + { + get + { + string path = Path.Join(UniGetUIDataDirectory, "InstallationOptions"); + if (!Directory.Exists(path)) Directory.CreateDirectory(path); + return path; + } + } + + /// + /// The directory where the metadata cache is stored. The directory is automatically created if it does not exist. + /// + public static string UniGetUICacheDirectory_Data + { + get + { + string path = Path.Join(UniGetUIDataDirectory, "CachedMetadata"); + if (!Directory.Exists(path)) Directory.CreateDirectory(path); + return path; + } + } + + /// + /// The directory where the cached icons and screenshots are saved. The directory is automatically created if it does not exist. + /// + public static string UniGetUICacheDirectory_Icons + { + get + { + string path = Path.Join(UniGetUIDataDirectory, "CachedMedia"); + if (!Directory.Exists(path)) Directory.CreateDirectory(path); + return path; + } + } + + /// + /// The directory where the cached language files are stored. The directory is automatically created if it does not exist. + /// + public static string UniGetUICacheDirectory_Lang + { + get + { + string path = Path.Join(UniGetUIDataDirectory, "CachedLanguageFiles"); + if (!Directory.Exists(path)) Directory.CreateDirectory(path); + return path; + } + } + + /// + /// The directory where package backups will be saved by default. + /// + public static string UniGetUI_DefaultBackupDirectory + { + get + { + string old_dir = Path.Join(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), "WingetUI"); + string new_dir = Path.Join(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), "UniGetUI"); + return GetNewDataDirectoryOrMoveOld(old_dir, new_dir); + } + } + + public static bool IsDaemon; + public static bool WasDaemon; + + /// + /// The ID of the notification that is used to inform the user that updates are available + /// + public const int UpdatesAvailableNotificationTag = 1234; + /// + /// The ID of the notification that is used to inform the user that UniGetUI can be updated + /// + public const int UniGetUICanBeUpdated = 1235; + /// + /// The ID of the notification that is used to inform the user that shortcuts are available for deletion + /// + public const int NewShortcutsNotificationTag = 1236; + + /// + /// A path pointing to the location where the app is installed + /// + public static string UniGetUIExecutableDirectory + { + get + { + string? dir = Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location); + if (dir is not null) + { + return dir; + } + + Logger.Error("System.Reflection.Assembly.GetExecutingAssembly().Location returned an empty path"); + + return Path.Join(Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles), "UniGetUI"); + } + } + + /// + /// A path pointing to the executable file of the app + /// + public static string UniGetUIExecutableFile + { + get + { + string? filename = Process.GetCurrentProcess().MainModule?.FileName; + if (filename is not null) + { + return filename.Replace(".dll", ".exe"); + } + + Logger.Error("System.Reflection.Assembly.GetExecutingAssembly().Location returned an empty path"); + + return Path.Join(Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles), "UniGetUI", "UniGetUI.exe"); + } + } + + public static string ElevatorPath = ""; + + /// + /// This method will return the most appropriate data directory. + /// If the new directory exists, it will be used. + /// If the new directory does not exist, but the old directory does, it will be moved to the new location, and the new location will be used. + /// If none exist, the new directory will be created. + /// + /// The old/legacy directory + /// The new directory + /// The path to an existing, valid directory + private static string GetNewDataDirectoryOrMoveOld(string old_path, string new_path) + { + if (Directory.Exists(new_path) && !Directory.Exists(old_path)) + { + return new_path; + } + + if (Directory.Exists(new_path) && Directory.Exists(old_path)) + { + try + { + foreach (string old_subdir in Directory.GetDirectories(old_path, "*", SearchOption.AllDirectories)) + { + string new_subdir = old_subdir.Replace(old_path, new_path); + if (!Directory.Exists(new_subdir)) + { + Logger.Debug("New directory: " + new_subdir); + Directory.CreateDirectory(new_subdir); + } + else + { + Logger.Debug("Directory " + new_subdir + " already exists"); + } + } + + foreach (string old_file in Directory.GetFiles(old_path, "*", SearchOption.AllDirectories)) + { + string new_file = old_file.Replace(old_path, new_path); + if (!File.Exists(new_file)) + { + Logger.Info("Copying " + old_file); + File.Move(old_file, new_file); + } + else + { + Logger.Debug("File " + new_file + " already exists."); + File.Delete(old_file); + } + } + + foreach (string old_subdir in Directory.GetDirectories(old_path, "*", SearchOption.AllDirectories).Reverse()) + { + if (!Directory.EnumerateFiles(old_subdir).Any() && !Directory.EnumerateDirectories(old_subdir).Any()) + { + Logger.Debug("Deleting old empty subdirectory " + old_subdir); + Directory.Delete(old_subdir); + } + } + + if (!Directory.EnumerateFiles(old_path).Any() && !Directory.EnumerateDirectories(old_path).Any()) + { + Logger.Info("Deleting old Chocolatey directory " + old_path); + Directory.Delete(old_path); + } + + return new_path; + } + catch (Exception e) + { + Logger.Error(e); + return new_path; + } + } + + if (/*Directory.Exists(new_path)*/Directory.Exists(old_path)) + { + try + { + Directory.Move(old_path, new_path); + Task.Delay(100).Wait(); + return new_path; + } + catch (Exception e) + { + Logger.Error("Cannot move old data directory to new location. Directory to move: " + old_path + ". Destination: " + new_path); + Logger.Error(e); + return old_path; + } + } + + try + { + Logger.Debug("Creating non-existing data directory at: " + new_path); + Directory.CreateDirectory(new_path); + return new_path; + } + catch (Exception e) + { + Logger.Error("Could not create new directory. You may perhaps need to disable Controlled Folder Access from Windows Settings or make an exception for UniGetUI."); + Logger.Error(e); + return new_path; + } + } + + public static JsonSerializerOptions SerializingOptions = new() + { + TypeInfoResolverChain = { new DefaultJsonTypeInfoResolver() }, + WriteIndented = true, + }; + + private static int GetCodePage() + { + try + { + Process p = new Process + { + StartInfo = new ProcessStartInfo + { + FileName = "chcp.com", + RedirectStandardOutput = true, + UseShellExecute = false, + CreateNoWindow = true, + } + }; + p.Start(); + string contents = p.StandardOutput.ReadToEnd(); + string purifiedString = ""; + + foreach (var c in contents.Split(':')[^1].Trim()) + { + if (c >= '0' && c <= '9') + { + purifiedString += c; + } + } + + return int.Parse(purifiedString); + } + catch (Exception e) + { + Logger.Error(e); + return 0; + } + } + + } +} From fbb2b91ff4ba3e73de87a046dd401341ffb9f948 Mon Sep 17 00:00:00 2001 From: Adrian Gaborek Date: Fri, 21 Feb 2025 18:56:20 +0100 Subject: [PATCH 2/6] add new property which points to user configuration directory and use load / save settings into it --- src/UniGetUI.Core.Data/CoreData.cs | 16 +++++++++++++++- src/UniGetUI.Core.Settings/SettingsEngine.cs | 16 ++++++++-------- .../SettingsEngine_Dictionaries.cs | 6 +++--- .../SettingsEngine_Lists.cs | 4 ++-- 4 files changed, 28 insertions(+), 14 deletions(-) diff --git a/src/UniGetUI.Core.Data/CoreData.cs b/src/UniGetUI.Core.Data/CoreData.cs index b015d6fd2a..2307f6265a 100644 --- a/src/UniGetUI.Core.Data/CoreData.cs +++ b/src/UniGetUI.Core.Data/CoreData.cs @@ -1,4 +1,4 @@ -using System.Diagnostics; +using System.Diagnostics; using System.Net; using System.Text.Json; using System.Text.Json.Serialization.Metadata; @@ -64,6 +64,20 @@ public static string UniGetUIDataDirectory } } + /// + /// The directory where the user configurations are stored. The directory is automatically created if it does not exist. + /// + public static string UniGetUIUserConfigurationDirectory + { + //TODO: add functionality to move old configurations to new location + get + { + string path = Path.Join(UniGetUIDataDirectory, "Configuration"); + if (!Directory.Exists(path)) Directory.CreateDirectory(path); + return path; + } + } + /// /// The directory where the installation options are stored. The directory is automatically created if it does not exist. /// diff --git a/src/UniGetUI.Core.Settings/SettingsEngine.cs b/src/UniGetUI.Core.Settings/SettingsEngine.cs index c443600b24..23bacb621f 100644 --- a/src/UniGetUI.Core.Settings/SettingsEngine.cs +++ b/src/UniGetUI.Core.Settings/SettingsEngine.cs @@ -17,7 +17,7 @@ public static bool Get(string setting, bool invert = false) } // Otherwise, load the value from disk and cache that setting - result = File.Exists(Path.Join(CoreData.UniGetUIDataDirectory, setting)); + result = File.Exists(Path.Join(CoreData.UniGetUIUserConfigurationDirectory, setting)); booleanSettings[setting] = result; return result ^ invert; } @@ -30,17 +30,17 @@ public static void Set(string setting, bool value) booleanSettings[setting] = value; // Update changes on disk if applicable - if (value && !File.Exists(Path.Join(CoreData.UniGetUIDataDirectory, setting))) + if (value && !File.Exists(Path.Join(CoreData.UniGetUIUserConfigurationDirectory, setting))) { - File.WriteAllText(Path.Join(CoreData.UniGetUIDataDirectory, setting), ""); + File.WriteAllText(Path.Join(CoreData.UniGetUIUserConfigurationDirectory, setting), ""); } else if (!value) { valueSettings[setting] = ""; - if (File.Exists(Path.Join(CoreData.UniGetUIDataDirectory, setting))) + if (File.Exists(Path.Join(CoreData.UniGetUIUserConfigurationDirectory, setting))) { - File.Delete(Path.Join(CoreData.UniGetUIDataDirectory, setting)); + File.Delete(Path.Join(CoreData.UniGetUIUserConfigurationDirectory, setting)); } } @@ -61,9 +61,9 @@ public static string GetValue(string setting) // Otherwise, load the setting from disk and cache that setting value = ""; - if (File.Exists(Path.Join(CoreData.UniGetUIDataDirectory, setting))) + if (File.Exists(Path.Join(CoreData.UniGetUIUserConfigurationDirectory, setting))) { - value = File.ReadAllText(Path.Join(CoreData.UniGetUIDataDirectory, setting)); + value = File.ReadAllText(Path.Join(CoreData.UniGetUIUserConfigurationDirectory, setting)); } valueSettings[setting] = value; @@ -83,7 +83,7 @@ public static void SetValue(string setting, string value) } else { - File.WriteAllText(Path.Join(CoreData.UniGetUIDataDirectory, setting), value); + File.WriteAllText(Path.Join(CoreData.UniGetUIUserConfigurationDirectory, setting), value); booleanSettings[setting] = true; valueSettings[setting] = value; } diff --git a/src/UniGetUI.Core.Settings/SettingsEngine_Dictionaries.cs b/src/UniGetUI.Core.Settings/SettingsEngine_Dictionaries.cs index 0be02e2ed0..a2ac0f978e 100644 --- a/src/UniGetUI.Core.Settings/SettingsEngine_Dictionaries.cs +++ b/src/UniGetUI.Core.Settings/SettingsEngine_Dictionaries.cs @@ -35,9 +35,9 @@ public static partial class Settings // Otherwise, load the setting from disk and cache that setting Dictionary value = []; - if (File.Exists(Path.Join(CoreData.UniGetUIDataDirectory, $"{setting}.json"))) + if (File.Exists(Path.Join(CoreData.UniGetUIUserConfigurationDirectory, $"{setting}.json"))) { - string result = File.ReadAllText(Path.Join(CoreData.UniGetUIDataDirectory, $"{setting}.json")); + string result = File.ReadAllText(Path.Join(CoreData.UniGetUIUserConfigurationDirectory, $"{setting}.json")); try { if (result != "") @@ -85,7 +85,7 @@ public static void SetDictionary(string setting, Dictionary value) kvp => (object?)kvp.Value ); - var file = Path.Join(CoreData.UniGetUIDataDirectory, $"{setting}.json"); + var file = Path.Join(CoreData.UniGetUIUserConfigurationDirectory, $"{setting}.json"); try { if (value.Count != 0) File.WriteAllText(file, JsonSerializer.Serialize(value)); diff --git a/src/UniGetUI.Core.Settings/SettingsEngine_Lists.cs b/src/UniGetUI.Core.Settings/SettingsEngine_Lists.cs index 97d134b2d0..4ecefbec10 100644 --- a/src/UniGetUI.Core.Settings/SettingsEngine_Lists.cs +++ b/src/UniGetUI.Core.Settings/SettingsEngine_Lists.cs @@ -31,7 +31,7 @@ public static partial class Settings // Otherwise, load the setting from disk and cache that setting List value = []; - var file = Path.Join(CoreData.UniGetUIDataDirectory, $"{setting}.json"); + var file = Path.Join(CoreData.UniGetUIUserConfigurationDirectory, $"{setting}.json"); if (File.Exists(file)) { string result = File.ReadAllText(file); @@ -73,7 +73,7 @@ public static partial class Settings public static void SetList(string setting, List value) { listSettings[setting] = value.Cast().ToList(); - var file = Path.Join(CoreData.UniGetUIDataDirectory, $"{setting}.json"); + var file = Path.Join(CoreData.UniGetUIUserConfigurationDirectory, $"{setting}.json"); try { if (value.Count != 0) File.WriteAllText(file, JsonSerializer.Serialize(value)); From f8fd352d09b81efb822492452fd442efc69d8cbc Mon Sep 17 00:00:00 2001 From: Adrian Gaborek Date: Fri, 21 Feb 2025 20:55:15 +0100 Subject: [PATCH 3/6] moves user configs to a new Configuration subdirectory in the data directory --- src/UniGetUI.Core.Data/CoreData.cs | 58 +++++++++++++++++++++++++++--- 1 file changed, 54 insertions(+), 4 deletions(-) diff --git a/src/UniGetUI.Core.Data/CoreData.cs b/src/UniGetUI.Core.Data/CoreData.cs index 2307f6265a..1a3215d5e4 100644 --- a/src/UniGetUI.Core.Data/CoreData.cs +++ b/src/UniGetUI.Core.Data/CoreData.cs @@ -69,12 +69,62 @@ public static string UniGetUIDataDirectory /// public static string UniGetUIUserConfigurationDirectory { - //TODO: add functionality to move old configurations to new location get { - string path = Path.Join(UniGetUIDataDirectory, "Configuration"); - if (!Directory.Exists(path)) Directory.CreateDirectory(path); - return path; + string oldConfigPath = UniGetUIDataDirectory; // Old config path was the data directory itself + string newConfigPath = Path.Join(dataDir, "Configuration"); + + if (Directory.Exists(oldConfigPath) && !Directory.Exists(newConfigPath)) + { + //Migration case + try + { + Logger.Info($"Moving configuration files from '{oldConfigPath}' to '{newConfigPath}'"); + Directory.CreateDirectory(newConfigPath); + + foreach (string file in Directory.GetFiles(oldConfigPath, "*.*", SearchOption.TopDirectoryOnly)) + { + string fileName = Path.GetFileName(file); + string fileExtension = Path.GetExtension(file); + bool isConfigFile = string.IsNullOrEmpty(fileExtension) || fileExtension.ToLowerInvariant() == ".json"; + + if (isConfigFile) + { + string newFile = Path.Join(newConfigPath, fileName); + // Avoid overwriting if somehow file already exists + if (!File.Exists(newFile)) + { + File.Move(file, newFile); + Logger.Debug($"Moved configuration file '{file}' to '{newFile}'"); + } + // Clean up old file to avoid duplicates and confusion + else + { + Logger.Warning($"Configuration file '{newFile}' already exists, skipping move from '{file}'."); + File.Delete(file); + } + } + else + { + Logger.Debug($"Skipping non-configuration file '{file}' during migration."); + } + } + Logger.Info($"Configuration files moved successfully to '{newConfigPath}'"); + } + catch (Exception ex) + { + // Fallback to old path if migration fails to not break functionality + Logger.Error($"Error moving configuration files from '{oldConfigPath}' to '{newConfigPath}'. Using old path for now. Manual migration might be needed."); + Logger.Error(ex); + return oldConfigPath; + } + } + else if (!Directory.Exists(newConfigPath)) + { + //New install case, migration not needed + Directory.CreateDirectory(newConfigPath); + } + return newConfigPath; } } From 78d66bcbade620990a8f561ceb81b4251d92728b Mon Sep 17 00:00:00 2001 From: Adrian Gaborek Date: Fri, 21 Feb 2025 21:01:51 +0100 Subject: [PATCH 4/6] update test files with path to new configuration directory --- src/UniGetUI.Core.Data/CoreData.cs | 6 ++-- .../SettingsTest.cs | 30 +++++++++---------- 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/src/UniGetUI.Core.Data/CoreData.cs b/src/UniGetUI.Core.Data/CoreData.cs index 1a3215d5e4..9a49f60926 100644 --- a/src/UniGetUI.Core.Data/CoreData.cs +++ b/src/UniGetUI.Core.Data/CoreData.cs @@ -1,4 +1,4 @@ -using System.Diagnostics; +using System.Diagnostics; using System.Net; using System.Text.Json; using System.Text.Json.Serialization.Metadata; @@ -72,7 +72,7 @@ public static string UniGetUIUserConfigurationDirectory get { string oldConfigPath = UniGetUIDataDirectory; // Old config path was the data directory itself - string newConfigPath = Path.Join(dataDir, "Configuration"); + string newConfigPath = Path.Join(UniGetUIDataDirectory, "Configuration"); if (Directory.Exists(oldConfigPath) && !Directory.Exists(newConfigPath)) { @@ -100,7 +100,7 @@ public static string UniGetUIUserConfigurationDirectory // Clean up old file to avoid duplicates and confusion else { - Logger.Warning($"Configuration file '{newFile}' already exists, skipping move from '{file}'."); + Logger.Warn($"Configuration file '{newFile}' already exists, skipping move from '{file}'."); File.Delete(file); } } diff --git a/src/UniGetUI.Core.Settings.Tests/SettingsTest.cs b/src/UniGetUI.Core.Settings.Tests/SettingsTest.cs index d99c67c9c3..a1abafe75f 100644 --- a/src/UniGetUI.Core.Settings.Tests/SettingsTest.cs +++ b/src/UniGetUI.Core.Settings.Tests/SettingsTest.cs @@ -31,23 +31,23 @@ public void TestBooleanSettings(string SettingName, bool st1, bool st2, bool st3 { Settings.Set(SettingName, st1); Assert.Equal(st1, Settings.Get(SettingName)); - Assert.Equal(st1, File.Exists(Path.Join(CoreData.UniGetUIDataDirectory, SettingName))); + Assert.Equal(st1, File.Exists(Path.Join(CoreData.UniGetUIUserConfigurationDirectory, SettingName))); Settings.Set(SettingName, st2); Assert.Equal(st2, Settings.Get(SettingName)); - Assert.Equal(st2, File.Exists(Path.Join(CoreData.UniGetUIDataDirectory, SettingName))); + Assert.Equal(st2, File.Exists(Path.Join(CoreData.UniGetUIUserConfigurationDirectory, SettingName))); Settings.Set(SettingName, st3); Assert.Equal(st3, Settings.Get(SettingName)); - Assert.Equal(st3, File.Exists(Path.Join(CoreData.UniGetUIDataDirectory, SettingName))); + Assert.Equal(st3, File.Exists(Path.Join(CoreData.UniGetUIUserConfigurationDirectory, SettingName))); Settings.Set(SettingName, st4); Assert.Equal(st4, Settings.Get(SettingName)); - Assert.Equal(st4, File.Exists(Path.Join(CoreData.UniGetUIDataDirectory, SettingName))); + Assert.Equal(st4, File.Exists(Path.Join(CoreData.UniGetUIUserConfigurationDirectory, SettingName))); Settings.Set(SettingName, false); // Cleanup Assert.False(Settings.Get(SettingName)); - Assert.False(File.Exists(Path.Join(CoreData.UniGetUIDataDirectory, SettingName))); + Assert.False(File.Exists(Path.Join(CoreData.UniGetUIUserConfigurationDirectory, SettingName))); } [Theory] @@ -60,24 +60,24 @@ public void TestValueSettings(string SettingName, string st1, string st2, string { Settings.SetValue(SettingName, st1); Assert.Equal(st1, Settings.GetValue(SettingName)); - Assert.Equal(st1 != "", File.Exists(Path.Join(CoreData.UniGetUIDataDirectory, SettingName))); + Assert.Equal(st1 != "", File.Exists(Path.Join(CoreData.UniGetUIUserConfigurationDirectory, SettingName))); Settings.SetValue(SettingName, st2); Assert.Equal(st2, Settings.GetValue(SettingName)); - Assert.Equal(st2 != "", File.Exists(Path.Join(CoreData.UniGetUIDataDirectory, SettingName))); + Assert.Equal(st2 != "", File.Exists(Path.Join(CoreData.UniGetUIUserConfigurationDirectory, SettingName))); Settings.SetValue(SettingName, st3); Assert.Equal(st3, Settings.GetValue(SettingName)); - Assert.Equal(st3 != "", File.Exists(Path.Join(CoreData.UniGetUIDataDirectory, SettingName))); + Assert.Equal(st3 != "", File.Exists(Path.Join(CoreData.UniGetUIUserConfigurationDirectory, SettingName))); Settings.SetValue(SettingName, st4); Assert.Equal(st4, Settings.GetValue(SettingName)); - Assert.Equal(st4 != "", File.Exists(Path.Join(CoreData.UniGetUIDataDirectory, SettingName))); + Assert.Equal(st4 != "", File.Exists(Path.Join(CoreData.UniGetUIUserConfigurationDirectory, SettingName))); Settings.Set(SettingName, false); // Cleanup Assert.False(Settings.Get(SettingName)); Assert.Equal("", Settings.GetValue(SettingName)); - Assert.False(File.Exists(Path.Join(CoreData.UniGetUIDataDirectory, SettingName))); + Assert.False(File.Exists(Path.Join(CoreData.UniGetUIUserConfigurationDirectory, SettingName))); } [Theory] @@ -114,7 +114,7 @@ public void TestListSettings(string SettingName, string[] ls1Array, int[] ls2Arr Assert.Equal("this is now a test case", Settings.GetListItem(SettingName, 3)); Assert.Null(Settings.GetListItem(SettingName, 4)); - Assert.Equal(Settings.GetListItem(SettingName, 0), JsonSerializer.Deserialize>(File.ReadAllText(Path.Join(CoreData.UniGetUIDataDirectory, $"{SettingName}.json")))[0]); + Assert.Equal(Settings.GetListItem(SettingName, 0), JsonSerializer.Deserialize>(File.ReadAllText(Path.Join(CoreData.UniGetUIUserConfigurationDirectory, $"{SettingName}.json")))[0]); Settings.ClearList(SettingName); Assert.Empty(Settings.GetList(SettingName) ?? ["this shouldn't be null; something's wrong"]); @@ -137,7 +137,7 @@ public void TestListSettings(string SettingName, string[] ls1Array, int[] ls2Arr Assert.Equal(ls3[1].sub.sub, Settings.GetListItem(SettingName, 0)?.sub.sub); Settings.ClearList(SettingName); // Cleanup Assert.Empty(Settings.GetList(SettingName) ?? ["this shouldn't be null; something's wrong"]); - Assert.False(File.Exists(Path.Join(CoreData.UniGetUIDataDirectory, $"{SettingName}.json"))); + Assert.False(File.Exists(Path.Join(CoreData.UniGetUIUserConfigurationDirectory, $"{SettingName}.json"))); } [Theory] @@ -168,7 +168,7 @@ public void TestDictionarySettings(string SettingName, string[] keyArray, int[] Settings.SetDictionaryItem(randStr, "key", 12); Assert.Equal(12, Settings.GetDictionaryItem(randStr, "key")); Settings.SetDictionary(SettingName, test); - Assert.Equal(JsonSerializer.Serialize(test), File.ReadAllLines(Path.Join(CoreData.UniGetUIDataDirectory, $"{SettingName}.json"))[0]); + Assert.Equal(JsonSerializer.Serialize(test), File.ReadAllLines(Path.Join(CoreData.UniGetUIUserConfigurationDirectory, $"{SettingName}.json"))[0]); Assert.Equal(test[keyArray[0]]?.sub.count, Settings.GetDictionary(SettingName)?[keyArray[0]]?.sub.count); Assert.Equal(test[keyArray[1]]?.sub.count, Settings.GetDictionaryItem(SettingName, keyArray[1])?.sub.count); Settings.SetDictionaryItem(SettingName, keyArray[0], test[keyArray[1]]); @@ -200,12 +200,12 @@ public void TestDictionarySettings(string SettingName, string[] keyArray, int[] Assert.Equal( JsonSerializer.Serialize(Settings.GetDictionary(SettingName)), - File.ReadAllLines(Path.Join(CoreData.UniGetUIDataDirectory, $"{SettingName}.json"))[0] + File.ReadAllLines(Path.Join(CoreData.UniGetUIUserConfigurationDirectory, $"{SettingName}.json"))[0] ); Settings.ClearDictionary(SettingName); // Cleanup Assert.Empty(Settings.GetDictionary(SettingName) ?? nonEmptyDictionary); - Assert.False(File.Exists(Path.Join(CoreData.UniGetUIDataDirectory, $"{SettingName}.json"))); + Assert.False(File.Exists(Path.Join(CoreData.UniGetUIUserConfigurationDirectory, $"{SettingName}.json"))); } } } From fa0b13d5f49f2bb5434658d466d55a49f120e0bc Mon Sep 17 00:00:00 2001 From: Adrian Gaborek Date: Sun, 23 Feb 2025 10:25:54 +0100 Subject: [PATCH 5/6] add tests to test settings migration and saving to new directory --- src/UniGetUI.Core.Data/CoreData.cs | 7 +++ .../SettingsTest.cs | 59 +++++++++++++++++++ 2 files changed, 66 insertions(+) diff --git a/src/UniGetUI.Core.Data/CoreData.cs b/src/UniGetUI.Core.Data/CoreData.cs index 9a49f60926..2bd78215cf 100644 --- a/src/UniGetUI.Core.Data/CoreData.cs +++ b/src/UniGetUI.Core.Data/CoreData.cs @@ -30,6 +30,8 @@ public static HttpClientHandler GenericHttpClientParameters private static bool? IS_PORTABLE; public static bool IsPortable { get => IS_PORTABLE ?? false; } + public static string? TEST_DataDirectoryOverride { private get; set; } + /// /// The directory where all the user data is stored. The directory is automatically created if it does not exist. /// @@ -37,6 +39,11 @@ public static string UniGetUIDataDirectory { get { + if (TEST_DataDirectoryOverride is not null) + { + return TEST_DataDirectoryOverride; + } + if (IS_PORTABLE is null) IS_PORTABLE = File.Exists(Path.Join(UniGetUIExecutableDirectory, "ForceUniGetUIPortable")); diff --git a/src/UniGetUI.Core.Settings.Tests/SettingsTest.cs b/src/UniGetUI.Core.Settings.Tests/SettingsTest.cs index a1abafe75f..02ea0514ab 100644 --- a/src/UniGetUI.Core.Settings.Tests/SettingsTest.cs +++ b/src/UniGetUI.Core.Settings.Tests/SettingsTest.cs @@ -20,6 +20,65 @@ public sealed class SerializableTest public class SettingsTest { + private readonly string _testRoot; + + private readonly string _oldConfigurationDirectory; + private readonly string _newConfigurationDirectory; + + public SettingsTest() + { + _testRoot = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString()); + Directory.CreateDirectory(_testRoot); + + // Configure the test environment. + CoreData.TEST_DataDirectoryOverride = Path.Combine(_testRoot, "Data"); + _oldConfigurationDirectory = CoreData.UniGetUIDataDirectory; + _newConfigurationDirectory = CoreData.UniGetUIUserConfigurationDirectory; + + // Ensure the new configuration directory is removed so that fresh installations are tested. + if (Directory.Exists(_newConfigurationDirectory)) + { + Directory.Delete(_newConfigurationDirectory, true); + } + } + + public void Dispose() + { + Directory.Delete(_testRoot, true); + } + + private string GetNewSettingPath(string fileName) => Path.Combine(_newConfigurationDirectory, fileName); + private string GetOldSettingsPath(string fileName) => Path.Combine(_oldConfigurationDirectory, fileName); + + + [Fact] + public void TestSettingsSaveToNewDirectory() + { + Settings.Set("FreshBoolSetting", true); + Settings.SetValue("FreshValue", "test"); + + Assert.True(File.Exists(GetNewSettingPath("FreshBoolSetting"))); + Assert.True(File.Exists(GetNewSettingPath("FreshValue"))); + } + + [Fact] + public void TestExistingSettingsMigrateToNewDirectory() + { + string settingName = "LegacyBoolSetting"; + var oldPath = GetOldSettingsPath(settingName); + File.WriteAllText(oldPath, ""); + + var migratedValue = Settings.Get(settingName); + var newPath = GetNewSettingPath(settingName); + var valueAfterMigration = Settings.Get(settingName); + + Assert.True(migratedValue); + Assert.True(valueAfterMigration); + + Assert.True(File.Exists(newPath)); + Assert.False(File.Exists(oldPath)); + } + [Theory] [InlineData("TestSetting1", true, false, false, true)] [InlineData("TestSetting2", true, false, false, false)] From 40aa90d38648eb398e1aa3ae7e478e53ca12887c Mon Sep 17 00:00:00 2001 From: Adrian Gaborek Date: Sun, 23 Feb 2025 11:07:53 +0100 Subject: [PATCH 6/6] fix core data whitespaces --- src/UniGetUI.Core.Data/CoreData.cs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/UniGetUI.Core.Data/CoreData.cs b/src/UniGetUI.Core.Data/CoreData.cs index 2bd78215cf..c8eefca7d0 100644 --- a/src/UniGetUI.Core.Data/CoreData.cs +++ b/src/UniGetUI.Core.Data/CoreData.cs @@ -30,7 +30,7 @@ public static HttpClientHandler GenericHttpClientParameters private static bool? IS_PORTABLE; public static bool IsPortable { get => IS_PORTABLE ?? false; } - public static string? TEST_DataDirectoryOverride { private get; set; } + public static string? TEST_DataDirectoryOverride { private get; set; } /// /// The directory where all the user data is stored. The directory is automatically created if it does not exist. @@ -39,10 +39,10 @@ public static string UniGetUIDataDirectory { get { - if (TEST_DataDirectoryOverride is not null) - { - return TEST_DataDirectoryOverride; - } + if (TEST_DataDirectoryOverride is not null) + { + return TEST_DataDirectoryOverride; + } if (IS_PORTABLE is null) IS_PORTABLE = File.Exists(Path.Join(UniGetUIExecutableDirectory, "ForceUniGetUIPortable")); @@ -79,7 +79,7 @@ public static string UniGetUIUserConfigurationDirectory get { string oldConfigPath = UniGetUIDataDirectory; // Old config path was the data directory itself - string newConfigPath = Path.Join(UniGetUIDataDirectory, "Configuration"); + string newConfigPath = Path.Join(UniGetUIDataDirectory, "Configuration"); if (Directory.Exists(oldConfigPath) && !Directory.Exists(newConfigPath)) { @@ -107,7 +107,7 @@ public static string UniGetUIUserConfigurationDirectory // Clean up old file to avoid duplicates and confusion else { - Logger.Warn($"Configuration file '{newFile}' already exists, skipping move from '{file}'."); + Logger.Warn($"Configuration file '{newFile}' already exists, skipping move from '{file}'."); File.Delete(file); } }