mirror of
https://github.com/rmcrackan/Libation.git
synced 2025-12-23 22:17:52 -05:00
- Add `LIBATION_FILES_DIR` environment variable to specify LibationFiles directory instead of appsettings.json - OptionsBase supports overriding setting - Added `EphemeralSettings` which are loaded from Settings.json once and can be modified with the `--override` command parameter - Added `get-setting` command - Prints (editable) settings and their values. Prints specified settings, or all settings if none specified - `--listEnumValues` option will list all names for a speficied enum-type settings. If no setting names are specified, prints all enum values for all enum settings. - Prints in a text-based table or bare with `-b` switch - Added `get-license` command which requests a content license and prints it as a json to stdout - Improved `liberate` command - Added `-force` option to force liberation without validation. - Added support to download with a license file supplied to stdin - Improve startup performance when downloading explicit ASIN(s) - Fix long-standing bug where cover art was not being downloading
267 lines
7.1 KiB
C#
267 lines
7.1 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using Dinah.Core;
|
|
using LibationFileManager;
|
|
using Newtonsoft.Json;
|
|
using Newtonsoft.Json.Linq;
|
|
|
|
#nullable enable
|
|
namespace AppScaffolding
|
|
{
|
|
/// <summary>
|
|
///
|
|
///
|
|
/// directly manipulates settings files without going through domain logic.
|
|
///
|
|
/// for migrations only. use with caution.
|
|
///
|
|
///
|
|
/// </summary>
|
|
public static class UNSAFE_MigrationHelper
|
|
{
|
|
public static string? SettingsDirectory
|
|
=> !APPSETTINGS_TryGet(LibationFiles.LIBATION_FILES_KEY, out var value) || value is null
|
|
? null
|
|
: value;
|
|
|
|
#region appsettings.json
|
|
|
|
public static bool APPSETTINGS_TryGet(string key, out string? value)
|
|
{
|
|
bool success = false;
|
|
JToken? val = null;
|
|
|
|
process_APPSETTINGS_Json(jObj => success = jObj.TryGetValue(key, out val), false);
|
|
|
|
value = success ? val?.Value<string>() : null;
|
|
return success;
|
|
}
|
|
|
|
/// <summary>only insert if not exists</summary>
|
|
public static void APPSETTINGS_Insert(string key, string value)
|
|
=> process_APPSETTINGS_Json(jObj => jObj.TryAdd(key, value));
|
|
|
|
/// <summary>only update if exists</summary>
|
|
public static void APPSETTINGS_Update(string key, string value)
|
|
=> process_APPSETTINGS_Json(jObj => {
|
|
if (jObj.ContainsKey(key))
|
|
jObj[key] = value;
|
|
});
|
|
|
|
/// <summary>only delete if exists</summary>
|
|
public static void APPSETTINGS_Delete(string key)
|
|
=> process_APPSETTINGS_Json(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_APPSETTINGS_Json(Action<JObject> action, bool save = true)
|
|
{
|
|
if (Configuration.Instance.LibationFiles.AppsettingsJsonFile is not string appSettingsFile)
|
|
return;
|
|
|
|
var startingContents = File.ReadAllText(appSettingsFile);
|
|
|
|
JObject jObj;
|
|
try
|
|
{
|
|
jObj = JObject.Parse(startingContents);
|
|
}
|
|
catch
|
|
{
|
|
return;
|
|
}
|
|
|
|
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(Configuration.Instance.LibationFiles.AppsettingsJsonFile, endingContents_indented);
|
|
System.Threading.Thread.Sleep(100);
|
|
}
|
|
#endregion
|
|
#region Settings.json
|
|
|
|
public static string? SettingsJsonPath => SettingsDirectory is null ? null : Path.Combine(SettingsDirectory, LibationFiles.SETTINGS_JSON);
|
|
|
|
public static bool Settings_TryGet(string key, out string? value)
|
|
{
|
|
bool success = false;
|
|
JToken? val = null;
|
|
|
|
process_SettingsJson(jObj => success = jObj.TryGetValue(key, out val), false);
|
|
|
|
value = success ? val?.Value<string>() : null;
|
|
return success;
|
|
}
|
|
|
|
public static bool Settings_JsonPathIsType(string jsonPath, JTokenType jTokenType)
|
|
{
|
|
JToken? val = null;
|
|
|
|
process_SettingsJson(jObj => val = jObj.SelectToken(jsonPath), false);
|
|
|
|
return val?.Type == jTokenType;
|
|
}
|
|
|
|
public static bool Settings_TryGetFromJsonPath(string jsonPath, out string? value)
|
|
{
|
|
JToken? val = null;
|
|
|
|
process_SettingsJson(jObj => val = jObj.SelectToken(jsonPath), false);
|
|
|
|
if (val?.Type == JTokenType.String)
|
|
{
|
|
value = val.Value<string>();
|
|
return true;
|
|
}
|
|
else
|
|
{
|
|
value = null;
|
|
return false;
|
|
}
|
|
}
|
|
|
|
public static void Settings_SetWithJsonPath(string jsonPath, string propertyName, string newValue)
|
|
{
|
|
if (!Settings_TryGetFromJsonPath($"{jsonPath}.{propertyName}", out _))
|
|
return;
|
|
|
|
process_SettingsJson(jObj =>
|
|
{
|
|
var token = jObj.SelectToken(jsonPath);
|
|
if (token is null
|
|
|| token is not JObject o
|
|
|| o[propertyName] is null)
|
|
return;
|
|
|
|
var oldValue = token.Value<string>(propertyName);
|
|
if (oldValue != newValue)
|
|
token[propertyName] = newValue;
|
|
});
|
|
}
|
|
|
|
public static bool Settings_TryGetArrayLength(string jsonPath, out int length)
|
|
{
|
|
length = 0;
|
|
|
|
if (!Settings_JsonPathIsType(jsonPath, JTokenType.Array))
|
|
return false;
|
|
|
|
JArray? array = null;
|
|
process_SettingsJson(jObj => array = jObj.SelectToken(jsonPath) as JArray);
|
|
|
|
length = array?.Count ?? 0;
|
|
return true;
|
|
}
|
|
|
|
public static void Settings_AddToArray(string jsonPath, string newValue)
|
|
{
|
|
if (!Settings_JsonPathIsType(jsonPath, JTokenType.Array))
|
|
return;
|
|
|
|
process_SettingsJson(jObj =>
|
|
{
|
|
(jObj.SelectToken(jsonPath) as JArray)?.Add(newValue);
|
|
});
|
|
}
|
|
|
|
/// <summary>Do not add if already exists</summary>
|
|
public static void Settings_AddUniqueToArray(string arrayPath, string newValue)
|
|
{
|
|
if (!Settings_TryGetArrayLength(arrayPath, out var qty))
|
|
return;
|
|
|
|
for (var i = 0; i < qty; i++)
|
|
{
|
|
var exists = Settings_TryGetFromJsonPath($"{arrayPath}[{i}]", out var value);
|
|
if (exists && value == newValue)
|
|
return;
|
|
}
|
|
|
|
Settings_AddToArray(arrayPath, newValue);
|
|
}
|
|
|
|
/// <summary>only remove if not exists</summary>
|
|
public static void Settings_RemoveFromArray(string jsonPath, int position)
|
|
{
|
|
if (!Settings_JsonPathIsType(jsonPath, JTokenType.Array))
|
|
return;
|
|
|
|
process_SettingsJson(jObj =>
|
|
{
|
|
if (jObj.SelectToken(jsonPath) is JArray array && position < array.Count)
|
|
array.RemoveAt(position);
|
|
});
|
|
}
|
|
|
|
/// <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 (!File.Exists(SettingsJsonPath))
|
|
return;
|
|
|
|
var startingContents = File.ReadAllText(SettingsJsonPath);
|
|
|
|
JObject jObj;
|
|
try
|
|
{
|
|
jObj = JObject.Parse(startingContents);
|
|
}
|
|
catch
|
|
{
|
|
return;
|
|
}
|
|
|
|
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
|
|
#region LibationContext.db
|
|
public const string LIBATION_CONTEXT = "LibationContext.db";
|
|
public static string? DatabaseFile => SettingsDirectory is null ? null : Path.Combine(SettingsDirectory, LIBATION_CONTEXT);
|
|
public static bool DatabaseFile_Exists => DatabaseFile is not null && File.Exists(DatabaseFile);
|
|
#endregion
|
|
}
|
|
}
|