Added UNSAFE_MigrationHelper to help with upgrades

This commit is contained in:
Robert McRackan 2021-07-16 23:06:59 -04:00
parent f94f66da94
commit 71617b9620
8 changed files with 467 additions and 313 deletions

View File

@ -32,9 +32,6 @@ namespace FileManager
public static string DecryptInProgress => Directory.CreateDirectory(Path.Combine(Configuration.Instance.DecryptInProgressEnum, "DecryptInProgress")).FullName; public static string DecryptInProgress => Directory.CreateDirectory(Path.Combine(Configuration.Instance.DecryptInProgressEnum, "DecryptInProgress")).FullName;
// not customizable. don't move to config
public static string DownloadsFinal => new DirectoryInfo(Configuration.Instance.LibationFiles).CreateSubdirectory("DownloadsFinal").FullName;
public static string BooksDirectory public static string BooksDirectory
{ {
get get

View File

@ -56,7 +56,7 @@ namespace FileManager
public const string USER_PROFILE_LABEL = "UserProfile"; public const string USER_PROFILE_LABEL = "UserProfile";
public static string AppDir_Relative => @".\LibationFiles"; public static string AppDir_Relative => @".\LibationFiles";
public static string AppDir_Absolute => Path.GetFullPath(Path.Combine(Path.GetDirectoryName(Exe.FileLocationOnDisk), LIBATION_FILES)); public static string AppDir_Absolute => Path.GetFullPath(Path.Combine(Path.GetDirectoryName(Exe.FileLocationOnDisk), LIBATION_FILES_KEY));
public static string MyDocs => Path.GetFullPath(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), "LibationFiles")); public static string MyDocs => Path.GetFullPath(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), "LibationFiles"));
public static string WinTemp => Path.GetFullPath(Path.Combine(Path.GetTempPath(), "Libation")); public static string WinTemp => Path.GetFullPath(Path.Combine(Path.GetTempPath(), "Libation"));
public static string UserProfile => Path.GetFullPath(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), "Libation")); public static string UserProfile => Path.GetFullPath(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), "Libation"));
@ -112,6 +112,13 @@ namespace FileManager
// exceptions: appsettings.json, LibationFiles dir, Settings.json // exceptions: appsettings.json, LibationFiles dir, Settings.json
// temp/working dir(s) should be outside of dropbox // temp/working dir(s) should be outside of dropbox
[Description("Temporary location of files while they're in process of being downloaded and decrypted.\r\nWhen decryption is complete, the final file will be in Books location\r\nRecommend not using a folder which is backed up real time. Eg: Dropbox, iCloud, Google Drive")]
public string InProgress
{
get => persistentDictionary.GetString(nameof(InProgress));
set => persistentDictionary.Set(nameof(InProgress), value);
}
[Description("Temporary location of files while they're in process of being downloaded.\r\nWhen download is complete, the final file will be in [LibationFiles]\\DownloadsFinal")] [Description("Temporary location of files while they're in process of being downloaded.\r\nWhen download is complete, the final file will be in [LibationFiles]\\DownloadsFinal")]
public string DownloadsInProgressEnum public string DownloadsInProgressEnum
{ {
@ -140,8 +147,8 @@ namespace FileManager
private Configuration() { } private Configuration() { }
private const string APPSETTINGS_JSON = "appsettings.json"; private const string APPSETTINGS_JSON = "appsettings.json";
// this is the key in appsettings. Happens to match the metadirectory name but separate concern. keep separate // this is the key in appsettings. The string happens to match the metadirectory name but separate concern. keep separate
private const string LIBATION_FILES = "LibationFiles"; private const string LIBATION_FILES_KEY = "LibationFiles";
[Description("Location for storage of program-created files")] [Description("Location for storage of program-created files")]
public string LibationFiles public string LibationFiles
@ -173,11 +180,9 @@ namespace FileManager
startingContents = File.ReadAllText(APPSETTINGS_JSON); startingContents = File.ReadAllText(APPSETTINGS_JSON);
var startingJObj = JObject.Parse(startingContents); var startingJObj = JObject.Parse(startingContents);
if (startingJObj.ContainsKey(LIBATION_FILES)) if (startingJObj.ContainsKey(LIBATION_FILES_KEY))
{ {
var startingValue = startingJObj[LIBATION_FILES].Value<string>(); var startingValue = startingJObj[LIBATION_FILES_KEY].Value<string>();
// do not check whether directory exists. special/meta directory (eg: AppDir) is valid
if (!string.IsNullOrWhiteSpace(startingValue)) if (!string.IsNullOrWhiteSpace(startingValue))
return startingValue; return startingValue;
} }
@ -186,7 +191,7 @@ namespace FileManager
catch { } catch { }
// not found. write to file. read from file // not found. write to file. read from file
var endingContents = new JObject { { LIBATION_FILES, UserProfile } }.ToString(Formatting.Indented); var endingContents = new JObject { { LIBATION_FILES_KEY, UserProfile } }.ToString(Formatting.Indented);
if (startingContents != endingContents) if (startingContents != endingContents)
{ {
File.WriteAllText(APPSETTINGS_JSON, endingContents); File.WriteAllText(APPSETTINGS_JSON, endingContents);
@ -196,7 +201,7 @@ namespace FileManager
// do not check whether directory exists. special/meta directory (eg: AppDir) is valid // do not check whether directory exists. special/meta directory (eg: AppDir) is valid
// verify from live file. no try/catch. want failures to be visible // verify from live file. no try/catch. want failures to be visible
var jObjFinal = JObject.Parse(File.ReadAllText(APPSETTINGS_JSON)); var jObjFinal = JObject.Parse(File.ReadAllText(APPSETTINGS_JSON));
var valueFinal = jObjFinal[LIBATION_FILES].Value<string>(); var valueFinal = jObjFinal[LIBATION_FILES_KEY].Value<string>();
return valueFinal; return valueFinal;
} }
@ -235,7 +240,7 @@ namespace FileManager
var startingContents = File.ReadAllText(APPSETTINGS_JSON); var startingContents = File.ReadAllText(APPSETTINGS_JSON);
var jObj = JObject.Parse(startingContents); var jObj = JObject.Parse(startingContents);
jObj[LIBATION_FILES] = directory; jObj[LIBATION_FILES_KEY] = directory;
var endingContents = JsonConvert.SerializeObject(jObj, Formatting.Indented); var endingContents = JsonConvert.SerializeObject(jObj, Formatting.Indented);
if (startingContents != endingContents) if (startingContents != endingContents)

View File

@ -26,13 +26,15 @@ namespace LibationLauncher
Application.EnableVisualStyles(); Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false); Application.SetCompatibleTextRenderingDefault(false);
// must occur before access to Configuration instance
migrate_to_v5_2_0();
createSettings(); createSettings();
AudibleApiStorage.EnsureAccountsSettingsFileExists(); AudibleApiStorage.EnsureAccountsSettingsFileExists();
migrate_to_v4_0_0(); migrate_to_v4_0_0();
migrate_to_v5_0_0(); migrate_to_v5_0_0();
migrate_to_v5_2_0();
ensureSerilogConfig(); ensureSerilogConfig();
configureLogging(); configureLogging();
@ -259,46 +261,32 @@ namespace LibationLauncher
} }
#endregion #endregion
#region migrate to v5.2.0 : get rid of meta-directories #region migrate to v5.2.0 : get rid of meta-directories, combine DownloadsInProgressEnum and DecryptInProgressEnum => InProgress
private static void migrate_to_v5_2_0() private static void migrate_to_v5_2_0()
{ {
var config = Configuration.Instance;
{ {
var newPath = TranslatePath(config.DecryptInProgressEnum); var settingsKey = "DownloadsInProgressEnum";
if (newPath != config.DecryptInProgressEnum) UNSAFE_MigrationHelper.Settings_Update(settingsKey, translatePath(UNSAFE_MigrationHelper.Settings_Get(settingsKey)));
config.DecryptInProgressEnum = newPath;
} }
{ {
var newPath = TranslatePath(config.DownloadsInProgressEnum); var settingsKey = "DecryptInProgressEnum";
if (newPath != config.DownloadsInProgressEnum) UNSAFE_MigrationHelper.Settings_Update(settingsKey, translatePath(UNSAFE_MigrationHelper.Settings_Get(settingsKey)));
config.DownloadsInProgressEnum = newPath;
} }
{ UNSAFE_MigrationHelper.AppSettings_Update(
var appsettings = "appsettings.json"; UNSAFE_MigrationHelper.LIBATION_FILES_KEY,
var libationFiles = "LibationFiles"; translatePath(UNSAFE_MigrationHelper.AppSettings_Get(UNSAFE_MigrationHelper.LIBATION_FILES_KEY))
);
var jObj = JObject.Parse(File.ReadAllText(appsettings));
var origVlaue = jObj[libationFiles].Value<string>();
var newValue = TranslatePath(origVlaue);
if (newValue != origVlaue)
{
var contents = new JObject { { libationFiles, newValue } }.ToString(Formatting.Indented);
File.WriteAllText(appsettings, contents);
}
}
} }
private static string TranslatePath(string path) private static string translatePath(string path)
=> path switch => path switch
{ {
"AppDir" => Configuration.AppDir_Relative, "AppDir" => @".\LibationFiles",
"MyDocs" => Configuration.MyDocs, "MyDocs" => Path.GetFullPath(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), "LibationFiles")),
Configuration.USER_PROFILE_LABEL => Configuration.UserProfile, "UserProfile" => Path.GetFullPath(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), "Libation")),
Configuration.WIN_TEMP_LABEL => Configuration.WinTemp, "WinTemp" => Path.GetFullPath(Path.Combine(Path.GetTempPath(), "Libation")),
_ => path _ => path
}; };
#endregion #endregion
@ -475,9 +463,6 @@ namespace LibationLauncher
DownloadsInProgressDir = AudibleFileStorage.DownloadsInProgress, DownloadsInProgressDir = AudibleFileStorage.DownloadsInProgress,
DownloadsInProgressFiles = Directory.EnumerateFiles(AudibleFileStorage.DownloadsInProgress).Count(), DownloadsInProgressFiles = Directory.EnumerateFiles(AudibleFileStorage.DownloadsInProgress).Count(),
AudibleFileStorage.DownloadsFinal,
DownloadsFinalFiles = Directory.EnumerateFiles(AudibleFileStorage.DownloadsFinal).Count(),
config.DecryptInProgressEnum, config.DecryptInProgressEnum,
DecryptInProgressDir = AudibleFileStorage.DecryptInProgress, DecryptInProgressDir = AudibleFileStorage.DecryptInProgress,
DecryptInProgressFiles = Directory.EnumerateFiles(AudibleFileStorage.DecryptInProgress).Count(), DecryptInProgressFiles = Directory.EnumerateFiles(AudibleFileStorage.DecryptInProgress).Count(),

