From 4989cda93c9f179b95a477eda5e4573e582349b1 Mon Sep 17 00:00:00 2001 From: Michael Bucari-Tovo Date: Tue, 10 Aug 2021 20:16:34 -0600 Subject: [PATCH] Added synchronous Picture downloader. --- AaxDecrypter/AaxcDownloadConverter.cs | 34 +++++-------------- FileManager/PictureStorage.cs | 24 +++++++++++-- .../ProcessorAutomationController.cs | 27 +-------------- 3 files changed, 31 insertions(+), 54 deletions(-) diff --git a/AaxDecrypter/AaxcDownloadConverter.cs b/AaxDecrypter/AaxcDownloadConverter.cs index 89d787f4..efbbda4a 100644 --- a/AaxDecrypter/AaxcDownloadConverter.cs +++ b/AaxDecrypter/AaxcDownloadConverter.cs @@ -1,19 +1,13 @@ using AAXClean; using Dinah.Core; -using Dinah.Core.Diagnostics; using Dinah.Core.IO; -using Dinah.Core.Logging; using Dinah.Core.StepRunner; using System; using System.IO; namespace AaxDecrypter { - public enum OutputFormat - { - Mp4a, - Mp3 - } + public enum OutputFormat { Mp4a, Mp3 } public class AaxcDownloadConverter { public event EventHandler RetrievedTags; @@ -26,7 +20,6 @@ namespace AaxDecrypter private string cacheDir { get; } private DownloadLicense downloadLicense { get; } private AaxFile aaxFile; - private byte[] coverArt; private OutputFormat OutputFormat; private StepSequence steps { get; } @@ -65,11 +58,15 @@ namespace AaxDecrypter }; } + /// + /// Setting cover art by this method will insert the art into the audiobook metadata + /// public void SetCoverArt(byte[] coverArt) { if (coverArt is null) return; - this.coverArt = coverArt; + aaxFile?.AppleTags.SetCoverArt(coverArt); + RetrievedCoverArt?.Invoke(this, coverArt); } @@ -98,7 +95,7 @@ namespace AaxDecrypter try { nfsPersister = new NetworkFileStreamPersister(jsonDownloadState); - //If More thaan ~1 hour has elapsed since getting the download url, it will expire. + //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)); } @@ -116,10 +113,9 @@ namespace AaxDecrypter nfsPersister.NetworkFileStream.BeginDownloading(); aaxFile = new AaxFile(nfsPersister.NetworkFileStream); - coverArt = aaxFile.AppleTags.Cover; RetrievedTags?.Invoke(this, aaxFile.AppleTags); - RetrievedCoverArt?.Invoke(this, coverArt); + RetrievedCoverArt?.Invoke(this, aaxFile.AppleTags.Cover); return !isCanceled; } @@ -136,7 +132,6 @@ namespace AaxDecrypter public bool Step2_DownloadAndCombine() { - DecryptProgressUpdate?.Invoke(this, 0); if (File.Exists(outputFileName)) @@ -147,7 +142,6 @@ namespace AaxDecrypter aaxFile.SetDecryptionKey(downloadLicense.AudibleKey, downloadLicense.AudibleIV); aaxFile.ConversionProgressUpdate += AaxFile_ConversionProgressUpdate; - var decryptionResult = OutputFormat == OutputFormat.Mp4a ? aaxFile.ConvertToMp4a(outFile, downloadLicense.ChapterInfo) : aaxFile.ConvertToMp3(outFile); aaxFile.ConversionProgressUpdate -= AaxFile_ConversionProgressUpdate; @@ -155,18 +149,6 @@ namespace AaxDecrypter downloadLicense.ChapterInfo = aaxFile.Chapters; - if (decryptionResult == ConversionResult.NoErrorsDetected - && coverArt is not null - && OutputFormat == OutputFormat.Mp4a) - { - //This handles a special case where the aaxc file doesn't contain cover art and - //Libation downloaded it instead (Animal Farm). Currently only works for Mp4a files. - using var decryptedBook = new Mp4File(outputFileName, FileAccess.ReadWrite); - decryptedBook.AppleTags?.SetCoverArt(coverArt); - decryptedBook.Save(); - decryptedBook.Close(); - } - nfsPersister.Dispose(); DecryptProgressUpdate?.Invoke(this, 0); diff --git a/FileManager/PictureStorage.cs b/FileManager/PictureStorage.cs index ef0ecdf2..4ea1bcf2 100644 --- a/FileManager/PictureStorage.cs +++ b/FileManager/PictureStorage.cs @@ -6,7 +6,7 @@ using System.Net.Http; namespace FileManager { - public enum PictureSize { _80x80, _300x300, _500x500 } + public enum PictureSize { _80x80 = 80, _300x300 = 300, _500x500 = 500 } public struct PictureDefinition { public string PictureId { get; } @@ -54,6 +54,26 @@ namespace FileManager return (cache[def] == null, cache[def] ?? getDefaultImage(def.Size)); } + public static byte[] GetPictureSynchronously(PictureDefinition def) + { + if (!cache.ContainsKey(def) || cache[def] == null) + { + var path = getPath(def); + byte[] bytes; + + if (File.Exists(path)) + bytes = File.ReadAllBytes(path); + else + { + bytes = downloadBytes(def); + saveFile(def, bytes); + } + + cache[def] = bytes; + } + return cache[def]; + } + private static Dictionary defaultImages { get; } = new Dictionary(); public static void SetDefaultImage(PictureSize pictureSize, byte[] bytes) => defaultImages[pictureSize] = bytes; @@ -100,7 +120,7 @@ namespace FileManager private static HttpClient imageDownloadClient { get; } = new HttpClient(); private static byte[] downloadBytes(PictureDefinition def) { - var sz = def.Size.ToString().Split('x')[1]; + var sz = ((int)def.Size).ToString(); return imageDownloadClient.GetByteArrayAsync("ht" + $"tps://images-na.ssl-images-amazon.com/images/I/{def.PictureId}._SL{sz}_.jpg").Result; } diff --git a/LibationWinForms/BookLiberation/ProcessorAutomationController.cs b/LibationWinForms/BookLiberation/ProcessorAutomationController.cs index 7496d81a..c8c5ced0 100644 --- a/LibationWinForms/BookLiberation/ProcessorAutomationController.cs +++ b/LibationWinForms/BookLiberation/ProcessorAutomationController.cs @@ -293,7 +293,6 @@ namespace LibationWinForms.BookLiberation #region define how model actions will affect form behavior void decryptBegin(object _, string __) => decryptDialog.Show(); - void titleDiscovered(object _, string title) => decryptDialog.SetTitle(actionName, title); void authorsDiscovered(object _, string authors) => decryptDialog.SetAuthorNames(authors); void narratorsDiscovered(object _, string narrators) => decryptDialog.SetNarratorNames(narrators); @@ -301,31 +300,7 @@ namespace LibationWinForms.BookLiberation void updateProgress(object _, int percentage) => decryptDialog.UpdateProgress(percentage); void updateRemainingTime(object _, TimeSpan remaining) => decryptDialog.UpdateRemainingTime(remaining); void decryptCompleted(object _, string __) => decryptDialog.Close(); - - void requestCoverArt(object _, Action setCoverArtDelegate) - { - var picDef = new FileManager.PictureDefinition(libraryBook.Book.PictureId, FileManager.PictureSize._500x500); - (bool isDefault, byte[] picture) = FileManager.PictureStorage.GetPicture(picDef); - - if (isDefault) - { - void pictureCached(object _, string pictureId) - { - if (pictureId == libraryBook.Book.PictureId) - { - FileManager.PictureStorage.PictureCached -= pictureCached; - - var picDef = new FileManager.PictureDefinition(libraryBook.Book.PictureId, FileManager.PictureSize._500x500); - (_, picture) = FileManager.PictureStorage.GetPicture(picDef); - - setCoverArtDelegate(picture); - } - }; - FileManager.PictureStorage.PictureCached += pictureCached; - } - else - setCoverArtDelegate(picture); - } + void requestCoverArt(object _, Action setCoverArtDelegate) => setCoverArtDelegate(FileManager.PictureStorage.GetPictureSynchronously(new FileManager.PictureDefinition(libraryBook.Book.PictureId, FileManager.PictureSize._500x500))); #endregion #region subscribe new form to model's events