Move DownloadOptions to FileLiberator

This commit is contained in:
Michael Bucari-Tovo 2022-06-20 10:22:21 -06:00
parent fdee254020
commit b2992da370
10 changed files with 100 additions and 107 deletions

View File

@ -11,8 +11,8 @@ namespace AaxDecrypter
protected AaxFile AaxFile;
protected AaxcDownloadConvertBase(string outFileName, string cacheDirectory, DownloadOptions dlLic)
: base(outFileName, cacheDirectory, dlLic) { }
protected AaxcDownloadConvertBase(string outFileName, string cacheDirectory, IDownloadOptions dlOptions)
: base(outFileName, cacheDirectory, dlOptions) { }
/// <summary>Setting cover art by this method will insert the art into the audiobook metadata</summary>
public override void SetCoverArt(byte[] coverArt)

View File

@ -13,24 +13,12 @@ namespace AaxDecrypter
public class AaxcDownloadMultiConverter : AaxcDownloadConvertBase
{
protected override StepSequence Steps { get; }
private Func<MultiConvertFileProperties, string> multipartFileNameCallback { get; }
private Func<MultiConvertFileProperties, string> multipartTitleNameCallback { get; }
private static TimeSpan minChapterLength { get; } = TimeSpan.FromSeconds(3);
private List<string> multiPartFilePaths { get; } = new List<string>();
public AaxcDownloadMultiConverter(
string outFileName,
string cacheDirectory,
DownloadOptions dlLic,
Func<MultiConvertFileProperties, string> multipartFileNameCallback,
Func<MultiConvertFileProperties, string> multipartTitleNameCallback
)
: base(outFileName, cacheDirectory, dlLic)
public AaxcDownloadMultiConverter(string outFileName, string cacheDirectory, IDownloadOptions dlOptions)
: base(outFileName, cacheDirectory, dlOptions)
{
ArgumentValidator.EnsureNotNull(multipartFileNameCallback, nameof(multipartFileNameCallback));
ArgumentValidator.EnsureNotNull(multipartTitleNameCallback, nameof(multipartTitleNameCallback));
Steps = new StepSequence
{
Name = "Download and Convert Aaxc To " + DownloadOptions.OutputFormat,
@ -39,8 +27,6 @@ namespace AaxDecrypter
["Step 2: Download Decrypted Audiobook"] = Step_DownloadAudiobookAsMultipleFilesPerChapter,
["Step 3: Cleanup"] = Step_Cleanup,
};
this.multipartFileNameCallback = multipartFileNameCallback;
this.multipartTitleNameCallback = multipartTitleNameCallback;
}
/*
@ -147,14 +133,14 @@ That naming may not be desirable for everyone, but it's an easy change to instea
Title = newSplitCallback?.Chapter?.Title,
};
newSplitCallback.OutputFile = createOutputFileStream(props);
newSplitCallback.TrackTitle = multipartTitleNameCallback(props);
newSplitCallback.TrackTitle = DownloadOptions.GetMultipartTitleName(props);
newSplitCallback.TrackNumber = currentChapter;
newSplitCallback.TrackCount = splitChapters.Count;
}
private FileStream createOutputFileStream(MultiConvertFileProperties multiConvertFileProperties)
{
var fileName = multipartFileNameCallback(multiConvertFileProperties);
var fileName = DownloadOptions.GetMultipartFileName(multiConvertFileProperties);
fileName = FileUtility.GetValidFilename(fileName);
multiPartFilePaths.Add(fileName);

View File

@ -11,8 +11,8 @@ namespace AaxDecrypter
{
protected override StepSequence Steps { get; }
public AaxcDownloadSingleConverter(string outFileName, string cacheDirectory, DownloadOptions dlLic)
: base(outFileName, cacheDirectory, dlLic)
public AaxcDownloadSingleConverter(string outFileName, string cacheDirectory, IDownloadOptions dlOptions)
: base(outFileName, cacheDirectory, dlOptions)
{
Steps = new StepSequence
{

View File

@ -25,7 +25,7 @@ namespace AaxDecrypter
public string TempFilePath { get; }
protected string OutputFileName { get; private set; }
protected DownloadOptions DownloadOptions { get; }
protected IDownloadOptions DownloadOptions { get; }
protected NetworkFileStream InputFileStream => (nfsPersister ??= OpenNetworkFileStream()).NetworkFileStream;
// Don't give the property a 'set'. This should have to be an obvious choice; not accidental
@ -36,7 +36,7 @@ namespace AaxDecrypter
private string jsonDownloadState { get; }
protected AudiobookDownloadBase(string outFileName, string cacheDirectory, DownloadOptions dlLic)
protected AudiobookDownloadBase(string outFileName, string cacheDirectory, IDownloadOptions dlOptions)
{
OutputFileName = ArgumentValidator.EnsureNotNullOrWhiteSpace(outFileName, nameof(outFileName));
@ -50,7 +50,7 @@ namespace AaxDecrypter
jsonDownloadState = Path.Combine(cacheDirectory, Path.GetFileName(Path.ChangeExtension(OutputFileName, ".json")));
TempFilePath = Path.ChangeExtension(jsonDownloadState, ".aaxc");
DownloadOptions = ArgumentValidator.EnsureNotNull(dlLic, nameof(dlLic));
DownloadOptions = ArgumentValidator.EnsureNotNull(dlOptions, nameof(dlOptions));
// delete file after validation is complete
FileUtility.SaferDelete(OutputFileName);

View File

@ -1,30 +0,0 @@
using AAXClean;
using Dinah.Core;
namespace AaxDecrypter
{
public class DownloadOptions
{
public string DownloadUrl { get; }
public string UserAgent { get; }
public string AudibleKey { get; init; }
public string AudibleIV { get; init; }
public OutputFormat OutputFormat { get; init; }
public bool TrimOutputToChapterLength { get; init; }
public bool RetainEncryptedFile { get; init; }
public bool StripUnabridged { get; init; }
public bool CreateCueSheet { get; init; }
public ChapterInfo ChapterInfo { get; set; }
public NAudio.Lame.LameConfig LameConfig { get; set; }
public bool Downsample { get; set; }
public bool MatchSourceBitrate { get; set; }
public DownloadOptions(string downloadUrl, string userAgent)
{
DownloadUrl = ArgumentValidator.EnsureNotNullOrEmpty(downloadUrl, nameof(downloadUrl));
UserAgent = ArgumentValidator.EnsureNotNullOrEmpty(userAgent, nameof(userAgent));
// no null/empty check for key/iv. unencrypted files do not have them
}
}
}

View File

@ -0,0 +1,23 @@
using AAXClean;
namespace AaxDecrypter
{
public interface IDownloadOptions
{
string DownloadUrl { get; }
string UserAgent { get; }
string AudibleKey { get; }
string AudibleIV { get; }
OutputFormat OutputFormat { get; }
bool TrimOutputToChapterLength { get; }
bool RetainEncryptedFile { get; }
bool StripUnabridged { get; }
bool CreateCueSheet { get; }
ChapterInfo ChapterInfo { get; set; }
NAudio.Lame.LameConfig LameConfig { get; set; }
bool Downsample { get; set; }
bool MatchSourceBitrate { get; set; }
string GetMultipartFileName(MultiConvertFileProperties props);
string GetMultipartTitleName(MultiConvertFileProperties props);
}
}

View File

@ -11,7 +11,7 @@ namespace AaxDecrypter
{
protected override StepSequence Steps { get; }
public UnencryptedAudiobookDownloader(string outFileName, string cacheDirectory, DownloadOptions dlLic)
public UnencryptedAudiobookDownloader(string outFileName, string cacheDirectory, IDownloadOptions dlLic)
: base(outFileName, cacheDirectory, dlLic)
{
Steps = new StepSequence

View File

@ -8,32 +8,6 @@ namespace FileLiberator
{
public static class AudioFileStorageExt
{
private class MultipartRenamer
{
private LibraryBook libraryBook { get; }
internal MultipartRenamer(LibraryBook libraryBook) => this.libraryBook = libraryBook;
internal string MultipartFilename(AaxDecrypter.MultiConvertFileProperties props)
=> Templates.ChapterFile.GetFilename(libraryBook.ToDto(), props);
}
private class MultipartTitleNamer
{
private LibraryBook libraryBook { get; }
internal MultipartTitleNamer(LibraryBook libraryBook) => this.libraryBook = libraryBook;
internal string MultipartTitle(AaxDecrypter.MultiConvertFileProperties props)
=> Templates.ChapterTitle.GetTitle(libraryBook.ToDto(), props);
}
public static Func<AaxDecrypter.MultiConvertFileProperties, string> CreateMultipartRenamerFunc(this AudioFileStorage _, LibraryBook libraryBook)
=> new MultipartRenamer(libraryBook).MultipartFilename;
public static Func<AaxDecrypter.MultiConvertFileProperties, string> CreateMultipartTitleNamer(this AudioFileStorage _, LibraryBook libraryBook)
=> new MultipartTitleNamer(libraryBook).MultipartTitle;
/// <summary>
/// DownloadDecryptBook:
/// File path for where to move files into.

View File

@ -101,24 +101,19 @@ namespace FileLiberator
var api = await libraryBook.GetApiAsync();
var contentLic = await api.GetDownloadLicenseAsync(libraryBook.Book.AudibleProductId);
var audiobookDlLic = BuildDownloadOptions(config, contentLic);
var dlOptions = BuildDownloadOptions(libraryBook, config, contentLic);
var outFileName = AudibleFileStorage.Audio.GetInProgressFilename(libraryBook, audiobookDlLic.OutputFormat.ToString().ToLower());
var outFileName = AudibleFileStorage.Audio.GetInProgressFilename(libraryBook, dlOptions.OutputFormat.ToString().ToLower());
var cacheDir = AudibleFileStorage.DownloadsInProgressDirectory;
if (contentLic.DrmType != AudibleApi.Common.DrmType.Adrm)
abDownloader = new UnencryptedAudiobookDownloader(outFileName, cacheDir, audiobookDlLic);
abDownloader = new UnencryptedAudiobookDownloader(outFileName, cacheDir, dlOptions);
else
{
AaxcDownloadConvertBase converter
= config.SplitFilesByChapter ?
new AaxcDownloadMultiConverter
(
outFileName, cacheDir, audiobookDlLic,
AudibleFileStorage.Audio.CreateMultipartRenamerFunc(libraryBook),
AudibleFileStorage.Audio.CreateMultipartTitleNamer(libraryBook)
) :
new AaxcDownloadSingleConverter(outFileName, cacheDir, audiobookDlLic);
new AaxcDownloadMultiConverter(outFileName, cacheDir, dlOptions) :
new AaxcDownloadSingleConverter(outFileName, cacheDir, dlOptions);
if (config.AllowLibationFixup)
converter.RetrievedMetadata += (_, tags) => tags.Generes = string.Join(", ", libraryBook.Book.CategoriesNames());
@ -140,7 +135,7 @@ namespace FileLiberator
return success;
}
private DownloadOptions BuildDownloadOptions(Configuration config, AudibleApi.Common.ContentLicense contentLic)
private DownloadOptions BuildDownloadOptions(LibraryBook libraryBook, Configuration config, AudibleApi.Common.ContentLicense contentLic)
{
//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.
@ -153,21 +148,22 @@ namespace FileLiberator
var dlOptions = new DownloadOptions
(
contentLic?.ContentMetadata?.ContentUrl?.OfflineUrl,
Resources.USER_AGENT
libraryBook,
contentLic?.ContentMetadata?.ContentUrl?.OfflineUrl,
Resources.USER_AGENT
)
{
AudibleKey = contentLic?.Voucher?.Key,
AudibleIV = contentLic?.Voucher?.Iv,
OutputFormat = outputFormat,
TrimOutputToChapterLength = config.AllowLibationFixup && config.StripAudibleBrandAudio,
RetainEncryptedFile = config.RetainAaxFile && encrypted,
StripUnabridged = config.AllowLibationFixup && config.StripUnabridged,
Downsample = config.AllowLibationFixup && config.LameDownsampleMono,
MatchSourceBitrate = config.AllowLibationFixup && config.LameMatchSourceBR && config.LameTargetBitrate,
CreateCueSheet = config.CreateCueSheet,
LameConfig = GetLameOptions(config)
};
{
AudibleKey = contentLic?.Voucher?.Key,
AudibleIV = contentLic?.Voucher?.Iv,
OutputFormat = outputFormat,
TrimOutputToChapterLength = config.AllowLibationFixup && config.StripAudibleBrandAudio,
RetainEncryptedFile = config.RetainAaxFile && encrypted,
StripUnabridged = config.AllowLibationFixup && config.StripUnabridged,
Downsample = config.AllowLibationFixup && config.LameDownsampleMono,
MatchSourceBitrate = config.AllowLibationFixup && config.LameMatchSourceBR && config.LameTargetBitrate,
CreateCueSheet = config.CreateCueSheet,
LameConfig = GetLameOptions(config)
};
if (config.AllowLibationFixup || outputFormat == OutputFormat.Mp3)
{

View File

@ -0,0 +1,44 @@
using AaxDecrypter;
using AAXClean;
using Dinah.Core;
using DataLayer;
using LibationFileManager;
namespace FileLiberator
{
public class DownloadOptions : IDownloadOptions
{
public LibraryBook LibraryBook { get; }
public LibraryBookDto LibraryBookDto { get; }
public string DownloadUrl { get; }
public string UserAgent { get; }
public string AudibleKey { get; init; }
public string AudibleIV { get; init; }
public AaxDecrypter.OutputFormat OutputFormat { get; init; }
public bool TrimOutputToChapterLength { get; init; }
public bool RetainEncryptedFile { get; init; }
public bool StripUnabridged { get; init; }
public bool CreateCueSheet { get; init; }
public ChapterInfo ChapterInfo { get; set; }
public NAudio.Lame.LameConfig LameConfig { get; set; }
public bool Downsample { get; set; }
public bool MatchSourceBitrate { get; set; }
public string GetMultipartFileName(MultiConvertFileProperties props)
=> Templates.ChapterFile.GetFilename(LibraryBookDto, props);
public string GetMultipartTitleName(MultiConvertFileProperties props)
=> Templates.ChapterTitle.GetTitle(LibraryBookDto, props);
public DownloadOptions(LibraryBook libraryBook, string downloadUrl, string userAgent)
{
LibraryBook = ArgumentValidator.EnsureNotNull(libraryBook, nameof(libraryBook));
DownloadUrl = ArgumentValidator.EnsureNotNullOrEmpty(downloadUrl, nameof(downloadUrl));
UserAgent = ArgumentValidator.EnsureNotNullOrEmpty(userAgent, nameof(userAgent));
LibraryBookDto = LibraryBook.ToDto();
// no null/empty check for key/iv. unencrypted files do not have them
}
}
}