Populate new values for book tracking state. Not using them yet, but getting much closer

This commit is contained in:
Robert McRackan 2021-07-28 16:05:00 -04:00
parent 8de8e50829
commit 5c6b5c0af2
8 changed files with 91 additions and 41 deletions

View File

@ -41,7 +41,8 @@ namespace ApplicationServices
// However, it comes with a scary warning when used with EntityFrameworkCore which I'm not yet ready to implement:
// https://github.com/RehanSaeed/Serilog.Exceptions
// work-around: use 3rd param. don't just put exception object in 3rd param -- info overload: stack trace, etc
Log.Logger.Error(lfEx, "Error importing library. Login failed. {@DebugInfo}", new {
Log.Logger.Error(lfEx, "Error importing library. Login failed. {@DebugInfo}", new
{
lfEx.RequestUrl,
ResponseStatusCodeNumber = (int)lfEx.ResponseStatusCode,
ResponseStatusCodeDesc = lfEx.ResponseStatusCode,
@ -100,10 +101,12 @@ namespace ApplicationServices
return newCount;
}
public static int UpdateTags(this LibationContext context, Book book, string newTags)
public static int UpdateTags(Book book, string newTags)
{
try
{
using var context = DbContexts.GetContext();
var udi = book.UserDefinedItem;
// Attach() NoTracking entities before SaveChanges()
@ -122,5 +125,52 @@ namespace ApplicationServices
throw;
}
}
public static int UpdateBook(LibraryBook libraryBook, LiberatedStatus liberatedStatus, string finalAudioPath)
{
try
{
using var context = DbContexts.GetContext();
var udi = libraryBook.Book.UserDefinedItem;
// Attach() NoTracking entities before SaveChanges()
udi.BookStatus = liberatedStatus;
udi.BookLocation = finalAudioPath;
context.Attach(udi).State = Microsoft.EntityFrameworkCore.EntityState.Modified;
var qtyChanges = context.SaveChanges();
if (qtyChanges > 0)
SearchEngineCommands.UpdateLiberatedStatus(libraryBook.Book);
return qtyChanges;
}
catch (Exception ex)
{
Log.Logger.Error(ex, "Error updating tags");
throw;
}
}
public static int UpdatePdf(LibraryBook libraryBook, LiberatedStatus liberatedStatus)
{
try
{
using var context = DbContexts.GetContext();
var udi = libraryBook.Book.UserDefinedItem;
// Attach() NoTracking entities before SaveChanges()
udi.PdfStatus = liberatedStatus;
context.Attach(udi).State = Microsoft.EntityFrameworkCore.EntityState.Modified;
var qtyChanges = context.SaveChanges();
return qtyChanges;
}
catch (Exception ex)
{
Log.Logger.Error(ex, "Error updating tags");
throw;
}
}
}
}

View File

@ -220,8 +220,11 @@ namespace DataLayer
ArgumentValidator.EnsureNotNullOrWhiteSpace(url, nameof(url));
if (!_supplements.Any(s => url.EqualsInsensitive(url)))
if (_supplements.Any(s => url.EqualsInsensitive(url)))
return;
_supplements.Add(new Supplement(this, url));
UserDefinedItem.PdfStatus ??= LiberatedStatus.NotLiberated;
}
#endregion

View File

