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