Merge pull request #132 from Mbucari/master

Convert IProcessable to abstract class Processable.
This commit is contained in:
rmcrackan 2021-10-06 11:06:25 -04:00 committed by GitHub
commit 40520b89d1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
20 changed files with 319 additions and 308 deletions

View File

@ -0,0 +1,44 @@
using System;
namespace FileLiberator
{
public abstract class AudioDecodable : Processable
{
public event EventHandler<Action<byte[]>> RequestCoverArt;
public event EventHandler<string> TitleDiscovered;
public event EventHandler<string> AuthorsDiscovered;
public event EventHandler<string> NarratorsDiscovered;
public event EventHandler<byte[]> CoverImageDiscovered;
public abstract void Cancel();
protected void OnRequestCoverArt(Action<byte[]> setCoverArtDel)
{
Serilog.Log.Logger.Debug("Event fired {@DebugInfo}", new { Name = nameof(RequestCoverArt) });
RequestCoverArt?.Invoke(this, setCoverArtDel);
}
protected void OnTitleDiscovered(string title)
{
Serilog.Log.Logger.Debug("Event fired {@DebugInfo}", new { Name = nameof(TitleDiscovered), Title = title });
TitleDiscovered?.Invoke(this, title);
}
protected void OnAuthorsDiscovered(string authors)
{
Serilog.Log.Logger.Debug("Event fired {@DebugInfo}", new { Name = nameof(AuthorsDiscovered), Authors = authors });
AuthorsDiscovered?.Invoke(this, authors);
}
protected void OnNarratorsDiscovered(string narrators)
{
Serilog.Log.Logger.Debug("Event fired {@DebugInfo}", new { Name = nameof(NarratorsDiscovered), Narrators = narrators });
NarratorsDiscovered?.Invoke(this, narrators);
}
protected void OnCoverImageDiscovered(byte[] coverImage)
{
Serilog.Log.Logger.Debug("Event fired {@DebugInfo}", new { Name = nameof(CoverImageDiscovered), CoverImageBytes = coverImage?.Length });
CoverImageDiscovered?.Invoke(this, coverImage);
}
}
}

View File

