From 3be7d8e825438a7726e6906352831d51c2fc5209 Mon Sep 17 00:00:00 2001
From: Mbucari <37587114+Mbucari@users.noreply.github.com>
Date: Sun, 2 Jul 2023 16:42:45 -0600
Subject: [PATCH] Minor cli edits and fix potential deadlock
---
Source/AaxDecrypter/NetworkFileStream.cs | 21 ++++++++++---------
.../UnencryptedAudiobookDownloader.cs | 6 +-----
Source/LibationCli/Options/SearchOptions.cs | 4 ++--
.../Options/SetDownloadStatusOptions.cs | 4 ++--
.../Options/_ProcessableOptionsBase.cs | 16 ++++++++------
Source/LibationCli/Program.cs | 2 +-
6 files changed, 27 insertions(+), 26 deletions(-)
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";