diff --git a/AudibleApiDomainService/AudibleApiDomainService.csproj b/AudibleApiDomainService/AudibleApiDomainService.csproj index af0258e8..8c0bac50 100644 --- a/AudibleApiDomainService/AudibleApiDomainService.csproj +++ b/AudibleApiDomainService/AudibleApiDomainService.csproj @@ -5,7 +5,9 @@ - + + + diff --git a/AudibleApiDomainService/AudibleApiLibationClient.cs b/AudibleApiDomainService/AudibleApiLibationClient.cs index b20a3c3d..ca9282fe 100644 --- a/AudibleApiDomainService/AudibleApiLibationClient.cs +++ b/AudibleApiDomainService/AudibleApiLibationClient.cs @@ -1,19 +1,122 @@ using System; +using System.IO; +using System.Net.Http; using System.Threading.Tasks; +using AudibleApi; +using AudibleApi.Authentication; +using AudibleApi.Authorization; +using Newtonsoft.Json.Linq; namespace AudibleApiDomainService { public class AudibleApiLibationClient { - private Settings settings; - public AudibleApiLibationClient(Settings settings) - => this.settings = settings ?? throw new ArgumentNullException(nameof(settings)); + private Api _api; + + #region initialize api + private AudibleApiLibationClient() { } + public async static Task CreateClientAsync(Settings settings, IAudibleApiResponder responder) + { + Localization.SetLocale(settings.LocaleCountryCode); + + Api api; + try + { + api = await EzApiCreator.GetApiAsync(settings.IdentityFilePath); + } + catch + { + var inMemoryIdentity = await loginAsync(responder); + api = await EzApiCreator.GetApiAsync(settings.IdentityFilePath, inMemoryIdentity); + } + + return new AudibleApiLibationClient { _api = api }; + } + + // LOGIN PATTERN + // - Start with Authenticate. Submit email + pw + // - Each step in the login process will return a LoginResult + // - Each result which has required user input has a SubmitAsync method + // - The final LoginComplete result returns "Identity" -- in-memory authorization items + private static async Task loginAsync(IAudibleApiResponder responder) + { + var login = new Authenticate(); + + var (email, password) = responder.GetLogin(); + + var loginResult = await login.SubmitCredentialsAsync(email, password); + + while (true) + { + switch (loginResult) + { + case CredentialsPage credentialsPage: + var (emailInput, pwInput) = responder.GetLogin(); + loginResult = await credentialsPage.SubmitAsync(emailInput, pwInput); + break; + + case CaptchaPage captchaResult: + var imageBytes = await downloadImageAsync(captchaResult.CaptchaImage); + var guess = responder.GetCaptchaAnswer(imageBytes); + loginResult = await captchaResult.SubmitAsync(guess); + break; + + case TwoFactorAuthenticationPage _2fa: + var _2faCode = responder.Get2faCode(); + loginResult = await _2fa.SubmitAsync(_2faCode); + break; + + case LoginComplete final: + return final.Identity; + + default: + throw new Exception("Unknown LoginResult"); + } + } + } + + private static async Task downloadImageAsync(Uri imageUri) + { + using var client = new HttpClient(); + using var contentStream = await client.GetStreamAsync(imageUri); + using var localStream = new MemoryStream(); + await contentStream.CopyToAsync(localStream); + return localStream.ToArray(); + } + #endregion + + public async Task TestGetLibraryAsync() + { + var x = await _api.GetLibraryAsync(); + return x; + } + + //public async Task DownloadBookAsync(string asinToDownload) + //{ + // // console example + // using var progressBar = new Dinah.Core.ConsoleLib.ProgressBar(); + // var progress = new Progress(); + // progress.ProgressChanged += (_, e) => progressBar.Report(Math.Round((double)(100 * e.BytesReceived) / e.TotalFileSize.Value) / 100); + + // logger.WriteLine("Download book"); + // var finalFile = await _api.DownloadAaxWorkaroundAsync(asinToDownload, "downloadExample.xyz", progress); + + // logger.WriteLine(" Done!"); + // logger.WriteLine("final file: " + Path.GetFullPath(finalFile)); + + // // benefit of this small delay: + // // - if you try to delete a file too soon after it's created, the OS isn't done with the creation and you can get an unexpected error + // // - give progressBar's internal timer time to finish. if timer is disposed before the final message is processed, "100%" will never get a chance to be displayed + // await Task.Delay(100); + + // File.Delete(finalFile); + //} public async Task ImportLibraryAsync() { - // call api - // translate to DTOs - // update database + // json = api.GetLibrary + // json => DTOs + // indexer.update(DTOs) } } } diff --git a/AudibleApiDomainService/FROM_DEMO/AudibleApiClient.cs b/AudibleApiDomainService/FROM_DEMO/AudibleApiClient.cs deleted file mode 100644 index c345fcdd..00000000 --- a/AudibleApiDomainService/FROM_DEMO/AudibleApiClient.cs +++ /dev/null @@ -1,205 +0,0 @@ -//using System; -//using System.IO; -//using System.Net.Http; -//using System.Threading.Tasks; -//using AudibleApi; -//using AudibleApi.Authentication; -//using AudibleApi.Authorization; -//using Dinah.Core.Net.Http; -//using Newtonsoft.Json; - -//namespace AudibleApiDomainService -//{ -// public class AudibleApiClient -// { -// #region initialize api -// public const string APP_SETTINGS = "appsettings.json"; -// private Api _api; - -// private static ClientSettings settings; - -// private AudibleApiClient() { } -// public async static Task CreateClientAsync() -// { -// settings = ClientSettings.FromFile(APP_SETTINGS); - -// restoreLocale(); - -// Api api; -// try -// { -// api = await EzApiCreator.GetApiAsync(settings.IdentityFilePath); -// } -// catch -// { -// var inMemoryIdentity = await loginAsync(email, password); -// api = await EzApiCreator.GetApiAsync(settings.IdentityFilePath, inMemoryIdentity); -// } - -// return new AudibleApiClient { _api = api }; -// } - -// private static void restoreLocale() -// { -// if (settings.LocaleCountryCode != null) -// Localization.SetLocale(settings.LocaleCountryCode); -// } - -// // LOGIN PATTERN -// // - Start with Authenticate. Submit email + pw -// // - Each step in the login process will return a LoginResult -// // - Each result which has required user input has a SubmitAsync method -// // - The final LoginComplete result returns "Identity" -- in-memory authorization items -// private static async Task loginAsync(string email, string pw) -// { -// var login = new Authenticate(); -// var loginResult = await login.SubmitCredentialsAsync(email, pw); - -// while (true) -// { -// switch (loginResult) -// { -// case CredentialsPage credentialsPage: -// Console.WriteLine("Email:"); -// var emailInput = Console.ReadLine(); -// Console.WriteLine("Password:"); -// var pwInput = Dinah.Core.ConsoleLib.ConsoleExt.ReadPassword(); -// loginResult = await credentialsPage.SubmitAsync(emailInput, pwInput); -// break; - -// case CaptchaPage captchaResult: -// var imageBytes = await downloadImageAsync(captchaResult.CaptchaImage); -// var guess = getUserCaptchaGuess(imageBytes); -// loginResult = await captchaResult.SubmitAsync(guess); -// break; - -// case TwoFactorAuthenticationPage _2fa: -// Console.WriteLine("Two-Step Verification code:"); -// var _2faCode = Console.ReadLine(); -// loginResult = await _2fa.SubmitAsync(_2faCode); -// break; - -// case LoginComplete final: -// return final.Identity; - -// default: -// throw new Exception("Unknown LoginResult"); -// } -// } -// } - -// private static async Task downloadImageAsync(Uri imageUri) -// { -// using var client = new HttpClient(); -// using var contentStream = await client.GetStreamAsync(imageUri); -// using var localStream = new MemoryStream(); -// await contentStream.CopyToAsync(localStream); -// return localStream.ToArray(); -// } - -// private static string getUserCaptchaGuess(byte[] captchaImage) -// { -// var tempFileName = Path.Combine(Path.GetTempPath(), "audible_api_captcha_" + Guid.NewGuid() + ".jpg"); - -// try -// { -// File.WriteAllBytes(tempFileName, captchaImage); - -// var processStartInfo = new System.Diagnostics.ProcessStartInfo -// { -// Verb = string.Empty, -// UseShellExecute = true, -// CreateNoWindow = true, -// FileName = tempFileName -// }; -// System.Diagnostics.Process.Start(processStartInfo); - -// Console.WriteLine("CAPTCHA answer: "); -// var guess = Console.ReadLine(); -// return guess; -// } -// finally -// { -// if (File.Exists(tempFileName)) -// File.Delete(tempFileName); -// } -// } -// #endregion - -// #region api call examples -// // Mimi's Adventure (3m) -// public const string TINY_BOOK_ASIN = "B079DZ8YMP"; - -// // Harry Potter 1 (8h 33m) -// public const string MEDIUM_BOOK_ASIN = "B017V4IM1G"; - -// // Sherlock Holmes (62h 52m) -// public const string HUGE_BOOK_ASIN = "B06WLMWF2S"; - -// public Task PrintLibraryAsync() => wrapCallAsync(printLibraryAsync); -// private async Task printLibraryAsync() -// { -// // test ad hoc api calls - -// string url; -// string allGroups; - -// url -// = "/1.0/library" -// + "?purchaseAfterDate=01/01/1970&page=23"; -// url = "/1.0/library/" + -// //TINY_BOOK_ASIN -// MEDIUM_BOOK_ASIN -// //HUGE_BOOK_ASIN -// ; - -// url += url.Contains("?") ? "&" : "?"; - -// //allGroups = "response_groups=badge_types,category_ladders,claim_code_url,contributors,is_downloaded,is_returnable,media,origin_asin,pdf_url,percent_complete,price,product_attrs,product_desc,product_extended_attrs,product_plan_details,product_plans,provided_review,rating,relationships,review_attrs,reviews,sample,series,sku"; -// allGroups = "response_groups=series,category_ladders,contributors"; - -// url += allGroups; -// var responseMsg = await _api.AdHocAuthenticatedGetAsync(url); -// var jObj = await responseMsg.Content.ReadAsJObjectAsync(); -// var str = jObj.ToString(Formatting.Indented); -// Console.WriteLine(str); -// } - -// public Task DownloadBookAsync() => wrapCallAsync(downloadBookAsync); -// private async Task downloadBookAsync() -// { -// using var progressBar = new Dinah.Core.ConsoleLib.ProgressBar(); -// var progress = new Progress(); -// progress.ProgressChanged += (_, e) => progressBar.Report(Math.Round((double)(100 * e.BytesReceived) / e.TotalFileSize.Value) / 100); - -// Console.Write("Download book"); -// var finalFile = await _api.DownloadAaxWorkaroundAsync(TINY_BOOK_ASIN, "downloadExample.xyz", progress); - -// Console.WriteLine(" Done!"); -// Console.WriteLine("final file: " + Path.GetFullPath(finalFile)); - -// // benefit of this small delay: -// // - if you try to delete a file too soon after it's created, the OS isn't done with the creation and you can get an unexpected error -// // - give progressBar's internal timer time to finish. if timer is disposed before the final message is processed, "100%" will never get a chance to be displayed -// await Task.Delay(100); - -// File.Delete(finalFile); -// } - -// private async Task wrapCallAsync(Func fn) -// { -// try -// { -// await fn(); -// } -// catch (AudibleApiException aex) -// { -// Console.WriteLine("ERROR:"); -// Console.WriteLine(aex.Message); -// Console.WriteLine(aex.JsonMessage.ToString()); -// Console.WriteLine(aex.RequestUri.ToString()); -// } -// } -// #endregion -// } -//} \ No newline at end of file diff --git a/AudibleApiDomainService/IAudibleApiResponder.cs b/AudibleApiDomainService/IAudibleApiResponder.cs new file mode 100644 index 00000000..6b9da2c2 --- /dev/null +++ b/AudibleApiDomainService/IAudibleApiResponder.cs @@ -0,0 +1,9 @@ +namespace AudibleApiDomainService +{ + public interface IAudibleApiResponder + { + (string email, string password) GetLogin(); + string GetCaptchaAnswer(byte[] captchaImage); + string Get2faCode(); + } +} \ No newline at end of file diff --git a/AudibleApiDomainService/Settings.cs b/AudibleApiDomainService/Settings.cs index 5f7e3688..0febe54d 100644 --- a/AudibleApiDomainService/Settings.cs +++ b/AudibleApiDomainService/Settings.cs @@ -1,10 +1,17 @@ -namespace AudibleApiDomainService +using System.IO; +using FileManager; + +namespace AudibleApiDomainService { public class Settings { - // identityTokens.json - public string IdentityFilePath { get; set; } + public string IdentityFilePath { get; } + public string LocaleCountryCode { get; } - public string LocaleCountryCode { get; set; } + public Settings(Configuration config) + { + IdentityFilePath = Path.Combine(config.LibationFiles, "identityTokens.json"); + LocaleCountryCode = config.LocaleCountryCode; + } } } \ No newline at end of file diff --git a/Libation.sln b/Libation.sln index 112e9a9e..1c6c06c0 100644 --- a/Libation.sln +++ b/Libation.sln @@ -11,7 +11,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "_Solution Items", "_Solutio REFERENCE.txt = REFERENCE.txt EndProjectSection EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "3.2 Domain Utilities (post database)", "3.2 Domain Utilities (post database)", "{41CDCC73-9B81-49DD-9570-C54406E852AF}" +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "3.2 Domain Utilities (database aware)", "3.2 Domain Utilities (database aware)", "{41CDCC73-9B81-49DD-9570-C54406E852AF}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "4 Application", "4 Application", "{8679CAC8-9164-4007-BDD2-F004810EDA14}" EndProject @@ -83,7 +83,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LuceneNet303r2.Tests", "..\ EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DTOs", "DTOs\DTOs.csproj", "{5FDA62B1-55FD-407A-BECA-38A969235541}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AudibleApiDomainService", "AudibleApiDomainService\AudibleApiDomainService.csproj", "{A1AB4B4B-6855-4BD0-BC54-C2FFDB20E050}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AudibleApiDomainService", "AudibleApiDomainService\AudibleApiDomainService.csproj", "{A1AB4B4B-6855-4BD0-BC54-C2FFDB20E050}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution diff --git a/LibationWinForm/UNTESTED/Dialogs/Login/AudibleLoginDialog.Designer.cs b/LibationWinForm/UNTESTED/Dialogs/Login/AudibleLoginDialog.Designer.cs new file mode 100644 index 00000000..5677f886 --- /dev/null +++ b/LibationWinForm/UNTESTED/Dialogs/Login/AudibleLoginDialog.Designer.cs @@ -0,0 +1,113 @@ +namespace LibationWinForm.Dialogs.Login +{ + partial class AudibleLoginDialog + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.passwordLbl = new System.Windows.Forms.Label(); + this.emailLbl = new System.Windows.Forms.Label(); + this.passwordTb = new System.Windows.Forms.TextBox(); + this.emailTb = new System.Windows.Forms.TextBox(); + this.submitBtn = new System.Windows.Forms.Button(); + this.SuspendLayout(); + // + // passwordLbl + // + this.passwordLbl.AutoSize = true; + this.passwordLbl.Location = new System.Drawing.Point(12, 41); + this.passwordLbl.Name = "passwordLbl"; + this.passwordLbl.Size = new System.Drawing.Size(53, 13); + this.passwordLbl.TabIndex = 2; + this.passwordLbl.Text = "Password"; + // + // emailLbl + // + this.emailLbl.AutoSize = true; + this.emailLbl.Location = new System.Drawing.Point(12, 15); + this.emailLbl.Name = "emailLbl"; + this.emailLbl.Size = new System.Drawing.Size(32, 13); + this.emailLbl.TabIndex = 0; + this.emailLbl.Text = "Email"; + // + // passwordTb + // + this.passwordTb.Location = new System.Drawing.Point(71, 38); + this.passwordTb.Name = "passwordTb"; + this.passwordTb.PasswordChar = '*'; + this.passwordTb.Size = new System.Drawing.Size(200, 20); + this.passwordTb.TabIndex = 3; + // + // emailTb + // + this.emailTb.Location = new System.Drawing.Point(71, 12); + this.emailTb.Name = "emailTb"; + this.emailTb.Size = new System.Drawing.Size(200, 20); + this.emailTb.TabIndex = 1; + // + // submitBtn + // + this.submitBtn.Location = new System.Drawing.Point(196, 64); + this.submitBtn.Name = "submitBtn"; + this.submitBtn.Size = new System.Drawing.Size(75, 23); + this.submitBtn.TabIndex = 4; + this.submitBtn.Text = "Submit"; + this.submitBtn.UseVisualStyleBackColor = true; + this.submitBtn.Click += new System.EventHandler(this.submitBtn_Click); + // + // AudibleLoginDialog + // + this.AcceptButton = this.submitBtn; + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(283, 99); + this.Controls.Add(this.submitBtn); + this.Controls.Add(this.passwordLbl); + this.Controls.Add(this.emailLbl); + this.Controls.Add(this.passwordTb); + this.Controls.Add(this.emailTb); + this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog; + this.MaximizeBox = false; + this.MinimizeBox = false; + this.Name = "AudibleLoginDialog"; + this.ShowIcon = false; + this.ShowInTaskbar = false; + this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; + this.Text = "Audible Login"; + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private System.Windows.Forms.Label passwordLbl; + private System.Windows.Forms.Label emailLbl; + private System.Windows.Forms.TextBox passwordTb; + private System.Windows.Forms.TextBox emailTb; + private System.Windows.Forms.Button submitBtn; + } +} \ No newline at end of file diff --git a/LibationWinForm/UNTESTED/Dialogs/Login/AudibleLoginDialog.cs b/LibationWinForm/UNTESTED/Dialogs/Login/AudibleLoginDialog.cs new file mode 100644 index 00000000..9011b449 --- /dev/null +++ b/LibationWinForm/UNTESTED/Dialogs/Login/AudibleLoginDialog.cs @@ -0,0 +1,23 @@ +using System; +using System.Windows.Forms; + +namespace LibationWinForm.Dialogs.Login +{ + public partial class AudibleLoginDialog : Form + { + public string Email { get; private set; } + public string Password { get; private set; } + + public AudibleLoginDialog() + { + InitializeComponent(); + } + + private void submitBtn_Click(object sender, EventArgs e) + { + Email = this.emailTb.Text; + Password = this.passwordTb.Text; + DialogResult = DialogResult.OK; + } + } +} diff --git a/LibationWinForm/UNTESTED/Dialogs/Login/CaptchaDialog.Designer.cs b/LibationWinForm/UNTESTED/Dialogs/Login/CaptchaDialog.Designer.cs new file mode 100644 index 00000000..1a0de084 --- /dev/null +++ b/LibationWinForm/UNTESTED/Dialogs/Login/CaptchaDialog.Designer.cs @@ -0,0 +1,103 @@ +namespace LibationWinForm.Dialogs.Login +{ + partial class CaptchaDialog + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.captchaPb = new System.Windows.Forms.PictureBox(); + this.answerTb = new System.Windows.Forms.TextBox(); + this.submitBtn = new System.Windows.Forms.Button(); + this.answerLbl = new System.Windows.Forms.Label(); + ((System.ComponentModel.ISupportInitialize)(this.captchaPb)).BeginInit(); + this.SuspendLayout(); + // + // captchaPb + // + this.captchaPb.Location = new System.Drawing.Point(12, 12); + this.captchaPb.Name = "captchaPb"; + this.captchaPb.Size = new System.Drawing.Size(429, 186); + this.captchaPb.TabIndex = 0; + this.captchaPb.TabStop = false; + // + // answerTb + // + this.answerTb.Location = new System.Drawing.Point(118, 206); + this.answerTb.Name = "answerTb"; + this.answerTb.Size = new System.Drawing.Size(100, 20); + this.answerTb.TabIndex = 1; + // + // submitBtn + // + this.submitBtn.Location = new System.Drawing.Point(366, 204); + this.submitBtn.Name = "submitBtn"; + this.submitBtn.Size = new System.Drawing.Size(75, 23); + this.submitBtn.TabIndex = 2; + this.submitBtn.Text = "Submit"; + this.submitBtn.UseVisualStyleBackColor = true; + this.submitBtn.Click += new System.EventHandler(this.submitBtn_Click); + // + // answerLbl + // + this.answerLbl.AutoSize = true; + this.answerLbl.Location = new System.Drawing.Point(12, 209); + this.answerLbl.Name = "answerLbl"; + this.answerLbl.Size = new System.Drawing.Size(100, 13); + this.answerLbl.TabIndex = 0; + this.answerLbl.Text = "CAPTCHA answer: "; + // + // CaptchaDialog + // + this.AcceptButton = this.submitBtn; + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(453, 239); + this.Controls.Add(this.answerLbl); + this.Controls.Add(this.submitBtn); + this.Controls.Add(this.answerTb); + this.Controls.Add(this.captchaPb); + this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog; + this.MaximizeBox = false; + this.MinimizeBox = false; + this.Name = "CaptchaDialog"; + this.ShowIcon = false; + this.ShowInTaskbar = false; + this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; + this.Text = "CAPTCHA"; + ((System.ComponentModel.ISupportInitialize)(this.captchaPb)).EndInit(); + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private System.Windows.Forms.PictureBox captchaPb; + private System.Windows.Forms.TextBox answerTb; + private System.Windows.Forms.Button submitBtn; + private System.Windows.Forms.Label answerLbl; + } +} \ No newline at end of file diff --git a/LibationWinForm/UNTESTED/Dialogs/Login/CaptchaDialog.cs b/LibationWinForm/UNTESTED/Dialogs/Login/CaptchaDialog.cs new file mode 100644 index 00000000..c25693f5 --- /dev/null +++ b/LibationWinForm/UNTESTED/Dialogs/Login/CaptchaDialog.cs @@ -0,0 +1,38 @@ +using System; +using System.Drawing; +using System.IO; +using System.Windows.Forms; + +namespace LibationWinForm.Dialogs.Login +{ + public partial class CaptchaDialog : Form + { + public string Answer { get; private set; } + + private MemoryStream ms { get; } + private Image image { get; } + + public CaptchaDialog(byte[] captchaImage) + { + InitializeComponent(); + + this.FormClosed += (_, __) => { ms?.Dispose(); image?.Dispose(); }; + + ms = new MemoryStream(captchaImage); + image = Image.FromStream(ms); + this.captchaPb.Image = image; + + var h1 = captchaPb.Height; + var w1 = captchaPb.Width; + + var h2 = captchaPb.Image.Height; + var w2 = captchaPb.Image.Width; + } + + private void submitBtn_Click(object sender, EventArgs e) + { + Answer = this.answerTb.Text; + DialogResult = DialogResult.OK; + } + } +} \ No newline at end of file diff --git a/LibationWinForm/UNTESTED/Dialogs/Login/WinformResponder.cs b/LibationWinForm/UNTESTED/Dialogs/Login/WinformResponder.cs new file mode 100644 index 00000000..53511a86 --- /dev/null +++ b/LibationWinForm/UNTESTED/Dialogs/Login/WinformResponder.cs @@ -0,0 +1,32 @@ +using System; +using LibationWinForm.Dialogs.Login; + +namespace LibationWinForm.Login +{ + public class WinformResponder : AudibleApiDomainService.IAudibleApiResponder + { + public string Get2faCode() + { + using var dialog = new _2faCodeDialog(); + if (dialog.ShowDialog() == System.Windows.Forms.DialogResult.OK) + return dialog.Code; + return null; + } + + public string GetCaptchaAnswer(byte[] captchaImage) + { + using var dialog = new CaptchaDialog(captchaImage); + if (dialog.ShowDialog() == System.Windows.Forms.DialogResult.OK) + return dialog.Answer; + return null; + } + + public (string email, string password) GetLogin() + { + using var dialog = new AudibleLoginDialog(); + if (dialog.ShowDialog() == System.Windows.Forms.DialogResult.OK) + return (dialog.Email, dialog.Password); + return (null, null); + } + } +} \ No newline at end of file diff --git a/LibationWinForm/UNTESTED/Dialogs/Login/_2faCodeDialog.Designer.cs b/LibationWinForm/UNTESTED/Dialogs/Login/_2faCodeDialog.Designer.cs new file mode 100644 index 00000000..2b406196 --- /dev/null +++ b/LibationWinForm/UNTESTED/Dialogs/Login/_2faCodeDialog.Designer.cs @@ -0,0 +1,90 @@ +namespace LibationWinForm.Dialogs.Login +{ + partial class _2faCodeDialog + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.submitBtn = new System.Windows.Forms.Button(); + this.codeTb = new System.Windows.Forms.TextBox(); + this.label1 = new System.Windows.Forms.Label(); + this.SuspendLayout(); + // + // submitBtn + // + this.submitBtn.Location = new System.Drawing.Point(15, 51); + this.submitBtn.Name = "SaveBtn"; + this.submitBtn.Size = new System.Drawing.Size(79, 23); + this.submitBtn.TabIndex = 1; + this.submitBtn.Text = "Submit"; + this.submitBtn.UseVisualStyleBackColor = true; + this.submitBtn.Click += new System.EventHandler(this.submitBtn_Click); + // + // codeTb + // + this.codeTb.Location = new System.Drawing.Point(15, 25); + this.codeTb.Name = "newTagsTb"; + this.codeTb.ScrollBars = System.Windows.Forms.ScrollBars.Both; + this.codeTb.Size = new System.Drawing.Size(79, 20); + this.codeTb.TabIndex = 0; + // + // label1 + // + this.label1.AutoSize = true; + this.label1.Location = new System.Drawing.Point(12, 9); + this.label1.Name = "label1"; + this.label1.Size = new System.Drawing.Size(82, 13); + this.label1.TabIndex = 2; + this.label1.Text = "Enter 2FA Code"; + // + // _2faCodeDialog + // + this.AcceptButton = this.submitBtn; + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(106, 86); + this.Controls.Add(this.label1); + this.Controls.Add(this.codeTb); + this.Controls.Add(this.submitBtn); + this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog; + this.MaximizeBox = false; + this.MinimizeBox = false; + this.Name = "_2faCodeDialog"; + this.ShowIcon = false; + this.ShowInTaskbar = false; + this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; + this.Text = "2FA Code"; + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + private System.Windows.Forms.Button submitBtn; + private System.Windows.Forms.TextBox codeTb; + private System.Windows.Forms.Label label1; + } +} \ No newline at end of file diff --git a/LibationWinForm/UNTESTED/Dialogs/Login/_2faCodeDialog.cs b/LibationWinForm/UNTESTED/Dialogs/Login/_2faCodeDialog.cs new file mode 100644 index 00000000..9c86fe93 --- /dev/null +++ b/LibationWinForm/UNTESTED/Dialogs/Login/_2faCodeDialog.cs @@ -0,0 +1,21 @@ +using System; +using System.Windows.Forms; + +namespace LibationWinForm.Dialogs.Login +{ + public partial class _2faCodeDialog : Form + { + public string Code { get; private set; } + + public _2faCodeDialog() + { + InitializeComponent(); + } + + private void submitBtn_Click(object sender, EventArgs e) + { + Code = this.codeTb.Text; + DialogResult = DialogResult.OK; + } + } +} diff --git a/LibationWinForm/UNTESTED/Form1.cs b/LibationWinForm/UNTESTED/Form1.cs index 3eb3a79d..c3235bec 100644 --- a/LibationWinForm/UNTESTED/Form1.cs +++ b/LibationWinForm/UNTESTED/Form1.cs @@ -358,8 +358,11 @@ namespace LibationWinForm private async void scanLibraryToolStripMenuItem_Click(object sender, EventArgs e) { // audible api -//var client = new AudibleApiDomainService.AudibleApiLibationClient(config.); -//await client.ImportLibraryAsync(); + var settings = new AudibleApiDomainService.Settings(config); + var responder = new Login.WinformResponder(); + var client = await AudibleApiDomainService.AudibleApiLibationClient.CreateClientAsync(settings, responder); +var testResult = await client.TestGetLibraryAsync(); +await client.ImportLibraryAsync(); // scrape await indexDialog(new ScanLibraryDialog()); diff --git a/WinFormsDesigner/IndexDialogs/ScanLibraryDialog.Designer.cs b/WinFormsDesigner/Dialogs/IndexDialogs/ScanLibraryDialog.Designer.cs similarity index 100% rename from WinFormsDesigner/IndexDialogs/ScanLibraryDialog.Designer.cs rename to WinFormsDesigner/Dialogs/IndexDialogs/ScanLibraryDialog.Designer.cs diff --git a/WinFormsDesigner/IndexDialogs/ScanLibraryDialog.cs b/WinFormsDesigner/Dialogs/IndexDialogs/ScanLibraryDialog.cs similarity index 100% rename from WinFormsDesigner/IndexDialogs/ScanLibraryDialog.cs rename to WinFormsDesigner/Dialogs/IndexDialogs/ScanLibraryDialog.cs diff --git a/WinFormsDesigner/IndexDialogs/ScanLibraryDialog.resx b/WinFormsDesigner/Dialogs/IndexDialogs/ScanLibraryDialog.resx similarity index 100% rename from WinFormsDesigner/IndexDialogs/ScanLibraryDialog.resx rename to WinFormsDesigner/Dialogs/IndexDialogs/ScanLibraryDialog.resx diff --git a/WinFormsDesigner/IndexDialogs/WebsiteProcessorControl.Designer.cs b/WinFormsDesigner/Dialogs/IndexDialogs/WebsiteProcessorControl.Designer.cs similarity index 100% rename from WinFormsDesigner/IndexDialogs/WebsiteProcessorControl.Designer.cs rename to WinFormsDesigner/Dialogs/IndexDialogs/WebsiteProcessorControl.Designer.cs diff --git a/WinFormsDesigner/IndexDialogs/WebsiteProcessorControl.cs b/WinFormsDesigner/Dialogs/IndexDialogs/WebsiteProcessorControl.cs similarity index 100% rename from WinFormsDesigner/IndexDialogs/WebsiteProcessorControl.cs rename to WinFormsDesigner/Dialogs/IndexDialogs/WebsiteProcessorControl.cs diff --git a/WinFormsDesigner/IndexDialogs/WebsiteProcessorControl.resx b/WinFormsDesigner/Dialogs/IndexDialogs/WebsiteProcessorControl.resx similarity index 100% rename from WinFormsDesigner/IndexDialogs/WebsiteProcessorControl.resx rename to WinFormsDesigner/Dialogs/IndexDialogs/WebsiteProcessorControl.resx diff --git a/WinFormsDesigner/Dialogs/Login/AudibleLoginDialog.Designer.cs b/WinFormsDesigner/Dialogs/Login/AudibleLoginDialog.Designer.cs new file mode 100644 index 00000000..aa1b7105 --- /dev/null +++ b/WinFormsDesigner/Dialogs/Login/AudibleLoginDialog.Designer.cs @@ -0,0 +1,112 @@ +namespace LibationWinForm_Framework.Dialogs.Login +{ + partial class AudibleLoginDialog + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.passwordLbl = new System.Windows.Forms.Label(); + this.emailLbl = new System.Windows.Forms.Label(); + this.passwordTb = new System.Windows.Forms.TextBox(); + this.emailTb = new System.Windows.Forms.TextBox(); + this.submitBtn = new System.Windows.Forms.Button(); + this.SuspendLayout(); + // + // passwordLbl + // + this.passwordLbl.AutoSize = true; + this.passwordLbl.Location = new System.Drawing.Point(12, 41); + this.passwordLbl.Name = "passwordLbl"; + this.passwordLbl.Size = new System.Drawing.Size(53, 13); + this.passwordLbl.TabIndex = 2; + this.passwordLbl.Text = "Password"; + // + // emailLbl + // + this.emailLbl.AutoSize = true; + this.emailLbl.Location = new System.Drawing.Point(12, 15); + this.emailLbl.Name = "emailLbl"; + this.emailLbl.Size = new System.Drawing.Size(32, 13); + this.emailLbl.TabIndex = 0; + this.emailLbl.Text = "Email"; + // + // passwordTb + // + this.passwordTb.Location = new System.Drawing.Point(71, 38); + this.passwordTb.Name = "passwordTb"; + this.passwordTb.PasswordChar = '*'; + this.passwordTb.Size = new System.Drawing.Size(200, 20); + this.passwordTb.TabIndex = 3; + // + // emailTb + // + this.emailTb.Location = new System.Drawing.Point(71, 12); + this.emailTb.Name = "emailTb"; + this.emailTb.Size = new System.Drawing.Size(200, 20); + this.emailTb.TabIndex = 1; + // + // submitBtn + // + this.submitBtn.Location = new System.Drawing.Point(196, 64); + this.submitBtn.Name = "submitBtn"; + this.submitBtn.Size = new System.Drawing.Size(75, 23); + this.submitBtn.TabIndex = 4; + this.submitBtn.Text = "Submit"; + this.submitBtn.UseVisualStyleBackColor = true; + // + // AudibleLoginDialog + // + this.AcceptButton = this.submitBtn; + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(283, 99); + this.Controls.Add(this.submitBtn); + this.Controls.Add(this.passwordLbl); + this.Controls.Add(this.emailLbl); + this.Controls.Add(this.passwordTb); + this.Controls.Add(this.emailTb); + this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog; + this.MaximizeBox = false; + this.MinimizeBox = false; + this.Name = "AudibleLoginDialog"; + this.ShowIcon = false; + this.ShowInTaskbar = false; + this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; + this.Text = "Audible Login"; + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private System.Windows.Forms.Label passwordLbl; + private System.Windows.Forms.Label emailLbl; + private System.Windows.Forms.TextBox passwordTb; + private System.Windows.Forms.TextBox emailTb; + private System.Windows.Forms.Button submitBtn; + } +} \ No newline at end of file diff --git a/WinFormsDesigner/Dialogs/Login/AudibleLoginDialog.cs b/WinFormsDesigner/Dialogs/Login/AudibleLoginDialog.cs new file mode 100644 index 00000000..c1f41cb9 --- /dev/null +++ b/WinFormsDesigner/Dialogs/Login/AudibleLoginDialog.cs @@ -0,0 +1,20 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Forms; + +namespace LibationWinForm_Framework.Dialogs.Login +{ + public partial class AudibleLoginDialog : Form + { + public AudibleLoginDialog() + { + InitializeComponent(); + } + } +} diff --git a/WinFormsDesigner/Dialogs/Login/AudibleLoginDialog.resx b/WinFormsDesigner/Dialogs/Login/AudibleLoginDialog.resx new file mode 100644 index 00000000..1af7de15 --- /dev/null +++ b/WinFormsDesigner/Dialogs/Login/AudibleLoginDialog.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/WinFormsDesigner/Dialogs/Login/CaptchaDialog.Designer.cs b/WinFormsDesigner/Dialogs/Login/CaptchaDialog.Designer.cs new file mode 100644 index 00000000..a20dc62a --- /dev/null +++ b/WinFormsDesigner/Dialogs/Login/CaptchaDialog.Designer.cs @@ -0,0 +1,102 @@ +namespace LibationWinForm_Framework.Dialogs.Login +{ + partial class CaptchaDialog + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.captchaPb = new System.Windows.Forms.PictureBox(); + this.answerTb = new System.Windows.Forms.TextBox(); + this.submitBtn = new System.Windows.Forms.Button(); + this.answerLbl = new System.Windows.Forms.Label(); + ((System.ComponentModel.ISupportInitialize)(this.captchaPb)).BeginInit(); + this.SuspendLayout(); + // + // captchaPb + // + this.captchaPb.Location = new System.Drawing.Point(12, 12); + this.captchaPb.Name = "captchaPb"; + this.captchaPb.Size = new System.Drawing.Size(429, 186); + this.captchaPb.TabIndex = 0; + this.captchaPb.TabStop = false; + // + // answerTb + // + this.answerTb.Location = new System.Drawing.Point(118, 206); + this.answerTb.Name = "answerTb"; + this.answerTb.Size = new System.Drawing.Size(100, 20); + this.answerTb.TabIndex = 1; + // + // submitBtn + // + this.submitBtn.Location = new System.Drawing.Point(366, 204); + this.submitBtn.Name = "submitBtn"; + this.submitBtn.Size = new System.Drawing.Size(75, 23); + this.submitBtn.TabIndex = 2; + this.submitBtn.Text = "Submit"; + this.submitBtn.UseVisualStyleBackColor = true; + // + // answerLbl + // + this.answerLbl.AutoSize = true; + this.answerLbl.Location = new System.Drawing.Point(12, 209); + this.answerLbl.Name = "answerLbl"; + this.answerLbl.Size = new System.Drawing.Size(100, 13); + this.answerLbl.TabIndex = 0; + this.answerLbl.Text = "CAPTCHA answer: "; + // + // CaptchaDialog + // + this.AcceptButton = this.submitBtn; + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(453, 239); + this.Controls.Add(this.answerLbl); + this.Controls.Add(this.submitBtn); + this.Controls.Add(this.answerTb); + this.Controls.Add(this.captchaPb); + this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog; + this.MaximizeBox = false; + this.MinimizeBox = false; + this.Name = "CaptchaDialog"; + this.ShowIcon = false; + this.ShowInTaskbar = false; + this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; + this.Text = "CAPTCHA"; + ((System.ComponentModel.ISupportInitialize)(this.captchaPb)).EndInit(); + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private System.Windows.Forms.PictureBox captchaPb; + private System.Windows.Forms.TextBox answerTb; + private System.Windows.Forms.Button submitBtn; + private System.Windows.Forms.Label answerLbl; + } +} \ No newline at end of file diff --git a/WinFormsDesigner/Dialogs/Login/CaptchaDialog.cs b/WinFormsDesigner/Dialogs/Login/CaptchaDialog.cs new file mode 100644 index 00000000..0b2e3623 --- /dev/null +++ b/WinFormsDesigner/Dialogs/Login/CaptchaDialog.cs @@ -0,0 +1,20 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Forms; + +namespace LibationWinForm_Framework.Dialogs.Login +{ + public partial class CaptchaDialog : Form + { + public CaptchaDialog() + { + InitializeComponent(); + } + } +} diff --git a/WinFormsDesigner/Dialogs/Login/CaptchaDialog.resx b/WinFormsDesigner/Dialogs/Login/CaptchaDialog.resx new file mode 100644 index 00000000..1af7de15 --- /dev/null +++ b/WinFormsDesigner/Dialogs/Login/CaptchaDialog.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/WinFormsDesigner/Dialogs/Login/_2faCodeDialog.Designer.cs b/WinFormsDesigner/Dialogs/Login/_2faCodeDialog.Designer.cs new file mode 100644 index 00000000..5410bf87 --- /dev/null +++ b/WinFormsDesigner/Dialogs/Login/_2faCodeDialog.Designer.cs @@ -0,0 +1,89 @@ +namespace WinFormsDesigner.Dialogs.Login +{ + partial class _2faCodeDialog + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.submitBtn = new System.Windows.Forms.Button(); + this.codeTb = new System.Windows.Forms.TextBox(); + this.label1 = new System.Windows.Forms.Label(); + this.SuspendLayout(); + // + // submitBtn + // + this.submitBtn.Location = new System.Drawing.Point(15, 51); + this.submitBtn.Name = "submitBtn"; + this.submitBtn.Size = new System.Drawing.Size(79, 23); + this.submitBtn.TabIndex = 1; + this.submitBtn.Text = "Submit"; + this.submitBtn.UseVisualStyleBackColor = true; + // + // codeTb + // + this.codeTb.Location = new System.Drawing.Point(15, 25); + this.codeTb.Name = "codeTb"; + this.codeTb.ScrollBars = System.Windows.Forms.ScrollBars.Both; + this.codeTb.Size = new System.Drawing.Size(79, 20); + this.codeTb.TabIndex = 0; + // + // label1 + // + this.label1.AutoSize = true; + this.label1.Location = new System.Drawing.Point(12, 9); + this.label1.Name = "label1"; + this.label1.Size = new System.Drawing.Size(82, 13); + this.label1.TabIndex = 2; + this.label1.Text = "Enter 2FA Code"; + // + // _2faCodeDialog + // + this.AcceptButton = this.submitBtn; + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(106, 86); + this.Controls.Add(this.label1); + this.Controls.Add(this.codeTb); + this.Controls.Add(this.submitBtn); + this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog; + this.MaximizeBox = false; + this.MinimizeBox = false; + this.Name = "_2faCodeDialog"; + this.ShowIcon = false; + this.ShowInTaskbar = false; + this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; + this.Text = "2FA Code"; + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + private System.Windows.Forms.Button submitBtn; + private System.Windows.Forms.TextBox codeTb; + private System.Windows.Forms.Label label1; + } +} \ No newline at end of file diff --git a/WinFormsDesigner/Dialogs/Login/_2faCodeDialog.cs b/WinFormsDesigner/Dialogs/Login/_2faCodeDialog.cs new file mode 100644 index 00000000..75fcaa73 --- /dev/null +++ b/WinFormsDesigner/Dialogs/Login/_2faCodeDialog.cs @@ -0,0 +1,15 @@ +using System; +using System.Windows.Forms; + +namespace WinFormsDesigner.Dialogs.Login +{ + public partial class _2faCodeDialog : Form + { + public string NewTags { get; private set; } + + public _2faCodeDialog() + { + InitializeComponent(); + } + } +} diff --git a/WinFormsDesigner/Dialogs/Login/_2faCodeDialog.resx b/WinFormsDesigner/Dialogs/Login/_2faCodeDialog.resx new file mode 100644 index 00000000..1af7de15 --- /dev/null +++ b/WinFormsDesigner/Dialogs/Login/_2faCodeDialog.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/WinFormsDesigner/WinFormsDesigner.csproj b/WinFormsDesigner/WinFormsDesigner.csproj index fdc51b34..f1a1660c 100644 --- a/WinFormsDesigner/WinFormsDesigner.csproj +++ b/WinFormsDesigner/WinFormsDesigner.csproj @@ -41,8 +41,10 @@ + + @@ -75,22 +77,40 @@ EditQuickFilters.cs + + Form + + + AudibleLoginDialog.cs + + + Form + + + CaptchaDialog.cs + + + Form + + + _2faCodeDialog.cs + Form EditTagsDialog.cs - + Form - + ScanLibraryDialog.cs - + UserControl - + WebsiteProcessorControl.cs @@ -137,10 +157,19 @@ EditTagsDialog.cs - + + AudibleLoginDialog.cs + + + CaptchaDialog.cs + + + _2faCodeDialog.cs + + ScanLibraryDialog.cs - + WebsiteProcessorControl.cs @@ -157,6 +186,7 @@ +