Minor cli edits and fix potential deadlock
This commit is contained in:
parent
29803c6ba0
commit
3be7d8e825
@ -14,7 +14,6 @@ namespace AaxDecrypter
|
|||||||
public class NetworkFileStream : Stream, IUpdatable
|
public class NetworkFileStream : Stream, IUpdatable
|
||||||
{
|
{
|
||||||
public event EventHandler Updated;
|
public event EventHandler Updated;
|
||||||
public event EventHandler DownloadCompleted;
|
|
||||||
|
|
||||||
#region Public Properties
|
#region Public Properties
|
||||||
|
|
||||||
@ -41,6 +40,9 @@ namespace AaxDecrypter
|
|||||||
[JsonIgnore]
|
[JsonIgnore]
|
||||||
public bool IsCancelled => _cancellationSource.IsCancellationRequested;
|
public bool IsCancelled => _cancellationSource.IsCancellationRequested;
|
||||||
|
|
||||||
|
[JsonIgnore]
|
||||||
|
public Task DownloadTask { get; private set; }
|
||||||
|
|
||||||
private long _speedLimit = 0;
|
private long _speedLimit = 0;
|
||||||
/// <summary>bytes per second</summary>
|
/// <summary>bytes per second</summary>
|
||||||
public long SpeedLimit { get => _speedLimit; set => _speedLimit = value <= 0 ? 0 : Math.Max(value, MIN_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 FileStream _readFile { get; }
|
||||||
private CancellationTokenSource _cancellationSource { get; } = new();
|
private CancellationTokenSource _cancellationSource { get; } = new();
|
||||||
private EventWaitHandle _downloadedPiece { get; set; }
|
private EventWaitHandle _downloadedPiece { get; set; }
|
||||||
private Task _backgroundDownloadTask { get; set; }
|
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
@ -128,7 +129,7 @@ namespace AaxDecrypter
|
|||||||
|
|
||||||
if (uriToSameFile.Host != Uri.Host)
|
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}");
|
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.");
|
throw new InvalidOperationException("Cannot change Uri after download has started.");
|
||||||
|
|
||||||
Uri = uriToSameFile;
|
Uri = uriToSameFile;
|
||||||
@ -141,7 +142,7 @@ namespace AaxDecrypter
|
|||||||
{
|
{
|
||||||
if (ContentLength != 0 && WritePosition == ContentLength)
|
if (ContentLength != 0 && WritePosition == ContentLength)
|
||||||
{
|
{
|
||||||
_backgroundDownloadTask = Task.CompletedTask;
|
DownloadTask = Task.CompletedTask;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -167,7 +168,8 @@ namespace AaxDecrypter
|
|||||||
_downloadedPiece = new EventWaitHandle(false, EventResetMode.AutoReset);
|
_downloadedPiece = new EventWaitHandle(false, EventResetMode.AutoReset);
|
||||||
|
|
||||||
//Download the file in the background.
|
//Download the file in the background.
|
||||||
_backgroundDownloadTask = Task.Run(() => DownloadFile(networkStream), _cancellationSource.Token);
|
|
||||||
|
DownloadTask = Task.Run(() => DownloadFile(networkStream), _cancellationSource.Token);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary> Download <see cref="Uri"/> to <see cref="SaveFilePath"/>.</summary>
|
/// <summary> Download <see cref="Uri"/> to <see cref="SaveFilePath"/>.</summary>
|
||||||
@ -234,7 +236,6 @@ namespace AaxDecrypter
|
|||||||
_writeFile.Close();
|
_writeFile.Close();
|
||||||
_downloadedPiece.Set();
|
_downloadedPiece.Set();
|
||||||
OnUpdate();
|
OnUpdate();
|
||||||
DownloadCompleted?.Invoke(this, null);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -256,7 +257,7 @@ namespace AaxDecrypter
|
|||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
if (_backgroundDownloadTask is null)
|
if (DownloadTask is null)
|
||||||
throw new InvalidOperationException($"Background downloader must first be started by calling {nameof(BeginDownloadingAsync)}");
|
throw new InvalidOperationException($"Background downloader must first be started by calling {nameof(BeginDownloadingAsync)}");
|
||||||
return ContentLength;
|
return ContentLength;
|
||||||
}
|
}
|
||||||
@ -280,7 +281,7 @@ namespace AaxDecrypter
|
|||||||
|
|
||||||
public override int Read(byte[] buffer, int offset, int count)
|
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)}");
|
throw new InvalidOperationException($"Background downloader must first be started by calling {nameof(BeginDownloadingAsync)}");
|
||||||
|
|
||||||
var toRead = Math.Min(count, Length - Position);
|
var toRead = Math.Min(count, Length - Position);
|
||||||
@ -306,7 +307,7 @@ namespace AaxDecrypter
|
|||||||
private void WaitToPosition(long requiredPosition)
|
private void WaitToPosition(long requiredPosition)
|
||||||
{
|
{
|
||||||
while (WritePosition < requiredPosition
|
while (WritePosition < requiredPosition
|
||||||
&& _backgroundDownloadTask?.IsCompleted is false
|
&& DownloadTask?.IsCompleted is false
|
||||||
&& !IsCancelled)
|
&& !IsCancelled)
|
||||||
{
|
{
|
||||||
_downloadedPiece.WaitOne(50);
|
_downloadedPiece.WaitOne(50);
|
||||||
@ -326,7 +327,7 @@ namespace AaxDecrypter
|
|||||||
if (disposing && !disposed)
|
if (disposing && !disposed)
|
||||||
{
|
{
|
||||||
_cancellationSource.Cancel();
|
_cancellationSource.Cancel();
|
||||||
_backgroundDownloadTask?.GetAwaiter().GetResult();
|
DownloadTask?.GetAwaiter().GetResult();
|
||||||
_downloadedPiece?.Dispose();
|
_downloadedPiece?.Dispose();
|
||||||
_cancellationSource?.Dispose();
|
_cancellationSource?.Dispose();
|
||||||
_readFile.Dispose();
|
_readFile.Dispose();
|
||||||
|
|||||||
@ -26,11 +26,7 @@ namespace AaxDecrypter
|
|||||||
|
|
||||||
protected override async Task<bool> Step_DownloadAndDecryptAudiobookAsync()
|
protected override async Task<bool> Step_DownloadAndDecryptAudiobookAsync()
|
||||||
{
|
{
|
||||||
TaskCompletionSource completionSource = new();
|
await InputFileStream.DownloadTask;
|
||||||
|
|
||||||
InputFileStream.DownloadCompleted += (_, _) => completionSource.SetResult();
|
|
||||||
|
|
||||||
await completionSource.Task;
|
|
||||||
|
|
||||||
if (IsCanceled)
|
if (IsCanceled)
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@ -10,7 +10,7 @@ namespace LibationCli.Options
|
|||||||
[Verb("search", HelpText = "Search for books in your library")]
|
[Verb("search", HelpText = "Search for books in your library")]
|
||||||
internal class SearchOptions : OptionsBase
|
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<string> Query { get; set; }
|
public IEnumerable<string> Query { get; set; }
|
||||||
|
|
||||||
protected override Task ProcessAsync()
|
protected override Task ProcessAsync()
|
||||||
@ -31,7 +31,7 @@ namespace LibationCli.Options
|
|||||||
if (waitForNextBatch)
|
if (waitForNextBatch)
|
||||||
{
|
{
|
||||||
Console.Write(nextPrompt);
|
Console.Write(nextPrompt);
|
||||||
waitForNextBatch = Console.ReadKey().Key != ConsoleKey.Escape;
|
waitForNextBatch = Console.ReadKey(intercept: true).Key != ConsoleKey.Escape;
|
||||||
ReplaceConsoleText(Console.Out, nextPrompt.Length, "");
|
ReplaceConsoleText(Console.Out, nextPrompt.Length, "");
|
||||||
Console.SetCursorPosition(0, Console.CursorTop);
|
Console.SetCursorPosition(0, Console.CursorTop);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -17,7 +17,7 @@ namespace LibationCli
|
|||||||
[Option(shortName: 'd', longName: "downloaded", Group = "Download Status", HelpText = "set download status to 'Downloaded'")]
|
[Option(shortName: 'd', longName: "downloaded", Group = "Download Status", HelpText = "set download status to 'Downloaded'")]
|
||||||
public bool SetDownloaded { get; set; }
|
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; }
|
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.")]
|
[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())
|
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();
|
libraryBooks = libraryBooks.Where(lb => lb.Book.AudibleProductId.ToLower().In(asins)).ToList();
|
||||||
|
|
||||||
if (libraryBooks.Count == 0)
|
if (libraryBooks.Count == 0)
|
||||||
|
|||||||
@ -51,16 +51,20 @@ namespace LibationCli
|
|||||||
|
|
||||||
protected async Task RunAsync(Processable Processable)
|
protected async Task RunAsync(Processable Processable)
|
||||||
{
|
{
|
||||||
var libraryBooks = DbContexts.GetLibrary_Flat_NoTracking().AsEnumerable();
|
var libraryBooks = DbContexts.GetLibrary_Flat_NoTracking();
|
||||||
|
|
||||||
if (Asins.Any())
|
if (Asins.Any())
|
||||||
{
|
{
|
||||||
var asinsLower = Asins.Select(a => a.ToLower()).ToArray();
|
var asinsLower = Asins.Select(a => a.TrimStart('[').TrimEnd(']').ToLower()).ToArray();
|
||||||
libraryBooks = libraryBooks.Where(lb => lb.Book.AudibleProductId.ToLower().In(asinsLower));
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (var libraryBook in Processable.GetValidLibraryBooks(libraryBooks))
|
foreach (var lb in libraryBooks.Where(lb => lb.Book.AudibleProductId.ToLower().In(asinsLower)))
|
||||||
await ProcessOneAsync(Processable, libraryBook, false);
|
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";
|
var done = "Done. All books have been processed";
|
||||||
Console.WriteLine(done);
|
Console.WriteLine(done);
|
||||||
|
|||||||
@ -21,7 +21,7 @@ namespace LibationCli
|
|||||||
{
|
{
|
||||||
|
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
string input = null;
|
string input = "";
|
||||||
|
|
||||||
//input = " set-status -n --force B017V4IM1G";
|
//input = " set-status -n --force B017V4IM1G";
|
||||||
//input = " liberate B017V4IM1G";
|
//input = " liberate B017V4IM1G";
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user