From 658729c0d487c6bb96b2755a7eb86abb27af7f5e Mon Sep 17 00:00:00 2001 From: Priya Date: Tue, 10 Oct 2017 17:44:37 +0530 Subject: [PATCH] Added two new Methods "GetMessages" and "GetMailHeaders" "GetMessages" This method Retrieves the set of mail messages with the specified unique identifiers (UIDs) using the specified set of header names. "GetMailHeaders" This method Retrieves the mail headers for the mail message with the specified unique identifiers (mailIds) in a single command, instead of sending the same command multiple times. Both the methods improve performance in retrieving mail just by sending one command to fetch a set of mails instead of sending same command multiple times. --- ImapClient.cs | 105 +++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 104 insertions(+), 1 deletion(-) diff --git a/ImapClient.cs b/ImapClient.cs index f92baf4..62f744b 100644 --- a/ImapClient.cs +++ b/ImapClient.cs @@ -1267,6 +1267,109 @@ public IEnumerable GetMessages(IEnumerable uids, FetchOptions return list; } + /// + /// Retrieves the set of mail messages with the specified unique identifiers (UIDs) using the + /// specified set of header names. + /// + /// Unique identifiers of the all tha mail messages to + /// retrieve + /// The mailbox the messages will be retrieved from. If this parameter is + /// omitted, the value of the DefaultMailbox property is used to determine the mailbox to + /// operate on. + /// Names of headers in the mail messages to + /// retrieve + /// An enumerable collection of initialized instances of the MailMessage class + /// representing the fetched mail messages. + /// The mail messages could not be fetched. The + /// message property of the exception contains the error message returned by the + /// server. + /// The ImapClient object has been disposed. + /// There was a failure writing to or reading from the + /// network. + /// The method was called in non-authenticated + /// state, i.e. before logging in. + /// A unique identifier (UID) is a 32-bit value assigned to each message which uniquely + /// identifies the message within the respective mailbox. No two messages in a mailbox share + /// the same UID. + public IEnumerable GetMessages(IEnumerable mailIds, string mailbox = null, IEnumerable headerNames = null) + { + var mails = GetMailHeaders(mailIds, mailbox, headerNames); + List list = new List(); + foreach (var msg in mails) + list.Add( MessageBuilder.FromHeader(msg)); + return list; + } + + /// + /// Retrieves the mail headers for the mail message with the specified unique identifiers (mailIds) in a single command. + /// instead of sending the same command multiple times. + /// + /// The list of UIDs of the mail message to retrieve the mail header for. + /// The mailbox the messages will be retrieved from. If this parameter is + /// omitted, the value of the DefaultMailbox property is used to determine the mailbox to + /// operate on. + /// Names of headers in the mail messages to retrieve + /// An enumerable collection containing the raw mail headers of the mail messages with the specified + /// mailIds. + /// The mail header could not be fetched. The + /// message property of the exception contains the error message returned by the + /// server. + /// The ImapClient object has been disposed. + /// There was a failure writing to or reading from the + /// network. + /// The method was called in non-authenticated + /// state, i.e. before logging in. + private IEnumerable GetMailHeaders(IEnumerable mailIds, string mailbox = null, IEnumerable headerNames = null) + { + this.AssertValid(true); + //Convert the collection of mailIds into a single string + string uids = string.Join(",", mailIds.Select(i => i.ToString()).ToArray()); + Dictionary source = new Dictionary(); + if (!string.IsNullOrEmpty(uids)) + { + lock (this.sequenceLock) + { + this.PauseIdling(); + this.SelectMailbox(mailbox); + string tag = this.GetTag(); + //Convert the collection of headerNames into a single string + string headerFields = (headerNames == null ? string.Empty : ".FIELDS (" + string.Join(" ", (string[])headerNames) + ")"); + string response1 = this.SendCommandGetResponse(tag + "UID FETCH " + uids + " (FLAGS BODY.PEEK[HEADER" + headerFields + "])", false); + StringBuilder stringBuilder = new StringBuilder(); + for (; response1.StartsWith("*"); response1 = this.GetResponse(false)) + { + // UID for gmail is added first in the response otherwise it will be in the end of the response. + Match match1 = Regex.Match(response1, "\\* (\\d+) FETCH\\s+\\((?:\\s*UID\\s+(\\d+)\\s+)?FLAGS\\s+\\((.*)\\).*{(\\d+)}"); + Convert.ToInt32(match1.Groups[1].Value); + string key = match1.Groups[2].Value; + string str = match1.Groups[3].Value; + if (match1.Success) + { + int int32 = Convert.ToInt32(match1.Groups[4].Value); + stringBuilder.Append(this.GetData(int32)); + string response2 = this.GetResponse(true); + Match match2 = Regex.Match(response2, "(?:UID\\s+(\\d+)\\s*)?\\)\\s*$"); + if (!match2.Success) + throw new BadServerResponseException(response2); + if (string.IsNullOrEmpty(key)) + key = match2.Groups[1].Value; + stringBuilder.AppendLine("X-UID: " + key); + stringBuilder.AppendLine("X-FLAG: " + str); + if (!source.ContainsKey(key)) + { + source[key] = stringBuilder.ToString(); + stringBuilder = new StringBuilder(); + } + } + } + this.ResumeIdling(); + if (!this.IsResponseOK(response1, tag)) + throw new BadServerResponseException(response1); + } + } + return source.Select, string>((Func, string>)(x => x.Value)); + } + /// /// Stores the specified mail message on the IMAP server. /// @@ -2290,4 +2393,4 @@ void AssertValid(bool requireAuth = true) { /// true to include the body part in the returned MailMessage object, or false to skip /// it. public delegate bool ExaminePartDelegate(Bodypart part); -} \ No newline at end of file +}