using System; using System.Collections.Generic; using System.ComponentModel; using System.IO; using System.Linq; using Dinah.Core; namespace FileManager { public class Configuration { // settings will be persisted when all are true // - property (not field) // - string // - public getter // - public setter #region // properties to test reflection /* // field should NOT be populated public string TestField; // int should NOT be populated public int TestInt { get; set; } // read-only should NOT be populated public string TestGet { get; } // get only: should NOT get auto-populated // set-only should NOT be populated public string TestSet { private get; set; } // get and set: SHOULD be auto-populated public string TestGetSet { get; set; } */ #endregion private PersistentDictionary persistentDictionary { get; } [Description("Location of the configuration file where these settings are saved. Please do not edit this file directly while Libation is running.")] public string Filepath => Path.Combine(Path.GetDirectoryName(Exe.FileLocationOnDisk), "Settings.json"); [Description("[Advanced. Leave alone in most cases.] Your user-specific key used to decrypt your audible files (*.aax) into audio files you can use anywhere (*.m4b)")] public string DecryptKey { get => persistentDictionary[nameof(DecryptKey)]; set => persistentDictionary[nameof(DecryptKey)] = value; } [Description("Location for book storage. Includes destination of newly liberated books")] public string Books { get => persistentDictionary[nameof(Books)]; set => persistentDictionary[nameof(Books)] = value; } public string WinTemp { get; } = Path.Combine(Path.GetTempPath(), "Libation"); [Description("Location for storage of program-created files")] public string LibationFiles { get => persistentDictionary[nameof(LibationFiles)]; set => persistentDictionary[nameof(LibationFiles)] = value; } // 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 // temp/working dir(s) should be outside of dropbox [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 { get => persistentDictionary[nameof(DownloadsInProgressEnum)]; set => persistentDictionary[nameof(DownloadsInProgressEnum)] = value; } // temp/working dir(s) should be outside of dropbox [Description("Temporary location of files while they're in process of being decrypted.\r\nWhen decryption is complete, the final file will be in Books location")] public string DecryptInProgressEnum { get => persistentDictionary[nameof(DecryptInProgressEnum)]; set => persistentDictionary[nameof(DecryptInProgressEnum)] = value; } public string LocaleCountryCode { get => persistentDictionary[nameof(LocaleCountryCode)]; set => persistentDictionary[nameof(LocaleCountryCode)] = value; } // singleton stuff public static Configuration Instance { get; } = new Configuration(); private Configuration() { // load json values into memory persistentDictionary = new PersistentDictionary(Filepath); ensureDictionaryEntries(); // don't create dir. dir creation is the responsibility of places that use the dir if (string.IsNullOrWhiteSpace(LibationFiles)) LibationFiles = Path.Combine(Path.GetDirectoryName(Exe.FileLocationOnDisk), "Libation"); } public static string GetDescription(string propertyName) { var attribute = typeof(Configuration) .GetProperty(propertyName) ?.GetCustomAttributes(typeof(DescriptionAttribute), true) .SingleOrDefault() as DescriptionAttribute; return attribute?.Description; } private void ensureDictionaryEntries() { var stringProperties = getDictionaryProperties().Select(p => p.Name).ToList(); var missingKeys = stringProperties.Except(persistentDictionary.Keys).ToArray(); persistentDictionary.AddKeys(missingKeys); } private IEnumerable dicPropertiesCache; private IEnumerable getDictionaryProperties() { if (dicPropertiesCache == null) dicPropertiesCache = PersistentDictionary.GetPropertiesToPersist(this.GetType()); return dicPropertiesCache; } } }