feat: Adding EmailClient

This commit is contained in:
Chris Cameron
2018-09-24 12:33:29 -04:00
parent 315bd703c7
commit e0fae0b112
4 changed files with 461 additions and 0 deletions

View File

@@ -0,0 +1,91 @@
#if SIMPLSHARP
using Crestron.SimplSharp;
#else
using System.Net.Mail;
#endif
using ICD.Common.Properties;
namespace ICD.Common.Utils.Email
{
public sealed class EmailClient
{
private readonly EmailStringCollection m_To;
private readonly EmailStringCollection m_Cc;
private readonly EmailStringCollection m_Bcc;
#region Properties
public string Host { get; set; }
public ushort Port { get; set; }
public bool Secure { get; set; }
public string Username { get; set; }
public string Password { get; set; }
public string From { get; set; }
public EmailStringCollection To { get { return m_To; } }
public EmailStringCollection Cc { get { return m_Cc; } }
public EmailStringCollection Bcc { get { return m_Bcc; } }
#endregion
/// <summary>
/// Constructor.
/// </summary>
public EmailClient()
{
m_To = new EmailStringCollection();
m_Cc = new EmailStringCollection();
m_Bcc = new EmailStringCollection();
}
#region Methods
/// <summary>
/// Sends the email.
/// </summary>
/// <param name="subject"></param>
/// <param name="message"></param>
/// <returns>Error codes.</returns>
[PublicAPI]
public eMailErrorCode Send(string subject, string message)
{
#if SIMPLSHARP
var response = CrestronMailFunctions.SendMail(Host, Port, Secure, Username, Password, From, m_To.ToString(), "",
m_Cc.ToString(), m_Bcc.ToString(), subject, message,
CrestronMailFunctions.eMailPriority.Normal, 0, "");
return MailErrorCodeUtils.FromSimplMailCode(response);
#else
try
{
MailMessage mailMessage = new MailMessage
{
From = new MailAddress(From),
To = {m_To.ToString()},
CC = {m_Cc.ToString()},
Bcc = {m_Bcc.ToString()},
Subject = subject,
Body = message
};
SmtpClient client = new SmtpClient
{
Port = Port,
DeliveryMethod = SmtpDeliveryMethod.Network,
UseDefaultCredentials = false,
Host = Host
};
client.Send(mailMessage);
}
catch (SmtpException ex)
{
return MailErrorCodeUtils.FromNetStandardMailCode(ex.StatusCode);
}
return eMailErrorCode.Ok;
#endif
}
#endregion
}
}

View File

