Refined changes to BookLiberation

This commit is contained in:
Michael Bucari-Tovo 2021-08-11 20:22:36 -06:00
parent 0045cf05ef
commit 687591e08e
16 changed files with 331 additions and 62 deletions

View File

@ -22,7 +22,7 @@ namespace FileLiberator
public event EventHandler<string> TitleDiscovered; public event EventHandler<string> TitleDiscovered;
public event EventHandler<string> AuthorsDiscovered; public event EventHandler<string> AuthorsDiscovered;
public event EventHandler<string> NarratorsDiscovered; public event EventHandler<string> NarratorsDiscovered;
public event EventHandler<byte[]> CoverImageFilepathDiscovered; public event EventHandler<byte[]> CoverImageDiscovered;
public event EventHandler<string> StreamingBegin; public event EventHandler<string> StreamingBegin;
public event EventHandler<DownloadProgress> StreamingProgressChanged; public event EventHandler<DownloadProgress> StreamingProgressChanged;
public event EventHandler<string> StreamingCompleted; public event EventHandler<string> StreamingCompleted;
@ -58,7 +58,7 @@ namespace FileLiberator
TitleDiscovered?.Invoke(this, m4bBook.AppleTags.Title); TitleDiscovered?.Invoke(this, m4bBook.AppleTags.Title);
AuthorsDiscovered?.Invoke(this, m4bBook.AppleTags.FirstAuthor); AuthorsDiscovered?.Invoke(this, m4bBook.AppleTags.FirstAuthor);
NarratorsDiscovered?.Invoke(this, m4bBook.AppleTags.Narrator); NarratorsDiscovered?.Invoke(this, m4bBook.AppleTags.Narrator);
CoverImageFilepathDiscovered?.Invoke(this, m4bBook.AppleTags.Cover); CoverImageDiscovered?.Invoke(this, m4bBook.AppleTags.Cover);
using var mp3File = File.OpenWrite(Path.GetTempFileName()); using var mp3File = File.OpenWrite(Path.GetTempFileName());

View File

@ -23,7 +23,7 @@ namespace FileLiberator
public event EventHandler<string> TitleDiscovered; public event EventHandler<string> TitleDiscovered;
public event EventHandler<string> AuthorsDiscovered; public event EventHandler<string> AuthorsDiscovered;
public event EventHandler<string> NarratorsDiscovered; public event EventHandler<string> NarratorsDiscovered;
public event EventHandler<byte[]> CoverImageFilepathDiscovered; public event EventHandler<byte[]> CoverImageDiscovered;
public event EventHandler<string> StreamingBegin; public event EventHandler<string> StreamingBegin;
public event EventHandler<DownloadProgress> StreamingProgressChanged; public event EventHandler<DownloadProgress> StreamingProgressChanged;
public event EventHandler<string> StreamingCompleted; public event EventHandler<string> StreamingCompleted;
@ -136,7 +136,7 @@ namespace FileLiberator
if (e is not null) if (e is not null)
{ {
CoverImageFilepathDiscovered?.Invoke(this, e); CoverImageDiscovered?.Invoke(this, e);
} }
} }

View File

@ -34,7 +34,7 @@ namespace FileLiberator
} }
private void OnProgressChanged(object sender, DownloadProgress e) private void OnProgressChanged(object sender, DownloadProgress e)
{ {
StreamingProgressChanged?.Invoke(this, e); StreamingProgressChanged.Invoke(this, e);
} }
} }
} }

View File

@ -10,7 +10,7 @@ namespace FileLiberator
event EventHandler<string> TitleDiscovered; event EventHandler<string> TitleDiscovered;
event EventHandler<string> AuthorsDiscovered; event EventHandler<string> AuthorsDiscovered;
event EventHandler<string> NarratorsDiscovered; event EventHandler<string> NarratorsDiscovered;
event EventHandler<byte[]> CoverImageFilepathDiscovered; event EventHandler<byte[]> CoverImageDiscovered;
void Cancel(); void Cancel();
} }

