This commit is contained in:
Michael Bucari-Tovo 2022-05-14 03:16:48 -06:00
parent 676af0210b
commit eeb4f4681a
10 changed files with 1502 additions and 752 deletions

View file

@ -1,142 +1,205 @@
using DataLayer;
using Dinah.Core.Threading;
using Dinah.Core.Threading;
using LibationWinForms.BookLiberation;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace LibationWinForms.ProcessQueue
{
{
internal partial class ProcessBookQueue : UserControl, ILogForm
{
TrackedQueue<ProcessBook> Queue = new();
private TrackedQueue<ProcessBook> Queue = new();
private readonly LogMe Logger;
private int QueuedCount
{
set
{
queueNumberLbl.Text = value.ToString();
queueNumberLbl.Visible = value > 0;
}
}
private int ErrorCount
{
set
{
errorNumberLbl.Text = value.ToString();
errorNumberLbl.Visible = value > 0;
}
}
private int CompletedCount
{
set
{
completedNumberLbl.Text = value.ToString();
completedNumberLbl.Visible = value > 0;
}
}
public Task QueueRunner { get; private set; }
public bool Running => !QueueRunner?.IsCompleted ?? false;
public ToolStripButton popoutBtn = new();
private int FirstVisible = 0;
private int NumVisible = 0;
private IReadOnlyList<ProcessBookControl> Panels;
public ProcessBookQueue()
{
InitializeComponent();
Logger = LogMe.RegisterForm(this);
this.popoutBtn.DisplayStyle = ToolStripItemDisplayStyle.Text;
this.popoutBtn.Name = "popoutBtn";
this.popoutBtn.Text = "Pop Out";
this.popoutBtn.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
this.popoutBtn.Alignment = ToolStripItemAlignment.Right;
this.popoutBtn.Anchor = AnchorStyles.Bottom | AnchorStyles.Right;
popoutBtn.DisplayStyle = ToolStripItemDisplayStyle.Text;
popoutBtn.Name = "popoutBtn";
popoutBtn.Text = "Pop Out";
popoutBtn.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
popoutBtn.Alignment = ToolStripItemAlignment.Right;
popoutBtn.Anchor = AnchorStyles.Bottom | AnchorStyles.Right;
statusStrip1.Items.Add(popoutBtn);
virtualFlowControl2.RequestData += VirtualFlowControl1_RequestData;
virtualFlowControl2.ButtonClicked += VirtualFlowControl2_ButtonClicked;
Queue.QueuededCountChanged += Queue_QueuededCountChanged;
Queue.CompletedCountChanged += Queue_CompletedCountChanged;
QueuedCount = 0;
ErrorCount = 0;
CompletedCount = 0;
}
private void Queue_CompletedCountChanged(object sender, int e)
{
int errCount = Queue.Completed.Count(p => p.Result is ProcessBookResult.FailedAbort or ProcessBookResult.FailedSkip or ProcessBookResult.ValidationFail);
int completeCount = Queue.Completed.Count(p => p.Result is ProcessBookResult.Success);
ErrorCount = errCount;
CompletedCount = completeCount;
UpdateProgressBar();
}
private void Queue_QueuededCountChanged(object sender, int cueCount)
{
QueuedCount = cueCount;
virtualFlowControl2.VirtualControlCount = Queue.Count;
UpdateProgressBar();
}
private void UpdateProgressBar()
{
toolStripProgressBar1.Maximum = Queue.Count;
toolStripProgressBar1.Value = Queue.Completed.Count;
}
private void VirtualFlowControl2_ButtonClicked(int itemIndex, string buttonName, ProcessBookControl panelClicked)
{
ProcessBook item = Queue[itemIndex];
if (buttonName == "cancelBtn")
{
item.Cancel();
Queue.RemoveQueued(item);
virtualFlowControl2.VirtualControlCount = Queue.Count;
UpdateControl(itemIndex);
}
else if (buttonName == "moveFirstBtn")
{
Queue.MoveQueuePosition(item, QueuePosition.Fisrt);
UpdateAllControls();
}
else if (buttonName == "moveUpBtn")
{
Queue.MoveQueuePosition(item, QueuePosition.OneUp);
UpdateControl(itemIndex - 1);
UpdateControl(itemIndex);
}
else if (buttonName == "moveDownBtn")
{
Queue.MoveQueuePosition(item, QueuePosition.OneDown);
UpdateControl(itemIndex + 1);
UpdateControl(itemIndex);
}
else if (buttonName == "moveLastBtn")
{
Queue.MoveQueuePosition(item, QueuePosition.Last);
UpdateAllControls();
}
}
private void UpdateControl(int queueIndex)
{
int i = queueIndex - FirstVisible;
if (i < 0 || i > NumVisible) return;
var proc = Queue[queueIndex];
Panels[i].Invoke(() =>
{
Panels[i].SuspendLayout();
Panels[i].SetCover(proc.Cover);
Panels[i].SetBookInfo(proc.BookText);
if (proc.Result != ProcessBookResult.None)
{
Panels[i].SetResult(proc.Result);
return;
}
Panels[i].SetStatus(proc.Status);
Panels[i].SetProgrss(proc.Progress);
Panels[i].SetRemainingTime(proc.TimeRemaining);
Panels[i].ResumeLayout();
});
}
private void UpdateAllControls()
{
int numToShow = Math.Min(NumVisible, Queue.Count - FirstVisible);
for (int i = 0; i < numToShow; i++)
UpdateControl(FirstVisible + i);
}
private void VirtualFlowControl1_RequestData(int firstIndex, int numVisible, IReadOnlyList<ProcessBookControl> panelsToFill)
{
int numToShow = Math.Min(numVisible, Queue.Count - firstIndex);
for (int i = 0; i < numToShow; i++)
{
var proc = Queue[firstIndex + i];
panelsToFill[i].SetCover(proc.Entry.Cover);
panelsToFill[i].SetTitle(proc.Entry.Title);
}
FirstVisible = firstIndex;
NumVisible = numVisible;
Panels = panelsToFill;
UpdateAllControls();
}
public async Task AddDownloadDecrypt(IEnumerable<GridEntry> entries)
public void AddDownloadDecrypt(IEnumerable<GridEntry> entries)
{
SuspendLayout();
foreach (var entry in entries)
await AddDownloadDecryptAsync(entry);
ResumeLayout();
AddDownloadDecryptAsync(entry);
}
int count = 0;
public async Task AddDownloadDecryptAsync(GridEntry gridEntry)
public void AddDownloadDecryptAsync(GridEntry gridEntry)
{
//if (Queue.Any(b=> b?.Entry?.AudibleProductId == gridEntry.AudibleProductId))
//return;
if (Queue.Any(b => b?.LibraryBook?.Book?.AudibleProductId == gridEntry.AudibleProductId))
return;
ProcessBook pbook = new ProcessBook(gridEntry, Logger);
pbook.Completed += Pbook_Completed;
pbook.Cancelled += Pbook_Cancelled;
pbook.RequestMove += (o,d) => RequestMove(o, d);
ProcessBook pbook = new(gridEntry.LibraryBook, gridEntry.Cover, Logger);
pbook.DataAvailable += Pbook_DataAvailable;
var libStatus = gridEntry.Liberate;
pbook.AddDownloadDecryptBook();
pbook.AddDownloadPdf();
if (libStatus.BookStatus != LiberatedStatus.Liberated)
pbook.AddDownloadDecryptProcessable();
if (libStatus.PdfStatus != LiberatedStatus.Liberated)
pbook.AddPdfProcessable();
Queue.EnqueueBook(pbook);
//await AddBookControlAsync(pbook.BookControl);
count++;
virtualFlowControl2.VirtualControlCount = count;
Queue.Enqueue(pbook);
if (!Running)
{
//QueueRunner = QueueLoop();
QueueRunner = QueueLoop();
}
toolStripStatusLabel1.Text = count.ToString();
}
private async void Pbook_Cancelled(ProcessBook sender, EventArgs e)
private void Pbook_DataAvailable(object sender, EventArgs e)
{
Queue.Remove(sender);
//await RemoveBookControlAsync(sender.BookControl);
}
/// <summary>
/// Handles requests by <see cref="ProcessBook"/> to change its order in the queue
/// </summary>
/// <param name="sender">The requesting <see cref="ProcessBook"/></param>
/// <param name="direction">The requested position</param>
/// <returns>The resultant position</returns>
private QueuePosition RequestMove(ProcessBook sender, QueuePositionRequest requested)
{
var direction = Queue.MoveQueuePosition(sender, requested);
if (direction is QueuePosition.Absent or QueuePosition.Current or QueuePosition.Completed)
return direction;
return direction;
/*
var firstQueue = autosizeFlowLayout1.Controls.Cast<ProcessBookControl>().FirstOrDefault(c => c.Status == ProcessBookStatus.Queued);
if (firstQueue is null) return QueuePosition.Current;
int firstQueueIndex = autosizeFlowLayout1.Controls.IndexOf(firstQueue);
var index = autosizeFlowLayout1.Controls.IndexOf(sender.BookControl);
int newIndex = direction switch
{
QueuePosition.Fisrt => firstQueueIndex,
QueuePosition.OneUp => index - 1,
QueuePosition.OneDown => index + 1,
QueuePosition.Last => autosizeFlowLayout1.Controls.Count - 1,
_ => -1,
};
if (newIndex < 0) return direction;
autosizeFlowLayout1.Controls.SetChildIndex(sender.BookControl, newIndex);
return direction;
*/
int index = Queue.IndexOf((ProcessBook)sender);
UpdateControl(index);
}
private async Task QueueLoop()
@ -147,80 +210,28 @@ namespace LibationWinForms.ProcessQueue
var result = await nextBook.ProcessOneAsync();
switch (result)
{
case ProcessBookResult.FailedRetry:
Queue.EnqueueBook(nextBook);
break;
case ProcessBookResult.FailedAbort:
return;
}
if (result == ProcessBookResult.FailedRetry)
Queue.Enqueue(nextBook);
else if (result == ProcessBookResult.FailedAbort)
return;
}
Queue_CompletedCountChanged(this, 0);
}
private void Pbook_Completed(object sender, EventArgs e)
private void cancelAllBtn_Click(object sender, EventArgs e)
{
}
private async void cancelAllBtn_Click(object sender, EventArgs e)
{
List<ProcessBook> l1 = Queue.QueuedItems();
Queue.ClearQueue();
Queue.Current?.Cancel();
//await RemoveBookControlsAsync(l1.Select(l => l.BookControl));
virtualFlowControl2.VirtualControlCount = Queue.Count;
UpdateAllControls();
}
private async void btnCleanFinished_Click(object sender, EventArgs e)
private void btnCleanFinished_Click(object sender, EventArgs e)
{
List<ProcessBook> l1 = Queue.CompletedItems();
Queue.ClearCompleted();
//await RemoveBookControlsAsync(l1.Select(l => l.BookControl));
}
private async Task AddBookControlAsync(ProcessBookControl control)
{
await Task.Run(() => Invoke(() =>
{
/*
control.Width = autosizeFlowLayout1.DesiredBookControlWidth;
autosizeFlowLayout1.Controls.Add(control);
autosizeFlowLayout1.SetFlowBreak(control, true);
*/
//Refresh();
//System.Threading.Thread.Sleep(1000);
}));
}
private async Task RemoveBookControlAsync(ProcessBookControl control)
{
await Task.Run(() => Invoke(() =>
{
//autosizeFlowLayout1.Controls.Remove(control);
}));
}
private async Task RemoveBookControlsAsync(IEnumerable<ProcessBookControl> control)
{
await Task.Run(() => Invoke(() =>
{
/*
SuspendLayout();
foreach (var l in control)
autosizeFlowLayout1.Controls.Remove(l);
ResumeLayout();
*/
}));
}
public void WriteLine(string text)
{
if (!IsDisposed)
logMeTbox.UIThreadAsync(() => logMeTbox.AppendText($"{DateTime.Now} {text}{Environment.NewLine}"));
virtualFlowControl2.VirtualControlCount = Queue.Count;
UpdateAllControls();
}
private void clearLogBtn_Click(object sender, EventArgs e)
@ -228,5 +239,10 @@ namespace LibationWinForms.ProcessQueue
logMeTbox.Clear();
}
public void WriteLine(string text)
{
if (!IsDisposed)
logMeTbox.UIThreadAsync(() => logMeTbox.AppendText($"{DateTime.Now} {text}{Environment.NewLine}"));
}
}
}