Compare commits

...

19 Commits

Author SHA1 Message Date
Robert McRackan
efca1f9c1d added license debugging 2021-07-26 18:30:13 -04:00
Robert McRackan
ca14db79b9 Found the NRE. Underlying problem persists. Now it will be reported correctly 2021-07-26 17:12:40 -04:00
Robert McRackan
9d00da006c Trim title 2021-07-26 17:11:49 -04:00
Robert McRackan
b479096fc2 Added logging. Bug fix in MFA login form 2021-07-25 16:49:07 -04:00
rmcrackan
ad09d36588 Merge pull request #69 from Mbucari/master
Added logging of download license.
2021-07-24 19:56:55 -04:00
Mbucari
1a9c0188a4 Update AaxcDownloadConverter.cs 2021-07-24 16:12:11 -06:00
Mbucari
ca75b55da4 Merge branch 'rmcrackan:master' into master 2021-07-24 15:12:12 -06:00
Michael Bucari-Tovo
285b1e7b45 Removed dll. 2021-07-24 15:11:50 -06:00
Michael Bucari-Tovo
6912a499d0 Moved download licnse from debug log to verbose log. 2021-07-24 15:11:05 -06:00
Robert McRackan
4e70365150 increm ver # 2021-07-24 16:27:17 -04:00
Robert McRackan
811a95aedf After LogLevel changed in settings: warn if Verbose logging level 2021-07-24 16:26:50 -04:00
Michael Bucari-Tovo
20971124ab Add DLL temporarily. 2021-07-24 11:29:49 -06:00
Michael Bucari-Tovo
fa66a361dc Add logging of download license in DebugInfo 2021-07-24 11:28:58 -06:00
Robert McRackan
61d7f5a5cb version 2021-07-22 22:44:07 -04:00
Robert McRackan
f8c788297e Better error info when offering to skip problematic book (issue #65) 2021-07-22 22:08:36 -04:00
Robert McRackan
79e5545fd3 config bug fix 2021-07-22 14:08:15 -04:00
Robert McRackan
b4def2e2d6 Remember screen position. Issue #61 2021-07-21 23:13:14 -04:00
Robert McRackan
281d615649 Merge branch 'master' of https://github.com/rmcrackan/Libation 2021-07-21 14:45:22 -04:00
Robert McRackan
c2c6a31716 Remove "advanced settings". Too error prone 2021-07-21 14:43:59 -04:00
15 changed files with 333 additions and 157 deletions

View File

@@ -2,6 +2,7 @@
using Dinah.Core;
using Dinah.Core.Diagnostics;
using Dinah.Core.IO;
using Dinah.Core.Logging;
using Dinah.Core.StepRunner;
using System;
using System.IO;
@@ -39,6 +40,7 @@ namespace AaxDecrypter
ArgumentValidator.EnsureNotNullOrWhiteSpace(outFileName, nameof(outFileName));
OutputFileName = outFileName;
var outDir = Path.GetDirectoryName(OutputFileName);
if (!Directory.Exists(outDir))
throw new ArgumentNullException(nameof(outDir), "Directory does not exist");
if (File.Exists(OutputFileName))
@@ -51,6 +53,8 @@ namespace AaxDecrypter
downloadLicense = ArgumentValidator.EnsureNotNull(dlLic, nameof(dlLic));
OutputFormat = outputFormat;
Serilog.Log.Logger.Verbose("Download License. {@DebugInfo}", downloadLicense);
steps = new StepSequence
{
Name = "Download and Convert Aaxc To " + (outputFormat == OutputFormat.Mp4a ? "M4b" : "Mp3"),

View File

@@ -88,8 +88,8 @@ namespace DataLayer
Category = category;
// simple assigns
Title = title;
Description = description;
Title = title.Trim();
Description = description.Trim();
LengthInMinutes = lengthInMinutes;
// assigns with biz logic

View File

@@ -67,9 +67,6 @@ namespace DtoImporterService
{
var item = importItem.DtoItem;
//Add any subtitle after the title title.
var title = item.Title + (!string.IsNullOrWhiteSpace(item.Subtitle) ? $": {item.Subtitle}" : "");
// absence of authors is very rare, but possible
if (!item.Authors?.Any() ?? true)
item.Authors = new[] { new Person { Name = "", Asin = null } };
@@ -105,7 +102,7 @@ namespace DtoImporterService
var book = DbContext.Books.Add(new Book(
new AudibleProductId(item.ProductId),
title,
item.TitleWithSubtitle,
item.Description,
item.LengthInMinutes,
authors,

View File

@@ -70,12 +70,12 @@ namespace FileLiberator
var api = await InternalUtilities.AudibleApiActions.GetApiAsync(libraryBook.Account, libraryBook.Book.Locale);
var contentLic = await api.GetDownloadLicenseAsync(libraryBook.Book.AudibleProductId);
var aaxcDecryptDlLic = new DownloadLicense
(
contentLic.ContentMetadata?.ContentUrl?.OfflineUrl,
contentLic.Voucher?.Key,
contentLic.Voucher?.Iv,
contentLic?.ContentMetadata?.ContentUrl?.OfflineUrl,
contentLic?.Voucher?.Key,
contentLic?.Voucher?.Iv,
Resources.UserAgent
);

View File

@@ -48,7 +48,11 @@ namespace FileManager
public object GetObject(string propertyName) => persistentDictionary.GetObject(propertyName);
public void SetObject(string propertyName, object newValue) => persistentDictionary.SetNonString(propertyName, newValue);
public void SetWithJsonPath(string jsonPath, string propertyName, string newValue, bool suppressLogging = false) => persistentDictionary.SetWithJsonPath(jsonPath, propertyName, newValue, suppressLogging);
/// <summary>WILL ONLY set if already present. WILL NOT create new</summary>
/// <returns>Value was changed</returns>
public bool SetWithJsonPath(string jsonPath, string propertyName, string newValue, bool suppressLogging = false)
=> persistentDictionary.SetWithJsonPath(jsonPath, propertyName, newValue, suppressLogging);
public string SettingsFilePath => Path.Combine(LibationFiles, "Settings.json");
@@ -65,6 +69,38 @@ namespace FileManager
public bool Exists(string propertyName) => persistentDictionary.Exists(propertyName);
#region MainForm: X, Y, Width, Height, MainFormIsMaximized
public int MainFormX
{
get => persistentDictionary.GetNonString<int>(nameof(MainFormX));
set => persistentDictionary.SetNonString(nameof(MainFormX), value);
}
public int MainFormY
{
get => persistentDictionary.GetNonString<int>(nameof(MainFormY));
set => persistentDictionary.SetNonString(nameof(MainFormY), value);
}
public int MainFormWidth
{
get => persistentDictionary.GetNonString<int>(nameof(MainFormWidth));
set => persistentDictionary.SetNonString(nameof(MainFormWidth), value);
}
public int MainFormHeight
{
get => persistentDictionary.GetNonString<int>(nameof(MainFormHeight));
set => persistentDictionary.SetNonString(nameof(MainFormHeight), value);
}
public bool MainFormIsMaximized
{
get => persistentDictionary.GetNonString<bool>(nameof(MainFormIsMaximized));
set => persistentDictionary.SetNonString(nameof(MainFormIsMaximized), value);
}
#endregion
[Description("Location for book storage. Includes destination of newly liberated books")]
public string Books
{
@@ -187,7 +223,12 @@ namespace FileManager
}
set
{
persistentDictionary.SetWithJsonPath("Serilog", "MinimumLevel", value.ToString());
var valueWasChanged = persistentDictionary.SetWithJsonPath("Serilog", "MinimumLevel", value.ToString());
if (!valueWasChanged)
{
Log.Logger.Information("LogLevel.set attempt. No change");
return;
}
configuration.Reload();
@@ -231,8 +272,9 @@ namespace FileManager
// Config init in Program.ensureSerilogConfig() only happens when serilog setting is first created (prob on 1st run).
// This Set() enforces current LibationFiles every time we restart Libation or redirect LibationFiles
var logPath = Path.Combine(LibationFiles, "Log.log");
SetWithJsonPath("Serilog.WriteTo[1].Args", "path", logPath, true);
configuration?.Reload();
bool settingWasChanged = SetWithJsonPath("Serilog.WriteTo[1].Args", "path", logPath, true);
if (settingWasChanged)
configuration?.Reload();
return libationFilesPathCache;
}
@@ -275,19 +317,8 @@ namespace FileManager
return valueFinal;
}
public bool TrySetLibationFiles(string directory)
public void SetLibationFiles(string directory)
{
// this is WRONG. need to MOVE settings; not DELETE them
//// if moving from default, delete old settings file and dir (if empty)
//if (LibationFiles.EqualsInsensitive(AppDir))
//{
// File.Delete(SettingsFilePath);
// System.Threading.Thread.Sleep(100);
// if (!Directory.EnumerateDirectories(AppDir).Any() && !Directory.EnumerateFiles(AppDir).Any())
// Directory.Delete(AppDir);
//}
libationFilesPathCache = null;
var startingContents = File.ReadAllText(APPSETTINGS_JSON);
@@ -297,7 +328,7 @@ namespace FileManager
var endingContents = JsonConvert.SerializeObject(jObj, Formatting.Indented);
if (startingContents == endingContents)
return true;
return;
// now it's set in the file again but no settings have moved yet
File.WriteAllText(APPSETTINGS_JSON, endingContents);
@@ -307,13 +338,6 @@ namespace FileManager
Log.Logger.Information("Libation files changed {@DebugInfo}", new { APPSETTINGS_JSON, LIBATION_FILES_KEY, directory });
}
catch { }
//// attempting this will try to change the settings file which has not yet been moved
//// after this is fixed, can remove it from Program.configureLogging()
// var logPath = Path.Combine(LibationFiles, "Log.log");
// SetWithJsonPath("Serilog.WriteTo[1].Args", "path", logPath, true);
return true;
}
#endregion
}

View File

@@ -142,33 +142,44 @@ namespace FileManager
catch { }
}
public void SetWithJsonPath(string jsonPath, string propertyName, string newValue, bool suppressLogging = false)
/// <summary>WILL ONLY set if already present. WILL NOT create new</summary>
/// <returns>Value was changed</returns>
public bool SetWithJsonPath(string jsonPath, string propertyName, string newValue, bool suppressLogging = false)
{
if (IsReadOnly)
return;
return false;
var path = $"{jsonPath}.{propertyName}";
{
// only do this check in string cache, NOT object cache
if (stringCache.ContainsKey(path) && stringCache[path] == newValue)
return;
return false;
// set cache
stringCache[path] = newValue;
}
lock (locker)
try
{
var jObject = readFile();
var token = jObject.SelectToken(jsonPath);
var oldValue = token.Value<string>(propertyName);
lock (locker)
{
var jObject = readFile();
var token = jObject.SelectToken(jsonPath);
if (token is null || token[propertyName] is null)
return false;
if (oldValue == newValue)
return;
var oldValue = token.Value<string>(propertyName);
if (oldValue == newValue)
return false;
token[propertyName] = newValue;
File.WriteAllText(Filepath, JsonConvert.SerializeObject(jObject, Formatting.Indented));
token[propertyName] = newValue;
File.WriteAllText(Filepath, JsonConvert.SerializeObject(jObject, Formatting.Indented));
}
}
catch (Exception exDebug)
{
return false;
}
if (!suppressLogging)
@@ -180,6 +191,8 @@ namespace FileManager
}
catch { }
}
return true;
}
private static string formatValueForLog(string value)

