From 2c4705de6eb930061c316a2df1eb071ce2d450cc Mon Sep 17 00:00:00 2001 From: Mbucari Date: Tue, 13 Jun 2023 08:54:00 -0600 Subject: [PATCH] Address #625 comments and refactor --- .../BulkSetDownloadStatus.cs | 14 ++-- Source/ApplicationServices/LibraryCommands.cs | 52 ++++++--------- .../SearchEngineCommands.cs | 6 +- Source/FileLiberator/DownloadDecryptBook.cs | 2 +- Source/FileLiberator/DownloadPdf.cs | 2 +- .../Dialogs/BookDetailsDialog.axaml.cs | 2 +- .../ViewModels/ProcessBookViewModel.cs | 2 +- .../ViewModels/ProcessQueueViewModel.cs | 2 +- .../Views/ProductsDisplay.axaml.cs | 4 +- Source/LibationSearchEngine/BookRule.cs | 21 ------ Source/LibationSearchEngine/IIndexRule.cs | 22 ------- Source/LibationSearchEngine/IndexRule.cs | 42 ++++++++++++ .../IndexRuleCollection.cs | 17 +++-- .../LibationSearchEngine/LibraryBookRule.cs | 21 ------ .../LibationSearchEngine/LuceneExtensions.cs | 15 +---- Source/LibationSearchEngine/SearchEngine.cs | 64 +++++++++---------- .../GridView/GridEntry[TStatus].cs | 2 +- .../GridView/ProductsDisplay.cs | 6 +- .../ProcessQueue/ProcessBook.cs | 2 +- .../ProcessQueue/ProcessQueueControl.cs | 2 +- 20 files changed, 126 insertions(+), 174 deletions(-) delete mode 100644 Source/LibationSearchEngine/BookRule.cs delete mode 100644 Source/LibationSearchEngine/IIndexRule.cs create mode 100644 Source/LibationSearchEngine/IndexRule.cs delete mode 100644 Source/LibationSearchEngine/LibraryBookRule.cs diff --git a/Source/ApplicationServices/BulkSetDownloadStatus.cs b/Source/ApplicationServices/BulkSetDownloadStatus.cs index f0f835d3..13a303be 100644 --- a/Source/ApplicationServices/BulkSetDownloadStatus.cs +++ b/Source/ApplicationServices/BulkSetDownloadStatus.cs @@ -10,7 +10,7 @@ namespace ApplicationServices { public class BulkSetDownloadStatus { - private List<(string message, LiberatedStatus newStatus, IEnumerable Books)> actionSets { get; } = new(); + private List<(string message, LiberatedStatus newStatus, IEnumerable LibraryBooks)> actionSets { get; } = new(); public int Count => actionSets.Count; @@ -33,7 +33,7 @@ namespace ApplicationServices var bookExistsList = _libraryBooks .Select(libraryBook => new { - libraryBook.Book, + LibraryBook = libraryBook, FileExists = AudibleFileStorage.Audio.GetPath(libraryBook.Book.AudibleProductId) is not null }) .ToList(); @@ -41,8 +41,8 @@ namespace ApplicationServices if (_setDownloaded) { var books2change = bookExistsList - .Where(a => a.FileExists && a.Book.UserDefinedItem.BookStatus != LiberatedStatus.Liberated) - .Select(a => a.Book) + .Where(a => a.FileExists && a.LibraryBook.Book.UserDefinedItem.BookStatus != LiberatedStatus.Liberated) + .Select(a => a.LibraryBook) .ToList(); if (books2change.Any()) @@ -55,8 +55,8 @@ namespace ApplicationServices if (_setNotDownloaded) { var books2change = bookExistsList - .Where(a => !a.FileExists && a.Book.UserDefinedItem.BookStatus != LiberatedStatus.NotLiberated) - .Select(a => a.Book) + .Where(a => !a.FileExists && a.LibraryBook.Book.UserDefinedItem.BookStatus != LiberatedStatus.NotLiberated) + .Select(a => a.LibraryBook) .ToList(); if (books2change.Any()) @@ -72,7 +72,7 @@ namespace ApplicationServices public void Execute() { foreach (var a in actionSets) - a.Books.UpdateBookStatus(a.newStatus); + a.LibraryBooks.UpdateBookStatus(a.newStatus); } } } diff --git a/Source/ApplicationServices/LibraryCommands.cs b/Source/ApplicationServices/LibraryCommands.cs index a690458d..5179aec2 100644 --- a/Source/ApplicationServices/LibraryCommands.cs +++ b/Source/ApplicationServices/LibraryCommands.cs @@ -446,25 +446,25 @@ namespace ApplicationServices /// /// Occurs when the size of the library does not change but book(s) details do. Especially when , , or changed values are successfully persisted. /// - public static event EventHandler> BookUserDefinedItemCommitted; + public static event EventHandler> BookUserDefinedItemCommitted; #region Update book details public static int UpdateUserDefinedItem( - this Book book, + this LibraryBook lb, string tags = null, LiberatedStatus? bookStatus = null, LiberatedStatus? pdfStatus = null, Rating rating = null) - => new[] { book }.UpdateUserDefinedItem(tags, bookStatus, pdfStatus, rating); + => new[] { lb }.UpdateUserDefinedItem(tags, bookStatus, pdfStatus, rating); public static int UpdateUserDefinedItem( - this IEnumerable books, + this IEnumerable lb, string tags = null, LiberatedStatus? bookStatus = null, LiberatedStatus? pdfStatus = null, Rating rating = null) => updateUserDefinedItem( - books, + lb, udi => { // blank tags are expected. null tags are not if (tags is not null) @@ -480,66 +480,52 @@ namespace ApplicationServices udi.UpdateRating(rating.OverallRating, rating.PerformanceRating, rating.StoryRating); }); - public static int UpdateBookStatus(this Book book, LiberatedStatus bookStatus, Version libationVersion) - => book.UpdateUserDefinedItem(udi => { udi.BookStatus = bookStatus; udi.SetLastDownloaded(libationVersion); }); - public static int UpdateBookStatus(this Book book, LiberatedStatus bookStatus) - => book.UpdateUserDefinedItem(udi => udi.BookStatus = bookStatus); - public static int UpdateBookStatus(this IEnumerable books, LiberatedStatus bookStatus) - => books.UpdateUserDefinedItem(udi => udi.BookStatus = bookStatus); + public static int UpdateBookStatus(this LibraryBook lb, LiberatedStatus bookStatus, Version libationVersion) + => lb.UpdateUserDefinedItem(udi => { udi.BookStatus = bookStatus; udi.SetLastDownloaded(libationVersion); }); + public static int UpdateBookStatus(this LibraryBook libraryBook, LiberatedStatus bookStatus) => libraryBook.UpdateUserDefinedItem(udi => udi.BookStatus = bookStatus); public static int UpdateBookStatus(this IEnumerable libraryBooks, LiberatedStatus bookStatus) => libraryBooks.UpdateUserDefinedItem(udi => udi.BookStatus = bookStatus); - public static int UpdatePdfStatus(this Book book, LiberatedStatus pdfStatus) - => book.UpdateUserDefinedItem(udi => udi.SetPdfStatus(pdfStatus)); - public static int UpdatePdfStatus(this IEnumerable books, LiberatedStatus pdfStatus) - => books.UpdateUserDefinedItem(udi => udi.SetPdfStatus(pdfStatus)); public static int UpdatePdfStatus(this LibraryBook libraryBook, LiberatedStatus pdfStatus) => libraryBook.UpdateUserDefinedItem(udi => udi.SetPdfStatus(pdfStatus)); public static int UpdatePdfStatus(this IEnumerable libraryBooks, LiberatedStatus pdfStatus) => libraryBooks.UpdateUserDefinedItem(udi => udi.SetPdfStatus(pdfStatus)); - public static int UpdateTags(this Book book, string tags) - => book.UpdateUserDefinedItem(udi => udi.Tags = tags); - public static int UpdateTags(this IEnumerable books, string tags) - => books.UpdateUserDefinedItem(udi => udi.Tags = tags); public static int UpdateTags(this LibraryBook libraryBook, string tags) => libraryBook.UpdateUserDefinedItem(udi => udi.Tags = tags); public static int UpdateTags(this IEnumerable libraryBooks, string tags) => libraryBooks.UpdateUserDefinedItem(udi => udi.Tags = tags); public static int UpdateUserDefinedItem(this LibraryBook libraryBook, Action action) - => libraryBook.Book.updateUserDefinedItem(action); + => libraryBook.updateUserDefinedItem(action); public static int UpdateUserDefinedItem(this IEnumerable libraryBooks, Action action) - => libraryBooks.Select(lb => lb.Book).updateUserDefinedItem(action); + => libraryBooks.updateUserDefinedItem(action); - public static int UpdateUserDefinedItem(this Book book, Action action) => book.updateUserDefinedItem(action); - public static int UpdateUserDefinedItem(this IEnumerable books, Action action) => books.updateUserDefinedItem(action); - - private static int updateUserDefinedItem(this Book book, Action action) => new[] { book }.updateUserDefinedItem(action); - private static int updateUserDefinedItem(this IEnumerable books, Action action) + private static int updateUserDefinedItem(this LibraryBook libraryBook, Action action) => new[] { libraryBook }.updateUserDefinedItem(action); + private static int updateUserDefinedItem(this IEnumerable libraryBooks, Action action) { try { - if (books is null || !books.Any()) + if (libraryBooks is null || !libraryBooks.Any()) return 0; - foreach (var book in books) - action?.Invoke(book.UserDefinedItem); + foreach (var book in libraryBooks) + action?.Invoke(book.Book.UserDefinedItem); using var context = DbContexts.GetContext(); // Attach() NoTracking entities before SaveChanges() - foreach (var book in books) + foreach (var book in libraryBooks) { - context.Attach(book.UserDefinedItem).State = Microsoft.EntityFrameworkCore.EntityState.Modified; - context.Attach(book.UserDefinedItem.Rating).State = Microsoft.EntityFrameworkCore.EntityState.Modified; + context.Attach(book.Book.UserDefinedItem).State = Microsoft.EntityFrameworkCore.EntityState.Modified; + context.Attach(book.Book.UserDefinedItem.Rating).State = Microsoft.EntityFrameworkCore.EntityState.Modified; } var qtyChanges = context.SaveChanges(); if (qtyChanges > 0) - BookUserDefinedItemCommitted?.Invoke(null, books); + BookUserDefinedItemCommitted?.Invoke(null, libraryBooks); return qtyChanges; } diff --git a/Source/ApplicationServices/SearchEngineCommands.cs b/Source/ApplicationServices/SearchEngineCommands.cs index b87326f8..377248d5 100644 --- a/Source/ApplicationServices/SearchEngineCommands.cs +++ b/Source/ApplicationServices/SearchEngineCommands.cs @@ -34,7 +34,7 @@ namespace ApplicationServices #region Update private static bool isUpdating; - public static void UpdateBooks(IEnumerable books) + public static void UpdateBooks(IEnumerable books) { // Semi-arbitrary. At some point it's more worth it to do a full re-index than to do one offs. // I did not benchmark before choosing the number here @@ -49,10 +49,10 @@ namespace ApplicationServices public static void FullReIndex() => performSafeCommand(fullReIndex); - internal static void UpdateUserDefinedItems(Book book) => performSafeCommand(e => + internal static void UpdateUserDefinedItems(LibraryBook book) => performSafeCommand(e => { e.UpdateLiberatedStatus(book); - e.UpdateTags(book.AudibleProductId, book.UserDefinedItem.Tags); + e.UpdateTags(book.Book.AudibleProductId, book.Book.UserDefinedItem.Tags); e.UpdateUserRatings(book); } ); diff --git a/Source/FileLiberator/DownloadDecryptBook.cs b/Source/FileLiberator/DownloadDecryptBook.cs index 3d43c8b6..0318adcf 100644 --- a/Source/FileLiberator/DownloadDecryptBook.cs +++ b/Source/FileLiberator/DownloadDecryptBook.cs @@ -80,7 +80,7 @@ namespace FileLiberator { Task.Run(() => downloadCoverArt(libraryBook)), Task.Run(() => moveFilesToBooksDir(libraryBook, entries)), - Task.Run(() => libraryBook.Book.UpdateBookStatus(LiberatedStatus.Liberated, Configuration.LibationVersion)), + Task.Run(() => libraryBook.UpdateBookStatus(LiberatedStatus.Liberated, Configuration.LibationVersion)), Task.Run(() => WindowsDirectory.SetCoverAsFolderIcon(libraryBook.Book.PictureId, finalStorageDir)) }; diff --git a/Source/FileLiberator/DownloadPdf.cs b/Source/FileLiberator/DownloadPdf.cs index 9f259cc4..8fe19a12 100644 --- a/Source/FileLiberator/DownloadPdf.cs +++ b/Source/FileLiberator/DownloadPdf.cs @@ -30,7 +30,7 @@ namespace FileLiberator var actualDownloadedFilePath = await downloadPdfAsync(libraryBook, proposedDownloadFilePath); var result = verifyDownload(actualDownloadedFilePath); - libraryBook.Book.UpdatePdfStatus(result.IsSuccess ? LiberatedStatus.Liberated : LiberatedStatus.NotLiberated); + libraryBook.UpdatePdfStatus(result.IsSuccess ? LiberatedStatus.Liberated : LiberatedStatus.NotLiberated); return result; } diff --git a/Source/LibationAvalonia/Dialogs/BookDetailsDialog.axaml.cs b/Source/LibationAvalonia/Dialogs/BookDetailsDialog.axaml.cs index 2cb4218b..0e26b28f 100644 --- a/Source/LibationAvalonia/Dialogs/BookDetailsDialog.axaml.cs +++ b/Source/LibationAvalonia/Dialogs/BookDetailsDialog.axaml.cs @@ -48,7 +48,7 @@ namespace LibationAvalonia.Dialogs protected override void SaveAndClose() { - LibraryBook.Book.UpdateUserDefinedItem(NewTags, bookStatus: BookLiberatedStatus, pdfStatus: PdfLiberatedStatus); + LibraryBook.UpdateUserDefinedItem(NewTags, bookStatus: BookLiberatedStatus, pdfStatus: PdfLiberatedStatus); base.SaveAndClose(); } diff --git a/Source/LibationAvalonia/ViewModels/ProcessBookViewModel.cs b/Source/LibationAvalonia/ViewModels/ProcessBookViewModel.cs index d4607ed0..f8fc4159 100644 --- a/Source/LibationAvalonia/ViewModels/ProcessBookViewModel.cs +++ b/Source/LibationAvalonia/ViewModels/ProcessBookViewModel.cs @@ -390,7 +390,7 @@ $@" Title: {libraryBook.Book.Title} if (dialogResult == SkipResult) { - libraryBook.Book.UpdateBookStatus(LiberatedStatus.Error); + libraryBook.UpdateBookStatus(LiberatedStatus.Error); Logger.Info($"Error. Skip: [{libraryBook.Book.AudibleProductId}] {libraryBook.Book.Title}"); diff --git a/Source/LibationAvalonia/ViewModels/ProcessQueueViewModel.cs b/Source/LibationAvalonia/ViewModels/ProcessQueueViewModel.cs index 50e9cea1..0f86d4b5 100644 --- a/Source/LibationAvalonia/ViewModels/ProcessQueueViewModel.cs +++ b/Source/LibationAvalonia/ViewModels/ProcessQueueViewModel.cs @@ -223,7 +223,7 @@ namespace LibationAvalonia.ViewModels else if (result == ProcessBookResult.FailedAbort) Queue.ClearQueue(); else if (result == ProcessBookResult.FailedSkip) - nextBook.LibraryBook.Book.UpdateBookStatus(LiberatedStatus.Error); + nextBook.LibraryBook.UpdateBookStatus(LiberatedStatus.Error); else if (result == ProcessBookResult.LicenseDeniedPossibleOutage && !shownServiceOutageMessage) { await MessageBox.Show(@$" diff --git a/Source/LibationAvalonia/Views/ProductsDisplay.axaml.cs b/Source/LibationAvalonia/Views/ProductsDisplay.axaml.cs index bd85f92f..2e421f09 100644 --- a/Source/LibationAvalonia/Views/ProductsDisplay.axaml.cs +++ b/Source/LibationAvalonia/Views/ProductsDisplay.axaml.cs @@ -112,7 +112,7 @@ namespace LibationAvalonia.Views if (entry.Liberate.IsSeries) setDownloadMenuItem.Click += (_, __) => ((ISeriesEntry)entry).Children.Select(c => c.LibraryBook).UpdateBookStatus(LiberatedStatus.Liberated); else - setDownloadMenuItem.Click += (_, __) => entry.Book.UpdateBookStatus(LiberatedStatus.Liberated); + setDownloadMenuItem.Click += (_, __) => entry.LibraryBook.UpdateBookStatus(LiberatedStatus.Liberated); #endregion #region Set Download status to Not Downloaded @@ -128,7 +128,7 @@ namespace LibationAvalonia.Views if (entry.Liberate.IsSeries) setNotDownloadMenuItem.Click += (_, __) => ((ISeriesEntry)entry).Children.Select(c => c.LibraryBook).UpdateBookStatus(LiberatedStatus.NotLiberated); else - setNotDownloadMenuItem.Click += (_, __) => entry.Book.UpdateBookStatus(LiberatedStatus.NotLiberated); + setNotDownloadMenuItem.Click += (_, __) => entry.LibraryBook.UpdateBookStatus(LiberatedStatus.NotLiberated); #endregion #region Remove from library diff --git a/Source/LibationSearchEngine/BookRule.cs b/Source/LibationSearchEngine/BookRule.cs deleted file mode 100644 index e7c296e1..00000000 --- a/Source/LibationSearchEngine/BookRule.cs +++ /dev/null @@ -1,21 +0,0 @@ -using DataLayer; -using System; -using System.Collections.ObjectModel; - -namespace LibationSearchEngine; - -public class BookRule : IIndexRule -{ - public FieldType FieldType { get; } - public Func ValueGetter { get; } - public ReadOnlyCollection FieldNames { get; } - - public BookRule(FieldType fieldType, Func valueGetter, params string[] fieldNames) - { - ValueGetter = valueGetter; - FieldType = fieldType; - FieldNames = new ReadOnlyCollection(fieldNames); - } - - public string GetValue(LibraryBook libraryBook) => ValueGetter(libraryBook.Book); -} diff --git a/Source/LibationSearchEngine/IIndexRule.cs b/Source/LibationSearchEngine/IIndexRule.cs deleted file mode 100644 index dcaa441f..00000000 --- a/Source/LibationSearchEngine/IIndexRule.cs +++ /dev/null @@ -1,22 +0,0 @@ -using DataLayer; -using System.Collections.ObjectModel; - -namespace LibationSearchEngine; - -public enum FieldType -{ - Bool, - String, - Number, - ID, - Raw -} - -public interface IIndexRule -{ - /// This rule's value type. - FieldType FieldType { get; } - /// All aliases of this search index rule - ReadOnlyCollection FieldNames { get; } - string GetValue(LibraryBook libraryBook); -} diff --git a/Source/LibationSearchEngine/IndexRule.cs b/Source/LibationSearchEngine/IndexRule.cs new file mode 100644 index 00000000..79ff21cc --- /dev/null +++ b/Source/LibationSearchEngine/IndexRule.cs @@ -0,0 +1,42 @@ +using DataLayer; +using Dinah.Core; +using System; +using System.Collections.ObjectModel; +using System.Linq; + +namespace LibationSearchEngine; + +public enum FieldType +{ + Bool, + String, + Number, + ID, + Raw +} + +public class IndexRule +{ + public FieldType FieldType { get; } + public Func GetValue { get; } + public ReadOnlyCollection FieldNames { get; } + + public IndexRule(FieldType fieldType, Func valueGetter, params string[] fieldNames) + { + ArgumentValidator.EnsureNotNull(valueGetter, nameof(valueGetter)); + ArgumentValidator.EnsureNotNull(fieldNames, nameof(fieldNames)); + ArgumentValidator.EnsureGreaterThan(fieldNames.Length, $"{nameof(fieldNames)}.{nameof(fieldNames.Length)}", 0); + var fieldNamesValidated + = fieldNames + .Select((n, i) => ArgumentValidator.EnsureNotNullOrWhiteSpace(n, $"{nameof(fieldNames)}[{i}]") + .Trim()); + + GetValue = valueGetter; + FieldType = fieldType; + FieldNames = new ReadOnlyCollection(fieldNamesValidated.ToList()); + } + public override string ToString() + => FieldNames.Count == 1 + ? $"{FieldNames.First()}" + : $"{FieldNames.First()} ({string.Join(", ", FieldNames.Skip(1))})"; +} diff --git a/Source/LibationSearchEngine/IndexRuleCollection.cs b/Source/LibationSearchEngine/IndexRuleCollection.cs index 2a20dad1..5033897f 100644 --- a/Source/LibationSearchEngine/IndexRuleCollection.cs +++ b/Source/LibationSearchEngine/IndexRuleCollection.cs @@ -2,27 +2,26 @@ using System; using System.Collections; using System.Collections.Generic; +using System.Diagnostics; using System.Linq; namespace LibationSearchEngine; -public class IndexRuleCollection : IEnumerable +[DebuggerDisplay("Count = {rules.Count,nq}")] +public class IndexRuleCollection : IEnumerable { - private readonly List rules = new(); + private readonly List rules = new(); public IEnumerable IdFieldNames => rules.Where(x => x.FieldType is FieldType.ID).SelectMany(r => r.FieldNames); public IEnumerable BoolFieldNames => rules.Where(x => x.FieldType is FieldType.Bool).SelectMany(r => r.FieldNames); public IEnumerable StringFieldNames => rules.Where(x => x.FieldType is FieldType.String).SelectMany(r => r.FieldNames); public IEnumerable NumberFieldNames => rules.Where(x => x.FieldType is FieldType.Number).SelectMany(r => r.FieldNames); public void Add(FieldType fieldType, Func getter, params string[] fieldNames) - => rules.Add(new LibraryBookRule(fieldType, getter, fieldNames)); - - public void Add(FieldType fieldType, Func getter, params string[] fieldNames) - => rules.Add(new BookRule(fieldType, getter, fieldNames)); + => rules.Add(new IndexRule(fieldType, getter, fieldNames)); - public T GetRuleByFieldName(string fieldName) where T : IIndexRule - => (T)rules.SingleOrDefault(r => r.FieldNames.Any(n => n.Equals(fieldName, StringComparison.OrdinalIgnoreCase))); + public IndexRule GetRuleByFieldName(string fieldName) + => rules.SingleOrDefault(r => r.FieldNames.Any(n => n.Equals(fieldName, StringComparison.OrdinalIgnoreCase))); - public IEnumerator GetEnumerator() => rules.GetEnumerator(); + public IEnumerator GetEnumerator() => rules.GetEnumerator(); IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); } diff --git a/Source/LibationSearchEngine/LibraryBookRule.cs b/Source/LibationSearchEngine/LibraryBookRule.cs deleted file mode 100644 index 6c9036b7..00000000 --- a/Source/LibationSearchEngine/LibraryBookRule.cs +++ /dev/null @@ -1,21 +0,0 @@ -using DataLayer; -using System; -using System.Collections.ObjectModel; - -namespace LibationSearchEngine; - -public class LibraryBookRule : IIndexRule -{ - public FieldType FieldType { get; } - public Func ValueGetter { get; } - public ReadOnlyCollection FieldNames { get; } - - public LibraryBookRule(FieldType fieldType, Func valueGetter, params string[] fieldNames) - { - ValueGetter = valueGetter; - FieldType = fieldType; - FieldNames = new ReadOnlyCollection(fieldNames); - } - - public string GetValue(LibraryBook libraryBook) => ValueGetter(libraryBook); -} diff --git a/Source/LibationSearchEngine/LuceneExtensions.cs b/Source/LibationSearchEngine/LuceneExtensions.cs index 0e09fe8d..32e7ab46 100644 --- a/Source/LibationSearchEngine/LuceneExtensions.cs +++ b/Source/LibationSearchEngine/LuceneExtensions.cs @@ -17,7 +17,7 @@ namespace LibationSearchEngine document.Add(new Field(name.ToLowerInvariant(), value, Field.Store.YES, Field.Index.ANALYZED)); } - internal static void RemoveRule(this Document document, IIndexRule rule) + internal static void RemoveRule(this Document document, IndexRule rule) { // fields are key value pairs. MULTIPLE FIELDS CAN POTENTIALLY HAVE THE SAME KEY. // ie: must remove old before adding new else will create unwanted duplicates. @@ -25,20 +25,9 @@ namespace LibationSearchEngine document.RemoveFields(name.ToLowerInvariant()); } - internal static void AddIndexRule(this Document document, IIndexRule rule, LibraryBook libraryBook) + internal static void AddIndexRule(this Document document, IndexRule rule, LibraryBook libraryBook) { string value = rule.GetValue(libraryBook); - - addIndexRule(document, rule, value); - } - - internal static void AddIndexRule(this Document document, BookRule rule, Book libraryBook) - { - addIndexRule(document, rule, rule.ValueGetter(libraryBook)); - } - - private static void addIndexRule(Document document, IIndexRule rule, string value) - { if (value is null) return; foreach (var name in rule.FieldNames) diff --git a/Source/LibationSearchEngine/SearchEngine.cs b/Source/LibationSearchEngine/SearchEngine.cs index 872a4b1a..00b80db7 100644 --- a/Source/LibationSearchEngine/SearchEngine.cs +++ b/Source/LibationSearchEngine/SearchEngine.cs @@ -33,34 +33,34 @@ namespace LibationSearchEngine // use these common fields in the "all" default search field public static IndexRuleCollection FieldIndexRules { get; } = new IndexRuleCollection { - { FieldType.ID, Book => Book.AudibleProductId.ToLowerInvariant(), nameof(Book.AudibleProductId), "ProductId", "Id", "ASIN" }, - { FieldType.Raw, Book => Book.AudibleProductId, _ID_ }, - { FieldType.String, Book => Book.Title, nameof(Book.Title), "ProductId", "Id", "ASIN" }, - { FieldType.String, Book => Book.AuthorNames(), "AuthorNames", "Author", "Authors" }, - { FieldType.String, Book => Book.NarratorNames(), "NarratorNames", "Narrator", "Narrators" }, - { FieldType.String, Book => Book.Publisher, nameof(Book.Publisher) }, - { FieldType.String, Book => Book.SeriesNames(), "SeriesNames", "Narrator", "Series" }, - { FieldType.String, Book => string.Join(", ", Book.SeriesLink.Select(s => s.Series.AudibleSeriesId)), "SeriesId" }, - { FieldType.String, Book => Book.CategoriesIds() is null ? null : string.Join(", ", Book.CategoriesIds()), nameof(Book.Category), "Categories", "CategoriesId", "CategoryId", "CategoriesNames" }, - { FieldType.String, Book => Book.UserDefinedItem.Tags, TAGS.FirstCharToUpper() }, - { FieldType.String, Book => Book.Locale, "Locale", "Region" }, + { FieldType.ID, lb => lb.Book.AudibleProductId.ToLowerInvariant(), nameof(Book.AudibleProductId), "ProductId", "Id", "ASIN" }, + { FieldType.Raw, lb => lb.Book.AudibleProductId, _ID_ }, + { FieldType.String, lb => lb.Book.Title, nameof(Book.Title), "ProductId", "Id", "ASIN" }, + { FieldType.String, lb => lb.Book.AuthorNames(), "AuthorNames", "Author", "Authors" }, + { FieldType.String, lb => lb.Book.NarratorNames(), "NarratorNames", "Narrator", "Narrators" }, + { FieldType.String, lb => lb.Book.Publisher, nameof(Book.Publisher) }, + { FieldType.String, lb => lb.Book.SeriesNames(), "SeriesNames", "Narrator", "Series" }, + { FieldType.String, lb => string.Join(", ", lb.Book.SeriesLink.Select(s => s.Series.AudibleSeriesId)), "SeriesId" }, + { FieldType.String, lb => lb.Book.CategoriesIds() is null ? null : string.Join(", ", lb.Book.CategoriesIds()), nameof(Book.Category), "Categories", "CategoriesId", "CategoryId", "CategoriesNames" }, + { FieldType.String, lb => lb.Book.UserDefinedItem.Tags, TAGS.FirstCharToUpper() }, + { FieldType.String, lb => lb.Book.Locale, "Locale", "Region" }, { FieldType.String, lb => lb.Account, "Account", "Email" }, - { FieldType.Bool, Book => Book.HasPdf().ToString(), "HasDownloads", "HasDownload", "Downloads" , "Download", "HasPDFs", "HasPDF" , "PDFs", "PDF" }, - { FieldType.Bool, Book => (Book.UserDefinedItem.Rating.OverallRating > 0f).ToString(), "IsRated", "Rated" }, - { FieldType.Bool, Book => isAuthorNarrated(Book).ToString(), "IsAuthorNarrated", "AuthorNarrated" }, - { FieldType.Bool, Book => Book.IsAbridged.ToString(), nameof(Book.IsAbridged), "Abridged" }, - { FieldType.Bool, Book => (Book.UserDefinedItem.BookStatus == LiberatedStatus.Liberated).ToString(), "IsLiberated", "Liberated" }, - { FieldType.Bool, Book => (Book.UserDefinedItem.BookStatus == LiberatedStatus.Error).ToString(), "LiberatedError" }, - { FieldType.Bool, Book => Book.IsEpisodeChild().ToString(), "Podcast", "Podcasts", "IsPodcast", "Episode", "Episodes", "IsEpisode" }, + { FieldType.Bool, lb => lb.Book.HasPdf().ToString(), "HasDownloads", "HasDownload", "Downloads" , "Download", "HasPDFs", "HasPDF" , "PDFs", "PDF" }, + { FieldType.Bool, lb => (lb.Book.UserDefinedItem.Rating.OverallRating > 0f).ToString(), "IsRated", "Rated" }, + { FieldType.Bool, lb => isAuthorNarrated(lb.Book).ToString(), "IsAuthorNarrated", "AuthorNarrated" }, + { FieldType.Bool, lb => lb.Book.IsAbridged.ToString(), nameof(Book.IsAbridged), "Abridged" }, + { FieldType.Bool, lb => (lb.Book.UserDefinedItem.BookStatus == LiberatedStatus.Liberated).ToString(), "IsLiberated", "Liberated" }, + { FieldType.Bool, lb => (lb.Book.UserDefinedItem.BookStatus == LiberatedStatus.Error).ToString(), "LiberatedError" }, + { FieldType.Bool, lb => lb.Book.IsEpisodeChild().ToString(), "Podcast", "Podcasts", "IsPodcast", "Episode", "Episodes", "IsEpisode" }, { FieldType.Bool, lb => lb.AbsentFromLastScan.ToString(), "AbsentFromLastScan", "Absent" }, // all numbers are padded to 8 char.s // This will allow a single method to auto-pad numbers. The method will match these as well as date: yyyymmdd - { FieldType.Number, Book => Book.LengthInMinutes.ToLuceneString(), nameof(Book.LengthInMinutes), "Length", "Minutes" }, - { FieldType.Number, Book => (Book.LengthInMinutes / 60).ToLuceneString(), "Hours" }, - { FieldType.Number, Book => Book.Rating.OverallRating.ToLuceneString(), "ProductRating", "Rating" }, - { FieldType.Number, Book => Book.UserDefinedItem.Rating.OverallRating.ToLuceneString(), "UserRating", "MyRating" }, - { FieldType.Number, Book => Book.DatePublished?.ToLuceneString() ?? "", nameof(Book.DatePublished) }, - { FieldType.Number, Book => Book.UserDefinedItem.LastDownloaded.ToLuceneString(), nameof(UserDefinedItem.LastDownloaded), "LastDownload" }, + { FieldType.Number, lb => lb.Book.LengthInMinutes.ToLuceneString(), nameof(Book.LengthInMinutes), "Length", "Minutes" }, + { FieldType.Number, lb => (lb.Book.LengthInMinutes / 60).ToLuceneString(), "Hours" }, + { FieldType.Number, lb => lb.Book.Rating.OverallRating.ToLuceneString(), "ProductRating", "Rating" }, + { FieldType.Number, lb => lb.Book.UserDefinedItem.Rating.OverallRating.ToLuceneString(), "UserRating", "MyRating" }, + { FieldType.Number, lb => lb.Book.DatePublished?.ToLuceneString() ?? "", nameof(Book.DatePublished) }, + { FieldType.Number, lb => lb.Book.UserDefinedItem.LastDownloaded.ToLuceneString(), nameof(UserDefinedItem.LastDownloaded), "LastDownload" }, { FieldType.Number, lb => lb.DateAdded.ToLuceneString(), nameof(LibraryBook.DateAdded) } }; #endregion @@ -132,14 +132,14 @@ namespace LibationSearchEngine }); // update single document entry - public void UpdateLiberatedStatus(Book book) + public void UpdateLiberatedStatus(LibraryBook book) => updateDocument( - book.AudibleProductId, + book.Book.AudibleProductId, d => { - var lib = FieldIndexRules.GetRuleByFieldName("IsLiberated"); - var libError = FieldIndexRules.GetRuleByFieldName("LiberatedError"); - var lastDl = FieldIndexRules.GetRuleByFieldName(nameof(UserDefinedItem.LastDownloaded)); + var lib = FieldIndexRules.GetRuleByFieldName("IsLiberated"); + var libError = FieldIndexRules.GetRuleByFieldName("LiberatedError"); + var lastDl = FieldIndexRules.GetRuleByFieldName(nameof(UserDefinedItem.LastDownloaded)); d.RemoveRule(lib); d.RemoveRule(libError); @@ -150,12 +150,12 @@ namespace LibationSearchEngine d.AddIndexRule(lastDl, book); }); - public void UpdateUserRatings(Book book) + public void UpdateUserRatings(LibraryBook book) =>updateDocument( - book.AudibleProductId, + book.Book.AudibleProductId, d => { - var rating = FieldIndexRules.GetRuleByFieldName("UserRating"); + var rating = FieldIndexRules.GetRuleByFieldName("UserRating"); d.RemoveRule(rating); d.AddIndexRule(rating, book); diff --git a/Source/LibationUiBase/GridView/GridEntry[TStatus].cs b/Source/LibationUiBase/GridView/GridEntry[TStatus].cs index 52513304..01d89f01 100644 --- a/Source/LibationUiBase/GridView/GridEntry[TStatus].cs +++ b/Source/LibationUiBase/GridView/GridEntry[TStatus].cs @@ -88,7 +88,7 @@ namespace LibationUiBase.GridView var api = await LibraryBook.GetApiAsync(); if (await api.ReviewAsync(Book.AudibleProductId, (int)rating.OverallRating, (int)rating.PerformanceRating, (int)rating.StoryRating)) - LibraryBook.Book.UpdateUserDefinedItem(Book.UserDefinedItem.Tags, Book.UserDefinedItem.BookStatus, Book.UserDefinedItem.PdfStatus, rating); + LibraryBook.UpdateUserDefinedItem(Book.UserDefinedItem.Tags, Book.UserDefinedItem.BookStatus, Book.UserDefinedItem.PdfStatus, rating); } #endregion diff --git a/Source/LibationWinForms/GridView/ProductsDisplay.cs b/Source/LibationWinForms/GridView/ProductsDisplay.cs index 95c1ea7f..342c5fcf 100644 --- a/Source/LibationWinForms/GridView/ProductsDisplay.cs +++ b/Source/LibationWinForms/GridView/ProductsDisplay.cs @@ -93,7 +93,7 @@ namespace LibationWinForms.GridView { var bookDetailsForm = new BookDetailsDialog(liveGridEntry.LibraryBook); if (bookDetailsForm.ShowDialog() == DialogResult.OK) - liveGridEntry.Book.UpdateUserDefinedItem(bookDetailsForm.NewTags, bookDetailsForm.BookLiberatedStatus, bookDetailsForm.PdfLiberatedStatus); + liveGridEntry.LibraryBook.UpdateUserDefinedItem(bookDetailsForm.NewTags, bookDetailsForm.BookLiberatedStatus, bookDetailsForm.PdfLiberatedStatus); } #endregion @@ -131,7 +131,7 @@ namespace LibationWinForms.GridView if (entry.Liberate.IsSeries) setDownloadMenuItem.Click += (_, _) => ((ISeriesEntry)entry).Children.Select(c => c.LibraryBook).UpdateBookStatus(LiberatedStatus.Liberated); else - setDownloadMenuItem.Click += (_, _) => entry.Book.UpdateBookStatus(LiberatedStatus.Liberated); + setDownloadMenuItem.Click += (_, _) => entry.LibraryBook.UpdateBookStatus(LiberatedStatus.Liberated); #endregion #region Set Download status to Not Downloaded @@ -147,7 +147,7 @@ namespace LibationWinForms.GridView if (entry.Liberate.IsSeries) setNotDownloadMenuItem.Click += (_, _) => ((ISeriesEntry)entry).Children.Select(c => c.LibraryBook).UpdateBookStatus(LiberatedStatus.NotLiberated); else - setNotDownloadMenuItem.Click += (_, _) => entry.Book.UpdateBookStatus(LiberatedStatus.NotLiberated); + setNotDownloadMenuItem.Click += (_, _) => entry.LibraryBook.UpdateBookStatus(LiberatedStatus.NotLiberated); #endregion #region Remove from library diff --git a/Source/LibationWinForms/ProcessQueue/ProcessBook.cs b/Source/LibationWinForms/ProcessQueue/ProcessBook.cs index 1159b24b..50b3e1b5 100644 --- a/Source/LibationWinForms/ProcessQueue/ProcessBook.cs +++ b/Source/LibationWinForms/ProcessQueue/ProcessBook.cs @@ -377,7 +377,7 @@ $@" Title: {libraryBook.Book.Title} if (dialogResult == SkipResult) { - libraryBook.Book.UpdateBookStatus(LiberatedStatus.Error); + libraryBook.UpdateBookStatus(LiberatedStatus.Error); Logger.Info($"Error. Skip: [{libraryBook.Book.AudibleProductId}] {libraryBook.Book.Title}"); diff --git a/Source/LibationWinForms/ProcessQueue/ProcessQueueControl.cs b/Source/LibationWinForms/ProcessQueue/ProcessQueueControl.cs index af788041..e05b23b7 100644 --- a/Source/LibationWinForms/ProcessQueue/ProcessQueueControl.cs +++ b/Source/LibationWinForms/ProcessQueue/ProcessQueueControl.cs @@ -184,7 +184,7 @@ namespace LibationWinForms.ProcessQueue else if (result == ProcessBookResult.FailedAbort) Queue.ClearQueue(); else if (result == ProcessBookResult.FailedSkip) - nextBook.LibraryBook.Book.UpdateBookStatus(DataLayer.LiberatedStatus.Error); + nextBook.LibraryBook.UpdateBookStatus(DataLayer.LiberatedStatus.Error); else if (result == ProcessBookResult.LicenseDeniedPossibleOutage && !shownServiceOutageMessage) { MessageBox.Show(@$"