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
-
+
+
+
-
+
+
+
+