@ -12,39 +12,26 @@ using System.Threading.Tasks;
namespace FileLiberator namespace FileLiberator
{ {
public class ConvertToMp3 : IAudioDecodable public class ConvertToMp3 : AudioDecodable
{ {
private Mp4File m4bBook; private Mp4File m4bBook;
public event EventHandler<TimeSpan> StreamingTimeRemaining;
public event EventHandler<Action<byte[]>> RequestCoverArt;
public event EventHandler<string> TitleDiscovered;
public event EventHandler<string> AuthorsDiscovered;
public event EventHandler<string> NarratorsDiscovered;
public event EventHandler<byte[]> CoverImageDiscovered;
public event EventHandler<string> StreamingBegin;
public event EventHandler<DownloadProgress> StreamingProgressChanged;
public event EventHandler<string> StreamingCompleted;
public event EventHandler<LibraryBook> Begin;
public event EventHandler<string> StatusUpdate;
public event EventHandler<LibraryBook> Completed;
private long fileSize; private long fileSize;
private string Mp3FileName(string m4bPath) => m4bPath is null ? string.Empty : PathLib.ReplaceExtension(m4bPath, ".mp3"); private string Mp3FileName(string m4bPath) => m4bPath is null ? string.Empty : PathLib.ReplaceExtension(m4bPath, ".mp3");
public void Cancel() => m4bBook?.Cancel(); public override void Cancel() => m4bBook?.Cancel();
public bool Validate(LibraryBook libraryBook) public override bool Validate(LibraryBook libraryBook)
{ {
var path = AudibleFileStorage.Audio.GetPath(libraryBook.Book.AudibleProductId); var path = AudibleFileStorage.Audio.GetPath(libraryBook.Book.AudibleProductId);
return path?.ToLower()?.EndsWith(".m4b") == true && !File.Exists(Mp3FileName(path)); return path?.ToLower()?.EndsWith(".m4b") == true && !File.Exists(Mp3FileName(path));
} }
public async Task<StatusHandler> ProcessAsync(LibraryBook libraryBook) public override async Task<StatusHandler> ProcessAsync(LibraryBook libraryBook)
{ {
Begin?.Invoke(this, libraryBook); OnBegin(libraryBook);
StreamingBegin?.Invoke(this, $"Begin converting {libraryBook} to mp3"); OnStreamingBegin($"Begin converting {libraryBook} to mp3");
try try
{ {
@ -54,10 +41,10 @@ namespace FileLiberator
fileSize = m4bBook.InputStream.Length; fileSize = m4bBook.InputStream.Length;
TitleDiscovered?.Invoke(this, m4bBook.AppleTags.Title); OnTitleDiscovered(m4bBook.AppleTags.Title);
AuthorsDiscovered?.Invoke(this, m4bBook.AppleTags.FirstAuthor); OnAuthorsDiscovered(m4bBook.AppleTags.FirstAuthor);
NarratorsDiscovered?.Invoke(this, m4bBook.AppleTags.Narrator); OnNarratorsDiscovered(m4bBook.AppleTags.Narrator);
CoverImageDiscovered?.Invoke(this, m4bBook.AppleTags.Cover); OnCoverImageDiscovered(m4bBook.AppleTags.Cover);
using var mp3File = File.OpenWrite(Path.GetTempFileName()); using var mp3File = File.OpenWrite(Path.GetTempFileName());
@ -78,8 +65,8 @@ namespace FileLiberator
} }
finally finally
{ {
StreamingCompleted?.Invoke(this, $"Completed converting to mp3: {libraryBook.Book.Title}"); OnStreamingCompleted($"Completed converting to mp3: {libraryBook.Book.Title}");
Completed?.Invoke(this, libraryBook); OnCompleted(libraryBook);
} }
} }
@ -90,11 +77,11 @@ namespace FileLiberator
double estTimeRemaining = remainingSecsToProcess / e.ProcessSpeed; double estTimeRemaining = remainingSecsToProcess / e.ProcessSpeed;
if (double.IsNormal(estTimeRemaining)) if (double.IsNormal(estTimeRemaining))
StreamingTimeRemaining?.Invoke(this, TimeSpan.FromSeconds(estTimeRemaining)); OnStreamingTimeRemaining(TimeSpan.FromSeconds(estTimeRemaining));
double progressPercent = 100 * e.ProcessPosition.TotalSeconds / duration.TotalSeconds; double progressPercent = 100 * e.ProcessPosition.TotalSeconds / duration.TotalSeconds;
StreamingProgressChanged?.Invoke(this, OnStreamingProgressChanged(
new DownloadProgress new DownloadProgress
{ {
ProgressPercentage = progressPercent, ProgressPercentage = progressPercent,

View File

@ -8,31 +8,17 @@ using AudibleApi;
using DataLayer; using DataLayer;
using Dinah.Core; using Dinah.Core;
using Dinah.Core.ErrorHandling; using Dinah.Core.ErrorHandling;
using Dinah.Core.Net.Http;
using FileManager; using FileManager;
namespace FileLiberator namespace FileLiberator
{ {
public class DownloadDecryptBook : IAudioDecodable public class DownloadDecryptBook : AudioDecodable
{ {
private AudiobookDownloadBase aaxcDownloader; private AudiobookDownloadBase abDownloader;
public event EventHandler<TimeSpan> StreamingTimeRemaining; public override async Task<StatusHandler> ProcessAsync(LibraryBook libraryBook)
public event EventHandler<Action<byte[]>> RequestCoverArt;
public event EventHandler<string> TitleDiscovered;
public event EventHandler<string> AuthorsDiscovered;
public event EventHandler<string> NarratorsDiscovered;
public event EventHandler<byte[]> CoverImageDiscovered;
public event EventHandler<string> StreamingBegin;
public event EventHandler<DownloadProgress> StreamingProgressChanged;
public event EventHandler<string> StreamingCompleted;
public event EventHandler<LibraryBook> Begin;
public event EventHandler<string> StatusUpdate;
public event EventHandler<LibraryBook> Completed;
public async Task<StatusHandler> ProcessAsync(LibraryBook libraryBook)
{ {
Begin?.Invoke(this, libraryBook); OnBegin(libraryBook);
try try
{ {
@ -57,13 +43,13 @@ namespace FileLiberator
} }
finally finally
{ {
Completed?.Invoke(this, libraryBook); OnCompleted(libraryBook);
} }
} }
private async Task<string> downloadAudiobookAsync(string cacheDir, string destinationDir, LibraryBook libraryBook) private async Task<string> downloadAudiobookAsync(string cacheDir, string destinationDir, LibraryBook libraryBook)
{ {
StreamingBegin?.Invoke(this, $"Begin decrypting {libraryBook}"); OnStreamingBegin($"Begin decrypting {libraryBook}");
try try
{ {
@ -98,18 +84,19 @@ namespace FileLiberator
var outFileName = Path.Combine(destinationDir, $"{PathLib.ToPathSafeString(libraryBook.Book.Title)} [{libraryBook.Book.AudibleProductId}].{outputFormat.ToString().ToLower()}"); var outFileName = Path.Combine(destinationDir, $"{PathLib.ToPathSafeString(libraryBook.Book.Title)} [{libraryBook.Book.AudibleProductId}].{outputFormat.ToString().ToLower()}");
aaxcDownloader = contentLic.DrmType == AudibleApi.Common.DrmType.Adrm abDownloader = contentLic.DrmType == AudibleApi.Common.DrmType.Adrm
? new AaxcDownloadConverter(outFileName, cacheDir, audiobookDlLic, outputFormat, Configuration.Instance.SplitFilesByChapter) { AppName = "Libation" } ? new AaxcDownloadConverter(outFileName, cacheDir, audiobookDlLic, outputFormat, Configuration.Instance.SplitFilesByChapter)
: new UnencryptedAudiobookDownloader(outFileName, cacheDir, audiobookDlLic); : new UnencryptedAudiobookDownloader(outFileName, cacheDir, audiobookDlLic);
aaxcDownloader.DecryptProgressUpdate += (s, progress) => StreamingProgressChanged?.Invoke(this, progress); abDownloader.AppName = "Libation";
aaxcDownloader.DecryptTimeRemaining += (s, remaining) => StreamingTimeRemaining?.Invoke(this, remaining); abDownloader.DecryptProgressUpdate += (_, progress) => OnStreamingProgressChanged(progress);
aaxcDownloader.RetrievedTitle += (s, title) => TitleDiscovered?.Invoke(this, title); abDownloader.DecryptTimeRemaining += (_, remaining) => OnStreamingTimeRemaining(remaining);
aaxcDownloader.RetrievedAuthors += (s, authors) => AuthorsDiscovered?.Invoke(this, authors); abDownloader.RetrievedTitle += (_, title) => OnTitleDiscovered(title);
aaxcDownloader.RetrievedNarrators += (s, narrators) => NarratorsDiscovered?.Invoke(this, narrators); abDownloader.RetrievedAuthors += (_, authors) => OnAuthorsDiscovered(authors);
aaxcDownloader.RetrievedCoverArt += AaxcDownloader_RetrievedCoverArt; abDownloader.RetrievedNarrators += (_, narrators) => OnNarratorsDiscovered(narrators);
abDownloader.RetrievedCoverArt += AaxcDownloader_RetrievedCoverArt;
// REAL WORK DONE HERE // REAL WORK DONE HERE
var success = await Task.Run(() => aaxcDownloader.Run()); var success = await Task.Run(abDownloader.Run);
// decrypt failed // decrypt failed
if (!success) if (!success)
@ -119,7 +106,7 @@ namespace FileLiberator
} }
finally finally
{ {
StreamingCompleted?.Invoke(this, $"Completed downloading and decrypting {libraryBook.Book.Title}"); OnStreamingCompleted($"Completed downloading and decrypting {libraryBook.Book.Title}");
} }
} }
@ -127,12 +114,12 @@ namespace FileLiberator
{ {
if (e is null && Configuration.Instance.AllowLibationFixup) if (e is null && Configuration.Instance.AllowLibationFixup)
{ {
RequestCoverArt?.Invoke(this, aaxcDownloader.SetCoverArt); OnRequestCoverArt(abDownloader.SetCoverArt);
} }
if (e is not null) if (e is not null)
{ {
CoverImageDiscovered?.Invoke(this, e); OnCoverImageDiscovered(e);
} }
} }
@ -214,11 +201,11 @@ namespace FileLiberator
throw new Exception(errorString("Locale")); throw new Exception(errorString("Locale"));
} }
public bool Validate(LibraryBook libraryBook) => !libraryBook.Book.Audio_Exists; public override bool Validate(LibraryBook libraryBook) => !libraryBook.Book.Audio_Exists;
public void Cancel() public override void Cancel()
{ {
aaxcDownloader?.Cancel(); abDownloader?.Cancel();
} }
} }
} }

View File

@ -6,21 +6,16 @@ using Dinah.Core.Net.Http;
namespace FileLiberator namespace FileLiberator
{ {
// currently only used to download the .zip flies for upgrade // currently only used to download the .zip flies for upgrade
public class DownloadFile : IStreamable public class DownloadFile : Streamable
{ {
public event EventHandler<string> StreamingBegin;
public event EventHandler<DownloadProgress> StreamingProgressChanged;
public event EventHandler<string> StreamingCompleted;
public event EventHandler<TimeSpan> StreamingTimeRemaining;
public async Task<string> PerformDownloadFileAsync(string downloadUrl, string proposedDownloadFilePath) public async Task<string> PerformDownloadFileAsync(string downloadUrl, string proposedDownloadFilePath)
{ {
var client = new HttpClient(); var client = new HttpClient();
var progress = new Progress<DownloadProgress>(); var progress = new Progress<DownloadProgress>();
progress.ProgressChanged += (_, e) => StreamingProgressChanged?.Invoke(this, e); progress.ProgressChanged += (_, e) => OnStreamingProgressChanged(e);
StreamingBegin?.Invoke(this, proposedDownloadFilePath); OnStreamingBegin(proposedDownloadFilePath);
try try
{ {
@ -29,7 +24,7 @@ namespace FileLiberator
} }
finally finally
{ {
StreamingCompleted?.Invoke(this, proposedDownloadFilePath); OnStreamingCompleted(proposedDownloadFilePath);
} }
} }
} }

View File

@ -11,25 +11,15 @@ using FileManager;
namespace FileLiberator namespace FileLiberator
{ {
public class DownloadPdf : IProcessable public class DownloadPdf : Processable
{ {
public event EventHandler<LibraryBook> Begin; public override bool Validate(LibraryBook libraryBook)
public event EventHandler<LibraryBook> Completed;
public event EventHandler<string> StreamingBegin;
public event EventHandler<DownloadProgress> StreamingProgressChanged;
public event EventHandler<string> StreamingCompleted;
public event EventHandler<string> StatusUpdate;
public event EventHandler<TimeSpan> StreamingTimeRemaining;
public bool Validate(LibraryBook libraryBook)
=> !string.IsNullOrWhiteSpace(getdownloadUrl(libraryBook)) => !string.IsNullOrWhiteSpace(getdownloadUrl(libraryBook))
&& !libraryBook.Book.PDF_Exists; && !libraryBook.Book.PDF_Exists;
public async Task<StatusHandler> ProcessAsync(LibraryBook libraryBook) public override async Task<StatusHandler> ProcessAsync(LibraryBook libraryBook)
{ {
Begin?.Invoke(this, libraryBook); OnBegin(libraryBook);
try try
{ {
@ -43,7 +33,7 @@ namespace FileLiberator
} }
finally finally
{ {
Completed?.Invoke(this, libraryBook); OnCompleted(libraryBook);
} }
} }
@ -69,7 +59,7 @@ namespace FileLiberator
private async Task<string> downloadPdfAsync(LibraryBook libraryBook, string proposedDownloadFilePath) private async Task<string> downloadPdfAsync(LibraryBook libraryBook, string proposedDownloadFilePath)
{ {
StreamingBegin?.Invoke(this, proposedDownloadFilePath); OnStreamingBegin(proposedDownloadFilePath);
try try
{ {
@ -77,17 +67,17 @@ namespace FileLiberator
var downloadUrl = await api.GetPdfDownloadLinkAsync(libraryBook.Book.AudibleProductId); var downloadUrl = await api.GetPdfDownloadLinkAsync(libraryBook.Book.AudibleProductId);
var progress = new Progress<DownloadProgress>(); var progress = new Progress<DownloadProgress>();
progress.ProgressChanged += (_, e) => StreamingProgressChanged?.Invoke(this, e); progress.ProgressChanged += (_, e) => OnStreamingProgressChanged(e);
var client = new HttpClient(); var client = new HttpClient();
var actualDownloadedFilePath = await client.DownloadFileAsync(downloadUrl, proposedDownloadFilePath, progress); var actualDownloadedFilePath = await client.DownloadFileAsync(downloadUrl, proposedDownloadFilePath, progress);
StatusUpdate?.Invoke(this, actualDownloadedFilePath); OnStatusUpdate(actualDownloadedFilePath);
return actualDownloadedFilePath; return actualDownloadedFilePath;
} }
finally finally
{ {
StreamingCompleted?.Invoke(this, proposedDownloadFilePath); OnStreamingCompleted(proposedDownloadFilePath);
} }
} }

View File

@ -1,14 +0,0 @@
using System;
namespace FileLiberator
{
public interface IAudioDecodable : IProcessable
{
event EventHandler<Action<byte[]>> RequestCoverArt;
event EventHandler<string> TitleDiscovered;
event EventHandler<string> AuthorsDiscovered;
event EventHandler<string> NarratorsDiscovered;
event EventHandler<byte[]> CoverImageDiscovered;
void Cancel();
}
}

View File

@ -1,23 +0,0 @@
using System;
using System.Threading.Tasks;
using DataLayer;
using Dinah.Core.ErrorHandling;
namespace FileLiberator
{
public interface IProcessable : IStreamable
{
event EventHandler<LibraryBook> Begin;
/// <summary>General string message to display. DON'T rely on this for success, failure, or control logic</summary>
event EventHandler<string> StatusUpdate;
event EventHandler<LibraryBook> Completed;
/// <returns>True == Valid</returns>
bool Validate(LibraryBook libraryBook);
/// <returns>True == success</returns>
Task<StatusHandler> ProcessAsync(LibraryBook libraryBook);
}
}

View File

@ -1,45 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using DataLayer;
using Dinah.Core;
using Dinah.Core.ErrorHandling;
namespace FileLiberator
{
public static class IProcessableExt
{
// when used in foreach: stateful. deferred execution
public static IEnumerable<LibraryBook> GetValidLibraryBooks(this IProcessable processable, IEnumerable<LibraryBook> library)
=> library.Where(libraryBook =>
processable.Validate(libraryBook)
&& (libraryBook.Book.ContentType != ContentType.Episode || FileManager.Configuration.Instance.DownloadEpisodes)
);
public static async Task<StatusHandler> ProcessSingleAsync(this IProcessable processable, LibraryBook libraryBook, bool validate)
{
if (validate && !processable.Validate(libraryBook))
return new StatusHandler { "Validation failed" };
Serilog.Log.Logger.Information("Begin " + nameof(ProcessSingleAsync) + " {@DebugInfo}", new
{
libraryBook.Book.Title,
libraryBook.Book.AudibleProductId,
libraryBook.Book.Locale,
Account = libraryBook.Account?.ToMask() ?? "[empty]"
});
var status
= (await processable.ProcessAsync(libraryBook))
?? new StatusHandler { "Processable should never return a null status" };
return status;
}
public static async Task<StatusHandler> TryProcessAsync(this IProcessable processable, LibraryBook libraryBook)
=> processable.Validate(libraryBook)
? await processable.ProcessAsync(libraryBook)
: new StatusHandler();
}
}

View File

@ -1,13 +0,0 @@
using System;
using Dinah.Core.Net.Http;
namespace FileLiberator
{
public interface IStreamable
{
event EventHandler<string> StreamingBegin;
event EventHandler<DownloadProgress> StreamingProgressChanged;
event EventHandler<TimeSpan> StreamingTimeRemaining;
event EventHandler<string> StreamingCompleted;
}
}

View File

@ -0,0 +1,76 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using DataLayer;
using Dinah.Core;
using Dinah.Core.ErrorHandling;
namespace FileLiberator
{
public abstract class Processable : Streamable
{
public event EventHandler<LibraryBook> Begin;
/// <summary>General string message to display. DON'T rely on this for success, failure, or control logic</summary>
public event EventHandler<string> StatusUpdate;
public event EventHandler<LibraryBook> Completed;
/// <returns>True == Valid</returns>
public abstract bool Validate(LibraryBook libraryBook);
/// <returns>True == success</returns>
public abstract Task<StatusHandler> ProcessAsync(LibraryBook libraryBook);
// when used in foreach: stateful. deferred execution
protected IEnumerable<LibraryBook> GetValidLibraryBooks(IEnumerable<LibraryBook> library)
=> library.Where(libraryBook =>
Validate(libraryBook)
&& (libraryBook.Book.ContentType != ContentType.Episode || FileManager.Configuration.Instance.DownloadEpisodes)
);
protected async Task<StatusHandler> ProcessSingleAsync(LibraryBook libraryBook, bool validate)
{
if (validate && !Validate(libraryBook))
return new StatusHandler { "Validation failed" };
Serilog.Log.Logger.Information("Begin " + nameof(ProcessSingleAsync) + " {@DebugInfo}", new
{
libraryBook.Book.Title,
libraryBook.Book.AudibleProductId,
libraryBook.Book.Locale,
Account = libraryBook.Account?.ToMask() ?? "[empty]"
});
var status
= (await ProcessAsync(libraryBook))
?? new StatusHandler { "Processable should never return a null status" };
return status;
}
protected async Task<StatusHandler> TryProcessAsync(LibraryBook libraryBook)
=> Validate(libraryBook)
? await ProcessAsync(libraryBook)
: new StatusHandler();
protected void OnBegin(LibraryBook libraryBook)
{
Serilog.Log.Logger.Debug("Event fired {@DebugInfo}", new { Name = nameof(Begin), Book = libraryBook.LogFriendly() });
Begin?.Invoke(this, libraryBook);
}
protected void OnStatusUpdate(string statusUpdate)
{
Serilog.Log.Logger.Debug("Event fired {@DebugInfo}", new { Name = nameof(StatusUpdate), Status = statusUpdate });
StatusUpdate?.Invoke(this, statusUpdate);
}
protected void OnCompleted(LibraryBook libraryBook)
{
Serilog.Log.Logger.Debug("Event fired {@DebugInfo}", new { Name = nameof(Completed), Book = libraryBook.LogFriendly() });
Completed?.Invoke(this, libraryBook);
}
}
}

View File

@ -0,0 +1,37 @@
using System;
using Dinah.Core.Net.Http;
namespace FileLiberator
{
public abstract class Streamable
{
public event EventHandler<string> StreamingBegin;
public event EventHandler<DownloadProgress> StreamingProgressChanged;
public event EventHandler<TimeSpan> StreamingTimeRemaining;
public event EventHandler<string> StreamingCompleted;
protected void OnStreamingBegin(string filePath)
{
Serilog.Log.Logger.Debug("Event fired {@DebugInfo}", new { Name = nameof(StreamingBegin), Message = filePath });
StreamingBegin?.Invoke(this, filePath);
}
protected void OnStreamingProgressChanged(DownloadProgress progress)
{
StreamingProgressChanged?.Invoke(this, progress);
}
protected void OnStreamingTimeRemaining(TimeSpan timeRemaining)
{
StreamingTimeRemaining?.Invoke(this, timeRemaining);
}
protected void OnStreamingCompleted(string filePath)
{
Serilog.Log.Logger.Debug("Event fired {@DebugInfo}", new { Name = nameof(StreamingCompleted), Message = filePath });
StreamingCompleted?.Invoke(this, filePath);
//TODO: Update file cache
}
}
}

View File

@ -20,7 +20,7 @@ namespace LibationCli
? RunAsync(CreateProcessable<DownloadPdf>()) ? RunAsync(CreateProcessable<DownloadPdf>())
: RunAsync(CreateBackupBook()); : RunAsync(CreateBackupBook());
private static IProcessable CreateBackupBook() private static Processable CreateBackupBook()
{ {
var downloadPdf = CreateProcessable<DownloadPdf>(); var downloadPdf = CreateProcessable<DownloadPdf>();

View File

@ -13,7 +13,7 @@ namespace LibationCli
public abstract class ProcessableOptionsBase : OptionsBase public abstract class ProcessableOptionsBase : OptionsBase
{ {
protected static TProcessable CreateProcessable<TProcessable>(EventHandler<LibraryBook> completedAction = null) protected static TProcessable CreateProcessable<TProcessable>(EventHandler<LibraryBook> completedAction = null)
where TProcessable : IProcessable, new() where TProcessable : Processable, new()
{ {
var strProc = new TProcessable(); var strProc = new TProcessable();
@ -25,7 +25,7 @@ namespace LibationCli
return strProc; return strProc;
} }
protected static async Task RunAsync(IProcessable Processable) protected static async Task RunAsync(Processable Processable)
{ {
foreach (var libraryBook in Processable.GetValidLibraryBooks(DbContexts.GetLibrary_Flat_NoTracking())) foreach (var libraryBook in Processable.GetValidLibraryBooks(DbContexts.GetLibrary_Flat_NoTracking()))
await ProcessOneAsync(Processable, libraryBook, false); await ProcessOneAsync(Processable, libraryBook, false);
@ -35,7 +35,7 @@ namespace LibationCli
Serilog.Log.Logger.Information(done); Serilog.Log.Logger.Information(done);
} }
private static async Task ProcessOneAsync(IProcessable Processable, LibraryBook libraryBook, bool validate) private static async Task ProcessOneAsync(Processable Processable, LibraryBook libraryBook, bool validate)
{ {
try try
{ {

View File

@ -16,16 +16,16 @@ namespace LibationWinForms.BookLiberation
public override string DecodeActionName => "Converting"; public override string DecodeActionName => "Converting";
#endregion #endregion
#region IProcessable event handler overrides #region Processable event handler overrides
public override void OnBegin(object sender, LibraryBook libraryBook) public override void Processable_Begin(object sender, LibraryBook libraryBook)
{ {
LogMe.Info($"Convert Step, Begin: {libraryBook.Book}"); LogMe.Info($"Convert Step, Begin: {libraryBook.Book}");
base.OnBegin(sender, libraryBook); base.Processable_Begin(sender, libraryBook);
} }
public override void OnCompleted(object sender, LibraryBook libraryBook) public override void Processable_Completed(object sender, LibraryBook libraryBook)
{ {
base.OnCompleted(sender, libraryBook); base.Processable_Completed(sender, libraryBook);
LogMe.Info($"Convert Step, Completed: {libraryBook.Book}{Environment.NewLine}"); LogMe.Info($"Convert Step, Completed: {libraryBook.Book}{Environment.NewLine}");
} }

View File

@ -18,10 +18,10 @@ namespace LibationWinForms.BookLiberation
private string authorNames; private string authorNames;
private string narratorNames; private string narratorNames;
#region IProcessable event handler overrides #region Processable event handler overrides
public override void OnBegin(object sender, LibraryBook libraryBook) public override void Processable_Begin(object sender, LibraryBook libraryBook)
{ {
base.OnBegin(sender, libraryBook); base.Processable_Begin(sender, libraryBook);
GetCoverArtDelegate = () => FileManager.PictureStorage.GetPictureSynchronously( GetCoverArtDelegate = () => FileManager.PictureStorage.GetPictureSynchronously(
new FileManager.PictureDefinition( new FileManager.PictureDefinition(
@ -29,10 +29,10 @@ namespace LibationWinForms.BookLiberation
FileManager.PictureSize._500x500)); FileManager.PictureSize._500x500));
//Set default values from library //Set default values from library
OnTitleDiscovered(sender, libraryBook.Book.Title); AudioDecodable_TitleDiscovered(sender, libraryBook.Book.Title);
OnAuthorsDiscovered(sender, string.Join(", ", libraryBook.Book.Authors)); AudioDecodable_AuthorsDiscovered(sender, string.Join(", ", libraryBook.Book.Authors));
OnNarratorsDiscovered(sender, string.Join(", ", libraryBook.Book.NarratorNames)); AudioDecodable_NarratorsDiscovered(sender, string.Join(", ", libraryBook.Book.NarratorNames));
OnCoverImageDiscovered(sender, AudioDecodable_CoverImageDiscovered(sender,
FileManager.PictureStorage.GetPicture( FileManager.PictureStorage.GetPicture(
new FileManager.PictureDefinition( new FileManager.PictureDefinition(
libraryBook.Book.PictureId, libraryBook.Book.PictureId,
@ -40,10 +40,10 @@ namespace LibationWinForms.BookLiberation
} }
#endregion #endregion
#region IStreamable event handler overrides #region Streamable event handler overrides
public override void OnStreamingProgressChanged(object sender, DownloadProgress downloadProgress) public override void Streamable_StreamingProgressChanged(object sender, DownloadProgress downloadProgress)
{ {
base.OnStreamingProgressChanged(sender, downloadProgress); base.Streamable_StreamingProgressChanged(sender, downloadProgress);
if (!downloadProgress.ProgressPercentage.HasValue) if (!downloadProgress.ProgressPercentage.HasValue)
return; return;
@ -53,46 +53,46 @@ namespace LibationWinForms.BookLiberation
progressBar1.UIThreadAsync(() => progressBar1.Value = (int)downloadProgress.ProgressPercentage); progressBar1.UIThreadAsync(() => progressBar1.Value = (int)downloadProgress.ProgressPercentage);
} }
public override void OnStreamingTimeRemaining(object sender, TimeSpan timeRemaining) public override void Streamable_StreamingTimeRemaining(object sender, TimeSpan timeRemaining)
{ {
base.OnStreamingTimeRemaining(sender, timeRemaining); base.Streamable_StreamingTimeRemaining(sender, timeRemaining);
updateRemainingTime((int)timeRemaining.TotalSeconds); updateRemainingTime((int)timeRemaining.TotalSeconds);
} }
#endregion #endregion
#region IAudioDecodable event handlers #region AudioDecodable event handlers
public override void OnRequestCoverArt(object sender, Action<byte[]> setCoverArtDelegate) public override void AudioDecodable_RequestCoverArt(object sender, Action<byte[]> setCoverArtDelegate)
{ {
base.OnRequestCoverArt(sender, setCoverArtDelegate); base.AudioDecodable_RequestCoverArt(sender, setCoverArtDelegate);
setCoverArtDelegate(GetCoverArtDelegate?.Invoke()); setCoverArtDelegate(GetCoverArtDelegate?.Invoke());
} }
public override void OnTitleDiscovered(object sender, string title) public override void AudioDecodable_TitleDiscovered(object sender, string title)
{ {
base.OnTitleDiscovered(sender, title); base.AudioDecodable_TitleDiscovered(sender, title);
this.UIThreadAsync(() => this.Text = DecodeActionName + " " + title); this.UIThreadAsync(() => this.Text = DecodeActionName + " " + title);
this.title = title; this.title = title;
updateBookInfo(); updateBookInfo();
} }
public override void OnAuthorsDiscovered(object sender, string authors) public override void AudioDecodable_AuthorsDiscovered(object sender, string authors)
{ {
base.OnAuthorsDiscovered(sender, authors); base.AudioDecodable_AuthorsDiscovered(sender, authors);
authorNames = authors; authorNames = authors;
updateBookInfo(); updateBookInfo();
} }
public override void OnNarratorsDiscovered(object sender, string narrators) public override void AudioDecodable_NarratorsDiscovered(object sender, string narrators)
{ {
base.OnNarratorsDiscovered(sender, narrators); base.AudioDecodable_NarratorsDiscovered(sender, narrators);
narratorNames = narrators; narratorNames = narrators;
updateBookInfo(); updateBookInfo();
} }
public override void OnCoverImageDiscovered(object sender, byte[] coverArt) public override void AudioDecodable_CoverImageDiscovered(object sender, byte[] coverArt)
{ {
base.OnCoverImageDiscovered(sender, coverArt); base.AudioDecodable_CoverImageDiscovered(sender, coverArt);
pictureBox1.UIThreadAsync(() => pictureBox1.Image = Dinah.Core.Drawing.ImageReader.ToImage(coverArt)); pictureBox1.UIThreadAsync(() => pictureBox1.Image = Dinah.Core.Drawing.ImageReader.ToImage(coverArt));
} }
#endregion #endregion

View File

@ -16,16 +16,16 @@ namespace LibationWinForms.BookLiberation
public override string DecodeActionName => "Decrypting"; public override string DecodeActionName => "Decrypting";
#endregion #endregion
#region IProcessable event handler overrides #region Processable event handler overrides
public override void OnBegin(object sender, LibraryBook libraryBook) public override void Processable_Begin(object sender, LibraryBook libraryBook)
{ {
LogMe.Info($"Download & Decrypt Step, Begin: {libraryBook.Book}"); LogMe.Info($"Download & Decrypt Step, Begin: {libraryBook.Book}");
base.OnBegin(sender, libraryBook); base.Processable_Begin(sender, libraryBook);
} }
public override void OnCompleted(object sender, LibraryBook libraryBook) public override void Processable_Completed(object sender, LibraryBook libraryBook)
{ {
base.OnCompleted(sender, libraryBook); base.Processable_Completed(sender, libraryBook);
LogMe.Info($"Download & Decrypt Step, Completed: {libraryBook.Book}{Environment.NewLine}"); LogMe.Info($"Download & Decrypt Step, Completed: {libraryBook.Book}{Environment.NewLine}");
} }

View File

@ -9,7 +9,7 @@ namespace LibationWinForms.BookLiberation.BaseForms
{ {
public class LiberationBaseForm : Form public class LiberationBaseForm : Form
{ {
protected IStreamable Streamable { get; private set; } protected Streamable Streamable { get; private set; }
protected LogMe LogMe { get; private set; } protected LogMe LogMe { get; private set; }
private SynchronizeInvoker Invoker { get; init; } private SynchronizeInvoker Invoker { get; init; }
@ -21,7 +21,7 @@ namespace LibationWinForms.BookLiberation.BaseForms
Invoker = new SynchronizeInvoker(); Invoker = new SynchronizeInvoker();
} }
public void RegisterFileLiberator(IStreamable streamable, LogMe logMe = null) public void RegisterFileLiberator(Streamable streamable, LogMe logMe = null)
{ {
if (streamable is null) return; if (streamable is null) return;
@ -30,52 +30,52 @@ namespace LibationWinForms.BookLiberation.BaseForms
Subscribe(streamable); Subscribe(streamable);
if (Streamable is IProcessable processable) if (Streamable is Processable processable)
Subscribe(processable); Subscribe(processable);
if (Streamable is IAudioDecodable audioDecodable) if (Streamable is AudioDecodable audioDecodable)
Subscribe(audioDecodable); Subscribe(audioDecodable);
} }
#region Event Subscribers and Unsubscribers #region Event Subscribers and Unsubscribers
private void Subscribe(IStreamable streamable) private void Subscribe(Streamable streamable)
{ {
UnsubscribeStreamable(this, EventArgs.Empty); UnsubscribeStreamable(this, EventArgs.Empty);
streamable.StreamingBegin += OnStreamingBeginShow; streamable.StreamingBegin += OnStreamingBeginShow;
streamable.StreamingBegin += OnStreamingBegin; streamable.StreamingBegin += Streamable_StreamingBegin;
streamable.StreamingProgressChanged += OnStreamingProgressChanged; streamable.StreamingProgressChanged += Streamable_StreamingProgressChanged;
streamable.StreamingTimeRemaining += OnStreamingTimeRemaining; streamable.StreamingTimeRemaining += Streamable_StreamingTimeRemaining;
streamable.StreamingCompleted += OnStreamingCompleted; streamable.StreamingCompleted += Streamable_StreamingCompleted;
streamable.StreamingCompleted += OnStreamingCompletedClose; streamable.StreamingCompleted += OnStreamingCompletedClose;
Disposed += UnsubscribeStreamable; Disposed += UnsubscribeStreamable;
} }
private void Subscribe(IProcessable processable) private void Subscribe(Processable processable)
{ {
UnsubscribeProcessable(this, null); UnsubscribeProcessable(this, null);
processable.Begin += OnBegin; processable.Begin += Processable_Begin;
processable.StatusUpdate += OnStatusUpdate; processable.StatusUpdate += Processable_StatusUpdate;
processable.Completed += OnCompleted; processable.Completed += Processable_Completed;
//The form is created on IProcessable.Begin and we //The form is created on Processable.Begin and we
//dispose of it on IProcessable.Completed //dispose of it on Processable.Completed
processable.Completed += OnCompletedDispose; processable.Completed += OnCompletedDispose;
//Don't unsubscribe from Dispose because it fires when //Don't unsubscribe from Dispose because it fires when
//IStreamable.StreamingCompleted closes the form, and //Streamable.StreamingCompleted closes the form, and
//the IProcessable events need to live past that event. //the Processable events need to live past that event.
processable.Completed += UnsubscribeProcessable; processable.Completed += UnsubscribeProcessable;
} }
private void Subscribe(IAudioDecodable audioDecodable) private void Subscribe(AudioDecodable audioDecodable)
{ {
UnsubscribeAudioDecodable(this, EventArgs.Empty); UnsubscribeAudioDecodable(this, EventArgs.Empty);
audioDecodable.RequestCoverArt += OnRequestCoverArt; audioDecodable.RequestCoverArt += AudioDecodable_RequestCoverArt;
audioDecodable.TitleDiscovered += OnTitleDiscovered; audioDecodable.TitleDiscovered += AudioDecodable_TitleDiscovered;
audioDecodable.AuthorsDiscovered += OnAuthorsDiscovered; audioDecodable.AuthorsDiscovered += AudioDecodable_AuthorsDiscovered;
audioDecodable.NarratorsDiscovered += OnNarratorsDiscovered; audioDecodable.NarratorsDiscovered += AudioDecodable_NarratorsDiscovered;
audioDecodable.CoverImageDiscovered += OnCoverImageDiscovered; audioDecodable.CoverImageDiscovered += AudioDecodable_CoverImageDiscovered;
Disposed += UnsubscribeAudioDecodable; Disposed += UnsubscribeAudioDecodable;
} }
@ -84,34 +84,34 @@ namespace LibationWinForms.BookLiberation.BaseForms
Disposed -= UnsubscribeStreamable; Disposed -= UnsubscribeStreamable;
Streamable.StreamingBegin -= OnStreamingBeginShow; Streamable.StreamingBegin -= OnStreamingBeginShow;
Streamable.StreamingBegin -= OnStreamingBegin; Streamable.StreamingBegin -= Streamable_StreamingBegin;
Streamable.StreamingProgressChanged -= OnStreamingProgressChanged; Streamable.StreamingProgressChanged -= Streamable_StreamingProgressChanged;
Streamable.StreamingTimeRemaining -= OnStreamingTimeRemaining; Streamable.StreamingTimeRemaining -= Streamable_StreamingTimeRemaining;
Streamable.StreamingCompleted -= OnStreamingCompleted; Streamable.StreamingCompleted -= Streamable_StreamingCompleted;
Streamable.StreamingCompleted -= OnStreamingCompletedClose; Streamable.StreamingCompleted -= OnStreamingCompletedClose;
} }
private void UnsubscribeProcessable(object sender, LibraryBook e) private void UnsubscribeProcessable(object sender, LibraryBook e)
{ {
if (Streamable is not IProcessable processable) if (Streamable is not Processable processable)
return; return;
processable.Completed -= UnsubscribeProcessable; processable.Completed -= UnsubscribeProcessable;
processable.Completed -= OnCompletedDispose; processable.Completed -= OnCompletedDispose;
processable.Completed -= OnCompleted; processable.Completed -= Processable_Completed;
processable.StatusUpdate -= OnStatusUpdate; processable.StatusUpdate -= Processable_StatusUpdate;
processable.Begin -= OnBegin; processable.Begin -= Processable_Begin;
} }
private void UnsubscribeAudioDecodable(object sender, EventArgs e) private void UnsubscribeAudioDecodable(object sender, EventArgs e)
{ {
if (Streamable is not IAudioDecodable audioDecodable) if (Streamable is not AudioDecodable audioDecodable)
return; return;
Disposed -= UnsubscribeAudioDecodable; Disposed -= UnsubscribeAudioDecodable;
audioDecodable.RequestCoverArt -= OnRequestCoverArt; audioDecodable.RequestCoverArt -= AudioDecodable_RequestCoverArt;
audioDecodable.TitleDiscovered -= OnTitleDiscovered; audioDecodable.TitleDiscovered -= AudioDecodable_TitleDiscovered;
audioDecodable.AuthorsDiscovered -= OnAuthorsDiscovered; audioDecodable.AuthorsDiscovered -= AudioDecodable_AuthorsDiscovered;
audioDecodable.NarratorsDiscovered -= OnNarratorsDiscovered; audioDecodable.NarratorsDiscovered -= AudioDecodable_NarratorsDiscovered;
audioDecodable.CoverImageDiscovered -= OnCoverImageDiscovered; audioDecodable.CoverImageDiscovered -= AudioDecodable_CoverImageDiscovered;
audioDecodable.Cancel(); audioDecodable.Cancel();
} }
@ -136,37 +136,27 @@ namespace LibationWinForms.BookLiberation.BaseForms
#endregion #endregion
#region IStreamable event handlers #region Streamable event handlers
public virtual void OnStreamingBegin(object sender, string beginString) public virtual void Streamable_StreamingBegin(object sender, string beginString) { }
=> Serilog.Log.Logger.Debug("Event fired {@DebugInfo}", new { Name = nameof(IStreamable.StreamingBegin), Message = beginString }); public virtual void Streamable_StreamingProgressChanged(object sender, DownloadProgress downloadProgress) { }
public virtual void OnStreamingProgressChanged(object sender, DownloadProgress downloadProgress) { } public virtual void Streamable_StreamingTimeRemaining(object sender, TimeSpan timeRemaining) { }
public virtual void OnStreamingTimeRemaining(object sender, TimeSpan timeRemaining) { } public virtual void Streamable_StreamingCompleted(object sender, string completedString) { }
public virtual void OnStreamingCompleted(object sender, string completedString)
=> Serilog.Log.Logger.Debug("Event fired {@DebugInfo}", new { Name = nameof(IStreamable.StreamingCompleted), Message = completedString });
#endregion #endregion
#region IProcessable event handlers #region Processable event handlers
public virtual void OnBegin(object sender, LibraryBook libraryBook) public virtual void Processable_Begin(object sender, LibraryBook libraryBook) { }
=> Serilog.Log.Logger.Debug("Event fired {@DebugInfo}", new { Name = nameof(IProcessable.Begin), Book = libraryBook.LogFriendly() }); public virtual void Processable_StatusUpdate(object sender, string statusUpdate) { }
public virtual void OnStatusUpdate(object sender, string statusUpdate) public virtual void Processable_Completed(object sender, LibraryBook libraryBook) { }
=> Serilog.Log.Logger.Debug("Event fired {@DebugInfo}", new { Name = nameof(IProcessable.StatusUpdate), Status = statusUpdate });
public virtual void OnCompleted(object sender, LibraryBook libraryBook)
=> Serilog.Log.Logger.Debug("Event fired {@DebugInfo}", new { Name = nameof(IProcessable.Completed), Book = libraryBook.LogFriendly() });
#endregion #endregion
#region IAudioDecodable event handlers #region AudioDecodable event handlers
public virtual void OnRequestCoverArt(object sender, Action<byte[]> setCoverArtDelegate) public virtual void AudioDecodable_RequestCoverArt(object sender, Action<byte[]> setCoverArtDelegate) { }
=> Serilog.Log.Logger.Debug("Event fired {@DebugInfo}", new { Name = nameof(IAudioDecodable.RequestCoverArt) }); public virtual void AudioDecodable_TitleDiscovered(object sender, string title) { }
public virtual void OnTitleDiscovered(object sender, string title) public virtual void AudioDecodable_AuthorsDiscovered(object sender, string authors) { }
=> Serilog.Log.Logger.Debug("Event fired {@DebugInfo}", new { Name = nameof(IAudioDecodable.TitleDiscovered), Title = title }); public virtual void AudioDecodable_NarratorsDiscovered(object sender, string narrators) { }
public virtual void OnAuthorsDiscovered(object sender, string authors) public virtual void AudioDecodable_CoverImageDiscovered(object sender, byte[] coverArt) { }
=> Serilog.Log.Logger.Debug("Event fired {@DebugInfo}", new { Name = nameof(IAudioDecodable.AuthorsDiscovered), Authors = authors });
public virtual void OnNarratorsDiscovered(object sender, string narrators)
=> Serilog.Log.Logger.Debug("Event fired {@DebugInfo}", new { Name = nameof(IAudioDecodable.NarratorsDiscovered), Narrators = narrators });
public virtual void OnCoverImageDiscovered(object sender, byte[] coverArt)
=> Serilog.Log.Logger.Debug("Event fired {@DebugInfo}", new { Name = nameof(IAudioDecodable.CoverImageDiscovered), CoverImageBytes = coverArt?.Length });
#endregion #endregion
} }
} }

View File

@ -17,15 +17,15 @@ namespace LibationWinForms.BookLiberation
} }
#region IStreamable event handler overrides #region Streamable event handler overrides
public override void OnStreamingBegin(object sender, string beginString) public override void Streamable_StreamingBegin(object sender, string beginString)
{ {
base.OnStreamingBegin(sender, beginString); base.Streamable_StreamingBegin(sender, beginString);
filenameLbl.UIThreadAsync(() => filenameLbl.Text = beginString); filenameLbl.UIThreadAsync(() => filenameLbl.Text = beginString);
} }
public override void OnStreamingProgressChanged(object sender, DownloadProgress downloadProgress) public override void Streamable_StreamingProgressChanged(object sender, DownloadProgress downloadProgress)
{ {
base.OnStreamingProgressChanged(sender, downloadProgress); base.Streamable_StreamingProgressChanged(sender, downloadProgress);
// this won't happen with download file. it will happen with download string // this won't happen with download file. it will happen with download string
if (!downloadProgress.TotalBytesToReceive.HasValue || downloadProgress.TotalBytesToReceive.Value <= 0) if (!downloadProgress.TotalBytesToReceive.HasValue || downloadProgress.TotalBytesToReceive.Value <= 0)
return; return;

View File

@ -4,14 +4,14 @@ namespace LibationWinForms.BookLiberation
{ {
internal class PdfDownloadForm : DownloadForm internal class PdfDownloadForm : DownloadForm
{ {
public override void OnBegin(object sender, LibraryBook libraryBook) public override void Processable_Begin(object sender, LibraryBook libraryBook)
{ {
base.OnBegin(sender, libraryBook); base.Processable_Begin(sender, libraryBook);
LogMe.Info($"PDF Step, Begin: {libraryBook.Book}"); LogMe.Info($"PDF Step, Begin: {libraryBook.Book}");
} }
public override void OnCompleted(object sender, LibraryBook libraryBook) public override void Processable_Completed(object sender, LibraryBook libraryBook)
{ {
base.OnCompleted(sender, libraryBook); base.Processable_Completed(sender, libraryBook);
LogMe.Info($"PDF Step, Completed: {libraryBook.Book}"); LogMe.Info($"PDF Step, Completed: {libraryBook.Book}");
} }
} }

View File

@ -96,7 +96,7 @@ namespace LibationWinForms.BookLiberation
await new BackupLoop(logMe, downloadPdf, automatedBackupsForm).RunBackupAsync(); await new BackupLoop(logMe, downloadPdf, automatedBackupsForm).RunBackupAsync();
} }
private static IProcessable CreateBackupBook(LogMe logMe) private static Processable CreateBackupBook(LogMe logMe)
{ {
var downloadPdf = CreateProcessable<DownloadPdf, PdfDownloadForm>(logMe); var downloadPdf = CreateProcessable<DownloadPdf, PdfDownloadForm>(logMe);
@ -132,16 +132,16 @@ namespace LibationWinForms.BookLiberation
} }
/// <summary> /// <summary>
/// Create a new <see cref="IProcessable"/> and links it to a new <see cref="LiberationBaseForm"/>. /// Create a new <see cref="Processable"/> and links it to a new <see cref="LiberationBaseForm"/>.
/// </summary> /// </summary>
/// <typeparam name="TProcessable">The <see cref="IProcessable"/> derived type to create.</typeparam> /// <typeparam name="TProcessable">The <see cref="Processable"/> derived type to create.</typeparam>
/// <typeparam name="TForm">The <see cref="LiberationBaseForm"/> derived Form to create on <see cref="IProcessable.Begin"/>, Show on <see cref="IStreamable.StreamingBegin"/>, Close on <see cref="IStreamable.StreamingCompleted"/>, and Dispose on <see cref="IProcessable.Completed"/> </typeparam> /// <typeparam name="TForm">The <see cref="LiberationBaseForm"/> derived Form to create on <see cref="Processable.Begin"/>, Show on <see cref="Streamable.StreamingBegin"/>, Close on <see cref="Streamable.StreamingCompleted"/>, and Dispose on <see cref="Processable.Completed"/> </typeparam>
/// <param name="logMe">The logger</param> /// <param name="logMe">The logger</param>
/// <param name="completedAction">An additional event handler to handle <see cref="IProcessable.Completed"/></param> /// <param name="completedAction">An additional event handler to handle <see cref="Processable.Completed"/></param>
/// <returns>A new <see cref="IProcessable"/> of type <typeparamref name="TProcessable"/></returns> /// <returns>A new <see cref="Processable"/> of type <typeparamref name="TProcessable"/></returns>
private static TProcessable CreateProcessable<TProcessable, TForm>(LogMe logMe, EventHandler<LibraryBook> completedAction = null) private static TProcessable CreateProcessable<TProcessable, TForm>(LogMe logMe, EventHandler<LibraryBook> completedAction = null)
where TForm : LiberationBaseForm, new() where TForm : LiberationBaseForm, new()
where TProcessable : IProcessable, new() where TProcessable : Processable, new()
{ {
var strProc = new TProcessable(); var strProc = new TProcessable();
@ -149,7 +149,7 @@ namespace LibationWinForms.BookLiberation
{ {
var processForm = new TForm(); var processForm = new TForm();
processForm.RegisterFileLiberator(strProc, logMe); processForm.RegisterFileLiberator(strProc, logMe);
processForm.OnBegin(sender, libraryBook); processForm.Processable_Begin(sender, libraryBook);
}; };
strProc.Completed += completedAction; strProc.Completed += completedAction;
@ -161,10 +161,10 @@ namespace LibationWinForms.BookLiberation
internal abstract class BackupRunner internal abstract class BackupRunner
{ {
protected LogMe LogMe { get; } protected LogMe LogMe { get; }
protected IProcessable Processable { get; } protected Processable Processable { get; }
protected AutomatedBackupsForm AutomatedBackupsForm { get; } protected AutomatedBackupsForm AutomatedBackupsForm { get; }
protected BackupRunner(LogMe logMe, IProcessable processable, AutomatedBackupsForm automatedBackupsForm = null) protected BackupRunner(LogMe logMe, Processable processable, AutomatedBackupsForm automatedBackupsForm = null)
{ {
LogMe = logMe; LogMe = logMe;
Processable = processable; Processable = processable;
@ -278,7 +278,7 @@ An error occurred while trying to process this book. Skip this book permanently?
protected override MessageBoxDefaultButton SkipDialogDefaultButton => MessageBoxDefaultButton.Button2; protected override MessageBoxDefaultButton SkipDialogDefaultButton => MessageBoxDefaultButton.Button2;
protected override DialogResult SkipResult => DialogResult.Yes; protected override DialogResult SkipResult => DialogResult.Yes;
public BackupSingle(LogMe logMe, IProcessable processable, LibraryBook libraryBook) public BackupSingle(LogMe logMe, Processable processable, LibraryBook libraryBook)
: base(logMe, processable) : base(logMe, processable)
{ {
_libraryBook = libraryBook; _libraryBook = libraryBook;
@ -307,7 +307,7 @@ An error occurred while trying to process this book.
protected override MessageBoxDefaultButton SkipDialogDefaultButton => MessageBoxDefaultButton.Button1; protected override MessageBoxDefaultButton SkipDialogDefaultButton => MessageBoxDefaultButton.Button1;
protected override DialogResult SkipResult => DialogResult.Ignore; protected override DialogResult SkipResult => DialogResult.Ignore;
public BackupLoop(LogMe logMe, IProcessable processable, AutomatedBackupsForm automatedBackupsForm) public BackupLoop(LogMe logMe, Processable processable, AutomatedBackupsForm automatedBackupsForm)
: base(logMe, processable, automatedBackupsForm) { } : base(logMe, processable, automatedBackupsForm) { }
protected override async Task RunAsync() protected override async Task RunAsync()