diff --git a/FileLiberator/ConvertToMp3.cs b/FileLiberator/ConvertToMp3.cs index 6b514837..6c682b20 100644 --- a/FileLiberator/ConvertToMp3.cs +++ b/FileLiberator/ConvertToMp3.cs @@ -22,7 +22,7 @@ namespace FileLiberator public event EventHandler TitleDiscovered; public event EventHandler AuthorsDiscovered; public event EventHandler NarratorsDiscovered; - public event EventHandler CoverImageFilepathDiscovered; + public event EventHandler CoverImageDiscovered; public event EventHandler StreamingBegin; public event EventHandler StreamingProgressChanged; public event EventHandler StreamingCompleted; @@ -58,7 +58,7 @@ namespace FileLiberator TitleDiscovered?.Invoke(this, m4bBook.AppleTags.Title); AuthorsDiscovered?.Invoke(this, m4bBook.AppleTags.FirstAuthor); 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()); diff --git a/FileLiberator/DownloadDecryptBook.cs b/FileLiberator/DownloadDecryptBook.cs index 8565a1da..d8596ae3 100644 --- a/FileLiberator/DownloadDecryptBook.cs +++ b/FileLiberator/DownloadDecryptBook.cs @@ -23,7 +23,7 @@ namespace FileLiberator public event EventHandler TitleDiscovered; public event EventHandler AuthorsDiscovered; public event EventHandler NarratorsDiscovered; - public event EventHandler CoverImageFilepathDiscovered; + public event EventHandler CoverImageDiscovered; public event EventHandler StreamingBegin; public event EventHandler StreamingProgressChanged; public event EventHandler StreamingCompleted; @@ -136,7 +136,7 @@ namespace FileLiberator if (e is not null) { - CoverImageFilepathDiscovered?.Invoke(this, e); + CoverImageDiscovered?.Invoke(this, e); } } diff --git a/FileLiberator/DownloadFile.cs b/FileLiberator/DownloadFile.cs index d4735420..dd67f8e0 100644 --- a/FileLiberator/DownloadFile.cs +++ b/FileLiberator/DownloadFile.cs @@ -34,7 +34,7 @@ namespace FileLiberator } private void OnProgressChanged(object sender, DownloadProgress e) { - StreamingProgressChanged?.Invoke(this, e); + StreamingProgressChanged.Invoke(this, e); } } } diff --git a/FileLiberator/IAudioDecodable.cs b/FileLiberator/IAudioDecodable.cs index 8eaab624..eb18bb91 100644 --- a/FileLiberator/IAudioDecodable.cs +++ b/FileLiberator/IAudioDecodable.cs @@ -10,7 +10,7 @@ namespace FileLiberator event EventHandler TitleDiscovered; event EventHandler AuthorsDiscovered; event EventHandler NarratorsDiscovered; - event EventHandler CoverImageFilepathDiscovered; + event EventHandler CoverImageDiscovered; void Cancel(); } diff --git a/LibationLauncher/LibationLauncher.csproj b/LibationLauncher/LibationLauncher.csproj index ca7b53f8..b55ca588 100644 --- a/LibationLauncher/LibationLauncher.csproj +++ b/LibationLauncher/LibationLauncher.csproj @@ -13,7 +13,7 @@ win-x64 - 5.4.9.200 + 5.4.9.239 diff --git a/LibationLauncher/Program.cs b/LibationLauncher/Program.cs index 0184b1a7..0786e414 100644 --- a/LibationLauncher/Program.cs +++ b/LibationLauncher/Program.cs @@ -63,9 +63,6 @@ namespace LibationLauncher #if !DEBUG checkForUpdate(config); #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()); } diff --git a/LibationWinForms/BookLiberation/AudioConvertForm.resx b/LibationWinForms/BookLiberation/AudioConvertForm.resx new file mode 100644 index 00000000..1af7de15 --- /dev/null +++ b/LibationWinForms/BookLiberation/AudioConvertForm.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/LibationWinForms/BookLiberation/AudioDecodeBaseForm.Designer.cs b/LibationWinForms/BookLiberation/BaseForms/AudioDecodeBaseForm.Designer.cs similarity index 100% rename from LibationWinForms/BookLiberation/AudioDecodeBaseForm.Designer.cs rename to LibationWinForms/BookLiberation/BaseForms/AudioDecodeBaseForm.Designer.cs diff --git a/LibationWinForms/BookLiberation/AudioDecodeBaseForm.cs b/LibationWinForms/BookLiberation/BaseForms/AudioDecodeBaseForm.cs similarity index 91% rename from LibationWinForms/BookLiberation/AudioDecodeBaseForm.cs rename to LibationWinForms/BookLiberation/BaseForms/AudioDecodeBaseForm.cs index 3354460a..a2691eec 100644 --- a/LibationWinForms/BookLiberation/AudioDecodeBaseForm.cs +++ b/LibationWinForms/BookLiberation/BaseForms/AudioDecodeBaseForm.cs @@ -18,6 +18,7 @@ namespace LibationWinForms.BookLiberation private string authorNames; private string narratorNames; + #region ProcessBaseForm overrides public override void SetProcessable(IStreamable streamProcessable, Action infoLog) { base.SetProcessable(streamProcessable, infoLog); @@ -30,21 +31,24 @@ namespace LibationWinForms.BookLiberation audioDecodable.TitleDiscovered += OnTitleDiscovered; audioDecodable.AuthorsDiscovered += OnAuthorsDiscovered; audioDecodable.NarratorsDiscovered += OnNarratorsDiscovered; - audioDecodable.CoverImageFilepathDiscovered += OnCoverImageFilepathDiscovered; + audioDecodable.CoverImageDiscovered += OnCoverImageDiscovered; Disposed += OnUnsubscribeAll; } + } + #endregion + private void OnUnsubscribeAll(object sender, EventArgs e) { Disposed -= OnUnsubscribeAll; - if (Streamable is not null && Streamable is IAudioDecodable audioDecodable) + if (Streamable is IAudioDecodable audioDecodable) { audioDecodable.RequestCoverArt -= OnRequestCoverArt; audioDecodable.TitleDiscovered -= OnTitleDiscovered; audioDecodable.AuthorsDiscovered -= OnAuthorsDiscovered; audioDecodable.NarratorsDiscovered -= OnNarratorsDiscovered; - audioDecodable.CoverImageFilepathDiscovered -= OnCoverImageFilepathDiscovered; + audioDecodable.CoverImageDiscovered -= OnCoverImageDiscovered; audioDecodable.Cancel(); } @@ -62,7 +66,7 @@ namespace LibationWinForms.BookLiberation OnTitleDiscovered(null, libraryBook.Book.Title); OnAuthorsDiscovered(null, string.Join(", ", libraryBook.Book.Authors)); OnNarratorsDiscovered(null, string.Join(", ", libraryBook.Book.NarratorNames)); - OnCoverImageFilepathDiscovered(null, + OnCoverImageDiscovered(null, FileManager.PictureStorage.GetPictureSynchronously( new FileManager.PictureDefinition( libraryBook.Book.PictureId, @@ -112,7 +116,7 @@ namespace LibationWinForms.BookLiberation 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)); #endregion diff --git a/LibationWinForms/BookLiberation/AudioDecodeBaseForm.resx b/LibationWinForms/BookLiberation/BaseForms/AudioDecodeBaseForm.resx similarity index 100% rename from LibationWinForms/BookLiberation/AudioDecodeBaseForm.resx rename to LibationWinForms/BookLiberation/BaseForms/AudioDecodeBaseForm.resx diff --git a/LibationWinForms/BookLiberation/ProcessBaseForm.cs b/LibationWinForms/BookLiberation/BaseForms/ProcessBaseForm.cs similarity index 94% rename from LibationWinForms/BookLiberation/ProcessBaseForm.cs rename to LibationWinForms/BookLiberation/BaseForms/ProcessBaseForm.cs index acd8b6bd..24d80acf 100644 --- a/LibationWinForms/BookLiberation/ProcessBaseForm.cs +++ b/LibationWinForms/BookLiberation/BaseForms/ProcessBaseForm.cs @@ -23,12 +23,13 @@ namespace LibationWinForms.BookLiberation processable.StatusUpdate += OnStatusUpdate; Disposed += OnUnsubscribeAll; } + } private void OnUnsubscribeAll(object sender, EventArgs e) { Disposed -= OnUnsubscribeAll; - if (Streamable is not null && Streamable is IProcessable processable) + if (Streamable is IProcessable processable) { processable.Begin -= OnBegin; processable.Completed -= OnCompleted; diff --git a/LibationWinForms/BookLiberation/StreamBaseForm.cs b/LibationWinForms/BookLiberation/BaseForms/StreamBaseForm.cs similarity index 55% rename from LibationWinForms/BookLiberation/StreamBaseForm.cs rename to LibationWinForms/BookLiberation/BaseForms/StreamBaseForm.cs index f6907131..e6cbde79 100644 --- a/LibationWinForms/BookLiberation/StreamBaseForm.cs +++ b/LibationWinForms/BookLiberation/BaseForms/StreamBaseForm.cs @@ -1,16 +1,25 @@ using Dinah.Core.Net.Http; +using Dinah.Core.Windows.Forms; using FileLiberator; using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; +using System.ComponentModel; +using System.Threading; using System.Windows.Forms; namespace LibationWinForms.BookLiberation { 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; } public void SetStreamable(IStreamable streamable) { @@ -39,14 +48,41 @@ namespace LibationWinForms.BookLiberation } #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 OnStreamingTimeRemaining(object sender, TimeSpan timeRemaining) { } public virtual void OnStreamingCompleted(object sender, string completedString) - { - Close(); - Dispose(); - } + => this.UIThread(() => + { + Close(); + Dispose(); + }); #endregion } } diff --git a/LibationWinForms/BookLiberation/PdfDownloadForm.resx b/LibationWinForms/BookLiberation/PdfDownloadForm.resx new file mode 100644 index 00000000..1af7de15 --- /dev/null +++ b/LibationWinForms/BookLiberation/PdfDownloadForm.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/LibationWinForms/BookLiberation/ProcessorAutomationController.cs b/LibationWinForms/BookLiberation/ProcessorAutomationController.cs index 8cbc11ba..d43613e1 100644 --- a/LibationWinForms/BookLiberation/ProcessorAutomationController.cs +++ b/LibationWinForms/BookLiberation/ProcessorAutomationController.cs @@ -1,7 +1,6 @@ using DataLayer; using Dinah.Core; using Dinah.Core.ErrorHandling; -using Dinah.Core.Windows.Forms; using FileLiberator; using System; using System.Linq; @@ -82,15 +81,15 @@ namespace LibationWinForms.BookLiberation var automatedBackupsForm = new AutomatedBackupsForm(); LogMe logMe = LogMe.RegisterForm(automatedBackupsForm); - var convertBook = CreateStreamableProcessable(null, logMe); + var convertBook = CreateStreamProcessable(null, logMe); await new BackupLoop(logMe, convertBook, automatedBackupsForm).RunBackupAsync(); } private static BackupBook CreateBackupBook(EventHandler completedAction, LogMe logMe) { - var downloadPdf = CreateStreamableProcessable(completedAction, logMe); - var downloadDecryptBook = CreateStreamableProcessable(completedAction, logMe); + var downloadPdf = CreateStreamProcessable(completedAction, logMe); + var downloadDecryptBook = CreateStreamProcessable(completedAction, logMe); return new BackupBook(downloadDecryptBook, downloadPdf); } @@ -101,34 +100,35 @@ namespace LibationWinForms.BookLiberation var automatedBackupsForm = new AutomatedBackupsForm(); LogMe logMe = LogMe.RegisterForm(automatedBackupsForm); - var downloadPdf = CreateStreamableProcessable(completedAction, logMe); + var downloadPdf = CreateStreamProcessable(completedAction, logMe); await new BackupLoop(logMe, downloadPdf, automatedBackupsForm).RunBackupAsync(); } 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(); - 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(OnCompleted); + + new System.Threading.Thread(() =>downloadFile.PerformDownloadFileAsync(url, destination).GetAwaiter().GetResult()) { IsBackground = true } .Start(); + } /// - /// Create a new and which creates a new on IProcessable.Begin. + /// Create a new and which creates a new on . /// /// The derrived type to create. - /// The derrived form to create on Begin - /// An additional event handler to handle .Completed + /// The derrived form to create on and and be Shown on + /// An additional event handler to handle /// A new of type - private static TStrProc CreateStreamableProcessable(EventHandler completedAction = null, LogMe logMe = null) + private static TStrProc CreateStreamProcessable(EventHandler completedAction = null, LogMe logMe = null) where TForm : ProcessBaseForm, new() where TStrProc : IStreamProcessable, new() { @@ -137,7 +137,8 @@ namespace LibationWinForms.BookLiberation strProc.Begin += (sender, libraryBook) => { var processForm = new TForm(); - processForm.SetProcessable(strProc, logMe.Info); + Action logAction = logMe is null ? (s) => { } : logMe.Info; + processForm.SetProcessable(strProc, logAction); processForm.OnBegin(sender, libraryBook); }; @@ -146,7 +147,14 @@ namespace LibationWinForms.BookLiberation return strProc; } - private static (TStrProc, TForm) CreateStreamable(EventHandler completedAction = null) + + /// + /// Creates a new and links it to a new + /// + /// The derrived type to create. + /// The derrived form to create, which will be Shown on . + /// An additional event handler to handle + private static (TStrProc, TForm) CreateStreamable(EventHandler completedAction = null) where TForm : StreamBaseForm, new() where TStrProc : IStreamable, new() { @@ -155,6 +163,9 @@ namespace LibationWinForms.BookLiberation var streamForm = new TForm(); streamForm.SetStreamable(strProc); + if (completedAction != null) + strProc.StreamingCompleted += completedAction; + return (strProc, streamForm); } } diff --git a/LibationWinForms/Form1.Designer.cs b/LibationWinForms/Form1.Designer.cs index ad89b4ef..bd26f759 100644 --- a/LibationWinForms/Form1.Designer.cs +++ b/LibationWinForms/Form1.Designer.cs @@ -61,7 +61,6 @@ this.backupsCountsLbl = new System.Windows.Forms.ToolStripStatusLabel(); this.pdfsCountsLbl = new System.Windows.Forms.ToolStripStatusLabel(); this.addFilterBtn = new System.Windows.Forms.Button(); - this.button1 = new System.Windows.Forms.Button(); this.menuStrip1.SuspendLayout(); this.statusStrip1.SuspendLayout(); this.SuspendLayout(); @@ -337,22 +336,11 @@ this.addFilterBtn.UseVisualStyleBackColor = true; 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 // this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.ClientSize = new System.Drawing.Size(1007, 539); - this.Controls.Add(this.button1); this.Controls.Add(this.filterBtn); this.Controls.Add(this.addFilterBtn); this.Controls.Add(this.filterSearchTb); @@ -410,6 +398,5 @@ private System.Windows.Forms.ToolStripMenuItem removeLibraryBooksToolStripMenuItem; private System.Windows.Forms.ToolStripMenuItem removeAllAccountsToolStripMenuItem; private System.Windows.Forms.ToolStripMenuItem removeSomeAccountsToolStripMenuItem; - private System.Windows.Forms.Button button1; } } diff --git a/LibationWinForms/Form1.cs b/LibationWinForms/Form1.cs index e9e0c350..7caaf420 100644 --- a/LibationWinForms/Form1.cs +++ b/LibationWinForms/Form1.cs @@ -496,12 +496,5 @@ namespace LibationWinForms private void basicSettingsToolStripMenuItem_Click(object sender, EventArgs e) => new SettingsDialog().ShowDialog(); #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"); - } } }