View File

@ -13,7 +13,7 @@
<!-- <PublishSingleFile>true</PublishSingleFile> --> <!-- <PublishSingleFile>true</PublishSingleFile> -->
<RuntimeIdentifier>win-x64</RuntimeIdentifier> <RuntimeIdentifier>win-x64</RuntimeIdentifier>
<Version>5.4.9.200</Version> <Version>5.4.9.239</Version>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">

View File

@ -63,9 +63,6 @@ namespace LibationLauncher
#if !DEBUG #if !DEBUG
checkForUpdate(config); checkForUpdate(config);
#endif #endif
LibationWinForms.BookLiberation.ProcessorAutomationController.DownloadFile(
"https://github.com/rmcrackan/Libation/releases/download/v5.4.9/Libation.5.4.9.zip",
@"C:\Users\mbuca\Downloads\libation test dl.zip");
Application.Run(new Form1()); Application.Run(new Form1());
} }

View File

@ -0,0 +1,120 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

View File

@ -18,6 +18,7 @@ namespace LibationWinForms.BookLiberation
private string authorNames; private string authorNames;
private string narratorNames; private string narratorNames;
#region ProcessBaseForm overrides
public override void SetProcessable(IStreamable streamProcessable, Action<string> infoLog) public override void SetProcessable(IStreamable streamProcessable, Action<string> infoLog)
{ {
base.SetProcessable(streamProcessable, infoLog); base.SetProcessable(streamProcessable, infoLog);
@ -30,21 +31,24 @@ namespace LibationWinForms.BookLiberation
audioDecodable.TitleDiscovered += OnTitleDiscovered; audioDecodable.TitleDiscovered += OnTitleDiscovered;
audioDecodable.AuthorsDiscovered += OnAuthorsDiscovered; audioDecodable.AuthorsDiscovered += OnAuthorsDiscovered;
audioDecodable.NarratorsDiscovered += OnNarratorsDiscovered; audioDecodable.NarratorsDiscovered += OnNarratorsDiscovered;
audioDecodable.CoverImageFilepathDiscovered += OnCoverImageFilepathDiscovered; audioDecodable.CoverImageDiscovered += OnCoverImageDiscovered;
Disposed += OnUnsubscribeAll; Disposed += OnUnsubscribeAll;
} }
} }
#endregion
private void OnUnsubscribeAll(object sender, EventArgs e) private void OnUnsubscribeAll(object sender, EventArgs e)
{ {
Disposed -= OnUnsubscribeAll; Disposed -= OnUnsubscribeAll;
if (Streamable is not null && Streamable is IAudioDecodable audioDecodable) if (Streamable is IAudioDecodable audioDecodable)
{ {
audioDecodable.RequestCoverArt -= OnRequestCoverArt; audioDecodable.RequestCoverArt -= OnRequestCoverArt;
audioDecodable.TitleDiscovered -= OnTitleDiscovered; audioDecodable.TitleDiscovered -= OnTitleDiscovered;
audioDecodable.AuthorsDiscovered -= OnAuthorsDiscovered; audioDecodable.AuthorsDiscovered -= OnAuthorsDiscovered;
audioDecodable.NarratorsDiscovered -= OnNarratorsDiscovered; audioDecodable.NarratorsDiscovered -= OnNarratorsDiscovered;
audioDecodable.CoverImageFilepathDiscovered -= OnCoverImageFilepathDiscovered; audioDecodable.CoverImageDiscovered -= OnCoverImageDiscovered;
audioDecodable.Cancel(); audioDecodable.Cancel();
} }
@ -62,7 +66,7 @@ namespace LibationWinForms.BookLiberation
OnTitleDiscovered(null, libraryBook.Book.Title); OnTitleDiscovered(null, libraryBook.Book.Title);
OnAuthorsDiscovered(null, string.Join(", ", libraryBook.Book.Authors)); OnAuthorsDiscovered(null, string.Join(", ", libraryBook.Book.Authors));
OnNarratorsDiscovered(null, string.Join(", ", libraryBook.Book.NarratorNames)); OnNarratorsDiscovered(null, string.Join(", ", libraryBook.Book.NarratorNames));
OnCoverImageFilepathDiscovered(null, OnCoverImageDiscovered(null,
FileManager.PictureStorage.GetPictureSynchronously( FileManager.PictureStorage.GetPictureSynchronously(
new FileManager.PictureDefinition( new FileManager.PictureDefinition(
libraryBook.Book.PictureId, libraryBook.Book.PictureId,
@ -112,7 +116,7 @@ namespace LibationWinForms.BookLiberation
updateBookInfo(); updateBookInfo();
} }
public virtual void OnCoverImageFilepathDiscovered(object sender, byte[] coverArt) public virtual void OnCoverImageDiscovered(object sender, byte[] coverArt)
=> pictureBox1.UIThread(() => pictureBox1.Image = Dinah.Core.Drawing.ImageReader.ToImage(coverArt)); => pictureBox1.UIThread(() => pictureBox1.Image = Dinah.Core.Drawing.ImageReader.ToImage(coverArt));
#endregion #endregion

View File

@ -23,12 +23,13 @@ namespace LibationWinForms.BookLiberation
processable.StatusUpdate += OnStatusUpdate; processable.StatusUpdate += OnStatusUpdate;
Disposed += OnUnsubscribeAll; Disposed += OnUnsubscribeAll;
} }
} }
private void OnUnsubscribeAll(object sender, EventArgs e) private void OnUnsubscribeAll(object sender, EventArgs e)
{ {
Disposed -= OnUnsubscribeAll; Disposed -= OnUnsubscribeAll;
if (Streamable is not null && Streamable is IProcessable processable) if (Streamable is IProcessable processable)
{ {
processable.Begin -= OnBegin; processable.Begin -= OnBegin;
processable.Completed -= OnCompleted; processable.Completed -= OnCompleted;

View File

@ -1,16 +1,25 @@
using Dinah.Core.Net.Http; using Dinah.Core.Net.Http;
using Dinah.Core.Windows.Forms;
using FileLiberator; using FileLiberator;
using System; using System;
using System.Collections.Generic; using System.ComponentModel;
using System.Linq; using System.Threading;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms; using System.Windows.Forms;
namespace LibationWinForms.BookLiberation namespace LibationWinForms.BookLiberation
{ {
public class StreamBaseForm : Form public class StreamBaseForm : Form
{ {
private int InstanceThreadId { get; } = Thread.CurrentThread.ManagedThreadId;
public new bool InvokeRequired => Thread.CurrentThread.ManagedThreadId != InstanceThreadId;
private SynchronizationContext SyncContext { get; }
public StreamBaseForm()
{
//Will not work if set outside constructor.
SyncContext = SynchronizationContext.Current;
}
protected IStreamable Streamable { get; private set; } protected IStreamable Streamable { get; private set; }
public void SetStreamable(IStreamable streamable) public void SetStreamable(IStreamable streamable)
{ {
@ -39,14 +48,41 @@ namespace LibationWinForms.BookLiberation
} }
#region IStreamable event handlers #region IStreamable event handlers
public virtual void OnStreamingBegin(object sender, string beginString) => Show(); public virtual void OnStreamingBegin(object sender, string beginString)
{
//If StreamingBegin is fired from a worker thread, the form will be created on
//that UI thread. Form.BeginInvoke won't work until the form is created (ie. shown),
//so we need to make certain that we show the form on the same thread that created
//this StreamBaseForm.
static void sendCallback(object asyncArgs)
{
var e = asyncArgs as AsyncCompletedEventArgs;
((Action)e.UserState)();
}
Action code = Show;
if (InvokeRequired)
{
var args = new AsyncCompletedEventArgs(null, false, code);
SyncContext.Send(
sendCallback,
args);
}
else
{
code();
}
}
public virtual void OnStreamingProgressChanged(object sender, DownloadProgress downloadProgress) { } public virtual void OnStreamingProgressChanged(object sender, DownloadProgress downloadProgress) { }
public virtual void OnStreamingTimeRemaining(object sender, TimeSpan timeRemaining) { } public virtual void OnStreamingTimeRemaining(object sender, TimeSpan timeRemaining) { }
public virtual void OnStreamingCompleted(object sender, string completedString) public virtual void OnStreamingCompleted(object sender, string completedString)
{ => this.UIThread(() =>
Close(); {
Dispose(); Close();
} Dispose();
});
#endregion #endregion
} }
} }

View File

@ -0,0 +1,120 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

View File

@ -1,7 +1,6 @@
using DataLayer; using DataLayer;
using Dinah.Core; using Dinah.Core;
using Dinah.Core.ErrorHandling; using Dinah.Core.ErrorHandling;
using Dinah.Core.Windows.Forms;
using FileLiberator; using FileLiberator;
using System; using System;
using System.Linq; using System.Linq;
@ -82,15 +81,15 @@ namespace LibationWinForms.BookLiberation
var automatedBackupsForm = new AutomatedBackupsForm(); var automatedBackupsForm = new AutomatedBackupsForm();
LogMe logMe = LogMe.RegisterForm(automatedBackupsForm); LogMe logMe = LogMe.RegisterForm(automatedBackupsForm);
var convertBook = CreateStreamableProcessable<ConvertToMp3, AudioConvertForm>(null, logMe); var convertBook = CreateStreamProcessable<ConvertToMp3, AudioConvertForm>(null, logMe);
await new BackupLoop(logMe, convertBook, automatedBackupsForm).RunBackupAsync(); await new BackupLoop(logMe, convertBook, automatedBackupsForm).RunBackupAsync();
} }
private static BackupBook CreateBackupBook(EventHandler<LibraryBook> completedAction, LogMe logMe) private static BackupBook CreateBackupBook(EventHandler<LibraryBook> completedAction, LogMe logMe)
{ {
var downloadPdf = CreateStreamableProcessable<DownloadPdf, DownloadForm>(completedAction, logMe); var downloadPdf = CreateStreamProcessable<DownloadPdf, DownloadForm>(completedAction, logMe);
var downloadDecryptBook = CreateStreamableProcessable<DownloadDecryptBook, AudioDecryptForm>(completedAction, logMe); var downloadDecryptBook = CreateStreamProcessable<DownloadDecryptBook, AudioDecryptForm>(completedAction, logMe);
return new BackupBook(downloadDecryptBook, downloadPdf); return new BackupBook(downloadDecryptBook, downloadPdf);
} }
@ -101,34 +100,35 @@ namespace LibationWinForms.BookLiberation
var automatedBackupsForm = new AutomatedBackupsForm(); var automatedBackupsForm = new AutomatedBackupsForm();
LogMe logMe = LogMe.RegisterForm(automatedBackupsForm); LogMe logMe = LogMe.RegisterForm(automatedBackupsForm);
var downloadPdf = CreateStreamableProcessable<DownloadPdf, DownloadForm>(completedAction, logMe); var downloadPdf = CreateStreamProcessable<DownloadPdf, DownloadForm>(completedAction, logMe);
await new BackupLoop(logMe, downloadPdf, automatedBackupsForm).RunBackupAsync(); await new BackupLoop(logMe, downloadPdf, automatedBackupsForm).RunBackupAsync();
} }
public static void DownloadFile(string url, string destination, bool showDownloadCompletedDialog = false) public static void DownloadFile(string url, string destination, bool showDownloadCompletedDialog = false)
{ {
new System.Threading.Thread(() => void OnCompleted(object o, string s)
{ {
(DownloadFile downloadFile, DownloadForm downloadForm) = CreateStreamable<DownloadFile, DownloadForm>();
if (showDownloadCompletedDialog) if (showDownloadCompletedDialog)
downloadFile.StreamingCompleted += (_, __) => MessageBox.Show("File downloaded"); MessageBox.Show("File downloaded to:\r\n\r\n" + s);
}
downloadFile.PerformDownloadFileAsync(url, destination).GetAwaiter().GetResult(); (DownloadFile downloadFile, DownloadForm downloadForm) = CreateStreamable<DownloadFile, DownloadForm>(OnCompleted);
})
new System.Threading.Thread(() =>downloadFile.PerformDownloadFileAsync(url, destination).GetAwaiter().GetResult())
{ IsBackground = true } { IsBackground = true }
.Start(); .Start();
} }
/// <summary> /// <summary>
/// Create a new <see cref="IStreamProcessable"/> and which creates a new <see cref="ProcessBaseForm"/> on IProcessable.Begin. /// Create a new <see cref="IStreamProcessable"/> and which creates a new <see cref="ProcessBaseForm"/> on <see cref="IProcessable.Begin"/>.
/// </summary> /// </summary>
/// <typeparam name="TStrProc">The <see cref="IStreamProcessable"/> derrived type to create.</typeparam> /// <typeparam name="TStrProc">The <see cref="IStreamProcessable"/> derrived type to create.</typeparam>
/// <typeparam name="TForm">The <see cref="ProcessBaseForm"/> derrived form to create on Begin</typeparam> /// <typeparam name="TForm">The <see cref="ProcessBaseForm"/> derrived form to create on <see cref="IProcessable.Begin"/> and and be Shown on <see cref="IStreamable.StreamingBegin"/></typeparam>
/// <param name="completedAction">An additional event handler to handle <typeparamref name="TStrProc"/>.Completed</param> /// <param name="completedAction">An additional event handler to handle <see cref="IProcessable.Completed"/></param>
/// <returns>A new <see cref="IStreamProcessable"/> of type <typeparamref name="TStrProc"/></returns> /// <returns>A new <see cref="IStreamProcessable"/> of type <typeparamref name="TStrProc"/></returns>
private static TStrProc CreateStreamableProcessable<TStrProc, TForm>(EventHandler<LibraryBook> completedAction = null, LogMe logMe = null) private static TStrProc CreateStreamProcessable<TStrProc, TForm>(EventHandler<LibraryBook> completedAction = null, LogMe logMe = null)
where TForm : ProcessBaseForm, new() where TForm : ProcessBaseForm, new()
where TStrProc : IStreamProcessable, new() where TStrProc : IStreamProcessable, new()
{ {
@ -137,7 +137,8 @@ namespace LibationWinForms.BookLiberation
strProc.Begin += (sender, libraryBook) => strProc.Begin += (sender, libraryBook) =>
{ {
var processForm = new TForm(); var processForm = new TForm();
processForm.SetProcessable(strProc, logMe.Info); Action<string> logAction = logMe is null ? (s) => { } : logMe.Info;
processForm.SetProcessable(strProc, logAction);
processForm.OnBegin(sender, libraryBook); processForm.OnBegin(sender, libraryBook);
}; };
@ -146,7 +147,14 @@ namespace LibationWinForms.BookLiberation
return strProc; return strProc;
} }
private static (TStrProc, TForm) CreateStreamable<TStrProc, TForm>(EventHandler<LibraryBook> completedAction = null)
/// <summary>
/// Creates a new <see cref="IStreamable"/> and links it to a new <see cref="StreamBaseForm"/>
/// </summary>
/// <typeparam name="TStrProc">The <see cref="IStreamable"/> derrived type to create.</typeparam>
/// <typeparam name="TForm">The <see cref="StreamBaseForm"/> derrived form to create, which will be Shown on <see cref="IStreamable.StreamingBegin"/>.</typeparam>
/// <param name="completedAction">An additional event handler to handle <see cref="IStreamable.StreamingCompleted"/></param>
private static (TStrProc, TForm) CreateStreamable<TStrProc, TForm>(EventHandler<string> completedAction = null)
where TForm : StreamBaseForm, new() where TForm : StreamBaseForm, new()
where TStrProc : IStreamable, new() where TStrProc : IStreamable, new()
{ {
@ -155,6 +163,9 @@ namespace LibationWinForms.BookLiberation
var streamForm = new TForm(); var streamForm = new TForm();
streamForm.SetStreamable(strProc); streamForm.SetStreamable(strProc);
if (completedAction != null)
strProc.StreamingCompleted += completedAction;
return (strProc, streamForm); return (strProc, streamForm);
} }
} }

