From e714179c309dd34099c642e5847f6aeebea3dd43 Mon Sep 17 00:00:00 2001 From: Michael Bucari-Tovo Date: Thu, 23 Sep 2021 18:01:39 -0600 Subject: [PATCH 1/6] Add support for unencrypted mp3 audiobooks. --- AaxDecrypter/AaxcDownloadConverter.cs | 169 ++++-------------- AaxDecrypter/AudioDownloadBase.cs | 165 +++++++++++++++++ AaxDecrypter/Mp3Downloader.cs | 86 +++++++++ AaxDecrypter/NetworkFileStream.cs | 10 +- FileLiberator/DownloadDecryptBook.cs | 34 ++-- .../Dialogs/SettingsDialog.Designer.cs | 8 +- 6 files changed, 310 insertions(+), 162 deletions(-) create mode 100644 AaxDecrypter/AudioDownloadBase.cs create mode 100644 AaxDecrypter/Mp3Downloader.cs diff --git a/AaxDecrypter/AaxcDownloadConverter.cs b/AaxDecrypter/AaxcDownloadConverter.cs index c91429ba..28192d07 100644 --- a/AaxDecrypter/AaxcDownloadConverter.cs +++ b/AaxDecrypter/AaxcDownloadConverter.cs @@ -1,5 +1,4 @@ using AAXClean; -using Dinah.Core; using Dinah.Core.IO; using Dinah.Core.Net.Http; using Dinah.Core.StepRunner; @@ -8,52 +7,25 @@ using System.IO; namespace AaxDecrypter { - public enum OutputFormat { Mp4a, Mp3 } - public class AaxcDownloadConverter + public class AaxcDownloadConverter : AudioDownloadBase { - public event EventHandler RetrievedTags; - public event EventHandler RetrievedCoverArt; - public event EventHandler DecryptProgressUpdate; - public event EventHandler DecryptTimeRemaining; + protected override StepSequence steps { get; } - public string AppName { get; set; } = nameof(AaxcDownloadConverter); - - private string outputFileName { get; } - private string cacheDir { get; } - private DownloadLicense downloadLicense { get; } private AaxFile aaxFile; - private OutputFormat OutputFormat; - private StepSequence steps { get; } - private NetworkFileStreamPersister nfsPersister; - private bool isCanceled { get; set; } - private string jsonDownloadState => Path.Combine(cacheDir, Path.GetFileNameWithoutExtension(outputFileName) + ".json"); - private string tempFile => PathLib.ReplaceExtension(jsonDownloadState, ".aaxc"); + private OutputFormat OutputFormat { get; } public AaxcDownloadConverter(string outFileName, string cacheDirectory, DownloadLicense dlLic, OutputFormat outputFormat) + :base(outFileName, cacheDirectory, dlLic) { - ArgumentValidator.EnsureNotNullOrWhiteSpace(outFileName, nameof(outFileName)); - outputFileName = outFileName; - - var outDir = Path.GetDirectoryName(outputFileName); - if (!Directory.Exists(outDir)) - throw new ArgumentNullException(nameof(outDir), "Directory does not exist"); - if (File.Exists(outputFileName)) - File.Delete(outputFileName); - - if (!Directory.Exists(cacheDirectory)) - throw new ArgumentNullException(nameof(cacheDirectory), "Directory does not exist"); - cacheDir = cacheDirectory; - - downloadLicense = ArgumentValidator.EnsureNotNull(dlLic, nameof(dlLic)); OutputFormat = outputFormat; steps = new StepSequence { - Name = "Download and Convert Aaxc To " + (outputFormat == OutputFormat.Mp4a ? "M4b" : "Mp3"), + Name = "Download and Convert Aaxc To " + OutputFormat, ["Step 1: Get Aaxc Metadata"] = Step1_GetMetadata, - ["Step 2: Download Decrypted Audiobook"] = Step2_DownloadAndCombine, + ["Step 2: Download Decrypted Audiobook"] = Step2_DownloadAudiobook, ["Step 3: Create Cue"] = Step3_CreateCue, ["Step 4: Cleanup"] = Step4_Cleanup, }; @@ -62,102 +34,56 @@ namespace AaxDecrypter /// /// Setting cover art by this method will insert the art into the audiobook metadata /// - public void SetCoverArt(byte[] coverArt) + public override void SetCoverArt(byte[] coverArt) { - if (coverArt is null) return; + base.SetCoverArt(coverArt); aaxFile?.AppleTags.SetCoverArt(coverArt); - - RetrievedCoverArt?.Invoke(this, coverArt); } - public bool Run() - { - var (IsSuccess, Elapsed) = steps.Run(); + protected override bool Step1_GetMetadata() + { + aaxFile = new AaxFile(InputFileStream); - if (!IsSuccess) - { - Console.WriteLine("WARNING-Conversion failed"); - return false; - } - - var speedup = (int)(aaxFile.Duration.TotalSeconds / (long)Elapsed.TotalSeconds); - Serilog.Log.Logger.Information($"Speedup is {speedup}x realtime."); - return true; - } - - public bool Step1_GetMetadata() - { - //Get metadata from the file over http - - if (File.Exists(jsonDownloadState)) - { - try - { - nfsPersister = new NetworkFileStreamPersister(jsonDownloadState); - //If More than ~1 hour has elapsed since getting the download url, it will expire. - //The new url will be to the same file. - nfsPersister.NetworkFileStream.SetUriForSameFile(new Uri(downloadLicense.DownloadUrl)); - } - catch - { - FileExt.SafeDelete(jsonDownloadState); - FileExt.SafeDelete(tempFile); - nfsPersister = NewNetworkFilePersister(); - } - } - else - { - nfsPersister = NewNetworkFilePersister(); - } - - aaxFile = new AaxFile(nfsPersister.NetworkFileStream); - - RetrievedTags?.Invoke(this, aaxFile.AppleTags); - RetrievedCoverArt?.Invoke(this, aaxFile.AppleTags.Cover); + OnRetrievedTitle(aaxFile.AppleTags.TitleSansUnabridged); + OnRetrievedAuthors(aaxFile.AppleTags.FirstAuthor ?? "[unknown]"); + OnRetrievedNarrators(aaxFile.AppleTags.Narrator ?? "[unknown]"); + OnRetrievedCoverArt(aaxFile.AppleTags.Cover); return !isCanceled; } - private NetworkFileStreamPersister NewNetworkFilePersister() - { - var headers = new System.Net.WebHeaderCollection - { - { "User-Agent", downloadLicense.UserAgent } - }; - var networkFileStream = new NetworkFileStream(tempFile, new Uri(downloadLicense.DownloadUrl), 0, headers); - return new NetworkFileStreamPersister(networkFileStream, jsonDownloadState); - } - - public bool Step2_DownloadAndCombine() + protected override bool Step2_DownloadAudiobook() { var zeroProgress = new DownloadProgress { BytesReceived = 0, ProgressPercentage = 0, - TotalBytesToReceive = nfsPersister.NetworkFileStream.Length + TotalBytesToReceive = InputFileStream.Length }; - DecryptProgressUpdate?.Invoke(this, zeroProgress); + OnDecryptProgressUpdate(zeroProgress); + + + aaxFile.SetDecryptionKey(downloadLicense.AudibleKey, downloadLicense.AudibleIV); + if (File.Exists(outputFileName)) FileExt.SafeDelete(outputFileName); - FileStream outFile = File.Open(outputFileName, FileMode.OpenOrCreate, FileAccess.ReadWrite); - - aaxFile.SetDecryptionKey(downloadLicense.AudibleKey, downloadLicense.AudibleIV); + var outputFile = File.Open(outputFileName, FileMode.OpenOrCreate, FileAccess.ReadWrite); aaxFile.ConversionProgressUpdate += AaxFile_ConversionProgressUpdate; - var decryptionResult = OutputFormat == OutputFormat.Mp4a ? aaxFile.ConvertToMp4a(outFile, downloadLicense.ChapterInfo) : aaxFile.ConvertToMp3(outFile); + var decryptionResult = OutputFormat == OutputFormat.M4b ? aaxFile.ConvertToMp4a(outputFile, downloadLicense.ChapterInfo) : aaxFile.ConvertToMp3(outputFile); aaxFile.ConversionProgressUpdate -= AaxFile_ConversionProgressUpdate; aaxFile.Close(); downloadLicense.ChapterInfo = aaxFile.Chapters; - nfsPersister.Dispose(); + CloseInputFileStream(); - DecryptProgressUpdate?.Invoke(this, zeroProgress); + OnDecryptProgressUpdate(zeroProgress); return decryptionResult == ConversionResult.NoErrorsDetected && !isCanceled; } @@ -169,47 +95,28 @@ namespace AaxDecrypter double estTimeRemaining = remainingSecsToProcess / e.ProcessSpeed; if (double.IsNormal(estTimeRemaining)) - DecryptTimeRemaining?.Invoke(this, TimeSpan.FromSeconds(estTimeRemaining)); + OnDecryptTimeRemaining(TimeSpan.FromSeconds(estTimeRemaining)); - double progressPercent = 100 * e.ProcessPosition.TotalSeconds / duration.TotalSeconds; + double progressPercent = e.ProcessPosition.TotalSeconds / duration.TotalSeconds; - DecryptProgressUpdate?.Invoke(this, + OnDecryptProgressUpdate( new DownloadProgress { - ProgressPercentage = progressPercent, - BytesReceived = (long)(nfsPersister.NetworkFileStream.Length * progressPercent), - TotalBytesToReceive = nfsPersister.NetworkFileStream.Length + ProgressPercentage = 100 * progressPercent, + BytesReceived = (long)(InputFileStream.Length * progressPercent), + TotalBytesToReceive = InputFileStream.Length }); } - public bool Step3_CreateCue() - { - // not a critical step. its failure should not prevent future steps from running - try - { - File.WriteAllText(PathLib.ReplaceExtension(outputFileName, ".cue"), Cue.CreateContents(Path.GetFileName(outputFileName), downloadLicense.ChapterInfo)); - } - catch (Exception ex) - { - Serilog.Log.Logger.Error(ex, $"{nameof(Step3_CreateCue)}. FAILED"); - } - return !isCanceled; - } - - public bool Step4_Cleanup() - { - FileExt.SafeDelete(jsonDownloadState); - FileExt.SafeDelete(tempFile); - return !isCanceled; - } - - public void Cancel() + public override void Cancel() { isCanceled = true; aaxFile?.Cancel(); aaxFile?.Dispose(); - nfsPersister?.NetworkFileStream?.Close(); - nfsPersister?.Dispose(); + CloseInputFileStream(); } - } + + protected override int GetSpeedup(TimeSpan elapsed) + => (int)(aaxFile.Duration.TotalSeconds / (long)elapsed.TotalSeconds); + } } diff --git a/AaxDecrypter/AudioDownloadBase.cs b/AaxDecrypter/AudioDownloadBase.cs new file mode 100644 index 00000000..2792265d --- /dev/null +++ b/AaxDecrypter/AudioDownloadBase.cs @@ -0,0 +1,165 @@ +using Dinah.Core; +using Dinah.Core.IO; +using Dinah.Core.Net.Http; +using Dinah.Core.StepRunner; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace AaxDecrypter +{ + public enum OutputFormat { M4b, Mp3 } + + public abstract class AudioDownloadBase + { + public event EventHandler RetrievedTitle; + public event EventHandler RetrievedAuthors; + public event EventHandler RetrievedNarrators; + public event EventHandler RetrievedCoverArt; + public event EventHandler DecryptProgressUpdate; + public event EventHandler DecryptTimeRemaining; + + public string AppName { get; set; } + + protected bool isCanceled { get; set; } + protected string outputFileName { get; } + protected string cacheDir { get; } + protected DownloadLicense downloadLicense { get; } + protected NetworkFileStream InputFileStream => (nfsPersister ??= OpenNetworkFileStream()).NetworkFileStream; + + + protected abstract StepSequence steps { get; } + private NetworkFileStreamPersister nfsPersister; + + private string jsonDownloadState => Path.Combine(cacheDir, Path.GetFileNameWithoutExtension(outputFileName) + ".json"); + private string tempFile => PathLib.ReplaceExtension(jsonDownloadState, ".tmp"); + + public AudioDownloadBase(string outFileName, string cacheDirectory, DownloadLicense dlLic) + { + AppName = GetType().Name; + + ArgumentValidator.EnsureNotNullOrWhiteSpace(outFileName, nameof(outFileName)); + outputFileName = outFileName; + + var outDir = Path.GetDirectoryName(outputFileName); + if (!Directory.Exists(outDir)) + throw new ArgumentNullException(nameof(outDir), "Directory does not exist"); + if (File.Exists(outputFileName)) + File.Delete(outputFileName); + + if (!Directory.Exists(cacheDirectory)) + throw new ArgumentNullException(nameof(cacheDirectory), "Directory does not exist"); + cacheDir = cacheDirectory; + + downloadLicense = ArgumentValidator.EnsureNotNull(dlLic, nameof(dlLic)); + } + + public abstract void Cancel(); + protected abstract int GetSpeedup(TimeSpan elapsed); + protected abstract bool Step2_DownloadAudiobook(); + protected abstract bool Step1_GetMetadata(); + + public virtual void SetCoverArt(byte[] coverArt) + { + if (coverArt is null) return; + + OnRetrievedCoverArt(coverArt); + } + + + public bool Run() + { + var (IsSuccess, Elapsed) = steps.Run(); + + if (!IsSuccess) + { + Console.WriteLine("WARNING-Conversion failed"); + return false; + } + + Serilog.Log.Logger.Information($"Speedup is {GetSpeedup(Elapsed)}x realtime."); + return true; + } + + protected void OnRetrievedTitle(string title) + => RetrievedTitle?.Invoke(this, title); + protected void OnRetrievedAuthors(string authors) + => RetrievedAuthors?.Invoke(this, authors); + protected void OnRetrievedNarrators(string narrators) + => RetrievedNarrators?.Invoke(this, narrators); + protected void OnRetrievedCoverArt(byte[] coverArt) + => RetrievedCoverArt?.Invoke(this, coverArt); + protected void OnDecryptProgressUpdate(DownloadProgress downloadProgress) + => DecryptProgressUpdate?.Invoke(this, downloadProgress); + protected void OnDecryptTimeRemaining(TimeSpan timeRemaining) + => DecryptTimeRemaining?.Invoke(this, timeRemaining); + + protected void CloseInputFileStream() + { + nfsPersister?.NetworkFileStream?.Close(); + nfsPersister?.Dispose(); + } + + protected bool Step3_CreateCue() + { + // not a critical step. its failure should not prevent future steps from running + try + { + File.WriteAllText(PathLib.ReplaceExtension(outputFileName, ".cue"), Cue.CreateContents(Path.GetFileName(outputFileName), downloadLicense.ChapterInfo)); + } + catch (Exception ex) + { + Serilog.Log.Logger.Error(ex, $"{nameof(Step3_CreateCue)}. FAILED"); + } + return !isCanceled; + } + + protected bool Step4_Cleanup() + { + FileExt.SafeDelete(jsonDownloadState); + FileExt.SafeDelete(tempFile); + return !isCanceled; + } + + private NetworkFileStreamPersister OpenNetworkFileStream() + { + NetworkFileStreamPersister nfsp; + + if (File.Exists(jsonDownloadState)) + { + try + { + nfsp = new NetworkFileStreamPersister(jsonDownloadState); + //If More than ~1 hour has elapsed since getting the download url, it will expire. + //The new url will be to the same file. + nfsp.NetworkFileStream.SetUriForSameFile(new Uri(downloadLicense.DownloadUrl)); + } + catch + { + FileExt.SafeDelete(jsonDownloadState); + FileExt.SafeDelete(tempFile); + nfsp = NewNetworkFilePersister(); + } + } + else + { + nfsp = NewNetworkFilePersister(); + } + return nfsp; + } + + private NetworkFileStreamPersister NewNetworkFilePersister() + { + var headers = new System.Net.WebHeaderCollection + { + { "User-Agent", downloadLicense.UserAgent } + }; + + var networkFileStream = new NetworkFileStream(tempFile, new Uri(downloadLicense.DownloadUrl), 0, headers); + return new NetworkFileStreamPersister(networkFileStream, jsonDownloadState); + } + } +} diff --git a/AaxDecrypter/Mp3Downloader.cs b/AaxDecrypter/Mp3Downloader.cs new file mode 100644 index 00000000..72265d3c --- /dev/null +++ b/AaxDecrypter/Mp3Downloader.cs @@ -0,0 +1,86 @@ +using Dinah.Core.IO; +using Dinah.Core.Net.Http; +using Dinah.Core.StepRunner; +using System; +using System.IO; +using System.Linq; +using System.Threading; + +namespace AaxDecrypter +{ + public class Mp3Downloader : AudioDownloadBase + { + protected override StepSequence steps { get; } + + public Mp3Downloader(string outFileName, string cacheDirectory, DownloadLicense dlLic) + : base(outFileName, cacheDirectory, dlLic) + { + + steps = new StepSequence + { + Name = "Download Mp3 Audiobook", + + ["Step 1: Get Mp3 Metadata"] = Step1_GetMetadata, + ["Step 2: Download Audiobook"] = Step2_DownloadAudiobook, + ["Step 3: Create Cue"] = Step3_CreateCue, + ["Step 4: Cleanup"] = Step4_Cleanup, + }; + } + + public override void Cancel() + { + isCanceled = true; + CloseInputFileStream(); + } + + protected override int GetSpeedup(TimeSpan elapsed) + { + //Not implemented + return 0; + } + + protected override bool Step1_GetMetadata() + { + OnRetrievedCoverArt(null); + + return !isCanceled; + } + + protected override bool Step2_DownloadAudiobook() + { + DateTime startTime = DateTime.Now; + + //MUST put InputFileStream.Length first, because it starts background downloader. + + while (InputFileStream.Length > InputFileStream.WritePosition && !InputFileStream.IsCancelled) + { + var rate = InputFileStream.WritePosition / (DateTime.Now - startTime).TotalSeconds; + + var estTimeRemaining = (InputFileStream.Length - InputFileStream.WritePosition) / rate; + + if (double.IsNormal(estTimeRemaining)) + OnDecryptTimeRemaining(TimeSpan.FromSeconds(estTimeRemaining)); + + var progressPercent = (double)InputFileStream.WritePosition / InputFileStream.Length; + + OnDecryptProgressUpdate( + new DownloadProgress + { + ProgressPercentage = 100 * progressPercent, + BytesReceived = (long)(InputFileStream.Length * progressPercent), + TotalBytesToReceive = InputFileStream.Length + }); + Thread.Sleep(200); + } + + CloseInputFileStream(); + + if (File.Exists(outputFileName)) + FileExt.SafeDelete(outputFileName); + + FileExt.SafeMove(InputFileStream.SaveFilePath, outputFileName); + + return !isCanceled; + } + } +} diff --git a/AaxDecrypter/NetworkFileStream.cs b/AaxDecrypter/NetworkFileStream.cs index 01b63781..d2314b11 100644 --- a/AaxDecrypter/NetworkFileStream.cs +++ b/AaxDecrypter/NetworkFileStream.cs @@ -83,7 +83,7 @@ namespace AaxDecrypter private FileStream _readFile { get; } private Stream _networkStream { get; set; } private bool hasBegunDownloading { get; set; } - private bool isCancelled { get; set; } + public bool IsCancelled { get; private set; } private EventWaitHandle downloadEnded { get; set; } private EventWaitHandle downloadedPiece { get; set; } @@ -238,7 +238,7 @@ namespace AaxDecrypter downloadedPiece.Set(); } - } while (downloadPosition < ContentLength && !isCancelled); + } while (downloadPosition < ContentLength && !IsCancelled); _writeFile.Close(); _networkStream.Close(); @@ -248,7 +248,7 @@ namespace AaxDecrypter downloadedPiece.Set(); downloadEnded.Set(); - if (!isCancelled && WritePosition < ContentLength) + if (!IsCancelled && WritePosition < ContentLength) throw new WebException($"Downloaded size (0x{WritePosition:X10}) is less than {nameof(ContentLength)} (0x{ContentLength:X10})."); if (WritePosition > ContentLength) @@ -421,12 +421,12 @@ namespace AaxDecrypter /// The minimum required flished data length in . private void WaitToPosition(long requiredPosition) { - while (requiredPosition > WritePosition && !isCancelled && hasBegunDownloading && !downloadedPiece.WaitOne(1000)) ; + while (requiredPosition > WritePosition && !IsCancelled && hasBegunDownloading && !downloadedPiece.WaitOne(1000)) ; } public override void Close() { - isCancelled = true; + IsCancelled = true; while (downloadEnded is not null && !downloadEnded.WaitOne(1000)) ; diff --git a/FileLiberator/DownloadDecryptBook.cs b/FileLiberator/DownloadDecryptBook.cs index 98d87b2a..b08b0d18 100644 --- a/FileLiberator/DownloadDecryptBook.cs +++ b/FileLiberator/DownloadDecryptBook.cs @@ -15,7 +15,7 @@ namespace FileLiberator { public class DownloadDecryptBook : IAudioDecodable { - private AaxcDownloadConverter aaxcDownloader; + private AudioDownloadBase aaxcDownloader; public event EventHandler StreamingTimeRemaining; public event EventHandler> RequestCoverArt; @@ -103,24 +103,22 @@ namespace FileLiberator aaxcDecryptDlLic.ChapterInfo.AddChapter(chap.Title, TimeSpan.FromMilliseconds(chap.LengthMs)); } + //I assume if ContentFormat == "MPEG" that the delivered file is an unencrypted mp3. + //This may be wrong, and only time and bug reports will tell. + var outputFormat = + contentLic.ContentMetadata.ContentReference.ContentFormat == "MPEG" || + Configuration.Instance.DecryptToLossy ? + OutputFormat.Mp3 : OutputFormat.M4b; - var format = Configuration.Instance.DecryptToLossy ? OutputFormat.Mp3 : OutputFormat.Mp4a; + var outFileName = Path.Combine(destinationDir, $"{PathLib.ToPathSafeString(libraryBook.Book.Title)} [{libraryBook.Book.AudibleProductId}].{outputFormat.ToString().ToLower()}"); - var extension = format switch - { - OutputFormat.Mp4a => "m4b", - OutputFormat.Mp3 => "mp3", - _ => throw new NotImplementedException(), - }; - - var outFileName = Path.Combine(destinationDir, $"{PathLib.ToPathSafeString(libraryBook.Book.Title)} [{libraryBook.Book.AudibleProductId}].{extension}"); - - - aaxcDownloader = new AaxcDownloadConverter(outFileName, cacheDir, aaxcDecryptDlLic, format) { AppName = "Libation" }; + aaxcDownloader = contentLic.DrmType == AudibleApi.Common.DrmType.Adrm ? new AaxcDownloadConverter(outFileName, cacheDir, aaxcDecryptDlLic, outputFormat) { AppName = "Libation" } : new Mp3Downloader(outFileName, cacheDir, aaxcDecryptDlLic); aaxcDownloader.DecryptProgressUpdate += (s, progress) => StreamingProgressChanged?.Invoke(this, progress); aaxcDownloader.DecryptTimeRemaining += (s, remaining) => StreamingTimeRemaining?.Invoke(this, remaining); + aaxcDownloader.RetrievedTitle += (s, title) => TitleDiscovered?.Invoke(this, title); + aaxcDownloader.RetrievedAuthors += (s, authors) => AuthorsDiscovered?.Invoke(this, authors); + aaxcDownloader.RetrievedNarrators += (s, narrators) => NarratorsDiscovered?.Invoke(this, narrators); aaxcDownloader.RetrievedCoverArt += AaxcDownloader_RetrievedCoverArt; - aaxcDownloader.RetrievedTags += aaxcDownloader_RetrievedTags; // REAL WORK DONE HERE var success = await Task.Run(() => aaxcDownloader.Run()); @@ -137,7 +135,6 @@ namespace FileLiberator } } - private void AaxcDownloader_RetrievedCoverArt(object sender, byte[] e) { if (e is null && Configuration.Instance.AllowLibationFixup) @@ -151,13 +148,6 @@ namespace FileLiberator } } - private void aaxcDownloader_RetrievedTags(object sender, AAXClean.AppleTags e) - { - TitleDiscovered?.Invoke(this, e.TitleSansUnabridged); - AuthorsDiscovered?.Invoke(this, e.FirstAuthor ?? "[unknown]"); - NarratorsDiscovered?.Invoke(this, e.Narrator ?? "[unknown]"); - } - private static (string destinationDir, bool movedAudioFile) MoveFilesToBooksDir(Book product, string outputAudioFilename) { // create final directory. move each file into it. MOVE AUDIO FILE LAST diff --git a/LibationWinForms/Dialogs/SettingsDialog.Designer.cs b/LibationWinForms/Dialogs/SettingsDialog.Designer.cs index 1764204c..bb9694f3 100644 --- a/LibationWinForms/Dialogs/SettingsDialog.Designer.cs +++ b/LibationWinForms/Dialogs/SettingsDialog.Designer.cs @@ -204,9 +204,9 @@ this.convertLossyRb.AutoSize = true; this.convertLossyRb.Location = new System.Drawing.Point(6, 81); this.convertLossyRb.Name = "convertLossyRb"; - this.convertLossyRb.Size = new System.Drawing.Size(242, 19); + this.convertLossyRb.Size = new System.Drawing.Size(329, 19); this.convertLossyRb.TabIndex = 10; - this.convertLossyRb.Text = "Download my books as .MP3 files (Lossy)"; + this.convertLossyRb.Text = "Download my books as .MP3 files (transcode if necessary)"; this.convertLossyRb.UseVisualStyleBackColor = true; // // convertLosslessRb @@ -215,10 +215,10 @@ this.convertLosslessRb.Checked = true; this.convertLosslessRb.Location = new System.Drawing.Point(6, 56); this.convertLosslessRb.Name = "convertLosslessRb"; - this.convertLosslessRb.Size = new System.Drawing.Size(327, 19); + this.convertLosslessRb.Size = new System.Drawing.Size(335, 19); this.convertLosslessRb.TabIndex = 9; this.convertLosslessRb.TabStop = true; - this.convertLosslessRb.Text = "Download my books as .M4B files (Lossless Mp4a format)"; + this.convertLosslessRb.Text = "Download my books in the original audio format (Lossless)"; this.convertLosslessRb.UseVisualStyleBackColor = true; // // inProgressSelectControl From 9f09a62a1e5594759b7d6fe120960013f4e4c2a5 Mon Sep 17 00:00:00 2001 From: Michael Bucari-Tovo Date: Thu, 23 Sep 2021 18:04:12 -0600 Subject: [PATCH 2/6] Ensure chapter info is downloaded for unencrypted MP3s --- FileLiberator/DownloadDecryptBook.cs | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/FileLiberator/DownloadDecryptBook.cs b/FileLiberator/DownloadDecryptBook.cs index b08b0d18..8ef3e189 100644 --- a/FileLiberator/DownloadDecryptBook.cs +++ b/FileLiberator/DownloadDecryptBook.cs @@ -95,7 +95,14 @@ namespace FileLiberator Resources.USER_AGENT ); - if (Configuration.Instance.AllowLibationFixup) + //I assume if ContentFormat == "MPEG" that the delivered file is an unencrypted mp3. + //This may be wrong, and only time and bug reports will tell. + var outputFormat = + contentLic.ContentMetadata.ContentReference.ContentFormat == "MPEG" || + (Configuration.Instance.AllowLibationFixup && Configuration.Instance.DecryptToLossy) ? + OutputFormat.Mp3 : OutputFormat.M4b; + + if (Configuration.Instance.AllowLibationFixup || outputFormat == OutputFormat.Mp3) { aaxcDecryptDlLic.ChapterInfo = new AAXClean.ChapterInfo(); @@ -103,13 +110,6 @@ namespace FileLiberator aaxcDecryptDlLic.ChapterInfo.AddChapter(chap.Title, TimeSpan.FromMilliseconds(chap.LengthMs)); } - //I assume if ContentFormat == "MPEG" that the delivered file is an unencrypted mp3. - //This may be wrong, and only time and bug reports will tell. - var outputFormat = - contentLic.ContentMetadata.ContentReference.ContentFormat == "MPEG" || - Configuration.Instance.DecryptToLossy ? - OutputFormat.Mp3 : OutputFormat.M4b; - var outFileName = Path.Combine(destinationDir, $"{PathLib.ToPathSafeString(libraryBook.Book.Title)} [{libraryBook.Book.AudibleProductId}].{outputFormat.ToString().ToLower()}"); aaxcDownloader = contentLic.DrmType == AudibleApi.Common.DrmType.Adrm ? new AaxcDownloadConverter(outFileName, cacheDir, aaxcDecryptDlLic, outputFormat) { AppName = "Libation" } : new Mp3Downloader(outFileName, cacheDir, aaxcDecryptDlLic); From df42ba584e9b3fd75215ac864758ed7d19d50dcc Mon Sep 17 00:00:00 2001 From: Michael Bucari-Tovo Date: Thu, 23 Sep 2021 18:05:45 -0600 Subject: [PATCH 3/6] Better naming. --- AaxDecrypter/AaxcDownloadConverter.cs | 2 +- .../{AudioDownloadBase.cs => AudiobookDownloadBase.cs} | 4 ++-- .../{Mp3Downloader.cs => Mp3AudiobookDownloader.cs} | 4 ++-- FileLiberator/DownloadDecryptBook.cs | 8 ++++---- 4 files changed, 9 insertions(+), 9 deletions(-) rename AaxDecrypter/{AudioDownloadBase.cs => AudiobookDownloadBase.cs} (97%) rename AaxDecrypter/{Mp3Downloader.cs => Mp3AudiobookDownloader.cs} (92%) diff --git a/AaxDecrypter/AaxcDownloadConverter.cs b/AaxDecrypter/AaxcDownloadConverter.cs index 28192d07..0fa7606b 100644 --- a/AaxDecrypter/AaxcDownloadConverter.cs +++ b/AaxDecrypter/AaxcDownloadConverter.cs @@ -7,7 +7,7 @@ using System.IO; namespace AaxDecrypter { - public class AaxcDownloadConverter : AudioDownloadBase + public class AaxcDownloadConverter : AudiobookDownloadBase { protected override StepSequence steps { get; } diff --git a/AaxDecrypter/AudioDownloadBase.cs b/AaxDecrypter/AudiobookDownloadBase.cs similarity index 97% rename from AaxDecrypter/AudioDownloadBase.cs rename to AaxDecrypter/AudiobookDownloadBase.cs index 2792265d..7a2425d4 100644 --- a/AaxDecrypter/AudioDownloadBase.cs +++ b/AaxDecrypter/AudiobookDownloadBase.cs @@ -13,7 +13,7 @@ namespace AaxDecrypter { public enum OutputFormat { M4b, Mp3 } - public abstract class AudioDownloadBase + public abstract class AudiobookDownloadBase { public event EventHandler RetrievedTitle; public event EventHandler RetrievedAuthors; @@ -37,7 +37,7 @@ namespace AaxDecrypter private string jsonDownloadState => Path.Combine(cacheDir, Path.GetFileNameWithoutExtension(outputFileName) + ".json"); private string tempFile => PathLib.ReplaceExtension(jsonDownloadState, ".tmp"); - public AudioDownloadBase(string outFileName, string cacheDirectory, DownloadLicense dlLic) + public AudiobookDownloadBase(string outFileName, string cacheDirectory, DownloadLicense dlLic) { AppName = GetType().Name; diff --git a/AaxDecrypter/Mp3Downloader.cs b/AaxDecrypter/Mp3AudiobookDownloader.cs similarity index 92% rename from AaxDecrypter/Mp3Downloader.cs rename to AaxDecrypter/Mp3AudiobookDownloader.cs index 72265d3c..d0dfe48e 100644 --- a/AaxDecrypter/Mp3Downloader.cs +++ b/AaxDecrypter/Mp3AudiobookDownloader.cs @@ -8,11 +8,11 @@ using System.Threading; namespace AaxDecrypter { - public class Mp3Downloader : AudioDownloadBase + public class Mp3AudiobookDownloader : AudiobookDownloadBase { protected override StepSequence steps { get; } - public Mp3Downloader(string outFileName, string cacheDirectory, DownloadLicense dlLic) + public Mp3AudiobookDownloader(string outFileName, string cacheDirectory, DownloadLicense dlLic) : base(outFileName, cacheDirectory, dlLic) { diff --git a/FileLiberator/DownloadDecryptBook.cs b/FileLiberator/DownloadDecryptBook.cs index 8ef3e189..9cf43a88 100644 --- a/FileLiberator/DownloadDecryptBook.cs +++ b/FileLiberator/DownloadDecryptBook.cs @@ -15,7 +15,7 @@ namespace FileLiberator { public class DownloadDecryptBook : IAudioDecodable { - private AudioDownloadBase aaxcDownloader; + private AudiobookDownloadBase aaxcDownloader; public event EventHandler StreamingTimeRemaining; public event EventHandler> RequestCoverArt; @@ -54,7 +54,7 @@ namespace FileLiberator if (libraryBook.Book.Audio_Exists) return new StatusHandler { "Cannot find decrypt. Final audio file already exists" }; - var outputAudioFilename = await aaxToM4bConverterDecryptAsync(AudibleFileStorage.DownloadsInProgress, AudibleFileStorage.DecryptInProgress, libraryBook); + var outputAudioFilename = await downloadAudiobookAsync(AudibleFileStorage.DownloadsInProgress, AudibleFileStorage.DecryptInProgress, libraryBook); // decrypt failed if (outputAudioFilename is null) @@ -76,7 +76,7 @@ namespace FileLiberator } } - private async Task aaxToM4bConverterDecryptAsync(string cacheDir, string destinationDir, LibraryBook libraryBook) + private async Task downloadAudiobookAsync(string cacheDir, string destinationDir, LibraryBook libraryBook) { StreamingBegin?.Invoke(this, $"Begin decrypting {libraryBook}"); @@ -112,7 +112,7 @@ namespace FileLiberator var outFileName = Path.Combine(destinationDir, $"{PathLib.ToPathSafeString(libraryBook.Book.Title)} [{libraryBook.Book.AudibleProductId}].{outputFormat.ToString().ToLower()}"); - aaxcDownloader = contentLic.DrmType == AudibleApi.Common.DrmType.Adrm ? new AaxcDownloadConverter(outFileName, cacheDir, aaxcDecryptDlLic, outputFormat) { AppName = "Libation" } : new Mp3Downloader(outFileName, cacheDir, aaxcDecryptDlLic); + aaxcDownloader = contentLic.DrmType == AudibleApi.Common.DrmType.Adrm ? new AaxcDownloadConverter(outFileName, cacheDir, aaxcDecryptDlLic, outputFormat) { AppName = "Libation" } : new Mp3AudiobookDownloader(outFileName, cacheDir, aaxcDecryptDlLic); aaxcDownloader.DecryptProgressUpdate += (s, progress) => StreamingProgressChanged?.Invoke(this, progress); aaxcDownloader.DecryptTimeRemaining += (s, remaining) => StreamingTimeRemaining?.Invoke(this, remaining); aaxcDownloader.RetrievedTitle += (s, title) => TitleDiscovered?.Invoke(this, title); From d9f3fa825ce1f8b2ad0ad3c6ca6dc470aa4be411 Mon Sep 17 00:00:00 2001 From: Michael Bucari-Tovo Date: Thu, 23 Sep 2021 18:13:43 -0600 Subject: [PATCH 4/6] Renaming and comments. --- ...ownloader.cs => UnencryptedAudiobookDownloader.cs} | 4 ++-- FileLiberator/DownloadDecryptBook.cs | 11 ++++++----- 2 files changed, 8 insertions(+), 7 deletions(-) rename AaxDecrypter/{Mp3AudiobookDownloader.cs => UnencryptedAudiobookDownloader.cs} (92%) diff --git a/AaxDecrypter/Mp3AudiobookDownloader.cs b/AaxDecrypter/UnencryptedAudiobookDownloader.cs similarity index 92% rename from AaxDecrypter/Mp3AudiobookDownloader.cs rename to AaxDecrypter/UnencryptedAudiobookDownloader.cs index d0dfe48e..b12ade35 100644 --- a/AaxDecrypter/Mp3AudiobookDownloader.cs +++ b/AaxDecrypter/UnencryptedAudiobookDownloader.cs @@ -8,11 +8,11 @@ using System.Threading; namespace AaxDecrypter { - public class Mp3AudiobookDownloader : AudiobookDownloadBase + public class UnencryptedAudiobookDownloader : AudiobookDownloadBase { protected override StepSequence steps { get; } - public Mp3AudiobookDownloader(string outFileName, string cacheDirectory, DownloadLicense dlLic) + public UnencryptedAudiobookDownloader(string outFileName, string cacheDirectory, DownloadLicense dlLic) : base(outFileName, cacheDirectory, dlLic) { diff --git a/FileLiberator/DownloadDecryptBook.cs b/FileLiberator/DownloadDecryptBook.cs index 9cf43a88..16288d1b 100644 --- a/FileLiberator/DownloadDecryptBook.cs +++ b/FileLiberator/DownloadDecryptBook.cs @@ -87,7 +87,7 @@ namespace FileLiberator var api = await libraryBook.GetApiAsync(); var contentLic = await api.GetDownloadLicenseAsync(libraryBook.Book.AudibleProductId); - var aaxcDecryptDlLic = new DownloadLicense + var audiobookDlLic = new DownloadLicense ( contentLic?.ContentMetadata?.ContentUrl?.OfflineUrl, contentLic?.Voucher?.Key, @@ -96,7 +96,8 @@ namespace FileLiberator ); //I assume if ContentFormat == "MPEG" that the delivered file is an unencrypted mp3. - //This may be wrong, and only time and bug reports will tell. + //I also assume that if DrmType == Adrm, the file will be an mp3. + //These assumptions may be wrong, and only time and bug reports will tell. var outputFormat = contentLic.ContentMetadata.ContentReference.ContentFormat == "MPEG" || (Configuration.Instance.AllowLibationFixup && Configuration.Instance.DecryptToLossy) ? @@ -104,15 +105,15 @@ namespace FileLiberator if (Configuration.Instance.AllowLibationFixup || outputFormat == OutputFormat.Mp3) { - aaxcDecryptDlLic.ChapterInfo = new AAXClean.ChapterInfo(); + audiobookDlLic.ChapterInfo = new AAXClean.ChapterInfo(); foreach (var chap in contentLic.ContentMetadata?.ChapterInfo?.Chapters) - aaxcDecryptDlLic.ChapterInfo.AddChapter(chap.Title, TimeSpan.FromMilliseconds(chap.LengthMs)); + audiobookDlLic.ChapterInfo.AddChapter(chap.Title, TimeSpan.FromMilliseconds(chap.LengthMs)); } var outFileName = Path.Combine(destinationDir, $"{PathLib.ToPathSafeString(libraryBook.Book.Title)} [{libraryBook.Book.AudibleProductId}].{outputFormat.ToString().ToLower()}"); - aaxcDownloader = contentLic.DrmType == AudibleApi.Common.DrmType.Adrm ? new AaxcDownloadConverter(outFileName, cacheDir, aaxcDecryptDlLic, outputFormat) { AppName = "Libation" } : new Mp3AudiobookDownloader(outFileName, cacheDir, aaxcDecryptDlLic); + aaxcDownloader = contentLic.DrmType == AudibleApi.Common.DrmType.Adrm ? new AaxcDownloadConverter(outFileName, cacheDir, audiobookDlLic, outputFormat) { AppName = "Libation" } : new UnencryptedAudiobookDownloader(outFileName, cacheDir, audiobookDlLic); aaxcDownloader.DecryptProgressUpdate += (s, progress) => StreamingProgressChanged?.Invoke(this, progress); aaxcDownloader.DecryptTimeRemaining += (s, remaining) => StreamingTimeRemaining?.Invoke(this, remaining); aaxcDownloader.RetrievedTitle += (s, title) => TitleDiscovered?.Invoke(this, title); From 803a0b7ccf7f99aa0f231d7cb6c4164e9f29a63e Mon Sep 17 00:00:00 2001 From: Michael Bucari-Tovo Date: Thu, 23 Sep 2021 18:14:29 -0600 Subject: [PATCH 5/6] Comment typo. --- FileLiberator/DownloadDecryptBook.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/FileLiberator/DownloadDecryptBook.cs b/FileLiberator/DownloadDecryptBook.cs index 16288d1b..f832c8a8 100644 --- a/FileLiberator/DownloadDecryptBook.cs +++ b/FileLiberator/DownloadDecryptBook.cs @@ -96,7 +96,7 @@ namespace FileLiberator ); //I assume if ContentFormat == "MPEG" that the delivered file is an unencrypted mp3. - //I also assume that if DrmType == Adrm, the file will be an mp3. + //I also assume that if DrmType != Adrm, the file will be an mp3. //These assumptions may be wrong, and only time and bug reports will tell. var outputFormat = contentLic.ContentMetadata.ContentReference.ContentFormat == "MPEG" || From 71075838eb459d7fb2f0f902990f9c7bcfc732e6 Mon Sep 17 00:00:00 2001 From: Mbucari <37587114+Mbucari@users.noreply.github.com> Date: Thu, 23 Sep 2021 19:29:25 -0600 Subject: [PATCH 6/6] Moved event logging to LibationBaseForm --- FileLiberator/ConvertToMp3.cs | 15 --------- FileLiberator/DownloadDecryptBook.cs | 15 --------- FileLiberator/DownloadFile.cs | 6 ---- FileLiberator/DownloadPdf.cs | 9 ------ .../BookLiberation/AudioConvertForm.cs | 5 ++- .../BookLiberation/AudioDecodeForm.cs | 23 ++++++++++--- .../BookLiberation/AudioDecryptForm.cs | 5 ++- .../BaseForms/LiberationBaseForm.cs | 32 +++++++++++++------ .../BookLiberation/DownloadForm.cs | 2 ++ .../BookLiberation/PdfDownloadForm.cs | 12 +++++-- 10 files changed, 61 insertions(+), 63 deletions(-) diff --git a/FileLiberator/ConvertToMp3.cs b/FileLiberator/ConvertToMp3.cs index 07da90bf..ab99927a 100644 --- a/FileLiberator/ConvertToMp3.cs +++ b/FileLiberator/ConvertToMp3.cs @@ -29,21 +29,6 @@ namespace FileLiberator public event EventHandler StatusUpdate; public event EventHandler Completed; - public ConvertToMp3() - { - RequestCoverArt += (o, e) => Serilog.Log.Logger.Debug("Event fired {@DebugInfo}", new { Name = nameof(RequestCoverArt) }); - TitleDiscovered += (o, e) => Serilog.Log.Logger.Debug("Event fired {@DebugInfo}", new { Name = nameof(TitleDiscovered), Title = e }); - AuthorsDiscovered += (o, e) => Serilog.Log.Logger.Debug("Event fired {@DebugInfo}", new { Name = nameof(AuthorsDiscovered), Authors = e }); - NarratorsDiscovered += (o, e) => Serilog.Log.Logger.Debug("Event fired {@DebugInfo}", new { Name = nameof(NarratorsDiscovered), Narrators = e }); - CoverImageDiscovered += (o, e) => Serilog.Log.Logger.Debug("Event fired {@DebugInfo}", new { Name = nameof(CoverImageDiscovered), CoverImageBytes = e?.Length }); - - StreamingBegin += (o, e) => Serilog.Log.Logger.Information("Event fired {@DebugInfo}", new { Name = nameof(StreamingBegin), Message = e }); - StreamingCompleted += (o, e) => Serilog.Log.Logger.Information("Event fired {@DebugInfo}", new { Name = nameof(StreamingCompleted), Message = e }); - - Begin += (o, e) => Serilog.Log.Logger.Information("Event fired {@DebugInfo}", new { Name = nameof(Begin), Book = e.LogFriendly() }); - Completed += (o, e) => Serilog.Log.Logger.Information("Event fired {@DebugInfo}", new { Name = nameof(Completed), Book = e.LogFriendly() }); - } - private long fileSize; private string Mp3FileName(string m4bPath) => m4bPath is null ? string.Empty : PathLib.ReplaceExtension(m4bPath, ".mp3"); diff --git a/FileLiberator/DownloadDecryptBook.cs b/FileLiberator/DownloadDecryptBook.cs index f832c8a8..4843ecd1 100644 --- a/FileLiberator/DownloadDecryptBook.cs +++ b/FileLiberator/DownloadDecryptBook.cs @@ -30,21 +30,6 @@ namespace FileLiberator public event EventHandler StatusUpdate; public event EventHandler Completed; - public DownloadDecryptBook() - { - RequestCoverArt += (o, e) => Serilog.Log.Logger.Debug("Event fired {@DebugInfo}", new { Name = nameof(RequestCoverArt) }); - TitleDiscovered += (o, e) => Serilog.Log.Logger.Debug("Event fired {@DebugInfo}", new { Name = nameof(TitleDiscovered), Title = e }); - AuthorsDiscovered += (o, e) => Serilog.Log.Logger.Debug("Event fired {@DebugInfo}", new { Name = nameof(AuthorsDiscovered), Authors = e }); - NarratorsDiscovered += (o, e) => Serilog.Log.Logger.Debug("Event fired {@DebugInfo}", new { Name = nameof(NarratorsDiscovered), Narrators = e }); - CoverImageDiscovered += (o, e) => Serilog.Log.Logger.Debug("Event fired {@DebugInfo}", new { Name = nameof(CoverImageDiscovered), CoverImageBytes = e?.Length }); - - StreamingBegin += (o, e) => Serilog.Log.Logger.Information("Event fired {@DebugInfo}", new { Name = nameof(StreamingBegin), Message = e }); - StreamingCompleted += (o, e) => Serilog.Log.Logger.Information("Event fired {@DebugInfo}", new { Name = nameof(StreamingCompleted), Message = e }); - - Begin += (o, e) => Serilog.Log.Logger.Information("Event fired {@DebugInfo}", new { Name = nameof(Begin), Book = e.LogFriendly() }); - Completed += (o, e) => Serilog.Log.Logger.Information("Event fired {@DebugInfo}", new { Name = nameof(Completed), Book = e.LogFriendly() }); - } - public async Task ProcessAsync(LibraryBook libraryBook) { Begin?.Invoke(this, libraryBook); diff --git a/FileLiberator/DownloadFile.cs b/FileLiberator/DownloadFile.cs index d0a816b8..9f23b1e0 100644 --- a/FileLiberator/DownloadFile.cs +++ b/FileLiberator/DownloadFile.cs @@ -13,12 +13,6 @@ namespace FileLiberator public event EventHandler StreamingCompleted; public event EventHandler StreamingTimeRemaining; - public DownloadFile() - { - StreamingBegin += (o, e) => Serilog.Log.Logger.Information("Event fired {@DebugInfo}", new { Name = nameof(StreamingBegin), Message = e }); - StreamingCompleted += (o, e) => Serilog.Log.Logger.Information("Event fired {@DebugInfo}", new { Name = nameof(StreamingCompleted), Message = e }); - } - public async Task PerformDownloadFileAsync(string downloadUrl, string proposedDownloadFilePath) { var client = new HttpClient(); diff --git a/FileLiberator/DownloadPdf.cs b/FileLiberator/DownloadPdf.cs index 74e4a66d..0ed4cd6b 100644 --- a/FileLiberator/DownloadPdf.cs +++ b/FileLiberator/DownloadPdf.cs @@ -17,15 +17,6 @@ namespace FileLiberator => !string.IsNullOrWhiteSpace(getdownloadUrl(libraryBook)) && !libraryBook.Book.PDF_Exists; - public DownloadPdf() - { - StreamingBegin += (o, e) => Serilog.Log.Logger.Information("Event fired {@DebugInfo}", new { Name = nameof(StreamingBegin), Message = e }); - StreamingCompleted += (o, e) => Serilog.Log.Logger.Information("Event fired {@DebugInfo}", new { Name = nameof(StreamingCompleted), Message = e }); - - Begin += (o, e) => Serilog.Log.Logger.Information("Event fired {@DebugInfo}", new { Name = nameof(Begin), Book = e.LogFriendly() }); - Completed += (o, e) => Serilog.Log.Logger.Information("Event fired {@DebugInfo}", new { Name = nameof(Completed), Book = e.LogFriendly() }); - } - public override async Task ProcessItemAsync(LibraryBook libraryBook) { var proposedDownloadFilePath = getProposedDownloadFilePath(libraryBook); diff --git a/LibationWinForms/BookLiberation/AudioConvertForm.cs b/LibationWinForms/BookLiberation/AudioConvertForm.cs index 1bedf9bf..4960cfa3 100644 --- a/LibationWinForms/BookLiberation/AudioConvertForm.cs +++ b/LibationWinForms/BookLiberation/AudioConvertForm.cs @@ -24,7 +24,10 @@ namespace LibationWinForms.BookLiberation base.OnBegin(sender, libraryBook); } public override void OnCompleted(object sender, LibraryBook libraryBook) - => LogMe.Info($"Convert Step, Completed: {libraryBook.Book}{Environment.NewLine}"); + { + base.OnCompleted(sender, libraryBook); + LogMe.Info($"Convert Step, Completed: {libraryBook.Book}{Environment.NewLine}"); + } #endregion } diff --git a/LibationWinForms/BookLiberation/AudioDecodeForm.cs b/LibationWinForms/BookLiberation/AudioDecodeForm.cs index 255268c4..3a54f5aa 100644 --- a/LibationWinForms/BookLiberation/AudioDecodeForm.cs +++ b/LibationWinForms/BookLiberation/AudioDecodeForm.cs @@ -21,6 +21,8 @@ namespace LibationWinForms.BookLiberation #region IProcessable event handler overrides public override void OnBegin(object sender, LibraryBook libraryBook) { + base.OnBegin(sender, libraryBook); + GetCoverArtDelegate = () => FileManager.PictureStorage.GetPictureSynchronously( new FileManager.PictureDefinition( libraryBook.Book.PictureId, @@ -41,6 +43,7 @@ namespace LibationWinForms.BookLiberation #region IStreamable event handler overrides public override void OnStreamingProgressChanged(object sender, DownloadProgress downloadProgress) { + base.OnStreamingProgressChanged(sender, downloadProgress); if (!downloadProgress.ProgressPercentage.HasValue) return; @@ -51,16 +54,23 @@ namespace LibationWinForms.BookLiberation } public override void OnStreamingTimeRemaining(object sender, TimeSpan timeRemaining) - => updateRemainingTime((int)timeRemaining.TotalSeconds); + { + base.OnStreamingTimeRemaining(sender, timeRemaining); + updateRemainingTime((int)timeRemaining.TotalSeconds); + } #endregion #region IAudioDecodable event handlers public override void OnRequestCoverArt(object sender, Action setCoverArtDelegate) - => setCoverArtDelegate(GetCoverArtDelegate?.Invoke()); + { + base.OnRequestCoverArt(sender, setCoverArtDelegate); + setCoverArtDelegate(GetCoverArtDelegate?.Invoke()); + } public override void OnTitleDiscovered(object sender, string title) { + base.OnTitleDiscovered(sender, title); this.UIThreadAsync(() => this.Text = DecodeActionName + " " + title); this.title = title; updateBookInfo(); @@ -68,18 +78,23 @@ namespace LibationWinForms.BookLiberation public override void OnAuthorsDiscovered(object sender, string authors) { + base.OnAuthorsDiscovered(sender, authors); authorNames = authors; updateBookInfo(); } public override void OnNarratorsDiscovered(object sender, string narrators) { + base.OnNarratorsDiscovered(sender, narrators); narratorNames = narrators; updateBookInfo(); } - public override void OnCoverImageDiscovered(object sender, byte[] coverArt) - => pictureBox1.UIThreadAsync(() => pictureBox1.Image = Dinah.Core.Drawing.ImageReader.ToImage(coverArt)); + public override void OnCoverImageDiscovered(object sender, byte[] coverArt) + { + base.OnCoverImageDiscovered(sender, coverArt); + pictureBox1.UIThreadAsync(() => pictureBox1.Image = Dinah.Core.Drawing.ImageReader.ToImage(coverArt)); + } #endregion // thread-safe UI updates diff --git a/LibationWinForms/BookLiberation/AudioDecryptForm.cs b/LibationWinForms/BookLiberation/AudioDecryptForm.cs index 477c3bb7..58d8d3ac 100644 --- a/LibationWinForms/BookLiberation/AudioDecryptForm.cs +++ b/LibationWinForms/BookLiberation/AudioDecryptForm.cs @@ -24,7 +24,10 @@ namespace LibationWinForms.BookLiberation base.OnBegin(sender, libraryBook); } public override void OnCompleted(object sender, LibraryBook libraryBook) - => LogMe.Info($"Download & Decrypt Step, Completed: {libraryBook.Book}{Environment.NewLine}"); + { + base.OnCompleted(sender, libraryBook); + LogMe.Info($"Download & Decrypt Step, Completed: {libraryBook.Book}{Environment.NewLine}"); + } #endregion } diff --git a/LibationWinForms/BookLiberation/BaseForms/LiberationBaseForm.cs b/LibationWinForms/BookLiberation/BaseForms/LiberationBaseForm.cs index 5cd32e01..0b8eeef7 100644 --- a/LibationWinForms/BookLiberation/BaseForms/LiberationBaseForm.cs +++ b/LibationWinForms/BookLiberation/BaseForms/LiberationBaseForm.cs @@ -137,24 +137,36 @@ namespace LibationWinForms.BookLiberation.BaseForms #endregion #region IStreamable event handlers - public virtual void OnStreamingBegin(object sender, string beginString) { } + public virtual void OnStreamingBegin(object sender, string beginString) + => Serilog.Log.Logger.Debug("Event fired {@DebugInfo}", new { Name = nameof(IStreamable.StreamingBegin), Message = beginString }); public virtual void OnStreamingProgressChanged(object sender, DownloadProgress downloadProgress) { } public virtual void OnStreamingTimeRemaining(object sender, TimeSpan timeRemaining) { } - public virtual void OnStreamingCompleted(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 #region IProcessable event handlers - public virtual void OnBegin(object sender, LibraryBook libraryBook) { } - public virtual void OnStatusUpdate(object sender, string statusUpdate) { } - public virtual void OnCompleted(object sender, LibraryBook libraryBook) { } + public virtual void OnBegin(object sender, LibraryBook libraryBook) + => Serilog.Log.Logger.Debug("Event fired {@DebugInfo}", new { Name = nameof(IProcessable.Begin), Book = libraryBook.LogFriendly() }); + public virtual void OnStatusUpdate(object sender, string statusUpdate) + => 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 #region IAudioDecodable event handlers - public virtual void OnRequestCoverArt(object sender, Action setCoverArtDelegate) { } - public virtual void OnTitleDiscovered(object sender, string title) { } - public virtual void OnAuthorsDiscovered(object sender, string authors) { } - public virtual void OnNarratorsDiscovered(object sender, string narrators) { } - public virtual void OnCoverImageDiscovered(object sender, byte[] coverArt) { } + public virtual void OnRequestCoverArt(object sender, Action setCoverArtDelegate) + => Serilog.Log.Logger.Debug("Event fired {@DebugInfo}", new { Name = nameof(IAudioDecodable.RequestCoverArt) }); + public virtual void OnTitleDiscovered(object sender, string title) + => Serilog.Log.Logger.Debug("Event fired {@DebugInfo}", new { Name = nameof(IAudioDecodable.TitleDiscovered), Title = title }); + public virtual void OnAuthorsDiscovered(object sender, string authors) + => 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 } } diff --git a/LibationWinForms/BookLiberation/DownloadForm.cs b/LibationWinForms/BookLiberation/DownloadForm.cs index 1843aaa3..42127070 100644 --- a/LibationWinForms/BookLiberation/DownloadForm.cs +++ b/LibationWinForms/BookLiberation/DownloadForm.cs @@ -20,10 +20,12 @@ namespace LibationWinForms.BookLiberation #region IStreamable event handler overrides public override void OnStreamingBegin(object sender, string beginString) { + base.OnStreamingBegin(sender, beginString); filenameLbl.UIThreadAsync(() => filenameLbl.Text = beginString); } public override void OnStreamingProgressChanged(object sender, DownloadProgress downloadProgress) { + base.OnStreamingProgressChanged(sender, downloadProgress); // this won't happen with download file. it will happen with download string if (!downloadProgress.TotalBytesToReceive.HasValue || downloadProgress.TotalBytesToReceive.Value <= 0) return; diff --git a/LibationWinForms/BookLiberation/PdfDownloadForm.cs b/LibationWinForms/BookLiberation/PdfDownloadForm.cs index 3def88c2..85d85eef 100644 --- a/LibationWinForms/BookLiberation/PdfDownloadForm.cs +++ b/LibationWinForms/BookLiberation/PdfDownloadForm.cs @@ -4,7 +4,15 @@ namespace LibationWinForms.BookLiberation { internal class PdfDownloadForm : DownloadForm { - public override void OnBegin(object sender, LibraryBook libraryBook) => LogMe.Info($"PDF Step, Begin: {libraryBook.Book}"); - public override void OnCompleted(object sender, LibraryBook libraryBook) => LogMe.Info($"PDF Step, Completed: {libraryBook.Book}"); + public override void OnBegin(object sender, LibraryBook libraryBook) + { + base.OnBegin(sender, libraryBook); + LogMe.Info($"PDF Step, Begin: {libraryBook.Book}"); + } + public override void OnCompleted(object sender, LibraryBook libraryBook) + { + base.OnCompleted(sender, libraryBook); + LogMe.Info($"PDF Step, Completed: {libraryBook.Book}"); + } } }