From c303e44d4b75ab4ecfb1a4e4ab65a9eba30288aa Mon Sep 17 00:00:00 2001 From: "G\\Matt" Date: Wed, 8 Apr 2020 18:01:00 +0100 Subject: [PATCH] no message --- .../Olive.Aws.Ses.AutoFetch.Tests.csproj | 15 +++ Olive.Aws.Ses.AutoFetch.Tests/UnitTest1.cs | 18 ++++ .../AwsSesEmailDispatcher.cs | 52 +++++------ .../DatabaseTableService.cs | 29 ++++++ Olive.Aws.Ses.AutoFetch/EmailAccount.cs | 39 ++++++++ Olive.Aws.Ses.AutoFetch/EmailAccount_T.cs | 15 +++ Olive.Aws.Ses.AutoFetch/FetchClient.cs | 93 +++++++++++++++++++ Olive.Aws.Ses.AutoFetch/IMailMessage.cs | 19 ++++ Olive.Aws.Ses.AutoFetch/MailMessage.cs | 11 +++ .../Olive.Aws.Ses.AutoFetch.csproj | 9 +- 10 files changed, 268 insertions(+), 32 deletions(-) create mode 100644 Olive.Aws.Ses.AutoFetch.Tests/Olive.Aws.Ses.AutoFetch.Tests.csproj create mode 100644 Olive.Aws.Ses.AutoFetch.Tests/UnitTest1.cs create mode 100644 Olive.Aws.Ses.AutoFetch/DatabaseTableService.cs create mode 100644 Olive.Aws.Ses.AutoFetch/EmailAccount.cs create mode 100644 Olive.Aws.Ses.AutoFetch/EmailAccount_T.cs create mode 100644 Olive.Aws.Ses.AutoFetch/FetchClient.cs create mode 100644 Olive.Aws.Ses.AutoFetch/IMailMessage.cs create mode 100644 Olive.Aws.Ses.AutoFetch/MailMessage.cs diff --git a/Olive.Aws.Ses.AutoFetch.Tests/Olive.Aws.Ses.AutoFetch.Tests.csproj b/Olive.Aws.Ses.AutoFetch.Tests/Olive.Aws.Ses.AutoFetch.Tests.csproj new file mode 100644 index 000000000..e53258255 --- /dev/null +++ b/Olive.Aws.Ses.AutoFetch.Tests/Olive.Aws.Ses.AutoFetch.Tests.csproj @@ -0,0 +1,15 @@ + + + + netcoreapp3.1 + + false + + + + + + + + + diff --git a/Olive.Aws.Ses.AutoFetch.Tests/UnitTest1.cs b/Olive.Aws.Ses.AutoFetch.Tests/UnitTest1.cs new file mode 100644 index 000000000..25fc56b54 --- /dev/null +++ b/Olive.Aws.Ses.AutoFetch.Tests/UnitTest1.cs @@ -0,0 +1,18 @@ +using NUnit.Framework; + +namespace Olive.Aws.Ses.AutoFetch.Tests +{ + public class Tests + { + [SetUp] + public void Setup() + { + } + + [Test] + public void Test1() + { + Assert.Pass(); + } + } +} \ No newline at end of file diff --git a/Olive.Aws.Ses.AutoFetch/AwsSesEmailDispatcher.cs b/Olive.Aws.Ses.AutoFetch/AwsSesEmailDispatcher.cs index 88bd2d338..24b16c7ea 100644 --- a/Olive.Aws.Ses.AutoFetch/AwsSesEmailDispatcher.cs +++ b/Olive.Aws.Ses.AutoFetch/AwsSesEmailDispatcher.cs @@ -1,49 +1,41 @@ -using Amazon.SimpleEmail; -using Amazon.SimpleEmail.Model; -using Olive.Email; +using Olive.Email; using System; +using System.Collections.Generic; using System.Linq; using System.Net.Mail; using System.Threading.Tasks; -namespace Olive.Aws.Ses +namespace Olive.Aws.Ses.AutoFetch { - public class AwsSesEmailDispatcher : IEmailDispatcher + public class Mailbox { - public async Task Dispatch(MailMessage mail, IEmailMessage _) + static List Accounts = new List(); + public static void Watch(string emailS3Bucket) { - var request = CreateEmailRequest(mail); + DatabaseTableService.EnsureDatabaseTable(); + Watch(emailS3Bucket); + } - using (var client = new AmazonSimpleEmailServiceClient()) - { - var response = await client.SendEmailAsync(request); - if (response.HttpStatusCode != System.Net.HttpStatusCode.OK) - throw new Exception("Failed to send an email: " + response.HttpStatusCode); - } + public static void Watch(string emailS3Bucket) where TMailMessage : IMailMessage, new() + { + Accounts.Add(new EmailAccount(emailS3Bucket)); } - SendEmailRequest CreateEmailRequest(MailMessage mail) + public static async Task FetchAll() { - return new SendEmailRequest + foreach (var account in Accounts) { - Source = mail.From.Address, - Destination = new Destination + try { - ToAddresses = mail.To.Select(t => t.Address).ToList() - }, - Message = new Message + Log.For(typeof(Mailbox)).Info("Fetching emails for " + account.S3Bucket); + await FetchClient.Fetch(account); + Log.For(typeof(Mailbox)).Info("Fetched emails for " + account.S3Bucket); + } + catch (Exception ex) { - Subject = new Content(mail.Subject), - Body = new Body - { - Html = new Content - { - Charset = "UTF-8", - Data = mail.Body - } - } + Log.For(typeof(Mailbox)).Error(ex); } - }; + } } } } diff --git a/Olive.Aws.Ses.AutoFetch/DatabaseTableService.cs b/Olive.Aws.Ses.AutoFetch/DatabaseTableService.cs new file mode 100644 index 000000000..53032c44b --- /dev/null +++ b/Olive.Aws.Ses.AutoFetch/DatabaseTableService.cs @@ -0,0 +1,29 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Threading.Tasks; + +namespace Olive.Aws.Ses.AutoFetch +{ + class DatabaseTableService + { + const string CREATE_TABLE_COMMAND = @" +if not exists (select * from sysobjects where name='MailMessages' and xtype='U') +/****** Object: Table [dbo].[MailMessages] ******/ +CREATE TABLE [dbo].[MailMessages]( + [From] [nvarchar](1000) NOT NULL, + [Subject] [nvarchar](1000) NOT NULL, + [To] [nvarchar](1000) NOT NULL, + [Bcc] [nvarchar](1000) NULL, + [Cc] [nvarchar](1000) NULL, + [Date] [datetime] NOT NULL, + [Sender] [nvarchar](300) NULL, + [Body] [nvarchar](max) NULL, +) ON [PRIMARY] + +GO + +"; + internal static Task EnsureDatabaseTable() => Entities.Data.DataAccess.Create().ExecuteNonQuery(CREATE_TABLE_COMMAND); + } +} diff --git a/Olive.Aws.Ses.AutoFetch/EmailAccount.cs b/Olive.Aws.Ses.AutoFetch/EmailAccount.cs new file mode 100644 index 000000000..28be9d046 --- /dev/null +++ b/Olive.Aws.Ses.AutoFetch/EmailAccount.cs @@ -0,0 +1,39 @@ +using MimeKit; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace Olive.Aws.Ses.AutoFetch +{ + class EmailAccount + { + public string S3Bucket { get; private set; } + EmailAccount() + { + + } + + internal EmailAccount(string s3Bucket) + { + S3Bucket = s3Bucket; + } + + protected virtual IMailMessage CreateMailMessageInstance() => new MailMessage(); + + internal IMailMessage CreateMailMessage(MimeMessage message) + { + var result = CreateMailMessageInstance(); + + result.From = message.From.Select(f => f.Name).ToString(","); + result.To = message.To.Select(f => f.Name).ToString(","); + result.HtmlBody = message.HtmlBody; + result.Date = message.Date.DateTime; + result.Sender = message.Sender.Name; + result.Subject = message.Subject; + + + return result; + } + } +} diff --git a/Olive.Aws.Ses.AutoFetch/EmailAccount_T.cs b/Olive.Aws.Ses.AutoFetch/EmailAccount_T.cs new file mode 100644 index 000000000..d05a364c8 --- /dev/null +++ b/Olive.Aws.Ses.AutoFetch/EmailAccount_T.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace Olive.Aws.Ses.AutoFetch +{ + class EmailAccount : EmailAccount where TMailMessage : IMailMessage, new() + { + internal EmailAccount(string s3Bucket) : base(s3Bucket) + { + } + + internal override IMailMessage CreateMailMessageInstance() => new TMailMessage(); + } +} diff --git a/Olive.Aws.Ses.AutoFetch/FetchClient.cs b/Olive.Aws.Ses.AutoFetch/FetchClient.cs new file mode 100644 index 000000000..626678c80 --- /dev/null +++ b/Olive.Aws.Ses.AutoFetch/FetchClient.cs @@ -0,0 +1,93 @@ +using Olive.Entities.Data; +using Olive; +using System; +using System.Collections.Generic; +using System.Text; +using System.Threading.Tasks; +using Newtonsoft.Json; +using MimeKit; +using System.IO; + +namespace Olive.Aws.Ses.AutoFetch +{ + class FetchClient : IDisposable + { + EmailAccount Account; + Amazon.S3.AmazonS3Client S3Client; + Database Database => Olive.Context.Current.Database(); + FetchClient() + { + S3Client = new Amazon.S3.AmazonS3Client(); + } + + internal static async Task Fetch(EmailAccount account) + { + using (var client = new FetchClient { Account = account }) + await client.Fetch(); + } + + void LogInfo(string log) => Log.For(this).Info(log); + + private async Task Fetch() + { + var isEmpty = false; + while (!isEmpty) + { + LogInfo($"Downloading from " + Account.S3Bucket); + var request = new Amazon.S3.Model.ListObjectsV2Request { BucketName = Account.S3Bucket }; + var response = await S3Client.ListObjectsV2Async(request); + + LogInfo($"Downloaded {response.S3Objects.Count} items from " + Account.S3Bucket); + + foreach (var item in response.S3Objects) + { + await Fetch(item); + } + + Log.For(this).Info($"Downloaded {response.S3Objects.Count} items from " + Account.S3Bucket); + + isEmpty = response.NextContinuationToken.IsEmpty(); + + if (isEmpty) + Log.For("Downloaded all the objects from " + Account.S3Bucket); + } + } + + async Task Fetch(Amazon.S3.Model.S3Object item) + { + LogInfo("Downloading object " + item.Key); + var message = await GetObject(item); + LogInfo("Downloaded object " + item.Key); + + using (var scope = Database.CreateTransactionScope()) + { + await Database.Save(message); + + LogInfo("Deleting object " + item.Key); + await Delete(item); + LogInfo("Deleted object " + item.Key); + } + + } + + async Task GetObject(Amazon.S3.Model.S3Object item) + { + var request = new Amazon.S3.Model.GetObjectRequest { Key = item.Key, BucketName = item.BucketName }; + var response = await S3Client.GetObjectAsync(request); + var sesMessage = MimeMessage.Load(response.ResponseStream); + return Account.CreateMailMessage(sesMessage); + } + + Task Delete(Amazon.S3.Model.S3Object item) + { + var request = new Amazon.S3.Model.DeleteObjectRequest { BucketName = item.BucketName, Key = item.Key }; + + return S3Client.DeleteObjectAsync(request); + } + + public void Dispose() + { + S3Client?.Dispose(); + } + } +} diff --git a/Olive.Aws.Ses.AutoFetch/IMailMessage.cs b/Olive.Aws.Ses.AutoFetch/IMailMessage.cs new file mode 100644 index 000000000..c50bd2997 --- /dev/null +++ b/Olive.Aws.Ses.AutoFetch/IMailMessage.cs @@ -0,0 +1,19 @@ +using Olive.Entities; +using System; +using System.Collections.Generic; +using System.Text; + +namespace Olive.Aws.Ses.AutoFetch +{ + public interface IMailMessage : IEntity + { + string From { get; set; } + string To { get; set; } + string Bcc { get; set; } + string Cc { get; set; } + string Subject { get; set; } + string HtmlBody { get; set; } + string Sender { get; set; } + DateTime Date { get; set; } + } +} diff --git a/Olive.Aws.Ses.AutoFetch/MailMessage.cs b/Olive.Aws.Ses.AutoFetch/MailMessage.cs new file mode 100644 index 000000000..b71e59adc --- /dev/null +++ b/Olive.Aws.Ses.AutoFetch/MailMessage.cs @@ -0,0 +1,11 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace Olive.Aws.Ses.AutoFetch +{ + class MailMessage : IMailMessage + { + + } +} diff --git a/Olive.Aws.Ses.AutoFetch/Olive.Aws.Ses.AutoFetch.csproj b/Olive.Aws.Ses.AutoFetch/Olive.Aws.Ses.AutoFetch.csproj index cae07f14e..2d1770ca7 100644 --- a/Olive.Aws.Ses.AutoFetch/Olive.Aws.Ses.AutoFetch.csproj +++ b/Olive.Aws.Ses.AutoFetch/Olive.Aws.Ses.AutoFetch.csproj @@ -17,13 +17,18 @@ 1701;1702;1705;1591;1573;NU1701 - + + + - + + + +