diff --git a/AppScaffolding/AppScaffolding.csproj b/AppScaffolding/AppScaffolding.csproj index 8d5dee78..762e5daf 100644 --- a/AppScaffolding/AppScaffolding.csproj +++ b/AppScaffolding/AppScaffolding.csproj @@ -3,7 +3,7 @@ net5.0 - 5.7.0.1 + 5.7.1.1 diff --git a/AppScaffolding/LibationScaffolding.cs b/AppScaffolding/LibationScaffolding.cs index ecfcf307..bdd74b10 100644 --- a/AppScaffolding/LibationScaffolding.cs +++ b/AppScaffolding/LibationScaffolding.cs @@ -57,6 +57,7 @@ namespace AppScaffolding // Migrations.migrate_to_v5_2_0__post_config(config); + Migrations.migrate_to_v5_7_1(config); } /// Initialize logging. Run after migration @@ -321,5 +322,12 @@ namespace AppScaffolding config.DecryptToLossy = false; } #endregion + + // add config.BadBook + public static void migrate_to_v5_7_1(Configuration config) + { + if (!config.Exists(nameof(config.BadBook))) + config.BadBook = Configuration.BadBookAction.Ask; + } } } diff --git a/FileManager/Configuration.cs b/FileManager/Configuration.cs index 3faebd06..16930238 100644 --- a/FileManager/Configuration.cs +++ b/FileManager/Configuration.cs @@ -102,6 +102,29 @@ namespace FileManager set => persistentDictionary.SetNonString(nameof(DecryptToLossy), value); } + public enum BadBookAction + { + [Description("Ask each time what action to take.")] + Ask = 0, + [Description("Stop processing books.")] + Abort = 1, + [Description("Retry book later. Skip for now. Continue processing books.")] + Retry = 2, + [Description("Permanently ignore book. Continue processing books. Do not try book again.")] + Ignore = 3 + } + + [Description("When liberating books and there is an error, Libation should:")] + public BadBookAction BadBook + { + get + { + var badBookStr = persistentDictionary.GetString(nameof(BadBook)); + return Enum.TryParse(badBookStr, out var badBookEnum) ? badBookEnum : BadBookAction.Ask; + } + set => persistentDictionary.SetString(nameof(BadBook), value.ToString()); + } + #endregion #region known directories @@ -178,16 +201,8 @@ namespace FileManager { get { - try - { - var logLevelStr = persistentDictionary.GetStringFromJsonPath("Serilog", "MinimumLevel"); - var logLevelEnum = Enum.Parse(logLevelStr); - return logLevelEnum; - } - catch - { - return LogEventLevel.Information; - } + var logLevelStr = persistentDictionary.GetStringFromJsonPath("Serilog", "MinimumLevel"); + return Enum.TryParse(logLevelStr, out var logLevelEnum) ? logLevelEnum : LogEventLevel.Information; } set { @@ -219,7 +234,6 @@ namespace FileManager #endregion #region LibationFiles - private static string APPSETTINGS_JSON { get; } = Path.Combine(Path.GetDirectoryName(System.Reflection.Assembly.GetEntryAssembly().Location), "appsettings.json"); private const string LIBATION_FILES_KEY = "LibationFiles"; diff --git a/LibationWinForms/BookLiberation/ProcessorAutomationController.cs b/LibationWinForms/BookLiberation/ProcessorAutomationController.cs index c2f8482c..7582d790 100644 --- a/LibationWinForms/BookLiberation/ProcessorAutomationController.cs +++ b/LibationWinForms/BookLiberation/ProcessorAutomationController.cs @@ -196,8 +196,6 @@ namespace LibationWinForms.BookLiberation protected async Task ProcessOneAsync(LibraryBook libraryBook, bool validate) { - string logMessage; - try { var statusHandler = await Processable.ProcessSingleAsync(libraryBook, validate); @@ -207,18 +205,28 @@ namespace LibationWinForms.BookLiberation foreach (var errorMessage in statusHandler.Errors) LogMe.Error(errorMessage); - - logMessage = statusHandler.Errors.Aggregate((a, b) => $"{a}\r\n{b}"); } catch (Exception ex) { LogMe.Error(ex); - - logMessage = ex.Message + "\r\n|\r\n" + ex.StackTrace; } + return showRetry(libraryBook); + } + + private bool showRetry(LibraryBook libraryBook) + { LogMe.Error("ERROR. All books have not been processed. Most recent book: processing failed"); + DialogResult? dialogResult = FileManager.Configuration.Instance.BadBook switch + { + FileManager.Configuration.BadBookAction.Abort => DialogResult.Abort, + FileManager.Configuration.BadBookAction.Retry => DialogResult.Retry, + FileManager.Configuration.BadBookAction.Ignore => DialogResult.Ignore, + FileManager.Configuration.BadBookAction.Ask => null, + _ => null + }; + string details; try { @@ -238,7 +246,8 @@ $@" Title: {libraryBook.Book.Title} details = "[Error retrieving details]"; } - var dialogResult = MessageBox.Show(string.Format(SkipDialogText, details), "Skip importing this book?", SkipDialogButtons, MessageBoxIcon.Question, SkipDialogDefaultButton); + // if null then ask user + dialogResult ??= MessageBox.Show(string.Format(SkipDialogText + "\r\n\r\nSee Settings to avoid this box in the future.", details), "Skip importing this book?", SkipDialogButtons, MessageBoxIcon.Question, SkipDialogDefaultButton); if (dialogResult == DialogResult.Abort) return false; @@ -288,7 +297,7 @@ An error occurred while trying to process this book. Skip this book permanently? An error occurred while trying to process this book. {0} -- ABORT: stop processing books. +- ABORT: Stop processing books. - RETRY: retry this book later. Just skip it for now. Continue processing books. (Will try this book again later.) diff --git a/LibationWinForms/Dialogs/SettingsDialog.Designer.cs b/LibationWinForms/Dialogs/SettingsDialog.Designer.cs index c58b75ce..f0da3af0 100644 --- a/LibationWinForms/Dialogs/SettingsDialog.Designer.cs +++ b/LibationWinForms/Dialogs/SettingsDialog.Designer.cs @@ -42,8 +42,16 @@ this.booksGb = new System.Windows.Forms.GroupBox(); this.loggingLevelLbl = new System.Windows.Forms.Label(); this.loggingLevelCb = new System.Windows.Forms.ComboBox(); + this.decryptAndConvertGb = new System.Windows.Forms.GroupBox(); + this.badBookGb = new System.Windows.Forms.GroupBox(); + this.badBookAskRb = new System.Windows.Forms.RadioButton(); + this.badBookAbortRb = new System.Windows.Forms.RadioButton(); + this.badBookRetryRb = new System.Windows.Forms.RadioButton(); + this.badBookIgnoreRb = new System.Windows.Forms.RadioButton(); this.advancedSettingsGb.SuspendLayout(); this.booksGb.SuspendLayout(); + this.decryptAndConvertGb.SuspendLayout(); + this.badBookGb.SuspendLayout(); this.SuspendLayout(); // // booksLocationDescLbl @@ -53,27 +61,27 @@ this.booksLocationDescLbl.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0); this.booksLocationDescLbl.Name = "booksLocationDescLbl"; this.booksLocationDescLbl.Size = new System.Drawing.Size(69, 15); - this.booksLocationDescLbl.TabIndex = 2; + this.booksLocationDescLbl.TabIndex = 1; this.booksLocationDescLbl.Text = "[book desc]"; // // inProgressDescLbl // this.inProgressDescLbl.AutoSize = true; - this.inProgressDescLbl.Location = new System.Drawing.Point(8, 127); + this.inProgressDescLbl.Location = new System.Drawing.Point(8, 149); this.inProgressDescLbl.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0); this.inProgressDescLbl.Name = "inProgressDescLbl"; this.inProgressDescLbl.Size = new System.Drawing.Size(43, 45); - this.inProgressDescLbl.TabIndex = 1; + this.inProgressDescLbl.TabIndex = 15; this.inProgressDescLbl.Text = "[desc]\r\n[line 2]\r\n[line 3]"; // // saveBtn // this.saveBtn.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); - this.saveBtn.Location = new System.Drawing.Point(714, 419); + this.saveBtn.Location = new System.Drawing.Point(714, 445); this.saveBtn.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); this.saveBtn.Name = "saveBtn"; this.saveBtn.Size = new System.Drawing.Size(88, 27); - this.saveBtn.TabIndex = 4; + this.saveBtn.TabIndex = 17; this.saveBtn.Text = "Save"; this.saveBtn.UseVisualStyleBackColor = true; this.saveBtn.Click += new System.EventHandler(this.saveBtn_Click); @@ -82,40 +90,40 @@ // this.cancelBtn.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); this.cancelBtn.DialogResult = System.Windows.Forms.DialogResult.Cancel; - this.cancelBtn.Location = new System.Drawing.Point(832, 419); + this.cancelBtn.Location = new System.Drawing.Point(832, 445); this.cancelBtn.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); this.cancelBtn.Name = "cancelBtn"; this.cancelBtn.Size = new System.Drawing.Size(88, 27); - this.cancelBtn.TabIndex = 5; + this.cancelBtn.TabIndex = 18; this.cancelBtn.Text = "Cancel"; this.cancelBtn.UseVisualStyleBackColor = true; this.cancelBtn.Click += new System.EventHandler(this.cancelBtn_Click); // // advancedSettingsGb // - this.advancedSettingsGb.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + this.advancedSettingsGb.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Right))); - this.advancedSettingsGb.Controls.Add(this.convertLossyRb); - this.advancedSettingsGb.Controls.Add(this.convertLosslessRb); + this.advancedSettingsGb.Controls.Add(this.badBookGb); + this.advancedSettingsGb.Controls.Add(this.decryptAndConvertGb); this.advancedSettingsGb.Controls.Add(this.inProgressSelectControl); - this.advancedSettingsGb.Controls.Add(this.allowLibationFixupCbox); this.advancedSettingsGb.Controls.Add(this.inProgressDescLbl); this.advancedSettingsGb.Location = new System.Drawing.Point(12, 176); this.advancedSettingsGb.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); this.advancedSettingsGb.Name = "advancedSettingsGb"; this.advancedSettingsGb.Padding = new System.Windows.Forms.Padding(4, 3, 4, 3); - this.advancedSettingsGb.Size = new System.Drawing.Size(908, 232); - this.advancedSettingsGb.TabIndex = 5; + this.advancedSettingsGb.Size = new System.Drawing.Size(908, 258); + this.advancedSettingsGb.TabIndex = 6; this.advancedSettingsGb.TabStop = false; this.advancedSettingsGb.Text = "Advanced settings for control freaks"; // // convertLossyRb // this.convertLossyRb.AutoSize = true; - this.convertLossyRb.Location = new System.Drawing.Point(7, 88); + this.convertLossyRb.Location = new System.Drawing.Point(6, 81); this.convertLossyRb.Name = "convertLossyRb"; this.convertLossyRb.Size = new System.Drawing.Size(242, 19); - this.convertLossyRb.TabIndex = 0; + this.convertLossyRb.TabIndex = 10; this.convertLossyRb.Text = "Download my books as .MP3 files (Lossy)"; this.convertLossyRb.UseVisualStyleBackColor = true; // @@ -123,10 +131,10 @@ // this.convertLosslessRb.AutoSize = true; this.convertLosslessRb.Checked = true; - this.convertLosslessRb.Location = new System.Drawing.Point(7, 63); + this.convertLosslessRb.Location = new System.Drawing.Point(6, 56); this.convertLosslessRb.Name = "convertLosslessRb"; this.convertLosslessRb.Size = new System.Drawing.Size(327, 19); - this.convertLosslessRb.TabIndex = 0; + this.convertLosslessRb.TabIndex = 9; this.convertLosslessRb.TabStop = true; this.convertLosslessRb.Text = "Download my books as .M4B files (Lossless Mp4a format)"; this.convertLosslessRb.UseVisualStyleBackColor = true; @@ -135,20 +143,20 @@ // this.inProgressSelectControl.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Right))); - this.inProgressSelectControl.Location = new System.Drawing.Point(10, 175); + this.inProgressSelectControl.Location = new System.Drawing.Point(7, 197); this.inProgressSelectControl.Name = "inProgressSelectControl"; this.inProgressSelectControl.Size = new System.Drawing.Size(552, 52); - this.inProgressSelectControl.TabIndex = 2; + this.inProgressSelectControl.TabIndex = 16; // // allowLibationFixupCbox // this.allowLibationFixupCbox.AutoSize = true; this.allowLibationFixupCbox.Checked = true; this.allowLibationFixupCbox.CheckState = System.Windows.Forms.CheckState.Checked; - this.allowLibationFixupCbox.Location = new System.Drawing.Point(7, 22); + this.allowLibationFixupCbox.Location = new System.Drawing.Point(6, 22); this.allowLibationFixupCbox.Name = "allowLibationFixupCbox"; this.allowLibationFixupCbox.Size = new System.Drawing.Size(262, 19); - this.allowLibationFixupCbox.TabIndex = 0; + this.allowLibationFixupCbox.TabIndex = 8; this.allowLibationFixupCbox.Text = "Allow Libation to fix up audiobook metadata"; this.allowLibationFixupCbox.UseVisualStyleBackColor = true; this.allowLibationFixupCbox.CheckedChanged += new System.EventHandler(this.allowLibationFixupCbox_CheckedChanged); @@ -158,7 +166,7 @@ this.logsBtn.Location = new System.Drawing.Point(262, 147); this.logsBtn.Name = "logsBtn"; this.logsBtn.Size = new System.Drawing.Size(132, 23); - this.logsBtn.TabIndex = 4; + this.logsBtn.TabIndex = 5; this.logsBtn.Text = "Open log folder"; this.logsBtn.UseVisualStyleBackColor = true; this.logsBtn.Click += new System.EventHandler(this.logsBtn_Click); @@ -170,7 +178,7 @@ this.booksSelectControl.Location = new System.Drawing.Point(7, 37); this.booksSelectControl.Name = "booksSelectControl"; this.booksSelectControl.Size = new System.Drawing.Size(895, 87); - this.booksSelectControl.TabIndex = 1; + this.booksSelectControl.TabIndex = 2; // // booksGb // @@ -181,7 +189,7 @@ this.booksGb.Location = new System.Drawing.Point(12, 12); this.booksGb.Name = "booksGb"; this.booksGb.Size = new System.Drawing.Size(908, 129); - this.booksGb.TabIndex = 1; + this.booksGb.TabIndex = 0; this.booksGb.TabStop = false; this.booksGb.Text = "Books location"; // @@ -191,7 +199,7 @@ this.loggingLevelLbl.Location = new System.Drawing.Point(12, 150); this.loggingLevelLbl.Name = "loggingLevelLbl"; this.loggingLevelLbl.Size = new System.Drawing.Size(78, 15); - this.loggingLevelLbl.TabIndex = 2; + this.loggingLevelLbl.TabIndex = 3; this.loggingLevelLbl.Text = "Logging level"; // // loggingLevelCb @@ -201,7 +209,76 @@ this.loggingLevelCb.Location = new System.Drawing.Point(96, 147); this.loggingLevelCb.Name = "loggingLevelCb"; this.loggingLevelCb.Size = new System.Drawing.Size(129, 23); - this.loggingLevelCb.TabIndex = 3; + this.loggingLevelCb.TabIndex = 4; + // + // decryptAndConvertGb + // + this.decryptAndConvertGb.Controls.Add(this.allowLibationFixupCbox); + this.decryptAndConvertGb.Controls.Add(this.convertLossyRb); + this.decryptAndConvertGb.Controls.Add(this.convertLosslessRb); + this.decryptAndConvertGb.Location = new System.Drawing.Point(7, 22); + this.decryptAndConvertGb.Name = "decryptAndConvertGb"; + this.decryptAndConvertGb.Size = new System.Drawing.Size(359, 124); + this.decryptAndConvertGb.TabIndex = 7; + this.decryptAndConvertGb.TabStop = false; + this.decryptAndConvertGb.Text = "Decrypt and convert"; + // + // badBookGb + // + this.badBookGb.Controls.Add(this.badBookIgnoreRb); + this.badBookGb.Controls.Add(this.badBookRetryRb); + this.badBookGb.Controls.Add(this.badBookAbortRb); + this.badBookGb.Controls.Add(this.badBookAskRb); + this.badBookGb.Location = new System.Drawing.Point(372, 22); + this.badBookGb.Name = "badBookGb"; + this.badBookGb.Size = new System.Drawing.Size(529, 124); + this.badBookGb.TabIndex = 11; + this.badBookGb.TabStop = false; + this.badBookGb.Text = "badBookGb"; + // + // badBookAskRb + // + this.badBookAskRb.AutoSize = true; + this.badBookAskRb.Location = new System.Drawing.Point(6, 22); + this.badBookAskRb.Name = "badBookAskRb"; + this.badBookAskRb.Size = new System.Drawing.Size(94, 19); + this.badBookAskRb.TabIndex = 12; + this.badBookAskRb.TabStop = true; + this.badBookAskRb.Text = "radioButton1"; + this.badBookAskRb.UseVisualStyleBackColor = true; + // + // badBookAbortRb + // + this.badBookAbortRb.AutoSize = true; + this.badBookAbortRb.Location = new System.Drawing.Point(6, 47); + this.badBookAbortRb.Name = "badBookAbortRb"; + this.badBookAbortRb.Size = new System.Drawing.Size(94, 19); + this.badBookAbortRb.TabIndex = 13; + this.badBookAbortRb.TabStop = true; + this.badBookAbortRb.Text = "radioButton2"; + this.badBookAbortRb.UseVisualStyleBackColor = true; + // + // badBookRetryRb + // + this.badBookRetryRb.AutoSize = true; + this.badBookRetryRb.Location = new System.Drawing.Point(6, 72); + this.badBookRetryRb.Name = "badBookRetryRb"; + this.badBookRetryRb.Size = new System.Drawing.Size(94, 19); + this.badBookRetryRb.TabIndex = 14; + this.badBookRetryRb.TabStop = true; + this.badBookRetryRb.Text = "radioButton3"; + this.badBookRetryRb.UseVisualStyleBackColor = true; + // + // badBookIgnoreRb + // + this.badBookIgnoreRb.AutoSize = true; + this.badBookIgnoreRb.Location = new System.Drawing.Point(6, 97); + this.badBookIgnoreRb.Name = "badBookIgnoreRb"; + this.badBookIgnoreRb.Size = new System.Drawing.Size(94, 19); + this.badBookIgnoreRb.TabIndex = 15; + this.badBookIgnoreRb.TabStop = true; + this.badBookIgnoreRb.Text = "radioButton4"; + this.badBookIgnoreRb.UseVisualStyleBackColor = true; // // SettingsDialog // @@ -209,7 +286,7 @@ this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.CancelButton = this.cancelBtn; - this.ClientSize = new System.Drawing.Size(933, 462); + this.ClientSize = new System.Drawing.Size(933, 488); this.Controls.Add(this.logsBtn); this.Controls.Add(this.loggingLevelCb); this.Controls.Add(this.loggingLevelLbl); @@ -227,6 +304,10 @@ this.advancedSettingsGb.PerformLayout(); this.booksGb.ResumeLayout(false); this.booksGb.PerformLayout(); + this.decryptAndConvertGb.ResumeLayout(false); + this.decryptAndConvertGb.PerformLayout(); + this.badBookGb.ResumeLayout(false); + this.badBookGb.PerformLayout(); this.ResumeLayout(false); this.PerformLayout(); @@ -247,5 +328,11 @@ private System.Windows.Forms.Button logsBtn; private System.Windows.Forms.Label loggingLevelLbl; private System.Windows.Forms.ComboBox loggingLevelCb; + private System.Windows.Forms.GroupBox decryptAndConvertGb; + private System.Windows.Forms.GroupBox badBookGb; + private System.Windows.Forms.RadioButton badBookRetryRb; + private System.Windows.Forms.RadioButton badBookAbortRb; + private System.Windows.Forms.RadioButton badBookAskRb; + private System.Windows.Forms.RadioButton badBookIgnoreRb; } } \ No newline at end of file diff --git a/LibationWinForms/Dialogs/SettingsDialog.cs b/LibationWinForms/Dialogs/SettingsDialog.cs index 371385db..cca90cbe 100644 --- a/LibationWinForms/Dialogs/SettingsDialog.cs +++ b/LibationWinForms/Dialogs/SettingsDialog.cs @@ -56,6 +56,21 @@ namespace LibationWinForms.Dialogs Configuration.KnownDirectories.LibationFiles }, Configuration.KnownDirectories.WinTemp); inProgressSelectControl.SelectDirectory(config.InProgress); + + badBookGb.Text = desc(nameof(config.BadBook)); + badBookAskRb.Text = Configuration.BadBookAction.Ask.GetDescription(); + badBookAbortRb.Text = Configuration.BadBookAction.Abort.GetDescription(); + badBookRetryRb.Text = Configuration.BadBookAction.Retry.GetDescription(); + badBookIgnoreRb.Text = Configuration.BadBookAction.Ignore.GetDescription(); + var rb = config.BadBook switch + { + Configuration.BadBookAction.Ask => this.badBookAskRb, + Configuration.BadBookAction.Abort => this.badBookAbortRb, + Configuration.BadBookAction.Retry => this.badBookRetryRb, + Configuration.BadBookAction.Ignore => this.badBookIgnoreRb, + _ => this.badBookAskRb + }; + rb.Checked = true; } private void allowLibationFixupCbox_CheckedChanged(object sender, EventArgs e) @@ -111,6 +126,13 @@ namespace LibationWinForms.Dialogs config.InProgress = inProgressSelectControl.SelectedDirectory; + config.BadBook + = badBookAskRb.Checked ? Configuration.BadBookAction.Ask + : badBookAbortRb.Checked ? Configuration.BadBookAction.Abort + : badBookRetryRb.Checked ? Configuration.BadBookAction.Retry + : badBookIgnoreRb.Checked ? Configuration.BadBookAction.Ignore + : Configuration.BadBookAction.Ask; + this.DialogResult = DialogResult.OK; this.Close(); }