Keep download license details with aax file, not in db

This commit is contained in:
Robert McRackan 2021-06-22 16:49:19 -04:00
parent 9416f4e040
commit b1a033e162
5 changed files with 35 additions and 28 deletions

View File

@ -119,13 +119,5 @@ namespace ApplicationServices
throw; throw;
} }
} }
// I hate how unintuitive this is to use/remember. Will hopefully be cleaned up in a future comprehensive data strategy overhaul
public static void UpdateBook(Book book)
{
using var context = DbContexts.GetContext();
context.Update(book);
context.SaveChanges();
}
} }
} }

View File

@ -31,8 +31,6 @@ namespace DataLayer
// mutable // mutable
public string PictureId { get; set; } public string PictureId { get; set; }
public string AudibleKey { get; set; }
public string AudibleIV { get; set; }
// book details // book details
public bool IsAbridged { get; private set; } public bool IsAbridged { get; private set; }

View File

@ -57,30 +57,33 @@ namespace FileLiberator
if (AudibleFileStorage.Audio.Exists(libraryBook.Book.AudibleProductId)) if (AudibleFileStorage.Audio.Exists(libraryBook.Book.AudibleProductId))
return new StatusHandler { "Cannot find decrypt. Final audio file already exists" }; return new StatusHandler { "Cannot find decrypt. Final audio file already exists" };
var api = await AudibleApiActions.GetApiAsync(libraryBook.Account, libraryBook.Book.Locale); var chapters = await downloadChapterNamesAsync(libraryBook);
var chapters = await downloadChapterNames(libraryBook, api); var outputAudioFilename = await aaxToM4bConverterDecryptAsync(aaxFilename, libraryBook, chapters);
var outputAudioFilename = await aaxToM4bConverterDecrypt(aaxFilename, libraryBook, chapters, api);
// decrypt failed // decrypt failed
if (outputAudioFilename == null) if (outputAudioFilename == null)
return new StatusHandler { "Decrypt failed" }; return new StatusHandler { "Decrypt failed" };
// moves files and returns dest dir. Do not put inside of if(RetainAaxFiles)
var destinationDir = moveFilesToBooksDir(libraryBook.Book, outputAudioFilename); var destinationDir = moveFilesToBooksDir(libraryBook.Book, outputAudioFilename);
var config = Configuration.Instance; var jsonFilename = PathLib.ReplaceExtension(aaxFilename, "json");
if (config.RetainAaxFiles) if (Configuration.Instance.RetainAaxFiles)
{ {
var newAaxFilename = FileUtility.GetValidFilename( var newAaxFilename = FileUtility.GetValidFilename(
destinationDir, destinationDir,
Path.GetFileNameWithoutExtension(aaxFilename), Path.GetFileNameWithoutExtension(aaxFilename),
"aax"); "aax");
File.Move(aaxFilename, newAaxFilename); File.Move(aaxFilename, newAaxFilename);
var newJsonFilename = PathLib.ReplaceExtension(newAaxFilename, "json");
File.Move(jsonFilename, newJsonFilename);
} }
else else
{ {
Dinah.Core.IO.FileExt.SafeDelete(aaxFilename); Dinah.Core.IO.FileExt.SafeDelete(aaxFilename);
Dinah.Core.IO.FileExt.SafeDelete(jsonFilename);
} }
var finalAudioExists = AudibleFileStorage.Audio.Exists(libraryBook.Book.AudibleProductId); var finalAudioExists = AudibleFileStorage.Audio.Exists(libraryBook.Book.AudibleProductId);
@ -95,10 +98,11 @@ namespace FileLiberator
} }
} }
private static async Task<Chapters> downloadChapterNames(LibraryBook libraryBook, Api api) private static async Task<Chapters> downloadChapterNamesAsync(LibraryBook libraryBook)
{ {
try try
{ {
var api = await AudibleApiActions.GetApiAsync(libraryBook.Account, libraryBook.Book.Locale);
var contentMetadata = await api.GetLibraryBookMetadataAsync(libraryBook.Book.AudibleProductId); var contentMetadata = await api.GetLibraryBookMetadataAsync(libraryBook.Book.AudibleProductId);
if (contentMetadata?.ChapterInfo is null) if (contentMetadata?.ChapterInfo is null)
return null; return null;
@ -111,15 +115,17 @@ namespace FileLiberator
} }
} }
private async Task<string> aaxToM4bConverterDecrypt(string aaxFilename, LibraryBook libraryBook, Chapters chapters, Api api) private async Task<string> aaxToM4bConverterDecryptAsync(string aaxFilename, LibraryBook libraryBook, Chapters chapters)
{ {
DecryptBegin?.Invoke(this, $"Begin decrypting {aaxFilename}"); DecryptBegin?.Invoke(this, $"Begin decrypting {aaxFilename}");
try try
{ {
using var persister = AudibleApiStorage.GetAccountsSettingsPersister(); var jsonPath = PathLib.ReplaceExtension(aaxFilename, "json");
var jsonContents = File.ReadAllText(jsonPath);
var dlLic = Newtonsoft.Json.JsonConvert.DeserializeObject<AudibleApiDTOs.DownloadLicense>(jsonContents);
var converter = await AaxToM4bConverter.CreateAsync(aaxFilename, libraryBook.Book.AudibleKey, libraryBook.Book.AudibleIV, chapters); var converter = await AaxToM4bConverter.CreateAsync(aaxFilename, dlLic.AudibleKey, dlLic.AudibleIV, chapters);
converter.AppName = "Libation"; converter.AppName = "Libation";
TitleDiscovered?.Invoke(this, converter.tags.title); TitleDiscovered?.Invoke(this, converter.tags.title);

View File

@ -41,6 +41,7 @@ namespace FileLiberator
libraryBook.Book.Title, libraryBook.Book.Title,
"aax", "aax",
libraryBook.Book.AudibleProductId); libraryBook.Book.AudibleProductId);
private async Task<string> downloadAaxcBookAsync(LibraryBook libraryBook, string tempAaxFilename) private async Task<string> downloadAaxcBookAsync(LibraryBook libraryBook, string tempAaxFilename)
{ {
validate(libraryBook); validate(libraryBook);
@ -49,26 +50,30 @@ namespace FileLiberator
var dlLic = await api.GetDownloadLicenseAsync(libraryBook.Book.AudibleProductId); var dlLic = await api.GetDownloadLicenseAsync(libraryBook.Book.AudibleProductId);
libraryBook.Book.AudibleKey = dlLic.AudibleKey;
libraryBook.Book.AudibleIV = dlLic.AudibleIV;
// persist changes
ApplicationServices.LibraryCommands.UpdateBook(libraryBook.Book);
var client = new HttpClient(); var client = new HttpClient();
client.DefaultRequestHeaders.Add("User-Agent", Resources.UserAgent); client.DefaultRequestHeaders.Add("User-Agent", Resources.UserAgent);
var actualFilePath = await PerformDownloadAsync( var actualFilePath = await PerformDownloadAsync(
tempAaxFilename, tempAaxFilename,
(p) => client.DownloadFileAsync(dlLic.DownloadUri.AbsoluteUri, tempAaxFilename, p)); (p) => client.DownloadFileAsync(new Uri(dlLic.DownloadUrl).AbsoluteUri, tempAaxFilename, p));
System.Threading.Thread.Sleep(100); System.Threading.Thread.Sleep(100);
// if bad file download, a 0-33 byte file will be created // if bad file download, a 0-33 byte file will be created
// if service unavailable, a 52 byte string will be saved as file // if service unavailable, a 52 byte string will be saved as file
var length = new FileInfo(actualFilePath).Length; var length = new FileInfo(actualFilePath).Length;
// success. save json and return
if (length > 100) if (length > 100)
return actualFilePath; {
// save along side book
var jsonPath = PathLib.ReplaceExtension(actualFilePath, "json");
var jsonContents = Newtonsoft.Json.JsonConvert.SerializeObject(dlLic, Newtonsoft.Json.Formatting.Indented);
File.WriteAllText(jsonPath, jsonContents);
return actualFilePath;
}
// else: failure. clean up and throw
var contents = File.ReadAllText(actualFilePath); var contents = File.ReadAllText(actualFilePath);
File.Delete(actualFilePath); File.Delete(actualFilePath);
@ -121,6 +126,12 @@ namespace FileLiberator
"aax", "aax",
libraryBook.Book.AudibleProductId); libraryBook.Book.AudibleProductId);
File.Move(actualFilePath, newAaxFilename); File.Move(actualFilePath, newAaxFilename);
// also move DownloadLicense json file
var jsonPathOld = PathLib.ReplaceExtension(actualFilePath, "json");
var jsonPathNew = PathLib.ReplaceExtension(newAaxFilename, "json");
File.Move(jsonPathOld, jsonPathNew);
Invoke_StatusUpdate($"Successfully downloaded. Moved to: {newAaxFilename}"); Invoke_StatusUpdate($"Successfully downloaded. Moved to: {newAaxFilename}");
} }

View File

@ -13,7 +13,7 @@
<!-- <PublishSingleFile>true</PublishSingleFile> --> <!-- <PublishSingleFile>true</PublishSingleFile> -->
<RuntimeIdentifier>win-x64</RuntimeIdentifier> <RuntimeIdentifier>win-x64</RuntimeIdentifier>
<Version>4.4.0.35</Version> <Version>4.4.0.60</Version>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>