diff --git a/ApplicationServices/UNTESTED/LibraryCommands.cs b/ApplicationServices/UNTESTED/LibraryCommands.cs index b920bea9..186fd6c1 100644 --- a/ApplicationServices/UNTESTED/LibraryCommands.cs +++ b/ApplicationServices/UNTESTED/LibraryCommands.cs @@ -16,16 +16,16 @@ namespace ApplicationServices var audibleApiActions = new AudibleApiActions(); var items = await audibleApiActions.GetAllLibraryItemsAsync(callback); var totalCount = items.Count; - Serilog.Log.Logger.Debug($"GetAllLibraryItems: Total count {totalCount}"); + Serilog.Log.Logger.Information($"GetAllLibraryItems: Total count {totalCount}"); using var context = DbContexts.GetContext(); var libImporter = new LibraryImporter(context); var newCount = await Task.Run(() => libImporter.Import(items)); context.SaveChanges(); - Serilog.Log.Logger.Debug($"Import: New count {newCount}"); + Serilog.Log.Logger.Information($"Import: New count {newCount}"); await Task.Run(() => SearchEngineCommands.FullReIndex()); - Serilog.Log.Logger.Debug("FullReIndex: success"); + Serilog.Log.Logger.Information("FullReIndex: success"); return (totalCount, newCount); } diff --git a/FileManager/UNTESTED/Configuration.cs b/FileManager/UNTESTED/Configuration.cs index 9a51ed8e..80cbed5e 100644 --- a/FileManager/UNTESTED/Configuration.cs +++ b/FileManager/UNTESTED/Configuration.cs @@ -35,14 +35,13 @@ namespace FileManager private PersistentDictionary persistentDictionary; - public bool IsComplete + public bool FilesExist => File.Exists(APPSETTINGS_JSON) - && Directory.Exists(LibationFiles) - && Directory.Exists(Books) && File.Exists(SettingsJsonPath) - && !string.IsNullOrWhiteSpace(LocaleCountryCode) - && !string.IsNullOrWhiteSpace(DownloadsInProgressEnum) - && !string.IsNullOrWhiteSpace(DecryptInProgressEnum); + && Directory.Exists(LibationFiles) + && Directory.Exists(Books); + + public string SettingsJsonPath => Path.Combine(LibationFiles, "Settings.json"); [Description("Your user-specific key used to decrypt your audible files (*.aax) into audio files you can use anywhere (*.m4b). Leave alone in most cases")] public string DecryptKey @@ -69,7 +68,7 @@ namespace FileManager ["MyDocs"] = MyDocs, ["WinTemp"] = WinTemp }; - private Dictionary cache { get; } = new Dictionary(); + private string libationFilesPathCache; // default setting and directory creation occur in class responsible for files. // config class is only responsible for path. not responsible for setting defaults, dir validation, or dir creation @@ -107,57 +106,51 @@ namespace FileManager private const string LIBATION_FILES = "LibationFiles"; [Description("Location for storage of program-created files")] - public string LibationFiles - => cache.ContainsKey(LIBATION_FILES) - ? cache[LIBATION_FILES] - : getLibationFiles(); + public string LibationFiles => libationFilesPathCache ?? getLibationFiles(); private string getLibationFiles() { var value = getLiberationFilesSettingFromJson(); + // this looks weird but is correct for translating wellKnownPaths if (wellKnownPaths.ContainsKey(value)) value = wellKnownPaths[value]; - // must write here before SettingsJsonPath in next step tries to read from dictionary - cache[LIBATION_FILES] = value; + // must write here before SettingsJsonPath in next step reads cache + libationFilesPathCache = value; // load json values into memory. create if not exists persistentDictionary = new PersistentDictionary(SettingsJsonPath); - return value; + return libationFilesPathCache; } private string getLiberationFilesSettingFromJson() { - static string createSettingsJson() - { - var dir = APP_DIR; - File.WriteAllText(APPSETTINGS_JSON, new JObject { { LIBATION_FILES, dir } }.ToString(Formatting.Indented)); - return dir; - } - - if (!File.Exists(APPSETTINGS_JSON)) - return createSettingsJson(); - - var appSettingsContents = File.ReadAllText(APPSETTINGS_JSON); - - JObject jObj; try { - jObj = JObject.Parse(appSettingsContents); - } - catch - { - return createSettingsJson(); - } + if (File.Exists(APPSETTINGS_JSON)) + { + var appSettingsContents = File.ReadAllText(APPSETTINGS_JSON); + var jObj = JObject.Parse(appSettingsContents); - if (!jObj.ContainsKey(LIBATION_FILES)) - return createSettingsJson(); + if (jObj.ContainsKey(LIBATION_FILES)) + { + var value = jObj[LIBATION_FILES].Value(); - var value = jObj[LIBATION_FILES].Value(); - return value; + // do not check whether directory exists. special/meta directory (eg: AppDir) is valid + if (!string.IsNullOrWhiteSpace(value)) + return value; + } + } + } + catch { } + + File.WriteAllText(APPSETTINGS_JSON, new JObject { { LIBATION_FILES, APP_DIR } }.ToString(Formatting.Indented)); + return APP_DIR; } - private string SettingsJsonPath => Path.Combine(LibationFiles, "Settings.json"); + public object GetObject(string propertyName) => persistentDictionary.GetObject(propertyName); + public void SetObject(string propertyName, object newValue) => persistentDictionary.Set(propertyName, newValue); + public void SetWithJsonPath(string jsonPath, string propertyName, string newValue) => persistentDictionary.SetWithJsonPath(jsonPath, propertyName, newValue); public static string GetDescription(string propertyName) { @@ -185,7 +178,7 @@ namespace FileManager } - cache.Remove(LIBATION_FILES); + libationFilesPathCache = null; var contents = File.ReadAllText(APPSETTINGS_JSON); diff --git a/FileManager/UNTESTED/PersistentDictionary.cs b/FileManager/UNTESTED/PersistentDictionary.cs index 27fe98fa..f5ee0b45 100644 --- a/FileManager/UNTESTED/PersistentDictionary.cs +++ b/FileManager/UNTESTED/PersistentDictionary.cs @@ -87,6 +87,18 @@ namespace FileManager } } + public void SetWithJsonPath(string jsonPath, string propertyName, string newValue) + { + lock (locker) + { + var jObject = readFile(); + var token = jObject.SelectToken(jsonPath); + var debug_oldValue = (string)token[propertyName]; + token[propertyName] = newValue; + File.WriteAllText(Filepath, JsonConvert.SerializeObject(jObject, Formatting.Indented)); + } + } + private JObject readFile() { var settingsJsonContents = File.ReadAllText(Filepath); diff --git a/InternalUtilities/UNTESTED/AudibleApiExtensions.cs b/InternalUtilities/UNTESTED/AudibleApiExtensions.cs index 0eb02a9d..63d00d18 100644 --- a/InternalUtilities/UNTESTED/AudibleApiExtensions.cs +++ b/InternalUtilities/UNTESTED/AudibleApiExtensions.cs @@ -44,7 +44,7 @@ namespace InternalUtilities if (!libResult.Items.Any()) break; else - Serilog.Log.Logger.Debug($"Page {i}: {libResult.Items.Length} results"); + Serilog.Log.Logger.Information($"Page {i}: {libResult.Items.Length} results"); allItems.AddRange(libResult.Items); } diff --git a/LibationLauncher/Program.cs b/LibationLauncher/Program.cs index ca4c4205..34efa9d3 100644 --- a/LibationLauncher/Program.cs +++ b/LibationLauncher/Program.cs @@ -6,6 +6,7 @@ using FileManager; using LibationWinForms; using LibationWinForms.Dialogs; using Microsoft.Extensions.Configuration; +using Newtonsoft.Json.Linq; using Serilog; namespace LibationLauncher @@ -28,7 +29,7 @@ namespace LibationLauncher private static void createSettings() { var config = Configuration.Instance; - if (config.IsComplete) + if (configSetupIsComplete(config)) return; var isAdvanced = false; @@ -53,7 +54,7 @@ namespace LibationLauncher MessageBox.Show("Libation Files location not changed"); } - if (config.IsComplete) + if (configSetupIsComplete(config)) return; if (new SettingsDialog().ShowDialog() == DialogResult.OK) @@ -64,8 +65,75 @@ namespace LibationLauncher Environment.Exit(0); } + private static bool configSetupIsComplete(Configuration config) + => config.FilesExist + && !string.IsNullOrWhiteSpace(config.LocaleCountryCode) + && !string.IsNullOrWhiteSpace(config.DownloadsInProgressEnum) + && !string.IsNullOrWhiteSpace(config.DecryptInProgressEnum); + private static void initLogging() { + var config = Configuration.Instance; + + ensureLoggingConfig(config); + ensureSerilogConfig(config); + + // override path. always use current libation files + var logPath = Path.Combine(Configuration.Instance.LibationFiles, "Log.log"); + config.SetWithJsonPath("Serilog.WriteTo[1].Args", "path", logPath); + + //// hack which achieves the same + //configuration["Serilog:WriteTo:1:Args:path"] = logPath; + + // CONFIGURATION-DRIVEN (json) + var configuration = new ConfigurationBuilder() + .AddJsonFile(config.SettingsJsonPath) + .Build(); + Log.Logger = new LoggerConfiguration() + .ReadFrom.Configuration(configuration) + .CreateLogger(); + + //// MANUAL HARD CODED + //Log.Logger = new LoggerConfiguration() + // .Enrich.WithCaller() + // .MinimumLevel.Information() + // .WriteTo.File(logPath, + // rollingInterval: RollingInterval.Month, + // outputTemplate: code_outputTemplate) + // .CreateLogger(); + + Log.Logger.Information("Begin Libation"); + + // .Here() captures debug info via System.Runtime.CompilerServices attributes. Warning: expensive + //var withLineNumbers_outputTemplate = "[{Timestamp:HH:mm:ss} {Level}] {SourceContext}{NewLine}{Message}{NewLine}in method {MemberName} at {FilePath}:{LineNumber}{NewLine}{Exception}{NewLine}"; + //Log.Logger.Here().Debug("Begin Libation. Debug with line numbers"); + } + + private static string defaultLoggingLevel = "Information"; + private static void ensureLoggingConfig(Configuration config) + { + if (config.GetObject("Logging") != null) + return; + + // "Logging": { + // "LogLevel": { + // "Default": "Debug" + // } + // } + var loggingObj = new JObject + { + { + "LogLevel", new JObject { { "Default", defaultLoggingLevel } } + } + }; + config.SetObject("Logging", loggingObj); + } + + private static void ensureSerilogConfig(Configuration config) + { + if (config.GetObject("Serilog") != null) + return; + // default. for reference. output example: // 2019-11-26 08:48:40.224 -05:00 [DBG] Begin Libation var default_outputTemplate = "{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} [{Level:u3}] {Message:lj}{NewLine}{Exception}"; @@ -73,28 +141,48 @@ namespace LibationLauncher // 2019-11-26 08:48:40.224 -05:00 [DBG] (at LibationWinForms.Program.init()) Begin Libation var code_outputTemplate = "{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} [{Level:u3}] (at {Caller}) {Message:lj}{NewLine}{Exception}"; - - var logPath = Path.Combine(Configuration.Instance.LibationFiles, "Log.log"); - -//var configuration = new ConfigurationBuilder() -// .AddJsonFile("appsettings.json") -// .Build(); -//Log.Logger = new LoggerConfiguration() -// .ReadFrom.Configuration(configuration) -// .CreateLogger(); - Log.Logger = new LoggerConfiguration() - .Enrich.WithCaller() - .MinimumLevel.Debug() - .WriteTo.File(logPath, - rollingInterval: RollingInterval.Month, - outputTemplate: code_outputTemplate) - .CreateLogger(); - - Log.Logger.Debug("Begin Libation"); - - // .Here() captures debug info via System.Runtime.CompilerServices attributes. Warning: expensive - //var withLineNumbers_outputTemplate = "[{Timestamp:HH:mm:ss} {Level}] {SourceContext}{NewLine}{Message}{NewLine}in method {MemberName} at {FilePath}:{LineNumber}{NewLine}{Exception}{NewLine}"; - //Log.Logger.Here().Debug("Begin Libation. Debug with line numbers"); + // "Serilog": { + // "MinimumLevel": "Information" + // "WriteTo": [ + // { + // "Name": "Console" + // }, + // { + // "Name": "File", + // "Args": { + // "rollingInterval": "Day", + // "outputTemplate": ... + // } + // } + // ], + // "Using": [ "Dinah.Core" ], + // "Enrich": [ "WithCaller" ] + // } + var serilogObj = new JObject + { + { "MinimumLevel", defaultLoggingLevel }, + { "WriteTo", new JArray + { + new JObject { {"Name", "Console" } }, + new JObject + { + { "Name", "File" }, + { "Args", + new JObject + { + // for this sink to work, a path must be provided. we override this below + { "path", Path.Combine(Configuration.Instance.LibationFiles, "_Log.log") }, + { "rollingInterval", "Month" }, + { "outputTemplate", code_outputTemplate } + } + } + } + } + }, + { "Using", new JArray{ "Dinah.Core" } }, // dll's name, NOT namespace + { "Enrich", new JArray{ "WithCaller" } }, + }; + config.SetObject("Serilog", serilogObj); } } } diff --git a/LibationWinForms/UNTESTED/BookLiberation/AutomatedBackupsForm.cs b/LibationWinForms/UNTESTED/BookLiberation/AutomatedBackupsForm.cs index 6974e10e..eeb19adc 100644 --- a/LibationWinForms/UNTESTED/BookLiberation/AutomatedBackupsForm.cs +++ b/LibationWinForms/UNTESTED/BookLiberation/AutomatedBackupsForm.cs @@ -31,7 +31,7 @@ namespace LibationWinForms.BookLiberation } public void AppendText(string text) { - Serilog.Log.Logger.Debug($"Automated backup: {text}"); + Serilog.Log.Logger.Information($"Automated backup: {text}"); appendText(text); } private void appendText(string text)