@ -20,7 +20,7 @@ namespace FileLiberator
public event EventHandler<string> StatusUpdate;
public event EventHandler<LibraryBook> Completed;
public DownloadDecryptBook DecryptBook { get; } = new DownloadDecryptBook();
public DownloadDecryptBook DownloadDecryptBook { get; } = new DownloadDecryptBook();
public DownloadPdf DownloadPdf { get; } = new DownloadPdf();
public bool Validate(LibraryBook libraryBook)
@ -35,7 +35,7 @@ namespace FileLiberator
try
{
{
var statusHandler = await DecryptBook.TryProcessAsync(libraryBook);
var statusHandler = await DownloadDecryptBook.TryProcessAsync(libraryBook);
if (statusHandler.HasErrors)
return statusHandler;
}

View File

@ -1,15 +1,14 @@
using DataLayer;
using Dinah.Core;
using Dinah.Core.ErrorHandling;
using FileManager;
using System;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using AaxDecrypter;
using AudibleApi;
using DataLayer;
using Dinah.Core;
using Dinah.Core.ErrorHandling;
using FileManager;
namespace FileLiberator
{
@ -51,6 +50,11 @@ namespace FileLiberator
if (!finalAudioExists)
return new StatusHandler { "Cannot find final audio file after decryption" };
// GetPath() is very cheap when file exists
var finalAudioPath = AudibleFileStorage.Audio.GetPath(libraryBook.Book.AudibleProductId);
// only need to update if success. if failure, it will remain at 0 == NotLiberated
ApplicationServices.LibraryCommands.UpdateBook(libraryBook, LiberatedStatus.Liberated, finalAudioPath);
return new StatusHandler();
}
finally

View File

@ -1,4 +1,6 @@
using System.IO;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net.Http;
using System.Threading.Tasks;
@ -19,7 +21,12 @@ namespace FileLiberator
{
var proposedDownloadFilePath = getProposedDownloadFilePath(libraryBook);
await downloadPdfAsync(libraryBook, proposedDownloadFilePath);
return verifyDownload(libraryBook);
var result = verifyDownload(libraryBook);
var liberatedStatus = result.IsSuccess ? LiberatedStatus.Liberated : LiberatedStatus.NotLiberated;
ApplicationServices.LibraryCommands.UpdatePdf(libraryBook, liberatedStatus);
return result;
}
private static string getProposedDownloadFilePath(LibraryBook libraryBook)

View File

@ -1,4 +1,5 @@
using System.Collections.Generic;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using ApplicationServices;

View File

@ -86,7 +86,6 @@ namespace LibationWinForms.BookLiberation
var convertBook = new ConvertToMp3();
convertBook.Begin += (_, l) => wireUpEvents(convertBook, l, "Converting");
convertBook.Completed += updateLiberatedStatus;
var automatedBackupsForm = new AutomatedBackupsForm();
@ -104,36 +103,24 @@ namespace LibationWinForms.BookLiberation
convertBook.Begin -= convertBookBegin;
convertBook.StatusUpdate -= statusUpdate;
convertBook.Completed -= convertBookCompleted;
convertBook.Completed -= updateLiberatedStatus;
}
private static BackupBook getWiredUpBackupBook(EventHandler<LibraryBook> completedAction)
{
var backupBook = new BackupBook();
backupBook.DecryptBook.Begin += (_, l) => wireUpEvents(backupBook.DecryptBook, l);
backupBook.DownloadDecryptBook.Begin += (_, l) => wireUpEvents(backupBook.DownloadDecryptBook, l);
backupBook.DownloadPdf.Begin += (_, __) => wireUpEvents(backupBook.DownloadPdf);
// must occur before completedAction. A common use case is:
// - filter by -liberated
// - liberate only that book
// completedAction is to refresh grid
// - want to see that book disappear from grid
// also for this to work, updateIsLiberated can NOT be async
backupBook.DecryptBook.Completed += updateLiberatedStatus;
backupBook.DownloadPdf.Completed += updateLiberatedStatus;
if (completedAction != null)
{
backupBook.DecryptBook.Completed += completedAction;
backupBook.DownloadDecryptBook.Completed += completedAction;
backupBook.DownloadPdf.Completed += completedAction;
}
return backupBook;
}
private static void updateLiberatedStatus(object sender, LibraryBook e) => ApplicationServices.SearchEngineCommands.UpdateLiberatedStatus(e.Book);
private static (Action unsubscribeEvents, LogMe) attachToBackupsForm(BackupBook backupBook, AutomatedBackupsForm automatedBackupsForm = null)
{
#region create logger
@ -151,9 +138,9 @@ namespace LibationWinForms.BookLiberation
#endregion
#region subscribe new form to model's events
backupBook.DecryptBook.Begin += decryptBookBegin;
backupBook.DecryptBook.StatusUpdate += statusUpdate;
backupBook.DecryptBook.Completed += decryptBookCompleted;
backupBook.DownloadDecryptBook.Begin += decryptBookBegin;
backupBook.DownloadDecryptBook.StatusUpdate += statusUpdate;
backupBook.DownloadDecryptBook.Completed += decryptBookCompleted;
backupBook.DownloadPdf.Begin += downloadPdfBegin;
backupBook.DownloadPdf.StatusUpdate += statusUpdate;
backupBook.DownloadPdf.Completed += downloadPdfCompleted;
@ -163,9 +150,9 @@ namespace LibationWinForms.BookLiberation
// unsubscribe so disposed forms aren't still trying to receive notifications
Action unsubscribe = () =>
{
backupBook.DecryptBook.Begin -= decryptBookBegin;
backupBook.DecryptBook.StatusUpdate -= statusUpdate;
backupBook.DecryptBook.Completed -= decryptBookCompleted;
backupBook.DownloadDecryptBook.Begin -= decryptBookBegin;
backupBook.DownloadDecryptBook.StatusUpdate -= statusUpdate;
backupBook.DownloadDecryptBook.Completed -= decryptBookCompleted;
backupBook.DownloadPdf.Begin -= downloadPdfBegin;
backupBook.DownloadPdf.StatusUpdate -= statusUpdate;
backupBook.DownloadPdf.Completed -= downloadPdfCompleted;
@ -497,6 +484,7 @@ $@" Title: {libraryBook.Book.Title}
if (dialogResult == CreateSkipFileResult)
{
ApplicationServices.LibraryCommands.UpdateBook(libraryBook, LiberatedStatus.Error, null);
var path = FileManager.AudibleFileStorage.Audio.CreateSkipFile(libraryBook.Book.Title, libraryBook.Book.AudibleProductId, logMessage);
LogMe.Info($@"
Created new 'skip' file

View File

@ -36,8 +36,6 @@ namespace LibationWinForms
// alias
private DataGridView dataGridView => gridEntryDataGridView;
private LibationContext context;
public ProductsGrid()
{
InitializeComponent();
@ -45,7 +43,6 @@ namespace LibationWinForms
addLiberateButtons();
addEditTagsButtons();
formatColumns();
Disposed += (_, __) => context?.Dispose();
manageLiveImageUpdateSubscriptions();
}
@ -250,7 +247,7 @@ namespace LibationWinForms
if (editTagsForm.ShowDialog() != DialogResult.OK)
return;
var qtyChanges = context.UpdateTags(liveGridEntry.GetBook(), editTagsForm.NewTags);
var qtyChanges = LibraryCommands.UpdateTags(liveGridEntry.GetBook(), editTagsForm.NewTags);
if (qtyChanges == 0)
return;
@ -337,7 +334,7 @@ namespace LibationWinForms
//
// transform into sorted GridEntry.s BEFORE binding
//
context = DbContexts.GetContext();
using var context = DbContexts.GetContext();
var lib = context.GetLibrary_Flat_NoTracking();
// if no data. hide all columns. return