From 559977ce0b7a74de9b71c91b1d71ebe2ad42727b Mon Sep 17 00:00:00 2001 From: Mbucari Date: Wed, 8 Mar 2023 11:26:07 -0700 Subject: [PATCH] Add 'Unavailable' book and pdf counts. --- Source/ApplicationServices/LibraryCommands.cs | 72 ++++++++++++++----- .../ViewModels/MainWindowViewModel.cs | 18 ----- .../Views/MainWindow.VisibleBooks.cs | 9 ++- .../LibationAvalonia/Views/MainWindow.axaml | 2 +- .../Views/ProductsDisplay.axaml.cs | 25 ++++--- Source/LibationWinForms/Form1.BackupCounts.cs | 36 ++-------- Source/LibationWinForms/Form1.Designer.cs | 12 +--- Source/LibationWinForms/Form1.VisibleBooks.cs | 20 ++---- 8 files changed, 85 insertions(+), 109 deletions(-) diff --git a/Source/ApplicationServices/LibraryCommands.cs b/Source/ApplicationServices/LibraryCommands.cs index e5a9b04f..235bade3 100644 --- a/Source/ApplicationServices/LibraryCommands.cs +++ b/Source/ApplicationServices/LibraryCommands.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Text; using System.Threading.Tasks; using AudibleApi; using AudibleUtilities; @@ -453,41 +454,74 @@ namespace ApplicationServices // below are queries, not commands. maybe I should make a LibraryQueries. except there's already one of those... - public record LibraryStats(int booksFullyBackedUp, int booksDownloadedOnly, int booksNoProgress, int booksError, int pdfsDownloaded, int pdfsNotDownloaded) + public record LibraryStats(int booksFullyBackedUp, int booksDownloadedOnly, int booksNoProgress, int booksError, int booksUnavailable, int pdfsDownloaded, int pdfsNotDownloaded, int pdfsUnavailable) { public int PendingBooks => booksNoProgress + booksDownloadedOnly; public bool HasPendingBooks => PendingBooks > 0; - public bool HasBookResults => 0 < (booksFullyBackedUp + booksDownloadedOnly + booksNoProgress + booksError); - public bool HasPdfResults => 0 < (pdfsNotDownloaded + pdfsDownloaded); - } - public static LibraryStats GetCounts() + public bool HasBookResults => 0 < (booksFullyBackedUp + booksDownloadedOnly + booksNoProgress + booksError + booksUnavailable); + public bool HasPdfResults => 0 < (pdfsNotDownloaded + pdfsDownloaded + pdfsUnavailable); + + public string StatusString => HasPdfResults ? $"{toBookStatusString()} | {toPdfStatusString()}" : toBookStatusString(); + + private string toBookStatusString() + { + if (!HasBookResults) return "No books. Begin by importing your library"; + + if (!HasPendingBooks && booksError + booksUnavailable == 0) return $"All {"book".PluralizeWithCount(booksFullyBackedUp)} backed up"; + + var sb = new StringBuilder($"BACKUPS: No progress: {booksNoProgress} In process: {booksDownloadedOnly} Fully backed up: {booksFullyBackedUp}"); + + if (booksError > 0) + sb.Append($" Errors: {booksError}"); + if (booksUnavailable > 0) + sb.Append($" Unavailable: {booksUnavailable}"); + + return sb.ToString(); + } + + private string toPdfStatusString() + { + if (pdfsNotDownloaded + pdfsUnavailable == 0) return $"All {pdfsDownloaded} PDFs downloaded"; + + var sb = new StringBuilder($"PDFs: NOT d/l'ed: {pdfsNotDownloaded} Downloaded: {pdfsDownloaded}"); + + if (pdfsUnavailable > 0) + sb.Append($" Unavailable: {pdfsUnavailable}"); + + return sb.ToString(); + } + } + public static LibraryStats GetCounts(IEnumerable libraryBooks = null) { - var libraryBooks = DbContexts.GetLibrary_Flat_NoTracking(); + libraryBooks ??= DbContexts.GetLibrary_Flat_NoTracking(); var results = libraryBooks .AsParallel() - .Where(lb => !lb.AbsentFromLastScan) - .Select(lb => Liberated_Status(lb.Book)) + .Select(lb => new { absent = lb.AbsentFromLastScan, status = Liberated_Status(lb.Book) }) .ToList(); - var booksFullyBackedUp = results.Count(r => r == LiberatedStatus.Liberated); - var booksDownloadedOnly = results.Count(r => r == LiberatedStatus.PartialDownload); - var booksNoProgress = results.Count(r => r == LiberatedStatus.NotLiberated); - var booksError = results.Count(r => r == LiberatedStatus.Error); - Log.Logger.Information("Book counts. {@DebugInfo}", new { total = results.Count, booksFullyBackedUp, booksDownloadedOnly, booksNoProgress, booksError }); + var booksFullyBackedUp = results.Count(r => r.status == LiberatedStatus.Liberated); + var booksDownloadedOnly = results.Count(r => !r.absent && r.status == LiberatedStatus.PartialDownload); + var booksNoProgress = results.Count(r => !r.absent && r.status == LiberatedStatus.NotLiberated); + var booksError = results.Count(r => r.status == LiberatedStatus.Error); + var booksUnavailable = results.Count(r => r.absent && r.status is LiberatedStatus.NotLiberated or LiberatedStatus.PartialDownload); - var boolResults = libraryBooks + Log.Logger.Information("Book counts. {@DebugInfo}", new { total = results.Count, booksFullyBackedUp, booksDownloadedOnly, booksNoProgress, booksError, booksUnavailable }); + + var pdfResults = libraryBooks .AsParallel() .Where(lb => lb.Book.HasPdf()) - .Select(lb => Pdf_Status(lb.Book)) + .Select(lb => new { absent = lb.AbsentFromLastScan, status = Pdf_Status(lb.Book) }) .ToList(); - var pdfsDownloaded = boolResults.Count(r => r == LiberatedStatus.Liberated); - var pdfsNotDownloaded = boolResults.Count(r => r == LiberatedStatus.NotLiberated); - Log.Logger.Information("PDF counts. {@DebugInfo}", new { total = boolResults.Count, pdfsDownloaded, pdfsNotDownloaded }); + var pdfsDownloaded = pdfResults.Count(r => r.status == LiberatedStatus.Liberated); + var pdfsNotDownloaded = pdfResults.Count(r => !r.absent && r.status == LiberatedStatus.NotLiberated); + var pdfsUnavailable = pdfResults.Count(r => r.absent && r.status == LiberatedStatus.NotLiberated); - return new(booksFullyBackedUp, booksDownloadedOnly, booksNoProgress, booksError, pdfsDownloaded, pdfsNotDownloaded); + Log.Logger.Information("PDF counts. {@DebugInfo}", new { total = pdfResults.Count, pdfsDownloaded, pdfsNotDownloaded, pdfsUnavailable }); + + return new(booksFullyBackedUp, booksDownloadedOnly, booksNoProgress, booksError, booksUnavailable, pdfsDownloaded, pdfsNotDownloaded, pdfsUnavailable); } } } diff --git a/Source/LibationAvalonia/ViewModels/MainWindowViewModel.cs b/Source/LibationAvalonia/ViewModels/MainWindowViewModel.cs index db96c036..ba953362 100644 --- a/Source/LibationAvalonia/ViewModels/MainWindowViewModel.cs +++ b/Source/LibationAvalonia/ViewModels/MainWindowViewModel.cs @@ -1,6 +1,4 @@ using ApplicationServices; -using Avalonia.Media.Imaging; -using Dinah.Core; using LibationFileManager; using ReactiveUI; @@ -167,18 +165,6 @@ namespace LibationAvalonia.ViewModels { this.RaiseAndSetIfChanged(ref _libraryStats, value); - var backupsCountText - = !LibraryStats.HasBookResults ? "No books. Begin by importing your library" - : !LibraryStats.HasPendingBooks ? $"All {"book".PluralizeWithCount(LibraryStats.booksFullyBackedUp)} backed up" - : $"BACKUPS: No progress: {LibraryStats.booksNoProgress} In process: {LibraryStats.booksDownloadedOnly} Fully backed up: {LibraryStats.booksFullyBackedUp} {(LibraryStats.booksError > 0 ? $" Errors : {LibraryStats.booksError}" : "")}"; - - var pdfCountText - = !LibraryStats.HasPdfResults ? "" - : LibraryStats.pdfsNotDownloaded == 0 ? $" | All {LibraryStats.pdfsDownloaded} PDFs downloaded" - : $" | PDFs: NOT d/l'ed: {LibraryStats.pdfsNotDownloaded} Downloaded: {LibraryStats.pdfsDownloaded}"; - - StatusCountText = backupsCountText + pdfCountText; - BookBackupsToolStripText = LibraryStats.HasPendingBooks ? $"Begin _Book and PDF Backups: {LibraryStats.PendingBooks} remaining" @@ -189,21 +175,17 @@ namespace LibationAvalonia.ViewModels ? $"Begin _PDF Only Backups: {LibraryStats.pdfsNotDownloaded} remaining" : "All PDFs have been downloaded"; - this.RaisePropertyChanged(nameof(StatusCountText)); this.RaisePropertyChanged(nameof(BookBackupsToolStripText)); this.RaisePropertyChanged(nameof(PdfBackupsToolStripText)); } } - /// Bottom-left library statistics display text - public string StatusCountText { get; private set; } = "[Calculating backed up book quantities] | [Calculating backed up PDFs]"; /// The "Begin Book and PDF Backup" menu item header text public string BookBackupsToolStripText { get; private set; } = "Begin _Book and PDF Backups: 0"; /// The "Begin PDF Only Backup" menu item header text public string PdfBackupsToolStripText { get; private set; } = "Begin _PDF Only Backups: 0"; - /// The number of books visible in the Products Display that have not yet been liberated public int VisibleNotLiberated { diff --git a/Source/LibationAvalonia/Views/MainWindow.VisibleBooks.cs b/Source/LibationAvalonia/Views/MainWindow.VisibleBooks.cs index 492635db..caa5a52b 100644 --- a/Source/LibationAvalonia/Views/MainWindow.VisibleBooks.cs +++ b/Source/LibationAvalonia/Views/MainWindow.VisibleBooks.cs @@ -154,10 +154,9 @@ namespace LibationAvalonia.Views await Dispatcher.UIThread.InvokeAsync(setLiberatedVisibleMenuItem); } void setLiberatedVisibleMenuItem() - => _viewModel.VisibleNotLiberated - = _viewModel.ProductsDisplay - .GetVisibleBookEntries() - .Where(lb => !lb.AbsentFromLastScan) - .Count(lb => lb.Book.UserDefinedItem.BookStatus == LiberatedStatus.NotLiberated); + { + var libraryStats = LibraryCommands.GetCounts(_viewModel.ProductsDisplay.GetVisibleBookEntries()); + _viewModel.VisibleNotLiberated = libraryStats.PendingBooks; + } } } diff --git a/Source/LibationAvalonia/Views/MainWindow.axaml b/Source/LibationAvalonia/Views/MainWindow.axaml index ae60660e..f6490cd1 100644 --- a/Source/LibationAvalonia/Views/MainWindow.axaml +++ b/Source/LibationAvalonia/Views/MainWindow.axaml @@ -209,7 +209,7 @@ - + diff --git a/Source/LibationAvalonia/Views/ProductsDisplay.axaml.cs b/Source/LibationAvalonia/Views/ProductsDisplay.axaml.cs index 14e30db3..3e9f866a 100644 --- a/Source/LibationAvalonia/Views/ProductsDisplay.axaml.cs +++ b/Source/LibationAvalonia/Views/ProductsDisplay.axaml.cs @@ -31,17 +31,22 @@ namespace LibationAvalonia.Views if (Design.IsDesignMode) { using var context = DbContexts.GetContext(); - List sampleEntries = new() + List sampleEntries; + try { - //context.GetLibraryBook_Flat_NoTracking("B00DCD0OXU"), - context.GetLibraryBook_Flat_NoTracking("B002V8H7G4"), - context.GetLibraryBook_Flat_NoTracking("B017V4IWVG"), - context.GetLibraryBook_Flat_NoTracking("B017V4JA2Q"), - context.GetLibraryBook_Flat_NoTracking("B017V4NUPO"), - context.GetLibraryBook_Flat_NoTracking("B017V4NMX4"), - context.GetLibraryBook_Flat_NoTracking("B017V4NOZ0"), - context.GetLibraryBook_Flat_NoTracking("B017WJ5ZK6") - }; + sampleEntries = new() + { + //context.GetLibraryBook_Flat_NoTracking("B00DCD0OXU"),try{ + context.GetLibraryBook_Flat_NoTracking("B017WJ5ZK6"), + context.GetLibraryBook_Flat_NoTracking("B017V4IWVG"), + context.GetLibraryBook_Flat_NoTracking("B017V4JA2Q"), + context.GetLibraryBook_Flat_NoTracking("B017V4NUPO"), + context.GetLibraryBook_Flat_NoTracking("B017V4NMX4"), + context.GetLibraryBook_Flat_NoTracking("B017V4NOZ0"), + context.GetLibraryBook_Flat_NoTracking("B017WJ5ZK6") + }; + } + catch { sampleEntries = new(); } var pdvm = new ProductsDisplayViewModel(); pdvm.BindToGrid(sampleEntries); diff --git a/Source/LibationWinForms/Form1.BackupCounts.cs b/Source/LibationWinForms/Form1.BackupCounts.cs index f12c58ed..386c7afc 100644 --- a/Source/LibationWinForms/Form1.BackupCounts.cs +++ b/Source/LibationWinForms/Form1.BackupCounts.cs @@ -13,7 +13,6 @@ namespace LibationWinForms // init formattable beginBookBackupsToolStripMenuItem.Format(0); beginPdfBackupsToolStripMenuItem.Format(0); - pdfsCountsLbl.Text = "| [Calculating backed up PDFs]"; Load += setBackupCounts; LibraryCommands.LibrarySizeChanged += setBackupCounts; @@ -21,9 +20,8 @@ namespace LibationWinForms updateCountsBw.DoWork += UpdateCountsBw_DoWork; updateCountsBw.RunWorkerCompleted += exportMenuEnable; - updateCountsBw.RunWorkerCompleted += updateBottomBookNumbers; + updateCountsBw.RunWorkerCompleted += updateBottomStats; updateCountsBw.RunWorkerCompleted += update_BeginBookBackups_menuItem; - updateCountsBw.RunWorkerCompleted += updateBottomPdfNumbers; updateCountsBw.RunWorkerCompleted += udpate_BeginPdfOnlyBackups_menuItem; } @@ -52,27 +50,13 @@ namespace LibationWinForms Invoke(() => exportLibraryToolStripMenuItem.Enabled = libraryStats.HasBookResults); } - // this cannot be cleanly be FormattableToolStripMenuItem because of the optional "Errors" text - private const string backupsCountsLbl_Format = "BACKUPS: No progress: {0} In process: {1} Fully backed up: {2}"; - - private void updateBottomBookNumbers(object _, System.ComponentModel.RunWorkerCompletedEventArgs e) + private void updateBottomStats(object _, System.ComponentModel.RunWorkerCompletedEventArgs e) { var libraryStats = e.Result as LibraryCommands.LibraryStats; - - var formatString - = !libraryStats.HasBookResults ? "No books. Begin by importing your library" - : libraryStats.booksError > 0 ? backupsCountsLbl_Format + " Errors: {3}" - : libraryStats.HasPendingBooks ? backupsCountsLbl_Format - : $"All {"book".PluralizeWithCount(libraryStats.booksFullyBackedUp)} backed up"; - var statusStripText = string.Format(formatString, - libraryStats.booksNoProgress, - libraryStats.booksDownloadedOnly, - libraryStats.booksFullyBackedUp, - libraryStats.booksError); - statusStrip1.UIThreadAsync(() => backupsCountsLbl.Text = statusStripText); + statusStrip1.UIThreadAsync(() => backupsCountsLbl.Text = libraryStats.StatusString); } - // update 'begin book backups' menu item + // update 'begin book and pdf backups' menu item private void update_BeginBookBackups_menuItem(object _, System.ComponentModel.RunWorkerCompletedEventArgs e) { var libraryStats = e.Result as LibraryCommands.LibraryStats; @@ -88,18 +72,6 @@ namespace LibationWinForms }); } - private void updateBottomPdfNumbers(object _, System.ComponentModel.RunWorkerCompletedEventArgs e) - { - var libraryStats = e.Result as LibraryCommands.LibraryStats; - - // don't need to assign the output of Format(). It just makes this logic cleaner - var statusStripText - = !libraryStats.HasPdfResults ? "" - : libraryStats.pdfsNotDownloaded > 0 ? pdfsCountsLbl.Format(libraryStats.pdfsNotDownloaded, libraryStats.pdfsDownloaded) - : $"| All {libraryStats.pdfsDownloaded} PDFs downloaded"; - statusStrip1.UIThreadAsync(() => pdfsCountsLbl.Text = statusStripText); - } - // update 'begin pdf only backups' menu item private void udpate_BeginPdfOnlyBackups_menuItem(object _, System.ComponentModel.RunWorkerCompletedEventArgs e) { diff --git a/Source/LibationWinForms/Form1.Designer.cs b/Source/LibationWinForms/Form1.Designer.cs index e62fd0a4..ef404581 100644 --- a/Source/LibationWinForms/Form1.Designer.cs +++ b/Source/LibationWinForms/Form1.Designer.cs @@ -77,7 +77,6 @@ this.visibleCountLbl = new LibationWinForms.FormattableToolStripStatusLabel(); this.springLbl = new System.Windows.Forms.ToolStripStatusLabel(); this.backupsCountsLbl = new System.Windows.Forms.ToolStripStatusLabel(); - this.pdfsCountsLbl = new LibationWinForms.FormattableToolStripStatusLabel(); this.addQuickFilterBtn = new System.Windows.Forms.Button(); this.splitContainer1 = new System.Windows.Forms.SplitContainer(); this.panel1 = new System.Windows.Forms.Panel(); @@ -426,8 +425,7 @@ this.upgradePb, this.visibleCountLbl, this.springLbl, - this.backupsCountsLbl, - this.pdfsCountsLbl}); + this.backupsCountsLbl}); this.statusStrip1.Location = new System.Drawing.Point(0, 618); this.statusStrip1.Name = "statusStrip1"; this.statusStrip1.Padding = new System.Windows.Forms.Padding(1, 0, 16, 0); @@ -466,13 +464,6 @@ this.backupsCountsLbl.Size = new System.Drawing.Size(218, 17); this.backupsCountsLbl.Text = "[Calculating backed up book quantities]"; // - // pdfsCountsLbl - // - this.pdfsCountsLbl.FormatText = "| PDFs: NOT d/l\'ed: {0} Downloaded: {1}"; - this.pdfsCountsLbl.Name = "pdfsCountsLbl"; - this.pdfsCountsLbl.Size = new System.Drawing.Size(218, 17); - this.pdfsCountsLbl.Text = "| PDFs: NOT d/l\'ed: {0} Downloaded: {1}"; - // // addQuickFilterBtn // this.addQuickFilterBtn.Location = new System.Drawing.Point(50, 3); @@ -649,7 +640,6 @@ private System.Windows.Forms.ToolStripMenuItem liberateToolStripMenuItem; private System.Windows.Forms.ToolStripStatusLabel backupsCountsLbl; private LibationWinForms.FormattableToolStripMenuItem beginBookBackupsToolStripMenuItem; - private LibationWinForms.FormattableToolStripStatusLabel pdfsCountsLbl; private LibationWinForms.FormattableToolStripMenuItem beginPdfBackupsToolStripMenuItem; private System.Windows.Forms.TextBox filterSearchTb; private System.Windows.Forms.Button filterBtn; diff --git a/Source/LibationWinForms/Form1.VisibleBooks.cs b/Source/LibationWinForms/Form1.VisibleBooks.cs index a77c821d..ac24d058 100644 --- a/Source/LibationWinForms/Form1.VisibleBooks.cs +++ b/Source/LibationWinForms/Form1.VisibleBooks.cs @@ -27,25 +27,22 @@ namespace LibationWinForms => await Task.Run(setLiberatedVisibleMenuItem); void setLiberatedVisibleMenuItem() { - var notLiberated = productsDisplay.GetVisible().Count(lb => lb.Book.UserDefinedItem.BookStatus == LiberatedStatus.NotLiberated && !lb.AbsentFromLastScan); + var libraryStats = LibraryCommands.GetCounts(productsDisplay.GetVisible()); this.UIThreadSync(() => { - if (notLiberated > 0) + if (libraryStats.HasPendingBooks) { - liberateVisibleToolStripMenuItem_VisibleBooksMenu.Format(notLiberated); - liberateVisibleToolStripMenuItem_VisibleBooksMenu.Enabled = true; - - liberateVisibleToolStripMenuItem_LiberateMenu.Format(notLiberated); - liberateVisibleToolStripMenuItem_LiberateMenu.Enabled = true; + liberateVisibleToolStripMenuItem_VisibleBooksMenu.Format(libraryStats.PendingBooks); + liberateVisibleToolStripMenuItem_LiberateMenu.Format(libraryStats.PendingBooks); } else { liberateVisibleToolStripMenuItem_VisibleBooksMenu.Text = "All visible books are liberated"; - liberateVisibleToolStripMenuItem_VisibleBooksMenu.Enabled = false; - liberateVisibleToolStripMenuItem_LiberateMenu.Text = "All visible books are liberated"; - liberateVisibleToolStripMenuItem_LiberateMenu.Enabled = false; } + + liberateVisibleToolStripMenuItem_VisibleBooksMenu.Enabled = libraryStats.HasPendingBooks; + liberateVisibleToolStripMenuItem_LiberateMenu.Enabled = libraryStats.HasPendingBooks; }); } @@ -180,9 +177,6 @@ namespace LibationWinForms // top menu strip visibleBooksToolStripMenuItem.Format(qty); visibleBooksToolStripMenuItem.Enabled = qty > 0; - - //Not used for anything? - var notLiberatedCount = productsDisplay.GetVisible().Count(lb => lb.Book.UserDefinedItem.BookStatus == DataLayer.LiberatedStatus.NotLiberated); await Task.Run(setLiberatedVisibleMenuItem); }