Added synchronous Picture downloader.

This commit is contained in:
Michael Bucari-Tovo 2021-08-10 20:16:34 -06:00
parent 2f3c0e8a95
commit 4989cda93c
3 changed files with 31 additions and 54 deletions

View File

@ -1,19 +1,13 @@
using AAXClean; using AAXClean;
using Dinah.Core; using Dinah.Core;
using Dinah.Core.Diagnostics;
using Dinah.Core.IO; using Dinah.Core.IO;
using Dinah.Core.Logging;
using Dinah.Core.StepRunner; using Dinah.Core.StepRunner;
using System; using System;
using System.IO; using System.IO;
namespace AaxDecrypter namespace AaxDecrypter
{ {
public enum OutputFormat public enum OutputFormat { Mp4a, Mp3 }
{
Mp4a,
Mp3
}
public class AaxcDownloadConverter public class AaxcDownloadConverter
{ {
public event EventHandler<AppleTags> RetrievedTags; public event EventHandler<AppleTags> RetrievedTags;
@ -26,7 +20,6 @@ namespace AaxDecrypter
private string cacheDir { get; } private string cacheDir { get; }
private DownloadLicense downloadLicense { get; } private DownloadLicense downloadLicense { get; }
private AaxFile aaxFile; private AaxFile aaxFile;
private byte[] coverArt;
private OutputFormat OutputFormat; private OutputFormat OutputFormat;
private StepSequence steps { get; } private StepSequence steps { get; }
@ -65,11 +58,15 @@ namespace AaxDecrypter
}; };
} }
/// <summary>
/// Setting cover art by this method will insert the art into the audiobook metadata
/// </summary>
public void SetCoverArt(byte[] coverArt) public void SetCoverArt(byte[] coverArt)
{ {
if (coverArt is null) return; if (coverArt is null) return;
this.coverArt = coverArt; aaxFile?.AppleTags.SetCoverArt(coverArt);
RetrievedCoverArt?.Invoke(this, coverArt); RetrievedCoverArt?.Invoke(this, coverArt);
} }
@ -98,7 +95,7 @@ namespace AaxDecrypter
try try
{ {
nfsPersister = new NetworkFileStreamPersister(jsonDownloadState); 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. //The new url will be to the same file.
nfsPersister.NetworkFileStream.SetUriForSameFile(new Uri(downloadLicense.DownloadUrl)); nfsPersister.NetworkFileStream.SetUriForSameFile(new Uri(downloadLicense.DownloadUrl));
} }
@ -116,10 +113,9 @@ namespace AaxDecrypter
nfsPersister.NetworkFileStream.BeginDownloading(); nfsPersister.NetworkFileStream.BeginDownloading();
aaxFile = new AaxFile(nfsPersister.NetworkFileStream); aaxFile = new AaxFile(nfsPersister.NetworkFileStream);
coverArt = aaxFile.AppleTags.Cover;
RetrievedTags?.Invoke(this, aaxFile.AppleTags); RetrievedTags?.Invoke(this, aaxFile.AppleTags);
RetrievedCoverArt?.Invoke(this, coverArt); RetrievedCoverArt?.Invoke(this, aaxFile.AppleTags.Cover);
return !isCanceled; return !isCanceled;
} }
@ -136,7 +132,6 @@ namespace AaxDecrypter
public bool Step2_DownloadAndCombine() public bool Step2_DownloadAndCombine()
{ {
DecryptProgressUpdate?.Invoke(this, 0); DecryptProgressUpdate?.Invoke(this, 0);
if (File.Exists(outputFileName)) if (File.Exists(outputFileName))
@ -147,7 +142,6 @@ namespace AaxDecrypter
aaxFile.SetDecryptionKey(downloadLicense.AudibleKey, downloadLicense.AudibleIV); aaxFile.SetDecryptionKey(downloadLicense.AudibleKey, downloadLicense.AudibleIV);
aaxFile.ConversionProgressUpdate += AaxFile_ConversionProgressUpdate; aaxFile.ConversionProgressUpdate += AaxFile_ConversionProgressUpdate;
var decryptionResult = OutputFormat == OutputFormat.Mp4a ? aaxFile.ConvertToMp4a(outFile, downloadLicense.ChapterInfo) : aaxFile.ConvertToMp3(outFile); var decryptionResult = OutputFormat == OutputFormat.Mp4a ? aaxFile.ConvertToMp4a(outFile, downloadLicense.ChapterInfo) : aaxFile.ConvertToMp3(outFile);
aaxFile.ConversionProgressUpdate -= AaxFile_ConversionProgressUpdate; aaxFile.ConversionProgressUpdate -= AaxFile_ConversionProgressUpdate;
@ -155,18 +149,6 @@ namespace AaxDecrypter
downloadLicense.ChapterInfo = aaxFile.Chapters; 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(); nfsPersister.Dispose();
DecryptProgressUpdate?.Invoke(this, 0); DecryptProgressUpdate?.Invoke(this, 0);

View File

@ -6,7 +6,7 @@ using System.Net.Http;
namespace FileManager namespace FileManager
{ {
public enum PictureSize { _80x80, _300x300, _500x500 } public enum PictureSize { _80x80 = 80, _300x300 = 300, _500x500 = 500 }
public struct PictureDefinition public struct PictureDefinition
{ {
public string PictureId { get; } public string PictureId { get; }
@ -54,6 +54,26 @@ namespace FileManager
return (cache[def] == null, cache[def] ?? getDefaultImage(def.Size)); 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<PictureSize, byte[]> defaultImages { get; } = new Dictionary<PictureSize, byte[]>(); private static Dictionary<PictureSize, byte[]> defaultImages { get; } = new Dictionary<PictureSize, byte[]>();
public static void SetDefaultImage(PictureSize pictureSize, byte[] bytes) public static void SetDefaultImage(PictureSize pictureSize, byte[] bytes)
=> defaultImages[pictureSize] = bytes; => defaultImages[pictureSize] = bytes;
@ -100,7 +120,7 @@ namespace FileManager
private static HttpClient imageDownloadClient { get; } = new HttpClient(); private static HttpClient imageDownloadClient { get; } = new HttpClient();
private static byte[] downloadBytes(PictureDefinition def) 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; return imageDownloadClient.GetByteArrayAsync("ht" + $"tps://images-na.ssl-images-amazon.com/images/I/{def.PictureId}._SL{sz}_.jpg").Result;
} }

View File

@ -293,7 +293,6 @@ namespace LibationWinForms.BookLiberation
#region define how model actions will affect form behavior #region define how model actions will affect form behavior
void decryptBegin(object _, string __) => decryptDialog.Show(); void decryptBegin(object _, string __) => decryptDialog.Show();
void titleDiscovered(object _, string title) => decryptDialog.SetTitle(actionName, title); void titleDiscovered(object _, string title) => decryptDialog.SetTitle(actionName, title);
void authorsDiscovered(object _, string authors) => decryptDialog.SetAuthorNames(authors); void authorsDiscovered(object _, string authors) => decryptDialog.SetAuthorNames(authors);
void narratorsDiscovered(object _, string narrators) => decryptDialog.SetNarratorNames(narrators); void narratorsDiscovered(object _, string narrators) => decryptDialog.SetNarratorNames(narrators);
@ -301,31 +300,7 @@ namespace LibationWinForms.BookLiberation
void updateProgress(object _, int percentage) => decryptDialog.UpdateProgress(percentage); void updateProgress(object _, int percentage) => decryptDialog.UpdateProgress(percentage);
void updateRemainingTime(object _, TimeSpan remaining) => decryptDialog.UpdateRemainingTime(remaining); void updateRemainingTime(object _, TimeSpan remaining) => decryptDialog.UpdateRemainingTime(remaining);
void decryptCompleted(object _, string __) => decryptDialog.Close(); void decryptCompleted(object _, string __) => decryptDialog.Close();
void requestCoverArt(object _, Action<byte[]> setCoverArtDelegate) => setCoverArtDelegate(FileManager.PictureStorage.GetPictureSynchronously(new FileManager.PictureDefinition(libraryBook.Book.PictureId, FileManager.PictureSize._500x500)));
void requestCoverArt(object _, Action<byte[]> 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);
}
#endregion #endregion
#region subscribe new form to model's events #region subscribe new form to model's events