From cb5fb393f29110a9b52d0587827bb49037db1648 Mon Sep 17 00:00:00 2001 From: bryantbhowell Date: Fri, 14 Apr 2017 09:39:51 -0500 Subject: [PATCH] v1.2.0 Added bulk send capabilities --- Behold Emailer.csproj | 5 +- BeholdEmailer.cs | 39 ++++- Form1.resx | 120 +++++++++++++ Main App.Designer.cs | 351 ++++++++++++++++++++++++++----------- Main App.cs | 323 ++++++++++++++++++++++++++++++---- Main App.resx | 4 +- Properties/AssemblyInfo.cs | 4 +- Tabcmd.cs | 24 ++- app.config | 70 ++++---- 9 files changed, 753 insertions(+), 187 deletions(-) create mode 100644 Form1.resx diff --git a/Behold Emailer.csproj b/Behold Emailer.csproj index f4ab1f5..fe4a400 100644 --- a/Behold Emailer.csproj +++ b/Behold Emailer.csproj @@ -11,7 +11,8 @@ Behold_Emailer Behold Emailer v4.0 - Client + + 512 @@ -50,7 +51,9 @@ + + diff --git a/BeholdEmailer.cs b/BeholdEmailer.cs index 0e48695..dd16168 100644 --- a/BeholdEmailer.cs +++ b/BeholdEmailer.cs @@ -71,7 +71,7 @@ public void log(string l) } } - public void email_file_from_template(string from_user, string to_user, string subject, string simple_message_text, string filename_to_attach) + public void email_file_from_template(string from_user, string[] to_users, string[] cc_users, string[] bcc_users, string subject, string simple_message_text, string filename_to_attach) { string message_text = ""; // Load Text template @@ -93,10 +93,33 @@ public void email_file_from_template(string from_user, string to_user, string su message_text = simple_message_text; } - MailMessage message = new MailMessage(from_user, to_user); + MailMessage message = new MailMessage(from_user, to_users[0]); message.Body = message_text; message.Subject = subject; + var to_collect = message.To; + var cc_collect = message.CC; + var bcc_collect = message.Bcc; + for (var i = 1; i < to_users.Length; i++) + { + var add = new MailAddress(to_users[i]); + to_collect.Add(add); + } + + for (var i = 0; i < cc_users.Length; i++) + { + if (cc_users[i] == "") { continue; } + var add = new MailAddress(cc_users[i]); + cc_collect.Add(add); + } + + for (var i = 0; i < bcc_users.Length; i++) + { + if (bcc_users[i] == "") { continue; } + var add = new MailAddress(bcc_users[i]); + bcc_collect.Add(add); + } + // Load HTML template as alternative if (this.html_email_template_filename != "") { @@ -127,7 +150,7 @@ public void email_file_from_template(string from_user, string to_user, string su public string generate_export_and_watermark(string view_user, string view_location, string content_type, Dictionary view_filter_dictionary, Watermarker watermark) { - string filename_to_attach = this.tabcmd.create_export(content_type, view_location, new Dictionary(), view_user, "exported_workbook"); + string filename_to_attach = this.tabcmd.create_export(content_type, view_location, view_filter_dictionary, view_user, "exported_workbook"); this.log(String.Format("PDF created and saved successfully as {0}", filename_to_attach)); // Watermark the PDF (working copy) @@ -140,14 +163,14 @@ public string generate_export_and_watermark(string view_user, string view_locati return filename_to_attach; } - public bool generate_email_from_view(string email_from_user, string email_to_user, string email_subject, string email_template_name, + public bool generate_email_from_view(string email_from_user, string[] email_to, string[] email_cc, string[] email_bcc, string email_subject, string email_template_name, string view_user, string view_location, string email_content_type, Dictionary view_filter_dictionary, Watermarker watermark) { this.log(String.Format("Creating PDF export from tabcmd for {0} for user {1}", view_location, view_user)); try { - string filename_to_attach = this.generate_export_and_watermark(view_user, view_location, email_content_type, new Dictionary(), watermark); + string filename_to_attach = this.generate_export_and_watermark(view_user, view_location, email_content_type, view_filter_dictionary, watermark); this.log(String.Format("PDF created and saved successfully as {0}", filename_to_attach)); // Copy the file with a new name so that it can be archived @@ -165,8 +188,8 @@ public bool generate_email_from_view(string email_from_user, string email_to_use File.Copy(filename_to_attach, final_filename, true); - this.log(String.Format("Sending e-mail of exported and watermarked PDF to {0}", email_to_user)); - this.email_file_from_template(email_from_user, email_to_user, email_subject, email_template_name, final_filename); + this.log(String.Format("Sending e-mail of exported and watermarked PDF to {0}", email_to[0])); + this.email_file_from_template(email_from_user, email_to, email_cc, email_bcc, email_subject, email_template_name, final_filename); this.log(String.Format("Removing original file {0}", filename_to_attach)); File.Delete(filename_to_attach); @@ -205,7 +228,7 @@ public bool generate_emails_from_named_schedule_in_repository(string schedule_na this.log(String.Format("Generating e-mail of view {0} on site {1} for {2} at {3}", view_location, site, user, user_email)); - bool result = this.generate_email_from_view(from_user, user_email, email_subject, "", user, view_location, "fullpdf", + bool result = this.generate_email_from_view(from_user, new string[1] {user_email}, new string[0]{}, new string[0]{}, email_subject, "", user, view_location, "fullpdf", new Dictionary(), watermarker); if (all_suceeded == true && result == false){ all_suceeded = false; diff --git a/Form1.resx b/Form1.resx new file mode 100644 index 0000000..1af7de1 --- /dev/null +++ b/Form1.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/Main App.Designer.cs b/Main App.Designer.cs index 31c8c70..e88dab2 100644 --- a/Main App.Designer.cs +++ b/Main App.Designer.cs @@ -29,6 +29,9 @@ protected override void Dispose(bool disposing) private void InitializeComponent() { this.components = new System.ComponentModel.Container(); + System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle1 = new System.Windows.Forms.DataGridViewCellStyle(); + System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle2 = new System.Windows.Forms.DataGridViewCellStyle(); + System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle3 = new System.Windows.Forms.DataGridViewCellStyle(); this.saveConfig = new System.Windows.Forms.Button(); this.watermarkContextMenu = new System.Windows.Forms.ContextMenuStrip(this.components); this.textToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); @@ -83,6 +86,16 @@ private void InitializeComponent() this.label3 = new System.Windows.Forms.Label(); this.label10 = new System.Windows.Forms.Label(); this.emailTab = new System.Windows.Forms.TabPage(); + this.label22 = new System.Windows.Forms.Label(); + this.smtpServerTLS = new System.Windows.Forms.ComboBox(); + this.label21 = new System.Windows.Forms.Label(); + this.smtpServerPort = new System.Windows.Forms.TextBox(); + this.label20 = new System.Windows.Forms.Label(); + this.label19 = new System.Windows.Forms.Label(); + this.smtpServerPassword = new System.Windows.Forms.TextBox(); + this.label18 = new System.Windows.Forms.Label(); + this.smtpServerUsername = new System.Windows.Forms.TextBox(); + this.label17 = new System.Windows.Forms.Label(); this.button6 = new System.Windows.Forms.Button(); this.htmlEmailFilename = new System.Windows.Forms.TextBox(); this.textEmailFilename = new System.Windows.Forms.TextBox(); @@ -99,14 +112,12 @@ private void InitializeComponent() this.label15 = new System.Windows.Forms.Label(); this.label14 = new System.Windows.Forms.Label(); this.label13 = new System.Windows.Forms.Label(); - this.testEmailSubject = new System.Windows.Forms.TextBox(); this.testSite = new System.Windows.Forms.TextBox(); this.testFilename = new System.Windows.Forms.TextBox(); this.testViewLocation = new System.Windows.Forms.TextBox(); this.testEmailRecipient = new System.Windows.Forms.TextBox(); this.testUsernameForImpersonation = new System.Windows.Forms.TextBox(); this.label5 = new System.Windows.Forms.Label(); - this.label31 = new System.Windows.Forms.Label(); this.createExport = new System.Windows.Forms.Button(); this.label6 = new System.Windows.Forms.Label(); this.label4 = new System.Windows.Forms.Label(); @@ -125,17 +136,18 @@ private void InitializeComponent() this.label1 = new System.Windows.Forms.Label(); this.availableSchedulesList = new System.Windows.Forms.CheckedListBox(); this.mainTabBar = new System.Windows.Forms.TabControl(); + this.tabPage1 = new System.Windows.Forms.TabPage(); + this.pickBulkCSVFile = new System.Windows.Forms.Button(); + this.sendBulkEmails = new System.Windows.Forms.Button(); + this.bulkEmailPreview = new System.Windows.Forms.DataGridView(); this.toolTip1 = new System.Windows.Forms.ToolTip(this.components); - this.smtpServerUsername = new System.Windows.Forms.TextBox(); - this.label17 = new System.Windows.Forms.Label(); - this.smtpServerPassword = new System.Windows.Forms.TextBox(); - this.label18 = new System.Windows.Forms.Label(); - this.label19 = new System.Windows.Forms.Label(); - this.smtpServerPort = new System.Windows.Forms.TextBox(); - this.label20 = new System.Windows.Forms.Label(); - this.label21 = new System.Windows.Forms.Label(); - this.smtpServerTLS = new System.Windows.Forms.ComboBox(); - this.label22 = new System.Windows.Forms.Label(); + this.Status = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.label31 = new System.Windows.Forms.Label(); + this.testEmailSubject = new System.Windows.Forms.TextBox(); + this.bulkEmailSubject = new System.Windows.Forms.TextBox(); + this.label23 = new System.Windows.Forms.Label(); + this.bulkUsernameToImpersonateAs = new System.Windows.Forms.TextBox(); + this.label24 = new System.Windows.Forms.Label(); this.watermarkContextMenu.SuspendLayout(); this.configureTab.SuspendLayout(); this.configureTabBar.SuspendLayout(); @@ -146,6 +158,8 @@ private void InitializeComponent() this.testTab.SuspendLayout(); this.schedulesTab.SuspendLayout(); this.mainTabBar.SuspendLayout(); + this.tabPage1.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)(this.bulkEmailPreview)).BeginInit(); this.SuspendLayout(); // // saveConfig @@ -687,6 +701,93 @@ private void InitializeComponent() this.emailTab.Text = "E-mail Server"; this.emailTab.UseVisualStyleBackColor = true; // + // label22 + // + this.label22.AutoSize = true; + this.label22.Location = new System.Drawing.Point(6, 195); + this.label22.Name = "label22"; + this.label22.Size = new System.Drawing.Size(111, 13); + this.label22.TabIndex = 73; + this.label22.Text = "Email Body Templates"; + // + // smtpServerTLS + // + this.smtpServerTLS.FormattingEnabled = true; + this.smtpServerTLS.Items.AddRange(new object[] { + "No", + "Yes"}); + this.smtpServerTLS.Location = new System.Drawing.Point(191, 161); + this.smtpServerTLS.Name = "smtpServerTLS"; + this.smtpServerTLS.Size = new System.Drawing.Size(74, 21); + this.smtpServerTLS.TabIndex = 72; + this.smtpServerTLS.Text = "No"; + // + // label21 + // + this.label21.AutoSize = true; + this.label21.Location = new System.Drawing.Point(188, 145); + this.label21.Name = "label21"; + this.label21.Size = new System.Drawing.Size(80, 13); + this.label21.TabIndex = 70; + this.label21.Text = "Use TLS/SSL?"; + // + // smtpServerPort + // + this.smtpServerPort.Location = new System.Drawing.Point(18, 161); + this.smtpServerPort.Name = "smtpServerPort"; + this.smtpServerPort.Size = new System.Drawing.Size(152, 20); + this.smtpServerPort.TabIndex = 67; + // + // label20 + // + this.label20.AutoSize = true; + this.label20.Location = new System.Drawing.Point(15, 145); + this.label20.Name = "label20"; + this.label20.Size = new System.Drawing.Size(160, 13); + this.label20.TabIndex = 68; + this.label20.Text = "SMTP Server Port (if not default)"; + // + // label19 + // + this.label19.AutoSize = true; + this.label19.Location = new System.Drawing.Point(6, 73); + this.label19.Name = "label19"; + this.label19.Size = new System.Drawing.Size(110, 13); + this.label19.TabIndex = 66; + this.label19.Text = "SMTP Server Options"; + // + // smtpServerPassword + // + this.smtpServerPassword.Location = new System.Drawing.Point(191, 113); + this.smtpServerPassword.Name = "smtpServerPassword"; + this.smtpServerPassword.Size = new System.Drawing.Size(152, 20); + this.smtpServerPassword.TabIndex = 64; + // + // label18 + // + this.label18.AutoSize = true; + this.label18.Location = new System.Drawing.Point(188, 97); + this.label18.Name = "label18"; + this.label18.Size = new System.Drawing.Size(120, 13); + this.label18.TabIndex = 65; + this.label18.Text = "SMTP Server Password"; + // + // smtpServerUsername + // + this.smtpServerUsername.Location = new System.Drawing.Point(18, 113); + this.smtpServerUsername.Name = "smtpServerUsername"; + this.smtpServerUsername.Size = new System.Drawing.Size(152, 20); + this.smtpServerUsername.TabIndex = 62; + // + // label17 + // + this.label17.AutoSize = true; + this.label17.Location = new System.Drawing.Point(15, 97); + this.label17.Name = "label17"; + this.label17.Size = new System.Drawing.Size(122, 13); + this.label17.TabIndex = 63; + this.label17.Text = "SMTP Server Username"; + // // button6 // this.button6.Location = new System.Drawing.Point(268, 260); @@ -846,14 +947,6 @@ private void InitializeComponent() this.label13.TabIndex = 54; this.label13.Text = "Test Email"; // - // testEmailSubject - // - this.testEmailSubject.Location = new System.Drawing.Point(26, 165); - this.testEmailSubject.Name = "testEmailSubject"; - this.testEmailSubject.Size = new System.Drawing.Size(152, 20); - this.testEmailSubject.TabIndex = 15; - this.testEmailSubject.Validating += new System.ComponentModel.CancelEventHandler(this.validateTextBox); - // // testSite // this.testSite.Location = new System.Drawing.Point(26, 32); @@ -902,15 +995,6 @@ private void InitializeComponent() this.label5.TabIndex = 11; this.label5.Text = "Site"; // - // label31 - // - this.label31.AutoSize = true; - this.label31.Location = new System.Drawing.Point(23, 149); - this.label31.Name = "label31"; - this.label31.Size = new System.Drawing.Size(95, 13); - this.label31.TabIndex = 53; - this.label31.Text = "Test Email Subject"; - // // createExport // this.createExport.Location = new System.Drawing.Point(219, 272); @@ -1089,98 +1173,143 @@ private void InitializeComponent() this.mainTabBar.Controls.Add(this.schedulesTab); this.mainTabBar.Controls.Add(this.testTab); this.mainTabBar.Controls.Add(this.configureTab); + this.mainTabBar.Controls.Add(this.tabPage1); this.mainTabBar.Location = new System.Drawing.Point(24, 16); this.mainTabBar.Name = "mainTabBar"; this.mainTabBar.SelectedIndex = 0; this.mainTabBar.Size = new System.Drawing.Size(405, 343); this.mainTabBar.TabIndex = 2; // - // smtpServerUsername - // - this.smtpServerUsername.Location = new System.Drawing.Point(18, 113); - this.smtpServerUsername.Name = "smtpServerUsername"; - this.smtpServerUsername.Size = new System.Drawing.Size(152, 20); - this.smtpServerUsername.TabIndex = 62; - // - // label17 + // tabPage1 + // + this.tabPage1.Controls.Add(this.bulkUsernameToImpersonateAs); + this.tabPage1.Controls.Add(this.label24); + this.tabPage1.Controls.Add(this.bulkEmailSubject); + this.tabPage1.Controls.Add(this.label23); + this.tabPage1.Controls.Add(this.pickBulkCSVFile); + this.tabPage1.Controls.Add(this.sendBulkEmails); + this.tabPage1.Controls.Add(this.bulkEmailPreview); + this.tabPage1.Location = new System.Drawing.Point(4, 22); + this.tabPage1.Name = "tabPage1"; + this.tabPage1.Padding = new System.Windows.Forms.Padding(3); + this.tabPage1.Size = new System.Drawing.Size(397, 317); + this.tabPage1.TabIndex = 9; + this.tabPage1.Text = "Bulk"; + this.tabPage1.UseVisualStyleBackColor = true; + this.tabPage1.Click += new System.EventHandler(this.tabPage1_Click); + // + // pickBulkCSVFile + // + this.pickBulkCSVFile.Location = new System.Drawing.Point(272, 87); + this.pickBulkCSVFile.Name = "pickBulkCSVFile"; + this.pickBulkCSVFile.Size = new System.Drawing.Size(116, 23); + this.pickBulkCSVFile.TabIndex = 61; + this.pickBulkCSVFile.Text = "Load from CSV"; + this.pickBulkCSVFile.UseVisualStyleBackColor = true; + this.pickBulkCSVFile.Click += new System.EventHandler(this.pickBulkCSVFile_Click); + // + // sendBulkEmails + // + this.sendBulkEmails.Location = new System.Drawing.Point(6, 288); + this.sendBulkEmails.Name = "sendBulkEmails"; + this.sendBulkEmails.Size = new System.Drawing.Size(75, 23); + this.sendBulkEmails.TabIndex = 3; + this.sendBulkEmails.Text = "Send Emails"; + this.sendBulkEmails.UseVisualStyleBackColor = true; + this.sendBulkEmails.Click += new System.EventHandler(this.sendBulkEmails_Click); + // + // bulkEmailPreview + // + this.bulkEmailPreview.AllowUserToAddRows = false; + this.bulkEmailPreview.AllowUserToDeleteRows = false; + dataGridViewCellStyle1.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleLeft; + dataGridViewCellStyle1.BackColor = System.Drawing.SystemColors.Control; + dataGridViewCellStyle1.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + dataGridViewCellStyle1.ForeColor = System.Drawing.SystemColors.WindowText; + dataGridViewCellStyle1.SelectionBackColor = System.Drawing.SystemColors.Highlight; + dataGridViewCellStyle1.SelectionForeColor = System.Drawing.SystemColors.HighlightText; + dataGridViewCellStyle1.WrapMode = System.Windows.Forms.DataGridViewTriState.True; + this.bulkEmailPreview.ColumnHeadersDefaultCellStyle = dataGridViewCellStyle1; + this.bulkEmailPreview.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize; + this.bulkEmailPreview.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] { + this.Status}); + dataGridViewCellStyle2.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleLeft; + dataGridViewCellStyle2.BackColor = System.Drawing.SystemColors.Window; + dataGridViewCellStyle2.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + dataGridViewCellStyle2.ForeColor = System.Drawing.SystemColors.ControlText; + dataGridViewCellStyle2.SelectionBackColor = System.Drawing.SystemColors.Highlight; + dataGridViewCellStyle2.SelectionForeColor = System.Drawing.SystemColors.HighlightText; + dataGridViewCellStyle2.WrapMode = System.Windows.Forms.DataGridViewTriState.False; + this.bulkEmailPreview.DefaultCellStyle = dataGridViewCellStyle2; + this.bulkEmailPreview.Location = new System.Drawing.Point(3, 116); + this.bulkEmailPreview.Name = "bulkEmailPreview"; + this.bulkEmailPreview.ReadOnly = true; + dataGridViewCellStyle3.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleLeft; + dataGridViewCellStyle3.BackColor = System.Drawing.SystemColors.Control; + dataGridViewCellStyle3.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + dataGridViewCellStyle3.ForeColor = System.Drawing.SystemColors.WindowText; + dataGridViewCellStyle3.SelectionBackColor = System.Drawing.SystemColors.Highlight; + dataGridViewCellStyle3.SelectionForeColor = System.Drawing.SystemColors.HighlightText; + dataGridViewCellStyle3.WrapMode = System.Windows.Forms.DataGridViewTriState.True; + this.bulkEmailPreview.RowHeadersDefaultCellStyle = dataGridViewCellStyle3; + this.bulkEmailPreview.ShowEditingIcon = false; + this.bulkEmailPreview.Size = new System.Drawing.Size(385, 166); + this.bulkEmailPreview.TabIndex = 1; + // + // Status + // + this.Status.HeaderText = "Status"; + this.Status.Name = "Status"; + this.Status.ReadOnly = true; // - this.label17.AutoSize = true; - this.label17.Location = new System.Drawing.Point(15, 97); - this.label17.Name = "label17"; - this.label17.Size = new System.Drawing.Size(122, 13); - this.label17.TabIndex = 63; - this.label17.Text = "SMTP Server Username"; - // - // smtpServerPassword - // - this.smtpServerPassword.Location = new System.Drawing.Point(191, 113); - this.smtpServerPassword.Name = "smtpServerPassword"; - this.smtpServerPassword.Size = new System.Drawing.Size(152, 20); - this.smtpServerPassword.TabIndex = 64; - // - // label18 - // - this.label18.AutoSize = true; - this.label18.Location = new System.Drawing.Point(188, 97); - this.label18.Name = "label18"; - this.label18.Size = new System.Drawing.Size(120, 13); - this.label18.TabIndex = 65; - this.label18.Text = "SMTP Server Password"; - // - // label19 + // label31 // - this.label19.AutoSize = true; - this.label19.Location = new System.Drawing.Point(6, 73); - this.label19.Name = "label19"; - this.label19.Size = new System.Drawing.Size(110, 13); - this.label19.TabIndex = 66; - this.label19.Text = "SMTP Server Options"; + this.label31.AutoSize = true; + this.label31.Location = new System.Drawing.Point(23, 149); + this.label31.Name = "label31"; + this.label31.Size = new System.Drawing.Size(95, 13); + this.label31.TabIndex = 53; + this.label31.Text = "Test Email Subject"; // - // smtpServerPort + // testEmailSubject // - this.smtpServerPort.Location = new System.Drawing.Point(18, 161); - this.smtpServerPort.Name = "smtpServerPort"; - this.smtpServerPort.Size = new System.Drawing.Size(152, 20); - this.smtpServerPort.TabIndex = 67; + this.testEmailSubject.Location = new System.Drawing.Point(26, 165); + this.testEmailSubject.Name = "testEmailSubject"; + this.testEmailSubject.Size = new System.Drawing.Size(152, 20); + this.testEmailSubject.TabIndex = 15; + this.testEmailSubject.Validating += new System.ComponentModel.CancelEventHandler(this.validateTextBox); // - // label20 + // bulkEmailSubject // - this.label20.AutoSize = true; - this.label20.Location = new System.Drawing.Point(15, 145); - this.label20.Name = "label20"; - this.label20.Size = new System.Drawing.Size(160, 13); - this.label20.TabIndex = 68; - this.label20.Text = "SMTP Server Port (if not default)"; + this.bulkEmailSubject.Location = new System.Drawing.Point(9, 31); + this.bulkEmailSubject.Name = "bulkEmailSubject"; + this.bulkEmailSubject.Size = new System.Drawing.Size(152, 20); + this.bulkEmailSubject.TabIndex = 62; // - // label21 + // label23 // - this.label21.AutoSize = true; - this.label21.Location = new System.Drawing.Point(188, 145); - this.label21.Name = "label21"; - this.label21.Size = new System.Drawing.Size(80, 13); - this.label21.TabIndex = 70; - this.label21.Text = "Use TLS/SSL?"; + this.label23.AutoSize = true; + this.label23.Location = new System.Drawing.Point(6, 15); + this.label23.Name = "label23"; + this.label23.Size = new System.Drawing.Size(71, 13); + this.label23.TabIndex = 63; + this.label23.Text = "Email Subject"; // - // smtpServerTLS + // bulkUsernameToImpersonateAs // - this.smtpServerTLS.FormattingEnabled = true; - this.smtpServerTLS.Items.AddRange(new object[] { - "No", - "Yes"}); - this.smtpServerTLS.Location = new System.Drawing.Point(191, 161); - this.smtpServerTLS.Name = "smtpServerTLS"; - this.smtpServerTLS.Size = new System.Drawing.Size(74, 21); - this.smtpServerTLS.TabIndex = 72; - this.smtpServerTLS.Text = "No"; + this.bulkUsernameToImpersonateAs.Location = new System.Drawing.Point(9, 79); + this.bulkUsernameToImpersonateAs.Name = "bulkUsernameToImpersonateAs"; + this.bulkUsernameToImpersonateAs.Size = new System.Drawing.Size(152, 20); + this.bulkUsernameToImpersonateAs.TabIndex = 64; // - // label22 + // label24 // - this.label22.AutoSize = true; - this.label22.Location = new System.Drawing.Point(6, 195); - this.label22.Name = "label22"; - this.label22.Size = new System.Drawing.Size(111, 13); - this.label22.TabIndex = 73; - this.label22.Text = "Email Body Templates"; + this.label24.AutoSize = true; + this.label24.Location = new System.Drawing.Point(6, 63); + this.label24.Name = "label24"; + this.label24.Size = new System.Drawing.Size(143, 13); + this.label24.TabIndex = 65; + this.label24.Text = "Username to Impersonate As"; // // Configure // @@ -1209,6 +1338,9 @@ private void InitializeComponent() this.schedulesTab.ResumeLayout(false); this.schedulesTab.PerformLayout(); this.mainTabBar.ResumeLayout(false); + this.tabPage1.ResumeLayout(false); + this.tabPage1.PerformLayout(); + ((System.ComponentModel.ISupportInitialize)(this.bulkEmailPreview)).EndInit(); this.ResumeLayout(false); } @@ -1282,14 +1414,12 @@ private void InitializeComponent() private System.Windows.Forms.TabPage testTab; private System.Windows.Forms.Label label14; private System.Windows.Forms.Label label13; - private System.Windows.Forms.TextBox testEmailSubject; private System.Windows.Forms.TextBox testSite; private System.Windows.Forms.TextBox testFilename; private System.Windows.Forms.TextBox testViewLocation; private System.Windows.Forms.TextBox testEmailRecipient; private System.Windows.Forms.TextBox testUsernameForImpersonation; private System.Windows.Forms.Label label5; - private System.Windows.Forms.Label label31; private System.Windows.Forms.Button createExport; private System.Windows.Forms.Label label6; private System.Windows.Forms.Label label4; @@ -1322,6 +1452,17 @@ private void InitializeComponent() private System.Windows.Forms.Label label17; private System.Windows.Forms.Label label22; private System.Windows.Forms.ComboBox smtpServerTLS; + private System.Windows.Forms.TabPage tabPage1; + private System.Windows.Forms.DataGridView bulkEmailPreview; + private System.Windows.Forms.Button sendBulkEmails; + private System.Windows.Forms.Button pickBulkCSVFile; + private System.Windows.Forms.DataGridViewTextBoxColumn Status; + private System.Windows.Forms.TextBox testEmailSubject; + private System.Windows.Forms.Label label31; + private System.Windows.Forms.TextBox bulkUsernameToImpersonateAs; + private System.Windows.Forms.Label label24; + private System.Windows.Forms.TextBox bulkEmailSubject; + private System.Windows.Forms.Label label23; } } diff --git a/Main App.cs b/Main App.cs index b3a8e7a..17b7c27 100644 --- a/Main App.cs +++ b/Main App.cs @@ -466,43 +466,77 @@ private void send_test_email(object sender, EventArgs e) /* * Main E-mailing methods (used by test and schedule) - */ - public bool send_email(string schedule_name) + */ + + public SmtpClient create_smtp_client_from_config() { + SmtpClient smtp_client = new SmtpClient(emailServer.Text); + // Set all of the SMTP Server options + if (smtpServerPort.Text != "") + { + smtp_client.Port = Int32.Parse(smtpServerPort.Text); + } + if (smtpServerTLS.Text == "Yes") + { + smtp_client.EnableSsl = true; + } + if (smtpServerUsername.Text != "" && smtpServerPassword.Text != "") + { + smtp_client.Credentials = new System.Net.NetworkCredential(smtpServerUsername.Text, smtpServerPassword.Text); + } + return smtp_client; + } - try + private BeholdEmailer create_behold_emailer_from_config() + { + TableauRepository tabrep = new TableauRepository(tableau_server_url.Text, repositoryPW.Text, "readonly"); + tabrep.logger = this.logger; + Tabcmd tabcmd = new Tabcmd(tabcmdProgramLocation.Text, tableau_server_url.Text, server_admin_username.Text, server_password.Text, testSite.Text, + tabcmdConfigLocation.Text, tabrep, this.logger); + + + BeholdEmailer tabemailer = new BeholdEmailer(tabcmd, this.create_smtp_client_from_config()); + tabemailer.logger = this.logger; + tabemailer.html_email_template_filename = htmlEmailFilename.Text; + tabemailer.text_email_template_filename = textEmailFilename.Text; + return tabemailer; + } + + private BeholdEmailer create_behold_emailer_from_config(string site) + { + TableauRepository tabrep = new TableauRepository(tableau_server_url.Text, repositoryPW.Text, "readonly"); + tabrep.logger = this.logger; + Tabcmd tabcmd = new Tabcmd(tabcmdProgramLocation.Text, tableau_server_url.Text, server_admin_username.Text, server_password.Text, site, + tabcmdConfigLocation.Text, tabrep, this.logger); + + + BeholdEmailer tabemailer = new BeholdEmailer(tabcmd, this.create_smtp_client_from_config()); + tabemailer.logger = this.logger; + tabemailer.html_email_template_filename = htmlEmailFilename.Text; + tabemailer.text_email_template_filename = textEmailFilename.Text; + return tabemailer; + } + + private Watermarker create_watermarker_from_config() + { + Watermarker wm = new Watermarker(); + string[] page_locations = { "top_left", "top_center", "top_right", "bottom_left", "bottom_center", "bottom_right" }; + foreach (string page_location in page_locations) { - TableauRepository tabrep = new TableauRepository(tableau_server_url.Text, repositoryPW.Text, "readonly"); - tabrep.logger = this.logger; - Tabcmd tabcmd = new Tabcmd(tabcmdProgramLocation.Text, tableau_server_url.Text, server_admin_username.Text, server_password.Text, testSite.Text, - tabcmdConfigLocation.Text, tabrep, this.logger); - SmtpClient smtp_client = new SmtpClient(emailServer.Text); - // Set all of the SMTP Server options - if (smtpServerPort.Text != "") - { - smtp_client.Port = Int32.Parse(smtpServerPort.Text); - } - if (smtpServerTLS.Text == "Yes") - { - smtp_client.EnableSsl = true; - } - if (smtpServerUsername.Text != "" && smtpServerPassword.Text != "") - { - smtp_client.Credentials = new System.Net.NetworkCredential(smtpServerUsername.Text, smtpServerPassword.Text); - } - BeholdEmailer tabemailer = new BeholdEmailer(tabcmd, smtp_client); - tabemailer.logger = this.logger; - tabemailer.html_email_template_filename = htmlEmailFilename.Text; - tabemailer.text_email_template_filename = textEmailFilename.Text; - Watermarker wm = new Watermarker(); - string[] page_locations = { "top_left", "top_center", "top_right", "bottom_left", "bottom_center", "bottom_right" }; - foreach (string page_location in page_locations) - { + string settingsPageLocation = page_location.Split('_')[0] + page_location.Split('_')[1].First() + page_location.Split('_')[1].Substring(1); + wm.setPageLocationWatermarkFromConfig(page_location, Configurator.GetConfigSerializableStringDict(settingsPageLocation)); + } + return wm; + } - string settingsPageLocation = page_location.Split('_')[0] + page_location.Split('_')[1].First() + page_location.Split('_')[1].Substring(1); - wm.setPageLocationWatermarkFromConfig(page_location, Configurator.GetConfigSerializableStringDict(settingsPageLocation)); - } + public bool send_email(string schedule_name) + { + + try + { + BeholdEmailer tabemailer = this.create_behold_emailer_from_config(); + Watermarker wm = this.create_watermarker_from_config(); try { @@ -517,7 +551,7 @@ public bool send_email(string schedule_name) else { - result = tabemailer.generate_email_from_view(emailSender.Text, testEmailRecipient.Text, testEmailSubject.Text, "Please see attached Tableau PDF", testUsernameForImpersonation.Text, + result = tabemailer.generate_email_from_view(emailSender.Text, new string[1]{testEmailRecipient.Text}, new string[0]{}, new string[0]{}, testEmailSubject.Text, "Please see attached Tableau PDF", testUsernameForImpersonation.Text, testViewLocation.Text, "fullpdf", new Dictionary(), wm); } @@ -538,6 +572,159 @@ public bool send_email(string schedule_name) } + public bool send_email() + { + try + { + BeholdEmailer tabemailer = this.create_behold_emailer_from_config(); + Watermarker wm = this.create_watermarker_from_config(); + + try + { + bool result; + + + result = tabemailer.generate_email_from_view(emailSender.Text, new string[1] { testEmailRecipient.Text }, new string[0] { }, new string[0] { }, testEmailSubject.Text, "Please see attached Tableau PDF", testUsernameForImpersonation.Text, + testViewLocation.Text, "fullpdf", new Dictionary(), wm); + + return result; + } + catch (ConfigurationException ce) + { + + this.logger.Log(ce.Message); + return false; + } + } + // From Repository Failing + catch (ConfigurationException ce) + { + this.logger.Log(ce.Message); + return false; + } + } + + public bool send_email(string site, string[] email_to, string[] email_cc, string[] email_bcc, string email_subject, string username_for_impersonation, string view_location, Dictionary view_filter_dictionary) + { + try + { + BeholdEmailer tabemailer = this.create_behold_emailer_from_config(site); + Watermarker wm = this.create_watermarker_from_config(); + + try + { + bool result; + + + result = tabemailer.generate_email_from_view(emailSender.Text, email_to, email_cc, email_bcc, email_subject, "Please see attached Tableau PDF", username_for_impersonation, + view_location, "fullpdf", view_filter_dictionary, wm); + + return result; + } + catch (ConfigurationException ce) + { + + this.logger.Log(ce.Message); + return false; + } + } + // From Repository Failing + catch (ConfigurationException ce) + { + this.logger.Log(ce.Message); + return false; + } + } + + + /* + * Bulk Send Tab + */ + private void loadCSV_Click(object sender, EventArgs e) + { + + } + + private void sendBulkEmails_Click(object sender, EventArgs e) + { + // Reset the sending messages + foreach (DataGridViewRow row in bulkEmailPreview.Rows) + { + row.Cells["Status"].Value = ""; + } + // Run through and send the e-mails + foreach (DataGridViewRow row in bulkEmailPreview.Rows) + { + row.Cells["Status"].Value = "Sending..."; + row.Selected = true; + string raw_to = (string)row.Cells["To:"].Value.ToString(); + if (raw_to == null) + { + continue; + } + var email_to = raw_to.Split(';'); + string raw_cc = (string)row.Cells["CC:"].Value.ToString(); + var email_cc = raw_cc.Split(';'); + string raw_bcc = (string)row.Cells["BCC:"].Value.ToString(); + var email_bcc = raw_bcc.Split(';'); + string view_location = (string)row.Cells["View Location"].Value.ToString(); + string site = (string)row.Cells["Site"].Value.ToString(); + + // Skip if there is no view location or site + if (view_location == "" || site == "") + { + row.Cells["Status"].Value = "Invalid"; + row.Selected = false; + continue; + } + + // Implement multiple to + + + Dictionary filters_dict = new Dictionary(); + + // Up to 25 filters (no one would realistically go this high) + int j = 1; + while (j <= 25){ + string filter_field_key = String.Format("Filter Field Name {0}", j.ToString()); + string filter_values_key = String.Format("Filter Values {0}", j.ToString()); + if (!bulkEmailPreview.Columns.Contains(filter_field_key) || !bulkEmailPreview.Columns.Contains(filter_values_key)) + { + break; + } + if (row.Cells[filter_field_key].ValueType != typeof(DBNull)){ + string filter_field_name = (string)row.Cells[filter_field_key].Value.ToString(); + + string filter_values_list_raw = (string)row.Cells[filter_values_key].Value.ToString(); + + + // Swap the semi-colons for commas as needed in the dict + string[] filter_values_list = filter_values_list_raw.Split(';'); + // Skip if there's nothing in the first split value + if (filter_values_list[0] == "") + { + j++; + continue; + } + string[] encoded_filters = new string[filter_values_list.Length]; + for (int i = 0; i < filter_values_list.Length; i++) + { + // Gotta double the % sign because batch files use %2 as a replacement token. + encoded_filters[i] = Uri.EscapeUriString(filter_values_list[i]).Replace("%", "%%"); + } + // Figure out how not to add if empty + string final_value_param = String.Join(",", encoded_filters); + + filters_dict.Add(filter_field_name, final_value_param); + } + j++; + } + + this.send_email(site, email_to, email_cc, email_bcc, bulkEmailSubject.Text, bulkUsernameToImpersonateAs.Text, view_location, filters_dict); + row.Cells["Status"].Value = "Sent"; + row.Selected = false; + } + } /* * Tableau Server Settings Tab Events */ @@ -583,6 +770,72 @@ private void htmlEmailTemplateButton_Click(object sender, EventArgs e) } } + private void pickBulkCSVFile_Click(object sender, EventArgs e) + { + DialogResult result = htmlEmailPicker.ShowDialog(); + if (result == DialogResult.OK) + { + string filename = htmlEmailPicker.FileName; + // Graciously taken from https://social.msdn.microsoft.com/Forums/vstudio/en-US/859ff0ed-40f9-41df-bf81-b8413465d053/csv-import-using-c?forum=csharpgeneral + System.Data.Odbc.OdbcConnection conn; + DataTable dt = new DataTable(); + System.Data.Odbc.OdbcDataAdapter da; + string file = System.IO.Path.GetFileName(filename); + string folder = System.IO.Path.GetDirectoryName(filename); + + + // Gotta construct a schema.ini file that specifies everything come in as text + // http://stackoverflow.com/questions/1688497/load-csv-into-oledb-and-force-all-inferred-datatypes-to-string + + // Open connection once to get the schema info + conn = new System.Data.Odbc.OdbcConnection(@"Driver={Microsoft Text Driver (*.txt; *.csv)};Dbq=" + folder + ";Extensions=asc,csv,tab,txt;Persist Security Info=False;"); + da = new System.Data.Odbc.OdbcDataAdapter("select * from [" + file + "]", conn); + da.Fill(dt); + + StringBuilder schema = new StringBuilder(); + schema.AppendLine("[" + file + "]"); + schema.AppendLine("ColNameHeader=True"); + // Validate that the minimum headers exist + Dictionary required_fields = new Dictionary { {"To:", false}, {"CC:", false}, {"BCC:", false}, + {"Site", false}, {"View Location", false}}; + for (int i = 0; i < dt.Columns.Count; i++) + { + if (required_fields.ContainsKey(dt.Columns[i].ColumnName)) + { + required_fields[dt.Columns[i].ColumnName] = true; + } + } + + // Break if headers not correct + + if (required_fields.ContainsValue(false)) + { + MessageBox.Show("CSV headers are not correct. The correct format is:\nTo:,CC:,BCC:,Site,View Location,Filter Field Name 1,Filter Values 1,..."); + return; + } + + + for (int i = 0; i < dt.Columns.Count; i++) + { + schema.AppendLine("col" + (i + 1).ToString() + "=\"" + dt.Columns[i].ColumnName + "\" Text"); + } + string schemaFileName = folder + @"\Schema.ini"; + TextWriter tw = new StreamWriter(schemaFileName); + tw.WriteLine(schema.ToString()); + tw.Close(); + + // Open again, schema.ini should be in use + DataTable dt2 = new DataTable(); + conn = new System.Data.Odbc.OdbcConnection(@"Driver={Microsoft Text Driver (*.txt; *.csv)};Dbq=" + folder + ";Extensions=asc,csv,tab,txt;Persist Security Info=False;"); + da = new System.Data.Odbc.OdbcDataAdapter("select * from [" + file + "]", conn); + da.Fill(dt2); + bulkEmailPreview.DataSource = dt2; + // Clean out the schema file + File.Delete(schemaFileName); + } + + } + private void validateTextBox(object sender, CancelEventArgs e) { TextBox t = (TextBox)sender; @@ -737,6 +990,10 @@ private void button1_Click(object sender, EventArgs e) Configurator.EncryptConfig(); } + private void tabPage1_Click(object sender, EventArgs e) + { + + } } } diff --git a/Main App.resx b/Main App.resx index f9a42bd..bb949fc 100644 --- a/Main App.resx +++ b/Main App.resx @@ -138,7 +138,7 @@ 1126, 17 - - 1126, 17 + + True \ No newline at end of file diff --git a/Properties/AssemblyInfo.cs b/Properties/AssemblyInfo.cs index aee52b5..27df52e 100644 --- a/Properties/AssemblyInfo.cs +++ b/Properties/AssemblyInfo.cs @@ -32,5 +32,5 @@ // You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.0.0.0")] +[assembly: AssemblyVersion("1.2.0.0")] +[assembly: AssemblyFileVersion("1.2.0.0")] diff --git a/Tabcmd.cs b/Tabcmd.cs index 0894357..520ebed 100644 --- a/Tabcmd.cs +++ b/Tabcmd.cs @@ -8,6 +8,8 @@ using System.Runtime.Serialization.Json; using Npgsql; using System.Diagnostics; +using System.Net; +using System.Web; namespace Behold_Emailer { @@ -167,6 +169,26 @@ public string build_export_cmd(string export_type, string filename, string view_ string additional_url_params = ""; if (view_filter_dictionary != null) { + + // WebUtility.HtmlEncode + var first_param = 0; + foreach (KeyValuePair pair in view_filter_dictionary) + { + if (first_param == 0){ + additional_url_params += "?"; + first_param++; + } + else { + additional_url_params += "&"; + } + // Gotta double the % sign because batch files use %2 as a replacement token. + additional_url_params += Uri.EscapeUriString(pair.Key).Replace("%","%%") + "=" + (pair.Value); + } + + if (refresh == true) + { + additional_url_params += "&:refresh"; + } } else if (view_filter_dictionary == null) { @@ -241,7 +263,7 @@ public string create_export(string export_type, string view_location, //cmds[1] = String.Format("del \"{0}\"", saved_filename); cmds[1] = this.build_export_cmd(export_type, saved_filename, view_location, view_filter_dictionary, false); - + try { File.WriteAllLines("export.bat", cmds); diff --git a/app.config b/app.config index 6a11636..bf72d8a 100644 --- a/app.config +++ b/app.config @@ -1,105 +1,105 @@ - + - -
-
+ +
+
- + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - \ No newline at end of file +