using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using System.Net.Mail;
using System.Net.Mime;
using EmailServer.Services.DTOs.RequestDTOs;
using EmailServer.Services.DTOs.ResponseDTOs;
using EmailServer.Repositories.Entities;
using System.Net;
using EmailServer.Repositories;
using EmailServer.Services.Enum;
using System.Net.Http;
using System.Net.Http.Headers;
using EmailServer.Services.Interfaces;
using System.Threading.Tasks.Dataflow;
using EmailServer.Services.RequestDTOs;
using Microsoft.AspNetCore.Hosting;
using EmailServer.Services.HelperClass;
using EmailServer.Repositories.Model;
using System.Text;
namespace CodyEmail.Services.ServiceClass
{
public class EmailService : GenericService<Email>, IEmailService
{
private readonly EmailConfiguration _emailConfig;
private readonly IHostingEnvironment _environment;
private readonly StaticUrlConfiguration _staticUrlConfiguration;
public EmailService(IGenericRepository<Email> repository, IHostingEnvironment environment, EmailConfiguration emailConfig, StaticUrlConfiguration staticUrlConfiguration) : base(repository)
{
_emailConfig = emailConfig;
_environment = environment;
_staticUrlConfiguration = staticUrlConfiguration;
}
public async Task SendingEmails()
{
var emails = (await repository.GetByCondition(x => x.SentStatusCode == (int)SentEmailStatus.Unsent)).OrderBy(o => o.CreatedDate).ToList();
if (emails != null && emails.Count > 0)
{
var newEmails = new List<Email>();
var sendingEmailBlock = new TransformBlock<Email, Email>(
async email =>
{
return await SendingEmail(email);
}, new ExecutionDataflowBlockOptions
{
MaxDegreeOfParallelism = DataflowBlockOptions.Unbounded
});
var getReturnEmailBlock = new ActionBlock<Email>(m => newEmails.Add(m));
sendingEmailBlock.LinkTo(
getReturnEmailBlock, new DataflowLinkOptions
{
PropagateCompletion = true
});
foreach (var email in emails)
sendingEmailBlock.Post(email);
sendingEmailBlock.Complete();
getReturnEmailBlock.Completion.Wait();
if (newEmails.Count > 0)
{
await repository.Update(newEmails);
}
}
}
private async Task<Email> SendingEmail(Email email)
{
MailMessage mail = new MailMessage();
SmtpClient smtpClient = new SmtpClient(_emailConfig.SmtpServer);
MemoryStream stream=new MemoryStream();
try
{
mail.From = new MailAddress(email.From);
mail.Subject = email.Subject;
mail.Body = email.Body;
mail.IsBodyHtml = true;
smtpClient.Port = _emailConfig.Port;
smtpClient.EnableSsl = true;
if (email.To != null && email.To != string.Empty)
{
mail.To.Add(email.To);
}
if (email.Cc != null && email.Cc != string.Empty)
{
mail.CC.Add(email.Cc);
}
if (email.Bcc != null && email.Bcc != string.Empty)
{
mail.Bcc.Add(email.Bcc);
}
if (!string.IsNullOrEmpty(email.AttachmentURLs))
{
foreach (var attachmentURL in email.GetAttachmentURLs())
{
string attachmentsPath = Path.Combine(_environment.WebRootPath, _staticUrlConfiguration.Attachments, attachmentURL);
stream = await FilesHelper.Decrypt(attachmentsPath);
stream.Seek(0, SeekOrigin.Begin);
string fileName = Path.GetFileName(attachmentURL);
fileName = fileName.Substring(fileName.IndexOf("_")+1);
var attachFile = new Attachment(stream, fileName);
ContentType ct = new ContentType();
ct.MediaType = MediaTypeNames.Text.Plain;
ct.Name = fileName;
attachFile.ContentType = ct;
mail.Attachments.Add(attachFile);
}
}
await smtpClient.SendMailAsync(mail);
Console.WriteLine($"Sent success to {email.To}");
email.SentDate = DateTime.Now;
email.SentStatusCode = (int)SentEmailStatus.Success;
email.SentDescription = $"Sent success to {email.To}";
return email;
}
catch (Exception ex)
{
Console.WriteLine($"Error from Smtp: {ex.Message}");
email.SentDate = DateTime.Now;
email.SentStatusCode = (int)SentEmailStatus.SmtpError;
email.SentDescription = $"Error from Smtp: {ex.Message}";
return email;
}
finally
{
if (!ReferenceEquals(mail, null))
mail.Dispose();
if (!ReferenceEquals(smtpClient, null))
smtpClient.Dispose();
if (stream != null)
{
stream.Dispose();
stream.Close();
}
}
}
}
}