mirror of
https://github.com/rmcrackan/Libation.git
synced 2026-09-12 21:57:19 -04:00
Two follow-ups to making the trash visible. Log every change to it. Startup already reported LibraryBooksInTrash as part of 'Initial database statistics'; now moving books to the trash, restoring them and permanently deleting them each log the action, how many books, and the resulting trash total. Reading the count must never fail the change that succeeded, so it degrades to a warning. Explain an empty filter result. A trashed book is filtered out of both the library and the search index, so searching for one returns nothing and looks exactly like a book that was never imported - which is how issue #1925 went a week without an answer. When a filter matches nothing, the grid now says so, and when the same filter matches something in the trash it says that too and offers a button to open it. The trash is indexed on demand rather than kept in step. Filtering runs on Enter or the Filter button, never per keystroke, so the work happens at human speed and only after the library has already come up empty. TrashBinSearch reuses the library's query syntax, so a fielded query means the same thing in both places, and returns nothing rather than throwing since it only powers a hint. Co-authored-by: rmcrackan <rmcrackan@gmail.com>
54 lines
1.8 KiB
C#
54 lines
1.8 KiB
C#
using DataLayer;
|
|
using Serilog;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
|
|
namespace ApplicationServices;
|
|
|
|
/// <summary>
|
|
/// Answers "is the book you searched for in the trash?".
|
|
/// A trashed book is filtered out of the library and out of the search index, so searching for one returns
|
|
/// nothing at all and looks exactly like a book that was never imported (issue #1925).
|
|
/// </summary>
|
|
public static class TrashBinSearch
|
|
{
|
|
/// <summary>
|
|
/// Books in the trash matching <paramref name="searchString"/>, using the same query syntax as the
|
|
/// library search so a fielded query means the same thing in both places.
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// Indexes the trash on the spot rather than keeping an index in step with it. Call only once a library
|
|
/// search has already come back empty: that happens on Enter, at human speed, so the work is rare.
|
|
/// Returns nothing rather than throwing; this only ever powers a hint.
|
|
/// </remarks>
|
|
public static List<LibraryBook> Search(string? searchString)
|
|
{
|
|
if (string.IsNullOrWhiteSpace(searchString))
|
|
return [];
|
|
|
|
try
|
|
{
|
|
//GetDeletedLibraryBooks also returns parents so the trash grid can nest episodes; only the
|
|
//genuinely deleted are candidates here.
|
|
var trashed = DbContexts.GetDeletedLibraryBooks().Where(lb => lb.IsDeleted).ToList();
|
|
if (trashed.Count == 0)
|
|
return [];
|
|
|
|
var searchEngine = new TempSearchEngine();
|
|
if (!searchEngine.ReindexSearchEngine(trashed))
|
|
return [];
|
|
|
|
if (searchEngine.GetSearchResultSet(searchString) is not { } results)
|
|
return [];
|
|
|
|
var matchedIds = results.Docs.Select(d => d.ProductId).ToHashSet();
|
|
return trashed.Where(lb => matchedIds.Contains(lb.Book.AudibleProductId)).ToList();
|
|
}
|
|
catch (System.Exception ex)
|
|
{
|
|
Log.Logger.Error(ex, "Failed to search the trash bin for {searchString}", searchString);
|
|
return [];
|
|
}
|
|
}
|
|
}
|