View File

@ -0,0 +1,145 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Dinah.Core;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
namespace LibationLauncher
{
/// <summary>for migrations only. directly manipulatings settings files without going through domain logic</summary>
internal static class UNSAFE_MigrationHelper
{
#region appsettings.json
public const string APPSETTINGS_JSON = "appsettings.json";
public static bool AppSettingsJson_Exists => File.Exists(APPSETTINGS_JSON);
public static string AppSettings_Get(string key)
{
bool success = false;
JToken val = null;
process_AppSettingsJson(jObj => success = jObj.TryGetValue(key, out val), false);
if (success)
return val.Value<string>();
return null;
}
/// <summary>only insert if not exists</summary>
public static void AppSettings_Insert(string key, string value)
=> process_AppSettingsJson(jObj => jObj.TryAdd(key, value));
/// <summary>only update if exists</summary>
public static void AppSettings_Update(string key, string value)
=> process_AppSettingsJson(jObj => {
if (jObj.ContainsKey(key))
jObj[key] = value;
});
/// <summary>only delete if exists</summary>
public static void AppSettings_Delete(string key)
=> process_AppSettingsJson(jObj => {
if (jObj.ContainsKey(key))
jObj.Remove(key);
});
/// <param name="save">True: save if contents changed. False: no not attempt save</param>
private static void process_AppSettingsJson(Action<JObject> action, bool save = true)
{
// only insert if not exists
if (!AppSettingsJson_Exists)
return;
var startingContents = File.ReadAllText(APPSETTINGS_JSON);
var jObj = JObject.Parse(startingContents);
action(jObj);
if (!save)
return;
// only save if different
var endingContents_indented = jObj.ToString(Formatting.Indented);
var endingContents_compact = jObj.ToString(Formatting.None);
if (startingContents.EqualsInsensitive(endingContents_indented) || startingContents.EqualsInsensitive(endingContents_compact))
return;
File.WriteAllText(APPSETTINGS_JSON, endingContents_indented);
System.Threading.Thread.Sleep(100);
}
#endregion
#region Settings.json
public const string LIBATION_FILES_KEY = "LibationFiles";
public const string SETTINGS_JSON = "Settings.json";
public static string SettingsJsonPath
{
get
{
var value = AppSettings_Get(LIBATION_FILES_KEY);
return value is null ? null : Path.Combine(value, SETTINGS_JSON);
}
}
public static bool SettingsJson_Exists => SettingsJsonPath is not null && File.Exists(SettingsJsonPath);
public static string Settings_Get(string key)
{
bool success = false;
JToken val = null;
process_SettingsJson(jObj => success = jObj.TryGetValue(key, out val), false);
if (success)
return val.Value<string>();
return null;
}
/// <summary>only insert if not exists</summary>
public static void Settings_Insert(string key, string value)
=> process_SettingsJson(jObj => jObj.TryAdd(key, value));
/// <summary>only update if exists</summary>
public static void Settings_Update(string key, string value)
=> process_SettingsJson(jObj => {
if (jObj.ContainsKey(key))
jObj[key] = value;
});
/// <summary>only delete if exists</summary>
public static void Settings_Delete(string key)
=> process_SettingsJson(jObj => {
if (jObj.ContainsKey(key))
jObj.Remove(key);
});
/// <param name="save">True: save if contents changed. False: no not attempt save</param>
private static void process_SettingsJson(Action<JObject> action, bool save = true)
{
// only insert if not exists
if (!SettingsJson_Exists)
return;
var startingContents = File.ReadAllText(SettingsJsonPath);
var jObj = JObject.Parse(startingContents);
action(jObj);
if (!save)
return;
// only save if different
var endingContents_indented = jObj.ToString(Formatting.Indented);
var endingContents_compact = jObj.ToString(Formatting.None);
if (startingContents.EqualsInsensitive(endingContents_indented) || startingContents.EqualsInsensitive(endingContents_compact))
return;
File.WriteAllText(SettingsJsonPath, endingContents_indented);
System.Threading.Thread.Sleep(100);
}
#endregion
}
}