View File

@@ -13,7 +13,7 @@
<!-- <PublishSingleFile>true</PublishSingleFile> -->
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
<Version>5.3.2.1</Version>
<Version>5.3.9.2</Version>
</PropertyGroup>
<ItemGroup>

View File

@@ -81,7 +81,7 @@ namespace LibationLauncher
// check for existing settigns in default location
var defaultSettingsFile = Path.Combine(defaultLibationFilesDir, "Settings.json");
if (Configuration.SettingsFileIsValid(defaultSettingsFile))
config.TrySetLibationFiles(defaultLibationFilesDir);
config.SetLibationFiles(defaultLibationFilesDir);
if (config.LibationSettingsAreValid)
return;
@@ -94,7 +94,7 @@ namespace LibationLauncher
}
if (setupDialog.IsNewUser)
config.TrySetLibationFiles(defaultLibationFilesDir);
config.SetLibationFiles(defaultLibationFilesDir);
else if (setupDialog.IsReturningUser)
{
var libationFilesDialog = new LibationFilesDialog();
@@ -105,7 +105,7 @@ namespace LibationLauncher
return;
}
config.TrySetLibationFiles(libationFilesDialog.SelectedDirectory);
config.SetLibationFiles(libationFilesDialog.SelectedDirectory);
if (config.LibationSettingsAreValid)
return;
@@ -328,19 +328,7 @@ namespace LibationLauncher
DecryptInProgressFiles = Directory.EnumerateFiles(AudibleFileStorage.DecryptInProgress).Count(),
});
// when turning on debug (and especially Verbose) to share logs, some privacy settings may not be obscured
if (Log.Logger.IsVerboseEnabled())
MessageBox.Show(@"
Warning: verbose logging is enabled.
This should be used for debugging only. It creates many
more logs and debug files, neither of which are as
strictly anonomous.
When you are finished debugging, it's highly recommended
to set your debug MinimumLevel to Information and restart
Libation.
".Trim(), "Verbose logging enabled", MessageBoxButtons.OK, MessageBoxIcon.Warning);
MessageBoxVerboseLoggingWarning.ShowIfTrue();
}
private static void checkForUpdate(Configuration config)
@@ -351,7 +339,7 @@ Libation.
try
{
// timed out
var latest = getLatestRelease(TimeSpan.FromSeconds(30));
var latest = getLatestRelease(TimeSpan.FromSeconds(10));
if (latest is null)
return;
@@ -388,6 +376,11 @@ Libation.
return;
selectedPath = fileSelector.FileName;
}
catch (AggregateException aggEx)
{
Log.Logger.Error(aggEx, "Checking for new version too often");
return;
}
catch (Exception ex)
{
MessageBoxAlertAdmin.Show("Error checking for update", "Error checking for update", ex);

View File

@@ -3,6 +3,7 @@ using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;
using DataLayer;
using Dinah.Core;
using Dinah.Core.ErrorHandling;
using Dinah.Core.Windows.Forms;
using FileLiberator;
@@ -440,7 +441,26 @@ namespace LibationWinForms.BookLiberation
LogMe.Error("ERROR. All books have not been processed. Most recent book: processing failed");
var dialogResult = MessageBox.Show(SkipDialogText, "Skip importing this book?", SkipDialogButtons, MessageBoxIcon.Question);
string details;
try
{
static string trunc(string str)
=> string.IsNullOrWhiteSpace(str) ? "[empty]"
: (str.Length > 50) ? $"{str.Truncate(47)}..."
: str;
details =
$@" Title: {libraryBook.Book.Title}
ID: {libraryBook.Book.AudibleProductId}
Author: {trunc(libraryBook.Book.AuthorNames)}
Narr: {trunc(libraryBook.Book.NarratorNames)}";
}
catch
{
details = "[Error retrieving details]";
}
var dialogResult = MessageBox.Show(string.Format(SkipDialogText, details), "Skip importing this book?", SkipDialogButtons, MessageBoxIcon.Question);
if (dialogResult == DialogResult.Abort)
return false;
@@ -464,6 +484,7 @@ Created new 'skip' file
protected override string SkipDialogText => @"
An error occurred while trying to process this book. Skip this book permanently?
{0}
- Click YES to skip this book permanently.
@@ -487,7 +508,8 @@ An error occurred while trying to process this book. Skip this book permanently?
class BackupLoop : BackupRunner
{
protected override string SkipDialogText => @"
An error occurred while trying to process this book
An error occurred while trying to process this book.
{0}
- ABORT: stop processing books.

View File

@@ -14,49 +14,74 @@ namespace LibationWinForms.Dialogs.Login
{
private RadioButton[] radioButtons { get; }
AudibleApi.MfaConfig _mfaConfig { get; }
public MfaDialog(AudibleApi.MfaConfig mfaConfig)
{
InitializeComponent();
_mfaConfig = mfaConfig;
radioButtons = new[] { this.radioButton1, this.radioButton2, this.radioButton3 };
// optional string settings
if (!string.IsNullOrWhiteSpace(mfaConfig.Title))
this.Text = mfaConfig.Title;
setOptional(this.radioButton1, mfaConfig.Button1Text);
setOptional(this.radioButton2, mfaConfig.Button2Text);
setOptional(this.radioButton3, mfaConfig.Button3Text);
// mandatory values
radioButton1.Name = mfaConfig.Button1Name;
radioButton1.Tag = mfaConfig.Button1Value;
setRadioButton(0, this.radioButton1);
setRadioButton(1, this.radioButton2);
setRadioButton(2, this.radioButton3);
radioButton2.Name = mfaConfig.Button2Name;
radioButton2.Tag = mfaConfig.Button2Value;
radioButton3.Name = mfaConfig.Button3Name;
radioButton3.Tag = mfaConfig.Button3Value;
Serilog.Log.Logger.Information("{@DebugInfo}", new {
paramButtonCount = mfaConfig.Buttons.Count,
visibleRadioButtonCount = radioButtons.Count(rb => rb.Visible)
});
}
private static void setOptional(RadioButton radioButton, string text)
private void setRadioButton(int pos, RadioButton rb)
{
if (!string.IsNullOrWhiteSpace(text))
radioButton.Text = text;
if (_mfaConfig.Buttons.Count <= pos)
{
rb.Checked = false;
rb.Enabled = false;
rb.Visible = false;
return;
}
var btn = _mfaConfig.Buttons[pos];
// optional
if (!string.IsNullOrWhiteSpace(btn.Text))
rb.Text = btn.Text;
// mandatory values
rb.Name = btn.Name;
rb.Tag = btn.Value;
}
public string SelectedName { get; private set; }
public string SelectedValue { get; private set; }
private void submitBtn_Click(object sender, EventArgs e)
{
Serilog.Log.Logger.Debug("RadioButton states: {@DebugInfo}", new {
Serilog.Log.Logger.Information("RadioButton states: {@DebugInfo}", new {
rb1_visible = radioButton1.Visible,
rb1_checked = radioButton1.Checked,
r21_visible = radioButton2.Visible,
r21_checked = radioButton2.Checked,
rb3_visible = radioButton3.Visible,
rb3_checked = radioButton3.Checked
});
var selected = radioButtons.Single(rb => rb.Checked);
var selected = radioButtons.FirstOrDefault(rb => rb.Checked);
if (selected is null)
{
MessageBox.Show("No MFA option selected", "None selected", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
Serilog.Log.Logger.Debug("Selected: {@DebugInfo}", new { isSelected = selected is not null, name = selected?.Name, value = selected?.Tag });
Serilog.Log.Logger.Information("Selected: {@DebugInfo}", new { isSelected = selected is not null, name = selected?.Name, value = selected?.Tag });
SelectedName = selected.Name;
SelectedValue = (string)selected.Tag;

View File

@@ -17,7 +17,7 @@ namespace LibationWinForms.Login
public string Get2faCode()
{
using var dialog = new _2faCodeDialog();
if (dialog.ShowDialog() == System.Windows.Forms.DialogResult.OK)
if (showDialog(dialog))
return dialog.Code;
return null;
}
@@ -25,7 +25,7 @@ namespace LibationWinForms.Login
public string GetCaptchaAnswer(byte[] captchaImage)
{
using var dialog = new CaptchaDialog(captchaImage);
if (dialog.ShowDialog() == System.Windows.Forms.DialogResult.OK)
if (showDialog(dialog))
return dialog.Answer;
return null;
}
@@ -33,7 +33,7 @@ namespace LibationWinForms.Login
public (string name, string value) GetMfaChoice(MfaConfig mfaConfig)
{
using var dialog = new MfaDialog(mfaConfig);
if (dialog.ShowDialog() == System.Windows.Forms.DialogResult.OK)
if (showDialog(dialog))
return (dialog.SelectedName, dialog.SelectedValue);
return (null, null);
}
@@ -41,7 +41,7 @@ namespace LibationWinForms.Login
public (string email, string password) GetLogin()
{
using var dialog = new AudibleLoginDialog(_account);
if (dialog.ShowDialog() == System.Windows.Forms.DialogResult.OK)
if (showDialog(dialog))
return (dialog.Email, dialog.Password);
return (null, null);
}
@@ -49,7 +49,15 @@ namespace LibationWinForms.Login
public void ShowApprovalNeeded()
{
using var dialog = new ApprovalNeededDialog();
dialog.ShowDialog();
showDialog(dialog);
}
/// <returns>True if ShowDialog's DialogResult == OK</returns>
private static bool showDialog(System.Windows.Forms.Form dialog)
{
var result = dialog.ShowDialog();
Serilog.Log.Logger.Debug("{@DebugInfo}", new { DialogResult = result });
return result == System.Windows.Forms.DialogResult.OK;
}
}
}

View File

@@ -94,7 +94,16 @@ namespace LibationWinForms.Dialogs
config.Books = newBooks;
config.LogLevel = (Serilog.Events.LogEventLevel)loggingLevelCb.SelectedItem;
{
var logLevelOld = config.LogLevel;
var logLevelNew = (Serilog.Events.LogEventLevel)loggingLevelCb.SelectedItem;
config.LogLevel = logLevelNew;
// only warn if changed during this time. don't want to warn every time user happens to change settings while level is verbose
if (logLevelOld != logLevelNew)
MessageBoxVerboseLoggingWarning.ShowIfTrue();
}
config.AllowLibationFixup = allowLibationFixupCbox.Checked;
config.DecryptToLossy = convertLossyRb.Checked;

View File

@@ -51,7 +51,6 @@
this.settingsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.accountsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.basicSettingsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.advancedSettingsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.statusStrip1 = new System.Windows.Forms.StatusStrip();
this.visibleCountLbl = new System.Windows.Forms.ToolStripStatusLabel();
this.springLbl = new System.Windows.Forms.ToolStripStatusLabel();
@@ -232,8 +231,7 @@
//
this.settingsToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.accountsToolStripMenuItem,
this.basicSettingsToolStripMenuItem,
this.advancedSettingsToolStripMenuItem});
this.basicSettingsToolStripMenuItem});
this.settingsToolStripMenuItem.Name = "settingsToolStripMenuItem";
this.settingsToolStripMenuItem.Size = new System.Drawing.Size(61, 20);
this.settingsToolStripMenuItem.Text = "&Settings";
@@ -241,24 +239,17 @@
// accountsToolStripMenuItem
//
this.accountsToolStripMenuItem.Name = "accountsToolStripMenuItem";
this.accountsToolStripMenuItem.Size = new System.Drawing.Size(181, 22);
this.accountsToolStripMenuItem.Size = new System.Drawing.Size(133, 22);
this.accountsToolStripMenuItem.Text = "&Accounts...";
this.accountsToolStripMenuItem.Click += new System.EventHandler(this.accountsToolStripMenuItem_Click);
//
// basicSettingsToolStripMenuItem
//
this.basicSettingsToolStripMenuItem.Name = "basicSettingsToolStripMenuItem";
this.basicSettingsToolStripMenuItem.Size = new System.Drawing.Size(181, 22);
this.basicSettingsToolStripMenuItem.Size = new System.Drawing.Size(133, 22);
this.basicSettingsToolStripMenuItem.Text = "&Settings...";
this.basicSettingsToolStripMenuItem.Click += new System.EventHandler(this.basicSettingsToolStripMenuItem_Click);
//
// advancedSettingsToolStripMenuItem
//
this.advancedSettingsToolStripMenuItem.Name = "advancedSettingsToolStripMenuItem";
this.advancedSettingsToolStripMenuItem.Size = new System.Drawing.Size(181, 22);
this.advancedSettingsToolStripMenuItem.Text = "&Move settings files...";
this.advancedSettingsToolStripMenuItem.Click += new System.EventHandler(this.advancedSettingsToolStripMenuItem_Click);
//
// statusStrip1
//
this.statusStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
@@ -325,6 +316,7 @@
this.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
this.Name = "Form1";
this.Text = "Libation: Liberate your Library";
this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.Form1_FormClosing);
this.Load += new System.EventHandler(this.Form1_Load);
this.menuStrip1.ResumeLayout(false);
this.menuStrip1.PerformLayout();
@@ -359,7 +351,6 @@
private System.Windows.Forms.ToolStripMenuItem editQuickFiltersToolStripMenuItem;
private System.Windows.Forms.ToolStripSeparator toolStripSeparator1;
private System.Windows.Forms.ToolStripMenuItem basicSettingsToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem advancedSettingsToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem accountsToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem scanLibraryOfAllAccountsToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem scanLibraryOfSomeAccountsToolStripMenuItem;

View File

@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;
using ApplicationServices;
using DataLayer;
@@ -33,6 +34,31 @@ namespace LibationWinForms
beginBookBackupsToolStripMenuItem_format = beginBookBackupsToolStripMenuItem.Text;
beginPdfBackupsToolStripMenuItem_format = beginPdfBackupsToolStripMenuItem.Text;
// after backing up formats: can set default/temp visible text
backupsCountsLbl.Text = "[Calculating backed up book quantities]";
pdfsCountsLbl.Text = "[Calculating backed up PDFs]";
setVisibleCount(null, 0);
if (this.DesignMode)
return;
// independent UI updates
this.Load += setBackupCountsAsync;
this.Load += (_, __) => RestoreSizeAndLocation();
this.Load += (_, __) => RefreshImportMenu();
// start background service
this.Load += (_, __) => startBackgroundImageDownloader();
}
private static void startBackgroundImageDownloader()
{
// load default/missing cover images. this will also initiate the background image downloader
var format = System.Drawing.Imaging.ImageFormat.Jpeg;
PictureStorage.SetDefaultImage(PictureSize._80x80, Properties.Resources.default_cover_80x80.ToBytes(format));
PictureStorage.SetDefaultImage(PictureSize._300x300, Properties.Resources.default_cover_300x300.ToBytes(format));
PictureStorage.SetDefaultImage(PictureSize._500x500, Properties.Resources.default_cover_500x500.ToBytes(format));
}
private void Form1_Load(object sender, EventArgs e)
@@ -40,29 +66,89 @@ namespace LibationWinForms
if (this.DesignMode)
return;
// load default/missing cover images. this will also initiate the background image downloader
var format = System.Drawing.Imaging.ImageFormat.Jpeg;
PictureStorage.SetDefaultImage(PictureSize._80x80, Properties.Resources.default_cover_80x80.ToBytes(format));
PictureStorage.SetDefaultImage(PictureSize._300x300, Properties.Resources.default_cover_300x300.ToBytes(format));
PictureStorage.SetDefaultImage(PictureSize._500x500, Properties.Resources.default_cover_500x500.ToBytes(format));
RefreshImportMenu();
setVisibleCount(null, 0);
reloadGrid();
reloadGrid();
// also applies filter. ONLY call AFTER loading grid
loadInitialQuickFilterState();
// init bottom counts
backupsCountsLbl.Text = "[Calculating backed up book quantities]";
pdfsCountsLbl.Text = "[Calculating backed up PDFs]";
setBackupCounts(null, null);
}
#region reload grid
bool isProcessingGridSelect = false;
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
SaveSizeAndLocation();
}
private void RestoreSizeAndLocation()
{
var config = Configuration.Instance;
var width = config.MainFormWidth;
var height = config.MainFormHeight;
// too small -- something must have gone wrong. use defaults
if (width < 25 || height < 25)
{
width = 1023;
height = 578;
}
// Fit to the current screen size in case the screen resolution changed since the size was last persisted
if (width > Screen.PrimaryScreen.WorkingArea.Width)
width = Screen.PrimaryScreen.WorkingArea.Width;
if (height > Screen.PrimaryScreen.WorkingArea.Height)
height = Screen.PrimaryScreen.WorkingArea.Height;
var x = config.MainFormX;
var y = config.MainFormY;
var rect = new System.Drawing.Rectangle(x, y, width, height);
// is proposed rect on a screen?
if (Screen.AllScreens.Any(screen => screen.WorkingArea.Contains(rect)))
{
this.StartPosition = FormStartPosition.Manual;
this.DesktopBounds = rect;
}
else
{
this.StartPosition = FormStartPosition.WindowsDefaultLocation;
this.Size = rect.Size;
}
// FINAL: for Maximized: start normal state, set size and location, THEN set max state
this.WindowState = config.MainFormIsMaximized ? FormWindowState.Maximized : FormWindowState.Normal;
}
private void SaveSizeAndLocation()
{
System.Drawing.Point location;
System.Drawing.Size size;
// save location and size if the state is normal
if (this.WindowState == FormWindowState.Normal)
{
location = this.Location;
size = this.Size;
}
else
{
// save the RestoreBounds if the form is minimized or maximized
location = this.RestoreBounds.Location;
size = this.RestoreBounds.Size;
}
var config = Configuration.Instance;
config.MainFormX = location.X;
config.MainFormY = location.Y;
config.MainFormWidth = size.Width;
config.MainFormHeight = size.Height;
config.MainFormIsMaximized = this.WindowState == FormWindowState.Maximized;
}
#region reload grid
bool isProcessingGridSelect = false;
private void reloadGrid()
{
// suppressed filter while init'ing UI
@@ -84,14 +170,14 @@ namespace LibationWinForms
{
gridPanel.Controls.Remove(currProductsGrid);
currProductsGrid.VisibleCountChanged -= setVisibleCount;
currProductsGrid.BackupCountsChanged -= setBackupCounts;
currProductsGrid.BackupCountsChanged -= setBackupCountsAsync;
currProductsGrid.Dispose();
}
currProductsGrid = new ProductsGrid { Dock = DockStyle.Fill };
currProductsGrid.VisibleCountChanged += setVisibleCount;
currProductsGrid.BackupCountsChanged += setBackupCounts;
gridPanel.Controls.Add(currProductsGrid);
currProductsGrid.BackupCountsChanged += setBackupCountsAsync;
gridPanel.UIThread(() => gridPanel.Controls.Add(currProductsGrid));
currProductsGrid.Display();
}
ResumeLayout();
@@ -103,15 +189,17 @@ namespace LibationWinForms
#endregion
#region bottom: backup counts
private void setBackupCounts(object _, object __)
private async void setBackupCountsAsync(object _, object __)
{
var books = DbContexts.GetContext()
.GetLibrary_Flat_NoTracking()
.Select(sp => sp.Book)
.ToList();
await Task.Run(() => {
var books = DbContexts.GetContext()
.GetLibrary_Flat_NoTracking()
.Select(sp => sp.Book)
.ToList();
setBookBackupCounts(books);
setPdfBackupCounts(books);
setBookBackupCounts(books);
setPdfBackupCounts(books);
});
}
enum AudioFileState { full, aax, none }
private void setBookBackupCounts(IEnumerable<Book> books)
@@ -395,31 +483,6 @@ namespace LibationWinForms
private void accountsToolStripMenuItem_Click(object sender, EventArgs e) => new AccountsDialog(this).ShowDialog();
private void basicSettingsToolStripMenuItem_Click(object sender, EventArgs e) => new SettingsDialog().ShowDialog();
private void advancedSettingsToolStripMenuItem_Click(object sender, EventArgs e)
{
var libationFilesDialog = new LibationFilesDialog();
if (libationFilesDialog.ShowDialog() != DialogResult.OK)
return;
// no change
if (System.IO.Path.GetFullPath(libationFilesDialog.SelectedDirectory).EqualsInsensitive(System.IO.Path.GetFullPath(Configuration.Instance.LibationFiles)))
return;
if (!Configuration.Instance.TrySetLibationFiles(libationFilesDialog.SelectedDirectory))
{
MessageBox.Show("Not saving change to Libation Files location. This folder does not exist:\r\n" + libationFilesDialog.SelectedDirectory, "Error saving change", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
MessageBox.Show(
"You have changed a file path important for this program. All files will remain in their original location; nothing will be moved. Libation must be restarted so these changes are handled correctly.",
"Closing Libation",
MessageBoxButtons.OK,
MessageBoxIcon.Exclamation);
Application.Exit();
Environment.Exit(0);
}
#endregion
}
#endregion
}
}

View File

@@ -0,0 +1,27 @@
using System;
using System.Windows.Forms;
using Dinah.Core.Logging;
using Serilog;
namespace LibationWinForms
{
public static class MessageBoxVerboseLoggingWarning
{
public static void ShowIfTrue()
{
// when turning on debug (and especially Verbose) to share logs, some privacy settings may not be obscured
if (Log.Logger.IsVerboseEnabled())
MessageBox.Show(@"
Warning: verbose logging is enabled.
This should be used for debugging only. It creates many
more logs and debug files, neither of which are as
strictly anonomous.
When you are finished debugging, it's highly recommended
to set your debug MinimumLevel to Information and restart
Libation.
".Trim(), "Verbose logging enabled", MessageBoxButtons.OK, MessageBoxIcon.Warning);
}
}
}