diff --git a/Source/AaxDecrypter/NetworkFileStream.cs b/Source/AaxDecrypter/NetworkFileStream.cs index bd8ce19c..2a8be0de 100644 --- a/Source/AaxDecrypter/NetworkFileStream.cs +++ b/Source/AaxDecrypter/NetworkFileStream.cs @@ -14,7 +14,6 @@ namespace AaxDecrypter public class NetworkFileStream : Stream, IUpdatable { public event EventHandler Updated; - public event EventHandler DownloadCompleted; #region Public Properties @@ -41,6 +40,9 @@ namespace AaxDecrypter [JsonIgnore] public bool IsCancelled => _cancellationSource.IsCancellationRequested; + [JsonIgnore] + public Task DownloadTask { get; private set; } + private long _speedLimit = 0; /// bytes per second public long SpeedLimit { get => _speedLimit; set => _speedLimit = value <= 0 ? 0 : Math.Max(value, MIN_BYTES_PER_SECOND); } @@ -52,7 +54,6 @@ namespace AaxDecrypter private FileStream _readFile { get; } private CancellationTokenSource _cancellationSource { get; } = new(); private EventWaitHandle _downloadedPiece { get; set; } - private Task _backgroundDownloadTask { get; set; } #endregion @@ -128,7 +129,7 @@ namespace AaxDecrypter if (uriToSameFile.Host != Uri.Host) throw new ArgumentException($"New uri to the same file must have the same host.\r\n Old Host :{Uri.Host}\r\nNew Host: {uriToSameFile.Host}"); - if (_backgroundDownloadTask is not null) + if (DownloadTask is not null) throw new InvalidOperationException("Cannot change Uri after download has started."); Uri = uriToSameFile; @@ -141,7 +142,7 @@ namespace AaxDecrypter { if (ContentLength != 0 && WritePosition == ContentLength) { - _backgroundDownloadTask = Task.CompletedTask; + DownloadTask = Task.CompletedTask; return; } @@ -167,7 +168,8 @@ namespace AaxDecrypter _downloadedPiece = new EventWaitHandle(false, EventResetMode.AutoReset); //Download the file in the background. - _backgroundDownloadTask = Task.Run(() => DownloadFile(networkStream), _cancellationSource.Token); + + DownloadTask = Task.Run(() => DownloadFile(networkStream), _cancellationSource.Token); } /// Download to . @@ -234,7 +236,6 @@ namespace AaxDecrypter _writeFile.Close(); _downloadedPiece.Set(); OnUpdate(); - DownloadCompleted?.Invoke(this, null); } } @@ -256,7 +257,7 @@ namespace AaxDecrypter { get { - if (_backgroundDownloadTask is null) + if (DownloadTask is null) throw new InvalidOperationException($"Background downloader must first be started by calling {nameof(BeginDownloadingAsync)}"); return ContentLength; } @@ -280,7 +281,7 @@ namespace AaxDecrypter public override int Read(byte[] buffer, int offset, int count) { - if (_backgroundDownloadTask is null) + if (DownloadTask is null) throw new InvalidOperationException($"Background downloader must first be started by calling {nameof(BeginDownloadingAsync)}"); var toRead = Math.Min(count, Length - Position); @@ -306,7 +307,7 @@ namespace AaxDecrypter private void WaitToPosition(long requiredPosition) { while (WritePosition < requiredPosition - && _backgroundDownloadTask?.IsCompleted is false + && DownloadTask?.IsCompleted is false && !IsCancelled) { _downloadedPiece.WaitOne(50); @@ -326,7 +327,7 @@ namespace AaxDecrypter if (disposing && !disposed) { _cancellationSource.Cancel(); - _backgroundDownloadTask?.GetAwaiter().GetResult(); + DownloadTask?.GetAwaiter().GetResult(); _downloadedPiece?.Dispose(); _cancellationSource?.Dispose(); _readFile.Dispose(); diff --git a/Source/AaxDecrypter/UnencryptedAudiobookDownloader.cs b/Source/AaxDecrypter/UnencryptedAudiobookDownloader.cs index 193cd9b6..200a4b5f 100644 --- a/Source/AaxDecrypter/UnencryptedAudiobookDownloader.cs +++ b/Source/AaxDecrypter/UnencryptedAudiobookDownloader.cs @@ -26,11 +26,7 @@ namespace AaxDecrypter protected override async Task Step_DownloadAndDecryptAudiobookAsync() { - TaskCompletionSource completionSource = new(); - - InputFileStream.DownloadCompleted += (_, _) => completionSource.SetResult(); - - await completionSource.Task; + await InputFileStream.DownloadTask; if (IsCanceled) return false; diff --git a/Source/LibationCli/Options/SearchOptions.cs b/Source/LibationCli/Options/SearchOptions.cs index 5ed00d6a..76479dcb 100644 --- a/Source/LibationCli/Options/SearchOptions.cs +++ b/Source/LibationCli/Options/SearchOptions.cs @@ -10,7 +10,7 @@ namespace LibationCli.Options [Verb("search", HelpText = "Search for books in your library")] internal class SearchOptions : OptionsBase { - [Value(0, MetaName = "query", Required = true, HelpText = "Lucene query test to search")] + [Value(0, MetaName = "query", Required = true, HelpText = "Lucene search string")] public IEnumerable Query { get; set; } protected override Task ProcessAsync() @@ -31,7 +31,7 @@ namespace LibationCli.Options if (waitForNextBatch) { Console.Write(nextPrompt); - waitForNextBatch = Console.ReadKey().Key != ConsoleKey.Escape; + waitForNextBatch = Console.ReadKey(intercept: true).Key != ConsoleKey.Escape; ReplaceConsoleText(Console.Out, nextPrompt.Length, ""); Console.SetCursorPosition(0, Console.CursorTop); } diff --git a/Source/LibationCli/Options/SetDownloadStatusOptions.cs b/Source/LibationCli/Options/SetDownloadStatusOptions.cs index 1c5f43ac..615a54a1 100644 --- a/Source/LibationCli/Options/SetDownloadStatusOptions.cs +++ b/Source/LibationCli/Options/SetDownloadStatusOptions.cs @@ -17,7 +17,7 @@ namespace LibationCli [Option(shortName: 'd', longName: "downloaded", Group = "Download Status", HelpText = "set download status to 'Downloaded'")] public bool SetDownloaded { get; set; } - [Option(shortName: 'n', longName: "not-downloaded", Group = "Download Status", HelpText = "set download status to 'Downloaded'")] + [Option(shortName: 'n', longName: "not-downloaded", Group = "Download Status", HelpText = "set download status to 'Not Downloaded'")] public bool SetNotDownloaded { get; set; } [Option("force", HelpText = "Set the download status regardless of whether the book's audio file can be found. Only one download status option may be used with this option.")] @@ -38,7 +38,7 @@ namespace LibationCli if (Asins.Any()) { - var asins = Asins.Select(a => a.ToLower()).ToArray(); + var asins = Asins.Select(a => a.TrimStart('[').TrimEnd(']').ToLower()).ToArray(); libraryBooks = libraryBooks.Where(lb => lb.Book.AudibleProductId.ToLower().In(asins)).ToList(); if (libraryBooks.Count == 0) diff --git a/Source/LibationCli/Options/_ProcessableOptionsBase.cs b/Source/LibationCli/Options/_ProcessableOptionsBase.cs index bb4cd735..6ad35f7e 100644 --- a/Source/LibationCli/Options/_ProcessableOptionsBase.cs +++ b/Source/LibationCli/Options/_ProcessableOptionsBase.cs @@ -51,16 +51,20 @@ namespace LibationCli protected async Task RunAsync(Processable Processable) { - var libraryBooks = DbContexts.GetLibrary_Flat_NoTracking().AsEnumerable(); + var libraryBooks = DbContexts.GetLibrary_Flat_NoTracking(); if (Asins.Any()) { - var asinsLower = Asins.Select(a => a.ToLower()).ToArray(); - libraryBooks = libraryBooks.Where(lb => lb.Book.AudibleProductId.ToLower().In(asinsLower)); - } + var asinsLower = Asins.Select(a => a.TrimStart('[').TrimEnd(']').ToLower()).ToArray(); - foreach (var libraryBook in Processable.GetValidLibraryBooks(libraryBooks)) - await ProcessOneAsync(Processable, libraryBook, false); + foreach (var lb in libraryBooks.Where(lb => lb.Book.AudibleProductId.ToLower().In(asinsLower))) + await ProcessOneAsync(Processable, lb, true); + } + else + { + foreach (var lb in Processable.GetValidLibraryBooks(libraryBooks)) + await ProcessOneAsync(Processable, lb, false); + } var done = "Done. All books have been processed"; Console.WriteLine(done); diff --git a/Source/LibationCli/Program.cs b/Source/LibationCli/Program.cs index 19538dd5..a6880c7d 100644 --- a/Source/LibationCli/Program.cs +++ b/Source/LibationCli/Program.cs @@ -21,7 +21,7 @@ namespace LibationCli { #if DEBUG - string input = null; + string input = ""; //input = " set-status -n --force B017V4IM1G"; //input = " liberate B017V4IM1G";