* New event SearchEngineCommands.SearchEngineUpdated
* Clean up redundant event notifications
This commit is contained in:
parent
7987dfb819
commit
3f2899e97e
@ -15,6 +15,7 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\ApplicationServices\ApplicationServices.csproj" />
|
||||||
<ProjectReference Include="..\AudibleUtilities\AudibleUtilities.csproj" />
|
<ProjectReference Include="..\AudibleUtilities\AudibleUtilities.csproj" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
|||||||
@ -3,6 +3,7 @@ using System.Collections.Generic;
|
|||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
|
using ApplicationServices;
|
||||||
using AudibleUtilities;
|
using AudibleUtilities;
|
||||||
using Dinah.Core;
|
using Dinah.Core;
|
||||||
using Dinah.Core.IO;
|
using Dinah.Core.IO;
|
||||||
@ -139,12 +140,14 @@ namespace AppScaffolding
|
|||||||
config.DownloadCoverArt = true;
|
config.DownloadCoverArt = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Initialize logging. Run after migration</summary>
|
/// <summary>Initialize logging. Wire-up events. Run after migration</summary>
|
||||||
public static void RunPostMigrationScaffolding(Configuration config)
|
public static void RunPostMigrationScaffolding(Configuration config)
|
||||||
{
|
{
|
||||||
ensureSerilogConfig(config);
|
ensureSerilogConfig(config);
|
||||||
configureLogging(config);
|
configureLogging(config);
|
||||||
logStartupState(config);
|
logStartupState(config);
|
||||||
|
|
||||||
|
wireUpSystemEvents(config);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void ensureSerilogConfig(Configuration config)
|
private static void ensureSerilogConfig(Configuration config)
|
||||||
@ -282,6 +285,12 @@ namespace AppScaffolding
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void wireUpSystemEvents(Configuration configuration)
|
||||||
|
{
|
||||||
|
LibraryCommands.LibrarySizeChanged += (_, __) => SearchEngineCommands.FullReIndex();
|
||||||
|
LibraryCommands.BookUserDefinedItemCommitted += (_, books) => SearchEngineCommands.UpdateBooks(books);
|
||||||
|
}
|
||||||
|
|
||||||
public static UpgradeProperties GetLatestRelease()
|
public static UpgradeProperties GetLatestRelease()
|
||||||
{
|
{
|
||||||
// timed out
|
// timed out
|
||||||
|
|||||||
@ -253,11 +253,7 @@ namespace ApplicationServices
|
|||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
// call this whenever books are added or removed from library
|
// call this whenever books are added or removed from library
|
||||||
private static void finalizeLibrarySizeChange()
|
private static void finalizeLibrarySizeChange() => LibrarySizeChanged?.Invoke(null, null);
|
||||||
{
|
|
||||||
SearchEngineCommands.FullReIndex();
|
|
||||||
LibrarySizeChanged?.Invoke(null, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>Occurs when the size of the library changes. ie: books are added or removed</summary>
|
/// <summary>Occurs when the size of the library changes. ie: books are added or removed</summary>
|
||||||
public static event EventHandler LibrarySizeChanged;
|
public static event EventHandler LibrarySizeChanged;
|
||||||
@ -265,9 +261,47 @@ namespace ApplicationServices
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Occurs when the size of the library does not change but book(s) details do. Especially when <see cref="UserDefinedItem.Tags"/>, <see cref="UserDefinedItem.BookStatus"/>, or <see cref="UserDefinedItem.PdfStatus"/> changed values are successfully persisted.
|
/// Occurs when the size of the library does not change but book(s) details do. Especially when <see cref="UserDefinedItem.Tags"/>, <see cref="UserDefinedItem.BookStatus"/>, or <see cref="UserDefinedItem.PdfStatus"/> changed values are successfully persisted.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static event EventHandler BookUserDefinedItemCommitted;
|
public static event EventHandler<IEnumerable<Book>> BookUserDefinedItemCommitted;
|
||||||
|
|
||||||
#region Update book details
|
#region Update book details
|
||||||
|
public static int UpdateBookStatus(this Book book, LiberatedStatus bookStatus)
|
||||||
|
{
|
||||||
|
book.UserDefinedItem.BookStatus = bookStatus;
|
||||||
|
return UpdateUserDefinedItem(book);
|
||||||
|
}
|
||||||
|
public static int UpdatePdfStatus(this Book book, LiberatedStatus pdfStatus)
|
||||||
|
{
|
||||||
|
book.UserDefinedItem.PdfStatus = pdfStatus;
|
||||||
|
return UpdateUserDefinedItem(book);
|
||||||
|
}
|
||||||
|
public static int UpdateBook(
|
||||||
|
this Book book,
|
||||||
|
string tags = null,
|
||||||
|
LiberatedStatus? bookStatus = null,
|
||||||
|
LiberatedStatus? pdfStatus = null)
|
||||||
|
=> UpdateBooks(tags, bookStatus, pdfStatus, book);
|
||||||
|
public static int UpdateBooks(
|
||||||
|
string tags = null,
|
||||||
|
LiberatedStatus? bookStatus = null,
|
||||||
|
LiberatedStatus? pdfStatus = null,
|
||||||
|
params Book[] books)
|
||||||
|
{
|
||||||
|
foreach (var book in books)
|
||||||
|
{
|
||||||
|
// blank tags are expected. null tags are not
|
||||||
|
if (tags is not null && book.UserDefinedItem.Tags != tags)
|
||||||
|
book.UserDefinedItem.Tags = tags;
|
||||||
|
|
||||||
|
if (bookStatus is not null && book.UserDefinedItem.BookStatus != bookStatus.Value)
|
||||||
|
book.UserDefinedItem.BookStatus = bookStatus.Value;
|
||||||
|
|
||||||
|
// even though PdfStatus is nullable, there's no case where we'd actually overwrite with null
|
||||||
|
if (pdfStatus is not null && book.UserDefinedItem.PdfStatus != pdfStatus.Value)
|
||||||
|
book.UserDefinedItem.PdfStatus = pdfStatus.Value;
|
||||||
|
}
|
||||||
|
|
||||||
|
return UpdateUserDefinedItem(books);
|
||||||
|
}
|
||||||
public static int UpdateUserDefinedItem(params Book[] books) => UpdateUserDefinedItem(books.ToList());
|
public static int UpdateUserDefinedItem(params Book[] books) => UpdateUserDefinedItem(books.ToList());
|
||||||
public static int UpdateUserDefinedItem(IEnumerable<Book> books)
|
public static int UpdateUserDefinedItem(IEnumerable<Book> books)
|
||||||
{
|
{
|
||||||
@ -283,23 +317,8 @@ namespace ApplicationServices
|
|||||||
context.Attach(book.UserDefinedItem).State = Microsoft.EntityFrameworkCore.EntityState.Modified;
|
context.Attach(book.UserDefinedItem).State = Microsoft.EntityFrameworkCore.EntityState.Modified;
|
||||||
|
|
||||||
var qtyChanges = context.SaveChanges();
|
var qtyChanges = context.SaveChanges();
|
||||||
if (qtyChanges == 0)
|
if (qtyChanges > 0)
|
||||||
return 0;
|
BookUserDefinedItemCommitted?.Invoke(null, 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
|
|
||||||
if (qtyChanges > 15)
|
|
||||||
SearchEngineCommands.FullReIndex();
|
|
||||||
else
|
|
||||||
{
|
|
||||||
foreach (var book in books)
|
|
||||||
{
|
|
||||||
SearchEngineCommands.UpdateLiberatedStatus(book);
|
|
||||||
SearchEngineCommands.UpdateBookTags(book);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
BookUserDefinedItemCommitted?.Invoke(null, null);
|
|
||||||
|
|
||||||
return qtyChanges;
|
return qtyChanges;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,5 +1,7 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
using DataLayer;
|
using DataLayer;
|
||||||
using LibationSearchEngine;
|
using LibationSearchEngine;
|
||||||
|
|
||||||
@ -7,51 +9,99 @@ namespace ApplicationServices
|
|||||||
{
|
{
|
||||||
public static class SearchEngineCommands
|
public static class SearchEngineCommands
|
||||||
{
|
{
|
||||||
public static void FullReIndex(SearchEngine engine = null)
|
#region Search
|
||||||
{
|
public static SearchResultSet Search(string searchString) => performSafeQuery(e =>
|
||||||
engine ??= new SearchEngine();
|
|
||||||
var library = DbContexts.GetLibrary_Flat_NoTracking();
|
|
||||||
engine.CreateNewIndex(library);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static SearchResultSet Search(string searchString) => performSearchEngineFunc_safe(e =>
|
|
||||||
e.Search(searchString)
|
e.Search(searchString)
|
||||||
);
|
);
|
||||||
|
|
||||||
public static void UpdateBookTags(Book book) => performSearchEngineAction_safe(e =>
|
private static T performSafeQuery<T>(Func<SearchEngine, T> func)
|
||||||
e.UpdateTags(book.AudibleProductId, book.UserDefinedItem.Tags)
|
{
|
||||||
|
var engine = new SearchEngine();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return func(engine);
|
||||||
|
}
|
||||||
|
catch (FileNotFoundException)
|
||||||
|
{
|
||||||
|
fullReIndex(engine);
|
||||||
|
return func(engine);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
public static EventHandler SearchEngineUpdated;
|
||||||
|
|
||||||
|
#region Update
|
||||||
|
private static bool isUpdating;
|
||||||
|
|
||||||
|
public static void UpdateBooks(IEnumerable<Book> 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
|
||||||
|
if (books.Count() > 15)
|
||||||
|
FullReIndex();
|
||||||
|
else
|
||||||
|
{
|
||||||
|
foreach (var book in books)
|
||||||
|
{
|
||||||
|
UpdateLiberatedStatus(book);
|
||||||
|
UpdateBookTags(book);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void FullReIndex() => performSafeCommand(e =>
|
||||||
|
fullReIndex(e)
|
||||||
);
|
);
|
||||||
|
|
||||||
public static void UpdateLiberatedStatus(Book book) => performSearchEngineAction_safe(e =>
|
internal static void UpdateLiberatedStatus(Book book) => performSafeCommand(e =>
|
||||||
e.UpdateLiberatedStatus(book)
|
e.UpdateLiberatedStatus(book)
|
||||||
);
|
);
|
||||||
|
|
||||||
private static void performSearchEngineAction_safe(Action<SearchEngine> action)
|
internal static void UpdateBookTags(Book book) => performSafeCommand(e =>
|
||||||
|
e.UpdateTags(book.AudibleProductId, book.UserDefinedItem.Tags)
|
||||||
|
);
|
||||||
|
|
||||||
|
private static void performSafeCommand(Action<SearchEngine> action)
|
||||||
{
|
{
|
||||||
var engine = new SearchEngine();
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
action(engine);
|
update(action);
|
||||||
}
|
}
|
||||||
catch (FileNotFoundException)
|
catch (FileNotFoundException)
|
||||||
{
|
{
|
||||||
FullReIndex(engine);
|
fullReIndex(new SearchEngine());
|
||||||
action(engine);
|
update(action);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static T performSearchEngineFunc_safe<T>(Func<SearchEngine, T> func)
|
private static void update(Action<SearchEngine> action)
|
||||||
{
|
{
|
||||||
var engine = new SearchEngine();
|
if (action is null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// support nesting incl recursion
|
||||||
|
var prevIsUpdating = isUpdating;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
return func(engine);
|
isUpdating = true;
|
||||||
|
|
||||||
|
action(new SearchEngine());
|
||||||
|
|
||||||
|
if (!prevIsUpdating)
|
||||||
|
SearchEngineUpdated?.Invoke(null, null);
|
||||||
}
|
}
|
||||||
catch (FileNotFoundException)
|
finally
|
||||||
{
|
{
|
||||||
FullReIndex(engine);
|
isUpdating = prevIsUpdating;
|
||||||
return func(engine);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void fullReIndex(SearchEngine engine)
|
||||||
|
{
|
||||||
|
var library = DbContexts.GetLibrary_Flat_NoTracking();
|
||||||
|
engine.CreateNewIndex(library);
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -4,6 +4,7 @@ using System.IO;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using AaxDecrypter;
|
using AaxDecrypter;
|
||||||
|
using ApplicationServices;
|
||||||
using AudibleApi;
|
using AudibleApi;
|
||||||
using DataLayer;
|
using DataLayer;
|
||||||
using Dinah.Core;
|
using Dinah.Core;
|
||||||
@ -82,8 +83,7 @@ namespace FileLiberator
|
|||||||
if (Configuration.Instance.DownloadCoverArt)
|
if (Configuration.Instance.DownloadCoverArt)
|
||||||
DownloadCoverArt(libraryBook);
|
DownloadCoverArt(libraryBook);
|
||||||
|
|
||||||
libraryBook.Book.UserDefinedItem.BookStatus = LiberatedStatus.Liberated;
|
libraryBook.Book.UpdateBookStatus(LiberatedStatus.Liberated);
|
||||||
ApplicationServices.LibraryCommands.UpdateUserDefinedItem(libraryBook.Book);
|
|
||||||
|
|
||||||
return new StatusHandler();
|
return new StatusHandler();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -4,6 +4,7 @@ using System.IO;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Net.Http;
|
using System.Net.Http;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using ApplicationServices;
|
||||||
using DataLayer;
|
using DataLayer;
|
||||||
using Dinah.Core.ErrorHandling;
|
using Dinah.Core.ErrorHandling;
|
||||||
using Dinah.Core.Net.Http;
|
using Dinah.Core.Net.Http;
|
||||||
@ -29,8 +30,7 @@ namespace FileLiberator
|
|||||||
var actualDownloadedFilePath = await downloadPdfAsync(libraryBook, proposedDownloadFilePath);
|
var actualDownloadedFilePath = await downloadPdfAsync(libraryBook, proposedDownloadFilePath);
|
||||||
var result = verifyDownload(actualDownloadedFilePath);
|
var result = verifyDownload(actualDownloadedFilePath);
|
||||||
|
|
||||||
libraryBook.Book.UserDefinedItem.PdfStatus = result.IsSuccess ? LiberatedStatus.Liberated : LiberatedStatus.NotLiberated;
|
libraryBook.Book.UpdatePdfStatus(result.IsSuccess ? LiberatedStatus.Liberated : LiberatedStatus.NotLiberated);
|
||||||
ApplicationServices.LibraryCommands.UpdateUserDefinedItem(libraryBook.Book);
|
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -33,7 +33,6 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\ApplicationServices\ApplicationServices.csproj" />
|
|
||||||
<ProjectReference Include="..\AppScaffolding\AppScaffolding.csproj" />
|
<ProjectReference Include="..\AppScaffolding\AppScaffolding.csproj" />
|
||||||
<ProjectReference Include="..\FileLiberator\FileLiberator.csproj" />
|
<ProjectReference Include="..\FileLiberator\FileLiberator.csproj" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|||||||
@ -27,7 +27,6 @@ namespace LibationCli
|
|||||||
// //
|
// //
|
||||||
//***********************************************//
|
//***********************************************//
|
||||||
Setup.Initialize();
|
Setup.Initialize();
|
||||||
Setup.SubscribeToDatabaseEvents();
|
|
||||||
|
|
||||||
var types = Setup.LoadVerbs();
|
var types = Setup.LoadVerbs();
|
||||||
|
|
||||||
|
|||||||
@ -50,11 +50,6 @@ namespace LibationCli
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void SubscribeToDatabaseEvents()
|
|
||||||
{
|
|
||||||
DataLayer.UserDefinedItem.ItemChanged += (sender, e) => ApplicationServices.LibraryCommands.UpdateUserDefinedItem(((DataLayer.UserDefinedItem)sender).Book);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Type[] LoadVerbs() => Assembly.GetExecutingAssembly()
|
public static Type[] LoadVerbs() => Assembly.GetExecutingAssembly()
|
||||||
.GetTypes()
|
.GetTypes()
|
||||||
.Where(t => t.GetCustomAttribute<VerbAttribute>() is not null)
|
.Where(t => t.GetCustomAttribute<VerbAttribute>() is not null)
|
||||||
|
|||||||
@ -22,7 +22,7 @@ namespace LibationWinForms
|
|||||||
|
|
||||||
LibraryCommands.BookUserDefinedItemCommitted += setLiberatedVisibleMenuItemAsync;
|
LibraryCommands.BookUserDefinedItemCommitted += setLiberatedVisibleMenuItemAsync;
|
||||||
}
|
}
|
||||||
private async void setLiberatedVisibleMenuItemAsync(object _, EventArgs __)
|
private async void setLiberatedVisibleMenuItemAsync(object _, object __)
|
||||||
=> await Task.Run(setLiberatedVisibleMenuItem);
|
=> await Task.Run(setLiberatedVisibleMenuItem);
|
||||||
void setLiberatedVisibleMenuItem()
|
void setLiberatedVisibleMenuItem()
|
||||||
{
|
{
|
||||||
|
|||||||
@ -25,6 +25,7 @@ namespace LibationWinForms.GridView
|
|||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
protected override Book Book => LibraryBook.Book;
|
protected override Book Book => LibraryBook.Book;
|
||||||
|
|
||||||
#region Model properties exposed to the view
|
#region Model properties exposed to the view
|
||||||
|
|
||||||
private DateTime lastStatusUpdate = default;
|
private DateTime lastStatusUpdate = default;
|
||||||
@ -75,6 +76,7 @@ namespace LibationWinForms.GridView
|
|||||||
if (AudibleProductId != libraryBook.Book.AudibleProductId)
|
if (AudibleProductId != libraryBook.Book.AudibleProductId)
|
||||||
throw new Exception("Invalid grid entry update. IDs must match");
|
throw new Exception("Invalid grid entry update. IDs must match");
|
||||||
|
|
||||||
|
UserDefinedItem.ItemChanged -= UserDefinedItem_ItemChanged;
|
||||||
setLibraryBook(libraryBook);
|
setLibraryBook(libraryBook);
|
||||||
|
|
||||||
NotifyPropertyChanged();
|
NotifyPropertyChanged();
|
||||||
@ -84,8 +86,6 @@ namespace LibationWinForms.GridView
|
|||||||
{
|
{
|
||||||
LibraryBook = libraryBook;
|
LibraryBook = libraryBook;
|
||||||
|
|
||||||
UserDefinedItem.ItemChanged -= UserDefinedItem_ItemChanged;
|
|
||||||
|
|
||||||
// Immutable properties
|
// Immutable properties
|
||||||
{
|
{
|
||||||
Title = Book.Title;
|
Title = Book.Title;
|
||||||
@ -110,7 +110,7 @@ namespace LibationWinForms.GridView
|
|||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// This event handler receives notifications from the model that it has changed.
|
/// This event handler receives notifications from the model that it has changed.
|
||||||
/// Save to the database and notify the view that it's changed.
|
/// Notify the view that it's changed.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private void UserDefinedItem_ItemChanged(object sender, string itemName)
|
private void UserDefinedItem_ItemChanged(object sender, string itemName)
|
||||||
{
|
{
|
||||||
@ -119,23 +119,23 @@ namespace LibationWinForms.GridView
|
|||||||
if (udi.Book.AudibleProductId != Book.AudibleProductId)
|
if (udi.Book.AudibleProductId != Book.AudibleProductId)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
// UDI changed, possibly in a different context/view. Update this viewmodel. Call NotifyPropertyChanged to notify view.
|
||||||
|
// - This method responds to tons of incidental changes. Do not persist to db from here. Committing to db must be a volitional action by the caller, not incidental. Otherwise batch changes would be impossible; we would only have slow one-offs
|
||||||
|
// - Don't restrict notifying view to 'only if property changed'. This same book instance can get passed to a different view, then changed there. When the chain of events makes its way back here, the property is unchanged (because it's the same instance), but this view is out of sync. NotifyPropertyChanged will then update this view.
|
||||||
switch (itemName)
|
switch (itemName)
|
||||||
{
|
{
|
||||||
case nameof(udi.Tags):
|
case nameof(udi.Tags):
|
||||||
Book.UserDefinedItem.Tags = udi.Tags;
|
Book.UserDefinedItem.Tags = udi.Tags;
|
||||||
SearchEngineCommands.UpdateBookTags(Book);
|
|
||||||
NotifyPropertyChanged(nameof(DisplayTags));
|
NotifyPropertyChanged(nameof(DisplayTags));
|
||||||
break;
|
break;
|
||||||
case nameof(udi.BookStatus):
|
case nameof(udi.BookStatus):
|
||||||
Book.UserDefinedItem.BookStatus = udi.BookStatus;
|
Book.UserDefinedItem.BookStatus = udi.BookStatus;
|
||||||
_bookStatus = udi.BookStatus;
|
_bookStatus = udi.BookStatus;
|
||||||
SearchEngineCommands.UpdateLiberatedStatus(Book);
|
|
||||||
NotifyPropertyChanged(nameof(Liberate));
|
NotifyPropertyChanged(nameof(Liberate));
|
||||||
break;
|
break;
|
||||||
case nameof(udi.PdfStatus):
|
case nameof(udi.PdfStatus):
|
||||||
Book.UserDefinedItem.PdfStatus = udi.PdfStatus;
|
Book.UserDefinedItem.PdfStatus = udi.PdfStatus;
|
||||||
_pdfStatus = udi.PdfStatus;
|
_pdfStatus = udi.PdfStatus;
|
||||||
SearchEngineCommands.UpdateLiberatedStatus(Book);
|
|
||||||
NotifyPropertyChanged(nameof(Liberate));
|
NotifyPropertyChanged(nameof(Liberate));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -143,23 +143,8 @@ namespace LibationWinForms.GridView
|
|||||||
|
|
||||||
/// <summary>Save edits to the database</summary>
|
/// <summary>Save edits to the database</summary>
|
||||||
public void Commit(string newTags, LiberatedStatus bookStatus, LiberatedStatus? pdfStatus)
|
public void Commit(string newTags, LiberatedStatus bookStatus, LiberatedStatus? pdfStatus)
|
||||||
{
|
// MVVM pass-through
|
||||||
// validate
|
=> Book.UpdateBook(newTags, bookStatus: bookStatus, pdfStatus: pdfStatus);
|
||||||
if (DisplayTags.EqualsInsensitive(newTags) &&
|
|
||||||
Liberate.BookStatus == bookStatus &&
|
|
||||||
Liberate.PdfStatus == pdfStatus)
|
|
||||||
return;
|
|
||||||
|
|
||||||
// update cache
|
|
||||||
_bookStatus = bookStatus;
|
|
||||||
_pdfStatus = pdfStatus;
|
|
||||||
|
|
||||||
// set + save
|
|
||||||
Book.UserDefinedItem.Tags = newTags;
|
|
||||||
Book.UserDefinedItem.BookStatus = bookStatus;
|
|
||||||
Book.UserDefinedItem.PdfStatus = pdfStatus;
|
|
||||||
LibraryCommands.UpdateUserDefinedItem(Book);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
|||||||
@ -1,8 +1,4 @@
|
|||||||
using DataLayer;
|
using System;
|
||||||
using Dinah.Core;
|
|
||||||
using FileLiberator;
|
|
||||||
using LibationFileManager;
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.ComponentModel;
|
using System.ComponentModel;
|
||||||
using System.Drawing;
|
using System.Drawing;
|
||||||
@ -10,6 +6,11 @@ using System.Linq;
|
|||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using System.Windows.Forms;
|
using System.Windows.Forms;
|
||||||
|
using ApplicationServices;
|
||||||
|
using DataLayer;
|
||||||
|
using Dinah.Core;
|
||||||
|
using FileLiberator;
|
||||||
|
using LibationFileManager;
|
||||||
|
|
||||||
namespace LibationWinForms.ProcessQueue
|
namespace LibationWinForms.ProcessQueue
|
||||||
{
|
{
|
||||||
@ -353,8 +354,7 @@ $@" Title: {libraryBook.Book.Title}
|
|||||||
|
|
||||||
if (dialogResult == SkipResult)
|
if (dialogResult == SkipResult)
|
||||||
{
|
{
|
||||||
libraryBook.Book.UserDefinedItem.BookStatus = LiberatedStatus.Error;
|
libraryBook.Book.UpdateBookStatus(LiberatedStatus.Error);
|
||||||
ApplicationServices.LibraryCommands.UpdateUserDefinedItem(libraryBook.Book);
|
|
||||||
|
|
||||||
Logger.Info($"Error. Skip: [{libraryBook.Book.AudibleProductId}] {libraryBook.Book.Title}");
|
Logger.Info($"Error. Skip: [{libraryBook.Book.AudibleProductId}] {libraryBook.Book.Title}");
|
||||||
|
|
||||||
|
|||||||
@ -4,6 +4,7 @@ using System.ComponentModel;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using System.Windows.Forms;
|
using System.Windows.Forms;
|
||||||
|
using ApplicationServices;
|
||||||
|
|
||||||
namespace LibationWinForms.ProcessQueue
|
namespace LibationWinForms.ProcessQueue
|
||||||
{
|
{
|
||||||
@ -156,10 +157,7 @@ namespace LibationWinForms.ProcessQueue
|
|||||||
else if (result == ProcessBookResult.FailedAbort)
|
else if (result == ProcessBookResult.FailedAbort)
|
||||||
Queue.ClearQueue();
|
Queue.ClearQueue();
|
||||||
else if (result == ProcessBookResult.FailedSkip)
|
else if (result == ProcessBookResult.FailedSkip)
|
||||||
{
|
nextBook.LibraryBook.Book.UpdateBookStatus(DataLayer.LiberatedStatus.Error);
|
||||||
nextBook.LibraryBook.Book.UserDefinedItem.BookStatus = DataLayer.LiberatedStatus.Error;
|
|
||||||
ApplicationServices.LibraryCommands.UpdateUserDefinedItem(nextBook.LibraryBook.Book);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
Queue_CompletedCountChanged(this, 0);
|
Queue_CompletedCountChanged(this, 0);
|
||||||
counterTimer.Stop();
|
counterTimer.Stop();
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user