@@ -0,0 +1,134 @@
using System.Collections;
using System.Collections.Generic;
using ICD.Common.Properties;
using ICD.Common.Utils.Extensions;
namespace ICD.Common.Utils.Email
{
/// <summary>
/// Stores addresses/paths and provides them in a ; delimited string.
/// </summary>
public sealed class EmailStringCollection : ICollection<string>
{
private const char DELIMITER = ';';
private readonly List<string> m_Items;
/// <summary>
/// Gets the number of items.
/// </summary>
public int Count { get { return m_Items.Count; } }
public bool IsReadOnly { get { return false; } }
/// <summary>
/// Constructor.
/// </summary>
public EmailStringCollection()
{
m_Items = new List<string>();
}
#region Methods
/// <summary>
/// Adds the item to the collection.
/// </summary>
/// <param name="item"></param>
/// <returns></returns>
[PublicAPI]
public bool Add(string item)
{
if (m_Items.Contains(item))
return false;
m_Items.Add(item);
return true;
}
/// <summary>
/// Removes the item from the collection.
/// </summary>
/// <param name="item"></param>
/// <returns></returns>
[PublicAPI]
public bool Remove(string item)
{
if (!m_Items.Contains(item))
return false;
m_Items.Remove(item);
return true;
}
/// <summary>
/// Clears all items.
/// </summary>
public void Clear()
{
m_Items.Clear();
}
/// <summary>
/// Returns true if the collection contains the item.
/// </summary>
/// <param name="item"></param>
/// <returns></returns>
[PublicAPI]
public bool Contains(string item)
{
return m_Items.Contains(item);
}
/// <summary>
/// Gets the items as a ; delimited string.
/// </summary>
/// <returns></returns>
public override string ToString()
{
return string.Join(DELIMITER.ToString(), m_Items.ToArray());
}
#endregion
#region Collection
void ICollection<string>.Add(string item)
{
Add(item);
}
/// <summary>
/// Adds multiple email addresses, seperated by ;
/// </summary>
/// <param name="items"></param>
public void AddMany(string items)
{
items = items.RemoveWhitespace();
string [] splitItems = items.Split(DELIMITER);
foreach (string item in splitItems)
Add(item);
}
public void CopyTo(string[] array, int arrayIndex)
{
m_Items.CopyTo(array, arrayIndex);
}
#endregion
#region Enumerable
public IEnumerator<string> GetEnumerator()
{
return m_Items.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
#endregion
}
}

View File

@@ -0,0 +1,233 @@
using System;
#if STANDARD
using System.Net.Mail;
#endif
#if SIMPLSHARP
using Crestron.SimplSharp;
#endif
namespace ICD.Common.Utils.Email
{
public enum eMailErrorCode
{
//
// Summary:
// The transaction could not occur. You receive this error when the specified SMTP
// host cannot be found.
GeneralFailure = -1,
//
// Summary:
// A system status or system Help reply.
SystemStatus = 211,
//
// Summary:
// A Help message was returned by the service.
HelpMessage = 214,
//
// Summary:
// The SMTP service is ready.
ServiceReady = 220,
//
// Summary:
// The SMTP service is closing the transmission channel.
ServiceClosingTransmissionChannel = 221,
//
// Summary:
// The email was successfully sent to the SMTP service.
Ok = 250,
//
// Summary:
// The user mailbox is not located on the receiving server; the server forwards
// the e-mail.
UserNotLocalWillForward = 251,
//
// Summary:
// The specified user is not local, but the receiving SMTP service accepted the
// message and attempted to deliver it. This status code is defined in RFC 1123,
// which is available at http://www.ietf.org/.
CannotVerifyUserWillAttemptDelivery = 252,
//
// Summary:
// The SMTP service is ready to receive the e-mail content.
StartMailInput = 354,
//
// Summary:
// The SMTP service is not available; the server is closing the transmission channel.
ServiceNotAvailable = 421,
//
// Summary:
// The destination mailbox is in use.
MailboxBusy = 450,
//
// Summary:
// The SMTP service cannot complete the request. This error can occur if the client's
// IP address cannot be resolved (that is, a reverse lookup failed). You can also
// receive this error if the client domain has been identified as an open relay
// or source for unsolicited e-mail (spam). For details, see RFC 2505, which is
// available at http://www.ietf.org/.
LocalErrorInProcessing = 451,
//
// Summary:
// The SMTP service does not have sufficient storage to complete the request.
InsufficientStorage = 452,
//
// Summary:
// The client was not authenticated or is not allowed to send mail using the specified
// SMTP host.
ClientNotPermitted = 454,
//
// Summary:
// The SMTP service does not recognize the specified command.
CommandUnrecognized = 500,
//
// Summary:
// The syntax used to specify a command or parameter is incorrect.
SyntaxError = 501,
//
// Summary:
// The SMTP service does not implement the specified command.
CommandNotImplemented = 502,
//
// Summary:
// The commands were sent in the incorrect sequence.
BadCommandSequence = 503,
//
// Summary:
// The SMTP service does not implement the specified command parameter.
CommandParameterNotImplemented = 504,
//
// Summary:
// The SMTP server is configured to accept only TLS connections, and the SMTP client
// is attempting to connect by using a non-TLS connection. The solution is for the
// user to set EnableSsl=true on the SMTP Client.
MustIssueStartTlsFirst = 530,
//
// Summary:
// The destination mailbox was not found or could not be accessed.
MailboxUnavailable = 550,
//
// Summary:
// The user mailbox is not located on the receiving server. You should resend using
// the supplied address information.
UserNotLocalTryAlternatePath = 551,
//
// Summary:
// The message is too large to be stored in the destination mailbox.
ExceededStorageAllocation = 552,
//
// Summary:
// The syntax used to specify the destination mailbox is incorrect.
MailboxNameNotAllowed = 553,
//
// Summary:
// The transaction failed.
TransactionFailed = 554
}
public static class MailErrorCodeUtils
{
#if STANDARD
public static eMailErrorCode FromNetStandardMailCode(SmtpStatusCode code)
{
switch (code)
{
case SmtpStatusCode.BadCommandSequence:
return eMailErrorCode.BadCommandSequence;
case SmtpStatusCode.CannotVerifyUserWillAttemptDelivery:
return eMailErrorCode.CannotVerifyUserWillAttemptDelivery;
case SmtpStatusCode.ClientNotPermitted:
return eMailErrorCode.ClientNotPermitted;
case SmtpStatusCode.CommandNotImplemented:
return eMailErrorCode.CommandNotImplemented;
case SmtpStatusCode.CommandParameterNotImplemented:
return eMailErrorCode.CommandParameterNotImplemented;
case SmtpStatusCode.CommandUnrecognized:
return eMailErrorCode.CommandUnrecognized;
case SmtpStatusCode.ExceededStorageAllocation:
return eMailErrorCode.ExceededStorageAllocation;
case SmtpStatusCode.GeneralFailure:
return eMailErrorCode.GeneralFailure;
case SmtpStatusCode.HelpMessage:
return eMailErrorCode.HelpMessage;
case SmtpStatusCode.InsufficientStorage:
return eMailErrorCode.InsufficientStorage;
case SmtpStatusCode.LocalErrorInProcessing:
return eMailErrorCode.LocalErrorInProcessing;
case SmtpStatusCode.MailboxBusy:
return eMailErrorCode.MailboxBusy;
case SmtpStatusCode.MailboxNameNotAllowed:
return eMailErrorCode.MailboxNameNotAllowed;
case SmtpStatusCode.MailboxUnavailable:
return eMailErrorCode.MailboxUnavailable;
case SmtpStatusCode.MustIssueStartTlsFirst:
return eMailErrorCode.MustIssueStartTlsFirst;
case SmtpStatusCode.Ok:
return eMailErrorCode.Ok;
case SmtpStatusCode.ServiceClosingTransmissionChannel:
return eMailErrorCode.ServiceClosingTransmissionChannel;
case SmtpStatusCode.ServiceNotAvailable:
return eMailErrorCode.ServiceNotAvailable;
case SmtpStatusCode.ServiceReady:
return eMailErrorCode.ServiceReady;
case SmtpStatusCode.StartMailInput:
return eMailErrorCode.StartMailInput;
case SmtpStatusCode.SyntaxError:
return eMailErrorCode.SyntaxError;
case SmtpStatusCode.SystemStatus:
return eMailErrorCode.SystemStatus;
case SmtpStatusCode.TransactionFailed:
return eMailErrorCode.TransactionFailed;
case SmtpStatusCode.UserNotLocalTryAlternatePath:
return eMailErrorCode.UserNotLocalTryAlternatePath;
case SmtpStatusCode.UserNotLocalWillForward:
return eMailErrorCode.UserNotLocalWillForward;
default:
throw new ArgumentOutOfRangeException(nameof(code), code, null);
}
}
#endif
#if SIMPLSHARP
public static eMailErrorCode FromSimplMailCode(CrestronMailFunctions.SendMailErrorCodes code)
{
switch (code)
{
case CrestronMailFunctions.SendMailErrorCodes.SMTP_OK:
return eMailErrorCode.Ok;
case CrestronMailFunctions.SendMailErrorCodes.SMTP_ERROR_FATAL:
return eMailErrorCode.GeneralFailure;
case CrestronMailFunctions.SendMailErrorCodes.SMTP_ERROR_ILLEGAL_CMD:
return eMailErrorCode.CommandUnrecognized;
case CrestronMailFunctions.SendMailErrorCodes.SMTP_ERROR_CONNECT:
return eMailErrorCode.ServiceNotAvailable;
case CrestronMailFunctions.SendMailErrorCodes.SMTP_ERROR_SEND:
return eMailErrorCode.GeneralFailure;
case CrestronMailFunctions.SendMailErrorCodes.SMTP_ERROR_RECV:
return eMailErrorCode.GeneralFailure;
case CrestronMailFunctions.SendMailErrorCodes.SMTP_ERROR_NU_CONNECT:
return eMailErrorCode.GeneralFailure;
case CrestronMailFunctions.SendMailErrorCodes.SMTP_ERROR_NU_BUFFERS:
return eMailErrorCode.GeneralFailure;
case CrestronMailFunctions.SendMailErrorCodes.SMTP_ERROR_AUTHENTICATION:
return eMailErrorCode.GeneralFailure;
case CrestronMailFunctions.SendMailErrorCodes.SMTP_ERROR_AUTH_LOGIN_UNSUPPORTED:
return eMailErrorCode.MustIssueStartTlsFirst;
case CrestronMailFunctions.SendMailErrorCodes.SMTP_INV_PARAM:
return eMailErrorCode.SyntaxError;
case CrestronMailFunctions.SendMailErrorCodes.SMTP_ETHER_NOT_ENABLED:
return eMailErrorCode.ServiceNotAvailable;
case CrestronMailFunctions.SendMailErrorCodes.SMTP_NO_SERVER_ADDRESS:
return eMailErrorCode.ServiceNotAvailable;
case CrestronMailFunctions.SendMailErrorCodes.SMTP_SEND_FAILED:
return eMailErrorCode.GeneralFailure;
case CrestronMailFunctions.SendMailErrorCodes.SMTP_GENERAL_SENDMAIL_ERROR:
return eMailErrorCode.GeneralFailure;
case CrestronMailFunctions.SendMailErrorCodes.SMTP_INVALID_FIRMWARE:
return eMailErrorCode.GeneralFailure;
default:
throw new ArgumentOutOfRangeException("code");
}
}
#endif
}
}

View File

@@ -84,6 +84,9 @@
<Compile Include="Comparers\PredicateComparer.cs" />
<Compile Include="Comparers\SequenceComparer.cs" />
<Compile Include="ConsoleColor.cs" />
<Compile Include="Email\EmailClient.cs" />
<Compile Include="Email\eMailErrorCode.cs" />
<Compile Include="Email\EmailStringCollection.cs" />
<Compile Include="EncodingUtils.cs" />
<Compile Include="Csv\CsvWriter.cs" />
<Compile Include="Csv\CsvWriterSettings.cs" />