View File

@ -61,7 +61,6 @@
this.backupsCountsLbl = new System.Windows.Forms.ToolStripStatusLabel(); this.backupsCountsLbl = new System.Windows.Forms.ToolStripStatusLabel();
this.pdfsCountsLbl = new System.Windows.Forms.ToolStripStatusLabel(); this.pdfsCountsLbl = new System.Windows.Forms.ToolStripStatusLabel();
this.addFilterBtn = new System.Windows.Forms.Button(); this.addFilterBtn = new System.Windows.Forms.Button();
this.button1 = new System.Windows.Forms.Button();
this.menuStrip1.SuspendLayout(); this.menuStrip1.SuspendLayout();
this.statusStrip1.SuspendLayout(); this.statusStrip1.SuspendLayout();
this.SuspendLayout(); this.SuspendLayout();
@ -337,22 +336,11 @@
this.addFilterBtn.UseVisualStyleBackColor = true; this.addFilterBtn.UseVisualStyleBackColor = true;
this.addFilterBtn.Click += new System.EventHandler(this.AddFilterBtn_Click); this.addFilterBtn.Click += new System.EventHandler(this.AddFilterBtn_Click);
// //
// button1
//
this.button1.Location = new System.Drawing.Point(648, 0);
this.button1.Name = "button1";
this.button1.Size = new System.Drawing.Size(123, 70);
this.button1.TabIndex = 0;
this.button1.Text = "button1";
this.button1.UseVisualStyleBackColor = true;
this.button1.Click += new System.EventHandler(this.button1_Click);
//
// Form1 // Form1
// //
this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F); this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(1007, 539); this.ClientSize = new System.Drawing.Size(1007, 539);
this.Controls.Add(this.button1);
this.Controls.Add(this.filterBtn); this.Controls.Add(this.filterBtn);
this.Controls.Add(this.addFilterBtn); this.Controls.Add(this.addFilterBtn);
this.Controls.Add(this.filterSearchTb); this.Controls.Add(this.filterSearchTb);
@ -410,6 +398,5 @@
private System.Windows.Forms.ToolStripMenuItem removeLibraryBooksToolStripMenuItem; private System.Windows.Forms.ToolStripMenuItem removeLibraryBooksToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem removeAllAccountsToolStripMenuItem; private System.Windows.Forms.ToolStripMenuItem removeAllAccountsToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem removeSomeAccountsToolStripMenuItem; private System.Windows.Forms.ToolStripMenuItem removeSomeAccountsToolStripMenuItem;
private System.Windows.Forms.Button button1;
} }
} }

View File

@ -496,12 +496,5 @@ namespace LibationWinForms
private void basicSettingsToolStripMenuItem_Click(object sender, EventArgs e) => new SettingsDialog().ShowDialog(); private void basicSettingsToolStripMenuItem_Click(object sender, EventArgs e) => new SettingsDialog().ShowDialog();
#endregion #endregion
private void button1_Click(object sender, EventArgs e)
{
BookLiberation.ProcessorAutomationController.DownloadFile(
"https://github.com/rmcrackan/Libation/releases/download/v5.4.9/Libation.5.4.9.zip",
@"C:\Users\mbuca\Downloads\libation test dl.zip");
}
} }
} }