View File

@ -227,11 +227,11 @@
this.groupBox1.TabStop = false; this.groupBox1.TabStop = false;
this.groupBox1.Text = "Advanced settings for control freaks"; this.groupBox1.Text = "Advanced settings for control freaks";
// //
// downloadChaptersCbox // allowLibationFixupCbox
// //
this.allowLibationFixupCbox.AutoSize = true; this.allowLibationFixupCbox.AutoSize = true;
this.allowLibationFixupCbox.Location = new System.Drawing.Point(10, 24); this.allowLibationFixupCbox.Location = new System.Drawing.Point(10, 24);
this.allowLibationFixupCbox.Name = "downloadChaptersCbox"; this.allowLibationFixupCbox.Name = "allowLibationFixupCbox";
this.allowLibationFixupCbox.Size = new System.Drawing.Size(262, 19); this.allowLibationFixupCbox.Size = new System.Drawing.Size(262, 19);
this.allowLibationFixupCbox.TabIndex = 6; this.allowLibationFixupCbox.TabIndex = 6;
this.allowLibationFixupCbox.Text = "Allow Libation to fix up audiobook metadata"; this.allowLibationFixupCbox.Text = "Allow Libation to fix up audiobook metadata";

View File

@ -3,7 +3,6 @@ using System.IO;
using System.Windows.Forms; using System.Windows.Forms;
using Dinah.Core; using Dinah.Core;
using FileManager; using FileManager;
using InternalUtilities;
namespace LibationWinForms.Dialogs namespace LibationWinForms.Dialogs
{ {
@ -12,10 +11,7 @@ namespace LibationWinForms.Dialogs
Configuration config { get; } = Configuration.Instance; Configuration config { get; } = Configuration.Instance;
Func<string, string> desc { get; } = Configuration.GetDescription; Func<string, string> desc { get; } = Configuration.GetDescription;
public SettingsDialog() public SettingsDialog() => InitializeComponent();
{
InitializeComponent();
}
private void SettingsDialog_Load(object sender, EventArgs e) private void SettingsDialog_Load(object sender, EventArgs e)
{ {

View File

@ -81,6 +81,15 @@
<metadata name="downloadsInProgressDescLbl.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"> <metadata name="downloadsInProgressDescLbl.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value> <value>True</value>
</metadata> </metadata>
<metadata name="downloadsInProgressLibationFilesRb.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="downloadsInProgressWinTempRb.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="downloadsInProgressDescLbl.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="decryptInProgressGb.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"> <metadata name="decryptInProgressGb.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value> <value>True</value>
</metadata> </metadata>
@ -93,6 +102,15 @@
<metadata name="decryptInProgressDescLbl.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"> <metadata name="decryptInProgressDescLbl.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value> <value>True</value>
</metadata> </metadata>
<metadata name="decryptInProgressLibationFilesRb.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="decryptInProgressWinTempRb.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="decryptInProgressDescLbl.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="saveBtn.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"> <metadata name="saveBtn.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value> <value>True</value>
</metadata> </metadata>
@ -102,10 +120,4 @@
<metadata name="groupBox1.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"> <metadata name="groupBox1.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value> <value>True</value>
</metadata> </metadata>
<metadata name="downloadChaptersCbox.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="$this.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
</root> </root>

View File

@ -23,6 +23,8 @@ namespace LibationWinForms.Dialogs
if (this.DesignMode) if (this.DesignMode)
return; return;
{ {
var dirCtrl = this.directorySelectControl1; var dirCtrl = this.directorySelectControl1;
dirCtrl.SetDirectoryItems(new() dirCtrl.SetDirectoryItems(new()
@ -40,36 +42,48 @@ namespace LibationWinForms.Dialogs
); );
} }
//{
// var dirOrCustCtrl = this.directoryOrCustomSelectControl1;
// dirOrCustCtrl.SetSearchTitle("Libation Files"); {
// dirOrCustCtrl.SetDirectoryItems(new() var dirOrCustCtrl = this.directoryOrCustomSelectControl1;
// { dirOrCustCtrl.SetSearchTitle("Libation Files");
// FileManager.Configuration.KnownDirectories.AppDir, dirOrCustCtrl.SetDirectoryItems(new()
// FileManager.Configuration.KnownDirectories.MyDocs, {
// FileManager.Configuration.KnownDirectories.LibationFiles, FileManager.Configuration.KnownDirectories.AppDir,
// FileManager.Configuration.KnownDirectories.MyDocs, FileManager.Configuration.KnownDirectories.MyDocs,
// FileManager.Configuration.KnownDirectories.None, FileManager.Configuration.KnownDirectories.LibationFiles,
// FileManager.Configuration.KnownDirectories.WinTemp, FileManager.Configuration.KnownDirectories.MyDocs,
// FileManager.Configuration.KnownDirectories.UserProfile FileManager.Configuration.KnownDirectories.None,
// } FileManager.Configuration.KnownDirectories.WinTemp,
// , FileManager.Configuration.KnownDirectories.UserProfile
// FileManager.Configuration.KnownDirectories.MyDocs }
// ); ,
//} FileManager.Configuration.KnownDirectories.MyDocs
);
}
} }
private void button1_Click(object sender, EventArgs e) private void button1_Click(object sender, EventArgs e)
{ {
var dirCtrl = this.directorySelectControl1; var dirCtrl = this.directorySelectControl1;
var x = dirCtrl.SelectedDirectory; var x = dirCtrl.SelectedDirectory;
dirCtrl.SelectDirectory(FileManager.Configuration.KnownDirectories.UserProfile); dirCtrl.SelectDirectory(FileManager.Configuration.KnownDirectories.UserProfile);
//var dirOrCustCtrl = this.directoryOrCustomSelectControl1;
//var y = dirOrCustCtrl.SelectedDirectory;
//dirOrCustCtrl.SelectDirectory(FileManager.Configuration.KnownDirectories.UserProfile);
var dirOrCustCtrl = this.directoryOrCustomSelectControl1;
var y = dirOrCustCtrl.SelectedDirectory;
dirOrCustCtrl.SelectDirectory(FileManager.Configuration.KnownDirectories.UserProfile);
} }
} }
} }