Merge branch 'rmcrackan:master' into master
This commit is contained in:
commit
41c4b12ae1
@ -1,34 +0,0 @@
|
|||||||
using System;
|
|
||||||
using DataLayer;
|
|
||||||
using LibationFileManager;
|
|
||||||
|
|
||||||
namespace LibationWinForms.BookLiberation
|
|
||||||
{
|
|
||||||
class AudioConvertForm : AudioDecodeForm
|
|
||||||
{
|
|
||||||
public AudioConvertForm()
|
|
||||||
{
|
|
||||||
this.Load += (_, _) => this.RestoreSizeAndLocation(Configuration.Instance);
|
|
||||||
this.FormClosing += (_, _) => this.SaveSizeAndLocation(Configuration.Instance);
|
|
||||||
}
|
|
||||||
|
|
||||||
#region AudioDecodeForm overrides
|
|
||||||
public override string DecodeActionName => "Converting";
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region Processable event handler overrides
|
|
||||||
public override void Processable_Begin(object sender, LibraryBook libraryBook)
|
|
||||||
{
|
|
||||||
LogMe.Info($"Convert Step, Begin: {libraryBook.Book}");
|
|
||||||
|
|
||||||
base.Processable_Begin(sender, libraryBook);
|
|
||||||
}
|
|
||||||
public override void Processable_Completed(object sender, LibraryBook libraryBook)
|
|
||||||
{
|
|
||||||
base.Processable_Completed(sender, libraryBook);
|
|
||||||
LogMe.Info($"Convert Step, Completed: {libraryBook.Book}{Environment.NewLine}");
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,61 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<root>
|
|
||||||
<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>
|
|
||||||
@ -1,104 +0,0 @@
|
|||||||
namespace LibationWinForms.BookLiberation
|
|
||||||
{
|
|
||||||
partial class AudioDecodeForm
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Required designer variable.
|
|
||||||
/// </summary>
|
|
||||||
private System.ComponentModel.IContainer components = null;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Clean up any resources being used.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
|
||||||
protected override void Dispose(bool disposing)
|
|
||||||
{
|
|
||||||
if (disposing && (components != null))
|
|
||||||
{
|
|
||||||
components.Dispose();
|
|
||||||
}
|
|
||||||
base.Dispose(disposing);
|
|
||||||
}
|
|
||||||
|
|
||||||
#region Windows Form Designer generated code
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Required method for Designer support - do not modify
|
|
||||||
/// the contents of this method with the code editor.
|
|
||||||
/// </summary>
|
|
||||||
private void InitializeComponent()
|
|
||||||
{
|
|
||||||
this.pictureBox1 = new System.Windows.Forms.PictureBox();
|
|
||||||
this.bookInfoLbl = new System.Windows.Forms.Label();
|
|
||||||
this.progressBar1 = new System.Windows.Forms.ProgressBar();
|
|
||||||
this.remainingTimeLbl = new System.Windows.Forms.Label();
|
|
||||||
((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).BeginInit();
|
|
||||||
this.SuspendLayout();
|
|
||||||
//
|
|
||||||
// pictureBox1
|
|
||||||
//
|
|
||||||
this.pictureBox1.Location = new System.Drawing.Point(14, 14);
|
|
||||||
this.pictureBox1.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
|
|
||||||
this.pictureBox1.Name = "pictureBox1";
|
|
||||||
this.pictureBox1.Size = new System.Drawing.Size(117, 115);
|
|
||||||
this.pictureBox1.SizeMode = System.Windows.Forms.PictureBoxSizeMode.StretchImage;
|
|
||||||
this.pictureBox1.TabIndex = 0;
|
|
||||||
this.pictureBox1.TabStop = false;
|
|
||||||
//
|
|
||||||
// bookInfoLbl
|
|
||||||
//
|
|
||||||
this.bookInfoLbl.AutoSize = true;
|
|
||||||
this.bookInfoLbl.Location = new System.Drawing.Point(138, 14);
|
|
||||||
this.bookInfoLbl.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
|
|
||||||
this.bookInfoLbl.Name = "bookInfoLbl";
|
|
||||||
this.bookInfoLbl.Size = new System.Drawing.Size(121, 15);
|
|
||||||
this.bookInfoLbl.TabIndex = 0;
|
|
||||||
this.bookInfoLbl.Text = "[multi-line book info]";
|
|
||||||
//
|
|
||||||
// progressBar1
|
|
||||||
//
|
|
||||||
this.progressBar1.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)
|
|
||||||
| System.Windows.Forms.AnchorStyles.Right)));
|
|
||||||
this.progressBar1.Location = new System.Drawing.Point(14, 143);
|
|
||||||
this.progressBar1.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
|
|
||||||
this.progressBar1.Name = "progressBar1";
|
|
||||||
this.progressBar1.Size = new System.Drawing.Size(611, 27);
|
|
||||||
this.progressBar1.TabIndex = 2;
|
|
||||||
//
|
|
||||||
// remainingTimeLbl
|
|
||||||
//
|
|
||||||
this.remainingTimeLbl.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
|
|
||||||
this.remainingTimeLbl.Location = new System.Drawing.Point(632, 143);
|
|
||||||
this.remainingTimeLbl.Name = "remainingTimeLbl";
|
|
||||||
this.remainingTimeLbl.Size = new System.Drawing.Size(60, 31);
|
|
||||||
this.remainingTimeLbl.TabIndex = 3;
|
|
||||||
this.remainingTimeLbl.Text = "ETA:\r\n";
|
|
||||||
this.remainingTimeLbl.TextAlign = System.Drawing.ContentAlignment.TopRight;
|
|
||||||
//
|
|
||||||
// DecryptForm
|
|
||||||
//
|
|
||||||
this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F);
|
|
||||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
|
||||||
this.ClientSize = new System.Drawing.Size(707, 183);
|
|
||||||
this.Controls.Add(this.remainingTimeLbl);
|
|
||||||
this.Controls.Add(this.progressBar1);
|
|
||||||
this.Controls.Add(this.bookInfoLbl);
|
|
||||||
this.Controls.Add(this.pictureBox1);
|
|
||||||
this.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
|
|
||||||
this.Name = "DecryptForm";
|
|
||||||
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
|
|
||||||
this.Text = "DecryptForm";
|
|
||||||
((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).EndInit();
|
|
||||||
this.ResumeLayout(false);
|
|
||||||
this.PerformLayout();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
private System.Windows.Forms.PictureBox pictureBox1;
|
|
||||||
private System.Windows.Forms.Label bookInfoLbl;
|
|
||||||
private System.Windows.Forms.ProgressBar progressBar1;
|
|
||||||
private System.Windows.Forms.Label remainingTimeLbl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,114 +0,0 @@
|
|||||||
using System;
|
|
||||||
using DataLayer;
|
|
||||||
using Dinah.Core.Net.Http;
|
|
||||||
using Dinah.Core.Threading;
|
|
||||||
using LibationFileManager;
|
|
||||||
using LibationWinForms.BookLiberation.BaseForms;
|
|
||||||
|
|
||||||
namespace LibationWinForms.BookLiberation
|
|
||||||
{
|
|
||||||
public partial class AudioDecodeForm : LiberationBaseForm
|
|
||||||
{
|
|
||||||
public virtual string DecodeActionName { get; } = "Decoding";
|
|
||||||
public AudioDecodeForm() => InitializeComponent();
|
|
||||||
|
|
||||||
private Func<byte[]> GetCoverArtDelegate;
|
|
||||||
|
|
||||||
#region Processable event handler overrides
|
|
||||||
public override void Processable_Begin(object sender, LibraryBook libraryBook)
|
|
||||||
{
|
|
||||||
base.Processable_Begin(sender, libraryBook);
|
|
||||||
|
|
||||||
GetCoverArtDelegate = () => PictureStorage.GetPictureSynchronously(
|
|
||||||
new PictureDefinition(
|
|
||||||
libraryBook.Book.PictureId,
|
|
||||||
PictureSize._500x500));
|
|
||||||
|
|
||||||
//Set default values from library
|
|
||||||
AudioDecodable_TitleDiscovered(sender, libraryBook.Book.Title);
|
|
||||||
AudioDecodable_AuthorsDiscovered(sender, libraryBook.Book.AuthorNames());
|
|
||||||
AudioDecodable_NarratorsDiscovered(sender, libraryBook.Book.NarratorNames());
|
|
||||||
AudioDecodable_CoverImageDiscovered(sender,
|
|
||||||
PictureStorage.GetPicture(
|
|
||||||
new PictureDefinition(
|
|
||||||
libraryBook.Book.PictureId,
|
|
||||||
PictureSize._80x80)).bytes);
|
|
||||||
}
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region Streamable event handler overrides
|
|
||||||
public override void Streamable_StreamingProgressChanged(object sender, DownloadProgress downloadProgress)
|
|
||||||
{
|
|
||||||
base.Streamable_StreamingProgressChanged(sender, downloadProgress);
|
|
||||||
if (!downloadProgress.ProgressPercentage.HasValue)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (downloadProgress.ProgressPercentage == 0)
|
|
||||||
updateRemainingTime(0);
|
|
||||||
else
|
|
||||||
progressBar1.UIThreadAsync(() => progressBar1.Value = (int)downloadProgress.ProgressPercentage);
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void Streamable_StreamingTimeRemaining(object sender, TimeSpan timeRemaining)
|
|
||||||
{
|
|
||||||
base.Streamable_StreamingTimeRemaining(sender, timeRemaining);
|
|
||||||
updateRemainingTime((int)timeRemaining.TotalSeconds);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void updateRemainingTime(int remaining)
|
|
||||||
=> remainingTimeLbl.UIThreadAsync(() => remainingTimeLbl.Text = $"ETA:\r\n{formatTime(remaining)}");
|
|
||||||
|
|
||||||
private string formatTime(int seconds)
|
|
||||||
{
|
|
||||||
var timeSpan = new TimeSpan(0, 0, seconds);
|
|
||||||
return
|
|
||||||
timeSpan.TotalHours >= 1 ? $"{timeSpan:%h}h {timeSpan:mm}m {timeSpan:ss}s"
|
|
||||||
: timeSpan.TotalMinutes >= 1 ? $"{timeSpan:%m}m {timeSpan:ss}s"
|
|
||||||
: $"{seconds} sec";
|
|
||||||
}
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region AudioDecodable event handlers
|
|
||||||
private string title;
|
|
||||||
private string authorNames;
|
|
||||||
private string narratorNames;
|
|
||||||
|
|
||||||
public override void AudioDecodable_TitleDiscovered(object sender, string title)
|
|
||||||
{
|
|
||||||
base.AudioDecodable_TitleDiscovered(sender, title);
|
|
||||||
this.UIThreadAsync(() => this.Text = DecodeActionName + " " + title);
|
|
||||||
this.title = title;
|
|
||||||
updateBookInfo();
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void AudioDecodable_AuthorsDiscovered(object sender, string authors)
|
|
||||||
{
|
|
||||||
base.AudioDecodable_AuthorsDiscovered(sender, authors);
|
|
||||||
authorNames = authors;
|
|
||||||
updateBookInfo();
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void AudioDecodable_NarratorsDiscovered(object sender, string narrators)
|
|
||||||
{
|
|
||||||
base.AudioDecodable_NarratorsDiscovered(sender, narrators);
|
|
||||||
narratorNames = narrators;
|
|
||||||
updateBookInfo();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void updateBookInfo()
|
|
||||||
=> bookInfoLbl.UIThreadAsync(() => bookInfoLbl.Text = $"{title}\r\nBy {authorNames}\r\nNarrated by {narratorNames}");
|
|
||||||
|
|
||||||
public override void AudioDecodable_RequestCoverArt(object sender, Action<byte[]> setCoverArtDelegate)
|
|
||||||
{
|
|
||||||
base.AudioDecodable_RequestCoverArt(sender, setCoverArtDelegate);
|
|
||||||
setCoverArtDelegate(GetCoverArtDelegate?.Invoke());
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void AudioDecodable_CoverImageDiscovered(object sender, byte[] coverArt)
|
|
||||||
{
|
|
||||||
base.AudioDecodable_CoverImageDiscovered(sender, coverArt);
|
|
||||||
pictureBox1.UIThreadAsync(() => pictureBox1.Image = Dinah.Core.Drawing.ImageReader.ToImage(coverArt));
|
|
||||||
}
|
|
||||||
#endregion
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,61 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<root>
|
|
||||||
<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>
|
|
||||||
@ -1,34 +0,0 @@
|
|||||||
using System;
|
|
||||||
using DataLayer;
|
|
||||||
using LibationFileManager;
|
|
||||||
|
|
||||||
namespace LibationWinForms.BookLiberation
|
|
||||||
{
|
|
||||||
class AudioDecryptForm : AudioDecodeForm
|
|
||||||
{
|
|
||||||
public AudioDecryptForm()
|
|
||||||
{
|
|
||||||
this.Load += (_, _) => this.RestoreSizeAndLocation(Configuration.Instance);
|
|
||||||
this.FormClosing += (_, _) => this.SaveSizeAndLocation(Configuration.Instance);
|
|
||||||
}
|
|
||||||
|
|
||||||
#region AudioDecodeForm overrides
|
|
||||||
public override string DecodeActionName => "Decrypting";
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region Processable event handler overrides
|
|
||||||
public override void Processable_Begin(object sender, LibraryBook libraryBook)
|
|
||||||
{
|
|
||||||
LogMe.Info($"Download & Decrypt Step, Begin: {libraryBook.Book}");
|
|
||||||
|
|
||||||
base.Processable_Begin(sender, libraryBook);
|
|
||||||
}
|
|
||||||
public override void Processable_Completed(object sender, LibraryBook libraryBook)
|
|
||||||
{
|
|
||||||
base.Processable_Completed(sender, libraryBook);
|
|
||||||
LogMe.Info($"Download & Decrypt Step, Completed: {libraryBook.Book}{Environment.NewLine}");
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,61 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<root>
|
|
||||||
<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>
|
|
||||||
@ -1,93 +0,0 @@
|
|||||||
namespace LibationWinForms.BookLiberation
|
|
||||||
{
|
|
||||||
partial class AutomatedBackupsForm
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Required designer variable.
|
|
||||||
/// </summary>
|
|
||||||
private System.ComponentModel.IContainer components = null;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Clean up any resources being used.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
|
||||||
protected override void Dispose(bool disposing)
|
|
||||||
{
|
|
||||||
if (disposing && (components != null))
|
|
||||||
{
|
|
||||||
components.Dispose();
|
|
||||||
}
|
|
||||||
base.Dispose(disposing);
|
|
||||||
}
|
|
||||||
|
|
||||||
#region Windows Form Designer generated code
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Required method for Designer support - do not modify
|
|
||||||
/// the contents of this method with the code editor.
|
|
||||||
/// </summary>
|
|
||||||
private void InitializeComponent()
|
|
||||||
{
|
|
||||||
this.keepGoingCb = new System.Windows.Forms.CheckBox();
|
|
||||||
this.logTb = new System.Windows.Forms.TextBox();
|
|
||||||
this.label1 = new System.Windows.Forms.Label();
|
|
||||||
this.SuspendLayout();
|
|
||||||
//
|
|
||||||
// keepGoingCb
|
|
||||||
//
|
|
||||||
this.keepGoingCb.AutoSize = true;
|
|
||||||
this.keepGoingCb.Checked = true;
|
|
||||||
this.keepGoingCb.CheckState = System.Windows.Forms.CheckState.Checked;
|
|
||||||
this.keepGoingCb.Location = new System.Drawing.Point(12, 12);
|
|
||||||
this.keepGoingCb.Name = "keepGoingCb";
|
|
||||||
this.keepGoingCb.Size = new System.Drawing.Size(325, 17);
|
|
||||||
this.keepGoingCb.TabIndex = 0;
|
|
||||||
this.keepGoingCb.Text = "Keep going. Uncheck to stop when current backup is complete";
|
|
||||||
this.keepGoingCb.UseVisualStyleBackColor = true;
|
|
||||||
//
|
|
||||||
// logTb
|
|
||||||
//
|
|
||||||
this.logTb.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
|
|
||||||
| System.Windows.Forms.AnchorStyles.Left)
|
|
||||||
| System.Windows.Forms.AnchorStyles.Right)));
|
|
||||||
this.logTb.Location = new System.Drawing.Point(12, 48);
|
|
||||||
this.logTb.Multiline = true;
|
|
||||||
this.logTb.Name = "logTb";
|
|
||||||
this.logTb.ReadOnly = true;
|
|
||||||
this.logTb.ScrollBars = System.Windows.Forms.ScrollBars.Both;
|
|
||||||
this.logTb.Size = new System.Drawing.Size(960, 202);
|
|
||||||
this.logTb.TabIndex = 1;
|
|
||||||
//
|
|
||||||
// label1
|
|
||||||
//
|
|
||||||
this.label1.AutoSize = true;
|
|
||||||
this.label1.Location = new System.Drawing.Point(9, 32);
|
|
||||||
this.label1.Name = "label1";
|
|
||||||
this.label1.Size = new System.Drawing.Size(501, 13);
|
|
||||||
this.label1.TabIndex = 2;
|
|
||||||
this.label1.Text = "NOTE: if the working directories are inside of Dropbox, some book liberation acti" +
|
|
||||||
"ons may hang indefinitely";
|
|
||||||
//
|
|
||||||
// AutomatedBackupsForm
|
|
||||||
//
|
|
||||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
|
||||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
|
||||||
this.ClientSize = new System.Drawing.Size(984, 262);
|
|
||||||
this.Controls.Add(this.label1);
|
|
||||||
this.Controls.Add(this.logTb);
|
|
||||||
this.Controls.Add(this.keepGoingCb);
|
|
||||||
this.Name = "AutomatedBackupsForm";
|
|
||||||
this.Text = "Automated Backups";
|
|
||||||
this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.AutomatedBackupsForm_FormClosing);
|
|
||||||
this.ResumeLayout(false);
|
|
||||||
this.PerformLayout();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
private System.Windows.Forms.CheckBox keepGoingCb;
|
|
||||||
private System.Windows.Forms.TextBox logTb;
|
|
||||||
private System.Windows.Forms.Label label1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,38 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Windows.Forms;
|
|
||||||
using Dinah.Core.Threading;
|
|
||||||
|
|
||||||
namespace LibationWinForms.BookLiberation
|
|
||||||
{
|
|
||||||
public interface ILogForm
|
|
||||||
{
|
|
||||||
void WriteLine(string text);
|
|
||||||
}
|
|
||||||
public partial class AutomatedBackupsForm : Form, ILogForm
|
|
||||||
{
|
|
||||||
public bool KeepGoingChecked => keepGoingCb.Checked;
|
|
||||||
|
|
||||||
public bool KeepGoing => keepGoingCb.Enabled && keepGoingCb.Checked;
|
|
||||||
|
|
||||||
public AutomatedBackupsForm()
|
|
||||||
{
|
|
||||||
InitializeComponent();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void WriteLine(string text)
|
|
||||||
{
|
|
||||||
if (!IsDisposed)
|
|
||||||
logTb.UIThreadAsync(() => logTb.AppendText($"{DateTime.Now} {text}{Environment.NewLine}"));
|
|
||||||
}
|
|
||||||
|
|
||||||
public void FinalizeUI()
|
|
||||||
{
|
|
||||||
keepGoingCb.Enabled = false;
|
|
||||||
|
|
||||||
if (!IsDisposed)
|
|
||||||
logTb.AppendText("");
|
|
||||||
}
|
|
||||||
|
|
||||||
private void AutomatedBackupsForm_FormClosing(object sender, FormClosingEventArgs e) => keepGoingCb.Checked = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,61 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<root>
|
|
||||||
<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>
|
|
||||||
9
Source/LibationWinForms/BookLiberation/ILogForm.cs
Normal file
9
Source/LibationWinForms/BookLiberation/ILogForm.cs
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
|
namespace LibationWinForms.BookLiberation
|
||||||
|
{
|
||||||
|
public interface ILogForm
|
||||||
|
{
|
||||||
|
void WriteLine(string text);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,18 +0,0 @@
|
|||||||
using DataLayer;
|
|
||||||
|
|
||||||
namespace LibationWinForms.BookLiberation
|
|
||||||
{
|
|
||||||
internal class PdfDownloadForm : DownloadForm
|
|
||||||
{
|
|
||||||
public override void Processable_Begin(object sender, LibraryBook libraryBook)
|
|
||||||
{
|
|
||||||
base.Processable_Begin(sender, libraryBook);
|
|
||||||
LogMe.Info($"PDF Step, Begin: {libraryBook.Book}");
|
|
||||||
}
|
|
||||||
public override void Processable_Completed(object sender, LibraryBook libraryBook)
|
|
||||||
{
|
|
||||||
base.Processable_Completed(sender, libraryBook);
|
|
||||||
LogMe.Info($"PDF Step, Completed: {libraryBook.Book}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,61 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<root>
|
|
||||||
<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>
|
|
||||||
@ -3,11 +3,7 @@ using System.Collections.Generic;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using System.Windows.Forms;
|
using System.Windows.Forms;
|
||||||
using DataLayer;
|
|
||||||
using Dinah.Core;
|
|
||||||
using FileLiberator;
|
using FileLiberator;
|
||||||
using LibationFileManager;
|
|
||||||
using LibationWinForms.BookLiberation.BaseForms;
|
|
||||||
|
|
||||||
namespace LibationWinForms.BookLiberation
|
namespace LibationWinForms.BookLiberation
|
||||||
{
|
{
|
||||||
@ -25,7 +21,6 @@ namespace LibationWinForms.BookLiberation
|
|||||||
LogError += (_, tuple) => Serilog.Log.Logger.Error(tuple.Item1, tuple.Item2 ?? "Automated backup: error");
|
LogError += (_, tuple) => Serilog.Log.Logger.Error(tuple.Item1, tuple.Item2 ?? "Automated backup: error");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static LogMe RegisterForm() => RegisterForm<ILogForm>(null);
|
|
||||||
public static LogMe RegisterForm<T>(T form) where T : ILogForm
|
public static LogMe RegisterForm<T>(T form) where T : ILogForm
|
||||||
{
|
{
|
||||||
var logMe = new LogMe();
|
var logMe = new LogMe();
|
||||||
@ -53,66 +48,6 @@ namespace LibationWinForms.BookLiberation
|
|||||||
|
|
||||||
public static class ProcessorAutomationController
|
public static class ProcessorAutomationController
|
||||||
{
|
{
|
||||||
public static async Task BackupSingleBookAsync(LibraryBook libraryBook)
|
|
||||||
{
|
|
||||||
Serilog.Log.Logger.Information($"Begin {nameof(BackupSingleBookAsync)} {{@DebugInfo}}", new { libraryBook?.Book?.AudibleProductId });
|
|
||||||
|
|
||||||
var logMe = LogMe.RegisterForm();
|
|
||||||
var backupBook = CreateBackupBook(logMe);
|
|
||||||
|
|
||||||
// continue even if libraryBook is null. we'll display even that in the processing box
|
|
||||||
await new BackupSingle(logMe, backupBook, libraryBook).RunBackupAsync();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static async Task BackupAllBooksAsync(List<LibraryBook> libraryBooks = null)
|
|
||||||
{
|
|
||||||
Serilog.Log.Logger.Information("Begin " + nameof(BackupAllBooksAsync));
|
|
||||||
|
|
||||||
var automatedBackupsForm = new AutomatedBackupsForm();
|
|
||||||
var logMe = LogMe.RegisterForm(automatedBackupsForm);
|
|
||||||
var backupBook = CreateBackupBook(logMe);
|
|
||||||
|
|
||||||
await new BackupLoop(logMe, backupBook, automatedBackupsForm, libraryBooks).RunBackupAsync();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static async Task ConvertAllBooksAsync()
|
|
||||||
{
|
|
||||||
Serilog.Log.Logger.Information("Begin " + nameof(ConvertAllBooksAsync));
|
|
||||||
|
|
||||||
var automatedBackupsForm = new AutomatedBackupsForm();
|
|
||||||
var logMe = LogMe.RegisterForm(automatedBackupsForm);
|
|
||||||
|
|
||||||
var convertBook = CreateProcessable<ConvertToMp3, AudioConvertForm>(logMe);
|
|
||||||
|
|
||||||
await new BackupLoop(logMe, convertBook, automatedBackupsForm).RunBackupAsync();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static async Task BackupAllPdfsAsync()
|
|
||||||
{
|
|
||||||
Serilog.Log.Logger.Information("Begin " + nameof(BackupAllPdfsAsync));
|
|
||||||
|
|
||||||
var automatedBackupsForm = new AutomatedBackupsForm();
|
|
||||||
var logMe = LogMe.RegisterForm(automatedBackupsForm);
|
|
||||||
|
|
||||||
var downloadPdf = CreateProcessable<DownloadPdf, PdfDownloadForm>(logMe);
|
|
||||||
|
|
||||||
await new BackupLoop(logMe, downloadPdf, automatedBackupsForm).RunBackupAsync();
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Processable CreateBackupBook(LogMe logMe)
|
|
||||||
{
|
|
||||||
var downloadPdf = CreateProcessable<DownloadPdf, PdfDownloadForm>(logMe);
|
|
||||||
|
|
||||||
//Chain pdf download on DownloadDecryptBook.Completed
|
|
||||||
async void onDownloadDecryptBookCompleted(object sender, LibraryBook e)
|
|
||||||
{
|
|
||||||
await downloadPdf.TryProcessAsync(e);
|
|
||||||
}
|
|
||||||
|
|
||||||
var downloadDecryptBook = CreateProcessable<DownloadDecryptBook, AudioDecryptForm>(logMe, onDownloadDecryptBookCompleted);
|
|
||||||
return downloadDecryptBook;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void DownloadFile(string url, string destination, bool showDownloadCompletedDialog = false)
|
public static void DownloadFile(string url, string destination, bool showDownloadCompletedDialog = false)
|
||||||
{
|
{
|
||||||
Serilog.Log.Logger.Information($"Begin {nameof(DownloadFile)} for {url}");
|
Serilog.Log.Logger.Information($"Begin {nameof(DownloadFile)} for {url}");
|
||||||
@ -133,212 +68,5 @@ namespace LibationWinForms.BookLiberation
|
|||||||
async void runDownload() => await downloadFile.PerformDownloadFileAsync(url, destination);
|
async void runDownload() => await downloadFile.PerformDownloadFileAsync(url, destination);
|
||||||
new Task(runDownload).Start();
|
new Task(runDownload).Start();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Create a new <see cref="Processable"/> and links it to a new <see cref="LiberationBaseForm"/>.
|
|
||||||
/// </summary>
|
|
||||||
/// <typeparam name="TProcessable">The <see cref="Processable"/> derived type to create.</typeparam>
|
|
||||||
/// <typeparam name="TForm">The <see cref="LiberationBaseForm"/> derived Form to create on <see cref="Processable.Begin"/>, Show on <see cref="Streamable.StreamingBegin"/>, Close on <see cref="Streamable.StreamingCompleted"/>, and Dispose on <see cref="Processable.Completed"/> </typeparam>
|
|
||||||
/// <param name="logMe">The logger</param>
|
|
||||||
/// <param name="completedAction">An additional event handler to handle <see cref="Processable.Completed"/></param>
|
|
||||||
/// <returns>A new <see cref="Processable"/> of type <typeparamref name="TProcessable"/></returns>
|
|
||||||
private static TProcessable CreateProcessable<TProcessable, TForm>(LogMe logMe, EventHandler<LibraryBook> completedAction = null)
|
|
||||||
where TForm : LiberationBaseForm, new()
|
|
||||||
where TProcessable : Processable, new()
|
|
||||||
{
|
|
||||||
var strProc = new TProcessable();
|
|
||||||
|
|
||||||
strProc.Begin += (sender, libraryBook) =>
|
|
||||||
{
|
|
||||||
var processForm = new TForm();
|
|
||||||
processForm.RegisterFileLiberator(strProc, logMe);
|
|
||||||
processForm.Processable_Begin(sender, libraryBook);
|
|
||||||
};
|
|
||||||
|
|
||||||
strProc.Completed += completedAction;
|
|
||||||
|
|
||||||
return strProc;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
internal abstract class BackupRunner
|
|
||||||
{
|
|
||||||
protected LogMe LogMe { get; }
|
|
||||||
protected Processable Processable { get; }
|
|
||||||
protected AutomatedBackupsForm AutomatedBackupsForm { get; }
|
|
||||||
|
|
||||||
protected BackupRunner(LogMe logMe, Processable processable, AutomatedBackupsForm automatedBackupsForm = null)
|
|
||||||
{
|
|
||||||
LogMe = logMe;
|
|
||||||
Processable = processable;
|
|
||||||
AutomatedBackupsForm = automatedBackupsForm;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected abstract Task RunAsync();
|
|
||||||
protected abstract string SkipDialogText { get; }
|
|
||||||
protected abstract MessageBoxButtons SkipDialogButtons { get; }
|
|
||||||
protected abstract MessageBoxDefaultButton SkipDialogDefaultButton { get; }
|
|
||||||
protected abstract DialogResult SkipResult { get; }
|
|
||||||
|
|
||||||
public async Task RunBackupAsync()
|
|
||||||
{
|
|
||||||
AutomatedBackupsForm?.Show();
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
await RunAsync();
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
LogMe.Error(ex);
|
|
||||||
}
|
|
||||||
|
|
||||||
AutomatedBackupsForm?.FinalizeUI();
|
|
||||||
LogMe.Info("DONE");
|
|
||||||
}
|
|
||||||
|
|
||||||
protected async Task<bool> ProcessOneAsync(LibraryBook libraryBook, bool validate)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
var statusHandler = await Processable.ProcessSingleAsync(libraryBook, validate);
|
|
||||||
|
|
||||||
if (statusHandler.IsSuccess)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
foreach (var errorMessage in statusHandler.Errors)
|
|
||||||
LogMe.Error(errorMessage);
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
LogMe.Error(ex);
|
|
||||||
}
|
|
||||||
|
|
||||||
return showRetry(libraryBook);
|
|
||||||
}
|
|
||||||
|
|
||||||
private bool showRetry(LibraryBook libraryBook)
|
|
||||||
{
|
|
||||||
LogMe.Error("ERROR. All books have not been processed. Most recent book: processing failed");
|
|
||||||
|
|
||||||
DialogResult? dialogResult = Configuration.Instance.BadBook switch
|
|
||||||
{
|
|
||||||
Configuration.BadBookAction.Abort => DialogResult.Abort,
|
|
||||||
Configuration.BadBookAction.Retry => DialogResult.Retry,
|
|
||||||
Configuration.BadBookAction.Ignore => DialogResult.Ignore,
|
|
||||||
Configuration.BadBookAction.Ask => null,
|
|
||||||
_ => null
|
|
||||||
};
|
|
||||||
|
|
||||||
string details;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
static string trunc(string str)
|
|
||||||
=> string.IsNullOrWhiteSpace(str) ? "[empty]"
|
|
||||||
: (str.Length > 50) ? $"{str.Truncate(47)}..."
|
|
||||||
: str;
|
|
||||||
|
|
||||||
details =
|
|
||||||
$@" Title: {libraryBook.Book.Title}
|
|
||||||
ID: {libraryBook.Book.AudibleProductId}
|
|
||||||
Author: {trunc(libraryBook.Book.AuthorNames())}
|
|
||||||
Narr: {trunc(libraryBook.Book.NarratorNames())}";
|
|
||||||
}
|
|
||||||
catch
|
|
||||||
{
|
|
||||||
details = "[Error retrieving details]";
|
|
||||||
}
|
|
||||||
|
|
||||||
// if null then ask user
|
|
||||||
dialogResult ??= MessageBox.Show(string.Format(SkipDialogText + "\r\n\r\nSee Settings to avoid this box in the future.", details), "Skip importing this book?", SkipDialogButtons, MessageBoxIcon.Question, SkipDialogDefaultButton);
|
|
||||||
|
|
||||||
if (dialogResult == DialogResult.Abort)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (dialogResult == SkipResult)
|
|
||||||
{
|
|
||||||
libraryBook.Book.UserDefinedItem.BookStatus = LiberatedStatus.Error;
|
|
||||||
ApplicationServices.LibraryCommands.UpdateUserDefinedItem(libraryBook.Book);
|
|
||||||
|
|
||||||
LogMe.Info($"Error. Skip: [{libraryBook.Book.AudibleProductId}] {libraryBook.Book.Title}");
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
internal class BackupSingle : BackupRunner
|
|
||||||
{
|
|
||||||
private LibraryBook _libraryBook { get; }
|
|
||||||
|
|
||||||
protected override string SkipDialogText => @"
|
|
||||||
An error occurred while trying to process this book. Skip this book permanently?
|
|
||||||
{0}
|
|
||||||
|
|
||||||
- Click YES to skip this book permanently.
|
|
||||||
|
|
||||||
- Click NO to skip the book this time only. We'll try again later.
|
|
||||||
".Trim();
|
|
||||||
protected override MessageBoxButtons SkipDialogButtons => MessageBoxButtons.YesNo;
|
|
||||||
protected override MessageBoxDefaultButton SkipDialogDefaultButton => MessageBoxDefaultButton.Button2;
|
|
||||||
protected override DialogResult SkipResult => DialogResult.Yes;
|
|
||||||
|
|
||||||
public BackupSingle(LogMe logMe, Processable processable, LibraryBook libraryBook)
|
|
||||||
: base(logMe, processable)
|
|
||||||
{
|
|
||||||
_libraryBook = libraryBook;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override async Task RunAsync()
|
|
||||||
{
|
|
||||||
if (_libraryBook is not null)
|
|
||||||
await ProcessOneAsync(_libraryBook, validate: true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
internal class BackupLoop : BackupRunner
|
|
||||||
{
|
|
||||||
protected override string SkipDialogText => @"
|
|
||||||
An error occurred while trying to process this book.
|
|
||||||
{0}
|
|
||||||
|
|
||||||
- ABORT: Stop processing books.
|
|
||||||
|
|
||||||
- RETRY: retry this book later. Just skip it for now. Continue processing books. (Will try this book again later.)
|
|
||||||
|
|
||||||
- IGNORE: Permanently ignore this book. Continue processing books. (Will not try this book again later.)
|
|
||||||
".Trim();
|
|
||||||
protected override MessageBoxButtons SkipDialogButtons => MessageBoxButtons.AbortRetryIgnore;
|
|
||||||
protected override MessageBoxDefaultButton SkipDialogDefaultButton => MessageBoxDefaultButton.Button1;
|
|
||||||
protected override DialogResult SkipResult => DialogResult.Ignore;
|
|
||||||
|
|
||||||
private List<LibraryBook> libraryBooks { get; }
|
|
||||||
|
|
||||||
public BackupLoop(LogMe logMe, Processable processable, AutomatedBackupsForm automatedBackupsForm, List<LibraryBook> libraryBooks = null)
|
|
||||||
: base(logMe, processable, automatedBackupsForm)
|
|
||||||
=> this.libraryBooks = libraryBooks ?? ApplicationServices.DbContexts.GetLibrary_Flat_NoTracking();
|
|
||||||
|
|
||||||
protected override async Task RunAsync()
|
|
||||||
{
|
|
||||||
// support for 'skip this time only' requires state. iterators provide this state for free. therefore: use foreach/iterator here
|
|
||||||
foreach (var libraryBook in Processable.GetValidLibraryBooks(libraryBooks))
|
|
||||||
{
|
|
||||||
var keepGoing = await ProcessOneAsync(libraryBook, validate: false);
|
|
||||||
if (!keepGoing)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (AutomatedBackupsForm.IsDisposed)
|
|
||||||
break;
|
|
||||||
|
|
||||||
if (!AutomatedBackupsForm.KeepGoing)
|
|
||||||
{
|
|
||||||
if (!AutomatedBackupsForm.KeepGoingChecked)
|
|
||||||
LogMe.Info("'Keep going' is unchecked");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
LogMe.Info("Done. All books have been processed");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -6,16 +6,14 @@ namespace LibationWinForms
|
|||||||
{
|
{
|
||||||
public partial class Form1
|
public partial class Form1
|
||||||
{
|
{
|
||||||
private string beginBookBackupsToolStripMenuItem_format;
|
|
||||||
private string beginPdfBackupsToolStripMenuItem_format;
|
|
||||||
|
|
||||||
protected void Configure_BackupCounts()
|
protected void Configure_BackupCounts()
|
||||||
{
|
{
|
||||||
// back up string formats
|
// init formattable
|
||||||
beginBookBackupsToolStripMenuItem_format = beginBookBackupsToolStripMenuItem.Text;
|
beginBookBackupsToolStripMenuItem.Format(0);
|
||||||
beginPdfBackupsToolStripMenuItem_format = beginPdfBackupsToolStripMenuItem.Text;
|
beginPdfBackupsToolStripMenuItem.Format(0);
|
||||||
|
pdfsCountsLbl.Text = "| [Calculating backed up PDFs]";
|
||||||
|
|
||||||
Load += setBackupCounts;
|
Load += setBackupCounts;
|
||||||
LibraryCommands.LibrarySizeChanged += setBackupCounts;
|
LibraryCommands.LibrarySizeChanged += setBackupCounts;
|
||||||
LibraryCommands.BookUserDefinedItemCommitted += setBackupCounts;
|
LibraryCommands.BookUserDefinedItemCommitted += setBackupCounts;
|
||||||
}
|
}
|
||||||
@ -56,54 +54,72 @@ namespace LibationWinForms
|
|||||||
setPdfBackupCounts(libraryStats);
|
setPdfBackupCounts(libraryStats);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// this cannot be cleanly be FormattableToolStripMenuItem because of the optional "Errors" text
|
||||||
|
private const string backupsCountsLbl_Format = "BACKUPS: No progress: {0} In process: {1} Fully backed up: {2}";
|
||||||
|
|
||||||
private void setBookBackupCounts(LibraryCommands.LibraryStats libraryStats)
|
private void setBookBackupCounts(LibraryCommands.LibraryStats libraryStats)
|
||||||
{
|
{
|
||||||
var backupsCountsLbl_Format = "BACKUPS: No progress: {0} In process: {1} Fully backed up: {2}";
|
var pending = libraryStats.booksNoProgress + libraryStats.booksDownloadedOnly;
|
||||||
|
var hasResults = 0 < (libraryStats.booksFullyBackedUp + libraryStats.booksDownloadedOnly + libraryStats.booksNoProgress + libraryStats.booksError);
|
||||||
|
|
||||||
// enable/disable export
|
// enable/disable export
|
||||||
var hasResults = 0 < (libraryStats.booksFullyBackedUp + libraryStats.booksDownloadedOnly + libraryStats.booksNoProgress + libraryStats.booksError);
|
{
|
||||||
exportLibraryToolStripMenuItem.Enabled = hasResults;
|
exportLibraryToolStripMenuItem.Enabled = hasResults;
|
||||||
|
}
|
||||||
|
|
||||||
// update bottom numbers
|
// update bottom numbers
|
||||||
var pending = libraryStats.booksNoProgress + libraryStats.booksDownloadedOnly;
|
{
|
||||||
var statusStripText
|
var formatString
|
||||||
= !hasResults ? "No books. Begin by importing your library"
|
= !hasResults ? "No books. Begin by importing your library"
|
||||||
: libraryStats.booksError > 0 ? string.Format(backupsCountsLbl_Format + " Errors: {3}", libraryStats.booksNoProgress, libraryStats.booksDownloadedOnly, libraryStats.booksFullyBackedUp, libraryStats.booksError)
|
: libraryStats.booksError > 0 ? backupsCountsLbl_Format + " Errors: {3}"
|
||||||
: pending > 0 ? string.Format(backupsCountsLbl_Format, libraryStats.booksNoProgress, libraryStats.booksDownloadedOnly, libraryStats.booksFullyBackedUp)
|
: pending > 0 ? backupsCountsLbl_Format
|
||||||
: $"All {"book".PluralizeWithCount(libraryStats.booksFullyBackedUp)} backed up";
|
: $"All {"book".PluralizeWithCount(libraryStats.booksFullyBackedUp)} backed up";
|
||||||
|
var statusStripText = string.Format(formatString,
|
||||||
|
libraryStats.booksNoProgress,
|
||||||
|
libraryStats.booksDownloadedOnly,
|
||||||
|
libraryStats.booksFullyBackedUp,
|
||||||
|
libraryStats.booksError);
|
||||||
|
statusStrip1.UIThreadAsync(() => backupsCountsLbl.Text = statusStripText);
|
||||||
|
}
|
||||||
|
|
||||||
// update menu item
|
// update 'begin book backups' menu item
|
||||||
var menuItemText
|
{
|
||||||
= pending > 0
|
var menuItemText
|
||||||
? $"{pending} remaining"
|
= pending > 0
|
||||||
: "All books have been liberated";
|
? $"{pending} remaining"
|
||||||
|
: "All books have been liberated";
|
||||||
// update UI
|
menuStrip1.UIThreadAsync(() =>
|
||||||
statusStrip1.UIThreadAsync(() => backupsCountsLbl.Text = statusStripText);
|
{
|
||||||
menuStrip1.UIThreadAsync(() => beginBookBackupsToolStripMenuItem.Enabled = pending > 0);
|
beginBookBackupsToolStripMenuItem.Format(menuItemText);
|
||||||
menuStrip1.UIThreadAsync(() => beginBookBackupsToolStripMenuItem.Text = string.Format(beginBookBackupsToolStripMenuItem_format, menuItemText));
|
beginBookBackupsToolStripMenuItem.Enabled = pending > 0;
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
private void setPdfBackupCounts(LibraryCommands.LibraryStats libraryStats)
|
private void setPdfBackupCounts(LibraryCommands.LibraryStats libraryStats)
|
||||||
{
|
{
|
||||||
var pdfsCountsLbl_Format = "| PDFs: NOT d/l\'ed: {0} Downloaded: {1}";
|
|
||||||
|
|
||||||
// update bottom numbers
|
// update bottom numbers
|
||||||
var hasResults = 0 < (libraryStats.pdfsNotDownloaded + libraryStats.pdfsDownloaded);
|
{
|
||||||
var statusStripText
|
var hasResults = 0 < (libraryStats.pdfsNotDownloaded + libraryStats.pdfsDownloaded);
|
||||||
= !hasResults ? ""
|
// don't need to assign the output of Format(). It just makes this logic cleaner
|
||||||
: libraryStats.pdfsNotDownloaded > 0 ? string.Format(pdfsCountsLbl_Format, libraryStats.pdfsNotDownloaded, libraryStats.pdfsDownloaded)
|
var statusStripText
|
||||||
: $"| All {libraryStats.pdfsDownloaded} PDFs downloaded";
|
= !hasResults ? ""
|
||||||
|
: libraryStats.pdfsNotDownloaded > 0 ? pdfsCountsLbl.Format(libraryStats.pdfsNotDownloaded, libraryStats.pdfsDownloaded)
|
||||||
|
: $"| All {libraryStats.pdfsDownloaded} PDFs downloaded";
|
||||||
|
statusStrip1.UIThreadAsync(() => pdfsCountsLbl.Text = statusStripText);
|
||||||
|
}
|
||||||
|
|
||||||
// update menu item
|
// update 'begin pdf only backups' menu item
|
||||||
var menuItemText
|
{
|
||||||
= libraryStats.pdfsNotDownloaded > 0
|
var menuItemText
|
||||||
? $"{libraryStats.pdfsNotDownloaded} remaining"
|
= libraryStats.pdfsNotDownloaded > 0
|
||||||
: "All PDFs have been downloaded";
|
? $"{libraryStats.pdfsNotDownloaded} remaining"
|
||||||
|
: "All PDFs have been downloaded";
|
||||||
// update UI
|
menuStrip1.UIThreadAsync(() =>
|
||||||
statusStrip1.UIThreadAsync(() => pdfsCountsLbl.Text = statusStripText);
|
{
|
||||||
menuStrip1.UIThreadAsync(() => beginPdfBackupsToolStripMenuItem.Enabled = libraryStats.pdfsNotDownloaded > 0);
|
beginPdfBackupsToolStripMenuItem.Format(menuItemText);
|
||||||
menuStrip1.UIThreadAsync(() => beginPdfBackupsToolStripMenuItem.Text = string.Format(beginPdfBackupsToolStripMenuItem_format, menuItemText));
|
beginPdfBackupsToolStripMenuItem.Enabled = libraryStats.pdfsNotDownloaded > 0;
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
32
Source/LibationWinForms/Form1.Designer.cs
generated
32
Source/LibationWinForms/Form1.Designer.cs
generated
@ -44,10 +44,10 @@
|
|||||||
this.removeAllAccountsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
this.removeAllAccountsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||||
this.removeSomeAccountsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
this.removeSomeAccountsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||||
this.liberateToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
this.liberateToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||||
this.beginBookBackupsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
this.beginBookBackupsToolStripMenuItem = new LibationWinForms.FormattableToolStripMenuItem();
|
||||||
this.beginPdfBackupsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
this.beginPdfBackupsToolStripMenuItem = new LibationWinForms.FormattableToolStripMenuItem();
|
||||||
this.convertAllM4bToMp3ToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
this.convertAllM4bToMp3ToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||||
this.liberateVisible2ToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
this.liberateVisible2ToolStripMenuItem = new LibationWinForms.FormattableToolStripMenuItem();
|
||||||
this.exportToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
this.exportToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||||
this.exportLibraryToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
this.exportLibraryToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||||
this.quickFiltersToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
this.quickFiltersToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||||
@ -55,8 +55,8 @@
|
|||||||
this.editQuickFiltersToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
this.editQuickFiltersToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||||
this.toolStripSeparator1 = new System.Windows.Forms.ToolStripSeparator();
|
this.toolStripSeparator1 = new System.Windows.Forms.ToolStripSeparator();
|
||||||
this.scanningToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
this.scanningToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||||
this.visibleBooksToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
this.visibleBooksToolStripMenuItem = new LibationWinForms.FormattableToolStripMenuItem();
|
||||||
this.liberateVisibleToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
this.liberateVisibleToolStripMenuItem = new LibationWinForms.FormattableToolStripMenuItem();
|
||||||
this.replaceTagsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
this.replaceTagsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||||
this.setDownloadedToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
this.setDownloadedToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||||
this.removeToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
this.removeToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||||
@ -66,10 +66,10 @@
|
|||||||
this.toolStripSeparator2 = new System.Windows.Forms.ToolStripSeparator();
|
this.toolStripSeparator2 = new System.Windows.Forms.ToolStripSeparator();
|
||||||
this.aboutToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
this.aboutToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||||
this.statusStrip1 = new System.Windows.Forms.StatusStrip();
|
this.statusStrip1 = new System.Windows.Forms.StatusStrip();
|
||||||
this.visibleCountLbl = new System.Windows.Forms.ToolStripStatusLabel();
|
this.visibleCountLbl = new LibationWinForms.FormattableToolStripStatusLabel();
|
||||||
this.springLbl = new System.Windows.Forms.ToolStripStatusLabel();
|
this.springLbl = new System.Windows.Forms.ToolStripStatusLabel();
|
||||||
this.backupsCountsLbl = new System.Windows.Forms.ToolStripStatusLabel();
|
this.backupsCountsLbl = new System.Windows.Forms.ToolStripStatusLabel();
|
||||||
this.pdfsCountsLbl = new System.Windows.Forms.ToolStripStatusLabel();
|
this.pdfsCountsLbl = new LibationWinForms.FormattableToolStripStatusLabel();
|
||||||
this.addQuickFilterBtn = new System.Windows.Forms.Button();
|
this.addQuickFilterBtn = new System.Windows.Forms.Button();
|
||||||
this.splitContainer1 = new System.Windows.Forms.SplitContainer();
|
this.splitContainer1 = new System.Windows.Forms.SplitContainer();
|
||||||
this.panel1 = new System.Windows.Forms.Panel();
|
this.panel1 = new System.Windows.Forms.Panel();
|
||||||
@ -407,7 +407,7 @@
|
|||||||
//
|
//
|
||||||
this.visibleCountLbl.Name = "visibleCountLbl";
|
this.visibleCountLbl.Name = "visibleCountLbl";
|
||||||
this.visibleCountLbl.Size = new System.Drawing.Size(68, 20);
|
this.visibleCountLbl.Size = new System.Drawing.Size(68, 20);
|
||||||
this.visibleCountLbl.Text = "Visible: 0";
|
this.visibleCountLbl.Text = "Visible: {0}";
|
||||||
//
|
//
|
||||||
// springLbl
|
// springLbl
|
||||||
//
|
//
|
||||||
@ -425,7 +425,7 @@
|
|||||||
//
|
//
|
||||||
this.pdfsCountsLbl.Name = "pdfsCountsLbl";
|
this.pdfsCountsLbl.Name = "pdfsCountsLbl";
|
||||||
this.pdfsCountsLbl.Size = new System.Drawing.Size(214, 20);
|
this.pdfsCountsLbl.Size = new System.Drawing.Size(214, 20);
|
||||||
this.pdfsCountsLbl.Text = "| [Calculating backed up PDFs]";
|
this.pdfsCountsLbl.Text = "| PDFs: NOT d/l\'ed: {0} Downloaded: {1}";
|
||||||
//
|
//
|
||||||
// addQuickFilterBtn
|
// addQuickFilterBtn
|
||||||
//
|
//
|
||||||
@ -531,12 +531,12 @@
|
|||||||
private System.Windows.Forms.ToolStripMenuItem importToolStripMenuItem;
|
private System.Windows.Forms.ToolStripMenuItem importToolStripMenuItem;
|
||||||
private System.Windows.Forms.StatusStrip statusStrip1;
|
private System.Windows.Forms.StatusStrip statusStrip1;
|
||||||
private System.Windows.Forms.ToolStripStatusLabel springLbl;
|
private System.Windows.Forms.ToolStripStatusLabel springLbl;
|
||||||
private System.Windows.Forms.ToolStripStatusLabel visibleCountLbl;
|
private LibationWinForms.FormattableToolStripStatusLabel visibleCountLbl;
|
||||||
private System.Windows.Forms.ToolStripMenuItem liberateToolStripMenuItem;
|
private System.Windows.Forms.ToolStripMenuItem liberateToolStripMenuItem;
|
||||||
private System.Windows.Forms.ToolStripStatusLabel backupsCountsLbl;
|
private System.Windows.Forms.ToolStripStatusLabel backupsCountsLbl;
|
||||||
private System.Windows.Forms.ToolStripMenuItem beginBookBackupsToolStripMenuItem;
|
private LibationWinForms.FormattableToolStripMenuItem beginBookBackupsToolStripMenuItem;
|
||||||
private System.Windows.Forms.ToolStripStatusLabel pdfsCountsLbl;
|
private LibationWinForms.FormattableToolStripStatusLabel pdfsCountsLbl;
|
||||||
private System.Windows.Forms.ToolStripMenuItem beginPdfBackupsToolStripMenuItem;
|
private LibationWinForms.FormattableToolStripMenuItem beginPdfBackupsToolStripMenuItem;
|
||||||
private System.Windows.Forms.TextBox filterSearchTb;
|
private System.Windows.Forms.TextBox filterSearchTb;
|
||||||
private System.Windows.Forms.Button filterBtn;
|
private System.Windows.Forms.Button filterBtn;
|
||||||
private System.Windows.Forms.Button filterHelpBtn;
|
private System.Windows.Forms.Button filterHelpBtn;
|
||||||
@ -562,12 +562,12 @@
|
|||||||
private System.Windows.Forms.ToolStripMenuItem aboutToolStripMenuItem;
|
private System.Windows.Forms.ToolStripMenuItem aboutToolStripMenuItem;
|
||||||
private System.Windows.Forms.ToolStripMenuItem scanningToolStripMenuItem;
|
private System.Windows.Forms.ToolStripMenuItem scanningToolStripMenuItem;
|
||||||
private System.Windows.Forms.ToolStripMenuItem autoScanLibraryToolStripMenuItem;
|
private System.Windows.Forms.ToolStripMenuItem autoScanLibraryToolStripMenuItem;
|
||||||
private System.Windows.Forms.ToolStripMenuItem visibleBooksToolStripMenuItem;
|
private LibationWinForms.FormattableToolStripMenuItem visibleBooksToolStripMenuItem;
|
||||||
private System.Windows.Forms.ToolStripMenuItem liberateVisibleToolStripMenuItem;
|
private LibationWinForms.FormattableToolStripMenuItem liberateVisibleToolStripMenuItem;
|
||||||
private System.Windows.Forms.ToolStripMenuItem replaceTagsToolStripMenuItem;
|
private System.Windows.Forms.ToolStripMenuItem replaceTagsToolStripMenuItem;
|
||||||
private System.Windows.Forms.ToolStripMenuItem setDownloadedToolStripMenuItem;
|
private System.Windows.Forms.ToolStripMenuItem setDownloadedToolStripMenuItem;
|
||||||
private System.Windows.Forms.ToolStripMenuItem removeToolStripMenuItem;
|
private System.Windows.Forms.ToolStripMenuItem removeToolStripMenuItem;
|
||||||
private System.Windows.Forms.ToolStripMenuItem liberateVisible2ToolStripMenuItem;
|
private LibationWinForms.FormattableToolStripMenuItem liberateVisible2ToolStripMenuItem;
|
||||||
private System.Windows.Forms.SplitContainer splitContainer1;
|
private System.Windows.Forms.SplitContainer splitContainer1;
|
||||||
private LibationWinForms.ProcessQueue.ProcessQueueControl processBookQueue1;
|
private LibationWinForms.ProcessQueue.ProcessQueueControl processBookQueue1;
|
||||||
private System.Windows.Forms.Panel panel1;
|
private System.Windows.Forms.Panel panel1;
|
||||||
|
|||||||
@ -10,22 +10,20 @@ namespace LibationWinForms
|
|||||||
{
|
{
|
||||||
public partial class Form1
|
public partial class Form1
|
||||||
{
|
{
|
||||||
private string visibleBooksToolStripMenuItem_format;
|
|
||||||
private string liberateVisibleToolStripMenuItem_format;
|
|
||||||
private string liberateVisible2ToolStripMenuItem_format;
|
|
||||||
|
|
||||||
protected void Configure_VisibleBooks()
|
protected void Configure_VisibleBooks()
|
||||||
{
|
{
|
||||||
|
// init formattable
|
||||||
|
visibleCountLbl.Format(0);
|
||||||
|
liberateVisibleToolStripMenuItem.Format(0);
|
||||||
|
liberateVisible2ToolStripMenuItem.Format(0);
|
||||||
|
|
||||||
// bottom-left visible count
|
// bottom-left visible count
|
||||||
productsGrid.VisibleCountChanged += (_, qty) => visibleCountLbl.Text = string.Format("Visible: {0}", qty);
|
productsGrid.VisibleCountChanged += (_, qty) => visibleCountLbl.Format(qty);
|
||||||
|
|
||||||
// back up string formats
|
|
||||||
visibleBooksToolStripMenuItem_format = visibleBooksToolStripMenuItem.Text;
|
|
||||||
liberateVisibleToolStripMenuItem_format = liberateVisibleToolStripMenuItem.Text;
|
|
||||||
liberateVisible2ToolStripMenuItem_format = liberateVisible2ToolStripMenuItem.Text;
|
|
||||||
|
|
||||||
|
// top menu strip
|
||||||
|
visibleBooksToolStripMenuItem.Format(0);
|
||||||
productsGrid.VisibleCountChanged += (_, qty) => {
|
productsGrid.VisibleCountChanged += (_, qty) => {
|
||||||
visibleBooksToolStripMenuItem.Text = string.Format(visibleBooksToolStripMenuItem_format, qty);
|
visibleBooksToolStripMenuItem.Format(qty);
|
||||||
visibleBooksToolStripMenuItem.Enabled = qty > 0;
|
visibleBooksToolStripMenuItem.Enabled = qty > 0;
|
||||||
|
|
||||||
var notLiberatedCount = productsGrid.GetVisible().Count(lb => lb.Book.UserDefinedItem.BookStatus == DataLayer.LiberatedStatus.NotLiberated);
|
var notLiberatedCount = productsGrid.GetVisible().Count(lb => lb.Book.UserDefinedItem.BookStatus == DataLayer.LiberatedStatus.NotLiberated);
|
||||||
@ -45,10 +43,10 @@ namespace LibationWinForms
|
|||||||
{
|
{
|
||||||
if (notLiberated > 0)
|
if (notLiberated > 0)
|
||||||
{
|
{
|
||||||
liberateVisibleToolStripMenuItem.Text = string.Format(liberateVisibleToolStripMenuItem_format, notLiberated);
|
liberateVisibleToolStripMenuItem.Format(notLiberated);
|
||||||
liberateVisibleToolStripMenuItem.Enabled = true;
|
liberateVisibleToolStripMenuItem.Enabled = true;
|
||||||
|
|
||||||
liberateVisible2ToolStripMenuItem.Text = string.Format(liberateVisible2ToolStripMenuItem_format, notLiberated);
|
liberateVisible2ToolStripMenuItem.Format(notLiberated);
|
||||||
liberateVisible2ToolStripMenuItem.Enabled = true;
|
liberateVisible2ToolStripMenuItem.Enabled = true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -63,7 +61,7 @@ namespace LibationWinForms
|
|||||||
}
|
}
|
||||||
|
|
||||||
private async void liberateVisible(object sender, EventArgs e)
|
private async void liberateVisible(object sender, EventArgs e)
|
||||||
=> await BookLiberation.ProcessorAutomationController.BackupAllBooksAsync(productsGrid.GetVisible());
|
=> await Task.Run(() => processBookQueue1.AddDownloadDecrypt(productsGrid.GetVisible()));
|
||||||
|
|
||||||
private void replaceTagsToolStripMenuItem_Click(object sender, EventArgs e)
|
private void replaceTagsToolStripMenuItem_Click(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
|
|||||||
32
Source/LibationWinForms/FormattableLabel.cs
Normal file
32
Source/LibationWinForms/FormattableLabel.cs
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
using System;
|
||||||
|
using System.Drawing;
|
||||||
|
using System.Windows.Forms;
|
||||||
|
|
||||||
|
namespace LibationWinForms
|
||||||
|
{
|
||||||
|
public class FormattableLabel : Label
|
||||||
|
{
|
||||||
|
public string FormatText { get; set; }
|
||||||
|
|
||||||
|
/// <summary>Text set: first non-null, non-whitespace <see cref="Text"/> set is also saved as <see cref="FormatText"/></summary>
|
||||||
|
public override string Text
|
||||||
|
{
|
||||||
|
get => base.Text;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (string.IsNullOrWhiteSpace(FormatText))
|
||||||
|
FormatText = value;
|
||||||
|
|
||||||
|
base.Text = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#region ctor.s
|
||||||
|
public FormattableLabel() : base() { }
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
/// <summary>Replaces the format item in a specified string with the string representation of a corresponding object in a specified array. Returns <see cref="Text"/> for convenience.</summary>
|
||||||
|
/// <param name="args">An object array that contains zero or more objects to format.</param>
|
||||||
|
public string Format(params object[] args) => Text = string.Format(FormatText, args);
|
||||||
|
}
|
||||||
|
}
|
||||||
39
Source/LibationWinForms/FormattableToolStripMenuItem.cs
Normal file
39
Source/LibationWinForms/FormattableToolStripMenuItem.cs
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
using System;
|
||||||
|
using System.Drawing;
|
||||||
|
using System.Windows.Forms;
|
||||||
|
|
||||||
|
namespace LibationWinForms
|
||||||
|
{
|
||||||
|
public class FormattableToolStripMenuItem : ToolStripMenuItem
|
||||||
|
{
|
||||||
|
public string FormatText { get; set; }
|
||||||
|
|
||||||
|
/// <summary>Text set: first non-null, non-whitespace <see cref="Text"/> set is also saved as <see cref="FormatText"/></summary>
|
||||||
|
public override string Text
|
||||||
|
{
|
||||||
|
get => base.Text;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (string.IsNullOrWhiteSpace(FormatText))
|
||||||
|
FormatText = value;
|
||||||
|
|
||||||
|
base.Text = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#region ctor.s
|
||||||
|
public FormattableToolStripMenuItem() : base() { }
|
||||||
|
public FormattableToolStripMenuItem(string text) : base(text) => FormatText = text;
|
||||||
|
public FormattableToolStripMenuItem(Image image) : base(image) { }
|
||||||
|
public FormattableToolStripMenuItem(string text, Image image) : base(text, image) => FormatText = text;
|
||||||
|
public FormattableToolStripMenuItem(string text, Image image, EventHandler onClick) : base(text, image, onClick) => FormatText = text;
|
||||||
|
public FormattableToolStripMenuItem(string text, Image image, params ToolStripItem[] dropDownItems) : base(text, image, dropDownItems) => FormatText = text;
|
||||||
|
public FormattableToolStripMenuItem(string text, Image image, EventHandler onClick, Keys shortcutKeys) : base(text, image, onClick, shortcutKeys) => FormatText = text;
|
||||||
|
public FormattableToolStripMenuItem(string text, Image image, EventHandler onClick, string name) : base(text, image, onClick, name) => FormatText = text;
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
/// <summary>Replaces the format item in a specified string with the string representation of a corresponding object in a specified array. Returns <see cref="Text"/> for convenience.</summary>
|
||||||
|
/// <param name="args">An object array that contains zero or more objects to format.</param>
|
||||||
|
public string Format(params object[] args) => Text = string.Format(FormatText, args);
|
||||||
|
}
|
||||||
|
}
|
||||||
37
Source/LibationWinForms/FormattableToolStripStatusLabel.cs
Normal file
37
Source/LibationWinForms/FormattableToolStripStatusLabel.cs
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
using System;
|
||||||
|
using System.Drawing;
|
||||||
|
using System.Windows.Forms;
|
||||||
|
|
||||||
|
namespace LibationWinForms
|
||||||
|
{
|
||||||
|
public class FormattableToolStripStatusLabel : ToolStripStatusLabel
|
||||||
|
{
|
||||||
|
public string FormatText { get; set; }
|
||||||
|
|
||||||
|
/// <summary>Text set: first non-null, non-whitespace <see cref="Text"/> set is also saved as <see cref="FormatText"/></summary>
|
||||||
|
public override string Text
|
||||||
|
{
|
||||||
|
get => base.Text;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (string.IsNullOrWhiteSpace(FormatText))
|
||||||
|
FormatText = value;
|
||||||
|
|
||||||
|
base.Text = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#region ctor.s
|
||||||
|
public FormattableToolStripStatusLabel() : base() { }
|
||||||
|
public FormattableToolStripStatusLabel(string text) : base(text) => FormatText = text;
|
||||||
|
public FormattableToolStripStatusLabel(Image image) : base(image) { }
|
||||||
|
public FormattableToolStripStatusLabel(string text, Image image) : base(text, image) => FormatText = text;
|
||||||
|
public FormattableToolStripStatusLabel(string text, Image image, EventHandler onClick) : base(text, image, onClick) => FormatText = text;
|
||||||
|
public FormattableToolStripStatusLabel(string text, Image image, EventHandler onClick, string name) : base(text, image, onClick, name) => FormatText = text;
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
/// <summary>Replaces the format item in a specified string with the string representation of a corresponding object in a specified array. Returns <see cref="Text"/> for convenience.</summary>
|
||||||
|
/// <param name="args">An object array that contains zero or more objects to format.</param>
|
||||||
|
public string Format(params object[] args) => Text = string.Format(FormatText, args);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -46,7 +46,6 @@ namespace LibationWinForms
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool DownloadInProgress { get; private set; }
|
|
||||||
public string ProductRating { get; private set; }
|
public string ProductRating { get; private set; }
|
||||||
public string PurchaseDate { get; private set; }
|
public string PurchaseDate { get; private set; }
|
||||||
public string MyRating { get; private set; }
|
public string MyRating { get; private set; }
|
||||||
@ -68,7 +67,8 @@ namespace LibationWinForms
|
|||||||
//Cache these statuses for faster sorting.
|
//Cache these statuses for faster sorting.
|
||||||
if ((DateTime.Now - lastStatusUpdate).TotalSeconds > 2)
|
if ((DateTime.Now - lastStatusUpdate).TotalSeconds > 2)
|
||||||
{
|
{
|
||||||
UpdateLiberatedStatus(notify: false);
|
_bookStatus = LibraryCommands.Liberated_Status(LibraryBook.Book);
|
||||||
|
_pdfStatus = LibraryCommands.Pdf_Status(LibraryBook.Book);
|
||||||
lastStatusUpdate = DateTime.Now;
|
lastStatusUpdate = DateTime.Now;
|
||||||
}
|
}
|
||||||
return (_bookStatus, _pdfStatus);
|
return (_bookStatus, _pdfStatus);
|
||||||
@ -84,23 +84,6 @@ namespace LibationWinForms
|
|||||||
|
|
||||||
public GridEntry(LibraryBook libraryBook) => setLibraryBook(libraryBook);
|
public GridEntry(LibraryBook libraryBook) => setLibraryBook(libraryBook);
|
||||||
|
|
||||||
public async Task DownloadBook()
|
|
||||||
{
|
|
||||||
if (DownloadInProgress)
|
|
||||||
return;
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
DownloadInProgress = true;
|
|
||||||
await BookLiberation.ProcessorAutomationController.BackupSingleBookAsync(LibraryBook);
|
|
||||||
UpdateLiberatedStatus();
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
DownloadInProgress = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void UpdateLibraryBook(LibraryBook libraryBook)
|
public void UpdateLibraryBook(LibraryBook libraryBook)
|
||||||
{
|
{
|
||||||
if (AudibleProductId != libraryBook.Book.AudibleProductId)
|
if (AudibleProductId != libraryBook.Book.AudibleProductId)
|
||||||
@ -209,14 +192,6 @@ namespace LibationWinForms
|
|||||||
Committed?.Invoke(this, null);
|
Committed?.Invoke(this, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void UpdateLiberatedStatus(bool notify = true)
|
|
||||||
{
|
|
||||||
_bookStatus = LibraryCommands.Liberated_Status(LibraryBook.Book);
|
|
||||||
_pdfStatus = LibraryCommands.Pdf_Status(LibraryBook.Book);
|
|
||||||
if (notify)
|
|
||||||
NotifyPropertyChanged(nameof(Liberate));
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Data Sorting
|
#region Data Sorting
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user