Add default values to Configuration

This commit is contained in:
Michael Bucari-Tovo 2023-01-09 14:05:33 -07:00
parent 915906e6ed
commit eee785377f
23 changed files with 58 additions and 185 deletions

View File

@ -77,7 +77,6 @@ namespace AppScaffolding
public static void RunPostConfigMigrations(Configuration config) public static void RunPostConfigMigrations(Configuration config)
{ {
AudibleApiStorage.EnsureAccountsSettingsFileExists(); AudibleApiStorage.EnsureAccountsSettingsFileExists();
PopulateMissingConfigValues(config);
// //
// migrations go below here // migrations go below here
@ -86,110 +85,6 @@ namespace AppScaffolding
Migrations.migrate_to_v6_6_9(config); Migrations.migrate_to_v6_6_9(config);
} }
public static void PopulateMissingConfigValues(Configuration config)
{
config.InProgress ??= Configuration.WinTemp;
if (!config.Exists(nameof(config.UseCoverAsFolderIcon)))
config.UseCoverAsFolderIcon = false;
if (!config.Exists(nameof(config.BetaOptIn)))
config.BetaOptIn = false;
if (!config.Exists(nameof(config.AllowLibationFixup)))
config.AllowLibationFixup = true;
if (!config.Exists(nameof(config.CreateCueSheet)))
config.CreateCueSheet = true;
if (!config.Exists(nameof(config.RetainAaxFile)))
config.RetainAaxFile = false;
if (!config.Exists(nameof(config.SplitFilesByChapter)))
config.SplitFilesByChapter = false;
if (!config.Exists(nameof(config.StripUnabridged)))
config.StripUnabridged = false;
if (!config.Exists(nameof(config.StripAudibleBrandAudio)))
config.StripAudibleBrandAudio = false;
if (!config.Exists(nameof(config.DecryptToLossy)))
config.DecryptToLossy = false;
if (!config.Exists(nameof(config.LameTargetBitrate)))
config.LameTargetBitrate = false;
if (!config.Exists(nameof(config.LameDownsampleMono)))
config.LameDownsampleMono = true;
if (!config.Exists(nameof(config.LameBitrate)))
config.LameBitrate = 64;
if (!config.Exists(nameof(config.LameConstantBitrate)))
config.LameConstantBitrate = false;
if (!config.Exists(nameof(config.LameMatchSourceBR)))
config.LameMatchSourceBR = true;
if (!config.Exists(nameof(config.LameVBRQuality)))
config.LameVBRQuality = 2;
if (!config.Exists(nameof(config.BadBook)))
config.BadBook = Configuration.BadBookAction.Ask;
if (!config.Exists(nameof(config.ShowImportedStats)))
config.ShowImportedStats = true;
if (!config.Exists(nameof(config.ImportEpisodes)))
config.ImportEpisodes = true;
if (!config.Exists(nameof(config.DownloadEpisodes)))
config.DownloadEpisodes = true;
if (!config.Exists(nameof(config.ReplacementCharacters)))
config.ReplacementCharacters = FileManager.ReplacementCharacters.Default;
if (!config.Exists(nameof(config.FolderTemplate)))
config.FolderTemplate = Templates.Folder.DefaultTemplate;
if (!config.Exists(nameof(config.FileTemplate)))
config.FileTemplate = Templates.File.DefaultTemplate;
if (!config.Exists(nameof(config.ChapterFileTemplate)))
config.ChapterFileTemplate = Templates.ChapterFile.DefaultTemplate;
if (!config.Exists(nameof(config.ChapterTitleTemplate)))
config.ChapterTitleTemplate = Templates.ChapterTitle.DefaultTemplate;
if (!config.Exists(nameof(config.AutoScan)))
config.AutoScan = true;
if (!config.Exists(nameof(config.GridColumnsVisibilities)))
config.GridColumnsVisibilities = new Dictionary<string, bool>();
if (!config.Exists(nameof(config.GridColumnsDisplayIndices)))
config.GridColumnsDisplayIndices = new Dictionary<string, int>();
if (!config.Exists(nameof(config.GridColumnsWidths)))
config.GridColumnsWidths = new Dictionary<string, int>();
if (!config.Exists(nameof(config.DownloadCoverArt)))
config.DownloadCoverArt = true;
if (!config.Exists(nameof(config.DownloadClipsBookmarks)))
config.DownloadClipsBookmarks = false;
if (!config.Exists(nameof(config.ClipsBookmarksFileFormat)))
config.ClipsBookmarksFileFormat = Configuration.ClipBookmarkFormat.CSV;
if (!config.Exists(nameof(config.AutoDownloadEpisodes)))
config.AutoDownloadEpisodes = false;
if (!config.Exists(nameof(config.DownloadSpeedLimit)))
config.DownloadSpeedLimit = 0;
}
/// <summary>Initialize logging. Wire-up events. Run after migration</summary> /// <summary>Initialize logging. Wire-up events. Run after migration</summary>
public static void RunPostMigrationScaffolding(Configuration config) public static void RunPostMigrationScaffolding(Configuration config)
{ {
@ -366,10 +261,6 @@ namespace AppScaffolding
if (!Version.TryParse(latestVersionString, out var latestRelease)) if (!Version.TryParse(latestVersionString, out var latestRelease))
return null; return null;
// we're up to date
if (latestRelease <= BuildVersion)
return null;
// we have an update // we have an update
var zipUrl = zip?.BrowserDownloadUrl; var zipUrl = zip?.BrowserDownloadUrl;
@ -405,6 +296,7 @@ namespace AppScaffolding
var repoName = "Libation"; var repoName = "Libation";
var gitHubClient = new Octokit.GitHubClient(new Octokit.ProductHeaderValue(repoName)); var gitHubClient = new Octokit.GitHubClient(new Octokit.ProductHeaderValue(repoName));
gitHubClient.Credentials = new("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");
//Download the release index //Download the release index
var bts = await gitHubClient.Repository.Content.GetRawContent(ownerAccount, repoName, ".releaseindex.json"); var bts = await gitHubClient.Repository.Content.GetRawContent(ownerAccount, repoName, ".releaseindex.json");

View File

@ -33,24 +33,24 @@ namespace FileManager
createNewFile(); createNewFile();
} }
public string GetString(string propertyName) public string GetString(string propertyName, string defaultValue = null)
{ {
if (!stringCache.ContainsKey(propertyName)) if (!stringCache.ContainsKey(propertyName))
{ {
var jObject = readFile(); var jObject = readFile();
if (!jObject.ContainsKey(propertyName)) if (!jObject.ContainsKey(propertyName))
return null; return defaultValue;
stringCache[propertyName] = jObject[propertyName].Value<string>(); stringCache[propertyName] = jObject[propertyName].Value<string>();
} }
return stringCache[propertyName]; return stringCache[propertyName];
} }
public T GetNonString<T>(string propertyName) public T GetNonString<T>(string propertyName, T defaultValue = default)
{ {
var obj = GetObject(propertyName); var obj = GetObject(propertyName);
if (obj is null) return default; if (obj is null) return defaultValue;
if (obj.GetType().IsAssignableTo(typeof(T))) return (T)obj; if (obj.GetType().IsAssignableTo(typeof(T))) return (T)obj;
if (obj is JObject jObject) return jObject.ToObject<T>(); if (obj is JObject jObject) return jObject.ToObject<T>();
if (obj is JValue jValue) if (obj is JValue jValue)

View File

@ -131,8 +131,6 @@ namespace LibationAvalonia
{ {
config.Books ??= Path.Combine(Configuration.UserProfile, "Books"); config.Books ??= Path.Combine(Configuration.UserProfile, "Books");
AppScaffolding.LibationScaffolding.PopulateMissingConfigValues(config);
var settingsDialog = new SettingsDialog(); var settingsDialog = new SettingsDialog();
desktop.MainWindow = settingsDialog; desktop.MainWindow = settingsDialog;
settingsDialog.RestoreSizeAndLocation(Configuration.Instance); settingsDialog.RestoreSizeAndLocation(Configuration.Instance);

View File

@ -28,8 +28,7 @@ namespace LibationAvalonia
if (Design.IsDesignMode) return; if (Design.IsDesignMode) return;
try try
{ {
var savedState = config.GetNonString<FormSizeAndPosition>(defaultValue: null, form.GetType().Name);
FormSizeAndPosition savedState = config.GetNonString<FormSizeAndPosition>(form.GetType().Name);
if (savedState is null) if (savedState is null)
return; return;

View File

@ -1,5 +1,4 @@
using ApplicationServices; using ApplicationServices;
using Avalonia.Controls;
using Avalonia.Platform.Storage; using Avalonia.Platform.Storage;
using LibationFileManager; using LibationFileManager;
using System; using System;
@ -7,7 +6,6 @@ using System.Linq;
namespace LibationAvalonia.Views namespace LibationAvalonia.Views
{ {
//DONE
public partial class MainWindow public partial class MainWindow
{ {
private void Configure_Export() { } private void Configure_Export() { }

View File

@ -5,7 +5,6 @@ using System.Threading.Tasks;
namespace LibationAvalonia.Views namespace LibationAvalonia.Views
{ {
//DONE
public partial class MainWindow public partial class MainWindow
{ {
protected void Configure_Filter() { } protected void Configure_Filter() { }

View File

@ -5,7 +5,6 @@ using System.Threading.Tasks;
namespace LibationAvalonia.Views namespace LibationAvalonia.Views
{ {
//DONE
public partial class MainWindow public partial class MainWindow
{ {
private void Configure_Liberate() { } private void Configure_Liberate() { }

View File

@ -6,12 +6,11 @@ using System.Linq;
namespace LibationAvalonia.Views namespace LibationAvalonia.Views
{ {
//DONE
public partial class MainWindow public partial class MainWindow
{ {
private void Configure_ProcessQueue() private void Configure_ProcessQueue()
{ {
var collapseState = !Configuration.Instance.GetNonString<bool>(nameof(_viewModel.QueueOpen)); var collapseState = !Configuration.Instance.GetNonString(defaultValue: true, nameof(_viewModel.QueueOpen));
SetQueueCollapseState(collapseState); SetQueueCollapseState(collapseState);
} }
@ -51,12 +50,12 @@ namespace LibationAvalonia.Views
private void SetQueueCollapseState(bool collapsed) private void SetQueueCollapseState(bool collapsed)
{ {
_viewModel.QueueOpen = !collapsed; _viewModel.QueueOpen = !collapsed;
Configuration.Instance.SetNonString(!collapsed, nameof(_viewModel.QueueOpen));
} }
public void ToggleQueueHideBtn_Click(object sender, Avalonia.Interactivity.RoutedEventArgs e) public void ToggleQueueHideBtn_Click(object sender, Avalonia.Interactivity.RoutedEventArgs e)
{ {
SetQueueCollapseState(_viewModel.QueueOpen); SetQueueCollapseState(_viewModel.QueueOpen);
Configuration.Instance.SetNonString(_viewModel.QueueOpen, nameof(_viewModel.QueueOpen));
} }
} }
} }

View File

@ -5,7 +5,6 @@ using System.Linq;
namespace LibationAvalonia.Views namespace LibationAvalonia.Views
{ {
//DONE
public partial class MainWindow public partial class MainWindow
{ {
private void Configure_QuickFilters() private void Configure_QuickFilters()

View File

@ -4,7 +4,6 @@ using System.Linq;
namespace LibationAvalonia.Views namespace LibationAvalonia.Views
{ {
//DONE
public partial class MainWindow public partial class MainWindow
{ {
private void Configure_RemoveBooks() private void Configure_RemoveBooks()

View File

@ -9,7 +9,6 @@ using System.Linq;
namespace LibationAvalonia.Views namespace LibationAvalonia.Views
{ {
//DONE
public partial class MainWindow public partial class MainWindow
{ {
private InterruptableTimer autoScanTimer; private InterruptableTimer autoScanTimer;

View File

@ -1,6 +1,5 @@
using ApplicationServices; using ApplicationServices;
using AudibleUtilities; using AudibleUtilities;
using Avalonia.Controls;
using LibationFileManager; using LibationFileManager;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
@ -9,7 +8,6 @@ using System.Threading.Tasks;
namespace LibationAvalonia.Views namespace LibationAvalonia.Views
{ {
//DONE
public partial class MainWindow public partial class MainWindow
{ {
private void Configure_ScanManual() private void Configure_ScanManual()

View File

@ -4,7 +4,6 @@ using System.Linq;
namespace LibationAvalonia.Views namespace LibationAvalonia.Views
{ {
//DONE
public partial class MainWindow public partial class MainWindow
{ {
private void Configure_ScanNotification() private void Configure_ScanNotification()

View File

@ -3,7 +3,6 @@ using System.Linq;
namespace LibationAvalonia.Views namespace LibationAvalonia.Views
{ {
//DONE
public partial class MainWindow public partial class MainWindow
{ {
private void Configure_Settings() { } private void Configure_Settings() { }

View File

@ -80,7 +80,7 @@ namespace LibationAvalonia.Views
const string ignoreUpdate = "IgnoreUpdate"; const string ignoreUpdate = "IgnoreUpdate";
var config = Configuration.Instance; var config = Configuration.Instance;
if (config.GetString(ignoreUpdate) == upgradeProperties.LatestRelease.ToString()) if (config.GetString(propertyName: ignoreUpdate) == upgradeProperties.LatestRelease.ToString())
return; return;
var notificationResult = await new UpgradeNotificationDialog(upgradeProperties, Configuration.IsWindows).ShowDialog<DialogResult>(this); var notificationResult = await new UpgradeNotificationDialog(upgradeProperties, Configuration.IsWindows).ShowDialog<DialogResult>(this);

View File

@ -1,15 +1,12 @@
using ApplicationServices; using ApplicationServices;
using Avalonia.Threading; using Avalonia.Threading;
using DataLayer; using DataLayer;
using Dinah.Core;
using LibationFileManager;
using System; using System;
using System.Linq; using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace LibationAvalonia.Views namespace LibationAvalonia.Views
{ {
//DONE
public partial class MainWindow public partial class MainWindow
{ {
private void Configure_VisibleBooks() private void Configure_VisibleBooks()

View File

@ -20,9 +20,9 @@ namespace LibationFileManager
private PersistentDictionary persistentDictionary; private PersistentDictionary persistentDictionary;
public T GetNonString<T>([CallerMemberName] string propertyName = "") => persistentDictionary.GetNonString<T>(propertyName); public T GetNonString<T>(T defaultValue, [CallerMemberName] string propertyName = "") => persistentDictionary.GetNonString(propertyName, defaultValue);
public object GetObject([CallerMemberName] string propertyName = "") => persistentDictionary.GetObject(propertyName); public object GetObject([CallerMemberName] string propertyName = "") => persistentDictionary.GetObject(propertyName);
public string GetString([CallerMemberName] string propertyName = "") => persistentDictionary.GetString(propertyName); public string GetString(string defaultValue = null, [CallerMemberName] string propertyName = "") => persistentDictionary.GetString(propertyName, defaultValue);
public void SetNonString(object newValue, [CallerMemberName] string propertyName = "") public void SetNonString(object newValue, [CallerMemberName] string propertyName = "")
{ {
var existing = getExistingValue(propertyName); var existing = getExistingValue(propertyName);
@ -74,77 +74,77 @@ namespace LibationFileManager
public bool Exists(string propertyName) => persistentDictionary.Exists(propertyName); public bool Exists(string propertyName) => persistentDictionary.Exists(propertyName);
[Description("Set cover art as the folder's icon. (Windows only)")] [Description("Set cover art as the folder's icon. (Windows only)")]
public bool UseCoverAsFolderIcon { get => GetNonString<bool>(); set => SetNonString(value); } public bool UseCoverAsFolderIcon { get => GetNonString(defaultValue: false); set => SetNonString(value); }
[Description("Use the beta version of Libation\r\nNew and experimental features, but probably buggy.\r\n(requires restart to take effect)")] [Description("Use the beta version of Libation\r\nNew and experimental features, but probably buggy.\r\n(requires restart to take effect)")]
public bool BetaOptIn { get => GetNonString<bool>(); set => SetNonString(value); } public bool BetaOptIn { get => GetNonString(defaultValue: false); set => SetNonString(value); }
[Description("Location for book storage. Includes destination of newly liberated books")] [Description("Location for book storage. Includes destination of newly liberated books")]
public string Books { get => GetString(); set => SetString(value); } public string Books { get => GetString(); set => SetString(value); }
// 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")] [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 => GetString(); set => SetString(value); } public string InProgress { get => GetString(defaultValue: WinTemp); set => SetString(value); }
[Description("Allow Libation to fix up audiobook metadata")] [Description("Allow Libation to fix up audiobook metadata")]
public bool AllowLibationFixup { get => GetNonString<bool>(); set => SetNonString(value); } public bool AllowLibationFixup { get => GetNonString(defaultValue: true); set => SetNonString(value); }
[Description("Create a cue sheet (.cue)")] [Description("Create a cue sheet (.cue)")]
public bool CreateCueSheet { get => GetNonString<bool>(); set => SetNonString(value); } public bool CreateCueSheet { get => GetNonString(defaultValue: true); set => SetNonString(value); }
[Description("Retain the Aax file after successfully decrypting")] [Description("Retain the Aax file after successfully decrypting")]
public bool RetainAaxFile { get => GetNonString<bool>(); set => SetNonString(value); } public bool RetainAaxFile { get => GetNonString(defaultValue: false); set => SetNonString(value); }
[Description("Split my books into multiple files by chapter")] [Description("Split my books into multiple files by chapter")]
public bool SplitFilesByChapter { get => GetNonString<bool>(); set => SetNonString(value); } public bool SplitFilesByChapter { get => GetNonString(defaultValue: false); set => SetNonString(value); }
[Description("Merge Opening/End Credits into the following/preceding chapters")] [Description("Merge Opening/End Credits into the following/preceding chapters")]
public bool MergeOpeningAndEndCredits { get => GetNonString<bool>(); set => SetNonString(value); } public bool MergeOpeningAndEndCredits { get => GetNonString(defaultValue: false); set => SetNonString(value); }
[Description("Strip \"(Unabridged)\" from audiobook metadata tags")] [Description("Strip \"(Unabridged)\" from audiobook metadata tags")]
public bool StripUnabridged { get => GetNonString<bool>(); set => SetNonString(value); } public bool StripUnabridged { get => GetNonString(defaultValue: false); set => SetNonString(value); }
[Description("Strip audible branding from the start and end of audiobooks.\r\n(e.g. \"This is Audible\")")] [Description("Strip audible branding from the start and end of audiobooks.\r\n(e.g. \"This is Audible\")")]
public bool StripAudibleBrandAudio { get => GetNonString<bool>(); set => SetNonString(value); } public bool StripAudibleBrandAudio { get => GetNonString(defaultValue: false); set => SetNonString(value); }
[Description("Decrypt to lossy format?")] [Description("Decrypt to lossy format?")]
public bool DecryptToLossy { get => GetNonString<bool>(); set => SetNonString(value); } public bool DecryptToLossy { get => GetNonString(defaultValue: false); set => SetNonString(value); }
[Description("Lame encoder target. true = Bitrate, false = Quality")] [Description("Lame encoder target. true = Bitrate, false = Quality")]
public bool LameTargetBitrate { get => GetNonString<bool>(); set => SetNonString(value); } public bool LameTargetBitrate { get => GetNonString(defaultValue: false); set => SetNonString(value); }
[Description("Lame encoder downsamples to mono")] [Description("Lame encoder downsamples to mono")]
public bool LameDownsampleMono { get => GetNonString<bool>(); set => SetNonString(value); } public bool LameDownsampleMono { get => GetNonString(defaultValue: true); set => SetNonString(value); }
[Description("Lame target bitrate [16,320]")] [Description("Lame target bitrate [16,320]")]
public int LameBitrate { get => GetNonString<int>(); set => SetNonString(value); } public int LameBitrate { get => GetNonString(defaultValue: 64); set => SetNonString(value); }
[Description("Restrict encoder to constant bitrate?")] [Description("Restrict encoder to constant bitrate?")]
public bool LameConstantBitrate { get => GetNonString<bool>(); set => SetNonString(value); } public bool LameConstantBitrate { get => GetNonString(defaultValue: false); set => SetNonString(value); }
[Description("Match the source bitrate?")] [Description("Match the source bitrate?")]
public bool LameMatchSourceBR { get => GetNonString<bool>(); set => SetNonString(value); } public bool LameMatchSourceBR { get => GetNonString(defaultValue: true); set => SetNonString(value); }
[Description("Lame target VBR quality [10,100]")] [Description("Lame target VBR quality [10,100]")]
public int LameVBRQuality { get => GetNonString<int>(); set => SetNonString(value); } public int LameVBRQuality { get => GetNonString(defaultValue: 2); set => SetNonString(value); }
[Description("A Dictionary of GridView data property names and bool indicating its column's visibility in ProductsGrid")] [Description("A Dictionary of GridView data property names and bool indicating its column's visibility in ProductsGrid")]
public Dictionary<string, bool> GridColumnsVisibilities { get => GetNonString<EquatableDictionary<string, bool>>().Clone(); set => SetNonString(value); } public Dictionary<string, bool> GridColumnsVisibilities { get => GetNonString(defaultValue: new EquatableDictionary<string, bool>()).Clone(); set => SetNonString(value); }
[Description("A Dictionary of GridView data property names and int indicating its column's display index in ProductsGrid")] [Description("A Dictionary of GridView data property names and int indicating its column's display index in ProductsGrid")]
public Dictionary<string, int> GridColumnsDisplayIndices { get => GetNonString<EquatableDictionary<string, int>>().Clone(); set => SetNonString(value); } public Dictionary<string, int> GridColumnsDisplayIndices { get => GetNonString(defaultValue: new EquatableDictionary<string, int>()).Clone(); set => SetNonString(value); }
[Description("A Dictionary of GridView data property names and int indicating its column's width in ProductsGrid")] [Description("A Dictionary of GridView data property names and int indicating its column's width in ProductsGrid")]
public Dictionary<string, int> GridColumnsWidths { get => GetNonString<EquatableDictionary<string, int>>().Clone(); set => SetNonString(value); } public Dictionary<string, int> GridColumnsWidths { get => GetNonString(defaultValue: new EquatableDictionary<string, int>()).Clone(); set => SetNonString(value); }
[Description("Save cover image alongside audiobook?")] [Description("Save cover image alongside audiobook?")]
public bool DownloadCoverArt { get => GetNonString<bool>(); set => SetNonString(value); } public bool DownloadCoverArt { get => GetNonString(defaultValue: true); set => SetNonString(value); }
[Description("Download clips and bookmarks?")] [Description("Download clips and bookmarks?")]
public bool DownloadClipsBookmarks { get => GetNonString<bool>(); set => SetNonString(value); } public bool DownloadClipsBookmarks { get => GetNonString(defaultValue: false); set => SetNonString(value); }
[Description("File format to save clips and bookmarks")] [Description("File format to save clips and bookmarks")]
public ClipBookmarkFormat ClipsBookmarksFileFormat { get => GetNonString<ClipBookmarkFormat>(); set => SetNonString(value); } public ClipBookmarkFormat ClipsBookmarksFileFormat { get => GetNonString(defaultValue: ClipBookmarkFormat.CSV); set => SetNonString(value); }
[JsonConverter(typeof(StringEnumConverter))] [JsonConverter(typeof(StringEnumConverter))]
public enum ClipBookmarkFormat public enum ClipBookmarkFormat
@ -171,33 +171,33 @@ namespace LibationFileManager
} }
[Description("When liberating books and there is an error, Libation should:")] [Description("When liberating books and there is an error, Libation should:")]
public BadBookAction BadBook { get => GetNonString<BadBookAction>(); set => SetNonString(value); } public BadBookAction BadBook { get => GetNonString(defaultValue: BadBookAction.Ask); set => SetNonString(value); }
[Description("Show number of newly imported titles? When unchecked, no pop-up will appear after library scan.")] [Description("Show number of newly imported titles? When unchecked, no pop-up will appear after library scan.")]
public bool ShowImportedStats { get => GetNonString<bool>(); set => SetNonString(value); } public bool ShowImportedStats { get => GetNonString(defaultValue: true); set => SetNonString(value); }
[Description("Import episodes? (eg: podcasts) When unchecked, episodes will not be imported into Libation.")] [Description("Import episodes? (eg: podcasts) When unchecked, episodes will not be imported into Libation.")]
public bool ImportEpisodes { get => GetNonString<bool>(); set => SetNonString(value); } public bool ImportEpisodes { get => GetNonString(defaultValue: true); set => SetNonString(value); }
[Description("Download episodes? (eg: podcasts). When unchecked, episodes already in Libation will not be downloaded.")] [Description("Download episodes? (eg: podcasts). When unchecked, episodes already in Libation will not be downloaded.")]
public bool DownloadEpisodes { get => GetNonString<bool>(); set => SetNonString(value); } public bool DownloadEpisodes { get => GetNonString(defaultValue: true); set => SetNonString(value); }
[Description("Automatically run periodic scans in the background?")] [Description("Automatically run periodic scans in the background?")]
public bool AutoScan { get => GetNonString<bool>(); set => SetNonString(value); } public bool AutoScan { get => GetNonString(defaultValue: true); set => SetNonString(value); }
[Description("Auto download books? After scan, download new books in 'checked' accounts.")] [Description("Auto download books? After scan, download new books in 'checked' accounts.")]
// poorly named setting. Should just be 'AutoDownload'. It is NOT episode specific // poorly named setting. Should just be 'AutoDownload'. It is NOT episode specific
public bool AutoDownloadEpisodes { get => GetNonString<bool>(); set => SetNonString(value); } public bool AutoDownloadEpisodes { get => GetNonString(defaultValue: false); set => SetNonString(value); }
[Description("Save all podcast episodes in a series to the series parent folder?")] [Description("Save all podcast episodes in a series to the series parent folder?")]
public bool SavePodcastsToParentFolder { get => GetNonString<bool>(); set => SetNonString(value); } public bool SavePodcastsToParentFolder { get => GetNonString(defaultValue: false); set => SetNonString(value); }
[Description("Global download speed limit in bytes per second.")] [Description("Global download speed limit in bytes per second.")]
public long DownloadSpeedLimit public long DownloadSpeedLimit
{ {
get get
{ {
var limit = GetNonString<long>(); var limit = GetNonString(defaultValue: 0L);
return limit <= 0 ? 0 : Math.Max(limit, AaxDecrypter.NetworkFileStream.MIN_BYTES_PER_SECOND); return limit <= 0 ? 0 : Math.Max(limit, AaxDecrypter.NetworkFileStream.MIN_BYTES_PER_SECOND);
} }
set set
@ -210,42 +210,41 @@ namespace LibationFileManager
#region templates: custom file naming #region templates: custom file naming
[Description("Edit how filename characters are replaced")] [Description("Edit how filename characters are replaced")]
public ReplacementCharacters ReplacementCharacters { get => GetNonString<ReplacementCharacters>(); set => SetNonString(value); } public ReplacementCharacters ReplacementCharacters { get => GetNonString(defaultValue: ReplacementCharacters.Default); set => SetNonString(value); }
[Description("How to format the folders in which files will be saved")] [Description("How to format the folders in which files will be saved")]
public string FolderTemplate public string FolderTemplate
{ {
get => getTemplate(nameof(FolderTemplate), Templates.Folder); get => Templates.Folder.GetValid(GetString(Templates.Folder.DefaultTemplate));
set => setTemplate(nameof(FolderTemplate), Templates.Folder, value); set => setTemplate(Templates.Folder, value);
} }
[Description("How to format the saved pdf and audio files")] [Description("How to format the saved pdf and audio files")]
public string FileTemplate public string FileTemplate
{ {
get => getTemplate(nameof(FileTemplate), Templates.File); get => Templates.File.GetValid(GetString(defaultValue: Templates.File.DefaultTemplate));
set => setTemplate(nameof(FileTemplate), Templates.File, value); set => setTemplate(Templates.File, value);
} }
[Description("How to format the saved audio files when split by chapters")] [Description("How to format the saved audio files when split by chapters")]
public string ChapterFileTemplate public string ChapterFileTemplate
{ {
get => getTemplate(nameof(ChapterFileTemplate), Templates.ChapterFile); get => Templates.ChapterFile.GetValid(GetString(defaultValue: Templates.ChapterFile.DefaultTemplate));
set => setTemplate(nameof(ChapterFileTemplate), Templates.ChapterFile, value); set => setTemplate(Templates.ChapterFile, value);
} }
[Description("How to format the file's Tile stored in metadata")] [Description("How to format the file's Tile stored in metadata")]
public string ChapterTitleTemplate public string ChapterTitleTemplate
{ {
get => getTemplate(nameof(ChapterTitleTemplate), Templates.ChapterTitle); get => Templates.ChapterTitle.GetValid(GetString(defaultValue: Templates.ChapterTitle.DefaultTemplate));
set => setTemplate(nameof(ChapterTitleTemplate), Templates.ChapterTitle, value); set => setTemplate(Templates.ChapterTitle, value);
} }
private string getTemplate(string settingName, Templates templ) => templ.GetValid(GetString(settingName)); private void setTemplate(Templates templ, string newValue, [CallerMemberName] string propertyName = "")
private void setTemplate(string settingName, Templates templ, string newValue)
{ {
var template = newValue?.Trim(); var template = newValue?.Trim();
if (templ.IsValid(template)) if (templ.IsValid(template))
SetString(template, settingName); SetString(template, propertyName);
} }
#endregion #endregion
} }

View File

@ -11,6 +11,7 @@ namespace LibationFileManager
*/ */
private class EquatableDictionary<TKey, TValue> : Dictionary<TKey, TValue> private class EquatableDictionary<TKey, TValue> : Dictionary<TKey, TValue>
{ {
public EquatableDictionary() { }
public EquatableDictionary(IEnumerable<KeyValuePair<TKey, TValue>> keyValuePairs) : base(keyValuePairs) { } public EquatableDictionary(IEnumerable<KeyValuePair<TKey, TValue>> keyValuePairs) : base(keyValuePairs) { }
public EquatableDictionary<TKey, TValue> Clone() => new(this); public EquatableDictionary<TKey, TValue> Clone() => new(this);
public override bool Equals(object obj) public override bool Equals(object obj)

View File

@ -30,7 +30,7 @@ namespace LibationWinForms.Dialogs
private void UpgradeNotificationDialog_Load(object sender, EventArgs e) private void UpgradeNotificationDialog_Load(object sender, EventArgs e)
{ {
//This dialog starts before Form1, soposition it at the center of where Form1 will be. //This dialog starts before Form1, soposition it at the center of where Form1 will be.
var savedState = Configuration.Instance.GetNonString<FormSizeAndPosition>(nameof(Form1)); var savedState = Configuration.Instance.GetNonString<FormSizeAndPosition>(defaultValue: null, nameof(Form1));
if (savedState is null) return; if (savedState is null) return;

View File

@ -16,7 +16,7 @@ namespace LibationWinForms
{ {
processBookQueue1.popoutBtn.Click += ProcessBookQueue1_PopOut; processBookQueue1.popoutBtn.Click += ProcessBookQueue1_PopOut;
splitContainer1.Panel2MinSize = 350; splitContainer1.Panel2MinSize = 350;
var coppalseState = Configuration.Instance.GetNonString<bool>(nameof(splitContainer1.Panel2Collapsed)); var coppalseState = Configuration.Instance.GetNonString(defaultValue: false, nameof(splitContainer1.Panel2Collapsed));
WidthChange = splitContainer1.Panel2.Width + splitContainer1.SplitterWidth; WidthChange = splitContainer1.Panel2.Width + splitContainer1.SplitterWidth;
int width = this.Width; int width = this.Width;
SetQueueCollapseState(coppalseState); SetQueueCollapseState(coppalseState);

View File

@ -21,7 +21,7 @@ namespace LibationWinForms
public static void RestoreSizeAndLocation(this Form form, Configuration config) public static void RestoreSizeAndLocation(this Form form, Configuration config)
{ {
FormSizeAndPosition savedState = config.GetNonString<FormSizeAndPosition>(form.Name); var savedState = config.GetNonString<FormSizeAndPosition>(defaultValue: null, form.Name);
if (savedState is null) if (savedState is null)
return; return;

View File

@ -144,7 +144,6 @@ namespace LibationWinForms
// INIT DEFAULT SETTINGS // INIT DEFAULT SETTINGS
// if 'new user' was clicked, or if 'returning user' chose new install: show basic settings dialog // if 'new user' was clicked, or if 'returning user' chose new install: show basic settings dialog
config.Books ??= Path.Combine(defaultLibationFilesDir, "Books"); config.Books ??= Path.Combine(defaultLibationFilesDir, "Books");
AppScaffolding.LibationScaffolding.PopulateMissingConfigValues(config);
if (new SettingsDialog().ShowDialog() != DialogResult.OK) if (new SettingsDialog().ShowDialog() != DialogResult.OK)
{ {

View File

@ -29,7 +29,7 @@ namespace LibationWinForms
const string ignoreUpdate = "IgnoreUpdate"; const string ignoreUpdate = "IgnoreUpdate";
var config = Configuration.Instance; var config = Configuration.Instance;
if (config.GetString(ignoreUpdate) == args.CurrentVersion) if (config.GetString(propertyName: ignoreUpdate) == args.CurrentVersion)
return; return;
var notificationResult = new UpgradeNotificationDialog(upgradeProperties).ShowDialog(); var notificationResult = new UpgradeNotificationDialog(upgradeProperties).ShowDialog();